[ofw] [PATCH] Update libibmad and infiniband-diags
Smith, Stan
stan.smith at intel.com
Mon Aug 8 12:57:00 PDT 2011
Do the git commits imply SVN commits?
Since you are likely one of the 'few' who use git for windows projects, it is not a burden on the rest of the Windows IB project members to force everyone else to refer to the git trees for changes and/or an explanation of the bigger picture of what/how things have changed?
Does opensm still build?
We 'really' need to separate out from ib_types.h the diags/MAD/opensm issues into separate header files...the kitchen sink is rather larger and continues to grow. :-(
Stan.
>-----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 12:34 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