#include <infiniband/mad.h>
-extern int ibdebug;
extern int ibverbose;
extern char *ibd_ca;
extern int ibd_ca_port;
DIRS = \\r
ibaddr \\r
+ iblinkinfo \\r
ibnetdiscover \\r
ibping \\r
ibportstate \\r
#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)
{
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);
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);
}
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
#include <ibdiag_common.h>
#include <ibdiag_version.h>
-int ibdebug;
int ibverbose;
char *ibd_ca;
int ibd_ca_port;
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;
--- /dev/null
+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
--- /dev/null
+/*\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
--- /dev/null
+#\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
/*
* 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:
}
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");
}
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),
}
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;
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);
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);
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");
}
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;
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;
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" },
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);
}
\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
!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
#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];
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;
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);
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;
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);
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);
report(0);
+ mad_rpc_close_port(srcport);
+
exit(-1);
}
#include "ibdiag_common.h"
+struct ibmad_port *srcport;
+
/*******************************************/
static int
{
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);
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) {
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)
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" */
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;
}
}
+ mad_rpc_close_port(srcport);
exit(0);
}
#include "ibdiag_common.h"
+struct ibmad_port *srcport;
+
static int brief, dump_all, multicast;
/*******************************************/
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);
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;
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";
}
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);
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;
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)
if (err)
IBERROR("dump tables: %s", err);
+ mad_rpc_close_port(srcport);
exit(0);
}
/*
* 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;
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));
trap_rpc.dataoffs = IB_SMP_DATA_OFFS;
memset(¬ice, 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(¬ice, &selfportid);
- return (mad_send(&trap_rpc, &sm_port, NULL, ¬ice));
+ return mad_send_via(&trap_rpc, &sm_port, NULL, ¬ice, 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)
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,
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;
}
#define MAX_CPUS 8
+struct ibmad_port *srcport;
+
enum ib_sysstat_attr_t {
IB_PING_ATTR = 0x10,
IB_HOSTINFO_ATTR = 0x11,
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;
}
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)));
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)
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();
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);
}
#include "ibdiag_common.h"
+struct ibmad_port *srcport;
+
#define MAXHOPS 63
static char *node_type_str[] = {
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++) {
*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);
{
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);
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",
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);
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;
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++) {
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) {
dump_mcpath(endnode, dumplevel);
close_node_name_map(node_name_map);
+
+ mad_rpc_close_port(srcport);
+
exit(0);
}
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);
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;
}
#if 1
- port = madrpc_portid();
+ port = mad_rpc_portid(srcport);
#else
ret = umad_init();
#include "ibdiag_common.h"
+struct ibmad_port *srcport;
+
struct perf_count {
uint32_t portselect;
uint32_t counterselect;
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 */
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();
{
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");
}
}
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");
}
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");
}
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 */
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);
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)
dump_perfcounters(extended, ibd_timeout, cap_mask, &portid, port, 0);
if (!reset)
- exit(0);
+ goto done;
do_reset:
else
reset_counters(extended, ibd_timeout, mask, &portid, port);
+done:
+ mad_rpc_close_port(srcport);
exit(0);
}
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));
}
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.");
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;
static uint8_t sminfo[1024];
+struct ibmad_port *srcport;
+
int strdata, xdata=1, bindata;
enum {
SMINFO_NOTACT,
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]);
}
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);
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);
}
#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 {
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);
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);
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);
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);
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);
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
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;
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);
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);
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);
/* 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) {
}
}
- 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);
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;
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);
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);
}
/* 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;
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;
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;
}
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
};
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 */
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;
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++)
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++)
ntohl(cs->record[i].data));
}
+ mad_rpc_close_port(srcport);
exit(0);
}
libibverbs \\r
libibumad \\r
libibmad \\r
+ libibnetdisc\\r
librdmacm \\r
nd\r
#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,
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,
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)
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,
IB_SA_PR_DLID_F,
IB_SA_PR_SLID_F,
IB_SA_PR_NPATH_F,
+ IB_SA_PR_SL_F,
/*
* MC Member rec
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
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,
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)
{
}
/* 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,
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
#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
\r
#define MAD_EXPORT __declspec(dllexport)\r
\r
-#define __attribute__(X)\r
+#define DEPRECATED\r
\r
#if !defined( __cplusplus )\r
#define inline __inline\r
#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
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
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
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)
fputc('\n', file);
cp += 2;
}
- if (i % 16) {
+ if (i % 16)
fputc('\n', file);
- }
}
{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},
{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},
{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},
*/
{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
{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},
{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},
{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},
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);
}
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);
}
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);
+}
#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;
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;
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);
}
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
\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
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;
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;
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;
ib_resolve_guid_via;
ib_resolve_portid_str_via;
ib_resolve_self_via;
- perf_classportinfo_query_via;
+ mad_field_name;
+ bm_call_via;
local: *;
};
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <arpa/inet.h>
#include <infiniband/mad.h>
#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 &&
return 1;
case IB_CC_CLASS:
return 2;
+ case IB_BOARD_MGMT_CLASS:
+ return 1;
}
return 0;
{
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)
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,
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) {
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;
}
#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];
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 };
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;
}
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];
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);
}
/*
* 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)))
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);
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) {
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);
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;
}
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);
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;
}
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;
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;
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);
}
#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;
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)
#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;
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;
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);
}
#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;
(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;
}
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;
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 */
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;
}
}
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");
#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 };
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 };
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);
}
#include <string.h>
#include <infiniband/mad.h>
+#include "mad_internal.h"
#undef DEBUG
#define DEBUG if (ibdebug) IBWARN
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;
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 */
}
--- /dev/null
+[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
--- /dev/null
+DIRS = \\r
+ src
\ No newline at end of file
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+!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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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);
+ }
+}
+
--- /dev/null
+/*\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
--- /dev/null
+#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
--- /dev/null
+/*\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
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+#\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
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