Hi Hal,

I tried using the umad code as per the latest repository. (The latest fix is on 
libibumad/umad.c Line # 806 right?) I manually applied that patch. It doesn't 
seem to work yet. 

Infact, what I figured out was that the 'poll' on the umad->fd isn't blocking 
either. 

The read returns the correct 'mad_agent' ie. 0 in this case and some length 
which is usually 24 for the specific code.

I am attaching the local copy of infiniband/include/mad.h and src/fields.c, so 
that you may be able to try this code.  (There may be stray printf's in those 
files!). Also, since I was not quite clear about whether the subscriptions 
should include the RID information (as per section 15.2.5), so I tried 
including it first, which the SA doesn't seem to like, but the subscriptions 
work after I get rid of the RID header. This particular aspect is not quite 
clear to me yet. 

Please let me know what you find.

Regards.

-abhijit


On Aug 10, 2006 08:02 PM, Hal Rosenstock <[EMAIL PROTECTED]> wrote:

> Hi again Abhijit,
> 
> On Thu, 2006-08-10 at 09:46, Abhijit Gadgil wrote:
> > Hi Hal, 
> > 
> > Please see below.
> > 
> > On Aug 10, 2006 07:01 PM, Hal Rosenstock <[EMAIL PROTECTED]> wrote:
> > 
> > > Hi Abhijit,
> > > 
> > > On Thu, 2006-08-10 at 07:21, Abhijit Gadgil wrote:
> > > > Hi All, 
> > > > 
> > > > I am trying to write a simple program using libibumad to 'subscribe' 
> > > > for traps and then receive traps from the SA. Most of the things seem 
> > > > to work fine, however I am facing a small problem where, after first 
> > > > read for the trap, all subsequent reads are not blocking (and return 
> > > > some incorrect length). 
> > > 
> > > What do those calls return ? What version of management are you using ? 
> > > 
> > 
> > I am running the management code from the SVN (svn release 8781, it may be 
> > slightly outdated!) 
> 
> A fix just went in to libibumad:umad_recv which may impact your results.
> Can you update this and retry ?
> 
> What do the reads return other than incorrect length ? 
> 
> -- Hal
> 
> > > > Attached is the simple code, can someone tell, what exactly is wrong 
> > > > out here? 
> > > 
> > > I didn't build and run this so my comments are based on just looking at
> > > the code. I don't think it would build as there are other changes needed
> > > to support this (e.g. IB_SA_INFINFO_XXX in libibmad at a minimum).
> > > 
> > 
> > Oh I am sorry, I didn't mention this before, I modified the libibmad 
> > sources (specifically src/fields.c and include/infiniband/mad.h) files to 
> > accomplish this. Once I get it right, I will submit a patch. (It's too 
> > hacky right now)
> > 
> > > Is the main loop based on some operational program ? If so, which one ?
> > > 
> > > A couple of specific comments:
> > > 
> > > init_sa_headers: InformInfo does not actually use RMPP so the
> > > initialization here needs to change. Not sure what doing this would
> > > cause without actually building and running this.
> > > 
> > 
> > This was my first try of trying to use umad, hence for simplicity I copied 
> > from some reference code that was having RMPP enabled. I think I should get 
> > rid of this as well. 
> > 
> > 
> > > Based on this, what is the result of the subscription ? Does it really
> > > succeed ?
> > 
> > Well the subscriptions in-deed succeeded and I was able to receive IPoIB 
> > broadcast multicast group creation/deletion traps as well, but the problem 
> > mentioned below (ie. non-blocking reads) started appearing. 
> > 
> > > main: Rather than hard coding SM LID to 0x12, there are ways to get this
> > > dynamically. There are examples of how to do this.
> > 
> > Sorry about this again. I realized it later that it is stupid to hard code 
> > it (eg. I could have got it from the ca[].port->sm_lid), will fix that 
> > eventually. 
> > 
> > Thanks.
> > 
> > -abhijit
> > 
> > > -- Hal
> > > 
> > > > Thanks
> > > > 
> > > > -abhijit



/*
 * Copyright (c) 2004,2005 Voltaire Inc.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * $Id: fields.c 8484 2006-07-10 23:13:53Z halr $
 */

#if HAVE_CONFIG_H
#  include <config.h>
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <mad.h>
#include <infiniband/common.h>

/*
 * BITSOFFS and BE_OFFS are required due the fact that the bit offsets are 
inconsistently
 * encoded in the IB spec - IB headers are encoded such that the bit offsets
 * are in big endian convention (BE_OFFS), while the SMI/GSI queries data 
fields bit
 * offsets are specified using real bit offset (?!)
 * The following macros normalize everything to big endian offsets.
 */
#define BITSOFFS(o, w)  (((o) & ~31) | ((32 - ((o) & 31) - (w)))), (w)
#define BE_OFFS(o, w)   (o), (w)
#define BE_TO_BITSOFFS(o, w)    (((o) & ~31) | ((32 - ((o) & 31) - (w))))

ib_field_t ib_mad_f [] = {
        [0]     {0, 0},         /* IB_NO_FIELD - reserved as invalid */

        [IB_GID_PREFIX_F]               {0, 64, "GidPrefix", mad_dump_rhex},
        [IB_GID_GUID_F]                 {64, 64, "GidGuid", mad_dump_rhex},

        /*
         * MAD: common MAD fields (IB spec 13.4.2)
         * SMP: Subnet Management packets - lid routed (IB spec 14.2.1.1)
         * DSMP: Subnet Management packets - direct route (IB spec 14.2.1.2)
         * SA: Subnet Administration packets (IB spec 15.2.1.1)
         */

        /* first MAD word (0-3 bytes) */
        [IB_MAD_METHOD_F]               {BE_OFFS(0, 7), "MadMethod", 
mad_dump_hex}, /* TODO: add dumper */
        [IB_MAD_RESPONSE_F]             {BE_OFFS(7, 1), "MadIsResponse", 
mad_dump_uint}, /* TODO: add dumper */
        [IB_MAD_CLASSVER_F]             {BE_OFFS(8, 8), "MadClassVersion", 
mad_dump_uint},
        [IB_MAD_MGMTCLASS_F]            {BE_OFFS(16, 8), "MadMgmtClass", 
mad_dump_uint},  /* TODO: add dumper */
        [IB_MAD_BASEVER_F]              {BE_OFFS(24, 8), "MadBaseVersion", 
mad_dump_uint},

        /* second MAD word (4-7 bytes) */
        [IB_MAD_STATUS_F]               {BE_OFFS(48, 16), "MadStatus", 
mad_dump_hex}, /* TODO: add dumper */

        /* DR SMP only */
        [IB_DRSMP_HOPCNT_F]             {BE_OFFS(32, 8), "DrSmpHopCnt", 
mad_dump_uint},
        [IB_DRSMP_HOPPTR_F]             {BE_OFFS(40, 8), "DrSmpHopPtr", 
mad_dump_uint},
        [IB_DRSMP_STATUS_F]             {BE_OFFS(48, 15), "DrSmpStatus", 
mad_dump_hex}, /* TODO: add dumper */
        [IB_DRSMP_DIRECTION_F]          {BE_OFFS(63, 1), "DrSmpDirection", 
mad_dump_uint}, /* TODO: add dumper */

        /* words 3,4,5,6 (8-23 bytes) */
        [IB_MAD_TRID_F]                 {64, 64, "MadTRID", mad_dump_hex},
        [IB_MAD_ATTRID_F]               {BE_OFFS(144, 16), "MadAttr", 
mad_dump_hex}, /* TODO: add dumper */
        [IB_MAD_ATTRMOD_F]              {160, 32, "MadModifier", mad_dump_hex}, 
/* TODO: add dumper */

        /* word 7,8 (24-31 bytes) */
        [IB_MAD_MKEY_F]                 {196, 64, "MadMkey", mad_dump_hex},

        /* word 9 (32-37 bytes) */
        [IB_DRSMP_DRDLID_F]             {BE_OFFS(256, 16), "DrSmpDLID", 
mad_dump_hex},
        [IB_DRSMP_DRSLID_F]             {BE_OFFS(272, 16), "DrSmpSLID", 
mad_dump_hex},

        /* word 12 (44-47 bytes) */
        [IB_SA_ATTROFFS_F]              {BE_OFFS(46*8, 16), "SaAttrOffs", 
mad_dump_uint},

        /* word 13,14 (48-55 bytes) */
        [IB_SA_COMPMASK_F]              {48*8, 64, "SaCompMask", mad_dump_hex},

        /* word 13,14 (56-255 bytes) */
        [IB_SA_DATA_F]                  {56*8, (256-56)*8, "SaData", 
mad_dump_hex},

        [IB_DRSMP_PATH_F]               {1024, 512, "DrSmpPath", mad_dump_hex},
        [IB_DRSMP_RPATH_F]              {1536, 512, "DrSmpRetPath", 
mad_dump_hex},

        [IB_GS_DATA_F]                  {64*8, (256-64) * 8, "GsData", 
mad_dump_hex},

        /*
         * PortInfo fields:
         */
        [IB_PORT_MKEY_F]                {0, 64, "Mkey", mad_dump_hex},
        [IB_PORT_GID_PREFIX_F]          {64, 64, "GidPrefix", mad_dump_hex},
        [IB_PORT_LID_F]                 {BITSOFFS(128, 16), "Lid", 
mad_dump_hex},
        [IB_PORT_SMLID_F]               {BITSOFFS(144, 16), "SMLid", 
mad_dump_hex},
        [IB_PORT_CAPMASK_F]             {160, 32, "CapMask", 
mad_dump_portcapmask},
        [IB_PORT_DIAG_F]                {BITSOFFS(192, 16), "DiagCode", 
mad_dump_hex},
        [IB_PORT_MKEY_LEASE_F]          {BITSOFFS(208, 16), "MkeyLeasePeriod", 
mad_dump_uint},
        [IB_PORT_LOCAL_PORT_F]          {BITSOFFS(224, 8), "LocalPort", 
mad_dump_uint},
        [IB_PORT_LINK_WIDTH_ENABLED_F]  {BITSOFFS(232, 8), "LinkWidthEnabled", 
mad_dump_linkwidthen},
        [IB_PORT_LINK_WIDTH_SUPPORTED_F]        {BITSOFFS(240, 8), 
"LinkWidthSupported", mad_dump_linkwidthsup},
        [IB_PORT_LINK_WIDTH_ACTIVE_F]   {BITSOFFS(248, 8), "LinkWidthActive", 
mad_dump_linkwidth},
        [IB_PORT_LINK_SPEED_SUPPORTED_F]        {BITSOFFS(256, 4), 
"LinkSpeedSupported", mad_dump_linkspeedsup},
        [IB_PORT_STATE_F]               {BITSOFFS(260, 4), "LinkState", 
mad_dump_portstate},
        [IB_PORT_PHYS_STATE_F]          {BITSOFFS(264, 4), "PhysLinkState", 
mad_dump_physportstate},
        [IB_PORT_LINK_DOWN_DEF_F]       {BITSOFFS(268, 4), "LinkDownDefState", 
mad_dump_linkdowndefstate},
        [IB_PORT_MKEY_PROT_BITS_F]      {BITSOFFS(272, 2), "ProtectBits", 
mad_dump_uint},
        [IB_PORT_LMC_F]                 {BITSOFFS(277, 3), "LMC", 
mad_dump_uint},
        [IB_PORT_LINK_SPEED_ACTIVE_F]   {BITSOFFS(280, 4), "LinkSpeedActive", 
mad_dump_linkspeed},
        [IB_PORT_LINK_SPEED_ENABLED_F]  {BITSOFFS(284, 4), "LinkSpeedEnabled", 
mad_dump_linkspeeden},
        [IB_PORT_NEIGHBOR_MTU_F]        {BITSOFFS(288, 4), "NeighborMTU", 
mad_dump_mtu},
        [IB_PORT_SMSL_F]                {BITSOFFS(292, 4), "SMSL", 
mad_dump_uint},
        [IB_PORT_VL_CAP_F]              {BITSOFFS(296, 4), "VLCap", 
mad_dump_vlcap},
        [IB_PORT_INIT_TYPE_F]           {BITSOFFS(300, 4), "InitType", 
mad_dump_hex},
        [IB_PORT_VL_HIGH_LIMIT_F]       {BITSOFFS(304, 8), "VLHighLimit", 
mad_dump_uint},
        [IB_PORT_VL_ARBITRATION_HIGH_CAP_F]     {BITSOFFS(312, 8), 
"VLArbHighCap", mad_dump_uint},
        [IB_PORT_VL_ARBITRATION_LOW_CAP_F]      {BITSOFFS(320, 8), 
"VLArbLowCap", mad_dump_uint},

        [IB_PORT_INIT_TYPE_REPLY_F]     {BITSOFFS(328, 4), "InitReply", 
mad_dump_hex},
        [IB_PORT_MTRU_CAP_F]            {BITSOFFS(332, 4), "MtuCap", 
mad_dump_mtu},
        [IB_PORT_VL_STALL_COUNT_F]      {BITSOFFS(336, 3), "VLStallCount", 
mad_dump_uint},
        [IB_PORT_HOQ_LIFE_F]            {BITSOFFS(339, 5), "HoqLife", 
mad_dump_uint},
        [IB_PORT_OPER_VLS_F]            {BITSOFFS(344, 4), "OperVLs", 
mad_dump_opervls},
        [IB_PORT_PART_EN_INB_F]         {BITSOFFS(348, 1), "PartEnforceInb", 
mad_dump_uint},
        [IB_PORT_PART_EN_OUTB_F]        {BITSOFFS(349, 1), "PartEnforceOutb", 
mad_dump_uint},
        [IB_PORT_FILTER_RAW_INB_F]      {BITSOFFS(350, 1), "FilterRawInb", 
mad_dump_uint},
        [IB_PORT_FILTER_RAW_OUTB_F]     {BITSOFFS(351, 1), "FilterRawOutb", 
mad_dump_uint},
        [IB_PORT_MKEY_VIOL_F]           {BITSOFFS(352, 16), "MkeyViolations", 
mad_dump_uint},
        [IB_PORT_PKEY_VIOL_F]           {BITSOFFS(368, 16), "PkeyViolations", 
mad_dump_uint},
        [IB_PORT_QKEY_VIOL_F]           {BITSOFFS(384, 16), "QkeyViolations", 
mad_dump_uint},
        [IB_PORT_GUID_CAP_F]            {BITSOFFS(400, 8), "GuidCap", 
mad_dump_uint},
        [IB_PORT_CLIENT_REREG_F]        {BITSOFFS(408, 1), "ClientReregister", 
mad_dump_uint},
        [IB_PORT_SUBN_TIMEOUT_F]        {BITSOFFS(411, 5), "SubnetTimeout", 
mad_dump_uint},
        [IB_PORT_RESP_TIME_VAL_F]       {BITSOFFS(419, 5), "RespTimeVal", 
mad_dump_uint},
        [IB_PORT_LOCAL_PHYS_ERR_F]      {BITSOFFS(424, 4), "LocalPhysErr", 
mad_dump_uint},
        [IB_PORT_OVERRUN_ERR_F]         {BITSOFFS(428, 4), "OverrunErr", 
mad_dump_uint},
        [IB_PORT_MAX_CREDIT_HINT_F]     {BITSOFFS(432, 16), "MaxCreditHint", 
mad_dump_uint},
        [IB_PORT_LINK_ROUND_TRIP_F]     {BITSOFFS(456, 24), "RoundTrip", 
mad_dump_uint},

        /*
         * NodeInfo fields:
         */
        [IB_NODE_BASE_VERS_F]           {BITSOFFS(0,8), "BaseVers", 
mad_dump_uint},
        [IB_NODE_CLASS_VERS_F]          {BITSOFFS(8,8), "ClassVers", 
mad_dump_uint},
        [IB_NODE_TYPE_F]                {BITSOFFS(16,8), "NodeType", 
mad_dump_node_type},
        [IB_NODE_NPORTS_F]              {BITSOFFS(24,8), "NumPorts", 
mad_dump_uint},
        [IB_NODE_SYSTEM_GUID_F]         {32, 64, "SystemGuid", mad_dump_hex},
        [IB_NODE_GUID_F]                {96, 64, "Guid", mad_dump_hex},
        [IB_NODE_PORT_GUID_F]           {160, 64, "PortGuid", mad_dump_hex},
        [IB_NODE_PARTITION_CAP_F]       {BITSOFFS(224,16), "PartCap", 
mad_dump_uint},
        [IB_NODE_DEVID_F]               {BITSOFFS(240,16), "DevId", 
mad_dump_hex},
        [IB_NODE_REVISION_F]            {256, 32, "Revision", mad_dump_hex},
        [IB_NODE_LOCAL_PORT_F]          {BITSOFFS(288,8), "LocalPort", 
mad_dump_uint},
        [IB_NODE_VENDORID_F]            {BITSOFFS(296,24), "VendorId", 
mad_dump_hex},

        /*
         * SwitchInfo fields:
         */
        [IB_SW_LINEAR_FDB_CAP_F]        {BITSOFFS(0, 16), "LinearFdbCap", 
mad_dump_uint},
        [IB_SW_RANDOM_FDB_CAP_F]        {BITSOFFS(16, 16), "RandomFdbCap", 
mad_dump_uint},
        [IB_SW_MCAST_FDB_CAP_F]         {BITSOFFS(32, 16), "McastFdbCap", 
mad_dump_uint},
        [IB_SW_LINEAR_FDB_TOP_F]        {BITSOFFS(48, 16), "LinearFdbTop", 
mad_dump_uint},
        [IB_SW_DEF_PORT_F]              {BITSOFFS(64, 8), "DefPort", 
mad_dump_uint},
        [IB_SW_DEF_MCAST_PRIM_F]        {BITSOFFS(72, 8), "DefMcastPrimPort", 
mad_dump_uint},
        [IB_SW_DEF_MCAST_NOT_PRIM_F]    {BITSOFFS(80, 8), 
"DefMcastNotPrimPort", mad_dump_uint},
        [IB_SW_LIFE_TIME_F]             {BITSOFFS(88, 5), "LifeTime", 
mad_dump_uint},
        [IB_SW_STATE_CHANGE_F]          {BITSOFFS(93, 1), "StateChange", 
mad_dump_uint},
        [IB_SW_LIDS_PER_PORT_F]         {BITSOFFS(96,16), "LidsPerPort", 
mad_dump_uint},
        [IB_SW_PARTITION_ENFORCE_CAP_F] {BITSOFFS(112, 16), "PartEnforceCap", 
mad_dump_uint},
        [IB_SW_PARTITION_ENF_INB_F]     {BITSOFFS(128, 1), "InboundPartEnf", 
mad_dump_uint},
        [IB_SW_PARTITION_ENF_OUTB_F]    {BITSOFFS(129, 1), "OutboundPartEnf", 
mad_dump_uint},
        [IB_SW_FILTER_RAW_INB_F]        {BITSOFFS(130, 1), "FilterRawInbound", 
mad_dump_uint},
        [IB_SW_FILTER_RAW_OUTB_F]       {BITSOFFS(131, 1), "FilterRawInbound", 
mad_dump_uint},
        [IB_SW_ENHANCED_PORT0_F]        {BITSOFFS(132, 1), "EnhancedPort0", 
mad_dump_uint},

        /*
         * SwitchLinearForwardingTable fields:
         */
        [IB_LINEAR_FORW_TBL_F]          {0, 512, "LinearForwTbl", 
mad_dump_array},

        /*
         * SwitchMulticastForwardingTable fields:
         */
        [IB_MULTICAST_FORW_TBL_F]       {0, 512, "MulticastForwTbl", 
mad_dump_array},

        /*
         * Notice/Trap fields
         */
        [IB_NOTICE_IS_GENERIC_F]        {BITSOFFS(0, 1), "NoticeIsGeneric", 
mad_dump_uint},
        [IB_NOTICE_TYPE_F]              {BITSOFFS(1, 7), "NoticeType", 
mad_dump_uint},
        [IB_NOTICE_PRODUCER_F]          {BITSOFFS(8, 24), "NoticeProducerType", 
mad_dump_node_type},
        [IB_NOTICE_TRAP_NUMBER_F]       {BITSOFFS(32, 16), "NoticeTrapNumber", 
mad_dump_uint},
        [IB_NOTICE_ISSUER_LID_F]        {BITSOFFS(48, 16), "NoticeIssuerLID", 
mad_dump_uint},
        [IB_NOTICE_TOGGLE_F]            {BITSOFFS(64, 1), "NoticeToggle", 
mad_dump_uint},
        [IB_NOTICE_COUNT_F]             {BITSOFFS(65, 15), "NoticeCount", 
mad_dump_uint},
        [IB_NOTICE_DATA_LID_F]          {BITSOFFS(80, 16), "NoticeDataLID", 
mad_dump_uint},

        /*
         * NodeDescription fields:
         */
        [IB_NODE_DESC_F]                {0, 64*8, "NodeDesc", mad_dump_string},

        /*
         * Port counters
         */
        [IB_PC_PORT_SELECT_F]           {BITSOFFS(8, 8), "PortSelect", 
mad_dump_uint},
        [IB_PC_COUNTER_SELECT_F]        {BITSOFFS(16, 16), "CounterSelect", 
mad_dump_hex},
        [IB_PC_ERR_SYM_F]               {BITSOFFS(32, 16), "SymbolErrors", 
mad_dump_uint},
        [IB_PC_LINK_RECOVERS_F]         {BITSOFFS(48, 8), "LinkRecovers", 
mad_dump_uint},
        [IB_PC_LINK_DOWNED_F]           {BITSOFFS(56, 8), "LinkDowned", 
mad_dump_uint},
        [IB_PC_ERR_RCV_F]               {BITSOFFS(64, 16), "RcvErrors", 
mad_dump_uint},
        [IB_PC_ERR_PHYSRCV_F]           {BITSOFFS(80, 16), 
"RcvRemotePhysErrors", mad_dump_uint},
        [IB_PC_ERR_SWITCH_REL_F]        {BITSOFFS(96, 16), "RcvSwRelayErrors", 
mad_dump_uint},
        [IB_PC_XMT_DISCARDS_F]          {BITSOFFS(112, 16), "XmtDiscards", 
mad_dump_uint},
        [IB_PC_ERR_XMTCONSTR_F]         {BITSOFFS(128, 8), 
"XmtConstraintErrors", mad_dump_uint},
        [IB_PC_ERR_RCVCONSTR_F]         {BITSOFFS(136, 8), 
"RcvConstraintErrors", mad_dump_uint},
        [IB_PC_ERR_LOCALINTEG_F]        {BITSOFFS(152, 4), 
"LinkIntegrityErrors", mad_dump_uint},
        [IB_PC_ERR_EXCESS_OVR_F]        {BITSOFFS(156, 4), 
"ExcBufOverrunErrors", mad_dump_uint},
        [IB_PC_VL15_DROPPED_F]          {BITSOFFS(176, 16), "VL15Dropped", 
mad_dump_uint},
        [IB_PC_XMT_BYTES_F]             {192, 32, "XmtBytes", mad_dump_uint},
        [IB_PC_RCV_BYTES_F]             {224, 32, "RcvBytes", mad_dump_uint},
        [IB_PC_XMT_PKTS_F]              {256, 32, "XmtPkts", mad_dump_uint},
        [IB_PC_RCV_PKTS_F]              {288, 32, "RcvPkts", mad_dump_uint},

        /*
         * SMInfo
         */
        [IB_SMINFO_GUID_F]              {0, 64, "SmInfoGuid", mad_dump_hex},
        [IB_SMINFO_KEY_F]               {64, 64, "SmInfoKey", mad_dump_hex},
        [IB_SMINFO_ACT_F]               {128, 32, "SmActivity", mad_dump_uint},
        [IB_SMINFO_PRIO_F]              {BITSOFFS(160, 4), "SmPriority", 
mad_dump_uint},
        [IB_SMINFO_STATE_F]             {BITSOFFS(164, 4), "SmState", 
mad_dump_uint},

        /*
         * SA RMPP
         */
        [IB_SA_RMPP_VERS_F]             {BE_OFFS(24*8+24, 8), "RmppVers", 
mad_dump_uint},
        [IB_SA_RMPP_TYPE_F]             {BE_OFFS(24*8+16, 8), "RmppType", 
mad_dump_uint},
        [IB_SA_RMPP_RESP_F]             {BE_OFFS(24*8+11, 5), "RmppResp", 
mad_dump_uint},
        [IB_SA_RMPP_FLAGS_F]            {BE_OFFS(24*8+8, 3), "RmppFlags", 
mad_dump_hex},
        [IB_SA_RMPP_STATUS_F]           {BE_OFFS(24*8+0, 8), "RmppStatus", 
mad_dump_hex},

        /* data1 */
        [IB_SA_RMPP_D1_F]               {28*8, 32, "RmppData1", mad_dump_hex},
        [IB_SA_RMPP_SEGNUM_F]           {28*8, 32, "RmppSegNum", mad_dump_uint},
        /* data2 */
        [IB_SA_RMPP_D2_F]               {32*8, 32, "RmppData2", mad_dump_hex},
        [IB_SA_RMPP_LEN_F]              {32*8, 32, "RmppPayload", 
mad_dump_uint},
        [IB_SA_RMPP_NEWWIN_F]           {32*8, 32, "RmppNewWin", mad_dump_uint},

        /*
         * SA Path rec
         */
        [IB_SA_PR_DGID_F]               {64,128, "PathRecDGid", mad_dump_array},
        [IB_SA_PR_SGID_F]               {192,128, "PathRecSGid", 
mad_dump_array},
        [IB_SA_PR_DLID_F]               {BITSOFFS(320,16), "PathRecDLid", 
mad_dump_hex},
        [IB_SA_PR_SLID_F]               {BITSOFFS(336,16), "PathRecSLid", 
mad_dump_hex},
        [IB_SA_PR_NPATH_F]              {BITSOFFS(393,7), "PathRecNumPath", 
mad_dump_uint},

        /*
         * SA Get Multi Path
         */
        [IB_SA_MP_NPATH_F]              {BITSOFFS(41,7), "MultiPathNumPath", 
mad_dump_uint},
        [IB_SA_MP_NSRC_F]               {BITSOFFS(120,8), "MultiPathNumSrc", 
mad_dump_uint},
        [IB_SA_MP_NDEST_F]              {BITSOFFS(128,8), "MultiPathNumDest", 
mad_dump_uint},
        [IB_SA_MP_GID0_F]               {192,128, "MultiPathGid", 
mad_dump_array},

        /*
         * MC Member rec
         */
        [IB_SA_MCM_MGID_F]              {0, 128, "McastMemMGid", 
mad_dump_array},
        [IB_SA_MCM_PORTGID_F]           {128, 128, "McastMemPortGid", 
mad_dump_array},
        [IB_SA_MCM_QKEY_F]              {256, 32, "McastMemQkey", mad_dump_hex},
        [IB_SA_MCM_MLID_F]              {BITSOFFS(288, 16), "McastMemMLid", 
mad_dump_hex},
        [IB_SA_MCM_MTU_F]               {BITSOFFS(306, 6), "McastMemMTU", 
mad_dump_uint},
        [IB_SA_MCM_TCLASS_F]            {BITSOFFS(312, 8), "McastMemTClass", 
mad_dump_uint},
        [IB_SA_MCM_PKEY_F]              {BITSOFFS(320, 16), "McastMemPkey", 
mad_dump_uint},
        [IB_SA_MCM_RATE_F]              {BITSOFFS(338, 6), "McastMemRate", 
mad_dump_uint},
        [IB_SA_MCM_SL_F]                {BITSOFFS(352, 4), "McastMemSL", 
mad_dump_uint},
        [IB_SA_MCM_FLOW_LABEL_F]        {BITSOFFS(356, 20), "McastMemFlowLbl", 
mad_dump_uint},
        [IB_SA_MCM_JOIN_STATE_F]        {BITSOFFS(388, 4), "McastMemJoinState", 
mad_dump_uint},
        [IB_SA_MCM_PROXY_JOIN_F]        {BITSOFFS(392, 1), "McastMemProxyJoin", 
mad_dump_uint},

        /*
         * Service record
         */
        [IB_SA_SR_ID_F]                 {0, 64, "ServRecID", mad_dump_hex},
        [IB_SA_SR_GID_F]                {64, 128, "ServRecGid", mad_dump_array},
        [IB_SA_SR_PKEY_F]               {BITSOFFS(192, 16), "ServRecPkey", 
mad_dump_hex},
        [IB_SA_SR_LEASE_F]              {224, 32, "ServRecLease", mad_dump_hex},
        [IB_SA_SR_KEY_F]                {256, 128, "ServRecKey", mad_dump_hex},
        [IB_SA_SR_NAME_F]               {384, 512, "ServRecName", 
mad_dump_string},
        [IB_SA_SR_DATA_F]               {896, 512, "ServRecData", 
mad_dump_array},      /* ATS for example */

        /*
         * ATS SM record - within SA_SR_DATA
         */
        [IB_ATS_SM_NODE_ADDR_F]         {12*8, 32, "ATSNodeAddr", mad_dump_hex},
        [IB_ATS_SM_MAGIC_KEY_F]         {BITSOFFS(16*8, 16), "ATSMagicKey", 
mad_dump_hex},
        [IB_ATS_SM_NODE_TYPE_F]         {BITSOFFS(18*8, 16), "ATSNodeType", 
mad_dump_hex},
        [IB_ATS_SM_NODE_NAME_F]         {32*8, 32*8, "ATSNodeName", 
mad_dump_string},
        
        /*
         * SLTOVL MAPPING TABLE
         */
        [IB_SLTOVL_MAPPING_TABLE_F]     {0, 64, "SLToVLMap", mad_dump_hex},

        /*
         * VL ARBITRATION TABLE
         */
        [IB_VL_ARBITRATION_TABLE_F]     {0, 512, "VLArbTbl", mad_dump_array},

        /*
         * IB vendor classes range 2
         */
        [IB_VEND2_OUI_F]                {BE_OFFS(36*8, 24), "OUI", 
mad_dump_array},
        [IB_VEND2_DATA_F]               {40*8, (256-40)*8, "Vendor2Data", 
mad_dump_array},

        /*
         * IB InformInfo rec
         * Trying two types of InformInfo Rec, one with RID and one without RID 
         *
        [IB_SA_INFINFO_SUBGID_F]        {0, 128, "InformInfoSubscriberGID", 
mad_dump_array},
        [IB_SA_INFINFO_ENUM_F]          {128, 16, "InformInfoEnum", 
mad_dump_hex},
        [IB_SA_INFINFO_RESV0_F]         {144, 48, "InformInfoReservd", 
mad_dump_uint},
        [IB_SA_INFINFO_GID_F]           {192,128, "InformInfoGID", 
mad_dump_array},   
        [IB_SA_INFINFO_LID_BEGIN_F]     {320, 16, "InformInfoLIDBegin", 
mad_dump_hex},  
        [IB_SA_INFINFO_LID_END_F]       {336, 16, "InformInfoEnd", 
mad_dump_hex}, 
        [IB_SA_INFINFO_RESV1_F]         {352, 16, "InformInfoReserved", 
mad_dump_hex}, 
        [IB_SA_INFINFO_ISGENERIC_F]     {368, 8, "InformInfoIsGeneric", 
mad_dump_uint}, 
        [IB_SA_INFINFO_SUBSCRIBE_F]     {376, 8, "InformInfoSubsribe", 
mad_dump_uint},
        [IB_SA_INFINFO_TYPE_F]          {384, 16, "InformInfoType", 
mad_dump_uint}, 
        [IB_SA_INFINFO_TRAP_DEVID_F]    {400, 16, 
"InformInfoTrapNumber/DeviceID", mad_dump_uint},
        [IB_SA_INFINFO_QPN_F]           {BITSOFFS(416, 24), "InformInfoQPN", 
mad_dump_hex}, 
        [IB_SA_INFINFO_RES2_F]          {BITSOFFS(440, 3), "InformInfoResrve", 
mad_dump_hex},    
        [IB_SA_INFINFO_RESPTIME_F]      {BITSOFFS(443, 5), 
"InformInfoRespTimeValue", mad_dump_hex}, 
        [IB_SA_INFINFO_RESV3_F]         {448, 8, "InformInfoReserved", 
mad_dump_hex},
        [IB_SA_INFINFO_VENDORID_F]      {456,  24, 
"InformInfoProducerType/DeviceID", mad_dump_hex},
         */
        [IB_SA_INFINFO_GID_F]           {0,128, "InformInfoGID", 
mad_dump_array},   
        [IB_SA_INFINFO_LID_BEGIN_F]     {BITSOFFS(128, 16), 
"InformInfoLIDBegin", mad_dump_hex},  
        [IB_SA_INFINFO_LID_END_F]       {BITSOFFS(144, 16), "InformInfoEnd", 
mad_dump_hex}, 
        [IB_SA_INFINFO_RESV1_F]         {BITSOFFS(160, 16), 
"InformInfoReserved", mad_dump_hex}, 
        [IB_SA_INFINFO_ISGENERIC_F]     {BITSOFFS(176, 8), 
"InformInfoIsGeneric", mad_dump_uint}, 
        [IB_SA_INFINFO_SUBSCRIBE_F]     {BITSOFFS(184, 8), 
"InformInfoSubsribe", mad_dump_uint},
        [IB_SA_INFINFO_TYPE_F]          {BITSOFFS(192, 16), "InformInfoType", 
mad_dump_uint}, 
        [IB_SA_INFINFO_TRAP_DEVID_F]    {BITSOFFS(208, 16), 
"InformInfoTrapNumber/DeviceID", mad_dump_uint},
        [IB_SA_INFINFO_QPN_F]           {BITSOFFS(224, 24), "InformInfoQPN", 
mad_dump_hex}, 
        [IB_SA_INFINFO_RES2_F]          {BITSOFFS(248, 3), "InformInfoResrve", 
mad_dump_hex},    
        [IB_SA_INFINFO_RESPTIME_F]      {BITSOFFS(251, 5), 
"InformInfoRespTimeValue", mad_dump_hex}, 
        [IB_SA_INFINFO_RESV3_F]         {BITSOFFS(256, 8), 
"InformInfoReserved", mad_dump_hex},
        [IB_SA_INFINFO_VENDORID_F]      {BITSOFFS(264,  24), 
"InformInfoProducerType/DeviceID", mad_dump_hex},
};

void
_set_field64(void *buf, int base_offs, ib_field_t *f, uint64_t val)
{
        *(uint64_t *)((char *)buf + base_offs + f->bitoffs / 8) = htonll(val);
}

uint64_t
_get_field64(void *buf, int base_offs, ib_field_t *f)
{
        uint64_t val = *(uint64_t *)((char *)buf + base_offs + f->bitoffs / 8);
        return ntohll(val);
}

void
_set_field(void *buf, int base_offs, ib_field_t *f, uint32_t val)
{
        int prebits = (8 - (f->bitoffs & 7)) & 7;
        int postbits = (f->bitoffs + f->bitlen) & 7;
        int bytelen = f->bitlen / 8;
        uint idx = base_offs + f->bitoffs / 8;
        char *p = (char *)buf;

        if (!bytelen && (f->bitoffs & 7) + f->bitlen < 8) {
                p[3^idx] &= ~((((1 << f->bitlen) - 1)) << (f->bitoffs & 7));
                p[3^idx] |= (val & ((1 << f->bitlen) - 1)) << (f->bitoffs & 7);
                return;
        }

        if (prebits) {  /* val lsb in byte msb */
                p[3^idx] &= (1 << (8 - prebits)) - 1;
                p[3^idx++] |= (val & ((1 << prebits) - 1)) << (8 - prebits);
                val >>= prebits;
        }

        /* BIG endian byte order */
        for (; bytelen--; val >>= 8)
                p[3^idx++] = val & 0xff;

        if (postbits) { /* val msb in byte lsb */
                p[3^idx] &= ~((1 << postbits) - 1);
                p[3^idx] |= val;
        }
}

uint32_t
_get_field(void *buf, int base_offs, ib_field_t *f)
{
        int prebits = (8 - (f->bitoffs & 7)) & 7;
        int postbits = (f->bitoffs + f->bitlen) & 7;
        int bytelen = f->bitlen / 8;
        uint idx = base_offs + f->bitoffs / 8;
        uint8_t *p = (uint8_t *)buf;
        uint32_t val = 0, v = 0, i;

        if (!bytelen && (f->bitoffs & 7) + f->bitlen < 8)
                return (p[3^idx] >> (f->bitoffs & 7)) & ((1 << f->bitlen) - 1);

        if (prebits)    /* val lsb from byte msb */
                v = p[3^idx++] >> (8 - prebits);

        if (postbits) { /* val msb from byte lsb */
                i = base_offs + (f->bitoffs + f->bitlen) / 8;
                val = (p[3^i] & ((1 << postbits) - 1));
        }

        /* BIG endian byte order */
        for (idx += bytelen - 1; bytelen--; idx--)
                val = (val << 8) | p[3^idx];

        return (val << prebits) | v;
}

/* field must be byte aligned */
void
_set_array(void *buf, int base_offs, ib_field_t *f, void *val)
{
        int bitoffs = f->bitoffs;;

        if (f->bitlen < 32)
                bitoffs = BE_TO_BITSOFFS(bitoffs, f->bitlen);

        memcpy((uint8_t *)buf + base_offs + bitoffs / 8, val, f->bitlen / 8);
}

void
_get_array(void *buf, int base_offs, ib_field_t *f, void *val)
{
        int bitoffs = f->bitoffs;;

        if (f->bitlen < 32)
                bitoffs = BE_TO_BITSOFFS(bitoffs, f->bitlen);

        memcpy(val, (uint8_t *)buf + base_offs + bitoffs / 8, f->bitlen / 8);
}
/*
 * Copyright (c) 2004-2006 Voltaire Inc.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * $Id: mad.h 8630 2006-07-22 10:41:25Z halr $
 */
#ifndef _MAD_H_
#define _MAD_H_

#include <stdint.h>
#include <string.h>

#ifdef __cplusplus
#  define BEGIN_C_DECLS extern "C" {
#  define END_C_DECLS   }
#else /* !__cplusplus */
#  define BEGIN_C_DECLS
#  define END_C_DECLS
#endif /* __cplusplus */

BEGIN_C_DECLS

#define IB_SUBNET_PATH_HOPS_MAX 64
#define IB_DEFAULT_SUBN_PREFIX  0xfe80000000000000llu
#define IB_DEFAULT_QP1_QKEY     0x80010000

#define IB_MAD_SIZE             256

#define IB_SMP_DATA_OFFS        64
#define IB_SMP_DATA_SIZE        64

#define IB_VENDOR_RANGE1_DATA_OFFS      24
#define IB_VENDOR_RANGE1_DATA_SIZE      (IB_MAD_SIZE - 
IB_VENDOR_RANGE1_DATA_OFFS)

