[ofw] [PATCH] Update libibmad and infiniband-diags
Uri Habusha
urih at mellanox.co.il
Thu Aug 11 11:05:43 PDT 2011
Hi Sean,
Did you check-in this patch to OFW svn. I look for it today in following svn: svn://openib.tc.cornell.edu/gen1/trunk and didn't find it.
Following is log output
b:\users\urih\projects\ofed1\trunk>svn log -l 10 -q
------------------------------------------------------------------------
r3085 | xalex | 2011-01-30 17:20:50 +0200 (Sun, 30 Jan 2011)
------------------------------------------------------------------------
r3084 | xalex | 2011-01-30 17:17:28 +0200 (Sun, 30 Jan 2011)
------------------------------------------------------------------------
r3083 | xalex | 2011-01-27 11:47:10 +0200 (Thu, 27 Jan 2011)
------------------------------------------------------------------------
r3082 | xalex | 2011-01-26 10:27:44 +0200 (Wed, 26 Jan 2011)
------------------------------------------------------------------------
r3081 | xalex | 2011-01-26 10:26:04 +0200 (Wed, 26 Jan 2011)
------------------------------------------------------------------------
r3080 | ftillier | 2011-01-21 23:38:29 +0200 (Fri, 21 Jan 2011)
------------------------------------------------------------------------
r3079 | ftillier | 2011-01-21 23:33:56 +0200 (Fri, 21 Jan 2011)
------------------------------------------------------------------------
r3078 | ftillier | 2011-01-21 23:01:07 +0200 (Fri, 21 Jan 2011)
------------------------------------------------------------------------
r3077 | stansmith | 2011-01-21 18:55:40 +0200 (Fri, 21 Jan 2011)
------------------------------------------------------------------------
-----Original Message-----
From: ofw-bounces at lists.openfabrics.org [mailto:ofw-bounces at lists.openfabrics.org] On Behalf Of Hefty, Sean
Sent: Monday, August 08, 2011 10:35 PM
To: ofw at lists.openfabrics.org
Subject: [ofw] [PATCH] Update libibmad and infiniband-diags
Update libibmad to commit 818fcb2260ea0308e09ad434acb76691d25ff95d and
ib-diags to commit a817e38e5275dcf75404af19b8592c03f4822118
This results in all diags needing a dependency on ibal for ib_get_err_str() and
adds one new executable, ibcacheedit. For a separate breakout of changes, refer
to the git trees.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
trunk/inc/iba/ib_types.h | 2
.../tools/infiniband-diags/include/ibdiag_common.h | 55 ++
.../infiniband-diags/include/windows/config.h | 3
trunk/tools/infiniband-diags/src/dirs | 1
trunk/tools/infiniband-diags/src/ibaddr.c | 5
trunk/tools/infiniband-diags/src/ibaddr/SOURCES | 1
.../tools/infiniband-diags/src/ibcacheedit/SOURCES | 28 +
.../src/ibcacheedit/ibcacheedit.rc | 47 ++
.../infiniband-diags/src/ibcacheedit/makefile | 7
trunk/tools/infiniband-diags/src/ibdiag_common.c | 193 ++++++++
trunk/tools/infiniband-diags/src/iblinkinfo.c | 416 +++++++++++++++--
.../tools/infiniband-diags/src/iblinkinfo/SOURCES | 1
trunk/tools/infiniband-diags/src/ibnetdiscover.c | 69 +++
.../infiniband-diags/src/ibnetdiscover/SOURCES | 1
trunk/tools/infiniband-diags/src/ibping.c | 2
trunk/tools/infiniband-diags/src/ibping/SOURCES | 1
trunk/tools/infiniband-diags/src/ibportstate.c | 6
.../tools/infiniband-diags/src/ibportstate/SOURCES | 1
trunk/tools/infiniband-diags/src/ibqueryerrors.c | 491 ++++++++++++++++----
.../infiniband-diags/src/ibqueryerrors/SOURCES | 1
trunk/tools/infiniband-diags/src/ibroute.c | 10
trunk/tools/infiniband-diags/src/ibroute/SOURCES | 1
trunk/tools/infiniband-diags/src/ibsendtrap.c | 5
.../tools/infiniband-diags/src/ibsendtrap/SOURCES | 1
trunk/tools/infiniband-diags/src/ibstat.c | 17 -
trunk/tools/infiniband-diags/src/ibstat/SOURCES | 1
trunk/tools/infiniband-diags/src/ibsysstat/SOURCES | 1
trunk/tools/infiniband-diags/src/ibtracert.c | 14 -
trunk/tools/infiniband-diags/src/ibtracert/SOURCES | 1
.../infiniband-diags/src/mcm_rereg_test/SOURCES | 1
trunk/tools/infiniband-diags/src/perfquery.c | 301 +++++++++++-
trunk/tools/infiniband-diags/src/perfquery/SOURCES | 1
trunk/tools/infiniband-diags/src/saquery.c | 405 ++++++----------
trunk/tools/infiniband-diags/src/sminfo.c | 3
trunk/tools/infiniband-diags/src/sminfo/SOURCES | 1
trunk/tools/infiniband-diags/src/smpdump/SOURCES | 1
trunk/tools/infiniband-diags/src/smpquery.c | 48 +-
trunk/tools/infiniband-diags/src/smpquery/SOURCES | 1
trunk/tools/infiniband-diags/src/vendstat.c | 1
trunk/tools/infiniband-diags/src/vendstat/SOURCES | 1
trunk/ulp/libibmad/include/infiniband/mad.h | 355 ++++++++++++++
trunk/ulp/libibmad/include/infiniband/mad_osd.h | 1
trunk/ulp/libibmad/src/dump.c | 207 ++++++++
trunk/ulp/libibmad/src/fields.c | 364 +++++++++++++--
trunk/ulp/libibmad/src/gs.c | 23 +
trunk/ulp/libibmad/src/ibmad_exports.src | 167 +++++--
trunk/ulp/libibmad/src/libibmad.map | 19 +
trunk/ulp/libibmad/src/mad.c | 19 -
trunk/ulp/libibmad/src/register.c | 2
trunk/ulp/libibmad/src/rpc.c | 34 +
trunk/ulp/libibmad/src/serv.c | 2
trunk/ulp/libibmad/src/smp.c | 41 +-
trunk/ulp/libibmad/src/vendor.c | 17 -
.../libibnetdisc/include/infiniband/ibnetdisc.h | 22 +
.../include/infiniband/ibnetdisc_osd.h | 41 ++
trunk/ulp/libibnetdisc/src/chassis.c | 275 ++++++++++-
trunk/ulp/libibnetdisc/src/chassis.h | 6
trunk/ulp/libibnetdisc/src/ibnetdisc.c | 213 ++++++---
trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c | 19 +
trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src | 5
trunk/ulp/libibnetdisc/src/internal.h | 1
trunk/ulp/opensm/user/opensm/osm_helper.c | 4
62 files changed, 3282 insertions(+), 701 deletions(-)
create mode 100644 trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES
create mode 100644 trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc
create mode 100644 trunk/tools/infiniband-diags/src/ibcacheedit/makefile
create mode 100644 trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h
diff --git a/trunk/inc/iba/ib_types.h b/trunk/inc/iba/ib_types.h
index 665bdad..21781d5 100644
--- a/trunk/inc/iba/ib_types.h
+++ b/trunk/inc/iba/ib_types.h
@@ -6228,7 +6228,7 @@ typedef struct _ib_portinfo_record
{
ib_net16_t lid;
uint8_t port_num;
- uint8_t resv;
+ uint8_t options;
ib_port_info_t port_info;
} PACK_SUFFIX ib_portinfo_record_t;
diff --git a/trunk/tools/infiniband-diags/include/ibdiag_common.h b/trunk/tools/infiniband-diags/include/ibdiag_common.h
index 9b2add7..57bde20 100644
--- a/trunk/tools/infiniband-diags/include/ibdiag_common.h
+++ b/trunk/tools/infiniband-diags/include/ibdiag_common.h
@@ -1,6 +1,10 @@
/*
* Copyright (c) 2006-2007 The Regents of the University of California.
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ * Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Lawrence Livermore National Security. 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
@@ -35,6 +39,7 @@
#ifndef _IBDIAG_COMMON_H_
#define _IBDIAG_COMMON_H_
+#include <infiniband/iba/ib_types.h>
#include <infiniband/mad.h>
extern int ibverbose;
@@ -57,6 +62,11 @@ extern int ibd_timeout;
} while (0)
#define IBERROR(fmt, ...) iberror(__FUNCTION__, fmt, ## __VA_ARGS__)
+/* not all versions of ib_types.h will have this define */
+#ifndef IB_PM_PC_XMIT_WAIT_SUP
+#define IB_PM_PC_XMIT_WAIT_SUP (CL_HTON16(((uint16_t)1)<<12))
+#endif
+
struct ibdiag_opt {
const char *name;
char letter;
@@ -75,4 +85,49 @@ extern int ibdiag_process_opts(int argc, char *const argv[], void *context,
extern void ibdiag_show_usage();
extern void iberror(const char *fn, char *msg, ...);
+/* define an SA query structure to be common
+ * This is by no means optimal but it moves the saquery functionality out of
+ * the saquery tool and provides it to other utilities.
+ */
+struct bind_handle {
+ int fd, agent;
+ ib_portid_t dport;
+ struct ibmad_port *srcport;
+};
+typedef struct bind_handle * bind_handle_t;
+bind_handle_t sa_get_bind_handle(void);
+void sa_free_bind_handle(bind_handle_t h);
+
+struct sa_query_result {
+ uint32_t status;
+ unsigned result_cnt;
+ void *p_result_madw;
+};
+int sa_query(struct bind_handle *h, uint8_t method,
+ uint16_t attr, uint32_t mod, uint64_t comp_mask, uint64_t sm_key,
+ void *data, struct sa_query_result *result);
+void sa_free_result_mad(struct sa_query_result *result);
+void *sa_get_query_rec(void *mad, unsigned i);
+void sa_report_err(int status);
+
+#define cl_hton8(x) (x)
+#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
+ if ((int##size##_t) val != (int##size##_t) comp_with) { \
+ target = cl_hton##size((uint##size##_t) val); \
+ comp_mask |= IB_##name##_COMPMASK_##mask; \
+ }
+
+#define CHECK_AND_SET_GID(val, target, name, mask) \
+ if (valid_gid(&(val))) { \
+ memcpy(&(target), &(val), sizeof(val)); \
+ comp_mask |= IB_##name##_COMPMASK_##mask; \
+ }
+
+#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
+ if (val) { \
+ target = val; \
+ comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
+ comp_mask |= IB_##name##_COMPMASK_##mask; \
+ }
+
#endif /* _IBDIAG_COMMON_H_ */
diff --git a/trunk/tools/infiniband-diags/include/windows/config.h b/trunk/tools/infiniband-diags/include/windows/config.h
index c6365bf..3a46b6f 100644
--- a/trunk/tools/infiniband-diags/include/windows/config.h
+++ b/trunk/tools/infiniband-diags/include/windows/config.h
@@ -37,4 +37,7 @@
#include <_errno.h>
#include <_string.h>
+#define IBDIAG_CONFIG_PATH "."
+#define UINT16_MAX 0xffffffff
+
#endif /* _CONFIG_H_ */
diff --git a/trunk/tools/infiniband-diags/src/dirs b/trunk/tools/infiniband-diags/src/dirs
index 822f325..c36a414 100644
--- a/trunk/tools/infiniband-diags/src/dirs
+++ b/trunk/tools/infiniband-diags/src/dirs
@@ -1,5 +1,6 @@
DIRS = \
ibaddr \
+ ibcacheedit \
iblinkinfo \
ibnetdiscover \
ibping \
diff --git a/trunk/tools/infiniband-diags/src/ibaddr.c b/trunk/tools/infiniband-diags/src/ibaddr.c
index 6e17458..397ef77 100644
--- a/trunk/tools/infiniband-diags/src/ibaddr.c
+++ b/trunk/tools/infiniband-diags/src/ibaddr.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -52,8 +53,8 @@ static int ib_resolve_addr(ib_portid_t * portid, int portnum, int show_lid,
int show_gid)
{
char gid_str[INET6_ADDRSTRLEN];
- uint8_t portinfo[64];
- uint8_t nodeinfo[64];
+ uint8_t portinfo[IB_SMP_DATA_SIZE] = { 0 };
+ uint8_t nodeinfo[IB_SMP_DATA_SIZE] = { 0 };
uint64_t guid, prefix;
ibmad_gid_t gid;
int lmc;
diff --git a/trunk/tools/infiniband-diags/src/ibaddr/SOURCES b/trunk/tools/infiniband-diags/src/ibaddr/SOURCES
index f7462a5..91a22fb 100644
--- a/trunk/tools/infiniband-diags/src/ibaddr/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibaddr/SOURCES
@@ -21,6 +21,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H /DUSE_INET
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib \
$(TARGETPATH)\*\libibnetdisc.lib
diff --git a/trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES b/trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES
new file mode 100644
index 0000000..c00ddb9
--- /dev/null
+++ b/trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES
@@ -0,0 +1,28 @@
+TARGETNAME = ibcacheedit
+TARGETPATH = ..\..\..\..\bin\user\obj$(BUILD_ALT_DIR)
+TARGETTYPE = PROGRAM
+
+UMTYPE = console
+UMENTRY = main
+
+USE_MSVCRT = 1
+
+SOURCES = ..\ibcacheedit.c ..\ibdiag_common.c ..\ibdiag_windows.c ibcacheedit.rc
+
+INCLUDES = ..\..\include;..\..\include\windows;\
+ ..\..\..\..\ulp\libibnetdisc\include;\
+ ..\..\..\..\ulp\libibmad\include;\
+ ..\..\..\..\ulp\libibumad\include;\
+ ..\..\..\..\inc;..\..\..\..\inc\user;\
+ ..\..\..\..\inc\user\linux;
+
+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
+
+TARGETLIBS = \
+ $(SDK_LIB_PATH)\kernel32.lib \
+ $(TARGETPATH)\*\ibal.lib \
+ $(TARGETPATH)\*\libibmad.lib \
+ $(TARGETPATH)\*\libibumad.lib \
+ $(TARGETPATH)\*\libibnetdisc.lib
+
+MSC_WARNING_LEVEL = /W3 /WX /wd4007
diff --git a/trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc b/trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc
new file mode 100644
index 0000000..c358cda
--- /dev/null
+++ b/trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under 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.
+ *
+ * $Id$
+ */
+
+
+#include <oib_ver.h>
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+
+#ifdef DBG
+#define VER_FILEDESCRIPTION_STR "Edit InfiniBand Diagnostic Cache Information (Debug)"
+#else
+#define VER_FILEDESCRIPTION_STR "Edit InfiniBand Diagnostic Cache Information"
+#endif
+
+#define VER_INTERNALNAME_STR "ibcacheedit.exe"
+#define VER_ORIGINALFILENAME_STR "ibcacheedit.exe"
+
+#include <common.ver>
diff --git a/trunk/tools/infiniband-diags/src/ibcacheedit/makefile b/trunk/tools/infiniband-diags/src/ibcacheedit/makefile
new file mode 100644
index 0000000..a0c0627
--- /dev/null
+++ b/trunk/tools/infiniband-diags/src/ibcacheedit/makefile
@@ -0,0 +1,7 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the driver components of the OpenIB Windows project.
+#
+
+!INCLUDE ..\..\..\..\inc\openib.def
diff --git a/trunk/tools/infiniband-diags/src/ibdiag_common.c b/trunk/tools/infiniband-diags/src/ibdiag_common.c
index 99861f1..e7e1590 100644
--- a/trunk/tools/infiniband-diags/src/ibdiag_common.c
+++ b/trunk/tools/infiniband-diags/src/ibdiag_common.c
@@ -1,6 +1,10 @@
/*
* Copyright (c) 2006-2007 The Regents of the University of California.
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ * Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Lawrence Livermore National Security. 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
@@ -47,6 +51,7 @@
#include <ctype.h>
#include <config.h>
#include <getopt.h>
+#include <limits.h>
#include <infiniband/umad.h>
#include <infiniband/mad.h>
@@ -138,7 +143,8 @@ void ibdiag_show_usage()
static int process_opt(int ch, char *optarg)
{
- int val;
+ char *endp;
+ long val;
switch (ch) {
case 'h':
@@ -175,9 +181,16 @@ static int process_opt(int ch, char *optarg)
ibd_dest_type = IB_DEST_GUID;
break;
case 't':
- val = strtoul(optarg, 0, 0);
- madrpc_set_timeout(val);
- ibd_timeout = val;
+ errno = 0;
+ val = strtol(optarg, &endp, 0);
+ if (errno || (endp && *endp != '\0') || val <= 0 ||
+ val > INT_MAX)
+ IBERROR("Invalid timeout \"%s\". Timeout requires a "
+ "positive integer value < %d.", optarg, INT_MAX);
+ else {
+ madrpc_set_timeout((int)val);
+ ibd_timeout = (int)val;
+ }
break;
case 's':
/* srcport is not required when resolving via IB_DEST_LID */
@@ -328,3 +341,175 @@ void iberror(const char *fn, char *msg, ...)
exit(-1);
}
+
+/* define a common SA query structure
+ * This is by no means optimal but it moves the saquery functionality out of
+ * the saquery tool and provides it to other utilities.
+ */
+bind_handle_t sa_get_bind_handle(void)
+{
+ struct ibmad_port * srcport;
+ bind_handle_t handle;
+ int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
+
+ srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
+ if (!srcport) {
+ IBWARN("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
+ return (NULL);
+ }
+
+ handle = calloc(1, sizeof(*handle));
+ if (!handle)
+ IBPANIC("calloc failed");
+
+ ib_resolve_smlid_via(&handle->dport, ibd_timeout, srcport);
+ if (!handle->dport.lid) {
+ IBWARN("No SM found.");
+ free(handle);
+ return (NULL);
+ }
+
+ handle->dport.qp = 1;
+ if (!handle->dport.qkey)
+ handle->dport.qkey = IB_DEFAULT_QP1_QKEY;
+
+ handle->srcport = srcport;
+ handle->fd = mad_rpc_portid(srcport);
+ handle->agent = umad_register(handle->fd, IB_SA_CLASS, 2, 1, NULL);
+
+ return handle;
+}
+
+void sa_free_bind_handle(bind_handle_t h)
+{
+ umad_unregister(h->fd, h->agent);
+ mad_rpc_close_port(h->srcport);
+ free(h);
+}
+
+int sa_query(bind_handle_t h, uint8_t method,
+ uint16_t attr, uint32_t mod, uint64_t comp_mask,
+ uint64_t sm_key, void *data, struct sa_query_result *result)
+{
+ ib_rpc_t rpc;
+ void *umad, *mad;
+ int ret, offset, len = 256;
+
+ memset(&rpc, 0, sizeof(rpc));
+ rpc.mgtclass = IB_SA_CLASS;
+ rpc.method = method;
+ rpc.attr.id = attr;
+ rpc.attr.mod = mod;
+ rpc.mask = comp_mask;
+ rpc.datasz = IB_SA_DATA_SIZE;
+ rpc.dataoffs = IB_SA_DATA_OFFS;
+
+ umad = calloc(1, len + umad_size());
+ if (!umad)
+ IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));
+
+ mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
+
+ mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
+
+ if (ibdebug > 1)
+ xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
+
+ ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
+ if (ret < 0) {
+ IBWARN("umad_send failed: attr %u: %s\n",
+ attr, strerror(errno));
+ free(umad);
+ return (IB_ERROR);
+ }
+
+recv_mad:
+ ret = umad_recv(h->fd, umad, &len, ibd_timeout);
+ if (ret < 0) {
+ if (errno == ENOSPC) {
+ umad = realloc(umad, umad_size() + len);
+ goto recv_mad;
+ }
+ IBWARN("umad_recv failed: attr 0x%x: %s\n", attr,
+ strerror(errno));
+ free(umad);
+ return (IB_ERROR);
+ }
+
+ if ((ret = umad_status(umad)))
+ return ret;
+
+ mad = umad_get_mad(umad);
+
+ if (ibdebug > 1)
+ xdump(stdout, "SA Response:\n", mad, len);
+
+ method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
+ offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
+ result->status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
+ result->p_result_madw = mad;
+ if (result->status != IB_SA_MAD_STATUS_SUCCESS)
+ result->result_cnt = 0;
+ else if (method != IB_MAD_METHOD_GET_TABLE)
+ result->result_cnt = 1;
+ else if (!offset)
+ result->result_cnt = 0;
+ else
+ result->result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
+
+ return 0;
+}
+
+void sa_free_result_mad(struct sa_query_result *result)
+{
+ if (result->p_result_madw) {
+ free((uint8_t *) result->p_result_madw - umad_size());
+ result->p_result_madw = NULL;
+ }
+}
+
+void *sa_get_query_rec(void *mad, unsigned i)
+{
+ int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
+ return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
+}
+
+static const char *ib_sa_error_str[] = {
+ "SA_NO_ERROR",
+ "SA_ERR_NO_RESOURCES",
+ "SA_ERR_REQ_INVALID",
+ "SA_ERR_NO_RECORDS",
+ "SA_ERR_TOO_MANY_RECORDS",
+ "SA_ERR_REQ_INVALID_GID",
+ "SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
+ "SA_ERR_REQ_DENIED",
+ "SA_ERR_STATUS_PRIO_SUGGESTED",
+ "SA_ERR_UNKNOWN"
+};
+
+#define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+#define SA_ERR_UNKNOWN (ARR_SIZE(ib_sa_error_str) - 1)
+
+static inline const char *ib_sa_err_str(IN uint8_t status)
+{
+ if (status > SA_ERR_UNKNOWN)
+ status = SA_ERR_UNKNOWN;
+ return (ib_sa_error_str[status]);
+}
+
+void sa_report_err(int status)
+{
+ int st = status & 0xff;
+ char sm_err_str[64] = { 0 };
+ char sa_err_str[64] = { 0 };
+
+ if (st)
+ sprintf(sm_err_str, " SM(%s)", ib_get_err_str(st));
+
+ st = status >> 8;
+ if (st)
+ sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
+
+ fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
+ status, sm_err_str, sa_err_str);
+}
diff --git a/trunk/tools/infiniband-diags/src/iblinkinfo.c b/trunk/tools/infiniband-diags/src/iblinkinfo.c
index d0c9b13..c07d33e 100644
--- a/trunk/tools/infiniband-diags/src/iblinkinfo.c
+++ b/trunk/tools/infiniband-diags/src/iblinkinfo.c
@@ -2,6 +2,7 @@
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
* Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
+ * Copyright (c) 2010,2011 Mellanox Technologies LTD. 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
@@ -53,9 +54,20 @@
#include "ibdiag_common.h"
+#define DIFF_FLAG_PORT_CONNECTION 0x01
+#define DIFF_FLAG_PORT_STATE 0x02
+#define DIFF_FLAG_LID 0x04
+#define DIFF_FLAG_NODE_DESCRIPTION 0x08
+
+#define DIFF_FLAG_DEFAULT (DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_PORT_STATE)
+
static char *node_name_map_file = NULL;
static nn_map_t *node_name_map = NULL;
static char *load_cache_file = NULL;
+static char *diff_cache_file = NULL;
+static unsigned diffcheck_flags = DIFF_FLAG_DEFAULT;
+static char *filterdownports_cache_file = NULL;
+static ibnd_fabric_t *filterdownports_fabric = NULL;
static uint64_t guid = 0;
static char *guid_str = NULL;
@@ -65,7 +77,6 @@ static int all = 0;
static int down_links_only = 0;
static int line_mode = 0;
static int add_sw_settings = 0;
-static int print_port_guids = 0;
static unsigned int get_max(unsigned int num)
{
@@ -107,7 +118,31 @@ void get_msg(char *width_msg, char *speed_msg, int msg_size, ibnd_port_t * port)
buf, 64, &max_speed));
}
-void print_port(ibnd_node_t * node, ibnd_port_t * port)
+int filterdownport_check(ibnd_node_t * node, ibnd_port_t * port)
+{
+ ibnd_node_t *fsw;
+ ibnd_port_t *fport;
+ int fistate;
+
+ fsw = ibnd_find_node_guid(filterdownports_fabric, node->guid);
+
+ if (!fsw)
+ return 0;
+
+ if (port->portnum > fsw->numports)
+ return 0;
+
+ fport = fsw->ports[port->portnum];
+
+ if (!fport)
+ return 0;
+
+ fistate = mad_get_field(fport->info, 0, IB_PORT_STATE_F);
+
+ return (fistate == IB_LINK_DOWN) ? 1 : 0;
+}
+
+void print_port(ibnd_node_t * node, ibnd_port_t * port, char *out_prefix)
{
char width[64], speed[64], state[64], physstate[64];
char remote_guid_str[256];
@@ -133,6 +168,11 @@ void print_port(ibnd_node_t * node, ibnd_port_t * port)
width_msg[0] = '\0';
speed_msg[0] = '\0';
+ if (istate == IB_LINK_DOWN
+ && filterdownports_fabric
+ && filterdownport_check(node, port))
+ return;
+
/* C14-24.2.1 states that a down port allows for invalid data to be
* returned for all PortInfo components except PortState and
* PortPhysicalState */
@@ -176,14 +216,9 @@ void print_port(ibnd_node_t * node, ibnd_port_t * port)
get_msg(width_msg, speed_msg, 256, port);
if (line_mode) {
- if (print_port_guids)
- snprintf(remote_guid_str, 256,
- "0x%016" PRIx64 " ",
- port->remoteport->guid);
- else
- snprintf(remote_guid_str, 256,
- "0x%016" PRIx64 " ",
- port->remoteport->node->guid);
+ snprintf(remote_guid_str, 256,
+ "0x%016" PRIx64 " ",
+ port->remoteport->guid);
}
snprintf(remote_str, 256, "%s%6d %4d[%2s] \"%s\" (%s %s)\n",
@@ -204,21 +239,64 @@ void print_port(ibnd_node_t * node, ibnd_port_t * port)
if (line_mode) {
char *remap = remap_node_name(node_name_map, node->guid,
node->nodedesc);
- printf("0x%016" PRIx64 " \"%30s\" ", node->guid, remap);
+ printf("%s0x%016" PRIx64 " \"%30s\" ",
+ out_prefix ? out_prefix : "",
+ port->guid, remap);
free(remap);
} else
- printf(" ");
+ printf("%s ", out_prefix ? out_prefix : "");
+
+ if (port->node->type != IB_NODE_SWITCH) {
+ if (!line_mode)
+ printf("0x%016" PRIx64 " ", port->guid);
+
+ printf("%6d %4d[%2s] ==%s==> %s",
+ port->base_lid,
+ port->portnum, ext_port_str, link_str, remote_str);
+ } else
+ printf("%6d %4d[%2s] ==%s==> %s",
+ node->smalid, port->portnum, ext_port_str,
+ link_str, remote_str);
+}
+
+static inline const char *nodetype_str(ibnd_node_t * node)
+{
+ switch (node->type) {
+ case IB_NODE_SWITCH:
+ return "Switch";
+ case IB_NODE_CA:
+ return "CA";
+ case IB_NODE_ROUTER:
+ return "Router";
+ }
+ return "??";
+}
- printf("%6d %4d[%2s] ==%s==> %s",
- node->smalid, port->portnum, ext_port_str, link_str, remote_str);
+void print_node_header(ibnd_node_t *node, int *out_header_flag,
+ char *out_prefix)
+{
+ if ((!out_header_flag || !(*out_header_flag)) && !line_mode) {
+ char *remap =
+ remap_node_name(node_name_map, node->guid, node->nodedesc);
+ if (node->type == IB_NODE_SWITCH)
+ printf("%s%s: 0x%016" PRIx64 " %s:\n",
+ out_prefix ? out_prefix : "",
+ nodetype_str(node),
+ node->ports[0]->guid, remap);
+ else
+ printf("%s%s: %s:\n",
+ out_prefix ? out_prefix : "",
+ nodetype_str(node), remap);
+ (*out_header_flag)++;
+ free(remap);
+ }
}
-void print_switch(ibnd_node_t * node, void *user_data)
+void print_node(ibnd_node_t * node, void *user_data)
{
int i = 0;
int head_print = 0;
- char *remap =
- remap_node_name(node_name_map, node->guid, node->nodedesc);
+ char *out_prefix = (char *)user_data;
for (i = 1; i <= node->numports; i++) {
ibnd_port_t *port = node->ports[i];
@@ -227,20 +305,192 @@ void print_switch(ibnd_node_t * node, void *user_data)
if (!down_links_only ||
mad_get_field(port->info, 0,
IB_PORT_STATE_F) == IB_LINK_DOWN) {
- if (!head_print && !line_mode) {
- printf("Switch 0x%016" PRIx64 " %s:\n",
- node->guid, remap);
- head_print = 1;
- }
- print_port(node, port);
+ print_node_header(node, &head_print, out_prefix);
+ print_port(node, port, out_prefix);
}
}
- free(remap);
+}
+
+struct iter_diff_data {
+ uint32_t diff_flags;
+ ibnd_fabric_t *fabric1;
+ ibnd_fabric_t *fabric2;
+ char *fabric1_prefix;
+ char *fabric2_prefix;
+};
+
+void diff_node_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
+ int *head_print, struct iter_diff_data *data)
+{
+ int i = 0;
+
+ for (i = 1; i <= fabric1_node->numports; i++) {
+ ibnd_port_t *fabric1_port, *fabric2_port;
+ int output_diff = 0;
+
+ fabric1_port = fabric1_node->ports[i];
+ fabric2_port = fabric2_node->ports[i];
+
+ if (!fabric1_port && !fabric2_port)
+ continue;
+
+ if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION) {
+ if ((fabric1_port && !fabric2_port)
+ || (!fabric1_port && fabric2_port)
+ || (fabric1_port->remoteport
+ && !fabric2_port->remoteport)
+ || (!fabric1_port->remoteport
+ && fabric2_port->remoteport)
+ || (fabric1_port->remoteport
+ && fabric2_port->remoteport
+ && fabric1_port->remoteport->guid !=
+ fabric2_port->remoteport->guid))
+ output_diff++;
+ }
+
+ /* if either fabric1_port or fabric2_port NULL, should be
+ * handled by port connection diff code
+ */
+ if (data->diff_flags & DIFF_FLAG_PORT_STATE
+ && fabric1_port
+ && fabric2_port) {
+ int state1, state2;
+
+ state1 = mad_get_field(fabric1_port->info, 0,
+ IB_PORT_STATE_F);
+ state2 = mad_get_field(fabric2_port->info, 0,
+ IB_PORT_STATE_F);
+
+ if (state1 != state2)
+ output_diff++;
+ }
+
+ if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
+ && data->diff_flags & DIFF_FLAG_LID
+ && fabric1_port && fabric2_port
+ && fabric1_port->remoteport && fabric2_port->remoteport
+ && fabric1_port->remoteport->base_lid != fabric2_port->remoteport->base_lid)
+ output_diff++;
+
+ if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
+ && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
+ && fabric1_port && fabric2_port
+ && fabric1_port->remoteport && fabric2_port->remoteport
+ && memcmp(fabric1_port->remoteport->node->nodedesc,
+ fabric2_port->remoteport->node->nodedesc,
+ IB_SMP_DATA_SIZE))
+ output_diff++;
+
+ if (output_diff && fabric1_port) {
+ print_node_header(fabric1_node,
+ head_print,
+ NULL);
+ print_port(fabric1_node,
+ fabric1_port,
+ data->fabric1_prefix);
+ }
+
+ if (output_diff && fabric2_port) {
+ print_node_header(fabric1_node,
+ head_print,
+ NULL);
+ print_port(fabric2_node,
+ fabric2_port,
+ data->fabric2_prefix);
+ }
+ }
+}
+
+void diff_node_iter(ibnd_node_t * fabric1_node, void *iter_user_data)
+{
+ struct iter_diff_data *data = iter_user_data;
+ ibnd_node_t *fabric2_node;
+ int head_print = 0;
+
+ DEBUG("DEBUG: fabric1_node %p\n", fabric1_node);
+
+ fabric2_node = ibnd_find_node_guid(data->fabric2, fabric1_node->guid);
+ if (!fabric2_node)
+ print_node(fabric1_node, data->fabric1_prefix);
+ else if (data->diff_flags &
+ (DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_PORT_STATE
+ | DIFF_FLAG_LID | DIFF_FLAG_NODE_DESCRIPTION)) {
+
+ if ((fabric1_node->type == IB_NODE_SWITCH
+ && data->diff_flags & DIFF_FLAG_LID
+ && fabric1_node->smalid != fabric2_node->smalid) ||
+ (data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
+ && memcmp(fabric1_node->nodedesc, fabric2_node->nodedesc,
+ IB_SMP_DATA_SIZE))) {
+ print_node_header(fabric1_node,
+ NULL,
+ data->fabric1_prefix);
+ print_node_header(fabric2_node,
+ NULL,
+ data->fabric2_prefix);
+ head_print++;
+ }
+
+ if (fabric1_node->numports != fabric2_node->numports) {
+ print_node_header(fabric1_node,
+ &head_print,
+ NULL);
+ printf("%snumports = %d\n", data->fabric1_prefix,
+ fabric1_node->numports);
+ printf("%snumports = %d\n", data->fabric2_prefix,
+ fabric2_node->numports);
+ return;
+ }
+
+ diff_node_ports(fabric1_node, fabric2_node,
+ &head_print, data);
+ }
+}
+
+int diff_node(ibnd_node_t * node, ibnd_fabric_t * orig_fabric,
+ ibnd_fabric_t * new_fabric)
+{
+ struct iter_diff_data iter_diff_data;
+
+ iter_diff_data.diff_flags = diffcheck_flags;
+ iter_diff_data.fabric1 = orig_fabric;
+ iter_diff_data.fabric2 = new_fabric;
+ iter_diff_data.fabric1_prefix = "< ";
+ iter_diff_data.fabric2_prefix = "> ";
+ if (node)
+ diff_node_iter(node, &iter_diff_data);
+ else
+ ibnd_iter_nodes(orig_fabric, diff_node_iter, &iter_diff_data);
+
+ /* Do opposite diff to find existence of node types
+ * in new_fabric but not in orig_fabric.
+ *
+ * In this diff, we don't need to check port connections,
+ * port state, lids, or node descriptions since it has already
+ * been done (i.e. checks are only done when guid exists on both
+ * orig and new).
+ */
+ iter_diff_data.diff_flags = diffcheck_flags & ~DIFF_FLAG_PORT_CONNECTION;
+ iter_diff_data.diff_flags &= ~DIFF_FLAG_PORT_STATE;
+ iter_diff_data.diff_flags &= ~DIFF_FLAG_LID;
+ iter_diff_data.diff_flags &= ~DIFF_FLAG_NODE_DESCRIPTION;
+ iter_diff_data.fabric1 = new_fabric;
+ iter_diff_data.fabric2 = orig_fabric;
+ iter_diff_data.fabric1_prefix = "> ";
+ iter_diff_data.fabric2_prefix = "< ";
+ if (node)
+ diff_node_iter(node, &iter_diff_data);
+ else
+ ibnd_iter_nodes(new_fabric, diff_node_iter, &iter_diff_data);
+
+ return 0;
}
static int process_opt(void *context, int ch, char *optarg)
{
struct ibnd_config *cfg = context;
+ char *p;
+
switch (ch) {
case 1:
node_name_map_file = strdup(optarg);
@@ -248,7 +498,34 @@ static int process_opt(void *context, int ch, char *optarg)
case 2:
load_cache_file = strdup(optarg);
break;
+ case 3:
+ diff_cache_file = strdup(optarg);
+ break;
+ case 4:
+ diffcheck_flags = 0;
+ p = strtok(optarg, ",");
+ while (p) {
+ if (!strcasecmp(p, "port"))
+ diffcheck_flags |= DIFF_FLAG_PORT_CONNECTION;
+ else if (!strcasecmp(p, "state"))
+ diffcheck_flags |= DIFF_FLAG_PORT_STATE;
+ else if (!strcasecmp(p, "lid"))
+ diffcheck_flags |= DIFF_FLAG_LID;
+ else if (!strcasecmp(p, "nodedesc"))
+ diffcheck_flags |= DIFF_FLAG_NODE_DESCRIPTION;
+ else {
+ fprintf(stderr, "invalid diff check key: %s\n",
+ p);
+ return -1;
+ }
+ p = strtok(NULL, ",");
+ }
+ break;
+ case 5:
+ filterdownports_cache_file = strdup(optarg);
+ break;
case 'S':
+ case 'G':
guid_str = optarg;
guid = (uint64_t) strtoull(guid_str, 0, 0);
break;
@@ -270,9 +547,6 @@ static int process_opt(void *context, int ch, char *optarg)
case 'p':
add_sw_settings = 1;
break;
- case 'g':
- print_port_guids = 1;
- break;
case 'R': /* nop */
break;
case 'o':
@@ -291,6 +565,7 @@ int main(int argc, char **argv)
int rc = 0;
int resolved = -1;
ibnd_fabric_t *fabric = NULL;
+ ibnd_fabric_t *diff_fabric = NULL;
struct ibmad_port *ibmad_port;
ib_portid_t port_id = { 0 };
int mgmt_classes[3] =
@@ -298,23 +573,29 @@ int main(int argc, char **argv)
const struct ibdiag_opt opts[] = {
{"node-name-map", 1, 1, "<file>", "node name map file"},
- {"switch", 'S', 1, "<switch_guid>",
- "query only <switch_guid> (hex format)"},
+ {"switch", 'S', 1, "<port_guid>",
+ "start partial scan at the port specified by <port_guid> (hex format)"},
+ {"port-guid", 'G', 1, "<port_guid>",
+ "(same as -S)"},
{"Direct", 'D', 1, "<dr_path>",
- "query only node specified by <dr_path>"},
+ "start partial scan at the port specified by <dr_path>"},
{"all", 'a', 0, NULL,
- "print all switches found in a partial fabric scan"},
+ "print all nodes found in a partial fabric scan"},
{"hops", 'n', 1, "<hops>",
"Number of hops to include away from specified node"},
{"down", 'd', 0, NULL, "print only down links"},
{"line", 'l', 0, NULL,
"(line mode) print all information for each link on a single line"},
{"additional", 'p', 0, NULL,
- "print additional switch settings (PktLifeTime, HoqLife, VLStallCount)"},
- {"portguids", 'g', 0, NULL,
- "print port guids instead of node guids"},
+ "print additional port settings (PktLifeTime, HoqLife, VLStallCount)"},
{"load-cache", 2, 1, "<file>",
"filename of ibnetdiscover cache to load"},
+ {"diff", 3, 1, "<file>",
+ "filename of ibnetdiscover cache to diff"},
+ {"diffcheck", 4, 1, "<key(s)>",
+ "specify checks to execute for --diff"},
+ {"filterdownports", 5, 1, "<file>",
+ "filename of ibnetdiscover cache to filter downports"},
{"outstanding_smps", 'o', 1, NULL,
"specify the number of outstanding SMP's which should be "
"issued during the scan"},
@@ -355,7 +636,7 @@ int main(int argc, char **argv)
ib_resolve_portid_str_via(&port_id, dr_path,
IB_DEST_DRPATH, NULL,
ibmad_port)) < 0)
- IBWARN("Failed to resolve %s; attempting full scan\n",
+ IBWARN("Failed to resolve %s; attempting full scan",
dr_path);
} else if (guid_str) {
if ((resolved =
@@ -365,17 +646,28 @@ int main(int argc, char **argv)
guid_str);
}
+ if (diff_cache_file &&
+ !(diff_fabric = ibnd_load_fabric(diff_cache_file, 0)))
+ IBERROR("loading cached fabric for diff failed\n");
+
+ if (filterdownports_cache_file &&
+ !(filterdownports_fabric = ibnd_load_fabric(filterdownports_cache_file, 0)))
+ IBERROR("loading cached fabric for filterdownports failed\n");
+
if (load_cache_file) {
if ((fabric = ibnd_load_fabric(load_cache_file, 0)) == NULL) {
fprintf(stderr, "loading cached fabric failed\n");
exit(1);
}
} else {
- if (resolved >= 0 &&
- !(fabric =
- ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
- IBWARN("Single node discover failed;"
- " attempting full scan\n");
+ if (resolved >= 0) {
+ if (!config.max_hops)
+ config.max_hops = 1;
+ if (!(fabric =
+ ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
+ IBWARN("Partial fabric scan failed;"
+ " attempting full scan\n");
+ }
if (!fabric &&
!(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config))) {
@@ -386,31 +678,45 @@ int main(int argc, char **argv)
}
if (!all && guid_str) {
- ibnd_node_t *sw = ibnd_find_node_guid(fabric, guid);
- if (sw)
- print_switch(sw, NULL);
+ ibnd_port_t *p = ibnd_find_port_guid(fabric, guid);
+ if (p) {
+ ibnd_node_t *n = p->node;
+ if (diff_fabric)
+ diff_node(n, diff_fabric, fabric);
+ else
+ print_node(n, NULL);
+ }
else
- fprintf(stderr, "Failed to find switch: %s\n",
- guid_str);
+ fprintf(stderr, "Failed to find port: %s\n", guid_str);
} else if (!all && dr_path) {
- ibnd_node_t *sw = NULL;
- uint8_t ni[IB_SMP_DATA_SIZE];
+ ibnd_port_t *p = NULL;
+ uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
if (!smp_query_via(ni, &port_id, IB_ATTR_NODE_INFO, 0,
ibd_timeout, ibmad_port))
return -1;
- mad_decode_field(ni, IB_NODE_GUID_F, &(guid));
+ mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(guid));
- sw = ibnd_find_node_guid(fabric, guid);
- if (sw)
- print_switch(sw, NULL);
+ p = ibnd_find_port_guid(fabric, guid);
+ if (p) {
+ ibnd_node_t *n = p->node;
+ if (diff_fabric)
+ diff_node(n, diff_fabric, fabric);
+ else
+ print_node(n, NULL);
+ }
else
- fprintf(stderr, "Failed to find switch: %s\n", dr_path);
- } else
- ibnd_iter_nodes_type(fabric, print_switch, IB_NODE_SWITCH,
- NULL);
+ fprintf(stderr, "Failed to find port: %s\n", dr_path);
+ } else {
+ if (diff_fabric)
+ diff_node(NULL, diff_fabric, fabric);
+ else
+ ibnd_iter_nodes(fabric, print_node, NULL);
+ }
ibnd_destroy_fabric(fabric);
+ if (diff_fabric)
+ ibnd_destroy_fabric(diff_fabric);
close_port:
close_node_name_map(node_name_map);
diff --git a/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES b/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES
index e864598..2761041 100644
--- a/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES
+++ b/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES
@@ -22,6 +22,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib \
$(TARGETPATH)\*\libibnetdisc.lib
diff --git a/trunk/tools/infiniband-diags/src/ibnetdiscover.c b/trunk/tools/infiniband-diags/src/ibnetdiscover.c
index 347e7b2..59304b6 100644
--- a/trunk/tools/infiniband-diags/src/ibnetdiscover.c
+++ b/trunk/tools/infiniband-diags/src/ibnetdiscover.c
@@ -77,6 +77,7 @@ static char *diff_cache_file = NULL;
static unsigned diffcheck_flags = DIFF_FLAG_DEFAULT;
static int report_max_hops = 0;
+static int full_info;
/**
* Define our own conversion functions to maintain compatibility with the old
@@ -214,7 +215,9 @@ void out_ids(ibnd_node_t * node, int group, char *chname, char *out_prefix)
fprintf(f, " slot %d",
node->ports[1]->remoteport->portnum);
}
- fprintf(f, "\n");
+ if (sysimgguid ||
+ (group && node->chassis && node->chassis->chassisnum))
+ fprintf(f, "\n");
}
uint64_t out_chassis(ibnd_fabric_t * fabric, unsigned char chassisnum)
@@ -364,6 +367,9 @@ void out_switch_port(ibnd_port_t * port, int group, char *out_prefix)
port->remoteport->base_lid,
dump_linkwidth_compat(iwidth), dump_linkspeed_compat(ispeed));
+ if (full_info)
+ fprintf(f, " s=%d w=%d", ispeed, iwidth);
+
if (ibnd_is_xsigo_tca(port->remoteport->guid))
fprintf(f, " slot %d", port->portnum);
else if (ibnd_is_xsigo_hca(port->remoteport->guid))
@@ -397,13 +403,17 @@ void out_ca_port(ibnd_port_t * port, int group, char *out_prefix)
port->remoteport->node->guid,
port->remoteport->node->nodedesc);
- fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s\n",
+ fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s",
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));
+ if (full_info)
+ fprintf(f, " s=%d w=%d", ispeed, iwidth);
+ fprintf(f, "\n");
+
free(rem_nodename);
}
@@ -616,6 +626,8 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
{
int p = 0;
ibnd_port_t *port = NULL;
+ char *nodename = NULL;
+ char *rem_nodename = NULL;
/* for each port */
for (p = node->numports, port = node->ports[p]; p > 0;
@@ -627,6 +639,9 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
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);
+ nodename = remap_node_name(node_name_map,
+ port->node->guid,
+ port->node->nodedesc);
fprintf(stdout, "%2s %5d %2d 0x%016" PRIx64 " %s %s",
ports_nt_str_compat(node),
node->type ==
@@ -634,7 +649,10 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
port->portnum, port->guid,
dump_linkwidth_compat(iwidth),
dump_linkspeed_compat(ispeed));
- if (port->remoteport)
+ if (port->remoteport) {
+ rem_nodename = remap_node_name(node_name_map,
+ port->remoteport->node->guid,
+ port->remoteport->node->nodedesc);
fprintf(stdout,
" - %2s %5d %2d 0x%016" PRIx64
" ( '%s' - '%s' )\n",
@@ -643,10 +661,12 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
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);
+ port->remoteport->guid, nodename, rem_nodename);
+ free(rem_nodename);
+ } else
+ fprintf(stdout, "%36s'%s'\n", "", nodename);
+
+ free(nodename);
}
}
@@ -714,6 +734,37 @@ static void diff_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
fabric2_out++;
}
+ if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
+ && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
+ && fabric1_port && fabric2_port
+ && fabric1_port->remoteport && fabric2_port->remoteport
+ && memcmp(fabric1_port->remoteport->node->nodedesc,
+ fabric2_port->remoteport->node->nodedesc,
+ IB_SMP_DATA_SIZE)) {
+ fabric1_out++;
+ fabric2_out++;
+ }
+
+ if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
+ && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
+ && fabric1_port && fabric2_port
+ && fabric1_port->remoteport && fabric2_port->remoteport
+ && memcmp(fabric1_port->remoteport->node->nodedesc,
+ fabric2_port->remoteport->node->nodedesc,
+ IB_SMP_DATA_SIZE)) {
+ fabric1_out++;
+ fabric2_out++;
+ }
+
+ if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
+ && data->diff_flags & DIFF_FLAG_LID
+ && fabric1_port && fabric2_port
+ && fabric1_port->remoteport && fabric2_port->remoteport
+ && fabric1_port->remoteport->base_lid != fabric2_port->remoteport->base_lid) {
+ fabric1_out++;
+ fabric2_out++;
+ }
+
if (fabric1_out) {
diff_iter_out_header(fabric1_node, data,
out_header_flag);
@@ -895,6 +946,9 @@ static int process_opt(void *context, int ch, char *optarg)
case 's':
cfg->show_progress = 1;
break;
+ case 'f':
+ full_info = 1;
+ break;
case 'l':
list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE;
break;
@@ -933,6 +987,7 @@ int main(int argc, char **argv)
ibnd_fabric_t *diff_fabric = NULL;
const struct ibdiag_opt opts[] = {
+ {"full", 'f', 0, NULL, "show full information (ports' speed and width)"},
{"show", 's', 0, NULL, "show more information"},
{"list", 'l', 0, NULL, "list of connected nodes"},
{"grouping", 'g', 0, NULL, "show grouping"},
diff --git a/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES b/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES
index 22bfc67..86eae18 100644
--- a/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES
@@ -22,6 +22,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib \
$(TARGETPATH)\*\libibnetdisc.lib
diff --git a/trunk/tools/infiniband-diags/src/ibping.c b/trunk/tools/infiniband-diags/src/ibping.c
index dafab1c..016679d 100644
--- a/trunk/tools/infiniband-diags/src/ibping.c
+++ b/trunk/tools/infiniband-diags/src/ibping.c
@@ -138,7 +138,7 @@ static uint64_t minrtt = ~0ull, maxrtt, total_rtt;
static uint64_t start, total_time, replied, lost, ntrans;
static ib_portid_t portid = { 0 };
-void __cdecl report(int sig)
+void report(int sig)
{
total_time = cl_get_time_stamp() - start;
diff --git a/trunk/tools/infiniband-diags/src/ibping/SOURCES b/trunk/tools/infiniband-diags/src/ibping/SOURCES
index 341f589..12d3a5e 100644
--- a/trunk/tools/infiniband-diags/src/ibping/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibping/SOURCES
@@ -21,6 +21,7 @@ TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/ibportstate.c b/trunk/tools/infiniband-diags/src/ibportstate.c
index 499dabc..1f0f42e 100644
--- a/trunk/tools/infiniband-diags/src/ibportstate.c
+++ b/trunk/tools/infiniband-diags/src/ibportstate.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -125,7 +126,7 @@ static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
char buf[2048];
char val[64];
- mad_dump_portstates(buf, sizeof buf, data, sizeof data);
+ mad_dump_portstates(buf, sizeof buf, data, sizeof *data);
mad_decode_field(data, IB_PORT_LID_F, val);
mad_dump_field(IB_PORT_LID_F, buf + strlen(buf),
sizeof buf - strlen(buf), val);
@@ -247,7 +248,7 @@ int main(int argc, char **argv)
int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss,
peerlsa;
int peerwidth, peerspeed;
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
ib_portid_t peerportid = { 0 };
int portnum = 0;
ib_portid_t selfportid = { 0 };
@@ -356,6 +357,7 @@ int main(int argc, char **argv)
printf("Initial %s PortInfo:\n", is_switch ? "Switch" : "CA");
else
printf("%s PortInfo:\n", is_switch ? "Switch" : "CA");
+ memset(data, 0, sizeof(data));
get_port_info(&portid, data, portnum);
show_port_info(&portid, data, portnum);
diff --git a/trunk/tools/infiniband-diags/src/ibportstate/SOURCES b/trunk/tools/infiniband-diags/src/ibportstate/SOURCES
index 1fa9adc..851e77f 100644
--- a/trunk/tools/infiniband-diags/src/ibportstate/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibportstate/SOURCES
@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/ibqueryerrors.c b/trunk/tools/infiniband-diags/src/ibqueryerrors.c
index f04e47f..4677db4 100644
--- a/trunk/tools/infiniband-diags/src/ibqueryerrors.c
+++ b/trunk/tools/infiniband-diags/src/ibqueryerrors.c
@@ -3,6 +3,7 @@
* Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
* Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -61,9 +62,10 @@ static nn_map_t *node_name_map = NULL;
static char *load_cache_file = NULL;
int data_counters = 0;
+int data_counters_only = 0;
int port_config = 0;
-uint64_t node_guid = 0;
-char *node_guid_str = NULL;
+uint64_t port_guid = 0;
+char *port_guid_str = NULL;
#define SUP_MAX 64
int sup_total = 0;
enum MAD_FIELDS suppressed_fields[SUP_MAX];
@@ -76,6 +78,88 @@ unsigned clear_errors = 0, clear_counts = 0, details = 0;
#define PRINT_ROUTER 0x4
#define PRINT_ALL 0xFF /* all nodes default flag */
+struct {
+ int nodes_checked;
+ int bad_nodes;
+ int ports_checked;
+ int bad_ports;
+} summary = { 0 };
+
+#define DEF_THRES_FILE IBDIAG_CONFIG_PATH"/error_thresholds"
+static char *threshold_file = DEF_THRES_FILE;
+
+/* define a "packet" with threshold values in it */
+uint8_t thresholds[1204] = { 0 };
+char * threshold_str = "";
+
+static void set_thres(char *name, uint32_t val)
+{
+ int f;
+ int n;
+ char tmp[256];
+ for (f = IB_PC_FIRST_F; f <= IB_PC_LAST_F; f++) {
+ if (strcmp(name, mad_field_name(f)) == 0) {
+ mad_encode_field(thresholds, f, &val);
+ snprintf(tmp, 255, "[%s = %u]", name, val);
+ threshold_str = realloc(threshold_str,
+ strlen(threshold_str)+strlen(tmp)+1);
+ if (!threshold_str) {
+ fprintf(stderr, "Failed to allocate memory: "
+ "%s\n", strerror(errno));
+ exit(1);
+ }
+ n = strlen(threshold_str);
+ strcpy(threshold_str+n, tmp);
+ }
+ }
+}
+
+static void set_thresholds(char *threshold_file)
+{
+ char buf[1024];
+ int val = 0;
+ FILE *thresf = fopen(threshold_file, "r");
+ char *p_prefix, *p_last;
+ char *name;
+ char *val_str;
+ char str[64];
+
+ if (!thresf)
+ return;
+
+ snprintf(str, 63, "Thresholds: ");
+ threshold_str = malloc(strlen(str)+1);
+ if (!threshold_str) {
+ fprintf(stderr, "Failed to allocate memory: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ strcpy(threshold_str, str);
+ while (fgets(buf, sizeof buf, thresf) != NULL) {
+ p_prefix = strtok_r(buf, "\n", &p_last);
+ if (!p_prefix)
+ continue; /* ignore blank lines */
+
+ if (*p_prefix == '#')
+ continue; /* ignore comment lines */
+
+ name = strtok_r(p_prefix, "=", &p_last);
+ val_str = strtok_r(NULL, "\n", &p_last);
+
+ val = strtoul(val_str, NULL, 0);
+ set_thres(name, val);
+ }
+
+ fclose(thresf);
+}
+
+static int exceeds_threshold(int field, unsigned val)
+{
+ uint32_t thres = 0;
+ mad_decode_field(thresholds, field, &thres);
+ return (val > thres);
+}
+
static unsigned int get_max(unsigned int num)
{
unsigned r = 0; // r will be lg(num)
@@ -175,7 +259,7 @@ static void print_port_config(char *node_name, ibnd_node_t * node, int portnum)
snprintf(remote_str, 256,
"0x%016" PRIx64 " %6d %4d[%2s] \"%s\" (%s %s)\n",
- port->remoteport->node->guid,
+ port->remoteport->guid,
port->remoteport->base_lid ? port->remoteport->
base_lid : port->remoteport->node->smalid,
port->remoteport->portnum, ext_port_str, rem_node_name,
@@ -211,12 +295,22 @@ static int suppress(enum MAD_FIELDS field)
static void report_suppressed(void)
{
int i = 0;
- printf("Suppressing:");
+ printf("## Suppresed:");
for (i = 0; i < sup_total; i++)
printf(" %s", mad_field_name(suppressed_fields[i]));
printf("\n");
}
+static void print_summary(void)
+{
+ printf("\n## Summary: %d nodes checked, %d bad nodes found\n",
+ summary.nodes_checked, summary.bad_nodes);
+ printf("## %d ports checked, %d ports have errors beyond threshold\n",
+ summary.ports_checked, summary.bad_ports);
+ printf("## %s\n", threshold_str);
+ report_suppressed();
+}
+
static int query_and_dump(char *buf, size_t size, ib_portid_t * portid,
ibnd_node_t * node, char *node_name, int portnum,
const char *attr_name, uint16_t attr_id,
@@ -245,9 +339,9 @@ static int query_and_dump(char *buf, size_t size, ib_portid_t * portid,
return n;
}
-static void print_results(ib_portid_t * portid, char *node_name,
- ibnd_node_t * node, uint8_t * pc, int portnum,
- int *header_printed)
+static int print_results(ib_portid_t * portid, char *node_name,
+ ibnd_node_t * node, uint8_t * pc, int portnum,
+ int *header_printed, uint8_t *pce, uint16_t cap_mask)
{
char buf[1024];
char *str = buf;
@@ -263,65 +357,91 @@ static void print_results(ib_portid_t * portid, char *node_name,
continue;
mad_decode_field(pc, i, (void *)&val);
- if (val)
+ if (exceeds_threshold(i, val)) {
n += snprintf(str + n, 1024 - n, " [%s == %u]",
mad_field_name(i), val);
- /* If there are PortXmitDiscards, get details (if supported) */
- if (i == IB_PC_XMT_DISCARDS_F && details && val) {
- n += query_and_dump(str + n, sizeof(buf) - n, portid,
- node, node_name, portnum,
- "PortXmitDiscardDetails",
- IB_GSI_PORT_XMIT_DISCARD_DETAILS,
- IB_PC_RCV_LOCAL_PHY_ERR_F,
- IB_PC_RCV_ERR_LAST_F);
- /* If there are PortRcvErrors, get details (if supported) */
- } else if (i == IB_PC_ERR_RCV_F && details && val) {
- n += query_and_dump(str + n, sizeof(buf) - n, portid,
- node, node_name, portnum,
- "PortRcvErrorDetails",
- IB_GSI_PORT_RCV_ERROR_DETAILS,
- IB_PC_XMT_INACT_DISC_F,
- IB_PC_XMT_DISC_LAST_F);
+ /* If there are PortXmitDiscards, get details (if supported) */
+ if (i == IB_PC_XMT_DISCARDS_F && details) {
+ n += query_and_dump(str + n, sizeof(buf) - n, portid,
+ node, node_name, portnum,
+ "PortXmitDiscardDetails",
+ IB_GSI_PORT_XMIT_DISCARD_DETAILS,
+ IB_PC_RCV_LOCAL_PHY_ERR_F,
+ IB_PC_RCV_ERR_LAST_F);
+ /* If there are PortRcvErrors, get details (if supported) */
+ } else if (i == IB_PC_ERR_RCV_F && details) {
+ n += query_and_dump(str + n, sizeof(buf) - n, portid,
+ node, node_name, portnum,
+ "PortRcvErrorDetails",
+ IB_GSI_PORT_RCV_ERROR_DETAILS,
+ IB_PC_XMT_INACT_DISC_F,
+ IB_PC_XMT_DISC_LAST_F);
+ }
}
}
if (!suppress(IB_PC_XMT_WAIT_F)) {
mad_decode_field(pc, IB_PC_XMT_WAIT_F, (void *)&val);
- if (val)
+ if (exceeds_threshold(IB_PC_XMT_WAIT_F, val))
n += snprintf(str + n, 1024 - n, " [%s == %u]",
mad_field_name(IB_PC_XMT_WAIT_F), val);
}
/* if we found errors. */
if (n != 0) {
- if (data_counters)
- for (i = IB_PC_XMT_BYTES_F; i <= IB_PC_RCV_PKTS_F; i++) {
+ if (data_counters) {
+ uint8_t *pkt = pc;
+ int start_field = IB_PC_XMT_BYTES_F;
+ int end_field = IB_PC_RCV_PKTS_F;
+
+ if (pce) {
+ pkt = pce;
+ start_field = IB_PC_EXT_XMT_BYTES_F;
+ if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
+ end_field = IB_PC_EXT_RCV_MPKTS_F;
+ else
+ end_field = IB_PC_EXT_RCV_PKTS_F;
+ }
+
+ for (i = start_field; i <= end_field; i++) {
uint64_t val64 = 0;
- mad_decode_field(pc, i, (void *)&val64);
+ mad_decode_field(pkt, i, (void *)&val64);
if (val64)
n += snprintf(str + n, 1024 - n,
- " [%s == %" PRIu64 "]",
- mad_field_name(i), val64);
+ " [%s == %" PRIu64 "]",
+ mad_field_name(i), val64);
}
+ }
if (!*header_printed) {
- printf("Errors for 0x%" PRIx64 " \"%s\"\n", node->guid,
- node_name);
+ if (node->type == IB_NODE_SWITCH)
+ printf("Errors for 0x%" PRIx64 " \"%s\"\n",
+ node->ports[0]->guid, node_name);
+ else
+ printf("Errors for \"%s\"\n", node_name);
*header_printed = 1;
+ summary.bad_nodes++;
}
- printf(" GUID 0x%" PRIx64 " port %d:%s\n", node->guid,
- portnum, str);
- if (port_config)
+ if (portnum == 0xFF)
+ printf(" GUID 0x%" PRIx64 " port ALL:%s\n",
+ node->ports[0]->guid, str);
+ else
+ printf(" GUID 0x%" PRIx64 " port %d:%s\n",
+ node->ports[portnum]->guid, portnum, str);
+ if (portnum != 0xFF && port_config)
print_port_config(node_name, node, portnum);
+
+ summary.bad_ports++;
}
+ return (n);
}
static int query_cap_mask(ib_portid_t * portid, char *node_name, int portnum,
uint16_t * cap_mask)
{
- uint8_t pc[1024];
+ uint8_t pc[1024] = { 0 };
uint16_t rc_cap_mask;
/* PerfMgt ClassPortInfo is a required attribute */
@@ -335,63 +455,192 @@ static int query_cap_mask(ib_portid_t * portid, char *node_name, int portnum,
/* ClassPortInfo should be supported as part of libibmad */
memcpy(&rc_cap_mask, pc + 2, sizeof(rc_cap_mask)); /* CapabilityMask */
- *cap_mask = ntohs(rc_cap_mask);
+ *cap_mask = rc_cap_mask;
return 0;
}
-static void print_port(ib_portid_t * portid, uint16_t cap_mask, char *node_name,
- ibnd_node_t * node, int portnum, int *header_printed)
+static int print_data_cnts(ib_portid_t * portid, uint16_t cap_mask,
+ char *node_name, ibnd_node_t * node, int portnum,
+ int *header_printed)
+{
+ uint8_t pc[1024];
+ int i;
+ int start_field = IB_PC_XMT_BYTES_F;
+ int end_field = IB_PC_RCV_PKTS_F;
+
+ memset(pc, 0, 1024);
+
+ if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
+ if (!pma_query_via(pc, portid, portnum, ibd_timeout,
+ IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) {
+ IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d",
+ node_name, portid2str(portid), portnum);
+ return (1);
+ }
+ start_field = IB_PC_EXT_XMT_BYTES_F;
+ if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
+ end_field = IB_PC_EXT_RCV_MPKTS_F;
+ else
+ end_field = IB_PC_EXT_RCV_PKTS_F;
+ } else {
+ if (!pma_query_via(pc, portid, portnum, ibd_timeout,
+ IB_GSI_PORT_COUNTERS, ibmad_port)) {
+ IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d",
+ node_name, portid2str(portid), portnum);
+ return (1);
+ }
+ start_field = IB_PC_XMT_BYTES_F;
+ end_field = IB_PC_RCV_PKTS_F;
+ }
+
+ if (!*header_printed) {
+ printf("Data Counters for 0x%" PRIx64 " \"%s\"\n", node->guid,
+ node_name);
+ *header_printed = 1;
+ }
+
+ if (portnum == 0xFF)
+ printf(" GUID 0x%" PRIx64 " port ALL:", node->guid);
+ else
+ printf(" GUID 0x%" PRIx64 " port %d:",
+ node->guid, portnum);
+
+ for (i = start_field; i <= end_field; i++) {
+ uint64_t val64 = 0;
+ mad_decode_field(pc, i, (void *)&val64);
+ printf(" [%s == %" PRIu64 "]", mad_field_name(i), val64);
+ }
+ printf("\n");
+
+ if (portnum != 0xFF && port_config)
+ print_port_config(node_name, node, portnum);
+
+ return (0);
+}
+
+static int print_errors(ib_portid_t * portid, uint16_t cap_mask,
+ char *node_name, ibnd_node_t * node, int portnum,
+ int *header_printed)
{
uint8_t pc[1024];
+ uint8_t pce[1024];
+ uint8_t *pc_ext = NULL;
memset(pc, 0, 1024);
+ memset(pce, 0, 1024);
if (!pma_query_via(pc, portid, portnum, ibd_timeout,
IB_GSI_PORT_COUNTERS, ibmad_port)) {
IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d",
node_name, portid2str(portid), portnum);
- return;
+ return (0);
+ }
+
+ if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
+ if (!pma_query_via(pce, portid, portnum, ibd_timeout,
+ IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) {
+ IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d",
+ node_name, portid2str(portid), portnum);
+ return (0);
+ }
+ pc_ext = pce;
}
- if (!(cap_mask & 0x1000)) {
+
+ if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) {
/* if PortCounters:PortXmitWait not supported clear this counter */
uint32_t foo = 0;
mad_encode_field(pc, IB_PC_XMT_WAIT_F, &foo);
}
- print_results(portid, node_name, node, pc, portnum, header_printed);
+ return (print_results(portid, node_name, node, pc, portnum,
+ header_printed, pc_ext, cap_mask));
+}
+
+uint8_t *reset_pc_ext(void *rcvbuf, ib_portid_t * dest,
+ int port, unsigned mask, unsigned timeout,
+ const struct ibmad_port * srcport)
+{
+ ib_rpc_t rpc = { 0 };
+ int lid = dest->lid;
+
+ DEBUG("lid %u port %d mask 0x%x", lid, port, mask);
+
+ if (lid == -1) {
+ IBWARN("only lid routed is supported");
+ return NULL;
+ }
+
+ if (!mask)
+ mask = ~0;
+
+ rpc.mgtclass = IB_PERFORMANCE_CLASS;
+ rpc.method = IB_MAD_METHOD_SET;
+ rpc.attr.id = IB_GSI_PORT_COUNTERS_EXT;
+
+ memset(rcvbuf, 0, IB_MAD_SIZE);
+
+ /* Same for attribute IDs */
+ mad_set_field(rcvbuf, 0, IB_PC_EXT_PORT_SELECT_F, port);
+ mad_set_field(rcvbuf, 0, IB_PC_EXT_COUNTER_SELECT_F, mask);
+ rpc.attr.mod = 0;
+ rpc.timeout = timeout;
+ rpc.datasz = IB_PC_DATA_SZ;
+ rpc.dataoffs = IB_PC_DATA_OFFS;
+ if (!dest->qp)
+ dest->qp = 1;
+ if (!dest->qkey)
+ dest->qkey = IB_DEFAULT_QP1_QKEY;
+
+ return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
}
static void clear_port(ib_portid_t * portid, uint16_t cap_mask,
char *node_name, int port)
{
- uint8_t pc[1024];
+ uint8_t pc[1024] = { 0 };
/* bits defined in Table 228 PortCounters CounterSelect and
* CounterSelect2
*/
uint32_t mask = 0;
- if (!clear_errors && !clear_counts)
- return;
-
if (clear_errors) {
mask |= 0xFFF;
- if (cap_mask & 0x1000)
+ if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)
mask |= 0x10000;
}
if (clear_counts)
mask |= 0xF000;
- if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
- IB_GSI_PORT_COUNTERS, ibmad_port))
- IBERROR("Failed to reset errors %s port %d", node_name, port);
+ if (mask)
+ if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
+ IB_GSI_PORT_COUNTERS, ibmad_port))
+ IBERROR("Failed to reset errors %s port %d", node_name,
+ port);
- if (details && clear_errors) {
+ if (clear_errors && details) {
+ memset(pc, 0, 1024);
performance_reset_via(pc, portid, port, 0xf, ibd_timeout,
IB_GSI_PORT_XMIT_DISCARD_DETAILS,
ibmad_port);
+ memset(pc, 0, 1024);
performance_reset_via(pc, portid, port, 0x3f, ibd_timeout,
IB_GSI_PORT_RCV_ERROR_DETAILS,
ibmad_port);
}
+
+ if (clear_counts &&
+ (cap_mask &
+ (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP))) {
+ if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
+ mask = 0xFF;
+ else
+ mask = 0x0F;
+
+ if (!reset_pc_ext(pc, portid, port, mask, ibd_timeout,
+ ibmad_port))
+ IBERROR("Failed to reset extended data counters %s, "
+ "%s port %d", node_name, portid2str(portid),
+ port);
+ }
}
void print_node(ibnd_node_t * node, void *user_data)
@@ -425,28 +674,67 @@ void print_node(ibnd_node_t * node, void *user_data)
node_name = remap_node_name(node_name_map, node->guid, node->nodedesc);
- for (p = startport; p <= node->numports; p++) {
- if (node->ports[p]) {
- if (node->type == IB_NODE_SWITCH)
- ib_portid_set(&portid, node->smalid, 0, 0);
- else
- ib_portid_set(&portid, node->ports[p]->base_lid,
+ if (node->type == IB_NODE_SWITCH) {
+ ib_portid_set(&portid, node->smalid, 0, 0);
+ p = 0;
+ } else {
+ for (p = 1; p <= node->numports; p++) {
+ if (node->ports[p]) {
+ ib_portid_set(&portid,
+ node->ports[p]->base_lid,
0, 0);
+ break;
+ }
+ }
+ }
- if (query_cap_mask(&portid, node_name, p, &cap_mask) <
- 0)
- continue;
-
- if (cap_mask & 0x100)
- all_port_sup = 1;
+ if ((query_cap_mask(&portid, node_name, p, &cap_mask) == 0) &&
+ (cap_mask & IB_PM_ALL_PORT_SELECT))
+ all_port_sup = 1;
+
+ if (data_counters_only) {
+ for (p = startport; p <= node->numports; p++) {
+ if (node->ports[p]) {
+ if (node->type == IB_NODE_SWITCH)
+ ib_portid_set(&portid, node->smalid, 0, 0);
+ else
+ ib_portid_set(&portid, node->ports[p]->base_lid,
+ 0, 0);
+
+ print_data_cnts(&portid, cap_mask, node_name, node, p,
+ &header_printed);
+ summary.ports_checked++;
+ if (!all_port_sup)
+ clear_port(&portid, cap_mask, node_name, p);
+ }
+ }
+ } else {
+ if (all_port_sup)
+ if (!print_errors(&portid, cap_mask, node_name, node,
+ 0xFF, &header_printed)) {
+ summary.ports_checked += node->numports;
+ goto clear;
+ }
- print_port(&portid, cap_mask, node_name, node, p,
- &header_printed);
- if (!all_port_sup)
- clear_port(&portid, cap_mask, node_name, p);
+ for (p = startport; p <= node->numports; p++) {
+ if (node->ports[p]) {
+ if (node->type == IB_NODE_SWITCH)
+ ib_portid_set(&portid, node->smalid, 0, 0);
+ else
+ ib_portid_set(&portid, node->ports[p]->base_lid,
+ 0, 0);
+
+ print_errors(&portid, cap_mask, node_name, node, p,
+ &header_printed);
+ summary.ports_checked++;
+ if (!all_port_sup)
+ clear_port(&portid, cap_mask, node_name, p);
+ }
}
}
+clear:
+ summary.nodes_checked++;
if (all_port_sup)
clear_port(&portid, cap_mask, node_name, 0xFF);
@@ -512,10 +800,16 @@ static int process_opt(void *context, int ch, char *optarg)
case 7:
load_cache_file = strdup(optarg);
break;
+ case 8:
+ threshold_file = strdup(optarg);
+ break;
+ case 9:
+ data_counters_only = 1;
+ break;
case 'G':
case 'S':
- node_guid_str = optarg;
- node_guid = strtoull(optarg, 0, 0);
+ port_guid_str = optarg;
+ port_guid = strtoull(optarg, 0, 0);
break;
case 'D':
dr_path = strdup(optarg);
@@ -559,20 +853,24 @@ int main(int argc, char **argv)
{"suppress-common", 'c', 0, NULL,
"suppress some of the common counters"},
{"node-name-map", 1, 1, "<file>", "node name map file"},
- {"node-guid", 'G', 1, "<node_guid>", "query only <node_guid>"},
- {"", 'S', 1, "<node_guid>",
+ {"port-guid", 'G', 1, "<port_guid>",
+ "report the node containing the port specified by <port_guid>"},
+ {"", 'S', 1, "<port_guid>",
"Same as \"-G\" for backward compatibility"},
{"Direct", 'D', 1, "<dr_path>",
- "query only switch specified by <dr_path>"},
+ "report the node containing the port specified by <dr_path>"},
{"report-port", 'r', 0, NULL,
- "report port configuration information"},
+ "report port link information"},
+ {"threshold-file", 8, 1, NULL,
+ "specify an alternate threshold file, default: " DEF_THRES_FILE},
{"GNDN", 'R', 0, NULL,
"(This option is obsolete and does nothing)"},
- {"data", 2, 0, NULL, "include the data counters in the output"},
+ {"data", 2, 0, NULL, "include data counters for ports with errors"},
{"switch", 3, 0, NULL, "print data for switches only"},
{"ca", 4, 0, NULL, "print data for CA's only"},
{"router", 5, 0, NULL, "print data for routers only"},
{"details", 6, 0, NULL, "include transmit discard details"},
+ {"counters", 9, 0, NULL, "print data counters only"},
{"clear-errors", 'k', 0, NULL,
"Clear error counters after read"},
{"clear-counts", 'K', 0, NULL,
@@ -619,13 +917,13 @@ int main(int argc, char **argv)
NULL, ibmad_port)) < 0)
IBWARN("Failed to resolve %s; attempting full scan",
dr_path);
- } else if (node_guid_str) {
+ } else if (port_guid_str) {
if ((resolved =
- ib_resolve_portid_str_via(&portid, node_guid_str,
+ ib_resolve_portid_str_via(&portid, port_guid_str,
IB_DEST_GUID, ibd_sm_id,
ibmad_port)) < 0)
IBWARN("Failed to resolve %s; attempting full scan",
- node_guid_str);
+ port_guid_str);
}
if (load_cache_file) {
@@ -634,11 +932,14 @@ int main(int argc, char **argv)
exit(1);
}
} else {
- if (resolved >= 0 &&
- !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
+ if (resolved >= 0) {
+ if (!config.max_hops)
+ config.max_hops = 1;
+ if (!(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
&portid, &config)))
- IBWARN("Single node discover failed;"
- " attempting full scan");
+ IBWARN("Single node discover failed;"
+ " attempting full scan");
+ }
if (!fabric && !(fabric = ibnd_discover_fabric(ibd_ca,
ibd_ca_port,
@@ -650,34 +951,36 @@ int main(int argc, char **argv)
}
}
- report_suppressed();
+ set_thresholds(threshold_file);
- if (node_guid_str) {
- ibnd_node_t *node = ibnd_find_node_guid(fabric, node_guid);
- if (node)
- print_node(node, NULL);
+ if (port_guid_str) {
+ ibnd_port_t *port = ibnd_find_port_guid(fabric, port_guid);
+ if (port)
+ print_node(port->node, NULL);
else
fprintf(stderr, "Failed to find node: %s\n",
- node_guid_str);
+ port_guid_str);
} else if (dr_path) {
- ibnd_node_t *node = ibnd_find_node_dr(fabric, dr_path);
- uint8_t ni[IB_SMP_DATA_SIZE];
+ ibnd_port_t *port = ibnd_find_port_dr(fabric, dr_path);
+ uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
if (!smp_query_via(ni, &portid, IB_ATTR_NODE_INFO, 0,
ibd_timeout, ibmad_port)) {
rc = -1;
goto destroy_fabric;
}
- mad_decode_field(ni, IB_NODE_GUID_F, &(node_guid));
+ mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(port_guid));
- node = ibnd_find_node_guid(fabric, node_guid);
- if (node)
- print_node(node, NULL);
- else
+ port = ibnd_find_port_guid(fabric, port_guid);
+ if (port) {
+ print_node(port->node, NULL);
+ } else
fprintf(stderr, "Failed to find node: %s\n", dr_path);
} else
ibnd_iter_nodes(fabric, print_node, NULL);
+ print_summary();
+
destroy_fabric:
ibnd_destroy_fabric(fabric);
diff --git a/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES b/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES
index 8c529dd..ab323bc 100644
--- a/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES
@@ -22,6 +22,7 @@ TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib \
$(TARGETPATH)\*\libibnetdisc.lib
diff --git a/trunk/tools/infiniband-diags/src/ibroute.c b/trunk/tools/infiniband-diags/src/ibroute.c
index b765c84..7339218 100644
--- a/trunk/tools/infiniband-diags/src/ibroute.c
+++ b/trunk/tools/infiniband-diags/src/ibroute.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
- * Copyright (c) 2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2009-2011 Mellanox Technologies LTD. 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
@@ -130,7 +130,7 @@ int dump_mlid(char *str, int strlen, unsigned mlid, unsigned nports,
return i * 2;
}
-uint16_t mft[16][IB_MLIDS_IN_BLOCK];
+uint16_t mft[16][IB_MLIDS_IN_BLOCK] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0}, { 0 }, { 0 } };
char *dump_multicast_tables(ib_portid_t * portid, unsigned startlid,
unsigned endlid)
@@ -303,9 +303,9 @@ int dump_lid(char *str, int strlen, int lid, int valid)
char *dump_unicast_tables(ib_portid_t * portid, int startlid, int endlid)
{
- char lft[IB_SMP_DATA_SIZE];
- char nd[IB_SMP_DATA_SIZE];
- uint8_t sw[IB_SMP_DATA_SIZE];
+ char lft[IB_SMP_DATA_SIZE] = { 0 };
+ char nd[IB_SMP_DATA_SIZE] = { 0 };
+ uint8_t sw[IB_SMP_DATA_SIZE] = { 0 };
char str[200], *s;
uint64_t nodeguid;
int block, i, e, top;
diff --git a/trunk/tools/infiniband-diags/src/ibroute/SOURCES b/trunk/tools/infiniband-diags/src/ibroute/SOURCES
index 5e7763d..26bf224 100644
--- a/trunk/tools/infiniband-diags/src/ibroute/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibroute/SOURCES
@@ -21,6 +21,7 @@ TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/ibsendtrap.c b/trunk/tools/infiniband-diags/src/ibsendtrap.c
index 1b91595..618706b 100644
--- a/trunk/tools/infiniband-diags/src/ibsendtrap.c
+++ b/trunk/tools/infiniband-diags/src/ibsendtrap.c
@@ -2,6 +2,7 @@
* Copyright (c) 2008 Lawrence Livermore National Security
* Copyright (c) 2008-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
*
* Produced at Lawrence Livermore National Laboratory.
* Written by Ira Weiny <weiny2 at llnl.gov>.
@@ -56,7 +57,7 @@ int error_port = 1;
static uint16_t get_node_type(ib_portid_t * port)
{
uint16_t node_type = IB_NODE_TYPE_CA;
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
if (smp_query_via(data, port, IB_ATTR_NODE_INFO, 0, 0, srcport))
node_type = (uint16_t) mad_get_field(data, 0, IB_NODE_TYPE_F);
@@ -65,7 +66,7 @@ static uint16_t get_node_type(ib_portid_t * port)
static uint32_t get_cap_mask(ib_portid_t * port)
{
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
uint32_t cap_mask = 0;
if (smp_query_via(data, port, IB_ATTR_PORT_INFO, 0, 0, srcport))
diff --git a/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES b/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES
index 6ebf711..51b9ddd 100644
--- a/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES
@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/ibstat.c b/trunk/tools/infiniband-diags/src/ibstat.c
index c44d8c4..92fcd0f 100644
--- a/trunk/tools/infiniband-diags/src/ibstat.c
+++ b/trunk/tools/infiniband-diags/src/ibstat.c
@@ -72,10 +72,9 @@ static void ca_dump(umad_ca_t * ca)
printf("\tNumber of ports: %d\n", ca->numports);
printf("\tFirmware version: %s\n", ca->fw_ver);
printf("\tHardware version: %s\n", ca->hw_ver);
- printf("\tNode GUID: 0x%016llx\n",
- (long long unsigned)ntohll(ca->node_guid));
- printf("\tSystem image GUID: 0x%016llx\n",
- (long long unsigned)ntohll(ca->system_guid));
+ printf("\tNode GUID: 0x%016" PRIx64 "\n", ntohll(ca->node_guid));
+ printf("\tSystem image GUID: 0x%016" PRIx64 "\n",
+ ntohll(ca->system_guid));
}
static char *port_state_str[] = {
@@ -115,16 +114,17 @@ static int port_dump(umad_port_t * port, int alone)
(unsigned)port->state <=
4 ? port_state_str[port->state] : "???");
printf("%sPhysical state: %s\n", pre,
- (unsigned)port->state <=
+ (unsigned)port->phys_state <=
7 ? port_phy_state_str[port->phys_state] : "???");
printf("%sRate: %d\n", pre, port->rate);
printf("%sBase lid: %d\n", pre, port->base_lid);
printf("%sLMC: %d\n", pre, port->lmc);
printf("%sSM lid: %d\n", pre, port->sm_lid);
printf("%sCapability mask: 0x%08x\n", pre, ntohl(port->capmask));
- printf("%sPort GUID: 0x%016llx\n", pre,
- (long long unsigned)ntohll(port->port_guid));
+ printf("%sPort GUID: 0x%016" PRIx64 "\n", pre, ntohll(port->port_guid));
+#ifdef HAVE_UMAD_PORT_LINK_LAYER
printf("%sLink layer: %s\n", pre, port->link_layer);
+#endif
return 0;
}
@@ -182,8 +182,7 @@ static int ports_list(char names[][UMAD_CA_NAME_LEN], int n)
for (i = 0; i < found; i++)
if (guids[i])
- printf("0x%016llx\n",
- (long long unsigned)ntohll(guids[i]));
+ printf("0x%016" PRIx64 "\n", ntohll(guids[i]));
return found;
}
diff --git a/trunk/tools/infiniband-diags/src/ibstat/SOURCES b/trunk/tools/infiniband-diags/src/ibstat/SOURCES
index 03c809c..599e656 100644
--- a/trunk/tools/infiniband-diags/src/ibstat/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibstat/SOURCES
@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES b/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES
index d1add5c..f7c92f5 100644
--- a/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES
@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/ibtracert.c b/trunk/tools/infiniband-diags/src/ibtracert.c
index 80694f2..c9f511b 100644
--- a/trunk/tools/infiniband-diags/src/ibtracert.c
+++ b/trunk/tools/infiniband-diags/src/ibtracert.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2010,2011 Mellanox Technologies LTD. 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
@@ -118,9 +119,11 @@ static int get_node(Node * node, Port * port, ib_portid_t * portid)
void *pi = port->portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;
char *s, *e;
+ memset(ni, 0, sizeof(node->nodeinfo));
if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, timeout, srcport))
return -1;
+ memset(nd, 0, sizeof(node->nodedesc));
if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout, srcport))
return -1;
@@ -131,6 +134,7 @@ static int get_node(Node * node, Port * port, ib_portid_t * portid)
*s = ' ';
}
+ memset(pi, 0, sizeof(port->portinfo));
if (!smp_query_via(pi, portid, IB_ATTR_PORT_INFO, 0, timeout, srcport))
return -1;
@@ -153,6 +157,7 @@ static int switch_lookup(Switch * sw, ib_portid_t * portid, int lid)
{
void *si = sw->switchinfo, *fdb = sw->fdb;
+ memset(si, 0, sizeof(sw->switchinfo));
if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout,
srcport))
return -1;
@@ -163,6 +168,7 @@ static int switch_lookup(Switch * sw, ib_portid_t * portid, int lid)
if (lid >= sw->linearcap && lid > sw->linearFDBtop)
return -1;
+ memset(fdb, 0, sizeof(sw->fdb));
if (!smp_query_via(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64,
timeout, srcport))
return -1;
@@ -382,7 +388,7 @@ static int insert_node(Node * new)
static int get_port(Port * port, int portnum, ib_portid_t * portid)
{
- char portinfo[64];
+ char portinfo[64] = { 0 };
void *pi = portinfo;
port->portnum = portnum;
@@ -445,6 +451,7 @@ static int switch_mclookup(Node * node, ib_portid_t * portid, int mlid,
memset(map, 0, 256);
+ memset(si, 0, sizeof(sw.switchinfo));
if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout,
srcport))
return -1;
@@ -460,6 +467,7 @@ static int switch_mclookup(Node * node, ib_portid_t * portid, int mlid,
maxsets = (node->numports + 15) / 16; /* round up */
for (set = 0; set < maxsets; set++) {
+ memset(mdb, 0, sizeof(mdb));
if (!smp_query_via(mdb, portid, IB_ATTR_MULTICASTFORWTBL,
block | (set << 28), timeout, srcport))
return -1;
@@ -685,7 +693,7 @@ free_name:
static int resolve_lid(ib_portid_t * portid, const void *srcport)
{
- uint8_t portinfo[64];
+ uint8_t portinfo[64] = { 0 };
uint16_t lid;
if (!smp_query_via(portinfo, portid, IB_ATTR_PORT_INFO, 0, 0, srcport))
@@ -749,7 +757,7 @@ int main(int argc, char **argv)
NULL,
};
- ibdiag_process_opts(argc, argv, NULL, NULL, opts, process_opt,
+ ibdiag_process_opts(argc, argv, NULL, "D", opts, process_opt,
usage_args, usage_examples);
f = stdout;
diff --git a/trunk/tools/infiniband-diags/src/ibtracert/SOURCES b/trunk/tools/infiniband-diags/src/ibtracert/SOURCES
index 65f8c0d..63c9982 100644
--- a/trunk/tools/infiniband-diags/src/ibtracert/SOURCES
+++ b/trunk/tools/infiniband-diags/src/ibtracert/SOURCES
@@ -21,6 +21,7 @@ TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES b/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES
index d026c0e..65b2fa5 100644
--- a/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES
+++ b/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES
@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/perfquery.c b/trunk/tools/infiniband-diags/src/perfquery.c
index 07a9226..0ea68aa 100644
--- a/trunk/tools/infiniband-diags/src/perfquery.c
+++ b/trunk/tools/infiniband-diags/src/perfquery.c
@@ -2,6 +2,7 @@
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -45,6 +46,7 @@
#include <infiniband/umad.h>
#include <infiniband/mad.h>
+#include <infiniband/iba/ib_types.h>
#include "ibdiag_common.h"
@@ -186,7 +188,8 @@ static void aggregate_perfcounters(void)
aggregate_32bit(&perf_count.xmtwait, val);
}
-static void output_aggregate_perfcounters(ib_portid_t * portid)
+static void output_aggregate_perfcounters(ib_portid_t * portid,
+ uint16_t cap_mask)
{
char buf[1024];
uint32_t val = ALL_PORTS;
@@ -220,11 +223,11 @@ static void output_aggregate_perfcounters(ib_portid_t * portid)
mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
- printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS,
- buf);
+ printf("# Port counters: %s port %d (CapMask: 0x%02X)\n%s",
+ portid2str(portid), ALL_PORTS, ntohs(cap_mask), buf);
}
-static void aggregate_perfcounters_ext(void)
+static void aggregate_perfcounters_ext(uint16_t cap_mask)
{
uint32_t val;
uint64_t val64;
@@ -241,21 +244,27 @@ static void aggregate_perfcounters_ext(void)
aggregate_64bit(&perf_count_ext.portxmitpkts, val64);
mad_decode_field(pc, IB_PC_EXT_RCV_PKTS_F, &val64);
aggregate_64bit(&perf_count_ext.portrcvpkts, val64);
- mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64);
- aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64);
- mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64);
- aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64);
- mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64);
- aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64);
- mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64);
- aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64);
+
+ if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) {
+ mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64);
+ aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64);
+ mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64);
+ aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64);
+ mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64);
+ aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64);
+ mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64);
+ aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64);
+ }
}
-static void output_aggregate_perfcounters_ext(ib_portid_t * portid)
+static void output_aggregate_perfcounters_ext(ib_portid_t * portid,
+ uint16_t cap_mask)
{
char buf[1024];
uint32_t val = ALL_PORTS;
+ memset(buf, 0, 1024);
+
/* set port_select to 255 to emulate AllPortSelect */
mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val);
mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F,
@@ -267,19 +276,22 @@ static void output_aggregate_perfcounters_ext(ib_portid_t * portid)
mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F,
&perf_count_ext.portxmitpkts);
mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts);
- mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F,
- &perf_count_ext.portunicastxmitpkts);
- mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F,
- &perf_count_ext.portunicastrcvpkts);
- mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F,
- &perf_count_ext.portmulticastxmitpkits);
- mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F,
- &perf_count_ext.portmulticastrcvpkts);
+
+ if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) {
+ mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F,
+ &perf_count_ext.portunicastxmitpkts);
+ mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F,
+ &perf_count_ext.portunicastrcvpkts);
+ mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F,
+ &perf_count_ext.portmulticastxmitpkits);
+ mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F,
+ &perf_count_ext.portmulticastrcvpkts);
+ }
mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
- printf("# Port extended counters: %s port %d\n%s", portid2str(portid),
- ALL_PORTS, buf);
+ printf("# Port extended counters: %s port %d (CapMask: 0x%02X)\n%s",
+ portid2str(portid), ALL_PORTS, ntohs(cap_mask), buf);
}
static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
@@ -288,10 +300,11 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
char buf[1024];
if (extended != 1) {
+ memset(pc, 0, sizeof(pc));
if (!pma_query_via(pc, portid, port, timeout,
IB_GSI_PORT_COUNTERS, srcport))
IBERROR("perfquery");
- if (!(cap_mask & 0x1000)) {
+ if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) {
/* if PortCounters:PortXmitWait not supported clear this counter */
VERBOSE("PortXmitWait not indicated"
" so ignore this counter");
@@ -304,19 +317,24 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
else
mad_dump_fields(buf, sizeof buf, pc, sizeof pc,
IB_PC_FIRST_F,
- (cap_mask & 0x1000)?IB_PC_LAST_F:(IB_PC_RCV_PKTS_F+1));
+ (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)?IB_PC_LAST_F:(IB_PC_RCV_PKTS_F+1));
} else {
- if (!(cap_mask & 0x200)) /* 1.2 errata: bit 9 is extended counter support */
+ /* 1.2 errata: bit 9 is extended counter support
+ * bit 10 is extended counter NoIETF
+ */
+ if (!(cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) &&
+ !(cap_mask & IB_PM_EXT_WIDTH_NOIETF_SUP))
IBWARN
- ("PerfMgt ClassPortInfo 0x%x extended counters not indicated\n",
- cap_mask);
+ ("PerfMgt ClassPortInfo 0x%x; No extended counter support indicated\n",
+ ntohs(cap_mask));
+ memset(pc, 0, sizeof(pc));
if (!pma_query_via(pc, portid, port, timeout,
IB_GSI_PORT_COUNTERS_EXT, srcport))
IBERROR("perfextquery");
if (aggregate)
- aggregate_perfcounters_ext();
+ aggregate_perfcounters_ext(cap_mask);
else
mad_dump_perfcounters_ext(buf, sizeof buf, pc,
sizeof pc);
@@ -324,17 +342,20 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
if (!aggregate) {
if (extended)
- printf("# Port extended counters: %s port %d\n%s",
- portid2str(portid), port, buf);
+ printf("# Port extended counters: %s port %d "
+ "(CapMask: 0x%02X)\n%s",
+ portid2str(portid), port, ntohs(cap_mask), buf);
else
- printf("# Port counters: %s port %d\n%s",
- portid2str(portid), port, buf);
+ printf("# Port counters: %s port %d "
+ "(CapMask: 0x%02X)\n%s",
+ portid2str(portid), port, ntohs(cap_mask), buf);
}
}
static void reset_counters(int extended, int timeout, int mask,
ib_portid_t * portid, int port)
{
+ memset(pc, 0, sizeof(pc));
if (extended != 1) {
if (!performance_reset_via(pc, portid, port, mask, timeout,
IB_GSI_PORT_COUNTERS, srcport))
@@ -347,7 +368,9 @@ static void reset_counters(int extended, int timeout, int mask,
}
static int reset, reset_only, all_ports, loop_ports, port, extended, xmt_sl,
- rcv_sl, xmt_disc, rcv_err, smpl_ctl;
+ rcv_sl, xmt_disc, rcv_err, smpl_ctl, oprcvcounters, flowctlcounters,
+ vloppackets, vlopdata, vlxmitflowctlerrors, vlxmitcounters, swportvlcong,
+ rcvcc, slrcvfecn, slrcvbecn, xmitcc, vlxmittimecc;
static void common_func(ib_portid_t * portid, int port_num, int mask,
unsigned query, unsigned reset,
@@ -357,6 +380,7 @@ static void common_func(ib_portid_t * portid, int port_num, int mask,
char buf[1024];
if (query) {
+ memset(pc, 0, sizeof(pc));
if (!pma_query_via(pc, portid, port_num, ibd_timeout, attr,
srcport))
IBERROR("cannot query %s", name);
@@ -367,6 +391,7 @@ static void common_func(ib_portid_t * portid, int port_num, int mask,
portid2str(portid), port_num, buf);
}
+ memset(pc, 0, sizeof(pc));
if (reset && !performance_reset_via(pc, portid, port, mask, ibd_timeout,
attr, srcport))
IBERROR("cannot reset %s", name);
@@ -400,10 +425,95 @@ static void rcv_err_query(ib_portid_t * portid, int port, int mask)
mad_dump_perfcounters_rcv_err);
}
+static void oprcvcounters_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortOpRcvCounters", IB_GSI_PORT_PORT_OP_RCV_COUNTERS,
+ mad_dump_perfcounters_port_op_rcv_counters);
+}
+
+static void flowctlcounters_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortFlowCtlCounters", IB_GSI_PORT_PORT_FLOW_CTL_COUNTERS,
+ mad_dump_perfcounters_port_flow_ctl_counters);
+}
+
+static void vloppackets_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortVLOpPackets", IB_GSI_PORT_PORT_VL_OP_PACKETS,
+ mad_dump_perfcounters_port_vl_op_packet);
+}
+
+static void vlopdata_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortVLOpData", IB_GSI_PORT_PORT_VL_OP_DATA,
+ mad_dump_perfcounters_port_vl_op_data);
+}
+
+static void vlxmitflowctlerrors_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortVLXmitFlowCtlUpdateErrors", IB_GSI_PORT_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS,
+ mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors);
+}
+
+static void vlxmitcounters_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortVLXmitWaitCounters", IB_GSI_PORT_PORT_VL_XMIT_WAIT_COUNTERS,
+ mad_dump_perfcounters_port_vl_xmit_wait_counters);
+}
+
+static void swportvlcong_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "SwPortVLCongestion", IB_GSI_SW_PORT_VL_CONGESTION,
+ mad_dump_perfcounters_sw_port_vl_congestion);
+}
+
+static void rcvcc_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortRcvConCtrl", IB_GSI_PORT_RCV_CON_CTRL,
+ mad_dump_perfcounters_rcv_con_ctrl);
+}
+
+static void slrcvfecn_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortSLRcvFECN", IB_GSI_PORT_SL_RCV_FECN,
+ mad_dump_perfcounters_sl_rcv_fecn);
+}
+
+static void slrcvbecn_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortSLRcvBECN", IB_GSI_PORT_SL_RCV_BECN,
+ mad_dump_perfcounters_sl_rcv_becn);
+}
+
+static void xmitcc_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortXmitConCtrl", IB_GSI_PORT_XMIT_CON_CTRL,
+ mad_dump_perfcounters_xmit_con_ctrl);
+}
+
+static void vlxmittimecc_query(ib_portid_t * portid, int port, int mask)
+{
+ common_func(portid, port, mask, !reset_only, (reset_only || reset),
+ "PortVLXmitTimeCong", IB_GSI_PORT_VL_XMIT_TIME_CONG,
+ mad_dump_perfcounters_vl_xmit_time_cong);
+}
+
void dump_portsamples_control(ib_portid_t * portid, int port)
{
char buf[1024];
+ memset(pc, 0, sizeof(pc));
if (!pma_query_via(pc, portid, port, ibd_timeout,
IB_GSI_PORT_SAMPLES_CONTROL, srcport))
IBERROR("sampctlquery");
@@ -434,6 +544,42 @@ static int process_opt(void *context, int ch, char *optarg)
case 'c':
smpl_ctl = 1;
break;
+ case 1:
+ oprcvcounters = 1;
+ break;
+ case 2:
+ flowctlcounters = 1;
+ break;
+ case 3:
+ vloppackets = 1;
+ break;
+ case 4:
+ vlopdata = 1;
+ break;
+ case 5:
+ vlxmitflowctlerrors = 1;
+ break;
+ case 6:
+ vlxmitcounters = 1;
+ break;
+ case 7:
+ swportvlcong = 1;
+ break;
+ case 8:
+ rcvcc = 1;
+ break;
+ case 9:
+ slrcvfecn = 1;
+ break;
+ case 10:
+ slrcvbecn = 1;
+ break;
+ case 11:
+ xmitcc = 1;
+ break;
+ case 12:
+ vlxmittimecc = 1;
+ break;
case 'a':
all_ports++;
port = ALL_PORTS;
@@ -463,7 +609,7 @@ int main(int argc, char **argv)
uint16_t cap_mask;
int all_ports_loop = 0;
int node_type, num_ports = 0;
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
int start_port = 1;
int enhancedport0;
int i;
@@ -474,6 +620,18 @@ int main(int argc, char **argv)
{"rcvsl", 'S', 0, NULL, "show Rcv SL port counters"},
{"xmtdisc", 'D', 0, NULL, "show Xmt Discard Details"},
{"rcverr", 'E', 0, NULL, "show Rcv Error Details"},
+ {"oprcvcounters", 1, 0, NULL, "show Rcv Counters per Op code"},
+ {"flowctlcounters", 2, 0, NULL, "show flow control counters"},
+ {"vloppackets", 3, 0, NULL, "show packets received per Op code per VL"},
+ {"vlopdata", 4, 0, NULL, "show data received per Op code per VL"},
+ {"vlxmitflowctlerrors", 5, 0, NULL, "show flow control update errors per VL"},
+ {"vlxmitcounters", 6, 0, NULL, "show ticks waiting to transmit counters per VL"},
+ {"swportvlcong", 7, 0, NULL, "show sw port VL congestion"},
+ {"rcvcc", 8, 0, NULL, "show Rcv congestion control counters"},
+ {"slrcvfecn", 9, 0, NULL, "show SL Rcv FECN counters"},
+ {"slrcvbecn", 10, 0, NULL, "show SL Rcv BECN counters"},
+ {"xmitcc", 11, 0, NULL, "show Xmit congestion control counters"},
+ {"vlxmittimecc", 12, 0, NULL, "show VL Xmit Time congestion control counters"},
{"smplctl", 'c', 0, NULL, "show samples control"},
{"all_ports", 'a', 0, NULL, "show aggregated counters"},
{"loop_ports", 'l', 0, NULL, "iterate through each port"},
@@ -522,13 +680,13 @@ int main(int argc, char **argv)
}
/* PerfMgt ClassPortInfo is a required attribute */
+ memset(pc, 0, sizeof(pc));
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 */
- cap_mask = ntohs(cap_mask);
- if (!(cap_mask & 0x100)) { /* bit 8 is AllPortSelect */
+ if (!(cap_mask & IB_PM_ALL_PORT_SELECT)) { /* bit 8 is AllPortSelect */
if (!all_ports && port == ALL_PORTS)
IBERROR("AllPortSelect not supported");
if (all_ports)
@@ -555,11 +713,72 @@ int main(int argc, char **argv)
goto done;
}
+ if (oprcvcounters) {
+ oprcvcounters_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (flowctlcounters) {
+ flowctlcounters_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (vloppackets) {
+ vloppackets_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (vlopdata) {
+ vlopdata_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (vlxmitflowctlerrors) {
+ vlxmitflowctlerrors_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (vlxmitcounters) {
+ vlxmitcounters_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (swportvlcong) {
+ swportvlcong_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (rcvcc) {
+ rcvcc_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (slrcvfecn) {
+ slrcvfecn_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (slrcvbecn) {
+ slrcvbecn_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (xmitcc) {
+ xmitcc_query(&portid, port, mask);
+ goto done;
+ }
+
+ if (vlxmittimecc) {
+ vlxmittimecc_query(&portid, port, mask);
+ goto done;
+ }
+
if (smpl_ctl) {
dump_portsamples_control(&portid, port);
goto done;
}
+
if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
if (smp_query_via(data, &portid, IB_ATTR_NODE_INFO, 0, 0,
srcport) < 0)
@@ -593,9 +812,11 @@ int main(int argc, char **argv)
&& !loop_ports));
if (all_ports_loop && !loop_ports) {
if (extended != 1)
- output_aggregate_perfcounters(&portid);
+ output_aggregate_perfcounters(&portid,
+ cap_mask);
else
- output_aggregate_perfcounters_ext(&portid);
+ output_aggregate_perfcounters_ext(&portid,
+ cap_mask);
}
} else
dump_perfcounters(extended, ibd_timeout, cap_mask, &portid,
@@ -605,7 +826,7 @@ int main(int argc, char **argv)
goto done;
do_reset:
- if (argc <= 2 && !extended && (cap_mask & 0x1000))
+ if (argc <= 2 && !extended && (cap_mask & IB_PM_PC_XMIT_WAIT_SUP))
mask |= (1 << 16); /* reset portxmitwait */
if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
diff --git a/trunk/tools/infiniband-diags/src/perfquery/SOURCES b/trunk/tools/infiniband-diags/src/perfquery/SOURCES
index 7e0079b..c71dfac 100644
--- a/trunk/tools/infiniband-diags/src/perfquery/SOURCES
+++ b/trunk/tools/infiniband-diags/src/perfquery/SOURCES
@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/saquery.c b/trunk/tools/infiniband-diags/src/saquery.c
index 5e9a5ad..f82772f 100644
--- a/trunk/tools/infiniband-diags/src/saquery.c
+++ b/trunk/tools/infiniband-diags/src/saquery.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2006,2007 The Regents of the University of California.
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
*
@@ -48,7 +48,6 @@
#include <ctype.h>
#include <string.h>
#include <errno.h>
-#include <assert.h>
#define _GNU_SOURCE
#include <getopt.h>
@@ -60,19 +59,6 @@
#include "ibdiag_common.h"
-struct bind_handle {
- int fd, agent;
- ib_portid_t dport;
-};
-
-struct query_res {
- int status;
- unsigned result_cnt;
- void *p_result_madw;
-};
-
-typedef struct bind_handle *bind_handle_t;
-
struct query_params {
ib_gid_t sgid, dgid, gid, mgid;
uint16_t slid, dlid, mlid;
@@ -106,7 +92,6 @@ static uint64_t smkey = 1;
*/
#define MAX_PORTS (8)
#define DEFAULT_SA_TIMEOUT_MS (1000)
-static struct query_res result;
enum {
ALL,
@@ -124,119 +109,6 @@ int requested_lid_flag = 0;
uint64_t requested_guid = 0;
int requested_guid_flag = 0;
-#define SA_ERR_UNKNOWN IB_SA_MAD_STATUS_PRIO_SUGGESTED
-
-const char *ib_sa_error_str[] = {
- "SA_NO_ERROR",
- "SA_ERR_NO_RESOURCES",
- "SA_ERR_REQ_INVALID",
- "SA_ERR_NO_RECORDS",
- "SA_ERR_TOO_MANY_RECORDS",
- "SA_ERR_REQ_INVALID_GID",
- "SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
- "SA_ERR_REQ_DENIED",
- "SA_ERR_STATUS_PRIO_SUGGESTED",
- "SA_ERR_UNKNOWN"
-};
-
-static inline const char *ib_sa_err_str(IN uint8_t status)
-{
- if (status > SA_ERR_UNKNOWN)
- status = SA_ERR_UNKNOWN;
- return (ib_sa_error_str[status]);
-}
-
-static inline void report_err(int status)
-{
- int st = status & 0xff;
- char sm_err_str[64] = { 0 };
- char sa_err_str[64] = { 0 };
-
- if (st)
- sprintf(sm_err_str, " SM(%s)", ib_get_err_str(st));
-
- st = status >> 8;
- if (st)
- sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
-
- fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
- status, sm_err_str, sa_err_str);
-}
-
-static int sa_query(struct bind_handle *h, uint8_t method,
- uint16_t attr, uint32_t mod, uint64_t comp_mask,
- uint64_t sm_key, void *data)
-{
- ib_rpc_t rpc;
- void *umad, *mad;
- int ret, offset, len = 256;
-
- memset(&rpc, 0, sizeof(rpc));
- rpc.mgtclass = IB_SA_CLASS;
- rpc.method = method;
- rpc.attr.id = attr;
- rpc.attr.mod = mod;
- rpc.mask = comp_mask;
- rpc.datasz = IB_SA_DATA_SIZE;
- rpc.dataoffs = IB_SA_DATA_OFFS;
-
- umad = calloc(1, len + umad_size());
- if (!umad)
- IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));
-
- mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
-
- mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
-
- if (ibdebug > 1)
- xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
-
- ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
- if (ret < 0)
- IBPANIC("umad_send failed: attr %u: %s\n",
- attr, strerror(errno));
-
-recv_mad:
- ret = umad_recv(h->fd, umad, &len, ibd_timeout);
- if (ret < 0) {
- if (errno == ENOSPC) {
- umad = realloc(umad, umad_size() + len);
- goto recv_mad;
- }
- IBPANIC("umad_recv failed: attr 0x%x: %s\n", attr,
- strerror(errno));
- }
-
- if ((ret = umad_status(umad)))
- return ret;
-
- mad = umad_get_mad(umad);
-
- if (ibdebug > 1)
- xdump(stdout, "SA Response:\n", mad, len);
-
- method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
- offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
- result.status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
- result.p_result_madw = mad;
- if (result.status)
- result.result_cnt = 0;
- else if (method != IB_MAD_METHOD_GET_TABLE)
- result.result_cnt = 1;
- else if (!offset)
- result.result_cnt = 0;
- else
- result.result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
-
- return 0;
-}
-
-static void *get_query_rec(void *mad, unsigned i)
-{
- int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
- return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
-}
-
static unsigned valid_gid(ib_gid_t * gid)
{
ib_gid_t zero_gid;
@@ -418,7 +290,7 @@ static void dump_portinfo_record(void *data)
static void dump_one_portinfo_record(void *data)
{
- char buf[2048], buf2[4096];
+ char buf[2300], buf2[4096];
ib_portinfo_record_t *pir = data;
ib_port_info_t *pi = &pir->port_info;
@@ -428,9 +300,9 @@ static void dump_one_portinfo_record(void *data)
"\tRID:\n"
"\t\tEndPortLid..............%u\n"
"\t\tPortNum.................%u\n"
- "\t\tReserved................0x%x\n"
+ "\t\tOptions.................0x%x\n"
"\tPortInfo dump:\n\t\t%s",
- cl_ntoh16(pir->lid), pir->port_num, pir->resv, buf2);
+ cl_ntoh16(pir->lid), pir->port_num, pir->options, buf2);
}
static void dump_one_mcmember_record(void *data)
@@ -461,7 +333,7 @@ static void dump_one_mcmember_record(void *data)
inet_ntop(AF_INET6, mr->port_gid.raw, gid, sizeof(gid)),
cl_ntoh32(mr->qkey), cl_ntoh16(mr->mlid), mr->mtu, mr->tclass,
cl_ntoh16(mr->pkey), mr->rate, mr->pkt_life, sl,
- cl_ntoh32(flow), hop, scope, join, mr->proxy_join);
+ flow, hop, scope, join, mr->proxy_join);
}
static void dump_multicast_group_record(void *data)
@@ -482,11 +354,11 @@ static void dump_multicast_group_record(void *data)
p_mcmr->mtu, cl_ntoh16(p_mcmr->pkey), p_mcmr->rate, sl);
}
-static void dump_multicast_member_record(void *data)
+static void dump_multicast_member_record(ib_member_rec_t *p_mcmr,
+ struct sa_query_result *nr_result)
{
char gid_str[INET6_ADDRSTRLEN];
char gid_str2[INET6_ADDRSTRLEN];
- ib_member_rec_t *p_mcmr = data;
uint16_t mlid = cl_ntoh16(p_mcmr->mlid);
unsigned i = 0;
char *node_name = "<unknown>";
@@ -495,8 +367,8 @@ static void dump_multicast_member_record(void *data)
* this port gid interface id.
* This gives us a node name to print, if available.
*/
- for (i = 0; i < result.result_cnt; i++) {
- ib_node_record_t *nr = get_query_rec(result.p_result_madw, i);
+ for (i = 0; i < nr_result->result_cnt; i++) {
+ ib_node_record_t *nr = sa_get_query_rec(nr_result->p_result_madw, i);
if (nr->node_info.port_guid ==
p_mcmr->port_gid.unicast.interface_id) {
node_name =
@@ -781,6 +653,31 @@ static void dump_one_lft_record(void *data)
printf("\n");
}
+static void dump_one_guidinfo_record(void *data)
+{
+ ib_guidinfo_record_t *gir = data;
+ printf("GUIDInfo Record dump:\n"
+ "\t\tLID........................%u\n"
+ "\t\tBlock......................%u\n"
+ "\t\tGUID 0.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 1.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 2.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 3.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 4.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 5.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 6.....................0x%016" PRIx64 "\n"
+ "\t\tGUID 7.....................0x%016" PRIx64 "\n",
+ cl_ntoh16(gir->lid), gir->block_num,
+ cl_ntoh64(gir->guid_info.guid[0]),
+ cl_ntoh64(gir->guid_info.guid[1]),
+ cl_ntoh64(gir->guid_info.guid[2]),
+ cl_ntoh64(gir->guid_info.guid[3]),
+ cl_ntoh64(gir->guid_info.guid[4]),
+ cl_ntoh64(gir->guid_info.guid[5]),
+ cl_ntoh64(gir->guid_info.guid[6]),
+ cl_ntoh64(gir->guid_info.guid[7]));
+}
+
static void dump_one_mft_record(void *data)
{
ib_mft_record_t *mftr = data;
@@ -788,53 +685,48 @@ static void dump_one_mft_record(void *data)
unsigned block = cl_ntoh16(mftr->position_block_num) &
IB_MCAST_BLOCK_ID_MASK_HO;
int i;
+ unsigned offset;
+
printf("MFT Record dump:\n"
"\t\tLID........................%u\n"
"\t\tPosition...................%u\n"
"\t\tBlock......................%u\n"
"\t\tMFT:\n\t\tMLID\tPort Mask\n",
cl_ntoh16(mftr->lid), position, block);
+ offset = IB_LID_MCAST_START_HO + block * 32;
for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++)
- printf("\t\t0x%x\t0x%x\n",
- IB_LID_MCAST_START_HO + block * 64 + i,
- cl_ntoh16(mftr->mft[i]));
+ printf("\t\t0x%04x\t0x%04x\n",
+ offset + i, cl_ntoh16(mftr->mft[i]));
printf("\n");
}
-static void dump_results(struct query_res *r, void (*dump_func) (void *))
+static void dump_results(struct sa_query_result *r, void (*dump_func) (void *))
{
unsigned i;
for (i = 0; i < r->result_cnt; i++) {
- void *data = get_query_rec(r->p_result_madw, i);
+ void *data = sa_get_query_rec(r->p_result_madw, i);
dump_func(data);
}
}
-static void return_mad(void)
-{
- if (result.p_result_madw) {
- free((uint8_t *) result.p_result_madw - umad_size());
- result.p_result_madw = NULL;
- }
-}
-
/**
* Get any record(s)
*/
static int get_any_records(bind_handle_t h,
uint16_t attr_id, uint32_t attr_mod,
- ib_net64_t comp_mask, void *attr, uint64_t sm_key)
+ ib_net64_t comp_mask, void *attr, uint64_t sm_key,
+ struct sa_query_result *result)
{
int ret = sa_query(h, IB_MAD_METHOD_GET_TABLE, attr_id, attr_mod,
- cl_ntoh64(comp_mask), sm_key, attr);
+ cl_ntoh64(comp_mask), sm_key, attr, result);
if (ret) {
fprintf(stderr, "Query SA failed: %s\n", ib_get_err_str(ret));
return ret;
}
- if (result.status != IB_SUCCESS) {
- report_err(result.status);
- return result.status;
+ if (result->status != IB_SA_MAD_STATUS_SUCCESS) {
+ sa_report_err(result->status);
+ return EIO;
}
return ret;
@@ -845,33 +737,37 @@ static int get_and_dump_any_records(bind_handle_t h, uint16_t attr_id,
void *attr, uint64_t sm_key,
void (*dump_func) (void *))
{
+ struct sa_query_result result;
int ret = get_any_records(h, attr_id, attr_mod, comp_mask, attr,
- sm_key);
+ sm_key, &result);
if (ret)
return ret;
dump_results(&result, dump_func);
-
+ sa_free_result_mad(&result);
return 0;
}
/**
* Get all the records available for requested query type.
*/
-static int get_all_records(bind_handle_t h, uint16_t attr_id, int trusted)
+static int get_all_records(bind_handle_t h, uint16_t attr_id, int trusted,
+ struct sa_query_result *result)
{
- return get_any_records(h, attr_id, 0, 0, NULL, trusted ? smkey : 0);
+ return get_any_records(h, attr_id, 0, 0, NULL, trusted ? smkey : 0,
+ result);
}
static int get_and_dump_all_records(bind_handle_t h, uint16_t attr_id,
int trusted, void (*dump_func) (void *))
{
- int ret = get_all_records(h, attr_id, 0);
+ struct sa_query_result result;
+ int ret = get_all_records(h, attr_id, 0, &result);
if (ret)
return ret;
dump_results(&result, dump_func);
- return_mad();
+ sa_free_result_mad(&result);
return ret;
}
@@ -884,24 +780,27 @@ static int get_lid_from_name(bind_handle_t h, const char *name, uint16_t * lid)
ib_node_info_t *p_ni = NULL;
unsigned i;
int ret;
+ struct sa_query_result result;
- ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0);
+ ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0, &result);
if (ret)
return ret;
+ ret = IB_NOT_FOUND;
for (i = 0; i < result.result_cnt; i++) {
- node_record = get_query_rec(result.p_result_madw, i);
+ node_record = sa_get_query_rec(result.p_result_madw, i);
p_ni = &(node_record->node_info);
if (name
&& strncmp(name, (char *)node_record->node_desc.description,
sizeof(node_record->node_desc.description)) ==
0) {
*lid = cl_ntoh16(node_record->lid);
+ ret = IB_SUCCESS;
break;
}
}
- return_mad();
- return 0;
+ sa_free_result_mad(&result);
+ return ret;
}
static uint16_t get_lid(bind_handle_t h, const char *name)
@@ -910,12 +809,22 @@ static uint16_t get_lid(bind_handle_t h, const char *name)
if (!name)
return 0;
- if (isalpha(name[0]))
- assert(get_lid_from_name(h, name, &rc_lid) == IB_SUCCESS);
- else
- rc_lid = (uint16_t) atoi(name);
- if (rc_lid == 0)
- fprintf(stderr, "Failed to find lid for \"%s\"\n", name);
+ if (isalpha(name[0])) {
+ if (get_lid_from_name(h, name, &rc_lid) != IB_SUCCESS) {
+ fprintf(stderr, "Failed to find lid for \"%s\"\n", name);
+ exit(EINVAL);
+ }
+ } else {
+ long val;
+ errno = 0;
+ val = strtol(name, NULL, 0);
+ if (errno != 0 || val <= 0 || val > UINT16_MAX) {
+ fprintf(stderr, "Invalid lid specified: \"%s\"\n", name);
+ exit(EINVAL);
+ }
+ rc_lid = (uint16_t)val;
+ }
+
return rc_lid;
}
@@ -959,30 +868,11 @@ static int parse_lid_and_ports(bind_handle_t h,
return 0;
}
-#define cl_hton8(x) (x)
-#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
- if ((int##size##_t) val != (int##size##_t) comp_with) { \
- target = cl_hton##size((uint##size##_t) val); \
- comp_mask |= IB_##name##_COMPMASK_##mask; \
- }
-
-#define CHECK_AND_SET_GID(val, target, name, mask) \
- if (valid_gid(&(val))) { \
- memcpy(&(target), &(val), sizeof(val)); \
- comp_mask |= IB_##name##_COMPMASK_##mask; \
- }
-
-#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
- if (val) { \
- target = val; \
- comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
- comp_mask |= IB_##name##_COMPMASK_##mask; \
- }
-
/*
* Get the portinfo records available with IsSM or IsSMdisabled CapabilityMask bit on.
*/
-static int get_issm_records(bind_handle_t h, ib_net32_t capability_mask)
+static int get_issm_records(bind_handle_t h, ib_net32_t capability_mask,
+ struct sa_query_result *result)
{
ib_portinfo_record_t attr;
@@ -990,15 +880,16 @@ static int get_issm_records(bind_handle_t h, ib_net32_t capability_mask)
attr.port_info.capability_mask = capability_mask;
return get_any_records(h, IB_SA_ATTR_PORTINFORECORD, 1 << 31,
- IB_PIR_COMPMASK_CAPMASK, &attr, 0);
+ IB_PIR_COMPMASK_CAPMASK, &attr, 0, result);
}
static int print_node_records(bind_handle_t h)
{
unsigned i;
int ret;
+ struct sa_query_result result;
- ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0);
+ ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0, &result);
if (ret)
return ret;
@@ -1008,7 +899,7 @@ static int print_node_records(bind_handle_t h)
}
for (i = 0; i < result.result_cnt; i++) {
ib_node_record_t *node_record;
- node_record = get_query_rec(result.p_result_madw, i);
+ node_record = sa_get_query_rec(result.p_result_madw, i);
if (node_print_desc == ALL_DESC) {
print_node_desc(node_record);
} else if (node_print_desc == NAME_OF_LID) {
@@ -1027,31 +918,34 @@ static int print_node_records(bind_handle_t h)
node_desc.description)) == 0)) {
print_node_record(node_record);
if (node_print_desc == UNIQUE_LID_ONLY) {
- return_mad();
+ sa_free_result_mad(&result);
exit(0);
}
}
}
}
- return_mad();
+ sa_free_result_mad(&result);
return ret;
}
static int get_print_class_port_info(bind_handle_t h)
{
+ struct sa_query_result result;
int ret = sa_query(h, IB_MAD_METHOD_GET, CLASS_PORT_INFO, 0, 0,
- 0, NULL);
+ 0, NULL, &result);
if (ret) {
fprintf(stderr, "ERROR: Query SA failed: %s\n",
ib_get_err_str(ret));
return ret;
}
- if (result.status != IB_SUCCESS) {
- report_err(result.status);
- return (result.status);
+ if (result.status != IB_SA_MAD_STATUS_SUCCESS) {
+ sa_report_err(result.status);
+ ret = EIO;
+ goto Exit;
}
dump_results(&result, dump_class_port_info);
- return_mad();
+Exit:
+ sa_free_result_mad(&result);
return ret;
}
@@ -1089,52 +983,58 @@ static int query_path_records(const struct query_cmd *q, bind_handle_t h,
&pr, 0, dump_path_record);
}
-static ib_api_status_t print_issm_records(bind_handle_t h)
+static int print_issm_records(bind_handle_t h)
{
- ib_api_status_t status;
+ struct sa_query_result result;
+ int ret = 0;
/* First, get IsSM records */
- status = get_issm_records(h, IB_PORT_CAP_IS_SM);
- if (status != IB_SUCCESS)
- return (status);
+ ret = get_issm_records(h, IB_PORT_CAP_IS_SM, &result);
+ if (ret != 0)
+ return (ret);
printf("IsSM ports\n");
dump_results(&result, dump_portinfo_record);
- return_mad();
+ sa_free_result_mad(&result);
/* Now, get IsSMdisabled records */
- status = get_issm_records(h, IB_PORT_CAP_SM_DISAB);
- if (status != IB_SUCCESS)
- return (status);
+ ret = get_issm_records(h, IB_PORT_CAP_SM_DISAB, &result);
+ if (ret != 0)
+ return (ret);
printf("\nIsSMdisabled ports\n");
dump_results(&result, dump_portinfo_record);
- return_mad();
+ sa_free_result_mad(&result);
- return (status);
+ return (ret);
}
static int print_multicast_member_records(bind_handle_t h)
{
- struct query_res mc_group_result;
+ struct sa_query_result mc_group_result;
+ struct sa_query_result nr_result;
int ret;
+ unsigned i;
- ret = get_all_records(h, IB_SA_ATTR_MCRECORD, 1);
+ ret = get_all_records(h, IB_SA_ATTR_MCRECORD, 1, &mc_group_result);
if (ret)
return ret;
- mc_group_result = result;
-
- ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0);
+ ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0, &nr_result);
if (ret)
goto return_mc;
- dump_results(&mc_group_result, dump_multicast_member_record);
- return_mad();
+ for (i = 0; i < mc_group_result.result_cnt; i++) {
+ ib_member_rec_t *rec = (ib_member_rec_t *)
+ sa_get_query_rec(mc_group_result.p_result_madw,
+ i);
+ dump_multicast_member_record(rec, &nr_result);
+ }
+
+ sa_free_result_mad(&nr_result);
return_mc:
- if (mc_group_result.p_result_madw)
- free((uint8_t *) mc_group_result.p_result_madw - umad_size());
+ sa_free_result_mad(&mc_group_result);
return ret;
}
@@ -1337,6 +1237,25 @@ static int query_lft_records(const struct query_cmd *q, bind_handle_t h,
&lftr, 0, dump_one_lft_record);
}
+static int query_guidinfo_records(const struct query_cmd *q, bind_handle_t h,
+ struct query_params *p, int argc, char *argv[])
+{
+ ib_guidinfo_record_t gir;
+ ib_net64_t comp_mask = 0;
+ int lid = 0, block = -1;
+
+ if (argc > 0)
+ parse_lid_and_ports(h, argv[0], &lid, &block, NULL);
+
+ memset(&gir, 0, sizeof(gir));
+ CHECK_AND_SET_VAL(lid, 16, 0, gir.lid, GIR, LID);
+ CHECK_AND_SET_VAL(block, 8, -1, gir.block_num, GIR, BLOCKNUM);
+
+ return get_and_dump_any_records(h, IB_SA_ATTR_GUIDINFORECORD, 0,
+ comp_mask, &gir, 0,
+ dump_one_guidinfo_record);
+}
+
static int query_mft_records(const struct query_cmd *q, bind_handle_t h,
struct query_params *p, int argc, char *argv[])
{
@@ -1359,37 +1278,6 @@ static int query_mft_records(const struct query_cmd *q, bind_handle_t h,
&mftr, 0, dump_one_mft_record);
}
-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 };
-
- 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_via(&handle.dport, ibd_timeout, srcport);
- if (!handle.dport.lid)
- IBPANIC("No SM found.");
-
- handle.dport.qp = 1;
- if (!handle.dport.qkey)
- handle.dport.qkey = IB_DEFAULT_QP1_QKEY;
-
- handle.fd = mad_rpc_portid(srcport);
- handle.agent = umad_register(handle.fd, IB_SA_CLASS, 2, 1, NULL);
-
- return &handle;
-}
-
-static void clean_up(struct bind_handle *h)
-{
- umad_unregister(h->fd, h->agent);
- umad_close_port(h->fd);
- umad_done();
-}
-
static const struct query_cmd query_cmds[] = {
{"ClassPortInfo", "CPI", CLASS_PORT_INFO,
NULL, query_class_port_info},
@@ -1417,6 +1305,8 @@ static const struct query_cmd query_cmds[] = {
"[[lid]/[block]]", query_lft_records},
{"MFTRecord", "MFTR", IB_SA_ATTR_MFTRECORD,
"[[mlid]/[position]/[block]]", query_mft_records},
+ {"GUIDInfoRecord", "GIR", IB_SA_ATTR_GUIDINFORECORD,
+ "[[lid]/[block]]", query_guidinfo_records},
{0}
};
@@ -1639,7 +1529,7 @@ int main(int argc, char **argv)
bind_handle_t h;
struct query_params params;
const struct query_cmd *q;
- ib_api_status_t status;
+ int status;
int n;
const struct ibdiag_opt opts[] = {
@@ -1784,7 +1674,10 @@ int main(int argc, char **argv)
ibdiag_show_usage();
}
- h = get_bind_handle();
+ h = sa_get_bind_handle();
+ if (!h)
+ IBPANIC("Failed to bind to the SA");
+
node_name_map = open_node_name_map(node_name_map_file);
if (src_lid && *src_lid)
@@ -1821,7 +1714,7 @@ int main(int argc, char **argv)
if (src_lid)
free(src_lid);
- clean_up(h);
+ sa_free_bind_handle(h);
close_node_name_map(node_name_map);
return (status);
}
diff --git a/trunk/tools/infiniband-diags/src/sminfo.c b/trunk/tools/infiniband-diags/src/sminfo.c
index ef13911..b02906f 100644
--- a/trunk/tools/infiniband-diags/src/sminfo.c
+++ b/trunk/tools/infiniband-diags/src/sminfo.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -46,7 +47,7 @@
#include "ibdiag_common.h"
-static uint8_t sminfo[1024];
+static uint8_t sminfo[1024] = { 0 };
struct ibmad_port *srcport;
diff --git a/trunk/tools/infiniband-diags/src/sminfo/SOURCES b/trunk/tools/infiniband-diags/src/sminfo/SOURCES
index 9596c16..0910bf0 100644
--- a/trunk/tools/infiniband-diags/src/sminfo/SOURCES
+++ b/trunk/tools/infiniband-diags/src/sminfo/SOURCES
@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/smpdump/SOURCES b/trunk/tools/infiniband-diags/src/smpdump/SOURCES
index 8e308ce..d8f7d6d 100644
--- a/trunk/tools/infiniband-diags/src/smpdump/SOURCES
+++ b/trunk/tools/infiniband-diags/src/smpdump/SOURCES
@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/smpquery.c b/trunk/tools/infiniband-diags/src/smpquery.c
index a1559e8..6753ba9 100644
--- a/trunk/tools/infiniband-diags/src/smpquery.c
+++ b/trunk/tools/infiniband-diags/src/smpquery.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -62,7 +63,7 @@ typedef struct match_rec {
} match_rec_t;
static op_fn_t node_desc, node_info, port_info, switch_info, pkey_table,
- sl2vl_table, vlarb_table, guid_info;
+ sl2vl_table, vlarb_table, guid_info, mlnx_ext_port_info;
static const match_rec_t match_tbl[] = {
{"NodeInfo", "NI", node_info},
@@ -73,6 +74,7 @@ static const match_rec_t match_tbl[] = {
{"SL2VLTable", "SL2VL", sl2vl_table, 1},
{"VLArbitration", "VLArb", vlarb_table, 1},
{"GUIDInfo", "GI", guid_info},
+ {"MlnxExtPortInfo", "MEPI", mlnx_ext_port_info, 1},
{0}
};
@@ -84,8 +86,8 @@ static char *node_desc(ib_portid_t * dest, char **argv, int argc)
{
int node_type, l;
uint64_t node_guid;
- char nd[IB_SMP_DATA_SIZE];
- uint8_t data[IB_SMP_DATA_SIZE];
+ char nd[IB_SMP_DATA_SIZE] = { 0 };
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
char dots[128];
char *nodename = NULL;
@@ -117,7 +119,7 @@ static char *node_desc(ib_portid_t * dest, char **argv, int argc)
static char *node_info(ib_portid_t * dest, char **argv, int argc)
{
char buf[2048];
- char data[IB_SMP_DATA_SIZE];
+ char data[IB_SMP_DATA_SIZE] = { 0 };
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
return "node info query failed";
@@ -130,8 +132,8 @@ static char *node_info(ib_portid_t * dest, char **argv, int argc)
static char *port_info(ib_portid_t * dest, char **argv, int argc)
{
- char buf[2048];
- char data[IB_SMP_DATA_SIZE];
+ char buf[2300];
+ char data[IB_SMP_DATA_SIZE] = { 0 };
int portnum = 0;
if (argc > 0)
@@ -146,10 +148,28 @@ static char *port_info(ib_portid_t * dest, char **argv, int argc)
return 0;
}
+static char *mlnx_ext_port_info(ib_portid_t * dest, char **argv, int argc)
+{
+ char buf[2300];
+ char data[IB_SMP_DATA_SIZE];
+ int portnum = 0;
+
+ if (argc > 0)
+ portnum = strtol(argv[0], 0, 0);
+
+ if (!smp_query_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO, portnum, 0, srcport))
+ return "Mellanox ext port info query failed";
+
+ mad_dump_mlnx_ext_port_info(buf, sizeof buf, data, sizeof data);
+
+ printf("# MLNX ext Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
+ return 0;
+}
+
static char *switch_info(ib_portid_t * dest, char **argv, int argc)
{
char buf[2048];
- char data[IB_SMP_DATA_SIZE];
+ char data[IB_SMP_DATA_SIZE] = { 0 };
if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
return "switch info query failed";
@@ -162,7 +182,7 @@ static char *switch_info(ib_portid_t * dest, char **argv, int argc)
static char *pkey_table(ib_portid_t * dest, char **argv, int argc)
{
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
int i, j, k;
uint16_t *p;
unsigned mod;
@@ -215,7 +235,7 @@ static char *pkey_table(ib_portid_t * dest, char **argv, int argc)
static char *sl2vl_dump_table_entry(ib_portid_t * dest, int in, int out)
{
char buf[2048];
- char data[IB_SMP_DATA_SIZE];
+ char data[IB_SMP_DATA_SIZE] = { 0 };
int portnum = (in << 8) | out;
if (!smp_query_via(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0, srcport))
@@ -229,7 +249,7 @@ static char *sl2vl_dump_table_entry(ib_portid_t * dest, int in, int out)
static char *sl2vl_table(ib_portid_t * dest, char **argv, int argc)
{
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
int type, num_ports, portnum = 0;
int i;
char *ret;
@@ -266,7 +286,7 @@ static char *vlarb_dump_table_entry(ib_portid_t * dest, int portnum, int offset,
unsigned cap)
{
char buf[2048];
- char data[IB_SMP_DATA_SIZE];
+ char data[IB_SMP_DATA_SIZE] = { 0 };
if (!smp_query_via(data, dest, IB_ATTR_VL_ARBITRATION,
(offset << 16) | portnum, 0, srcport))
@@ -292,7 +312,7 @@ static char *vlarb_dump_table(ib_portid_t * dest, int portnum,
static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
{
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
int portnum = 0;
int type, enhsp0, lowcap, highcap;
char *ret = 0;
@@ -308,6 +328,7 @@ static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
mad_decode_field(data, IB_NODE_TYPE_F, &type);
if (type == IB_NODE_SWITCH) {
+ memset(data, 0, sizeof(data));
if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0,
0, srcport))
return "switch info query failed";
@@ -318,6 +339,7 @@ static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
portid2str(dest), 0);
return 0;
}
+ memset(data, 0, sizeof(data));
}
}
@@ -341,7 +363,7 @@ static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
static char *guid_info(ib_portid_t * dest, char **argv, int argc)
{
- uint8_t data[IB_SMP_DATA_SIZE];
+ uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
int i, j, k;
uint64_t *p;
unsigned mod;
diff --git a/trunk/tools/infiniband-diags/src/smpquery/SOURCES b/trunk/tools/infiniband-diags/src/smpquery/SOURCES
index a6ecae4..b276a21 100644
--- a/trunk/tools/infiniband-diags/src/smpquery/SOURCES
+++ b/trunk/tools/infiniband-diags/src/smpquery/SOURCES
@@ -21,6 +21,7 @@ TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
$(TARGETPATH)\*\complib.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/tools/infiniband-diags/src/vendstat.c b/trunk/tools/infiniband-diags/src/vendstat.c
index 92a90c8..8dbd1ee 100644
--- a/trunk/tools/infiniband-diags/src/vendstat.c
+++ b/trunk/tools/infiniband-diags/src/vendstat.c
@@ -375,6 +375,7 @@ int main(int argc, char **argv)
gi = (is3_general_info_t *) & buf;
if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
IB_MLX_IS3_GENERAL_INFO, 0, gi))
+ IBERROR("generalinfo query");
if (general_info) {
/* dump IS3 or IS4 general info here */
diff --git a/trunk/tools/infiniband-diags/src/vendstat/SOURCES b/trunk/tools/infiniband-diags/src/vendstat/SOURCES
index 06fd5f4..450502b 100644
--- a/trunk/tools/infiniband-diags/src/vendstat/SOURCES
+++ b/trunk/tools/infiniband-diags/src/vendstat/SOURCES
@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
TARGETLIBS = \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ws2_32.lib \
+ $(TARGETPATH)\*\ibal.lib \
$(TARGETPATH)\*\libibmad.lib \
$(TARGETPATH)\*\libibumad.lib
diff --git a/trunk/ulp/libibmad/include/infiniband/mad.h b/trunk/ulp/libibmad/include/infiniband/mad.h
index 7571a61..6d65a29 100644
--- a/trunk/ulp/libibmad/include/infiniband/mad.h
+++ b/trunk/ulp/libibmad/include/infiniband/mad.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
- * Copyright (c) 2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2009-2011 Mellanox Technologies LTD. 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
@@ -46,6 +46,9 @@
#endif /* __cplusplus */
BEGIN_C_DECLS
+#define IB_MAD_RPC_VERSION_MASK 0x0f00
+#define IB_MAD_RPC_VERSION1 (1<<8)
+
#define IB_SUBNET_PATH_HOPS_MAX 64
#define IB_DEFAULT_SUBN_PREFIX 0xfe80000000000000ULL
#define IB_DEFAULT_QP1_QKEY 0x80010000
@@ -62,6 +65,7 @@ BEGIN_C_DECLS
#define IB_PC_DATA_SZ (IB_MAD_SIZE - IB_PC_DATA_OFFS)
#define IB_SA_MCM_RECSZ 53
#define IB_SA_PR_RECSZ 64
+#define IB_SA_GIR_RECSZ 72
#define IB_BM_DATA_OFFS 64
#define IB_BM_DATA_SZ (IB_MAD_SIZE - IB_BM_DATA_OFFS)
#define IB_BM_BKEY_OFFS 24
@@ -137,7 +141,9 @@ enum SMI_ATTR_ID {
IB_ATTR_VENDORMADSTBL = 0x1d,
IB_ATTR_SMINFO = 0x20,
- IB_ATTR_LAST
+ IB_ATTR_LAST,
+
+ IB_ATTR_MLNX_EXT_PORT_INFO = 0xff90,
};
enum SA_ATTR_ID {
@@ -170,7 +176,20 @@ enum GSI_ATTR_ID {
IB_GSI_PORT_COUNTERS = 0x12,
IB_GSI_PORT_RCV_ERROR_DETAILS = 0x15,
IB_GSI_PORT_XMIT_DISCARD_DETAILS = 0x16,
+ IB_GSI_PORT_PORT_OP_RCV_COUNTERS = 0x17,
+ IB_GSI_PORT_PORT_FLOW_CTL_COUNTERS = 0x18,
+ IB_GSI_PORT_PORT_VL_OP_PACKETS = 0x19,
+ IB_GSI_PORT_PORT_VL_OP_DATA = 0x1A,
+ IB_GSI_PORT_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS = 0x1B,
+ IB_GSI_PORT_PORT_VL_XMIT_WAIT_COUNTERS = 0x1C,
IB_GSI_PORT_COUNTERS_EXT = 0x1D,
+ IB_GSI_PORT_EXT_SPEEDS_COUNTERS = 0x1F,
+ IB_GSI_SW_PORT_VL_CONGESTION = 0x30,
+ IB_GSI_PORT_RCV_CON_CTRL = 0x31,
+ IB_GSI_PORT_SL_RCV_FECN = 0x32,
+ IB_GSI_PORT_SL_RCV_BECN = 0x33,
+ IB_GSI_PORT_XMIT_CON_CTRL = 0x34,
+ IB_GSI_PORT_VL_XMIT_TIME_CONG = 0x35,
IB_GSI_PORT_XMIT_DATA_SL = 0x36,
IB_GSI_PORT_RCV_DATA_SL = 0x37,
IB_GSI_ATTR_LAST
@@ -234,6 +253,22 @@ typedef struct {
uint32_t oui; /* for vendor range 2 mads */
} ib_rpc_t;
+typedef struct {
+ int mgtclass;
+ int method;
+ ib_attr_t attr;
+ uint32_t rstatus; /* return status */
+ int dataoffs;
+ int datasz;
+ uint64_t mkey;
+ uint64_t trid; /* used for out mad if nonzero, return real val */
+ uint64_t mask; /* for sa mads */
+ unsigned recsz; /* for sa mads (attribute offset) */
+ int timeout;
+ uint32_t oui; /* for vendor range 2 mads */
+ int error; /* errno */
+} ib_rpc_v1_t;
+
typedef struct portid {
int lid; /* lid or 0 if directed route */
ib_dr_path_t drpath;
@@ -579,7 +614,8 @@ enum MAD_FIELDS {
/*
* GUIDInfo fields
*/
- IB_GUID_GUID0_F,
+ IB_GUID_GUID0_F, /* Obsolete, kept for compatibility
+ Use IB_GI_GUID0_F going forward */
/*
* ClassPortInfo fields
@@ -706,6 +742,301 @@ enum MAD_FIELDS {
IB_PSC_SAMPLES_ONLY_OPT_MASK_F,
IB_PSC_LAST_F,
+ /*
+ * GUIDInfo fields
+ */
+ IB_GI_GUID0_F, /* a duplicate of IB_GUID_GUID0_F for backwards
+ compatibility */
+ IB_GI_GUID1_F,
+ IB_GI_GUID2_F,
+ IB_GI_GUID3_F,
+ IB_GI_GUID4_F,
+ IB_GI_GUID5_F,
+ IB_GI_GUID6_F,
+ IB_GI_GUID7_F,
+
+ /*
+ * GUID Info Record
+ */
+ IB_SA_GIR_LID_F,
+ IB_SA_GIR_BLOCKNUM_F,
+ IB_SA_GIR_GUID0_F,
+ IB_SA_GIR_GUID1_F,
+ IB_SA_GIR_GUID2_F,
+ IB_SA_GIR_GUID3_F,
+ IB_SA_GIR_GUID4_F,
+ IB_SA_GIR_GUID5_F,
+ IB_SA_GIR_GUID6_F,
+ IB_SA_GIR_GUID7_F,
+
+ /*
+ * More PortInfo fields
+ */
+ IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
+ IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
+ IB_PORT_LINK_SPEED_EXT_ENABLED_F,
+ IB_PORT_LINK_SPEED_EXT_LAST_F,
+
+ /*
+ * PortExtendedSpeedsCounters fields
+ */
+ IB_PESC_PORT_SELECT_F,
+ IB_PESC_COUNTER_SELECT_F,
+ IB_PESC_SYNC_HDR_ERR_CTR_F,
+ IB_PESC_UNK_BLOCK_CTR_F,
+ IB_PESC_ERR_DET_CTR_LANE0_F,
+ IB_PESC_ERR_DET_CTR_LANE1_F,
+ IB_PESC_ERR_DET_CTR_LANE2_F,
+ IB_PESC_ERR_DET_CTR_LANE3_F,
+ IB_PESC_ERR_DET_CTR_LANE4_F,
+ IB_PESC_ERR_DET_CTR_LANE5_F,
+ IB_PESC_ERR_DET_CTR_LANE6_F,
+ IB_PESC_ERR_DET_CTR_LANE7_F,
+ IB_PESC_ERR_DET_CTR_LANE8_F,
+ IB_PESC_ERR_DET_CTR_LANE9_F,
+ IB_PESC_ERR_DET_CTR_LANE10_F,
+ IB_PESC_ERR_DET_CTR_LANE11_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE0_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE1_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE2_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE3_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE4_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE5_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE6_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE7_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE8_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE9_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE10_F,
+ IB_PESC_FEC_CORR_BLOCK_CTR_LANE11_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE0_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE1_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE2_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE3_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE4_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE5_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE6_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE7_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE8_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE9_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE10_F,
+ IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE11_F,
+ IB_PESC_LAST_F,
+
+ /*
+ * PortOpRcvCounters fields
+ */
+ IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F,
+ IB_PC_PORT_OP_RCV_PKTS_F = IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F,
+ IB_PC_PORT_OP_RCV_DATA_F,
+ IB_PC_PORT_OP_RCV_COUNTERS_LAST_F,
+
+ /*
+ * PortFlowCtlCounters fields
+ */
+ IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F,
+ IB_PC_PORT_XMIT_FLOW_PKTS_F = IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F,
+ IB_PC_PORT_RCV_FLOW_PKTS_F,
+ IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F,
+
+ /*
+ * PortVLOpPackets fields
+ */
+ IB_PC_PORT_VL_OP_PACKETS_FIRST_F,
+ IB_PC_PORT_VL_OP_PACKETS0_F = IB_PC_PORT_VL_OP_PACKETS_FIRST_F,
+ IB_PC_PORT_VL_OP_PACKETS1_F,
+ IB_PC_PORT_VL_OP_PACKETS2_F,
+ IB_PC_PORT_VL_OP_PACKETS3_F,
+ IB_PC_PORT_VL_OP_PACKETS4_F,
+ IB_PC_PORT_VL_OP_PACKETS5_F,
+ IB_PC_PORT_VL_OP_PACKETS6_F,
+ IB_PC_PORT_VL_OP_PACKETS7_F,
+ IB_PC_PORT_VL_OP_PACKETS8_F,
+ IB_PC_PORT_VL_OP_PACKETS9_F,
+ IB_PC_PORT_VL_OP_PACKETS10_F,
+ IB_PC_PORT_VL_OP_PACKETS11_F,
+ IB_PC_PORT_VL_OP_PACKETS12_F,
+ IB_PC_PORT_VL_OP_PACKETS13_F,
+ IB_PC_PORT_VL_OP_PACKETS14_F,
+ IB_PC_PORT_VL_OP_PACKETS15_F,
+ IB_PC_PORT_VL_OP_PACKETS_LAST_F,
+
+ /*
+ * PortVLOpData fields
+ */
+ IB_PC_PORT_VL_OP_DATA_FIRST_F,
+ IB_PC_PORT_VL_OP_DATA0_F = IB_PC_PORT_VL_OP_DATA_FIRST_F,
+ IB_PC_PORT_VL_OP_DATA1_F,
+ IB_PC_PORT_VL_OP_DATA2_F,
+ IB_PC_PORT_VL_OP_DATA3_F,
+ IB_PC_PORT_VL_OP_DATA4_F,
+ IB_PC_PORT_VL_OP_DATA5_F,
+ IB_PC_PORT_VL_OP_DATA6_F,
+ IB_PC_PORT_VL_OP_DATA7_F,
+ IB_PC_PORT_VL_OP_DATA8_F,
+ IB_PC_PORT_VL_OP_DATA9_F,
+ IB_PC_PORT_VL_OP_DATA10_F,
+ IB_PC_PORT_VL_OP_DATA11_F,
+ IB_PC_PORT_VL_OP_DATA12_F,
+ IB_PC_PORT_VL_OP_DATA13_F,
+ IB_PC_PORT_VL_OP_DATA14_F,
+ IB_PC_PORT_VL_OP_DATA15_F,
+ IB_PC_PORT_VL_OP_DATA_LAST_F,
+
+ /*
+ * PortVLXmitFlowCtlUpdateErrors fields
+ */
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS0_F = IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS1_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS2_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS3_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS4_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS5_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS6_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS7_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS8_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS9_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS10_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS11_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS12_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS13_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS14_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS15_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F,
+
+ /*
+ * PortVLXmitWaitCounters fields
+ */
+ IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
+ IB_PC_PORT_VL_XMIT_WAIT0_F = IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
+ IB_PC_PORT_VL_XMIT_WAIT1_F,
+ IB_PC_PORT_VL_XMIT_WAIT2_F,
+ IB_PC_PORT_VL_XMIT_WAIT3_F,
+ IB_PC_PORT_VL_XMIT_WAIT4_F,
+ IB_PC_PORT_VL_XMIT_WAIT5_F,
+ IB_PC_PORT_VL_XMIT_WAIT6_F,
+ IB_PC_PORT_VL_XMIT_WAIT7_F,
+ IB_PC_PORT_VL_XMIT_WAIT8_F,
+ IB_PC_PORT_VL_XMIT_WAIT9_F,
+ IB_PC_PORT_VL_XMIT_WAIT10_F,
+ IB_PC_PORT_VL_XMIT_WAIT11_F,
+ IB_PC_PORT_VL_XMIT_WAIT12_F,
+ IB_PC_PORT_VL_XMIT_WAIT13_F,
+ IB_PC_PORT_VL_XMIT_WAIT14_F,
+ IB_PC_PORT_VL_XMIT_WAIT15_F,
+ IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F,
+
+ /*
+ * SwPortVLCongestion fields
+ */
+ IB_PC_SW_PORT_VL_CONGESTION_FIRST_F,
+ IB_PC_SW_PORT_VL_CONGESTION0_F = IB_PC_SW_PORT_VL_CONGESTION_FIRST_F,
+ IB_PC_SW_PORT_VL_CONGESTION1_F,
+ IB_PC_SW_PORT_VL_CONGESTION2_F,
+ IB_PC_SW_PORT_VL_CONGESTION3_F,
+ IB_PC_SW_PORT_VL_CONGESTION4_F,
+ IB_PC_SW_PORT_VL_CONGESTION5_F,
+ IB_PC_SW_PORT_VL_CONGESTION6_F,
+ IB_PC_SW_PORT_VL_CONGESTION7_F,
+ IB_PC_SW_PORT_VL_CONGESTION8_F,
+ IB_PC_SW_PORT_VL_CONGESTION9_F,
+ IB_PC_SW_PORT_VL_CONGESTION10_F,
+ IB_PC_SW_PORT_VL_CONGESTION11_F,
+ IB_PC_SW_PORT_VL_CONGESTION12_F,
+ IB_PC_SW_PORT_VL_CONGESTION13_F,
+ IB_PC_SW_PORT_VL_CONGESTION14_F,
+ IB_PC_SW_PORT_VL_CONGESTION15_F,
+ IB_PC_SW_PORT_VL_CONGESTION_LAST_F,
+
+ /*
+ * PortRcvConCtrl fields
+ */
+ IB_PC_RCV_CON_CTRL_FIRST_F,
+ IB_PC_RCV_CON_CTRL_PKT_RCV_FECN_F = IB_PC_RCV_CON_CTRL_FIRST_F,
+ IB_PC_RCV_CON_CTRL_PKT_RCV_BECN_F,
+ IB_PC_RCV_CON_CTRL_LAST_F,
+
+ /*
+ * PortSLRcvFECN fields
+ */
+ IB_PC_SL_RCV_FECN_FIRST_F,
+ IB_PC_SL_RCV_FECN0_F = IB_PC_SL_RCV_FECN_FIRST_F,
+ IB_PC_SL_RCV_FECN1_F,
+ IB_PC_SL_RCV_FECN2_F,
+ IB_PC_SL_RCV_FECN3_F,
+ IB_PC_SL_RCV_FECN4_F,
+ IB_PC_SL_RCV_FECN5_F,
+ IB_PC_SL_RCV_FECN6_F,
+ IB_PC_SL_RCV_FECN7_F,
+ IB_PC_SL_RCV_FECN8_F,
+ IB_PC_SL_RCV_FECN9_F,
+ IB_PC_SL_RCV_FECN10_F,
+ IB_PC_SL_RCV_FECN11_F,
+ IB_PC_SL_RCV_FECN12_F,
+ IB_PC_SL_RCV_FECN13_F,
+ IB_PC_SL_RCV_FECN14_F,
+ IB_PC_SL_RCV_FECN15_F,
+ IB_PC_SL_RCV_FECN_LAST_F,
+
+ /*
+ * PortSLRcvBECN fields
+ */
+ IB_PC_SL_RCV_BECN_FIRST_F,
+ IB_PC_SL_RCV_BECN0_F = IB_PC_SL_RCV_BECN_FIRST_F,
+ IB_PC_SL_RCV_BECN1_F,
+ IB_PC_SL_RCV_BECN2_F,
+ IB_PC_SL_RCV_BECN3_F,
+ IB_PC_SL_RCV_BECN4_F,
+ IB_PC_SL_RCV_BECN5_F,
+ IB_PC_SL_RCV_BECN6_F,
+ IB_PC_SL_RCV_BECN7_F,
+ IB_PC_SL_RCV_BECN8_F,
+ IB_PC_SL_RCV_BECN9_F,
+ IB_PC_SL_RCV_BECN10_F,
+ IB_PC_SL_RCV_BECN11_F,
+ IB_PC_SL_RCV_BECN12_F,
+ IB_PC_SL_RCV_BECN13_F,
+ IB_PC_SL_RCV_BECN14_F,
+ IB_PC_SL_RCV_BECN15_F,
+ IB_PC_SL_RCV_BECN_LAST_F,
+
+ /*
+ * PortXmitConCtrl fields
+ */
+ IB_PC_XMIT_CON_CTRL_FIRST_F,
+ IB_PC_XMIT_CON_CTRL_TIME_CONG_F = IB_PC_XMIT_CON_CTRL_FIRST_F,
+ IB_PC_XMIT_CON_CTRL_LAST_F,
+
+ /*
+ * PortVLXmitTimeCong fields
+ */
+ IB_PC_VL_XMIT_TIME_CONG_FIRST_F,
+ IB_PC_VL_XMIT_TIME_CONG0_F = IB_PC_VL_XMIT_TIME_CONG_FIRST_F,
+ IB_PC_VL_XMIT_TIME_CONG1_F,
+ IB_PC_VL_XMIT_TIME_CONG2_F,
+ IB_PC_VL_XMIT_TIME_CONG3_F,
+ IB_PC_VL_XMIT_TIME_CONG4_F,
+ IB_PC_VL_XMIT_TIME_CONG5_F,
+ IB_PC_VL_XMIT_TIME_CONG6_F,
+ IB_PC_VL_XMIT_TIME_CONG7_F,
+ IB_PC_VL_XMIT_TIME_CONG8_F,
+ IB_PC_VL_XMIT_TIME_CONG9_F,
+ IB_PC_VL_XMIT_TIME_CONG10_F,
+ IB_PC_VL_XMIT_TIME_CONG11_F,
+ IB_PC_VL_XMIT_TIME_CONG12_F,
+ IB_PC_VL_XMIT_TIME_CONG13_F,
+ IB_PC_VL_XMIT_TIME_CONG14_F,
+ IB_PC_VL_XMIT_TIME_CONG_LAST_F,
+
+ /*
+ * Mellanox ExtendedPortInfo fields
+ */
+ IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
+ IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F,
+ IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
+ IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F,
+ IB_MLNX_EXT_PORT_LAST_F,
+
IB_FIELD_LAST_ /* must be last */
};
@@ -959,6 +1290,14 @@ MAD_EXPORT uint8_t *smp_query_via(void *buf, ib_portid_t * id, unsigned attrid,
MAD_EXPORT uint8_t *smp_set_via(void *buf, ib_portid_t * id, unsigned attrid,
unsigned mod, unsigned timeout,
const struct ibmad_port *srcport);
+MAD_EXPORT uint8_t *smp_query_status_via(void *rcvbuf, ib_portid_t * portid,
+ unsigned attrid, unsigned mod,
+ unsigned timeout, int *rstatus,
+ const struct ibmad_port *srcport);
+MAD_EXPORT uint8_t *smp_set_status_via(void *data, ib_portid_t * portid,
+ unsigned attrid, unsigned mod,
+ unsigned timeout, int *rstatus,
+ const struct ibmad_port *srcport);
/* sa.c */
uint8_t *sa_call(void *rcvbuf, ib_portid_t * portid, ib_sa_call_t * sa,
@@ -1021,6 +1360,7 @@ MAD_EXPORT ib_mad_dump_fn
mad_dump_linkwidth, mad_dump_linkwidthsup, mad_dump_linkwidthen,
mad_dump_linkdowndefstate,
mad_dump_linkspeed, mad_dump_linkspeedsup, mad_dump_linkspeeden,
+ mad_dump_linkspeedext, mad_dump_linkspeedextsup, mad_dump_linkspeedexten,
mad_dump_portstate, mad_dump_portstates,
mad_dump_physportstate, mad_dump_portcapmask,
mad_dump_mtu, mad_dump_vlcap, mad_dump_opervls,
@@ -1029,7 +1369,14 @@ MAD_EXPORT ib_mad_dump_fn
mad_dump_switchinfo, mad_dump_perfcounters, mad_dump_perfcounters_ext,
mad_dump_perfcounters_xmt_sl, mad_dump_perfcounters_rcv_sl,
mad_dump_perfcounters_xmt_disc, mad_dump_perfcounters_rcv_err,
- mad_dump_portsamples_control;
+ mad_dump_portsamples_control, mad_dump_port_ext_speeds_counters,
+ mad_dump_perfcounters_port_op_rcv_counters, mad_dump_perfcounters_port_flow_ctl_counters,
+ mad_dump_perfcounters_port_vl_op_packet, mad_dump_perfcounters_port_vl_op_data,
+ mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors, mad_dump_perfcounters_port_vl_xmit_wait_counters,
+ mad_dump_perfcounters_sw_port_vl_congestion, mad_dump_perfcounters_rcv_con_ctrl,
+ mad_dump_perfcounters_sl_rcv_fecn, mad_dump_perfcounters_sl_rcv_becn,
+ mad_dump_perfcounters_xmit_con_ctrl, mad_dump_perfcounters_vl_xmit_time_cong,
+ mad_dump_mlnx_ext_port_info;
MAD_EXPORT void mad_dump_fields(char *buf, int bufsz, void *val, int valsz,
int start, int end);
diff --git a/trunk/ulp/libibmad/include/infiniband/mad_osd.h b/trunk/ulp/libibmad/include/infiniband/mad_osd.h
index faabaec..c32e666 100644
--- a/trunk/ulp/libibmad/include/infiniband/mad_osd.h
+++ b/trunk/ulp/libibmad/include/infiniband/mad_osd.h
@@ -35,6 +35,7 @@
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
+#include <_errno.h>
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
diff --git a/trunk/ulp/libibmad/src/dump.c b/trunk/ulp/libibmad/src/dump.c
index c29f625..29fb742 100644
--- a/trunk/ulp/libibmad/src/dump.c
+++ b/trunk/ulp/libibmad/src/dump.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
- * Copyright (c) 2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2009-2011 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
*
* This software is available to you under a choice of one of two
@@ -308,6 +308,70 @@ void mad_dump_linkspeeden(char *buf, int bufsz, void *val, int valsz)
dump_linkspeed(buf, bufsz, speed);
}
+void mad_dump_linkspeedext(char *buf, int bufsz, void *val, int valsz)
+{
+ int speed = *(int *)val;
+
+ switch (speed) {
+ case 0:
+ snprintf(buf, bufsz, "No Extended Speed");
+ break;
+ case 1:
+ snprintf(buf, bufsz, "14.0625 Gbps");
+ break;
+ case 2:
+ snprintf(buf, bufsz, "25.78125 Gbps");
+ break;
+ default:
+ snprintf(buf, bufsz, "undefined (%d)", speed);
+ break;
+ }
+}
+
+static void dump_linkspeedext(char *buf, int bufsz, int speed)
+{
+ int n = 0;
+
+ if (speed == 0) {
+ sprintf(buf, "%d", speed);
+ return;
+ }
+
+ if (speed & 0x1)
+ n += snprintf(buf + n, bufsz - n, "14.0625 Gbps or ");
+ if (n < bufsz && speed & 0x2)
+ n += snprintf(buf + n, bufsz - n, "25.78125 Gbps or ");
+ if (n >= bufsz) {
+ if (bufsz > 3)
+ buf[n - 4] = '\0';
+ return;
+ }
+
+ if (speed >> 2) {
+ n += snprintf(buf + n, bufsz - n, "undefined (%d)", speed);
+ return;
+ } else if (bufsz > 3)
+ buf[n - 4] = '\0';
+}
+
+void mad_dump_linkspeedextsup(char *buf, int bufsz, void *val, int valsz)
+{
+ int speed = *(int *)val;
+
+ dump_linkspeedext(buf, bufsz, speed);
+}
+
+void mad_dump_linkspeedexten(char *buf, int bufsz, void *val, int valsz)
+{
+ int speed = *(int *)val;
+
+ if (speed == 30) {
+ sprintf(buf, "%s", "Extended link speeds disabled");
+ return;
+ }
+ dump_linkspeedext(buf, bufsz, speed);
+}
+
void mad_dump_portstate(char *buf, int bufsz, void *val, int valsz)
{
int state = *(int *)val;
@@ -495,6 +559,8 @@ void mad_dump_portcapmask(char *buf, int bufsz, void *val, int valsz)
if (mask & (1 << 12))
s += sprintf(s,
"\t\t\t\tIsPkeySwitchExternalPortTrapSupported\n");
+ if (mask & (1 << 14))
+ s += sprintf(s, "\t\t\t\tIsExtendedSpeedsSupported\n");
if (mask & (1 << 16))
s += sprintf(s, "\t\t\t\tIsCommunicatonManagementSupported\n");
if (mask & (1 << 17))
@@ -692,7 +758,12 @@ void mad_dump_nodeinfo(char *buf, int bufsz, void *val, int valsz)
void mad_dump_portinfo(char *buf, int bufsz, void *val, int valsz)
{
- _dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F);
+ int cnt;
+
+ cnt = _dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F);
+ _dump_fields(buf + cnt, bufsz - cnt, val,
+ IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
+ IB_PORT_LINK_SPEED_EXT_LAST_F);
}
void mad_dump_portstates(char *buf, int bufsz, void *val, int valsz)
@@ -760,6 +831,138 @@ void mad_dump_portsamples_control(char *buf, int bufsz, void *val, int valsz)
_dump_fields(buf, bufsz, val, IB_PSC_OPCODE_F, IB_PSC_LAST_F);
}
+void mad_dump_port_ext_speeds_counters(char *buf, int bufsz, void *val, int valsz)
+{
+ _dump_fields(buf, bufsz, val, IB_PESC_PORT_SELECT_F, IB_PESC_LAST_F);
+}
+
+void mad_dump_perfcounters_port_op_rcv_counters(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_PORT_OP_RCV_COUNTERS_FIRST_F,
+ IB_PC_PORT_OP_RCV_COUNTERS_LAST_F);
+}
+
+void mad_dump_perfcounters_port_flow_ctl_counters(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_PORT_FLOW_CTL_COUNTERS_FIRST_F,
+ IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F);
+}
+
+void mad_dump_perfcounters_port_vl_op_packet(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_PORT_VL_OP_PACKETS_FIRST_F,
+ IB_PC_PORT_VL_OP_PACKETS_LAST_F);
+}
+
+void mad_dump_perfcounters_port_vl_op_data(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_PORT_VL_OP_DATA_FIRST_F,
+ IB_PC_PORT_VL_OP_DATA_LAST_F);
+}
+
+void mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
+ IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F);
+}
+
+void mad_dump_perfcounters_port_vl_xmit_wait_counters(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
+ IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F);
+}
+
+void mad_dump_perfcounters_sw_port_vl_congestion(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_SW_PORT_VL_CONGESTION_FIRST_F,
+ IB_PC_SW_PORT_VL_CONGESTION_LAST_F);
+}
+
+void mad_dump_perfcounters_rcv_con_ctrl(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_CON_CTRL_FIRST_F,
+ IB_PC_RCV_CON_CTRL_LAST_F);
+}
+
+
+void mad_dump_perfcounters_sl_rcv_fecn(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_SL_RCV_FECN_FIRST_F,
+ IB_PC_SL_RCV_FECN_LAST_F);
+}
+
+void mad_dump_perfcounters_sl_rcv_becn(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_SL_RCV_BECN_FIRST_F,
+ IB_PC_SL_RCV_BECN_LAST_F);
+}
+
+void mad_dump_perfcounters_xmit_con_ctrl(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_XMIT_CON_CTRL_FIRST_F,
+ IB_PC_XMIT_CON_CTRL_LAST_F);
+}
+
+void mad_dump_perfcounters_vl_xmit_time_cong(char *buf, int bufsz, void *val, int valsz)
+{
+ 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_VL_XMIT_TIME_CONG_FIRST_F,
+ IB_PC_VL_XMIT_TIME_CONG_LAST_F);
+}
+
+void mad_dump_mlnx_ext_port_info(char *buf, int bufsz, void *val, int valsz)
+{
+ _dump_fields(buf, bufsz, val, IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
+ IB_MLNX_EXT_PORT_LAST_F);
+}
+
void xdump(FILE * file, char *msg, void *p, int size)
{
#define HEX(x) ((x) < 10 ? '0' + (x) : 'a' + ((x) -10))
diff --git a/trunk/ulp/libibmad/src/fields.c b/trunk/ulp/libibmad/src/fields.c
index a5a510a..7e5ac7d 100644
--- a/trunk/ulp/libibmad/src/fields.c
+++ b/trunk/ulp/libibmad/src/fields.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
- * Copyright (c) 2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2009-2010 Mellanox Technologies LTD. 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
@@ -246,24 +246,24 @@ static const ib_field_t ib_mad_f[] = {
*/
{BITSOFFS(8, 8), "PortSelect", mad_dump_uint},
{BITSOFFS(16, 16), "CounterSelect", mad_dump_hex},
- {BITSOFFS(32, 16), "SymbolErrors", mad_dump_uint},
- {BITSOFFS(48, 8), "LinkRecovers", mad_dump_uint},
- {BITSOFFS(56, 8), "LinkDowned", mad_dump_uint},
- {BITSOFFS(64, 16), "RcvErrors", mad_dump_uint},
- {BITSOFFS(80, 16), "RcvRemotePhysErrors", mad_dump_uint},
- {BITSOFFS(96, 16), "RcvSwRelayErrors", 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(32, 16), "SymbolErrorCounter", mad_dump_uint},
+ {BITSOFFS(48, 8), "LinkErrorRecoveryCounter", mad_dump_uint},
+ {BITSOFFS(56, 8), "LinkDownedCounter", mad_dump_uint},
+ {BITSOFFS(64, 16), "PortRcvErrors", mad_dump_uint},
+ {BITSOFFS(80, 16), "PortRcvRemotePhysicalErrors", mad_dump_uint},
+ {BITSOFFS(96, 16), "PortRcvSwitchRelayErrors", mad_dump_uint},
+ {BITSOFFS(112, 16), "PortXmitDiscards", mad_dump_uint},
+ {BITSOFFS(128, 8), "PortXmitConstraintErrors", mad_dump_uint},
+ {BITSOFFS(136, 8), "PortRcvConstraintErrors", 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(152, 4), "LocalLinkIntegrityErrors", mad_dump_uint},
+ {BITSOFFS(156, 4), "ExcessiveBufferOverrunErrors", mad_dump_uint},
{BITSOFFS(176, 16), "VL15Dropped", mad_dump_uint},
- {192, 32, "XmtData", mad_dump_uint},
- {224, 32, "RcvData", mad_dump_uint},
- {256, 32, "XmtPkts", mad_dump_uint},
- {288, 32, "RcvPkts", mad_dump_uint},
- {320, 32, "XmtWait", mad_dump_uint},
+ {192, 32, "PortXmitData", mad_dump_uint},
+ {224, 32, "PortRcvData", mad_dump_uint},
+ {256, 32, "PortXmitPkts", mad_dump_uint},
+ {288, 32, "PortRcvPkts", mad_dump_uint},
+ {320, 32, "PortXmitWait", mad_dump_uint},
{0, 0}, /* IB_PC_LAST_F */
/*
@@ -452,21 +452,21 @@ static const ib_field_t ib_mad_f[] = {
/*
* PortXmitDiscardDetails fields
*/
- {32, 16, "PortInactiveDiscards", mad_dump_uint},
- {48, 16, "PortNeighborMTUDiscards", mad_dump_uint},
- {64, 16, "PortSwLifetimeLimitDiscards", mad_dump_uint},
- {80, 16, "PortSwHOQLifetimeLimitDiscards", mad_dump_uint},
+ {BITSOFFS(32, 16), "PortInactiveDiscards", mad_dump_uint},
+ {BITSOFFS(48, 16), "PortNeighborMTUDiscards", mad_dump_uint},
+ {BITSOFFS(64, 16), "PortSwLifetimeLimitDiscards", mad_dump_uint},
+ {BITSOFFS(80, 16), "PortSwHOQLifetimeLimitDiscards", mad_dump_uint},
{0, 0}, /* IB_PC_XMT_DISC_LAST_F */
/*
* PortRcvErrorDetails fields
*/
- {32, 16, "PortLocalPhysicalErrors", mad_dump_uint},
- {48, 16, "PortMalformedPktErrors", mad_dump_uint},
- {64, 16, "PortBufferOverrunErrors", mad_dump_uint},
- {80, 16, "PortDLIDMappingErrors", mad_dump_uint},
- {96, 16, "PortVLMappingErrors", mad_dump_uint},
- {112, 16, "PortLoopingErrors", mad_dump_uint},
+ {BITSOFFS(32, 16), "PortLocalPhysicalErrors", mad_dump_uint},
+ {BITSOFFS(48, 16), "PortMalformedPktErrors", mad_dump_uint},
+ {BITSOFFS(64, 16), "PortBufferOverrunErrors", mad_dump_uint},
+ {BITSOFFS(80, 16), "PortDLIDMappingErrors", mad_dump_uint},
+ {BITSOFFS(96, 16), "PortVLMappingErrors", mad_dump_uint},
+ {BITSOFFS(112, 16), "PortLoopingErrors", mad_dump_uint},
{0, 0}, /* IB_PC_RCV_ERR_LAST_F */
/*
@@ -485,25 +485,303 @@ static const ib_field_t ib_mad_f[] = {
{160, 64, "VendorMask", mad_dump_hex},
{224, 32, "SampleStart", mad_dump_uint},
{256, 32, "SampleInterval", mad_dump_uint},
- {288, 16, "Tag", mad_dump_hex},
- {304, 16, "CounterSelect0", mad_dump_hex},
- {320, 16, "CounterSelect1", mad_dump_hex},
- {336, 16, "CounterSelect2", mad_dump_hex},
- {352, 16, "CounterSelect3", mad_dump_hex},
- {368, 16, "CounterSelect4", mad_dump_hex},
- {384, 16, "CounterSelect5", mad_dump_hex},
- {400, 16, "CounterSelect6", mad_dump_hex},
- {416, 16, "CounterSelect7", mad_dump_hex},
- {432, 16, "CounterSelect8", mad_dump_hex},
- {448, 16, "CounterSelect9", mad_dump_hex},
- {464, 16, "CounterSelect10", mad_dump_hex},
- {480, 16, "CounterSelect11", mad_dump_hex},
- {496, 16, "CounterSelect12", mad_dump_hex},
- {512, 16, "CounterSelect13", mad_dump_hex},
- {528, 16, "CounterSelect14", mad_dump_hex},
+ {BITSOFFS(288, 16), "Tag", mad_dump_hex},
+ {BITSOFFS(304, 16), "CounterSelect0", mad_dump_hex},
+ {BITSOFFS(320, 16), "CounterSelect1", mad_dump_hex},
+ {BITSOFFS(336, 16), "CounterSelect2", mad_dump_hex},
+ {BITSOFFS(352, 16), "CounterSelect3", mad_dump_hex},
+ {BITSOFFS(368, 16), "CounterSelect4", mad_dump_hex},
+ {BITSOFFS(384, 16), "CounterSelect5", mad_dump_hex},
+ {BITSOFFS(400, 16), "CounterSelect6", mad_dump_hex},
+ {BITSOFFS(416, 16), "CounterSelect7", mad_dump_hex},
+ {BITSOFFS(432, 16), "CounterSelect8", mad_dump_hex},
+ {BITSOFFS(448, 16), "CounterSelect9", mad_dump_hex},
+ {BITSOFFS(464, 16), "CounterSelect10", mad_dump_hex},
+ {BITSOFFS(480, 16), "CounterSelect11", mad_dump_hex},
+ {BITSOFFS(496, 16), "CounterSelect12", mad_dump_hex},
+ {BITSOFFS(512, 16), "CounterSelect13", mad_dump_hex},
+ {BITSOFFS(528, 16), "CounterSelect14", mad_dump_hex},
{576, 64, "SamplesOnlyOptionMask", mad_dump_hex},
{0, 0}, /* IB_PSC_LAST_F */
+ /* GUIDInfo fields */
+ {0, 64, "GUID0", mad_dump_hex},
+ {64, 64, "GUID1", mad_dump_hex},
+ {128, 64, "GUID2", mad_dump_hex},
+ {192, 64, "GUID3", mad_dump_hex},
+ {256, 64, "GUID4", mad_dump_hex},
+ {320, 64, "GUID5", mad_dump_hex},
+ {384, 64, "GUID6", mad_dump_hex},
+ {448, 64, "GUID7", mad_dump_hex},
+
+ /* GUID Info Record */
+ {BITSOFFS(0, 16), "Lid", mad_dump_uint},
+ {BITSOFFS(16, 8), "BlockNum", mad_dump_uint},
+ {64, 64, "Guid0", mad_dump_hex},
+ {128, 64, "Guid1", mad_dump_hex},
+ {192, 64, "Guid2", mad_dump_hex},
+ {256, 64, "Guid3", mad_dump_hex},
+ {320, 64, "Guid4", mad_dump_hex},
+ {384, 64, "Guid5", mad_dump_hex},
+ {448, 64, "Guid6", mad_dump_hex},
+ {512, 64, "Guid7", mad_dump_hex},
+
+ /*
+ * More PortInfo fields
+ */
+ {BITSOFFS(496, 4), "LinkSpeedExtActive", mad_dump_linkspeedext},
+ {BITSOFFS(500, 4), "LinkSpeedExtSupported", mad_dump_linkspeedextsup},
+ {BITSOFFS(507, 5), "LinkSpeedExtEnabled", mad_dump_linkspeedexten},
+ {0, 0}, /* IB_PORT_LINK_SPEED_EXT_LAST_F */
+
+ /*
+ * PortExtendedSpeedsCounters fields
+ */
+ {BITSOFFS(8, 8), "PortSelect", mad_dump_uint},
+ {64, 64, "CounterSelect", mad_dump_hex},
+ {BITSOFFS(128, 8), "SyncHeaderErrorCounter", mad_dump_uint},
+ {BITSOFFS(136, 8), "UnknownBlockCounter", mad_dump_uint},
+ {BITSOFFS(144, 8), "ErrorDetectionCounterLane0", mad_dump_uint},
+ {BITSOFFS(152, 8), "ErrorDetectionCounterLane1", mad_dump_uint},
+ {BITSOFFS(160, 8), "ErrorDetectionCounterLane2", mad_dump_uint},
+ {BITSOFFS(168, 8), "ErrorDetectionCounterLane3", mad_dump_uint},
+ {BITSOFFS(176, 8), "ErrorDetectionCounterLane4", mad_dump_uint},
+ {BITSOFFS(184, 8), "ErrorDetectionCounterLane5", mad_dump_uint},
+ {BITSOFFS(192, 8), "ErrorDetectionCounterLane6", mad_dump_uint},
+ {BITSOFFS(200, 8), "ErrorDetectionCounterLane7", mad_dump_uint},
+ {BITSOFFS(208, 8), "ErrorDetectionCounterLane8", mad_dump_uint},
+ {BITSOFFS(216, 8), "ErrorDetectionCounterLane9", mad_dump_uint},
+ {BITSOFFS(224, 8), "ErrorDetectionCounterLane10", mad_dump_uint},
+ {BITSOFFS(232, 8), "ErrorDetectionCounterLane11", mad_dump_uint},
+ {256, 32, "FECCorrectableBlockCtrLane0", mad_dump_uint},
+ {288, 32, "FECCorrectableBlockCtrLane1", mad_dump_uint},
+ {320, 32, "FECCorrectableBlockCtrLane2", mad_dump_uint},
+ {352, 32, "FECCorrectableBlockCtrLane3", mad_dump_uint},
+ {384, 32, "FECCorrectableBlockCtrLane4", mad_dump_uint},
+ {416, 32, "FECCorrectableBlockCtrLane5", mad_dump_uint},
+ {448, 32, "FECCorrectableBlockCtrLane6", mad_dump_uint},
+ {480, 32, "FECCorrectableBlockCtrLane7", mad_dump_uint},
+ {512, 32, "FECCorrectableBlockCtrLane8", mad_dump_uint},
+ {544, 32, "FECCorrectableBlockCtrLane9", mad_dump_uint},
+ {580, 32, "FECCorrectableBlockCtrLane10", mad_dump_uint},
+ {608, 32, "FECCorrectableBlockCtrLane11", mad_dump_uint},
+ {640, 32, "FECUncorrectableBlockCtrLane0", mad_dump_uint},
+ {672, 32, "FECUncorrectableBlockCtrLane1", mad_dump_uint},
+ {704, 32, "FECUncorrectableBlockCtrLane2", mad_dump_uint},
+ {736, 32, "FECUncorrectableBlockCtrLane3", mad_dump_uint},
+ {768, 32, "FECUncorrectableBlockCtrLane4", mad_dump_uint},
+ {800, 32, "FECUncorrectableBlockCtrLane5", mad_dump_uint},
+ {832, 32, "FECUncorrectableBlockCtrLane6", mad_dump_uint},
+ {864, 32, "FECUncorrectableBlockCtrLane7", mad_dump_uint},
+ {896, 32, "FECUncorrectableBlockCtrLane8", mad_dump_uint},
+ {928, 32, "FECUncorrectableBlockCtrLane9", mad_dump_uint},
+ {960, 32, "FECUncorrectableBlockCtrLane10", mad_dump_uint},
+ {992, 32, "FECUncorrectableBlockCtrLane11", mad_dump_uint},
+ {0, 0}, /* IB_PESC_LAST_F */
+
+ /*
+ * PortOpRcvCounters fields
+ */
+ {32, 32, "PortOpRcvPkts", mad_dump_uint},
+ {64, 32, "PortOpRcvData", mad_dump_uint},
+ {0, 0}, /* IB_PC_PORT_OP_RCV_COUNTERS_LAST_F */
+
+ /*
+ * PortFlowCtlCounters fields
+ */
+ {32, 32, "PortXmitFlowPkts", mad_dump_uint},
+ {64, 32, "PortRcvFlowPkts", mad_dump_uint},
+ {0, 0}, /* IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F */
+
+ /*
+ * PortVLOpPackets fields
+ */
+ {BITSOFFS(32, 16), "PortVLOpPackets0", mad_dump_uint},
+ {BITSOFFS(48, 16), "PortVLOpPackets1", mad_dump_uint},
+ {BITSOFFS(64, 16), "PortVLOpPackets2", mad_dump_uint},
+ {BITSOFFS(80, 16), "PortVLOpPackets3", mad_dump_uint},
+ {BITSOFFS(96, 16), "PortVLOpPackets4", mad_dump_uint},
+ {BITSOFFS(112, 16), "PortVLOpPackets5", mad_dump_uint},
+ {BITSOFFS(128, 16), "PortVLOpPackets6", mad_dump_uint},
+ {BITSOFFS(144, 16), "PortVLOpPackets7", mad_dump_uint},
+ {BITSOFFS(160, 16), "PortVLOpPackets8", mad_dump_uint},
+ {BITSOFFS(176, 16), "PortVLOpPackets9", mad_dump_uint},
+ {BITSOFFS(192, 16), "PortVLOpPackets10", mad_dump_uint},
+ {BITSOFFS(208, 16), "PortVLOpPackets11", mad_dump_uint},
+ {BITSOFFS(224, 16), "PortVLOpPackets12", mad_dump_uint},
+ {BITSOFFS(240, 16), "PortVLOpPackets13", mad_dump_uint},
+ {BITSOFFS(256, 16), "PortVLOpPackets14", mad_dump_uint},
+ {BITSOFFS(272, 16), "PortVLOpPackets15", mad_dump_uint},
+ {0, 0}, /* IB_PC_PORT_VL_OP_PACKETS_LAST_F */
+
+ /*
+ * PortVLOpData fields
+ */
+ {32, 32, "PortVLOpData0", mad_dump_uint},
+ {64, 32, "PortVLOpData1", mad_dump_uint},
+ {96, 32, "PortVLOpData2", mad_dump_uint},
+ {128, 32, "PortVLOpData3", mad_dump_uint},
+ {160, 32, "PortVLOpData4", mad_dump_uint},
+ {192, 32, "PortVLOpData5", mad_dump_uint},
+ {224, 32, "PortVLOpData6", mad_dump_uint},
+ {256, 32, "PortVLOpData7", mad_dump_uint},
+ {288, 32, "PortVLOpData8", mad_dump_uint},
+ {320, 32, "PortVLOpData9", mad_dump_uint},
+ {352, 32, "PortVLOpData10", mad_dump_uint},
+ {384, 32, "PortVLOpData11", mad_dump_uint},
+ {416, 32, "PortVLOpData12", mad_dump_uint},
+ {448, 32, "PortVLOpData13", mad_dump_uint},
+ {480, 32, "PortVLOpData14", mad_dump_uint},
+ {512, 32, "PortVLOpData15", mad_dump_uint},
+ {0, 0}, /* IB_PC_PORT_VL_OP_DATA_LAST_F */
+
+ /*
+ * PortVLXmitFlowCtlUpdateErrors fields
+ */
+ {BITSOFFS(32, 2), "PortVLXmitFlowCtlUpdateErrors0", mad_dump_uint},
+ {BITSOFFS(34, 2), "PortVLXmitFlowCtlUpdateErrors1", mad_dump_uint},
+ {BITSOFFS(36, 2), "PortVLXmitFlowCtlUpdateErrors2", mad_dump_uint},
+ {BITSOFFS(38, 2), "PortVLXmitFlowCtlUpdateErrors3", mad_dump_uint},
+ {BITSOFFS(40, 2), "PortVLXmitFlowCtlUpdateErrors4", mad_dump_uint},
+ {BITSOFFS(42, 2), "PortVLXmitFlowCtlUpdateErrors5", mad_dump_uint},
+ {BITSOFFS(44, 2), "PortVLXmitFlowCtlUpdateErrors6", mad_dump_uint},
+ {BITSOFFS(46, 2), "PortVLXmitFlowCtlUpdateErrors7", mad_dump_uint},
+ {BITSOFFS(48, 2), "PortVLXmitFlowCtlUpdateErrors8", mad_dump_uint},
+ {BITSOFFS(50, 2), "PortVLXmitFlowCtlUpdateErrors9", mad_dump_uint},
+ {BITSOFFS(52, 2), "PortVLXmitFlowCtlUpdateErrors10", mad_dump_uint},
+ {BITSOFFS(54, 2), "PortVLXmitFlowCtlUpdateErrors11", mad_dump_uint},
+ {BITSOFFS(56, 2), "PortVLXmitFlowCtlUpdateErrors12", mad_dump_uint},
+ {BITSOFFS(58, 2), "PortVLXmitFlowCtlUpdateErrors13", mad_dump_uint},
+ {BITSOFFS(60, 2), "PortVLXmitFlowCtlUpdateErrors14", mad_dump_uint},
+ {BITSOFFS(62, 2), "PortVLXmitFlowCtlUpdateErrors15", mad_dump_uint},
+ {0, 0}, /* IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F */
+
+ /*
+ * PortVLXmitWaitCounters fields
+ */
+ {BITSOFFS(32, 16), "PortVLXmitWait0", mad_dump_uint},
+ {BITSOFFS(48, 16), "PortVLXmitWait1", mad_dump_uint},
+ {BITSOFFS(64, 16), "PortVLXmitWait2", mad_dump_uint},
+ {BITSOFFS(80, 16), "PortVLXmitWait3", mad_dump_uint},
+ {BITSOFFS(96, 16), "PortVLXmitWait4", mad_dump_uint},
+ {BITSOFFS(112, 16), "PortVLXmitWait5", mad_dump_uint},
+ {BITSOFFS(128, 16), "PortVLXmitWait6", mad_dump_uint},
+ {BITSOFFS(144, 16), "PortVLXmitWait7", mad_dump_uint},
+ {BITSOFFS(160, 16), "PortVLXmitWait8", mad_dump_uint},
+ {BITSOFFS(176, 16), "PortVLXmitWait9", mad_dump_uint},
+ {BITSOFFS(192, 16), "PortVLXmitWait10", mad_dump_uint},
+ {BITSOFFS(208, 16), "PortVLXmitWait11", mad_dump_uint},
+ {BITSOFFS(224, 16), "PortVLXmitWait12", mad_dump_uint},
+ {BITSOFFS(240, 16), "PortVLXmitWait13", mad_dump_uint},
+ {BITSOFFS(256, 16), "PortVLXmitWait14", mad_dump_uint},
+ {BITSOFFS(272, 16), "PortVLXmitWait15", mad_dump_uint},
+ {0, 0}, /* IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F */
+
+ /*
+ * SwPortVLCongestion fields
+ */
+ {BITSOFFS(32, 16), "SWPortVLCongestion0", mad_dump_uint},
+ {BITSOFFS(48, 16), "SWPortVLCongestion1", mad_dump_uint},
+ {BITSOFFS(64, 16), "SWPortVLCongestion2", mad_dump_uint},
+ {BITSOFFS(80, 16), "SWPortVLCongestion3", mad_dump_uint},
+ {BITSOFFS(96, 16), "SWPortVLCongestion4", mad_dump_uint},
+ {BITSOFFS(112, 16), "SWPortVLCongestion5", mad_dump_uint},
+ {BITSOFFS(128, 16), "SWPortVLCongestion6", mad_dump_uint},
+ {BITSOFFS(144, 16), "SWPortVLCongestion7", mad_dump_uint},
+ {BITSOFFS(160, 16), "SWPortVLCongestion8", mad_dump_uint},
+ {BITSOFFS(176, 16), "SWPortVLCongestion9", mad_dump_uint},
+ {BITSOFFS(192, 16), "SWPortVLCongestion10", mad_dump_uint},
+ {BITSOFFS(208, 16), "SWPortVLCongestion11", mad_dump_uint},
+ {BITSOFFS(224, 16), "SWPortVLCongestion12", mad_dump_uint},
+ {BITSOFFS(240, 16), "SWPortVLCongestion13", mad_dump_uint},
+ {BITSOFFS(256, 16), "SWPortVLCongestion14", mad_dump_uint},
+ {BITSOFFS(272, 16), "SWPortVLCongestion15", mad_dump_uint},
+ {0, 0}, /* IB_PC_SW_PORT_VL_CONGESTION_LAST_F */
+
+ /*
+ * PortRcvConCtrl fields
+ */
+ {32, 32, "PortPktRcvFECN", mad_dump_uint},
+ {64, 32, "PortPktRcvBECN", mad_dump_uint},
+ {0, 0}, /* IB_PC_RCV_CON_CTRL_LAST_F */
+
+ /*
+ * PortSLRcvFECN fields
+ */
+ {32, 32, "PortSLRcvFECN0", mad_dump_uint},
+ {64, 32, "PortSLRcvFECN1", mad_dump_uint},
+ {96, 32, "PortSLRcvFECN2", mad_dump_uint},
+ {128, 32, "PortSLRcvFECN3", mad_dump_uint},
+ {160, 32, "PortSLRcvFECN4", mad_dump_uint},
+ {192, 32, "PortSLRcvFECN5", mad_dump_uint},
+ {224, 32, "PortSLRcvFECN6", mad_dump_uint},
+ {256, 32, "PortSLRcvFECN7", mad_dump_uint},
+ {288, 32, "PortSLRcvFECN8", mad_dump_uint},
+ {320, 32, "PortSLRcvFECN9", mad_dump_uint},
+ {352, 32, "PortSLRcvFECN10", mad_dump_uint},
+ {384, 32, "PortSLRcvFECN11", mad_dump_uint},
+ {416, 32, "PortSLRcvFECN12", mad_dump_uint},
+ {448, 32, "PortSLRcvFECN13", mad_dump_uint},
+ {480, 32, "PortSLRcvFECN14", mad_dump_uint},
+ {512, 32, "PortSLRcvFECN15", mad_dump_uint},
+ {0, 0}, /* IB_PC_SL_RCV_FECN_LAST_F */
+
+ /*
+ * PortSLRcvBECN fields
+ */
+ {32, 32, "PortSLRcvBECN0", mad_dump_uint},
+ {64, 32, "PortSLRcvBECN1", mad_dump_uint},
+ {96, 32, "PortSLRcvBECN2", mad_dump_uint},
+ {128, 32, "PortSLRcvBECN3", mad_dump_uint},
+ {160, 32, "PortSLRcvBECN4", mad_dump_uint},
+ {192, 32, "PortSLRcvBECN5", mad_dump_uint},
+ {224, 32, "PortSLRcvBECN6", mad_dump_uint},
+ {256, 32, "PortSLRcvBECN7", mad_dump_uint},
+ {288, 32, "PortSLRcvBECN8", mad_dump_uint},
+ {320, 32, "PortSLRcvBECN9", mad_dump_uint},
+ {352, 32, "PortSLRcvBECN10", mad_dump_uint},
+ {384, 32, "PortSLRcvBECN11", mad_dump_uint},
+ {416, 32, "PortSLRcvBECN12", mad_dump_uint},
+ {448, 32, "PortSLRcvBECN13", mad_dump_uint},
+ {480, 32, "PortSLRcvBECN14", mad_dump_uint},
+ {512, 32, "PortSLRcvBECN15", mad_dump_uint},
+ {0, 0}, /* IB_PC_SL_RCV_BECN_LAST_F */
+
+ /*
+ * PortXmitConCtrl fields
+ */
+ {32, 32, "PortXmitTimeCong", mad_dump_uint},
+ {0, 0}, /* IB_PC_XMIT_CON_CTRL_LAST_F */
+
+ /*
+ * PortVLXmitTimeCong fields
+ */
+ {32, 32, "PortVLXmitTimeCong0", mad_dump_uint},
+ {64, 32, "PortVLXmitTimeCong1", mad_dump_uint},
+ {96, 32, "PortVLXmitTimeCong2", mad_dump_uint},
+ {128, 32, "PortVLXmitTimeCong3", mad_dump_uint},
+ {160, 32, "PortVLXmitTimeCong4", mad_dump_uint},
+ {192, 32, "PortVLXmitTimeCong5", mad_dump_uint},
+ {224, 32, "PortVLXmitTimeCong6", mad_dump_uint},
+ {256, 32, "PortVLXmitTimeCong7", mad_dump_uint},
+ {288, 32, "PortVLXmitTimeCong8", mad_dump_uint},
+ {320, 32, "PortVLXmitTimeCong9", mad_dump_uint},
+ {352, 32, "PortVLXmitTimeCong10", mad_dump_uint},
+ {384, 32, "PortVLXmitTimeCong11", mad_dump_uint},
+ {416, 32, "PortVLXmitTimeCong12", mad_dump_uint},
+ {448, 32, "PortVLXmitTimeCong13", mad_dump_uint},
+ {480, 32, "PortVLXmitTimeCong14", mad_dump_uint},
+ {0, 0}, /* IB_PC_VL_XMIT_TIME_CONG_LAST_F */
+
+ /*
+ * Mellanox ExtendedPortInfo fields
+ */
+ {BITSOFFS(24, 8), "StateChangeEnable", mad_dump_hex},
+ {BITSOFFS(56, 8), "LinkSpeedSupported", mad_dump_hex},
+ {BITSOFFS(88, 8), "LinkSpeedEnabled", mad_dump_hex},
+ {BITSOFFS(120, 8), "LinkSpeedActive", mad_dump_hex},
+ {0, 0}, /* IB_MLNX_EXT_PORT_LAST_F */
+
{0, 0} /* IB_FIELD_LAST_ */
};
diff --git a/trunk/ulp/libibmad/src/gs.c b/trunk/ulp/libibmad/src/gs.c
index 3cb2b25..5541b6b 100644
--- a/trunk/ulp/libibmad/src/gs.c
+++ b/trunk/ulp/libibmad/src/gs.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -38,6 +39,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <infiniband/umad.h>
#include <infiniband/mad.h>
@@ -49,8 +51,10 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
unsigned timeout, unsigned id,
const struct ibmad_port * srcport)
{
- ib_rpc_t rpc = { 0 };
+ ib_rpc_v1_t rpc = { 0 };
+ ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc;
int lid = dest->lid;
+ void *p_ret;
DEBUG("lid %u port %d", lid, port);
@@ -59,7 +63,7 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
return NULL;
}
- rpc.mgtclass = IB_PERFORMANCE_CLASS;
+ rpc.mgtclass = IB_PERFORMANCE_CLASS | IB_MAD_RPC_VERSION1;
rpc.method = IB_MAD_METHOD_GET;
rpc.attr.id = id;
@@ -75,15 +79,20 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
if (!dest->qkey)
dest->qkey = IB_DEFAULT_QP1_QKEY;
- return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
+ p_ret = mad_rpc(srcport, rpcold, dest, rcvbuf, rcvbuf);
+ errno = rpc.error;
+ return p_ret;
}
uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
int port, unsigned mask, unsigned timeout,
unsigned id, const struct ibmad_port * srcport)
{
- ib_rpc_t rpc = { 0 };
+ ib_rpc_v1_t rpc = { 0 };
+ ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc;
+
int lid = dest->lid;
+ void *p_ret;
DEBUG("lid %u port %d mask 0x%x", lid, port, mask);
@@ -95,7 +104,7 @@ uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
if (!mask)
mask = ~0;
- rpc.mgtclass = IB_PERFORMANCE_CLASS;
+ rpc.mgtclass = IB_PERFORMANCE_CLASS | IB_MAD_RPC_VERSION1;
rpc.method = IB_MAD_METHOD_SET;
rpc.attr.id = id;
@@ -115,5 +124,7 @@ uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
if (!dest->qkey)
dest->qkey = IB_DEFAULT_QP1_QKEY;
- return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
+ p_ret = mad_rpc(srcport, rpcold, dest, rcvbuf, rcvbuf);
+ errno = rpc.error;
+ return p_ret;
}
diff --git a/trunk/ulp/libibmad/src/ibmad_exports.src b/trunk/ulp/libibmad/src/ibmad_exports.src
index d0f9480..c0d3489 100644
--- a/trunk/ulp/libibmad/src/ibmad_exports.src
+++ b/trunk/ulp/libibmad/src/ibmad_exports.src
@@ -2,42 +2,133 @@ LIBRARY libibmad.dll
#ifndef _WIN64
EXPORTS
- mad_set_field;
- mad_get_field;
- mad_set_array;
- mad_get_array;
- mad_set_field64;
- mad_get_field64;
- mad_decode_field;
- mad_encode_field;
- mad_encode;
- mad_trid;
- mad_build_pkt;
- mad_register_port_client;
- mad_register_client;
- mad_register_server;
- mad_class_agent;
- mad_send;
- mad_receive;
- mad_respond;
- mad_alloc;
- mad_free;
- madrpc_portid;
- madrpc_init;
- madrpc_set_retries;
- madrpc_set_timeout;
- madrpc_show_errors;
- smp_query;
- smp_set;
- smp_query_via;
- ib_vendor_call;
- ib_path_query;
- ib_resolve_smlid;
- ib_resolve_portid_str;
- ib_resolve_self;
- portid2str;
- portid2portnum;
- str2drpath;
- drpath2str;
- xdump
+ xdump;
+ mad_dump_field;
+ mad_dump_val;
+ mad_print_field;
+ mad_dump_array;
+ mad_dump_bitfield;
+ mad_dump_hex;
+ mad_dump_int;
+ mad_dump_linkdowndefstate;
+ mad_dump_linkspeed;
+ mad_dump_linkspeeden;
+ mad_dump_linkspeedsup;
+ mad_dump_linkspeedext;
+ mad_dump_linkspeedexten;
+ mad_dump_linkspeedextsup;
+ mad_dump_linkwidth;
+ mad_dump_linkwidthen;
+ mad_dump_linkwidthsup;
+ mad_dump_mlnx_ext_port_info;
+ mad_dump_mtu;
+ mad_dump_node_type;
+ mad_dump_nodedesc;
+ mad_dump_nodeinfo;
+ mad_dump_opervls;
+ mad_dump_fields;
+ mad_dump_perfcounters;
+ mad_dump_perfcounters_ext;
+ mad_dump_perfcounters_xmt_sl;
+ mad_dump_perfcounters_rcv_sl;
+ mad_dump_perfcounters_xmt_disc;
+ mad_dump_perfcounters_rcv_err;
+ mad_dump_physportstate;
+ mad_dump_portcapmask;
+ mad_dump_portinfo;
+ mad_dump_portsamples_control;
+ mad_dump_perfcounters_port_op_rcv_counters;
+ mad_dump_perfcounters_port_flow_ctl_counters;
+ mad_dump_perfcounters_port_vl_op_packet;
+ mad_dump_perfcounters_port_vl_op_data;
+ mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors;
+ mad_dump_perfcounters_port_vl_xmit_wait_counters;
+ mad_dump_perfcounters_sw_port_vl_congestion;
+ mad_dump_perfcounters_rcv_con_ctrl;
+ mad_dump_perfcounters_sl_rcv_fecn;
+ mad_dump_perfcounters_sl_rcv_becn;
+ mad_dump_perfcounters_xmit_con_ctrl;
+ mad_dump_perfcounters_vl_xmit_time_cong;
+ mad_dump_portstates;
+ mad_dump_portstate;
+ mad_dump_rhex;
+ mad_dump_sltovl;
+ mad_dump_string;
+ mad_dump_switchinfo;
+ mad_dump_uint;
+ mad_dump_vlarbitration;
+ mad_dump_vlcap;
+ mad_get_field;
+ mad_set_field;
+ mad_get_field64;
+ mad_set_field64;
+ mad_get_array;
+ mad_set_array;
+ pma_query_via;
+ performance_reset_via;
+ mad_build_pkt;
+ mad_decode_field;
+ mad_encode;
+ mad_encode_field;
+ mad_trid;
+ portid2portnum;
+ portid2str;
+ str2drpath;
+ drpath2str;
+ mad_class_agent;
+ mad_register_client;
+ mad_register_server;
+ mad_register_client_via;
+ mad_register_server_via;
+ ib_resolve_portid_str;
+ ib_resolve_self;
+ ib_resolve_smlid;
+ ibdebug;
+ mad_rpc_open_port;
+ mad_rpc_close_port;
+ mad_rpc;
+ mad_rpc_rmpp;
+ mad_rpc_portid;
+ mad_rpc_class_agent;
+ mad_rpc_set_retries;
+ mad_rpc_set_timeout;
+ mad_get_timeout;
+ mad_get_retries;
+ madrpc;
+ madrpc_def_timeout;
+ madrpc_init;
+ madrpc_portid;
+ madrpc_rmpp;
+ madrpc_save_mad;
+ madrpc_set_retries;
+ madrpc_set_timeout;
+ madrpc_show_errors;
+ ib_path_query;
+ sa_call;
+ sa_rpc_call;
+ mad_alloc;
+ 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_query_status_via;
+ smp_set_via;
+ smp_set_status_via;
+ ib_path_query_via;
+ ib_resolve_smlid_via;
+ ib_resolve_guid_via;
+ ib_resolve_gid_via;
+ ib_resolve_portid_str_via;
+ ib_resolve_self_via;
+ mad_field_name;
+ bm_call_via;
+ mad_dump_port_ext_speeds_counters;
#endif
diff --git a/trunk/ulp/libibmad/src/libibmad.map b/trunk/ulp/libibmad/src/libibmad.map
index 5778e3e..508c18b 100644
--- a/trunk/ulp/libibmad/src/libibmad.map
+++ b/trunk/ulp/libibmad/src/libibmad.map
@@ -12,9 +12,13 @@ IBMAD_1.3 {
mad_dump_linkspeed;
mad_dump_linkspeeden;
mad_dump_linkspeedsup;
+ mad_dump_linkspeedext;
+ mad_dump_linkspeedexten;
+ mad_dump_linkspeedextsup;
mad_dump_linkwidth;
mad_dump_linkwidthen;
mad_dump_linkwidthsup;
+ mad_dump_mlnx_ext_port_info;
mad_dump_mtu;
mad_dump_node_type;
mad_dump_nodedesc;
@@ -31,6 +35,18 @@ IBMAD_1.3 {
mad_dump_portcapmask;
mad_dump_portinfo;
mad_dump_portsamples_control;
+ mad_dump_perfcounters_port_op_rcv_counters;
+ mad_dump_perfcounters_port_flow_ctl_counters;
+ mad_dump_perfcounters_port_vl_op_packet;
+ mad_dump_perfcounters_port_vl_op_data;
+ mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors;
+ mad_dump_perfcounters_port_vl_xmit_wait_counters;
+ mad_dump_perfcounters_sw_port_vl_congestion;
+ mad_dump_perfcounters_rcv_con_ctrl;
+ mad_dump_perfcounters_sl_rcv_fecn;
+ mad_dump_perfcounters_sl_rcv_becn;
+ mad_dump_perfcounters_xmit_con_ctrl;
+ mad_dump_perfcounters_vl_xmit_time_cong;
mad_dump_portstates;
mad_dump_portstate;
mad_dump_rhex;
@@ -101,7 +117,9 @@ IBMAD_1.3 {
ib_vendor_call;
ib_vendor_call_via;
smp_query_via;
+ smp_query_status_via;
smp_set_via;
+ smp_set_status_via;
ib_path_query_via;
ib_resolve_smlid_via;
ib_resolve_guid_via;
@@ -110,5 +128,6 @@ IBMAD_1.3 {
ib_resolve_self_via;
mad_field_name;
bm_call_via;
+ mad_dump_port_ext_speeds_counters;
local: *;
};
diff --git a/trunk/ulp/libibmad/src/mad.c b/trunk/ulp/libibmad/src/mad.c
index acd0e85..463c61d 100644
--- a/trunk/ulp/libibmad/src/mad.c
+++ b/trunk/ulp/libibmad/src/mad.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -83,12 +84,12 @@ void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath, void *data)
mad_set_field(buf, 0, IB_MAD_METHOD_F, rpc->method);
mad_set_field(buf, 0, IB_MAD_RESPONSE_F, is_resp ? 1 : 0);
mad_set_field(buf, 0, IB_MAD_CLASSVER_F,
- rpc->mgtclass == IB_SA_CLASS ? 2 : 1);
- mad_set_field(buf, 0, IB_MAD_MGMTCLASS_F, rpc->mgtclass);
+ (rpc->mgtclass & 0xff) == IB_SA_CLASS ? 2 : 1);
+ mad_set_field(buf, 0, IB_MAD_MGMTCLASS_F, rpc->mgtclass & 0xff);
mad_set_field(buf, 0, IB_MAD_BASEVER_F, 1);
/* second word */
- if (rpc->mgtclass == IB_SMI_DIRECT_CLASS) {
+ if ((rpc->mgtclass & 0xff) == IB_SMI_DIRECT_CLASS) {
if (!drpath) {
IBWARN("encoding dr mad without drpath (null)");
return NULL;
@@ -116,7 +117,7 @@ void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath, void *data)
/* words 7,8 */
mad_set_field64(buf, 0, IB_MAD_MKEY_F, rpc->mkey);
- if (rpc->mgtclass == IB_SMI_DIRECT_CLASS) {
+ if ((rpc->mgtclass & 0xff) == IB_SMI_DIRECT_CLASS) {
/* word 9 */
mad_set_field(buf, 0, IB_DRSMP_DRDLID_F,
drpath->drdlid ? drpath->drdlid : 0xffff);
@@ -130,14 +131,14 @@ void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath, void *data)
mad_set_array(buf, 0, IB_DRSMP_PATH_F, drpath->p);
}
- if (rpc->mgtclass == IB_SA_CLASS)
+ if ((rpc->mgtclass & 0xff) == IB_SA_CLASS)
mad_set_field64(buf, 0, IB_SA_COMPMASK_F, rpc->mask);
if (data)
memcpy((char *)buf + rpc->dataoffs, data, rpc->datasz);
/* vendor mads range 2 */
- if (mad_is_vendor_range2(rpc->mgtclass))
+ if (mad_is_vendor_range2(rpc->mgtclass & 0xff))
mad_set_field(buf, 0, IB_VEND2_OUI_F, rpc->oui);
return (uint8_t *) buf + IB_MAD_SIZE;
@@ -147,9 +148,9 @@ int mad_build_pkt(void *umad, ib_rpc_t * rpc, ib_portid_t * dport,
ib_rmpp_hdr_t * rmpp, void *data)
{
uint8_t *p, *mad;
- int lid_routed = rpc->mgtclass != IB_SMI_DIRECT_CLASS;
- int is_smi = (rpc->mgtclass == IB_SMI_CLASS ||
- rpc->mgtclass == IB_SMI_DIRECT_CLASS);
+ int lid_routed = (rpc->mgtclass & 0xff) != IB_SMI_DIRECT_CLASS;
+ int is_smi = ((rpc->mgtclass & 0xff) == IB_SMI_CLASS ||
+ (rpc->mgtclass & 0xff) == IB_SMI_DIRECT_CLASS);
struct ib_mad_addr addr;
if (!is_smi)
diff --git a/trunk/ulp/libibmad/src/register.c b/trunk/ulp/libibmad/src/register.c
index 0ff8006..1fdb64a 100644
--- a/trunk/ulp/libibmad/src/register.c
+++ b/trunk/ulp/libibmad/src/register.c
@@ -77,7 +77,7 @@ static int mgmt_class_vers(int mgmt_class)
int mad_class_agent(int mgmt)
{
- if (mgmt < 1 || mgmt > MAX_CLASS)
+ if (mgmt < 1 || mgmt >= MAX_CLASS)
return -1;
return ibmp->class_agents[mgmt];
}
diff --git a/trunk/ulp/libibmad/src/rpc.c b/trunk/ulp/libibmad/src/rpc.c
index c5246fe..d20c321 100644
--- a/trunk/ulp/libibmad/src/rpc.c
+++ b/trunk/ulp/libibmad/src/rpc.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2009 HNR Consulting. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -119,14 +120,14 @@ int mad_rpc_portid(struct ibmad_port *srcport)
int mad_rpc_class_agent(struct ibmad_port *port, int class)
{
- if (class < 1 || class > MAX_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 max_retries)
+ int timeout, int max_retries, int *p_error)
{
uint32_t trid; /* only low 32 bits */
int retries;
@@ -181,6 +182,7 @@ _do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
return length;
}
+ *p_error = ETIMEDOUT;
ERRS("timeout after %d retries, %d ms", retries, timeout * retries);
return -1;
}
@@ -212,7 +214,11 @@ void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
int status, len;
uint8_t sndbuf[1024], rcvbuf[1024], *mad;
int redirect = 1;
+ ib_rpc_v1_t *rpcv1 = (ib_rpc_v1_t *)rpc;
+ int error = 0;
+ if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
+ rpcv1->error = 0;
while (redirect) {
len = 0;
memset(sndbuf, 0, umad_size() + IB_MAD_SIZE);
@@ -221,9 +227,12 @@ void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
return NULL;
if ((len = _do_madrpc(port->port_id, sndbuf, rcvbuf,
- port->class_agents[rpc->mgtclass],
+ port->class_agents[rpc->mgtclass & 0xff],
len, mad_get_timeout(port, rpc->timeout),
- mad_get_retries(port))) < 0) {
+ mad_get_retries(port), &error)) < 0) {
+ if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) ==
+ IB_MAD_RPC_VERSION1)
+ rpcv1->error = error;
IBWARN("_do_madrpc failed; dport (%s)",
portid2str(dport));
return NULL;
@@ -243,6 +252,10 @@ void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
redirect = 0;
}
+ if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
+ rpcv1->error = error;
+ rpc->rstatus = status;
+
if (status != 0) {
ERRS("MAD completed with error status 0x%x; dport (%s)",
status, portid2str(dport));
@@ -265,22 +278,31 @@ void *mad_rpc_rmpp(const struct ibmad_port *port, ib_rpc_t * rpc,
{
int status, len;
uint8_t sndbuf[1024], rcvbuf[1024], *mad;
+ ib_rpc_v1_t *rpcv1 = (ib_rpc_v1_t *)rpc;
+ int error = 0;
memset(sndbuf, 0, umad_size() + IB_MAD_SIZE);
DEBUG("rmpp %p data %p", rmpp, data);
+ if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
+ rpcv1->error = 0;
if ((len = mad_build_pkt(sndbuf, rpc, dport, rmpp, data)) < 0)
return NULL;
if ((len = _do_madrpc(port->port_id, sndbuf, rcvbuf,
- port->class_agents[rpc->mgtclass],
+ port->class_agents[rpc->mgtclass & 0xff],
len, mad_get_timeout(port, rpc->timeout),
- mad_get_retries(port))) < 0) {
+ mad_get_retries(port), &error)) < 0) {
+ if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
+ rpcv1->error = error;
IBWARN("_do_madrpc failed; dport (%s)", portid2str(dport));
return NULL;
}
+ if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
+ rpcv1->error = error;
+
mad = umad_get_mad(rcvbuf);
if ((status = mad_get_field(mad, 0, IB_MAD_STATUS_F)) != 0) {
diff --git a/trunk/ulp/libibmad/src/serv.c b/trunk/ulp/libibmad/src/serv.c
index df61f25..2e3b7ef 100644
--- a/trunk/ulp/libibmad/src/serv.c
+++ b/trunk/ulp/libibmad/src/serv.c
@@ -72,7 +72,7 @@ int mad_send_via(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
(char *)umad_get_mad(umad) + rpc->dataoffs, rpc->datasz);
}
- if (umad_send(srcport->port_id, srcport->class_agents[rpc->mgtclass],
+ if (umad_send(srcport->port_id, srcport->class_agents[rpc->mgtclass & 0xff],
umad, IB_MAD_SIZE, mad_get_timeout(srcport, rpc->timeout),
0) < 0) {
IBWARN("send failed; %m");
diff --git a/trunk/ulp/libibmad/src/smp.c b/trunk/ulp/libibmad/src/smp.c
index 3ff58ce..a337663 100644
--- a/trunk/ulp/libibmad/src/smp.c
+++ b/trunk/ulp/libibmad/src/smp.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -45,11 +46,12 @@
#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 struct ibmad_port *srcport)
+uint8_t *smp_set_status_via(void *data, ib_portid_t * portid, unsigned attrid,
+ unsigned mod, unsigned timeout, int *rstatus,
+ const struct ibmad_port *srcport)
{
ib_rpc_t rpc = { 0 };
+ uint8_t *res;
DEBUG("attr 0x%x mod 0x%x route %s", attrid, mod, portid2str(portid));
if ((portid->lid <= 0) ||
@@ -69,7 +71,18 @@ uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
portid->sl = 0;
portid->qp = 0;
- return mad_rpc(srcport, &rpc, portid, data, data);
+ res = mad_rpc(srcport, &rpc, portid, data, data);
+ if (rstatus)
+ *rstatus = rpc.rstatus;
+ return res;
+}
+
+uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
+ unsigned mod, unsigned timeout,
+ const struct ibmad_port *srcport)
+{
+ return smp_set_status_via(data, portid, attrid, mod, timeout, NULL,
+ srcport);
}
uint8_t *smp_set(void *data, ib_portid_t * portid, unsigned attrid,
@@ -78,11 +91,12 @@ uint8_t *smp_set(void *data, ib_portid_t * portid, unsigned attrid,
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 struct ibmad_port * srcport)
+uint8_t *smp_query_status_via(void *rcvbuf, ib_portid_t * portid,
+ unsigned attrid, unsigned mod, unsigned timeout,
+ int *rstatus, const struct ibmad_port * srcport)
{
ib_rpc_t rpc = { 0 };
+ uint8_t *res;
DEBUG("attr 0x%x mod 0x%x route %s", attrid, mod, portid2str(portid));
rpc.method = IB_MAD_METHOD_GET;
@@ -102,7 +116,18 @@ uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
portid->sl = 0;
portid->qp = 0;
- return mad_rpc(srcport, &rpc, portid, 0, rcvbuf);
+ res = mad_rpc(srcport, &rpc, portid, rcvbuf, rcvbuf);
+ if (rstatus)
+ *rstatus = rpc.rstatus;
+ return res;
+}
+
+uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
+ unsigned mod, unsigned timeout,
+ const struct ibmad_port * srcport)
+{
+ return smp_query_status_via(rcvbuf, portid, attrid, mod, timeout, NULL,
+ srcport);
}
uint8_t *smp_query(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
diff --git a/trunk/ulp/libibmad/src/vendor.c b/trunk/ulp/libibmad/src/vendor.c
index 11efd76..22d6843 100644
--- a/trunk/ulp/libibmad/src/vendor.c
+++ b/trunk/ulp/libibmad/src/vendor.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
+ * Copyright (c) 2011 Mellanox Technologies LTD. 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
@@ -38,6 +39,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <infiniband/mad.h>
#include "mad_internal.h"
@@ -61,8 +63,10 @@ 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 };
+ ib_rpc_v1_t rpc = { 0 };
+ ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc;
int range1 = 0, resp_expected;
+ void *p_ret;
DEBUG("route %s data %p", portid2str(portid), data);
if (portid->lid <= 0)
@@ -74,7 +78,7 @@ uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
resp_expected = response_expected(call->method);
- rpc.mgtclass = call->mgmt_class;
+ rpc.mgtclass = call->mgmt_class | IB_MAD_RPC_VERSION1;
rpc.method = call->method;
rpc.attr.id = call->attrid;
@@ -97,8 +101,11 @@ uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
if (!portid->qkey)
portid->qkey = IB_DEFAULT_QP1_QKEY;
- if (resp_expected)
- return mad_rpc_rmpp(srcport, &rpc, portid, 0, data); /* FIXME: no RMPP for now */
+ if (resp_expected) {
+ p_ret = mad_rpc_rmpp(srcport, rpcold, portid, 0, data); /* FIXME: no RMPP for now */
+ errno = rpc.error;
+ return p_ret;
+ }
- return mad_send_via(&rpc, portid, 0, data, srcport) < 0 ? 0 : data; /* FIXME: no RMPP for now */
+ return mad_send_via(rpcold, portid, 0, data, srcport) < 0 ? 0 : data; /* FIXME: no RMPP for now */
}
diff --git a/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
index 49ff743..300094e 100644
--- a/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
+++ b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2009 Voltaire, Inc. All rights reserved.
* Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
+ * Copyright (c) 2010 Mellanox Technologies LTD. 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
@@ -39,9 +40,13 @@
#include <infiniband/mad.h>
#include <iba/ib_types.h>
+#include <infiniband/ibnetdisc_osd.h>
+
struct ibnd_chassis; /* forward declare */
struct ibnd_port; /* forward declare */
+#define CHASSIS_TYPE_SIZE 20
+
/** =========================================================================
* Node
*/
@@ -79,6 +84,7 @@ typedef struct ibnd_node {
struct ibnd_node *next_chassis_node; /* next node in ibnd_chassis_t->nodes */
struct ibnd_chassis *chassis; /* if != NULL the chassis this node belongs to */
unsigned char ch_type;
+ char ch_type_str[CHASSIS_TYPE_SIZE];
unsigned char ch_anafanum;
unsigned char ch_slotnum;
unsigned char ch_slot;
@@ -149,6 +155,8 @@ typedef struct ibnd_fabric {
* or by default the node you ar running on
*/
ibnd_node_t *from_node;
+ int from_portnum;
+
/* NULL term list of all nodes in the fabric */
ibnd_node_t *nodes;
/* NULL terminated list of all chassis found in the fabric */
@@ -187,6 +195,9 @@ IBND_EXPORT ibnd_fabric_t *ibnd_load_fabric(const char *file,
IBND_EXPORT int ibnd_cache_fabric(ibnd_fabric_t * fabric, const char *file,
unsigned int flags);
+#define IBND_CACHE_FABRIC_FLAG_DEFAULT 0x0000
+#define IBND_CACHE_FABRIC_FLAG_NO_OVERWRITE 0x0001
+
/** =========================================================================
* Node operations
*/
@@ -202,6 +213,17 @@ IBND_EXPORT void ibnd_iter_nodes_type(ibnd_fabric_t * fabric,
int node_type, void *user_data);
/** =========================================================================
+ * Port operations
+ */
+IBND_EXPORT ibnd_port_t *ibnd_find_port_guid(ibnd_fabric_t * fabric,
+ uint64_t guid);
+IBND_EXPORT ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric,
+ char *dr_str);
+typedef void (*ibnd_iter_port_func_t) (ibnd_port_t * port, void *user_data);
+IBND_EXPORT void ibnd_iter_ports(ibnd_fabric_t * fabric,
+ ibnd_iter_port_func_t func, void *user_data);
+
+/** =========================================================================
* Chassis queries
*/
IBND_EXPORT uint64_t ibnd_get_chassis_guid(ibnd_fabric_t * fabric,
diff --git a/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h
new file mode 100644
index 0000000..b25104a
--- /dev/null
+++ b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011 Lawrence Livermore National Security. 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_OSD_H_
+#define _IBNETDISC_OSD_H_
+
+/* Define OS specific bits */
+
+/* Windows */
+
+#endif /* _IBNETDISC_OSD_H_ */
diff --git a/trunk/ulp/libibnetdisc/src/chassis.c b/trunk/ulp/libibnetdisc/src/chassis.c
index 25d7473..5726f8e 100644
--- a/trunk/ulp/libibnetdisc/src/chassis.c
+++ b/trunk/ulp/libibnetdisc/src/chassis.c
@@ -50,9 +50,9 @@
#include "internal.h"
#include "chassis.h"
-static char *ChassisTypeStr[6] =
-{ "", "ISR9288", "ISR9096", "ISR2012", "ISR2004", "ISR4700" };
-static char *ChassisSlotTypeStr[4] = { "", "Line", "Spine", "SRBD" };
+static char *ChassisTypeStr[] =
+{ "", "ISR9288", "ISR9096", "ISR2012", "ISR2004", "ISR4700", "ISR4200" };
+static char *ChassisSlotTypeStr[] = { "", "Line", "Spine", "SRBD" };
typedef struct chassis_scan {
ibnd_chassis_t *first_chassis;
@@ -62,30 +62,53 @@ typedef struct chassis_scan {
char *ibnd_get_chassis_type(ibnd_node_t * node)
{
+ int chassis_type;
+
if (!node) {
IBND_DEBUG("node parameter NULL\n");
return NULL;
}
- /* Currently, only if Voltaire chassis */
- if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
- return NULL;
if (!node->chassis)
return NULL;
- if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4700_CT)
- return NULL;
- return ChassisTypeStr[node->ch_type];
+
+ chassis_type = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
+
+ switch (chassis_type)
+ {
+ case VTR_VENDOR_ID: /* Voltaire chassis */
+ {
+ if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
+ return NULL;
+ return ChassisTypeStr[node->ch_type];
+ }
+ case MLX_VENDOR_ID:
+ {
+ if (node->ch_type_str[0] == '\0')
+ return NULL;
+ return node->ch_type_str;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return NULL;
}
char *ibnd_get_chassis_slot_str(ibnd_node_t * node, char *str, size_t size)
{
+ int vendor_id;
+
if (!node) {
IBND_DEBUG("node parameter NULL\n");
return NULL;
}
- /* Currently, only if Voltaire chassis */
- if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
+ /* Currently, only if Voltaire or Mellanox chassis */
+ vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
+
+ if ((vendor_id != VTR_VENDOR_ID) && (vendor_id != MLX_VENDOR_ID))
return NULL;
if (!node->chassis)
return NULL;
@@ -286,11 +309,18 @@ static int is_spine_4700x2(ibnd_node_t * n)
return (devid == VTR_DEVID_SFB4700X2);
}
+static int is_spine_4200(ibnd_node_t * n)
+{
+ uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
+ return (devid == VTR_DEVID_SFB4200);
+}
+
static int is_spine(ibnd_node_t * n)
{
return (is_spine_9096(n) || is_spine_9288(n) ||
is_spine_2004(n) || is_spine_2012(n) ||
- is_spine_4700(n) || is_spine_4700x2(n));
+ is_spine_4700(n) || is_spine_4700x2(n) ||
+ is_spine_4200(n));
}
static int is_line_24(ibnd_node_t * n)
@@ -376,6 +406,18 @@ char anafa_line_slot_2_sfb18x2[37] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
+/* LB slot = table[spine port] */
+char line_slot_2_sfb4200[37] = {
+ 0,
+ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
+ 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9};
+/* LB asic num = table[spine port] */
+char anafa_line_slot_2_sfb4200[37] = {
+ 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
/* IPR FCR modules connectivity while using sFB4 port as reference */
char ipr_slot_2_sfb4_port[37] = {
0,
@@ -424,6 +466,18 @@ char anafa_spine18x2_slot_2_slb[37] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
+/* FB slot = table[line port] */
+char sfb4200_slot_2_slb[37] = {
+ 0,
+ 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+/* FB asic = table[line port] */
+char anafa_sfb4200_slot_2_slb[37] = {
+ 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 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 }; */
@@ -454,10 +508,13 @@ static int get_sfb_slot(ibnd_node_t * n, ibnd_port_t * lineport)
n->ch_type = ISR4700_CT;
n->ch_slotnum = spine18_slot_2_slb[lineport->portnum];
n->ch_anafanum = anafa_spine18x2_slot_2_slb[lineport->portnum];
+ } else if (is_spine_4200(n)) {
+ n->ch_type = ISR4200_CT;
+ n->ch_slotnum = sfb4200_slot_2_slb[lineport->portnum];
+ n->ch_anafanum = anafa_sfb4200_slot_2_slb[lineport->portnum];
} else {
IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
n->guid);
- return -1;
}
return 0;
}
@@ -498,7 +555,6 @@ static int get_router_slot(ibnd_node_t * n, ibnd_port_t * spineport)
} else {
IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
spineport->node->guid);
- return -1;
}
return 0;
}
@@ -530,14 +586,177 @@ static int get_slb_slot(ibnd_node_t * n, ibnd_port_t * spineport)
n->ch_type = ISR4700_CT;
n->ch_slotnum = line_slot_2_sfb18x2[spineport->portnum];
n->ch_anafanum = anafa_line_slot_2_sfb18x2[spineport->portnum];
+ } else if (is_spine_4200(spineport->node)) {
+ n->ch_type = ISR4200_CT;
+ n->ch_slotnum = line_slot_2_sfb4200[spineport->portnum];
+ n->ch_anafanum = anafa_line_slot_2_sfb4200[spineport->portnum];
} else {
IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
spineport->node->guid);
- return -1;
}
return 0;
}
+
+/*
+ This function called for every Mellanox node in fabric
+*/
+static int fill_mellanox_chassis_record(ibnd_node_t * node)
+{
+ int p = 0;
+ ibnd_port_t *port;
+
+ char node_desc[IB_SMP_DATA_SIZE];
+ char *system_name;
+ char *system_type;
+ char *system_slot_name;
+ char *node_index;
+ char *iter;
+ int dev_id;
+
+ /*
+ The node description has the following format:
+
+ 'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
+
+ - System slot name in our systems can be L[01-36] , S[01-18]
+ - Node index is always 1 (we don.t have boards with multiple IS4 chips).
+ - System name is taken from the currently configured host name.
+ -The board type is optional and we don.t set it currently - A leaf or spine slot can currently hold a single type of board.
+ */
+
+ memcpy(node_desc, node->nodedesc, IB_SMP_DATA_SIZE);
+
+ IBND_DEBUG("fill_mellanox_chassis_record: node_desc:%s \n",node_desc);
+
+ if (node->ch_found) /* somehow this node has already been passed */
+ return 0;
+
+ /* All mellanox IS4 switches have the same vendor id*/
+ dev_id = mad_get_field(node->info, 0,IB_NODE_DEVID_F);
+ if (dev_id != MLX_DEVID_IS4)
+ return 0;
+
+ if((node_desc[0] != 'M') ||
+ (node_desc[1] != 'F') ||
+ (node_desc[2] != '0') ||
+ (node_desc[3] != ';')) {
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s \n",node_desc);
+ return 0;
+ }
+
+ /* parse system name*/
+ system_name = &node_desc[4];
+ for (iter = system_name ; (*iter != ':') && (*iter != '\0') ; iter++);
+ if(*iter == '\0'){
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_name failed) \n",node_desc);
+ return 0;
+ }
+ *iter = '\0';
+ iter++;
+ /* parse system type*/
+ system_type = iter;
+ for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
+ if(*iter == '\0'){
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_type failed) \n",node_desc);
+ return 0;
+ }
+ *iter = '\0';
+ iter++;
+ /* parse system slot name*/
+ system_slot_name = iter;
+ for ( ; (*iter != '/') && (*iter != ':') && (*iter != '\0') ; iter++);
+ if(*iter == '\0'){
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_slot_name failed) \n",node_desc);
+ return 0;
+ }
+ if(*iter == ':'){
+ *iter = '\0';
+ iter++;
+ for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
+ if(*iter == '\0'){
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get board type failed) \n",node_desc);
+ return 0;
+ }
+ }
+ *iter = '\0';
+ iter++;
+ node_index = iter;
+ if(node_index[0] != 'U'){
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get node index) \n",node_desc);
+ return 0;
+ }
+
+ /* set Chip number (node index) */
+ node->ch_anafanum = (unsigned char) atoi(&node_index[1]);
+ if(node->ch_anafanum != 1){
+ IBND_DEBUG("Unexpected Chip number:%d \n",node->ch_anafanum);
+ }
+
+
+ /* set Line Spine numbers */
+ if(system_slot_name[0] == 'L')
+ node->ch_slot = LINE_CS;
+ else if(system_slot_name[0] == 'S')
+ node->ch_slot = SPINE_CS;
+ else{
+ IBND_DEBUG("fill_mellanox_chassis_record: Unsupported system_slot_name:%s \n",system_slot_name);
+ return 0;
+ }
+
+ /* The switch will be displayed under Line or Spine and not under Chassis switches */
+ node->ch_found = 1;
+
+ node->ch_slotnum = (unsigned char) atoi(&system_slot_name[1]);
+ if((node->ch_slot == LINE_CS && (node->ch_slotnum > (LINES_MAX_NUM + 1))) ||
+ (node->ch_slot == SPINE_CS && (node->ch_slotnum > (SPINES_MAX_NUM + 1)))){
+ IBND_ERROR("fill_mellanox_chassis_record: invalid slot number:%d \n",node->ch_slotnum);
+ node->ch_slotnum = 0;
+ return 0;
+ }
+
+ /*set ch_type_str*/
+ strncpy(node->ch_type_str , system_type, sizeof(node->ch_type_str)-1);
+
+ /* Line ports 1-18 are mapped to external ports 1-18*/
+ if(node->ch_slot == LINE_CS)
+ {
+ for (p = 1; p <= node->numports && p <= 18 ; p++) {
+ port = node->ports[p];
+ if (!port)
+ continue;
+ port->ext_portnum = p;
+ }
+ }
+
+ return 0;
+}
+
+static int insert_mellanox_line_and_spine(ibnd_node_t * node, ibnd_chassis_t * chassis)
+{
+ if (node->ch_slot == LINE_CS){
+
+ if (chassis->linenode[node->ch_slotnum])
+ return 0; /* already filled slot */
+
+ chassis->linenode[node->ch_slotnum] = node;
+ }
+ else if (node->ch_slot == SPINE_CS){
+
+ if (chassis->spinenode[node->ch_slotnum])
+ return 0; /* already filled slot */
+
+ chassis->spinenode[node->ch_slotnum] = node;
+ }
+ else
+ return 0;
+
+ node->chassis = chassis;
+
+ return 0;
+}
+
+
/* forward declare this */
static void voltaire_portmap(ibnd_port_t * port);
/*
@@ -588,8 +807,7 @@ static int fill_voltaire_chassis_record(ibnd_node_t * node)
}
if (!node->ch_type)
/* we assume here that remoteport belongs to line */
- if (get_sfb_slot(node, port->remoteport))
- return -1;
+ get_sfb_slot(node, port->remoteport);
/* we could break here, but need to find if more routers connected */
}
@@ -607,8 +825,7 @@ static int fill_voltaire_chassis_record(ibnd_node_t * node)
continue;
/* we assume here that remoteport belongs to spine */
- if (get_slb_slot(node, port->remoteport))
- return -1;
+ get_slb_slot(node, port->remoteport);
break;
}
}
@@ -1025,6 +1242,7 @@ int group_nodes(ibnd_fabric_t * fabric)
ibnd_chassis_t *chassis;
ibnd_chassis_t *ch, *ch_next;
chassis_scan_t chassis_scan;
+ int vendor_id;
chassis_scan.first_chassis = NULL;
chassis_scan.current_chassis = NULL;
@@ -1035,10 +1253,16 @@ int group_nodes(ibnd_fabric_t * fabric)
/* according to internal connectivity */
/* not very efficient but clear code so... */
for (node = fabric->switches; node; node = node->type_next) {
- if (mad_get_field(node->info, 0,
- IB_NODE_VENDORID_F) == VTR_VENDOR_ID
+
+ vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
+
+ if (vendor_id == VTR_VENDOR_ID
&& fill_voltaire_chassis_record(node))
goto cleanup;
+ else if (vendor_id == MLX_VENDOR_ID
+ && fill_mellanox_chassis_record(node))
+ goto cleanup;
+
}
/* separate every Voltaire chassis from each other and build linked list of them */
@@ -1084,8 +1308,10 @@ int group_nodes(ibnd_fabric_t * fabric)
/* now, make another pass to see which nodes are part of chassis */
/* (defined as chassis->nodecount > 1) */
for (node = fabric->nodes; node; node = node->next) {
- if (mad_get_field(node->info, 0,
- IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
+
+ vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
+
+ if (vendor_id == VTR_VENDOR_ID)
continue;
if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
chassis = find_chassisguid(fabric, node);
@@ -1096,6 +1322,9 @@ int group_nodes(ibnd_fabric_t * fabric)
node->ch_found = 1;
add_node_to_chassis(chassis, node);
}
+ else if (vendor_id == MLX_VENDOR_ID){
+ insert_mellanox_line_and_spine(node, chassis);
+ }
}
}
}
diff --git a/trunk/ulp/libibnetdisc/src/chassis.h b/trunk/ulp/libibnetdisc/src/chassis.h
index f8e0ee2..7a91be3 100644
--- a/trunk/ulp/libibnetdisc/src/chassis.h
+++ b/trunk/ulp/libibnetdisc/src/chassis.h
@@ -73,16 +73,20 @@
#define VTR_DEVID_SLB4018 0x5a5b
#define VTR_DEVID_SFB4700 0x5a5c
#define VTR_DEVID_SFB4700X2 0x5a5d
+#define VTR_DEVID_SFB4200 0x5a60
+
+#define MLX_DEVID_IS4 0xbd36
/* Vendor IDs (for chassis based systems) */
#define VTR_VENDOR_ID 0x8f1 /* Voltaire */
+#define MLX_VENDOR_ID 0x2c9 /* Mellanox */
#define TS_VENDOR_ID 0x5ad /* Cisco */
#define SS_VENDOR_ID 0x66a /* InfiniCon */
#define XS_VENDOR_ID 0x1397 /* Xsigo */
enum ibnd_chassis_type {
UNRESOLVED_CT, ISR9288_CT, ISR9096_CT, ISR2012_CT, ISR2004_CT,
- ISR4700_CT
+ ISR4700_CT, ISR4200_CT
};
enum ibnd_chassis_slot_type { UNRESOLVED_CS, LINE_CS, SPINE_CS, SRBD_CS };
diff --git a/trunk/ulp/libibnetdisc/src/ibnetdisc.c b/trunk/ulp/libibnetdisc/src/ibnetdisc.c
index f525d71..9800c9d 100644
--- a/trunk/ulp/libibnetdisc/src/ibnetdisc.c
+++ b/trunk/ulp/libibnetdisc/src/ibnetdisc.c
@@ -2,6 +2,7 @@
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
* Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
* Copyright (c) 2008 Lawrence Livermore National Laboratory
+ * Copyright (c) 2010 Mellanox Technologies LTD. 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
@@ -55,8 +56,13 @@
#include "chassis.h"
/* forward declare */
+struct ni_cbdata
+{
+ ibnd_node_t *node;
+ int port_num;
+};
static int query_node_info(smp_engine_t * engine, ib_portid_t * portid,
- ibnd_node_t * node);
+ struct ni_cbdata * cbdata);
static int recv_switch_info(smp_engine_t * engine, ibnd_smp_t * smp,
uint8_t * mad, void *cb_data)
@@ -79,13 +85,33 @@ static int query_switch_info(smp_engine_t * engine, ib_portid_t * portid,
static int add_port_to_dpath(ib_dr_path_t * path, int nextport)
{
- if (path->cnt > sizeof(path->p) - 1)
+ if (path->cnt > sizeof(path->p) - 2)
return -1;
++path->cnt;
path->p[path->cnt] = (uint8_t) nextport;
return path->cnt;
}
+static int retract_dpath(smp_engine_t * engine, ib_portid_t * portid)
+{
+ ibnd_scan_t *scan = engine->user_data;
+ ibnd_fabric_t *fabric = scan->fabric;
+
+ if (scan->cfg->max_hops &&
+ fabric->maxhops_discovered > scan->cfg->max_hops)
+ return 0;
+
+ /* this may seem wrong but the only time we would retract the path is
+ * if the user specified a CA for the DR path and we are retracting
+ * from that to find the node it is connected to. This counts as a
+ * positive hop discovered
+ */
+ fabric->maxhops_discovered++;
+ portid->drpath.p[portid->drpath.cnt] = 0;
+ portid->drpath.cnt--;
+ return 1;
+}
+
static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
int nextport)
{
@@ -93,7 +119,7 @@ static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
ibnd_fabric_t *fabric = scan->fabric;
if (scan->cfg->max_hops &&
- fabric->maxhops_discovered >= scan->cfg->max_hops)
+ fabric->maxhops_discovered > scan->cfg->max_hops)
return 0;
if (portid->lid) {
@@ -114,8 +140,9 @@ static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
return -1;
}
- if ((unsigned) portid->drpath.cnt > fabric->maxhops_discovered)
- fabric->maxhops_discovered = portid->drpath.cnt;
+ if (((unsigned) portid->drpath.cnt - scan->initial_hops) >
+ fabric->maxhops_discovered)
+ fabric->maxhops_discovered++;
return 1;
}
@@ -170,7 +197,8 @@ static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
if (!port) {
port = node->ports[port_num] = calloc(1, sizeof(*port));
if (!port) {
- IBND_ERROR("Failed to allocate port\n");
+ IBND_ERROR("Failed to allocate 0x%" PRIx64 " port %u\n",
+ node->guid, port_num);
return -1;
}
port->guid =
@@ -199,10 +227,27 @@ static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
if (port_num && mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
== IB_PORT_PHYS_STATE_LINKUP
&& ((node->type == IB_NODE_SWITCH && port_num != local_port) ||
- (node == fabric->from_node && port_num == local_port))) {
+ (node == fabric->from_node && port_num == fabric->from_portnum))) {
+
+ int rc = 0;
ib_portid_t path = smp->path;
- if (extend_dpath(engine, &path, port_num) > 0)
- query_node_info(engine, &path, node);
+
+ if (node->type != IB_NODE_SWITCH &&
+ node == fabric->from_node &&
+ path.drpath.cnt > 1)
+ rc = retract_dpath(engine, &path);
+ else {
+ /* we can't proceed through an HCA with DR */
+ if (path.lid == 0 || node->type == IB_NODE_SWITCH)
+ rc = extend_dpath(engine, &path, port_num);
+ }
+
+ if (rc > 0) {
+ struct ni_cbdata * cbdata = malloc(sizeof(*cbdata));
+ cbdata->node = node;
+ cbdata->port_num = port_num;
+ query_node_info(engine, &path, cbdata);
+ }
}
return 0;
@@ -253,11 +298,6 @@ static ibnd_node_t *create_node(smp_engine_t * engine, ib_portid_t * path,
return rc;
}
-static int get_last_port(ib_portid_t * path)
-{
- return path->drpath.p[path->drpath.cnt];
-}
-
static void link_ports(ibnd_node_t * node, ibnd_port_t * port,
ibnd_node_t * remotenode, ibnd_port_t * remoteport)
{
@@ -292,7 +332,9 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
ibnd_fabric_t *fabric = scan->fabric;
int i = 0;
uint8_t *node_info = mad + IB_SMP_DATA_OFFS;
- ibnd_node_t *rem_node = cb_data;
+ struct ni_cbdata *ni_cbdata = (struct ni_cbdata *)cb_data;
+ ibnd_node_t *rem_node = NULL;
+ int rem_port_num = 0;
ibnd_node_t *node;
int node_is_new = 0;
uint64_t node_guid = mad_get_field64(node_info, 0, IB_NODE_GUID_F);
@@ -300,6 +342,12 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
int port_num = mad_get_field(node_info, 0, IB_NODE_LOCAL_PORT_F);
ibnd_port_t *port = NULL;
+ if (ni_cbdata) {
+ rem_node = ni_cbdata->node;
+ rem_port_num = ni_cbdata->port_num;
+ free(ni_cbdata);
+ }
+
node = ibnd_find_node_guid(fabric, node_guid);
if (!node) {
node = create_node(engine, &smp->path, node_info);
@@ -315,6 +363,8 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
if (!port) {
/* If we have not see this port before create a shell for it */
port = node->ports[port_num] = calloc(1, sizeof(*port));
+ if (!port)
+ return -1;
port->node = node;
port->portnum = port_num;
}
@@ -324,12 +374,11 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
dump_endnode(&smp->path, node_is_new ? "new" : "known",
node, port);
- if (rem_node == NULL) /* this is the start node */
+ if (rem_node == NULL) { /* this is the start node */
fabric->from_node = node;
- else {
+ fabric->from_portnum = port_num;
+ } else {
/* link ports... */
- int rem_port_num = get_last_port(&smp->path);
-
if (!rem_node->ports[rem_port_num]) {
IBND_ERROR("Internal Error; "
"Node(%p) 0x%" PRIx64
@@ -358,11 +407,11 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
}
static int query_node_info(smp_engine_t * engine, ib_portid_t * portid,
- ibnd_node_t * node)
+ struct ni_cbdata * cbdata)
{
IBND_DEBUG("Query Node Info; %s\n", portid2str(portid));
return issue_smp(engine, portid, IB_ATTR_NODE_INFO, 0,
- recv_node_info, node);
+ recv_node_info, (void *)cbdata);
}
ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
@@ -382,37 +431,13 @@ ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
return NULL;
}
+/* forward declare */
+ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric, char *dr_str);
+
ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str)
{
- int i = 0;
- ibnd_node_t *rc;
- ib_dr_path_t path;
-
- if (!fabric) {
- IBND_DEBUG("fabric parameter NULL\n");
- return NULL;
- }
-
- rc = fabric->from_node;
-
- 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;
+ ibnd_port_t *rc = ibnd_find_port_dr(fabric, dr_str);
+ return rc->node;
}
void add_to_nodeguid_hash(ibnd_node_t * node, ibnd_node_t * hash[])
@@ -479,15 +504,15 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
int nc = 2;
int mc[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
+ /* If not specified start from "my" port */
+ if (!from)
+ from = &my_portid;
+
if (set_config(&config, cfg)) {
IBND_ERROR("Invalid ibnd_config\n");
return NULL;
}
- /* If not specified start from "my" port */
- if (!from)
- from = &my_portid;
-
fabric = calloc(1, sizeof(*fabric));
if (!fabric) {
IBND_ERROR("OOM: failed to calloc ibnd_fabric_t\n");
@@ -499,6 +524,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
memset(&scan.selfportid, 0, sizeof(scan.selfportid));
scan.fabric = fabric;
scan.cfg = &config;
+ scan.initial_hops = from->drpath.cnt;
if (smp_engine_init(&engine, ca_name, ca_port, &scan, &config)) {
free(fabric);
@@ -521,6 +547,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
goto error;
fabric->total_mads_used = engine.total_smps;
+ fabric->maxhops_discovered += scan.initial_hops;
if (group_nodes(fabric))
goto error;
@@ -624,3 +651,81 @@ void ibnd_iter_nodes_type(ibnd_fabric_t * fabric, ibnd_iter_node_func_t func,
for (cur = list; cur; cur = cur->type_next)
func(cur, user_data);
}
+
+ibnd_port_t *ibnd_find_port_guid(ibnd_fabric_t * fabric, uint64_t guid)
+{
+ int hash = HASHGUID(guid) % HTSZ;
+ ibnd_port_t *port;
+
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return NULL;
+ }
+
+ for (port = fabric->portstbl[hash]; port; port = port->htnext)
+ if (port->guid == guid)
+ return port;
+
+ return NULL;
+}
+
+ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric, char *dr_str)
+{
+ int i = 0;
+ ibnd_node_t *cur_node;
+ ibnd_port_t *rc = NULL;
+ ib_dr_path_t path;
+
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return NULL;
+ }
+
+ if (!dr_str) {
+ IBND_DEBUG("dr_str parameter NULL\n");
+ return NULL;
+ }
+
+ cur_node = fabric->from_node;
+
+ 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 (!cur_node->ports)
+ return NULL;
+
+ remote_port = cur_node->ports[path.p[i]]->remoteport;
+ if (!remote_port)
+ return NULL;
+
+ rc = remote_port;
+ cur_node = remote_port->node;
+ }
+
+ return rc;
+}
+
+void ibnd_iter_ports(ibnd_fabric_t * fabric, ibnd_iter_port_func_t func,
+ void *user_data)
+{
+ int i = 0;
+ ibnd_port_t *cur = NULL;
+
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return;
+ }
+
+ if (!func) {
+ IBND_DEBUG("func parameter NULL\n");
+ return;
+ }
+
+ for (i = 0; i<HTSZ; i++)
+ for (cur = fabric->portstbl[i]; cur; cur = cur->htnext)
+ func(cur, user_data);
+}
diff --git a/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c b/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c
index 5151f63..2690373 100644
--- a/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c
+++ b/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c
@@ -326,6 +326,7 @@ static int _load_node(int fd, ibnd_fabric_cache_t * fabric_cache)
node = (ibnd_node_t *) malloc(sizeof(ibnd_node_t));
if (!node) {
IBND_DEBUG("OOM: node\n");
+ free(node_cache);
return -1;
}
memset(node, '\0', sizeof(ibnd_node_t));
@@ -426,6 +427,7 @@ static int _load_port(int fd, ibnd_fabric_cache_t * fabric_cache)
port = (ibnd_port_t *) malloc(sizeof(ibnd_port_t));
if (!port) {
IBND_DEBUG("OOM: port\n");
+ free(port_cache);
return -1;
}
memset(port, '\0', sizeof(ibnd_port_t));
@@ -887,9 +889,20 @@ int ibnd_cache_fabric(ibnd_fabric_t * fabric, const char *file,
return -1;
}
- if (!stat(file, &statbuf)) {
- IBND_DEBUG("file '%s' already exists\n", file);
- return -1;
+ if (!(flags & IBND_CACHE_FABRIC_FLAG_NO_OVERWRITE)) {
+ if (!stat(file, &statbuf)) {
+ if (unlink(file) < 0) {
+ IBND_DEBUG("error removing '%s': %s\n",
+ file, strerror(errno));
+ return -1;
+ }
+ }
+ }
+ else {
+ if (!stat(file, &statbuf)) {
+ IBND_DEBUG("file '%s' already exists\n", file);
+ return -1;
+ }
}
if ((fd = open(file, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {
diff --git a/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src b/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src
index 018bd17..776e154 100644
--- a/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src
+++ b/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src
@@ -4,6 +4,8 @@ LIBRARY libibnetdisc.dll
EXPORTS
ibnd_discover_fabric;
ibnd_destroy_fabric;
+ ibnd_load_fabric;
+ ibnd_cache_fabric;
ibnd_find_node_guid;
ibnd_find_node_dr;
ibnd_is_xsigo_guid;
@@ -14,4 +16,7 @@ EXPORTS
ibnd_get_chassis_slot_str;
ibnd_iter_nodes;
ibnd_iter_nodes_type;
+ ibnd_find_port_guid;
+ ibnd_find_port_dr;
+ ibnd_iter_ports;
#endif
diff --git a/trunk/ulp/libibnetdisc/src/internal.h b/trunk/ulp/libibnetdisc/src/internal.h
index 3c599ec..80918c4 100644
--- a/trunk/ulp/libibnetdisc/src/internal.h
+++ b/trunk/ulp/libibnetdisc/src/internal.h
@@ -62,6 +62,7 @@ typedef struct ibnd_scan {
ibnd_fabric_t *fabric;
struct ibnd_config *cfg;
struct ibmad_port *ibmad_port;
+ unsigned initial_hops;
} ibnd_scan_t;
typedef struct ibnd_smp ibnd_smp_t;
diff --git a/trunk/ulp/opensm/user/opensm/osm_helper.c b/trunk/ulp/opensm/user/opensm/osm_helper.c
index 54680da..fcb2597 100644
--- a/trunk/ulp/opensm/user/opensm/osm_helper.c
+++ b/trunk/ulp/opensm/user/opensm/osm_helper.c
@@ -860,7 +860,7 @@ void osm_dump_portinfo_record(IN osm_log_t * p_log,
"\t\t\t\tRID\n"
"\t\t\t\tEndPortLid..............%u\n"
"\t\t\t\tPortNum.................%u\n"
- "\t\t\t\tReserved................0x%X\n"
+ "\t\t\t\tOptions.................0x%X\n"
"\t\t\t\tPortInfo dump:\n"
"\t\t\t\tm_key...................0x%016" PRIx64 "\n"
"\t\t\t\tsubnet_prefix...........0x%016" PRIx64 "\n"
@@ -894,7 +894,7 @@ void osm_dump_portinfo_record(IN osm_log_t * p_log,
"\t\t\t\tsubnet_timeout..........0x%X\n"
"\t\t\t\tresp_time_value.........0x%X\n"
"\t\t\t\terror_threshold.........0x%X\n",
- cl_ntoh16(p_pir->lid), p_pir->port_num, p_pir->resv,
+ cl_ntoh16(p_pir->lid), p_pir->port_num, p_pir->options,
cl_ntoh64(p_pi->m_key), cl_ntoh64(p_pi->subnet_prefix),
cl_ntoh16(p_pi->base_lid),
cl_ntoh16(p_pi->master_sm_base_lid),
_______________________________________________
ofw mailing list
ofw at lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw
More information about the ofw
mailing list