public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
From: Tamir Ronen <tamirr-smomgflXvOZWk0Htik3J/w@public.gmane.org>
To: weiny2-i2BcT+NCU+M@public.gmane.org
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH] infiniband-diags: add support for ibnetdiscover grouping for Mellanox switches
Date: Wed, 9 Feb 2011 17:41:09 +0200	[thread overview]
Message-ID: <4D52B595.3020302@voltaire.com> (raw)


>From f1c92f4cae5605dec338b52ac6b261ddbe6e5609 Mon Sep 17 00:00:00 2001
From: Tamir Ronen <tamirr-smomgflXvOZWk0Htik3J/w@public.gmane.org>
Date: Tue, 8 Feb 2011 13:01:22 +0200
Subject: [PATCH] add support for ibnetdiscover grouping for Mellanox switches

Group Mellanox switches to the same chassis using SYSTEM_GUID
Use the node description format:
'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
to identify system type, slot type Line/Spine, slotnum and anafanum.
Map Line ports 1-18 as external ports 1-18.
---
 .../libibnetdisc/include/infiniband/ibnetdisc.h    |    3 +
 infiniband-diags/libibnetdisc/src/chassis.c        |  220 ++++++++++++++++++-
 infiniband-diags/libibnetdisc/src/chassis.h        |    3 +
 3 files changed, 214 insertions(+), 12 deletions(-)

diff --git a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
index 935e427..1efd1d6 100644
--- a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
+++ b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
@@ -43,6 +43,8 @@
 struct ibnd_chassis;		/* forward declare */
 struct ibnd_port;		/* forward declare */
 
+#define CHASSIS_TYPE_SIZE 20
+
 /** =========================================================================
  * Node
  */
@@ -80,6 +82,7 @@ typedef struct ibnd_node {
 	struct ibnd_node *next_chassis_node;	/* next node in ibnd_chassis_t->nodes */
 	struct ibnd_chassis *chassis;	/* if != NULL the chassis this node belongs to */
 	unsigned char ch_type;
+	char ch_type_str[CHASSIS_TYPE_SIZE];
 	unsigned char ch_anafanum;
 	unsigned char ch_slotnum;
 	unsigned char ch_slot;
diff --git a/infiniband-diags/libibnetdisc/src/chassis.c b/infiniband-diags/libibnetdisc/src/chassis.c
index 6bfc45b..3d90034 100644
--- a/infiniband-diags/libibnetdisc/src/chassis.c
+++ b/infiniband-diags/libibnetdisc/src/chassis.c
@@ -62,30 +62,53 @@ typedef struct chassis_scan {
 
 char *ibnd_get_chassis_type(ibnd_node_t * node)
 {
+	int chassis_type;
+
 	if (!node) {
 		IBND_DEBUG("node parameter NULL\n");
 		return NULL;
 	}
 
-	/* Currently, only if Voltaire chassis */
-	if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
-		return NULL;
 	if (!node->chassis)
 		return NULL;
-	if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
-		return NULL;
-	return ChassisTypeStr[node->ch_type];
+
+	chassis_type = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
+
+	switch (chassis_type)
+	{
+		case VTR_VENDOR_ID: /* Voltaire chassis */
+		{
+			if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
+				return NULL;
+			return ChassisTypeStr[node->ch_type];
+		}
+		case MLX_VENDOR_ID:
+		{
+			if (node->ch_type_str[0] == '\0')
+				return NULL;
+			return node->ch_type_str;
+		}
+		default:
+		{
+			break;
+		}
+	}
+	return NULL;
 }
 
 char *ibnd_get_chassis_slot_str(ibnd_node_t * node, char *str, size_t size)
 {
+	int vendor_id;
+
 	if (!node) {
 		IBND_DEBUG("node parameter NULL\n");
 		return NULL;
 	}
 
-	/* Currently, only if Voltaire chassis */
-	if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
+	/* Currently, only if Voltaire or Mellanox chassis */
+	vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
+
+	if ((vendor_id != VTR_VENDOR_ID) && (vendor_id != MLX_VENDOR_ID))
 		return NULL;
 	if (!node->chassis)
 		return NULL;
@@ -574,6 +597,166 @@ static int get_slb_slot(ibnd_node_t * n, ibnd_port_t * spineport)
 	return 0;
 }
 
+
+/*
+	This function called for every Mellanox node in fabric
+*/
+static int fill_mellanox_chassis_record(ibnd_node_t * node)
+{
+	int p = 0;
+	ibnd_port_t *port;
+
+	char node_desc[IB_SMP_DATA_SIZE];
+	char *system_name;
+	char *system_type;
+	char *system_slot_name;
+	char *node_index;
+	char *iter;
+	int dev_id;
+
+	/*
+	The node description has the following format:
+
+	'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
+
+     - System slot name in our systems can be L[01-36] , S[01-18]
+     - Node index is always 1 (we don.t have boards with multiple IS4 chips).
+     - System name is taken from the currently configured host name.
+     -The board type is optional and we don.t set it currently  - A leaf or spine slot can currently hold a single type of board.
+	 */
+
+	memcpy(node_desc, node->nodedesc, IB_SMP_DATA_SIZE);
+
+	IBND_DEBUG("fill_mellanox_chassis_record: node_desc:%s \n",node_desc);
+
+	if (node->ch_found)	/* somehow this node has already been passed */
+		return 0;
+
+	/* All mellanox IS4 switches have the same vendor id*/
+	dev_id = mad_get_field(node->info, 0,IB_NODE_DEVID_F);
+	if (dev_id != MLX_DEVID_IS4)
+		return 0;
+
+	if((node_desc[0] != 'M') ||
+	   (node_desc[1] != 'F') ||
+	   (node_desc[2] != '0') ||
+	   (node_desc[3] != ';')) {
+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s \n",node_desc);
+		return 0;
+	}
+
+	/* parse system name*/
+	system_name = &node_desc[4];
+	for (iter = system_name ; (*iter != ':') && (*iter != '\0') ; iter++);
+	if(*iter == '\0'){
+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_name failed) \n",node_desc);
+		return 0;
+	}
+	*iter = '\0';
+	iter++;
+	/* parse system type*/
+	system_type = iter;
+	for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
+	if(*iter == '\0'){
+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_type failed) \n",node_desc);
+		return 0;
+	}
+	*iter = '\0';
+	iter++;
+	/* parse system slot name*/
+	system_slot_name = iter;
+	for ( ; (*iter != '/') && (*iter != ':') && (*iter != '\0') ; iter++);
+	if(*iter == '\0'){
+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_slot_name failed) \n",node_desc);
+		return 0;
+	}
+	if(*iter == ':'){
+		*iter = '\0';
+		iter++;
+		for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
+		if(*iter == '\0'){
+			IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get board type failed) \n",node_desc);
+			return 0;
+		}
+	}
+	*iter = '\0';
+	iter++;
+	node_index = iter;
+	if(node_index[0] != 'U'){
+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get node index) \n",node_desc);
+		return 0;
+	}
+
+	/* set Chip number (node index) */
+	node->ch_anafanum = atoi(&node_index[1]);
+	if(node->ch_anafanum != 1){
+		IBND_DEBUG("Unexpected Chip number:%d \n",node->ch_anafanum);
+	}
+
+
+	/* set Line Spine numbers */
+	if(system_slot_name[0] == 'L')
+		node->ch_slot = LINE_CS;
+	else if(system_slot_name[0] == 'S')
+		node->ch_slot = SPINE_CS;
+	else{
+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported system_slot_name:%s \n",system_slot_name);
+		return 0;
+	}
+
+	/* The switch will be displayed under Line or Spine and not under Chassis switches */
+	node->ch_found = 1;
+
+	node->ch_slotnum = atoi(&system_slot_name[1]);
+	if((node->ch_slot == LINE_CS && (node->ch_slotnum >  (LINES_MAX_NUM + 1))) ||
+	   (node->ch_slot == SPINE_CS && (node->ch_slotnum > (SPINES_MAX_NUM + 1)))){
+		IBND_ERROR("fill_mellanox_chassis_record: invalid slot number:%d \n",node->ch_slotnum);
+		node->ch_slotnum = 0;
+		return 0;
+	}
+
+	/*set ch_type_str*/
+	strncpy(node->ch_type_str , system_type, sizeof(node->ch_type_str)-1);
+
+	/* Line ports 1-18 are mapped to external ports 1-18*/
+	if(node->ch_slot == LINE_CS)
+	{
+		for (p = 1; p <= node->numports && p <= 18 ; p++) {
+			port = node->ports[p];
+			if (!port)
+				continue;
+			port->ext_portnum = p;
+		}
+	}
+
+	return 0;
+}
+
+static int insert_mellanox_line_and_spine(ibnd_node_t * node, ibnd_chassis_t * chassis)
+{
+	if (node->ch_slot == LINE_CS){
+
+		if (chassis->linenode[node->ch_slotnum])
+			return 0;	/* already filled slot */
+
+		chassis->linenode[node->ch_slotnum] = node;
+	}
+	else if (node->ch_slot == SPINE_CS){
+
+		if (chassis->spinenode[node->ch_slotnum])
+			return 0;	/* already filled slot */
+
+		chassis->spinenode[node->ch_slotnum] = node;
+	}
+	else
+		return 0;
+
+	node->chassis = chassis;
+
+	return 0;
+}
+
+
 /* forward declare this */
 static void voltaire_portmap(ibnd_port_t * port);
 /*
@@ -1064,15 +1247,23 @@ int group_nodes(ibnd_fabric_t * fabric)
 	chassis_scan.current_chassis = NULL;
 	chassis_scan.last_chassis = NULL;
 
+	int vendor_id;
+
 	/* first pass on switches and build for every Voltaire node */
 	/* an appropriate chassis record (slotnum and position) */
 	/* according to internal connectivity */
 	/* not very efficient but clear code so... */
 	for (node = fabric->switches; node; node = node->type_next) {
-		if (mad_get_field(node->info, 0,
-				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID
+
+		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
+
+		if (vendor_id == VTR_VENDOR_ID
 		    && fill_voltaire_chassis_record(node))
 			goto cleanup;
+		else if (vendor_id == MLX_VENDOR_ID
+			&& fill_mellanox_chassis_record(node))
+			goto cleanup;
+
 	}
 
 	/* separate every Voltaire chassis from each other and build linked list of them */
@@ -1118,8 +1309,10 @@ int group_nodes(ibnd_fabric_t * fabric)
 	/* now, make another pass to see which nodes are part of chassis */
 	/* (defined as chassis->nodecount > 1) */
 	for (node = fabric->nodes; node; node = node->next) {
-		if (mad_get_field(node->info, 0,
-				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
+
+		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
+
+		if (vendor_id == VTR_VENDOR_ID)
 			continue;
 		if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
 			chassis = find_chassisguid(fabric, node);
@@ -1130,6 +1323,9 @@ int group_nodes(ibnd_fabric_t * fabric)
 					node->ch_found = 1;
 					add_node_to_chassis(chassis, node);
 				}
+				else if (vendor_id == MLX_VENDOR_ID){
+					insert_mellanox_line_and_spine(node, chassis);
+				}
 			}
 		}
 	}
diff --git a/infiniband-diags/libibnetdisc/src/chassis.h b/infiniband-diags/libibnetdisc/src/chassis.h
index 004156e..7a91be3 100644
--- a/infiniband-diags/libibnetdisc/src/chassis.h
+++ b/infiniband-diags/libibnetdisc/src/chassis.h
@@ -75,8 +75,11 @@
 #define VTR_DEVID_SFB4700X2		0x5a5d
 #define VTR_DEVID_SFB4200		0x5a60
 
+#define MLX_DEVID_IS4			0xbd36
+
 /* Vendor IDs (for chassis based systems) */
 #define VTR_VENDOR_ID			0x8f1	/* Voltaire */
+#define MLX_VENDOR_ID			0x2c9	/* Mellanox */
 #define TS_VENDOR_ID			0x5ad	/* Cisco */
 #define SS_VENDOR_ID			0x66a	/* InfiniCon */
 #define XS_VENDOR_ID			0x1397	/* Xsigo */
-- 
1.5.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

             reply	other threads:[~2011-02-09 15:41 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-09 15:41 Tamir Ronen [this message]
     [not found] ` <4D52B595.3020302-smomgflXvOZWk0Htik3J/w@public.gmane.org>
2011-02-15  0:06   ` [PATCH] infiniband-diags: add support for ibnetdiscover grouping for Mellanox switches Ira Weiny
  -- strict thread matches above, loose matches on Subject: below --
2011-02-15 12:10 Tamir Ronen
     [not found] ` <AA090FF3B57CA34BBC78B3CE7624333AB376-FXD4EHQYOQ+layAChLZOBkEOCMrvLtNR@public.gmane.org>
2011-02-25 23:38   ` Ira Weiny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D52B595.3020302@voltaire.com \
    --to=tamirr-smomgflxvozwk0htik3j/w@public.gmane.org \
    --cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=weiny2-i2BcT+NCU+M@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox