|
|
1f2507 |
From 5f45f370e132f144cdbab9ea718393bd37ee23db Mon Sep 17 00:00:00 2001
|
|
|
1f2507 |
From: Ido Schimmel <idosch@nvidia.com>
|
|
|
1f2507 |
Date: Tue, 12 Oct 2021 16:25:22 +0300
|
|
|
1f2507 |
Subject: [PATCH 23/35] cmis: Request specific pages for parsing in netlink
|
|
|
1f2507 |
path
|
|
|
1f2507 |
|
|
|
1f2507 |
In the netlink path, unlike the IOCTL path, user space requests specific
|
|
|
1f2507 |
EEPROM pages from the kernel. The presence of optional and banked pages
|
|
|
1f2507 |
is advertised via various bits in the EEPROM contents.
|
|
|
1f2507 |
|
|
|
1f2507 |
Currently, for CMIS, the Lower Memory, Page 00h and the optional Page
|
|
|
1f2507 |
01h are requested by the netlink code (i.e., netlink/module-eeprom.c)
|
|
|
1f2507 |
and passed to the CMIS code (i.e., cmis.c) as two arguments for parsing.
|
|
|
1f2507 |
|
|
|
1f2507 |
This is problematic for several reasons. First, this approach is not
|
|
|
1f2507 |
very scaleable as CMIS supports a lot of optional and banked pages.
|
|
|
1f2507 |
Passing them as separate arguments to the CMIS code is not going to
|
|
|
1f2507 |
work.
|
|
|
1f2507 |
|
|
|
1f2507 |
Second, the knowledge of which optional and banked pages are available
|
|
|
1f2507 |
is encapsulated in the CMIS parsing code. As such, the common netlink
|
|
|
1f2507 |
code has no business of fetching optional and banked pages that might be
|
|
|
1f2507 |
invalid.
|
|
|
1f2507 |
|
|
|
1f2507 |
Instead, pass the command context to the CMIS parsing function and allow
|
|
|
1f2507 |
it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
|
|
|
1f2507 |
message.
|
|
|
1f2507 |
|
|
|
1f2507 |
Tested by making sure that the output of 'ethtool -m' does not change
|
|
|
1f2507 |
before and after the patch.
|
|
|
1f2507 |
|
|
|
1f2507 |
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
|
|
1f2507 |
---
|
|
|
1f2507 |
cmis.c | 60 ++++++++++++++++++++++++++++++++---------
|
|
|
1f2507 |
cmis.h | 3 +--
|
|
|
1f2507 |
netlink/module-eeprom.c | 7 +++--
|
|
|
1f2507 |
3 files changed, 51 insertions(+), 19 deletions(-)
|
|
|
1f2507 |
|
|
|
1f2507 |
diff --git a/cmis.c b/cmis.c
|
|
|
1f2507 |
index eb7791dd59df..4798fd4c7d68 100644
|
|
|
1f2507 |
--- a/cmis.c
|
|
|
1f2507 |
+++ b/cmis.c
|
|
|
1f2507 |
@@ -9,9 +9,11 @@
|
|
|
1f2507 |
|
|
|
1f2507 |
#include <stdio.h>
|
|
|
1f2507 |
#include <math.h>
|
|
|
1f2507 |
+#include <errno.h>
|
|
|
1f2507 |
#include "internal.h"
|
|
|
1f2507 |
#include "sff-common.h"
|
|
|
1f2507 |
#include "cmis.h"
|
|
|
1f2507 |
+#include "netlink/extapi.h"
|
|
|
1f2507 |
|
|
|
1f2507 |
struct cmis_memory_map {
|
|
|
1f2507 |
const __u8 *lower_memory;
|
|
|
1f2507 |
@@ -21,6 +23,7 @@ struct cmis_memory_map {
|
|
|
1f2507 |
};
|
|
|
1f2507 |
|
|
|
1f2507 |
#define CMIS_PAGE_SIZE 0x80
|
|
|
1f2507 |
+#define CMIS_I2C_ADDRESS 0x50
|
|
|
1f2507 |
|
|
|
1f2507 |
static void cmis_show_identifier(const struct cmis_memory_map *map)
|
|
|
1f2507 |
{
|
|
|
1f2507 |
@@ -384,36 +387,67 @@ void cmis_show_all_ioctl(const __u8 *id)
|
|
|
1f2507 |
cmis_show_all_common(&map);
|
|
|
1f2507 |
}
|
|
|
1f2507 |
|
|
|
1f2507 |
-static void
|
|
|
1f2507 |
-cmis_memory_map_init_pages(struct cmis_memory_map *map,
|
|
|
1f2507 |
- const struct ethtool_module_eeprom *page_zero,
|
|
|
1f2507 |
- const struct ethtool_module_eeprom *page_one)
|
|
|
1f2507 |
+static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
|
|
|
1f2507 |
+ u8 page, u32 offset)
|
|
|
1f2507 |
{
|
|
|
1f2507 |
+ request->offset = offset;
|
|
|
1f2507 |
+ request->length = CMIS_PAGE_SIZE;
|
|
|
1f2507 |
+ request->page = page;
|
|
|
1f2507 |
+ request->bank = bank;
|
|
|
1f2507 |
+ request->i2c_address = CMIS_I2C_ADDRESS;
|
|
|
1f2507 |
+ request->data = NULL;
|
|
|
1f2507 |
+}
|
|
|
1f2507 |
+
|
|
|
1f2507 |
+static int
|
|
|
1f2507 |
+cmis_memory_map_init_pages(struct cmd_context *ctx,
|
|
|
1f2507 |
+ struct cmis_memory_map *map)
|
|
|
1f2507 |
+{
|
|
|
1f2507 |
+ struct ethtool_module_eeprom request;
|
|
|
1f2507 |
+ int ret;
|
|
|
1f2507 |
+
|
|
|
1f2507 |
/* Lower Memory and Page 00h are always present.
|
|
|
1f2507 |
*
|
|
|
1f2507 |
* Offset into Upper Memory is between page size and twice the page
|
|
|
1f2507 |
* size. Therefore, set the base address of each page to its base
|
|
|
1f2507 |
- * address minus page size. For Page 00h, this is the address of the
|
|
|
1f2507 |
- * Lower Memory.
|
|
|
1f2507 |
+ * address minus page size.
|
|
|
1f2507 |
*/
|
|
|
1f2507 |
- map->lower_memory = page_zero->data;
|
|
|
1f2507 |
- map->page_00h = page_zero->data;
|
|
|
1f2507 |
+ cmis_request_init(&request, 0, 0x0, 0);
|
|
|
1f2507 |
+ ret = nl_get_eeprom_page(ctx, &request);
|
|
|
1f2507 |
+ if (ret < 0)
|
|
|
1f2507 |
+ return ret;
|
|
|
1f2507 |
+ map->lower_memory = request.data;
|
|
|
1f2507 |
+
|
|
|
1f2507 |
+ cmis_request_init(&request, 0, 0x0, CMIS_PAGE_SIZE);
|
|
|
1f2507 |
+ ret = nl_get_eeprom_page(ctx, &request);
|
|
|
1f2507 |
+ if (ret < 0)
|
|
|
1f2507 |
+ return ret;
|
|
|
1f2507 |
+ map->page_00h = request.data - CMIS_PAGE_SIZE;
|
|
|
1f2507 |
|
|
|
1f2507 |
/* Page 01h is only present when the module memory model is paged and
|
|
|
1f2507 |
* not flat.
|
|
|
1f2507 |
*/
|
|
|
1f2507 |
if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
|
|
|
1f2507 |
CMIS_MEMORY_MODEL_MASK)
|
|
|
1f2507 |
- return;
|
|
|
1f2507 |
+ return 0;
|
|
|
1f2507 |
+
|
|
|
1f2507 |
+ cmis_request_init(&request, 0, 0x1, CMIS_PAGE_SIZE);
|
|
|
1f2507 |
+ ret = nl_get_eeprom_page(ctx, &request);
|
|
|
1f2507 |
+ if (ret < 0)
|
|
|
1f2507 |
+ return ret;
|
|
|
1f2507 |
+ map->page_01h = request.data - CMIS_PAGE_SIZE;
|
|
|
1f2507 |
|
|
|
1f2507 |
- map->page_01h = page_one->data - CMIS_PAGE_SIZE;
|
|
|
1f2507 |
+ return 0;
|
|
|
1f2507 |
}
|
|
|
1f2507 |
|
|
|
1f2507 |
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
|
|
1f2507 |
- const struct ethtool_module_eeprom *page_one)
|
|
|
1f2507 |
+int cmis_show_all_nl(struct cmd_context *ctx)
|
|
|
1f2507 |
{
|
|
|
1f2507 |
struct cmis_memory_map map = {};
|
|
|
1f2507 |
+ int ret;
|
|
|
1f2507 |
|
|
|
1f2507 |
- cmis_memory_map_init_pages(&map, page_zero, page_one);
|
|
|
1f2507 |
+ ret = cmis_memory_map_init_pages(ctx, &map);
|
|
|
1f2507 |
+ if (ret < 0)
|
|
|
1f2507 |
+ return ret;
|
|
|
1f2507 |
cmis_show_all_common(&map);
|
|
|
1f2507 |
+
|
|
|
1f2507 |
+ return 0;
|
|
|
1f2507 |
}
|
|
|
1f2507 |
diff --git a/cmis.h b/cmis.h
|
|
|
1f2507 |
index c878e3bc5afd..911491dc5c8f 100644
|
|
|
1f2507 |
--- a/cmis.h
|
|
|
1f2507 |
+++ b/cmis.h
|
|
|
1f2507 |
@@ -123,7 +123,6 @@
|
|
|
1f2507 |
|
|
|
1f2507 |
void cmis_show_all_ioctl(const __u8 *id);
|
|
|
1f2507 |
|
|
|
1f2507 |
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
|
|
1f2507 |
- const struct ethtool_module_eeprom *page_one);
|
|
|
1f2507 |
+int cmis_show_all_nl(struct cmd_context *ctx);
|
|
|
1f2507 |
|
|
|
1f2507 |
#endif /* CMIS_H__ */
|
|
|
1f2507 |
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
|
|
1f2507 |
index ee5508840157..a8e2662e0b8c 100644
|
|
|
1f2507 |
--- a/netlink/module-eeprom.c
|
|
|
1f2507 |
+++ b/netlink/module-eeprom.c
|
|
|
1f2507 |
@@ -314,11 +314,10 @@ static int decoder_prefetch(struct nl_context *nlctx)
|
|
|
1f2507 |
return page_fetch(nlctx, &request);
|
|
|
1f2507 |
}
|
|
|
1f2507 |
|
|
|
1f2507 |
-static void decoder_print(void)
|
|
|
1f2507 |
+static void decoder_print(struct cmd_context *ctx)
|
|
|
1f2507 |
{
|
|
|
1f2507 |
struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
|
|
|
1f2507 |
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
|
|
1f2507 |
- struct ethtool_module_eeprom *page_one = cache_get(1, 0, ETH_I2C_ADDRESS_LOW);
|
|
|
1f2507 |
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
|
|
1f2507 |
|
|
|
1f2507 |
switch (module_id) {
|
|
|
1f2507 |
@@ -332,7 +331,7 @@ static void decoder_print(void)
|
|
|
1f2507 |
break;
|
|
|
1f2507 |
case SFF8024_ID_QSFP_DD:
|
|
|
1f2507 |
case SFF8024_ID_DSFP:
|
|
|
1f2507 |
- cmis_show_all_nl(page_zero, page_one);
|
|
|
1f2507 |
+ cmis_show_all_nl(ctx);
|
|
|
1f2507 |
break;
|
|
|
1f2507 |
default:
|
|
|
1f2507 |
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
|
|
1f2507 |
@@ -524,7 +523,7 @@ int nl_getmodule(struct cmd_context *ctx)
|
|
|
1f2507 |
ret = decoder_prefetch(nlctx);
|
|
|
1f2507 |
if (ret)
|
|
|
1f2507 |
goto cleanup;
|
|
|
1f2507 |
- decoder_print();
|
|
|
1f2507 |
+ decoder_print(ctx);
|
|
|
1f2507 |
#endif
|
|
|
1f2507 |
}
|
|
|
1f2507 |
|
|
|
1f2507 |
--
|
|
|
1f2507 |
2.35.1
|
|
|
1f2507 |
|