|
|
2a1b01 |
From fdae2732b25090f9d41e192a5dd47a45a6516a94 Mon Sep 17 00:00:00 2001
|
|
|
2a1b01 |
From: Ido Schimmel <idosch@nvidia.com>
|
|
|
2a1b01 |
Date: Tue, 12 Oct 2021 16:25:23 +0300
|
|
|
2a1b01 |
Subject: [PATCH 24/35] sff-8636: Request specific pages for parsing in netlink
|
|
|
2a1b01 |
path
|
|
|
2a1b01 |
|
|
|
2a1b01 |
In the netlink path, unlike the IOCTL path, user space requests specific
|
|
|
2a1b01 |
EEPROM pages from the kernel. The presence of optional pages is
|
|
|
2a1b01 |
advertised via various bits in the EEPROM contents.
|
|
|
2a1b01 |
|
|
|
2a1b01 |
Currently, for SFF-8636, the Lower Memory, Page 00h and the optional
|
|
|
2a1b01 |
Page 03h are requested by the netlink code (i.e.,
|
|
|
2a1b01 |
netlink/module-eeprom.c) and passed to the SFF-8636 code (i.e., qsfp.c)
|
|
|
2a1b01 |
as two arguments for parsing.
|
|
|
2a1b01 |
|
|
|
2a1b01 |
This is problematic for several reasons. First, this approach is not
|
|
|
2a1b01 |
very scaleable as SFF-8636 supports a lot of optional pages. Passing
|
|
|
2a1b01 |
them as separate arguments to the SFF-8636 code is not going to work.
|
|
|
2a1b01 |
|
|
|
2a1b01 |
Second, the knowledge of which optional pages are available is
|
|
|
2a1b01 |
encapsulated in the SFF-8636 parsing code. As such, the common netlink
|
|
|
2a1b01 |
code has no business of fetching optional pages that might be invalid.
|
|
|
2a1b01 |
|
|
|
2a1b01 |
Instead, pass the command context to the SFF-8636 parsing function and
|
|
|
2a1b01 |
allow it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
|
|
|
2a1b01 |
message.
|
|
|
2a1b01 |
|
|
|
2a1b01 |
Tested by making sure that the output of 'ethtool -m' does not change
|
|
|
2a1b01 |
before and after the patch.
|
|
|
2a1b01 |
|
|
|
2a1b01 |
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
|
|
2a1b01 |
---
|
|
|
2a1b01 |
internal.h | 3 +--
|
|
|
2a1b01 |
netlink/module-eeprom.c | 3 +--
|
|
|
2a1b01 |
qsfp.c | 60 ++++++++++++++++++++++++++++++++---------
|
|
|
2a1b01 |
3 files changed, 49 insertions(+), 17 deletions(-)
|
|
|
2a1b01 |
|
|
|
2a1b01 |
diff --git a/internal.h b/internal.h
|
|
|
2a1b01 |
index a77efd385698..2407d3c223fa 100644
|
|
|
2a1b01 |
--- a/internal.h
|
|
|
2a1b01 |
+++ b/internal.h
|
|
|
2a1b01 |
@@ -392,8 +392,7 @@ void sff8472_show_all(const __u8 *id);
|
|
|
2a1b01 |
|
|
|
2a1b01 |
/* QSFP Optics diagnostics */
|
|
|
2a1b01 |
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
|
|
|
2a1b01 |
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
|
|
2a1b01 |
- const struct ethtool_module_eeprom *page_three);
|
|
|
2a1b01 |
+int sff8636_show_all_nl(struct cmd_context *ctx);
|
|
|
2a1b01 |
|
|
|
2a1b01 |
/* FUJITSU Extended Socket network device */
|
|
|
2a1b01 |
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
|
|
|
2a1b01 |
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
|
|
2a1b01 |
index a8e2662e0b8c..f04f8e134223 100644
|
|
|
2a1b01 |
--- a/netlink/module-eeprom.c
|
|
|
2a1b01 |
+++ b/netlink/module-eeprom.c
|
|
|
2a1b01 |
@@ -316,7 +316,6 @@ static int decoder_prefetch(struct nl_context *nlctx)
|
|
|
2a1b01 |
|
|
|
2a1b01 |
static void decoder_print(struct cmd_context *ctx)
|
|
|
2a1b01 |
{
|
|
|
2a1b01 |
- struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
|
|
|
2a1b01 |
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
|
|
2a1b01 |
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
|
|
2a1b01 |
|
|
|
2a1b01 |
@@ -327,7 +326,7 @@ static void decoder_print(struct cmd_context *ctx)
|
|
|
2a1b01 |
case SFF8024_ID_QSFP:
|
|
|
2a1b01 |
case SFF8024_ID_QSFP28:
|
|
|
2a1b01 |
case SFF8024_ID_QSFP_PLUS:
|
|
|
2a1b01 |
- sff8636_show_all_nl(page_zero, page_three);
|
|
|
2a1b01 |
+ sff8636_show_all_nl(ctx);
|
|
|
2a1b01 |
break;
|
|
|
2a1b01 |
case SFF8024_ID_QSFP_DD:
|
|
|
2a1b01 |
case SFF8024_ID_DSFP:
|
|
|
2a1b01 |
diff --git a/qsfp.c b/qsfp.c
|
|
|
2a1b01 |
index 4aa49351e6b7..e7c2f51cd9c6 100644
|
|
|
2a1b01 |
--- a/qsfp.c
|
|
|
2a1b01 |
+++ b/qsfp.c
|
|
|
2a1b01 |
@@ -55,10 +55,12 @@
|
|
|
2a1b01 |
**/
|
|
|
2a1b01 |
#include <stdio.h>
|
|
|
2a1b01 |
#include <math.h>
|
|
|
2a1b01 |
+#include <errno.h>
|
|
|
2a1b01 |
#include "internal.h"
|
|
|
2a1b01 |
#include "sff-common.h"
|
|
|
2a1b01 |
#include "qsfp.h"
|
|
|
2a1b01 |
#include "cmis.h"
|
|
|
2a1b01 |
+#include "netlink/extapi.h"
|
|
|
2a1b01 |
|
|
|
2a1b01 |
struct sff8636_memory_map {
|
|
|
2a1b01 |
const __u8 *lower_memory;
|
|
|
2a1b01 |
@@ -68,6 +70,7 @@ struct sff8636_memory_map {
|
|
|
2a1b01 |
};
|
|
|
2a1b01 |
|
|
|
2a1b01 |
#define SFF8636_PAGE_SIZE 0x80
|
|
|
2a1b01 |
+#define SFF8636_I2C_ADDRESS 0x50
|
|
|
2a1b01 |
|
|
|
2a1b01 |
#define MAX_DESC_SIZE 42
|
|
|
2a1b01 |
|
|
|
2a1b01 |
@@ -947,36 +950,67 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
|
|
2a1b01 |
sff8636_show_all_common(&map);
|
|
|
2a1b01 |
}
|
|
|
2a1b01 |
|
|
|
2a1b01 |
-static void
|
|
|
2a1b01 |
-sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
|
|
|
2a1b01 |
- const struct ethtool_module_eeprom *page_zero,
|
|
|
2a1b01 |
- const struct ethtool_module_eeprom *page_three)
|
|
|
2a1b01 |
+static void sff8636_request_init(struct ethtool_module_eeprom *request, u8 page,
|
|
|
2a1b01 |
+ u32 offset)
|
|
|
2a1b01 |
+{
|
|
|
2a1b01 |
+ request->offset = offset;
|
|
|
2a1b01 |
+ request->length = SFF8636_PAGE_SIZE;
|
|
|
2a1b01 |
+ request->page = page;
|
|
|
2a1b01 |
+ request->bank = 0;
|
|
|
2a1b01 |
+ request->i2c_address = SFF8636_I2C_ADDRESS;
|
|
|
2a1b01 |
+ request->data = NULL;
|
|
|
2a1b01 |
+}
|
|
|
2a1b01 |
+
|
|
|
2a1b01 |
+static int
|
|
|
2a1b01 |
+sff8636_memory_map_init_pages(struct cmd_context *ctx,
|
|
|
2a1b01 |
+ struct sff8636_memory_map *map)
|
|
|
2a1b01 |
{
|
|
|
2a1b01 |
+ struct ethtool_module_eeprom request;
|
|
|
2a1b01 |
+ int ret;
|
|
|
2a1b01 |
+
|
|
|
2a1b01 |
/* Lower Memory and Page 00h are always present.
|
|
|
2a1b01 |
*
|
|
|
2a1b01 |
* Offset into Upper Memory is between page size and twice the page
|
|
|
2a1b01 |
* size. Therefore, set the base address of each page to its base
|
|
|
2a1b01 |
- * address minus page size. For Page 00h, this is the address of the
|
|
|
2a1b01 |
- * Lower Memory.
|
|
|
2a1b01 |
+ * address minus page size.
|
|
|
2a1b01 |
*/
|
|
|
2a1b01 |
- map->lower_memory = page_zero->data;
|
|
|
2a1b01 |
- map->page_00h = page_zero->data;
|
|
|
2a1b01 |
+ sff8636_request_init(&request, 0x0, 0);
|
|
|
2a1b01 |
+ ret = nl_get_eeprom_page(ctx, &request);
|
|
|
2a1b01 |
+ if (ret < 0)
|
|
|
2a1b01 |
+ return ret;
|
|
|
2a1b01 |
+ map->lower_memory = request.data;
|
|
|
2a1b01 |
+
|
|
|
2a1b01 |
+ sff8636_request_init(&request, 0x0, SFF8636_PAGE_SIZE);
|
|
|
2a1b01 |
+ ret = nl_get_eeprom_page(ctx, &request);
|
|
|
2a1b01 |
+ if (ret < 0)
|
|
|
2a1b01 |
+ return ret;
|
|
|
2a1b01 |
+ map->page_00h = request.data - SFF8636_PAGE_SIZE;
|
|
|
2a1b01 |
|
|
|
2a1b01 |
/* Page 03h is only present when the module memory model is paged and
|
|
|
2a1b01 |
* not flat.
|
|
|
2a1b01 |
*/
|
|
|
2a1b01 |
if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
|
|
2a1b01 |
SFF8636_STATUS_PAGE_3_PRESENT)
|
|
|
2a1b01 |
- return;
|
|
|
2a1b01 |
+ return 0;
|
|
|
2a1b01 |
|
|
|
2a1b01 |
- map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
|
|
|
2a1b01 |
+ sff8636_request_init(&request, 0x3, SFF8636_PAGE_SIZE);
|
|
|
2a1b01 |
+ ret = nl_get_eeprom_page(ctx, &request);
|
|
|
2a1b01 |
+ if (ret < 0)
|
|
|
2a1b01 |
+ return ret;
|
|
|
2a1b01 |
+ map->page_03h = request.data - SFF8636_PAGE_SIZE;
|
|
|
2a1b01 |
+
|
|
|
2a1b01 |
+ return 0;
|
|
|
2a1b01 |
}
|
|
|
2a1b01 |
|
|
|
2a1b01 |
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
|
|
2a1b01 |
- const struct ethtool_module_eeprom *page_three)
|
|
|
2a1b01 |
+int sff8636_show_all_nl(struct cmd_context *ctx)
|
|
|
2a1b01 |
{
|
|
|
2a1b01 |
struct sff8636_memory_map map = {};
|
|
|
2a1b01 |
+ int ret;
|
|
|
2a1b01 |
|
|
|
2a1b01 |
- sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
|
|
2a1b01 |
+ ret = sff8636_memory_map_init_pages(ctx, &map);
|
|
|
2a1b01 |
+ if (ret < 0)
|
|
|
2a1b01 |
+ return ret;
|
|
|
2a1b01 |
sff8636_show_all_common(&map);
|
|
|
2a1b01 |
+
|
|
|
2a1b01 |
+ return 0;
|
|
|
2a1b01 |
}
|
|
|
2a1b01 |
--
|
|
|
2a1b01 |
2.35.1
|
|
|
2a1b01 |
|