1 /*
2 * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
3 * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
4 * Copyright (c) 2009 HNR Consulting. All rights reserved.
5 * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
6 *
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
12 *
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
15 * conditions are met:
16 *
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer.
20 *
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 * SOFTWARE.
34 *
35 */
36
37 #if HAVE_CONFIG_H
38 # include <config.h>
39 #endif /* HAVE_CONFIG_H */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <getopt.h>
45 #include <netinet/in.h>
46
47 #include <infiniband/umad.h>
48 #include <infiniband/mad.h>
49 #include <infiniband/iba/ib_types.h>
50
51 #include "ibdiag_common.h"
52
53 struct ibmad_port *srcport;
54
55 static ibmad_gid_t dgid;
56 static int with_grh;
57
58 struct perf_count {
59 uint32_t portselect;
60 uint32_t counterselect;
61 uint32_t symbolerrors;
62 uint32_t linkrecovers;
63 uint32_t linkdowned;
64 uint32_t rcverrors;
65 uint32_t rcvremotephyerrors;
66 uint32_t rcvswrelayerrors;
67 uint32_t xmtdiscards;
68 uint32_t xmtconstrainterrors;
69 uint32_t rcvconstrainterrors;
70 uint32_t linkintegrityerrors;
71 uint32_t excbufoverrunerrors;
72 uint32_t qp1dropped;
73 uint32_t vl15dropped;
74 uint32_t xmtdata;
75 uint32_t rcvdata;
76 uint32_t xmtpkts;
77 uint32_t rcvpkts;
78 uint32_t xmtwait;
79 };
80
81 struct perf_count_ext {
82 uint32_t portselect;
83 uint32_t counterselect;
84 uint64_t portxmitdata;
85 uint64_t portrcvdata;
86 uint64_t portxmitpkts;
87 uint64_t portrcvpkts;
88 uint64_t portunicastxmitpkts;
89 uint64_t portunicastrcvpkts;
90 uint64_t portmulticastxmitpkits;
91 uint64_t portmulticastrcvpkts;
92
93 uint32_t counterSelect2;
94 uint64_t symbolErrorCounter;
95 uint64_t linkErrorRecoveryCounter;
96 uint64_t linkDownedCounter;
97 uint64_t portRcvErrors;
98 uint64_t portRcvRemotePhysicalErrors;
99 uint64_t portRcvSwitchRelayErrors;
100 uint64_t portXmitDiscards;
101 uint64_t portXmitConstraintErrors;
102 uint64_t portRcvConstraintErrors;
103 uint64_t localLinkIntegrityErrors;
104 uint64_t excessiveBufferOverrunErrors;
105 uint64_t VL15Dropped;
106 uint64_t portXmitWait;
107 uint64_t QP1Dropped;
108 };
109
110 static uint8_t pc[1024];
111
112 struct perf_count perf_count = {0};
113 struct perf_count_ext perf_count_ext = {0};
114
115 #define ALL_PORTS 0xFF
116 #define MAX_PORTS 255
117
118 /* Notes: IB semantics is to cap counters if count has exceeded limits.
119 * Therefore we must check for overflows and cap the counters if necessary.
120 *
121 * mad_decode_field and mad_encode_field assume 32 bit integers passed in
122 * for fields < 32 bits in length.
123 */
124
aggregate_4bit(uint32_t * dest,uint32_t val)125 static void aggregate_4bit(uint32_t * dest, uint32_t val)
126 {
127 if ((((*dest) + val) < (*dest)) || ((*dest) + val) > 0xf)
128 (*dest) = 0xf;
129 else
130 (*dest) = (*dest) + val;
131 }
132
aggregate_8bit(uint32_t * dest,uint32_t val)133 static void aggregate_8bit(uint32_t * dest, uint32_t val)
134 {
135 if ((((*dest) + val) < (*dest))
136 || ((*dest) + val) > 0xff)
137 (*dest) = 0xff;
138 else
139 (*dest) = (*dest) + val;
140 }
141
aggregate_16bit(uint32_t * dest,uint32_t val)142 static void aggregate_16bit(uint32_t * dest, uint32_t val)
143 {
144 if ((((*dest) + val) < (*dest))
145 || ((*dest) + val) > 0xffff)
146 (*dest) = 0xffff;
147 else
148 (*dest) = (*dest) + val;
149 }
150
aggregate_32bit(uint32_t * dest,uint32_t val)151 static void aggregate_32bit(uint32_t * dest, uint32_t val)
152 {
153 if (((*dest) + val) < (*dest))
154 (*dest) = 0xffffffff;
155 else
156 (*dest) = (*dest) + val;
157 }
158
aggregate_64bit(uint64_t * dest,uint64_t val)159 static void aggregate_64bit(uint64_t * dest, uint64_t val)
160 {
161 if (((*dest) + val) < (*dest))
162 (*dest) = 0xffffffffffffffffULL;
163 else
164 (*dest) = (*dest) + val;
165 }
166
aggregate_perfcounters(void)167 static void aggregate_perfcounters(void)
168 {
169 uint32_t val;
170
171 mad_decode_field(pc, IB_PC_PORT_SELECT_F, &val);
172 perf_count.portselect = val;
173 mad_decode_field(pc, IB_PC_COUNTER_SELECT_F, &val);
174 perf_count.counterselect = val;
175 mad_decode_field(pc, IB_PC_ERR_SYM_F, &val);
176 aggregate_16bit(&perf_count.symbolerrors, val);
177 mad_decode_field(pc, IB_PC_LINK_RECOVERS_F, &val);
178 aggregate_8bit(&perf_count.linkrecovers, val);
179 mad_decode_field(pc, IB_PC_LINK_DOWNED_F, &val);
180 aggregate_8bit(&perf_count.linkdowned, val);
181 mad_decode_field(pc, IB_PC_ERR_RCV_F, &val);
182 aggregate_16bit(&perf_count.rcverrors, val);
183 mad_decode_field(pc, IB_PC_ERR_PHYSRCV_F, &val);
184 aggregate_16bit(&perf_count.rcvremotephyerrors, val);
185 mad_decode_field(pc, IB_PC_ERR_SWITCH_REL_F, &val);
186 aggregate_16bit(&perf_count.rcvswrelayerrors, val);
187 mad_decode_field(pc, IB_PC_XMT_DISCARDS_F, &val);
188 aggregate_16bit(&perf_count.xmtdiscards, val);
189 mad_decode_field(pc, IB_PC_ERR_XMTCONSTR_F, &val);
190 aggregate_8bit(&perf_count.xmtconstrainterrors, val);
191 mad_decode_field(pc, IB_PC_ERR_RCVCONSTR_F, &val);
192 aggregate_8bit(&perf_count.rcvconstrainterrors, val);
193 mad_decode_field(pc, IB_PC_ERR_LOCALINTEG_F, &val);
194 aggregate_4bit(&perf_count.linkintegrityerrors, val);
195 mad_decode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &val);
196 aggregate_4bit(&perf_count.excbufoverrunerrors, val);
197 #ifdef HAVE_IB_PC_QP1_DROP_F
198 mad_decode_field(pc, IB_PC_QP1_DROP_F, &val);
199 aggregate_16bit(&perf_count.qp1dropped, val);
200 #endif
201 mad_decode_field(pc, IB_PC_VL15_DROPPED_F, &val);
202 aggregate_16bit(&perf_count.vl15dropped, val);
203 mad_decode_field(pc, IB_PC_XMT_BYTES_F, &val);
204 aggregate_32bit(&perf_count.xmtdata, val);
205 mad_decode_field(pc, IB_PC_RCV_BYTES_F, &val);
206 aggregate_32bit(&perf_count.rcvdata, val);
207 mad_decode_field(pc, IB_PC_XMT_PKTS_F, &val);
208 aggregate_32bit(&perf_count.xmtpkts, val);
209 mad_decode_field(pc, IB_PC_RCV_PKTS_F, &val);
210 aggregate_32bit(&perf_count.rcvpkts, val);
211 mad_decode_field(pc, IB_PC_XMT_WAIT_F, &val);
212 aggregate_32bit(&perf_count.xmtwait, val);
213 }
214
output_aggregate_perfcounters(ib_portid_t * portid,uint16_t cap_mask)215 static void output_aggregate_perfcounters(ib_portid_t * portid,
216 uint16_t cap_mask)
217 {
218 char buf[1024];
219 uint32_t val = ALL_PORTS;
220
221 /* set port_select to 255 to emulate AllPortSelect */
222 mad_encode_field(pc, IB_PC_PORT_SELECT_F, &val);
223 mad_encode_field(pc, IB_PC_COUNTER_SELECT_F, &perf_count.counterselect);
224 mad_encode_field(pc, IB_PC_ERR_SYM_F, &perf_count.symbolerrors);
225 mad_encode_field(pc, IB_PC_LINK_RECOVERS_F, &perf_count.linkrecovers);
226 mad_encode_field(pc, IB_PC_LINK_DOWNED_F, &perf_count.linkdowned);
227 mad_encode_field(pc, IB_PC_ERR_RCV_F, &perf_count.rcverrors);
228 mad_encode_field(pc, IB_PC_ERR_PHYSRCV_F,
229 &perf_count.rcvremotephyerrors);
230 mad_encode_field(pc, IB_PC_ERR_SWITCH_REL_F,
231 &perf_count.rcvswrelayerrors);
232 mad_encode_field(pc, IB_PC_XMT_DISCARDS_F, &perf_count.xmtdiscards);
233 mad_encode_field(pc, IB_PC_ERR_XMTCONSTR_F,
234 &perf_count.xmtconstrainterrors);
235 mad_encode_field(pc, IB_PC_ERR_RCVCONSTR_F,
236 &perf_count.rcvconstrainterrors);
237 mad_encode_field(pc, IB_PC_ERR_LOCALINTEG_F,
238 &perf_count.linkintegrityerrors);
239 mad_encode_field(pc, IB_PC_ERR_EXCESS_OVR_F,
240 &perf_count.excbufoverrunerrors);
241 #ifdef HAVE_IB_PC_QP1_DROP_F
242 mad_encode_field(pc, IB_PC_QP1_DROP_F, &perf_count.qp1dropped);
243 #endif
244 mad_encode_field(pc, IB_PC_VL15_DROPPED_F, &perf_count.vl15dropped);
245 mad_encode_field(pc, IB_PC_XMT_BYTES_F, &perf_count.xmtdata);
246 mad_encode_field(pc, IB_PC_RCV_BYTES_F, &perf_count.rcvdata);
247 mad_encode_field(pc, IB_PC_XMT_PKTS_F, &perf_count.xmtpkts);
248 mad_encode_field(pc, IB_PC_RCV_PKTS_F, &perf_count.rcvpkts);
249 mad_encode_field(pc, IB_PC_XMT_WAIT_F, &perf_count.xmtwait);
250
251 mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
252
253 printf("# Port counters: %s port %d (CapMask: 0x%02X)\n%s",
254 portid2str(portid), ALL_PORTS, ntohs(cap_mask), buf);
255 }
256
aggregate_perfcounters_ext(uint16_t cap_mask,uint32_t cap_mask2)257 static void aggregate_perfcounters_ext(uint16_t cap_mask, uint32_t cap_mask2)
258 {
259 uint32_t val;
260 uint64_t val64;
261
262 mad_decode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val);
263 perf_count_ext.portselect = val;
264 mad_decode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &val);
265 perf_count_ext.counterselect = val;
266 mad_decode_field(pc, IB_PC_EXT_XMT_BYTES_F, &val64);
267 aggregate_64bit(&perf_count_ext.portxmitdata, val64);
268 mad_decode_field(pc, IB_PC_EXT_RCV_BYTES_F, &val64);
269 aggregate_64bit(&perf_count_ext.portrcvdata, val64);
270 mad_decode_field(pc, IB_PC_EXT_XMT_PKTS_F, &val64);
271 aggregate_64bit(&perf_count_ext.portxmitpkts, val64);
272 mad_decode_field(pc, IB_PC_EXT_RCV_PKTS_F, &val64);
273 aggregate_64bit(&perf_count_ext.portrcvpkts, val64);
274
275 if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) {
276 mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64);
277 aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64);
278 mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64);
279 aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64);
280 mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64);
281 aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64);
282 mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64);
283 aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64);
284 }
285
286 if (htonl(cap_mask2) & IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP) {
287 mad_decode_field(pc, IB_PC_EXT_COUNTER_SELECT2_F, &val);
288 perf_count_ext.counterSelect2 = val;
289 mad_decode_field(pc, IB_PC_EXT_ERR_SYM_F, &val64);
290 aggregate_64bit(&perf_count_ext.symbolErrorCounter, val64);
291 mad_decode_field(pc, IB_PC_EXT_LINK_RECOVERS_F, &val64);
292 aggregate_64bit(&perf_count_ext.linkErrorRecoveryCounter, val64);
293 mad_decode_field(pc, IB_PC_EXT_LINK_DOWNED_F, &val64);
294 aggregate_64bit(&perf_count_ext.linkDownedCounter, val64);
295 mad_decode_field(pc, IB_PC_EXT_ERR_RCV_F, &val64);
296 aggregate_64bit(&perf_count_ext.portRcvErrors, val64);
297 mad_decode_field(pc, IB_PC_EXT_ERR_PHYSRCV_F, &val64);
298 aggregate_64bit(&perf_count_ext.portRcvRemotePhysicalErrors, val64);
299 mad_decode_field(pc, IB_PC_EXT_ERR_SWITCH_REL_F, &val64);
300 aggregate_64bit(&perf_count_ext.portRcvSwitchRelayErrors, val64);
301 mad_decode_field(pc, IB_PC_EXT_XMT_DISCARDS_F, &val64);
302 aggregate_64bit(&perf_count_ext.portXmitDiscards, val64);
303 mad_decode_field(pc, IB_PC_EXT_ERR_XMTCONSTR_F, &val64);
304 aggregate_64bit(&perf_count_ext.portXmitConstraintErrors, val64);
305 mad_decode_field(pc, IB_PC_EXT_ERR_RCVCONSTR_F, &val64);
306 aggregate_64bit(&perf_count_ext.portRcvConstraintErrors, val64);
307 mad_decode_field(pc, IB_PC_EXT_ERR_LOCALINTEG_F, &val64);
308 aggregate_64bit(&perf_count_ext.localLinkIntegrityErrors, val64);
309 mad_decode_field(pc, IB_PC_EXT_ERR_EXCESS_OVR_F, &val64);
310 aggregate_64bit(&perf_count_ext.excessiveBufferOverrunErrors, val64);
311 mad_decode_field(pc, IB_PC_EXT_VL15_DROPPED_F, &val64);
312 aggregate_64bit(&perf_count_ext.VL15Dropped, val64);
313 mad_decode_field(pc, IB_PC_EXT_XMT_WAIT_F, &val64);
314 aggregate_64bit(&perf_count_ext.portXmitWait, val64);
315 mad_decode_field(pc, IB_PC_EXT_QP1_DROP_F, &val64);
316 aggregate_64bit(&perf_count_ext.QP1Dropped, val64);
317 }
318 }
319
output_aggregate_perfcounters_ext(ib_portid_t * portid,uint16_t cap_mask,uint32_t cap_mask2)320 static void output_aggregate_perfcounters_ext(ib_portid_t * portid,
321 uint16_t cap_mask, uint32_t cap_mask2)
322 {
323 char buf[1536];
324 uint32_t val = ALL_PORTS;
325
326 memset(buf, 0, sizeof(buf));
327
328 /* set port_select to 255 to emulate AllPortSelect */
329 mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val);
330 mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F,
331 &perf_count_ext.counterselect);
332 mad_encode_field(pc, IB_PC_EXT_XMT_BYTES_F,
333 &perf_count_ext.portxmitdata);
334 mad_encode_field(pc, IB_PC_EXT_RCV_BYTES_F,
335 &perf_count_ext.portrcvdata);
336 mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F,
337 &perf_count_ext.portxmitpkts);
338 mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts);
339
340 if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) {
341 mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F,
342 &perf_count_ext.portunicastxmitpkts);
343 mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F,
344 &perf_count_ext.portunicastrcvpkts);
345 mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F,
346 &perf_count_ext.portmulticastxmitpkits);
347 mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F,
348 &perf_count_ext.portmulticastrcvpkts);
349 }
350
351 if (htonl(cap_mask2) & IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP) {
352 mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT2_F,
353 &perf_count_ext.counterSelect2);
354 mad_encode_field(pc, IB_PC_EXT_ERR_SYM_F,
355 &perf_count_ext.symbolErrorCounter);
356 mad_encode_field(pc, IB_PC_EXT_LINK_RECOVERS_F,
357 &perf_count_ext.linkErrorRecoveryCounter);
358 mad_encode_field(pc, IB_PC_EXT_LINK_DOWNED_F,
359 &perf_count_ext.linkDownedCounter);
360 mad_encode_field(pc, IB_PC_EXT_ERR_RCV_F,
361 &perf_count_ext.portRcvErrors);
362 mad_encode_field(pc, IB_PC_EXT_ERR_PHYSRCV_F,
363 &perf_count_ext.portRcvRemotePhysicalErrors);
364 mad_encode_field(pc, IB_PC_EXT_ERR_SWITCH_REL_F,
365 &perf_count_ext.portRcvSwitchRelayErrors);
366 mad_encode_field(pc, IB_PC_EXT_XMT_DISCARDS_F,
367 &perf_count_ext.portXmitDiscards);
368 mad_encode_field(pc, IB_PC_EXT_ERR_XMTCONSTR_F,
369 &perf_count_ext.portXmitConstraintErrors);
370 mad_encode_field(pc, IB_PC_EXT_ERR_RCVCONSTR_F,
371 &perf_count_ext.portRcvConstraintErrors);
372 mad_encode_field(pc, IB_PC_EXT_ERR_LOCALINTEG_F,
373 &perf_count_ext.localLinkIntegrityErrors);
374 mad_encode_field(pc, IB_PC_EXT_ERR_EXCESS_OVR_F,
375 &perf_count_ext.excessiveBufferOverrunErrors);
376 mad_encode_field(pc, IB_PC_EXT_VL15_DROPPED_F,
377 &perf_count_ext.VL15Dropped);
378 mad_encode_field(pc, IB_PC_EXT_XMT_WAIT_F,
379 &perf_count_ext.portXmitWait);
380 mad_encode_field(pc, IB_PC_EXT_QP1_DROP_F,
381 &perf_count_ext.QP1Dropped);
382 }
383
384 mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
385
386 printf("# Port extended counters: %s port %d (CapMask: 0x%02X CapMask2: 0x%07X)\n%s",
387 portid2str(portid), ALL_PORTS, ntohs(cap_mask), cap_mask2, buf);
388 }
389
dump_perfcounters(int extended,int timeout,uint16_t cap_mask,uint32_t cap_mask2,ib_portid_t * portid,int port,int aggregate)390 static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
391 uint32_t cap_mask2, ib_portid_t * portid,
392 int port, int aggregate)
393 {
394 char buf[1536];
395
396 if (extended != 1) {
397 memset(pc, 0, sizeof(pc));
398 if (!pma_query_via(pc, portid, port, timeout,
399 IB_GSI_PORT_COUNTERS, srcport))
400 IBEXIT("perfquery");
401 if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) {
402 /* if PortCounters:PortXmitWait not supported clear this counter */
403 VERBOSE("PortXmitWait not indicated"
404 " so ignore this counter");
405 perf_count.xmtwait = 0;
406 mad_encode_field(pc, IB_PC_XMT_WAIT_F,
407 &perf_count.xmtwait);
408 }
409 if (aggregate)
410 aggregate_perfcounters();
411 else {
412 #ifdef HAVE_IB_PC_QP1_DROP_F
413 mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
414 #else
415 mad_dump_fields(buf, sizeof buf, pc, sizeof pc,
416 IB_PC_FIRST_F,
417 (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)?IB_PC_LAST_F:(IB_PC_RCV_PKTS_F+1));
418 #endif
419 }
420 } else {
421 /* 1.2 errata: bit 9 is extended counter support
422 * bit 10 is extended counter NoIETF
423 */
424 if (!(cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) &&
425 !(cap_mask & IB_PM_EXT_WIDTH_NOIETF_SUP))
426 IBWARN
427 ("PerfMgt ClassPortInfo CapMask 0x%02X; No extended counter support indicated\n",
428 ntohs(cap_mask));
429
430 memset(pc, 0, sizeof(pc));
431 if (!pma_query_via(pc, portid, port, timeout,
432 IB_GSI_PORT_COUNTERS_EXT, srcport))
433 IBEXIT("perfextquery");
434 if (aggregate)
435 aggregate_perfcounters_ext(cap_mask, cap_mask2);
436 else
437 mad_dump_perfcounters_ext(buf, sizeof buf, pc,
438 sizeof pc);
439 }
440
441 if (!aggregate) {
442 if (extended)
443 printf("# Port extended counters: %s port %d "
444 "(CapMask: 0x%02X CapMask2: 0x%07X)\n%s",
445 portid2str(portid), port, ntohs(cap_mask),
446 cap_mask2, buf);
447 else
448 printf("# Port counters: %s port %d "
449 "(CapMask: 0x%02X)\n%s",
450 portid2str(portid), port, ntohs(cap_mask), buf);
451 }
452 }
453
reset_counters(int extended,int timeout,int mask,ib_portid_t * portid,int port)454 static void reset_counters(int extended, int timeout, int mask,
455 ib_portid_t * portid, int port)
456 {
457 memset(pc, 0, sizeof(pc));
458 if (extended != 1) {
459 if (!performance_reset_via(pc, portid, port, mask, timeout,
460 IB_GSI_PORT_COUNTERS, srcport))
461 IBEXIT("perf reset");
462 } else {
463 if (!performance_reset_via(pc, portid, port, mask, timeout,
464 IB_GSI_PORT_COUNTERS_EXT, srcport))
465 IBEXIT("perf ext reset");
466 }
467 }
468
469 static int reset, reset_only, all_ports, loop_ports, port, extended, xmt_sl,
470 rcv_sl, xmt_disc, rcv_err, extended_speeds, smpl_ctl, oprcvcounters, flowctlcounters,
471 vloppackets, vlopdata, vlxmitflowctlerrors, vlxmitcounters, swportvlcong,
472 rcvcc, slrcvfecn, slrcvbecn, xmitcc, vlxmittimecc;
473 static int ports[MAX_PORTS];
474 static int ports_count;
475
common_func(ib_portid_t * portid,int port_num,int mask,unsigned query,unsigned reset,const char * name,uint16_t attr,void dump_func (char *,int,void *,int))476 static void common_func(ib_portid_t * portid, int port_num, int mask,
477 unsigned query, unsigned reset,
478 const char *name, uint16_t attr,
479 void dump_func(char *, int, void *, int))
480 {
481 char buf[1536];
482
483 if (query) {
484 memset(pc, 0, sizeof(pc));
485 if (!pma_query_via(pc, portid, port_num, ibd_timeout, attr,
486 srcport))
487 IBEXIT("cannot query %s", name);
488
489 dump_func(buf, sizeof(buf), pc, sizeof(pc));
490
491 printf("# %s counters: %s port %d\n%s", name,
492 portid2str(portid), port_num, buf);
493 }
494
495 memset(pc, 0, sizeof(pc));
496 if (reset && !performance_reset_via(pc, portid, port, mask, ibd_timeout,
497 attr, srcport))
498 IBEXIT("cannot reset %s", name);
499 }
500
xmt_sl_query(ib_portid_t * portid,int port,int mask)501 static void xmt_sl_query(ib_portid_t * portid, int port, int mask)
502 {
503 common_func(portid, port, mask, !reset_only, (reset_only || reset),
504 "PortXmitDataSL", IB_GSI_PORT_XMIT_DATA_SL,
505 mad_dump_perfcounters_xmt_sl);
506 }
507
rcv_sl_query(ib_portid_t * portid,int port,int mask)508 static void rcv_sl_query(ib_portid_t * portid, int port, int mask)
509 {
510 common_func(portid, port, mask, !reset_only, (reset_only || reset),
511 "PortRcvDataSL", IB_GSI_PORT_RCV_DATA_SL,
512 mad_dump_perfcounters_rcv_sl);
513 }
514
xmt_disc_query(ib_portid_t * portid,int port,int mask)515 static void xmt_disc_query(ib_portid_t * portid, int port, int mask)
516 {
517 common_func(portid, port, mask, !reset_only, (reset_only || reset),
518 "PortXmitDiscardDetails", IB_GSI_PORT_XMIT_DISCARD_DETAILS,
519 mad_dump_perfcounters_xmt_disc);
520 }
521
rcv_err_query(ib_portid_t * portid,int port,int mask)522 static void rcv_err_query(ib_portid_t * portid, int port, int mask)
523 {
524 common_func(portid, port, mask, !reset_only, (reset_only || reset),
525 "PortRcvErrorDetails", IB_GSI_PORT_RCV_ERROR_DETAILS,
526 mad_dump_perfcounters_rcv_err);
527 }
528
ext_speeds_reset_via(void * rcvbuf,ib_portid_t * dest,int port,uint64_t mask,unsigned timeout,const struct ibmad_port * srcport)529 static uint8_t *ext_speeds_reset_via(void *rcvbuf, ib_portid_t * dest,
530 int port, uint64_t mask, unsigned timeout,
531 const struct ibmad_port * srcport)
532 {
533 ib_rpc_t rpc = { 0 };
534 int lid = dest->lid;
535
536 DEBUG("lid %u port %d mask 0x%" PRIx64, lid, port, mask);
537
538 if (lid == -1) {
539 IBWARN("only lid routed is supported");
540 return NULL;
541 }
542
543 if (!mask)
544 mask = ~0;
545
546 rpc.mgtclass = IB_PERFORMANCE_CLASS;
547 rpc.method = IB_MAD_METHOD_SET;
548 rpc.attr.id = IB_GSI_PORT_EXT_SPEEDS_COUNTERS;
549
550 memset(rcvbuf, 0, IB_MAD_SIZE);
551
552 mad_set_field(rcvbuf, 0, IB_PESC_PORT_SELECT_F, port);
553 mad_set_field64(rcvbuf, 0, IB_PESC_COUNTER_SELECT_F, mask);
554 rpc.attr.mod = 0;
555 rpc.timeout = timeout;
556 rpc.datasz = IB_PC_DATA_SZ;
557 rpc.dataoffs = IB_PC_DATA_OFFS;
558 if (!dest->qp)
559 dest->qp = 1;
560 if (!dest->qkey)
561 dest->qkey = IB_DEFAULT_QP1_QKEY;
562
563 return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
564 }
565
is_rsfec_mode_active(ib_portid_t * portid,int port,uint16_t cap_mask)566 static uint8_t is_rsfec_mode_active(ib_portid_t * portid, int port,
567 uint16_t cap_mask)
568 {
569 uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
570 uint32_t fec_mode_active = 0;
571 uint32_t pie_capmask = 0;
572 if (cap_mask & IS_PM_RSFEC_COUNTERS_SUP) {
573 if (!is_port_info_extended_supported(portid, port, srcport)) {
574 IBWARN("Port Info Extended not supported");
575 return 0;
576 }
577
578 if (!smp_query_via(data, portid, IB_ATTR_PORT_INFO_EXT, port, 0,
579 srcport))
580 IBEXIT("smp query portinfo extended failed");
581
582 mad_decode_field(data, IB_PORT_EXT_CAPMASK_F, &pie_capmask);
583 mad_decode_field(data, IB_PORT_EXT_FEC_MODE_ACTIVE_F,
584 &fec_mode_active);
585 if((pie_capmask &
586 CL_NTOH32(IB_PORT_EXT_CAP_IS_FEC_MODE_SUPPORTED)) &&
587 (CL_NTOH16(IB_PORT_EXT_RS_FEC_MODE_ACTIVE) == (fec_mode_active & 0xffff)))
588 return 1;
589 }
590
591 return 0;
592 }
593
extended_speeds_query(ib_portid_t * portid,int port,uint64_t ext_mask,uint16_t cap_mask)594 static void extended_speeds_query(ib_portid_t * portid, int port,
595 uint64_t ext_mask, uint16_t cap_mask)
596 {
597 int mask = ext_mask;
598
599 if (!reset_only) {
600 if (is_rsfec_mode_active(portid, port, cap_mask))
601 common_func(portid, port, mask, 1, 0,
602 "PortExtendedSpeedsCounters with RS-FEC Active",
603 IB_GSI_PORT_EXT_SPEEDS_COUNTERS,
604 mad_dump_port_ext_speeds_counters_rsfec_active);
605 else
606 common_func(portid, port, mask, 1, 0,
607 "PortExtendedSpeedsCounters",
608 IB_GSI_PORT_EXT_SPEEDS_COUNTERS,
609 mad_dump_port_ext_speeds_counters);
610 }
611
612 if ((reset_only || reset) &&
613 !ext_speeds_reset_via(pc, portid, port, ext_mask, ibd_timeout, srcport))
614 IBEXIT("cannot reset PortExtendedSpeedsCounters");
615 }
616
oprcvcounters_query(ib_portid_t * portid,int port,int mask)617 static void oprcvcounters_query(ib_portid_t * portid, int port, int mask)
618 {
619 common_func(portid, port, mask, !reset_only, (reset_only || reset),
620 "PortOpRcvCounters", IB_GSI_PORT_PORT_OP_RCV_COUNTERS,
621 mad_dump_perfcounters_port_op_rcv_counters);
622 }
623
flowctlcounters_query(ib_portid_t * portid,int port,int mask)624 static void flowctlcounters_query(ib_portid_t * portid, int port, int mask)
625 {
626 common_func(portid, port, mask, !reset_only, (reset_only || reset),
627 "PortFlowCtlCounters", IB_GSI_PORT_PORT_FLOW_CTL_COUNTERS,
628 mad_dump_perfcounters_port_flow_ctl_counters);
629 }
630
vloppackets_query(ib_portid_t * portid,int port,int mask)631 static void vloppackets_query(ib_portid_t * portid, int port, int mask)
632 {
633 common_func(portid, port, mask, !reset_only, (reset_only || reset),
634 "PortVLOpPackets", IB_GSI_PORT_PORT_VL_OP_PACKETS,
635 mad_dump_perfcounters_port_vl_op_packet);
636 }
637
vlopdata_query(ib_portid_t * portid,int port,int mask)638 static void vlopdata_query(ib_portid_t * portid, int port, int mask)
639 {
640 common_func(portid, port, mask, !reset_only, (reset_only || reset),
641 "PortVLOpData", IB_GSI_PORT_PORT_VL_OP_DATA,
642 mad_dump_perfcounters_port_vl_op_data);
643 }
644
vlxmitflowctlerrors_query(ib_portid_t * portid,int port,int mask)645 static void vlxmitflowctlerrors_query(ib_portid_t * portid, int port, int mask)
646 {
647 common_func(portid, port, mask, !reset_only, (reset_only || reset),
648 "PortVLXmitFlowCtlUpdateErrors", IB_GSI_PORT_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS,
649 mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors);
650 }
651
vlxmitcounters_query(ib_portid_t * portid,int port,int mask)652 static void vlxmitcounters_query(ib_portid_t * portid, int port, int mask)
653 {
654 common_func(portid, port, mask, !reset_only, (reset_only || reset),
655 "PortVLXmitWaitCounters", IB_GSI_PORT_PORT_VL_XMIT_WAIT_COUNTERS,
656 mad_dump_perfcounters_port_vl_xmit_wait_counters);
657 }
658
swportvlcong_query(ib_portid_t * portid,int port,int mask)659 static void swportvlcong_query(ib_portid_t * portid, int port, int mask)
660 {
661 common_func(portid, port, mask, !reset_only, (reset_only || reset),
662 "SwPortVLCongestion", IB_GSI_SW_PORT_VL_CONGESTION,
663 mad_dump_perfcounters_sw_port_vl_congestion);
664 }
665
rcvcc_query(ib_portid_t * portid,int port,int mask)666 static void rcvcc_query(ib_portid_t * portid, int port, int mask)
667 {
668 common_func(portid, port, mask, !reset_only, (reset_only || reset),
669 "PortRcvConCtrl", IB_GSI_PORT_RCV_CON_CTRL,
670 mad_dump_perfcounters_rcv_con_ctrl);
671 }
672
slrcvfecn_query(ib_portid_t * portid,int port,int mask)673 static void slrcvfecn_query(ib_portid_t * portid, int port, int mask)
674 {
675 common_func(portid, port, mask, !reset_only, (reset_only || reset),
676 "PortSLRcvFECN", IB_GSI_PORT_SL_RCV_FECN,
677 mad_dump_perfcounters_sl_rcv_fecn);
678 }
679
slrcvbecn_query(ib_portid_t * portid,int port,int mask)680 static void slrcvbecn_query(ib_portid_t * portid, int port, int mask)
681 {
682 common_func(portid, port, mask, !reset_only, (reset_only || reset),
683 "PortSLRcvBECN", IB_GSI_PORT_SL_RCV_BECN,
684 mad_dump_perfcounters_sl_rcv_becn);
685 }
686
xmitcc_query(ib_portid_t * portid,int port,int mask)687 static void xmitcc_query(ib_portid_t * portid, int port, int mask)
688 {
689 common_func(portid, port, mask, !reset_only, (reset_only || reset),
690 "PortXmitConCtrl", IB_GSI_PORT_XMIT_CON_CTRL,
691 mad_dump_perfcounters_xmit_con_ctrl);
692 }
693
vlxmittimecc_query(ib_portid_t * portid,int port,int mask)694 static void vlxmittimecc_query(ib_portid_t * portid, int port, int mask)
695 {
696 common_func(portid, port, mask, !reset_only, (reset_only || reset),
697 "PortVLXmitTimeCong", IB_GSI_PORT_VL_XMIT_TIME_CONG,
698 mad_dump_perfcounters_vl_xmit_time_cong);
699 }
700
dump_portsamples_control(ib_portid_t * portid,int port)701 void dump_portsamples_control(ib_portid_t * portid, int port)
702 {
703 char buf[1280];
704
705 memset(pc, 0, sizeof(pc));
706 if (!pma_query_via(pc, portid, port, ibd_timeout,
707 IB_GSI_PORT_SAMPLES_CONTROL, srcport))
708 IBEXIT("sampctlquery");
709
710 mad_dump_portsamples_control(buf, sizeof buf, pc, sizeof pc);
711 printf("# PortSamplesControl: %s port %d\n%s", portid2str(portid),
712 port, buf);
713 }
714
process_opt(void * context,int ch,char * optarg)715 static int process_opt(void *context, int ch, char *optarg)
716 {
717 switch (ch) {
718 case 'x':
719 extended = 1;
720 break;
721 case 'X':
722 xmt_sl = 1;
723 break;
724 case 'S':
725 rcv_sl = 1;
726 break;
727 case 'D':
728 xmt_disc = 1;
729 break;
730 case 'E':
731 rcv_err = 1;
732 break;
733 case 'T':
734 extended_speeds = 1;
735 break;
736 case 'c':
737 smpl_ctl = 1;
738 break;
739 case 1:
740 oprcvcounters = 1;
741 break;
742 case 2:
743 flowctlcounters = 1;
744 break;
745 case 3:
746 vloppackets = 1;
747 break;
748 case 4:
749 vlopdata = 1;
750 break;
751 case 5:
752 vlxmitflowctlerrors = 1;
753 break;
754 case 6:
755 vlxmitcounters = 1;
756 break;
757 case 7:
758 swportvlcong = 1;
759 break;
760 case 8:
761 rcvcc = 1;
762 break;
763 case 9:
764 slrcvfecn = 1;
765 break;
766 case 10:
767 slrcvbecn = 1;
768 break;
769 case 11:
770 xmitcc = 1;
771 break;
772 case 12:
773 vlxmittimecc = 1;
774 break;
775 case 'a':
776 all_ports++;
777 port = ALL_PORTS;
778 break;
779 case 'l':
780 loop_ports++;
781 break;
782 case 'r':
783 reset++;
784 break;
785 case 'R':
786 reset_only++;
787 break;
788 case 25:
789 if (!inet_pton(AF_INET6, optarg, &dgid)) {
790 fprintf(stderr, "dgid format is wrong!\n");
791 ibdiag_show_usage();
792 return 1;
793 }
794 with_grh = 1;
795 break;
796 default:
797 return -1;
798 }
799 return 0;
800 }
801
main(int argc,char ** argv)802 int main(int argc, char **argv)
803 {
804 int mgmt_classes[3] = { IB_SMI_CLASS, IB_SA_CLASS, IB_PERFORMANCE_CLASS };
805 ib_portid_t portid = { 0 };
806 int mask = 0xffff;
807 uint64_t ext_mask = 0xffffffffffffffffULL;
808 uint32_t cap_mask2;
809 uint16_t cap_mask;
810 int all_ports_loop = 0;
811 int node_type, num_ports = 0;
812 uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
813 int start_port = 1;
814 int enhancedport0;
815 char *tmpstr;
816 int i;
817
818 const struct ibdiag_opt opts[] = {
819 {"extended", 'x', 0, NULL, "show extended port counters"},
820 {"xmtsl", 'X', 0, NULL, "show Xmt SL port counters"},
821 {"rcvsl", 'S', 0, NULL, "show Rcv SL port counters"},
822 {"xmtdisc", 'D', 0, NULL, "show Xmt Discard Details"},
823 {"rcverr", 'E', 0, NULL, "show Rcv Error Details"},
824 {"extended_speeds", 'T', 0, NULL, "show port extended speeds counters"},
825 {"oprcvcounters", 1, 0, NULL, "show Rcv Counters per Op code"},
826 {"flowctlcounters", 2, 0, NULL, "show flow control counters"},
827 {"vloppackets", 3, 0, NULL, "show packets received per Op code per VL"},
828 {"vlopdata", 4, 0, NULL, "show data received per Op code per VL"},
829 {"vlxmitflowctlerrors", 5, 0, NULL, "show flow control update errors per VL"},
830 {"vlxmitcounters", 6, 0, NULL, "show ticks waiting to transmit counters per VL"},
831 {"swportvlcong", 7, 0, NULL, "show sw port VL congestion"},
832 {"rcvcc", 8, 0, NULL, "show Rcv congestion control counters"},
833 {"slrcvfecn", 9, 0, NULL, "show SL Rcv FECN counters"},
834 {"slrcvbecn", 10, 0, NULL, "show SL Rcv BECN counters"},
835 {"xmitcc", 11, 0, NULL, "show Xmit congestion control counters"},
836 {"vlxmittimecc", 12, 0, NULL, "show VL Xmit Time congestion control counters"},
837 {"smplctl", 'c', 0, NULL, "show samples control"},
838 {"all_ports", 'a', 0, NULL, "show aggregated counters"},
839 {"loop_ports", 'l', 0, NULL, "iterate through each port"},
840 {"reset_after_read", 'r', 0, NULL, "reset counters after read"},
841 {"Reset_only", 'R', 0, NULL, "only reset counters"},
842 {"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
843 {0}
844 };
845 char usage_args[] = " [<lid|guid> [[port(s)] [reset_mask]]]";
846 const char *usage_examples[] = {
847 "\t\t# read local port's performance counters",
848 "32 1\t\t# read performance counters from lid 32, port 1",
849 "-x 32 1\t# read extended performance counters from lid 32, port 1",
850 "-a 32\t\t# read performance counters from lid 32, all ports",
851 "-r 32 1\t# read performance counters and reset",
852 "-x -r 32 1\t# read extended performance counters and reset",
853 "-R 0x20 1\t# reset performance counters of port 1 only",
854 "-x -R 0x20 1\t# reset extended performance counters of port 1 only",
855 "-R -a 32\t# reset performance counters of all ports",
856 "-R 32 2 0x0fff\t# reset only error counters of port 2",
857 "-R 32 2 0xf000\t# reset only non-error counters of port 2",
858 "-a 32 1-10\t# read performance counters from lid 32, port 1-10, aggregate output",
859 "-l 32 1-10\t# read performance counters from lid 32, port 1-10, output each port",
860 "-a 32 1,4,8\t# read performance counters from lid 32, port 1, 4, and 8, aggregate output",
861 "-l 32 1,4,8\t# read performance counters from lid 32, port 1, 4, and 8, output each port",
862 NULL,
863 };
864
865 ibdiag_process_opts(argc, argv, NULL, "DK", opts, process_opt,
866 usage_args, usage_examples);
867
868 argc -= optind;
869 argv += optind;
870
871 if (argc > 1) {
872 if (strchr(argv[1], ',')) {
873 tmpstr = strtok(argv[1], ",");
874 while (tmpstr) {
875 ports[ports_count++] = strtoul(tmpstr, 0, 0);
876 tmpstr = strtok(NULL, ",");
877 }
878 port = ports[0];
879 }
880 else if ((tmpstr = strchr(argv[1], '-'))) {
881 int pmin, pmax;
882
883 *tmpstr = '\0';
884 tmpstr++;
885
886 pmin = strtoul(argv[1], 0, 0);
887 pmax = strtoul(tmpstr, 0, 0);
888
889 if (pmin >= pmax)
890 IBEXIT("max port must be greater than min port in range");
891
892 while (pmin <= pmax)
893 ports[ports_count++] = pmin++;
894
895 port = ports[0];
896 }
897 else
898 port = strtoul(argv[1], 0, 0);
899 }
900 if (argc > 2) {
901 ext_mask = strtoull(argv[2], 0, 0);
902 mask = ext_mask;
903 }
904
905 srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
906 if (!srcport)
907 IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
908
909 smp_mkey_set(srcport, ibd_mkey);
910
911 if (argc) {
912 if (with_grh && ibd_dest_type != IB_DEST_LID)
913 IBEXIT("When using GRH, LID should be provided");
914 if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
915 ibd_dest_type, ibd_sm_id, srcport) < 0)
916 IBEXIT("can't resolve destination port %s", argv[0]);
917 if (with_grh) {
918 portid.grh_present = 1;
919 memcpy(&portid.gid, &dgid, sizeof(portid.gid));
920 }
921 } else {
922 if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, 0) < 0)
923 IBEXIT("can't resolve self port %s", argv[0]);
924 }
925
926 /* PerfMgt ClassPortInfo is a required attribute */
927 memset(pc, 0, sizeof(pc));
928 if (!pma_query_via(pc, &portid, port, ibd_timeout, CLASS_PORT_INFO,
929 srcport))
930 IBEXIT("classportinfo query");
931 /* ClassPortInfo should be supported as part of libibmad */
932 memcpy(&cap_mask, pc + 2, sizeof(cap_mask)); /* CapabilityMask */
933 memcpy(&cap_mask2, pc + 4, sizeof(cap_mask2)); /* CapabilityMask2 */
934 cap_mask2 = ntohl(cap_mask2) >> 5;
935
936 if (!(cap_mask & IB_PM_ALL_PORT_SELECT)) { /* bit 8 is AllPortSelect */
937 if (!all_ports && port == ALL_PORTS)
938 IBEXIT("AllPortSelect not supported");
939 if (all_ports && port == ALL_PORTS)
940 all_ports_loop = 1;
941 }
942
943 if (xmt_sl) {
944 xmt_sl_query(&portid, port, mask);
945 goto done;
946 }
947
948 if (rcv_sl) {
949 rcv_sl_query(&portid, port, mask);
950 goto done;
951 }
952
953 if (xmt_disc) {
954 xmt_disc_query(&portid, port, mask);
955 goto done;
956 }
957
958 if (rcv_err) {
959 rcv_err_query(&portid, port, mask);
960 goto done;
961 }
962
963 if (extended_speeds) {
964 extended_speeds_query(&portid, port, ext_mask, cap_mask);
965 goto done;
966 }
967
968 if (oprcvcounters) {
969 oprcvcounters_query(&portid, port, mask);
970 goto done;
971 }
972
973 if (flowctlcounters) {
974 flowctlcounters_query(&portid, port, mask);
975 goto done;
976 }
977
978 if (vloppackets) {
979 vloppackets_query(&portid, port, mask);
980 goto done;
981 }
982
983 if (vlopdata) {
984 vlopdata_query(&portid, port, mask);
985 goto done;
986 }
987
988 if (vlxmitflowctlerrors) {
989 vlxmitflowctlerrors_query(&portid, port, mask);
990 goto done;
991 }
992
993 if (vlxmitcounters) {
994 vlxmitcounters_query(&portid, port, mask);
995 goto done;
996 }
997
998 if (swportvlcong) {
999 swportvlcong_query(&portid, port, mask);
1000 goto done;
1001 }
1002
1003 if (rcvcc) {
1004 rcvcc_query(&portid, port, mask);
1005 goto done;
1006 }
1007
1008 if (slrcvfecn) {
1009 slrcvfecn_query(&portid, port, mask);
1010 goto done;
1011 }
1012
1013 if (slrcvbecn) {
1014 slrcvbecn_query(&portid, port, mask);
1015 goto done;
1016 }
1017
1018 if (xmitcc) {
1019 xmitcc_query(&portid, port, mask);
1020 goto done;
1021 }
1022
1023 if (vlxmittimecc) {
1024 vlxmittimecc_query(&portid, port, mask);
1025 goto done;
1026 }
1027
1028 if (smpl_ctl) {
1029 dump_portsamples_control(&portid, port);
1030 goto done;
1031 }
1032
1033
1034 if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
1035 if (!smp_query_via(data, &portid, IB_ATTR_NODE_INFO, 0, 0,
1036 srcport))
1037 IBEXIT("smp query nodeinfo failed");
1038 node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
1039 mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports);
1040 if (!num_ports)
1041 IBEXIT("smp query nodeinfo: num ports invalid");
1042
1043 if (node_type == IB_NODE_SWITCH) {
1044 if (!smp_query_via(data, &portid, IB_ATTR_SWITCH_INFO,
1045 0, 0, srcport))
1046 IBEXIT("smp query nodeinfo failed");
1047 enhancedport0 =
1048 mad_get_field(data, 0, IB_SW_ENHANCED_PORT0_F);
1049 if (enhancedport0)
1050 start_port = 0;
1051 }
1052 if (all_ports_loop && !loop_ports)
1053 IBWARN
1054 ("Emulating AllPortSelect by iterating through all ports");
1055 }
1056
1057 if (reset_only)
1058 goto do_reset;
1059
1060 if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
1061 for (i = start_port; i <= num_ports; i++)
1062 dump_perfcounters(extended, ibd_timeout,
1063 cap_mask, cap_mask2,
1064 &portid, i, (all_ports_loop
1065 && !loop_ports));
1066 if (all_ports_loop && !loop_ports) {
1067 if (extended != 1)
1068 output_aggregate_perfcounters(&portid,
1069 cap_mask);
1070 else
1071 output_aggregate_perfcounters_ext(&portid,
1072 cap_mask, cap_mask2);
1073 }
1074 } else if (ports_count > 1) {
1075 for (i = 0; i < ports_count; i++)
1076 dump_perfcounters(extended, ibd_timeout, cap_mask,
1077 cap_mask2, &portid, ports[i],
1078 (all_ports && !loop_ports));
1079 if (all_ports && !loop_ports) {
1080 if (extended != 1)
1081 output_aggregate_perfcounters(&portid,
1082 cap_mask);
1083 else
1084 output_aggregate_perfcounters_ext(&portid,
1085 cap_mask, cap_mask2);
1086 }
1087 } else
1088 dump_perfcounters(extended, ibd_timeout, cap_mask, cap_mask2,
1089 &portid, port, 0);
1090
1091 if (!reset)
1092 goto done;
1093
1094 do_reset:
1095 if (argc <= 2 && !extended) {
1096 if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)
1097 mask |= (1 << 16); /* reset portxmitwait */
1098 if (cap_mask & IB_PM_IS_QP1_DROP_SUP)
1099 mask |= (1 << 17); /* reset qp1dropped */
1100 }
1101
1102 if (extended) {
1103 mask |= 0xfff0000;
1104 if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)
1105 mask |= (1 << 28);
1106 if (cap_mask & IB_PM_IS_QP1_DROP_SUP)
1107 mask |= (1 << 29);
1108 }
1109
1110 if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
1111 for (i = start_port; i <= num_ports; i++)
1112 reset_counters(extended, ibd_timeout, mask, &portid, i);
1113 } else if (ports_count > 1) {
1114 for (i = 0; i < ports_count; i++)
1115 reset_counters(extended, ibd_timeout, mask, &portid, ports[i]);
1116 } else
1117 reset_counters(extended, ibd_timeout, mask, &portid, port);
1118
1119 done:
1120 mad_rpc_close_port(srcport);
1121 exit(0);
1122 }
1123