Add a 'raw' parameter to the 'modinfo' subcommand. This is handy when
trying to figure out why a QSFP+/SFP+ connector or cable wasn't identified correctly by cxgbe(4). Its output looks like this: # cxgbetool t5nex0 modinfo 0 raw 00: 03 04 21 00 00 00 00 00 ..!. .... 08: 04 00 00 00 67 00 00 00 .... g... 10: 00 00 05 00 41 6d 70 68 .... Amph 18: 65 6e 6f 6c 20 20 20 20 enol 20: 20 20 20 20 00 41 50 48 .APH 28: 35 37 31 35 34 30 30 30 5715 4000 30: 33 20 20 20 20 20 20 20 3 38: 4b 20 20 20 01 00 00 fa K .... 40: 00 00 00 00 41 50 46 31 .... APF1 48: 30 30 34 30 30 33 30 30 0040 0300 50: 30 33 20 20 31 30 30 31 03 1001 58: 33 30 20 20 00 00 00 97 30 .... MFC after: 3 days
This commit is contained in:
parent
f6b4f5ca21
commit
4f43c2cbda
@ -95,7 +95,7 @@ usage(FILE *fp)
|
||||
"\ti2c <port> <devaddr> <addr> [<len>] read from i2c device\n"
|
||||
"\tloadfw <fw-image.bin> install firmware\n"
|
||||
"\tmemdump <addr> <len> dump a memory range\n"
|
||||
"\tmodinfo <port> optics/cable information\n"
|
||||
"\tmodinfo <port> [raw] optics/cable information\n"
|
||||
"\treg <address>[=<val>] read/write register\n"
|
||||
"\treg64 <address>[=<val>] read/write 64 bit register\n"
|
||||
"\tregdump [<module>] ... dump registers\n"
|
||||
@ -1872,6 +1872,41 @@ tracer_cmd(int argc, const char *argv[])
|
||||
return set_tracer(idx, argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
static int
|
||||
modinfo_raw(int port_id)
|
||||
{
|
||||
uint8_t offset;
|
||||
struct t4_i2c_data i2cd;
|
||||
int rc;
|
||||
|
||||
for (offset = 0; offset < 96; offset += sizeof(i2cd.data)) {
|
||||
bzero(&i2cd, sizeof(i2cd));
|
||||
i2cd.port_id = port_id;
|
||||
i2cd.dev_addr = 0xa0;
|
||||
i2cd.offset = offset;
|
||||
i2cd.len = sizeof(i2cd.data);
|
||||
rc = doit(CHELSIO_T4_GET_I2C, &i2cd);
|
||||
if (rc != 0)
|
||||
return (rc);
|
||||
printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
offset, i2cd.data[0], i2cd.data[1], i2cd.data[2],
|
||||
i2cd.data[3], i2cd.data[4], i2cd.data[5], i2cd.data[6],
|
||||
i2cd.data[7]);
|
||||
|
||||
printf(" %c%c%c%c %c%c%c%c\n",
|
||||
isprint(i2cd.data[0]) ? i2cd.data[0] : '.',
|
||||
isprint(i2cd.data[1]) ? i2cd.data[1] : '.',
|
||||
isprint(i2cd.data[2]) ? i2cd.data[2] : '.',
|
||||
isprint(i2cd.data[3]) ? i2cd.data[3] : '.',
|
||||
isprint(i2cd.data[4]) ? i2cd.data[4] : '.',
|
||||
isprint(i2cd.data[5]) ? i2cd.data[5] : '.',
|
||||
isprint(i2cd.data[6]) ? i2cd.data[6] : '.',
|
||||
isprint(i2cd.data[7]) ? i2cd.data[7] : '.');
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
modinfo(int argc, const char *argv[])
|
||||
{
|
||||
@ -1881,17 +1916,31 @@ modinfo(int argc, const char *argv[])
|
||||
int rc, i;
|
||||
uint16_t temp, vcc, tx_bias, tx_power, rx_power;
|
||||
|
||||
if (argc != 1) {
|
||||
if (argc < 1) {
|
||||
warnx("must supply a port");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
warnx("too many arguments");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
p = str_to_number(argv[0], &port, NULL);
|
||||
if (*p || port > UCHAR_MAX) {
|
||||
warnx("invalid port id \"%s\"", argv[0]);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
if (!strcmp(argv[1], "raw"))
|
||||
return (modinfo_raw(port));
|
||||
else {
|
||||
warnx("second argument can only be \"raw\"");
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
bzero(&i2cd, sizeof(i2cd));
|
||||
i2cd.len = 1;
|
||||
i2cd.port_id = port;
|
||||
|
Loading…
Reference in New Issue
Block a user