#define IB_VENDOR_RANGE2_DATA_OFFS      40
#define IB_VENDOR_RANGE2_DATA_SIZE      (IB_MAD_SIZE - 
IB_VENDOR_RANGE2_DATA_OFFS)

#define IB_SA_DATA_SIZE         200
#define IB_SA_DATA_OFFS         56

#define IB_PC_DATA_OFFS         64
#define IB_PC_DATA_SZ           (IB_MAD_SIZE - IB_PC_DATA_OFFS)

#define IB_SA_MCM_RECSZ         53
#define IB_SA_PR_RECSZ          64

enum MAD_CLASSES {
        IB_SMI_CLASS =          0x1,
        IB_SMI_DIRECT_CLASS =   0x81,
        IB_SA_CLASS =           0x3,
        IB_PERFORMANCE_CLASS =  0x4,
        IB_BOARD_MGMT_CLASS =   0x5,
        IB_DEVICE_MGMT_CLASS =  0x6,
        IB_CM_CLASS =           0x7,
        IB_SNMP_CLASS =         0x8,
        IB_VENDOR_RANGE1_START_CLASS = 0x9,
        IB_VENDOR_RANGE1_END_CLASS = 0x0f,
        IB_VENDOR_RANGE2_START_CLASS = 0x30,
        IB_VENDOR_RANGE2_END_CLASS = 0x4f,
};

enum MAD_METHODS {
        IB_MAD_METHOD_GET =             0x1,
        IB_MAD_METHOD_SET =             0x2,
        IB_MAD_METHOD_GET_RESPONSE =    0x81,

        IB_MAD_METHOD_SEND =            0x3,
        IB_MAD_METHOD_TRAP =            0x5,
        IB_MAD_METHOD_TRAP_REPRESS =    0x7,

        IB_MAD_METHOD_REPORT =          0x6,
        IB_MAD_METHOD_REPORT_RESPONSE = 0x86,
        IB_MAD_METHOD_GET_TABLE =       0x12,
        IB_MAD_METHOD_GET_TABLE_RESPONSE =  0x92,
        IB_MAD_METHOD_GET_TRACE_TABLE = 0x13,
        IB_MAD_METHOD_GET_TRACE_TABLE_RESPONSE = 0x93,
        IB_MAD_METHOD_GETMULTI =        0x14,
        IB_MAD_METHOD_GETMULTI_RESPONSE = 0x94,
        IB_MAD_METHOD_DELETE =          0x15,
        IB_MAD_METHOD_DELETE_RESPONSE = 0x95,

        IB_MAD_RESPONSE =               0x80,
};

enum MAD_ATTR_ID {
        CLASS_PORT_INFO = 0x1,
        NOTICE = 0x2,
        INFORM_INFO = 0x3,
};

