1/*
2 * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
3 * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
4 * Copyright (c) 2009-2011 Mellanox Technologies LTD.  All rights reserved.
5 * Copyright (c) 2009 HNR Consulting.  All rights reserved.
6 *
7 * This software is available to you under a choice of one of two
8 * licenses.  You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
12 *
13 *     Redistribution and use in source and binary forms, with or
14 *     without modification, are permitted provided that the following
15 *     conditions are met:
16 *
17 *      - Redistributions of source code must retain the above
18 *        copyright notice, this list of conditions and the following
19 *        disclaimer.
20 *
21 *      - Redistributions in binary form must reproduce the above
22 *        copyright notice, this list of conditions and the following
23 *        disclaimer in the documentation and/or other materials
24 *        provided with the distribution.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 * SOFTWARE.
34 *
35 */
36
37#if HAVE_CONFIG_H
38#  include <config.h>
39#endif				/* HAVE_CONFIG_H */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44
45#include <infiniband/mad.h>
46
47void mad_dump_int(char *buf, int bufsz, void *val, int valsz)
48{
49	switch (valsz) {
50	case 1:
51		snprintf(buf, bufsz, "%d", *(uint32_t *) val & 0xff);
52		break;
53	case 2:
54		snprintf(buf, bufsz, "%d", *(uint32_t *) val & 0xffff);
55		break;
56	case 3:
57	case 4:
58		snprintf(buf, bufsz, "%d", *(uint32_t *) val);
59		break;
60	case 5:
61	case 6:
62	case 7:
63	case 8:
64		snprintf(buf, bufsz, "%" PRIu64, *(uint64_t *) val);
65		break;
66	default:
67		IBWARN("bad int sz %d", valsz);
68		buf[0] = 0;
69	}
70}
71
72void mad_dump_uint(char *buf, int bufsz, void *val, int valsz)
73{
74	switch (valsz) {
75	case 1:
76		snprintf(buf, bufsz, "%u", *(uint32_t *) val & 0xff);
77		break;
78	case 2:
79		snprintf(buf, bufsz, "%u", *(uint32_t *) val & 0xffff);
80		break;
81	case 3:
82	case 4:
83		snprintf(buf, bufsz, "%u", *(uint32_t *) val);
84		break;
85	case 5:
86	case 6:
87	case 7:
88	case 8:
89		snprintf(buf, bufsz, "%" PRIu64, *(uint64_t *) val);
90		break;
91	default:
92		IBWARN("bad int sz %u", valsz);
93		buf[0] = 0;
94	}
95}
96
97void mad_dump_hex(char *buf, int bufsz, void *val, int valsz)
98{
99	switch (valsz) {
100	case 1:
101		snprintf(buf, bufsz, "0x%02x", *(uint32_t *) val & 0xff);
102		break;
103	case 2:
104		snprintf(buf, bufsz, "0x%04x", *(uint32_t *) val & 0xffff);
105		break;
106	case 3:
107		snprintf(buf, bufsz, "0x%06x", *(uint32_t *) val & 0xffffff);
108		break;
109	case 4:
110		snprintf(buf, bufsz, "0x%08x", *(uint32_t *) val);
111		break;
112	case 5:
113		snprintf(buf, bufsz, "0x%010" PRIx64,
114			 *(uint64_t *) val & (uint64_t) 0xffffffffffULL);
115		break;
116	case 6:
117		snprintf(buf, bufsz, "0x%012" PRIx64,
118			 *(uint64_t *) val & (uint64_t) 0xffffffffffffULL);
119		break;
120	case 7:
121		snprintf(buf, bufsz, "0x%014" PRIx64,
122			 *(uint64_t *) val & (uint64_t) 0xffffffffffffffULL);
123		break;
124	case 8:
125		snprintf(buf, bufsz, "0x%016" PRIx64, *(uint64_t *) val);
126		break;
127	default:
128		IBWARN("bad int sz %d", valsz);
129		buf[0] = 0;
130	}
131}
132
133void mad_dump_rhex(char *buf, int bufsz, void *val, int valsz)
134{
135	switch (valsz) {
136	case 1:
137		snprintf(buf, bufsz, "%02x", *(uint32_t *) val & 0xff);
138		break;
139	case 2:
140		snprintf(buf, bufsz, "%04x", *(uint32_t *) val & 0xffff);
141		break;
142	case 3:
143		snprintf(buf, bufsz, "%06x", *(uint32_t *) val & 0xffffff);
144		break;
145	case 4:
146		snprintf(buf, bufsz, "%08x", *(uint32_t *) val);
147		break;
148	case 5:
149		snprintf(buf, bufsz, "%010" PRIx64,
150			 *(uint64_t *) val & (uint64_t) 0xffffffffffULL);
151		break;
152	case 6:
153		snprintf(buf, bufsz, "%012" PRIx64,
154			 *(uint64_t *) val & (uint64_t) 0xffffffffffffULL);
155		break;
156	case 7:
157		snprintf(buf, bufsz, "%014" PRIx64,
158			 *(uint64_t *) val & (uint64_t) 0xffffffffffffffULL);
159		break;
160	case 8:
161		snprintf(buf, bufsz, "%016" PRIx64, *(uint64_t *) val);
162		break;
163	default:
164		IBWARN("bad int sz %d", valsz);
165		buf[0] = 0;
166	}
167}
168
169void mad_dump_linkwidth(char *buf, int bufsz, void *val, int valsz)
170{
171	int width = *(int *)val;
172
173	switch (width) {
174	case 1:
175		snprintf(buf, bufsz, "1X");
176		break;
177	case 2:
178		snprintf(buf, bufsz, "4X");
179		break;
180	case 4:
181		snprintf(buf, bufsz, "8X");
182		break;
183	case 8:
184		snprintf(buf, bufsz, "12X");
185		break;
186	case 16:
187		snprintf(buf, bufsz, "2X");
188		break;
189	default:
190		IBWARN("bad width %d", width);
191		snprintf(buf, bufsz, "undefined (%d)", width);
192		break;
193	}
194}
195
196static void dump_linkwidth(char *buf, int bufsz, int width)
197{
198	int n = 0;
199
200	if (width & 0x1)
201		n += snprintf(buf + n, bufsz - n, "1X or ");
202	if (n < bufsz && (width & 0x2))
203		n += snprintf(buf + n, bufsz - n, "4X or ");
204	if (n < bufsz && (width & 0x4))
205		n += snprintf(buf + n, bufsz - n, "8X or ");
206	if (n < bufsz && (width & 0x8))
207		n += snprintf(buf + n, bufsz - n, "12X or ");
208	if (n < bufsz && (width & 0x10))
209		n += snprintf(buf + n, bufsz - n, "2X or ");
210
211	if (n >= bufsz)
212		return;
213	else if (width == 0 || (width >> 5))
214		snprintf(buf + n, bufsz - n, "undefined (%d)", width);
215	else if (bufsz > 3)
216		buf[n - 4] = '\0';
217}
218
219void mad_dump_linkwidthsup(char *buf, int bufsz, void *val, int valsz)
220{
221	int width = *(int *)val;
222
223	dump_linkwidth(buf, bufsz, width);
224
225	switch (width) {
226	case 1:
227	case 3:
228	case 7:
229	case 11:
230	case 15:
231	case 17:
232	case 19:
233	case 23:
234	case 27:
235	case 31:
236		break;
237
238	default:
239		if (!(width >> 5))
240			snprintf(buf + strlen(buf), bufsz - strlen(buf),
241				 " (IBA extension)");
242		break;
243	}
244}
245
246void mad_dump_linkwidthen(char *buf, int bufsz, void *val, int valsz)
247{
248	int width = *(int *)val;
249
250	dump_linkwidth(buf, bufsz, width);
251}
252
253void mad_dump_linkspeed(char *buf, int bufsz, void *val, int valsz)
254{
255	int speed = *(int *)val;
256
257	switch (speed) {
258	case 0:
259		snprintf(buf, bufsz, "Extended speed");
260		break;
261	case 1:
262		snprintf(buf, bufsz, "2.5 Gbps");
263		break;
264	case 2:
265		snprintf(buf, bufsz, "5.0 Gbps");
266		break;
267	case 4:
268		snprintf(buf, bufsz, "10.0 Gbps");
269		break;
270	default:
271		snprintf(buf, bufsz, "undefined (%d)", speed);
272		break;
273	}
274}
275
276static void dump_linkspeed(char *buf, int bufsz, int speed)
277{
278	int n = 0;
279
280	if (speed & 0x1)
281		n += snprintf(buf + n, bufsz - n, "2.5 Gbps or ");
282	if (n < bufsz && (speed & 0x2))
283		n += snprintf(buf + n, bufsz - n, "5.0 Gbps or ");
284	if (n < bufsz && (speed & 0x4))
285		n += snprintf(buf + n, bufsz - n, "10.0 Gbps or ");
286
287	if (n >= bufsz)
288		return;
289	else if (speed == 0 || (speed >> 3)) {
290		n += snprintf(buf + n, bufsz - n, "undefined (%d)", speed);
291		if (n >= bufsz)
292			return;
293	} else if (bufsz > 3) {
294		buf[n - 4] = '\0';
295		n -= 4;
296	}
297
298	switch (speed) {
299	case 1:
300	case 3:
301	case 5:
302	case 7:
303		break;
304	default:
305		if (!(speed >> 3))
306			snprintf(buf + n, bufsz - n, " (IBA extension)");
307		break;
308	}
309}
310
311void mad_dump_linkspeedsup(char *buf, int bufsz, void *val, int valsz)
312{
313	int speed = *(int *)val;
314
315	dump_linkspeed(buf, bufsz, speed);
316}
317
318void mad_dump_linkspeeden(char *buf, int bufsz, void *val, int valsz)
319{
320	int speed = *(int *)val;
321
322	dump_linkspeed(buf, bufsz, speed);
323}
324
325void mad_dump_linkspeedext(char *buf, int bufsz, void *val, int valsz)
326{
327	int speed = *(int *)val;
328
329	switch (speed) {
330	case 0:
331		snprintf(buf, bufsz, "No Extended Speed");
332		break;
333	case 1:
334		snprintf(buf, bufsz, "14.0625 Gbps");
335		break;
336	case 2:
337		snprintf(buf, bufsz, "25.78125 Gbps");
338		break;
339	default:
340		snprintf(buf, bufsz, "undefined (%d)", speed);
341		break;
342	}
343}
344
345static void dump_linkspeedext(char *buf, int bufsz, int speed)
346{
347	int n = 0;
348
349	if (speed == 0) {
350		sprintf(buf, "%d", speed);
351		return;
352	}
353
354	if (speed & 0x1)
355		n += snprintf(buf + n, bufsz - n, "14.0625 Gbps or ");
356	if (n < bufsz && speed & 0x2)
357		n += snprintf(buf + n, bufsz - n, "25.78125 Gbps or ");
358	if (n >= bufsz) {
359		if (bufsz > 3)
360			buf[n - 4] = '\0';
361		return;
362	}
363
364	if (speed >> 2) {
365		n += snprintf(buf + n, bufsz - n, "undefined (%d)", speed);
366		return;
367	} else if (bufsz > 3)
368		buf[n - 4] = '\0';
369}
370
371void mad_dump_linkspeedextsup(char *buf, int bufsz, void *val, int valsz)
372{
373	int speed = *(int *)val;
374
375	dump_linkspeedext(buf, bufsz, speed);
376}
377
378void mad_dump_linkspeedexten(char *buf, int bufsz, void *val, int valsz)
379{
380	int speed = *(int *)val;
381
382	if (speed == 30) {
383		sprintf(buf, "%s", "Extended link speeds disabled");
384		return;
385	}
386	dump_linkspeedext(buf, bufsz, speed);
387}
388
389void mad_dump_portstate(char *buf, int bufsz, void *val, int valsz)
390{
391	int state = *(int *)val;
392
393	switch (state) {
394	case 0:
395		snprintf(buf, bufsz, "NoChange");
396		break;
397	case 1:
398		snprintf(buf, bufsz, "Down");
399		break;
400	case 2:
401		snprintf(buf, bufsz, "Initialize");
402		break;
403	case 3:
404		snprintf(buf, bufsz, "Armed");
405		break;
406	case 4:
407		snprintf(buf, bufsz, "Active");
408		break;
409	default:
410		snprintf(buf, bufsz, "?(%d)", state);
411	}
412}
413
414void mad_dump_linkdowndefstate(char *buf, int bufsz, void *val, int valsz)
415{
416	int state = *(int *)val;
417
418	switch (state) {
419	case 0:
420		snprintf(buf, bufsz, "NoChange");
421		break;
422	case 1:
423		snprintf(buf, bufsz, "Sleep");
424		break;
425	case 2:
426		snprintf(buf, bufsz, "Polling");
427		break;
428	default:
429		snprintf(buf, bufsz, "?(%d)", state);
430		break;
431	}
432}
433
434void mad_dump_physportstate(char *buf, int bufsz, void *val, int valsz)
435{
436	int state = *(int *)val;
437
438	switch (state) {
439	case 0:
440		snprintf(buf, bufsz, "NoChange");
441		break;
442	case 1:
443		snprintf(buf, bufsz, "Sleep");
444		break;
445	case 2:
446		snprintf(buf, bufsz, "Polling");
447		break;
448	case 3:
449		snprintf(buf, bufsz, "Disabled");
450		break;
451	case 4:
452		snprintf(buf, bufsz, "PortConfigurationTraining");
453		break;
454	case 5:
455		snprintf(buf, bufsz, "LinkUp");
456		break;
457	case 6:
458		snprintf(buf, bufsz, "LinkErrorRecovery");
459		break;
460	case 7:
461		snprintf(buf, bufsz, "PhyTest");
462		break;
463	default:
464		snprintf(buf, bufsz, "?(%d)", state);
465	}
466}
467
468void mad_dump_mtu(char *buf, int bufsz, void *val, int valsz)
469{
470	int mtu = *(int *)val;
471
472	switch (mtu) {
473	case 1:
474		snprintf(buf, bufsz, "256");
475		break;
476	case 2:
477		snprintf(buf, bufsz, "512");
478		break;
479	case 3:
480		snprintf(buf, bufsz, "1024");
481		break;
482	case 4:
483		snprintf(buf, bufsz, "2048");
484		break;
485	case 5:
486		snprintf(buf, bufsz, "4096");
487		break;
488	default:
489		snprintf(buf, bufsz, "?(%d)", mtu);
490	}
491}
492
493void mad_dump_vlcap(char *buf, int bufsz, void *val, int valsz)
494{
495	int vlcap = *(int *)val;
496
497	switch (vlcap) {
498	case 1:
499		snprintf(buf, bufsz, "VL0");
500		break;
501	case 2:
502		snprintf(buf, bufsz, "VL0-1");
503		break;
504	case 3:
505		snprintf(buf, bufsz, "VL0-3");
506		break;
507	case 4:
508		snprintf(buf, bufsz, "VL0-7");
509		break;
510	case 5:
511		snprintf(buf, bufsz, "VL0-14");
512		break;
513	default:
514		snprintf(buf, bufsz, "?(%d)", vlcap);
515	}
516}
517
518void mad_dump_opervls(char *buf, int bufsz, void *val, int valsz)
519{
520	int opervls = *(int *)val;
521
522	switch (opervls) {
523	case 0:
524		snprintf(buf, bufsz, "No change");
525		break;
526	case 1:
527		snprintf(buf, bufsz, "VL0");
528		break;
529	case 2:
530		snprintf(buf, bufsz, "VL0-1");
531		break;
532	case 3:
533		snprintf(buf, bufsz, "VL0-3");
534		break;
535	case 4:
536		snprintf(buf, bufsz, "VL0-7");
537		break;
538	case 5:
539		snprintf(buf, bufsz, "VL0-14");
540		break;
541	default:
542		snprintf(buf, bufsz, "?(%d)", opervls);
543	}
544}
545
546void mad_dump_portcapmask(char *buf, int bufsz, void *val, int valsz)
547{
548	unsigned mask = *(unsigned *)val;
549	char *s = buf;
550
551	s += sprintf(s, "0x%x\n", mask);
552	if (mask & (1 << 1))
553		s += sprintf(s, "\t\t\t\tIsSM\n");
554	if (mask & (1 << 2))
555		s += sprintf(s, "\t\t\t\tIsNoticeSupported\n");
556	if (mask & (1 << 3))
557		s += sprintf(s, "\t\t\t\tIsTrapSupported\n");
558	if (mask & (1 << 4))
559		s += sprintf(s, "\t\t\t\tIsOptionalIPDSupported\n");
560	if (mask & (1 << 5))
561		s += sprintf(s, "\t\t\t\tIsAutomaticMigrationSupported\n");
562	if (mask & (1 << 6))
563		s += sprintf(s, "\t\t\t\tIsSLMappingSupported\n");
564	if (mask & (1 << 7))
565		s += sprintf(s, "\t\t\t\tIsMKeyNVRAM\n");
566	if (mask & (1 << 8))
567		s += sprintf(s, "\t\t\t\tIsPKeyNVRAM\n");
568	if (mask & (1 << 9))
569		s += sprintf(s, "\t\t\t\tIsLedInfoSupported\n");
570	if (mask & (1 << 10))
571		s += sprintf(s, "\t\t\t\tIsSMdisabled\n");
572	if (mask & (1 << 11))
573		s += sprintf(s, "\t\t\t\tIsSystemImageGUIDsupported\n");
574	if (mask & (1 << 12))
575		s += sprintf(s,
576			     "\t\t\t\tIsPkeySwitchExternalPortTrapSupported\n");
577	if (mask & (1 << 14))
578		s += sprintf(s, "\t\t\t\tIsExtendedSpeedsSupported\n");
579	if (mask & (1 << 15))
580		s += sprintf(s, "\t\t\t\tIsCapabilityMask2Supported\n");
581	if (mask & (1 << 16))
582		s += sprintf(s, "\t\t\t\tIsCommunicatonManagementSupported\n");
583	if (mask & (1 << 17))
584		s += sprintf(s, "\t\t\t\tIsSNMPTunnelingSupported\n");
585	if (mask & (1 << 18))
586		s += sprintf(s, "\t\t\t\tIsReinitSupported\n");
587	if (mask & (1 << 19))
588		s += sprintf(s, "\t\t\t\tIsDeviceManagementSupported\n");
589	if (mask & (1 << 20))
590		s += sprintf(s, "\t\t\t\tIsVendorClassSupported\n");
591	if (mask & (1 << 21))
592		s += sprintf(s, "\t\t\t\tIsDRNoticeSupported\n");
593	if (mask & (1 << 22))
594		s += sprintf(s, "\t\t\t\tIsCapabilityMaskNoticeSupported\n");
595	if (mask & (1 << 23))
596		s += sprintf(s, "\t\t\t\tIsBootManagementSupported\n");
597	if (mask & (1 << 24))
598		s += sprintf(s, "\t\t\t\tIsLinkRoundTripLatencySupported\n");
599	if (mask & (1 << 25))
600		s += sprintf(s, "\t\t\t\tIsClientRegistrationSupported\n");
601	if (mask & (1 << 26))
602		s += sprintf(s, "\t\t\t\tIsOtherLocalChangesNoticeSupported\n");
603	if (mask & (1 << 27))
604		s += sprintf(s,
605			     "\t\t\t\tIsLinkSpeedWidthPairsTableSupported\n");
606	if (mask & (1 << 28))
607		s += sprintf(s, "\t\t\t\tIsVendorSpecificMadsTableSupported\n");
608	if (mask & (1 << 29))
609		s += sprintf(s, "\t\t\t\tIsMcastPkeyTrapSuppressionSupported\n");
610	if (mask & (1 << 30))
611		s += sprintf(s, "\t\t\t\tIsMulticastFDBTopSupported\n");
612	if (mask & (1 << 31))
613		s += sprintf(s, "\t\t\t\tIsHierarchyInfoSupported\n");
614
615	if (s != buf)
616		*(--s) = 0;
617}
618
619void mad_dump_portcapmask2(char *buf, int bufsz, void *val, int valsz)
620{
621	int mask = *(int *)val;
622	char *s = buf;
623
624	s += sprintf(s, "0x%x\n", mask);
625	if (mask & (1 << 0))
626		s += sprintf(s, "\t\t\t\tIsSetNodeDescriptionSupported\n");
627	if (mask & (1 << 1))
628		s += sprintf(s, "\t\t\t\tIsPortInfoExtendedSupported\n");
629	if (mask & (1 << 2))
630		s += sprintf(s, "\t\t\t\tIsVirtualizationSupported\n");
631	if (mask & (1 << 3))
632		s += sprintf(s, "\t\t\t\tIsSwitchPortStateTableSupported\n");
633	if (mask & (1 << 4))
634		s += sprintf(s, "\t\t\t\tIsLinkWidth2xSupported\n");
635
636	if (s != buf)
637		*(--s) = 0;
638}
639
640void mad_dump_bitfield(char *buf, int bufsz, void *val, int valsz)
641{
642	snprintf(buf, bufsz, "0x%x", *(uint32_t *) val);
643}
644
645void mad_dump_array(char *buf, int bufsz, void *val, int valsz)
646{
647	uint8_t *p = val, *e;
648	char *s = buf;
649
650	if (bufsz < valsz * 2)
651		valsz = bufsz / 2;
652
653	for (p = val, e = p + valsz; p < e; p++, s += 2)
654		sprintf(s, "%02x", *p);
655}
656
657void mad_dump_string(char *buf, int bufsz, void *val, int valsz)
658{
659	if (bufsz < valsz)
660		valsz = bufsz;
661
662	snprintf(buf, valsz, "'%s'", (char *)val);
663}
664
665void mad_dump_node_type(char *buf, int bufsz, void *val, int valsz)
666{
667	int nodetype = *(int *)val;
668
669	switch (nodetype) {
670	case 1:
671		snprintf(buf, bufsz, "Channel Adapter");
672		break;
673	case 2:
674		snprintf(buf, bufsz, "Switch");
675		break;
676	case 3:
677		snprintf(buf, bufsz, "Router");
678		break;
679	default:
680		snprintf(buf, bufsz, "?(%d)?", nodetype);
681		break;
682	}
683}
684
685#define IB_MAX_NUM_VLS 16
686#define IB_MAX_NUM_VLS_TO_U8 ((IB_MAX_NUM_VLS)/2)
687
688typedef struct _ib_slvl_table {
689	uint8_t vl_by_sl_num[IB_MAX_NUM_VLS_TO_U8];
690} ib_slvl_table_t;
691
692static inline void ib_slvl_get_i(ib_slvl_table_t * tbl, int i, uint8_t * vl)
693{
694	*vl = (tbl->vl_by_sl_num[i >> 1] >> ((!(i & 1)) << 2)) & 0xf;
695}
696
697#define IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK 32
698
699typedef struct _ib_vl_arb_table {
700	struct {
701		uint8_t res_vl;
702		uint8_t weight;
703	} vl_entry[IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK];
704} ib_vl_arb_table_t;
705
706static inline void ib_vl_arb_get_vl(uint8_t res_vl, uint8_t * const vl)
707{
708	*vl = res_vl & 0x0F;
709}
710
711void mad_dump_sltovl(char *buf, int bufsz, void *val, int valsz)
712{
713	ib_slvl_table_t *p_slvl_tbl = val;
714	uint8_t vl;
715	int i, n = 0;
716	n = snprintf(buf, bufsz, "|");
717	for (i = 0; i < 16; i++) {
718		ib_slvl_get_i(p_slvl_tbl, i, &vl);
719		n += snprintf(buf + n, bufsz - n, "%2u|", vl);
720		if (n >= bufsz)
721			break;
722	}
723	snprintf(buf + n, bufsz - n, "\n");
724}
725
726void mad_dump_vlarbitration(char *buf, int bufsz, void *val, int num)
727{
728	ib_vl_arb_table_t *p_vla_tbl = val;
729	int i, n;
730	uint8_t vl;
731
732	num /= sizeof(p_vla_tbl->vl_entry[0]);
733
734	n = snprintf(buf, bufsz, "\nVL    : |");
735	if (n >= bufsz)
736		return;
737	for (i = 0; i < num; i++) {
738		ib_vl_arb_get_vl(p_vla_tbl->vl_entry[i].res_vl, &vl);
739		n += snprintf(buf + n, bufsz - n, "0x%-2X|", vl);
740		if (n >= bufsz)
741			return;
742	}
743
744	n += snprintf(buf + n, bufsz - n, "\nWEIGHT: |");
745	if (n >= bufsz)
746		return;
747	for (i = 0; i < num; i++) {
748		n += snprintf(buf + n, bufsz - n, "0x%-2X|",
749			      p_vla_tbl->vl_entry[i].weight);
750		if (n >= bufsz)
751			return;
752	}
753
754	snprintf(buf + n, bufsz - n, "\n");
755}
756
757static int _dump_fields(char *buf, int bufsz, void *data, int start, int end)
758{
759	char val[64];
760	char *s = buf;
761	int n, field;
762
763	for (field = start; field < end && bufsz > 0; field++) {
764		mad_decode_field(data, field, val);
765		if (!mad_dump_field(field, s, bufsz-1, val))
766			return -1;
767		n = strlen(s);
768		s += n;
769		*s++ = '\n';
770		*s = 0;
771		n++;
772		bufsz -= n;
773	}
774
775	return (int)(s - buf);
776}
777
778void mad_dump_fields(char *buf, int bufsz, void *val, int valsz, int start,
779		     int end)
780{
781	_dump_fields(buf, bufsz, val, start, end);
782}
783
784void mad_dump_nodedesc(char *buf, int bufsz, void *val, int valsz)
785{
786	strncpy(buf, val, bufsz);
787
788	if (valsz < bufsz)
789		buf[valsz] = 0;
790}
791
792void mad_dump_nodeinfo(char *buf, int bufsz, void *val, int valsz)
793{
794	_dump_fields(buf, bufsz, val, IB_NODE_FIRST_F, IB_NODE_LAST_F);
795}
796
797void mad_dump_portinfo(char *buf, int bufsz, void *val, int valsz)
798{
799	int cnt;
800
801	cnt = _dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F);
802	if (cnt < 0)
803		return;
804
805	_dump_fields(buf + cnt, bufsz - cnt, val,
806		     IB_PORT_CAPMASK2_F, IB_PORT_LINK_SPEED_EXT_LAST_F);
807}
808
809void mad_dump_portstates(char *buf, int bufsz, void *val, int valsz)
810{
811	_dump_fields(buf, bufsz, val, IB_PORT_STATE_F, IB_PORT_LINK_DOWN_DEF_F);
812}
813
814void mad_dump_switchinfo(char *buf, int bufsz, void *val, int valsz)
815{
816	_dump_fields(buf, bufsz, val, IB_SW_FIRST_F, IB_SW_LAST_F);
817}
818
819void mad_dump_perfcounters(char *buf, int bufsz, void *val, int valsz)
820{
821	int cnt, cnt2;
822
823	cnt = _dump_fields(buf, bufsz, val,
824			   IB_PC_FIRST_F, IB_PC_VL15_DROPPED_F);
825	if (cnt < 0)
826		return;
827
828	cnt2 = _dump_fields(buf + cnt, bufsz - cnt, val,
829			    IB_PC_QP1_DROP_F, IB_PC_QP1_DROP_F + 1);
830	if (cnt2 < 0)
831		return;
832
833	_dump_fields(buf + cnt + cnt2, bufsz - cnt - cnt2, val,
834		     IB_PC_VL15_DROPPED_F, IB_PC_LAST_F);
835}
836
837void mad_dump_perfcounters_ext(char *buf, int bufsz, void *val, int valsz)
838{
839	int cnt;
840
841	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_FIRST_F, IB_PC_EXT_LAST_F);
842	if (cnt < 0)
843		return;
844
845	 _dump_fields(buf + cnt, bufsz - cnt, val,
846		      IB_PC_EXT_COUNTER_SELECT2_F, IB_PC_EXT_ERR_LAST_F);
847}
848
849void mad_dump_perfcounters_xmt_sl(char *buf, int bufsz, void *val, int valsz)
850{
851	int cnt;
852
853	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
854			   IB_PC_EXT_XMT_BYTES_F);
855	if (cnt < 0)
856		return;
857
858	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMT_DATA_SL_FIRST_F,
859		     IB_PC_XMT_DATA_SL_LAST_F);
860}
861
862void mad_dump_perfcounters_rcv_sl(char *buf, int bufsz, void *val, int valsz)
863{
864	int cnt;
865
866	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
867			   IB_PC_EXT_XMT_BYTES_F);
868	if (cnt < 0)
869		return;
870
871	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_DATA_SL_FIRST_F,
872		     IB_PC_RCV_DATA_SL_LAST_F);
873}
874
875void mad_dump_perfcounters_xmt_disc(char *buf, int bufsz, void *val, int valsz)
876{
877	int cnt;
878
879	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
880			   IB_PC_EXT_XMT_BYTES_F);
881	if (cnt < 0)
882		return;
883
884	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMT_INACT_DISC_F,
885		     IB_PC_XMT_DISC_LAST_F);
886}
887
888void mad_dump_perfcounters_rcv_err(char *buf, int bufsz, void *val, int valsz)
889{
890	int cnt;
891
892	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
893			   IB_PC_EXT_XMT_BYTES_F);
894	if (cnt < 0)
895		return;
896
897	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_LOCAL_PHY_ERR_F,
898		     IB_PC_RCV_ERR_LAST_F);
899}
900
901void mad_dump_portsamples_control(char *buf, int bufsz, void *val, int valsz)
902{
903	_dump_fields(buf, bufsz, val, IB_PSC_OPCODE_F, IB_PSC_LAST_F);
904}
905
906void mad_dump_port_ext_speeds_counters_rsfec_active(char *buf, int bufsz,
907						    void *val, int valsz)
908{
909	_dump_fields(buf, bufsz, val, IB_PESC_RSFEC_PORT_SELECT_F,
910		     IB_PESC_RSFEC_LAST_F);
911}
912
913void mad_dump_port_ext_speeds_counters(char *buf, int bufsz, void *val, int valsz)
914{
915	_dump_fields(buf, bufsz, val, IB_PESC_PORT_SELECT_F, IB_PESC_LAST_F);
916}
917
918void mad_dump_perfcounters_port_op_rcv_counters(char *buf, int bufsz, void *val, int valsz)
919{
920	int cnt;
921
922	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
923			   IB_PC_EXT_XMT_BYTES_F);
924	if (cnt < 0)
925		return;
926
927	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F,
928		     IB_PC_PORT_OP_RCV_COUNTERS_LAST_F);
929}
930
931void mad_dump_perfcounters_port_flow_ctl_counters(char *buf, int bufsz, void *val, int valsz)
932{
933	int cnt;
934
935	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
936			   IB_PC_EXT_XMT_BYTES_F);
937	if (cnt < 0)
938		return;
939
940	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F,
941		     IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F);
942}
943
944void mad_dump_perfcounters_port_vl_op_packet(char *buf, int bufsz, void *val, int valsz)
945{
946	int cnt;
947
948	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
949			   IB_PC_EXT_XMT_BYTES_F);
950	if (cnt < 0)
951		return;
952
953	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_OP_PACKETS_FIRST_F,
954		     IB_PC_PORT_VL_OP_PACKETS_LAST_F);
955}
956
957void mad_dump_perfcounters_port_vl_op_data(char *buf, int bufsz, void *val, int valsz)
958{
959	int cnt;
960
961	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
962			   IB_PC_EXT_XMT_BYTES_F);
963	if (cnt < 0)
964		return;
965
966	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_OP_DATA_FIRST_F,
967		     IB_PC_PORT_VL_OP_DATA_LAST_F);
968}
969
970void mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors(char *buf, int bufsz, void *val, int valsz)
971{
972	int cnt;
973
974	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
975			   IB_PC_EXT_XMT_BYTES_F);
976	if (cnt < 0)
977		return;
978
979	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
980		     IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F);
981}
982
983void mad_dump_perfcounters_port_vl_xmit_wait_counters(char *buf, int bufsz, void *val, int valsz)
984{
985	int cnt;
986
987	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
988			   IB_PC_EXT_XMT_BYTES_F);
989	if (cnt < 0)
990		return;
991
992	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
993		     IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F);
994}
995
996void mad_dump_perfcounters_sw_port_vl_congestion(char *buf, int bufsz, void *val, int valsz)
997{
998	int cnt;
999
1000	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
1001			   IB_PC_EXT_XMT_BYTES_F);
1002	if (cnt < 0)
1003		return;
1004
1005	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SW_PORT_VL_CONGESTION_FIRST_F,
1006		     IB_PC_SW_PORT_VL_CONGESTION_LAST_F);
1007}
1008
1009void mad_dump_perfcounters_rcv_con_ctrl(char *buf, int bufsz, void *val, int valsz)
1010{
1011	int cnt;
1012
1013	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
1014			   IB_PC_EXT_XMT_BYTES_F);
1015	if (cnt < 0)
1016		return;
1017
1018	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_CON_CTRL_FIRST_F,
1019		     IB_PC_RCV_CON_CTRL_LAST_F);
1020}
1021
1022
1023void mad_dump_perfcounters_sl_rcv_fecn(char *buf, int bufsz, void *val, int valsz)
1024{
1025	int cnt;
1026
1027	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
1028			   IB_PC_EXT_XMT_BYTES_F);
1029	if (cnt < 0)
1030		return;
1031
1032	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SL_RCV_FECN_FIRST_F,
1033		     IB_PC_SL_RCV_FECN_LAST_F);
1034}
1035
1036void mad_dump_perfcounters_sl_rcv_becn(char *buf, int bufsz, void *val, int valsz)
1037{
1038	int cnt;
1039
1040	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
1041			   IB_PC_EXT_XMT_BYTES_F);
1042	if (cnt < 0)
1043		return;
1044
1045	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SL_RCV_BECN_FIRST_F,
1046		     IB_PC_SL_RCV_BECN_LAST_F);
1047}
1048
1049void mad_dump_perfcounters_xmit_con_ctrl(char *buf, int bufsz, void *val, int valsz)
1050{
1051	int cnt;
1052
1053	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
1054			   IB_PC_EXT_XMT_BYTES_F);
1055	if (cnt < 0)
1056		return;
1057
1058	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMIT_CON_CTRL_FIRST_F,
1059		     IB_PC_XMIT_CON_CTRL_LAST_F);
1060}
1061
1062void mad_dump_perfcounters_vl_xmit_time_cong(char *buf, int bufsz, void *val, int valsz)
1063{
1064	int cnt;
1065
1066	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
1067			   IB_PC_EXT_XMT_BYTES_F);
1068	if (cnt < 0)
1069		return;
1070
1071	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_VL_XMIT_TIME_CONG_FIRST_F,
1072		     IB_PC_VL_XMIT_TIME_CONG_LAST_F);
1073}
1074
1075void mad_dump_mlnx_ext_port_info(char *buf, int bufsz, void *val, int valsz)
1076{
1077	_dump_fields(buf, bufsz, val, IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
1078		     IB_MLNX_EXT_PORT_LAST_F);
1079}
1080
1081void mad_dump_portsamples_result(char *buf, int bufsz, void *val, int valsz)
1082{
1083	_dump_fields(buf, bufsz, val, IB_PSR_TAG_F, IB_PSR_LAST_F);
1084}
1085
1086void mad_dump_cc_congestioninfo(char *buf, int bufsz, void *val, int valsz)
1087{
1088	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_INFO_FIRST_F,
1089		     IB_CC_CONGESTION_INFO_LAST_F);
1090}
1091
1092void mad_dump_cc_congestionkeyinfo(char *buf, int bufsz, void *val, int valsz)
1093{
1094	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_KEY_INFO_FIRST_F,
1095		     IB_CC_CONGESTION_KEY_INFO_LAST_F);
1096}
1097
1098void mad_dump_cc_congestionlog(char *buf, int bufsz, void *val, int valsz)
1099{
1100	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_LOG_FIRST_F,
1101		     IB_CC_CONGESTION_LOG_LAST_F);
1102}
1103
1104void mad_dump_cc_congestionlogswitch(char *buf, int bufsz, void *val, int valsz)
1105{
1106	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_LOG_SWITCH_FIRST_F,
1107		     IB_CC_CONGESTION_LOG_SWITCH_LAST_F);
1108}
1109
1110void mad_dump_cc_congestionlogentryswitch(char *buf, int bufsz, void *val, int valsz)
1111{
1112	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_LOG_ENTRY_SWITCH_FIRST_F,
1113		     IB_CC_CONGESTION_LOG_ENTRY_SWITCH_LAST_F);
1114}
1115
1116void mad_dump_cc_congestionlogca(char *buf, int bufsz, void *val, int valsz)
1117{
1118	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_LOG_CA_FIRST_F,
1119		     IB_CC_CONGESTION_LOG_CA_LAST_F);
1120}
1121
1122void mad_dump_cc_congestionlogentryca(char *buf, int bufsz, void *val, int valsz)
1123{
1124	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_LOG_ENTRY_CA_FIRST_F,
1125		     IB_CC_CONGESTION_LOG_ENTRY_CA_LAST_F);
1126}
1127
1128void mad_dump_cc_switchcongestionsetting(char *buf, int bufsz, void *val, int valsz)
1129{
1130	_dump_fields(buf, bufsz, val, IB_CC_SWITCH_CONGESTION_SETTING_FIRST_F,
1131		     IB_CC_SWITCH_CONGESTION_SETTING_LAST_F);
1132}
1133
1134void mad_dump_cc_switchportcongestionsettingelement(char *buf, int bufsz, void *val, int valsz)
1135{
1136	_dump_fields(buf, bufsz, val, IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_FIRST_F,
1137		     IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_LAST_F);
1138}
1139
1140void mad_dump_cc_cacongestionsetting(char *buf, int bufsz, void *val, int valsz)
1141{
1142	_dump_fields(buf, bufsz, val, IB_CC_CA_CONGESTION_SETTING_FIRST_F,
1143		     IB_CC_CA_CONGESTION_SETTING_LAST_F);
1144}
1145
1146void mad_dump_cc_cacongestionentry(char *buf, int bufsz, void *val, int valsz)
1147{
1148	_dump_fields(buf, bufsz, val, IB_CC_CA_CONGESTION_ENTRY_FIRST_F,
1149		     IB_CC_CA_CONGESTION_ENTRY_LAST_F);
1150}
1151
1152void mad_dump_cc_congestioncontroltable(char *buf, int bufsz, void *val, int valsz)
1153{
1154	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_CONTROL_TABLE_FIRST_F,
1155		     IB_CC_CONGESTION_CONTROL_TABLE_LAST_F);
1156}
1157
1158void mad_dump_cc_congestioncontroltableentry(char *buf, int bufsz, void *val, int valsz)
1159{
1160	_dump_fields(buf, bufsz, val, IB_CC_CONGESTION_CONTROL_TABLE_ENTRY_FIRST_F,
1161		     IB_CC_CONGESTION_CONTROL_TABLE_ENTRY_LAST_F);
1162}
1163
1164void mad_dump_cc_timestamp(char *buf, int bufsz, void *val, int valsz)
1165{
1166	_dump_fields(buf, bufsz, val, IB_CC_TIMESTAMP_FIRST_F,
1167		     IB_CC_TIMESTAMP_LAST_F);
1168}
1169
1170void mad_dump_classportinfo(char *buf, int bufsz, void *val, int valsz)
1171{
1172	/* no FIRST_F and LAST_F for CPI field enums, must do a hack */
1173	_dump_fields(buf, bufsz, val, IB_CPI_BASEVER_F, IB_CPI_TRAP_QKEY_F + 1);
1174}
1175
1176void mad_dump_portmirror_route(char *buf, int bufsz, void *val, int valsz)
1177{
1178	_dump_fields(buf, bufsz, val, IB_PMR_FIRST_F, IB_PMR_LAST_F);
1179}
1180
1181void mad_dump_portmirror_filter(char *buf, int bufsz, void *val, int valsz)
1182{
1183	_dump_fields(buf, bufsz, val, IB_PMF_FIRST_F, IB_PMF_LAST_F);
1184}
1185
1186void mad_dump_portmirror_ports(char *buf, int bufsz, void *val, int valsz)
1187{
1188	_dump_fields(buf, bufsz, val, IB_PMP_FIRST_F, IB_PMP_LAST_F);
1189}
1190
1191void mad_dump_portinfo_ext(char *buf, int bufsz, void *val, int valsz)
1192{
1193	_dump_fields(buf, bufsz, val, IB_PORT_EXT_CAPMASK_F,
1194		     IB_PORT_EXT_LAST_F);
1195}
1196
1197void xdump(FILE * file, char *msg, void *p, int size)
1198{
1199#define HEX(x)  ((x) < 10 ? '0' + (x) : 'a' + ((x) -10))
1200	uint8_t *cp = p;
1201	int i;
1202
1203	if (msg)
1204		fputs(msg, file);
1205
1206	for (i = 0; i < size;) {
1207		fputc(HEX(*cp >> 4), file);
1208		fputc(HEX(*cp & 0xf), file);
1209		if (++i >= size)
1210			break;
1211		fputc(HEX(cp[1] >> 4), file);
1212		fputc(HEX(cp[1] & 0xf), file);
1213		if ((++i) % 16)
1214			fputc(' ', file);
1215		else
1216			fputc('\n', file);
1217		cp += 2;
1218	}
1219	if (i % 16)
1220		fputc('\n', file);
1221}
1222