aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@nvidia.com>2021-11-23 19:40:58 +0200
committerMichal Kubecek <mkubecek@suse.cz>2021-12-02 21:53:05 +0100
commit27b42a92286b62491a7e023823c27662f463b8e6 (patch)
tree833a18395d76e2b701a4cce72fa3822acaac7d14
parent8658852e0ef7558ca39d2016948207c54d26318c (diff)
downloadethtool-27b42a92286b62491a7e023823c27662f463b8e6.tar.gz
cmis: Initialize Banked Page 11h in memory map
Banked Page 11h stores, among other things, lane-specific flags and monitors that are going to be parsed and displayed in subsequent patches. Request it via the 'MODULE_EEPROM_GET' netlink message and initialize it in the memory map. Only initialize it in supported Banks. Signed-off-by: Ido Schimmel <idosch@nvidia.com>
-rw-r--r--cmis.c49
-rw-r--r--cmis.h7
2 files changed, 54 insertions, 2 deletions
diff --git a/cmis.c b/cmis.c
index 55b9d1b..83ced4d 100644
--- a/cmis.c
+++ b/cmis.c
@@ -15,9 +15,17 @@
#include "cmis.h"
#include "netlink/extapi.h"
+/* The maximum number of supported Banks. Relevant documents:
+ * [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
+ */
+#define CMIS_MAX_BANKS 4
+
+/* We are not parsing further than Page 11h. */
+#define CMIS_MAX_PAGES 18
+
struct cmis_memory_map {
const __u8 *lower_memory;
- const __u8 *upper_memory[1][3]; /* Bank, Page */
+ const __u8 *upper_memory[CMIS_MAX_BANKS][CMIS_MAX_PAGES];
#define page_00h upper_memory[0x0][0x0]
#define page_01h upper_memory[0x0][0x1]
#define page_02h upper_memory[0x0][0x2]
@@ -399,12 +407,33 @@ static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
request->data = NULL;
}
+static int cmis_num_banks_get(const struct cmis_memory_map *map,
+ int *p_num_banks)
+{
+ switch (map->page_01h[CMIS_PAGES_ADVER_OFFSET] &
+ CMIS_BANKS_SUPPORTED_MASK) {
+ case CMIS_BANK_0_SUPPORTED:
+ *p_num_banks = 1;
+ break;
+ case CMIS_BANK_0_1_SUPPORTED:
+ *p_num_banks = 2;
+ break;
+ case CMIS_BANK_0_3_SUPPORTED:
+ *p_num_banks = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int
cmis_memory_map_init_pages(struct cmd_context *ctx,
struct cmis_memory_map *map)
{
struct ethtool_module_eeprom request;
- int ret;
+ int num_banks, i, ret;
/* Lower Memory and Page 00h are always present.
*
@@ -443,6 +472,22 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
return ret;
map->page_02h = request.data - CMIS_PAGE_SIZE;
+ /* Bank 0 of Page 11h provides lane-specific registers for the first 8
+ * lanes, and each additional Banks provides support for an additional
+ * 8 lanes. Only initialize supported Banks.
+ */
+ ret = cmis_num_banks_get(map, &num_banks);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < num_banks; i++) {
+ cmis_request_init(&request, i, 0x11, CMIS_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->upper_memory[i][0x11] = request.data - CMIS_PAGE_SIZE;
+ }
+
return 0;
}
diff --git a/cmis.h b/cmis.h
index 911491d..8d90a04 100644
--- a/cmis.h
+++ b/cmis.h
@@ -114,6 +114,13 @@
#define CMIS_WAVELENGTH_TOL_MSB 0x8C
#define CMIS_WAVELENGTH_TOL_LSB 0x8D
+/* Supported Pages Advertising (Page 1) */
+#define CMIS_PAGES_ADVER_OFFSET 0x8E
+#define CMIS_BANKS_SUPPORTED_MASK 0x03
+#define CMIS_BANK_0_SUPPORTED 0x00
+#define CMIS_BANK_0_1_SUPPORTED 0x01
+#define CMIS_BANK_0_3_SUPPORTED 0x02
+
/* Signal integrity controls */
#define CMIS_SIG_INTEG_TX_OFFSET 0xA1
#define CMIS_SIG_INTEG_RX_OFFSET 0xA2