diff options
author | np <np@FreeBSD.org> | 2014-07-31 23:09:22 +0000 |
---|---|---|
committer | np <np@FreeBSD.org> | 2014-07-31 23:09:22 +0000 |
commit | d3402f0f6200047ac05f87fe9d936202829e3050 (patch) | |
tree | 9d80193be1505eacfba6155c6ace49df51e40ec0 | |
parent | 072ac2f2da086a7f38f0374707f6c98a21aaf15e (diff) | |
download | FreeBSD-src-d3402f0f6200047ac05f87fe9d936202829e3050.zip FreeBSD-src-d3402f0f6200047ac05f87fe9d936202829e3050.tar.gz |
MFC r269106:
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 ....
-rw-r--r-- | tools/tools/cxgbetool/cxgbetool.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/tools/tools/cxgbetool/cxgbetool.c b/tools/tools/cxgbetool/cxgbetool.c index ab6fee5..729ad9f 100644 --- a/tools/tools/cxgbetool/cxgbetool.c +++ b/tools/tools/cxgbetool/cxgbetool.c @@ -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" @@ -1873,6 +1873,41 @@ tracer_cmd(int argc, const char *argv[]) } 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[]) { long port; @@ -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; |