1/*
2 * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses.  You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 *     Redistribution and use in source and binary forms, with or
11 *     without modification, are permitted provided that the following
12 *     conditions are met:
13 *
14 *      - Redistributions of source code must retain the above
15 *        copyright notice, this list of conditions and the following
16 *        disclaimer.
17 *
18 *      - Redistributions in binary form must reproduce the above
19 *        copyright notice, this list of conditions and the following
20 *        disclaimer in the documentation and/or other materials
21 *        provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 */
33
34#if HAVE_CONFIG_H
35#  include <config.h>
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <unistd.h>
41#include <string.h>
42
43#include <mad.h>
44#include <infiniband/common.h>
45
46/*
47 * BITSOFFS and BE_OFFS are required due the fact that the bit offsets are inconsistently
48 * encoded in the IB spec - IB headers are encoded such that the bit offsets
49 * are in big endian convention (BE_OFFS), while the SMI/GSI queries data fields bit
50 * offsets are specified using real bit offset (?!)
51 * The following macros normalize everything to big endian offsets.
52 */
53#define BITSOFFS(o, w)	(((o) & ~31) | ((32 - ((o) & 31) - (w)))), (w)
54#define BE_OFFS(o, w)	(o), (w)
55#define BE_TO_BITSOFFS(o, w)	(((o) & ~31) | ((32 - ((o) & 31) - (w))))
56
57ib_field_t ib_mad_f [] = {
58	[0]	{0, 0},		/* IB_NO_FIELD - reserved as invalid */
59
60	[IB_GID_PREFIX_F]		{0, 64, "GidPrefix", mad_dump_rhex},
61	[IB_GID_GUID_F]			{64, 64, "GidGuid", mad_dump_rhex},
62
63	/*
64	 * MAD: common MAD fields (IB spec 13.4.2)
65	 * SMP: Subnet Management packets - lid routed (IB spec 14.2.1.1)
66	 * DSMP: Subnet Management packets - direct route (IB spec 14.2.1.2)
67	 * SA: Subnet Administration packets (IB spec 15.2.1.1)
68	 */
69
70	/* first MAD word (0-3 bytes) */
71	[IB_MAD_METHOD_F]		{BE_OFFS(0, 7), "MadMethod", mad_dump_hex}, /* TODO: add dumper */
72	[IB_MAD_RESPONSE_F] 		{BE_OFFS(7, 1), "MadIsResponse", mad_dump_uint}, /* TODO: add dumper */
73	[IB_MAD_CLASSVER_F] 		{BE_OFFS(8, 8), "MadClassVersion", mad_dump_uint},
74	[IB_MAD_MGMTCLASS_F] 		{BE_OFFS(16, 8), "MadMgmtClass", mad_dump_uint},  /* TODO: add dumper */
75	[IB_MAD_BASEVER_F] 		{BE_OFFS(24, 8), "MadBaseVersion", mad_dump_uint},
76
77	/* second MAD word (4-7 bytes) */
78	[IB_MAD_STATUS_F] 		{BE_OFFS(48, 16), "MadStatus", mad_dump_hex}, /* TODO: add dumper */
79
80	/* DR SMP only */
81	[IB_DRSMP_HOPCNT_F] 		{BE_OFFS(32, 8), "DrSmpHopCnt", mad_dump_uint},
82	[IB_DRSMP_HOPPTR_F] 		{BE_OFFS(40, 8), "DrSmpHopPtr", mad_dump_uint},
83	[IB_DRSMP_STATUS_F] 		{BE_OFFS(48, 15), "DrSmpStatus", mad_dump_hex}, /* TODO: add dumper */
84	[IB_DRSMP_DIRECTION_F] 		{BE_OFFS(63, 1), "DrSmpDirection", mad_dump_uint}, /* TODO: add dumper */
85
86	/* words 3,4,5,6 (8-23 bytes) */
87	[IB_MAD_TRID_F] 		{64, 64, "MadTRID", mad_dump_hex},
88	[IB_MAD_ATTRID_F] 		{BE_OFFS(144, 16), "MadAttr", mad_dump_hex}, /* TODO: add dumper */
89	[IB_MAD_ATTRMOD_F] 		{160, 32, "MadModifier", mad_dump_hex}, /* TODO: add dumper */
90
91	/* word 7,8 (24-31 bytes) */
92	[IB_MAD_MKEY_F] 		{196, 64, "MadMkey", mad_dump_hex},
93
94	/* word 9 (32-37 bytes) */
95	[IB_DRSMP_DRDLID_F] 		{BE_OFFS(256, 16), "DrSmpDLID", mad_dump_hex},
96	[IB_DRSMP_DRSLID_F] 		{BE_OFFS(272, 16), "DrSmpSLID", mad_dump_hex},
97
98	/* word 12 (44-47 bytes) */
99	[IB_SA_ATTROFFS_F] 		{BE_OFFS(46*8, 16), "SaAttrOffs", mad_dump_uint},
100
101	/* word 13,14 (48-55 bytes) */
102	[IB_SA_COMPMASK_F] 		{48*8, 64, "SaCompMask", mad_dump_hex},
103
104	/* word 13,14 (56-255 bytes) */
105	[IB_SA_DATA_F] 			{56*8, (256-56)*8, "SaData", mad_dump_hex},
106
107	[IB_DRSMP_PATH_F] 		{1024, 512, "DrSmpPath", mad_dump_hex},
108	[IB_DRSMP_RPATH_F] 		{1536, 512, "DrSmpRetPath", mad_dump_hex},
109
110	[IB_GS_DATA_F] 			{64*8, (256-64) * 8, "GsData", mad_dump_hex},
111
112	/*
113	 * PortInfo fields:
114	 */
115	[IB_PORT_MKEY_F]		{0, 64, "Mkey", mad_dump_hex},
116	[IB_PORT_GID_PREFIX_F]		{64, 64, "GidPrefix", mad_dump_hex},
117	[IB_PORT_LID_F]			{BITSOFFS(128, 16), "Lid", mad_dump_hex},
118	[IB_PORT_SMLID_F]		{BITSOFFS(144, 16), "SMLid", mad_dump_hex},
119	[IB_PORT_CAPMASK_F]		{160, 32, "CapMask", mad_dump_portcapmask},
120	[IB_PORT_DIAG_F]		{BITSOFFS(192, 16), "DiagCode", mad_dump_hex},
121	[IB_PORT_MKEY_LEASE_F]		{BITSOFFS(208, 16), "MkeyLeasePeriod", mad_dump_uint},
122	[IB_PORT_LOCAL_PORT_F]		{BITSOFFS(224, 8), "LocalPort", mad_dump_uint},
123	[IB_PORT_LINK_WIDTH_ENABLED_F]	{BITSOFFS(232, 8), "LinkWidthEnabled", mad_dump_linkwidthen},
124	[IB_PORT_LINK_WIDTH_SUPPORTED_F]	{BITSOFFS(240, 8), "LinkWidthSupported", mad_dump_linkwidthsup},
125	[IB_PORT_LINK_WIDTH_ACTIVE_F]	{BITSOFFS(248, 8), "LinkWidthActive", mad_dump_linkwidth},
126	[IB_PORT_LINK_SPEED_SUPPORTED_F]	{BITSOFFS(256, 4), "LinkSpeedSupported", mad_dump_linkspeedsup},
127	[IB_PORT_STATE_F]		{BITSOFFS(260, 4), "LinkState", mad_dump_portstate},
128	[IB_PORT_PHYS_STATE_F]		{BITSOFFS(264, 4), "PhysLinkState", mad_dump_physportstate},
129	[IB_PORT_LINK_DOWN_DEF_F]	{BITSOFFS(268, 4), "LinkDownDefState", mad_dump_linkdowndefstate},
130	[IB_PORT_MKEY_PROT_BITS_F]	{BITSOFFS(272, 2), "ProtectBits", mad_dump_uint},
131	[IB_PORT_LMC_F]			{BITSOFFS(277, 3), "LMC", mad_dump_uint},
132	[IB_PORT_LINK_SPEED_ACTIVE_F]	{BITSOFFS(280, 4), "LinkSpeedActive", mad_dump_linkspeed},
133	[IB_PORT_LINK_SPEED_ENABLED_F]	{BITSOFFS(284, 4), "LinkSpeedEnabled", mad_dump_linkspeeden},
134	[IB_PORT_NEIGHBOR_MTU_F]	{BITSOFFS(288, 4), "NeighborMTU", mad_dump_mtu},
135	[IB_PORT_SMSL_F]		{BITSOFFS(292, 4), "SMSL", mad_dump_uint},
136	[IB_PORT_VL_CAP_F]		{BITSOFFS(296, 4), "VLCap", mad_dump_vlcap},
137	[IB_PORT_INIT_TYPE_F]		{BITSOFFS(300, 4), "InitType", mad_dump_hex},
138	[IB_PORT_VL_HIGH_LIMIT_F] 	{BITSOFFS(304, 8), "VLHighLimit", mad_dump_uint},
139	[IB_PORT_VL_ARBITRATION_HIGH_CAP_F]	{BITSOFFS(312, 8), "VLArbHighCap", mad_dump_uint},
140	[IB_PORT_VL_ARBITRATION_LOW_CAP_F]	{BITSOFFS(320, 8), "VLArbLowCap", mad_dump_uint},
141
142	[IB_PORT_INIT_TYPE_REPLY_F]	{BITSOFFS(328, 4), "InitReply", mad_dump_hex},
143	[IB_PORT_MTU_CAP_F]		{BITSOFFS(332, 4), "MtuCap", mad_dump_mtu},
144	[IB_PORT_VL_STALL_COUNT_F]	{BITSOFFS(336, 3), "VLStallCount", mad_dump_uint},
145	[IB_PORT_HOQ_LIFE_F]		{BITSOFFS(339, 5), "HoqLife", mad_dump_uint},
146	[IB_PORT_OPER_VLS_F]		{BITSOFFS(344, 4), "OperVLs", mad_dump_opervls},
147	[IB_PORT_PART_EN_INB_F]		{BITSOFFS(348, 1), "PartEnforceInb", mad_dump_uint},
148	[IB_PORT_PART_EN_OUTB_F]	{BITSOFFS(349, 1), "PartEnforceOutb", mad_dump_uint},
149	[IB_PORT_FILTER_RAW_INB_F]	{BITSOFFS(350, 1), "FilterRawInb", mad_dump_uint},
150	[IB_PORT_FILTER_RAW_OUTB_F]	{BITSOFFS(351, 1), "FilterRawOutb", mad_dump_uint},
151	[IB_PORT_MKEY_VIOL_F]		{BITSOFFS(352, 16), "MkeyViolations", mad_dump_uint},
152	[IB_PORT_PKEY_VIOL_F]		{BITSOFFS(368, 16), "PkeyViolations", mad_dump_uint},
153	[IB_PORT_QKEY_VIOL_F]		{BITSOFFS(384, 16), "QkeyViolations", mad_dump_uint},
154	[IB_PORT_GUID_CAP_F]		{BITSOFFS(400, 8), "GuidCap", mad_dump_uint},
155	[IB_PORT_CLIENT_REREG_F]	{BITSOFFS(408, 1), "ClientReregister", mad_dump_uint},
156	[IB_PORT_SUBN_TIMEOUT_F]	{BITSOFFS(411, 5), "SubnetTimeout", mad_dump_uint},
157	[IB_PORT_RESP_TIME_VAL_F]	{BITSOFFS(419, 5), "RespTimeVal", mad_dump_uint},
158	[IB_PORT_LOCAL_PHYS_ERR_F]	{BITSOFFS(424, 4), "LocalPhysErr", mad_dump_uint},
159	[IB_PORT_OVERRUN_ERR_F]		{BITSOFFS(428, 4), "OverrunErr", mad_dump_uint},
160	[IB_PORT_MAX_CREDIT_HINT_F]	{BITSOFFS(432, 16), "MaxCreditHint", mad_dump_uint},
161	[IB_PORT_LINK_ROUND_TRIP_F]	{BITSOFFS(456, 24), "RoundTrip", mad_dump_uint},
162
163	/*
164	 * NodeInfo fields:
165	 */
166	[IB_NODE_BASE_VERS_F]		{BITSOFFS(0,8), "BaseVers", mad_dump_uint},
167	[IB_NODE_CLASS_VERS_F]		{BITSOFFS(8,8), "ClassVers", mad_dump_uint},
168	[IB_NODE_TYPE_F]		{BITSOFFS(16,8), "NodeType", mad_dump_node_type},
169	[IB_NODE_NPORTS_F]		{BITSOFFS(24,8), "NumPorts", mad_dump_uint},
170	[IB_NODE_SYSTEM_GUID_F]		{32, 64, "SystemGuid", mad_dump_hex},
171	[IB_NODE_GUID_F]		{96, 64, "Guid", mad_dump_hex},
172	[IB_NODE_PORT_GUID_F]		{160, 64, "PortGuid", mad_dump_hex},
173	[IB_NODE_PARTITION_CAP_F]	{BITSOFFS(224,16), "PartCap", mad_dump_uint},
174	[IB_NODE_DEVID_F]		{BITSOFFS(240,16), "DevId", mad_dump_hex},
175	[IB_NODE_REVISION_F]		{256, 32, "Revision", mad_dump_hex},
176	[IB_NODE_LOCAL_PORT_F]		{BITSOFFS(288,8), "LocalPort", mad_dump_uint},
177	[IB_NODE_VENDORID_F]		{BITSOFFS(296,24), "VendorId", mad_dump_hex},
178
179	/*
180	 * SwitchInfo fields:
181	 */
182	[IB_SW_LINEAR_FDB_CAP_F]	{BITSOFFS(0, 16), "LinearFdbCap", mad_dump_uint},
183	[IB_SW_RANDOM_FDB_CAP_F]	{BITSOFFS(16, 16), "RandomFdbCap", mad_dump_uint},
184	[IB_SW_MCAST_FDB_CAP_F]		{BITSOFFS(32, 16), "McastFdbCap", mad_dump_uint},
185	[IB_SW_LINEAR_FDB_TOP_F]	{BITSOFFS(48, 16), "LinearFdbTop", mad_dump_uint},
186	[IB_SW_DEF_PORT_F]		{BITSOFFS(64, 8), "DefPort", mad_dump_uint},
187	[IB_SW_DEF_MCAST_PRIM_F]	{BITSOFFS(72, 8), "DefMcastPrimPort", mad_dump_uint},
188	[IB_SW_DEF_MCAST_NOT_PRIM_F]	{BITSOFFS(80, 8), "DefMcastNotPrimPort", mad_dump_uint},
189	[IB_SW_LIFE_TIME_F]		{BITSOFFS(88, 5), "LifeTime", mad_dump_uint},
190	[IB_SW_STATE_CHANGE_F]		{BITSOFFS(93, 1), "StateChange", mad_dump_uint},
191	[IB_SW_LIDS_PER_PORT_F]		{BITSOFFS(96,16), "LidsPerPort", mad_dump_uint},
192	[IB_SW_PARTITION_ENFORCE_CAP_F]	{BITSOFFS(112, 16), "PartEnforceCap", mad_dump_uint},
193	[IB_SW_PARTITION_ENF_INB_F]	{BITSOFFS(128, 1), "InboundPartEnf", mad_dump_uint},
194	[IB_SW_PARTITION_ENF_OUTB_F]	{BITSOFFS(129, 1), "OutboundPartEnf", mad_dump_uint},
195	[IB_SW_FILTER_RAW_INB_F]	{BITSOFFS(130, 1), "FilterRawInbound", mad_dump_uint},
196	[IB_SW_FILTER_RAW_OUTB_F]	{BITSOFFS(131, 1), "FilterRawOutbound", mad_dump_uint},
197	[IB_SW_ENHANCED_PORT0_F]	{BITSOFFS(132, 1), "EnhancedPort0", mad_dump_uint},
198
199	/*
200	 * SwitchLinearForwardingTable fields:
201	 */
202	[IB_LINEAR_FORW_TBL_F]		{0, 512, "LinearForwTbl", mad_dump_array},
203
204	/*
205	 * SwitchMulticastForwardingTable fields:
206	 */
207	[IB_MULTICAST_FORW_TBL_F]	{0, 512, "MulticastForwTbl", mad_dump_array},
208
209	/*
210	 * Notice/Trap fields
211	 */
212	[IB_NOTICE_IS_GENERIC_F]  	{BITSOFFS(0, 1), "NoticeIsGeneric", mad_dump_uint},
213	[IB_NOTICE_TYPE_F]        	{BITSOFFS(1, 7), "NoticeType", mad_dump_uint},
214	[IB_NOTICE_PRODUCER_F]    	{BITSOFFS(8, 24), "NoticeProducerType", mad_dump_node_type},
215	[IB_NOTICE_TRAP_NUMBER_F] 	{BITSOFFS(32, 16), "NoticeTrapNumber", mad_dump_uint},
216	[IB_NOTICE_ISSUER_LID_F]  	{BITSOFFS(48, 16), "NoticeIssuerLID", mad_dump_uint},
217	[IB_NOTICE_TOGGLE_F]      	{BITSOFFS(64, 1), "NoticeToggle", mad_dump_uint},
218	[IB_NOTICE_COUNT_F]       	{BITSOFFS(65, 15), "NoticeCount", mad_dump_uint},
219	[IB_NOTICE_DATA_DETAILS_F]    	{80, 432, "NoticeDataDetails", mad_dump_array},
220	[IB_NOTICE_DATA_LID_F]    	{BITSOFFS(80, 16), "NoticeDataLID", mad_dump_uint},
221	[IB_NOTICE_DATA_144_LID_F]    	{BITSOFFS(96, 16), "NoticeDataTrap144LID", mad_dump_uint},
222	[IB_NOTICE_DATA_144_CAPMASK_F]  {BITSOFFS(128, 32), "NoticeDataTrap144CapMask", mad_dump_uint},
223
224	/*
225	 * NodeDescription fields:
226	 */
227	[IB_NODE_DESC_F]		{0, 64*8, "NodeDesc", mad_dump_string},
228
229	/*
230	 * Port counters
231	 */
232	[IB_PC_PORT_SELECT_F] 		{BITSOFFS(8, 8), "PortSelect", mad_dump_uint},
233	[IB_PC_COUNTER_SELECT_F] 	{BITSOFFS(16, 16), "CounterSelect", mad_dump_hex},
234	[IB_PC_ERR_SYM_F] 		{BITSOFFS(32, 16), "SymbolErrors", mad_dump_uint},
235	[IB_PC_LINK_RECOVERS_F] 	{BITSOFFS(48, 8), "LinkRecovers", mad_dump_uint},
236	[IB_PC_LINK_DOWNED_F] 		{BITSOFFS(56, 8), "LinkDowned", mad_dump_uint},
237	[IB_PC_ERR_RCV_F] 		{BITSOFFS(64, 16), "RcvErrors", mad_dump_uint},
238	[IB_PC_ERR_PHYSRCV_F] 		{BITSOFFS(80, 16), "RcvRemotePhysErrors", mad_dump_uint},
239	[IB_PC_ERR_SWITCH_REL_F]	{BITSOFFS(96, 16), "RcvSwRelayErrors", mad_dump_uint},
240	[IB_PC_XMT_DISCARDS_F] 		{BITSOFFS(112, 16), "XmtDiscards", mad_dump_uint},
241	[IB_PC_ERR_XMTCONSTR_F] 	{BITSOFFS(128, 8), "XmtConstraintErrors", mad_dump_uint},
242	[IB_PC_ERR_RCVCONSTR_F] 	{BITSOFFS(136, 8), "RcvConstraintErrors", mad_dump_uint},
243	[IB_PC_ERR_LOCALINTEG_F] 	{BITSOFFS(152, 4), "LinkIntegrityErrors", mad_dump_uint},
244	[IB_PC_ERR_EXCESS_OVR_F] 	{BITSOFFS(156, 4), "ExcBufOverrunErrors", mad_dump_uint},
245	[IB_PC_VL15_DROPPED_F] 		{BITSOFFS(176, 16), "VL15Dropped", mad_dump_uint},
246	[IB_PC_XMT_BYTES_F] 		{192, 32, "XmtData", mad_dump_uint},
247	[IB_PC_RCV_BYTES_F] 		{224, 32, "RcvData", mad_dump_uint},
248	[IB_PC_XMT_PKTS_F] 		{256, 32, "XmtPkts", mad_dump_uint},
249	[IB_PC_RCV_PKTS_F] 		{288, 32, "RcvPkts", mad_dump_uint},
250
251	/*
252	 * SMInfo
253	 */
254	[IB_SMINFO_GUID_F]		{0, 64, "SmInfoGuid", mad_dump_hex},
255	[IB_SMINFO_KEY_F]		{64, 64, "SmInfoKey", mad_dump_hex},
256	[IB_SMINFO_ACT_F]		{128, 32, "SmActivity", mad_dump_uint},
257	[IB_SMINFO_PRIO_F]		{BITSOFFS(160, 4), "SmPriority", mad_dump_uint},
258	[IB_SMINFO_STATE_F]		{BITSOFFS(164, 4), "SmState", mad_dump_uint},
259
260	/*
261	 * SA RMPP
262	 */
263	[IB_SA_RMPP_VERS_F]		{BE_OFFS(24*8+24, 8), "RmppVers", mad_dump_uint},
264	[IB_SA_RMPP_TYPE_F]		{BE_OFFS(24*8+16, 8), "RmppType", mad_dump_uint},
265	[IB_SA_RMPP_RESP_F]		{BE_OFFS(24*8+11, 5), "RmppResp", mad_dump_uint},
266	[IB_SA_RMPP_FLAGS_F]		{BE_OFFS(24*8+8, 3), "RmppFlags", mad_dump_hex},
267	[IB_SA_RMPP_STATUS_F]		{BE_OFFS(24*8+0, 8), "RmppStatus", mad_dump_hex},
268
269	/* data1 */
270	[IB_SA_RMPP_D1_F]		{28*8, 32, "RmppData1", mad_dump_hex},
271	[IB_SA_RMPP_SEGNUM_F]		{28*8, 32, "RmppSegNum", mad_dump_uint},
272	/* data2 */
273	[IB_SA_RMPP_D2_F]		{32*8, 32, "RmppData2", mad_dump_hex},
274	[IB_SA_RMPP_LEN_F]		{32*8, 32, "RmppPayload", mad_dump_uint},
275	[IB_SA_RMPP_NEWWIN_F]		{32*8, 32, "RmppNewWin", mad_dump_uint},
276
277	/*
278	 * SA Path rec
279	 */
280	[IB_SA_PR_DGID_F]		{64, 128, "PathRecDGid", mad_dump_array},
281	[IB_SA_PR_SGID_F]		{192, 128, "PathRecSGid", mad_dump_array},
282	[IB_SA_PR_DLID_F]		{BITSOFFS(320,16), "PathRecDLid", mad_dump_hex},
283	[IB_SA_PR_SLID_F]		{BITSOFFS(336,16), "PathRecSLid", mad_dump_hex},
284	[IB_SA_PR_NPATH_F]		{BITSOFFS(393,7), "PathRecNumPath", mad_dump_uint},
285
286	/*
287	 * SA Get Multi Path
288	 */
289	[IB_SA_MP_NPATH_F]		{BITSOFFS(41,7), "MultiPathNumPath", mad_dump_uint},
290	[IB_SA_MP_NSRC_F]		{BITSOFFS(120,8), "MultiPathNumSrc", mad_dump_uint},
291	[IB_SA_MP_NDEST_F]		{BITSOFFS(128,8), "MultiPathNumDest", mad_dump_uint},
292	[IB_SA_MP_GID0_F]		{192, 128, "MultiPathGid", mad_dump_array},
293
294	/*
295	 * MC Member rec
296	 */
297	[IB_SA_MCM_MGID_F]		{0, 128, "McastMemMGid", mad_dump_array},
298	[IB_SA_MCM_PORTGID_F]		{128, 128, "McastMemPortGid", mad_dump_array},
299	[IB_SA_MCM_QKEY_F]		{256, 32, "McastMemQkey", mad_dump_hex},
300	[IB_SA_MCM_MLID_F]		{BITSOFFS(288, 16), "McastMemMLid", mad_dump_hex},
301	[IB_SA_MCM_MTU_F]		{BITSOFFS(306, 6), "McastMemMTU", mad_dump_uint},
302	[IB_SA_MCM_TCLASS_F]		{BITSOFFS(312, 8), "McastMemTClass", mad_dump_uint},
303	[IB_SA_MCM_PKEY_F]		{BITSOFFS(320, 16), "McastMemPkey", mad_dump_uint},
304	[IB_SA_MCM_RATE_F]		{BITSOFFS(338, 6), "McastMemRate", mad_dump_uint},
305	[IB_SA_MCM_SL_F]		{BITSOFFS(352, 4), "McastMemSL", mad_dump_uint},
306	[IB_SA_MCM_FLOW_LABEL_F]	{BITSOFFS(356, 20), "McastMemFlowLbl", mad_dump_uint},
307	[IB_SA_MCM_JOIN_STATE_F]	{BITSOFFS(388, 4), "McastMemJoinState", mad_dump_uint},
308	[IB_SA_MCM_PROXY_JOIN_F]	{BITSOFFS(392, 1), "McastMemProxyJoin", mad_dump_uint},
309
310	/*
311	 * Service record
312	 */
313	[IB_SA_SR_ID_F]			{0, 64, "ServRecID", mad_dump_hex},
314	[IB_SA_SR_GID_F]		{64, 128, "ServRecGid", mad_dump_array},
315	[IB_SA_SR_PKEY_F]		{BITSOFFS(192, 16), "ServRecPkey", mad_dump_hex},
316	[IB_SA_SR_LEASE_F]		{224, 32, "ServRecLease", mad_dump_hex},
317	[IB_SA_SR_KEY_F]		{256, 128, "ServRecKey", mad_dump_hex},
318	[IB_SA_SR_NAME_F]		{384, 512, "ServRecName", mad_dump_string},
319	[IB_SA_SR_DATA_F]		{896, 512, "ServRecData", mad_dump_array},	/* ATS for example */
320
321	/*
322	 * ATS SM record - within SA_SR_DATA
323	 */
324	[IB_ATS_SM_NODE_ADDR_F]		{12*8, 32, "ATSNodeAddr", mad_dump_hex},
325	[IB_ATS_SM_MAGIC_KEY_F]		{BITSOFFS(16*8, 16), "ATSMagicKey", mad_dump_hex},
326	[IB_ATS_SM_NODE_TYPE_F]		{BITSOFFS(18*8, 16), "ATSNodeType", mad_dump_hex},
327	[IB_ATS_SM_NODE_NAME_F]		{32*8, 32*8, "ATSNodeName", mad_dump_string},
328
329	/*
330	 * SLTOVL MAPPING TABLE
331	 */
332	[IB_SLTOVL_MAPPING_TABLE_F]	{0, 64, "SLToVLMap", mad_dump_hex},
333
334	/*
335	 * VL ARBITRATION TABLE
336	 */
337	[IB_VL_ARBITRATION_TABLE_F]	{0, 512, "VLArbTbl", mad_dump_array},
338
339	/*
340	 * IB vendor classes range 2
341	 */
342	[IB_VEND2_OUI_F]		{BE_OFFS(36*8, 24), "OUI", mad_dump_array},
343	[IB_VEND2_DATA_F]		{40*8, (256-40)*8, "Vendor2Data", mad_dump_array},
344
345	/*
346	 * Extended port counters
347	 */
348	[IB_PC_EXT_PORT_SELECT_F]	{BITSOFFS(8, 8), "PortSelect", mad_dump_uint},
349	[IB_PC_EXT_COUNTER_SELECT_F]	{BITSOFFS(16, 16), "CounterSelect", mad_dump_hex},
350	[IB_PC_EXT_XMT_BYTES_F]		{64, 64, "PortXmitData", mad_dump_uint},
351	[IB_PC_EXT_RCV_BYTES_F]		{128, 64, "PortRcvData", mad_dump_uint},
352	[IB_PC_EXT_XMT_PKTS_F]		{192, 64, "PortXmitPkts", mad_dump_uint},
353	[IB_PC_EXT_RCV_PKTS_F]		{256, 64, "PortRcvPkts", mad_dump_uint},
354	[IB_PC_EXT_XMT_UPKTS_F]		{320, 64, "PortUnicastXmitPkts", mad_dump_uint},
355	[IB_PC_EXT_RCV_UPKTS_F]		{384, 64, "PortUnicastRcvPkts", mad_dump_uint},
356	[IB_PC_EXT_XMT_MPKTS_F]		{448, 64, "PortMulticastXmitPkts", mad_dump_uint},
357	[IB_PC_EXT_RCV_MPKTS_F]		{512, 64, "PortMulticastRcvPkts", mad_dump_uint},
358
359	/*
360	 * GUIDInfo fields
361	 */
362	[IB_GUID_GUID0_F]		{0, 64, "GUID0", mad_dump_hex},
363
364};
365
366void
367_set_field64(void *buf, int base_offs, ib_field_t *f, uint64_t val)
368{
369	uint64_t nval;
370
371	nval = htonll(val);
372	memcpy((char *)buf + base_offs + f->bitoffs / 8, &nval, sizeof(uint64_t));
373}
374
375uint64_t
376_get_field64(void *buf, int base_offs, ib_field_t *f)
377{
378	uint64_t val;
379	memcpy(&val, ((char *)buf + base_offs + f->bitoffs / 8), sizeof(uint64_t));
380	return ntohll(val);
381}
382
383void
384_set_field(void *buf, int base_offs, ib_field_t *f, uint32_t val)
385{
386	int prebits = (8 - (f->bitoffs & 7)) & 7;
387	int postbits = (f->bitoffs + f->bitlen) & 7;
388	int bytelen = f->bitlen / 8;
389	unsigned idx = base_offs + f->bitoffs / 8;
390	char *p = (char *)buf;
391
392	if (!bytelen && (f->bitoffs & 7) + f->bitlen < 8) {
393		p[3^idx] &= ~((((1 << f->bitlen) - 1)) << (f->bitoffs & 7));
394		p[3^idx] |= (val & ((1 << f->bitlen) - 1)) << (f->bitoffs & 7);
395		return;
396	}
397
398	if (prebits) {	/* val lsb in byte msb */
399		p[3^idx] &= (1 << (8 - prebits)) - 1;
400		p[3^idx++] |= (val & ((1 << prebits) - 1)) << (8 - prebits);
401		val >>= prebits;
402	}
403
404	/* BIG endian byte order */
405	for (; bytelen--; val >>= 8)
406		p[3^idx++] = val & 0xff;
407
408	if (postbits) {	/* val msb in byte lsb */
409		p[3^idx] &= ~((1 << postbits) - 1);
410		p[3^idx] |= val;
411	}
412}
413
414uint32_t
415_get_field(void *buf, int base_offs, ib_field_t *f)
416{
417	int prebits = (8 - (f->bitoffs & 7)) & 7;
418	int postbits = (f->bitoffs + f->bitlen) & 7;
419	int bytelen = f->bitlen / 8;
420	unsigned idx = base_offs + f->bitoffs / 8;
421	uint8_t *p = (uint8_t *)buf;
422	uint32_t val = 0, v = 0, i;
423
424	if (!bytelen && (f->bitoffs & 7) + f->bitlen < 8)
425		return (p[3^idx] >> (f->bitoffs & 7)) & ((1 << f->bitlen) - 1);
426
427	if (prebits)	/* val lsb from byte msb */
428		v = p[3^idx++] >> (8 - prebits);
429
430	if (postbits) {	/* val msb from byte lsb */
431		i = base_offs + (f->bitoffs + f->bitlen) / 8;
432		val = (p[3^i] & ((1 << postbits) - 1));
433	}
434
435	/* BIG endian byte order */
436	for (idx += bytelen - 1; bytelen--; idx--)
437		val = (val << 8) | p[3^idx];
438
439	return (val << prebits) | v;
440}
441
442/* field must be byte aligned */
443void
444_set_array(void *buf, int base_offs, ib_field_t *f, void *val)
445{
446	int bitoffs = f->bitoffs;
447
448	if (f->bitlen < 32)
449		bitoffs = BE_TO_BITSOFFS(bitoffs, f->bitlen);
450
451	memcpy((uint8_t *)buf + base_offs + bitoffs / 8, val, f->bitlen / 8);
452}
453
454void
455_get_array(void *buf, int base_offs, ib_field_t *f, void *val)
456{
457	int bitoffs = f->bitoffs;
458
459	if (f->bitlen < 32)
460		bitoffs = BE_TO_BITSOFFS(bitoffs, f->bitlen);
461
462	memcpy(val, (uint8_t *)buf + base_offs + bitoffs / 8, f->bitlen / 8);
463}
464