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:
Navdeep Parhar 2014-07-26 00:51:45 +00:00
parent f6b4f5ca21
commit 4f43c2cbda

View File

@ -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;