infiniband-diags: initial port of linux ib diags
[mirror/winof/.git] / tools / infiniband_diags / src / ibstat.c
1 /*\r
2  * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
3  *\r
4  * This software is available to you under a choice of one of two\r
5  * licenses.  You may choose to be licensed under the terms of the GNU\r
6  * General Public License (GPL) Version 2, available from the file\r
7  * COPYING in the main directory of this source tree, or the\r
8  * OpenIB.org BSD license below:\r
9  *\r
10  *     Redistribution and use in source and binary forms, with or\r
11  *     without modification, are permitted provided that the following\r
12  *     conditions are met:\r
13  *\r
14  *      - Redistributions of source code must retain the above\r
15  *        copyright notice, this list of conditions and the following\r
16  *        disclaimer.\r
17  *\r
18  *      - Redistributions in binary form must reproduce the above\r
19  *        copyright notice, this list of conditions and the following\r
20  *        disclaimer in the documentation and/or other materials\r
21  *        provided with the distribution.\r
22  *\r
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
30  * SOFTWARE.\r
31  *\r
32  */\r
33 \r
34 #include <stdio.h>\r
35 #include <stdlib.h>\r
36 \r
37 #if !defined(_WIN32) \r
38 #define _GNU_SOURCE\r
39 \r
40 #if HAVE_CONFIG_H\r
41 #  include <config.h>\r
42 #endif /* HAVE_CONFIG_H */\r
43 \r
44 #include <inttypes.h>\r
45 #include <string.h>\r
46 #include <errno.h>\r
47 #include <stdio.h>\r
48 #include <stdlib.h>\r
49 #include <unistd.h>\r
50 #include <stdarg.h>\r
51 #include <sys/types.h>\r
52 #include <sys/stat.h>\r
53 #include <fcntl.h>\r
54 #include <sys/ioctl.h>\r
55 #include <unistd.h>\r
56 #include <string.h>\r
57 #include <getopt.h>\r
58 #include <endian.h>\r
59 #include <byteswap.h>\r
60 #include <sys/poll.h>\r
61 #include <syslog.h>\r
62 #include <netinet/in.h>\r
63 #else\r
64 #include "..\..\..\..\etc\user\getopt.c"\r
65 #endif\r
66 \r
67 #include <infiniband/umad.h>\r
68 #include <infiniband/mad.h>\r
69 #include <ibdiag_common.h>\r
70 \r
71 static int debug;\r
72 \r
73 char *argv0 = "ibstat";\r
74 \r
75 static char *node_type_str[] = {\r
76         "???",\r
77         "CA",\r
78         "Switch",\r
79         "Router",\r
80         "iWARP RNIC"\r
81 };\r
82 \r
83 static void\r
84 ca_dump(umad_ca_t *ca)\r
85 {\r
86         if (!ca->node_type)\r
87                 return;\r
88         printf("%s '%s'\n", ((unsigned int)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"), ca->ca_name);\r
89         printf("\t%s type: %s\n", ((unsigned int)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"),ca->ca_type);\r
90         printf("\tNumber of ports: %d\n", ca->numports);\r
91         printf("\tFirmware version: %s\n", ca->fw_ver);\r
92         printf("\tHardware version: %s\n", ca->hw_ver);\r
93         printf("\tNode GUID: 0x%016"PRIx64"\n", ntohll(ca->node_guid));\r
94         printf("\tSystem image GUID: 0x%016"PRIx64"\n", ntohll(ca->system_guid));\r
95 }\r
96 \r
97 static char *port_state_str[] = {\r
98         "???",\r
99         "Down",\r
100         "Initializing",\r
101         "Armed",\r
102         "Active"\r
103 };\r
104 \r
105 static char *port_phy_state_str[] = {\r
106         "No state change",\r
107         "Sleep",\r
108         "Polling",\r
109         "Disabled",\r
110         "PortConfigurationTraining",\r
111         "LinkUp",\r
112         "LinkErrorRecovery",\r
113         "PhyTest"\r
114 };\r
115 \r
116 static int\r
117 port_dump(umad_port_t *port, int alone)\r
118 {\r
119         char *pre = "";\r
120         char *hdrpre = "";\r
121 \r
122         if (!port)\r
123                 return -1;\r
124 \r
125         if (!alone) {\r
126                 pre = "         ";\r
127                 hdrpre = "      ";\r
128         }\r
129 \r
130         printf("%sPort %d:\n", hdrpre, port->portnum);\r
131         printf("%sState: %s\n", pre, (unsigned int)port->state <= 4 ? port_state_str[port->state] : "???");\r
132         printf("%sPhysical state: %s\n", pre, (unsigned int)port->state <= 7 ? port_phy_state_str[port->phys_state] : "???");\r
133         printf("%sRate: %d\n", pre, port->rate);\r
134         printf("%sBase lid: %d\n", pre, port->base_lid);\r
135         printf("%sLMC: %d\n", pre, port->lmc);\r
136         printf("%sSM lid: %d\n", pre, port->sm_lid);\r
137         printf("%sCapability mask: 0x%08x\n", pre, (unsigned int)ntohll(port->capmask));\r
138         printf("%sPort GUID: 0x%016"PRIx64"\n", pre, (long long unsigned)ntohll(port->port_guid));\r
139         return 0;\r
140 }\r
141 \r
142 static int\r
143 ca_stat(char *ca_name, int portnum, int no_ports)\r
144 {\r
145         umad_ca_t ca;\r
146         int r;\r
147 \r
148         if ((r = umad_get_ca(ca_name, &ca)) < 0)\r
149                 return r;\r
150 \r
151         if (!ca.node_type)\r
152                 return 0;\r
153 \r
154         if (!no_ports && portnum >= 0) {\r
155                 if (portnum > ca.numports || !ca.ports[portnum]) {\r
156                         IBWARN("%s: '%s' has no port number %d - max (%d)",\r
157                                 ((unsigned int)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"),\r
158                                 ca_name, portnum, ca.numports);\r
159                         return -1;\r
160                 }\r
161                 printf("%s: '%s'\n", ((unsigned int)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"), ca.ca_name);\r
162                 port_dump(ca.ports[portnum], 1);\r
163                 return 0;\r
164         }\r
165 \r
166         /* print ca header */\r
167         ca_dump(&ca);\r
168 \r
169         if (no_ports)\r
170                 return 0;\r
171 \r
172         for (portnum = 0; portnum < ca.numports; portnum++)\r
173                 port_dump(ca.ports[portnum], 0);\r
174 \r
175         return 0;\r
176 }\r
177 \r
178 static int\r
179 ports_list(char names[][UMAD_CA_NAME_LEN], int n)\r
180 {\r
181         uint64_t guids[64];\r
182         int found, ports, i;\r
183 \r
184         for (i = 0, found = 0; i < n && found < 64; i++) {\r
185                 if ((ports = umad_get_ca_portguids(names[i], guids + found, 64 - found)) < 0)\r
186                         return -1;\r
187                 found += ports;\r
188         }\r
189 \r
190         for (i = 0; i < found; i++)\r
191                 if (guids[i])\r
192                         printf("0x%016"PRIx64"\n", (long long unsigned)ntohll(guids[i]));\r
193         return found;\r
194 }\r
195 \r
196 void\r
197 usage(void)\r
198 {\r
199         fprintf(stderr, "Usage: %s [-d(ebug) -l(ist_of_cas) -s(hort) -p(ort_list) -V(ersion)] <ca_name> [portnum]\n", argv0);\r
200         fprintf(stderr, "\tExamples:\n");\r
201         fprintf(stderr, "\t\t%s -l        # list all IB devices\n", argv0);\r
202         fprintf(stderr, "\t\t%s mthca0 2 # stat port 2 of 'mthca0'\n", argv0);\r
203         exit(-1);\r
204 }\r
205 \r
206 int __cdecl\r
207 main(int argc, char *argv[])\r
208 {\r
209         char names[20][UMAD_CA_NAME_LEN];\r
210         int dev_port = -1;\r
211         int list_only = 0, short_format = 0, list_ports = 0;\r
212         int n, i;\r
213 \r
214         static char str_opts[] = "dlspVhu";\r
215         static struct option long_opts[] = {\r
216                 { "debug", 0, 0, 'd'},\r
217                 { "list_of_cas", 0, 0, 'l'},\r
218                 { "short", 0, 0, 's'},\r
219                 { "port_list", 0, 0, 'p'},\r
220                 { "Version", 0, 0, 'V'},\r
221                 { "help", 0, 0, 'h'},\r
222                 { "usage", 0, 0, 'u'},\r
223                 { 0 }\r
224         };\r
225 \r
226         argv0 = argv[0];\r
227 \r
228         while (1) {\r
229                 int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);\r
230                 if ( ch == -1 )\r
231                         break;\r
232                 switch(ch) {\r
233                 case 'd':\r
234                         debug++;\r
235                         break;\r
236                 case 'l':\r
237                         list_only++;\r
238                         break;\r
239                 case 's':\r
240                         short_format++;\r
241                         break;\r
242                 case 'p':\r
243                         list_ports++;\r
244                         break;\r
245                 case 'V':\r
246                         fprintf(stderr, "%s %s\n", argv0, get_build_version() );\r
247                         exit(-1);\r
248                 default:\r
249                         usage();\r
250                         break;\r
251                 }\r
252         }\r
253         argc -= optind;\r
254         argv += optind;\r
255 \r
256         if (argc > 1)\r
257                 dev_port = strtol(argv[1], 0, 0);\r
258 \r
259         if (umad_init() < 0)\r
260                 IBPANIC("can't init UMAD library");\r
261 \r
262         if ((n = umad_get_cas_names((void *)names, UMAD_CA_NAME_LEN)) < 0)\r
263                 IBPANIC("can't list IB device names");\r
264 \r
265         if (argc) {\r
266                 for (i = 0; i < n; i++)\r
267                         if (!strncmp(names[i], argv[0], sizeof names[i]))\r
268                                 break;\r
269                 if (i >= n)\r
270                         IBPANIC("'%s' IB device can't be found", argv[0]);\r
271 \r
272                 strncpy(names[i], argv[0], sizeof names[i]);\r
273                 n = 1;\r
274         }\r
275 \r
276         if (list_ports) {\r
277                 if (ports_list(names, n) < 0)\r
278                         IBPANIC("can't list ports");\r
279                 return 0;\r
280         }\r
281 \r
282         if (!list_only && argc) {\r
283                 if (ca_stat(argv[0], dev_port, short_format) < 0)\r
284                         IBPANIC("stat of IB device '%s' failed", argv[0]);\r
285                 return 0;\r
286         }\r
287 \r
288         for (i = 0; i < n; i++) {\r
289                 if (list_only)\r
290                         printf("%s\n", names[i]);\r
291                 else\r
292                         if (ca_stat(names[i], -1, short_format) < 0)\r
293                                 IBPANIC("stat of IB device '%s' failed", names[i]);\r
294         }\r
295 \r
296         return 0;\r
297 }\r