ib-mgmt: sync with management.git tree
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 6 May 2009 06:09:56 +0000 (06:09 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 6 May 2009 06:09:56 +0000 (06:09 +0000)
Adds new libibnetdisc library to ib-mgmt diags

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2154 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

53 files changed:
tools/infiniband-diags/include/ibdiag_common.h
tools/infiniband-diags/src/dirs
tools/infiniband-diags/src/ibaddr.c
tools/infiniband-diags/src/ibaddr/SOURCES
tools/infiniband-diags/src/ibdiag_common.c
tools/infiniband-diags/src/iblinkinfo/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/iblinkinfo/iblinkinfo.rc [new file with mode: 0644]
tools/infiniband-diags/src/iblinkinfo/makefile [new file with mode: 0644]
tools/infiniband-diags/src/ibnetdiscover.c
tools/infiniband-diags/src/ibnetdiscover/SOURCES
tools/infiniband-diags/src/ibping.c
tools/infiniband-diags/src/ibportstate.c
tools/infiniband-diags/src/ibroute.c
tools/infiniband-diags/src/ibsendtrap.c
tools/infiniband-diags/src/ibsysstat.c
tools/infiniband-diags/src/ibtracert.c
tools/infiniband-diags/src/mcm_rereg_test.c
tools/infiniband-diags/src/perfquery.c
tools/infiniband-diags/src/saquery.c
tools/infiniband-diags/src/sminfo.c
tools/infiniband-diags/src/smpquery.c
tools/infiniband-diags/src/vendstat.c
ulp/dirs
ulp/libibmad/include/infiniband/mad.h
ulp/libibmad/include/infiniband/mad_osd.h
ulp/libibmad/src/Sources
ulp/libibmad/src/dump.c
ulp/libibmad/src/fields.c
ulp/libibmad/src/gs.c
ulp/libibmad/src/ibmad_exports.src
ulp/libibmad/src/ibmad_main.cpp
ulp/libibmad/src/libibmad.map
ulp/libibmad/src/portid.c
ulp/libibmad/src/register.c
ulp/libibmad/src/resolve.c
ulp/libibmad/src/rpc.c
ulp/libibmad/src/sa.c
ulp/libibmad/src/serv.c
ulp/libibmad/src/smp.c
ulp/libibmad/src/vendor.c
ulp/libibnetdisc/README.txt [new file with mode: 0644]
ulp/libibnetdisc/dirs [new file with mode: 0644]
ulp/libibnetdisc/include/infiniband/ibnetdisc.h [new file with mode: 0644]
ulp/libibnetdisc/src/Sources [new file with mode: 0644]
ulp/libibnetdisc/src/chassis.c [new file with mode: 0644]
ulp/libibnetdisc/src/chassis.h [new file with mode: 0644]
ulp/libibnetdisc/src/ibnetdisc.c [new file with mode: 0644]
ulp/libibnetdisc/src/ibnetdisc_export.def [new file with mode: 0644]
ulp/libibnetdisc/src/ibnetdisc_exports.src [new file with mode: 0644]
ulp/libibnetdisc/src/ibnetdisc_main.cpp [new file with mode: 0644]
ulp/libibnetdisc/src/internal.h [new file with mode: 0644]
ulp/libibnetdisc/src/makefile [new file with mode: 0644]
ulp/libibumad/include/infiniband/umad.h

index 52fd147..5c74b07 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <infiniband/mad.h>
 
-extern int ibdebug;
 extern int ibverbose;
 extern char *ibd_ca;
 extern int ibd_ca_port;
index b361fe5..91f2c3f 100644 (file)
@@ -1,5 +1,6 @@
 DIRS = \\r
        ibaddr          \\r
+       iblinkinfo      \\r
        ibnetdiscover   \\r
        ibping          \\r
        ibportstate     \\r
index 9098699..7909a52 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <arpa/inet.h>
 
 #include <infiniband/umad.h>
 #include <infiniband/mad.h>
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 static int
 ib_resolve_addr(ib_portid_t *portid, int portnum, int show_lid, int show_gid)
 {
@@ -55,10 +58,10 @@ ib_resolve_addr(ib_portid_t *portid, int portnum, int show_lid, int show_gid)
        ibmad_gid_t gid;
        int lmc;
 
-       if (!smp_query(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0))
+       if (!smp_query_via(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0, srcport))
                return -1;
 
-       if (!smp_query(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0))
+       if (!smp_query_via(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0, srcport))
                return -1;
 
        mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid);
@@ -137,17 +140,22 @@ int main(int argc, char **argv)
        if (!show_lid && !show_gid)
                show_lid = show_gid = 1;
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (argc) {
-               if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+               if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                                               ibd_sm_id, srcport) < 0)
                        IBERROR("can't resolve destination port %s", argv[0]);
        } else {
-               if (ib_resolve_self(&portid, &port, 0) < 0)
+               if (ib_resolve_self_via(&portid, &port, 0, srcport) < 0)
                        IBERROR("can't resolve self port %s", argv[0]);
        }
 
        if (ib_resolve_addr(&portid, port, show_lid, show_gid) < 0)
                IBERROR("can't resolve requested address");
+
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index 1d72abc..1a98f88 100644 (file)
@@ -10,22 +10,25 @@ USE_MSVCRT = 1
 SOURCES = ..\ibaddr.c ..\ibdiag_common.c ..\ibdiag_windows.c ibaddr.rc\r
        \r
 INCLUDES = ..\..\include;..\..\include\windows;\\r
+                  ..\..\..\..\ulp\libibnetdisc\include;\\r
                   ..\..\..\..\ulp\libibmad\include;\\r
                   ..\..\..\..\ulp\libibumad\include;\\r
                   ..\..\..\..\inc;..\..\..\..\inc\user;\\r
                   ..\..\..\..\inc\user\linux;\r
 \r
-C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H\r
+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H /DUSE_INET\r
 \r
 TARGETLIBS = \\r
        $(SDK_LIB_PATH)\kernel32.lib    \\r
        $(SDK_LIB_PATH)\ws2_32.lib              \\r
 !if $(FREEBUILD)\r
        $(TARGETPATH)\*\libibmad.lib    \\r
-       $(TARGETPATH)\*\libibumad.lib   \r
+       $(TARGETPATH)\*\libibumad.lib   \\r
+       $(TARGETPATH)\*\libibnetdisc.lib\r
 !else\r
        $(TARGETPATH)\*\libibmadd.lib   \\r
-       $(TARGETPATH)\*\libibumadd.lib  \r
+       $(TARGETPATH)\*\libibumadd.lib  \\r
+       $(TARGETPATH)\*\libibnetdiscd.lib\r
 !endif\r
 \r
 MSC_WARNING_LEVEL = /W3 /WX /wd4007\r
index 5f2472d..4ffa3f0 100644 (file)
@@ -53,7 +53,6 @@
 #include <ibdiag_common.h>
 #include <ibdiag_version.h>
 
-int ibdebug;
 int ibverbose;
 char *ibd_ca;
 int ibd_ca_port;
@@ -179,7 +178,9 @@ static int process_opt(int ch, char *optarg)
                ibd_timeout = val;
                break;
        case 's':
-               if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)
+               /* srcport is not required when resolving via IB_DEST_LID */
+               if (ib_resolve_portid_str_via(&sm_portid, optarg, IB_DEST_LID,
+                               0, NULL) < 0)
                        IBERROR("cannot resolve SM destination port %s", optarg);
                ibd_sm_id = &sm_portid;
                break;
diff --git a/tools/infiniband-diags/src/iblinkinfo/SOURCES b/tools/infiniband-diags/src/iblinkinfo/SOURCES
new file mode 100644 (file)
index 0000000..ee5de7b
--- /dev/null
@@ -0,0 +1,36 @@
+TARGETNAME = iblinkinfo\r
+TARGETPATH = ..\..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE = PROGRAM\r
+\r
+UMTYPE = console\r
+UMENTRY = main\r
+\r
+USE_MSVCRT = 1\r
+\r
+SOURCES = ..\iblinkinfo.c ..\ibdiag_common.c ..\ibdiag_windows.c\\r
+                 iblinkinfo.rc\r
+       \r
+INCLUDES = ..\..\include;..\..\include\windows;\\r
+                  ..\..\..\..\ulp\libibnetdisc\include;\\r
+                  ..\..\..\..\ulp\libibmad\include;\\r
+                  ..\..\..\..\ulp\libibumad\include;\\r
+                  ..\..\..\..\inc;..\..\..\..\inc\user;\\r
+                  ..\..\..\..\inc\user\linux;\r
+\r
+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H\r
+\r
+TARGETLIBS = \\r
+       $(SDK_LIB_PATH)\kernel32.lib    \\r
+!if $(FREEBUILD)\r
+       $(TARGETPATH)\*\complib.lib             \\r
+       $(TARGETPATH)\*\libibmad.lib    \\r
+       $(TARGETPATH)\*\libibumad.lib   \\r
+       $(TARGETPATH)\*\libibnetdisc.lib\r
+!else\r
+       $(TARGETPATH)\*\complibd.lib    \\r
+       $(TARGETPATH)\*\libibmadd.lib   \\r
+       $(TARGETPATH)\*\libibumadd.lib  \\r
+       $(TARGETPATH)\*\libibnetdiscd.lib\r
+!endif\r
+\r
+MSC_WARNING_LEVEL = /W3 /WX /wd4007
\ No newline at end of file
diff --git a/tools/infiniband-diags/src/iblinkinfo/iblinkinfo.rc b/tools/infiniband-diags/src/iblinkinfo/iblinkinfo.rc
new file mode 100644 (file)
index 0000000..9dfb753
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * Copyright (c) 2009 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+\r
+#include <oib_ver.h>\r
+\r
+#define VER_FILETYPE                   VFT_APP\r
+#define VER_FILESUBTYPE                        VFT2_UNKNOWN\r
+\r
+#ifdef DBG\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand Network Link Information (Debug)"\r
+#else\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand Network Link Information"\r
+#endif\r
+\r
+#define VER_INTERNALNAME_STR           "iblinkinfo.exe"\r
+#define VER_ORIGINALFILENAME_STR       "iblinkinfo.exe"\r
+\r
+#include <common.ver>\r
diff --git a/tools/infiniband-diags/src/iblinkinfo/makefile b/tools/infiniband-diags/src/iblinkinfo/makefile
new file mode 100644 (file)
index 0000000..a0c0627
--- /dev/null
@@ -0,0 +1,7 @@
+#\r
+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source\r
+# file to this component.  This file merely indirects to the real make file\r
+# that is shared by all the driver components of the OpenIB Windows project.\r
+#\r
+\r
+!INCLUDE ..\..\..\..\inc\openib.def\r
index 6946fd7..810b8db 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.
  * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
+ * Copyright (c) 2008 Lawrence Livermore National Lab.  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
 #include <infiniband/umad.h>
 #include <infiniband/mad.h>
 #include <complib/cl_nodenamemap.h>
+#include <infiniband/ibnetdisc.h>
 
-#include "ibnetdiscover.h"
-#include "grouping.h"
 #include "ibdiag_common.h"
 
-static char *node_type_str[] = {
-       "???",
-       "ca",
-       "switch",
-       "router",
-       "iwarp rnic"
-};
-
-static char *linkwidth_str[] = {
-       "??",
-       "1x",
-       "4x",
-       "??",
-       "8x",
-       "??",
-       "??",
-       "??",
-       "12x"
-};
+#define LIST_CA_NODE    (1 << IB_NODE_CA)
+#define LIST_SWITCH_NODE (1 << IB_NODE_SWITCH)
+#define LIST_ROUTER_NODE (1 << IB_NODE_ROUTER)
 
-static char *linkspeed_str[] = {
-       "???",
-       "SDR",
-       "DDR",
-       "???",
-       "QDR"
-};
+struct ibmad_port *srcport;
 
 static int timeout = 2000;             /* ms */
-static int dumplevel = 0;
 static FILE *f;
 
 static char *node_name_map_file = NULL;
 static nn_map_t *node_name_map = NULL;
 
-Node *nodesdist[MAXHOPS+1];     /* last is Ca list */
-Node *mynode;
-int maxhops_discovered = 0;
-
-struct ChassisList *chassis = NULL;
-
-static char *
-get_linkwidth_str(int linkwidth)
+/**
+ * Define our own conversion functions to maintain compatibility with the old
+ * ibnetdiscover which did not use the ibmad conversion functions.
+ */
+char *dump_linkspeed_compat(uint32_t speed)
 {
-       if (linkwidth > 8)
-               return linkwidth_str[0];
-       else
-               return linkwidth_str[linkwidth];
+       switch (speed) {
+       case 1:
+               return ("SDR");
+               break;
+       case 2:
+               return ("DDR");
+               break;
+       case 4:
+               return ("QDR");
+               break;
+       }
+       return ("???");
 }
 
-static char *
-get_linkspeed_str(int linkspeed)
+char *dump_linkwidth_compat(uint32_t width)
 {
-       if (linkspeed > 4)
-               return linkspeed_str[0];
-       else
-               return linkspeed_str[linkspeed];
+       switch (width) {
+       case 1:
+               return ("1x");
+               break;
+       case 2:
+               return ("4x");
+               break;
+       case 4:
+               return ("8x");
+               break;
+       case 8:
+               return ("12x");
+               break;
+       }
+       return ("??");
 }
 
 static inline const char*
-node_type_str2(Node *node)
+ports_nt_str_compat(ibnd_node_t *node)
 {
        switch(node->type) {
-       case SWITCH_NODE: return "SW";
-       case CA_NODE:     return "CA";
-       case ROUTER_NODE: return "RT";
+       case IB_NODE_SWITCH: return "SW";
+       case IB_NODE_CA:     return "CA";
+       case IB_NODE_ROUTER: return "RT";
        }
        return "??";
 }
 
-void
-decode_port_info(void *pi, Port *port)
-{
-       mad_decode_field(pi, IB_PORT_LID_F, &port->lid);
-       mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc);
-       mad_decode_field(pi, IB_PORT_STATE_F, &port->state);
-       mad_decode_field(pi, IB_PORT_PHYS_STATE_F, &port->physstate);
-       mad_decode_field(pi, IB_PORT_LINK_WIDTH_ACTIVE_F, &port->linkwidth);
-       mad_decode_field(pi, IB_PORT_LINK_SPEED_ACTIVE_F, &port->linkspeed);
-}
-
-
-int
-get_port(Port *port, int portnum, ib_portid_t *portid)
-{
-       char portinfo[64];
-       void *pi = portinfo;
-
-       port->portnum = portnum;
-
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout))
-               return -1;
-       decode_port_info(pi, port);
-
-       DEBUG("portid %s portnum %d: lid %d state %d physstate %d %s %s",
-               portid2str(portid), portnum, port->lid, port->state, port->physstate, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed));
-       return 1;
-}
-/*
- * Returns 0 if non switch node is found, 1 if switch is found, -1 if error.
- */
-int
-get_node(Node *node, Port *port, ib_portid_t *portid)
-{
-       char portinfo[64];
-       char switchinfo[64];
-       void *pi = portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;
-       void *si = switchinfo;
-
-       if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout))
-               return -1;
-
-       mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid);
-       mad_decode_field(ni, IB_NODE_TYPE_F, &node->type);
-       mad_decode_field(ni, IB_NODE_NPORTS_F, &node->numports);
-       mad_decode_field(ni, IB_NODE_DEVID_F, &node->devid);
-       mad_decode_field(ni, IB_NODE_VENDORID_F, &node->vendid);
-       mad_decode_field(ni, IB_NODE_SYSTEM_GUID_F, &node->sysimgguid);
-       mad_decode_field(ni, IB_NODE_PORT_GUID_F, &node->portguid);
-       mad_decode_field(ni, IB_NODE_LOCAL_PORT_F, &node->localport);
-       port->portnum = node->localport;
-       port->portguid = node->portguid;
-
-       if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout))
-               return -1;
-
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout))
-               return -1;
-       decode_port_info(pi, port);
-
-       if (node->type != SWITCH_NODE)
-               return 0;
-
-       node->smalid = port->lid;
-       node->smalmc = port->lmc;
-
-       /* after we have the sma information find out the real PortInfo for this port */
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, node->localport, timeout))
-               return -1;
-       decode_port_info(pi, port);
-
-       port->lid = node->smalid;  /* LID is still defined by port 0 */
-       port->lmc = node->smalmc;
-
-        if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))
-                node->smaenhsp0 = 0;   /* assume base SP0 */
-       else
-               mad_decode_field(si, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0);
-
-       DEBUG("portid %s: got switch node %" PRIx64 " '%s'",
-             portid2str(portid), node->nodeguid, node->nodedesc);
-       return 1;
-}
-
-static int
-extend_dpath(ib_dr_path_t *path, int nextport)
-{
-       if (path->cnt+2 >= sizeof(path->p))
-               return -1;
-       ++path->cnt;
-       if (path->cnt > maxhops_discovered)
-               maxhops_discovered = path->cnt;
-       path->p[path->cnt] = (uint8_t) nextport;
-       return path->cnt;
-}
-
-static void
-dump_endnode(ib_portid_t *path, char *prompt, Node *node, Port *port)
-{
-       if (!dumplevel)
-               return;
-
-       fprintf(f, "%s -> %s %s {%016" PRIx64 "} portnum %d lid %d-%d\"%s\"\n",
-               portid2str(path), prompt,
-               (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
-               node->nodeguid, node->type == SWITCH_NODE ? 0 : port->portnum,
-               port->lid, port->lid + (1 << port->lmc) - 1,
-               clean_nodedesc(node->nodedesc));
-}
-
-#define HASHGUID(guid)         ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103)))
-#define HTSZ 137
-
-static Node *nodestbl[HTSZ];
-
-static Node *
-find_node(Node *new)
-{
-       int hash = HASHGUID(new->nodeguid) % HTSZ;
-       Node *node;
-
-       for (node = nodestbl[hash]; node; node = node->htnext)
-               if (node->nodeguid == new->nodeguid)
-                       return node;
-
-       return NULL;
-}
-
-static Node *
-create_node(Node *temp, ib_portid_t *path, int dist)
-{
-       Node *node;
-       int hash = HASHGUID(temp->nodeguid) % HTSZ;
-
-       node = malloc(sizeof(*node));
-       if (!node)
-               return NULL;
-
-       memcpy(node, temp, sizeof(*node));
-       node->dist = dist;
-       node->path = *path;
-
-       node->htnext = nodestbl[hash];
-       nodestbl[hash] = node;
-
-       if (node->type != SWITCH_NODE)
-               dist = MAXHOPS;         /* special Ca list */
-
-       node->dnext = nodesdist[dist];
-       nodesdist[dist] = node;
-
-       return node;
-}
-
-static Port *
-find_port(Node *node, Port *port)
-{
-       Port *old;
-
-       for (old = node->ports; old; old = old->next)
-               if (old->portnum == port->portnum)
-                       return old;
-
-       return NULL;
-}
-
-static Port *
-create_port(Node *node, Port *temp)
-{
-       Port *port;
-
-       port = malloc(sizeof(*port));
-       if (!port)
-               return NULL;
-
-       memcpy(port, temp, sizeof(*port));
-       port->node = node;
-       port->next = node->ports;
-       node->ports = port;
-
-       return port;
-}
-
-static void
-link_ports(Node *node, Port *port, Node *remotenode, Port *remoteport)
-{
-       DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u",
-               node->nodeguid, node, port, port->portnum,
-               remotenode->nodeguid, remotenode, remoteport, remoteport->portnum);
-       if (port->remoteport)
-               port->remoteport->remoteport = NULL;
-       if (remoteport->remoteport)
-               remoteport->remoteport->remoteport = NULL;
-       port->remoteport = remoteport;
-       remoteport->remoteport = port;
-}
-
-static int
-handle_port(Node *node, Port *port, ib_portid_t *path, int portnum, int dist)
-{
-       Node node_buf;
-       Port port_buf;
-       Node *remotenode, *oldnode;
-       Port *remoteport, *oldport;
-
-       memset(&node_buf, 0, sizeof(node_buf));
-       memset(&port_buf, 0, sizeof(port_buf));
-
-       DEBUG("handle node %p port %p:%d dist %d", node, port, portnum, dist);
-       if (port->physstate != 5)       /* LinkUp */
-               return -1;
-
-       if (extend_dpath(&path->drpath, portnum) < 0)
-               return -1;
-
-       if (get_node(&node_buf, &port_buf, path) < 0) {
-               IBWARN("NodeInfo on %s failed, skipping port",
-                       portid2str(path));
-               path->drpath.cnt--;     /* restore path */
-               return -1;
-       }
-
-       oldnode = find_node(&node_buf);
-       if (oldnode)
-               remotenode = oldnode;
-       else if (!(remotenode = create_node(&node_buf, path, dist + 1)))
-               IBERROR("no memory");
-
-       oldport = find_port(remotenode, &port_buf);
-       if (oldport) {
-               remoteport = oldport;
-               if (node != remotenode || port != remoteport)
-                       IBWARN("port moving...");
-       } else if (!(remoteport = create_port(remotenode, &port_buf)))
-               IBERROR("no memory");
-
-       dump_endnode(path, oldnode ? "known remote" : "new remote",
-                    remotenode, remoteport);
-
-       link_ports(node, port, remotenode, remoteport);
-
-       path->drpath.cnt--;     /* restore path */
-       return 0;
-}
-
-/*
- * Return 1 if found, 0 if not, -1 on errors.
- */
-static int
-discover(ib_portid_t *from)
-{
-       Node node_buf;
-       Port port_buf;
-       Node *node;
-       Port *port;
-       int i;
-       int dist = 0;
-       ib_portid_t *path;
-
-       DEBUG("from %s", portid2str(from));
-
-       memset(&node_buf, 0, sizeof(node_buf));
-       memset(&port_buf, 0, sizeof(port_buf));
-
-       if (get_node(&node_buf, &port_buf, from) < 0) {
-               IBWARN("can't reach node %s", portid2str(from));
-               return -1;
-       }
-
-       node = create_node(&node_buf, from, 0);
-       if (!node)
-               IBERROR("out of memory");
-
-       mynode = node;
-
-       port = create_port(node, &port_buf);
-       if (!port)
-               IBERROR("out of memory");
-
-       if (node->type != SWITCH_NODE &&
-           handle_port(node, port, from, node->localport, 0) < 0)
-               return 0;
-
-       for (dist = 0; dist < MAXHOPS; dist++) {
-
-               for (node = nodesdist[dist]; node; node = node->dnext) {
-
-                       path = &node->path;
-
-                       DEBUG("dist %d node %p", dist, node);
-                       dump_endnode(path, "processing", node, port);
-
-                       for (i = 1; i <= node->numports; i++) {
-                               if (i == node->localport)
-                                       continue;
-
-                               if (get_port(&port_buf, i, path) < 0) {
-                                       IBWARN("can't reach node %s port %d", portid2str(path), i);
-                                       continue;
-                               }
-
-                               port = find_port(node, &port_buf);
-                               if (port)
-                                       continue;
-
-                               port = create_port(node, &port_buf);
-                               if (!port)
-                                       IBERROR("out of memory");
-
-                               /* If switch, set port GUID to node GUID */
-                               if (node->type == SWITCH_NODE)
-                                       port->portguid = node->portguid;
-
-                               handle_port(node, port, path, i, dist);
-                       }
-               }
-       }
-
-       return 0;
-}
-
 char *
-node_name(Node *node)
+node_name(ibnd_node_t *node)
 {
        static char buf[256];
 
        switch(node->type) {
-       case SWITCH_NODE:
+       case IB_NODE_SWITCH:
                sprintf(buf, "\"%s", "S");
                break;
-       case CA_NODE:
+       case IB_NODE_CA:
                sprintf(buf, "\"%s", "H");
                break;
-       case ROUTER_NODE:
+       case IB_NODE_ROUTER:
                sprintf(buf, "\"%s", "R");
                break;
        default:
                sprintf(buf, "\"%s", "?");
                break;
        }
-       sprintf(buf+2, "-%016" PRIx64 "\"", node->nodeguid);
+       sprintf(buf+2, "-%016" PRIx64 "\"", node->guid);
 
        return buf;
 }
 
 void
-list_node(Node *node)
+list_node(ibnd_node_t *node, void *user_data)
 {
        char *node_type;
-       char *nodename = remap_node_name(node_name_map, node->nodeguid,
+       char *nodename = remap_node_name(node_name_map, node->guid,
                                              node->nodedesc);
 
        switch(node->type) {
-       case SWITCH_NODE:
+       case IB_NODE_SWITCH:
                node_type = "Switch";
                break;
-       case CA_NODE:
+       case IB_NODE_CA:
                node_type = "Ca";
                break;
-       case ROUTER_NODE:
+       case IB_NODE_ROUTER:
                node_type = "Router";
                break;
        default:
@@ -491,36 +162,58 @@ list_node(Node *node)
        }
        fprintf(f, "%s\t : 0x%016" PRIx64 " ports %d devid 0x%x vendid 0x%x \"%s\"\n",
                node_type,
-               node->nodeguid, node->numports, node->devid, node->vendid,
+               node->guid, node->numports,
+               mad_get_field(node->info, 0, IB_NODE_DEVID_F),
+               mad_get_field(node->info, 0, IB_NODE_VENDORID_F),
                nodename);
 
        free(nodename);
 }
 
 void
-out_ids(Node *node, int group, char *chname)
+list_nodes(ibnd_fabric_t *fabric, int list)
+{
+       if (list & LIST_CA_NODE) {
+               ibnd_iter_nodes_type(fabric, list_node, IB_NODE_CA, NULL);
+       }
+       if (list & LIST_SWITCH_NODE) {
+               ibnd_iter_nodes_type(fabric, list_node, IB_NODE_SWITCH, NULL);
+       }
+       if (list & LIST_ROUTER_NODE) {
+               ibnd_iter_nodes_type(fabric, list_node, IB_NODE_ROUTER, NULL);
+       }
+}
+
+void
+out_ids(ibnd_node_t *node, int group, char *chname)
 {
-       fprintf(f, "\nvendid=0x%x\ndevid=0x%x\n", node->vendid, node->devid);
-       if (node->sysimgguid)
-               fprintf(f, "sysimgguid=0x%" PRIx64, node->sysimgguid);
+       uint64_t sysimgguid = mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
+
+       fprintf(f, "\nvendid=0x%x\ndevid=0x%x\n",
+               mad_get_field(node->info, 0, IB_NODE_VENDORID_F),
+               mad_get_field(node->info, 0, IB_NODE_DEVID_F));
+       if (sysimgguid)
+               fprintf(f, "sysimgguid=0x%" PRIx64, sysimgguid);
        if (group
-           && node->chrecord && node->chrecord->chassisnum) {
-               fprintf(f, "\t\t# Chassis %d", node->chrecord->chassisnum);
+           && node->chassis && node->chassis->chassisnum) {
+               fprintf(f, "\t\t# Chassis %d", node->chassis->chassisnum);
                if (chname)
-                       fprintf(f, " (%s)", chname);
-               if (is_xsigo_tca(node->nodeguid) && node->ports->remoteport)
-                       fprintf(f, " slot %d", node->ports->remoteport->portnum);
+                       fprintf(f, " (%s)", clean_nodedesc(chname));
+               if (ibnd_is_xsigo_tca(node->guid)
+                               && node->ports[1]
+                               && node->ports[1]->remoteport)
+                       fprintf(f, " slot %d", node->ports[1]->remoteport->portnum);
        }
        fprintf(f, "\n");
 }
 
 uint64_t
-out_chassis(unsigned char chassisnum)
+out_chassis(ibnd_fabric_t *fabric, unsigned char chassisnum)
 {
        uint64_t guid;
 
-       fprintf(f, "\nChassis %d", chassisnum);
-       guid = get_chassis_guid(chassisnum);
+       fprintf(f, "\nChassis %u", chassisnum);
+       guid = ibnd_get_chassis_guid(fabric, chassisnum);
        if (guid)
                fprintf(f, " (guid 0x%" PRIx64 ")", guid);
        fprintf(f, "\n");
@@ -528,29 +221,25 @@ out_chassis(unsigned char chassisnum)
 }
 
 void
-out_switch(Node *node, int group, char *chname)
+out_switch(ibnd_node_t *node, int group, char *chname)
 {
        char *str;
+       char  str2[256];
        char *nodename = NULL;
 
        out_ids(node, group, chname);
-       fprintf(f, "switchguid=0x%" PRIx64, node->nodeguid);
-       fprintf(f, "(%" PRIx64 ")", node->portguid);
-       /* Currently, only if Voltaire chassis */
-       if (group
-           && node->chrecord && node->chrecord->chassisnum
-           && node->vendid == VTR_VENDOR_ID) {
-               str = get_chassis_type(node->chrecord->chassistype);
+       fprintf(f, "switchguid=0x%" PRIx64, node->guid);
+       fprintf(f, "(%" PRIx64 ")", mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F));
+       if (group) {
+               str = ibnd_get_chassis_type(node);
                if (str)
                        fprintf(f, "%s ", str);
-               str = get_chassis_slot(node->chrecord->chassisslot);
+               str = ibnd_get_chassis_slot_str(node, str2, 256);
                if (str)
-                       fprintf(f, "%s ", str);
-               fprintf(f, "%d Chip %d", node->chrecord->slotnum, node->chrecord->anafanum);
+                       fprintf(f, "%s", str);
        }
 
-       nodename = remap_node_name(node_name_map, node->nodeguid,
-                               node->nodedesc);
+       nodename = remap_node_name(node_name_map, node->guid, node->nodedesc);
 
        fprintf(f, "\nSwitch\t%d %s\t\t# \"%s\" %s port 0 lid %d lmc %d\n",
                node->numports, node_name(node),
@@ -562,20 +251,18 @@ out_switch(Node *node, int group, char *chname)
 }
 
 void
-out_ca(Node *node, int group, char *chname)
+out_ca(ibnd_node_t *node, int group, char *chname)
 {
        char *node_type;
        char *node_type2;
-       char *nodename = remap_node_name(node_name_map, node->nodeguid,
-                                             node->nodedesc);
 
        out_ids(node, group, chname);
        switch(node->type) {
-       case CA_NODE:
+       case IB_NODE_CA:
                node_type = "ca";
                node_type2 = "Ca";
                break;
-       case ROUTER_NODE:
+       case IB_NODE_ROUTER:
                node_type = "rt";
                node_type2 = "Rt";
                break;
@@ -585,37 +272,41 @@ out_ca(Node *node, int group, char *chname)
                break;
        }
 
-       fprintf(f, "%sguid=0x%" PRIx64 "\n", node_type, node->nodeguid);
+       fprintf(f, "%sguid=0x%" PRIx64 "\n", node_type, node->guid);
        fprintf(f, "%s\t%d %s\t\t# \"%s\"",
                node_type2, node->numports, node_name(node),
-               nodename);
-       if (group && is_xsigo_hca(node->nodeguid))
+               clean_nodedesc(node->nodedesc));
+       if (group && ibnd_is_xsigo_hca(node->guid))
                fprintf(f, " (scp)");
        fprintf(f, "\n");
-
-       free(nodename);
 }
 
+#define OUT_BUFFER_SIZE 16
 static char *
-out_ext_port(Port *port, int group)
+out_ext_port(ibnd_port_t *port, int group)
 {
-       char *str = NULL;
+       static char mapping[OUT_BUFFER_SIZE];
 
-       /* Currently, only if Voltaire chassis */
-       if (group
-           && port->node->chrecord && port->node->vendid == VTR_VENDOR_ID)
-               str = portmapstring(port);
+       if (group && port->ext_portnum != 0) {
+               snprintf(mapping, OUT_BUFFER_SIZE,
+                       "[ext %d]", port->ext_portnum);
+               return (mapping);
+       }
 
-       return (str);
+       return (NULL);
 }
 
 void
-out_switch_port(Port *port, int group)
+out_switch_port(ibnd_port_t *port, int group)
 {
        char *ext_port_str = NULL;
        char *rem_nodename = NULL;
+       uint32_t iwidth = mad_get_field(port->info, 0,
+                                       IB_PORT_LINK_WIDTH_ACTIVE_F);
+       uint32_t ispeed = mad_get_field(port->info, 0,
+                                       IB_PORT_LINK_SPEED_ACTIVE_F);
 
-       DEBUG("port %p:%d remoteport %p", port, port->portnum, port->remoteport);
+       DEBUG("port %p:%d remoteport %p\n", port, port->portnum, port->remoteport);
        fprintf(f, "[%d]", port->portnum);
 
        ext_port_str = out_ext_port(port, group);
@@ -623,7 +314,7 @@ out_switch_port(Port *port, int group)
                fprintf(f, "%s", ext_port_str);
 
        rem_nodename = remap_node_name(node_name_map,
-                               port->remoteport->node->nodeguid,
+                               port->remoteport->node->guid,
                                port->remoteport->node->nodedesc);
 
        ext_port_str = out_ext_port(port->remoteport, group);
@@ -631,17 +322,19 @@ out_switch_port(Port *port, int group)
                node_name(port->remoteport->node),
                port->remoteport->portnum,
                ext_port_str ? ext_port_str : "");
-       if (port->remoteport->node->type != SWITCH_NODE)
-               fprintf(f, "(%" PRIx64 ") ", port->remoteport->portguid);
+       if (port->remoteport->node->type != IB_NODE_SWITCH)
+               fprintf(f, "(%" PRIx64 ") ", port->remoteport->guid);
        fprintf(f, "\t\t# \"%s\" lid %d %s%s",
                rem_nodename,
-               port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,
-               get_linkwidth_str(port->linkwidth),
-               get_linkspeed_str(port->linkspeed));
+               port->remoteport->node->type == IB_NODE_SWITCH ?
+                       port->remoteport->node->smalid :
+                       port->remoteport->base_lid,
+                       dump_linkwidth_compat(iwidth),
+                       dump_linkspeed_compat(ispeed));
 
-       if (is_xsigo_tca(port->remoteport->portguid))
+       if (ibnd_is_xsigo_tca(port->remoteport->guid))
                fprintf(f, " slot %d", port->portnum);
-       else if (is_xsigo_hca(port->remoteport->portguid))
+       else if (ibnd_is_xsigo_hca(port->remoteport->guid))
                fprintf(f, " (scp)");
        fprintf(f, "\n");
 
@@ -649,272 +342,275 @@ out_switch_port(Port *port, int group)
 }
 
 void
-out_ca_port(Port *port, int group)
+out_ca_port(ibnd_port_t *port, int group)
 {
        char *str = NULL;
        char *rem_nodename = NULL;
+       uint32_t iwidth = mad_get_field(port->info, 0,
+                                       IB_PORT_LINK_WIDTH_ACTIVE_F);
+       uint32_t ispeed = mad_get_field(port->info, 0,
+                                       IB_PORT_LINK_SPEED_ACTIVE_F);
 
        fprintf(f, "[%d]", port->portnum);
-       if (port->node->type != SWITCH_NODE)
-               fprintf(f, "(%" PRIx64 ") ", port->portguid);
+       if (port->node->type != IB_NODE_SWITCH)
+               fprintf(f, "(%" PRIx64 ") ", port->guid);
        fprintf(f, "\t%s[%d]",
                node_name(port->remoteport->node),
                port->remoteport->portnum);
        str = out_ext_port(port->remoteport, group);
        if (str)
                fprintf(f, "%s", str);
-       if (port->remoteport->node->type != SWITCH_NODE)
-               fprintf(f, " (%" PRIx64 ") ", port->remoteport->portguid);
+       if (port->remoteport->node->type != IB_NODE_SWITCH)
+               fprintf(f, " (%" PRIx64 ") ", port->remoteport->guid);
 
        rem_nodename = remap_node_name(node_name_map,
-                               port->remoteport->node->nodeguid,
+                               port->remoteport->node->guid,
                                port->remoteport->node->nodedesc);
 
        fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s\n",
-               port->lid, port->lmc, rem_nodename,
-               port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,
-               get_linkwidth_str(port->linkwidth),
-               get_linkspeed_str(port->linkspeed));
+               port->base_lid, port->lmc, rem_nodename,
+               port->remoteport->node->type == IB_NODE_SWITCH ?
+                       port->remoteport->node->smalid :
+                       port->remoteport->base_lid,
+               dump_linkwidth_compat(iwidth),
+               dump_linkspeed_compat(ispeed));
 
        free(rem_nodename);
 }
 
+
+struct iter_user_data {
+       int group;
+       int skip_chassis_nodes;
+};
+
+static void
+switch_iter_func(ibnd_node_t *node, void *iter_user_data)
+{
+       ibnd_port_t *port;
+       int p = 0;
+       struct iter_user_data *data = (struct iter_user_data *)iter_user_data;
+
+       DEBUG("SWITCH: node %p\n", node);
+
+       /* skip chassis based switches if flagged */
+       if (data->skip_chassis_nodes && node->chassis && node->chassis->chassisnum)
+               return;
+
+       out_switch(node, data->group, NULL);
+       for (p = 1; p <= node->numports; p++) {
+               port = node->ports[p];
+               if (port && port->remoteport)
+                       out_switch_port(port, data->group);
+       }
+}
+
+static void
+ca_iter_func(ibnd_node_t *node, void *iter_user_data)
+{
+       ibnd_port_t *port;
+       int p = 0;
+       struct iter_user_data *data = (struct iter_user_data *)iter_user_data;
+
+       DEBUG("CA: node %p\n", node);
+       /* Now, skip chassis based CAs */
+       if (data->group && node->chassis && node->chassis->chassisnum)
+               return;
+       out_ca(node, data->group, NULL);
+
+       for (p = 1; p <= node->numports; p++) {
+               port = node->ports[p];
+               if (port && port->remoteport)
+                       out_ca_port(port, data->group);
+       }
+}
+
+static void
+router_iter_func(ibnd_node_t *node, void *iter_user_data)
+{
+       ibnd_port_t *port;
+       int p = 0;
+       struct iter_user_data *data = (struct iter_user_data *)iter_user_data;
+
+       DEBUG("RT: node %p\n", node);
+       /* Now, skip chassis based RTs */
+       if (data->group && node->chassis &&
+           node->chassis->chassisnum)
+               return;
+       out_ca(node, data->group, NULL);
+       for (p = 1; p <= node->numports; p++) {
+               port = node->ports[p];
+               if (port && port->remoteport)
+                       out_ca_port(port, data->group);
+       }
+}
+
 int
-dump_topology(int listtype, int group)
+dump_topology(int group, ibnd_fabric_t *fabric)
 {
-       Node *node;
-       Port *port;
-       int i = 0, dist = 0;
+       ibnd_node_t *node;
+       ibnd_port_t *port;
+       int i = 0, p = 0;
        time_t t = time(0);
        uint64_t chguid;
        char *chname = NULL;
+       struct iter_user_data iter_user_data;
 
-       if (!listtype) {
-               fprintf(f, "#\n# Topology file: generated on %s#\n", ctime(&t));
-               fprintf(f, "# Max of %d hops discovered\n", maxhops_discovered);
-               fprintf(f, "# Initiated from node %016" PRIx64 " port %016" PRIx64 "\n", mynode->nodeguid, mynode->portguid);
-       }
+       fprintf(f, "#\n# Topology file: generated on %s#\n", ctime(&t));
+       fprintf(f, "# Max of %d hops discovered\n", fabric->maxhops_discovered);
+       fprintf(f, "# Initiated from node %016" PRIx64 " port %016" PRIx64 "\n",
+               fabric->from_node->guid,
+               mad_get_field64(fabric->from_node->info, 0, IB_NODE_PORT_GUID_F));
 
        /* Make pass on switches */
-       if (group && !listtype) {
-               ChassisList *ch = NULL;
+       if (group) {
+               ibnd_chassis_t *ch = NULL;
 
                /* Chassis based switches first */
-               for (ch = chassis; ch; ch = ch->next) {
+               for (ch = fabric->chassis; ch; ch = ch->next) {
                        int n = 0;
 
                        if (!ch->chassisnum)
                                continue;
-                       chguid = out_chassis(ch->chassisnum);
-                       if (chname)
-                               free(chname);
+                       chguid = out_chassis(fabric, ch->chassisnum);
+
                        chname = NULL;
-                       if (is_xsigo_guid(chguid)) {
-                               for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {
-                                       if (!node->chrecord ||
-                                           !node->chrecord->chassisnum)
-                                               continue;
-
-                                       if (node->chrecord->chassisnum != ch->chassisnum)
-                                               continue;
-
-                                       if (is_xsigo_hca(node->nodeguid)) {
-                                               chname = remap_node_name(node_name_map,
-                                                               node->nodeguid,
-                                                               node->nodedesc);
-                                               fprintf(f, "Hostname: %s\n", chname);
+/**
+ * Will this work for Xsigo?
+ */
+                       if (ibnd_is_xsigo_guid(chguid)) {
+                               for (node = ch->nodes; node;
+                                               node = node->next_chassis_node) {
+                                       if (ibnd_is_xsigo_hca(node->guid)) {
+                                               chname = node->nodedesc;
+                                               fprintf(f, "Hostname: %s\n", clean_nodedesc(node->nodedesc));
                                        }
                                }
                        }
 
                        fprintf(f, "\n# Spine Nodes");
-                       for (n = 1; n <= (SPINES_MAX_NUM+1); n++) {
+                       for (n = 1; n <= SPINES_MAX_NUM; n++) {
                                if (ch->spinenode[n]) {
                                        out_switch(ch->spinenode[n], group, chname);
-                                       for (port = ch->spinenode[n]->ports; port; port = port->next, i++)
-                                               if (port->remoteport)
+                                       for (p = 1; p <= ch->spinenode[n]->numports; p++) {
+                                               port = ch->spinenode[n]->ports[p];
+                                               if (port && port->remoteport)
                                                        out_switch_port(port, group);
+                                       }
                                }
                        }
                        fprintf(f, "\n# Line Nodes");
-                       for (n = 1; n <= (LINES_MAX_NUM+1); n++) {
+                       for (n = 1; n <= LINES_MAX_NUM; n++) {
                                if (ch->linenode[n]) {
                                        out_switch(ch->linenode[n], group, chname);
-                                       for (port = ch->linenode[n]->ports; port; port = port->next, i++)
-                                               if (port->remoteport)
+                                       for (p = 1; p <= ch->linenode[n]->numports; p++) {
+                                               port = ch->linenode[n]->ports[p];
+                                               if (port && port->remoteport)
                                                        out_switch_port(port, group);
+                                       }
                                }
                        }
 
                        fprintf(f, "\n# Chassis Switches");
-                       for (dist = 0; dist <= maxhops_discovered; dist++) {
-
-                               for (node = nodesdist[dist]; node; node = node->dnext) {
-
-                                       /* Non Voltaire chassis */
-                                       if (node->vendid == VTR_VENDOR_ID)
-                                               continue;
-                                       if (!node->chrecord ||
-                                           !node->chrecord->chassisnum)
-                                               continue;
-
-                                       if (node->chrecord->chassisnum != ch->chassisnum)
-                                               continue;
-
+                       for (node = ch->nodes; node;
+                                       node = node->next_chassis_node) {
+                               if (node->type == IB_NODE_SWITCH) {
                                        out_switch(node, group, chname);
-                                       for (port = node->ports; port; port = port->next, i++)
-                                               if (port->remoteport)
+                                       for (p = 1; p <= node->numports; p++) {
+                                               port = node->ports[p];
+                                               if (port && port->remoteport)
                                                        out_switch_port(port, group);
-
+                                       }
                                }
 
                        }
 
                        fprintf(f, "\n# Chassis CAs");
-                       for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {
-                               if (!node->chrecord ||
-                                   !node->chrecord->chassisnum)
-                                       continue;
-
-                               if (node->chrecord->chassisnum != ch->chassisnum)
-                                       continue;
-
-                               out_ca(node, group, chname);
-                               for (port = node->ports; port; port = port->next, i++)
-                                       if (port->remoteport)
-                                               out_ca_port(port, group);
-
+                       for (node = ch->nodes; node;
+                                       node = node->next_chassis_node) {
+                               if (node->type == IB_NODE_CA) {
+                                       out_ca(node, group, chname);
+                                       for (p = 1; p <= node->numports; p++) {
+                                               port = node->ports[p];
+                                               if (port && port->remoteport)
+                                                       out_ca_port(port, group);
+                                       }
+                               }
                        }
 
                }
 
-       } else {
-               for (dist = 0; dist <= maxhops_discovered; dist++) {
-
-                       for (node = nodesdist[dist]; node; node = node->dnext) {
 
-                               DEBUG("SWITCH: dist %d node %p", dist, node);
-                               if (!listtype)
-                                       out_switch(node, group, chname);
-                               else {
-                                       if (listtype & LIST_SWITCH_NODE)
-                                               list_node(node);
-                                       continue;
-                               }
-
-                               for (port = node->ports; port; port = port->next, i++)
-                                       if (port->remoteport)
-                                               out_switch_port(port, group);
-                       }
-               }
+       } else { /* !group */
+               iter_user_data.group = group;
+               iter_user_data.skip_chassis_nodes = 0;
+               ibnd_iter_nodes_type(fabric, switch_iter_func,
+                               IB_NODE_SWITCH, &iter_user_data);
        }
 
-       if (chname)
-               free(chname);
        chname = NULL;
-       if (group && !listtype) {
+       if (group) {
+               iter_user_data.group = group;
+               iter_user_data.skip_chassis_nodes = 1;
 
                fprintf(f, "\nNon-Chassis Nodes\n");
 
-               for (dist = 0; dist <= maxhops_discovered; dist++) {
-
-                       for (node = nodesdist[dist]; node; node = node->dnext) {
-
-                               DEBUG("SWITCH: dist %d node %p", dist, node);
-                               /* Now, skip chassis based switches */
-                               if (node->chrecord &&
-                                   node->chrecord->chassisnum)
-                                       continue;
-                               out_switch(node, group, chname);
-
-                               for (port = node->ports; port; port = port->next, i++)
-                                       if (port->remoteport)
-                                               out_switch_port(port, group);
-                       }
-
-               }
-
+               ibnd_iter_nodes_type(fabric, switch_iter_func,
+                               IB_NODE_SWITCH, &iter_user_data);
        }
 
+       iter_user_data.group = group;
+       iter_user_data.skip_chassis_nodes = 0;
        /* Make pass on CAs */
-       for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {
-
-               DEBUG("CA: dist %d node %p", dist, node);
-               if (!listtype) {
-                       /* Now, skip chassis based CAs */
-                       if (group && node->chrecord &&
-                           node->chrecord->chassisnum)
-                               continue;
-                       out_ca(node, group, chname);
-               } else {
-                       if (((listtype & LIST_CA_NODE) && (node->type == CA_NODE)) ||
-                           ((listtype & LIST_ROUTER_NODE) && (node->type == ROUTER_NODE)))
-                               list_node(node);
-                       continue;
-               }
-
-               for (port = node->ports; port; port = port->next, i++)
-                       if (port->remoteport)
-                               out_ca_port(port, group);
-       }
+       ibnd_iter_nodes_type(fabric, ca_iter_func, IB_NODE_CA,
+                       &iter_user_data);
 
-       if (chname)
-               free(chname);
+       /* make pass on routers */
+       ibnd_iter_nodes_type(fabric, router_iter_func, IB_NODE_ROUTER,
+                       &iter_user_data);
 
        return i;
 }
 
-void dump_ports_report ()
+void dump_ports_report (ibnd_node_t *node, void *user_data)
 {
-       int b, n = 0, p;
-       Node *node;
-       Port *port;
-
-       // If switch and LID == 0, search of other switch ports with
-       // valid LID and assign it to all ports of that switch
-       for (b = 0; b <= MAXHOPS; b++)
-               for (node = nodesdist[b]; node; node = node->dnext)
-                       if (node->type == SWITCH_NODE) {
-                               int swlid = 0;
-                               for (p = 0, port = node->ports;
-                                    p < node->numports && port && !swlid;
-                                    port = port->next)
-                                       if (port->lid != 0)
-                                               swlid = port->lid;
-                               for (p = 0, port = node->ports;
-                                    p < node->numports && port;
-                                    port = port->next)
-                                       port->lid = swlid;
-                       }
-
-       for (b = 0; b <= MAXHOPS; b++)
-               for (node = nodesdist[b]; node; node = node->dnext) {
-                       for (p = 0, port = node->ports;
-                            p < node->numports && port;
-                            p++, port = port->next) {
-                               fprintf(stdout,
-                                       "%2s %5d %2d 0x%016" PRIx64 " %s %s",
-                                       node_type_str2(port->node), port->lid,
-                                       port->portnum,
-                                       port->portguid,
-                                       get_linkwidth_str(port->linkwidth),
-                                       get_linkspeed_str(port->linkspeed));
-                               if (port->remoteport)
-                                       fprintf(stdout,
-                                               " - %2s %5d %2d 0x%016" PRIx64
-                                               " ( '%s' - '%s' )\n",
-                                               node_type_str2(port->remoteport->node),
-                                               port->remoteport->lid,
-                                               port->remoteport->portnum,
-                                               port->remoteport->portguid,
-                                               port->node->nodedesc,
-                                               port->remoteport->node->nodedesc);
-                               else
-                                       fprintf(stdout, "%36s'%s'\n", "",
-                                               port->node->nodedesc);
-                       }
-                       n++;
-               }
+       int p = 0;
+       ibnd_port_t *port = NULL;
+
+       /* for each port */
+       for (p = node->numports, port = node->ports[p];
+            p > 0;
+            port = node->ports[--p]) {
+               uint32_t iwidth, ispeed;
+               if (port == NULL)
+                       continue;
+               iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
+               ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
+               fprintf(stdout,
+                       "%2s %5d %2d 0x%016" PRIx64 " %s %s",
+                       ports_nt_str_compat(node),
+                       node->type == IB_NODE_SWITCH ?
+                               node->smalid : port->base_lid,
+                       port->portnum,
+                       port->guid,
+                       dump_linkwidth_compat(iwidth),
+                       dump_linkspeed_compat(ispeed));
+               if (port->remoteport)
+                       fprintf(stdout,
+                               " - %2s %5d %2d 0x%016" PRIx64
+                               " ( '%s' - '%s' )\n",
+                               ports_nt_str_compat(port->remoteport->node),
+                               port->remoteport->node->type == IB_NODE_SWITCH ?
+                                       port->remoteport->node->smalid :
+                                       port->remoteport->base_lid,
+                               port->remoteport->portnum,
+                               port->remoteport->guid,
+                               port->node->nodedesc,
+                               port->remoteport->node->nodedesc);
+               else
+                       fprintf(stdout, "%36s'%s'\n", "",
+                               port->node->nodedesc);
+       }
 }
 
 static int list, group, ports_report;
@@ -926,7 +622,7 @@ static int process_opt(void *context, int ch, char *optarg)
                node_name_map_file = strdup(optarg);
                break;
        case 's':
-               dumplevel = 1;
+               ibnd_show_progress(1);
                break;
        case 'l':
                list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE;
@@ -955,8 +651,10 @@ static int process_opt(void *context, int ch, char *optarg)
 
 int main(int argc, char **argv)
 {
+       ibnd_fabric_t *fabric = NULL;
+
+       struct ibmad_port *ibmad_port;
        int mgmt_classes[2] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS};
-       ib_portid_t my_portid = {0};
 
        const struct ibdiag_opt opts[] = {
                { "show", 's', 0, NULL, "show more information" },
@@ -983,25 +681,31 @@ int main(int argc, char **argv)
                timeout = ibd_timeout;
 
        if (ibverbose)
-               dumplevel = 1;
+               ibnd_debug(1);
+
+       ibmad_port = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
+       if (!ibmad_port)
+               IBERROR("Failed to open %s port %d", ibd_ca, ibd_ca_port);
 
        if (argc && !(f = fopen(argv[0], "w")))
                IBERROR("can't open file %s for writing", argv[0]);
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 2);
        node_name_map = open_node_name_map(node_name_map_file);
 
-       if (discover(&my_portid) < 0)
-               IBERROR("discover");
-
-       if (group)
-               chassis = group_nodes();
+       if ((fabric = ibnd_discover_fabric(ibmad_port, ibd_timeout, NULL, -1)) == NULL)
+               IBERROR("discover failed\n");
 
        if (ports_report)
-               dump_ports_report();
+               ibnd_iter_nodes(fabric,
+                               dump_ports_report,
+                               NULL);
+       else if (list)
+               list_nodes(fabric, list);
        else
-               dump_topology(list, group);
+               dump_topology(group, fabric);
 
+       ibnd_destroy_fabric(fabric);
        close_node_name_map(node_name_map);
+       mad_rpc_close_port(ibmad_port);
        exit(0);
 }
index 300925b..03f0384 100644 (file)
@@ -7,10 +7,11 @@ UMENTRY = main
 \r
 USE_MSVCRT = 1\r
 \r
-SOURCES = ..\ibnetdiscover.c ..\grouping.c ..\ibdiag_common.c ..\ibdiag_windows.c\\r
+SOURCES = ..\ibnetdiscover.c ..\ibdiag_common.c ..\ibdiag_windows.c\\r
                  ibnetdiscover.rc\r
        \r
 INCLUDES = ..\..\include;..\..\include\windows;\\r
+                  ..\..\..\..\ulp\libibnetdisc\include;\\r
                   ..\..\..\..\ulp\libibmad\include;\\r
                   ..\..\..\..\ulp\libibumad\include;\\r
                   ..\..\..\..\inc;..\..\..\..\inc\user;\\r
@@ -23,11 +24,13 @@ TARGETLIBS = \
 !if $(FREEBUILD)\r
        $(TARGETPATH)\*\complib.lib             \\r
        $(TARGETPATH)\*\libibmad.lib    \\r
-       $(TARGETPATH)\*\libibumad.lib   \r
+       $(TARGETPATH)\*\libibumad.lib   \\r
+       $(TARGETPATH)\*\libibnetdisc.lib\r
 !else\r
        $(TARGETPATH)\*\complibd.lib    \\r
        $(TARGETPATH)\*\libibmadd.lib   \\r
-       $(TARGETPATH)\*\libibumadd.lib  \r
+       $(TARGETPATH)\*\libibumadd.lib  \\r
+       $(TARGETPATH)\*\libibnetdiscd.lib\r
 !endif\r
 \r
 MSC_WARNING_LEVEL = /W3 /WX /wd4007
\ No newline at end of file
index 210b648..7da48e2 100644 (file)
@@ -48,6 +48,8 @@
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 static char host_and_domain[IB_VENDOR_RANGE2_DATA_SIZE];
 static char last_host[IB_VENDOR_RANGE2_DATA_SIZE];
 
@@ -82,7 +84,7 @@ ibping_serv(void)
 
        DEBUG("starting to serve...");
 
-       while ((umad = mad_receive(0, -1))) {
+       while ((umad = mad_receive_via(0, -1, srcport))) {
 
                mad = umad_get_mad(umad);
                data = (char *)mad + IB_VENDOR_RANGE2_DATA_OFFS;
@@ -91,7 +93,7 @@ ibping_serv(void)
 
                DEBUG("Pong: %s", data);
 
-               if (mad_respond(umad, 0, 0) < 0)
+               if (mad_respond_via(umad, 0, 0, srcport) < 0)
                        DEBUG("respond failed");
 
                mad_free(umad);
@@ -120,7 +122,7 @@ ibping(ib_portid_t *portid, int quiet)
        call.timeout = 0;
        memset(&call.rmpp, 0, sizeof call.rmpp);
 
-       if (!ib_vendor_call(data, portid, &call))
+       if (!ib_vendor_call_via(data, portid, &call, srcport))
                return ~0ull;
 
        rtt = cl_get_time_stamp() - start;
@@ -208,10 +210,12 @@ int main(int argc, char **argv)
        if (!argc && !server)
                ibdiag_show_usage();
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (server) {
-               if (mad_register_server(ping_class, 0, 0, oui) < 0)
+               if (mad_register_server_via(ping_class, 0, 0, oui, srcport) < 0)
                        IBERROR("can't serve class %d on this port", ping_class);
 
                get_host_and_domain(host_and_domain, sizeof host_and_domain);
@@ -221,10 +225,11 @@ int main(int argc, char **argv)
                exit(0);
        }
 
-       if (mad_register_client(ping_class, 0) < 0)
+       if (mad_register_client_via(ping_class, 0, srcport) < 0)
                IBERROR("can't register ping class %d on this port", ping_class);
 
-       if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+       if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                                       ibd_sm_id, srcport) < 0)
                IBERROR("can't resolve destination port %s", argv[0]);
 
        signal(SIGINT, report);
@@ -252,5 +257,7 @@ int main(int argc, char **argv)
 
        report(0);
 
+       mad_rpc_close_port(srcport);
+
        exit(-1);
 }
index c0b9b34..65c9ca1 100644 (file)
@@ -46,6 +46,8 @@
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 /*******************************************/
 
 static int
@@ -53,7 +55,7 @@ get_node_info(ib_portid_t *dest, uint8_t *data)
 {
        int node_type;
 
-       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
                return -1;
 
        node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
@@ -69,7 +71,7 @@ get_port_info(ib_portid_t *dest, uint8_t *data, int portnum, int port_op)
        char buf[2048];
        char val[64];
 
-       if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
                return -1;
 
        if (port_op != 4) {
@@ -108,7 +110,7 @@ set_port_info(ib_portid_t *dest, uint8_t *data, int portnum, int port_op)
        char buf[2048];
        char val[64];
 
-       if (!smp_set(data, dest, IB_ATTR_PORT_INFO, portnum, 0))
+       if (!smp_set_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
                return -1;
 
        if (port_op != 4)
@@ -223,9 +225,12 @@ int main(int argc, char **argv)
        if (argc < 2)
                ibdiag_show_usage();
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
-       if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+       if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                               ibd_sm_id, srcport) < 0)
                IBERROR("can't resolve destination port %s", argv[0]);
 
        /* First, make sure it is a switch port if it is a "set" */
@@ -314,7 +319,8 @@ int main(int argc, char **argv)
                                        peerportid.drpath.p[1] = (uint8_t) portnum;
 
                                        /* Set DrSLID to local lid */
-                                       if (ib_resolve_self(&selfportid, &selfport, 0) < 0)
+                                       if (ib_resolve_self_via(&selfportid,
+                                                       &selfport, 0, srcport) < 0)
                                                IBERROR("could not resolve self");
                                        peerportid.drpath.drslid = (uint16_t) selfportid.lid;
                                        peerportid.drpath.drdlid = 0xffff;
@@ -354,5 +360,6 @@ int main(int argc, char **argv)
                }
        }
 
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index 047b9d5..31b8e4c 100644 (file)
@@ -49,6 +49,8 @@
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 static int brief, dump_all, multicast;
 
 /*******************************************/
@@ -61,12 +63,12 @@ check_switch(ib_portid_t *portid, unsigned int *nports, uint64_t *guid,
        int type;
 
        DEBUG("checking node type");
-       if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, 0)) {
+       if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, 0, srcport)) {
                xdump(stderr, "nodeinfo\n", ni, sizeof ni);
                return "node info failed: valid addr?";
        }
 
-       if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, 0))
+       if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, 0, srcport))
                return "node desc failed";
 
        mad_decode_field(ni, IB_NODE_TYPE_F, &type);
@@ -77,7 +79,7 @@ check_switch(ib_portid_t *portid, unsigned int *nports, uint64_t *guid,
        mad_decode_field(ni, IB_NODE_NPORTS_F, nports);
        mad_decode_field(ni, IB_NODE_GUID_F, guid);
 
-       if (!smp_query(sw, portid, IB_ATTR_SWITCH_INFO, 0, 0))
+       if (!smp_query_via(sw, portid, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
                return "switch info failed: is a switch node?";
 
        return 0;
@@ -195,7 +197,8 @@ dump_multicast_tables(ib_portid_t *portid, unsigned startlid, unsigned endlid)
                        mod = (block - IB_MIN_MCAST_LID/IB_MLIDS_IN_BLOCK) | (j << 28);
 
                        DEBUG("reading block %x chunk %d mod %x", block, j, mod);
-                       if (!smp_query(mft + j, portid, IB_ATTR_MULTICASTFORWTBL, mod, 0))
+                       if (!smp_query_via(mft + j, portid,
+                                       IB_ATTR_MULTICASTFORWTBL, mod, 0, srcport))
                                return "multicast forwarding table get failed";
                }
 
@@ -259,9 +262,9 @@ dump_lid(char *str, int strlen, int lid, int valid)
        portguid = 0;
        lidport.lid = lid;
 
-       if (!smp_query(nd, &lidport, IB_ATTR_NODE_DESC, 0, 100) ||
-           !smp_query(pi, &lidport, IB_ATTR_PORT_INFO, 0, 100) ||
-           !smp_query(ni, &lidport, IB_ATTR_NODE_INFO, 0, 100))
+       if (!smp_query_via(nd, &lidport, IB_ATTR_NODE_DESC, 0, 100, srcport) ||
+           !smp_query_via(pi, &lidport, IB_ATTR_PORT_INFO, 0, 100, srcport) ||
+           !smp_query_via(ni, &lidport, IB_ATTR_NODE_INFO, 0, 100, srcport))
                return snprintf(str, strlen, ": (unknown node and type)");
 
        mad_decode_field(ni, IB_NODE_PORT_GUID_F, &portguid);
@@ -317,7 +320,8 @@ dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid)
        endblock = ALIGN(endlid, IB_SMP_DATA_SIZE) / IB_SMP_DATA_SIZE;
        for (block = startblock; block <= endblock; block++) {
                DEBUG("reading block %d", block);
-               if (!smp_query(lft, portid, IB_ATTR_LINEARFORWTBL, block, 0))
+               if (!smp_query_via(lft, portid, IB_ATTR_LINEARFORWTBL, block,
+                               0, srcport))
                        return "linear forwarding table get failed";
                i = block * IB_SMP_DATA_SIZE;
                e = i + IB_SMP_DATA_SIZE;
@@ -404,12 +408,15 @@ int main(int argc, char **argv)
        if (argc > 2)
                endlid = strtoul(argv[2], 0, 0);
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (!argc) {
-               if (ib_resolve_self(&portid, 0, 0) < 0)
+               if (ib_resolve_self_via(&portid, 0, 0, srcport) < 0)
                        IBERROR("can't resolve self addr");
-       } else if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+       } else if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                       ibd_sm_id, srcport) < 0)
                IBERROR("can't resolve destination port %s", argv[1]);
 
        if (multicast)
@@ -420,5 +427,6 @@ int main(int argc, char **argv)
        if (err)
                IBERROR("dump tables: %s", err);
 
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index 92b72f1..7ad588e 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2008 Lawrence Livermore National Security
+ * Copyright (c) 2009 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2009 HNR Consulting.  All rights reserved.
  *
  * Produced at Lawrence Livermore National Laboratory.
  * Written by Ira Weiny <weiny2@llnl.gov>.
 
 #include "ibdiag_common.h"
 
-static int send_144_node_desc_update(void)
+struct ibmad_port *srcport;
+/* for local link integrity */
+int error_port = 1;
+
+static int get_node_type(ib_portid_t *port)
+{
+       int node_type = IB_NODE_TYPE_CA;
+       uint8_t data[IB_SMP_DATA_SIZE];
+
+       if (smp_query_via(data, port, IB_ATTR_NODE_INFO, 0, 0, srcport))
+               node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
+       return node_type;
+}
+
+static void build_trap144(ib_mad_notice_attr_t * n, ib_portid_t *port)
+{
+       n->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
+       n->g_or_v.generic.prod_type_lsb = cl_hton16((uint16_t) get_node_type(port));
+       n->g_or_v.generic.trap_num = cl_hton16(144);
+       n->issuer_lid = cl_hton16((uint16_t) port->lid);
+       n->data_details.ntc_144.lid = n->issuer_lid;
+       n->data_details.ntc_144.local_changes =
+           TRAP_144_MASK_OTHER_LOCAL_CHANGES;
+       n->data_details.ntc_144.change_flgs =
+           TRAP_144_MASK_NODE_DESCRIPTION_CHANGE;
+}
+
+static void build_trap129(ib_mad_notice_attr_t * n, ib_portid_t *port)
+{
+       n->generic_type = 0x80 | IB_NOTICE_TYPE_URGENT;
+       n->g_or_v.generic.prod_type_lsb = cl_hton16((uint16_t) get_node_type(port));
+       n->g_or_v.generic.trap_num = cl_hton16(129);
+       n->issuer_lid = cl_hton16((uint16_t) port->lid);
+       n->data_details.ntc_129_131.lid = n->issuer_lid;
+       n->data_details.ntc_129_131.pad = 0;
+       n->data_details.ntc_129_131.port_num = (uint8_t) error_port;
+}
+
+static int send_trap(const char *name,
+                    void (*build) (ib_mad_notice_attr_t *, ib_portid_t *))
 {
        ib_portid_t sm_port;
        ib_portid_t selfportid;
@@ -55,10 +96,10 @@ static int send_144_node_desc_update(void)
        ib_rpc_t trap_rpc;
        ib_mad_notice_attr_t notice;
 
-       if (ib_resolve_self(&selfportid, &selfport, NULL))
+       if (ib_resolve_self_via(&selfportid, &selfport, NULL, srcport))
                IBERROR("can't resolve self");
 
-       if (ib_resolve_smlid(&sm_port, 0))
+       if (ib_resolve_smlid_via(&sm_port, 0, srcport))
                IBERROR("can't resolve SM destination port");
 
        memset(&trap_rpc, 0, sizeof(trap_rpc));
@@ -70,40 +111,31 @@ static int send_144_node_desc_update(void)
        trap_rpc.dataoffs = IB_SMP_DATA_OFFS;
 
        memset(&notice, 0, sizeof(notice));
-       notice.generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
-       notice.g_or_v.generic.prod_type_lsb = cl_hton16(IB_NODE_TYPE_CA);
-       notice.g_or_v.generic.trap_num = cl_hton16(144);
-       notice.issuer_lid = cl_hton16((uint16_t) selfportid.lid);
-       notice.data_details.ntc_144.lid = cl_hton16((uint16_t) selfportid.lid);
-       notice.data_details.ntc_144.local_changes =
-           TRAP_144_MASK_OTHER_LOCAL_CHANGES;
-       notice.data_details.ntc_144.change_flgs =
-           TRAP_144_MASK_NODE_DESCRIPTION_CHANGE;
+       build(&notice, &selfportid);
 
-       return (mad_send(&trap_rpc, &sm_port, NULL, &notice));
+       return mad_send_via(&trap_rpc, &sm_port, NULL, &notice, srcport);
 }
 
 typedef struct _trap_def {
        char *trap_name;
-       int (*send_func) (void);
+       void (*build_func) (ib_mad_notice_attr_t *, ib_portid_t *);
 } trap_def_t;
 
-trap_def_t traps[2] = {
-       {"node_desc_change", send_144_node_desc_update},
+trap_def_t traps[3] = {
+       {"node_desc_change", build_trap144},
+       {"local_link_integrity", build_trap129},
        {NULL, NULL}
 };
 
-int send_trap(char *trap_name)
+int process_send_trap(char *trap_name)
 {
        int i;
 
-       for (i = 0; traps[i].trap_name; i++) {
-               if (strcmp(traps[i].trap_name, trap_name) == 0) {
-                       return (traps[i].send_func());
-               }
-       }
+       for (i = 0; traps[i].trap_name; i++)
+               if (strcmp(traps[i].trap_name, trap_name) == 0)
+                       return send_trap(trap_name, traps[i].build_func);
        ibdiag_show_usage();
-       exit(1);
+       return 1;
 }
 
 int main(int argc, char **argv)
@@ -111,9 +143,9 @@ int main(int argc, char **argv)
        char usage_args[1024];
        int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
        char *trap_name = NULL;
-       int i, n;
+       int i, n, rc;
 
-       n = sprintf(usage_args, "[<trap_name>]\n"
+       n = sprintf(usage_args, "[<trap_name>] [<error_port>]\n"
                    "\nArgument <trap_name> can be one of the following:\n");
        for (i = 0; traps[i].trap_name; i++) {
                n += snprintf(usage_args + n, sizeof(usage_args) - n,
@@ -130,14 +162,18 @@ int main(int argc, char **argv)
        argc -= optind;
        argv += optind;
 
-       if (!argv[0]) {
-               trap_name = traps[0].trap_name;
-       } else {
-               trap_name = argv[0];
-       }
+       trap_name = argv[0] ? argv[0] : traps[0].trap_name;
+
+       if (argc > 1)
+               error_port = atoi(argv[1]);
 
        madrpc_show_errors(1);
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 2);
 
-       return (send_trap(trap_name));
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
+
+       rc = process_send_trap(trap_name);
+       mad_rpc_close_port(srcport);
+       return rc;
 }
index da86d8e..03c0515 100644 (file)
@@ -48,6 +48,8 @@
 
 #define MAX_CPUS 8
 
+struct ibmad_port *srcport;
+
 enum ib_sysstat_attr_t {
        IB_PING_ATTR = 0x10,
        IB_HOSTINFO_ATTR = 0x11,
@@ -101,8 +103,9 @@ static int server_respond(void *umad, int size)
        if (ibdebug > 1)
                xdump(stderr, "mad respond pkt\n", mad, IB_MAD_SIZE);
 
-       if (umad_send(madrpc_portid(), mad_class_agent(rpc.mgtclass), umad,
-                     size, rpc.timeout, 0) < 0) {
+       if (umad_send(mad_rpc_portid(srcport),
+                     mad_rpc_class_agent(srcport, rpc.mgtclass), umad, size,
+                     rpc.timeout, 0) < 0) {
                DEBUG("send failed; %m");
                return -1;
        }
@@ -169,7 +172,7 @@ static char *ibsystat_serv(void)
 
        DEBUG("starting to serve...");
 
-       while ((umad = mad_receive(buf, -1))) {
+       while ((umad = mad_receive_via(buf, -1, srcport))) {
                if (umad_status(buf)) {
                        DEBUG("drop mad with status %x: %s", umad_status(buf),
                              strerror(umad_status(buf)));
@@ -230,8 +233,8 @@ static char *ibsystat(ib_portid_t *portid, int attr)
        if ((len = mad_build_pkt(buf, &rpc, portid, NULL, NULL)) < 0)
                IBPANIC("cannot build packet.");
 
-       fd = madrpc_portid();
-       agent = mad_class_agent(rpc.mgtclass);
+       fd = mad_rpc_portid(srcport);
+       agent = mad_rpc_class_agent(srcport, rpc.mgtclass);
        timeout = ibd_timeout ? ibd_timeout : MAD_DEF_TIMEOUT_MS;
 
        if (umad_send(fd, agent, buf, len, timeout, 0) < 0)
@@ -334,10 +337,12 @@ int main(int argc, char **argv)
        if (argc > 1 && (attr = match_attr(argv[1])) < 0)
                ibdiag_show_usage();
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (server) {
-               if (mad_register_server(sysstat_class, 1, 0, oui) < 0)
+               if (mad_register_server_via(sysstat_class, 1, 0, oui, srcport) < 0)
                        IBERROR("can't serve class %d", sysstat_class);
 
                host_ncpu = build_cpuinfo();
@@ -347,14 +352,16 @@ int main(int argc, char **argv)
                exit(0);
        }
 
-       if (mad_register_client(sysstat_class, 1) < 0)
+       if (mad_register_client_via(sysstat_class, 1, srcport) < 0)
                IBERROR("can't register to sysstat class %d", sysstat_class);
 
-       if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+       if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                       ibd_sm_id, srcport) < 0)
                IBERROR("can't resolve destination port %s", argv[0]);
 
        if ((err = ibsystat(&portid, attr)))
                IBERROR("ibsystat to %s: %s", portid2str(&portid), err);
 
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index db3b906..a887157 100644 (file)
@@ -50,6 +50,8 @@
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 #define MAXHOPS        63
 
 static char *node_type_str[] = {
@@ -116,10 +118,10 @@ get_node(Node *node, Port *port, ib_portid_t *portid)
        void *pi = port->portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;
        char *s, *e;
 
-       if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout))
+       if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, timeout, srcport))
                return -1;
 
-       if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout))
+       if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout, srcport))
                return -1;
 
        for (s = nd, e = s + 64; s < e; s++) {
@@ -129,7 +131,7 @@ get_node(Node *node, Port *port, ib_portid_t *portid)
                        *s = ' ';
        }
 
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout))
+       if (!smp_query_via(pi, portid, IB_ATTR_PORT_INFO, 0, timeout, srcport))
                return -1;
 
        mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid);
@@ -151,7 +153,7 @@ switch_lookup(Switch *sw, ib_portid_t *portid, int lid)
 {
        void *si = sw->switchinfo, *fdb = sw->fdb;
 
-       if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))
+       if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout, srcport))
                return -1;
 
        mad_decode_field(si, IB_SW_LINEAR_FDB_CAP_F, &sw->linearcap);
@@ -160,7 +162,8 @@ switch_lookup(Switch *sw, ib_portid_t *portid, int lid)
        if (lid > sw->linearcap && lid > sw->linearFDBtop)
                return -1;
 
-       if (!smp_query(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64, timeout))
+       if (!smp_query_via(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64,
+                       timeout, srcport))
                return -1;
 
        DEBUG("portid %s: forward lid %d to port %d",
@@ -382,7 +385,8 @@ get_port(Port *port, int portnum, ib_portid_t *portid)
 
        port->portnum = portnum;
 
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout))
+       if (!smp_query_via(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout,
+                       srcport))
                return -1;
 
        mad_decode_field(pi, IB_PORT_LID_F, &port->lid);
@@ -439,7 +443,7 @@ switch_mclookup(Node *node, ib_portid_t *portid, int mlid, char *map)
 
        memset(map, 0, 256);
 
-       if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))
+       if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout, srcport))
                return -1;
 
        mlid -= 0xc000;
@@ -453,8 +457,8 @@ switch_mclookup(Node *node, ib_portid_t *portid, int mlid, char *map)
        maxsets = (node->numports + 15) / 16;           /* round up */
 
        for (set = 0; set < maxsets; set++) {
-               if (!smp_query(mdb, portid, IB_ATTR_MULTICASTFORWTBL,
-                   block | (set << 28), timeout))
+               if (!smp_query_via(mdb, portid, IB_ATTR_MULTICASTFORWTBL,
+                   block | (set << 28), timeout, srcport))
                        return -1;
 
                for (i = 0; i < 16; i++, map++) {
@@ -746,13 +750,18 @@ int main(int argc, char **argv)
        if (ibd_timeout)
                timeout = ibd_timeout;
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
+
        node_name_map = open_node_name_map(node_name_map_file);
 
-       if (ib_resolve_portid_str(&src_portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+       if (ib_resolve_portid_str_via(&src_portid, argv[0], ibd_dest_type,
+                       ibd_sm_id, srcport) < 0)
                IBERROR("can't resolve source port %s", argv[0]);
 
-       if (ib_resolve_portid_str(&dest_portid, argv[1], ibd_dest_type, ibd_sm_id) < 0)
+       if (ib_resolve_portid_str_via(&dest_portid, argv[1], ibd_dest_type,
+                       ibd_sm_id, srcport) < 0)
                IBERROR("can't resolve destination port %s", argv[1]);
 
        if (ibd_dest_type == IB_DEST_DRPATH) {
@@ -796,5 +805,8 @@ int main(int argc, char **argv)
        dump_mcpath(endnode, dumplevel);
 
        close_node_name_map(node_name_map);
+
+       mad_rpc_close_port(srcport);
+
        exit(0);
 }
index 5252459..de5ea90 100644 (file)
@@ -78,6 +78,8 @@ static ibmad_gid_t mgid_ipoib = {
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
 };
 
+struct ibmad_port *srcport;
+
 uint64_t build_mcm_rec(uint8_t *data, ibmad_gid_t mgid, ibmad_gid_t port_gid)
 {
        memset(data, 0, IB_SA_DATA_SIZE);
@@ -442,10 +444,13 @@ int main(int argc, char **argv)
        if (argc > 1)
                guid_file = argv[1];
 
-       madrpc_init(NULL, 0, mgmt_classes, 2);
+       srcport = mad_rpc_open_port(NULL, 0, mgmt_classes, 2);
+       if (!srcport)
+               err("Failed to open port");
+
 
 #if 1
-       ib_resolve_smlid(&dport_id, TMO);
+       ib_resolve_smlid_via(&dport_id, TMO, srcport);
 #else
        memset(&dport_id, 0, sizeof(dport_id));
        dport_id.lid = 1;
@@ -463,7 +468,7 @@ int main(int argc, char **argv)
        }
 
 #if 1
-       port = madrpc_portid();
+       port = mad_rpc_portid(srcport);
 #else
        ret = umad_init();
 
index ff2fc08..b0bda49 100644 (file)
@@ -47,6 +47,8 @@
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 struct perf_count {
        uint32_t portselect;
        uint32_t counterselect;
@@ -270,7 +272,7 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
 
        if (extended != 1) {
                if (!pma_query_via(pc, portid, port, timeout,
-                                               IB_GSI_PORT_COUNTERS, NULL))
+                                  IB_GSI_PORT_COUNTERS, srcport))
                        IBERROR("perfquery");
                if (!(cap_mask & 0x1000)) {
                        /* if PortCounters:PortXmitWait not suppported clear this counter */
@@ -286,7 +288,7 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
                        IBWARN("PerfMgt ClassPortInfo 0x%x extended counters not indicated\n", cap_mask);
 
                if (!pma_query_via(pc, portid, port, timeout,
-                                       IB_GSI_PORT_COUNTERS_EXT, NULL))
+                                  IB_GSI_PORT_COUNTERS_EXT, srcport))
                        IBERROR("perfextquery");
                if (aggregate)
                        aggregate_perfcounters_ext();
@@ -302,11 +304,11 @@ static void reset_counters(int extended, int timeout, int mask, ib_portid_t *por
 {
        if (extended != 1) {
                if (!performance_reset_via(pc, portid, port, mask, timeout,
-                                               IB_GSI_PORT_COUNTERS, NULL))
+                                          IB_GSI_PORT_COUNTERS, srcport))
                        IBERROR("perf reset");
        } else {
                if (!performance_reset_via(pc, portid, port, mask, timeout,
-                                               IB_GSI_PORT_COUNTERS_EXT, NULL))
+                                          IB_GSI_PORT_COUNTERS_EXT, srcport))
                        IBERROR("perf ext reset");
        }
 }
@@ -319,21 +321,21 @@ void xmt_sl_query(ib_portid_t *portid, int port, int mask)
 
        if (reset_only) {
                if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
-                                               IB_GSI_PORT_XMIT_DATA_SL, NULL))
+                                               IB_GSI_PORT_XMIT_DATA_SL, srcport))
                        IBERROR("perfslreset");
                return;
        }
 
        if (!pma_query_via(pc, portid, port, ibd_timeout,
-                               IB_GSI_PORT_XMIT_DATA_SL, NULL))
+                               IB_GSI_PORT_XMIT_DATA_SL, srcport))
                IBERROR("perfslquery");
 
        mad_dump_perfcounters_xmt_sl(buf, sizeof buf, pc, sizeof pc);
-       printf("# Port counters: %s port %d\n%s", portid2str(portid), port, buf);
+       printf("# PortXmitDataSL counters: %s port %d\n%s", portid2str(portid), port, buf);
 
-       if(reset)
+       if (reset)
                if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
-                                               IB_GSI_PORT_XMIT_DATA_SL, NULL))
+                                               IB_GSI_PORT_XMIT_DATA_SL, srcport))
                        IBERROR("perfslreset");
 }
 
@@ -343,21 +345,21 @@ void rcv_sl_query(ib_portid_t *portid, int port, int mask)
 
        if (reset_only) {
                if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
-                                               IB_GSI_PORT_RCV_DATA_SL, NULL))
+                                               IB_GSI_PORT_RCV_DATA_SL, srcport))
                        IBERROR("perfslreset");
                return;
        }
 
        if (!pma_query_via(pc, portid, port, ibd_timeout,
-                               IB_GSI_PORT_RCV_DATA_SL, NULL))
+                               IB_GSI_PORT_RCV_DATA_SL, srcport))
                IBERROR("perfslquery");
 
        mad_dump_perfcounters_rcv_sl(buf, sizeof buf, pc, sizeof pc);
-       printf("# Port counters: %s port %d\n%s", portid2str(portid), port, buf);
+       printf("# PortRcvDataSL counters: %s port %d\n%s", portid2str(portid), port, buf);
 
-       if(reset)
+       if (reset)
                if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
-                                               IB_GSI_PORT_RCV_DATA_SL, NULL))
+                                               IB_GSI_PORT_RCV_DATA_SL, srcport))
                        IBERROR("perfslreset");
 }
 
@@ -442,19 +444,22 @@ int main(int argc, char **argv)
        if (argc > 2)
                mask = strtoul(argv[2], 0, 0);
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 4);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 4);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (argc) {
-               if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+               if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                               ibd_sm_id, srcport) < 0)
                        IBERROR("can't resolve destination port %s", argv[0]);
        } else {
-               if (ib_resolve_self(&portid, &port, 0) < 0)
+               if (ib_resolve_self_via(&portid, &port, 0, srcport) < 0)
                        IBERROR("can't resolve self port %s", argv[0]);
        }
 
        /* PerfMgt ClassPortInfo is a required attribute */
-       if (!pma_query_via(pc, &portid, port, ibd_timeout,
-                                       CLASS_PORT_INFO, NULL))
+       if (!pma_query_via(pc, &portid, port, ibd_timeout, CLASS_PORT_INFO,
+                          srcport))
                IBERROR("classportinfo query");
        /* ClassPortInfo should be supported as part of libibmad */
        memcpy(&cap_mask, pc + 2, sizeof(cap_mask));    /* CapabilityMask */
@@ -468,16 +473,17 @@ int main(int argc, char **argv)
 
        if (xmt_sl) {
                xmt_sl_query(&portid, port, mask);
-               exit(0);
+               goto done;
        }
 
        if (rcv_sl) {
                rcv_sl_query(&portid, port, mask);
-               exit(0);
+               goto done;
        }
 
        if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
-               if (smp_query(data, &portid, IB_ATTR_NODE_INFO, 0, 0) < 0)
+               if (smp_query_via(data, &portid, IB_ATTR_NODE_INFO, 0, 0,
+                               srcport) < 0)
                        IBERROR("smp query nodeinfo failed");
                node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
                mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports);
@@ -485,7 +491,8 @@ int main(int argc, char **argv)
                        IBERROR("smp query nodeinfo: num ports invalid");
 
                if (node_type == IB_NODE_SWITCH) {
-                       if (smp_query(data, &portid, IB_ATTR_SWITCH_INFO, 0, 0) < 0)
+                       if (smp_query_via(data, &portid, IB_ATTR_SWITCH_INFO,
+                                       0, 0, srcport) < 0)
                                IBERROR("smp query nodeinfo failed");
                        enhancedport0 = mad_get_field(data, 0, IB_SW_ENHANCED_PORT0_F);
                        if (enhancedport0)
@@ -513,7 +520,7 @@ int main(int argc, char **argv)
                dump_perfcounters(extended, ibd_timeout, cap_mask, &portid, port, 0);
 
        if (!reset)
-               exit(0);
+               goto done;
 
 do_reset:
 
@@ -527,5 +534,7 @@ do_reset:
        else
                reset_counters(extended, ibd_timeout, mask, &portid, port);
 
+done:
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index 90ad512..4dcd712 100644 (file)
@@ -163,7 +163,7 @@ recv_mad:
                        umad = realloc(umad, umad_size() + len);
                        goto recv_mad;
                }
-               IBPANIC("umad_recv failed: attr %u: %s\n", attr,
+               IBPANIC("umad_recv failed: attr 0x%x: %s\n", attr,
                        strerror(errno));
        }
 
@@ -1324,12 +1324,15 @@ static int query_mft_records(const struct query_cmd *q, bind_handle_t h,
 
 static bind_handle_t get_bind_handle(void)
 {
+       static struct ibmad_port *srcport;
        static struct bind_handle handle;
        int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 2);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
-       ib_resolve_smlid(&handle.dport, ibd_timeout);
+       ib_resolve_smlid_via(&handle.dport, ibd_timeout, srcport);
        if (!handle.dport.lid)
                IBPANIC("No SM found.");
 
@@ -1337,7 +1340,7 @@ static bind_handle_t get_bind_handle(void)
        if (!handle.dport.qkey)
                handle.dport.qkey = IB_DEFAULT_QP1_QKEY;
 
-       handle.fd = madrpc_portid();
+       handle.fd = mad_rpc_portid(srcport);
        handle.agent = umad_register(handle.fd, IB_SA_CLASS, 2, 1, NULL);
 
        return &handle;
index 549cb81..ebf6a47 100644 (file)
@@ -48,6 +48,8 @@
 
 static uint8_t sminfo[1024];
 
+struct ibmad_port *srcport;
+
 int strdata, xdata=1, bindata;
 enum {
        SMINFO_NOTACT,
@@ -113,13 +115,16 @@ int main(int argc, char **argv)
        if (argc > 1)
                mod = atoi(argv[1]);
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (argc) {
-               if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, 0) < 0)
+               if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                               0, srcport) < 0)
                        IBERROR("can't resolve destination port %s", argv[0]);
        } else {
-               if (ib_resolve_smlid(&portid, ibd_timeout) < 0)
+               if (ib_resolve_smlid_via(&portid, ibd_timeout, srcport) < 0)
                        IBERROR("can't resolve sm port %s", argv[0]);
        }
 
@@ -130,10 +135,12 @@ int main(int argc, char **argv)
        mad_encode_field(sminfo, IB_SMINFO_STATE_F, &state);
 
        if (mod) {
-               if (!(p = smp_set(sminfo, &portid, IB_ATTR_SMINFO, mod, ibd_timeout)))
+               if (!(p = smp_set_via(sminfo, &portid, IB_ATTR_SMINFO, mod,
+                               ibd_timeout, srcport)))
                        IBERROR("query");
        } else
-               if (!(p = smp_query(sminfo, &portid, IB_ATTR_SMINFO, 0, ibd_timeout)))
+               if (!(p = smp_query_via(sminfo, &portid, IB_ATTR_SMINFO, 0,
+                               ibd_timeout, srcport)))
                        IBERROR("query");
 
        mad_decode_field(sminfo, IB_SMINFO_GUID_F, &guid);
@@ -145,5 +152,6 @@ int main(int argc, char **argv)
        printf("sminfo: sm lid %d sm guid 0x%" PRIx64 ", activity count %u priority %d state %d %s\n",
                portid.lid, guid, act, prio, state, STATESTR(state));
 
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index bf1626d..2ed1e65 100644 (file)
@@ -51,6 +51,8 @@
 
 #include "ibdiag_common.h"
 
+struct ibmad_port *srcport;
+
 typedef char *(op_fn_t)(ib_portid_t *dest, char **argv, int argc);
 
 typedef struct match_rec {
@@ -88,13 +90,13 @@ node_desc(ib_portid_t *dest, char **argv, int argc)
        char      dots[128];
        char     *nodename = NULL;
 
-       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
                return "node info query failed";
 
        mad_decode_field(data, IB_NODE_TYPE_F, &node_type);
        mad_decode_field(data, IB_NODE_GUID_F, &node_guid);
 
-       if (!smp_query(nd, dest, IB_ATTR_NODE_DESC, 0, 0))
+       if (!smp_query_via(nd, dest, IB_ATTR_NODE_DESC, 0, 0, srcport))
                return "node desc query failed";
 
        nodename = remap_node_name(node_name_map, node_guid, nd);
@@ -119,7 +121,7 @@ node_info(ib_portid_t *dest, char **argv, int argc)
        char buf[2048];
        char data[IB_SMP_DATA_SIZE];
 
-       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
                return "node info query failed";
 
        mad_dump_nodeinfo(buf, sizeof buf, data, sizeof data);
@@ -138,7 +140,7 @@ port_info(ib_portid_t *dest, char **argv, int argc)
        if (argc > 0)
                portnum = strtol(argv[0], 0, 0);
 
-       if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
                return "port info query failed";
 
        mad_dump_portinfo(buf, sizeof buf, data, sizeof data);
@@ -153,7 +155,7 @@ switch_info(ib_portid_t *dest, char **argv, int argc)
        char buf[2048];
        char data[IB_SMP_DATA_SIZE];
 
-       if (!smp_query(data, dest, IB_ATTR_SWITCH_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
                return "switch info query failed";
 
        mad_dump_switchinfo(buf, sizeof buf, data, sizeof data);
@@ -176,7 +178,7 @@ pkey_table(ib_portid_t *dest, char **argv, int argc)
                portnum = strtol(argv[0], 0, 0);
 
        /* Get the partition capacity */
-       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
                return "node info query failed";
 
        mad_decode_field(data, IB_NODE_TYPE_F, &t);
@@ -185,7 +187,8 @@ pkey_table(ib_portid_t *dest, char **argv, int argc)
                return "invalid port number";
 
        if ((t == IB_NODE_SWITCH) && (portnum != 0)) {
-               if (!smp_query(data, dest, IB_ATTR_SWITCH_INFO, 0, 0))
+               if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0,
+                               srcport))
                        return "switch info failed";
                mad_decode_field(data, IB_SW_PARTITION_ENFORCE_CAP_F, &n);
        } else
@@ -193,7 +196,8 @@ pkey_table(ib_portid_t *dest, char **argv, int argc)
 
        for (i = 0; i < (n + 31) / 32; i++) {
                mod =  i | (portnum << 16);
-               if (!smp_query(data, dest, IB_ATTR_PKEY_TBL, mod, 0))
+               if (!smp_query_via(data, dest, IB_ATTR_PKEY_TBL, mod, 0,
+                               srcport))
                        return "pkey table query failed";
                if (i + 1 == (n + 31) / 32)
                        k = ((n + 7 - i * 32) / 8) * 8;
@@ -220,7 +224,7 @@ static char *sl2vl_dump_table_entry(ib_portid_t *dest, int in, int out)
        char data[IB_SMP_DATA_SIZE];
        int portnum = (in << 8) | out;
 
-       if (!smp_query(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0, srcport))
                return "slvl query failed";
 
        mad_dump_sltovl(buf, sizeof buf, data, sizeof data);
@@ -240,7 +244,7 @@ sl2vl_table(ib_portid_t *dest, char **argv, int argc)
        if (argc > 0)
                portnum = strtol(argv[0], 0, 0);
 
-       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
                return "node info query failed";
 
        mad_decode_field(data, IB_NODE_TYPE_F, &type);
@@ -270,8 +274,8 @@ static char *vlarb_dump_table_entry(ib_portid_t *dest, int portnum, int offset,
        char buf[2048];
        char data[IB_SMP_DATA_SIZE];
 
-       if (!smp_query(data, dest, IB_ATTR_VL_ARBITRATION,
-                       (offset << 16) | portnum, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_VL_ARBITRATION,
+                       (offset << 16) | portnum, 0, srcport))
                return "vl arb query failed";
        mad_dump_vlarbitration(buf, sizeof(buf), data, cap * 2);
        printf("%s", buf);
@@ -305,12 +309,14 @@ vlarb_table(ib_portid_t *dest, char **argv, int argc)
 
        /* port number of 0 could mean SP0 or port MAD arrives on */
        if (portnum == 0) {
-               if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+               if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0,
+                               srcport))
                        return "node info query failed";
 
                mad_decode_field(data, IB_NODE_TYPE_F, &type);
                if (type == IB_NODE_SWITCH) {
-                       if (!smp_query(data, dest, IB_ATTR_SWITCH_INFO, 0, 0))
+                       if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0,
+                                       0, srcport))
                                return "switch info query failed";
                        mad_decode_field(data, IB_SW_ENHANCED_PORT0_F, &enhsp0);
                        if (!enhsp0) {
@@ -321,7 +327,7 @@ vlarb_table(ib_portid_t *dest, char **argv, int argc)
                }
        }
 
-       if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
                return "port info query failed";
 
        mad_decode_field(data, IB_PORT_VL_ARBITRATION_LOW_CAP_F, &lowcap);
@@ -349,13 +355,14 @@ guid_info(ib_portid_t *dest, char **argv, int argc)
        int n;
 
        /* Get the guid capacity */
-       if (!smp_query(data, dest, IB_ATTR_PORT_INFO, 0, 0))
+       if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, 0, 0, srcport))
                return "port info failed";
        mad_decode_field(data, IB_PORT_GUID_CAP_F, &n);
 
        for (i = 0; i < (n + 7) / 8; i++) {
                mod =  i;
-               if (!smp_query(data, dest, IB_ATTR_GUID_INFO, mod, 0))
+               if (!smp_query_via(data, dest, IB_ATTR_GUID_INFO, mod, 0,
+                               srcport))
                        return "guid info query failed";
                if (i + 1 == (n + 7) / 8)
                        k = ((n + 1 - i * 8) / 2) * 2;
@@ -445,11 +452,15 @@ int main(int argc, char **argv)
        if (!(fn = match_op(argv[0])))
                IBERROR("operation '%s' not supported", argv[0]);
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
+
        node_name_map = open_node_name_map(node_name_map_file);
 
        if (ibd_dest_type != IB_DEST_DRSLID) {
-               if (ib_resolve_portid_str(&portid, argv[1], ibd_dest_type, ibd_sm_id) < 0)
+               if (ib_resolve_portid_str_via(&portid, argv[1], ibd_dest_type,
+                               ibd_sm_id, srcport) < 0)
                        IBERROR("can't resolve destination port %s", argv[1]);
                if ((err = fn(&portid, argv+2, argc-2)))
                        IBERROR("operation %s: %s", argv[0], err);
@@ -458,11 +469,13 @@ int main(int argc, char **argv)
 
                memset(concat, 0, 64);
                snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]);
-               if (ib_resolve_portid_str(&portid, concat, ibd_dest_type, ibd_sm_id) < 0)
+               if (ib_resolve_portid_str_via(&portid, concat, ibd_dest_type,
+                               ibd_sm_id, srcport) < 0)
                        IBERROR("can't resolve destination port %s", concat);
                if ((err = fn(&portid, argv+3, argc-3)))
                        IBERROR("operation %s: %s", argv[0], err);
        }
        close_node_name_map(node_name_map);
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index db87e38..0bf9616 100644 (file)
 /* Vendor specific Attribute IDs */
 #define IB_MLX_IS3_GENERAL_INFO                0x17
 #define IB_MLX_IS3_CONFIG_SPACE_ACCESS 0x50
+#define IB_MLX_IS4_COUNTER_GROUP_INFO   0x90
+#define IB_MLX_IS4_CONFIG_COUNTER_GROUP 0x91
 /* Config space addresses */
 #define IB_MLX_IS3_PORT_XMIT_WAIT      0x10013C
 
+struct ibmad_port *srcport;
+
 typedef struct {
        uint16_t hw_revision;
        uint16_t device_id;
@@ -103,10 +107,102 @@ typedef struct {
        is3_record_t record[18];
 } is3_config_space_t;
 
-static int general_info, xmit_wait = 0;
+#define COUNTER_GROUPS_NUM 2
+
+typedef struct {
+       uint8_t reserved1[8];
+       uint8_t reserved[3];
+       uint8_t num_of_counter_groups;
+       uint32_t group_masks[COUNTER_GROUPS_NUM];
+}  is4_counter_group_info_t;
+
+typedef struct {
+       uint8_t reserved[3];
+       uint8_t group_select;
+} is4_group_select_t;
+
+typedef struct {
+       uint8_t reserved1[8];
+       uint8_t reserved[4];
+       is4_group_select_t group_selects[COUNTER_GROUPS_NUM];
+} is4_config_counter_groups_t;
+
+void counter_groups_info(ib_portid_t *portid, int port)
+{
+       char buf[1024];
+       ib_vendor_call_t call;
+       is4_counter_group_info_t *cg_info;
+       int i, num_cg;
+
+       memset(&call, 0, sizeof(call));
+       call.mgmt_class = IB_MLX_VENDOR_CLASS;
+       call.method  =  IB_MAD_METHOD_GET;
+       call.timeout = ibd_timeout;
+       call.attrid  = IB_MLX_IS4_COUNTER_GROUP_INFO;
+       call.mod     = port;
+
+       /* Counter Group Info */
+       memset(&buf, 0, sizeof(buf));
+       if (!ib_vendor_call_via(&buf, portid, &call, srcport))
+               IBERROR("counter group info query");
+
+       cg_info = (is4_counter_group_info_t *)&buf;
+       num_cg = cg_info->num_of_counter_groups;
+       printf("counter_group_info:\n");
+       printf("%d counter groups\n", num_cg);
+       for (i = 0; i < num_cg; i++)
+               printf("group%d mask %#x\n", i, ntohl(cg_info->group_masks[i]));
+}
+
+/* Group0 counter config values */
+#define IS4_G0_PortXmtDataSL_0_7  0
+#define IS4_G0_PortXmtDataSL_8_15 1
+#define IS4_G0_PortRcvDataSL_0_7  2
+
+/* Group1 counter config values */
+#define IS4_G1_PortXmtDataSL_8_15 1
+#define IS4_G1_PortRcvDataSL_0_7  2
+#define IS4_G1_PortRcvDataSL_8_15 8
+
+static int cg0, cg1;
+
+void config_counter_groups(ib_portid_t *portid, int port)
+{
+       char buf[1024];
+       ib_vendor_call_t call;
+       is4_config_counter_groups_t *cg_config;
+
+       memset(&call, 0, sizeof(call));
+       call.mgmt_class = IB_MLX_VENDOR_CLASS;
+       call.attrid  = IB_MLX_IS4_CONFIG_COUNTER_GROUP;
+       call.timeout = ibd_timeout;
+       call.mod     = port;
+       /* configure counter groups for groups 0 and 1 */
+       call.method  = IB_MAD_METHOD_SET;
+
+       memset(&buf, 0, sizeof(buf));
+       cg_config = (is4_config_counter_groups_t *)&buf;
+
+       printf("counter_groups_config: configuring group0 %d group1 %d\n", cg0, cg1);
+       cg_config->group_selects[0].group_select = (uint8_t) cg0;
+       cg_config->group_selects[1].group_select = (uint8_t) cg1;
+
+       if (!ib_vendor_call_via(&buf, portid, &call, srcport))
+               IBERROR("config counter group set");
+
+       /* get config counter groups */
+       memset(&buf, 0, sizeof(buf));
+       call.method  =  IB_MAD_METHOD_GET;
+
+       if (!ib_vendor_call_via(&buf, portid, &call, srcport))
+               IBERROR("config counter group query");
+}
+
+static int general_info, xmit_wait, counter_group_info, config_counter_group;
 
 static int process_opt(void *context, int ch, char *optarg)
 {
+       int ret;
        switch (ch) {
        case 'N':
                general_info = 1;
@@ -114,6 +210,15 @@ static int process_opt(void *context, int ch, char *optarg)
        case 'w':
                xmit_wait = 1;
                break;
+       case 'i':
+               counter_group_info = 1;
+               break;
+       case 'c':
+               config_counter_group = 1;
+               ret = sscanf(optarg, "%d,%d", &cg0, &cg1);
+               if (ret != 2)
+                       return -1;
+               break;
        default:
                return -1;
        }
@@ -134,12 +239,18 @@ int main(int argc, char **argv)
        const struct ibdiag_opt opts[] = {
                { "N", 'N', 0, NULL, "show IS3 general information"},
                { "w", 'w', 0, NULL, "show IS3 port xmit wait counters"},
+               { "i", 'i', 0, NULL, "show IS4 counter group info"},
+               { "c", 'c', 1, "<num,num>", "configure IS4 counter groups"},
                { 0 }
        };
-       char usage_args[] = "<lid|guid>";
+
+       char usage_args[] = "<lid|guid> [port]";
        const char *usage_examples[] = {
                "-N 6\t\t# read IS3 general information",
                "-w 6\t\t# read IS3 port xmit wait counters",
+               "-i 6 12\t# read IS4 port 12 counter group info",
+               "-c 0,1 6 12\t# configure IS4 port 12 counter groups for PortXmitDataSL",
+               "-c 2,8 6 12\t# configure IS4 port 12 counter groups for PortRcvDataSL",
                NULL
        };
 
@@ -152,23 +263,36 @@ int main(int argc, char **argv)
        if (argc > 1)
                port = strtoul(argv[1], 0, 0);
 
-       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 4);
+       srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 4);
+       if (!srcport)
+               IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
 
        if (argc) {
-               if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+               if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
+                               ibd_sm_id, srcport) < 0)
                        IBERROR("can't resolve destination port %s", argv[0]);
        } else {
-               if (ib_resolve_self(&portid, &port, 0) < 0)
+               if (ib_resolve_self_via(&portid, &port, 0, srcport) < 0)
                        IBERROR("can't resolve self port %s", argv[0]);
        }
 
+       if (counter_group_info) {
+               counter_groups_info(&portid, port);
+               exit(0);
+       }
+
+       if (config_counter_group) {
+               config_counter_groups(&portid, port);
+               exit(0);
+       }
+
+       /* These are Mellanox specific vendor MADs */
+       /* but vendors change the VendorId so how know for sure ? */
        /* Only General Info and Port Xmit Wait Counters */
        /* queries are currently supported */
        if (!general_info && !xmit_wait)
                IBERROR("at least one of -N and -w must be specified");
 
-       /* These are Mellanox specific vendor MADs */
-       /* but vendors change the VendorId so how know for sure ? */
        /* Would need a list of these and it might not be complete */
        /* so for right now, punt on this */
 
@@ -180,12 +304,12 @@ int main(int argc, char **argv)
        memset(&buf, 0, sizeof(buf));
        /* vendor ClassPortInfo is required attribute if class supported */
        call.attrid = CLASS_PORT_INFO;
-       if (!ib_vendor_call(&buf, &portid, &call))
+       if (!ib_vendor_call_via(&buf, &portid, &call, srcport))
                IBERROR("classportinfo query");
 
        memset(&buf, 0, sizeof(buf));
        call.attrid = IB_MLX_IS3_GENERAL_INFO;
-       if (!ib_vendor_call(&buf, &portid, &call))
+       if (!ib_vendor_call_via(&buf, &portid, &call, srcport))
                IBERROR("vendstat");
        gi = (is3_general_info_t *)&buf;
 
@@ -217,7 +341,7 @@ int main(int argc, char **argv)
                cs = (is3_config_space_t *)&buf;
                for (i = 0; i < 16; i++)
                        cs->record[i].address = htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 1) << 12));
-               if (!ib_vendor_call(&buf, &portid, &call))
+               if (!ib_vendor_call_via(&buf, &portid, &call, srcport))
                        IBERROR("vendstat");
 
                for (i = 0; i < 16; i++)
@@ -232,7 +356,7 @@ int main(int argc, char **argv)
                cs = (is3_config_space_t *)&buf;
                for (i = 0; i < 8; i++)
                        cs->record[i].address = htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 17) << 12));
-               if (!ib_vendor_call(&buf, &portid, &call))
+               if (!ib_vendor_call_via(&buf, &portid, &call, srcport))
                        IBERROR("vendstat");
 
                for (i = 0; i < 8; i++)
@@ -242,5 +366,6 @@ int main(int argc, char **argv)
                                       ntohl(cs->record[i].data));
        }
 
+       mad_rpc_close_port(srcport);
        exit(0);
 }
index 00e28ae..31a7d72 100644 (file)
--- a/ulp/dirs
+++ b/ulp/dirs
@@ -9,5 +9,6 @@ DIRS =                  \
        libibverbs      \\r
        libibumad       \\r
        libibmad        \\r
+       libibnetdisc\\r
        librdmacm       \\r
        nd\r
index 5f9dea3..b404816 100644 (file)
@@ -63,6 +63,11 @@ BEGIN_C_DECLS
 #define IB_SA_MCM_RECSZ                53
 #define IB_SA_PR_RECSZ         64
 
+#define IB_BM_DATA_OFFS                64
+#define IB_BM_DATA_SZ          (IB_MAD_SIZE - IB_BM_DATA_OFFS)
+#define IB_BM_BKEY_OFFS                24
+#define IB_BM_BKEY_AND_DATA_SZ (IB_MAD_SIZE - IB_BM_BKEY_OFFS)
+
 enum MAD_CLASSES {
        IB_SMI_CLASS = 0x1,
        IB_SMI_DIRECT_CLASS = 0x81,
@@ -108,6 +113,14 @@ enum MAD_ATTR_ID {
        INFORM_INFO = 0x3,
 };
 
+enum MAD_STATUS {
+       IB_MAD_STS_OK                        = (0 << 2),
+       IB_MAD_STS_BAD_BASE_VER_OR_CLASS     = (1 << 2),
+       IB_MAD_STS_METHOD_NOT_SUPPORTED      = (2 << 2),
+       IB_MAD_STS_METHOD_ATTR_NOT_SUPPORTED = (3 << 2),
+       IB_MAD_STS_INV_ATTR_VALUE            = (7 << 2),
+};
+
 enum SMI_ATTR_ID {
        IB_ATTR_NODE_DESC = 0x10,
        IB_ATTR_NODE_INFO = 0x11,
@@ -158,6 +171,28 @@ enum GSI_ATTR_ID {
        IB_GSI_ATTR_LAST
 };
 
+enum BM_ATTR_ID {
+        IB_BM_ATTR_BKEYINFO = 0x10,
+        IB_BM_ATTR_WRITE_VPD = 0x20,
+        IB_BM_ATTR_READ_VPD = 0x21,
+        IB_BM_ATTR_RESET_IBML = 0x22,
+        IB_BM_ATTR_SET_MODULE_PM_CONTROL = 0x23,
+        IB_BM_ATTR_GET_MODULE_PM_CONTROL = 0x24,
+        IB_BM_ATTR_SET_UNIT_PM_CONTROL = 0x25,
+        IB_BM_ATTR_GET_UNIT_PM_CONTROL = 0x26,
+        IB_BM_ATTR_SET_IOC_PM_CONTROL = 0x27,
+        IB_BM_ATTR_GET_IOC_PM_CONTROL = 0x28,
+        IB_BM_ATTR_SET_MODULE_STATE = 0x29,
+        IB_BM_ATTR_SET_MODULE_ATTENTION = 0x2A,
+        IB_BM_ATTR_GET_MODULE_STATUS = 0x2B,
+        IB_BM_ATTR_IB2IBML = 0x2C,
+        IB_BM_ATTR_IB2CME = 0x2D,
+        IB_BM_ATTR_IB2MME = 0x2E,
+        IB_BM_ATTR_OEM = 0x2F,
+
+        IB_BM_ATTR_LAST
+};
+
 #define IB_VENDOR_OPENIB_PING_CLASS    (IB_VENDOR_RANGE2_START_CLASS + 2)
 #define IB_VENDOR_OPENIB_SYSSTAT_CLASS (IB_VENDOR_RANGE2_START_CLASS + 3)
 #define IB_OPENIB_OUI                  (0x001405)
@@ -357,6 +392,7 @@ enum MAD_FIELDS {
        IB_SW_DEF_MCAST_NOT_PRIM_F,
        IB_SW_LIFE_TIME_F,
        IB_SW_STATE_CHANGE_F,
+       IB_SW_OPT_SLTOVL_MAPPING_F,
        IB_SW_LIDS_PER_PORT_F,
        IB_SW_PARTITION_ENFORCE_CAP_F,
        IB_SW_PARTITION_ENF_INB_F,
@@ -464,6 +500,7 @@ enum MAD_FIELDS {
        IB_SA_PR_DLID_F,
        IB_SA_PR_SLID_F,
        IB_SA_PR_NPATH_F,
+       IB_SA_PR_SL_F,
 
        /*
         * MC Member rec
@@ -661,6 +698,14 @@ typedef struct ib_vendor_call {
        ib_rmpp_hdr_t rmpp;
 } ib_vendor_call_t;
 
+typedef struct ib_bm_call {
+       unsigned method;
+       unsigned attrid;
+       unsigned mod;
+       unsigned timeout;
+       uint64_t bkey;
+} ib_bm_call_t;
+
 #define IB_MIN_UCAST_LID       1
 #define IB_MAX_UCAST_LID       (0xc000-1)
 #define IB_MIN_MCAST_LID       0xc000
@@ -722,6 +767,7 @@ MAD_EXPORT void mad_encode_field(uint8_t * buf, enum MAD_FIELDS field, void *val
 MAD_EXPORT int mad_print_field(enum MAD_FIELDS field, const char *name, void *val);
 MAD_EXPORT char *mad_dump_field(enum MAD_FIELDS field, char *buf, int bufsz, void *val);
 MAD_EXPORT char *mad_dump_val(enum MAD_FIELDS field, char *buf, int bufsz, void *val);
+MAD_EXPORT const char *mad_field_name(enum MAD_FIELDS field);
 
 /* mad.c */
 MAD_EXPORT void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath,
@@ -730,27 +776,67 @@ MAD_EXPORT uint64_t mad_trid(void);
 MAD_EXPORT int mad_build_pkt(void *umad, ib_rpc_t * rpc, ib_portid_t * dport,
                             ib_rmpp_hdr_t * rmpp, void *data);
 
+/* New interface */
+MAD_EXPORT void madrpc_show_errors(int set);
+MAD_EXPORT int madrpc_set_retries(int retries);
+MAD_EXPORT int madrpc_set_timeout(int timeout);
+MAD_EXPORT struct ibmad_port *mad_rpc_open_port(char *dev_name, int dev_port,
+                       int *mgmt_classes, int num_classes);
+MAD_EXPORT void mad_rpc_close_port(struct ibmad_port *srcport);
+MAD_EXPORT void *mad_rpc(const struct ibmad_port *srcport, ib_rpc_t * rpc,
+                       ib_portid_t * dport, void *payload, void *rcvdata);
+MAD_EXPORT void *mad_rpc_rmpp(const struct ibmad_port *srcport, ib_rpc_t * rpc,
+                             ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
+                             void *data);
+MAD_EXPORT int mad_rpc_portid(struct ibmad_port *srcport);
+MAD_EXPORT void mad_rpc_set_retries(struct ibmad_port *port, int retries);
+MAD_EXPORT void mad_rpc_set_timeout(struct ibmad_port *port, int timeout);
+MAD_EXPORT int mad_rpc_class_agent(struct ibmad_port *srcport, int cls);
+
 /* register.c */
 MAD_EXPORT int mad_register_port_client(int port_id, int mgmt,
                                        uint8_t rmpp_version);
-MAD_EXPORT int mad_register_client(int mgmt, uint8_t rmpp_version);
+MAD_EXPORT int mad_register_client(int mgmt, uint8_t rmpp_version)
+                       DEPRECATED;
 MAD_EXPORT int mad_register_server(int mgmt, uint8_t rmpp_version,
                                   long method_mask[16 / sizeof(long)],
-                                  uint32_t class_oui);
-MAD_EXPORT int mad_class_agent(int mgmt);
-MAD_EXPORT int mad_agent_class(int agent);
+                                  uint32_t class_oui) DEPRECATED;
+/* register.c new interface */
+MAD_EXPORT int mad_register_client_via(int mgmt, uint8_t rmpp_version,
+                                      struct ibmad_port *srcport);
+MAD_EXPORT int mad_register_server_via(int mgmt, uint8_t rmpp_version,
+                                      long method_mask[16 / sizeof(long)],
+                                      uint32_t class_oui,
+                                      struct ibmad_port *srcport);
+MAD_EXPORT int mad_class_agent(int mgmt) DEPRECATED;
 
 /* serv.c */
 MAD_EXPORT int mad_send(ib_rpc_t * rpc, ib_portid_t * dport,
-                       ib_rmpp_hdr_t * rmpp, void *data);
-MAD_EXPORT void *mad_receive(void *umad, int timeout);
-MAD_EXPORT int mad_respond(void *umad, ib_portid_t * portid, uint32_t rstatus);
+                       ib_rmpp_hdr_t * rmpp, void *data) DEPRECATED;
+MAD_EXPORT void *mad_receive(void *umad, int timeout)
+               DEPRECATED;
+MAD_EXPORT int mad_respond(void *umad, ib_portid_t * portid, uint32_t rstatus)
+               DEPRECATED;
+
+/* serv.c new interface */
+MAD_EXPORT int mad_send_via(ib_rpc_t * rpc, ib_portid_t * dport,
+                           ib_rmpp_hdr_t * rmpp, void *data,
+                           struct ibmad_port *srcport);
+MAD_EXPORT void *mad_receive_via(void *umad, int timeout,
+                                struct ibmad_port *srcport);
+MAD_EXPORT int mad_respond_via(void *umad, ib_portid_t * portid, uint32_t rstatus,
+                              struct ibmad_port *srcport);
 MAD_EXPORT void *mad_alloc(void);
 MAD_EXPORT void mad_free(void *umad);
 
 /* vendor.c */
 MAD_EXPORT uint8_t *ib_vendor_call(void *data, ib_portid_t * portid,
-                                  ib_vendor_call_t * call);
+                                  ib_vendor_call_t * call) DEPRECATED;
+
+/* vendor.c new interface */
+MAD_EXPORT uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
+                                      ib_vendor_call_t * call,
+                                      struct ibmad_port *srcport);
 
 static inline int mad_is_vendor_range1(int mgmt)
 {
@@ -763,70 +849,79 @@ static inline int mad_is_vendor_range2(int mgmt)
 }
 
 /* rpc.c */
-MAD_EXPORT int madrpc_portid(void);
-MAD_EXPORT int madrpc_set_retries(int retries);
-MAD_EXPORT int madrpc_set_timeout(int timeout);
-void *madrpc(ib_rpc_t * rpc, ib_portid_t * dport, void *payload, void *rcvdata);
-void *madrpc_rmpp(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
-                 void *data);
+MAD_EXPORT int madrpc_portid(void) DEPRECATED;
+void *madrpc(ib_rpc_t * rpc, ib_portid_t * dport, void *payload, void *rcvdata)
+               DEPRECATED;
+void *madrpc_rmpp(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp, void *data)
+               DEPRECATED;
 MAD_EXPORT void madrpc_init(char *dev_name, int dev_port, int *mgmt_classes,
-                           int num_classes);
-void madrpc_save_mad(void *madbuf, int len);
-MAD_EXPORT void madrpc_show_errors(int set);
-
-void *mad_rpc_open_port(char *dev_name, int dev_port, int *mgmt_classes,
-                       int num_classes);
-void mad_rpc_close_port(void *ibmad_port);
-void *mad_rpc(const void *ibmad_port, ib_rpc_t * rpc, ib_portid_t * dport,
-             void *payload, void *rcvdata);
-void *mad_rpc_rmpp(const void *ibmad_port, ib_rpc_t * rpc, ib_portid_t * dport,
-                  ib_rmpp_hdr_t * rmpp, void *data);
+                           int num_classes) DEPRECATED;
+void madrpc_save_mad(void *madbuf, int len) DEPRECATED;
 
 /* smp.c */
 MAD_EXPORT uint8_t *smp_query(void *buf, ib_portid_t * id, unsigned attrid,
-                             unsigned mod, unsigned timeout);
+                             unsigned mod, unsigned timeout) DEPRECATED;
 MAD_EXPORT uint8_t *smp_set(void *buf, ib_portid_t * id, unsigned attrid,
-                           unsigned mod, unsigned timeout);
+                           unsigned mod, unsigned timeout) DEPRECATED;
+
+/* smp.c new interface */
 MAD_EXPORT uint8_t *smp_query_via(void *buf, ib_portid_t * id, unsigned attrid,
-                      unsigned mod, unsigned timeout, const void *srcport);
-uint8_t *smp_set_via(void *buf, ib_portid_t * id, unsigned attrid, unsigned mod,
-                    unsigned timeout, const void *srcport);
+                                 unsigned mod, unsigned timeout,
+                                 const struct ibmad_port *srcport);
+MAD_EXPORT uint8_t *smp_set_via(void *buf, ib_portid_t * id, unsigned attrid,
+                               unsigned mod, unsigned timeout,
+                               const struct ibmad_port *srcport);
 
 /* sa.c */
 uint8_t *sa_call(void *rcvbuf, ib_portid_t * portid, ib_sa_call_t * sa,
-                unsigned timeout);
-uint8_t *sa_rpc_call(const void *ibmad_port, void *rcvbuf, ib_portid_t * portid,
-                    ib_sa_call_t * sa, unsigned timeout);
-MAD_EXPORT int ib_path_query(ibmad_gid_t srcgid, ibmad_gid_t destgid, ib_portid_t * sm_id, void *buf); /* returns lid */
-int ib_path_query_via(const void *srcport, ibmad_gid_t srcgid,
-                     ibmad_gid_t destgid, ib_portid_t * sm_id, void *buf);
+                unsigned timeout) DEPRECATED;
+MAD_EXPORT int ib_path_query(ibmad_gid_t srcgid, ibmad_gid_t destgid,
+                            ib_portid_t * sm_id, void *buf) DEPRECATED;
+
+/* sa.c new interface */
+MAD_EXPORT uint8_t *sa_rpc_call(const struct ibmad_port *srcport, void *rcvbuf,
+                               ib_portid_t * portid, ib_sa_call_t * sa,
+                               unsigned timeout);
+MAD_EXPORT int ib_path_query_via(const struct ibmad_port *srcport,
+                                ibmad_gid_t srcgid, ibmad_gid_t destgid,
+                                ib_portid_t * sm_id, void *buf);
+       /* returns lid */
 
 /* resolve.c */
-MAD_EXPORT int ib_resolve_smlid(ib_portid_t * sm_id, int timeout);
-MAD_EXPORT int ib_resolve_guid(ib_portid_t * portid, uint64_t * guid,
-                              ib_portid_t * sm_id, int timeout);
+MAD_EXPORT int ib_resolve_smlid(ib_portid_t * sm_id, int timeout)
+                               DEPRECATED;
 MAD_EXPORT int ib_resolve_portid_str(ib_portid_t * portid, char *addr_str,
-                                    enum MAD_DEST dest, ib_portid_t * sm_id);
+                                    enum MAD_DEST dest, ib_portid_t * sm_id)
+                               DEPRECATED;
 MAD_EXPORT int ib_resolve_self(ib_portid_t * portid, int *portnum,
-                              ibmad_gid_t * gid);
-
-int ib_resolve_smlid_via(ib_portid_t * sm_id, int timeout, const void *srcport);
-int ib_resolve_guid_via(ib_portid_t * portid, uint64_t * guid,
-                       ib_portid_t * sm_id, int timeout, const void *srcport);
-int ib_resolve_portid_str_via(ib_portid_t * portid, char *addr_str,
-                             enum MAD_DEST dest, ib_portid_t * sm_id,
-                             const void *srcport);
-int ib_resolve_self_via(ib_portid_t * portid, int *portnum, ibmad_gid_t * gid,
-                       const void *srcport);
-
-/* gs.c */
+                              ibmad_gid_t * gid)
+                               DEPRECATED;
+
+/* resolve.c new interface */
+MAD_EXPORT int ib_resolve_smlid_via(ib_portid_t * sm_id, int timeout,
+                                   const struct ibmad_port *srcport);
+MAD_EXPORT int ib_resolve_guid_via(ib_portid_t * portid, uint64_t * guid,
+                                  ib_portid_t * sm_id, int timeout,
+                                  const struct ibmad_port *srcport);
+MAD_EXPORT int ib_resolve_portid_str_via(ib_portid_t * portid, char *addr_str,
+                                        enum MAD_DEST dest, ib_portid_t * sm_id,
+                                        const struct ibmad_port *srcport);
+MAD_EXPORT int ib_resolve_self_via(ib_portid_t * portid, int *portnum,
+                                  ibmad_gid_t * gid,
+                                  const struct ibmad_port *srcport);
+
+/* gs.c new interface */
 MAD_EXPORT uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
-                             unsigned timeout, unsigned id,
-                             const void *srcport);
-
+                                 unsigned timeout, unsigned id,
+                                 const struct ibmad_port *srcport);
 MAD_EXPORT uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
-                                     int port, unsigned mask, unsigned timeout,
-                                     unsigned id, const void *srcport);
+                                         int port, unsigned mask,
+                                         unsigned timeout, unsigned id,
+                                         const struct ibmad_port *srcport);
+
+/* bm.c */
+MAD_EXPORT uint8_t * bm_call_via(void *data, ib_portid_t *portid, ib_bm_call_t *call, struct ibmad_port *srcport);
+
 /* dump.c */
 MAD_EXPORT ib_mad_dump_fn
     mad_dump_int, mad_dump_uint, mad_dump_hex, mad_dump_rhex,
@@ -842,7 +937,7 @@ MAD_EXPORT ib_mad_dump_fn
     mad_dump_switchinfo, mad_dump_perfcounters, mad_dump_perfcounters_ext,
     mad_dump_perfcounters_xmt_sl, mad_dump_perfcounters_rcv_sl;
 
-extern int ibdebug;
+MAD_EXPORT int ibdebug;
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 #ifndef ntohll
index dde6e3a..dff3a79 100644 (file)
@@ -34,7 +34,7 @@
 #include <string.h>\r
 #include <windows.h>\r
 #include <winsock2.h>\r
-#include <ws2tcpip.h> \r
+#include <ws2tcpip.h>\r
 \r
 typedef unsigned __int8                uint8_t;\r
 typedef unsigned __int16       uint16_t;\r
@@ -48,7 +48,7 @@ typedef unsigned __int64      uint64_t;
 \r
 #define MAD_EXPORT     __declspec(dllexport)\r
 \r
-#define __attribute__(X)\r
+#define DEPRECATED\r
 \r
 #if !defined( __cplusplus )\r
 #define inline __inline\r
@@ -66,48 +66,4 @@ typedef unsigned __int64     uint64_t;
 #define random         rand\r
 #define srandom                srand\r
 \r
-static __inline\r
-const char * _inet_ntop(int family, const void *addr, char *dst, size_t len)\r
-{\r
-       if (family == AF_INET)\r
-       {\r
-               struct sockaddr_in in;\r
-               in.sin_family = AF_INET;\r
-               memcpy(&in.sin_addr, addr, 4);\r
-               if (getnameinfo((struct sockaddr *)&in,\r
-                               (socklen_t) (sizeof(struct sockaddr_in)),\r
-                               dst, len, NULL, 0, NI_NUMERICHOST))\r
-                       return NULL;\r
-       }\r
-       else if (family == AF_INET6)\r
-       {\r
-               struct sockaddr_in6 in6;\r
-               memset(&in6, 0, sizeof in6);\r
-               in6.sin6_family = AF_INET6;\r
-               memcpy(&in6.sin6_addr, addr, sizeof(struct in_addr6));\r
-\r
-               /* if no ipv6 support return simple IPv6 format rule:\r
-                * A series of "0's in a 16bit block can be represented by "0" \r
-                */\r
-               if (getnameinfo((struct sockaddr *)&in6, (socklen_t) (sizeof in6),\r
-                                dst, len, NULL, 0, NI_NUMERICHOST)) \r
-               {\r
-                       char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];\r
-                       int i, n=0;\r
-                                       \r
-                       if (len < sizeof(tmp))\r
-                               return NULL;\r
-\r
-                       for (i = 0; i < 8; i++) \r
-                               n += sprintf(tmp+n, "%s%x", \r
-                                            i?":":"",\r
-                                            ntohs(((unsigned short*)addr)[i]));\r
-                       tmp[n]='\0';\r
-                       strcpy(dst, tmp);\r
-               }\r
-       }\r
-       return dst;\r
-}\r
-#define inet_ntop _inet_ntop\r
-\r
 #endif /* _MAD_OSD_H_ */\r
index e487615..8c0e817 100644 (file)
@@ -10,7 +10,7 @@ TARGETTYPE = DYNLINK
 DLLDEF = $(OBJ_PATH)\$O\ibmad_exports.def\r
 \r
 DLLENTRY = DllMain\r
-USE_MSVCRT=1\r
+USE_MSVCRT = 1\r
 \r
 SOURCES = \\r
        ibmad_main.cpp \\r
@@ -28,10 +28,12 @@ SOURCES = \
        vendor.c\r
        \r
 INCLUDES =     ..\include\infiniband;\\r
-                       ..\..\libibmad\include;\\r
+                       ..\include;\\r
                        ..\..\libibverbs\include;\\r
                        ..\..\libibumad\include;\\r
-                       ..\..\..\inc;..\..\..\inc\user;\r
+                       ..\..\..\inc;\\r
+                       ..\..\..\inc\user;\\r
+                       ..\..\..\inc\user\linux;\r
 \r
 USER_C_FLAGS = $(USER_C_FLAGS) -DEXPORT_IBMAD_SYMBOLS\r
 \r
index e75e178..051c708 100644 (file)
@@ -701,12 +701,22 @@ void mad_dump_perfcounters_ext(char *buf, int bufsz, void *val, int valsz)
 
 void mad_dump_perfcounters_xmt_sl(char *buf, int bufsz, void *val, int valsz)
 {
-       _dump_fields(buf, bufsz, val, IB_PC_XMT_DATA_SL_FIRST_F, IB_PC_XMT_DATA_SL_LAST_F);
+       int cnt;
+
+       cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
+                          IB_PC_EXT_XMT_BYTES_F);
+       _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMT_DATA_SL_FIRST_F,
+                    IB_PC_XMT_DATA_SL_LAST_F);
 }
 
 void mad_dump_perfcounters_rcv_sl(char *buf, int bufsz, void *val, int valsz)
 {
-       _dump_fields(buf, bufsz, val, IB_PC_RCV_DATA_SL_FIRST_F, IB_PC_RCV_DATA_SL_LAST_F);
+       int cnt;
+
+       cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
+                          IB_PC_EXT_XMT_BYTES_F);
+       _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_DATA_SL_FIRST_F,
+                    IB_PC_RCV_DATA_SL_LAST_F);
 }
 
 void xdump(FILE * file, char *msg, void *p, int size)
@@ -731,7 +741,6 @@ void xdump(FILE * file, char *msg, void *p, int size)
                        fputc('\n', file);
                cp += 2;
        }
-       if (i % 16) {
+       if (i % 16)
                fputc('\n', file);
-       }
 }
index 7b69310..129f7e5 100644 (file)
@@ -91,8 +91,8 @@ static const ib_field_t ib_mad_f[] = {
        {192, 64, "MadMkey", mad_dump_hex},
 
        /* word 9 (32-37 bytes) */
-       {BE_OFFS(256, 16), "DrSmpDLID", mad_dump_hex},
-       {BE_OFFS(272, 16), "DrSmpSLID", mad_dump_hex},
+       {BE_OFFS(256, 16), "DrSmpDLID", mad_dump_uint},
+       {BE_OFFS(272, 16), "DrSmpSLID", mad_dump_uint},
 
        /* word 10,11 (36-43 bytes) */
        {288, 64, "SaSMkey", mad_dump_hex},
@@ -198,6 +198,7 @@ static const ib_field_t ib_mad_f[] = {
        {BITSOFFS(80, 8), "DefMcastNotPrimPort", mad_dump_uint},
        {BITSOFFS(88, 5), "LifeTime", mad_dump_uint},
        {BITSOFFS(93, 1), "StateChange", mad_dump_uint},
+       {BITSOFFS(94, 2), "OptSLtoVLMapping", mad_dump_uint},
        {BITSOFFS(96, 16), "LidsPerPort", mad_dump_uint},
        {BITSOFFS(112, 16), "PartEnforceCap", mad_dump_uint},
        {BITSOFFS(128, 1), "InboundPartEnf", mad_dump_uint},
@@ -251,7 +252,7 @@ static const ib_field_t ib_mad_f[] = {
        {BITSOFFS(112, 16), "XmtDiscards", mad_dump_uint},
        {BITSOFFS(128, 8), "XmtConstraintErrors", mad_dump_uint},
        {BITSOFFS(136, 8), "RcvConstraintErrors", mad_dump_uint},
-       {BITSOFFS(144, 8), "CounterSelect2", mad_dump_uint},
+       {BITSOFFS(144, 8), "CounterSelect2", mad_dump_hex},
        {BITSOFFS(152, 4), "LinkIntegrityErrors", mad_dump_uint},
        {BITSOFFS(156, 4), "ExcBufOverrunErrors", mad_dump_uint},
        {BITSOFFS(176, 16), "VL15Dropped", mad_dump_uint},
@@ -301,9 +302,10 @@ static const ib_field_t ib_mad_f[] = {
         */
        {64, 128, "PathRecDGid", mad_dump_array},
        {192, 128, "PathRecSGid", mad_dump_array},
-       {BITSOFFS(320, 16), "PathRecDLid", mad_dump_hex},
-       {BITSOFFS(336, 16), "PathRecSLid", mad_dump_hex},
+       {BITSOFFS(320, 16), "PathRecDLid", mad_dump_uint},
+       {BITSOFFS(336, 16), "PathRecSLid", mad_dump_uint},
        {BITSOFFS(393, 7), "PathRecNumPath", mad_dump_uint},
+       {BITSOFFS(428, 4), "PathRecSL", mad_dump_uint},
 
        /*
         * MC Member rec
@@ -388,7 +390,7 @@ static const ib_field_t ib_mad_f[] = {
        {BITSOFFS(192, 8), "RedirectTC", mad_dump_hex},
        {BITSOFFS(200, 4), "RedirectSL", mad_dump_uint},
        {BITSOFFS(204, 20), "RedirectFL", mad_dump_hex},
-       {BITSOFFS(224, 16), "RedirectLID", mad_dump_hex},
+       {BITSOFFS(224, 16), "RedirectLID", mad_dump_uint},
        {BITSOFFS(240, 16), "RedirectPKey", mad_dump_hex},
        {BITSOFFS(264, 24), "RedirectQP", mad_dump_hex},
        {288, 32, "RedirectQKey", mad_dump_hex},
@@ -396,18 +398,18 @@ static const ib_field_t ib_mad_f[] = {
        {BITSOFFS(448, 8), "TrapTC", mad_dump_hex},
        {BITSOFFS(456, 4), "TrapSL", mad_dump_uint},
        {BITSOFFS(460, 20), "TrapFL", mad_dump_hex},
-       {BITSOFFS(480, 16), "TrapLID", mad_dump_hex},
+       {BITSOFFS(480, 16), "TrapLID", mad_dump_uint},
        {BITSOFFS(496, 16), "TrapPKey", mad_dump_hex},
        {BITSOFFS(512, 8), "TrapHL", mad_dump_uint},
        {BITSOFFS(520, 24), "TrapQP", mad_dump_hex},
        {544, 32, "TrapQKey", mad_dump_hex},
 
-       {32,  32, "XmtDataSL0", mad_dump_uint},
-       {64,  32, "XmtDataSL1", mad_dump_uint},
-       {96,  32, "XmtDataSL2", mad_dump_uint},
+       {32, 32, "XmtDataSL0", mad_dump_uint},
+       {64, 32, "XmtDataSL1", mad_dump_uint},
+       {96, 32, "XmtDataSL2", mad_dump_uint},
        {128, 32, "XmtDataSL3", mad_dump_uint},
        {160, 32, "XmtDataSL4", mad_dump_uint},
-       {196, 32, "XmtDataSL5", mad_dump_uint},
+       {192, 32, "XmtDataSL5", mad_dump_uint},
        {224, 32, "XmtDataSL6", mad_dump_uint},
        {256, 32, "XmtDataSL7", mad_dump_uint},
        {288, 32, "XmtDataSL8", mad_dump_uint},
@@ -420,12 +422,12 @@ static const ib_field_t ib_mad_f[] = {
        {512, 32, "XmtDataSL15", mad_dump_uint},
        {0, 0},                 /* IB_PC_XMT_DATA_SL_LAST_F */
 
-       {32,  32, "RcvDataSL0", mad_dump_uint},
-       {64,  32, "RcvDataSL1", mad_dump_uint},
-       {96,  32, "RcvDataSL2", mad_dump_uint},
+       {32, 32, "RcvDataSL0", mad_dump_uint},
+       {64, 32, "RcvDataSL1", mad_dump_uint},
+       {96, 32, "RcvDataSL2", mad_dump_uint},
        {128, 32, "RcvDataSL3", mad_dump_uint},
        {160, 32, "RcvDataSL4", mad_dump_uint},
-       {196, 32, "RcvDataSL5", mad_dump_uint},
+       {192, 32, "RcvDataSL5", mad_dump_uint},
        {224, 32, "RcvDataSL6", mad_dump_uint},
        {256, 32, "RcvDataSL7", mad_dump_uint},
        {288, 32, "RcvDataSL8", mad_dump_uint},
@@ -548,7 +550,8 @@ uint32_t mad_get_field(void *buf, int base_offs, enum MAD_FIELDS field)
        return _get_field(buf, base_offs, ib_mad_f + field);
 }
 
-void mad_set_field(void *buf, int base_offs, enum MAD_FIELDS field, uint32_t val)
+void mad_set_field(void *buf, int base_offs, enum MAD_FIELDS field,
+                  uint32_t val)
 {
        _set_field(buf, base_offs, ib_mad_f + field, val);
 }
@@ -558,7 +561,8 @@ uint64_t mad_get_field64(void *buf, int base_offs, enum MAD_FIELDS field)
        return _get_field64(buf, base_offs, ib_mad_f + field);
 }
 
-void mad_set_field64(void *buf, int base_offs, enum MAD_FIELDS field, uint64_t val)
+void mad_set_field64(void *buf, int base_offs, enum MAD_FIELDS field,
+                    uint64_t val)
 {
        _set_field64(buf, base_offs, ib_mad_f + field, val);
 }
@@ -686,3 +690,8 @@ char *mad_dump_val(enum MAD_FIELDS field, char *buf, int bufsz, void *val)
                return 0;
        return _mad_dump_val(ib_mad_f + field, buf, bufsz, val);
 }
+
+const char *mad_field_name(enum MAD_FIELDS field)
+{
+       return (ib_mad_f[field].name);
+}
index 5b7ed88..f3d245e 100644 (file)
@@ -46,8 +46,8 @@
 #define DEBUG  if (ibdebug)    IBWARN
 
 uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
-                     unsigned timeout, unsigned id,
-                     const void *srcport)
+                      unsigned timeout, unsigned id,
+                      const struct ibmad_port * srcport)
 {
        ib_rpc_t rpc = { 0 };
        int lid = dest->lid;
@@ -74,16 +74,12 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
        if (!dest->qkey)
                dest->qkey = IB_DEFAULT_QP1_QKEY;
 
-       if (srcport) {
-               return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
-       } else {
-               return madrpc(&rpc, dest, rcvbuf, rcvbuf);
-       }
+       return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
 }
 
 uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
-                             int port, unsigned mask, unsigned timeout,
-                             unsigned id, const void *srcport)
+                              int port, unsigned mask, unsigned timeout,
+                              unsigned id, const struct ibmad_port * srcport)
 {
        ib_rpc_t rpc = { 0 };
        int lid = dest->lid;
@@ -117,9 +113,5 @@ uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
        if (!dest->qkey)
                dest->qkey = IB_DEFAULT_QP1_QKEY;
 
-       if (srcport) {
-               return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
-       } else {
-               return madrpc(&rpc, dest, rcvbuf, rcvbuf);
-       }
+       return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
 }
index cbd8803..00e1b44 100644 (file)
@@ -21,7 +21,6 @@ EXPORTS
        mad_register_client;\r
        mad_register_server;\r
        mad_class_agent;\r
-       mad_agent_class;\r
        mad_send;\r
        mad_receive;\r
        mad_respond;\r
index 7a48a48..dc1d374 100644 (file)
 \r
 #include <windows.h>\r
 \r
+#if WINVER < 0x600\r
+#include "..\..\..\..\etc\user\inet.c"\r
+#endif\r
+\r
 BOOLEAN WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
 {\r
        UNREFERENCED_PARAMETER(hInstance);\r
index 8db9e65..7b49a4d 100644 (file)
@@ -53,11 +53,11 @@ IBMAD_1.3 {
                portid2str;
                str2drpath;
                drpath2str;
-               mad_agent_class;
                mad_class_agent;
                mad_register_client;
                mad_register_server;
-               ib_resolve_guid;
+               mad_register_client_via;
+               mad_register_server_via;
                ib_resolve_portid_str;
                ib_resolve_self;
                ib_resolve_smlid;
@@ -66,6 +66,10 @@ IBMAD_1.3 {
                mad_rpc_close_port;
                mad_rpc;
                mad_rpc_rmpp;
+               mad_rpc_portid;
+               mad_rpc_class_agent;
+               mad_rpc_set_retries;
+               mad_rpc_set_timeout;
                madrpc;
                madrpc_def_timeout;
                madrpc_init;
@@ -82,10 +86,14 @@ IBMAD_1.3 {
                mad_free;
                mad_receive;
                mad_respond;
+               mad_receive_via;
+               mad_respond_via;
                mad_send;
+               mad_send_via;
                smp_query;
                smp_set;
                ib_vendor_call;
+               ib_vendor_call_via;
                smp_query_via;
                smp_set_via;
                ib_path_query_via;
@@ -93,6 +101,7 @@ IBMAD_1.3 {
                ib_resolve_guid_via;
                ib_resolve_portid_str_via;
                ib_resolve_self_via;
-               perf_classportinfo_query_via;
+               mad_field_name;
+               bm_call_via;
        local: *;
 };
index de9e2d3..6f8fea2 100644 (file)
@@ -38,6 +38,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <arpa/inet.h>
 
 #include <infiniband/mad.h>
 
index 4d91ff8..adc6c87 100644 (file)
 #include <infiniband/umad.h>
 #include <infiniband/mad.h>
 
+#include "mad_internal.h"
+
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
 
-#define MAX_CLASS      256
-#define MAX_AGENTS     256
-
-static int class_agent[MAX_CLASS];
-static int agent_class[MAX_AGENTS];
-
-static int register_agent(int agent, int mclass)
-{
-       static int initialized;
-
-       if (!initialized) {
-               initialized++;
-               memset(class_agent, 0xff, sizeof class_agent);
-               memset(agent_class, 0xff, sizeof agent_class);
-       }
-
-       if (mclass < 0 || mclass >= MAX_CLASS ||
-           agent < 0 || agent >= MAX_AGENTS) {
-               DEBUG("bad mgmt class %d or agent %d", mclass, agent);
-               return -1;
-       }
-
-       class_agent[mclass] = agent;
-       agent_class[agent] = mclass;
-
-       return 0;
-}
-
 static int mgmt_class_vers(int mgmt_class)
 {
        if ((mgmt_class >= IB_VENDOR_RANGE1_START_CLASS &&
@@ -94,6 +68,8 @@ static int mgmt_class_vers(int mgmt_class)
                return 1;
        case IB_CC_CLASS:
                return 2;
+       case IB_BOARD_MGMT_CLASS:
+               return 1;
        }
 
        return 0;
@@ -103,14 +79,7 @@ int mad_class_agent(int mgmt)
 {
        if (mgmt < 1 || mgmt > MAX_CLASS)
                return -1;
-       return class_agent[mgmt];
-}
-
-int mad_agent_class(int agent)
-{
-       if (agent < 1 || agent > MAX_AGENTS)
-               return -1;
-       return agent_class[agent];
+       return ibmp->class_agents[mgmt];
 }
 
 int mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version)
@@ -121,37 +90,50 @@ int mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version)
                DEBUG("Unknown class %d mgmt_class", mgmt);
                return -1;
        }
-       if ((agent = umad_register(port_id, mgmt, vers, rmpp_version, 0)) < 0) {
-               DEBUG("Can't register agent for class %d", mgmt);
-               return -1;
-       }
 
-       if (mgmt < 0 || mgmt >= MAX_CLASS || agent >= MAX_AGENTS) {
-               DEBUG("bad mgmt class %d or agent %d", mgmt, agent);
-               return -1;
-       }
+       agent = umad_register(port_id, mgmt, vers, rmpp_version, 0);
+       if (agent < 0)
+               DEBUG("Can't register agent for class %d", mgmt);
 
        return agent;
 }
 
 int mad_register_client(int mgmt, uint8_t rmpp_version)
+{
+       return mad_register_client_via(mgmt, rmpp_version, ibmp);
+}
+
+int mad_register_client_via(int mgmt, uint8_t rmpp_version,
+                           struct ibmad_port *srcport)
 {
        int agent;
 
-       agent = mad_register_port_client(madrpc_portid(), mgmt, rmpp_version);
+       if (!srcport)
+               return -1;
+
+       agent = mad_register_port_client(mad_rpc_portid(srcport), mgmt,
+                                        rmpp_version);
        if (agent < 0)
                return agent;
 
-       return register_agent(agent, mgmt);
+       srcport->class_agents[mgmt] = agent;
+       return 0;
 }
 
-int
-mad_register_server(int mgmt, uint8_t rmpp_version,
-                   long method_mask[], uint32_t class_oui)
+int mad_register_server(int mgmt, uint8_t rmpp_version,
+                       long method_mask[], uint32_t class_oui)
+{
+       return mad_register_server_via(mgmt, rmpp_version, method_mask,
+                                      class_oui, ibmp);
+}
+
+int mad_register_server_via(int mgmt, uint8_t rmpp_version,
+                           long method_mask[], uint32_t class_oui,
+                           struct ibmad_port *srcport)
 {
        long class_method_mask[16 / sizeof(long)];
        uint8_t oui[3];
-       int agent, vers, mad_portid;
+       int agent, vers;
 
        if (method_mask)
                memcpy(class_method_mask, method_mask,
@@ -159,11 +141,12 @@ mad_register_server(int mgmt, uint8_t rmpp_version,
        else
                memset(class_method_mask, 0xff, sizeof(class_method_mask));
 
-       if ((mad_portid = madrpc_portid()) < 0)
+       if (!srcport)
                return -1;
 
-       if (class_agent[mgmt] >= 0) {
-               DEBUG("Class 0x%x already registered", mgmt);
+       if (srcport->class_agents[mgmt] >= 0) {
+               DEBUG("Class 0x%x already registered %d",
+                     mgmt, srcport->class_agents[mgmt]);
                return -1;
        }
        if ((vers = mgmt_class_vers(mgmt)) <= 0) {
@@ -175,19 +158,21 @@ mad_register_server(int mgmt, uint8_t rmpp_version,
                oui[0] = (class_oui >> 16) & 0xff;
                oui[1] = (class_oui >> 8) & 0xff;
                oui[2] = class_oui & 0xff;
-               if ((agent = umad_register_oui(mad_portid, mgmt, rmpp_version,
-                                              oui, class_method_mask)) < 0) {
+               if ((agent =
+                    umad_register_oui(srcport->port_id, mgmt, rmpp_version,
+                                      oui, class_method_mask)) < 0) {
                        DEBUG("Can't register agent for class %d", mgmt);
                        return -1;
                }
-       } else if ((agent = umad_register(mad_portid, mgmt, vers, rmpp_version,
-                                         class_method_mask)) < 0) {
+       } else
+           if ((agent =
+                umad_register(srcport->port_id, mgmt, vers, rmpp_version,
+                              class_method_mask)) < 0) {
                DEBUG("Can't register agent for class %d", mgmt);
                return -1;
        }
 
-       if (register_agent(agent, mgmt) < 0)
-               return -1;
+       srcport->class_agents[mgmt] = agent;
 
        return agent;
 }
index 553949d..691bdc3 100644 (file)
 
 #include <infiniband/umad.h>
 #include <infiniband/mad.h>
+#include "mad_internal.h"
 
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
 
-int ib_resolve_smlid_via(ib_portid_t * sm_id, int timeout, const void *srcport)
+int ib_resolve_smlid_via(ib_portid_t * sm_id, int timeout,
+                        const struct ibmad_port *srcport)
 {
        ib_portid_t self = { 0 };
        uint8_t portinfo[64];
@@ -63,11 +65,12 @@ int ib_resolve_smlid_via(ib_portid_t * sm_id, int timeout, const void *srcport)
 
 int ib_resolve_smlid(ib_portid_t * sm_id, int timeout)
 {
-       return ib_resolve_smlid_via(sm_id, timeout, NULL);
+       return ib_resolve_smlid_via(sm_id, timeout, ibmp);
 }
 
 int ib_resolve_guid_via(ib_portid_t * portid, uint64_t * guid,
-                       ib_portid_t * sm_id, int timeout, const void *srcport)
+                       ib_portid_t * sm_id, int timeout,
+                       const struct ibmad_port *srcport)
 {
        ib_portid_t sm_portid;
        char buf[IB_SA_DATA_SIZE] = { 0 };
@@ -93,7 +96,7 @@ int ib_resolve_guid_via(ib_portid_t * portid, uint64_t * guid,
 
 int ib_resolve_portid_str_via(ib_portid_t * portid, char *addr_str,
                              enum MAD_DEST dest_type, ib_portid_t * sm_id,
-                             const void *srcport)
+                             const struct ibmad_port *srcport)
 {
        uint64_t guid;
        int lid;
@@ -143,14 +146,14 @@ int ib_resolve_portid_str_via(ib_portid_t * portid, char *addr_str,
 }
 
 int ib_resolve_portid_str(ib_portid_t * portid, char *addr_str,
-                       enum MAD_DEST dest_type, ib_portid_t * sm_id)
+                         enum MAD_DEST dest_type, ib_portid_t * sm_id)
 {
        return ib_resolve_portid_str_via(portid, addr_str, dest_type,
-                                        sm_id, NULL);
+                                        sm_id, ibmp);
 }
 
 int ib_resolve_self_via(ib_portid_t * portid, int *portnum, ibmad_gid_t * gid,
-                       const void *srcport)
+                       const struct ibmad_port *srcport)
 {
        ib_portid_t self = { 0 };
        uint8_t portinfo[64];
@@ -178,5 +181,5 @@ int ib_resolve_self_via(ib_portid_t * portid, int *portnum, ibmad_gid_t * gid,
 
 int ib_resolve_self(ib_portid_t * portid, int *portnum, ibmad_gid_t * gid)
 {
-       return ib_resolve_self_via(portid, portnum, gid, NULL);
+       return ib_resolve_self_via(portid, portnum, gid, ibmp);
 }
index e811526..07b623d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004-2006 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2009 HNR Consulting.  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
 #include <infiniband/umad.h>
 #include <infiniband/mad.h>
 
-#define MAX_CLASS 256
-
-struct ibmad_port {
-       int port_id;            /* file descriptor returned by umad_open() */
-       int class_agents[MAX_CLASS];    /* class2agent mapper */
-};
+#include "mad_internal.h"
 
 int ibdebug;
 
-static int mad_portid = -1;
+static struct ibmad_port mad_port;
+struct ibmad_port *ibmp = &mad_port;
+
 static int iberrs;
 
 static int madrpc_retries = MAD_DEF_RETRIES;
-static int def_madrpc_timeout = MAD_DEF_TIMEOUT_MS;
+static int madrpc_timeout = MAD_DEF_TIMEOUT_MS;
 static void *save_mad;
 static int save_mad_len = 256;
 
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
-#define ERRS   if (iberrs || ibdebug)  IBWARN
+#define ERRS(fmt, ...) do {    \
+       if (iberrs || ibdebug)  \
+               IBWARN(fmt, ## __VA_ARGS__); \
+} while (0)
 
 #define MAD_TID(mad)   (*((uint64_t *)((char *)(mad) + 8)))
 
@@ -86,31 +87,50 @@ int madrpc_set_retries(int retries)
 
 int madrpc_set_timeout(int timeout)
 {
-       def_madrpc_timeout = timeout;
+       madrpc_timeout = timeout;
        return 0;
 }
 
+void mad_rpc_set_retries(struct ibmad_port *port, int retries)
+{
+       port->retries = retries;
+}
+
+void mad_rpc_set_timeout(struct ibmad_port *port, int timeout)
+{
+       port->timeout = timeout;
+}
+
 int madrpc_def_timeout(void)
 {
-       return def_madrpc_timeout;
+       return madrpc_timeout;
 }
 
 int madrpc_portid(void)
 {
-       return mad_portid;
+       return ibmp->port_id;
+}
+
+int mad_rpc_portid(struct ibmad_port *srcport)
+{
+       return srcport->port_id;
+}
+
+int mad_rpc_class_agent(struct ibmad_port *port, int class)
+{
+       if (class < 1 || class > MAX_CLASS)
+               return -1;
+       return port->class_agents[class];
 }
 
 static int
 _do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
-          int timeout)
+          int timeout, int max_retries)
 {
        uint32_t trid;          /* only low 32 bits */
        int retries;
        int length, status;
 
-       if (!timeout)
-               timeout = def_madrpc_timeout;
-
        if (ibdebug > 1) {
                IBWARN(">>> sending: len %d pktsz %zu", len, umad_size() + len);
                xdump(stderr, "send buf\n", sndbuf, umad_size() + len);
@@ -125,10 +145,9 @@ _do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
        trid =
            (uint32_t) mad_get_field64(umad_get_mad(sndbuf), 0, IB_MAD_TRID_F);
 
-       for (retries = 0; retries < madrpc_retries; retries++) {
-               if (retries) {
+       for (retries = 0; retries < max_retries; retries++) {
+               if (retries)
                        ERRS("retry %d (timeout %d ms)", retries, timeout);
-               }
 
                length = len;
                if (umad_send(port_id, agentid, sndbuf, length, timeout, 0) < 0) {
@@ -164,12 +183,12 @@ _do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
        return -1;
 }
 
-void *mad_rpc(const void *port_id, ib_rpc_t * rpc, ib_portid_t * dport,
-             void *payload, void *rcvdata)
+void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
+             ib_portid_t * dport, void *payload, void *rcvdata)
 {
-       const struct ibmad_port *p = port_id;
        int status, len;
        uint8_t sndbuf[1024], rcvbuf[1024], *mad;
+       int timeout, retries;
 
        len = 0;
        memset(sndbuf, 0, umad_size() + IB_MAD_SIZE);
@@ -177,9 +196,13 @@ void *mad_rpc(const void *port_id, ib_rpc_t * rpc, ib_portid_t * dport,
        if ((len = mad_build_pkt(sndbuf, rpc, dport, 0, payload)) < 0)
                return 0;
 
-       if ((len = _do_madrpc(p->port_id, sndbuf, rcvbuf,
-                             p->class_agents[rpc->mgtclass],
-                             len, rpc->timeout)) < 0) {
+       timeout = rpc->timeout ? rpc->timeout :
+           port->timeout ? port->timeout : madrpc_timeout;
+       retries = port->retries ? port->retries : madrpc_retries;
+
+       if ((len = _do_madrpc(port->port_id, sndbuf, rcvbuf,
+                             port->class_agents[rpc->mgtclass],
+                             len, timeout, retries)) < 0) {
                IBWARN("_do_madrpc failed; dport (%s)", portid2str(dport));
                return 0;
        }
@@ -203,12 +226,12 @@ void *mad_rpc(const void *port_id, ib_rpc_t * rpc, ib_portid_t * dport,
        return rcvdata;
 }
 
-void *mad_rpc_rmpp(const void *port_id, ib_rpc_t * rpc, ib_portid_t * dport,
-                  ib_rmpp_hdr_t * rmpp, void *data)
+void *mad_rpc_rmpp(const struct ibmad_port *port, ib_rpc_t * rpc,
+                  ib_portid_t * dport, ib_rmpp_hdr_t * rmpp, void *data)
 {
-       const struct ibmad_port *p = port_id;
        int status, len;
        uint8_t sndbuf[1024], rcvbuf[1024], *mad;
+       int timeout, retries;
 
        memset(sndbuf, 0, umad_size() + IB_MAD_SIZE);
 
@@ -217,9 +240,13 @@ void *mad_rpc_rmpp(const void *port_id, ib_rpc_t * rpc, ib_portid_t * dport,
        if ((len = mad_build_pkt(sndbuf, rpc, dport, rmpp, data)) < 0)
                return 0;
 
-       if ((len = _do_madrpc(p->port_id, sndbuf, rcvbuf,
-                             p->class_agents[rpc->mgtclass],
-                             len, rpc->timeout)) < 0) {
+       timeout = rpc->timeout ? rpc->timeout :
+           port->timeout ? port->timeout : madrpc_timeout;
+       retries = port->retries ? port->retries : madrpc_retries;
+
+       if ((len = _do_madrpc(port->port_id, sndbuf, rcvbuf,
+                             port->class_agents[rpc->mgtclass],
+                             len, timeout, retries)) < 0) {
                IBWARN("_do_madrpc failed; dport (%s)", portid2str(dport));
                return 0;
        }
@@ -262,49 +289,45 @@ void *mad_rpc_rmpp(const void *port_id, ib_rpc_t * rpc, ib_portid_t * dport,
 
 void *madrpc(ib_rpc_t * rpc, ib_portid_t * dport, void *payload, void *rcvdata)
 {
-       struct ibmad_port port;
-
-       port.port_id = mad_portid;
-       port.class_agents[rpc->mgtclass] = mad_class_agent(rpc->mgtclass);
-       return mad_rpc(&port, rpc, dport, payload, rcvdata);
+       return mad_rpc(ibmp, rpc, dport, payload, rcvdata);
 }
 
 void *madrpc_rmpp(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
                  void *data)
 {
-       struct ibmad_port port;
-
-       port.port_id = mad_portid;
-       port.class_agents[rpc->mgtclass] = mad_class_agent(rpc->mgtclass);
-       return mad_rpc_rmpp(&port, rpc, dport, rmpp, data);
+       return mad_rpc_rmpp(ibmp, rpc, dport, rmpp, data);
 }
 
 void
 madrpc_init(char *dev_name, int dev_port, int *mgmt_classes, int num_classes)
 {
+       int fd;
+
        if (umad_init() < 0)
                IBPANIC("can't init UMAD library");
 
-       if ((mad_portid = umad_open_port(dev_name, dev_port)) < 0)
+       if ((fd = umad_open_port(dev_name, dev_port)) < 0)
                IBPANIC("can't open UMAD port (%s:%d)", dev_name, dev_port);
 
        if (num_classes >= MAX_CLASS)
                IBPANIC("too many classes %d requested", num_classes);
 
+       ibmp->port_id = fd;
+       memset(ibmp->class_agents, 0xff, sizeof ibmp->class_agents);
        while (num_classes--) {
                uint8_t rmpp_version = 0;
                int mgmt = *mgmt_classes++;
 
                if (mgmt == IB_SA_CLASS)
                        rmpp_version = 1;
-               if (mad_register_client(mgmt, rmpp_version) < 0)
+               if (mad_register_client_via(mgmt, rmpp_version, ibmp) < 0)
                        IBPANIC("client_register for mgmt class %d failed",
                                mgmt);
        }
 }
 
-void *mad_rpc_open_port(char *dev_name, int dev_port,
-                       int *mgmt_classes, int num_classes)
+struct ibmad_port *mad_rpc_open_port(char *dev_name, int dev_port,
+                                    int *mgmt_classes, int num_classes)
 {
        struct ibmad_port *p;
        int port_id;
@@ -336,16 +359,16 @@ void *mad_rpc_open_port(char *dev_name, int dev_port,
                return NULL;
        }
 
+       p->port_id = port_id;
+       memset(p->class_agents, 0xff, sizeof p->class_agents);
        while (num_classes--) {
                uint8_t rmpp_version = 0;
                int mgmt = *mgmt_classes++;
-               int agent;
 
                if (mgmt == IB_SA_CLASS)
                        rmpp_version = 1;
                if (mgmt < 0 || mgmt >= MAX_CLASS ||
-                   (agent = mad_register_port_client(port_id, mgmt,
-                                                     rmpp_version)) < 0) {
+                   mad_register_client_via(mgmt, rmpp_version, p) < 0) {
                        IBWARN("client_register for mgmt %d failed", mgmt);
                        if (!errno)
                                errno = EINVAL;
@@ -353,27 +376,13 @@ void *mad_rpc_open_port(char *dev_name, int dev_port,
                        free(p);
                        return NULL;
                }
-               p->class_agents[mgmt] = agent;
        }
 
-       p->port_id = port_id;
        return p;
 }
 
-void mad_rpc_close_port(void *port_id)
+void mad_rpc_close_port(struct ibmad_port *port)
 {
-       struct ibmad_port *p = port_id;
-
-       umad_close_port(p->port_id);
-       free(p);
-}
-
-uint8_t *sa_call(void *rcvbuf, ib_portid_t * portid, ib_sa_call_t * sa,
-                unsigned timeout)
-{
-       struct ibmad_port port;
-
-       port.port_id = mad_portid;
-       port.class_agents[IB_SA_CLASS] = mad_class_agent(IB_SA_CLASS);
-       return sa_rpc_call(&port, rcvbuf, portid, sa, timeout);
+       umad_close_port(port->port_id);
+       free(port);
 }
index 7403d4f..27e6ee9 100644 (file)
 #include <string.h>
 
 #include <infiniband/mad.h>
+#include "mad_internal.h"
 
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
 
-uint8_t *sa_rpc_call(const void *ibmad_port, void *rcvbuf, ib_portid_t * portid,
-                    ib_sa_call_t * sa, unsigned timeout)
+uint8_t *sa_rpc_call(const struct ibmad_port *ibmad_port, void *rcvbuf,
+                    ib_portid_t * portid, ib_sa_call_t * sa, unsigned timeout)
 {
        ib_rpc_t rpc = { 0 };
        uint8_t *p;
@@ -79,6 +80,12 @@ uint8_t *sa_rpc_call(const void *ibmad_port, void *rcvbuf, ib_portid_t * portid,
        return p;
 }
 
+uint8_t *sa_call(void *rcvbuf, ib_portid_t * portid, ib_sa_call_t * sa,
+                unsigned timeout)
+{
+       return sa_rpc_call(ibmp, rcvbuf, portid, sa, timeout);
+}
+
 /* PathRecord */
 #define IB_PR_COMPMASK_DGID                            (1ull<<2)
 #define IB_PR_COMPMASK_SGID                            (1ull<<3)
@@ -103,18 +110,15 @@ uint8_t *sa_rpc_call(const void *ibmad_port, void *rcvbuf, ib_portid_t * portid,
 #define        IB_PR_COMPMASK_PREFERENCE                       (1ull<<22)
 
 #define IB_PR_DEF_MASK (IB_PR_COMPMASK_DGID |\
-                       IB_PR_COMPMASK_SGID |\
-                       IB_PR_COMPMASK_NUMBPATH)
+                       IB_PR_COMPMASK_SGID)
 
-int ib_path_query_via(const void *srcport, ibmad_gid_t srcgid,
+int ib_path_query_via(const struct ibmad_port *srcport, ibmad_gid_t srcgid,
                      ibmad_gid_t destgid, ib_portid_t * sm_id, void *buf)
 {
-       int npath;
        ib_sa_call_t sa = { 0 };
        uint8_t *p;
        int dlid;
 
-       npath = 1;              /* only MAD_METHOD_GET is supported */
        memset(&sa, 0, sizeof sa);
        sa.method = IB_MAD_METHOD_GET;
        sa.attrid = IB_SA_ATTR_PATHRECORD;
@@ -123,15 +127,10 @@ int ib_path_query_via(const void *srcport, ibmad_gid_t srcgid,
 
        memset(buf, 0, IB_SA_PR_RECSZ);
 
-       mad_encode_field(buf, IB_SA_PR_NPATH_F, &npath);
        mad_encode_field(buf, IB_SA_PR_DGID_F, destgid);
        mad_encode_field(buf, IB_SA_PR_SGID_F, srcgid);
 
-       if (srcport) {
-               p = sa_rpc_call(srcport, buf, sm_id, &sa, 0);
-       } else {
-               p = sa_call(buf, sm_id, &sa, 0);
-       }
+       p = sa_rpc_call(srcport, buf, sm_id, &sa, 0);
        if (!p) {
                IBWARN("sa call path_query failed");
                return -1;
@@ -144,5 +143,5 @@ int ib_path_query_via(const void *srcport, ibmad_gid_t srcgid,
 int ib_path_query(ibmad_gid_t srcgid, ibmad_gid_t destgid, ib_portid_t * sm_id,
                  void *buf)
 {
-       return ib_path_query_via(NULL, srcgid, destgid, sm_id, buf);
+       return ib_path_query_via(ibmp, srcgid, destgid, sm_id, buf);
 }
index c7631bb..ac3a177 100644 (file)
 #include <infiniband/umad.h>
 #include <infiniband/mad.h>
 
+#include "mad_internal.h"
+
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
 
-int
-mad_send(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp, void *data)
+int mad_send(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
+            void *data)
+{
+       return mad_send_via(rpc, dport, rmpp, data, ibmp);
+}
+
+int mad_send_via(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
+                void *data, struct ibmad_port *srcport)
 {
        uint8_t pktbuf[1024];
        void *umad = pktbuf;
@@ -64,7 +72,7 @@ mad_send(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp, void *data)
                      (char *)umad_get_mad(umad) + rpc->dataoffs, rpc->datasz);
        }
 
-       if (umad_send(madrpc_portid(), mad_class_agent(rpc->mgtclass),
+       if (umad_send(srcport->port_id, srcport->class_agents[rpc->mgtclass],
                      umad, IB_MAD_SIZE, rpc->timeout, 0) < 0) {
                IBWARN("send failed; %m");
                return -1;
@@ -74,6 +82,12 @@ mad_send(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp, void *data)
 }
 
 int mad_respond(void *umad, ib_portid_t * portid, uint32_t rstatus)
+{
+       return mad_respond_via(umad, portid, rstatus, ibmp);
+}
+
+int mad_respond_via(void *umad, ib_portid_t * portid, uint32_t rstatus,
+                   struct ibmad_port *srcport)
 {
        uint8_t *mad = umad_get_mad(umad);
        ib_mad_addr_t *mad_addr;
@@ -113,6 +127,7 @@ int mad_respond(void *umad, ib_portid_t * portid, uint32_t rstatus)
                rpc.oui = mad_get_field(mad, 0, IB_VEND2_OUI_F);
 
        rpc.trid = mad_get_field64(mad, 0, IB_MAD_TRID_F);
+       rpc.rstatus = rstatus;
 
        /* cleared by default: timeout, datasz, dataoffs, mkey, mask */
 
@@ -138,8 +153,9 @@ int mad_respond(void *umad, ib_portid_t * portid, uint32_t rstatus)
        if (ibdebug > 1)
                xdump(stderr, "mad respond pkt\n", mad, IB_MAD_SIZE);
 
-       if (umad_send(madrpc_portid(), mad_class_agent(rpc.mgtclass), umad,
-                     IB_MAD_SIZE, rpc.timeout, 0) < 0) {
+       if (umad_send
+           (srcport->port_id, srcport->class_agents[rpc.mgtclass], umad,
+            IB_MAD_SIZE, rpc.timeout, 0) < 0) {
                DEBUG("send failed; %m");
                return -1;
        }
@@ -148,12 +164,17 @@ int mad_respond(void *umad, ib_portid_t * portid, uint32_t rstatus)
 }
 
 void *mad_receive(void *umad, int timeout)
+{
+       return mad_receive_via(umad, timeout, ibmp);
+}
+
+void *mad_receive_via(void *umad, int timeout, struct ibmad_port *srcport)
 {
        void *mad = umad ? umad : umad_alloc(1, umad_size() + IB_MAD_SIZE);
        int agent;
        int length = IB_MAD_SIZE;
 
-       if ((agent = umad_recv(madrpc_portid(), mad, &length, timeout)) < 0) {
+       if ((agent = umad_recv(srcport->port_id, mad, &length, timeout)) < 0) {
                if (!umad)
                        umad_free(mad);
                DEBUG("recv failed: %m");
index fad263c..5f55ec5 100644 (file)
 #include <string.h>
 
 #include <infiniband/mad.h>
+#include "mad_internal.h"
 
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
 
 uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
-                    unsigned mod, unsigned timeout, const void *srcport)
+                    unsigned mod, unsigned timeout,
+                    const struct ibmad_port *srcport)
 {
        ib_rpc_t rpc = { 0 };
 
@@ -67,21 +69,18 @@ uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
        portid->sl = 0;
        portid->qp = 0;
 
-       if (srcport) {
-               return mad_rpc(srcport, &rpc, portid, data, data);
-       } else {
-               return madrpc(&rpc, portid, data, data);
-       }
+       return mad_rpc(srcport, &rpc, portid, data, data);
 }
 
 uint8_t *smp_set(void *data, ib_portid_t * portid, unsigned attrid,
                 unsigned mod, unsigned timeout)
 {
-       return smp_set_via(data, portid, attrid, mod, timeout, NULL);
+       return smp_set_via(data, portid, attrid, mod, timeout, ibmp);
 }
 
 uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
-                      unsigned mod, unsigned timeout, const void *srcport)
+                      unsigned mod, unsigned timeout,
+                      const struct ibmad_port * srcport)
 {
        ib_rpc_t rpc = { 0 };
 
@@ -103,15 +102,11 @@ uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
        portid->sl = 0;
        portid->qp = 0;
 
-       if (srcport) {
-               return mad_rpc(srcport, &rpc, portid, 0, rcvbuf);
-       } else {
-               return madrpc(&rpc, portid, 0, rcvbuf);
-       }
+       return mad_rpc(srcport, &rpc, portid, 0, rcvbuf);
 }
 
 uint8_t *smp_query(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
                   unsigned mod, unsigned timeout)
 {
-       return smp_query_via(rcvbuf, portid, attrid, mod, timeout, NULL);
+       return smp_query_via(rcvbuf, portid, attrid, mod, timeout, ibmp);
 }
index 50a878e..4bf9561 100644 (file)
@@ -40,6 +40,7 @@
 #include <string.h>
 
 #include <infiniband/mad.h>
+#include "mad_internal.h"
 
 #undef DEBUG
 #define DEBUG  if (ibdebug)    IBWARN
@@ -52,6 +53,13 @@ static inline int response_expected(int method)
 
 uint8_t *ib_vendor_call(void *data, ib_portid_t * portid,
                        ib_vendor_call_t * call)
+{
+       return ib_vendor_call_via(data, portid, call, ibmp);
+}
+
+uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
+                           ib_vendor_call_t * call,
+                           struct ibmad_port * srcport)
 {
        ib_rpc_t rpc = { 0 };
        int range1 = 0, resp_expected;
@@ -90,7 +98,7 @@ uint8_t *ib_vendor_call(void *data, ib_portid_t * portid,
                portid->qkey = IB_DEFAULT_QP1_QKEY;
 
        if (resp_expected)
-               return madrpc_rmpp(&rpc, portid, 0, data);      /* FIXME: no RMPP for now */
+               return mad_rpc_rmpp(srcport, &rpc, portid, 0, data);    /* FIXME: no RMPP for now */
 
-       return mad_send(&rpc, portid, 0, data) < 0 ? 0 : data;  /* FIXME: no RMPP for now */
+       return mad_send_via(&rpc, portid, 0, data, srcport) < 0 ? 0 : data;     /* FIXME: no RMPP for now */
 }
diff --git a/ulp/libibnetdisc/README.txt b/ulp/libibnetdisc/README.txt
new file mode 100644 (file)
index 0000000..7c82b7e
--- /dev/null
@@ -0,0 +1,19 @@
+[1-06-09]\r
+\r
+These 'shared' OFED files (shared between Linux and Windows) are mirrored here for the convience\r
+of Windows developers.\r
+\r
+The 'offical' OFED source files are located in the OFED git repository.\r
+\r
+The policy is 'no source file changes' in non-build files (.h & .c) are accepted here.\r
+Any source file changes here will likely be overwritten when refreshed from the OFED git repository.\r
+\r
+The plan here is to have a single Linux and Windows source.\r
+\r
+If you require source file changes, push the changes to the OFED maintainers.\r
+\r
+For continuing policy discussion, please contact sean.hefty@intel.com\r
+\r
+thank you,\r
+\r
+Stan (stan.smith@intel.com)
\ No newline at end of file
diff --git a/ulp/libibnetdisc/dirs b/ulp/libibnetdisc/dirs
new file mode 100644 (file)
index 0000000..b1cbe45
--- /dev/null
@@ -0,0 +1,2 @@
+DIRS =         \\r
+       src
\ No newline at end of file
diff --git a/ulp/libibnetdisc/include/infiniband/ibnetdisc.h b/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
new file mode 100644 (file)
index 0000000..c7d293c
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2008 Lawrence Livermore National Lab.  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 _IBNETDISC_H_
+#define _IBNETDISC_H_
+
+#include <stdio.h>
+#include <infiniband/mad.h>
+#include <iba/ib_types.h>
+
+struct ib_fabric; /* forward declare */
+struct chassis; /* forward declare */
+struct port; /* forward declare */
+
+/** =========================================================================
+ * Node
+ */
+typedef struct node {
+       struct node *next; /* all node list in fabric */
+       struct ib_fabric *fabric; /* the fabric node belongs to */
+
+       ib_portid_t path_portid; /* path from "from_node" */
+       int dist; /* num of hops from "from_node" */
+       int smalid;
+       int smalmc;
+
+       /* quick cache of switchinfo below */
+       int smaenhsp0;
+       /* use libibmad decoder functions for switchinfo */
+       uint8_t switchinfo[IB_SMP_DATA_SIZE];
+
+       /* quick cache of info below */
+       uint64_t guid;
+       int type;
+       int numports;
+       /* use libibmad decoder functions for info */
+       uint8_t info[IB_SMP_DATA_SIZE];
+
+       char nodedesc[IB_SMP_DATA_SIZE];
+
+       struct port **ports; /* in order array of port pointers */
+                               /* the size of this array is info.numports + 1 */
+                               /* items MAY BE NULL!  (ie 0 == switches only) */
+
+       /* chassis info */
+       struct node *next_chassis_node; /* next node in ibnd_chassis_t->nodes */
+       struct chassis *chassis; /* if != NULL the chassis this node belongs to */
+       unsigned char ch_type;
+       unsigned char ch_anafanum;
+       unsigned char ch_slotnum;
+       unsigned char ch_slot;
+} ibnd_node_t;
+
+/** =========================================================================
+ * Port
+ */
+typedef struct port {
+       uint64_t guid;
+       int portnum;
+       int ext_portnum; /* optional if != 0 external port num */
+       ibnd_node_t *node; /* node this port belongs to */
+       struct port *remoteport; /* null if SMA, or does not exist */
+       /* quick cache of info below */
+       uint16_t base_lid;
+       uint8_t lmc;
+       /* use libibmad decoder functions for info */
+       uint8_t info[IB_SMP_DATA_SIZE];
+} ibnd_port_t;
+
+
+/** =========================================================================
+ * Chassis
+ */
+typedef struct chassis {
+       struct chassis *next;
+       uint64_t chassisguid;
+       unsigned char chassisnum;
+
+       /* generic grouping by SystemImageGUID */
+       unsigned char nodecount;
+       ibnd_node_t *nodes;
+
+       /* specific to voltaire type nodes */
+#define SPINES_MAX_NUM 12
+#define LINES_MAX_NUM 36
+       ibnd_node_t *spinenode[SPINES_MAX_NUM + 1];
+       ibnd_node_t *linenode[LINES_MAX_NUM + 1];
+} ibnd_chassis_t;
+
+/** =========================================================================
+ * Fabric
+ * Main fabric object which is returned and represents the data discovered
+ */
+typedef struct ib_fabric {
+       struct ibmad_port *ibmad_port;
+       /* the node the discover was initiated from
+        * "from" parameter in ibnd_discover_fabric
+        * or by default the node you ar running on
+        */
+       ibnd_node_t *from_node;
+       /* NULL term list of all nodes in the fabric */
+       ibnd_node_t *nodes;
+       /* NULL terminated list of all chassis found in the fabric */
+       ibnd_chassis_t *chassis;
+       int maxhops_discovered;
+} ibnd_fabric_t;
+
+/** =========================================================================
+ * Initialization (fabric operations)
+ */
+MAD_EXPORT void ibnd_debug(int i);
+MAD_EXPORT void ibnd_show_progress(int i);
+
+MAD_EXPORT ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port *ibmad_port,
+                                              int timeout_ms,
+                                              ib_portid_t *from, int hops);
+       /**
+        * open: (required) ibmad_port object from libibmad
+        * timeout_ms: (required) gives the timeout for a _SINGLE_ query on
+        *             the fabric.  So if there are multiple nodes not
+        *             responding this may result in a lengthy delay.
+        * from: (optional) specify the node to start scanning from.
+        *       If NULL start from the node we are running on.
+        * hops: (optional) Specify how much of the fabric to traverse.
+        *       negative value == scan entire fabric
+        */
+MAD_EXPORT void ibnd_destroy_fabric(ibnd_fabric_t *fabric);
+
+/** =========================================================================
+ * Node operations
+ */
+MAD_EXPORT ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t *fabric, uint64_t guid);
+MAD_EXPORT ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t *fabric, char *dr_str);
+MAD_EXPORT ibnd_node_t *ibnd_update_node(ibnd_node_t *node);
+
+typedef void (*ibnd_iter_node_func_t)(ibnd_node_t *node, void *user_data);
+MAD_EXPORT void         ibnd_iter_nodes(ibnd_fabric_t *fabric,
+                                       ibnd_iter_node_func_t func,
+                                       void *user_data);
+MAD_EXPORT void         ibnd_iter_nodes_type(ibnd_fabric_t *fabric,
+                                            ibnd_iter_node_func_t func,
+                                            int node_type,
+                                            void *user_data);
+
+/** =========================================================================
+ * Chassis queries
+ */
+MAD_EXPORT uint64_t  ibnd_get_chassis_guid(ibnd_fabric_t *fabric,
+                                          unsigned char chassisnum);
+MAD_EXPORT char     *ibnd_get_chassis_type(ibnd_node_t *node);
+MAD_EXPORT char     *ibnd_get_chassis_slot_str(ibnd_node_t *node,
+                                              char *str, size_t size);
+
+MAD_EXPORT int       ibnd_is_xsigo_guid(uint64_t guid);
+MAD_EXPORT int       ibnd_is_xsigo_tca(uint64_t guid);
+MAD_EXPORT int       ibnd_is_xsigo_hca(uint64_t guid);
+
+#endif /* _IBNETDISC_H_ */
diff --git a/ulp/libibnetdisc/src/Sources b/ulp/libibnetdisc/src/Sources
new file mode 100644 (file)
index 0000000..92ce29f
--- /dev/null
@@ -0,0 +1,45 @@
+!if $(FREEBUILD)\r
+TARGETNAME = libibnetdisc\r
+!else\r
+TARGETNAME = libibnetdiscd\r
+!endif\r
+\r
+TARGETPATH = ..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE = DYNLINK\r
+\r
+DLLDEF = $(OBJ_PATH)\$O\ibnetdisc_exports.def\r
+\r
+DLLENTRY = DllMain\r
+USE_MSVCRT = 1\r
+\r
+SOURCES = \\r
+       ibnetdisc_main.cpp \\r
+       ibnetdisc.c \\r
+       chassis.c\r
+       \r
+INCLUDES =     ..\include\infiniband;\\r
+                       ..\include;\\r
+                       ..\..\libibmad\include;\\r
+                       ..\..\..\tools\infiniband-diags\include;\\r
+                       ..\..\libibverbs\include;\\r
+                       ..\..\libibumad\include;\\r
+                       ..\..\..\inc;\\r
+                       ..\..\..\inc\user;\\r
+                       ..\..\..\inc\user\linux;\r
+\r
+USER_C_FLAGS = $(USER_C_FLAGS)\r
+\r
+TARGETLIBS = \\r
+       $(SDK_LIB_PATH)\kernel32.lib    \\r
+       $(SDK_LIB_PATH)\uuid.lib                \\r
+       $(SDK_LIB_PATH)\ws2_32.lib              \\r
+       $(SDK_LIB_PATH)\advapi32.lib    \\r
+       $(SDK_LIB_PATH)\user32.lib              \\r
+       $(SDK_LIB_PATH)\ole32.lib               \\r
+!if $(FREEBUILD)\r
+       $(TARGETPATH)\*\libibumad.lib   \\r
+       $(TARGETPATH)\*\libibmad.lib   \r
+!else\r
+       $(TARGETPATH)\*\libibumadd.lib  \\r
+       $(TARGETPATH)\*\libibmadd.lib  \r
+!endif\r
diff --git a/ulp/libibnetdisc/src/chassis.c b/ulp/libibnetdisc/src/chassis.c
new file mode 100644 (file)
index 0000000..dbb0abe
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
+ * Copyright (c) 2008 Lawrence Livermore National Lab.  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.
+ *
+ */
+
+/*========================================================*/
+/*               FABRIC SCANNER SPECIFIC DATA             */
+/*========================================================*/
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <infiniband/mad.h>
+
+#include "internal.h"
+#include "chassis.h"
+
+static char *ChassisTypeStr[5] = { "", "ISR9288", "ISR9096", "ISR2012", "ISR2004" };
+static char *ChassisSlotTypeStr[4] = { "", "Line", "Spine", "SRBD" };
+
+char *ibnd_get_chassis_type(ibnd_node_t *node)
+{
+       /* 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 > ISR2004_CT)
+               return (NULL);
+       return ChassisTypeStr[node->ch_type];
+}
+
+char *ibnd_get_chassis_slot_str(ibnd_node_t *node, char *str, size_t size)
+{
+       /* 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_slot == UNRESOLVED_CS
+               || node->ch_slot > SRBD_CS)
+               return (NULL);
+       if (!str)
+               return (NULL);
+       snprintf(str, size, "%s %d Chip %d",
+                       ChassisSlotTypeStr[node->ch_slot],
+                       node->ch_slotnum,
+                       node->ch_anafanum);
+       return (str);
+}
+
+static ibnd_chassis_t *find_chassisnum(struct ibnd_fabric *fabric, unsigned char chassisnum)
+{
+       ibnd_chassis_t *current;
+
+       for (current = fabric->first_chassis; current; current = current->next) {
+               if (current->chassisnum == chassisnum)
+                       return current;
+       }
+
+       return NULL;
+}
+
+static uint64_t topspin_chassisguid(uint64_t guid)
+{
+       /* Byte 3 in system image GUID is chassis type, and */
+       /* Byte 4 is location ID (slot) so just mask off byte 4 */
+       return guid & 0xffffffff00ffffffULL;
+}
+
+int ibnd_is_xsigo_guid(uint64_t guid)
+{
+       if ((guid & 0xffffff0000000000ULL) == 0x0013970000000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+static int is_xsigo_leafone(uint64_t guid)
+{
+       if ((guid & 0xffffffffff000000ULL) == 0x0013970102000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+int ibnd_is_xsigo_hca(uint64_t guid)
+{
+       /* NodeType 2 is HCA */
+       if ((guid & 0xffffffff00000000ULL) == 0x0013970200000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+int ibnd_is_xsigo_tca(uint64_t guid)
+{
+       /* NodeType 3 is TCA */
+       if ((guid & 0xffffffff00000000ULL) == 0x0013970300000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+static int is_xsigo_ca(uint64_t guid)
+{
+       if (ibnd_is_xsigo_hca(guid) || ibnd_is_xsigo_tca(guid))
+               return 1;
+       else
+               return 0;
+}
+
+static int is_xsigo_switch(uint64_t guid)
+{
+       if ((guid & 0xffffffff00000000ULL) == 0x0013970100000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+static uint64_t xsigo_chassisguid(ibnd_node_t *node)
+{
+       uint64_t sysimgguid = mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
+       uint64_t remote_sysimgguid;
+
+       if (!is_xsigo_ca(sysimgguid)) {
+               /* Byte 3 is NodeType and byte 4 is PortType */
+               /* If NodeType is 1 (switch), PortType is masked */
+               if (is_xsigo_switch(sysimgguid))
+                       return sysimgguid & 0xffffffff00ffffffULL;
+               else
+                       return sysimgguid;
+       } else {
+               if (!node->ports || !node->ports[1])
+                       return (0);
+
+               /* Is there a peer port ? */
+               if (!node->ports[1]->remoteport)
+                       return sysimgguid;
+
+               /* If peer port is Leaf 1, use its chassis GUID */
+               remote_sysimgguid = mad_get_field64(
+                                       node->ports[1]->remoteport->node->info,
+                                       0, IB_NODE_SYSTEM_GUID_F);
+               if (is_xsigo_leafone(remote_sysimgguid))
+                       return remote_sysimgguid & 0xffffffff00ffffffULL;
+               else
+                       return sysimgguid;
+       }
+}
+
+static uint64_t get_chassisguid(ibnd_node_t *node)
+{
+       uint32_t vendid = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
+       uint64_t sysimgguid = mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
+
+       if (vendid == TS_VENDOR_ID || vendid == SS_VENDOR_ID)
+               return topspin_chassisguid(sysimgguid);
+       else if (vendid == XS_VENDOR_ID || ibnd_is_xsigo_guid(sysimgguid))
+               return xsigo_chassisguid(node);
+       else
+               return sysimgguid;
+}
+
+static ibnd_chassis_t *find_chassisguid(ibnd_node_t *node)
+{
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(node->fabric);
+       ibnd_chassis_t *current;
+       uint64_t chguid;
+
+       chguid = get_chassisguid(node);
+       for (current = f->first_chassis; current; current = current->next) {
+               if (current->chassisguid == chguid)
+                       return current;
+       }
+
+       return NULL;
+}
+
+uint64_t ibnd_get_chassis_guid(ibnd_fabric_t *fabric, unsigned char chassisnum)
+{
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
+       ibnd_chassis_t *chassis;
+
+       chassis = find_chassisnum(f, chassisnum);
+       if (chassis)
+               return chassis->chassisguid;
+       else
+               return 0;
+}
+
+static int is_router(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_IB_FC_ROUTER ||
+               devid == VTR_DEVID_IB_IP_ROUTER);
+}
+
+static int is_spine_9096(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SFB4 ||
+               devid == VTR_DEVID_SFB4_DDR);
+}
+
+static int is_spine_9288(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SFB12 ||
+               devid == VTR_DEVID_SFB12_DDR);
+}
+
+static int is_spine_2004(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SFB2004);
+}
+
+static int is_spine_2012(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SFB2012);
+}
+
+static int is_spine(struct ibnd_node *n)
+{
+       return (is_spine_9096(n) || is_spine_9288(n) ||
+               is_spine_2004(n) || is_spine_2012(n));
+}
+
+static int is_line_24(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SLB24 ||
+               devid == VTR_DEVID_SLB24_DDR ||
+               devid == VTR_DEVID_SRB2004);
+}
+
+static int is_line_8(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SLB8);
+}
+
+static int is_line_2024(struct ibnd_node *n)
+{
+       uint32_t devid = mad_get_field(n->node.info, 0, IB_NODE_DEVID_F);
+       return (devid == VTR_DEVID_SLB2024);
+}
+
+static int is_line(struct ibnd_node *n)
+{
+       return (is_line_24(n) || is_line_8(n) || is_line_2024(n));
+}
+
+int is_chassis_switch(struct ibnd_node *n)
+{
+    return (is_spine(n) || is_line(n));
+}
+
+/* these structs help find Line (Anafa) slot number while using spine portnum */
+char line_slot_2_sfb4[25]        = { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 };
+char anafa_line_slot_2_sfb4[25]  = { 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2 };
+char line_slot_2_sfb12[25]       = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10, 10, 11, 11, 12, 12 };
+char anafa_line_slot_2_sfb12[25] = { 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 };
+
+/* IPR FCR modules connectivity while using sFB4 port as reference */
+char ipr_slot_2_sfb4_port[25]    = { 0, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1 };
+
+/* these structs help find Spine (Anafa) slot number while using spine portnum */
+char spine12_slot_2_slb[25]      = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+char anafa_spine12_slot_2_slb[25]= { 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+char spine4_slot_2_slb[25]       = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+char anafa_spine4_slot_2_slb[25] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+/*     reference                     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; */
+
+static void get_sfb_slot(struct ibnd_node *node, ibnd_port_t *lineport)
+{
+       ibnd_node_t *n = (ibnd_node_t *)node;
+
+       n->ch_slot = SPINE_CS;
+       if (is_spine_9096(node)) {
+               n->ch_type = ISR9096_CT;
+               n->ch_slotnum = spine4_slot_2_slb[lineport->portnum];
+               n->ch_anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
+       } else if (is_spine_9288(node)) {
+               n->ch_type = ISR9288_CT;
+               n->ch_slotnum = spine12_slot_2_slb[lineport->portnum];
+               n->ch_anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
+       } else if (is_spine_2012(node)) {
+               n->ch_type = ISR2012_CT;
+               n->ch_slotnum = spine12_slot_2_slb[lineport->portnum];
+               n->ch_anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
+       } else if (is_spine_2004(node)) {
+               n->ch_type = ISR2004_CT;
+               n->ch_slotnum = spine4_slot_2_slb[lineport->portnum];
+               n->ch_anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
+       } else {
+               IBPANIC("Unexpected node found: guid 0x%016" PRIx64,
+               node->node.guid);
+       }
+}
+
+static void get_router_slot(struct ibnd_node *node, ibnd_port_t *spineport)
+{
+       ibnd_node_t *n = (ibnd_node_t *)node;
+       uint64_t guessnum = 0;
+
+       node->ch_found = 1;
+
+       n->ch_slot = SRBD_CS;
+       if (is_spine_9096(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR9096_CT;
+               n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
+               n->ch_anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
+       } else if (is_spine_9288(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR9288_CT;
+               n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
+               /* this is a smart guess based on nodeguids order on sFB-12 module */
+               guessnum = spineport->node->guid % 4;
+               /* module 1 <--> remote anafa 3 */
+               /* module 2 <--> remote anafa 2 */
+               /* module 3 <--> remote anafa 1 */
+               n->ch_anafanum = (guessnum == 3 ? 1 : (guessnum == 1 ? 3 : 2));
+       } else if (is_spine_2012(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR2012_CT;
+               n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
+               /* this is a smart guess based on nodeguids order on sFB-12 module */
+               guessnum = spineport->node->guid % 4;
+               // module 1 <--> remote anafa 3
+               // module 2 <--> remote anafa 2
+               // module 3 <--> remote anafa 1
+               n->ch_anafanum = (guessnum == 3? 1 : (guessnum == 1 ? 3 : 2));
+       } else if (is_spine_2004(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR2004_CT;
+               n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
+               n->ch_anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
+       } else {
+               IBPANIC("Unexpected node found: guid 0x%016" PRIx64,
+               spineport->node->guid);
+       }
+}
+
+static void get_slb_slot(ibnd_node_t *n, ibnd_port_t *spineport)
+{
+       n->ch_slot = LINE_CS;
+       if (is_spine_9096(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR9096_CT;
+               n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
+               n->ch_anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
+       } else if (is_spine_9288(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR9288_CT;
+               n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
+               n->ch_anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
+       } else if (is_spine_2012(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR2012_CT;
+               n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
+               n->ch_anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
+       } else if (is_spine_2004(CONV_NODE_INTERNAL(spineport->node))) {
+               n->ch_type = ISR2004_CT;
+               n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
+               n->ch_anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
+       } else {
+               IBPANIC("Unexpected node found: guid 0x%016" PRIx64,
+               spineport->node->guid);
+       }
+}
+
+/* forward declare this */
+static void voltaire_portmap(ibnd_port_t *port);
+/*
+       This function called for every Voltaire node in fabric
+       It could be optimized so, but time overhead is very small
+       and its only diag.util
+*/
+static void fill_voltaire_chassis_record(struct ibnd_node *node)
+{
+       ibnd_node_t *n = (ibnd_node_t *)node;
+       int p = 0;
+       ibnd_port_t *port;
+       struct ibnd_node *remnode = 0;
+
+       if (node->ch_found) /* somehow this node has already been passed */
+               return;
+       node->ch_found = 1;
+
+       /* node is router only in case of using unique lid */
+       /* (which is lid of chassis router port) */
+       /* in such case node->ports is actually a requested port... */
+       if (is_router(node)) {
+               /* find the remote node */
+               for (p = 1; p <= node->node.numports; p++) {
+                       port = node->node.ports[p];
+                       if (port && is_spine(CONV_NODE_INTERNAL(port->remoteport->node)))
+                               get_router_slot(node, port->remoteport);
+               }
+       } else if (is_spine(node)) {
+               for (p = 1; p <= node->node.numports; p++) {
+                       port = node->node.ports[p];
+                       if (!port || !port->remoteport)
+                               continue;
+                       remnode = CONV_NODE_INTERNAL(port->remoteport->node);
+                       if (remnode->node.type != IB_NODE_SWITCH) {
+                               if (!remnode->ch_found)
+                                       get_router_slot(remnode, port);
+                               continue;
+                       }
+                       if (!n->ch_type)
+                               /* we assume here that remoteport belongs to line */
+                               get_sfb_slot(node, port->remoteport);
+
+                               /* we could break here, but need to find if more routers connected */
+               }
+
+       } else if (is_line(node)) {
+               for (p = 1; p <= node->node.numports; p++) {
+                       port = node->node.ports[p];
+                       if (!port || port->portnum > 12 || !port->remoteport)
+                               continue;
+                       /* we assume here that remoteport belongs to spine */
+                       get_slb_slot(n, port->remoteport);
+                       break;
+               }
+       }
+
+       /* for each port of this node, map external ports */
+       for (p = 1; p <= node->node.numports; p++) {
+               port = node->node.ports[p];
+               if (!port)
+                       continue;
+               voltaire_portmap(port);
+       }
+
+       return;
+}
+
+static int get_line_index(ibnd_node_t *node)
+{
+       int retval = 3 * (node->ch_slotnum - 1) + node->ch_anafanum;
+
+       if (retval > LINES_MAX_NUM || retval < 1)
+               IBPANIC("Internal error");
+       return retval;
+}
+
+static int get_spine_index(ibnd_node_t *node)
+{
+       int retval;
+
+       if (is_spine_9288(CONV_NODE_INTERNAL(node)) || is_spine_2012(CONV_NODE_INTERNAL(node)))
+               retval = 3 * (node->ch_slotnum - 1) + node->ch_anafanum;
+       else
+               retval = node->ch_slotnum;
+
+       if (retval > SPINES_MAX_NUM || retval < 1)
+               IBPANIC("Internal error");
+       return retval;
+}
+
+static void insert_line_router(ibnd_node_t *node, ibnd_chassis_t *chassis)
+{
+       int i = get_line_index(node);
+
+       if (chassis->linenode[i])
+               return;         /* already filled slot */
+
+       chassis->linenode[i] = node;
+       node->chassis = chassis;
+}
+
+static void insert_spine(ibnd_node_t *node, ibnd_chassis_t *chassis)
+{
+       int i = get_spine_index(node);
+
+       if (chassis->spinenode[i])
+               return;         /* already filled slot */
+
+       chassis->spinenode[i] = node;
+       node->chassis = chassis;
+}
+
+static void pass_on_lines_catch_spines(ibnd_chassis_t *chassis)
+{
+       ibnd_node_t *node, *remnode;
+       ibnd_port_t *port;
+       int i, p;
+
+       for (i = 1; i <= LINES_MAX_NUM; i++) {
+               node = chassis->linenode[i];
+
+               if (!(node && is_line(CONV_NODE_INTERNAL(node))))
+                       continue;       /* empty slot or router */
+
+               for (p = 1; p <= node->numports; p++) {
+                       port = node->ports[p];
+                       if (!port || port->portnum > 12 || !port->remoteport)
+                               continue;
+
+                       remnode = port->remoteport->node;
+
+                       if (!CONV_NODE_INTERNAL(remnode)->ch_found)
+                               continue;       /* some error - spine not initialized ? FIXME */
+                       insert_spine(remnode, chassis);
+               }
+       }
+}
+
+static void pass_on_spines_catch_lines(ibnd_chassis_t *chassis)
+{
+       ibnd_node_t *node, *remnode;
+       ibnd_port_t *port;
+       int i, p;
+
+       for (i = 1; i <= SPINES_MAX_NUM; i++) {
+               node = chassis->spinenode[i];
+               if (!node)
+                       continue;       /* empty slot */
+               for (p = 1; p <= node->numports; p++) {
+                       port = node->ports[p];
+                       if (!port || !port->remoteport)
+                               continue;
+                       remnode = port->remoteport->node;
+
+                       if (!CONV_NODE_INTERNAL(remnode)->ch_found)
+                               continue;       /* some error - line/router not initialized ? FIXME */
+                       insert_line_router(remnode, chassis);
+               }
+       }
+}
+
+/*
+       Stupid interpolation algorithm...
+       But nothing to do - have to be compliant with VoltaireSM/NMS
+*/
+static void pass_on_spines_interpolate_chguid(ibnd_chassis_t *chassis)
+{
+       ibnd_node_t *node;
+       int i;
+
+       for (i = 1; i <= SPINES_MAX_NUM; i++) {
+               node = chassis->spinenode[i];
+               if (!node)
+                       continue;       /* skip the empty slots */
+
+               /* take first guid minus one to be consistent with SM */
+               chassis->chassisguid = node->guid - 1;
+               break;
+       }
+}
+
+/*
+       This function fills chassis structure with all nodes
+       in that chassis
+       chassis structure = structure of one standalone chassis
+*/
+static void build_chassis(struct ibnd_node *node, ibnd_chassis_t *chassis)
+{
+       int p = 0;
+       struct ibnd_node *remnode = 0;
+       ibnd_port_t *port = 0;
+
+       /* we get here with node = chassis_spine */
+       insert_spine((ibnd_node_t *)node, chassis);
+
+       /* loop: pass on all ports of node */
+       for (p = 1; p <= node->node.numports; p++ ) {
+               port = node->node.ports[p];
+               if (!port || !port->remoteport)
+                       continue;
+               remnode = CONV_NODE_INTERNAL(port->remoteport->node);
+
+               if (!remnode->ch_found)
+                       continue; /* some error - line or router not initialized ? FIXME */
+
+               insert_line_router(&(remnode->node), chassis);
+       }
+
+       pass_on_lines_catch_spines(chassis);
+       /* this pass needed for to catch routers, since routers connected only */
+       /* to spines in slot 1 or 4 and we could miss them first time */
+       pass_on_spines_catch_lines(chassis);
+
+       /* additional 2 passes needed for to overcome a problem of pure "in-chassis" */
+       /* connectivity - extra pass to ensure that all related chips/modules */
+       /* inserted into the chassis */
+       pass_on_lines_catch_spines(chassis);
+       pass_on_spines_catch_lines(chassis);
+       pass_on_spines_interpolate_chguid(chassis);
+}
+
+/*========================================================*/
+/*                INTERNAL TO EXTERNAL PORT MAPPING       */
+/*========================================================*/
+
+/*
+Description : On ISR9288/9096 external ports indexing
+              is not matching the internal ( anafa ) port
+              indexes. Use this MAP to translate the data you get from
+              the OpenIB diagnostics (smpquery, ibroute, ibtracert, etc.)
+
+
+Module : sLB-24
+                anafa 1             anafa 2
+ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
+int port | 22 23 24 18 17 16 | 22 23 24 18 17 16
+ext port | 1  2  3  4  5  6  | 7  8  9  10 11 12
+int port | 19 20 21 15 14 13 | 19 20 21 15 14 13
+------------------------------------------------
+
+Module : sLB-8
+                anafa 1             anafa 2
+ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
+int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
+ext port | 1  2  3  4  5  6  | 7  8  9  10 11 12
+int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
+
+----------->
+                anafa 1             anafa 2
+ext port | -  -  5  -  -  6  | -  -  7  -  -  8
+int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
+ext port | -  -  1  -  -  2  | -  -  3  -  -  4
+int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
+------------------------------------------------
+
+Module : sLB-2024
+
+ext port | 13 14 15 16 17 18 19 20 21 22 23 24
+A1 int port| 13 14 15 16 17 18 19 20 21 22 23 24
+ext port | 1 2 3 4 5 6 7 8 9 10 11 12
+A2 int port| 13 14 15 16 17 18 19 20 21 22 23 24
+---------------------------------------------------
+
+*/
+
+int int2ext_map_slb24[2][25] = {
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 4, 18, 17, 16, 1, 2, 3, 13, 14, 15 },
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 11, 10, 24, 23, 22, 7, 8, 9, 19, 20, 21 }
+                               };
+int int2ext_map_slb8[2][25] = {
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 1, 1, 1, 5, 5, 5 },
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 8, 8, 8, 3, 3, 3, 7, 7, 7 }
+                               };
+int int2ext_map_slb2024[2][25] = {
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 },
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
+                               };
+/*     reference                       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; */
+
+/* map internal ports to external ports if appropriate */
+static void
+voltaire_portmap(ibnd_port_t *port)
+{
+       struct ibnd_node *n = CONV_NODE_INTERNAL(port->node);
+       int portnum = port->portnum;
+       int chipnum = 0;
+       ibnd_node_t *node = port->node;
+
+       if (!n->ch_found || !is_line(CONV_NODE_INTERNAL(node)) || (portnum < 13 || portnum > 24)) {
+               port->ext_portnum = 0;
+               return;
+       }
+
+       if (port->node->ch_anafanum < 1 || port->node->ch_anafanum > 2) {
+               port->ext_portnum = 0;
+               return;
+       }
+
+       chipnum = port->node->ch_anafanum - 1;
+
+       if (is_line_24(CONV_NODE_INTERNAL(node)))
+               port->ext_portnum = int2ext_map_slb24[chipnum][portnum];
+       else if (is_line_2024(CONV_NODE_INTERNAL(node)))
+               port->ext_portnum = int2ext_map_slb2024[chipnum][portnum];
+       else
+               port->ext_portnum = int2ext_map_slb8[chipnum][portnum];
+}
+
+static void add_chassis(struct ibnd_fabric *fabric)
+{
+       if (!(fabric->current_chassis = calloc(1, sizeof(ibnd_chassis_t))))
+               IBPANIC("out of mem");
+
+       if (fabric->first_chassis == NULL) {
+               fabric->first_chassis = fabric->current_chassis;
+               fabric->last_chassis = fabric->current_chassis;
+       } else {
+               fabric->last_chassis->next = fabric->current_chassis;
+               fabric->last_chassis = fabric->current_chassis;
+       }
+}
+
+static void
+add_node_to_chassis(ibnd_chassis_t *chassis, ibnd_node_t *node)
+{
+       node->chassis = chassis;
+       node->next_chassis_node = chassis->nodes;
+       chassis->nodes = node;
+}
+
+/*
+       Main grouping function
+       Algorithm:
+       1. pass on every Voltaire node
+       2. catch spine chip for every Voltaire node
+               2.1 build/interpolate chassis around this chip
+               2.2 go to 1.
+       3. pass on non Voltaire nodes (SystemImageGUID based grouping)
+       4. now group non Voltaire nodes by SystemImageGUID
+       Returns:
+       Pointer to the first chassis in a NULL terminated list of chassis in
+       the fabric specified.
+*/
+ibnd_chassis_t *group_nodes(struct ibnd_fabric *fabric)
+{
+       struct ibnd_node *node;
+       int dist;
+       int chassisnum = 0;
+       ibnd_chassis_t *chassis;
+
+       fabric->first_chassis = NULL;
+       fabric->current_chassis = NULL;
+
+       /* 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 (dist = 0; dist <= fabric->fabric.maxhops_discovered; dist++) {
+               for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
+                       if (mad_get_field(node->node.info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
+                               fill_voltaire_chassis_record(node);
+               }
+       }
+
+       /* separate every Voltaire chassis from each other and build linked list of them */
+       /* algorithm: catch spine and find all surrounding nodes */
+       for (dist = 0; dist <= fabric->fabric.maxhops_discovered; dist++) {
+               for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
+                       if (mad_get_field(node->node.info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
+                               continue;
+                       //if (!node->node.chrecord || node->node.chrecord->chassisnum || !is_spine(node))
+                       if (!node->ch_found
+                                       || (node->node.chassis && node->node.chassis->chassisnum)
+                                       || !is_spine(node))
+                               continue;
+                       add_chassis(fabric);
+                       fabric->current_chassis->chassisnum = ++chassisnum;
+                       build_chassis(node, fabric->current_chassis);
+               }
+       }
+
+       /* now make pass on nodes for chassis which are not Voltaire */
+       /* grouped by common SystemImageGUID */
+       for (dist = 0; dist <= fabric->fabric.maxhops_discovered; dist++) {
+               for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
+                       if (mad_get_field(node->node.info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
+                               continue;
+                       if (mad_get_field64(node->node.info, 0, IB_NODE_SYSTEM_GUID_F)) {
+                               chassis = find_chassisguid((ibnd_node_t *)node);
+                               if (chassis)
+                                       chassis->nodecount++;
+                               else {
+                                       /* Possible new chassis */
+                                       add_chassis(fabric);
+                                       fabric->current_chassis->chassisguid =
+                                                       get_chassisguid((ibnd_node_t *)node);
+                                       fabric->current_chassis->nodecount = 1;
+                               }
+                       }
+               }
+       }
+
+       /* now, make another pass to see which nodes are part of chassis */
+       /* (defined as chassis->nodecount > 1) */
+       for (dist = 0; dist <= MAXHOPS; ) {
+               for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
+                       if (mad_get_field(node->node.info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
+                               continue;
+                       if (mad_get_field64(node->node.info, 0, IB_NODE_SYSTEM_GUID_F)) {
+                               chassis = find_chassisguid((ibnd_node_t *)node);
+                               if (chassis && chassis->nodecount > 1) {
+                                       if (!chassis->chassisnum)
+                                               chassis->chassisnum = ++chassisnum;
+                                       if (!node->ch_found) {
+                                               node->ch_found = 1;
+                                               add_node_to_chassis(chassis, (ibnd_node_t *)node);
+                                       }
+                               }
+                       }
+               }
+               if (dist == fabric->fabric.maxhops_discovered)
+                       dist = MAXHOPS; /* skip to CAs */
+               else
+                       dist++;
+       }
+
+       return (fabric->first_chassis);
+}
diff --git a/ulp/libibnetdisc/src/chassis.h b/ulp/libibnetdisc/src/chassis.h
new file mode 100644 (file)
index 0000000..16dad49
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 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 _CHASSIS_H_
+#define _CHASSIS_H_
+
+#include <infiniband/ibnetdisc.h>
+
+#include "internal.h"
+
+/*========================================================*/
+/*                CHASSIS RECOGNITION SPECIFIC DATA       */
+/*========================================================*/
+
+/* Device IDs */
+#define VTR_DEVID_IB_FC_ROUTER         0x5a00
+#define VTR_DEVID_IB_IP_ROUTER         0x5a01
+#define VTR_DEVID_ISR9600_SPINE                0x5a02
+#define VTR_DEVID_ISR9600_LEAF         0x5a03
+#define VTR_DEVID_HCA1                 0x5a04
+#define VTR_DEVID_HCA2                 0x5a44
+#define VTR_DEVID_HCA3                 0x6278
+#define VTR_DEVID_SW_6IB4              0x5a05
+#define VTR_DEVID_ISR9024              0x5a06
+#define VTR_DEVID_ISR9288              0x5a07
+#define VTR_DEVID_SLB24                        0x5a09
+#define VTR_DEVID_SFB12                        0x5a08
+#define VTR_DEVID_SFB4                 0x5a0b
+#define VTR_DEVID_ISR9024_12           0x5a0c
+#define VTR_DEVID_SLB8                 0x5a0d
+#define VTR_DEVID_RLX_SWITCH_BLADE     0x5a20
+#define VTR_DEVID_ISR9024_DDR          0x5a31
+#define VTR_DEVID_SFB12_DDR            0x5a32
+#define VTR_DEVID_SFB4_DDR             0x5a33
+#define VTR_DEVID_SLB24_DDR            0x5a34
+#define VTR_DEVID_SFB2012              0x5a37
+#define VTR_DEVID_SLB2024              0x5a38
+#define VTR_DEVID_ISR2012              0x5a39
+#define VTR_DEVID_SFB2004              0x5a40
+#define VTR_DEVID_ISR2004              0x5a41
+#define VTR_DEVID_SRB2004              0x5a42
+
+/* Vendor IDs (for chassis based systems) */
+#define VTR_VENDOR_ID                  0x8f1   /* Voltaire */
+#define TS_VENDOR_ID                   0x5ad   /* Cisco */
+#define SS_VENDOR_ID                   0x66a   /* InfiniCon */
+#define XS_VENDOR_ID                   0x1397  /* Xsigo */
+
+enum ibnd_chassis_type { UNRESOLVED_CT, ISR9288_CT, ISR9096_CT, ISR2012_CT, ISR2004_CT };
+enum ibnd_chassis_slot_type { UNRESOLVED_CS, LINE_CS, SPINE_CS, SRBD_CS };
+
+ibnd_chassis_t *group_nodes(struct ibnd_fabric *fabric);
+
+#endif /* _CHASSIS_H_ */
diff --git a/ulp/libibnetdisc/src/ibnetdisc.c b/ulp/libibnetdisc/src/ibnetdisc.c
new file mode 100644 (file)
index 0000000..0ff5134
--- /dev/null
@@ -0,0 +1,701 @@
+/*
+ * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
+ * Copyright (c) 2008 Lawrence Livermore National Laboratory
+ *
+ * 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.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <time.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <infiniband/umad.h>
+#include <infiniband/mad.h>
+
+#include <infiniband/ibnetdisc.h>
+#include <complib/cl_nodenamemap.h>
+
+#include "internal.h"
+#include "chassis.h"
+
+static int timeout_ms = 2000;
+static int show_progress = 0;
+int ibdebug;
+
+void
+decode_port_info(ibnd_port_t *port)
+{
+       port->base_lid = (uint16_t) mad_get_field(port->info, 0, IB_PORT_LID_F);
+       port->lmc = (uint8_t) mad_get_field(port->info, 0, IB_PORT_LMC_F);
+}
+
+static int
+get_port_info(struct ibnd_fabric *fabric, struct ibnd_port *port,
+               int portnum, ib_portid_t *portid)
+{
+       char width[64], speed[64];
+       int iwidth;
+       int ispeed;
+
+       port->port.portnum = portnum;
+       iwidth = mad_get_field(port->port.info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
+       ispeed = mad_get_field(port->port.info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
+
+       if (!smp_query_via(port->port.info, portid, IB_ATTR_PORT_INFO, portnum, timeout_ms,
+                       fabric->fabric.ibmad_port))
+               return -1;
+
+       decode_port_info(&(port->port));
+
+       IBND_DEBUG("portid %s portnum %d: base lid %d state %d physstate %d %s %s\n",
+               portid2str(portid), portnum, port->port.base_lid,
+               mad_get_field(port->port.info, 0, IB_PORT_STATE_F),
+               mad_get_field(port->port.info, 0, IB_PORT_PHYS_STATE_F),
+               mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
+               mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed));
+       return 0;
+}
+
+/*
+ * Returns -1 if error.
+ */
+static int
+query_node_info(struct ibnd_fabric *fabric, struct ibnd_node *node, ib_portid_t *portid)
+{
+       if (!smp_query_via(&(node->node.info), portid, IB_ATTR_NODE_INFO, 0, timeout_ms,
+                       fabric->fabric.ibmad_port))
+               return -1;
+
+       /* decode just a couple of fields for quicker reference. */
+       mad_decode_field(node->node.info, IB_NODE_GUID_F, &(node->node.guid));
+       mad_decode_field(node->node.info, IB_NODE_TYPE_F, &(node->node.type));
+       mad_decode_field(node->node.info, IB_NODE_NPORTS_F,
+                       &(node->node.numports));
+
+       return (0);
+}
+
+/*
+ * Returns 0 if non switch node is found, 1 if switch is found, -1 if error.
+ */
+static int
+query_node(struct ibnd_fabric *fabric, struct ibnd_node *inode,
+               struct ibnd_port *iport, ib_portid_t *portid)
+{
+       ibnd_node_t *node = &(inode->node);
+       ibnd_port_t *port = &(iport->port);
+       void *nd = inode->node.nodedesc;
+
+       if (query_node_info(fabric, inode, portid))
+               return -1;
+
+       port->portnum = mad_get_field(node->info, 0, IB_NODE_LOCAL_PORT_F);
+       port->guid = mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F);
+
+       if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout_ms,
+                       fabric->fabric.ibmad_port))
+               return -1;
+
+       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, 0, timeout_ms,
+                       fabric->fabric.ibmad_port))
+               return -1;
+       decode_port_info(port);
+
+       if (node->type != IB_NODE_SWITCH)
+               return 0;
+
+       node->smalid = port->base_lid;
+       node->smalmc = port->lmc;
+
+       /* after we have the sma information find out the real PortInfo for this port */
+       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, port->portnum, timeout_ms,
+                       fabric->fabric.ibmad_port))
+               return -1;
+       decode_port_info(port);
+
+       port->base_lid = (uint16_t) node->smalid;  /* LID is still defined by port 0 */
+       port->lmc = (uint8_t) node->smalmc;
+
+        if (!smp_query_via(node->switchinfo, portid, IB_ATTR_SWITCH_INFO, 0, timeout_ms,
+                       fabric->fabric.ibmad_port))
+               node->smaenhsp0 = 0;    /* assume base SP0 */
+       else
+               mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0);
+
+       IBND_DEBUG("portid %s: got switch node %" PRIx64 " '%s'\n",
+             portid2str(portid), node->guid, node->nodedesc);
+       return 0;
+}
+
+static int
+add_port_to_dpath(ib_dr_path_t *path, int nextport)
+{
+       if (path->cnt+2 >= sizeof(path->p))
+               return -1;
+       ++path->cnt;
+       path->p[path->cnt] = (uint8_t) nextport;
+       return path->cnt;
+}
+
+static int
+extend_dpath(struct ibnd_fabric *f, ib_dr_path_t *path, int nextport)
+{
+       int rc = add_port_to_dpath(path, nextport);
+       if ((rc != -1) && (path->cnt > f->fabric.maxhops_discovered))
+               f->fabric.maxhops_discovered = path->cnt;
+       return (rc);
+}
+
+static void
+dump_endnode(ib_portid_t *path, char *prompt,
+               struct ibnd_node *node, struct ibnd_port *port)
+{
+       char type[64];
+       if (!show_progress)
+               return;
+
+       mad_dump_node_type(type, 64, &(node->node.type), sizeof(int)),
+
+       printf("%s -> %s %s {%016" PRIx64 "} portnum %d base lid %d-%d\"%s\"\n",
+               portid2str(path), prompt, type,
+               node->node.guid,
+               node->node.type == IB_NODE_SWITCH ? 0 : port->port.portnum,
+               port->port.base_lid, port->port.base_lid + (1 << port->port.lmc) - 1,
+               node->node.nodedesc);
+}
+
+static struct ibnd_node *
+find_existing_node(struct ibnd_fabric *fabric, struct ibnd_node *new)
+{
+       int hash = HASHGUID(new->node.guid) % HTSZ;
+       struct ibnd_node *node;
+
+       for (node = fabric->nodestbl[hash]; node; node = node->htnext)
+               if (node->node.guid == new->node.guid)
+                       return node;
+
+       return NULL;
+}
+
+ibnd_node_t *
+ibnd_find_node_guid(ibnd_fabric_t *fabric, uint64_t guid)
+{
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
+       int hash = HASHGUID(guid) % HTSZ;
+       struct ibnd_node *node;
+
+       for (node = f->nodestbl[hash]; node; node = node->htnext)
+               if (node->node.guid == guid)
+                       return (ibnd_node_t *)node;
+
+       return NULL;
+}
+
+ibnd_node_t *
+ibnd_update_node(ibnd_node_t *node)
+{
+       char portinfo_port0[IB_SMP_DATA_SIZE];
+       void *nd = node->nodedesc;
+       int p = 0;
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(node->fabric);
+       struct ibnd_node *n = CONV_NODE_INTERNAL(node);
+
+       if (query_node_info(f, n, &(n->node.path_portid)))
+               return (NULL);
+
+       if (!smp_query_via(nd, &(n->node.path_portid), IB_ATTR_NODE_DESC, 0, timeout_ms,
+                       f->fabric.ibmad_port))
+               return (NULL);
+
+       /* update all the port info's */
+       for (p = 1; p >= n->node.numports; p++) {
+               get_port_info(f, CONV_PORT_INTERNAL(n->node.ports[p]), p, &(n->node.path_portid));
+       }
+
+       if (n->node.type != IB_NODE_SWITCH)
+               goto done;
+
+       if (!smp_query_via(portinfo_port0, &(n->node.path_portid), IB_ATTR_PORT_INFO, 0, timeout_ms,
+                       f->fabric.ibmad_port))
+               return (NULL);
+
+       n->node.smalid = mad_get_field(portinfo_port0, 0, IB_PORT_LID_F);
+       n->node.smalmc = mad_get_field(portinfo_port0, 0, IB_PORT_LMC_F);
+
+        if (!smp_query_via(node->switchinfo, &(n->node.path_portid), IB_ATTR_SWITCH_INFO, 0, timeout_ms,
+                       f->fabric.ibmad_port))
+                node->smaenhsp0 = 0;   /* assume base SP0 */
+       else
+               mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F, &n->node.smaenhsp0);
+
+done:
+       return (node);
+}
+
+ibnd_node_t *
+ibnd_find_node_dr(ibnd_fabric_t *fabric, char *dr_str)
+{
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
+       int i = 0;
+       ibnd_node_t *rc = f->fabric.from_node;
+       ib_dr_path_t path;
+
+       if (str2drpath(&path, dr_str, 0, 0) == -1) {
+               return (NULL);
+       }
+
+       for (i = 0; i <= path.cnt; i++) {
+               ibnd_port_t *remote_port = NULL;
+               if (path.p[i] == 0)
+                       continue;
+               if (!rc->ports)
+                       return (NULL);
+
+               remote_port = rc->ports[path.p[i]]->remoteport;
+               if (!remote_port)
+                       return (NULL);
+
+               rc = remote_port->node;
+       }
+
+       return (rc);
+}
+
+static void
+add_to_nodeguid_hash(struct ibnd_node *node, struct ibnd_node *hash[])
+{
+       int hash_idx = HASHGUID(node->node.guid) % HTSZ;
+
+       node->htnext = hash[hash_idx];
+       hash[hash_idx] = node;
+}
+
+static void
+add_to_portguid_hash(struct ibnd_port *port, struct ibnd_port *hash[])
+{
+       int hash_idx = HASHGUID(port->port.guid) % HTSZ;
+
+       port->htnext = hash[hash_idx];
+       hash[hash_idx] = port;
+}
+
+static void
+add_to_type_list(struct ibnd_node*node, struct ibnd_fabric *fabric)
+{
+       switch (node->node.type) {
+               case IB_NODE_CA:
+                       node->type_next = fabric->ch_adapters;
+                       fabric->ch_adapters = node;
+                       break;
+               case IB_NODE_SWITCH:
+                       node->type_next = fabric->switches;
+                       fabric->switches = node;
+                       break;
+               case IB_NODE_ROUTER:
+                       node->type_next = fabric->routers;
+                       fabric->routers = node;
+                       break;
+       }
+}
+
+static void
+add_to_nodedist(struct ibnd_node *node, struct ibnd_fabric *fabric)
+{
+       int dist = node->node.dist;
+       if (node->node.type != IB_NODE_SWITCH)
+                       dist = MAXHOPS;         /* special Ca list */
+
+       node->dnext = fabric->nodesdist[dist];
+       fabric->nodesdist[dist] = node;
+}
+
+
+static struct ibnd_node *
+create_node(struct ibnd_fabric *fabric, struct ibnd_node *temp, ib_portid_t *path, int dist)
+{
+       struct ibnd_node *node;
+
+       node = malloc(sizeof(*node));
+       if (!node) {
+               IBPANIC("OOM: node creation failed\n");
+               return NULL;
+       }
+
+       memcpy(node, temp, sizeof(*node));
+       node->node.dist = dist;
+       node->node.path_portid = *path;
+       node->node.fabric = (ibnd_fabric_t *)fabric;
+
+       add_to_nodeguid_hash(node, fabric->nodestbl);
+
+       /* add this to the all nodes list */
+       node->node.next = fabric->fabric.nodes;
+       fabric->fabric.nodes = (ibnd_node_t *)node;
+
+       add_to_type_list(node, fabric);
+       add_to_nodedist(node, fabric);
+
+       return node;
+}
+
+static struct ibnd_port *
+find_existing_port_node(struct ibnd_node *node, struct ibnd_port *port)
+{
+       if (port->port.portnum > node->node.numports || node->node.ports == NULL )
+               return (NULL);
+
+       return (CONV_PORT_INTERNAL(node->node.ports[port->port.portnum]));
+}
+
+static struct ibnd_port *
+add_port_to_node(struct ibnd_fabric *fabric, struct ibnd_node *node, struct ibnd_port *temp)
+{
+       struct ibnd_port *port;
+
+       port = malloc(sizeof(*port));
+       if (!port)
+               return NULL;
+
+       memcpy(port, temp, sizeof(*port));
+       port->port.node = (ibnd_node_t *)node;
+       port->port.ext_portnum = 0;
+
+       if (node->node.ports == NULL) {
+               node->node.ports = calloc(sizeof(*node->node.ports), node->node.numports + 1);
+               if (!node->node.ports) {
+                       IBND_ERROR("Failed to allocate the ports array\n");
+                       return (NULL);
+               }
+       }
+
+       node->node.ports[temp->port.portnum] = (ibnd_port_t *)port;
+
+       add_to_portguid_hash(port, fabric->portstbl);
+       return port;
+}
+
+static void
+link_ports(struct ibnd_node *node, struct ibnd_port *port,
+               struct ibnd_node *remotenode, struct ibnd_port *remoteport)
+{
+       IBND_DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u\n",
+               node->node.guid, node, port, port->port.portnum,
+               remotenode->node.guid, remotenode,
+               remoteport, remoteport->port.portnum);
+       if (port->port.remoteport)
+               port->port.remoteport->remoteport = NULL;
+       if (remoteport->port.remoteport)
+               remoteport->port.remoteport->remoteport = NULL;
+       port->port.remoteport = (ibnd_port_t *)remoteport;
+       remoteport->port.remoteport = (ibnd_port_t *)port;
+}
+
+static int
+get_remote_node(struct ibnd_fabric *fabric, struct ibnd_node *node, struct ibnd_port *port, ib_portid_t *path,
+               int portnum, int dist)
+{
+       struct ibnd_node node_buf;
+       struct ibnd_port port_buf;
+       struct ibnd_node *remotenode, *oldnode;
+       struct ibnd_port *remoteport, *oldport;
+
+       memset(&node_buf, 0, sizeof(node_buf));
+       memset(&port_buf, 0, sizeof(port_buf));
+
+       IBND_DEBUG("handle node %p port %p:%d dist %d\n", node, port, portnum, dist);
+
+       if (mad_get_field(port->port.info, 0, IB_PORT_PHYS_STATE_F)
+                       != IB_PORT_PHYS_STATE_LINKUP)
+               return -1;
+
+       if (extend_dpath(fabric, &path->drpath, portnum) < 0)
+               return -1;
+
+       if (query_node(fabric, &node_buf, &port_buf, path)) {
+               IBWARN("NodeInfo on %s failed, skipping port",
+                       portid2str(path));
+               path->drpath.cnt--;     /* restore path */
+               return -1;
+       }
+
+       oldnode = find_existing_node(fabric, &node_buf);
+       if (oldnode)
+               remotenode = oldnode;
+       else if (!(remotenode = create_node(fabric, &node_buf, path, dist + 1)))
+               IBPANIC("no memory");
+
+       oldport = find_existing_port_node(remotenode, &port_buf);
+       if (oldport) {
+               remoteport = oldport;
+       } else if (!(remoteport = add_port_to_node(fabric, remotenode, &port_buf)))
+               IBPANIC("no memory");
+
+       dump_endnode(path, oldnode ? "known remote" : "new remote",
+                       remotenode, remoteport);
+
+       link_ports(node, port, remotenode, remoteport);
+
+       path->drpath.cnt--;     /* restore path */
+       return 0;
+}
+
+ibnd_fabric_t *
+ibnd_discover_fabric(struct ibmad_port *ibmad_port, int timeout_ms,
+                       ib_portid_t *from, int hops)
+{
+       struct ibnd_fabric *fabric = NULL;
+       ib_portid_t my_portid = {0};
+       struct ibnd_node node_buf;
+       struct ibnd_port port_buf;
+       struct ibnd_node *node;
+       struct ibnd_port *port;
+       int i;
+       int dist = 0;
+       ib_portid_t *path;
+       int max_hops = MAXHOPS-1; /* default find everything */
+
+       if (!ibmad_port) {
+               IBPANIC("ibmad_port must be specified to "
+                       "ibnd_discover_fabric\n");
+               return (NULL);
+       }
+       if (mad_rpc_class_agent(ibmad_port, IB_SMI_CLASS) == -1
+                       ||
+               mad_rpc_class_agent(ibmad_port, IB_SMI_DIRECT_CLASS) == -1) {
+               IBPANIC("ibmad_port must be opened with "
+                       "IB_SMI_CLASS && IB_SMI_DIRECT_CLASS\n");
+               return (NULL);
+       }
+
+       /* if not everything how much? */
+       if (hops >= 0) {
+               max_hops = hops;
+       }
+
+       /* If not specified start from "my" port */
+       if (!from)
+               from = &my_portid;
+
+       fabric = malloc(sizeof(*fabric));
+
+       if (!fabric) {
+               IBPANIC("OOM: failed to malloc ibnd_fabric_t\n");
+               return (NULL);
+       }
+
+       memset(fabric, 0, sizeof(*fabric));
+
+       fabric->fabric.ibmad_port = ibmad_port;
+
+       IBND_DEBUG("from %s\n", portid2str(from));
+
+       memset(&node_buf, 0, sizeof(node_buf));
+       memset(&port_buf, 0, sizeof(port_buf));
+
+       if (query_node(fabric, &node_buf, &port_buf, from)) {
+               IBWARN("can't reach node %s\n", portid2str(from));
+               goto error;
+       }
+
+       node = create_node(fabric, &node_buf, from, 0);
+       if (!node)
+               goto error;
+
+       fabric->fabric.from_node = (ibnd_node_t *)node;
+
+       port = add_port_to_node(fabric, node, &port_buf);
+       if (!port)
+               IBPANIC("out of memory");
+
+       if (node->node.type != IB_NODE_SWITCH &&
+           get_remote_node(fabric, node, port, from,
+                               mad_get_field(node->node.info, 0, IB_NODE_LOCAL_PORT_F),
+                               0) < 0)
+               return ((ibnd_fabric_t *)fabric);
+
+       for (dist = 0; dist <= max_hops; dist++) {
+
+               for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
+
+                       path = &node->node.path_portid;
+
+                       IBND_DEBUG("dist %d node %p\n", dist, node);
+                       dump_endnode(path, "processing", node, port);
+
+                       for (i = 1; i <= node->node.numports; i++) {
+                               if (i == mad_get_field(node->node.info, 0,
+                                                       IB_NODE_LOCAL_PORT_F))
+                                       continue;
+
+                               if (get_port_info(fabric, &port_buf, i, path)) {
+                                       IBWARN("can't reach node %s port %d", portid2str(path), i);
+                                       continue;
+                               }
+
+                               port = find_existing_port_node(node, &port_buf);
+                               if (port)
+                                       continue;
+
+                               port = add_port_to_node(fabric, node, &port_buf);
+                               if (!port)
+                                       IBPANIC("out of memory");
+
+                               /* If switch, set port GUID to node port GUID */
+                               if (node->node.type == IB_NODE_SWITCH) {
+                                       port->port.guid = mad_get_field64(node->node.info,
+                                                               0, IB_NODE_PORT_GUID_F);
+                               }
+
+                               get_remote_node(fabric, node, port, path, i, dist);
+                       }
+               }
+       }
+
+       fabric->fabric.chassis = group_nodes(fabric);
+
+       return ((ibnd_fabric_t *)fabric);
+error:
+       free(fabric);
+       return (NULL);
+}
+
+static void
+destroy_node(struct ibnd_node *node)
+{
+       int p = 0;
+
+       for (p = 0; p <= node->node.numports; p++) {
+               free(node->node.ports[p]);
+       }
+       free(node->node.ports);
+       free(node);
+}
+
+void
+ibnd_destroy_fabric(ibnd_fabric_t *fabric)
+{
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
+       int dist = 0;
+       struct ibnd_node *node = NULL;
+       struct ibnd_node *next = NULL;
+       ibnd_chassis_t *ch, *ch_next;
+
+       ch = f->first_chassis;
+       while (ch) {
+               ch_next = ch->next;
+               free(ch);
+               ch = ch_next;
+       }
+       for (dist = 0; dist <= MAXHOPS; dist++) {
+               node = f->nodesdist[dist];
+               while (node) {
+                       next = node->dnext;
+                       destroy_node(node);
+                       node = next;
+               }
+       }
+       free(f);
+}
+
+void
+ibnd_debug(int i)
+{
+       if (i) {
+               ibdebug++;
+               madrpc_show_errors(1);
+               umad_debug(i);
+       } else {
+               ibdebug = 0;
+               madrpc_show_errors(0);
+               umad_debug(0);
+       }
+}
+
+void
+ibnd_show_progress(int i)
+{
+       show_progress = i;
+}
+
+void
+ibnd_iter_nodes(ibnd_fabric_t *fabric,
+               ibnd_iter_node_func_t func,
+               void *user_data)
+{
+       ibnd_node_t *cur = NULL;
+
+       for (cur = fabric->nodes; cur; cur = cur->next) {
+               func(cur, user_data);
+       }
+}
+
+
+void
+ibnd_iter_nodes_type(ibnd_fabric_t *fabric,
+               ibnd_iter_node_func_t func,
+               int node_type,
+               void *user_data)
+{
+       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
+       struct ibnd_node *list = NULL;
+       struct ibnd_node *cur = NULL;
+
+       switch (node_type) {
+               case IB_NODE_SWITCH:
+                       list = f->switches;
+                       break;
+               case IB_NODE_CA:
+                       list = f->ch_adapters;
+                       break;
+               case IB_NODE_ROUTER:
+                       list = f->routers;
+                       break;
+               default:
+                       IBND_DEBUG("Invalid node_type specified %d\n", node_type);
+                       break;
+       }
+
+       for (cur = list; cur; cur = cur->type_next) {
+               func((ibnd_node_t *)cur, user_data);
+       }
+}
+
diff --git a/ulp/libibnetdisc/src/ibnetdisc_export.def b/ulp/libibnetdisc/src/ibnetdisc_export.def
new file mode 100644 (file)
index 0000000..62e0993
--- /dev/null
@@ -0,0 +1,34 @@
+/*\r
+ * Copyright (c) 2008-2009 Intel Corporation. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+LIBRARY        LIBIBNETDISC.DLL\r
+\r
+EXPORTS\r
+       DllCanUnloadNow         PRIVATE\r
+       DllGetClassObject       PRIVATE\r
diff --git a/ulp/libibnetdisc/src/ibnetdisc_exports.src b/ulp/libibnetdisc/src/ibnetdisc_exports.src
new file mode 100644 (file)
index 0000000..64c4085
--- /dev/null
@@ -0,0 +1,24 @@
+#if DBG\r
+LIBRARY libibnetdiscd.dll\r
+#else\r
+LIBRARY libibnetdisc.dll\r
+#endif\r
+\r
+#ifndef _WIN64\r
+EXPORTS\r
+               ibnd_debug;\r
+               ibnd_show_progress;\r
+               ibnd_discover_fabric;\r
+               ibnd_destroy_fabric;\r
+               ibnd_find_node_guid;\r
+               ibnd_update_node;\r
+               ibnd_find_node_dr;\r
+               ibnd_is_xsigo_guid;\r
+               ibnd_is_xsigo_tca;\r
+               ibnd_is_xsigo_hca;\r
+               ibnd_get_chassis_guid;\r
+               ibnd_get_chassis_type;\r
+               ibnd_get_chassis_slot_str;\r
+               ibnd_iter_nodes;\r
+               ibnd_iter_nodes_type;\r
+#endif\r
diff --git a/ulp/libibnetdisc/src/ibnetdisc_main.cpp b/ulp/libibnetdisc/src/ibnetdisc_main.cpp
new file mode 100644 (file)
index 0000000..7a48a48
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) 2008-2009 Intel Corporation. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+#include <windows.h>\r
+\r
+BOOLEAN WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
+{\r
+       UNREFERENCED_PARAMETER(hInstance);\r
+       UNREFERENCED_PARAMETER(dwReason);\r
+       UNREFERENCED_PARAMETER(lpReserved);\r
+\r
+       return TRUE;\r
+}\r
diff --git a/ulp/libibnetdisc/src/internal.h b/ulp/libibnetdisc/src/internal.h
new file mode 100644 (file)
index 0000000..4e6bb18
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2008 Lawrence Livermore National Laboratory
+ *
+ * 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.
+ *
+ */
+
+/** =========================================================================
+ * Define the internal data structures.
+ */
+
+#ifndef _INTERNAL_H_
+#define _INTERNAL_H_
+
+#include <infiniband/ibnetdisc.h>
+
+#define MAXHOPS                63
+
+#define        IBND_DEBUG(fmt, ...) \
+       if (ibdebug) { \
+               printf("%s:%u; " fmt, __FILE__, __LINE__, ## __VA_ARGS__); \
+       }
+#define        IBND_ERROR(fmt, ...) \
+               fprintf(stderr, "%s:%u; " fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+
+struct ibnd_node {
+       /* This member MUST BE FIRST */
+       ibnd_node_t node;
+
+       /* internal use only */
+       unsigned char ch_found;
+       struct ibnd_node *htnext; /* hash table list */
+       struct ibnd_node *dnext; /* nodesdist next */
+       struct ibnd_node *type_next; /* next based on type */
+};
+#define CONV_NODE_INTERNAL(node) ((struct ibnd_node *)node)
+
+struct ibnd_port {
+       /* This member MUST BE FIRST */
+       ibnd_port_t port;
+
+       /* internal use only */
+       struct ibnd_port *htnext;
+};
+#define CONV_PORT_INTERNAL(port) ((struct ibnd_port *)port)
+
+/* HASH table defines */
+#define HASHGUID(guid) ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103)))
+#define HTSZ 137
+
+struct ibnd_fabric {
+       /* This member MUST BE FIRST */
+       ibnd_fabric_t fabric;
+
+       /* internal use only */
+       struct ibnd_node *nodestbl[HTSZ];
+       struct ibnd_port *portstbl[HTSZ];
+       struct ibnd_node *nodesdist[MAXHOPS+1];
+       ibnd_chassis_t *first_chassis;
+       ibnd_chassis_t *current_chassis;
+       ibnd_chassis_t *last_chassis;
+       struct ibnd_node *switches;
+       struct ibnd_node *ch_adapters;
+       struct ibnd_node *routers;
+};
+#define CONV_FABRIC_INTERNAL(fabric) ((struct ibnd_fabric *)fabric)
+
+#endif /* _INTERNAL_H_ */
diff --git a/ulp/libibnetdisc/src/makefile b/ulp/libibnetdisc/src/makefile
new file mode 100644 (file)
index 0000000..bffacaa
--- /dev/null
@@ -0,0 +1,7 @@
+#\r
+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source\r
+# file to this component.  This file merely indirects to the real make file\r
+# that is shared by all the driver components of the OpenIB Windows project.\r
+#\r
+\r
+!INCLUDE ..\..\..\inc\openib.def\r
index ecbe67e..8d14fc1 100644 (file)
@@ -106,7 +106,7 @@ typedef struct umad_port
        unsigned                state;\r
        unsigned                phys_state;\r
        unsigned                rate;\r
-       uint64_t                capmask;\r
+       uint32_t                capmask;\r
        uint64_t                gid_prefix;\r
        uint64_t                port_guid;\r
        unsigned                pkeys_size;\r