|
Packit |
db064d |
/*
|
|
Packit |
db064d |
* Copyright (c) 2012 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
db064d |
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* This software is available to you under a choice of one of two
|
|
Packit |
db064d |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
db064d |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
db064d |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
db064d |
* OpenIB.org BSD license below:
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
db064d |
* without modification, are permitted provided that the following
|
|
Packit |
db064d |
* conditions are met:
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* - Redistributions of source code must retain the above
|
|
Packit |
db064d |
* copyright notice, this list of conditions and the following
|
|
Packit |
db064d |
* disclaimer.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
db064d |
* copyright notice, this list of conditions and the following
|
|
Packit |
db064d |
* disclaimer in the documentation and/or other materials
|
|
Packit |
db064d |
* provided with the distribution.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
db064d |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
db064d |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
db064d |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
db064d |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
db064d |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
db064d |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
db064d |
* SOFTWARE.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
*/
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#if HAVE_CONFIG_H
|
|
Packit |
db064d |
# include <config.h>
|
|
Packit |
db064d |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#include <stdio.h>
|
|
Packit |
db064d |
#include <stdlib.h>
|
|
Packit |
db064d |
#include <unistd.h>
|
|
Packit |
db064d |
#include <netinet/in.h>
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#include <infiniband/umad.h>
|
|
Packit |
db064d |
#include <infiniband/mad.h>
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#include "ibdiag_common.h"
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#define IS3_DEVICE_ID 47396
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#define IB_MLX_VENDOR_CLASS 10
|
|
Packit |
db064d |
/* Vendor specific Attribute IDs */
|
|
Packit |
db064d |
#define IB_MLX_IS3_GENERAL_INFO 0x17
|
|
Packit |
db064d |
#define IB_MLX_IS3_CONFIG_SPACE_ACCESS 0x50
|
|
Packit |
db064d |
#define IB_MLX_IS4_COUNTER_GROUP_INFO 0x90
|
|
Packit |
db064d |
#define IB_MLX_IS4_CONFIG_COUNTER_GROUP 0x91
|
|
Packit |
db064d |
/* Config space addresses */
|
|
Packit |
db064d |
#define IB_MLX_IS3_PORT_XMIT_WAIT 0x10013C
|
|
Packit |
db064d |
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static struct ibmad_port *srcport;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
__be16 hw_revision;
|
|
Packit |
db064d |
__be16 device_id;
|
|
Packit |
db064d |
uint8_t reserved[24];
|
|
Packit |
db064d |
__be32 uptime;
|
|
Packit |
db064d |
} is3_hw_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t resv1;
|
|
Packit |
db064d |
uint8_t major;
|
|
Packit |
db064d |
uint8_t minor;
|
|
Packit |
db064d |
uint8_t sub_minor;
|
|
Packit |
db064d |
__be32 build_id;
|
|
Packit |
db064d |
uint8_t month;
|
|
Packit |
db064d |
uint8_t day;
|
|
Packit |
db064d |
__be16 year;
|
|
Packit |
db064d |
__be16 resv2;
|
|
Packit |
db064d |
__be16 hour;
|
|
Packit |
db064d |
uint8_t psid[16];
|
|
Packit |
db064d |
__be32 ini_file_version;
|
|
Packit |
db064d |
} is3_fw_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
__be32 ext_major;
|
|
Packit |
db064d |
__be32 ext_minor;
|
|
Packit |
db064d |
__be32 ext_sub_minor;
|
|
Packit |
db064d |
__be32 reserved[4];
|
|
Packit |
db064d |
} is4_fw_ext_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t resv1;
|
|
Packit |
db064d |
uint8_t major;
|
|
Packit |
db064d |
uint8_t minor;
|
|
Packit |
db064d |
uint8_t sub_minor;
|
|
Packit |
db064d |
uint8_t resv2[28];
|
|
Packit |
db064d |
} is3_sw_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t reserved[8];
|
|
Packit |
db064d |
is3_hw_info_t hw_info;
|
|
Packit |
db064d |
is3_fw_info_t fw_info;
|
|
Packit |
db064d |
is3_sw_info_t sw_info;
|
|
Packit |
db064d |
} is3_general_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t reserved[8];
|
|
Packit |
db064d |
is3_hw_info_t hw_info;
|
|
Packit |
db064d |
is3_fw_info_t fw_info;
|
|
Packit |
db064d |
is4_fw_ext_info_t ext_fw_info;
|
|
Packit |
db064d |
is3_sw_info_t sw_info;
|
|
Packit |
db064d |
} is4_general_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t reserved[8];
|
|
Packit |
db064d |
struct is3_record {
|
|
Packit |
db064d |
__be32 address;
|
|
Packit |
db064d |
__be32 data;
|
|
Packit |
db064d |
__be32 mask;
|
|
Packit |
db064d |
} record[18];
|
|
Packit |
db064d |
} is3_config_space_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#define COUNTER_GROUPS_NUM 2
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t reserved1[8];
|
|
Packit |
db064d |
uint8_t reserved[3];
|
|
Packit |
db064d |
uint8_t num_of_counter_groups;
|
|
Packit |
db064d |
__be32 group_masks[COUNTER_GROUPS_NUM];
|
|
Packit |
db064d |
} is4_counter_group_info_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t reserved[3];
|
|
Packit |
db064d |
uint8_t group_select;
|
|
Packit |
db064d |
} is4_group_select_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
typedef struct {
|
|
Packit |
db064d |
uint8_t reserved1[8];
|
|
Packit |
db064d |
uint8_t reserved[4];
|
|
Packit |
db064d |
is4_group_select_t group_selects[COUNTER_GROUPS_NUM];
|
|
Packit |
db064d |
} is4_config_counter_groups_t;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static uint16_t ext_fw_info_device[][2] = {
|
|
Packit |
db064d |
{0x0245, 0x0245}, /* Switch-X */
|
|
Packit |
db064d |
{0xc738, 0xc73b}, /* Switch-X */
|
|
Packit |
db064d |
{0xcb20, 0xcb20}, /* Switch-IB */
|
|
Packit |
db064d |
{0xcf08, 0xcf08}, /* Switch-IB2 */
|
|
Packit |
db064d |
{0xd2f0, 0xd2f0}, /* Quantum */
|
|
Packit |
db064d |
{0x01b3, 0x01b3}, /* IS-4 */
|
|
Packit |
db064d |
{0x1003, 0x101b}, /* Connect-X */
|
|
Packit |
db064d |
{0xa2d2, 0xa2d2}, /* BlueField */
|
|
Packit |
db064d |
{0x1b02, 0x1b02}, /* Bull SwitchX */
|
|
Packit |
db064d |
{0x1b50, 0x1b50}, /* Bull SwitchX */
|
|
Packit |
db064d |
{0x1ba0, 0x1ba0}, /* Bull SwitchIB */
|
|
Packit |
db064d |
{0x1bd0, 0x1bd5}, /* Bull SwitchIB and SwitchIB2 */
|
|
Packit |
db064d |
{0x1bf0, 0x1bf0}, /* Bull Sequana Quantum */
|
|
Packit |
db064d |
{0x1b33, 0x1b33}, /* Bull ConnectX3 */
|
|
Packit |
db064d |
{0x1b73, 0x1b73}, /* Bull ConnectX3 */
|
|
Packit |
db064d |
{0x1b40, 0x1b41}, /* Bull ConnectX3 */
|
|
Packit |
db064d |
{0x1b60, 0x1b61}, /* Bull ConnectX3 */
|
|
Packit |
db064d |
{0x1b83, 0x1b83}, /* Bull ConnectIB */
|
|
Packit |
db064d |
{0x1b93, 0x1b94}, /* Bull ConnectIB */
|
|
Packit |
db064d |
{0x1bb4, 0x1bb5}, /* Bull ConnectX4 */
|
|
Packit |
db064d |
{0x1bc4, 0x1bc6}, /* Bull ConnectX4, Sequana HDR and HDR100 */
|
|
Packit |
db064d |
{0x0000, 0x0000}};
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int is_ext_fw_info_supported(uint16_t device_id) {
|
|
Packit |
db064d |
int i;
|
|
Packit |
db064d |
for (i = 0; ext_fw_info_device[i][0]; i++)
|
|
Packit |
db064d |
if (ext_fw_info_device[i][0] <= device_id &&
|
|
Packit |
db064d |
device_id <= ext_fw_info_device[i][1])
|
|
Packit |
db064d |
return 1;
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int do_vendor(ib_portid_t *portid, uint8_t class, uint8_t method,
|
|
Packit |
db064d |
uint16_t attr_id, uint32_t attr_mod, void *data)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
ib_vendor_call_t call;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
memset(&call, 0, sizeof(call));
|
|
Packit |
db064d |
call.mgmt_class = class;
|
|
Packit |
db064d |
call.method = method;
|
|
Packit |
db064d |
call.timeout = ibd_timeout;
|
|
Packit |
db064d |
call.attrid = attr_id;
|
|
Packit |
db064d |
call.mod = attr_mod;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!ib_vendor_call_via(data, portid, &call, srcport)) {
|
|
Packit |
db064d |
fprintf(stderr,"vendstat: method %u, attribute %u failure\n", method, attr_id);
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int do_config_space_records(ib_portid_t *portid, unsigned set,
|
|
Packit |
db064d |
is3_config_space_t *cs, unsigned records)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
unsigned i;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (records > 18)
|
|
Packit |
db064d |
records = 18;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (do_vendor(portid, IB_MLX_VENDOR_CLASS,
|
|
Packit |
db064d |
set ? IB_MAD_METHOD_SET : IB_MAD_METHOD_GET,
|
|
Packit |
db064d |
IB_MLX_IS3_CONFIG_SPACE_ACCESS, 2 << 22 | records << 16,
|
|
Packit |
db064d |
cs)) {
|
|
Packit |
db064d |
fprintf(stderr,"cannot %s config space records\n", set ? "set" : "get");
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
for (i = 0; i < records; i++) {
|
|
Packit |
db064d |
printf("Config space record at 0x%x: 0x%x\n",
|
|
Packit |
db064d |
ntohl(cs->record[i].address),
|
|
Packit |
db064d |
ntohl(cs->record[i].data & cs->record[i].mask));
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int counter_groups_info(ib_portid_t * portid, int port)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char buf[1024];
|
|
Packit |
db064d |
is4_counter_group_info_t *cg_info;
|
|
Packit |
db064d |
int i, num_cg;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* Counter Group Info */
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
if (do_vendor(portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
|
Packit |
db064d |
IB_MLX_IS4_COUNTER_GROUP_INFO, port, buf)) {
|
|
Packit |
db064d |
fprintf(stderr,"counter group info query failure\n");
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
cg_info = (is4_counter_group_info_t *) & buf;
|
|
Packit |
db064d |
num_cg = cg_info->num_of_counter_groups;
|
|
Packit |
db064d |
printf("counter_group_info:\n");
|
|
Packit |
db064d |
printf("%d counter groups\n", num_cg);
|
|
Packit |
db064d |
for (i = 0; i < num_cg; i++)
|
|
Packit |
db064d |
printf("group%d mask %#x\n", i, ntohl(cg_info->group_masks[i]));
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* Group0 counter config values */
|
|
Packit |
db064d |
#define IS4_G0_PortXmtDataSL_0_7 0
|
|
Packit |
db064d |
#define IS4_G0_PortXmtDataSL_8_15 1
|
|
Packit |
db064d |
#define IS4_G0_PortRcvDataSL_0_7 2
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* Group1 counter config values */
|
|
Packit |
db064d |
#define IS4_G1_PortXmtDataSL_8_15 1
|
|
Packit |
db064d |
#define IS4_G1_PortRcvDataSL_0_7 2
|
|
Packit |
db064d |
#define IS4_G1_PortRcvDataSL_8_15 8
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int cg0, cg1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int config_counter_groups(ib_portid_t * portid, int port)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char buf[1024];
|
|
Packit |
db064d |
is4_config_counter_groups_t *cg_config;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* configure counter groups for groups 0 and 1 */
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
cg_config = (is4_config_counter_groups_t *) & buf;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
printf("counter_groups_config: configuring group0 %d group1 %d\n", cg0,
|
|
Packit |
db064d |
cg1);
|
|
Packit |
db064d |
cg_config->group_selects[0].group_select = (uint8_t) cg0;
|
|
Packit |
db064d |
cg_config->group_selects[1].group_select = (uint8_t) cg1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (do_vendor(portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_SET,
|
|
Packit |
db064d |
IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
|
|
Packit |
db064d |
fprintf(stderr, "config counter group set failure\n");
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
/* get config counter groups */
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (do_vendor(portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
|
Packit |
db064d |
IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
|
|
Packit |
db064d |
fprintf(stderr, "config counter group query failure\n");
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int general_info, xmit_wait, counter_group_info, config_counter_group;
|
|
Packit |
db064d |
static is3_config_space_t write_cs, read_cs;
|
|
Packit |
db064d |
static unsigned write_cs_records, read_cs_records;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int process_opt(void *context, int ch)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
int ret;
|
|
Packit |
db064d |
unsigned int address, data, mask;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
switch (ch) {
|
|
Packit |
db064d |
case 'N':
|
|
Packit |
db064d |
general_info = 1;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'w':
|
|
Packit |
db064d |
xmit_wait = 1;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'i':
|
|
Packit |
db064d |
counter_group_info = 1;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'c':
|
|
Packit |
db064d |
config_counter_group = 1;
|
|
Packit |
db064d |
ret = sscanf(optarg, "%d,%d", &cg0, &cg1);
|
|
Packit |
db064d |
if (ret != 2)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'R':
|
|
Packit |
db064d |
if (read_cs_records >= 18)
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
ret = sscanf(optarg, "%x,%x", &address, &mask);
|
|
Packit |
db064d |
if (ret < 1)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
else if (ret == 1)
|
|
Packit |
db064d |
mask = 0xffffffff;
|
|
Packit |
db064d |
read_cs.record[read_cs_records].address = htobe32(address);
|
|
Packit |
db064d |
read_cs.record[read_cs_records].mask = htobe32(mask);
|
|
Packit |
db064d |
read_cs_records++;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'W':
|
|
Packit |
db064d |
if (write_cs_records >= 18)
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
ret = sscanf(optarg, "%x,%x,%x", &address, &data, &mask);
|
|
Packit |
db064d |
if (ret < 2)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
else if (ret == 2)
|
|
Packit |
db064d |
mask = 0xffffffff;
|
|
Packit |
db064d |
write_cs.record[write_cs_records].address = htobe32(address);
|
|
Packit |
db064d |
write_cs.record[write_cs_records].data = htobe32(data);
|
|
Packit |
db064d |
write_cs.record[write_cs_records].mask = htobe32(mask);
|
|
Packit |
db064d |
write_cs_records++;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
default:
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int main(int argc, char **argv)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
int mgmt_classes[2] = { IB_SA_CLASS, IB_MLX_VENDOR_CLASS };
|
|
Packit |
db064d |
ib_portid_t portid = { 0 };
|
|
Packit |
db064d |
int port = 0;
|
|
Packit |
db064d |
char buf[1024];
|
|
Packit |
db064d |
uint32_t fw_ver_major = 0;
|
|
Packit |
db064d |
uint32_t fw_ver_minor = 0;
|
|
Packit |
db064d |
uint32_t fw_ver_sub_minor = 0;
|
|
Packit |
db064d |
uint8_t sw_ver_major = 0, sw_ver_minor = 0, sw_ver_sub_minor = 0;
|
|
Packit |
db064d |
is3_general_info_t *gi_is3;
|
|
Packit |
db064d |
is4_general_info_t *gi_is4;
|
|
Packit |
db064d |
const struct ibdiag_opt opts[] = {
|
|
Packit |
db064d |
{"N", 'N', 0, NULL, "show IS3 or IS4 general information"},
|
|
Packit |
db064d |
{"w", 'w', 0, NULL, "show IS3 port xmit wait counters"},
|
|
Packit |
db064d |
{"i", 'i', 0, NULL, "show IS4 counter group info"},
|
|
Packit |
db064d |
{"c", 'c', 1, "<num,num>", "configure IS4 counter groups"},
|
|
Packit |
db064d |
{"Read", 'R', 1, "<addr,mask>", "Read configuration space record at addr"},
|
|
Packit |
db064d |
{"Write", 'W', 1, "<addr,val,mask>", "Write configuration space record at addr"},
|
|
Packit |
db064d |
{}
|
|
Packit |
db064d |
};
|
|
Packit |
db064d |
|
|
Packit |
db064d |
char usage_args[] = "<lid|guid> [port]";
|
|
Packit |
db064d |
const char *usage_examples[] = {
|
|
Packit |
db064d |
"-N 6\t\t# read IS3 or IS4 general information",
|
|
Packit |
db064d |
"-w 6\t\t# read IS3 port xmit wait counters",
|
|
Packit |
db064d |
"-i 6 12\t# read IS4 port 12 counter group info",
|
|
Packit |
db064d |
"-c 0,1 6 12\t# configure IS4 port 12 counter groups for PortXmitDataSL",
|
|
Packit |
db064d |
"-c 2,8 6 12\t# configure IS4 port 12 counter groups for PortRcvDataSL",
|
|
Packit |
db064d |
NULL
|
|
Packit |
db064d |
};
|
|
Packit |
db064d |
|
|
Packit |
db064d |
ibdiag_process_opts(argc, argv, NULL, "DKy", opts, process_opt,
|
|
Packit |
db064d |
usage_args, usage_examples);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
argc -= optind;
|
|
Packit |
db064d |
argv += optind;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (argc > 1)
|
|
Packit |
db064d |
port = strtoul(argv[1], NULL, 0);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
|
|
Packit |
db064d |
if (!srcport)
|
|
Packit |
db064d |
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (argc) {
|
|
Packit |
db064d |
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
|
Packit |
db064d |
ibd_dest_type, ibd_sm_id, srcport) < 0) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("can't resolve destination port %s", argv[0]);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
} else {
|
|
Packit |
db064d |
if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, NULL) < 0) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("can't resolve self port %s", argv[0]);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (counter_group_info) {
|
|
Packit |
db064d |
counter_groups_info(&portid, port);
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
exit(0);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (config_counter_group) {
|
|
Packit |
db064d |
config_counter_groups(&portid, port);
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
exit(0);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (read_cs_records || write_cs_records) {
|
|
Packit |
db064d |
if (read_cs_records)
|
|
Packit |
db064d |
do_config_space_records(&portid, 0, &read_cs,
|
|
Packit |
db064d |
read_cs_records);
|
|
Packit |
db064d |
if (write_cs_records)
|
|
Packit |
db064d |
do_config_space_records(&portid, 1, &write_cs,
|
|
Packit |
db064d |
write_cs_records);
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
exit(0);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* These are Mellanox specific vendor MADs */
|
|
Packit |
db064d |
/* but vendors change the VendorId so how know for sure ? */
|
|
Packit |
db064d |
/* Only General Info and Port Xmit Wait Counters */
|
|
Packit |
db064d |
/* queries are currently supported */
|
|
Packit |
db064d |
if (!general_info && !xmit_wait) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("at least one of -N and -w must be specified");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
/* Would need a list of these and it might not be complete */
|
|
Packit |
db064d |
/* so for right now, punt on this */
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* vendor ClassPortInfo is required attribute if class supported */
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
if (do_vendor(&portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
|
Packit |
db064d |
CLASS_PORT_INFO, 0, buf)) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("classportinfo query");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
gi_is3 = (is3_general_info_t *) &buf;
|
|
Packit |
db064d |
if (do_vendor(&portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
|
Packit |
db064d |
IB_MLX_IS3_GENERAL_INFO, 0, gi_is3)) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("generalinfo query");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (is_ext_fw_info_supported(ntohs(gi_is3->hw_info.device_id))) {
|
|
Packit |
db064d |
gi_is4 = (is4_general_info_t *) &buf;
|
|
Packit |
db064d |
fw_ver_major = ntohl(gi_is4->ext_fw_info.ext_major);
|
|
Packit |
db064d |
fw_ver_minor = ntohl(gi_is4->ext_fw_info.ext_minor);
|
|
Packit |
db064d |
fw_ver_sub_minor = ntohl(gi_is4->ext_fw_info.ext_sub_minor);
|
|
Packit |
db064d |
sw_ver_major = gi_is4->sw_info.major;
|
|
Packit |
db064d |
sw_ver_minor = gi_is4->sw_info.minor;
|
|
Packit |
db064d |
sw_ver_sub_minor = gi_is4->sw_info.sub_minor;
|
|
Packit |
db064d |
} else {
|
|
Packit |
db064d |
fw_ver_major = gi_is3->fw_info.major;
|
|
Packit |
db064d |
fw_ver_minor = gi_is3->fw_info.minor;
|
|
Packit |
db064d |
fw_ver_sub_minor = gi_is3->fw_info.sub_minor;
|
|
Packit |
db064d |
sw_ver_major = gi_is3->sw_info.major;
|
|
Packit |
db064d |
sw_ver_minor = gi_is3->sw_info.minor;
|
|
Packit |
db064d |
sw_ver_sub_minor = gi_is3->sw_info.sub_minor;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (general_info) {
|
|
Packit |
db064d |
/* dump IS3 or IS4 general info here */
|
|
Packit |
db064d |
printf("hw_dev_rev: 0x%04x\n", ntohs(gi_is3->hw_info.hw_revision));
|
|
Packit |
db064d |
printf("hw_dev_id: 0x%04x\n", ntohs(gi_is3->hw_info.device_id));
|
|
Packit |
db064d |
printf("hw_uptime: 0x%08x\n", ntohl(gi_is3->hw_info.uptime));
|
|
Packit |
db064d |
printf("fw_version: %02d.%02d.%02d\n",
|
|
Packit |
db064d |
fw_ver_major, fw_ver_minor, fw_ver_sub_minor);
|
|
Packit |
db064d |
printf("fw_build_id: 0x%04x\n", ntohl(gi_is3->fw_info.build_id));
|
|
Packit |
db064d |
printf("fw_date: %02x/%02x/%04x\n",
|
|
Packit |
db064d |
gi_is3->fw_info.month, gi_is3->fw_info.day,
|
|
Packit |
db064d |
ntohs(gi_is3->fw_info.year));
|
|
Packit |
db064d |
printf("fw_psid: '%s'\n", gi_is3->fw_info.psid);
|
|
Packit |
db064d |
printf("fw_ini_ver: %d\n",
|
|
Packit |
db064d |
ntohl(gi_is3->fw_info.ini_file_version));
|
|
Packit |
db064d |
printf("sw_version: %02d.%02d.%02d\n", sw_ver_major,
|
|
Packit |
db064d |
sw_ver_minor, sw_ver_sub_minor);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (xmit_wait) {
|
|
Packit |
db064d |
is3_config_space_t *cs;
|
|
Packit |
db064d |
unsigned i;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (ntohs(gi_is3->hw_info.device_id) != IS3_DEVICE_ID) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("Unsupported device ID 0x%x",
|
|
Packit |
db064d |
ntohs(gi_is3->hw_info.device_id));
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
/* Set record addresses for each port */
|
|
Packit |
db064d |
cs = (is3_config_space_t *) & buf;
|
|
Packit |
db064d |
for (i = 0; i < 16; i++)
|
|
Packit |
db064d |
cs->record[i].address =
|
|
Packit |
db064d |
htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 1) << 12));
|
|
Packit |
db064d |
if (do_vendor(&portid, IB_MLX_VENDOR_CLASS,
|
|
Packit |
db064d |
IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
|
|
Packit |
db064d |
2 << 22 | 16 << 16, cs)) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("vendstat");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
for (i = 0; i < 16; i++)
|
|
Packit |
db064d |
if (cs->record[i].data) /* PortXmitWait is 32 bit counter */
|
|
Packit |
db064d |
printf("Port %d: PortXmitWait 0x%x\n", i + 4, ntohl(cs->record[i].data)); /* port 4 is first port */
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* Last 8 ports is another query */
|
|
Packit |
db064d |
memset(&buf, 0, sizeof(buf));
|
|
Packit |
db064d |
/* Set record addresses for each port */
|
|
Packit |
db064d |
cs = (is3_config_space_t *) & buf;
|
|
Packit |
db064d |
for (i = 0; i < 8; i++)
|
|
Packit |
db064d |
cs->record[i].address =
|
|
Packit |
db064d |
htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 17) << 12));
|
|
Packit |
db064d |
if (do_vendor(&portid, IB_MLX_VENDOR_CLASS,
|
|
Packit |
db064d |
IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
|
|
Packit |
db064d |
2 << 22 | 8 << 16, cs)) {
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
IBEXIT("vendstat");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
for (i = 0; i < 8; i++)
|
|
Packit |
db064d |
if (cs->record[i].data) /* PortXmitWait is 32 bit counter */
|
|
Packit |
db064d |
printf("Port %d: PortXmitWait 0x%x\n",
|
|
Packit |
db064d |
i < 4 ? i + 21 : i - 3,
|
|
Packit |
db064d |
ntohl(cs->record[i].data));
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
mad_rpc_close_port(srcport);
|
|
Packit |
db064d |
exit(0);
|
|
Packit |
db064d |
}
|