enum SMI_ATTR_ID {
        IB_ATTR_NODE_DESC = 0x10,
        IB_ATTR_NODE_INFO = 0x11,
        IB_ATTR_SWITCH_INFO = 0x12,
        IB_ATTR_PORT_INFO = 0x15,
        IB_ATTR_PKEY_TBL = 0x16,
        IB_ATTR_SLVL_TABLE = 0x17,
        IB_ATTR_VL_ARBITRATION = 0x18,
        IB_ATTR_LINEARFORWTBL = 0x19,
        IB_ATTR_MULTICASTFORWTBL = 0x1b,
        IB_ATTR_SMINFO = 0x20,

        IB_ATTR_LAST
};

enum SA_ATTR_ID {
        IB_SA_ATTR_NOTICE = 0x02,
        IB_SA_ATTR_INFORMINFO = 0x03,
        IB_SA_ATTR_PORTINFORECORD = 0x12,
        IB_SA_ATTR_LINKRECORD = 0x20,
        IB_SA_ATTR_SERVICERECORD = 0x31,
        IB_SA_ATTR_PATHRECORD = 0x35,
        IB_SA_ATTR_MCRECORD = 0x38,
        IB_SA_ATTR_MULTIPATH = 0x3a,

        IB_SA_ATTR_LAST
};

