[VSTAT]added printing of more port states
[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  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 \r
34 \r
35 #include "stdio.h"\r
36 #include "string.h"\r
37 #include "stdlib.h"\r
38 \r
39 \r
40 #include <iba/ib_types.h>\r
41 #include <iba/ib_al.h>\r
42 #ifndef WIN32\r
43 #include <complib/cl_device.h>\r
44 #endif\r
45 #include <mthca/mthca_vc.h>\r
46 \r
47 \r
48 #define VEND_ID_MELLNOX 0x02c9\r
49 \r
50 \r
51 /*******************************************************************\r
52 *******************************************************************/\r
53 \r
54 \r
55 void print64bit(ib_net64_t u64, BOOLEAN hexFormat){\r
56         ib_net64_t mask = (1<<16)-1;\r
57         ib_net16_t tmp;\r
58         int i;\r
59         for(i=0;i<4;i++){\r
60                 tmp = (uint16_t)((u64>>(i*16))& mask);\r
61                 if(hexFormat){\r
62                         printf("%04x",cl_hton16(tmp));\r
63                         if(i<3){\r
64                                 printf(":");\r
65                         }\r
66                 }else{\r
67                         \r
68                         if((tmp>>8)<100){\r
69                                 printf("%02d", tmp>>8);\r
70                         }else{\r
71                                 printf("%03d", tmp>>8);\r
72                         }\r
73                         printf(".");\r
74                         if((tmp&(mask<<8)) <100){\r
75                                 printf("%02d", tmp&(mask<<8));\r
76                         }else{\r
77                                 printf("%03d", tmp&(mask<<8));\r
78                         }\r
79                         \r
80                 }\r
81         }\r
82 }       \r
83 \r
84 void printGUID(ib_net64_t guid){\r
85         printf("\tnode_guid=");\r
86         print64bit(guid, TRUE);\r
87         printf("\n");\r
88 }\r
89 \r
90 void printPortGID(ib_net64_t subnetPrefix, ib_net64_t portGuid){\r
91         printf("\t\tGID[0]=");\r
92         print64bit(subnetPrefix, TRUE);\r
93         printf(":");\r
94         print64bit(portGuid, TRUE);\r
95         printf("\n");\r
96 }\r
97 \r
98 \r
99 void printPortLinkState(int portState){ //TODO: check that these are all the options and that they are correct\r
100         switch(portState){\r
101                 case 1:\r
102                         printf("\t\tport_state=PORT_DOWN (%d)\n",portState);\r
103                         break;\r
104                 case 2:\r
105                         printf("\t\tport_state=PORT_INITIALIZE (%d)\n",portState);\r
106                         break;\r
107                 case 3:\r
108                         printf("\t\tport_state=PORT_ARMED (%d)\n",portState);\r
109                         break;\r
110                 case 4:\r
111                         printf("\t\tport_state=PORT_ACTIVE (%d)\n",portState);\r
112                         break;\r
113                 case 5:\r
114                         printf("\t\tport_state=PORT_ACTDEFER (%d)\n",portState);\r
115                         break;\r
116                 default:\r
117                         printf("\t\tport_state=UNKNOWN (%d)\n",portState); \r
118         }\r
119 }\r
120 \r
121 \r
122 \r
123 void printPortMTU(int mtu){ //TODO: check that these are all the options and that they are correct\r
124         switch(mtu){\r
125                 case 1:\r
126                         printf("\t\tmax_mtu=256 (%d)\n",mtu);\r
127                         break;\r
128                 case 2:\r
129                         printf("\t\tmax_mtu=512 (%d)\n",mtu);\r
130                         break;\r
131                 case 3:\r
132                         printf("\t\tmax_mtu=1024 (%d)\n",mtu);\r
133                         break;\r
134                 case 4:\r
135                         printf("\t\tmax_mtu=2048 (%d)\n",mtu);\r
136                         break;\r
137                 case 5:\r
138                         printf("\t\tmax_mtu=4096 (%d)\n",mtu);\r
139                         break;\r
140                 default:\r
141                         printf("\t\tmax_mtu=UNKNOWN (%d)\n",mtu); \r
142         }\r
143 }\r
144 \r
145 void printPortInfo(ib_port_attr_t* portPtr, BOOLEAN fullPrint){\r
146         printf("\t\tport=%d\n", portPtr->port_num);\r
147         printPortLinkState(portPtr->link_state);\r
148         printf("\t\tsm_lid=0x%04x\n", cl_ntoh16(portPtr->sm_lid));\r
149         printf("\t\tport_lid=0x%04x\n", cl_ntoh16(portPtr->lid));\r
150         printf("\t\tport_lmc=0x%x\n", portPtr->lmc);\r
151         printPortMTU(portPtr->mtu);\r
152         if(fullPrint){\r
153                 printf("\t\tmax_msg_sz=0x%x     (Max message size)\n", portPtr->max_msg_size);\r
154                 printf("\t\tcapability_mask=TBD\n");\r
155                 printf("\t\tmax_vl_num=0x%x             (Maximum number of VL supported by this port)\n", portPtr->max_vls);\r
156                 printf("\t\tbad_pkey_counter=0x%x       (Bad PKey counter)\n", portPtr->pkey_ctr);\r
157                 printf("\t\tqkey_viol_counter=0x%x      (QKey violation counter)\n", portPtr->qkey_ctr);\r
158                 printf("\t\tsm_sl=0x%x          (IB_SL to be used in communication with subnet manager)\n", portPtr->sm_sl);\r
159                 printf("\t\tpkey_tbl_len=0x%x   (Current size of pkey table)\n", portPtr->num_pkeys);\r
160                 printf("\t\tgid_tbl_len=0x%x    (Current size of GID table)\n", portPtr->num_gids);\r
161                 printf("\t\tsubnet_timeout=0x%x (Subnet Timeout for this port (see PortInfo))\n", portPtr->subnet_timeout);\r
162                 printf("\t\tinitTypeReply=0x%x  (optional InitTypeReply value. 0 if not supported)\n", portPtr->init_type_reply);\r
163                 printPortGID(portPtr->p_gid_table->unicast.prefix, portPtr->p_gid_table->unicast.interface_id);\r
164         }\r
165         printf("\n");\r
166 }\r
167 \r
168 \r
169 \r
170 \r
171 void vstat_print_ca_attr(int idx,  ib_ca_attr_t* ca_attr, BOOLEAN fullPrint){\r
172         int i;\r
173         \r
174         printf("\n\thca_idx=%d\n",idx);\r
175         printf("\tpci_location={BUS=NA,DEV/FUNC=NA}\n");\r
176         printf("\tvendor_id=0x%04x\n", ca_attr->vend_id);\r
177         printf("\tvendor_part_id=0x%04x\n", ca_attr->dev_id);\r
178         printf("\thw_ver=0x%x\n", ca_attr->revision); //TODO: ???\r
179         if(ca_attr->vend_id == VEND_ID_MELLNOX){\r
180                 printf("\tfw_ver=%d.%.2d.%.4d\n",\r
181                 (uint16_t )(ca_attr->fw_ver>>32),\r
182                 (uint16_t)(ca_attr->fw_ver>>16),\r
183                 (uint16_t )(ca_attr->fw_ver));\r
184                 printf("\tPSID=%s\n",mthca_get_board_id(ca_attr));\r
185         }else{\r
186                 printf("\tfw_ver=0x%I64x\n",ca_attr->fw_ver);\r
187         }\r
188         printGUID(ca_attr->ca_guid);\r
189         if(fullPrint){\r
190                 printf("\tnum_phys_ports = %d\n",ca_attr->num_ports);\r
191                 printf("\tmax_num_qp = 0x%x             (Maximum Number of QPs supported)\n", ca_attr->max_qps);\r
192                 printf("\tmax_qp_ous_wr = 0x%x          (Maximum Number of oustanding WR on any WQ)\n", ca_attr->max_wrs);\r
193                 printf("\tmax_num_sg_ent = 0x%x         (Max num of scatter/gather entries for WQE other than RD)\n", ca_attr->max_sges);\r
194                 printf("\tmax_num_sg_ent_rd = 0x%x              (Max num of scatter/gather entries for RD WQE)\n",  ca_attr->max_rd_sges);\r
195                 printf("\tmax_num_srq = 0                       (Maximum Number of SRQs supported)\n");\r
196                 printf("\tmax_wqe_per_srq = 0           (Maximum Number of oustanding WR on any SRQ)\n");\r
197                 printf("\tmax_srq_sentries = 0          (Maximum Number of scatter entries for SRQ WQE)\n");\r
198                 printf("\tsrq_resize_supported = 0      (SRQ resize supported)\n");\r
199                 printf("\tmax_num_cq = 0x%x             (Max num of supported CQs)\n", ca_attr->max_cqs);\r
200                 printf("\tmax_num_ent_cq = 0x%x (Max num of supported entries per CQ)\n", ca_attr->max_cqes);\r
201                 printf("\tmax_num_mr = 0x%x             (Maximum number of memory region supported)\n", ca_attr->init_regions);\r
202                 printf("\tmax_mr_size = 0x%x    (Largest contigous block of memory region in bytes)\n", ca_attr->init_region_size);\r
203                 printf("\tmax_pd_num = 0x%x             (Maximum number of protection domains supported)\n", ca_attr->max_pds);\r
204                 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
205 \r
206                 printf("\tlocal_ca_ack_delay = 0x%x             (Log2 4.096usec Max. RX to ACK or NAK delay)\n", ca_attr->local_ack_delay);\r
207                 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
208                 printf("\tmax_ee_ous_rd_atom = 0                (EE Maximum number of outs. RDMA read/atomic as target)\n");\r
209                 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
210                 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
211                 printf("\tmax_ee_init_rd_atom = 0               (EE Max. Num. of outs. RDMA read/atomic as initiator)\n");\r
212                 printf("\tatomic_cap = %s               (Level of Atomicity supported)\n",ca_attr->atomicity == IB_ATOMIC_GLOBAL?"GLOBAL":\r
213                                                                                                                                         ca_attr->atomicity == IB_ATOMIC_LOCAL?"LOCAL":"NORMAL");\r
214                 printf("\tmax_ee_num = 0x0              (Maximum number of EEC supported)\n");\r
215                 printf("\tmax_rdd_num = 0x0             (Maximum number of IB_RDD supported)\n");\r
216                 printf("\tmax_mw_num = 0x%x             (Maximum Number of memory windows supported)\n", ca_attr->init_windows);\r
217                 printf("\tmax_raw_ipv6_qp = 0x%x                (Maximum number of Raw IPV6 QPs supported)\n", ca_attr->max_ipv6_qps);\r
218                 printf("\tmax_raw_ethy_qp = 0x%x                (Maximum number of Raw Ethertypes QPs supported)\n", ca_attr->max_ether_qps);\r
219                 printf("\tmax_mcast_grp_num = 0x%x      (Maximum Number of multicast groups)\n", ca_attr->max_mcast_grps);\r
220                 printf("\tmax_mcast_qp_attach_num = 0x%x        (Maximum number of QP per multicast group)\n", ca_attr->max_qps_per_mcast_grp);\r
221                 printf("\tmax_ah_num = 0x%x             (Maximum number of address handles)\n", ca_attr->max_addr_handles);\r
222                 printf("\tmax_num_fmr = 0x%x            (Maximum number FMRs)\n", ca_attr->max_fmr);\r
223                 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
224         }else{\r
225                 printf("\tnum_phys_ports=%d\n",         ca_attr->num_ports);\r
226         }\r
227         for (i = 0; i<ca_attr->num_ports; i++){\r
228                 printPortInfo(ca_attr->p_port_attr+i, fullPrint);\r
229         }       \r
230 }\r
231 /* Internal Functions */\r
232 \r
233 void vstat_get_counters(ib_ca_handle_t h_ca,uint8_t port_num)\r
234 {\r
235         ib_mad_t                        *mad_in = NULL;\r
236         ib_mad_t                        *mad_out = NULL;\r
237         ib_port_counters_t      *port_counters;\r
238         ib_api_status_t         ib_status = IB_SUCCESS;\r
239         int i;\r
240         \r
241         mad_out = (ib_mad_t*)cl_zalloc(256);\r
242         CL_ASSERT(mad_out);\r
243 \r
244         mad_in = (ib_mad_t*)cl_zalloc(256);\r
245         CL_ASSERT(mad_in);\r
246 \r
247 \r
248         mad_in->attr_id = IB_MAD_ATTR_PORT_CNTRS;\r
249         mad_in->method = IB_MAD_METHOD_GET;\r
250         mad_in->base_ver = 1;\r
251         mad_in->class_ver =1;\r
252         mad_in->mgmt_class = IB_MCLASS_PERF;\r
253 \r
254         port_counters = (ib_port_counters_t*)(((ib_gmp_t*)mad_in)->data);\r
255 \r
256         port_counters->port_select= port_num;\r
257         port_counters->counter_select= 0xff;\r
258 \r
259         ib_status = ib_local_mad(h_ca ,port_num ,mad_in ,mad_out);\r
260         if(ib_status != IB_SUCCESS)\r
261         {\r
262                 printf("ib_local_mad failed with status = %d\n", ib_status);\r
263                 return;\r
264         }\r
265         \r
266         port_counters = (ib_port_counters_t*)(((ib_gmp_t*)mad_out)->data);\r
267 \r
268         printf("\nport counters for port %d\n",port_num);\r
269         printf("\tlink_error_recovery_counter\t0x%x \n",port_counters->link_error_recovery_counter);\r
270         printf("\tlink_down_counter\t0x%x \n",port_counters->link_down_counter);\r
271         printf("\tport_rcv_errors\t\t0x%x \n",CL_NTOH16(port_counters->port_rcv_errors));\r
272         printf("\tport_rcv_remote_physical_errors\t0x%x \n",CL_NTOH16(port_counters->port_rcv_remote_physical_errors));\r
273         printf("\tport_rcv_switch_relay_errors\t0x%x \n",CL_NTOH16(port_counters->port_rcv_switch_relay_errors));\r
274         printf("\tport_xmit_discard\t\t0x%x \n",CL_NTOH16(port_counters->port_xmit_discard));\r
275         printf("\tport_xmit_constraint_errors\t0x%x \n",port_counters->port_xmit_constraint_errors);\r
276         printf("\tport_rcv_constraint_errors\t0x%x \n",port_counters->port_rcv_constraint_errors);\r
277         printf("\tvl15_dropped\t\t\t0x%x \n",CL_NTOH16(port_counters->vl15_dropped));\r
278         printf("\tport_rcv_data\t\t\t0x%x \n",CL_NTOH32(port_counters->port_rcv_data));\r
279         printf("\tport_xmit_data\t\t\t0x%x \n",CL_NTOH32(port_counters->port_xmit_data));\r
280         printf("\tport_rcv_pkts\t\t\t0x%x \n",CL_NTOH32(port_counters->port_rcv_pkts));\r
281         printf("\tport_xmit_pkts\t\t\t0x%x \n\n",CL_NTOH32(port_counters->port_xmit_pkts));\r
282         \r
283 }\r
284 \r
285 ib_api_status_t\r
286 vstat_ca_attr(\r
287         boolean_t modify_attr,\r
288         BOOLEAN fullPrint,\r
289         BOOLEAN getCounters\r
290         )\r
291 {\r
292         ib_al_handle_t          h_al = NULL;\r
293         ib_api_status_t         ib_status = IB_SUCCESS;\r
294         ib_api_status_t         ret_status = IB_SUCCESS;\r
295         size_t                  guid_count;\r
296         ib_net64_t              *ca_guid_array;\r
297         ib_ca_attr_t            *vstat_ca_attr;\r
298         size_t                  i;\r
299         ib_ca_handle_t  h_ca = NULL;\r
300         uint32_t                        bsize;\r
301         ib_port_attr_mod_t port_attr_mod;\r
302         uint8_t                 port_idx;\r
303 \r
304         while(1)\r
305         {\r
306                 /*\r
307                  * Open the AL instance\r
308                  */\r
309                 ib_status = ib_open_al(&h_al);\r
310                 if(ib_status != IB_SUCCESS)\r
311                 {\r
312                         printf("ib_open_al failed status = %d\n", ib_status);\r
313                         ret_status = ib_status;                 \r
314                         break;\r
315                 }\r
316                 //xxxx\r
317                 //printf("ib_open_al PASSED.\n");\r
318                 //xxx\r
319                 CL_ASSERT(h_al);\r
320 \r
321                 /*\r
322                  * Get the Local CA Guids\r
323                  */\r
324                 ib_status = ib_get_ca_guids(h_al, NULL, &guid_count);\r
325                 if(ib_status != IB_INSUFFICIENT_MEMORY)\r
326                 {\r
327                         printf("ib_get_ca_guids1 failed status = %d\n", (uint32_t)ib_status);\r
328                         ret_status = ib_status;                 \r
329                         goto Cleanup1;\r
330                 }\r
331 \r
332                 \r
333 \r
334                 /*\r
335                  * If no CA's Present then return\r
336                  */\r
337 \r
338                 if(guid_count == 0)\r
339                         goto Cleanup1;\r
340 \r
341                 \r
342                 ca_guid_array = (ib_net64_t*)cl_malloc(sizeof(ib_net64_t) * guid_count);\r
343                 CL_ASSERT(ca_guid_array);\r
344                 \r
345                 ib_status = ib_get_ca_guids(h_al, ca_guid_array, &guid_count);\r
346                 if(ib_status != IB_SUCCESS)\r
347                 {\r
348                         printf("ib_get_ca_guids2 failed with status = %d\n", ib_status);\r
349                         ret_status = ib_status;                 \r
350                         goto Cleanup1;\r
351                 }\r
352 \r
353                 \r
354 \r
355                 /*\r
356                  * For Each CA Guid found Open the CA,\r
357                  * Query the CA Attribute and close the CA\r
358                  */\r
359                 for(i=0; i < guid_count; i++)\r
360                 {\r
361 \r
362                         /* Open the CA */\r
363                         ib_status = ib_open_ca(h_al,\r
364                                 ca_guid_array[i],\r
365                                 NULL,\r
366                                 NULL,   //ca_context\r
367                                 &h_ca);\r
368 \r
369                         if(ib_status != IB_SUCCESS)\r
370                         {\r
371                                 printf("ib_open_ca failed with status = %d\n", ib_status);\r
372                                 ret_status = ib_status;                         \r
373                                 goto Cleanup1;\r
374                         }\r
375 \r
376                         //xxx\r
377                         //printf("ib_open_ca passed i=%d\n",i); \r
378                         //xxx\r
379 \r
380 \r
381                         /* Query the CA */\r
382                         bsize = 0;\r
383                         ib_status = ib_query_ca(h_ca, NULL, &bsize);\r
384                         if(ib_status != IB_INSUFFICIENT_MEMORY)\r
385                         {\r
386                                 printf("ib_query_ca failed with status = %d\n", ib_status);\r
387                                 ret_status = ib_status;\r
388                                 goto Cleanup2;\r
389                         }\r
390                         CL_ASSERT(bsize);\r
391                         //xxxx\r
392                         //printf("ib_query_ca PASSED bsize = 0x%x.\n",bsize);\r
393                         //xxx\r
394                         /* Allocate the memory needed for query_ca */\r
395 \r
396                         vstat_ca_attr = (ib_ca_attr_t *)cl_zalloc(bsize);\r
397                         CL_ASSERT(vstat_ca_attr);\r
398 \r
399                         ib_status = ib_query_ca(h_ca, vstat_ca_attr, &bsize);\r
400                         if(ib_status != IB_SUCCESS)\r
401                         {\r
402                                 printf("ib_query_ca failed with status = %d\n", ib_status);\r
403                                 ret_status = ib_status;\r
404                                 goto Cleanup2;\r
405                         }\r
406 \r
407 \r
408                         \r
409 \r
410                         vstat_print_ca_attr((int)i, vstat_ca_attr, fullPrint);\r
411                         if(getCounters)\r
412                         {\r
413                                 for(port_idx =0; port_idx< vstat_ca_attr->num_ports;port_idx++){\r
414                                         vstat_get_counters(h_ca ,port_idx+1);\r
415                                 }\r
416                         }\r
417                         \r
418                         /* Free the memory */\r
419                         cl_free(vstat_ca_attr);\r
420                         vstat_ca_attr = NULL;\r
421                         /* Close the current open CA */\r
422                         ib_status = ib_close_ca(h_ca, NULL);\r
423                         if(ib_status != IB_SUCCESS)\r
424                         {\r
425                                 printf("ib_close_ca failed status = %d", ib_status);\r
426                                 ret_status = ib_status;\r
427                         }\r
428                         h_ca = NULL;\r
429 \r
430                 }\r
431 \r
432 Cleanup2:\r
433                 if(h_ca != NULL)\r
434                 {\r
435                         ib_status = ib_close_ca(h_ca, NULL);\r
436                         if(ib_status != IB_SUCCESS)\r
437                         {\r
438                                 printf("ib_close_ca failed status = %d", ib_status);\r
439                         }\r
440                 }\r
441 \r
442 Cleanup1:\r
443                 ib_status = ib_close_al(h_al);\r
444 \r
445                 if(ib_status != IB_SUCCESS)\r
446                 {\r
447                         printf("ib_close_al failed status = %d", ib_status);\r
448                 }\r
449 \r
450                 break;\r
451 \r
452         } //End of while(1)\r
453 \r
454         \r
455         return ret_status;\r
456 }\r
457 \r
458 \r
459 \r
460 int32_t __cdecl\r
461 main(\r
462         int32_t argc,\r
463         char* argv[])\r
464 {\r
465         ib_api_status_t ib_status;\r
466         BOOLEAN fullPrint = FALSE;\r
467         BOOLEAN getCounters = FALSE;\r
468         if(argc>1){\r
469                 int i = 2;\r
470                 while(i<=argc){\r
471                         if(!_stricmp(argv[i-1], "-v")){\r
472                                 fullPrint = TRUE;\r
473                                 i+=1;\r
474                         }else if(!_stricmp(argv[i-1], "-c")){\r
475                                 getCounters = TRUE;\r
476                                 i+=1;\r
477                         }else{\r
478                                 i+=2;\r
479                         }\r
480                 }\r
481         }\r
482         ib_status = vstat_ca_attr(FALSE, fullPrint,getCounters);\r
483 \r
484         return 0;\r
485 }\r
486 \r