[IBBUS,HW] add standby/hibernation support to IBBUS. [mlnx: 4750]
[mirror/winof/.git] / tools / vstat / user / vstat_main.c
1 /*\r
2  * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
5  *\r
6  * This software is available to you under the OpenIB.org BSD license\r
7  * below:\r
8  *\r
9  *     Redistribution and use in source and binary forms, with or\r
10  *     without modification, are permitted provided that the following\r
11  *     conditions are met:\r
12  *\r
13  *      - Redistributions of source code must retain the above\r
14  *        copyright notice, this list of conditions and the following\r
15  *        disclaimer.\r
16  *\r
17  *      - Redistributions in binary form must reproduce the above\r
18  *        copyright notice, this list of conditions and the following\r
19  *        disclaimer in the documentation and/or other materials\r
20  *        provided with the distribution.\r
21  *\r
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
29  * SOFTWARE.\r
30  *\r
31  * $Id$\r
32  */\r
33 \r
34 \r
35 \r
36 #include "stdio.h"\r
37 #include "string.h"\r
38 #include "stdlib.h"\r
39 \r
40 \r
41 #include <iba/ib_types.h>\r
42 #include <iba/ib_al.h>\r
43 #ifndef WIN32\r
44 #include <complib/cl_device.h>\r
45 #endif\r
46 #include <mthca/mthca_vc.h>\r
47 \r
48 \r
49 #define VEND_ID_MELLNOX 0x02c9\r
50 #define VEND_ID_VOLTAIRE        0x08f1\r
51 \r
52 enum link_speed_type_e {\r
53         LINK_SPEED_SUPPORTED = 0,\r
54         LINK_SPEED_ENABLED,\r
55         LINK_SPEED_ACTIVE\r
56 };\r
57 \r
58 /*******************************************************************\r
59 *******************************************************************/\r
60 \r
61 \r
62 void print64bit(ib_net64_t u64, BOOLEAN hexFormat){\r
63         ib_net64_t mask = (1<<16)-1;\r
64         ib_net16_t tmp;\r
65         int i;\r
66         for(i=0;i<4;i++){\r
67                 tmp = (uint16_t)((u64>>(i*16))& mask);\r
68                 if(hexFormat){\r
69                         printf("%04x",cl_hton16(tmp));\r
70                         if(i<3){\r
71                                 printf(":");\r
72                         }\r
73                 }else{\r
74                         \r
75                         if((tmp>>8)<100){\r
76                                 printf("%02d", tmp>>8);\r
77                         }else{\r
78                                 printf("%03d", tmp>>8);\r
79                         }\r
80                         printf(".");\r
81                         if((tmp&(mask<<8)) <100){\r
82                                 printf("%02d", tmp&(mask<<8));\r
83                         }else{\r
84                                 printf("%03d", tmp&(mask<<8));\r
85                         }\r
86                         \r
87                 }\r
88         }\r
89 }       \r
90 \r
91 void printGUID(char *title, ib_net64_t guid){\r
92         printf(title);\r
93         print64bit(guid, TRUE);\r
94         printf("\n");\r
95 }\r
96 \r
97 void printPortGID(ib_net64_t subnetPrefix, ib_net64_t portGuid){\r
98         printf("\t\tGID[0]=");\r
99         print64bit(subnetPrefix, TRUE);\r
100         printf(":");\r
101         print64bit(portGuid, TRUE);\r
102         printf("\n");\r
103 }\r
104 \r
105 \r
106 void printPortLinkState(int portState){ //TODO: check that these are all the options and that they are correct\r
107         switch(portState){\r
108                 case 1:\r
109                         printf("\t\tport_state=PORT_DOWN (%d)\n",portState);\r
110                         break;\r
111                 case 2:\r
112                         printf("\t\tport_state=PORT_INITIALIZE (%d)\n",portState);\r
113                         break;\r
114                 case 3:\r
115                         printf("\t\tport_state=PORT_ARMED (%d)\n",portState);\r
116                         break;\r
117                 case 4:\r
118                         printf("\t\tport_state=PORT_ACTIVE (%d)\n",portState);\r
119                         break;\r
120                 case 5:\r
121                         printf("\t\tport_state=PORT_ACTDEFER (%d)\n",portState);\r
122                         break;\r
123                 default:\r
124                         printf("\t\tport_state=UNKNOWN (%d)\n",portState); \r
125         }\r
126 }\r
127 \r
128 void printPortPhysState(uint8_t physState){ \r
129         switch(physState){\r
130                 case 1:\r
131                         printf("\t\tport_phys_state=SLEEP (%d)\n",physState);\r
132                         break;\r
133                 case 2:\r
134                         printf("\t\tport_phys_state=POLLING (%d)\n",physState);\r
135                         break;\r
136                 case 3:\r
137                         printf("\t\tport_phys_state=DISABLED (%d)\n",physState);\r
138                         break;\r
139                 case 4:\r
140                         printf("\t\tport_phys_state=CFG_TRAINING (%d)\n",physState);\r
141                         break;\r
142                 case 5:\r
143                         printf("\t\tport_phys_state=LINK_UP (%d)\n",physState);\r
144                         break;\r
145                 case 6:\r
146                         printf("\t\tport_phys_state=LINK_ERROR_RECOVERY (%d)\n",physState);\r
147                         break;\r
148                 case 7:\r
149                         printf("\t\tport_phys_state=PHY_TEST (%d)\n",physState);\r
150                         break;\r
151                 default:\r
152                         printf("\t\tport_phys_state=UNKNOWN (%d)\n",physState); \r
153         }\r
154 }\r
155 \r
156 void printPortRate(enum link_speed_type_e link_speed_type, int speed, int width, int portState, BOOLEAN moreVerbose){\r
157         char *link_speed_type_str[] = { "Supported", "Enabled", "Active" };\r
158 \r
159         if ((portState == 1) && (link_speed_type == LINK_SPEED_ACTIVE)){ /* In case the port is in Down state */\r
160                 printf("\t\tlink_speed=NA\n");\r
161                 printf("\t\tlink_width=NA \n\t\trate=NA\n");\r
162         }else{\r
163                 if (moreVerbose) {\r
164                         int link_width_arr[4] = { 1, 4, 8, 12 };\r
165                         float link_rate_arr[4] = { 2.5, 10.0, 20.0, 30.0 };\r
166                         int i, link_flag;\r
167                         float base_speed = 2.5;\r
168 \r
169                         link_flag = 0;\r
170                         printf("\t\t%s_link_speed=", link_speed_type_str[link_speed_type]);\r
171                         for (i=1; i <= 4; i*=2)\r
172                                 if (speed & i) {\r
173                                         printf("%2.1f Gbps (%d), ", base_speed*i, i);\r
174                                         link_flag = 1;\r
175                                 }\r
176                         if (!link_flag)\r
177                                 printf("UNKNOWN (%d)",speed);\r
178                         printf("\n");\r
179 \r
180                         link_flag = 0;\r
181                         printf("\t\t%s_link_width=", link_speed_type_str[link_speed_type]);\r
182                         for (i=0; i < 4; i++)\r
183                                 if ((width >> i) & 1) {\r
184                                         printf("%dx (%d), ", link_width_arr[i], 1<<i);\r
185                                         link_flag = 1;\r
186                                 }\r
187                         if (!link_flag)\r
188                                 printf("UNKNOWN (%d)",width);\r
189                         printf("\n");\r
190 \r
191                         if (link_speed_type == LINK_SPEED_ACTIVE) {\r
192                                 link_flag = 0;\r
193                                 printf("\t\t%s_rate=", link_speed_type_str[link_speed_type]);\r
194                                 for (i=0; i < 4; i++)\r
195                                         if ((width >> i) & 1) {\r
196                                                 printf("%2.1f Gbps, ", (i+1)*link_rate_arr[i]);\r
197                                                 link_flag = 1;\r
198                                         }\r
199                                 if (!link_flag)\r
200                                         printf("UNKNOWN (%d)",speed);\r
201                                 printf("\n");\r
202                         }\r
203                 }\r
204                 else {\r
205                         switch(speed){\r
206                         case 1:\r
207                                 printf("\t\tlink_speed=2.5 Gbps (%d)\n",speed);\r
208                                 break;\r
209                         case 2:\r
210                                 printf("\t\tlink_speed=5.0 Gbps (%d)\n",speed);\r
211                                 break;\r
212                         case 4:\r
213                                 printf("\t\tlink_speed=10.0 Gbps (%d)\n",speed);\r
214                                 break;\r
215                         default:\r
216                                 printf("\t\tlink_speed=UNKNOWN (%d)\n",speed); \r
217                 }\r
218 \r
219                         switch (width){\r
220                         case 1:\r
221                                 printf("\t\tlink_width=1x (%f) \n\t\trate=%d Gbps\n",width,2.5*speed);\r
222                                 break;\r
223                         case 2:\r
224                                 printf("\t\tlink_width=4x (%d) \n\t\trate=%d Gbps\n",width,10*speed);\r
225                                 break;\r
226                         case 4:\r
227                                 printf("\t\tlink_width=8x (%d) \n\t\trate=%d Gbps\n",width,20*speed);\r
228                                 break;\r
229                         case 8:\r
230                                 printf("\t\tlink_width=12x (%d) \n\t\trate=%d Gbps\n",width,30*speed);\r
231                                 break;\r
232                         default:\r
233                                 printf("\t\tlink_width=UNKNOWN (%d)\n",width);\r
234                 }\r
235 \r
236                 }\r
237         }\r
238 }\r
239 \r
240 \r
241 void printPortMTU(int mtu){ //TODO: check that these are all the options and that they are correct\r
242         switch(mtu){\r
243                 case 1:\r
244                         printf("\t\tmax_mtu=256 (%d)\n",mtu);\r
245                         break;\r
246                 case 2:\r
247                         printf("\t\tmax_mtu=512 (%d)\n",mtu);\r
248                         break;\r
249                 case 3:\r
250                         printf("\t\tmax_mtu=1024 (%d)\n",mtu);\r
251                         break;\r
252                 case 4:\r
253                         printf("\t\tmax_mtu=2048 (%d)\n",mtu);\r
254                         break;\r
255                 case 5:\r
256                         printf("\t\tmax_mtu=4096 (%d)\n",mtu);\r
257                         break;\r
258                 default:\r
259                         printf("\t\tmax_mtu=UNKNOWN (%d)\n",mtu); \r
260         }\r
261 }\r
262 \r
263 void printPortCaps(ib_port_cap_t *ibal_port_cap_p)\r
264 {\r
265 #define PRINT_CAP(cap, name)    if (ibal_port_cap_p->cap) printf( #name "," )\r
266         \r
267         printf("\t\tcapabilities: ");\r
268         PRINT_CAP(cm, CM);\r
269         PRINT_CAP(snmp, SNMP_TUNNEL);\r
270         PRINT_CAP(dev_mgmt, DEVICE_MGMT);\r
271         PRINT_CAP(sm_disable, SM_DISABLED);\r
272         PRINT_CAP(sm, SM);\r
273         PRINT_CAP(vend, VENDOR_CLASS);\r
274         PRINT_CAP(notice, NOTICE);\r
275         PRINT_CAP(trap, TRAP);\r
276         PRINT_CAP(apm, APM);\r
277         PRINT_CAP(slmap, SL_MAP);\r
278         PRINT_CAP(ledinfo, LED_INFO);\r
279         PRINT_CAP(client_reregister, CLIENT_REG);\r
280         PRINT_CAP(sysguid, SYSGUID);\r
281         PRINT_CAP(boot_mgmt, BOOT_MGMT);\r
282         PRINT_CAP(pkey_switch_ext_port, PKEY_SW_EXT_PORT_TRAP);\r
283         PRINT_CAP(link_rtl, LINK_LATENCY);\r
284         PRINT_CAP(reinit, REINIT);\r
285         PRINT_CAP(ipd, OPT_IPD);\r
286         PRINT_CAP(mkey_nvram, MKEY_NVRAM);\r
287         PRINT_CAP(pkey_nvram, PKEY_NVRAM);\r
288         printf("\n");\r
289 }\r
290 \r
291 void printPortActiveSpeed(uint8_t speed){ \r
292         switch(speed){\r
293                 case 1:\r
294                         printf("\t\tactive_speed=2.5 Gbps (%d)\n",speed);\r
295                         break;\r
296                 case 2:\r
297                         printf("\t\tactive_speed=5.0 Gbps (%d)\n",speed);\r
298                         break;\r
299                 case 4:\r
300                         printf("\t\tactive_speed=10.0 Gbps (%d)\n",speed);\r
301                         break;\r
302                 default:\r
303                         printf("\t\tactive_speed=UNKNOWN (%d)\n",speed); \r
304         }\r
305 }\r
306 \r
307 void printPortInfo(ib_port_attr_t* portPtr, ib_port_info_t portInfo, BOOLEAN fullPrint, BOOLEAN moreVerbose){\r
308         printf("\t\tport=%d\n", portPtr->port_num);\r
309         printPortLinkState(portPtr->link_state);\r
310         if (moreVerbose) {\r
311                 printPortRate(LINK_SPEED_SUPPORTED, portInfo.state_info1>>4, portInfo.link_width_supported, portPtr->link_state, moreVerbose);\r
312                 printPortRate(LINK_SPEED_ENABLED, (portInfo.link_speed & 0xF), portInfo.link_width_enabled, portPtr->link_state, moreVerbose);\r
313         }\r
314         printPortRate(LINK_SPEED_ACTIVE, portInfo.link_speed>>4, portInfo.link_width_active, portPtr->link_state, moreVerbose);\r
315         printPortPhysState(portPtr->phys_state);\r
316         printPortActiveSpeed(portPtr->active_speed);\r
317         printf("\t\tsm_lid=0x%04x\n", cl_ntoh16(portPtr->sm_lid));\r
318         printf("\t\tport_lid=0x%04x\n", cl_ntoh16(portPtr->lid));\r
319         printf("\t\tport_lmc=0x%x\n", portPtr->lmc);\r
320         printPortMTU(portPtr->mtu);\r
321         if(fullPrint){\r
322                 printf("\t\tmax_msg_sz=0x%x     (Max message size)\n", portPtr->max_msg_size);\r
323                 printPortCaps( &portPtr->cap );\r
324                 printf("\t\tmax_vl_num=0x%x             (Maximum number of VL supported by this port)\n", portPtr->max_vls);\r
325                 printf("\t\tbad_pkey_counter=0x%x       (Bad PKey counter)\n", portPtr->pkey_ctr);\r
326                 printf("\t\tqkey_viol_counter=0x%x      (QKey violation counter)\n", portPtr->qkey_ctr);\r
327                 printf("\t\tsm_sl=0x%x          (IB_SL to be used in communication with subnet manager)\n", portPtr->sm_sl);\r
328                 printf("\t\tpkey_tbl_len=0x%x   (Current size of pkey table)\n", portPtr->num_pkeys);\r
329                 printf("\t\tgid_tbl_len=0x%x    (Current size of GID table)\n", portPtr->num_gids);\r
330                 printf("\t\tsubnet_timeout=0x%x (Subnet Timeout for this port (see PortInfo))\n", portPtr->subnet_timeout);\r
331                 printf("\t\tinitTypeReply=0x%x  (optional InitTypeReply value. 0 if not supported)\n", portPtr->init_type_reply);\r
332                 printPortGID(portPtr->p_gid_table->unicast.prefix, portPtr->p_gid_table->unicast.interface_id);\r
333         }\r
334         printf("\n");\r
335 }\r
336 \r
337 void print_uplink_info(ib_ca_attr_t* ca_attr)\r
338 {\r
339         uplink_info_t*p_uplink_info = mthca_get_uplink_info(ca_attr);\r
340         char *bus_type, *link_speed, cap;\r
341         int freq;\r
342 \r
343         switch (p_uplink_info->bus_type) {\r
344                 case UPLINK_BUS_PCI: bus_type = "PCI"; break;\r
345                 case UPLINK_BUS_PCIX: bus_type = "PCI_X"; break;\r
346                 case UPLINK_BUS_PCIE: bus_type = "PCI_E"; break;\r
347                 default: printf("\tuplink={BUS=UNRECOGNIZED (%d)}\n", p_uplink_info->bus_type); return;\r
348         }\r
349 \r
350         switch (p_uplink_info->bus_type) {\r
351                 case UPLINK_BUS_PCI: \r
352                 case UPLINK_BUS_PCIX:\r
353                         if (p_uplink_info->u.pci_x.capabilities == UPLINK_BUS_PCIX_133)\r
354                                 freq = 133;\r
355                         else\r
356                                 freq = 66;\r
357                         printf("\tuplink={BUS=%s, CAPS=%d MHz}\n", bus_type, freq ); \r
358                         break;\r
359 \r
360                 case UPLINK_BUS_PCIE:\r
361                         cap = p_uplink_info->u.pci_e.capabilities;\r
362                         if (p_uplink_info->u.pci_e.link_speed == UPLINK_BUS_PCIE_SDR)\r
363                                 link_speed = "2.5 Gbps";\r
364                         else\r
365                         if (p_uplink_info->u.pci_e.link_speed == UPLINK_BUS_PCIE_DDR)\r
366                                 link_speed = "5.0 Gbps";\r
367                         else\r
368                                 link_speed = "unknown";\r
369                         printf("\tuplink={BUS=%s, SPEED=%s, WIDTH=x%d, CAPS=%s*x%d}\n",\r
370                                 bus_type, link_speed, p_uplink_info->u.pci_e.link_width,\r
371                                 (cap&1) ? "2.5" : "5", cap>>2 ); \r
372                         break;\r
373         }\r
374 \r
375         /* MSI-X */\r
376         if (p_uplink_info->x.valid)\r
377                 printf("\tMSI-X={ENABLED=%d, SUPPORTED=%d, GRANTED=%d, ALL_MASKED=%s}\n",\r
378                         p_uplink_info->x.enabled, p_uplink_info->x.requested,\r
379                         p_uplink_info->x.granted, p_uplink_info->x.masked ? "Y" : "N"); \r
380 }\r
381 \r
382 void vstat_print_ca_attr(int idx,  ib_ca_attr_t* ca_attr, ib_port_info_t* vstat_port_info, \r
383                          BOOLEAN fullPrint, BOOLEAN moreVerbose){\r
384         int i;\r
385 \r
386         printf("\n\thca_idx=%d\n", idx);\r
387         print_uplink_info(ca_attr);\r
388         printf("\tvendor_id=0x%04x\n", ca_attr->vend_id);\r
389         if(moreVerbose)\r
390                 printf("\tvendor_part_id=0x%04x (%d)\n", ca_attr->dev_id, ca_attr->dev_id);\r
391         else\r
392                 printf("\tvendor_part_id=%hu\n", ca_attr->dev_id);\r
393 \r
394         if (!ca_attr->num_ports) {\r
395                 printf("\n\tATTENTION! \n\t    The driver has reported zero physical ports. "\r
396                         "\n\t    It can be a result of incompatibility of user and kernel components."\r
397                         "\n\t    It can be also caused by a driver failure on startup. "\r
398                         "\n\t    Look into System Event Log for driver reports. "\r
399                         "\n\t    Use firmware tools to solve the problem (in second case)."\r
400                         "\n\t    The work with IB stack is impossible. \n");\r
401                 return;\r
402         }\r
403         \r
404         printf("\thw_ver=0x%x\n", ca_attr->revision); //TODO: ???\r
405         if(ca_attr->vend_id == VEND_ID_MELLNOX || ca_attr->vend_id == VEND_ID_VOLTAIRE) {\r
406                 printf("\tfw_ver=%d.%.2d.%.4d\n",\r
407                 (uint16_t)(ca_attr->fw_ver>>32),\r
408                 (uint16_t)(ca_attr->fw_ver>>16),\r
409                 (uint16_t)(ca_attr->fw_ver));\r
410                 printf("\tPSID=%s\n",mthca_get_board_id(ca_attr));\r
411         }else{\r
412                 printf("\tfw_ver=0x%I64x\n",ca_attr->fw_ver);\r
413         }\r
414         printGUID("\tnode_guid=", ca_attr->ca_guid);\r
415         if(fullPrint){\r
416                 printGUID("\tsys_image_guid=", ca_attr->system_image_guid);\r
417                 printf("\tnum_phys_ports = %d\n",ca_attr->num_ports);\r
418                 printf("\tmax_num_qp = 0x%x             (Maximum Number of QPs supported)\n", ca_attr->max_qps);\r
419                 printf("\tmax_qp_ous_wr = 0x%x          (Maximum Number of outstanding WR on any WQ)\n", ca_attr->max_wrs);\r
420                 printf("\tmax_num_sg_ent = 0x%x         (Max num of scatter/gather entries for WQE other than RD)\n", ca_attr->max_sges);\r
421                 printf("\tmax_num_sg_ent_rd = 0x%x              (Max num of scatter/gather entries for RD WQE)\n",  ca_attr->max_rd_sges);\r
422                 printf("\tmax_num_srq = 0x%x            (Maximum Number of SRQs supported)\n", ca_attr->max_srq);\r
423                 printf("\tmax_wqe_per_srq = 0x%x        (Maximum Number of outstanding WR on any SRQ)\n", ca_attr->max_srq_wrs);\r
424                 printf("\tmax_srq_sentries = 0x%x               (Maximum Number of scatter/gather entries for SRQ WQE)\n", ca_attr->max_srq_sges);\r
425                 printf("\tsrq_resize_supported = %d     (SRQ resize supported)\n", ca_attr->modify_srq_depth);\r
426                 printf("\tmax_num_cq = 0x%x             (Max num of supported CQs)\n", ca_attr->max_cqs);\r
427                 printf("\tmax_num_ent_cq = 0x%x (Max num of supported entries per CQ)\n", ca_attr->max_cqes);\r
428                 printf("\tmax_num_mr = 0x%x             (Maximum number of memory region supported)\n", ca_attr->init_regions);\r
429                 printf("\tmax_mr_size = 0x%x    (Largest contiguous block of memory region in bytes)\n", ca_attr->init_region_size);\r
430                 printf("\tmax_pd_num = 0x%x             (Maximum number of protection domains supported)\n", ca_attr->max_pds);\r
431                 printf("\tpage_size_cap = 0x%x          (Largest page size supported by this HCA)\n",ca_attr->p_page_size[ca_attr->num_page_sizes-1]);\r
432 \r
433                 printf("\tlocal_ca_ack_delay = 0x%x     (Log2 4.096usec Max. RX to ACK or NAK delay)\n", ca_attr->local_ack_delay);\r
434                 printf("\tmax_qp_ous_rd_atom = 0x%x     (Maximum number of oust. RDMA read/atomic as target)\n",ca_attr->max_qp_resp_res);\r
435                 printf("\tmax_ee_ous_rd_atom = 0                (EE Maximum number of outs. RDMA read/atomic as target)\n");\r
436                 printf("\tmax_res_rd_atom = 0x%x                (Max. Num. of resources used for RDMA read/atomic as target)\n",ca_attr->max_resp_res);\r
437                 printf("\tmax_qp_init_rd_atom = 0x%x    (Max. Num. of outs. RDMA read/atomic as initiator)\n",ca_attr->max_qp_init_depth);\r
438                 printf("\tmax_ee_init_rd_atom = 0               (EE Max. Num. of outs. RDMA read/atomic as initiator)\n");\r
439                 printf("\tatomic_cap = %s               (Level of Atomicity supported)\n",ca_attr->atomicity == IB_ATOMIC_GLOBAL?"GLOBAL":\r
440                                                                                                                                         ca_attr->atomicity == IB_ATOMIC_LOCAL?"LOCAL":"NORMAL");\r
441                 printf("\tmax_ee_num = 0x0              (Maximum number of EEC supported)\n");\r
442                 printf("\tmax_rdd_num = 0x0             (Maximum number of IB_RDD supported)\n");\r
443                 printf("\tmax_mw_num = 0x%x             (Maximum Number of memory windows supported)\n", ca_attr->init_windows);\r
444                 printf("\tmax_raw_ipv6_qp = 0x%x                (Maximum number of Raw IPV6 QPs supported)\n", ca_attr->max_ipv6_qps);\r
445                 printf("\tmax_raw_ethy_qp = 0x%x                (Maximum number of Raw Ethertypes QPs supported)\n", ca_attr->max_ether_qps);\r
446                 printf("\tmax_mcast_grp_num = 0x%x      (Maximum Number of multicast groups)\n", ca_attr->max_mcast_grps);\r
447                 printf("\tmax_mcast_qp_attach_num = 0x%x        (Maximum number of QP per multicast group)\n", ca_attr->max_qps_per_mcast_grp);\r
448                 printf("\tmax_ah_num = 0x%I64x          (Maximum number of address handles)\n", ca_attr->max_addr_handles);\r
449                 printf("\tmax_num_fmr = 0x%x            (Maximum number FMRs)\n", ca_attr->max_fmr);\r
450                 printf("\tmax_num_map_per_fmr = 0x%x    (Maximum number of (re)maps per FMR before an unmap operation in required)\n", ca_attr->max_map_per_fmr);\r
451                 printf("\tmodify_wr_depth = %d          (Capabilities: change QP depth during a modify QP)\n", !!ca_attr->modify_wr_depth);\r
452                 printf("\tmodify_srq_depth = %d                 (Capabilities: change SRQ depth - Not supported by driver!)\n", !!ca_attr->modify_srq_depth);\r
453                 printf("\tchange_primary_port = %d              (Capabilities: change primary port for a QP during a SQD->RTS transition)\n", !!ca_attr->change_primary_port);\r
454                 printf("\tav_port_check = %d            (Capabilities: check port number in address handles)\n", !!ca_attr->av_port_check);\r
455                 printf("\tinit_type_support = %d                (Capabilities: set init_type)\n", !!ca_attr->init_type_support);\r
456                 printf("\tshutdown_port = %d            (Capabilities: shutdown port support)\n", !!ca_attr->shutdown_port_capability);\r
457         }else{\r
458                 printf("\tnum_phys_ports=%d\n",         ca_attr->num_ports);\r
459         }\r
460         for (i = 0; i<ca_attr->num_ports; i++){\r
461                 printPortInfo(ca_attr->p_port_attr+i, vstat_port_info[i], fullPrint, moreVerbose);\r
462         }       \r
463 }\r
464 /* Internal Functions */\r
465 \r
466 void vstat_get_counters(ib_ca_handle_t h_ca,uint8_t port_num)\r
467 {\r
468         ib_mad_t                        *mad_in = NULL;\r
469         ib_mad_t                        *mad_out = NULL;\r
470         ib_port_counters_t      *port_counters;\r
471         ib_api_status_t         ib_status = IB_SUCCESS;\r
472         int i;\r
473         \r
474         mad_out = (ib_mad_t*)cl_zalloc(256);\r
475         CL_ASSERT(mad_out);\r
476 \r
477         mad_in = (ib_mad_t*)cl_zalloc(256);\r
478         CL_ASSERT(mad_in);\r
479 \r
480 \r
481         mad_in->attr_id = IB_MAD_ATTR_PORT_CNTRS;\r
482         mad_in->method = IB_MAD_METHOD_GET;\r
483         mad_in->base_ver = 1;\r
484         mad_in->class_ver =1;\r
485         mad_in->mgmt_class = IB_MCLASS_PERF;\r
486 \r
487         port_counters = (ib_port_counters_t*)(((ib_gmp_t*)mad_in)->data);\r
488 \r
489         port_counters->port_select= port_num;\r
490         port_counters->counter_select= 0xff;\r
491 \r
492         ib_status = ib_local_mad(h_ca ,port_num ,mad_in ,mad_out);\r
493         if(ib_status != IB_SUCCESS)\r
494         {\r
495                 printf("ib_local_mad failed with status = %d\n", ib_status);\r
496                 return;\r
497         }\r
498         \r
499         port_counters = (ib_port_counters_t*)(((ib_gmp_t*)mad_out)->data);\r
500 \r
501         printf("\n\tport counters for port %d\n",port_num);\r
502         printf("\t\tlink_error_recovery_counter\t0x%x \n",port_counters->link_error_recovery_counter);\r
503         printf("\t\tlink_down_counter\t\t0x%x \n",port_counters->link_down_counter);\r
504         printf("\t\tport_rcv_errors\t\t\t0x%x \n",CL_NTOH16(port_counters->port_rcv_errors));\r
505         printf("\t\tport_rcv_remote_physical_errors\t0x%x \n",CL_NTOH16(port_counters->port_rcv_remote_physical_errors));\r
506         printf("\t\tport_rcv_switch_relay_errors\t0x%x \n",CL_NTOH16(port_counters->port_rcv_switch_relay_errors));\r
507         printf("\t\tport_xmit_discard\t\t0x%x \n",CL_NTOH16(port_counters->port_xmit_discard));\r
508         printf("\t\tport_xmit_constraint_errors\t0x%x \n",port_counters->port_xmit_constraint_errors);\r
509         printf("\t\tport_rcv_constraint_errors\t0x%x \n",port_counters->port_rcv_constraint_errors);\r
510         printf("\t\tvl15_dropped\t\t\t0x%x \n",CL_NTOH16(port_counters->vl15_dropped));\r
511         printf("\t\tport_rcv_data\t\t\t0x%x \n",CL_NTOH32(port_counters->port_rcv_data));\r
512         printf("\t\tport_xmit_data\t\t\t0x%x \n",CL_NTOH32(port_counters->port_xmit_data));\r
513         printf("\t\tport_rcv_pkts\t\t\t0x%x \n",CL_NTOH32(port_counters->port_rcv_pkts));\r
514         printf("\t\tport_xmit_pkts\t\t\t0x%x \n\n",CL_NTOH32(port_counters->port_xmit_pkts));\r
515         \r
516 }\r
517 \r
518 \r
519 void vstat_get_port_info(ib_ca_handle_t h_ca,uint8_t port_num, ib_port_info_t* vstat_port_info)\r
520 {\r
521         ib_mad_t                        *mad_in = NULL;\r
522         ib_mad_t                        *mad_out = NULL;\r
523         ib_api_status_t         ib_status = IB_SUCCESS;\r
524         int i;\r
525         \r
526         mad_out = (ib_mad_t*)cl_zalloc(256);\r
527         CL_ASSERT(mad_out);\r
528 \r
529         mad_in = (ib_mad_t*)cl_zalloc(256);\r
530         CL_ASSERT(mad_in);\r
531 \r
532 \r
533         mad_in->attr_id = IB_MAD_ATTR_PORT_INFO;\r
534         mad_in->method = IB_MAD_METHOD_GET;\r
535         mad_in->base_ver = 1;\r
536         mad_in->class_ver =1;\r
537         mad_in->mgmt_class = IB_MCLASS_SUBN_LID;\r
538         \r
539 \r
540 \r
541         ib_status = ib_local_mad(h_ca ,port_num ,mad_in ,mad_out);\r
542         if(ib_status != IB_SUCCESS &&  0 != mad_in->status )\r
543         {\r
544                 printf("ib_local_mad failed with status = %d mad status = %d\n", ib_status,mad_in->status);\r
545                 return;\r
546         }\r
547 \r
548         cl_memcpy(vstat_port_info,(ib_port_info_t*)(((ib_smp_t*)mad_out)->data),sizeof(ib_port_info_t));\r
549 \r
550         \r
551 }\r
552 \r
553 \r
554 ib_api_status_t\r
555 vstat_ca_attr(\r
556         boolean_t modify_attr,\r
557         BOOLEAN fullPrint,\r
558         BOOLEAN getCounters,\r
559         BOOLEAN moreVerbose\r
560         )\r
561 {\r
562         ib_al_handle_t          h_al = NULL;\r
563         ib_api_status_t         ib_status = IB_SUCCESS;\r
564         ib_api_status_t         ret_status = IB_SUCCESS;\r
565         size_t                  guid_count;\r
566         ib_net64_t              *ca_guid_array;\r
567         ib_ca_attr_t            *vstat_ca_attr;\r
568         ib_port_info_t          vstat_port_info[2];\r
569         size_t                  i;\r
570         ib_ca_handle_t  h_ca = NULL;\r
571         uint32_t                        bsize;\r
572         ib_port_attr_mod_t port_attr_mod;\r
573         uint8_t                 port_idx;\r
574 \r
575         while(1)\r
576         {\r
577                 /*\r
578                  * Open the AL instance\r
579                  */\r
580                 ib_status = ib_open_al(&h_al);\r
581                 if(ib_status != IB_SUCCESS)\r
582                 {\r
583                         printf("ib_open_al failed status = %d\n", ib_status);\r
584                         ret_status = ib_status;                 \r
585                         break;\r
586                 }\r
587                 //xxxx\r
588                 //printf("ib_open_al PASSED.\n");\r
589                 //xxx\r
590                 CL_ASSERT(h_al);\r
591 \r
592                 /*\r
593                  * Get the Local CA Guids\r
594                  */\r
595                 ib_status = ib_get_ca_guids(h_al, NULL, &guid_count);\r
596                 if(ib_status != IB_INSUFFICIENT_MEMORY)\r
597                 {\r
598                         printf("ib_get_ca_guids1 failed status = %d\n", (uint32_t)ib_status);\r
599                         ret_status = ib_status;                 \r
600                         goto Cleanup1;\r
601                 }\r
602 \r
603                 \r
604 \r
605                 /*\r
606                  * If no CA's Present then return\r
607                  */\r
608 \r
609                 if(guid_count == 0)\r
610                         goto Cleanup1;\r
611 \r
612                 \r
613                 ca_guid_array = (ib_net64_t*)cl_malloc(sizeof(ib_net64_t) * guid_count);\r
614                 CL_ASSERT(ca_guid_array);\r
615                 \r
616                 ib_status = ib_get_ca_guids(h_al, ca_guid_array, &guid_count);\r
617                 if(ib_status != IB_SUCCESS)\r
618                 {\r
619                         printf("ib_get_ca_guids2 failed with status = %d\n", ib_status);\r
620                         ret_status = ib_status;                 \r
621                         goto Cleanup1;\r
622                 }\r
623 \r
624                 \r
625 \r
626                 /*\r
627                  * For Each CA Guid found Open the CA,\r
628                  * Query the CA Attribute and close the CA\r
629                  */\r
630                 for(i=0; i < guid_count; i++)\r
631                 {\r
632 \r
633                         /* Open the CA */\r
634                         ib_status = ib_open_ca(h_al,\r
635                                 ca_guid_array[i],\r
636                                 NULL,\r
637                                 NULL,   //ca_context\r
638                                 &h_ca);\r
639 \r
640                         if(ib_status != IB_SUCCESS)\r
641                         {\r
642                                 printf("ib_open_ca failed with status = %d\n", ib_status);\r
643                                 ret_status = ib_status;                         \r
644                                 goto Cleanup1;\r
645                         }\r
646 \r
647                         //xxx\r
648                         //printf("ib_open_ca passed i=%d\n",i); \r
649                         //xxx\r
650 \r
651 \r
652                         /* Query the CA */\r
653                         bsize = 0;\r
654                         ib_status = ib_query_ca(h_ca, NULL, &bsize);\r
655                         if(ib_status != IB_INSUFFICIENT_MEMORY)\r
656                         {\r
657                                 printf("ib_query_ca failed with status = %d\n", ib_status);\r
658                                 ret_status = ib_status;\r
659                                 goto Cleanup2;\r
660                         }\r
661                         CL_ASSERT(bsize);\r
662                         //xxxx\r
663                         //printf("ib_query_ca PASSED bsize = 0x%x.\n",bsize);\r
664                         //xxx\r
665                         /* Allocate the memory needed for query_ca */\r
666 \r
667                         vstat_ca_attr = (ib_ca_attr_t *)cl_zalloc(bsize);\r
668                         CL_ASSERT(vstat_ca_attr);\r
669 \r
670                         ib_status = ib_query_ca(h_ca, vstat_ca_attr, &bsize);\r
671                         if(ib_status != IB_SUCCESS)\r
672                         {\r
673                                 printf("ib_query_ca failed with status = %d\n", ib_status);\r
674                                 ret_status = ib_status;\r
675                                 goto Cleanup2;\r
676                         }\r
677 \r
678                         for(port_idx =0; port_idx< vstat_ca_attr->num_ports;port_idx++){\r
679                                 vstat_get_port_info(h_ca ,port_idx+1,&vstat_port_info[port_idx]);\r
680                         }\r
681 \r
682                         vstat_print_ca_attr((int)i, vstat_ca_attr, vstat_port_info, fullPrint, moreVerbose);\r
683                         if(getCounters)\r
684                         {\r
685                                 for(port_idx =0; port_idx< vstat_ca_attr->num_ports;port_idx++){\r
686                                         vstat_get_counters(h_ca ,port_idx+1);\r
687                                 }\r
688                         }\r
689                         \r
690                         /* Free the memory */\r
691                         cl_free(vstat_ca_attr);\r
692                         vstat_ca_attr = NULL;\r
693                         /* Close the current open CA */\r
694                         ib_status = ib_close_ca(h_ca, NULL);\r
695                         if(ib_status != IB_SUCCESS)\r
696                         {\r
697                                 printf("ib_close_ca failed status = %d", ib_status);\r
698                                 ret_status = ib_status;\r
699                         }\r
700                         h_ca = NULL;\r
701 \r
702                 }\r
703 \r
704 Cleanup2:\r
705                 if(h_ca != NULL)\r
706                 {\r
707                         ib_status = ib_close_ca(h_ca, NULL);\r
708                         if(ib_status != IB_SUCCESS)\r
709                         {\r
710                                 printf("ib_close_ca failed status = %d", ib_status);\r
711                         }\r
712                 }\r
713 \r
714 Cleanup1:\r
715                 cl_free(ca_guid_array);\r
716                 ib_status = ib_close_al(h_al);\r
717 \r
718                 if(ib_status != IB_SUCCESS)\r
719                 {\r
720                         printf("ib_close_al failed status = %d", ib_status);\r
721                 }\r
722 \r
723                 break;\r
724 \r
725         } //End of while(1)\r
726 \r
727         \r
728         return ret_status;\r
729 }\r
730 \r
731 void vstat_help()\r
732 {\r
733         printf("\n\tUsage: vstat [-v] [-c] [-m]\n");\r
734         printf("\t\t -v - verbose mode\n");\r
735         printf("\t\t -c - HCA error/statistic counters\n");\r
736         printf("\t\t -m - more verbose mode\n");\r
737         \r
738 }\r
739 \r
740 int32_t __cdecl\r
741 main(\r
742         int32_t argc,\r
743         char* argv[])\r
744 {\r
745         ib_api_status_t ib_status;\r
746         BOOLEAN fullPrint = FALSE;\r
747         BOOLEAN getCounters = FALSE;\r
748         BOOLEAN showHelp = FALSE;\r
749         BOOLEAN moreVerbose = FALSE;\r
750         if(argc>1){\r
751                 int i = 2;\r
752                 while(i<=argc){\r
753                         if(!_stricmp(argv[i-1], "-v")){\r
754                                 fullPrint = TRUE;\r
755                                 i+=1;\r
756                         }else if(!_stricmp(argv[i-1], "-h") || \r
757                                 !_stricmp(argv[i-1], "-help")){\r
758                                 showHelp = TRUE;\r
759                                 i+=1;\r
760                         }else if(!_stricmp(argv[i-1], "-c")){\r
761                                 getCounters = TRUE;\r
762                                 i+=1;\r
763                         }else if(!_stricmp(argv[i-1], "-m")){\r
764                                 fullPrint = TRUE;\r
765                                 moreVerbose = TRUE;\r
766                                 i+=1;\r
767                         }else{\r
768                                 i+=2;\r
769                         }\r
770                 }\r
771         }\r
772         if (showHelp)\r
773                 vstat_help();\r
774         else\r
775                 ib_status = vstat_ca_attr(FALSE, fullPrint,getCounters, moreVerbose);\r
776 \r
777         return 0;\r
778 }\r
779 \r
780 \r
781 \r