enum GSI_ATTR_ID {
        IB_GSI_PORT_SAMPLES_CONTROL = 0x10,
        IB_GSI_PORT_SAMPLES_RESULT = 0x11,
        IB_GSI_PORT_COUNTERS = 0x12,
        IB_GSI_PORT_COUNTERS_EXT = 0x1D,

        IB_GSI_ATTR_LAST
};

#define IB_VENDOR_OPENIB_PING_CLASS     (IB_VENDOR_RANGE2_START_CLASS + 2)
#define IB_VENDOR_OPENIB_SYSSTAT_CLASS  (IB_VENDOR_RANGE2_START_CLASS + 3)
#define IB_OPENIB_OUI                   (0x001405)

typedef uint8_t ib_gid_t[16];

typedef struct {
        int cnt;
        uint8_t p[IB_SUBNET_PATH_HOPS_MAX];
        uint16_t drslid;
        uint16_t drdlid;
} ib_dr_path_t;

typedef struct {
        uint id;
        uint mod;
} ib_attr_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 */
        uint recsz;     /* for sa mads (attribute offset) */
        int timeout;
        uint32_t oui;   /* for vendor mads range 2 */
} ib_rpc_t;

typedef struct portid {
        int lid;                /* lid or 0 if directed route */
        ib_dr_path_t drpath;
        int grh;                /* flag */
        ib_gid_t gid;
        uint32_t qp;
        uint32_t qkey;
        uint8_t sl;
        uint pkey_idx;
} ib_portid_t;

