[ewg] [PATCH 3/9] [RFC] Add in Xsigo session management protocol (XSMP)

Hal Rosenstock hrosenstock at xsigo.com
Fri Apr 4 06:13:06 PDT 2008


Xsigo session management protocol (XSMP) is an RC based management
protocol. It is utilized to obtain Xsigo chassis configuration 
information pertaining to the host as well as for "control" of the
data connection.

Signed-off-by: Hal Rosenstock <hal at xsigo.com>
---
 drivers/infiniband/ulp/xsigo/xscore/xs_versions.h  |   52 ++
 drivers/infiniband/ulp/xsigo/xscore/xsmp.c         |  487 ++++++++++++++++++++
 drivers/infiniband/ulp/xsigo/xscore/xsmp.h         |   61 +++
 drivers/infiniband/ulp/xsigo/xscore/xsmp_common.h  |   85 ++++
 drivers/infiniband/ulp/xsigo/xscore/xsmp_session.h |  112 +++++
 5 files changed, 797 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/ulp/xsigo/xscore/xs_versions.h
 create mode 100644 drivers/infiniband/ulp/xsigo/xscore/xsmp.c
 create mode 100644 drivers/infiniband/ulp/xsigo/xscore/xsmp.h
 create mode 100644 drivers/infiniband/ulp/xsigo/xscore/xsmp_common.h
 create mode 100644 drivers/infiniband/ulp/xsigo/xscore/xsmp_session.h

