1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
4*d6b92ffaSHans Petter Selasky *
5*d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
6*d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
7*d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
8*d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
9*d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
10*d6b92ffaSHans Petter Selasky *
11*d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
12*d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
13*d6b92ffaSHans Petter Selasky * conditions are met:
14*d6b92ffaSHans Petter Selasky *
15*d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
16*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
17*d6b92ffaSHans Petter Selasky * disclaimer.
18*d6b92ffaSHans Petter Selasky *
19*d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
20*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
21*d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
22*d6b92ffaSHans Petter Selasky * provided with the distribution.
23*d6b92ffaSHans Petter Selasky *
24*d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25*d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26*d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27*d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28*d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29*d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30*d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31*d6b92ffaSHans Petter Selasky * SOFTWARE.
32*d6b92ffaSHans Petter Selasky *
33*d6b92ffaSHans Petter Selasky */
34*d6b92ffaSHans Petter Selasky
35*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
36*d6b92ffaSHans Petter Selasky # include <config.h>
37*d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */
38*d6b92ffaSHans Petter Selasky
39*d6b92ffaSHans Petter Selasky #include <stdio.h>
40*d6b92ffaSHans Petter Selasky #include <stdlib.h>
41*d6b92ffaSHans Petter Selasky #include <unistd.h>
42*d6b92ffaSHans Petter Selasky #include <string.h>
43*d6b92ffaSHans Petter Selasky #include <getopt.h>
44*d6b92ffaSHans Petter Selasky #include <netinet/in.h>
45*d6b92ffaSHans Petter Selasky
46*d6b92ffaSHans Petter Selasky #define __STDC_FORMAT_MACROS
47*d6b92ffaSHans Petter Selasky #include <inttypes.h>
48*d6b92ffaSHans Petter Selasky
49*d6b92ffaSHans Petter Selasky #include <infiniband/umad.h>
50*d6b92ffaSHans Petter Selasky #include <infiniband/mad.h>
51*d6b92ffaSHans Petter Selasky #include <complib/cl_nodenamemap.h>
52*d6b92ffaSHans Petter Selasky
53*d6b92ffaSHans Petter Selasky #include "ibdiag_common.h"
54*d6b92ffaSHans Petter Selasky
55*d6b92ffaSHans Petter Selasky struct ibmad_port *srcport;
56*d6b92ffaSHans Petter Selasky
57*d6b92ffaSHans Petter Selasky static op_fn_t node_desc, node_info, port_info, switch_info, pkey_table,
58*d6b92ffaSHans Petter Selasky sl2vl_table, vlarb_table, guid_info, mlnx_ext_port_info, port_info_extended;
59*d6b92ffaSHans Petter Selasky
60*d6b92ffaSHans Petter Selasky static const match_rec_t match_tbl[] = {
61*d6b92ffaSHans Petter Selasky {"NodeInfo", "NI", node_info, 0, ""},
62*d6b92ffaSHans Petter Selasky {"NodeDesc", "ND", node_desc, 0, ""},
63*d6b92ffaSHans Petter Selasky {"PortInfo", "PI", port_info, 1, ""},
64*d6b92ffaSHans Petter Selasky {"PortInfoExtended", "PIE", port_info_extended, 1, ""},
65*d6b92ffaSHans Petter Selasky {"SwitchInfo", "SI", switch_info, 0, ""},
66*d6b92ffaSHans Petter Selasky {"PKeyTable", "PKeys", pkey_table, 1, ""},
67*d6b92ffaSHans Petter Selasky {"SL2VLTable", "SL2VL", sl2vl_table, 1, ""},
68*d6b92ffaSHans Petter Selasky {"VLArbitration", "VLArb", vlarb_table, 1, ""},
69*d6b92ffaSHans Petter Selasky {"GUIDInfo", "GI", guid_info, 0, ""},
70*d6b92ffaSHans Petter Selasky {"MlnxExtPortInfo", "MEPI", mlnx_ext_port_info, 1, ""},
71*d6b92ffaSHans Petter Selasky {0}
72*d6b92ffaSHans Petter Selasky };
73*d6b92ffaSHans Petter Selasky
74*d6b92ffaSHans Petter Selasky static char *node_name_map_file = NULL;
75*d6b92ffaSHans Petter Selasky static nn_map_t *node_name_map = NULL;
76*d6b92ffaSHans Petter Selasky static int extended_speeds = 0;
77*d6b92ffaSHans Petter Selasky
78*d6b92ffaSHans Petter Selasky /*******************************************/
node_desc(ib_portid_t * dest,char ** argv,int argc)79*d6b92ffaSHans Petter Selasky static char *node_desc(ib_portid_t * dest, char **argv, int argc)
80*d6b92ffaSHans Petter Selasky {
81*d6b92ffaSHans Petter Selasky int node_type, l;
82*d6b92ffaSHans Petter Selasky uint64_t node_guid;
83*d6b92ffaSHans Petter Selasky char nd[IB_SMP_DATA_SIZE] = { 0 };
84*d6b92ffaSHans Petter Selasky uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
85*d6b92ffaSHans Petter Selasky char dots[128];
86*d6b92ffaSHans Petter Selasky char *nodename = NULL;
87*d6b92ffaSHans Petter Selasky
88*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
89*d6b92ffaSHans Petter Selasky return "node info query failed";
90*d6b92ffaSHans Petter Selasky
91*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_TYPE_F, &node_type);
92*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_GUID_F, &node_guid);
93*d6b92ffaSHans Petter Selasky
94*d6b92ffaSHans Petter Selasky if (!smp_query_via(nd, dest, IB_ATTR_NODE_DESC, 0, 0, srcport))
95*d6b92ffaSHans Petter Selasky return "node desc query failed";
96*d6b92ffaSHans Petter Selasky
97*d6b92ffaSHans Petter Selasky nodename = remap_node_name(node_name_map, node_guid, nd);
98*d6b92ffaSHans Petter Selasky
99*d6b92ffaSHans Petter Selasky l = strlen(nodename);
100*d6b92ffaSHans Petter Selasky if (l < 32) {
101*d6b92ffaSHans Petter Selasky memset(dots, '.', 32 - l);
102*d6b92ffaSHans Petter Selasky dots[32 - l] = '\0';
103*d6b92ffaSHans Petter Selasky } else {
104*d6b92ffaSHans Petter Selasky dots[0] = '.';
105*d6b92ffaSHans Petter Selasky dots[1] = '\0';
106*d6b92ffaSHans Petter Selasky }
107*d6b92ffaSHans Petter Selasky
108*d6b92ffaSHans Petter Selasky printf("Node Description:%s%s\n", dots, nodename);
109*d6b92ffaSHans Petter Selasky free(nodename);
110*d6b92ffaSHans Petter Selasky return 0;
111*d6b92ffaSHans Petter Selasky }
112*d6b92ffaSHans Petter Selasky
node_info(ib_portid_t * dest,char ** argv,int argc)113*d6b92ffaSHans Petter Selasky static char *node_info(ib_portid_t * dest, char **argv, int argc)
114*d6b92ffaSHans Petter Selasky {
115*d6b92ffaSHans Petter Selasky char buf[2048];
116*d6b92ffaSHans Petter Selasky char data[IB_SMP_DATA_SIZE] = { 0 };
117*d6b92ffaSHans Petter Selasky
118*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
119*d6b92ffaSHans Petter Selasky return "node info query failed";
120*d6b92ffaSHans Petter Selasky
121*d6b92ffaSHans Petter Selasky mad_dump_nodeinfo(buf, sizeof buf, data, sizeof data);
122*d6b92ffaSHans Petter Selasky
123*d6b92ffaSHans Petter Selasky printf("# Node info: %s\n%s", portid2str(dest), buf);
124*d6b92ffaSHans Petter Selasky return 0;
125*d6b92ffaSHans Petter Selasky }
126*d6b92ffaSHans Petter Selasky
port_info_extended(ib_portid_t * dest,char ** argv,int argc)127*d6b92ffaSHans Petter Selasky static char *port_info_extended(ib_portid_t * dest, char **argv, int argc)
128*d6b92ffaSHans Petter Selasky {
129*d6b92ffaSHans Petter Selasky char buf[2048];
130*d6b92ffaSHans Petter Selasky uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
131*d6b92ffaSHans Petter Selasky int portnum = 0;
132*d6b92ffaSHans Petter Selasky
133*d6b92ffaSHans Petter Selasky if (argc > 0)
134*d6b92ffaSHans Petter Selasky portnum = strtol(argv[0], 0, 0);
135*d6b92ffaSHans Petter Selasky
136*d6b92ffaSHans Petter Selasky if (!is_port_info_extended_supported(dest, portnum, srcport))
137*d6b92ffaSHans Petter Selasky return "port info extended not supported";
138*d6b92ffaSHans Petter Selasky
139*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO_EXT, portnum, 0,
140*d6b92ffaSHans Petter Selasky srcport))
141*d6b92ffaSHans Petter Selasky return "port info extended query failed";
142*d6b92ffaSHans Petter Selasky
143*d6b92ffaSHans Petter Selasky mad_dump_portinfo_ext(buf, sizeof buf, data, sizeof data);
144*d6b92ffaSHans Petter Selasky printf("# Port info Extended: %s port %d\n%s", portid2str(dest),
145*d6b92ffaSHans Petter Selasky portnum, buf);
146*d6b92ffaSHans Petter Selasky return 0;
147*d6b92ffaSHans Petter Selasky }
148*d6b92ffaSHans Petter Selasky
port_info(ib_portid_t * dest,char ** argv,int argc)149*d6b92ffaSHans Petter Selasky static char *port_info(ib_portid_t * dest, char **argv, int argc)
150*d6b92ffaSHans Petter Selasky {
151*d6b92ffaSHans Petter Selasky char data[IB_SMP_DATA_SIZE] = { 0 };
152*d6b92ffaSHans Petter Selasky int portnum = 0, orig_portnum;
153*d6b92ffaSHans Petter Selasky
154*d6b92ffaSHans Petter Selasky if (argc > 0)
155*d6b92ffaSHans Petter Selasky portnum = strtol(argv[0], 0, 0);
156*d6b92ffaSHans Petter Selasky orig_portnum = portnum;
157*d6b92ffaSHans Petter Selasky if (extended_speeds)
158*d6b92ffaSHans Petter Selasky portnum |= 1 << 31;
159*d6b92ffaSHans Petter Selasky
160*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
161*d6b92ffaSHans Petter Selasky return "port info query failed";
162*d6b92ffaSHans Petter Selasky
163*d6b92ffaSHans Petter Selasky printf("# Port info: %s port %d\n", portid2str(dest), orig_portnum);
164*d6b92ffaSHans Petter Selasky dump_portinfo(data, 0);
165*d6b92ffaSHans Petter Selasky return 0;
166*d6b92ffaSHans Petter Selasky }
167*d6b92ffaSHans Petter Selasky
mlnx_ext_port_info(ib_portid_t * dest,char ** argv,int argc)168*d6b92ffaSHans Petter Selasky static char *mlnx_ext_port_info(ib_portid_t * dest, char **argv, int argc)
169*d6b92ffaSHans Petter Selasky {
170*d6b92ffaSHans Petter Selasky char buf[2300];
171*d6b92ffaSHans Petter Selasky char data[IB_SMP_DATA_SIZE];
172*d6b92ffaSHans Petter Selasky int portnum = 0;
173*d6b92ffaSHans Petter Selasky
174*d6b92ffaSHans Petter Selasky if (argc > 0)
175*d6b92ffaSHans Petter Selasky portnum = strtol(argv[0], 0, 0);
176*d6b92ffaSHans Petter Selasky
177*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO, portnum, 0, srcport))
178*d6b92ffaSHans Petter Selasky return "Mellanox ext port info query failed";
179*d6b92ffaSHans Petter Selasky
180*d6b92ffaSHans Petter Selasky mad_dump_mlnx_ext_port_info(buf, sizeof buf, data, sizeof data);
181*d6b92ffaSHans Petter Selasky
182*d6b92ffaSHans Petter Selasky printf("# MLNX ext Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
183*d6b92ffaSHans Petter Selasky return 0;
184*d6b92ffaSHans Petter Selasky }
185*d6b92ffaSHans Petter Selasky
switch_info(ib_portid_t * dest,char ** argv,int argc)186*d6b92ffaSHans Petter Selasky static char *switch_info(ib_portid_t * dest, char **argv, int argc)
187*d6b92ffaSHans Petter Selasky {
188*d6b92ffaSHans Petter Selasky char buf[2048];
189*d6b92ffaSHans Petter Selasky char data[IB_SMP_DATA_SIZE] = { 0 };
190*d6b92ffaSHans Petter Selasky
191*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
192*d6b92ffaSHans Petter Selasky return "switch info query failed";
193*d6b92ffaSHans Petter Selasky
194*d6b92ffaSHans Petter Selasky mad_dump_switchinfo(buf, sizeof buf, data, sizeof data);
195*d6b92ffaSHans Petter Selasky
196*d6b92ffaSHans Petter Selasky printf("# Switch info: %s\n%s", portid2str(dest), buf);
197*d6b92ffaSHans Petter Selasky return 0;
198*d6b92ffaSHans Petter Selasky }
199*d6b92ffaSHans Petter Selasky
pkey_table(ib_portid_t * dest,char ** argv,int argc)200*d6b92ffaSHans Petter Selasky static char *pkey_table(ib_portid_t * dest, char **argv, int argc)
201*d6b92ffaSHans Petter Selasky {
202*d6b92ffaSHans Petter Selasky uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
203*d6b92ffaSHans Petter Selasky int i, j, k;
204*d6b92ffaSHans Petter Selasky uint16_t *p;
205*d6b92ffaSHans Petter Selasky unsigned mod;
206*d6b92ffaSHans Petter Selasky int n, t, phy_ports;
207*d6b92ffaSHans Petter Selasky int portnum = 0;
208*d6b92ffaSHans Petter Selasky
209*d6b92ffaSHans Petter Selasky if (argc > 0)
210*d6b92ffaSHans Petter Selasky portnum = strtol(argv[0], 0, 0);
211*d6b92ffaSHans Petter Selasky
212*d6b92ffaSHans Petter Selasky /* Get the partition capacity */
213*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
214*d6b92ffaSHans Petter Selasky return "node info query failed";
215*d6b92ffaSHans Petter Selasky
216*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_TYPE_F, &t);
217*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_NPORTS_F, &phy_ports);
218*d6b92ffaSHans Petter Selasky if (portnum > phy_ports)
219*d6b92ffaSHans Petter Selasky return "invalid port number";
220*d6b92ffaSHans Petter Selasky
221*d6b92ffaSHans Petter Selasky if ((t == IB_NODE_SWITCH) && (portnum != 0)) {
222*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0,
223*d6b92ffaSHans Petter Selasky srcport))
224*d6b92ffaSHans Petter Selasky return "switch info failed";
225*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_SW_PARTITION_ENFORCE_CAP_F, &n);
226*d6b92ffaSHans Petter Selasky } else
227*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_PARTITION_CAP_F, &n);
228*d6b92ffaSHans Petter Selasky
229*d6b92ffaSHans Petter Selasky for (i = 0; i < (n + 31) / 32; i++) {
230*d6b92ffaSHans Petter Selasky mod = i | (portnum << 16);
231*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_PKEY_TBL, mod, 0,
232*d6b92ffaSHans Petter Selasky srcport))
233*d6b92ffaSHans Petter Selasky return "pkey table query failed";
234*d6b92ffaSHans Petter Selasky if (i + 1 == (n + 31) / 32)
235*d6b92ffaSHans Petter Selasky k = ((n + 7 - i * 32) / 8) * 8;
236*d6b92ffaSHans Petter Selasky else
237*d6b92ffaSHans Petter Selasky k = 32;
238*d6b92ffaSHans Petter Selasky p = (uint16_t *) data;
239*d6b92ffaSHans Petter Selasky for (j = 0; j < k; j += 8, p += 8) {
240*d6b92ffaSHans Petter Selasky printf
241*d6b92ffaSHans Petter Selasky ("%4u: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n",
242*d6b92ffaSHans Petter Selasky (i * 32) + j, ntohs(p[0]), ntohs(p[1]),
243*d6b92ffaSHans Petter Selasky ntohs(p[2]), ntohs(p[3]), ntohs(p[4]), ntohs(p[5]),
244*d6b92ffaSHans Petter Selasky ntohs(p[6]), ntohs(p[7]));
245*d6b92ffaSHans Petter Selasky }
246*d6b92ffaSHans Petter Selasky }
247*d6b92ffaSHans Petter Selasky printf("%d pkeys capacity for this port\n", n);
248*d6b92ffaSHans Petter Selasky
249*d6b92ffaSHans Petter Selasky return 0;
250*d6b92ffaSHans Petter Selasky }
251*d6b92ffaSHans Petter Selasky
sl2vl_dump_table_entry(ib_portid_t * dest,int in,int out)252*d6b92ffaSHans Petter Selasky static char *sl2vl_dump_table_entry(ib_portid_t * dest, int in, int out)
253*d6b92ffaSHans Petter Selasky {
254*d6b92ffaSHans Petter Selasky char buf[2048];
255*d6b92ffaSHans Petter Selasky char data[IB_SMP_DATA_SIZE] = { 0 };
256*d6b92ffaSHans Petter Selasky int portnum = (in << 8) | out;
257*d6b92ffaSHans Petter Selasky
258*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0, srcport))
259*d6b92ffaSHans Petter Selasky return "slvl query failed";
260*d6b92ffaSHans Petter Selasky
261*d6b92ffaSHans Petter Selasky mad_dump_sltovl(buf, sizeof buf, data, sizeof data);
262*d6b92ffaSHans Petter Selasky printf("ports: in %2d, out %2d: ", in, out);
263*d6b92ffaSHans Petter Selasky printf("%s", buf);
264*d6b92ffaSHans Petter Selasky return 0;
265*d6b92ffaSHans Petter Selasky }
266*d6b92ffaSHans Petter Selasky
sl2vl_table(ib_portid_t * dest,char ** argv,int argc)267*d6b92ffaSHans Petter Selasky static char *sl2vl_table(ib_portid_t * dest, char **argv, int argc)
268*d6b92ffaSHans Petter Selasky {
269*d6b92ffaSHans Petter Selasky uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
270*d6b92ffaSHans Petter Selasky int type, num_ports, portnum = 0;
271*d6b92ffaSHans Petter Selasky int i;
272*d6b92ffaSHans Petter Selasky char *ret;
273*d6b92ffaSHans Petter Selasky
274*d6b92ffaSHans Petter Selasky if (argc > 0)
275*d6b92ffaSHans Petter Selasky portnum = strtol(argv[0], 0, 0);
276*d6b92ffaSHans Petter Selasky
277*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
278*d6b92ffaSHans Petter Selasky return "node info query failed";
279*d6b92ffaSHans Petter Selasky
280*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_TYPE_F, &type);
281*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports);
282*d6b92ffaSHans Petter Selasky if (portnum > num_ports)
283*d6b92ffaSHans Petter Selasky return "invalid port number";
284*d6b92ffaSHans Petter Selasky
285*d6b92ffaSHans Petter Selasky printf("# SL2VL table: %s\n", portid2str(dest));
286*d6b92ffaSHans Petter Selasky printf("# SL: |");
287*d6b92ffaSHans Petter Selasky for (i = 0; i < 16; i++)
288*d6b92ffaSHans Petter Selasky printf("%2d|", i);
289*d6b92ffaSHans Petter Selasky printf("\n");
290*d6b92ffaSHans Petter Selasky
291*d6b92ffaSHans Petter Selasky if (type != IB_NODE_SWITCH)
292*d6b92ffaSHans Petter Selasky return sl2vl_dump_table_entry(dest, 0, 0);
293*d6b92ffaSHans Petter Selasky
294*d6b92ffaSHans Petter Selasky for (i = 0; i <= num_ports; i++) {
295*d6b92ffaSHans Petter Selasky ret = sl2vl_dump_table_entry(dest, i, portnum);
296*d6b92ffaSHans Petter Selasky if (ret)
297*d6b92ffaSHans Petter Selasky return ret;
298*d6b92ffaSHans Petter Selasky }
299*d6b92ffaSHans Petter Selasky return 0;
300*d6b92ffaSHans Petter Selasky }
301*d6b92ffaSHans Petter Selasky
vlarb_dump_table_entry(ib_portid_t * dest,int portnum,int offset,unsigned cap)302*d6b92ffaSHans Petter Selasky static char *vlarb_dump_table_entry(ib_portid_t * dest, int portnum, int offset,
303*d6b92ffaSHans Petter Selasky unsigned cap)
304*d6b92ffaSHans Petter Selasky {
305*d6b92ffaSHans Petter Selasky char buf[2048];
306*d6b92ffaSHans Petter Selasky char data[IB_SMP_DATA_SIZE] = { 0 };
307*d6b92ffaSHans Petter Selasky
308*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_VL_ARBITRATION,
309*d6b92ffaSHans Petter Selasky (offset << 16) | portnum, 0, srcport))
310*d6b92ffaSHans Petter Selasky return "vl arb query failed";
311*d6b92ffaSHans Petter Selasky mad_dump_vlarbitration(buf, sizeof(buf), data, cap * 2);
312*d6b92ffaSHans Petter Selasky printf("%s", buf);
313*d6b92ffaSHans Petter Selasky return 0;
314*d6b92ffaSHans Petter Selasky }
315*d6b92ffaSHans Petter Selasky
vlarb_dump_table(ib_portid_t * dest,int portnum,char * name,int offset,int cap)316*d6b92ffaSHans Petter Selasky static char *vlarb_dump_table(ib_portid_t * dest, int portnum,
317*d6b92ffaSHans Petter Selasky char *name, int offset, int cap)
318*d6b92ffaSHans Petter Selasky {
319*d6b92ffaSHans Petter Selasky char *ret;
320*d6b92ffaSHans Petter Selasky
321*d6b92ffaSHans Petter Selasky printf("# %s priority VL Arbitration Table:", name);
322*d6b92ffaSHans Petter Selasky ret = vlarb_dump_table_entry(dest, portnum, offset,
323*d6b92ffaSHans Petter Selasky cap < 32 ? cap : 32);
324*d6b92ffaSHans Petter Selasky if (!ret && cap > 32)
325*d6b92ffaSHans Petter Selasky ret = vlarb_dump_table_entry(dest, portnum, offset + 1,
326*d6b92ffaSHans Petter Selasky cap - 32);
327*d6b92ffaSHans Petter Selasky return ret;
328*d6b92ffaSHans Petter Selasky }
329*d6b92ffaSHans Petter Selasky
vlarb_table(ib_portid_t * dest,char ** argv,int argc)330*d6b92ffaSHans Petter Selasky static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
331*d6b92ffaSHans Petter Selasky {
332*d6b92ffaSHans Petter Selasky uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
333*d6b92ffaSHans Petter Selasky int portnum = 0;
334*d6b92ffaSHans Petter Selasky int type, enhsp0, lowcap, highcap;
335*d6b92ffaSHans Petter Selasky char *ret = 0;
336*d6b92ffaSHans Petter Selasky
337*d6b92ffaSHans Petter Selasky if (argc > 0)
338*d6b92ffaSHans Petter Selasky portnum = strtol(argv[0], 0, 0);
339*d6b92ffaSHans Petter Selasky
340*d6b92ffaSHans Petter Selasky /* port number of 0 could mean SP0 or port MAD arrives on */
341*d6b92ffaSHans Petter Selasky if (portnum == 0) {
342*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0,
343*d6b92ffaSHans Petter Selasky srcport))
344*d6b92ffaSHans Petter Selasky return "node info query failed";
345*d6b92ffaSHans Petter Selasky
346*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_NODE_TYPE_F, &type);
347*d6b92ffaSHans Petter Selasky if (type == IB_NODE_SWITCH) {
348*d6b92ffaSHans Petter Selasky memset(data, 0, sizeof(data));
349*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0,
350*d6b92ffaSHans Petter Selasky 0, srcport))
351*d6b92ffaSHans Petter Selasky return "switch info query failed";
352*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_SW_ENHANCED_PORT0_F, &enhsp0);
353*d6b92ffaSHans Petter Selasky if (!enhsp0) {
354*d6b92ffaSHans Petter Selasky printf
355*d6b92ffaSHans Petter Selasky ("# No VLArbitration tables (BSP0): %s port %d\n",
356*d6b92ffaSHans Petter Selasky portid2str(dest), 0);
357*d6b92ffaSHans Petter Selasky return 0;
358*d6b92ffaSHans Petter Selasky }
359*d6b92ffaSHans Petter Selasky memset(data, 0, sizeof(data));
360*d6b92ffaSHans Petter Selasky }
361*d6b92ffaSHans Petter Selasky }
362*d6b92ffaSHans Petter Selasky
363*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
364*d6b92ffaSHans Petter Selasky return "port info query failed";
365*d6b92ffaSHans Petter Selasky
366*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_PORT_VL_ARBITRATION_LOW_CAP_F, &lowcap);
367*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_PORT_VL_ARBITRATION_HIGH_CAP_F, &highcap);
368*d6b92ffaSHans Petter Selasky
369*d6b92ffaSHans Petter Selasky printf("# VLArbitration tables: %s port %d LowCap %d HighCap %d\n",
370*d6b92ffaSHans Petter Selasky portid2str(dest), portnum, lowcap, highcap);
371*d6b92ffaSHans Petter Selasky
372*d6b92ffaSHans Petter Selasky if (lowcap > 0)
373*d6b92ffaSHans Petter Selasky ret = vlarb_dump_table(dest, portnum, "Low", 1, lowcap);
374*d6b92ffaSHans Petter Selasky
375*d6b92ffaSHans Petter Selasky if (!ret && highcap > 0)
376*d6b92ffaSHans Petter Selasky ret = vlarb_dump_table(dest, portnum, "High", 3, highcap);
377*d6b92ffaSHans Petter Selasky
378*d6b92ffaSHans Petter Selasky return ret;
379*d6b92ffaSHans Petter Selasky }
380*d6b92ffaSHans Petter Selasky
guid_info(ib_portid_t * dest,char ** argv,int argc)381*d6b92ffaSHans Petter Selasky static char *guid_info(ib_portid_t * dest, char **argv, int argc)
382*d6b92ffaSHans Petter Selasky {
383*d6b92ffaSHans Petter Selasky uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
384*d6b92ffaSHans Petter Selasky int i, j, k;
385*d6b92ffaSHans Petter Selasky uint64_t *p;
386*d6b92ffaSHans Petter Selasky unsigned mod;
387*d6b92ffaSHans Petter Selasky int n;
388*d6b92ffaSHans Petter Selasky
389*d6b92ffaSHans Petter Selasky /* Get the guid capacity */
390*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, 0, 0, srcport))
391*d6b92ffaSHans Petter Selasky return "port info failed";
392*d6b92ffaSHans Petter Selasky mad_decode_field(data, IB_PORT_GUID_CAP_F, &n);
393*d6b92ffaSHans Petter Selasky
394*d6b92ffaSHans Petter Selasky for (i = 0; i < (n + 7) / 8; i++) {
395*d6b92ffaSHans Petter Selasky mod = i;
396*d6b92ffaSHans Petter Selasky if (!smp_query_via(data, dest, IB_ATTR_GUID_INFO, mod, 0,
397*d6b92ffaSHans Petter Selasky srcport))
398*d6b92ffaSHans Petter Selasky return "guid info query failed";
399*d6b92ffaSHans Petter Selasky if (i + 1 == (n + 7) / 8)
400*d6b92ffaSHans Petter Selasky k = ((n + 1 - i * 8) / 2) * 2;
401*d6b92ffaSHans Petter Selasky else
402*d6b92ffaSHans Petter Selasky k = 8;
403*d6b92ffaSHans Petter Selasky p = (uint64_t *) data;
404*d6b92ffaSHans Petter Selasky for (j = 0; j < k; j += 2, p += 2) {
405*d6b92ffaSHans Petter Selasky printf("%4u: 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
406*d6b92ffaSHans Petter Selasky (i * 8) + j, ntohll(p[0]), ntohll(p[1]));
407*d6b92ffaSHans Petter Selasky }
408*d6b92ffaSHans Petter Selasky }
409*d6b92ffaSHans Petter Selasky printf("%d guids capacity for this port\n", n);
410*d6b92ffaSHans Petter Selasky
411*d6b92ffaSHans Petter Selasky return 0;
412*d6b92ffaSHans Petter Selasky }
413*d6b92ffaSHans Petter Selasky
process_opt(void * context,int ch,char * optarg)414*d6b92ffaSHans Petter Selasky static int process_opt(void *context, int ch, char *optarg)
415*d6b92ffaSHans Petter Selasky {
416*d6b92ffaSHans Petter Selasky switch (ch) {
417*d6b92ffaSHans Petter Selasky case 1:
418*d6b92ffaSHans Petter Selasky node_name_map_file = strdup(optarg);
419*d6b92ffaSHans Petter Selasky break;
420*d6b92ffaSHans Petter Selasky case 'c':
421*d6b92ffaSHans Petter Selasky ibd_dest_type = IB_DEST_DRSLID;
422*d6b92ffaSHans Petter Selasky break;
423*d6b92ffaSHans Petter Selasky case 'x':
424*d6b92ffaSHans Petter Selasky extended_speeds = 1;
425*d6b92ffaSHans Petter Selasky break;
426*d6b92ffaSHans Petter Selasky default:
427*d6b92ffaSHans Petter Selasky return -1;
428*d6b92ffaSHans Petter Selasky }
429*d6b92ffaSHans Petter Selasky return 0;
430*d6b92ffaSHans Petter Selasky }
431*d6b92ffaSHans Petter Selasky
main(int argc,char ** argv)432*d6b92ffaSHans Petter Selasky int main(int argc, char **argv)
433*d6b92ffaSHans Petter Selasky {
434*d6b92ffaSHans Petter Selasky char usage_args[1024];
435*d6b92ffaSHans Petter Selasky int mgmt_classes[3] =
436*d6b92ffaSHans Petter Selasky { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
437*d6b92ffaSHans Petter Selasky ib_portid_t portid = { 0 };
438*d6b92ffaSHans Petter Selasky char *err;
439*d6b92ffaSHans Petter Selasky op_fn_t *fn;
440*d6b92ffaSHans Petter Selasky const match_rec_t *r;
441*d6b92ffaSHans Petter Selasky int n;
442*d6b92ffaSHans Petter Selasky
443*d6b92ffaSHans Petter Selasky const struct ibdiag_opt opts[] = {
444*d6b92ffaSHans Petter Selasky {"combined", 'c', 0, NULL,
445*d6b92ffaSHans Petter Selasky "use Combined route address argument"},
446*d6b92ffaSHans Petter Selasky {"node-name-map", 1, 1, "<file>", "node name map file"},
447*d6b92ffaSHans Petter Selasky {"extended", 'x', 0, NULL, "use extended speeds"},
448*d6b92ffaSHans Petter Selasky {0}
449*d6b92ffaSHans Petter Selasky };
450*d6b92ffaSHans Petter Selasky const char *usage_examples[] = {
451*d6b92ffaSHans Petter Selasky "portinfo 3 1\t\t\t\t# portinfo by lid, with port modifier",
452*d6b92ffaSHans Petter Selasky "-G switchinfo 0x2C9000100D051 1\t# switchinfo by guid",
453*d6b92ffaSHans Petter Selasky "-D nodeinfo 0\t\t\t\t# nodeinfo by direct route",
454*d6b92ffaSHans Petter Selasky "-c nodeinfo 6 0,12\t\t\t# nodeinfo by combined route",
455*d6b92ffaSHans Petter Selasky NULL
456*d6b92ffaSHans Petter Selasky };
457*d6b92ffaSHans Petter Selasky
458*d6b92ffaSHans Petter Selasky n = sprintf(usage_args, "<op> <dest dr_path|lid|guid> [op params]\n"
459*d6b92ffaSHans Petter Selasky "\nSupported ops (and aliases, case insensitive):\n");
460*d6b92ffaSHans Petter Selasky for (r = match_tbl; r->name; r++) {
461*d6b92ffaSHans Petter Selasky n += snprintf(usage_args + n, sizeof(usage_args) - n,
462*d6b92ffaSHans Petter Selasky " %s (%s) <addr>%s\n", r->name,
463*d6b92ffaSHans Petter Selasky r->alias ? r->alias : "",
464*d6b92ffaSHans Petter Selasky r->opt_portnum ? " [<portnum>]" : "");
465*d6b92ffaSHans Petter Selasky if (n >= sizeof(usage_args))
466*d6b92ffaSHans Petter Selasky exit(-1);
467*d6b92ffaSHans Petter Selasky }
468*d6b92ffaSHans Petter Selasky
469*d6b92ffaSHans Petter Selasky ibdiag_process_opts(argc, argv, NULL, NULL, opts, process_opt,
470*d6b92ffaSHans Petter Selasky usage_args, usage_examples);
471*d6b92ffaSHans Petter Selasky
472*d6b92ffaSHans Petter Selasky argc -= optind;
473*d6b92ffaSHans Petter Selasky argv += optind;
474*d6b92ffaSHans Petter Selasky
475*d6b92ffaSHans Petter Selasky if (argc < 2)
476*d6b92ffaSHans Petter Selasky ibdiag_show_usage();
477*d6b92ffaSHans Petter Selasky
478*d6b92ffaSHans Petter Selasky if (!(fn = match_op(match_tbl, argv[0])))
479*d6b92ffaSHans Petter Selasky IBEXIT("operation '%s' not supported", argv[0]);
480*d6b92ffaSHans Petter Selasky
481*d6b92ffaSHans Petter Selasky srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
482*d6b92ffaSHans Petter Selasky if (!srcport)
483*d6b92ffaSHans Petter Selasky IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
484*d6b92ffaSHans Petter Selasky
485*d6b92ffaSHans Petter Selasky smp_mkey_set(srcport, ibd_mkey);
486*d6b92ffaSHans Petter Selasky
487*d6b92ffaSHans Petter Selasky node_name_map = open_node_name_map(node_name_map_file);
488*d6b92ffaSHans Petter Selasky
489*d6b92ffaSHans Petter Selasky if (ibd_dest_type != IB_DEST_DRSLID) {
490*d6b92ffaSHans Petter Selasky if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1],
491*d6b92ffaSHans Petter Selasky ibd_dest_type, ibd_sm_id, srcport) < 0)
492*d6b92ffaSHans Petter Selasky IBEXIT("can't resolve destination port %s", argv[1]);
493*d6b92ffaSHans Petter Selasky if ((err = fn(&portid, argv + 2, argc - 2)))
494*d6b92ffaSHans Petter Selasky IBEXIT("operation %s: %s", argv[0], err);
495*d6b92ffaSHans Petter Selasky } else {
496*d6b92ffaSHans Petter Selasky char concat[64];
497*d6b92ffaSHans Petter Selasky
498*d6b92ffaSHans Petter Selasky memset(concat, 0, 64);
499*d6b92ffaSHans Petter Selasky snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]);
500*d6b92ffaSHans Petter Selasky if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, concat,
501*d6b92ffaSHans Petter Selasky ibd_dest_type, ibd_sm_id, srcport) < 0)
502*d6b92ffaSHans Petter Selasky IBEXIT("can't resolve destination port %s", concat);
503*d6b92ffaSHans Petter Selasky if ((err = fn(&portid, argv + 3, argc - 3)))
504*d6b92ffaSHans Petter Selasky IBEXIT("operation %s: %s", argv[0], err);
505*d6b92ffaSHans Petter Selasky }
506*d6b92ffaSHans Petter Selasky close_node_name_map(node_name_map);
507*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
508*d6b92ffaSHans Petter Selasky exit(0);
509*d6b92ffaSHans Petter Selasky }
510