]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ofed/libibmad/dump.c
Fix multiple vulnerabilities in rtsold.
[FreeBSD/FreeBSD.git] / contrib / ofed / libibmad / dump.c
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
47 void 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
72 void 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
97 void 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
133 void 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
169 void 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
196 static 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
219 void 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
246 void 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
253 void 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
276 static 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
311 void 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
318 void 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
325 void 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
345 static 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
371 void 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
378 void 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
389 void 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
414 void 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
434 void 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
468 void 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
493 void 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
518 void 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
546 void 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
619 void 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
640 void mad_dump_bitfield(char *buf, int bufsz, void *val, int valsz)
641 {
642         snprintf(buf, bufsz, "0x%x", *(uint32_t *) val);
643 }
644
645 void 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
657 void 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
665 void 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
688 typedef struct _ib_slvl_table {
689         uint8_t vl_by_sl_num[IB_MAX_NUM_VLS_TO_U8];
690 } ib_slvl_table_t;
691
692 static 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
699 typedef 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
706 static inline void ib_vl_arb_get_vl(uint8_t res_vl, uint8_t * const vl)
707 {
708         *vl = res_vl & 0x0F;
709 }
710
711 void 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
726 void 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
757 static 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
778 void 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
784 void 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
792 void 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
797 void 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
809 void 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
814 void 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
819 void 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
837 void 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
849 void 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
862 void 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
875 void 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
888 void 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
901 void 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
906 void 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
913 void 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
918 void 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
931 void 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
944 void 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
957 void 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
970 void 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
983 void 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
996 void 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
1009 void 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
1023 void 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
1036 void 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
1049 void 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
1062 void 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
1075 void 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
1081 void 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
1086 void 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
1092 void 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
1098 void 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
1104 void 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
1110 void 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
1116 void 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
1122 void 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
1128 void 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
1134 void 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
1140 void 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
1146 void 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
1152 void 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
1158 void 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
1164 void 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
1170 void 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
1176 void 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
1181 void 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
1186 void 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
1191 void 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
1197 void 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 }