From: Danielle Ratson <danieller@nvidia.com>
To: <netdev@vger.kernel.org>
Cc: <mkubecek@suse.cz>, <idosch@nvidia.com>, <petrm@nvidia.com>,
"Danielle Ratson" <danieller@nvidia.com>
Subject: [PATCH ethtool-next 3/5] module: Add per-type EEPROM page hex dump functions
Date: Thu, 7 May 2026 14:47:19 +0300 [thread overview]
Message-ID: <20260507114721.3409128-4-danieller@nvidia.com> (raw)
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
Extend sff8079_show_all_nl(), cmis_show_all_nl() and
sff8636_show_all_nl() with a bool dump_pages parameter to support
hex dump output alongside their existing pretty-print output. Each
function first retrieves all the necessary pages and then either
pretty-prints them or performs a hex dump according to the argument.
The hex dump and pretty-print logic is extracted into dedicated static
functions for each parser type:
- cmis_hex_dump() / cmis_pretty_print()
- sff8636_hex_dump() / sff8636_pretty_print()
- sff8079_hex_dump() / sff8079_pretty_print()
Each function dumps the same pages as the corresponding pretty-printer:
- CMIS: uses cmis_memory_map_init_pages() to read the lower memory and
relevant upper pages across all supported banks, using generic iteration
over the memory map. Uses module_dump_eeprom_page_hex() for hex output.
- SFF-8636: uses sff8636_memory_map_init_pages() to read the lower memory
and relevant upper pages, using generic iteration over the memory map.
Uses module_dump_eeprom_page_hex() for hex output.
- SFF-8079: uses sff8079_get_eeprom_page() to read A0h lower and optional
A2h lower and identifies each block by its I2C address. Uses dump_hex()
directly with I2C address headers.
Assisted-by: Claude:claude-sonnet-4.6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---
cmis.c | 49 +++++++++++++++++++++++++++++++++++------
cmis.h | 2 +-
internal.h | 4 ++--
netlink/module-eeprom.c | 6 ++---
qsfp.c | 48 ++++++++++++++++++++++++++++++++++------
sfpid.c | 43 +++++++++++++++++++++++++++---------
6 files changed, 122 insertions(+), 30 deletions(-)
diff --git a/cmis.c b/cmis.c
index 996e9eb..29592b2 100644
--- a/cmis.c
+++ b/cmis.c
@@ -1022,6 +1022,43 @@ void cmis_show_all_ioctl(const __u8 *id)
cmis_show_all_common(&map);
}
+static void cmis_hex_dump(const struct cmis_memory_map *map)
+{
+ u8 bank, page;
+
+ module_dump_eeprom_page_hex(map->lower_memory, 0, 0x0, 0,
+ CMIS_PAGE_SIZE);
+ for (bank = 0; bank < CMIS_MAX_BANKS; bank++) {
+ for (page = 0; page < CMIS_MAX_PAGES; page++) {
+ const __u8 *buf = map->upper_memory[bank][page];
+
+ if (!buf)
+ continue;
+
+ /* Upper memory starts at one page size into
+ * the buffer, since pages are accessed at
+ * offset between page size and twice the
+ * page size.
+ */
+ module_dump_eeprom_page_hex(buf + CMIS_PAGE_SIZE, bank,
+ page, CMIS_PAGE_SIZE,
+ CMIS_PAGE_SIZE);
+ }
+ }
+}
+
+static void cmis_pretty_print(struct cmd_context *ctx,
+ const struct cmis_memory_map *map)
+{
+ new_json_obj(ctx->json);
+ open_json_object(NULL);
+
+ cmis_show_all_common(map);
+
+ close_json_object();
+ delete_json_obj();
+}
+
static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
u8 page, u32 offset)
{
@@ -1117,21 +1154,19 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
return 0;
}
-int cmis_show_all_nl(struct cmd_context *ctx)
+int cmis_show_all_nl(struct cmd_context *ctx, bool dump_pages)
{
struct cmis_memory_map map = {};
int ret;
- new_json_obj(ctx->json);
- open_json_object(NULL);
-
ret = cmis_memory_map_init_pages(ctx, &map);
if (ret < 0)
return ret;
- cmis_show_all_common(&map);
- close_json_object();
- delete_json_obj();
+ if (dump_pages)
+ cmis_hex_dump(&map);
+ else
+ cmis_pretty_print(ctx, &map);
return 0;
}
diff --git a/cmis.h b/cmis.h
index 007632a..82fd245 100644
--- a/cmis.h
+++ b/cmis.h
@@ -201,6 +201,6 @@
void cmis_show_all_ioctl(const __u8 *id);
-int cmis_show_all_nl(struct cmd_context *ctx);
+int cmis_show_all_nl(struct cmd_context *ctx, bool dump_pages);
#endif /* CMIS_H__ */
diff --git a/internal.h b/internal.h
index cbf3c09..19fff41 100644
--- a/internal.h
+++ b/internal.h
@@ -381,14 +381,14 @@ int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
/* Module EEPROM parsing code */
void sff8079_show_all_ioctl(const __u8 *id);
-int sff8079_show_all_nl(struct cmd_context *ctx);
+int sff8079_show_all_nl(struct cmd_context *ctx, bool dump_pages);
/* Optics diagnostics */
void sff8472_show_all(const __u8 *id);
/* QSFP Optics diagnostics */
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
-int sff8636_show_all_nl(struct cmd_context *ctx);
+int sff8636_show_all_nl(struct cmd_context *ctx, bool dump_pages);
/* FUJITSU Extended Socket network device */
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index ce6a7d9..7e4e6ac 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -228,18 +228,18 @@ static int eeprom_parse(struct cmd_context *ctx)
case MODULE_ID_GBIC:
case MODULE_ID_SOLDERED_MODULE:
case MODULE_ID_SFP:
- return sff8079_show_all_nl(ctx);
+ return sff8079_show_all_nl(ctx, false);
case MODULE_ID_QSFP:
case MODULE_ID_QSFP28:
case MODULE_ID_QSFP_PLUS:
- return sff8636_show_all_nl(ctx);
+ return sff8636_show_all_nl(ctx, false);
case MODULE_ID_QSFP_DD:
case MODULE_ID_OSFP:
case MODULE_ID_DSFP:
case MODULE_ID_QSFP_PLUS_CMIS:
case MODULE_ID_SFP_DD_CMIS:
case MODULE_ID_SFP_PLUS_CMIS:
- return cmis_show_all_nl(ctx);
+ return cmis_show_all_nl(ctx, false);
#endif
default:
/* If we cannot recognize the memory map, default to dumping
diff --git a/qsfp.c b/qsfp.c
index 09d9ace..6e1b9ff 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -62,9 +62,11 @@
#include "cmis.h"
#include "netlink/extapi.h"
+#define SFF8636_MAX_PAGES 4
+
struct sff8636_memory_map {
const __u8 *lower_memory;
- const __u8 *upper_memory[4];
+ const __u8 *upper_memory[SFF8636_MAX_PAGES];
#define page_00h upper_memory[0x0]
#define page_03h upper_memory[0x3]
};
@@ -1078,21 +1080,53 @@ sff8636_memory_map_init_pages(struct cmd_context *ctx,
return 0;
}
-int sff8636_show_all_nl(struct cmd_context *ctx)
+static void sff8636_hex_dump(const struct sff8636_memory_map *map)
{
- struct sff8636_memory_map map = {};
- int ret;
+ u8 page;
+
+ module_dump_eeprom_page_hex(map->lower_memory, 0, 0x0, 0,
+ SFF8636_PAGE_SIZE);
+ for (page = 0; page < SFF8636_MAX_PAGES; page++) {
+ const __u8 *buf = map->upper_memory[page];
+
+ if (!buf)
+ continue;
+ /* Upper memory starts at one page size into the
+ * buffer, since pages are accessed at offset between
+ * page size and twice the page size.
+ */
+ module_dump_eeprom_page_hex(buf + SFF8636_PAGE_SIZE, 0,
+ page, SFF8636_PAGE_SIZE,
+ SFF8636_PAGE_SIZE);
+ }
+}
+
+static void sff8636_pretty_print(struct cmd_context *ctx,
+ const struct sff8636_memory_map *map)
+{
new_json_obj(ctx->json);
open_json_object(NULL);
+ sff8636_show_all_common(map);
+
+ close_json_object();
+ delete_json_obj();
+}
+
+int sff8636_show_all_nl(struct cmd_context *ctx, bool dump_pages)
+{
+ struct sff8636_memory_map map = {};
+ int ret;
+
ret = sff8636_memory_map_init_pages(ctx, &map);
if (ret < 0)
return ret;
- sff8636_show_all_common(&map);
- close_json_object();
- delete_json_obj();
+ if (dump_pages)
+ sff8636_hex_dump(&map);
+ else
+ sff8636_pretty_print(ctx, &map);
return 0;
}
diff --git a/sfpid.c b/sfpid.c
index f753917..73e714e 100644
--- a/sfpid.c
+++ b/sfpid.c
@@ -498,7 +498,35 @@ static int sff8079_get_eeprom_page(struct cmd_context *ctx, u8 i2c_address,
return ret;
}
-int sff8079_show_all_nl(struct cmd_context *ctx)
+static void sff8079_hex_dump(const u8 *buf, bool a2h_present)
+{
+ printf("I2C Address: 0x%02x\n\n", SFF8079_I2C_ADDRESS_LOW);
+ dump_hex(stdout, buf, SFF8079_PAGE_SIZE, 0);
+ printf("\n");
+
+ if (a2h_present) {
+ printf("I2C Address: 0x%02x\n\n", SFF8079_I2C_ADDRESS_HIGH);
+ dump_hex(stdout, buf + ETH_MODULE_SFF_8079_LEN,
+ SFF8079_PAGE_SIZE, 0);
+ printf("\n");
+ }
+}
+
+static void sff8079_pretty_print(struct cmd_context *ctx, const u8 *buf,
+ bool a2h_present)
+{
+ new_json_obj(ctx->json);
+ open_json_object(NULL);
+ sff8079_show_all_common(buf);
+
+ if (a2h_present)
+ sff8472_show_all(buf);
+
+ close_json_object();
+ delete_json_obj();
+}
+
+int sff8079_show_all_nl(struct cmd_context *ctx, bool dump_pages)
{
bool a2h_present;
u8 *buf;
@@ -530,15 +558,10 @@ int sff8079_show_all_nl(struct cmd_context *ctx)
}
}
- new_json_obj(ctx->json);
- open_json_object(NULL);
- sff8079_show_all_common(buf);
-
- if (a2h_present)
- sff8472_show_all(buf);
-
- close_json_object();
- delete_json_obj();
+ if (dump_pages)
+ sff8079_hex_dump(buf, a2h_present);
+ else
+ sff8079_pretty_print(ctx, buf, a2h_present);
out:
free(buf);
--
2.51.0
next prev parent reply other threads:[~2026-05-07 11:48 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-07 11:47 [PATCH ethtool-next 0/5] ethtool: Add 'pages on|off' option for module EEROM hex dump Danielle Ratson
2026-05-07 11:47 ` [PATCH ethtool-next 1/5] module-common: Add module_dump_eeprom_page_hex() helper Danielle Ratson
2026-05-07 11:47 ` [PATCH ethtool-next 2/5] sfpid: Refactor sff8079_show_all_nl() to separate page retrieval from display Danielle Ratson
2026-05-07 11:47 ` Danielle Ratson [this message]
2026-05-07 11:47 ` [PATCH ethtool-next 4/5] netlink: module-eeprom: Add 'hex on pages on' option for page-organized hex dump Danielle Ratson
2026-05-07 11:47 ` [PATCH ethtool-next 5/5] ethtool: Add man page and bash completion for 'pages on|off' Danielle Ratson
2026-05-07 12:07 ` [PATCH ethtool-next 0/5] ethtool: Add 'pages on|off' option for module EEROM hex dump Michal Kubecek
2026-05-07 12:37 ` Danielle Ratson
2026-05-07 14:32 ` Michal Kubecek
2026-05-07 12:23 ` Andrew Lunn
2026-05-07 17:19 ` Danielle Ratson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260507114721.3409128-4-danieller@nvidia.com \
--to=danieller@nvidia.com \
--cc=idosch@nvidia.com \
--cc=mkubecek@suse.cz \
--cc=netdev@vger.kernel.org \
--cc=petrm@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox