1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky * Copyright (c) 2012 Mellanox Technologies LTD. All rights reserved.
3*d6b92ffaSHans Petter Selasky * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
4*d6b92ffaSHans Petter Selasky *
5*d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
6*d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
7*d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
8*d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
9*d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
10*d6b92ffaSHans Petter Selasky *
11*d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
12*d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
13*d6b92ffaSHans Petter Selasky * conditions are met:
14*d6b92ffaSHans Petter Selasky *
15*d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
16*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
17*d6b92ffaSHans Petter Selasky * disclaimer.
18*d6b92ffaSHans Petter Selasky *
19*d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
20*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
21*d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
22*d6b92ffaSHans Petter Selasky * provided with the distribution.
23*d6b92ffaSHans Petter Selasky *
24*d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25*d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26*d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27*d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28*d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29*d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30*d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31*d6b92ffaSHans Petter Selasky * SOFTWARE.
32*d6b92ffaSHans Petter Selasky *
33*d6b92ffaSHans Petter Selasky */
34*d6b92ffaSHans Petter Selasky
35*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
36*d6b92ffaSHans Petter Selasky # include <config.h>
37*d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */
38*d6b92ffaSHans Petter Selasky
39*d6b92ffaSHans Petter Selasky #include <stdio.h>
40*d6b92ffaSHans Petter Selasky #include <stdlib.h>
41*d6b92ffaSHans Petter Selasky #include <unistd.h>
42*d6b92ffaSHans Petter Selasky #include <getopt.h>
43*d6b92ffaSHans Petter Selasky #include <netinet/in.h>
44*d6b92ffaSHans Petter Selasky
45*d6b92ffaSHans Petter Selasky #include <infiniband/umad.h>
46*d6b92ffaSHans Petter Selasky #include <infiniband/mad.h>
47*d6b92ffaSHans Petter Selasky
48*d6b92ffaSHans Petter Selasky #include "ibdiag_common.h"
49*d6b92ffaSHans Petter Selasky
50*d6b92ffaSHans Petter Selasky #define IS3_DEVICE_ID 47396
51*d6b92ffaSHans Petter Selasky
52*d6b92ffaSHans Petter Selasky #define IB_MLX_VENDOR_CLASS 10
53*d6b92ffaSHans Petter Selasky /* Vendor specific Attribute IDs */
54*d6b92ffaSHans Petter Selasky #define IB_MLX_IS3_GENERAL_INFO 0x17
55*d6b92ffaSHans Petter Selasky #define IB_MLX_IS3_CONFIG_SPACE_ACCESS 0x50
56*d6b92ffaSHans Petter Selasky #define IB_MLX_IS4_COUNTER_GROUP_INFO 0x90
57*d6b92ffaSHans Petter Selasky #define IB_MLX_IS4_CONFIG_COUNTER_GROUP 0x91
58*d6b92ffaSHans Petter Selasky /* Config space addresses */
59*d6b92ffaSHans Petter Selasky #define IB_MLX_IS3_PORT_XMIT_WAIT 0x10013C
60*d6b92ffaSHans Petter Selasky
61*d6b92ffaSHans Petter Selasky
62*d6b92ffaSHans Petter Selasky struct ibmad_port *srcport;
63*d6b92ffaSHans Petter Selasky
64*d6b92ffaSHans Petter Selasky static ibmad_gid_t dgid;
65*d6b92ffaSHans Petter Selasky static int with_grh;
66*d6b92ffaSHans Petter Selasky
67*d6b92ffaSHans Petter Selasky typedef struct {
68*d6b92ffaSHans Petter Selasky uint16_t hw_revision;
69*d6b92ffaSHans Petter Selasky uint16_t device_id;
70*d6b92ffaSHans Petter Selasky uint8_t reserved[24];
71*d6b92ffaSHans Petter Selasky uint32_t uptime;
72*d6b92ffaSHans Petter Selasky } is3_hw_info_t;
73*d6b92ffaSHans Petter Selasky
74*d6b92ffaSHans Petter Selasky typedef struct {
75*d6b92ffaSHans Petter Selasky uint8_t resv1;
76*d6b92ffaSHans Petter Selasky uint8_t major;
77*d6b92ffaSHans Petter Selasky uint8_t minor;
78*d6b92ffaSHans Petter Selasky uint8_t sub_minor;
79*d6b92ffaSHans Petter Selasky uint32_t build_id;
80*d6b92ffaSHans Petter Selasky uint8_t month;
81*d6b92ffaSHans Petter Selasky uint8_t day;
82*d6b92ffaSHans Petter Selasky uint16_t year;
83*d6b92ffaSHans Petter Selasky uint16_t resv2;
84*d6b92ffaSHans Petter Selasky uint16_t hour;
85*d6b92ffaSHans Petter Selasky uint8_t psid[16];
86*d6b92ffaSHans Petter Selasky uint32_t ini_file_version;
87*d6b92ffaSHans Petter Selasky } is3_fw_info_t;
88*d6b92ffaSHans Petter Selasky
89*d6b92ffaSHans Petter Selasky typedef struct {
90*d6b92ffaSHans Petter Selasky uint32_t ext_major;
91*d6b92ffaSHans Petter Selasky uint32_t ext_minor;
92*d6b92ffaSHans Petter Selasky uint32_t ext_sub_minor;
93*d6b92ffaSHans Petter Selasky uint32_t reserved[4];
94*d6b92ffaSHans Petter Selasky } is4_fw_ext_info_t;
95*d6b92ffaSHans Petter Selasky
96*d6b92ffaSHans Petter Selasky typedef struct {
97*d6b92ffaSHans Petter Selasky uint8_t resv1;
98*d6b92ffaSHans Petter Selasky uint8_t major;
99*d6b92ffaSHans Petter Selasky uint8_t minor;
100*d6b92ffaSHans Petter Selasky uint8_t sub_minor;
101*d6b92ffaSHans Petter Selasky uint8_t resv2[28];
102*d6b92ffaSHans Petter Selasky } is3_sw_info_t;
103*d6b92ffaSHans Petter Selasky
104*d6b92ffaSHans Petter Selasky typedef struct {
105*d6b92ffaSHans Petter Selasky uint8_t reserved[8];
106*d6b92ffaSHans Petter Selasky is3_hw_info_t hw_info;
107*d6b92ffaSHans Petter Selasky is3_fw_info_t fw_info;
108*d6b92ffaSHans Petter Selasky is3_sw_info_t sw_info;
109*d6b92ffaSHans Petter Selasky } is3_general_info_t;
110*d6b92ffaSHans Petter Selasky
111*d6b92ffaSHans Petter Selasky typedef struct {
112*d6b92ffaSHans Petter Selasky uint8_t reserved[8];
113*d6b92ffaSHans Petter Selasky is3_hw_info_t hw_info;
114*d6b92ffaSHans Petter Selasky is3_fw_info_t fw_info;
115*d6b92ffaSHans Petter Selasky is4_fw_ext_info_t ext_fw_info;
116*d6b92ffaSHans Petter Selasky is3_sw_info_t sw_info;
117*d6b92ffaSHans Petter Selasky } is4_general_info_t;
118*d6b92ffaSHans Petter Selasky
119*d6b92ffaSHans Petter Selasky typedef struct {
120*d6b92ffaSHans Petter Selasky uint8_t reserved[8];
121*d6b92ffaSHans Petter Selasky struct is3_record {
122*d6b92ffaSHans Petter Selasky uint32_t address;
123*d6b92ffaSHans Petter Selasky uint32_t data;
124*d6b92ffaSHans Petter Selasky uint32_t mask;
125*d6b92ffaSHans Petter Selasky } record[18];
126*d6b92ffaSHans Petter Selasky } is3_config_space_t;
127*d6b92ffaSHans Petter Selasky
128*d6b92ffaSHans Petter Selasky #define COUNTER_GROUPS_NUM 2
129*d6b92ffaSHans Petter Selasky
130*d6b92ffaSHans Petter Selasky typedef struct {
131*d6b92ffaSHans Petter Selasky uint8_t reserved1[8];
132*d6b92ffaSHans Petter Selasky uint8_t reserved[3];
133*d6b92ffaSHans Petter Selasky uint8_t num_of_counter_groups;
134*d6b92ffaSHans Petter Selasky uint32_t group_masks[COUNTER_GROUPS_NUM];
135*d6b92ffaSHans Petter Selasky } is4_counter_group_info_t;
136*d6b92ffaSHans Petter Selasky
137*d6b92ffaSHans Petter Selasky typedef struct {
138*d6b92ffaSHans Petter Selasky uint8_t reserved[3];
139*d6b92ffaSHans Petter Selasky uint8_t group_select;
140*d6b92ffaSHans Petter Selasky } is4_group_select_t;
141*d6b92ffaSHans Petter Selasky
142*d6b92ffaSHans Petter Selasky typedef struct {
143*d6b92ffaSHans Petter Selasky uint8_t reserved1[8];
144*d6b92ffaSHans Petter Selasky uint8_t reserved[4];
145*d6b92ffaSHans Petter Selasky is4_group_select_t group_selects[COUNTER_GROUPS_NUM];
146*d6b92ffaSHans Petter Selasky } is4_config_counter_groups_t;
147*d6b92ffaSHans Petter Selasky
148*d6b92ffaSHans Petter Selasky static uint16_t ext_fw_info_device[][2] = {
149*d6b92ffaSHans Petter Selasky {0x0245, 0x0245}, /* Switch-X */
150*d6b92ffaSHans Petter Selasky {0xc738, 0xc73b}, /* Switch-X */
151*d6b92ffaSHans Petter Selasky {0xcb20, 0xcb20}, /* Switch-IB */
152*d6b92ffaSHans Petter Selasky {0xcf08, 0xcf08}, /* Switch-IB2*/
153*d6b92ffaSHans Petter Selasky {0x01b3, 0x01b3}, /* IS-4 */
154*d6b92ffaSHans Petter Selasky {0x1003, 0x1017}, /* Connect-X */
155*d6b92ffaSHans Petter Selasky {0x1b02, 0x1b02}, /* Bull SwitchX */
156*d6b92ffaSHans Petter Selasky {0x1b50, 0x1b50}, /* Bull SwitchX */
157*d6b92ffaSHans Petter Selasky {0x1ba0, 0x1ba0}, /* Bull SwitchIB */
158*d6b92ffaSHans Petter Selasky {0x1bd0, 0x1bd5}, /* Bull SwitchIB and SwitchIB2 */
159*d6b92ffaSHans Petter Selasky {0x1b33, 0x1b33}, /* Bull ConnectX3 */
160*d6b92ffaSHans Petter Selasky {0x1b73, 0x1b73}, /* Bull ConnectX3 */
161*d6b92ffaSHans Petter Selasky {0x1b40, 0x1b41}, /* Bull ConnectX3 */
162*d6b92ffaSHans Petter Selasky {0x1b60, 0x1b61}, /* Bull ConnectX3 */
163*d6b92ffaSHans Petter Selasky {0x1b83, 0x1b83}, /* Bull ConnectIB */
164*d6b92ffaSHans Petter Selasky {0x1b93, 0x1b94}, /* Bull ConnectIB */
165*d6b92ffaSHans Petter Selasky {0x1bb4, 0x1bb5}, /* Bull ConnectX4 */
166*d6b92ffaSHans Petter Selasky {0x1bc4, 0x1bc4}, /* Bull ConnectX4 */
167*d6b92ffaSHans Petter Selasky {0x0000, 0x0000}};
168*d6b92ffaSHans Petter Selasky
is_ext_fw_info_supported(uint16_t device_id)169*d6b92ffaSHans Petter Selasky static int is_ext_fw_info_supported(uint16_t device_id) {
170*d6b92ffaSHans Petter Selasky int i;
171*d6b92ffaSHans Petter Selasky for (i = 0; ext_fw_info_device[i][0]; i++)
172*d6b92ffaSHans Petter Selasky if (ext_fw_info_device[i][0] <= device_id &&
173*d6b92ffaSHans Petter Selasky device_id <= ext_fw_info_device[i][1])
174*d6b92ffaSHans Petter Selasky return 1;
175*d6b92ffaSHans Petter Selasky return 0;
176*d6b92ffaSHans Petter Selasky }
177*d6b92ffaSHans Petter Selasky
do_vendor(ib_portid_t * portid,struct ibmad_port * srcport,uint8_t class,uint8_t method,uint16_t attr_id,uint32_t attr_mod,void * data)178*d6b92ffaSHans Petter Selasky static int do_vendor(ib_portid_t *portid, struct ibmad_port *srcport,
179*d6b92ffaSHans Petter Selasky uint8_t class, uint8_t method, uint16_t attr_id,
180*d6b92ffaSHans Petter Selasky uint32_t attr_mod, void *data)
181*d6b92ffaSHans Petter Selasky {
182*d6b92ffaSHans Petter Selasky ib_vendor_call_t call;
183*d6b92ffaSHans Petter Selasky
184*d6b92ffaSHans Petter Selasky memset(&call, 0, sizeof(call));
185*d6b92ffaSHans Petter Selasky call.mgmt_class = class;
186*d6b92ffaSHans Petter Selasky call.method = method;
187*d6b92ffaSHans Petter Selasky call.timeout = ibd_timeout;
188*d6b92ffaSHans Petter Selasky call.attrid = attr_id;
189*d6b92ffaSHans Petter Selasky call.mod = attr_mod;
190*d6b92ffaSHans Petter Selasky
191*d6b92ffaSHans Petter Selasky if (!ib_vendor_call_via(data, portid, &call, srcport)) {
192*d6b92ffaSHans Petter Selasky fprintf(stderr,"vendstat: method %u, attribute %u failure\n", method, attr_id);
193*d6b92ffaSHans Petter Selasky return -1;
194*d6b92ffaSHans Petter Selasky }
195*d6b92ffaSHans Petter Selasky return 0;
196*d6b92ffaSHans Petter Selasky }
197*d6b92ffaSHans Petter Selasky
do_config_space_records(ib_portid_t * portid,unsigned set,is3_config_space_t * cs,unsigned records)198*d6b92ffaSHans Petter Selasky static int do_config_space_records(ib_portid_t *portid, unsigned set,
199*d6b92ffaSHans Petter Selasky is3_config_space_t *cs, unsigned records)
200*d6b92ffaSHans Petter Selasky {
201*d6b92ffaSHans Petter Selasky unsigned i;
202*d6b92ffaSHans Petter Selasky
203*d6b92ffaSHans Petter Selasky if (records > 18)
204*d6b92ffaSHans Petter Selasky records = 18;
205*d6b92ffaSHans Petter Selasky for (i = 0; i < records; i++) {
206*d6b92ffaSHans Petter Selasky cs->record[i].address = htonl(cs->record[i].address);
207*d6b92ffaSHans Petter Selasky cs->record[i].data = htonl(cs->record[i].data);
208*d6b92ffaSHans Petter Selasky cs->record[i].mask = htonl(cs->record[i].mask);
209*d6b92ffaSHans Petter Selasky }
210*d6b92ffaSHans Petter Selasky
211*d6b92ffaSHans Petter Selasky if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS,
212*d6b92ffaSHans Petter Selasky set ? IB_MAD_METHOD_SET : IB_MAD_METHOD_GET,
213*d6b92ffaSHans Petter Selasky IB_MLX_IS3_CONFIG_SPACE_ACCESS, 2 << 22 | records << 16,
214*d6b92ffaSHans Petter Selasky cs)) {
215*d6b92ffaSHans Petter Selasky fprintf(stderr,"cannot %s config space records\n", set ? "set" : "get");
216*d6b92ffaSHans Petter Selasky return -1;
217*d6b92ffaSHans Petter Selasky }
218*d6b92ffaSHans Petter Selasky for (i = 0; i < records; i++) {
219*d6b92ffaSHans Petter Selasky printf("Config space record at 0x%x: 0x%x\n",
220*d6b92ffaSHans Petter Selasky ntohl(cs->record[i].address),
221*d6b92ffaSHans Petter Selasky ntohl(cs->record[i].data & cs->record[i].mask));
222*d6b92ffaSHans Petter Selasky }
223*d6b92ffaSHans Petter Selasky return 0;
224*d6b92ffaSHans Petter Selasky }
225*d6b92ffaSHans Petter Selasky
counter_groups_info(ib_portid_t * portid,int port)226*d6b92ffaSHans Petter Selasky static int counter_groups_info(ib_portid_t * portid, int port)
227*d6b92ffaSHans Petter Selasky {
228*d6b92ffaSHans Petter Selasky char buf[1024];
229*d6b92ffaSHans Petter Selasky is4_counter_group_info_t *cg_info;
230*d6b92ffaSHans Petter Selasky int i, num_cg;
231*d6b92ffaSHans Petter Selasky
232*d6b92ffaSHans Petter Selasky /* Counter Group Info */
233*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
234*d6b92ffaSHans Petter Selasky if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
235*d6b92ffaSHans Petter Selasky IB_MLX_IS4_COUNTER_GROUP_INFO, port, buf)) {
236*d6b92ffaSHans Petter Selasky fprintf(stderr,"counter group info query failure\n");
237*d6b92ffaSHans Petter Selasky return -1;
238*d6b92ffaSHans Petter Selasky }
239*d6b92ffaSHans Petter Selasky cg_info = (is4_counter_group_info_t *) & buf;
240*d6b92ffaSHans Petter Selasky num_cg = cg_info->num_of_counter_groups;
241*d6b92ffaSHans Petter Selasky printf("counter_group_info:\n");
242*d6b92ffaSHans Petter Selasky printf("%d counter groups\n", num_cg);
243*d6b92ffaSHans Petter Selasky for (i = 0; i < num_cg; i++)
244*d6b92ffaSHans Petter Selasky printf("group%d mask %#x\n", i, ntohl(cg_info->group_masks[i]));
245*d6b92ffaSHans Petter Selasky return 0;
246*d6b92ffaSHans Petter Selasky }
247*d6b92ffaSHans Petter Selasky
248*d6b92ffaSHans Petter Selasky /* Group0 counter config values */
249*d6b92ffaSHans Petter Selasky #define IS4_G0_PortXmtDataSL_0_7 0
250*d6b92ffaSHans Petter Selasky #define IS4_G0_PortXmtDataSL_8_15 1
251*d6b92ffaSHans Petter Selasky #define IS4_G0_PortRcvDataSL_0_7 2
252*d6b92ffaSHans Petter Selasky
253*d6b92ffaSHans Petter Selasky /* Group1 counter config values */
254*d6b92ffaSHans Petter Selasky #define IS4_G1_PortXmtDataSL_8_15 1
255*d6b92ffaSHans Petter Selasky #define IS4_G1_PortRcvDataSL_0_7 2
256*d6b92ffaSHans Petter Selasky #define IS4_G1_PortRcvDataSL_8_15 8
257*d6b92ffaSHans Petter Selasky
258*d6b92ffaSHans Petter Selasky static int cg0, cg1;
259*d6b92ffaSHans Petter Selasky
config_counter_groups(ib_portid_t * portid,int port)260*d6b92ffaSHans Petter Selasky static int config_counter_groups(ib_portid_t * portid, int port)
261*d6b92ffaSHans Petter Selasky {
262*d6b92ffaSHans Petter Selasky char buf[1024];
263*d6b92ffaSHans Petter Selasky is4_config_counter_groups_t *cg_config;
264*d6b92ffaSHans Petter Selasky
265*d6b92ffaSHans Petter Selasky /* configure counter groups for groups 0 and 1 */
266*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
267*d6b92ffaSHans Petter Selasky cg_config = (is4_config_counter_groups_t *) & buf;
268*d6b92ffaSHans Petter Selasky
269*d6b92ffaSHans Petter Selasky printf("counter_groups_config: configuring group0 %d group1 %d\n", cg0,
270*d6b92ffaSHans Petter Selasky cg1);
271*d6b92ffaSHans Petter Selasky cg_config->group_selects[0].group_select = (uint8_t) cg0;
272*d6b92ffaSHans Petter Selasky cg_config->group_selects[1].group_select = (uint8_t) cg1;
273*d6b92ffaSHans Petter Selasky
274*d6b92ffaSHans Petter Selasky if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_SET,
275*d6b92ffaSHans Petter Selasky IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
276*d6b92ffaSHans Petter Selasky fprintf(stderr, "config counter group set failure\n");
277*d6b92ffaSHans Petter Selasky return -1;
278*d6b92ffaSHans Petter Selasky }
279*d6b92ffaSHans Petter Selasky /* get config counter groups */
280*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
281*d6b92ffaSHans Petter Selasky
282*d6b92ffaSHans Petter Selasky if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
283*d6b92ffaSHans Petter Selasky IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
284*d6b92ffaSHans Petter Selasky fprintf(stderr, "config counter group query failure\n");
285*d6b92ffaSHans Petter Selasky return -1;
286*d6b92ffaSHans Petter Selasky }
287*d6b92ffaSHans Petter Selasky return 0;
288*d6b92ffaSHans Petter Selasky }
289*d6b92ffaSHans Petter Selasky
290*d6b92ffaSHans Petter Selasky static int general_info, xmit_wait, counter_group_info, config_counter_group;
291*d6b92ffaSHans Petter Selasky static is3_config_space_t write_cs, read_cs;
292*d6b92ffaSHans Petter Selasky static unsigned write_cs_records, read_cs_records;
293*d6b92ffaSHans Petter Selasky
294*d6b92ffaSHans Petter Selasky
process_opt(void * context,int ch,char * optarg)295*d6b92ffaSHans Petter Selasky static int process_opt(void *context, int ch, char *optarg)
296*d6b92ffaSHans Petter Selasky {
297*d6b92ffaSHans Petter Selasky int ret;
298*d6b92ffaSHans Petter Selasky switch (ch) {
299*d6b92ffaSHans Petter Selasky case 'N':
300*d6b92ffaSHans Petter Selasky general_info = 1;
301*d6b92ffaSHans Petter Selasky break;
302*d6b92ffaSHans Petter Selasky case 'w':
303*d6b92ffaSHans Petter Selasky xmit_wait = 1;
304*d6b92ffaSHans Petter Selasky break;
305*d6b92ffaSHans Petter Selasky case 'i':
306*d6b92ffaSHans Petter Selasky counter_group_info = 1;
307*d6b92ffaSHans Petter Selasky break;
308*d6b92ffaSHans Petter Selasky case 'c':
309*d6b92ffaSHans Petter Selasky config_counter_group = 1;
310*d6b92ffaSHans Petter Selasky ret = sscanf(optarg, "%d,%d", &cg0, &cg1);
311*d6b92ffaSHans Petter Selasky if (ret != 2)
312*d6b92ffaSHans Petter Selasky return -1;
313*d6b92ffaSHans Petter Selasky break;
314*d6b92ffaSHans Petter Selasky case 'R':
315*d6b92ffaSHans Petter Selasky if (read_cs_records >= 18)
316*d6b92ffaSHans Petter Selasky break;
317*d6b92ffaSHans Petter Selasky ret = sscanf(optarg, "%x,%x",
318*d6b92ffaSHans Petter Selasky &read_cs.record[read_cs_records].address,
319*d6b92ffaSHans Petter Selasky &read_cs.record[read_cs_records].mask);
320*d6b92ffaSHans Petter Selasky if (ret < 1)
321*d6b92ffaSHans Petter Selasky return -1;
322*d6b92ffaSHans Petter Selasky else if (ret == 1)
323*d6b92ffaSHans Petter Selasky read_cs.record[read_cs_records].mask = 0xffffffff;
324*d6b92ffaSHans Petter Selasky read_cs_records++;
325*d6b92ffaSHans Petter Selasky break;
326*d6b92ffaSHans Petter Selasky case 'W':
327*d6b92ffaSHans Petter Selasky if (write_cs_records >= 18)
328*d6b92ffaSHans Petter Selasky break;
329*d6b92ffaSHans Petter Selasky ret = sscanf(optarg, "%x,%x,%x",
330*d6b92ffaSHans Petter Selasky &write_cs.record[write_cs_records].address,
331*d6b92ffaSHans Petter Selasky &write_cs.record[write_cs_records].data,
332*d6b92ffaSHans Petter Selasky &write_cs.record[write_cs_records].mask);
333*d6b92ffaSHans Petter Selasky if (ret < 2)
334*d6b92ffaSHans Petter Selasky return -1;
335*d6b92ffaSHans Petter Selasky else if (ret == 2)
336*d6b92ffaSHans Petter Selasky write_cs.record[write_cs_records].mask = 0xffffffff;
337*d6b92ffaSHans Petter Selasky write_cs_records++;
338*d6b92ffaSHans Petter Selasky break;
339*d6b92ffaSHans Petter Selasky case 25:
340*d6b92ffaSHans Petter Selasky if (!inet_pton(AF_INET6, optarg, &dgid)) {
341*d6b92ffaSHans Petter Selasky fprintf(stderr, "dgid format is wrong!\n");
342*d6b92ffaSHans Petter Selasky ibdiag_show_usage();
343*d6b92ffaSHans Petter Selasky return 1;
344*d6b92ffaSHans Petter Selasky }
345*d6b92ffaSHans Petter Selasky with_grh = 1;
346*d6b92ffaSHans Petter Selasky break;
347*d6b92ffaSHans Petter Selasky default:
348*d6b92ffaSHans Petter Selasky return -1;
349*d6b92ffaSHans Petter Selasky }
350*d6b92ffaSHans Petter Selasky return 0;
351*d6b92ffaSHans Petter Selasky }
352*d6b92ffaSHans Petter Selasky
main(int argc,char ** argv)353*d6b92ffaSHans Petter Selasky int main(int argc, char **argv)
354*d6b92ffaSHans Petter Selasky {
355*d6b92ffaSHans Petter Selasky int mgmt_classes[2] = { IB_SA_CLASS, IB_MLX_VENDOR_CLASS };
356*d6b92ffaSHans Petter Selasky ib_portid_t portid = { 0 };
357*d6b92ffaSHans Petter Selasky int port = 0;
358*d6b92ffaSHans Petter Selasky char buf[1024];
359*d6b92ffaSHans Petter Selasky uint32_t fw_ver_major = 0;
360*d6b92ffaSHans Petter Selasky uint32_t fw_ver_minor = 0;
361*d6b92ffaSHans Petter Selasky uint32_t fw_ver_sub_minor = 0;
362*d6b92ffaSHans Petter Selasky uint8_t sw_ver_major = 0, sw_ver_minor = 0, sw_ver_sub_minor = 0;
363*d6b92ffaSHans Petter Selasky is3_general_info_t *gi_is3;
364*d6b92ffaSHans Petter Selasky is4_general_info_t *gi_is4;
365*d6b92ffaSHans Petter Selasky const struct ibdiag_opt opts[] = {
366*d6b92ffaSHans Petter Selasky {"N", 'N', 0, NULL, "show IS3 or IS4 general information"},
367*d6b92ffaSHans Petter Selasky {"w", 'w', 0, NULL, "show IS3 port xmit wait counters"},
368*d6b92ffaSHans Petter Selasky {"i", 'i', 0, NULL, "show IS4 counter group info"},
369*d6b92ffaSHans Petter Selasky {"c", 'c', 1, "<num,num>", "configure IS4 counter groups"},
370*d6b92ffaSHans Petter Selasky {"Read", 'R', 1, "<addr,mask>", "Read configuration space record at addr"},
371*d6b92ffaSHans Petter Selasky {"Write", 'W', 1, "<addr,val,mask>", "Write configuration space record at addr"},
372*d6b92ffaSHans Petter Selasky {"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
373*d6b92ffaSHans Petter Selasky {0}
374*d6b92ffaSHans Petter Selasky };
375*d6b92ffaSHans Petter Selasky
376*d6b92ffaSHans Petter Selasky char usage_args[] = "<lid|guid> [port]";
377*d6b92ffaSHans Petter Selasky const char *usage_examples[] = {
378*d6b92ffaSHans Petter Selasky "-N 6\t\t# read IS3 or IS4 general information",
379*d6b92ffaSHans Petter Selasky "-w 6\t\t# read IS3 port xmit wait counters",
380*d6b92ffaSHans Petter Selasky "-i 6 12\t# read IS4 port 12 counter group info",
381*d6b92ffaSHans Petter Selasky "-c 0,1 6 12\t# configure IS4 port 12 counter groups for PortXmitDataSL",
382*d6b92ffaSHans Petter Selasky "-c 2,8 6 12\t# configure IS4 port 12 counter groups for PortRcvDataSL",
383*d6b92ffaSHans Petter Selasky NULL
384*d6b92ffaSHans Petter Selasky };
385*d6b92ffaSHans Petter Selasky
386*d6b92ffaSHans Petter Selasky ibdiag_process_opts(argc, argv, NULL, "DKy", opts, process_opt,
387*d6b92ffaSHans Petter Selasky usage_args, usage_examples);
388*d6b92ffaSHans Petter Selasky
389*d6b92ffaSHans Petter Selasky argc -= optind;
390*d6b92ffaSHans Petter Selasky argv += optind;
391*d6b92ffaSHans Petter Selasky
392*d6b92ffaSHans Petter Selasky if (argc > 1)
393*d6b92ffaSHans Petter Selasky port = strtoul(argv[1], 0, 0);
394*d6b92ffaSHans Petter Selasky
395*d6b92ffaSHans Petter Selasky srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
396*d6b92ffaSHans Petter Selasky if (!srcport)
397*d6b92ffaSHans Petter Selasky IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
398*d6b92ffaSHans Petter Selasky
399*d6b92ffaSHans Petter Selasky if (argc) {
400*d6b92ffaSHans Petter Selasky if (with_grh && ibd_dest_type != IB_DEST_LID) {
401*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
402*d6b92ffaSHans Petter Selasky IBEXIT("When using GRH, LID should be provided");
403*d6b92ffaSHans Petter Selasky }
404*d6b92ffaSHans Petter Selasky if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
405*d6b92ffaSHans Petter Selasky ibd_dest_type, ibd_sm_id, srcport) < 0) {
406*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
407*d6b92ffaSHans Petter Selasky IBEXIT("can't resolve destination port %s", argv[0]);
408*d6b92ffaSHans Petter Selasky }
409*d6b92ffaSHans Petter Selasky if (with_grh) {
410*d6b92ffaSHans Petter Selasky portid.grh_present = 1;
411*d6b92ffaSHans Petter Selasky memcpy(&portid.gid, &dgid, sizeof(portid.gid));
412*d6b92ffaSHans Petter Selasky }
413*d6b92ffaSHans Petter Selasky } else {
414*d6b92ffaSHans Petter Selasky if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, 0) < 0) {
415*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
416*d6b92ffaSHans Petter Selasky IBEXIT("can't resolve self port %s", argv[0]);
417*d6b92ffaSHans Petter Selasky }
418*d6b92ffaSHans Petter Selasky }
419*d6b92ffaSHans Petter Selasky
420*d6b92ffaSHans Petter Selasky if (counter_group_info) {
421*d6b92ffaSHans Petter Selasky counter_groups_info(&portid, port);
422*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
423*d6b92ffaSHans Petter Selasky exit(0);
424*d6b92ffaSHans Petter Selasky }
425*d6b92ffaSHans Petter Selasky
426*d6b92ffaSHans Petter Selasky if (config_counter_group) {
427*d6b92ffaSHans Petter Selasky config_counter_groups(&portid, port);
428*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
429*d6b92ffaSHans Petter Selasky exit(0);
430*d6b92ffaSHans Petter Selasky }
431*d6b92ffaSHans Petter Selasky
432*d6b92ffaSHans Petter Selasky if (read_cs_records || write_cs_records) {
433*d6b92ffaSHans Petter Selasky if (read_cs_records)
434*d6b92ffaSHans Petter Selasky do_config_space_records(&portid, 0, &read_cs,
435*d6b92ffaSHans Petter Selasky read_cs_records);
436*d6b92ffaSHans Petter Selasky if (write_cs_records)
437*d6b92ffaSHans Petter Selasky do_config_space_records(&portid, 1, &write_cs,
438*d6b92ffaSHans Petter Selasky write_cs_records);
439*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
440*d6b92ffaSHans Petter Selasky exit(0);
441*d6b92ffaSHans Petter Selasky }
442*d6b92ffaSHans Petter Selasky
443*d6b92ffaSHans Petter Selasky /* These are Mellanox specific vendor MADs */
444*d6b92ffaSHans Petter Selasky /* but vendors change the VendorId so how know for sure ? */
445*d6b92ffaSHans Petter Selasky /* Only General Info and Port Xmit Wait Counters */
446*d6b92ffaSHans Petter Selasky /* queries are currently supported */
447*d6b92ffaSHans Petter Selasky if (!general_info && !xmit_wait) {
448*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
449*d6b92ffaSHans Petter Selasky IBEXIT("at least one of -N and -w must be specified");
450*d6b92ffaSHans Petter Selasky }
451*d6b92ffaSHans Petter Selasky /* Would need a list of these and it might not be complete */
452*d6b92ffaSHans Petter Selasky /* so for right now, punt on this */
453*d6b92ffaSHans Petter Selasky
454*d6b92ffaSHans Petter Selasky /* vendor ClassPortInfo is required attribute if class supported */
455*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
456*d6b92ffaSHans Petter Selasky if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
457*d6b92ffaSHans Petter Selasky CLASS_PORT_INFO, 0, buf)) {
458*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
459*d6b92ffaSHans Petter Selasky IBEXIT("classportinfo query");
460*d6b92ffaSHans Petter Selasky }
461*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
462*d6b92ffaSHans Petter Selasky gi_is3 = (is3_general_info_t *) &buf;
463*d6b92ffaSHans Petter Selasky if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
464*d6b92ffaSHans Petter Selasky IB_MLX_IS3_GENERAL_INFO, 0, gi_is3)) {
465*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
466*d6b92ffaSHans Petter Selasky IBEXIT("generalinfo query");
467*d6b92ffaSHans Petter Selasky }
468*d6b92ffaSHans Petter Selasky
469*d6b92ffaSHans Petter Selasky if (is_ext_fw_info_supported(ntohs(gi_is3->hw_info.device_id))) {
470*d6b92ffaSHans Petter Selasky gi_is4 = (is4_general_info_t *) &buf;
471*d6b92ffaSHans Petter Selasky fw_ver_major = ntohl(gi_is4->ext_fw_info.ext_major);
472*d6b92ffaSHans Petter Selasky fw_ver_minor = ntohl(gi_is4->ext_fw_info.ext_minor);
473*d6b92ffaSHans Petter Selasky fw_ver_sub_minor = ntohl(gi_is4->ext_fw_info.ext_sub_minor);
474*d6b92ffaSHans Petter Selasky sw_ver_major = gi_is4->sw_info.major;
475*d6b92ffaSHans Petter Selasky sw_ver_minor = gi_is4->sw_info.minor;
476*d6b92ffaSHans Petter Selasky sw_ver_sub_minor = gi_is4->sw_info.sub_minor;
477*d6b92ffaSHans Petter Selasky } else {
478*d6b92ffaSHans Petter Selasky fw_ver_major = gi_is3->fw_info.major;
479*d6b92ffaSHans Petter Selasky fw_ver_minor = gi_is3->fw_info.minor;
480*d6b92ffaSHans Petter Selasky fw_ver_sub_minor = gi_is3->fw_info.sub_minor;
481*d6b92ffaSHans Petter Selasky sw_ver_major = gi_is3->sw_info.major;
482*d6b92ffaSHans Petter Selasky sw_ver_minor = gi_is3->sw_info.minor;
483*d6b92ffaSHans Petter Selasky sw_ver_sub_minor = gi_is3->sw_info.sub_minor;
484*d6b92ffaSHans Petter Selasky }
485*d6b92ffaSHans Petter Selasky
486*d6b92ffaSHans Petter Selasky if (general_info) {
487*d6b92ffaSHans Petter Selasky /* dump IS3 or IS4 general info here */
488*d6b92ffaSHans Petter Selasky printf("hw_dev_rev: 0x%04x\n", ntohs(gi_is3->hw_info.hw_revision));
489*d6b92ffaSHans Petter Selasky printf("hw_dev_id: 0x%04x\n", ntohs(gi_is3->hw_info.device_id));
490*d6b92ffaSHans Petter Selasky printf("hw_uptime: 0x%08x\n", ntohl(gi_is3->hw_info.uptime));
491*d6b92ffaSHans Petter Selasky printf("fw_version: %02d.%02d.%02d\n",
492*d6b92ffaSHans Petter Selasky fw_ver_major, fw_ver_minor, fw_ver_sub_minor);
493*d6b92ffaSHans Petter Selasky printf("fw_build_id: 0x%04x\n", ntohl(gi_is3->fw_info.build_id));
494*d6b92ffaSHans Petter Selasky printf("fw_date: %02x/%02x/%04x\n",
495*d6b92ffaSHans Petter Selasky gi_is3->fw_info.month, gi_is3->fw_info.day,
496*d6b92ffaSHans Petter Selasky ntohs(gi_is3->fw_info.year));
497*d6b92ffaSHans Petter Selasky printf("fw_psid: '%s'\n", gi_is3->fw_info.psid);
498*d6b92ffaSHans Petter Selasky printf("fw_ini_ver: %d\n",
499*d6b92ffaSHans Petter Selasky ntohl(gi_is3->fw_info.ini_file_version));
500*d6b92ffaSHans Petter Selasky printf("sw_version: %02d.%02d.%02d\n", sw_ver_major,
501*d6b92ffaSHans Petter Selasky sw_ver_minor, sw_ver_sub_minor);
502*d6b92ffaSHans Petter Selasky }
503*d6b92ffaSHans Petter Selasky
504*d6b92ffaSHans Petter Selasky if (xmit_wait) {
505*d6b92ffaSHans Petter Selasky is3_config_space_t *cs;
506*d6b92ffaSHans Petter Selasky unsigned i;
507*d6b92ffaSHans Petter Selasky
508*d6b92ffaSHans Petter Selasky if (ntohs(gi_is3->hw_info.device_id) != IS3_DEVICE_ID) {
509*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
510*d6b92ffaSHans Petter Selasky IBEXIT("Unsupported device ID 0x%x",
511*d6b92ffaSHans Petter Selasky ntohs(gi_is3->hw_info.device_id));
512*d6b92ffaSHans Petter Selasky }
513*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
514*d6b92ffaSHans Petter Selasky /* Set record addresses for each port */
515*d6b92ffaSHans Petter Selasky cs = (is3_config_space_t *) & buf;
516*d6b92ffaSHans Petter Selasky for (i = 0; i < 16; i++)
517*d6b92ffaSHans Petter Selasky cs->record[i].address =
518*d6b92ffaSHans Petter Selasky htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 1) << 12));
519*d6b92ffaSHans Petter Selasky if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS,
520*d6b92ffaSHans Petter Selasky IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
521*d6b92ffaSHans Petter Selasky 2 << 22 | 16 << 16, cs)) {
522*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
523*d6b92ffaSHans Petter Selasky IBEXIT("vendstat");
524*d6b92ffaSHans Petter Selasky }
525*d6b92ffaSHans Petter Selasky for (i = 0; i < 16; i++)
526*d6b92ffaSHans Petter Selasky if (cs->record[i].data) /* PortXmitWait is 32 bit counter */
527*d6b92ffaSHans Petter Selasky printf("Port %d: PortXmitWait 0x%x\n", i + 4, ntohl(cs->record[i].data)); /* port 4 is first port */
528*d6b92ffaSHans Petter Selasky
529*d6b92ffaSHans Petter Selasky /* Last 8 ports is another query */
530*d6b92ffaSHans Petter Selasky memset(&buf, 0, sizeof(buf));
531*d6b92ffaSHans Petter Selasky /* Set record addresses for each port */
532*d6b92ffaSHans Petter Selasky cs = (is3_config_space_t *) & buf;
533*d6b92ffaSHans Petter Selasky for (i = 0; i < 8; i++)
534*d6b92ffaSHans Petter Selasky cs->record[i].address =
535*d6b92ffaSHans Petter Selasky htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 17) << 12));
536*d6b92ffaSHans Petter Selasky if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS,
537*d6b92ffaSHans Petter Selasky IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
538*d6b92ffaSHans Petter Selasky 2 << 22 | 8 << 16, cs)) {
539*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
540*d6b92ffaSHans Petter Selasky IBEXIT("vendstat");
541*d6b92ffaSHans Petter Selasky }
542*d6b92ffaSHans Petter Selasky
543*d6b92ffaSHans Petter Selasky for (i = 0; i < 8; i++)
544*d6b92ffaSHans Petter Selasky if (cs->record[i].data) /* PortXmitWait is 32 bit counter */
545*d6b92ffaSHans Petter Selasky printf("Port %d: PortXmitWait 0x%x\n",
546*d6b92ffaSHans Petter Selasky i < 4 ? i + 21 : i - 3,
547*d6b92ffaSHans Petter Selasky ntohl(cs->record[i].data));
548*d6b92ffaSHans Petter Selasky }
549*d6b92ffaSHans Petter Selasky
550*d6b92ffaSHans Petter Selasky mad_rpc_close_port(srcport);
551*d6b92ffaSHans Petter Selasky exit(0);
552*d6b92ffaSHans Petter Selasky }
553