From 2243e7eb4c91f729030d35c6804e7a1e9b29baed Mon Sep 17 00:00:00 2001 From: np Date: Thu, 31 Jul 2014 23:17:59 +0000 Subject: [PATCH] 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 .... git-svn-id: svn://svn.freebsd.org/base/stable/9@269359 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- tools/tools/cxgbetool/cxgbetool.c | 53 +++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/tools/tools/cxgbetool/cxgbetool.c b/tools/tools/cxgbetool/cxgbetool.c index 9733d7ae9..dabc3fc1f 100644 --- a/tools/tools/cxgbetool/cxgbetool.c +++ b/tools/tools/cxgbetool/cxgbetool.c @@ -95,7 +95,7 @@ usage(FILE *fp) "\ti2c [] read from i2c device\n" "\tloadfw install firmware\n" "\tmemdump dump a memory range\n" - "\tmodinfo optics/cable information\n" + "\tmodinfo [raw] optics/cable information\n" "\treg
[=] read/write register\n" "\treg64
[=] read/write 64 bit register\n" "\tregdump [] ... dump registers\n" @@ -1672,6 +1672,41 @@ clearstats(int argc, const char *argv[]) return doit(CHELSIO_T4_CLEAR_STATS, &port); } +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[]) { @@ -1681,17 +1716,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; -- 2.45.0