b893a667ae369711f63dd5a5037f4148357e802c
[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 \r
53 /*******************************************************************\r
54 *******************************************************************/\r
55 \r
56 \r
57 void print64bit(ib_net64_t u64, BOOLEAN hexFormat){\r
58         ib_net64_t mask = (1<<16)-1;\r
59         ib_net16_t tmp;\r
60         int i;\r
61         for(i=0;i<4;i++){\r
62                 tmp = (uint16_t)((u64>>(i*16))& mask);\r
63                 if(hexFormat){\r
64                         printf("%04x",cl_hton16(tmp));\r
65                         if(i<3){\r
66                                 printf(":");\r
67                         }\r
68                 }else{\r
69                         \r
70                         if((tmp>>8)<100){\r
71                                 printf("%02d", tmp>>8);\r
72                         }else{\r
73                                 printf("%03d", tmp>>8);\r
74                         }\r
75                         printf(".");\r
76                         if((tmp&(mask<<8)) <100){\r
77                                 printf("%02d", tmp&(mask<<8));\r
78                         }else{\r
79                                 printf("%03d", tmp&(mask<<8));\r
80                         }\r
81                         \r
82                 }\r
83         }\r
84 }       \r
85 \r
86 void printGUID(char *title, ib_net64_t guid){\r
87         printf(title);\r
88         print64bit(guid, TRUE);\r
89         printf("\n");\r
90 }\r
91 \r
92 void printPortGID(ib_net64_t subnetPrefix, ib_net64_t portGuid){\r
93         printf("\t\tGID[0]=");\r
94         print64bit(subnetPrefix, TRUE);\r
95         printf(":");\r
96         print64bit(portGuid, TRUE);\r
97         printf("\n");\r
98 }\r
99 \r
100 \r
101 void printPortLinkState(int portState){ //TODO: check that these are all the options and that they are correct\r
102         switch(portState){\r
103                 case 1:\r
104                         printf("\t\tport_state=PORT_DOWN (%d)\n",portState);\r
105                         break;\r
106                 case 2:\r
107                         printf("\t\tport_state=PORT_INITIALIZE (%d)\n",portState);\r
108                         break;\r
109                 case 3:\r
110                         printf("\t\tport_state=PORT_ARMED (%d)\n",portState);\r
111                         break;\r
112                 case 4:\r
113                         printf("\t\tport_state=PORT_ACTIVE (%d)\n",portState);\r
114                         break;\r
115                 case 5:\r
116                         printf("\t\tport_state=PORT_ACTDEFER (%d)\n",portState);\r
117                         break;\r
118                 default:\r
119                         printf("\t\tport_state=UNKNOWN (%d)\n",portState); \r
120         }\r
121 }\r
122 \r
123 void printPortPhysState(uint8_t physState){ \r
124         switch(physState){\r
125                 case 1:\r
126                         printf("\t\tport_phys_state=SLEEP (%d)\n",physState);\r
127                         break;\r
128                 case 2:\r
129                         printf("\t\tport_phys_state=POLLING (%d)\n",physState);\r
130                         break;\r
131                 case 3:\r
132                         printf("\t\tport_phys_state=DISABLED (%d)\n",physState);\r
133                         break;\r
134                 case 4:\r
135                         printf("\t\tport_phys_state=CFG_TRAINING (%d)\n",physState);\r
136                         break;\r
137                 case 5:\r
138                         printf("\t\tport_phys_state=LINK_UP (%d)\n",physState);\r
139                         break;\r
140                 case 6:\r
141                         printf("\t\tport_phys_state=LINK_ERROR_RECOVERY (%d)\n",physState);\r
142                         break;\r
143                 case 7:\r
144                         printf("\t\tport_phys_state=PHY_TEST (%d)\n",physState);\r
145                         break;\r
146                 default:\r
147                         printf("\t\tport_phys_state=UNKNOWN (%d)\n",physState); \r
148         }\r
149 }\r
150 \r
151 void printPortRate(int speed, int width, int portState){ \r
152         if (portState == 1){ /* In case the port is in Down state */\r
153                 printf("\t\tlink_speed=NA\n");\r
154                 printf("\t\tlink_width=NA \n\t\trate=NA\n");            \r
155         }else{  \r
156                 switch(speed){\r
157                         case 1:\r
158                                 printf("\t\tlink_speed=2.5 Gbps (%d)\n",speed);\r
159                                 break;\r
160                         case 2:\r
161                                 printf("\t\tlink_speed=5.0 Gbps (%d)\n",speed);\r
162                                 break;\r
163                         case 4:\r
164                                 printf("\t\tlink_speed=10.0 Gbps (%d)\n",speed);\r
165                                 break;\r
166                         default:\r
167                                 printf("\t\tlink_speed=UNKNOWN (%d)\n",speed); \r
168                 }\r
169 \r
170                 switch (width){\r
171                         case 1:\r
172                                 printf("\t\tlink_width=1x (%f) \n\t\trate=%d Gbps\n",width,2.5*speed);\r
173                                 break;\r
174                         case 2:\r
175                                 printf("\t\tlink_width=4x (%d) \n\t\trate=%d Gbps\n",width,10*speed);\r
176                                 break;\r
177                         case 4:\r
178                                 printf("\t\tlink_width=8x (%d) \n\t\trate=%d Gbps\n",width,20*speed);\r
179                                 break;\r
180                         case 8:\r
181                                 printf("\t\tlink_width=12x (%d) \n\t\trate=%d Gbps\n",width,30*speed);\r
182                                 break;\r
183                         default:\r
184                                 printf("\t\tlink_width=UNKNOWN (%d)\n",width);\r
185                 }\r
186         }\r
187                 \r
188 \r
189 }\r
190 \r
191 \r
192 void printPortMTU(int mtu){ //TODO: check that these are all the options and that they are correct\r
193         switch(mtu){\r
194                 case 1:\r
195                         printf("\t\tmax_mtu=256 (%d)\n",mtu);\r
196                         break;\r
197                 case 2:\r
198                         printf("\t\tmax_mtu=512 (%d)\n",mtu);\r
199                         break;\r
200                 case 3:\r
201                         printf("\t\tmax_mtu=1024 (%d)\n",mtu);\r
202                         break;\r
203                 case 4:\r
204                         printf("\t\tmax_mtu=2048 (%d)\n",mtu);\r
205                         break;\r
206                 case 5:\r
207                         printf("\t\tmax_mtu=4096 (%d)\n",mtu);\r
208                         break;\r
209                 default:\r
210                         printf("\t\tmax_mtu=UNKNOWN (%d)\n",mtu); \r
211         }\r
212 }\r
213 \r
214 void printPortCaps(ib_port_cap_t *ibal_port_cap_p)\r
215 {\r
216 #define PRINT_CAP(cap, name)    if (ibal_port_cap_p->cap) printf( #name "," )\r
217         \r
218         printf("\t\tcapabilities: ");\r
219         PRINT_CAP(cm, CM);\r
220         PRINT_CAP(snmp, SNMP_TUNNEL);\r
221         PRINT_CAP(dev_mgmt, DEVICE_MGMT);\r
222         PRINT_CAP(sm_disable, SM_DISABLED);\r
223         PRINT_CAP(sm, SM);\r
224         PRINT_CAP(vend, VENDOR_CLASS);\r
225         PRINT_CAP(notice, NOTICE);\r
226         PRINT_CAP(trap, TRAP);\r
227         PRINT_CAP(apm, APM);\r
228         PRINT_CAP(slmap, SL_MAP);\r
229         PRINT_CAP(ledinfo, LED_INFO);\r
230         PRINT_CAP(client_reregister, CLIENT_REG);\r
231         PRINT_CAP(sysguid, SYSGUID);\r
232         PRINT_CAP(boot_mgmt, BOOT_MGMT);\r
233         PRINT_CAP(pkey_switch_ext_port, PKEY_SW_EXT_PORT_TRAP);\r
234         PRINT_CAP(link_rtl, LINK_LATENCY);\r
235         PRINT_CAP(reinit, REINIT);\r
236         PRINT_CAP(ipd, OPT_IPD);\r
237         PRINT_CAP(mkey_nvram, MKEY_NVRAM);\r
238         PRINT_CAP(pkey_nvram, PKEY_NVRAM);\r
239         printf("\n");\r
240 }\r
241 \r
242 void printPortActiveSpeed(uint8_t speed){ \r
243         switch(speed){\r
244                 case 1:\r
245                         printf("\t\tactive_speed=2.5 Gbps (%d)\n",speed);\r
246                         break;\r
247                 case 2:\r
248                         printf("\t\tactive_speed=5.0 Gbps (%d)\n",speed);\r
249                         break;\r
250                 case 4:\r
251                         printf("\t\tactive_speed=10.0 Gbps (%d)\n",speed);\r
252                         break;\r
253                 default:\r
254                         printf("\t\tactive_speed=UNKNOWN (%d)\n",speed); \r
255         }\r
256 }\r
257 \r
258 void printPortInfo(ib_port_attr_t* portPtr, ib_port_info_t portInfo, BOOLEAN fullPrint){\r
259         printf("\t\tport=%d\n", portPtr->port_num);\r
260         printPortLinkState(portPtr->link_state);\r
261         printPortRate(portInfo.link_speed>>4,portInfo.link_width_active, portPtr->link_state);\r
262         printPortPhysState(portPtr->phys_state);\r
263         printPortActiveSpeed(portPtr->active_speed);\r
264         printf("\t\tsm_lid=0x%04x\n", cl_ntoh16(portPtr->sm_lid));\r
265         printf("\t\tport_lid=0x%04x\n", cl_ntoh16(portPtr->lid));\r
266         printf("\t\tport_lmc=0x%x\n", portPtr->lmc);\r
267         printPortMTU(portPtr->mtu);\r
268         if(fullPrint){\r
269                 printf("\t\tmax_msg_sz=0x%x     (Max message size)\n", portPtr->max_msg_size);\r
270                 printPortCaps( &portPtr->cap );\r
271                 printf("\t\tmax_vl_num=0x%x             (Maximum number of VL supported by this port)\n", portPtr->max_vls);\r
272                 printf("\t\tbad_pkey_counter=0x%x       (Bad PKey counter)\n", portPtr->pkey_ctr);\r
273                 printf("\t\tqkey_viol_counter=0x%x      (QKey violation counter)\n", portPtr->qkey_ctr);\r
274                 printf("\t\tsm_sl=0x%x          (IB_SL to be used in communication with subnet manager)\n", portPtr->sm_sl);\r
275                 printf("\t\tpkey_tbl_len=0x%x   (Current size of pkey table)\n", portPtr->num_pkeys);\r
276                 printf("\t\tgid_tbl_len=0x%x    (Current size of GID table)\n", portPtr->num_gids);\r
277                 printf("\t\tsubnet_timeout=0x%x (Subnet Timeout for this port (see PortInfo))\n", portPtr->subnet_timeout);\r
278                 printf("\t\tinitTypeReply=0x%x  (optional InitTypeReply value. 0 if not supported)\n", portPtr->init_type_reply);\r
279                 printPortGID(portPtr->p_gid_table->unicast.prefix, portPtr->p_gid_table->unicast.interface_id);\r
280         }\r
281         printf("\n");\r
282 }\r
283 \r
284 void print_uplink_info(ib_ca_attr_t* ca_attr)\r
285 {\r
286         uplink_info_t*p_uplink_info = mthca_get_uplink_info(ca_attr);\r
287         char *bus_type, *link_speed, cap;\r
288         int freq;\r
289 \r
290         switch (p_uplink_info->bus_type) {\r
291                 case UPLINK_BUS_PCI: bus_type = "PCI"; break;\r
292                 case UPLINK_BUS_PCIX: bus_type = "PCI_X"; break;\r
293                 case UPLINK_BUS_PCIE: bus_type = "PCI_E"; break;\r
294                 default: printf("\tuplink={BUS=UNRECOGNIZED (%d)}\n", p_uplink_info->bus_type); return;\r
295         }\r
296 \r
297         switch (p_uplink_info->bus_type) {\r
298                 case UPLINK_BUS_PCI: \r
299                 case UPLINK_BUS_PCIX:\r
300                         if (p_uplink_info->u.pci_x.capabilities == UPLINK_BUS_PCIX_133)\r
301                                 freq = 133;\r
302                         else\r
303                                 freq = 66;\r
304                         printf("\tuplink={BUS=%s, CAPS=%d MHz}\n", bus_type, freq ); \r
305                         return;\r
306 \r
307                 case UPLINK_BUS_PCIE:\r
308                         cap = p_uplink_info->u.pci_e.capabilities;\r
309                         if (p_uplink_info->u.pci_e.link_speed == UPLINK_BUS_PCIE_SDR)\r
310                                 link_speed = "2.5 Gbps";\r
311                         else\r
312                         if (p_uplink_info->u.pci_e.link_speed == UPLINK_BUS_PCIE_DDR)\r
313                                 link_speed = "5.0 Gbps";\r
314                         else\r
315                                 link_speed = "unknown";\r
316                         printf("\tuplink={BUS=%s, SPEED=%s, WIDTH=x%d, CAPS=%s*x%d}\n",\r
317                                 bus_type, link_speed, p_uplink_info->u.pci_e.link_width,\r
318                                 (cap&1) ? "2.5" : "5", cap>>2 ); \r
319                         return;\r
320         }\r
321 }\r
322 \r
323 void vstat_print_ca_attr(int idx,  ib_ca_attr_t* ca_attr, ib_port_info_t* vstat_port_info, BOOLEAN fullPrint){\r
324         int i;\r
325 \r
326         printf("\n\thca_idx=%d\n", idx);\r
327         if (ca_attr->dev_id & 1)\r
328                 printf("\tATTENTION! \n\t    The device is in 'Flash Recovery' mode, probably due to an incorrect firmware."\r
329                         "\n\t    Use firmware tools to solve the problem.\n",idx);\r
330         /*printf("\tpci_location={BUS=NA,DEV/FUNC=NA}\n");*/\r
331         print_uplink_info(ca_attr);\r
332         printf("\tvendor_id=0x%04x\n", ca_attr->vend_id);\r
333         printf("\tvendor_part_id=0x%04x\n", ca_attr->dev_id);\r
334         printf("\thw_ver=0x%x\n", ca_attr->revision); //TODO: ???\r
335         if(ca_attr->vend_id == VEND_ID_MELLNOX || ca_attr->vend_id == VEND_ID_VOLTAIRE) {\r
336                 printf("\tfw_ver=%d.%.2d.%.4d\n",\r
337                 (uint16_t)(ca_attr->fw_ver>>32),\r
338                 (uint16_t)(ca_attr->fw_ver>>16),\r
339                 (uint16_t)(ca_attr->fw_ver));\r
340                 printf("\tPSID=%s\n",mthca_get_board_id(ca_attr));\r
341         }else{\r
342                 printf("\tfw_ver=0x%I64x\n",ca_attr->fw_ver);\r
343         }\r
344         printGUID("\tnode_guid=", ca_attr->ca_guid);\r
345         if(fullPrint){\r
346                 printGUID("\tsys_image_guid=", ca_attr->system_image_guid);\r
347                 printf("\tnum_phys_ports = %d\n",ca_attr->num_ports);\r
348                 printf("\tmax_num_qp = 0x%x             (Maximum Number of QPs supported)\n", ca_attr->max_qps);\r
349                 printf("\tmax_qp_ous_wr = 0x%x          (Maximum Number of outstanding WR on any WQ)\n", ca_attr->max_wrs);\r
350                 printf("\tmax_num_sg_ent = 0x%x         (Max num of scatter/gather entries for WQE other than RD)\n", ca_attr->max_sges);\r
351                 printf("\tmax_num_sg_ent_rd = 0x%x              (Max num of scatter/gather entries for RD WQE)\n",  ca_attr->max_rd_sges);\r
352                 printf("\tmax_num_srq = 0x%x            (Maximum Number of SRQs supported)\n", ca_attr->max_srq);\r
353                 printf("\tmax_wqe_per_srq = 0x%x        (Maximum Number of outstanding WR on any SRQ)\n", ca_attr->max_srq_wrs);\r
354                 printf("\tmax_srq_sentries = 0x%x               (Maximum Number of scatter/gather entries for SRQ WQE)\n", ca_attr->max_srq_sges);\r
355                 printf("\tsrq_resize_supported = %d     (SRQ resize supported)\n", ca_attr->modify_srq_depth);\r
356                 printf("\tmax_num_cq = 0x%x             (Max num of supported CQs)\n", ca_attr->max_cqs);\r
357                 printf("\tmax_num_ent_cq = 0x%x (Max num of supported entries per CQ)\n", ca_attr->max_cqes);\r
358                 printf("\tmax_num_mr = 0x%x             (Maximum number of memory region supported)\n", ca_attr->init_regions);\r
359                 printf("\tmax_mr_size = 0x%x    (Largest contiguous block of memory region in bytes)\n", ca_attr->init_region_size);\r
360                 printf("\tmax_pd_num = 0x%x             (Maximum number of protection domains supported)\n", ca_attr->max_pds);\r
361                 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
362 \r
363                 printf("\tlocal_ca_ack_delay = 0x%x     (Log2 4.096usec Max. RX to ACK or NAK delay)\n", ca_attr->local_ack_delay);\r
364                 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
365                 printf("\tmax_ee_ous_rd_atom = 0                (EE Maximum number of outs. RDMA read/atomic as target)\n");\r
366                 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
367                 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
368                 printf("\tmax_ee_init_rd_atom = 0               (EE Max. Num. of outs. RDMA read/atomic as initiator)\n");\r
369                 printf("\tatomic_cap = %s               (Level of Atomicity supported)\n",ca_attr->atomicity == IB_ATOMIC_GLOBAL?"GLOBAL":\r
370                                                                                                                                         ca_attr->atomicity == IB_ATOMIC_LOCAL?"LOCAL":"NORMAL");\r
371                 printf("\tmax_ee_num = 0x0              (Maximum number of EEC supported)\n");\r
372                 printf("\tmax_rdd_num = 0x0             (Maximum number of IB_RDD supported)\n");\r
373                 printf("\tmax_mw_num = 0x%x             (Maximum Number of memory windows supported)\n", ca_attr->init_windows);\r
374                 printf("\tmax_raw_ipv6_qp = 0x%x                (Maximum number of Raw IPV6 QPs supported)\n", ca_attr->max_ipv6_qps);\r
375                 printf("\tmax_raw_ethy_qp = 0x%x                (Maximum number of Raw Ethertypes QPs supported)\n", ca_attr->max_ether_qps);\r
376                 printf("\tmax_mcast_grp_num = 0x%x      (Maximum Number of multicast groups)\n", ca_attr->max_mcast_grps);\r
377                 printf("\tmax_mcast_qp_attach_num = 0x%x        (Maximum number of QP per multicast group)\n", ca_attr->max_qps_per_mcast_grp);\r
378                 printf("\tmax_ah_num = 0x%x             (Maximum number of address handles)\n", ca_attr->max_addr_handles);\r
379                 printf("\tmax_num_fmr = 0x%x            (Maximum number FMRs)\n", ca_attr->max_fmr);\r
380                 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
381                 printf("\tmodify_wr_depth = %d          (Capabilities: change QP depth during a modify QP)\n", !!ca_attr->modify_wr_depth);\r
382                 printf("\tmodify_srq_depth = %d                 (Capabilities: change SRQ depth - Not supported by driver!)\n", !!ca_attr->modify_srq_depth);\r
383                 printf("\tchange_primary_port = %d              (Capabilities: change primary port for a QP during a SQD->RTS transition)\n", !!ca_attr->change_primary_port);\r
384                 printf("\tav_port_check = %d            (Capabilities: check port number in address handles)\n", !!ca_attr->av_port_check);\r
385                 printf("\tinit_type_support = %d                (Capabilities: set init_type)\n", !!ca_attr->init_type_support);\r
386                 printf("\tshutdown_port = %d            (Capabilities: shutdown port support)\n", !!ca_attr->shutdown_port_capability);\r
387         }else{\r
388                 printf("\tnum_phys_ports=%d\n",         ca_attr->num_ports);\r
389         }\r
390         for (i = 0; i<ca_attr->num_ports; i++){\r
391                 printPortInfo(ca_attr->p_port_attr+i, vstat_port_info[i], fullPrint);\r
392         }       \r
393 }\r
394 /* Internal Functions */\r
395 \r
396 void vstat_get_counters(ib_ca_handle_t h_ca,uint8_t port_num)\r
397 {\r
398         ib_mad_t                        *mad_in = NULL;\r
399         ib_mad_t                        *mad_out = NULL;\r
400         ib_port_counters_t      *port_counters;\r
401         ib_api_status_t         ib_status = IB_SUCCESS;\r
402         int i;\r
403         \r
404         mad_out = (ib_mad_t*)cl_zalloc(256);\r
405         CL_ASSERT(mad_out);\r
406 \r
407         mad_in = (ib_mad_t*)cl_zalloc(256);\r
408         CL_ASSERT(mad_in);\r
409 \r
410 \r
411         mad_in->attr_id = IB_MAD_ATTR_PORT_CNTRS;\r
412         mad_in->method = IB_MAD_METHOD_GET;\r
413         mad_in->base_ver = 1;\r
414         mad_in->class_ver =1;\r
415         mad_in->mgmt_class = IB_MCLASS_PERF;\r
416 \r
417         port_counters = (ib_port_counters_t*)(((ib_gmp_t*)mad_in)->data);\r
418 \r
419         port_counters->port_select= port_num;\r
420         port_counters->counter_select= 0xff;\r
421 \r
422         ib_status = ib_local_mad(h_ca ,port_num ,mad_in ,mad_out);\r
423         if(ib_status != IB_SUCCESS)\r
424         {\r
425                 printf("ib_local_mad failed with status = %d\n", ib_status);\r
426                 return;\r
427         }\r
428         \r
429         port_counters = (ib_port_counters_t*)(((ib_gmp_t*)mad_out)->data);\r
430 \r
431         printf("\n\tport counters for port %d\n",port_num);\r
432         printf("\t\tlink_error_recovery_counter\t0x%x \n",port_counters->link_error_recovery_counter);\r
433         printf("\t\tlink_down_counter\t\t0x%x \n",port_counters->link_down_counter);\r
434         printf("\t\tport_rcv_errors\t\t\t0x%x \n",CL_NTOH16(port_counters->port_rcv_errors));\r
435         printf("\t\tport_rcv_remote_physical_errors\t0x%x \n",CL_NTOH16(port_counters->port_rcv_remote_physical_errors));\r
436         printf("\t\tport_rcv_switch_relay_errors\t0x%x \n",CL_NTOH16(port_counters->port_rcv_switch_relay_errors));\r
437         printf("\t\tport_xmit_discard\t\t0x%x \n",CL_NTOH16(port_counters->port_xmit_discard));\r
438         printf("\t\tport_xmit_constraint_errors\t0x%x \n",port_counters->port_xmit_constraint_errors);\r
439         printf("\t\tport_rcv_constraint_errors\t0x%x \n",port_counters->port_rcv_constraint_errors);\r
440         printf("\t\tvl15_dropped\t\t\t0x%x \n",CL_NTOH16(port_counters->vl15_dropped));\r
441         printf("\t\tport_rcv_data\t\t\t0x%x \n",CL_NTOH32(port_counters->port_rcv_data));\r
442         printf("\t\tport_xmit_data\t\t\t0x%x \n",CL_NTOH32(port_counters->port_xmit_data));\r
443         printf("\t\tport_rcv_pkts\t\t\t0x%x \n",CL_NTOH32(port_counters->port_rcv_pkts));\r
444         printf("\t\tport_xmit_pkts\t\t\t0x%x \n\n",CL_NTOH32(port_counters->port_xmit_pkts));\r
445         \r
446 }\r
447 \r
448 \r
449 void vstat_get_port_info(ib_ca_handle_t h_ca,uint8_t port_num, ib_port_info_t* vstat_port_info)\r
450 {\r
451         ib_mad_t                        *mad_in = NULL;\r
452         ib_mad_t                        *mad_out = NULL;\r
453         ib_api_status_t         ib_status = IB_SUCCESS;\r
454         int i;\r
455         \r
456         mad_out = (ib_mad_t*)cl_zalloc(256);\r
457         CL_ASSERT(mad_out);\r
458 \r
459         mad_in = (ib_mad_t*)cl_zalloc(256);\r
460         CL_ASSERT(mad_in);\r
461 \r
462 \r
463         mad_in->attr_id = IB_MAD_ATTR_PORT_INFO;\r
464         mad_in->method = IB_MAD_METHOD_GET;\r
465         mad_in->base_ver = 1;\r
466         mad_in->class_ver =1;\r
467         mad_in->mgmt_class = IB_MCLASS_SUBN_LID;\r
468         \r
469 \r
470 \r
471         ib_status = ib_local_mad(h_ca ,port_num ,mad_in ,mad_out);\r
472         if(ib_status != IB_SUCCESS &&  0 != mad_in->status )\r
473         {\r
474                 printf("ib_local_mad failed with status = %d mad status = %d\n", ib_status,mad_in->status);\r
475                 return;\r
476         }\r
477 \r
478         cl_memcpy(vstat_port_info,(ib_port_info_t*)(((ib_smp_t*)mad_out)->data),sizeof(ib_port_info_t));\r
479 \r
480         \r
481 }\r
482 \r
483 \r
484 ib_api_status_t\r
485 vstat_ca_attr(\r
486         boolean_t modify_attr,\r
487         BOOLEAN fullPrint,\r
488         BOOLEAN getCounters\r
489         )\r
490 {\r
491         ib_al_handle_t          h_al = NULL;\r
492         ib_api_status_t         ib_status = IB_SUCCESS;\r
493         ib_api_status_t         ret_status = IB_SUCCESS;\r
494         size_t                  guid_count;\r
495         ib_net64_t              *ca_guid_array;\r
496         ib_ca_attr_t            *vstat_ca_attr;\r
497         ib_port_info_t          vstat_port_info[2];\r
498         size_t                  i;\r
499         ib_ca_handle_t  h_ca = NULL;\r
500         uint32_t                        bsize;\r
501         ib_port_attr_mod_t port_attr_mod;\r
502         uint8_t                 port_idx;\r
503 \r
504         while(1)\r
505         {\r
506                 /*\r
507                  * Open the AL instance\r
508                  */\r
509                 ib_status = ib_open_al(&h_al);\r
510                 if(ib_status != IB_SUCCESS)\r
511                 {\r
512                         printf("ib_open_al failed status = %d\n", ib_status);\r
513                         ret_status = ib_status;                 \r
514                         break;\r
515                 }\r
516                 //xxxx\r
517                 //printf("ib_open_al PASSED.\n");\r
518                 //xxx\r
519                 CL_ASSERT(h_al);\r
520 \r
521                 /*\r
522                  * Get the Local CA Guids\r
523                  */\r
524                 ib_status = ib_get_ca_guids(h_al, NULL, &guid_count);\r
525                 if(ib_status != IB_INSUFFICIENT_MEMORY)\r
526                 {\r
527                         printf("ib_get_ca_guids1 failed status = %d\n", (uint32_t)ib_status);\r
528                         ret_status = ib_status;                 \r
529                         goto Cleanup1;\r
530                 }\r
531 \r
532                 \r
533 \r
534                 /*\r
535                  * If no CA's Present then return\r
536                  */\r
537 \r
538                 if(guid_count == 0)\r
539                         goto Cleanup1;\r
540 \r
541                 \r
542                 ca_guid_array = (ib_net64_t*)cl_malloc(sizeof(ib_net64_t) * guid_count);\r
543                 CL_ASSERT(ca_guid_array);\r
544                 \r
545                 ib_status = ib_get_ca_guids(h_al, ca_guid_array, &guid_count);\r
546                 if(ib_status != IB_SUCCESS)\r
547                 {\r
548                         printf("ib_get_ca_guids2 failed with status = %d\n", ib_status);\r
549                         ret_status = ib_status;                 \r
550                         goto Cleanup1;\r
551                 }\r
552 \r
553                 \r
554 \r
555                 /*\r
556                  * For Each CA Guid found Open the CA,\r
557                  * Query the CA Attribute and close the CA\r
558                  */\r
559                 for(i=0; i < guid_count; i++)\r
560                 {\r
561 \r
562                         /* Open the CA */\r
563                         ib_status = ib_open_ca(h_al,\r
564                                 ca_guid_array[i],\r
565                                 NULL,\r
566                                 NULL,   //ca_context\r
567                                 &h_ca);\r
568 \r
569                         if(ib_status != IB_SUCCESS)\r
570                         {\r
571                                 printf("ib_open_ca failed with status = %d\n", ib_status);\r
572                                 ret_status = ib_status;                         \r
573                                 goto Cleanup1;\r
574                         }\r
575 \r
576                         //xxx\r
577                         //printf("ib_open_ca passed i=%d\n",i); \r
578                         //xxx\r
579 \r
580 \r
581                         /* Query the CA */\r
582                         bsize = 0;\r
583                         ib_status = ib_query_ca(h_ca, NULL, &bsize);\r
584                         if(ib_status != IB_INSUFFICIENT_MEMORY)\r
585                         {\r
586                                 printf("ib_query_ca failed with status = %d\n", ib_status);\r
587                                 ret_status = ib_status;\r
588                                 goto Cleanup2;\r
589                         }\r
590                         CL_ASSERT(bsize);\r
591                         //xxxx\r
592                         //printf("ib_query_ca PASSED bsize = 0x%x.\n",bsize);\r
593                         //xxx\r
594                         /* Allocate the memory needed for query_ca */\r
595 \r
596                         vstat_ca_attr = (ib_ca_attr_t *)cl_zalloc(bsize);\r
597                         CL_ASSERT(vstat_ca_attr);\r
598 \r
599                         ib_status = ib_query_ca(h_ca, vstat_ca_attr, &bsize);\r
600                         if(ib_status != IB_SUCCESS)\r
601                         {\r
602                                 printf("ib_query_ca failed with status = %d\n", ib_status);\r
603                                 ret_status = ib_status;\r
604                                 goto Cleanup2;\r
605                         }\r
606 \r
607                         for(port_idx =0; port_idx< vstat_ca_attr->num_ports;port_idx++){\r
608                                 vstat_get_port_info(h_ca ,port_idx+1,&vstat_port_info[port_idx]);\r
609                         }\r
610 \r
611                         vstat_print_ca_attr((int)i, vstat_ca_attr, vstat_port_info, fullPrint);\r
612                         if(getCounters)\r
613                         {\r
614                                 for(port_idx =0; port_idx< vstat_ca_attr->num_ports;port_idx++){\r
615                                         vstat_get_counters(h_ca ,port_idx+1);\r
616                                 }\r
617                         }\r
618                         \r
619                         /* Free the memory */\r
620                         cl_free(vstat_ca_attr);\r
621                         vstat_ca_attr = NULL;\r
622                         /* Close the current open CA */\r
623                         ib_status = ib_close_ca(h_ca, NULL);\r
624                         if(ib_status != IB_SUCCESS)\r
625                         {\r
626                                 printf("ib_close_ca failed status = %d", ib_status);\r
627                                 ret_status = ib_status;\r
628                         }\r
629                         h_ca = NULL;\r
630 \r
631                 }\r
632 \r
633 Cleanup2:\r
634                 if(h_ca != NULL)\r
635                 {\r
636                         ib_status = ib_close_ca(h_ca, NULL);\r
637                         if(ib_status != IB_SUCCESS)\r
638                         {\r
639                                 printf("ib_close_ca failed status = %d", ib_status);\r
640                         }\r
641                 }\r
642 \r
643 Cleanup1:\r
644                 cl_free(ca_guid_array);\r
645                 ib_status = ib_close_al(h_al);\r
646 \r
647                 if(ib_status != IB_SUCCESS)\r
648                 {\r
649                         printf("ib_close_al failed status = %d", ib_status);\r
650                 }\r
651 \r
652                 break;\r
653 \r
654         } //End of while(1)\r
655 \r
656         \r
657         return ret_status;\r
658 }\r
659 \r
660 void vstat_help()\r
661 {\r
662         printf("\n\tUsage: vstat [-v] [-c]\n");\r
663         printf("\t\t -v - verbose mode\n");\r
664         printf("\t\t -c - HCA error/statistic counters\n");\r
665 }\r
666 \r
667 int32_t __cdecl\r
668 main(\r
669         int32_t argc,\r
670         char* argv[])\r
671 {\r
672         ib_api_status_t ib_status;\r
673         BOOLEAN fullPrint = FALSE;\r
674         BOOLEAN getCounters = FALSE;\r
675         BOOLEAN showHelp = FALSE;\r
676         if(argc>1){\r
677                 int i = 2;\r
678                 while(i<=argc){\r
679                         if(!_stricmp(argv[i-1], "-v")){\r
680                                 fullPrint = TRUE;\r
681                                 i+=1;\r
682                         }else if(!_stricmp(argv[i-1], "-h") || \r
683                                 !_stricmp(argv[i-1], "-help")){\r
684                                 showHelp = TRUE;\r
685                                 i+=1;\r
686                         }else if(!_stricmp(argv[i-1], "-c")){\r
687                                 getCounters = TRUE;\r
688                                 i+=1;\r
689                         }else{\r
690                                 i+=2;\r
691                         }\r
692                 }\r
693         }\r
694         if (showHelp)\r
695                 vstat_help();\r
696         else\r
697                 ib_status = vstat_ca_attr(FALSE, fullPrint,getCounters);\r
698 \r
699         return 0;\r
700 }\r
701 \r
702 \r