diff --git a/drivers/infiniband/ulp/xsigo/xscore/xs_versions.h b/drivers/infiniband/ulp/xsigo/xscore/xs_versions.h
new file mode 100644
index 0000000..eb22104
--- /dev/null
+++ b/drivers/infiniband/ulp/xsigo/xscore/xs_versions.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006-2008 Xsigo Systems Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __XS_VERSIONS_H_INCLUDED__
+#define __XS_VERSIONS_H_INCLUDED__
+
+/*
+ * for the simplest implementation, the following is defined as hex integers
+ *
+ * e.g. version string 2.4.5  will be 0x020405
+ *
+ * The max version string can be: 255.255.255 (0xffffff)
+ *
+ */
+
+/* Current Linux driver version */
+#define XSIGO_LINUX_DRIVER_VERSION	0x010600	/* 1.6.0 */
+
+/* The minimum xsigos version that works with above driver version */
+#define MINIMUM_XSIGOS_VERSION		0x010500	/* 1.5.0 */
+
+#endif /* __XS_VERSIONS_H_INCLUDED__ */
diff --git a/drivers/infiniband/ulp/xsigo/xscore/xsmp.c b/drivers/infiniband/ulp/xsigo/xscore/xsmp.c
new file mode 100644
index 0000000..40ecf48
--- /dev/null
+++ b/drivers/infiniband/ulp/xsigo/xscore/xsmp.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2006-2008 Xsigo Systems Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+
+#include "xsmp.h"
+#include "xs_versions.h"
+
+struct kmem_cache *xsmp_cachep = NULL;
+
+/* Is this a local message for the XCPM: a session management message */
+int xsmp_is_local_msg(u8 *buf)
+{
+	return (*(u8 *) buf == XSMP_MESSAGE_TYPE_SESSION);
+}
+
+/* Convert all messages to and from network byte order */
+static int xsmp_swizzle(int direction, int link, u8 *msg)
+{
+	int rem_length, num_msgs, count;
+	int ret = 0;
+	struct xsmp_message_header *header = (struct xsmp_message_header *) msg;
+	struct xsmp_session_msg *session_msg =
+			(struct xsmp_session_msg *) (msg + sizeof(*header));
+	struct xsmp_error_stats_msg *error_stats_msg =
+			(struct xsmp_error_stats_msg *) (msg + sizeof(*header));
+
+	/* Total length of the message */
+	if (direction == N_TO_H && header->type == XSMP_MESSAGE_TYPE_SESSION)
+		rem_length = be16_to_cpu(header->length);
+	else if (direction == H_TO_N &&
+		 header->type == XSMP_MESSAGE_TYPE_SESSION) {
+		rem_length = header->length;
+		BUG_ON(rem_length > max(sizeof(struct xsmp_session_msg),
+					sizeof(struct xsmp_error_stats_msg)) + sizeof(struct xsmp_message_header));
+	} else {
+		xcpm_debug(KERN_ERR,
+			   "Header type <0x%x> not of a local message\n",
+			   header->type);
+		ret = -EINVAL;
+		goto xsmp_swizzle_exit;
+	}
+
+	if (direction == H_TO_N)
+		xcpm_debug(KERN_INFO,
+			   "Sending message: type <0x%x>, length <0x%x>\n",
+			   header->type, header->length);
+
+	if (direction == N_TO_H)
+		xcpm_debug(KERN_INFO,
+			   "Message received: type <0x%x>, length <0x%x>, "
+			   "sequence_number <0x%x>\n", header->type,
+			   cpu_to_be16(header->length),
+			   cpu_to_be32(header->seq_number));
+
+	/* Swizzle the header first */
+	header->length = be16_to_cpu(header->length);
+	header->seq_number = be32_to_cpu(header->seq_number);
+
+	rem_length -= sizeof(*header);
+
+	/* Is it an error_stats msg */
+	if (error_stats_msg->type == XSMP_SESSION_ERROR_STATS) {
+		if (rem_length % sizeof(*error_stats_msg) != 0) {
+			xcpm_debug(KERN_ERR,
+				   "Incorrect error stats message size\n");
+			log_link_error(link, XSMP_MESSAGE_LENGTH_INVALID);
+			ret = -EINVAL;
+			goto xsmp_swizzle_exit;
+		}
+
+		error_stats_msg->length = cpu_to_be16(error_stats_msg->length);
+
+		/* Swizzle */
+		for (count = 0; count < XSMP_MAX_ERROR_TYPES; count++)
+			error_stats_msg->error_counts[count] =
+			    cpu_to_be32(error_stats_msg->error_counts[count]);
+
+		/* Only one message */
+		goto xsmp_swizzle_exit;
+	}
+
+	if (rem_length % sizeof(*session_msg) != 0) {
+		xcpm_debug(KERN_ERR, "Incorrect session message size (%d %d)\n",
+			   rem_length, (int) sizeof(*session_msg));
+		log_link_error(link, XSMP_MESSAGE_LENGTH_INVALID);
+		ret = -EINVAL;
+		goto xsmp_swizzle_exit;
+	}
+
+	num_msgs = rem_length / sizeof(*session_msg);
+
+	for (count = 0; count < num_msgs; count++) {
+		session_msg->length = cpu_to_be16(session_msg->length);
+		session_msg->resource_flags =
+				cpu_to_be32(session_msg->resource_flags);
+		session_msg->version = cpu_to_be32(session_msg->version);
+		session_msg->chassis_version =
+				cpu_to_be32(session_msg->chassis_version);
+		session_msg->boot_flags = cpu_to_be32(session_msg->boot_flags);
+		session_msg->fw_ver = cpu_to_be64(session_msg->fw_ver);
+		session_msg->hw_ver = cpu_to_be32(session_msg->hw_ver);
+		session_msg->vendor_part_id =
+				cpu_to_be32(session_msg->vendor_part_id);
+
+		session_msg++;
+	}
+
+xsmp_swizzle_exit:
+	return ret;
+}
+
+/* Set the source and destination IDs in the message header */
+void xsmp_set_source_dest_ids(int link, u8 *data)
+{
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) data;
+
+	/* The 'primary' of the node ID is the port 'guid' */
+	m_header->source_id.node_id_primary = get_link_guid(link);
+
+	/* The 'aux' of the node ID is 0 for now */
+	m_header->source_id.node_id_aux = 0;
+	m_header->dest_id.node_id_primary = get_dest_guid(link);
+	m_header->dest_id.node_id_aux = 0;
+}
+
+/* Send a register message to the XCM */
+int xsmp_link_connect_send(int link, u32 resource_flags, u64 fw_ver, u32 hw_ver,
+			   u32 vendor_part_id)
+{
+	u8 *msg = (u8 *) kmem_cache_alloc(xsmp_cachep, GFP_ATOMIC);
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) msg;
+	struct xsmp_session_msg *m_session =
+			(struct xsmp_session_msg *) (msg + sizeof(*m_header));
+
+	if (!msg) {
+		printk(KERN_ERR PFX "%s cache allocation failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(msg, 0, sizeof(*m_header) + sizeof(*m_session));
+
+	m_header->type = XSMP_MESSAGE_TYPE_SESSION;
+	m_header->length = sizeof(*m_header) + sizeof(*m_session);
+
+	m_session->type = XSMP_SESSION_REGISTER;
+	m_session->length = sizeof(*m_session);
+	m_session->resource_flags = resource_flags;
+	m_session->version = XSIGO_LINUX_DRIVER_VERSION;
+	m_session->chassis_version = MINIMUM_XSIGOS_VERSION;
+	m_session->boot_flags = boot_flag;
+	m_session->fw_ver = fw_ver;
+	m_session->hw_ver = hw_ver;
+	m_session->vendor_part_id = vendor_part_id;
+
+	xsmp_swizzle(H_TO_N, link, msg);
+
+	return transmit_to_xcm(link, msg,
+			       sizeof(*m_header) + sizeof(*m_session));
+}
+
+static int xsmp_send_hello(int link)
+{
+	u8 *msg = (u8 *) kmem_cache_alloc(xsmp_cachep, GFP_ATOMIC);
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) msg;
+	struct xsmp_session_msg *m_session =
+			(struct xsmp_session_msg *) (msg + sizeof(*m_header));
+
+	if (!msg) {
+		printk(KERN_ERR PFX "%s cache allocation failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(msg, 0, sizeof(*m_header) + sizeof(*m_session));
+
+	m_header->type = XSMP_MESSAGE_TYPE_SESSION;
+	m_header->length = sizeof(*m_header) + sizeof(*m_session);
+
+	m_session->type = XSMP_SESSION_HELLO;
+	m_session->length = sizeof(*m_session);
+
+	xsmp_swizzle(H_TO_N, link, msg);
+
+	return transmit_to_xcm(link, msg,
+			       sizeof(*m_header) + sizeof(*m_session));
+}
+
+int xsmp_send_resource_list(int link, u32 resource_flags)
+{
+	u8 *msg = (u8 *) kmem_cache_alloc(xsmp_cachep, GFP_ATOMIC);
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) msg;
+	struct xsmp_session_msg *m_session =
+			(struct xsmp_session_msg *) (msg + sizeof(*m_header));
+
+	if (!msg) {
+		printk(KERN_ERR PFX "%s cache allocation failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(msg, 0, sizeof(*m_header) + sizeof(*m_session));
+
+	m_header->type = XSMP_MESSAGE_TYPE_SESSION;
+	m_header->length = sizeof(*m_header) + sizeof(*m_session);
+
+	m_session->type = XSMP_SESSION_RESOURCE_LIST;
+	m_session->length = sizeof(*m_session);
+	m_session->resource_flags = resource_flags;
+
+	xsmp_swizzle(H_TO_N, link, msg);
+
+	return transmit_to_xcm(link, msg,
+			       sizeof(*m_header) + sizeof(*m_session));
+}
+
+int xsmp_send_shutdown(int link)
+{
+	u8 *msg = (u8 *) kmem_cache_alloc(xsmp_cachep, GFP_ATOMIC);
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) msg;
+	struct xsmp_session_msg *m_session =
+			(struct xsmp_session_msg *) (msg + sizeof(*m_header));
+
+	if (!msg) {
+		printk(KERN_ERR PFX "%s cache allocation failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(msg, 0, sizeof(*m_header) + sizeof(*m_session));
+
+	m_header->type = XSMP_MESSAGE_TYPE_SESSION;
+	m_header->length = sizeof(*m_header) + sizeof(*m_session);
+
+	m_session->type = XSMP_SESSION_SHUTDOWN;
+	m_session->length = sizeof(*m_session);
+
+	xsmp_swizzle(H_TO_N, link, msg);
+
+	return transmit_to_xcm(link, msg,
+			       sizeof(*m_header) + sizeof(*m_session));
+}
+
+/* Process an XSMP message received on one of the links */
+void xsmp_process_local_msg(int link, u8 *data, int length)
+{
+	int num_msgs, count;
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) data;
+	struct xsmp_session_msg *m_session =
+			(struct xsmp_session_msg *) (data + sizeof(*m_header));
+
+	/* Message not long enough */
+	if (length < sizeof(*m_header)) {
+		xcpm_debug(KERN_ERR, "Message too short\n");
+		log_link_error(link, XSMP_MESSAGE_LENGTH_INVALID);
+		goto local_msg_exit;
+	}
+
+	if (xsmp_swizzle(N_TO_H, link, data)) {
+		xcpm_debug(KERN_ERR,
+			   "Errors in the received message, dropping it\n");
+		goto local_msg_exit;
+	}
+
+	/* Sanity checks */
+	if (m_header->type != XSMP_MESSAGE_TYPE_SESSION) {
+		xcpm_debug(KERN_ERR, "Wrong message type <0x%x>\n",
+			   m_header->type);
+		log_link_error(link, XSMP_MESSAGE_TYPE_INVALID);
+		goto local_msg_exit;
+	}
+
+	if (m_header->length > length) {
+		xcpm_debug(KERN_INFO,
+			   "(warning) Header length %d exceeds actual length %d\n",
+			   m_header->length, length);
+		log_link_error(link, XSMP_MESSAGE_LENGTH_INVALID);
+	}
+
+	length = m_header->length;
+	length -= sizeof(*m_header);
+
+	/* One message if it's an error count message */
+	if (m_session->type == XSMP_SESSION_ERROR_STATS)
+		num_msgs = length / sizeof(struct xsmp_error_stats_msg);
+	else
+		num_msgs = length / sizeof(*m_session);
+
+	for (count = 0; count < num_msgs; count++) {
+		switch (m_session->type) {
+		case XSMP_SESSION_HELLO:
+		{
+			struct timeval tv;
+
+			do_gettimeofday(&tv);
+
+			xcpm_debug(KERN_INFO, "Received a HELLO "
+				   "[secs: %d]\n", (int) tv.tv_sec);
+			if (is_link_alive(link) &&
+			    is_link_confirmed(link)) {
+				increment_hellos_received(link);
+
+				/* Reset the expiry time */
+				update_linkstate(link);
+
+				xcpm_debug(KERN_INFO, "Sending back a HELLO...\n");
+
+				/* Send back a HELLO (be polite) */
+				if (xsmp_send_hello(link) == 0)
+					increment_hellos_sent(link);
+			}
+
+			break;
+		}
+
+		case XSMP_SESSION_REG_CONFIRM:
+		{
+			/*
+			 * The link is in the 'Init' state,
+			 * put it to 'Up' now
+			 * Set the 'confirmed' bit indicating that
+			 * we got a confirmation
+			 * Pass the timeout parameters
+			 */
+			set_link_ready(link, m_session->version,
+				       m_session->resource_flags);
+
+			/* Send the latest resource list to the new XCM */
+			send_service_status(link);
+
+			break;
+		}
+
+		case XSMP_SESSION_REG_REJECT:
+		{
+			printk(KERN_ERR PFX "Received a REJECT "
+			       "(due to version mismatch with chassis), "
+			       "aborting connection\n");
+
+			/*
+			 * The connection has been rejected,
+			 * so bring down the link
+			 */
+			bring_down_link(link);
+
+			break;
+		}
+
+		case XSMP_SESSION_SHUTDOWN:
+		{
+			xcpm_debug(KERN_ERR,
+				   "Received a SHUTDOWN, aborting the connection\n");
+
+			delete_link(link);
+
+			break;
+		}
+
+		case XSMP_SESSION_ERROR_STATS:
+		{
+			xcpm_debug(KERN_INFO,
+				   "Error stats request received\n");
+
+			send_error_counts(link);
+
+			break;
+		}
+
+		default:
+		{
+			xcpm_debug(KERN_ERR,
+				   "Unknown session message type <0x%x>\n",
+				   m_session->type);
+			log_link_error(link, XSMP_SESSION_MESSAGE_TYPE_INVALID);
+			goto local_msg_exit;
+		}
+		}		/* end switch */
+
+		m_session++;
+	}
+
+local_msg_exit:
+	return;
+}
+
+/*
+ * Does the message belong to a service with the mentioned
+ * control message type ?
+ */
+int xsmp_msg_belongs(u16 ctrl_message_type, u8 *buf)
+{
+	return (ctrl_message_type == *(u8 *) buf);
+}
+
+/* Set the sequence number in the message (in the network byte order) */
+void xsmp_set_seq_number(u8 *data, u32 seq_number)
+{
+	*(u32 *) (data + 4) = cpu_to_be32(seq_number);
+}
+
+/* Get the sequence number from the message (in the network byte order) */
+u32 xsmp_get_seq_number(u8 *data)
+{
+	return be32_to_cpu(*(u32 *) (data + 4));
+}
+
+/* Handling of error count messages to the XCM */
+int xsmp_send_error_counts(int link, u32 *error_counts)
+{
+	u8 *msg = (u8 *) kmem_cache_alloc(xsmp_cachep, GFP_ATOMIC);
+	struct xsmp_message_header *m_header =
+					(struct xsmp_message_header *) msg;
+	struct xsmp_error_stats_msg *m_stats =
+			(struct xsmp_error_stats_msg *) (msg + sizeof(*m_header));
+
+	if (!msg) {
+		printk(KERN_ERR PFX "%s cache allocation failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(msg, 0, sizeof(*m_header) + sizeof(*m_stats));
+
+	m_header->type = XSMP_MESSAGE_TYPE_SESSION;
+	m_header->length = sizeof(*m_header) + sizeof(*m_stats);
+
+	m_stats->type = XSMP_SESSION_ERROR_STATS;
+	m_stats->length = sizeof(*m_stats);
+	memcpy(m_stats->error_counts, error_counts,
+	       sizeof(u32) * XSMP_MAX_ERROR_TYPES);
+
+	xsmp_swizzle(H_TO_N, link, msg);
+
+	return transmit_to_xcm(link, msg,
+			       sizeof(*m_header) + sizeof(*m_stats));
+}
+
+/* Memory pools */
+int alloc_xsmp_mem_pool(void)
+{
+	xsmp_cachep = kmem_cache_create("xscore_xcpm_xsmp_cache",
+					max(sizeof(struct xsmp_session_msg), sizeof(struct xsmp_error_stats_msg)) + sizeof(struct xsmp_message_header),
+					0, 0, NULL);
+
+	return (xsmp_cachep == NULL) ? -ENOMEM : 0;
+}
+
+void dealloc_xsmp_mem_pool(void)
+{
+	if (xsmp_cachep)
+		kmem_cache_destroy(xsmp_cachep);
+}
diff --git a/drivers/infiniband/ulp/xsigo/xscore/xsmp.h b/drivers/infiniband/ulp/xsigo/xscore/xsmp.h
new file mode 100644
index 0000000..3f35ad2
--- /dev/null
+++ b/drivers/infiniband/ulp/xsigo/xscore/xsmp.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006-2008 Xsigo Systems Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __XSMP_H__
+#define __XSMP_H__
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <asm/byteorder.h>
+
+#include "xsmp_session.h"
+#include "xcpm_export.h"
+
+#define H_TO_N	0
+#define N_TO_H	1
+
+int xsmp_is_local_msg(u8 *buf);
+void xsmp_process_local_msg(int link, u8 *data, int length);
+int xsmp_msg_belongs(u16 ctrl_message_type, u8 *buf);
+int xsmp_link_connect_send(int link, u32 resource_flags, u64 fw_ver,
+			   u32 hw_ver, u32 vendor_part_id);
+void xsmp_set_seq_number(u8 *data, u32 seq_number);
+u32 xsmp_get_seq_number(u8 *data);
+int xsmp_send_shutdown(int link);
+int xsmp_send_resource_list(int link, u32 resource_flags);
+void xsmp_set_source_dest_ids(int link, u8 *data);
+int xsmp_send_error_counts(int link, u32 *error_counts);
+int alloc_xsmp_mem_pool(void);
+void dealloc_xsmp_mem_pool(void);
+
+#endif	/* __XSMP_H__ */
diff --git a/drivers/infiniband/ulp/xsigo/xscore/xsmp_common.h b/drivers/infiniband/ulp/xsigo/xscore/xsmp_common.h
new file mode 100644
index 0000000..59686cf
--- /dev/null
+++ b/drivers/infiniband/ulp/xsigo/xscore/xsmp_common.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006-2008 Xsigo Systems Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __XSMP_COMMON_H__
+#define __XSMP_COMMON_H__
+
+/*
+ *	Node ID: A 96-bit identifier of the initiating node
+ *	The lower part is the 'guid'
+ */
+struct xsmp_node_id {
+	u32 node_id_aux;
+	u64 node_id_primary;
+} __attribute__ ((packed));
+
+/*
+ *	The XSMP message header
+ *
+ *	The message header precedes all XSMP messages from either
+ *	the XCM or the server.
+ *	'message_type' identifies the class of the message.
+ *	'seq_number' is a serially incrementing count (different
+ *	for each direction) used to track the order of messages.
+ *
+ *	This is followed by a series of message objects (of the same
+ *	class) adding up to the 'length' field of the header.
+ */
+struct xsmp_message_header {
+	u8 type;
+	u8 code;
+	u16 length;
+	u32 seq_number;
+	struct xsmp_node_id source_id;
+	struct xsmp_node_id dest_id;
+};
+
+#define XSMP_MESSAGE_TYPE_SESSION	1
+#define XSMP_MESSAGE_TYPE_VNIC		2
+#define XSMP_MESSAGE_TYPE_VHBA		3
+#define XSMP_MESSAGE_TYPE_VSSL		4
+#define XSMP_MESSAGE_TYPE_USPACE	5
+
+#define XSMP_MESSAGE_TYPE_MAX		8
+
+#define RESOURCE_VNIC	(1 << 0)
+#define RESOURCE_VHBA	(1 << 1)
+#define RESOURCE_VSSL	(1 << 2)
+#define RESOURCE_USPACE	(1 << 3)
+
+#define RESOURCE_FLAG_INDEX_VNIC	0
+#define RESOURCE_FLAG_INDEX_VHBA	1
+#define RESOURCE_FLAG_INDEX_VSSL	2
+#define RESOURCE_FLAG_INDEX_USPACE	3
+
+#endif	/* __XSMP_COMMON_H__ */
diff --git a/drivers/infiniband/ulp/xsigo/xscore/xsmp_session.h b/drivers/infiniband/ulp/xsigo/xscore/xsmp_session.h
new file mode 100644
index 0000000..16c07e4
--- /dev/null
+++ b/drivers/infiniband/ulp/xsigo/xscore/xsmp_session.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2006-2008 Xsigo Systems Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __XSMP_SESSION_H__
+#define __XSMP_SESSION_H__
+
+#include "xsmp_common.h"
+
+/* Session management messages */
+
+/* Session message types */
+enum xsmp_session_cmd_type {
+	XSMP_SESSION_UNUSED = 0,
+
+	/* Heartbeat between the server and XCM */
+	XSMP_SESSION_HELLO,
+
+	/*
+	 * Used by the server while initiating a connection to an XCM
+	 * 'resource_flags' specify which services are already active
+	 */
+	XSMP_SESSION_REGISTER,
+
+	/* Positive reply from XCM in response to a register from server */
+	XSMP_SESSION_REG_CONFIRM,
+
+	/*
+	 * Negative reply from XCM in response to a register from server
+	 * 'reason_code' specifies the reason for the reject
+	 */
+	XSMP_SESSION_REG_REJECT,
+
+	/* Session shutdown message: initiated by either server or XCM */
+	XSMP_SESSION_SHUTDOWN,
+
+	/* List of services that are active: sent by server to XCM */
+	XSMP_SESSION_RESOURCE_LIST,
+
+	/* Set of error counts sent by server to XCM */
+	XSMP_SESSION_ERROR_STATS,
+
+	/*
+	 * Secondary timeout value specified by XCM
+	 * after which the datapaths are aborted
+	 */
+	XSMP_VNIC_STALE_TIME,
+};
+
+struct xsmp_session_msg {
+	u8 type;
+	u8 code;
+	u16 length;
+	u32 resource_flags;
+	u32 version;         /* current driver version */
+	u32 chassis_version; /* version of chassis SW this driver can work with */
+	u32 boot_flags;
+	u64 fw_ver;
+	u32 hw_ver;
+	u32 vendor_part_id;
+} __attribute__ ((packed));
+
+#define XSMP_MAX_ERROR_TYPES	16
+
+/* Indices for the 'error_counts' field */
+enum xsmp_error_index {
+	XSMP_MESSAGE_TYPE_INVALID,	/* Message type invalid */
+	XSMP_SESSION_MESSAGE_TYPE_INVALID, /* Session message type invalid */
+	XSMP_MESSAGE_LENGTH_INVALID,	/* Invalid length of the message */
+	XSMP_UNDELIVERABLE_MSG_ERROR,	/* XSMP message undeliverable */
+
+	XSMP_ERROR_INDEX_MAX
+};
+
+struct xsmp_error_stats_msg {
+	u8 type;
+	u8 code;
+	u16 length;
+	u32 _reserved2;
+	u32 error_counts[XSMP_MAX_ERROR_TYPES];
+};
+
+#endif	/* __XSMP_SESSION_H__ */
-- 
1.5.2






More information about the ewg mailing list