The "show port <port_id> module_eeprom" command only prints a hexdump of the pluggable module EEPROM, which has to be decoded by hand against the SFF specifications.
Add the "show port <port_id> module_eeprom decode" command to print the fields decoded by rte_eth_module_eeprom_parse(), such as the vendor, the transceiver type and the digital diagnostics, in the same form as "ethtool -m". The EEPROM read is moved to a helper shared by both commands. Signed-off-by: Roman Khromenok <[email protected]> --- This adds the testpmd hook for rte_eth_module_eeprom_parse(), which is in dpdk-next-net for 26.11. The patch is based on next-net/for-main. Tested with net_null returning a synthetic SFF-8472 image (not part of the patch), built with gcc and with clang ASan/UBSan, no reports: testpmd> show port 0 module_eeprom decode Port 0 module EEPROM (type 0x2, 512 bytes): Identifier : 0x03 (SFP) ... Vendor name : TESTVENDOR ... Laser bias current : 8.000 mA Laser output power : 0.5000 mW / -3.01 dBm Receiver signal average optical power : 0.4000 mW / -3.98 dBm Module temperature : 37.50 degrees C / 99.50 degrees F Module voltage : 3.3000 V app/test-pmd/cmdline.c | 48 ++++++++++++++ app/test-pmd/config.c | 72 ++++++++++++++++----- app/test-pmd/testpmd.h | 1 + doc/guides/rel_notes/release_26_11.rst | 2 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 +++ 5 files changed, 115 insertions(+), 16 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index d52a0eff42..51078a2a73 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -172,6 +172,9 @@ static void cmd_help_long_parsed(void *parsed_result, "show port port_id (module_eeprom|eeprom)\n" " Display the module EEPROM or EEPROM information for port_id.\n\n" + "show port (port_id) module_eeprom decode\n" + " Display the decoded module EEPROM of port_id.\n\n" + "set port (port_id) eeprom (accept_risk) magic (magic_num)" " value (value) offset (offset)\n" " Set the device eeprom for certain port.\nNote:\n" @@ -7826,6 +7829,50 @@ static cmdline_parse_inst_t cmd_showeeprom = { }, }; +struct cmd_showeeprom_decode_result { + cmdline_fixed_string_t show; + cmdline_fixed_string_t port; + uint16_t portnum; + cmdline_fixed_string_t module_eeprom; + cmdline_fixed_string_t decode; +}; + +static void cmd_showeeprom_decode_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_showeeprom_decode_result *res = parsed_result; + + port_module_eeprom_decode_display(res->portnum); +} + +static cmdline_parse_token_string_t cmd_showeeprom_decode_show = + TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_decode_result, show, "show"); +static cmdline_parse_token_string_t cmd_showeeprom_decode_port = + TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_decode_result, port, "port"); +static cmdline_parse_token_num_t cmd_showeeprom_decode_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_showeeprom_decode_result, portnum, + RTE_UINT16); +static cmdline_parse_token_string_t cmd_showeeprom_decode_module_eeprom = + TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_decode_result, module_eeprom, + "module_eeprom"); +static cmdline_parse_token_string_t cmd_showeeprom_decode_decode = + TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_decode_result, decode, "decode"); + +static cmdline_parse_inst_t cmd_showeeprom_decode = { + .f = cmd_showeeprom_decode_parsed, + .data = NULL, + .help_str = "show port <port_id> module_eeprom decode", + .tokens = { + (void *)&cmd_showeeprom_decode_show, + (void *)&cmd_showeeprom_decode_port, + (void *)&cmd_showeeprom_decode_portnum, + (void *)&cmd_showeeprom_decode_module_eeprom, + (void *)&cmd_showeeprom_decode_decode, + NULL, + }, +}; + /* *** SET PORT EEPROM *** */ struct cmd_seteeprom_result { cmdline_fixed_string_t set; @@ -14219,6 +14266,7 @@ static cmdline_parse_ctx_t builtin_ctx[] = { &cmd_showport, &cmd_showqueue, &cmd_showeeprom, + &cmd_showeeprom_decode, &cmd_seteeprom, &cmd_showportall, &cmd_representor_info, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 9d1fa2f4d1..ec348cf854 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1145,20 +1145,18 @@ port_eeprom_set(portid_t port_id, fprintf(stderr, "Unable to set EEPROM: %s\n", rte_strerror(-ret)); } -void -port_module_eeprom_display(portid_t port_id) +static int +port_module_eeprom_read(portid_t port_id, struct rte_eth_dev_module_info *minfo, + struct rte_dev_eeprom_info *einfo) { - struct rte_eth_dev_module_info minfo; - struct rte_dev_eeprom_info einfo; int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) { print_valid_ports(); - return; + return -EINVAL; } - - ret = rte_eth_dev_get_module_info(port_id, &minfo); + ret = rte_eth_dev_get_module_info(port_id, minfo); if (ret != 0) { switch (ret) { case -ENODEV: @@ -1175,20 +1173,20 @@ port_module_eeprom_display(portid_t port_id) ret); break; } - return; + return ret; } - einfo.offset = 0; - einfo.length = minfo.eeprom_len; - einfo.data = calloc(1, minfo.eeprom_len); - if (!einfo.data) { + einfo->offset = 0; + einfo->length = minfo->eeprom_len; + einfo->data = calloc(1, minfo->eeprom_len); + if (!einfo->data) { fprintf(stderr, "Allocation of port %u eeprom data failed\n", port_id); - return; + return -ENOMEM; } - ret = rte_eth_dev_get_module_eeprom(port_id, &einfo); + ret = rte_eth_dev_get_module_eeprom(port_id, einfo); if (ret != 0) { switch (ret) { case -ENODEV: @@ -1205,15 +1203,57 @@ port_module_eeprom_display(portid_t port_id) ret); break; } - free(einfo.data); - return; + free(einfo->data); + einfo->data = NULL; + return ret; } + return 0; +} + +void +port_module_eeprom_display(portid_t port_id) +{ + struct rte_eth_dev_module_info minfo; + struct rte_dev_eeprom_info einfo; + + if (port_module_eeprom_read(port_id, &minfo, &einfo) != 0) + return; + rte_hexdump(stdout, "hexdump", einfo.data, einfo.length); printf("Finish -- Port: %d MODULE EEPROM length: %d bytes\n", port_id, einfo.length); free(einfo.data); } +static void +port_module_eeprom_field_print(const char *name, const char *value, + __rte_unused void *arg) +{ + printf("\t%-41s : %s\n", name, value); +} + +void +port_module_eeprom_decode_display(portid_t port_id) +{ + struct rte_eth_dev_module_info minfo; + struct rte_dev_eeprom_info einfo; + int ret; + + if (port_module_eeprom_read(port_id, &minfo, &einfo) != 0) + return; + + printf("Port %u module EEPROM (type 0x%x, %u bytes):\n", + port_id, minfo.type, einfo.length); + ret = rte_eth_module_eeprom_parse(minfo.type, einfo.data, einfo.length, + port_module_eeprom_field_print, NULL); + if (ret == -ENOTSUP) + fprintf(stderr, "Unsupported module type: 0x%x\n", minfo.type); + else if (ret != 0) + fprintf(stderr, "Unable to decode module EEPROM: %s\n", + rte_strerror(-ret)); + free(einfo.data); +} + int port_id_is_invalid(portid_t port_id, enum print_warning warning) { diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index d23950ab9d..2ca4aaf086 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -990,6 +990,7 @@ void port_eeprom_display(portid_t port_id); void port_eeprom_set(portid_t port_id, uint32_t magic, uint32_t offset, uint32_t length, uint8_t *value); void port_module_eeprom_display(portid_t port_id); +void port_module_eeprom_decode_display(portid_t port_id); void port_summary_header_display(void); void rx_queue_infos_display(portid_t port_idi, uint16_t queue_id); void tx_queue_infos_display(portid_t port_idi, uint16_t queue_id); diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index d25dc72edf..d0c896634b 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -84,6 +84,8 @@ New Features It can decode data read with ``rte_eth_dev_get_module_eeprom()`` or obtained from any other source with the same layout, such as the Linux ethtool ``ETHTOOL_GMODULEEEPROM`` ioctl. + The testpmd command ``show port (port_id) module_eeprom decode`` + uses it to display the decoded module EEPROM. * **Updated AF_XDP driver.** diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 30cac0ad8c..a967bbef76 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -222,6 +222,14 @@ Display the EEPROM information of a port:: testpmd> show port (port_id) (module_eeprom|eeprom) +show port module_eeprom decode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Display the module EEPROM of a port decoded according to the SFF specifications, +for example the vendor, the transceiver type and the digital diagnostics:: + + testpmd> show port (port_id) module_eeprom decode + set eeprom ~~~~~~~~~~ -- 2.47.3

