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