typedef void (ib_mad_dump_fn)(char *buf, int bufsz, void *val, int valsz);

#define IB_FIELD_NAME_LEN       32

typedef struct ib_field {
        int bitoffs;
        int bitlen;
        char name[IB_FIELD_NAME_LEN];
        ib_mad_dump_fn *def_dump_fn;
} ib_field_t;

enum MAD_FIELDS {
        IB_NO_FIELD,

        IB_GID_PREFIX_F,
        IB_GID_GUID_F,

        /* first MAD word (0-3 bytes) */
        IB_MAD_METHOD_F,
        IB_MAD_RESPONSE_F,
        IB_MAD_CLASSVER_F,
        IB_MAD_MGMTCLASS_F,
        IB_MAD_BASEVER_F,

        /* second MAD word (4-7 bytes) */
        IB_MAD_STATUS_F,

        /* DRSMP only */
        IB_DRSMP_HOPCNT_F,
        IB_DRSMP_HOPPTR_F,
        IB_DRSMP_STATUS_F,
        IB_DRSMP_DIRECTION_F,

        /* words 3,4,5,6 (8-23 bytes) */
        IB_MAD_TRID_F,
        IB_MAD_ATTRID_F,
        IB_MAD_ATTRMOD_F,

        /* word 7,8 (24-31 bytes) */
        IB_MAD_MKEY_F,

        /* word 9 (32-37 bytes) */
        IB_DRSMP_DRSLID_F,
        IB_DRSMP_DRDLID_F,

        /* word 10,11 (36-43 bytes) */
        IB_SA_MKEY_F,

        /* word 12 (44-47 bytes) */
        IB_SA_ATTROFFS_F,

        /* word 13,14 (48-55 bytes) */
        IB_SA_COMPMASK_F,

        /* word 13,14 (56-255 bytes) */
        IB_SA_DATA_F,

        /* bytes 64 - 127 */
        IB_SM_DATA_F,

        /* bytes 64 - 256 */
        IB_GS_DATA_F, 

        /* bytes 128 - 191 */
        IB_DRSMP_PATH_F,

        /* bytes 192 - 255 */
        IB_DRSMP_RPATH_F,

        /*
         * PortInfo fields:
         */
        IB_PORT_FIRST_F,
        IB_PORT_MKEY_F = IB_PORT_FIRST_F,
        IB_PORT_GID_PREFIX_F,
        IB_PORT_LID_F,
        IB_PORT_SMLID_F,
        IB_PORT_CAPMASK_F,
        IB_PORT_DIAG_F,
        IB_PORT_MKEY_LEASE_F,
        IB_PORT_LOCAL_PORT_F,
        IB_PORT_LINK_WIDTH_ENABLED_F,
        IB_PORT_LINK_WIDTH_SUPPORTED_F,
        IB_PORT_LINK_WIDTH_ACTIVE_F,
        IB_PORT_LINK_SPEED_SUPPORTED_F,
        IB_PORT_STATE_F,
        IB_PORT_PHYS_STATE_F,
        IB_PORT_LINK_DOWN_DEF_F,
        IB_PORT_MKEY_PROT_BITS_F,
        IB_PORT_LMC_F,
        IB_PORT_LINK_SPEED_ACTIVE_F,
        IB_PORT_LINK_SPEED_ENABLED_F,
        IB_PORT_NEIGHBOR_MTU_F,
        IB_PORT_SMSL_F,
        IB_PORT_VL_CAP_F,
        IB_PORT_INIT_TYPE_F,
        IB_PORT_VL_HIGH_LIMIT_F,
        IB_PORT_VL_ARBITRATION_HIGH_CAP_F,
        IB_PORT_VL_ARBITRATION_LOW_CAP_F,
        IB_PORT_INIT_TYPE_REPLY_F,
        IB_PORT_MTRU_CAP_F,
        IB_PORT_VL_STALL_COUNT_F,
        IB_PORT_HOQ_LIFE_F,
        IB_PORT_OPER_VLS_F,
        IB_PORT_PART_EN_INB_F,
        IB_PORT_PART_EN_OUTB_F,
        IB_PORT_FILTER_RAW_INB_F,
        IB_PORT_FILTER_RAW_OUTB_F,
        IB_PORT_MKEY_VIOL_F,
        IB_PORT_PKEY_VIOL_F,
        IB_PORT_QKEY_VIOL_F,
        IB_PORT_GUID_CAP_F,
        IB_PORT_CLIENT_REREG_F,
        IB_PORT_SUBN_TIMEOUT_F,
        IB_PORT_RESP_TIME_VAL_F,
        IB_PORT_LOCAL_PHYS_ERR_F,
        IB_PORT_OVERRUN_ERR_F,
        IB_PORT_MAX_CREDIT_HINT_F,
        IB_PORT_LINK_ROUND_TRIP_F,
        IB_PORT_LAST_F,

        /*
         * NodeInfo fields:
         */
        IB_NODE_FIRST_F,
        IB_NODE_BASE_VERS_F = IB_NODE_FIRST_F,
        IB_NODE_CLASS_VERS_F,
        IB_NODE_TYPE_F,
        IB_NODE_NPORTS_F,
        IB_NODE_SYSTEM_GUID_F,
        IB_NODE_GUID_F,
        IB_NODE_PORT_GUID_F,
        IB_NODE_PARTITION_CAP_F,
        IB_NODE_DEVID_F,
        IB_NODE_REVISION_F,
        IB_NODE_LOCAL_PORT_F,
        IB_NODE_VENDORID_F,
        IB_NODE_LAST_F,

        /*
         * SwitchInfo fields:
         */
        IB_SW_FIRST_F,
        IB_SW_LINEAR_FDB_CAP_F = IB_SW_FIRST_F,
        IB_SW_RANDOM_FDB_CAP_F,
        IB_SW_MCAST_FDB_CAP_F,
        IB_SW_LINEAR_FDB_TOP_F,
        IB_SW_DEF_PORT_F,
        IB_SW_DEF_MCAST_PRIM_F,
        IB_SW_DEF_MCAST_NOT_PRIM_F,
        IB_SW_LIFE_TIME_F,
        IB_SW_STATE_CHANGE_F,
        IB_SW_LIDS_PER_PORT_F,
        IB_SW_PARTITION_ENFORCE_CAP_F,
        IB_SW_PARTITION_ENF_INB_F,
        IB_SW_PARTITION_ENF_OUTB_F,
        IB_SW_FILTER_RAW_INB_F,
        IB_SW_FILTER_RAW_OUTB_F,
        IB_SW_ENHANCED_PORT0_F,
        IB_SW_LAST_F,

        /*
         * SwitchLinearForwardingTable fields:
         */
        IB_LINEAR_FORW_TBL_F,

        /*
         * SwitchMulticastForwardingTable fields:
         */
        IB_MULTICAST_FORW_TBL_F,

        /*
         * NodeDescription fields:
         */
        IB_NODE_DESC_F,

        /*
         * Notice/Trap fields
         */
        IB_NOTICE_IS_GENERIC_F,
        IB_NOTICE_TYPE_F,
        IB_NOTICE_PRODUCER_F,
        IB_NOTICE_TRAP_NUMBER_F,
        IB_NOTICE_ISSUER_LID_F,
        IB_NOTICE_TOGGLE_F,
        IB_NOTICE_COUNT_F,
        IB_NOTICE_DATA_LID_F,

        /*
         * GS Performance
         */
        IB_PC_FIRST_F,
        IB_PC_PORT_SELECT_F = IB_PC_FIRST_F,
        IB_PC_COUNTER_SELECT_F,
        IB_PC_ERR_SYM_F,
        IB_PC_LINK_RECOVERS_F,
        IB_PC_LINK_DOWNED_F,
        IB_PC_ERR_RCV_F,
        IB_PC_ERR_PHYSRCV_F,
        IB_PC_ERR_SWITCH_REL_F,
        IB_PC_XMT_DISCARDS_F,
        IB_PC_ERR_XMTCONSTR_F,
        IB_PC_ERR_RCVCONSTR_F,
        IB_PC_ERR_LOCALINTEG_F,
        IB_PC_ERR_EXCESS_OVR_F,
        IB_PC_VL15_DROPPED_F,
        IB_PC_XMT_BYTES_F,
        IB_PC_RCV_BYTES_F,
        IB_PC_XMT_PKTS_F,
        IB_PC_RCV_PKTS_F,
        IB_PC_LAST_F,

        /*
         * SMInfo
         */
        IB_SMINFO_GUID_F,
        IB_SMINFO_KEY_F,
        IB_SMINFO_ACT_F,
        IB_SMINFO_PRIO_F,
        IB_SMINFO_STATE_F,

        /*
         * SA RMPP
         */
        IB_SA_RMPP_VERS_F,
        IB_SA_RMPP_TYPE_F,
        IB_SA_RMPP_RESP_F,
        IB_SA_RMPP_FLAGS_F,
        IB_SA_RMPP_STATUS_F,

        /* data1 */
        IB_SA_RMPP_D1_F,
        IB_SA_RMPP_SEGNUM_F,
        /* data2 */
        IB_SA_RMPP_D2_F,
        IB_SA_RMPP_LEN_F,               /* DATA: Payload len */
        IB_SA_RMPP_NEWWIN_F,            /* ACK: new window last */

        /*
         * SA Get Multi Path
         */
        IB_SA_MP_NPATH_F,
        IB_SA_MP_NSRC_F,
        IB_SA_MP_NDEST_F,
        IB_SA_MP_GID0_F,

        /*
         * SA Path rec
         */
        IB_SA_PR_DGID_F,
        IB_SA_PR_SGID_F,
        IB_SA_PR_DLID_F,
        IB_SA_PR_SLID_F,
        IB_SA_PR_NPATH_F,

        /*
         * MC Member rec
         */
        IB_SA_MCM_MGID_F,
        IB_SA_MCM_PORTGID_F,
        IB_SA_MCM_QKEY_F,
        IB_SA_MCM_MLID_F,
        IB_SA_MCM_SL_F,
        IB_SA_MCM_MTU_F,
        IB_SA_MCM_RATE_F,
        IB_SA_MCM_TCLASS_F,
        IB_SA_MCM_PKEY_F,
        IB_SA_MCM_FLOW_LABEL_F,
        IB_SA_MCM_JOIN_STATE_F,
        IB_SA_MCM_PROXY_JOIN_F,

        /*
         * Service record
         */
        IB_SA_SR_ID_F,
        IB_SA_SR_GID_F,
        IB_SA_SR_PKEY_F,
        IB_SA_SR_LEASE_F,
        IB_SA_SR_KEY_F,
        IB_SA_SR_NAME_F,
        IB_SA_SR_DATA_F,

        /*
         * ATS SM record - within SA_SR_DATA
         */
        IB_ATS_SM_NODE_ADDR_F,
        IB_ATS_SM_MAGIC_KEY_F,
        IB_ATS_SM_NODE_TYPE_F,
        IB_ATS_SM_NODE_NAME_F,

        /*
         * SLTOVL MAPPING TABLE
         */
        IB_SLTOVL_MAPPING_TABLE_F,

        /*
         * VL ARBITRATION TABLE
         */
        IB_VL_ARBITRATION_TABLE_F,

        /*
         * IB vendor class range 2
         */
        IB_VEND2_OUI_F,
        IB_VEND2_DATA_F,

        /*
         * InformInfo record
        IB_SA_INFINFO_SUBGID_F,
        IB_SA_INFINFO_ENUM_F,
        IB_SA_INFINFO_RESV0_F,
         */
        IB_SA_INFINFO_GID_F,
        IB_SA_INFINFO_LID_BEGIN_F,  
        IB_SA_INFINFO_LID_END_F, 
        IB_SA_INFINFO_RESV1_F, 
        IB_SA_INFINFO_ISGENERIC_F, 
        IB_SA_INFINFO_SUBSCRIBE_F,
        IB_SA_INFINFO_TYPE_F, 
        IB_SA_INFINFO_TRAP_DEVID_F,
        IB_SA_INFINFO_QPN_F, 
        IB_SA_INFINFO_RES2_F, 
        IB_SA_INFINFO_RESPTIME_F, 
        IB_SA_INFINFO_RESV3_F,
        IB_SA_INFINFO_VENDORID_F,

        IB_FIELD_LAST_  /* must be last */
};

/*
 * SA RMPP section
 */
enum RMPP_TYPE_ENUM {
        IB_RMPP_TYPE_NONE,
        IB_RMPP_TYPE_DATA,
        IB_RMPP_TYPE_ACK,
        IB_RMPP_TYPE_STOP,
        IB_RMPP_TYPE_ABORT,
};

enum RMPP_FLAGS_ENUM {
        IB_RMPP_FLAG_ACTIVE = 1 << 0,
        IB_RMPP_FLAG_FIRST = 1 << 1,
        IB_RMPP_FLAG_LAST = 1 << 2,
};

typedef struct {
        int type;
        int flags;
        int status;
        union {
                uint32_t u;
                uint32_t segnum;
        } d1;
        union {
                uint32_t u;
                uint32_t len;
                uint32_t newwin;
        } d2;
} ib_rmpp_hdr_t;

enum SA_SIZES_ENUM {
        SA_HEADER_SZ = 20,
};

typedef struct ib_sa_call {
        uint attrid;
        uint mod;
        uint64_t mask;
        uint method;

        uint64_t trid;  /* used for out mad if nonzero, return real val */
        uint recsz;     /* return field */
        ib_rmpp_hdr_t rmpp;
} ib_sa_call_t;

typedef struct ib_vendor_call {
        uint method;
        uint mgmt_class;
        uint attrid;
        uint mod;
        uint32_t oui;
        uint timeout;
        ib_rmpp_hdr_t rmpp;
} ib_vendor_call_t;

#define IB_MIN_UCAST_LID        1
#define IB_MAX_UCAST_LID        (0xc000-1)
#define IB_MIN_MCAST_LID        0xc000
#define IB_MAX_MCAST_LID        (0xffff-1)

#define IB_LID_VALID(lid)       ((lid) >= IB_MIN_UCAST_LID && lid <= 
IB_MAX_UCAST_LID)
#define IB_MLID_VALID(lid)      ((lid) >= IB_MIN_MCAST_LID && lid <= 
IB_MAX_MCAST_LID)

#define MAD_DEF_RETRIES         3
#define MAD_DEF_TIMEOUT_MS      1000

enum {
        IB_DEST_LID,
        IB_DEST_DRPATH,
        IB_DEST_GUID,
};

enum {
        IB_NODE_CA = 1,
        IB_NODE_SWITCH,
        IB_NODE_ROUTER,
        NODE_RNIC,

        IB_NODE_MAX = NODE_RNIC 
};

/******************************************************************************/

/* portid.c */
char *  portid2str(ib_portid_t *portid);
int     portid2portnum(ib_portid_t *portid);
int     str2drpath(ib_dr_path_t *path, char *routepath, int drslid, int drdlid);

static inline int
ib_portid_set(ib_portid_t *portid, int lid, int qp, int qkey)
{
        portid->lid = lid;
        portid->qp = qp;
        portid->qkey = qkey;

        return 0;
}

/* fields.c */
extern ib_field_t ib_mad_f[];

void    _set_field(void *buf, int base_offs, ib_field_t *f, uint32_t val);
uint32_t _get_field(void *buf, int base_offs, ib_field_t *f);
void    _set_array(void *buf, int base_offs, ib_field_t *f, void *val);
void    _get_array(void *buf, int base_offs, ib_field_t *f, void *val);
void    _set_field64(void *buf, int base_offs, ib_field_t *f, uint64_t val);
uint64_t _get_field64(void *buf, int base_offs, ib_field_t *f);

/* mad.c */
static inline uint32_t
mad_get_field(void *buf, int base_offs, int field)
{
        return _get_field(buf, base_offs, ib_mad_f + field);
}

static inline void
mad_set_field(void *buf, int base_offs, int field, uint32_t val)
{
        _set_field(buf, base_offs, ib_mad_f + field, val);
}

/* field must be byte aligned */
static inline uint64_t
mad_get_field64(void *buf, int base_offs, int field)
{
        return _get_field64(buf, base_offs, ib_mad_f + field);
}

static inline void
mad_set_field64(void *buf, int base_offs, int field, uint64_t val)
{
        _set_field64(buf, base_offs, ib_mad_f + field, val);
}

static inline void
mad_set_array(void *buf, int base_offs, int field, void *val)
{
        _set_array(buf, base_offs, ib_mad_f + field, val);
}

static inline void
mad_get_array(void *buf, int base_offs, int field, void *val)
{
        _get_array(buf, base_offs, ib_mad_f + field, val);
}

void    mad_decode_field(uint8_t *buf, int field, void *val);
void    mad_encode_field(uint8_t *buf, int field, void *val);
void *  mad_encode(void *buf, ib_rpc_t *rpc, ib_dr_path_t *drpath, void *data);
uint64_t mad_trid(void);
int     mad_build_pkt(void *umad, ib_rpc_t *rpc, ib_portid_t *dport, 
ib_rmpp_hdr_t *rmpp, void *data);

/* register.c */
int     mad_register_client(int mgmt, uint8_t rmpp_version);
int     mad_register_server(int mgmt, uint8_t rmpp_version,
                            uint32_t method_mask[4], uint32_t class_oui);
int     mad_class_agent(int mgmt);
int     mad_agent_class(int agent);

/* serv.c */
int     mad_send(ib_rpc_t *rpc, ib_portid_t *dport, ib_rmpp_hdr_t *rmpp,
                 void *data);
void *  mad_receive(void *umad, int timeout);
int     mad_respond(void *umad, ib_portid_t *portid, uint32_t rstatus);
void *  mad_alloc(void);
void    mad_free(void *umad);

/* vendor */
uint8_t *ib_vendor_call(void *data, ib_portid_t *portid,
                        ib_vendor_call_t *call);

static inline int
mad_is_vendor_range1(int mgmt)
{
        return mgmt >= 0x9 && mgmt <= 0xf;
}

static inline int
mad_is_vendor_range2(int mgmt)
{
        return mgmt >= 0x30 && mgmt <= 0x4f;
}

/* rpc.c */
int     madrpc_portid(void);
int     madrpc_set_retries(int retries);
int     madrpc_set_timeout(int timeout);
void *  madrpc(ib_rpc_t *rpc, ib_portid_t *dport, void *payload, void *rcvdata);
void *  madrpc_rmpp(ib_rpc_t *rpc, ib_portid_t *dport, ib_rmpp_hdr_t *rmpp,
                    void *data);
void    madrpc_init(char *dev_name, int dev_port, int *mgmt_classes,
                    int num_classes);
void    madrpc_save_mad(void *madbuf, int len);
void    madrpc_lock(void);
void    madrpc_unlock(void);
void    madrpc_show_errors(int set);

/* smp.c */
uint8_t * smp_query(void *buf, ib_portid_t *id, uint attrid, uint mod,
                    uint timeout);
uint8_t * smp_set(void *buf, ib_portid_t *id, uint attrid, uint mod,
                  uint timeout);

inline static uint8_t *
safe_smp_query(void *rcvbuf, ib_portid_t *portid, uint attrid, uint mod,
               uint timeout)
{
        uint8_t *p;

        madrpc_lock();
        p = smp_query(rcvbuf, portid, attrid, mod, timeout);
        madrpc_unlock();

        return p;
}

inline static uint8_t *
safe_smp_set(void *rcvbuf, ib_portid_t *portid, uint attrid, uint mod,
             uint timeout)
{
        uint8_t *p;

        madrpc_lock();
        p = smp_set(rcvbuf, portid, attrid, mod, timeout);
        madrpc_unlock();

        return p;
}

/* sa.c */
uint8_t * sa_call(void *rcvbuf, ib_portid_t *portid, ib_sa_call_t *sa,
                  uint timeout);
int     ib_path_query(ib_gid_t srcgid, ib_gid_t destgid, ib_portid_t *sm_id,
                      void *buf);       /* returns lid */

inline static uint8_t *
safe_sa_call(void *rcvbuf, ib_portid_t *portid, ib_sa_call_t *sa,
             uint timeout)
{
        uint8_t *p;

        madrpc_lock();
        p = sa_call(rcvbuf, portid, sa, timeout);
        madrpc_unlock();

        return p;
}

/* resolve.c */
int     ib_resolve_smlid(ib_portid_t *sm_id, int timeout);
int     ib_resolve_guid(ib_portid_t *portid, uint64_t *guid,
                        ib_portid_t *sm_id, int timeout);
int     ib_resolve_portid_str(ib_portid_t *portid, char *addr_str,
                              int dest_type, ib_portid_t *sm_id);
int     ib_resolve_self(ib_portid_t *portid, int *portnum, ib_gid_t *gid);

/* gs.c */
uint8_t *perf_classportinfo_query(void *rcvbuf, ib_portid_t *dest, int port,
                                  uint timeout);
uint8_t *port_performance_query(void *rcvbuf, ib_portid_t *dest, int port,
                                uint timeout);
uint8_t *port_performance_reset(void *rcvbuf, ib_portid_t *dest, int port,
                                uint mask, uint timeout);
uint8_t *port_samples_control_query(void *rcvbuf, ib_portid_t *dest, int port,
                                    uint timeout);
uint8_t *port_samples_result_query(void *rcvbuf, ib_portid_t *dest, int port,
                                   uint timeout);

/* dump.c */
ib_mad_dump_fn
        mad_dump_int, mad_dump_uint, mad_dump_hex, mad_dump_rhex,
        mad_dump_bitfield, mad_dump_array, mad_dump_string,
        mad_dump_linkwidth, mad_dump_linkwidthsup, mad_dump_linkwidthen,
        mad_dump_linkdowndefstate,
        mad_dump_linkspeed, mad_dump_linkspeedsup, mad_dump_linkspeeden,
        mad_dump_portstate, mad_dump_portstates,
        mad_dump_physportstate, mad_dump_portcapmask,
        mad_dump_mtu, mad_dump_vlcap, mad_dump_opervls,
        mad_dump_node_type,
        mad_dump_sltovl, mad_dump_vlarbitration,
        mad_dump_nodedesc, mad_dump_nodeinfo, mad_dump_portinfo, 
mad_dump_switchinfo,
        mad_dump_perfcounters;

int     _mad_dump(ib_mad_dump_fn *fn, char *name, void *val, int valsz);
char *  _mad_dump_field(ib_field_t *f, char *name, char *buf, int bufsz,
                        void *val);
int     _mad_print_field(ib_field_t *f, char *name, void *val, int valsz);
char *  _mad_dump_val(ib_field_t *f, char *buf, int bufsz, void *val);

static inline int
mad_print_field(int field, char *name, void *val)
{
        if (field <= IB_NO_FIELD || field >= IB_FIELD_LAST_)
                return -1;
        return _mad_print_field(ib_mad_f + field, name, val, 0);
}

static inline char *
mad_dump_field(int field, char *buf, int bufsz, void *val)
{
        if (field <= IB_NO_FIELD || field >= IB_FIELD_LAST_)
                return 0;
        return _mad_dump_field(ib_mad_f + field, 0, buf, bufsz, val);
}

static inline char *
mad_dump_val(int field, char *buf, int bufsz, void *val)
{
        if (field <= IB_NO_FIELD || field >= IB_FIELD_LAST_)
                return 0;
        return _mad_dump_val(ib_mad_f + field, buf, bufsz, val);
}

extern int ibdebug;

END_C_DECLS

#endif /* _MAD_H_ */
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to