!37 ethtool: backport some patches to support more CMIS transceiver modules
From: @chen-hao418 Reviewed-by: @wangboe2022, @robertxw Signed-off-by: @robertxw
This commit is contained in:
commit
d66fcaff03
@ -1,7 +1,7 @@
|
||||
From 6428870f54e7107c2f37202f14818ebab0112e5f Mon Sep 17 00:00:00 2001
|
||||
From 17afa43fa85e03ebe3b9a4e82f5e18a6cfbef082 Mon Sep 17 00:00:00 2001
|
||||
From: Jie Wang <wangjie125@huawei.com>
|
||||
Date: Fri, 29 Apr 2022 17:17:03 +0800
|
||||
Subject: update UAPI header copies
|
||||
Subject: [PATCH] update UAPI header copies
|
||||
|
||||
Update to kernel commit cc4bdef26ecd.
|
||||
|
||||
@ -9,20 +9,20 @@ commit: bd138ee
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=bd138ee083c4
|
||||
change log: Some macros for rx buf len in other patch. To avoid add
|
||||
unnecrssary content, add like "ETHTOOL_TX_COPYBREAK_BUF_SIZE"
|
||||
"ETHTOOL_A_RINGS_RX_BUF_LEN" "IFLA_BOND_MISSED_MAX" in this patch
|
||||
"ETHTOOL_A_RINGS_RX_BUF_LEN" "IFLA_BOND_MISSED_MAX" and merger
|
||||
commit 1c5526968e27 in this patch.
|
||||
|
||||
Signed-off-by: Jie Wang <wangjie125@huawei.com>
|
||||
---
|
||||
uapi/linux/ethtool.h | 1 +
|
||||
uapi/linux/ethtool_netlink.h | 10 ++++
|
||||
uapi/linux/ethtool.h | 30 +++++++++++
|
||||
uapi/linux/ethtool_netlink.h | 31 +++++++++++-
|
||||
uapi/linux/if_link.h | 98 ++++++++++++++++++++++++++++++++++++
|
||||
uapi/linux/net_tstamp.h | 17 ++++++-
|
||||
uapi/linux/netlink.h | 1 +
|
||||
uapi/linux/rtnetlink.h | 16 ++++++
|
||||
6 files changed, 142 insertions(+), 1 deletion(-)
|
||||
5 files changed, 175 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h
|
||||
index a7f549a..4a36287 100644
|
||||
index a7f549a..85548f9 100644
|
||||
--- a/uapi/linux/ethtool.h
|
||||
+++ b/uapi/linux/ethtool.h
|
||||
@@ -229,6 +229,7 @@ enum tunable_id {
|
||||
@ -33,11 +33,79 @@ index a7f549a..4a36287 100644
|
||||
/*
|
||||
* Add your fresh new tunable attribute above and remember to update
|
||||
* tunable_strings[] in net/ethtool/common.c
|
||||
@@ -601,6 +602,7 @@ enum ethtool_link_ext_state {
|
||||
ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE,
|
||||
ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED,
|
||||
ETHTOOL_LINK_EXT_STATE_OVERHEAT,
|
||||
+ ETHTOOL_LINK_EXT_STATE_MODULE,
|
||||
};
|
||||
|
||||
/* More information in addition to ETHTOOL_LINK_EXT_STATE_AUTONEG. */
|
||||
@@ -647,6 +649,11 @@ enum ethtool_link_ext_substate_cable_issue {
|
||||
ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE,
|
||||
};
|
||||
|
||||
+/* More information in addition to ETHTOOL_LINK_EXT_STATE_MODULE. */
|
||||
+enum ethtool_link_ext_substate_module {
|
||||
+ ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY = 1,
|
||||
+};
|
||||
+
|
||||
#define ETH_GSTRING_LEN 32
|
||||
|
||||
/**
|
||||
@@ -704,6 +711,29 @@ enum ethtool_stringset {
|
||||
ETH_SS_COUNT
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * enum ethtool_module_power_mode_policy - plug-in module power mode policy
|
||||
+ * @ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH: Module is always in high power mode.
|
||||
+ * @ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO: Module is transitioned by the host
|
||||
+ * to high power mode when the first port using it is put administratively
|
||||
+ * up and to low power mode when the last port using it is put
|
||||
+ * administratively down.
|
||||
+ */
|
||||
+enum ethtool_module_power_mode_policy {
|
||||
+ ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH = 1,
|
||||
+ ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum ethtool_module_power_mode - plug-in module power mode
|
||||
+ * @ETHTOOL_MODULE_POWER_MODE_LOW: Module is in low power mode.
|
||||
+ * @ETHTOOL_MODULE_POWER_MODE_HIGH: Module is in high power mode.
|
||||
+ */
|
||||
+enum ethtool_module_power_mode {
|
||||
+ ETHTOOL_MODULE_POWER_MODE_LOW = 1,
|
||||
+ ETHTOOL_MODULE_POWER_MODE_HIGH,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct ethtool_gstrings - string set for data tagging
|
||||
* @cmd: Command number = %ETHTOOL_GSTRINGS
|
||||
diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h
|
||||
index 5665d64..aaadce7 100644
|
||||
index 5665d64..378ad7d 100644
|
||||
--- a/uapi/linux/ethtool_netlink.h
|
||||
+++ b/uapi/linux/ethtool_netlink.h
|
||||
@@ -314,6 +314,12 @@ enum {
|
||||
@@ -47,6 +47,8 @@ enum {
|
||||
ETHTOOL_MSG_MODULE_EEPROM_GET,
|
||||
ETHTOOL_MSG_STATS_GET,
|
||||
ETHTOOL_MSG_PHC_VCLOCKS_GET,
|
||||
+ ETHTOOL_MSG_MODULE_GET,
|
||||
+ ETHTOOL_MSG_MODULE_SET,
|
||||
|
||||
/* add new constants above here */
|
||||
__ETHTOOL_MSG_USER_CNT,
|
||||
@@ -90,6 +92,8 @@ enum {
|
||||
ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY,
|
||||
ETHTOOL_MSG_STATS_GET_REPLY,
|
||||
ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY,
|
||||
+ ETHTOOL_MSG_MODULE_GET_REPLY,
|
||||
+ ETHTOOL_MSG_MODULE_NTF,
|
||||
|
||||
/* add new constants above here */
|
||||
__ETHTOOL_MSG_KERNEL_CNT,
|
||||
@@ -314,6 +318,12 @@ enum {
|
||||
|
||||
/* RINGS */
|
||||
|
||||
@ -50,17 +118,48 @@ index 5665d64..aaadce7 100644
|
||||
enum {
|
||||
ETHTOOL_A_RINGS_UNSPEC,
|
||||
ETHTOOL_A_RINGS_HEADER, /* nest - _A_HEADER_* */
|
||||
@@ -325,6 +331,10 @@ enum {
|
||||
@@ -325,6 +335,10 @@ enum {
|
||||
ETHTOOL_A_RINGS_RX_MINI, /* u32 */
|
||||
ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */
|
||||
ETHTOOL_A_RINGS_TX, /* u32 */
|
||||
+ ETHTOOL_A_RINGS_RX_BUF_LEN, /* u32 */
|
||||
+ ETHTOOL_A_RINGS_TCP_DATA_SPLIT, /* u8 */
|
||||
+ ETHTOOL_A_RINGS_RX_BUF_LEN, /* u32 */
|
||||
+ ETHTOOL_A_RINGS_TCP_DATA_SPLIT, /* u8 */
|
||||
+ ETHTOOL_A_RINGS_CQE_SIZE, /* u32 */
|
||||
+ ETHTOOL_A_RINGS_TX_PUSH, /* u8 */
|
||||
+ ETHTOOL_A_RINGS_TX_PUSH, /* u8 */
|
||||
|
||||
/* add new constants above here */
|
||||
__ETHTOOL_A_RINGS_CNT,
|
||||
@@ -407,7 +421,9 @@ enum {
|
||||
ETHTOOL_A_PAUSE_STAT_TX_FRAMES,
|
||||
ETHTOOL_A_PAUSE_STAT_RX_FRAMES,
|
||||
|
||||
- /* add new constants above here */
|
||||
+ /* add new constants above here
|
||||
+ * adjust ETHTOOL_PAUSE_STAT_CNT if adding non-stats!
|
||||
+ */
|
||||
__ETHTOOL_A_PAUSE_STAT_CNT,
|
||||
ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1)
|
||||
};
|
||||
@@ -833,6 +849,19 @@ enum {
|
||||
ETHTOOL_A_STATS_RMON_MAX = (__ETHTOOL_A_STATS_RMON_CNT - 1)
|
||||
};
|
||||
|
||||
+/* MODULE */
|
||||
+
|
||||
+enum {
|
||||
+ ETHTOOL_A_MODULE_UNSPEC,
|
||||
+ ETHTOOL_A_MODULE_HEADER, /* nest - _A_HEADER_* */
|
||||
+ ETHTOOL_A_MODULE_POWER_MODE_POLICY, /* u8 */
|
||||
+ ETHTOOL_A_MODULE_POWER_MODE, /* u8 */
|
||||
+
|
||||
+ /* add new constants above here */
|
||||
+ __ETHTOOL_A_MODULE_CNT,
|
||||
+ ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1)
|
||||
+};
|
||||
+
|
||||
/* generic netlink info */
|
||||
#define ETHTOOL_GENL_NAME "ethtool"
|
||||
#define ETHTOOL_GENL_VERSION 1
|
||||
diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h
|
||||
index 1d4ed60..34002e7 100644
|
||||
--- a/uapi/linux/if_link.h
|
||||
@ -245,41 +344,6 @@ index 1d4ed60..34002e7 100644
|
||||
/* XDP section */
|
||||
|
||||
#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
|
||||
diff --git a/uapi/linux/net_tstamp.h b/uapi/linux/net_tstamp.h
|
||||
index fcc61c7..55501e5 100644
|
||||
--- a/uapi/linux/net_tstamp.h
|
||||
+++ b/uapi/linux/net_tstamp.h
|
||||
@@ -62,7 +62,7 @@ struct so_timestamping {
|
||||
/**
|
||||
* struct hwtstamp_config - %SIOCGHWTSTAMP and %SIOCSHWTSTAMP parameter
|
||||
*
|
||||
- * @flags: no flags defined right now, must be zero for %SIOCSHWTSTAMP
|
||||
+ * @flags: one of HWTSTAMP_FLAG_*
|
||||
* @tx_type: one of HWTSTAMP_TX_*
|
||||
* @rx_filter: one of HWTSTAMP_FILTER_*
|
||||
*
|
||||
@@ -78,6 +78,21 @@ struct hwtstamp_config {
|
||||
int rx_filter;
|
||||
};
|
||||
|
||||
+/* possible values for hwtstamp_config->flags */
|
||||
+enum hwtstamp_flags {
|
||||
+ /*
|
||||
+ * With this flag, the user could get bond active interface's
|
||||
+ * PHC index. Note this PHC index is not stable as when there
|
||||
+ * is a failover, the bond active interface will be changed, so
|
||||
+ * will be the PHC index.
|
||||
+ */
|
||||
+ HWTSTAMP_FLAG_BONDED_PHC_INDEX = (1<<0),
|
||||
+#define HWTSTAMP_FLAG_BONDED_PHC_INDEX HWTSTAMP_FLAG_BONDED_PHC_INDEX
|
||||
+
|
||||
+ HWTSTAMP_FLAG_LAST = HWTSTAMP_FLAG_BONDED_PHC_INDEX,
|
||||
+ HWTSTAMP_FLAG_MASK = (HWTSTAMP_FLAG_LAST - 1) | HWTSTAMP_FLAG_LAST
|
||||
+};
|
||||
+
|
||||
/* possible values for hwtstamp_config->tx_type */
|
||||
enum hwtstamp_tx_types {
|
||||
/*
|
||||
diff --git a/uapi/linux/netlink.h b/uapi/linux/netlink.h
|
||||
index e83e2e3..105b79f 100644
|
||||
--- a/uapi/linux/netlink.h
|
||||
@ -341,5 +405,5 @@ index e01efa2..8f874be 100644
|
||||
/* End of information exported to user level */
|
||||
|
||||
--
|
||||
2.33.0
|
||||
2.30.0
|
||||
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From 98d2c71b11a0ffb72f56da6bccb7d274e00d96f5 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:15 +0300
|
||||
Subject: [PATCH 10/26] cmis: Consolidate code between IOCTL and netlink paths
|
||||
|
||||
Now that both the netlink and IOCTL paths use the same memory map
|
||||
structure for parsing, the code can be easily consolidated.
|
||||
|
||||
commit: 6acaeb9
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=6acaeb94402a
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 38 ++++++++++++++++----------------------
|
||||
1 file changed, 16 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 2e01446..eb7791d 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -340,6 +340,20 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
|
||||
CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
}
|
||||
|
||||
+static void cmis_show_all_common(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ cmis_show_identifier(map);
|
||||
+ cmis_show_power_info(map);
|
||||
+ cmis_show_connector(map);
|
||||
+ cmis_show_cbl_asm_len(map);
|
||||
+ cmis_show_sig_integrity(map);
|
||||
+ cmis_show_mit_compliance(map);
|
||||
+ cmis_show_mod_lvl_monitors(map);
|
||||
+ cmis_show_link_len(map);
|
||||
+ cmis_show_vendor_info(map);
|
||||
+ cmis_show_rev_compliance(map);
|
||||
+}
|
||||
+
|
||||
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
|
||||
const __u8 *id)
|
||||
{
|
||||
@@ -367,17 +381,7 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
struct cmis_memory_map map = {};
|
||||
|
||||
cmis_memory_map_init_buf(&map, id);
|
||||
-
|
||||
- cmis_show_identifier(&map);
|
||||
- cmis_show_power_info(&map);
|
||||
- cmis_show_connector(&map);
|
||||
- cmis_show_cbl_asm_len(&map);
|
||||
- cmis_show_sig_integrity(&map);
|
||||
- cmis_show_mit_compliance(&map);
|
||||
- cmis_show_mod_lvl_monitors(&map);
|
||||
- cmis_show_link_len(&map);
|
||||
- cmis_show_vendor_info(&map);
|
||||
- cmis_show_rev_compliance(&map);
|
||||
+ cmis_show_all_common(&map);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -411,15 +415,5 @@ void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
struct cmis_memory_map map = {};
|
||||
|
||||
cmis_memory_map_init_pages(&map, page_zero, page_one);
|
||||
-
|
||||
- cmis_show_identifier(&map);
|
||||
- cmis_show_power_info(&map);
|
||||
- cmis_show_connector(&map);
|
||||
- cmis_show_cbl_asm_len(&map);
|
||||
- cmis_show_sig_integrity(&map);
|
||||
- cmis_show_mit_compliance(&map);
|
||||
- cmis_show_mod_lvl_monitors(&map);
|
||||
- cmis_show_link_len(&map);
|
||||
- cmis_show_vendor_info(&map);
|
||||
- cmis_show_rev_compliance(&map);
|
||||
+ cmis_show_all_common(&map);
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
148
backport-cmis-Initialize-CMIS-memory-map.patch
Normal file
148
backport-cmis-Initialize-CMIS-memory-map.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From 9cfd4eac291dfa43e63ea01309a3a0d400b3286a Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:13 +0300
|
||||
Subject: [PATCH 08/26] cmis: Initialize CMIS memory map
|
||||
|
||||
The CMIS memory map [1] consists of Lower Memory and Upper Memory.
|
||||
|
||||
The content of the Lower Memory is fixed and can be addressed using an
|
||||
offset between 0 and 127 (inclusive).
|
||||
|
||||
The Upper Memory is variable and optional and can be addressed by
|
||||
specifying a bank number, a page number and an offset between 128 and
|
||||
255 (inclusive).
|
||||
|
||||
Create a structure describing this memory map and initialize it with
|
||||
pointers to available pages.
|
||||
|
||||
In the IOCTL path, the structure holds pointers to regions of the
|
||||
continuous buffer passed to user space via the 'ETHTOOL_GMODULEEEPROM'
|
||||
command.
|
||||
|
||||
In the netlink path, the structure holds pointers to individual pages
|
||||
passed to user space via the 'MODULE_EEPROM_GET' message.
|
||||
|
||||
This structure will later allow us to consolidate the IOCTL and netlink
|
||||
parsing code paths and also easily support additional EEPROM pages.
|
||||
|
||||
[1] CMIS Rev. 5, pag. 97, section 8.1.1, Figure 8-1
|
||||
|
||||
commit: 369b43a
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=369b43a1a066
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
cmis.h | 2 ++
|
||||
2 files changed, 65 insertions(+)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 68c5b2d..8a67884 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -13,6 +13,15 @@
|
||||
#include "sff-common.h"
|
||||
#include "cmis.h"
|
||||
|
||||
+struct cmis_memory_map {
|
||||
+ const __u8 *lower_memory;
|
||||
+ const __u8 *upper_memory[1][2]; /* Bank, Page */
|
||||
+#define page_00h upper_memory[0x0][0x0]
|
||||
+#define page_01h upper_memory[0x0][0x1]
|
||||
+};
|
||||
+
|
||||
+#define CMIS_PAGE_SIZE 0x80
|
||||
+
|
||||
static void cmis_show_identifier(const __u8 *id)
|
||||
{
|
||||
sff8024_show_identifier(id, CMIS_ID_OFFSET);
|
||||
@@ -326,8 +335,34 @@ static void cmis_show_vendor_info(const __u8 *id)
|
||||
"CLEI code");
|
||||
}
|
||||
|
||||
+static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
|
||||
+ const __u8 *id)
|
||||
+{
|
||||
+ /* Lower Memory and Page 00h are always present.
|
||||
+ *
|
||||
+ * Offset into Upper Memory is between page size and twice the page
|
||||
+ * size. Therefore, set the base address of each page to base address
|
||||
+ * plus page size multiplied by the page number.
|
||||
+ */
|
||||
+ map->lower_memory = id;
|
||||
+ map->page_00h = id;
|
||||
+
|
||||
+ /* Page 01h is only present when the module memory model is paged and
|
||||
+ * not flat.
|
||||
+ */
|
||||
+ if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
|
||||
+ CMIS_MEMORY_MODEL_MASK)
|
||||
+ return;
|
||||
+
|
||||
+ map->page_01h = id + CMIS_PAGE_SIZE;
|
||||
+}
|
||||
+
|
||||
void cmis_show_all_ioctl(const __u8 *id)
|
||||
{
|
||||
+ struct cmis_memory_map map = {};
|
||||
+
|
||||
+ cmis_memory_map_init_buf(&map, id);
|
||||
+
|
||||
cmis_show_identifier(id);
|
||||
cmis_show_power_info(id);
|
||||
cmis_show_connector(id);
|
||||
@@ -340,10 +375,38 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
cmis_show_rev_compliance(id);
|
||||
}
|
||||
|
||||
+static void
|
||||
+cmis_memory_map_init_pages(struct cmis_memory_map *map,
|
||||
+ const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_one)
|
||||
+{
|
||||
+ /* Lower Memory and Page 00h are always present.
|
||||
+ *
|
||||
+ * Offset into Upper Memory is between page size and twice the page
|
||||
+ * size. Therefore, set the base address of each page to its base
|
||||
+ * address minus page size. For Page 00h, this is the address of the
|
||||
+ * Lower Memory.
|
||||
+ */
|
||||
+ map->lower_memory = page_zero->data;
|
||||
+ map->page_00h = page_zero->data;
|
||||
+
|
||||
+ /* Page 01h is only present when the module memory model is paged and
|
||||
+ * not flat.
|
||||
+ */
|
||||
+ if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
|
||||
+ CMIS_MEMORY_MODEL_MASK)
|
||||
+ return;
|
||||
+
|
||||
+ map->page_01h = page_one->data - CMIS_PAGE_SIZE;
|
||||
+}
|
||||
+
|
||||
void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
const struct ethtool_module_eeprom *page_one)
|
||||
{
|
||||
const __u8 *page_zero_data = page_zero->data;
|
||||
+ struct cmis_memory_map map = {};
|
||||
+
|
||||
+ cmis_memory_map_init_pages(&map, page_zero, page_one);
|
||||
|
||||
cmis_show_identifier(page_zero_data);
|
||||
cmis_show_power_info(page_zero_data);
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 734b90f..53cbb5f 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -4,6 +4,8 @@
|
||||
/* Identifier and revision compliance (Page 0) */
|
||||
#define CMIS_ID_OFFSET 0x00
|
||||
#define CMIS_REV_COMPLIANCE_OFFSET 0x01
|
||||
+#define CMIS_MEMORY_MODEL_OFFSET 0x02
|
||||
+#define CMIS_MEMORY_MODEL_MASK 0x80
|
||||
|
||||
#define CMIS_MODULE_TYPE_OFFSET 0x55
|
||||
#define CMIS_MT_MMF 0x01
|
||||
--
|
||||
2.30.0
|
||||
|
||||
98
backport-cmis-Rename-CMIS-parsing-functions.patch
Normal file
98
backport-cmis-Rename-CMIS-parsing-functions.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From 02055157bf85134de4551e496e3fb39930f68731 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:12 +0300
|
||||
Subject: [PATCH 07/26] cmis: Rename CMIS parsing functions
|
||||
|
||||
Currently, there are two CMIS parsing functions. qsfp_dd_show_all() and
|
||||
cmis_show_all(). The former is called from the IOCTL path with a buffer
|
||||
containing EEPROM contents and the latter is called from the netlink
|
||||
path with pointer to individual EEPROM pages.
|
||||
|
||||
Rename them with '_ioctl' and '_nl' suffixes to make the distinction
|
||||
clear.
|
||||
|
||||
In subsequent patches, these two functions will only differ in the way
|
||||
they initialize the CMIS memory map for parsing, while the parsing code
|
||||
itself will be shared between the two.
|
||||
|
||||
commit: 795f420
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=795f42092f20
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 6 +++---
|
||||
cmis.h | 6 +++---
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
qsfp.c | 2 +-
|
||||
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 591cc72..68c5b2d 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -326,7 +326,7 @@ static void cmis_show_vendor_info(const __u8 *id)
|
||||
"CLEI code");
|
||||
}
|
||||
|
||||
-void qsfp_dd_show_all(const __u8 *id)
|
||||
+void cmis_show_all_ioctl(const __u8 *id)
|
||||
{
|
||||
cmis_show_identifier(id);
|
||||
cmis_show_power_info(id);
|
||||
@@ -340,8 +340,8 @@ void qsfp_dd_show_all(const __u8 *id)
|
||||
cmis_show_rev_compliance(id);
|
||||
}
|
||||
|
||||
-void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one)
|
||||
+void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_one)
|
||||
{
|
||||
const __u8 *page_zero_data = page_zero->data;
|
||||
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index e3012cc..734b90f 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -120,9 +120,9 @@
|
||||
#define YESNO(x) (((x) != 0) ? "Yes" : "No")
|
||||
#define ONOFF(x) (((x) != 0) ? "On" : "Off")
|
||||
|
||||
-void qsfp_dd_show_all(const __u8 *id);
|
||||
+void cmis_show_all_ioctl(const __u8 *id);
|
||||
|
||||
-void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one);
|
||||
+void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_one);
|
||||
|
||||
#endif /* CMIS_H__ */
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 48cd2cc..fc4ef1a 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -332,7 +332,7 @@ static void decoder_print(void)
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
- cmis_show_all(page_zero, page_one);
|
||||
+ cmis_show_all_nl(page_zero, page_one);
|
||||
break;
|
||||
default:
|
||||
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 3f37f10..27fdd3b 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -856,7 +856,7 @@ static void sff8636_show_page_zero(const __u8 *id)
|
||||
void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
- qsfp_dd_show_all(id);
|
||||
+ cmis_show_all_ioctl(id);
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,197 @@
|
||||
From da5cd8deac6cfa6a45840e79a41c800282f043ce Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:22 +0300
|
||||
Subject: [PATCH 17/26] cmis: Request specific pages for parsing in netlink
|
||||
path
|
||||
|
||||
In the netlink path, unlike the IOCTL path, user space requests specific
|
||||
EEPROM pages from the kernel. The presence of optional and banked pages
|
||||
is advertised via various bits in the EEPROM contents.
|
||||
|
||||
Currently, for CMIS, the Lower Memory, Page 00h and the optional Page
|
||||
01h are requested by the netlink code (i.e., netlink/module-eeprom.c)
|
||||
and passed to the CMIS code (i.e., cmis.c) as two arguments for parsing.
|
||||
|
||||
This is problematic for several reasons. First, this approach is not
|
||||
very scaleable as CMIS supports a lot of optional and banked pages.
|
||||
Passing them as separate arguments to the CMIS code is not going to
|
||||
work.
|
||||
|
||||
Second, the knowledge of which optional and banked pages are available
|
||||
is encapsulated in the CMIS parsing code. As such, the common netlink
|
||||
code has no business of fetching optional and banked pages that might be
|
||||
invalid.
|
||||
|
||||
Instead, pass the command context to the CMIS parsing function and allow
|
||||
it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
|
||||
message.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
before and after the patch.
|
||||
|
||||
commit: 86792db
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=86792dbbebf3
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 60 ++++++++++++++++++++++++++++++++---------
|
||||
cmis.h | 3 +--
|
||||
netlink/module-eeprom.c | 7 +++--
|
||||
3 files changed, 51 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index eb7791d..4798fd4 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -9,9 +9,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
+#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "sff-common.h"
|
||||
#include "cmis.h"
|
||||
+#include "netlink/extapi.h"
|
||||
|
||||
struct cmis_memory_map {
|
||||
const __u8 *lower_memory;
|
||||
@@ -21,6 +23,7 @@ struct cmis_memory_map {
|
||||
};
|
||||
|
||||
#define CMIS_PAGE_SIZE 0x80
|
||||
+#define CMIS_I2C_ADDRESS 0x50
|
||||
|
||||
static void cmis_show_identifier(const struct cmis_memory_map *map)
|
||||
{
|
||||
@@ -384,36 +387,67 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
cmis_show_all_common(&map);
|
||||
}
|
||||
|
||||
-static void
|
||||
-cmis_memory_map_init_pages(struct cmis_memory_map *map,
|
||||
- const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one)
|
||||
+static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
|
||||
+ u8 page, u32 offset)
|
||||
{
|
||||
+ request->offset = offset;
|
||||
+ request->length = CMIS_PAGE_SIZE;
|
||||
+ request->page = page;
|
||||
+ request->bank = bank;
|
||||
+ request->i2c_address = CMIS_I2C_ADDRESS;
|
||||
+ request->data = NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+cmis_memory_map_init_pages(struct cmd_context *ctx,
|
||||
+ struct cmis_memory_map *map)
|
||||
+{
|
||||
+ struct ethtool_module_eeprom request;
|
||||
+ int ret;
|
||||
+
|
||||
/* Lower Memory and Page 00h are always present.
|
||||
*
|
||||
* Offset into Upper Memory is between page size and twice the page
|
||||
* size. Therefore, set the base address of each page to its base
|
||||
- * address minus page size. For Page 00h, this is the address of the
|
||||
- * Lower Memory.
|
||||
+ * address minus page size.
|
||||
*/
|
||||
- map->lower_memory = page_zero->data;
|
||||
- map->page_00h = page_zero->data;
|
||||
+ cmis_request_init(&request, 0, 0x0, 0);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->lower_memory = request.data;
|
||||
+
|
||||
+ cmis_request_init(&request, 0, 0x0, CMIS_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_00h = request.data - CMIS_PAGE_SIZE;
|
||||
|
||||
/* Page 01h is only present when the module memory model is paged and
|
||||
* not flat.
|
||||
*/
|
||||
if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
|
||||
CMIS_MEMORY_MODEL_MASK)
|
||||
- return;
|
||||
+ return 0;
|
||||
+
|
||||
+ cmis_request_init(&request, 0, 0x1, CMIS_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_01h = request.data - CMIS_PAGE_SIZE;
|
||||
|
||||
- map->page_01h = page_one->data - CMIS_PAGE_SIZE;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one)
|
||||
+int cmis_show_all_nl(struct cmd_context *ctx)
|
||||
{
|
||||
struct cmis_memory_map map = {};
|
||||
+ int ret;
|
||||
|
||||
- cmis_memory_map_init_pages(&map, page_zero, page_one);
|
||||
+ ret = cmis_memory_map_init_pages(ctx, &map);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
cmis_show_all_common(&map);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index c878e3b..911491d 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -123,7 +123,6 @@
|
||||
|
||||
void cmis_show_all_ioctl(const __u8 *id);
|
||||
|
||||
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one);
|
||||
+int cmis_show_all_nl(struct cmd_context *ctx);
|
||||
|
||||
#endif /* CMIS_H__ */
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index ee55088..a8e2662 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -314,11 +314,10 @@ static int decoder_prefetch(struct nl_context *nlctx)
|
||||
return page_fetch(nlctx, &request);
|
||||
}
|
||||
|
||||
-static void decoder_print(void)
|
||||
+static void decoder_print(struct cmd_context *ctx)
|
||||
{
|
||||
struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
|
||||
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
- struct ethtool_module_eeprom *page_one = cache_get(1, 0, ETH_I2C_ADDRESS_LOW);
|
||||
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
||||
|
||||
switch (module_id) {
|
||||
@@ -332,7 +331,7 @@ static void decoder_print(void)
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
- cmis_show_all_nl(page_zero, page_one);
|
||||
+ cmis_show_all_nl(ctx);
|
||||
break;
|
||||
default:
|
||||
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
||||
@@ -524,7 +523,7 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
ret = decoder_prefetch(nlctx);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
- decoder_print();
|
||||
+ decoder_print(ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
--
|
||||
2.30.0
|
||||
|
||||
397
backport-cmis-Use-memory-map-during-parsing.patch
Normal file
397
backport-cmis-Use-memory-map-during-parsing.patch
Normal file
@ -0,0 +1,397 @@
|
||||
From 7fba1d13bf33839c204fe3ea9d3d8db60e7cda0d Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:14 +0300
|
||||
Subject: [PATCH 09/26] cmis: Use memory map during parsing
|
||||
|
||||
Instead of passing one large buffer to the individual parsing functions,
|
||||
use the memory map structure from the previous patch.
|
||||
|
||||
This has the added benefit of checking which optional pages are actually
|
||||
available and it will also allow us to consolidate the IOCTL and netlink
|
||||
parsing code paths.
|
||||
|
||||
Tested by making sure that the only differences in output in both the
|
||||
IOCTL and netlink paths before and after the patch are in a few
|
||||
registers in Page 01h that were previously parsed from Page 00h.
|
||||
|
||||
commit: da16288
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=da1628840bd6
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 175 +++++++++++++++++++++++++++++----------------------------
|
||||
cmis.h | 1 -
|
||||
2 files changed, 88 insertions(+), 88 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 8a67884..2e01446 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -22,19 +22,19 @@ struct cmis_memory_map {
|
||||
|
||||
#define CMIS_PAGE_SIZE 0x80
|
||||
|
||||
-static void cmis_show_identifier(const __u8 *id)
|
||||
+static void cmis_show_identifier(const struct cmis_memory_map *map)
|
||||
{
|
||||
- sff8024_show_identifier(id, CMIS_ID_OFFSET);
|
||||
+ sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET);
|
||||
}
|
||||
|
||||
-static void cmis_show_connector(const __u8 *id)
|
||||
+static void cmis_show_connector(const struct cmis_memory_map *map)
|
||||
{
|
||||
- sff8024_show_connector(id, CMIS_CTOR_OFFSET);
|
||||
+ sff8024_show_connector(map->page_00h, CMIS_CTOR_OFFSET);
|
||||
}
|
||||
|
||||
-static void cmis_show_oui(const __u8 *id)
|
||||
+static void cmis_show_oui(const struct cmis_memory_map *map)
|
||||
{
|
||||
- sff8024_show_oui(id, CMIS_VENDOR_OUI_OFFSET);
|
||||
+ sff8024_show_oui(map->page_00h, CMIS_VENDOR_OUI_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,9 +42,9 @@ static void cmis_show_oui(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 45, section 1.7.2.1, Table 18
|
||||
* [2] CMIS Rev. 4, pag. 81, section 8.2.1, Table 8-2
|
||||
*/
|
||||
-static void cmis_show_rev_compliance(const __u8 *id)
|
||||
+static void cmis_show_rev_compliance(const struct cmis_memory_map *map)
|
||||
{
|
||||
- __u8 rev = id[CMIS_REV_COMPLIANCE_OFFSET];
|
||||
+ __u8 rev = map->lower_memory[CMIS_REV_COMPLIANCE_OFFSET];
|
||||
int major = (rev >> 4) & 0x0F;
|
||||
int minor = rev & 0x0F;
|
||||
|
||||
@@ -58,17 +58,17 @@ static void cmis_show_rev_compliance(const __u8 *id)
|
||||
* [2] CMIS Rev. 4, pag. 94, section 8.3.9, Table 8-18
|
||||
* [3] QSFP-DD Hardware Rev 5.0, pag. 22, section 4.2.1
|
||||
*/
|
||||
-static void cmis_show_power_info(const __u8 *id)
|
||||
+static void cmis_show_power_info(const struct cmis_memory_map *map)
|
||||
{
|
||||
float max_power = 0.0f;
|
||||
__u8 base_power = 0;
|
||||
__u8 power_class;
|
||||
|
||||
/* Get the power class (first 3 most significat bytes) */
|
||||
- power_class = (id[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
|
||||
+ power_class = (map->page_00h[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
|
||||
|
||||
/* Get the base power in multiples of 0.25W */
|
||||
- base_power = id[CMIS_PWR_MAX_POWER_OFFSET];
|
||||
+ base_power = map->page_00h[CMIS_PWR_MAX_POWER_OFFSET];
|
||||
max_power = base_power * 0.25f;
|
||||
|
||||
printf("\t%-41s : %d\n", "Power class", power_class + 1);
|
||||
@@ -83,20 +83,20 @@ static void cmis_show_power_info(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 59, section 1.7.3.10, Table 31
|
||||
* [2] CMIS Rev. 4, pag. 94, section 8.3.10, Table 8-19
|
||||
*/
|
||||
-static void cmis_show_cbl_asm_len(const __u8 *id)
|
||||
+static void cmis_show_cbl_asm_len(const struct cmis_memory_map *map)
|
||||
{
|
||||
static const char *fn = "Cable assembly length";
|
||||
float mul = 1.0f;
|
||||
float val = 0.0f;
|
||||
|
||||
/* Check if max length */
|
||||
- if (id[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
|
||||
+ if (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
|
||||
printf("\t%-41s : > 6.3km\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the multiplier from the first two bits */
|
||||
- switch (id[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
+ switch (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
case CMIS_MULTIPLIER_00:
|
||||
mul = 0.1f;
|
||||
break;
|
||||
@@ -114,7 +114,7 @@ static void cmis_show_cbl_asm_len(const __u8 *id)
|
||||
}
|
||||
|
||||
/* Get base value from first 6 bits and multiply by mul */
|
||||
- val = (id[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
+ val = (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
val = (float)val * mul;
|
||||
printf("\t%-41s : %0.2fm\n", fn, val);
|
||||
}
|
||||
@@ -126,14 +126,17 @@ static void cmis_show_cbl_asm_len(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 63, section 1.7.4.2, Table 39
|
||||
* [2] CMIS Rev. 4, pag. 99, section 8.4.2, Table 8-27
|
||||
*/
|
||||
-static void cmis_print_smf_cbl_len(const __u8 *id)
|
||||
+static void cmis_print_smf_cbl_len(const struct cmis_memory_map *map)
|
||||
{
|
||||
static const char *fn = "Length (SMF)";
|
||||
float mul = 1.0f;
|
||||
float val = 0.0f;
|
||||
|
||||
+ if (!map->page_01h)
|
||||
+ return;
|
||||
+
|
||||
/* Get the multiplier from the first two bits */
|
||||
- switch (id[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
+ switch (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
case CMIS_MULTIPLIER_00:
|
||||
mul = 0.1f;
|
||||
break;
|
||||
@@ -145,7 +148,7 @@ static void cmis_print_smf_cbl_len(const __u8 *id)
|
||||
}
|
||||
|
||||
/* Get base value from first 6 bits and multiply by mul */
|
||||
- val = (id[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
+ val = (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
val = (float)val * mul;
|
||||
printf("\t%-41s : %0.2fkm\n", fn, val);
|
||||
}
|
||||
@@ -155,21 +158,24 @@ static void cmis_print_smf_cbl_len(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 71, section 1.7.4.10, Table 46
|
||||
* [2] CMIS Rev. 4, pag. 105, section 8.4.10, Table 8-34
|
||||
*/
|
||||
-static void cmis_show_sig_integrity(const __u8 *id)
|
||||
+static void cmis_show_sig_integrity(const struct cmis_memory_map *map)
|
||||
{
|
||||
+ if (!map->page_01h)
|
||||
+ return;
|
||||
+
|
||||
/* CDR Bypass control: 2nd bit from each byte */
|
||||
printf("\t%-41s : ", "Tx CDR bypass control");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
|
||||
|
||||
printf("\t%-41s : ", "Rx CDR bypass control");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
|
||||
|
||||
/* CDR Implementation: 1st bit from each byte */
|
||||
printf("\t%-41s : ", "Tx CDR");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
|
||||
|
||||
printf("\t%-41s : ", "Rx CDR");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,14 +188,14 @@ static void cmis_show_sig_integrity(const __u8 *id)
|
||||
* --> pag. 98, section 8.4, Table 8-25
|
||||
* --> page 100, section 8.4.3, 8.4.4
|
||||
*/
|
||||
-static void cmis_show_mit_compliance(const __u8 *id)
|
||||
+static void cmis_show_mit_compliance(const struct cmis_memory_map *map)
|
||||
{
|
||||
static const char *cc = " (Copper cable,";
|
||||
|
||||
printf("\t%-41s : 0x%02x", "Transmitter technology",
|
||||
- id[CMIS_MEDIA_INTF_TECH_OFFSET]);
|
||||
+ map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]);
|
||||
|
||||
- switch (id[CMIS_MEDIA_INTF_TECH_OFFSET]) {
|
||||
+ switch (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]) {
|
||||
case CMIS_850_VCSEL:
|
||||
printf(" (850 nm VCSEL)\n");
|
||||
break;
|
||||
@@ -240,22 +246,22 @@ static void cmis_show_mit_compliance(const __u8 *id)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (id[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
|
||||
+ if (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 5GHz",
|
||||
- id[CMIS_COPPER_ATT_5GHZ]);
|
||||
+ map->page_00h[CMIS_COPPER_ATT_5GHZ]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 7GHz",
|
||||
- id[CMIS_COPPER_ATT_7GHZ]);
|
||||
+ map->page_00h[CMIS_COPPER_ATT_7GHZ]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
|
||||
- id[CMIS_COPPER_ATT_12P9GHZ]);
|
||||
+ map->page_00h[CMIS_COPPER_ATT_12P9GHZ]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 25.8GHz",
|
||||
- id[CMIS_COPPER_ATT_25P8GHZ]);
|
||||
- } else {
|
||||
+ map->page_00h[CMIS_COPPER_ATT_25P8GHZ]);
|
||||
+ } else if (map->page_01h) {
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
|
||||
- (((id[CMIS_NOM_WAVELENGTH_MSB] << 8) |
|
||||
- id[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
|
||||
+ (((map->page_01h[CMIS_NOM_WAVELENGTH_MSB] << 8) |
|
||||
+ map->page_01h[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
|
||||
- (((id[CMIS_WAVELENGTH_TOL_MSB] << 8) |
|
||||
- id[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
|
||||
+ (((map->page_01h[CMIS_WAVELENGTH_TOL_MSB] << 8) |
|
||||
+ map->page_01h[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,28 +281,16 @@ static void cmis_show_mit_compliance(const __u8 *id)
|
||||
* [2] CMIS Rev. 4:
|
||||
* --> pag. 84, section 8.2.4, Table 8-6
|
||||
*/
|
||||
-static void cmis_show_mod_lvl_monitors(const __u8 *id)
|
||||
+static void cmis_show_mod_lvl_monitors(const struct cmis_memory_map *map)
|
||||
{
|
||||
+ const __u8 *id = map->lower_memory;
|
||||
+
|
||||
PRINT_TEMP("Module temperature",
|
||||
OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
|
||||
PRINT_VCC("Module voltage",
|
||||
OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
|
||||
}
|
||||
|
||||
-static void cmis_show_link_len_from_page(const __u8 *page_one_data)
|
||||
-{
|
||||
- cmis_print_smf_cbl_len(page_one_data);
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM5_LEN_OFFSET,
|
||||
- "Length (OM5)", 2, "m");
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM4_LEN_OFFSET,
|
||||
- "Length (OM4)", 2, "m");
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM3_LEN_OFFSET,
|
||||
- "Length (OM3 50/125um)", 2, "m");
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM2_LEN_OFFSET,
|
||||
- "Length (OM2 50/125um)", 1, "m");
|
||||
-}
|
||||
-
|
||||
-
|
||||
/**
|
||||
* Print relevant info about the maximum supported fiber media length
|
||||
* for each type of fiber media at the maximum module-supported bit rate.
|
||||
@@ -304,9 +298,19 @@ static void cmis_show_link_len_from_page(const __u8 *page_one_data)
|
||||
* [1] CMIS Rev. 3, page 64, section 1.7.4.2, Table 39
|
||||
* [2] CMIS Rev. 4, page 99, section 8.4.2, Table 8-27
|
||||
*/
|
||||
-static void cmis_show_link_len(const __u8 *id)
|
||||
+static void cmis_show_link_len(const struct cmis_memory_map *map)
|
||||
{
|
||||
- cmis_show_link_len_from_page(id);
|
||||
+ cmis_print_smf_cbl_len(map);
|
||||
+ if (!map->page_01h)
|
||||
+ return;
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM5_LEN_OFFSET,
|
||||
+ "Length (OM5)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM4_LEN_OFFSET,
|
||||
+ "Length (OM4)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM3_LEN_OFFSET,
|
||||
+ "Length (OM3 50/125um)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM2_LEN_OFFSET,
|
||||
+ "Length (OM2 50/125um)", 1, "m");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,25 +318,26 @@ static void cmis_show_link_len(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, page 56, section 1.7.3, Table 27
|
||||
* [2] CMIS Rev. 4, page 91, section 8.2, Table 8-15
|
||||
*/
|
||||
-static void cmis_show_vendor_info(const __u8 *id)
|
||||
+static void cmis_show_vendor_info(const struct cmis_memory_map *map)
|
||||
{
|
||||
- const char *clei = (const char *)(id + CMIS_CLEI_START_OFFSET);
|
||||
+ const char *clei;
|
||||
|
||||
- sff_show_ascii(id, CMIS_VENDOR_NAME_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_NAME_START_OFFSET,
|
||||
CMIS_VENDOR_NAME_END_OFFSET, "Vendor name");
|
||||
- cmis_show_oui(id);
|
||||
- sff_show_ascii(id, CMIS_VENDOR_PN_START_OFFSET,
|
||||
+ cmis_show_oui(map);
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_PN_START_OFFSET,
|
||||
CMIS_VENDOR_PN_END_OFFSET, "Vendor PN");
|
||||
- sff_show_ascii(id, CMIS_VENDOR_REV_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_REV_START_OFFSET,
|
||||
CMIS_VENDOR_REV_END_OFFSET, "Vendor rev");
|
||||
- sff_show_ascii(id, CMIS_VENDOR_SN_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_SN_START_OFFSET,
|
||||
CMIS_VENDOR_SN_END_OFFSET, "Vendor SN");
|
||||
- sff_show_ascii(id, CMIS_DATE_YEAR_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_DATE_YEAR_OFFSET,
|
||||
CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
|
||||
|
||||
+ clei = (const char *)(map->page_00h + CMIS_CLEI_START_OFFSET);
|
||||
if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN))
|
||||
- sff_show_ascii(id, CMIS_CLEI_START_OFFSET, CMIS_CLEI_END_OFFSET,
|
||||
- "CLEI code");
|
||||
+ sff_show_ascii(map->page_00h, CMIS_CLEI_START_OFFSET,
|
||||
+ CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
}
|
||||
|
||||
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
|
||||
@@ -363,16 +368,16 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
|
||||
cmis_memory_map_init_buf(&map, id);
|
||||
|
||||
- cmis_show_identifier(id);
|
||||
- cmis_show_power_info(id);
|
||||
- cmis_show_connector(id);
|
||||
- cmis_show_cbl_asm_len(id);
|
||||
- cmis_show_sig_integrity(id);
|
||||
- cmis_show_mit_compliance(id);
|
||||
- cmis_show_mod_lvl_monitors(id);
|
||||
- cmis_show_link_len(id);
|
||||
- cmis_show_vendor_info(id);
|
||||
- cmis_show_rev_compliance(id);
|
||||
+ cmis_show_identifier(&map);
|
||||
+ cmis_show_power_info(&map);
|
||||
+ cmis_show_connector(&map);
|
||||
+ cmis_show_cbl_asm_len(&map);
|
||||
+ cmis_show_sig_integrity(&map);
|
||||
+ cmis_show_mit_compliance(&map);
|
||||
+ cmis_show_mod_lvl_monitors(&map);
|
||||
+ cmis_show_link_len(&map);
|
||||
+ cmis_show_vendor_info(&map);
|
||||
+ cmis_show_rev_compliance(&map);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -403,22 +408,18 @@ cmis_memory_map_init_pages(struct cmis_memory_map *map,
|
||||
void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
const struct ethtool_module_eeprom *page_one)
|
||||
{
|
||||
- const __u8 *page_zero_data = page_zero->data;
|
||||
struct cmis_memory_map map = {};
|
||||
|
||||
cmis_memory_map_init_pages(&map, page_zero, page_one);
|
||||
|
||||
- cmis_show_identifier(page_zero_data);
|
||||
- cmis_show_power_info(page_zero_data);
|
||||
- cmis_show_connector(page_zero_data);
|
||||
- cmis_show_cbl_asm_len(page_zero_data);
|
||||
- cmis_show_sig_integrity(page_zero_data);
|
||||
- cmis_show_mit_compliance(page_zero_data);
|
||||
- cmis_show_mod_lvl_monitors(page_zero_data);
|
||||
-
|
||||
- if (page_one)
|
||||
- cmis_show_link_len_from_page(page_one->data - 0x80);
|
||||
-
|
||||
- cmis_show_vendor_info(page_zero_data);
|
||||
- cmis_show_rev_compliance(page_zero_data);
|
||||
+ cmis_show_identifier(&map);
|
||||
+ cmis_show_power_info(&map);
|
||||
+ cmis_show_connector(&map);
|
||||
+ cmis_show_cbl_asm_len(&map);
|
||||
+ cmis_show_sig_integrity(&map);
|
||||
+ cmis_show_mit_compliance(&map);
|
||||
+ cmis_show_mod_lvl_monitors(&map);
|
||||
+ cmis_show_link_len(&map);
|
||||
+ cmis_show_vendor_info(&map);
|
||||
+ cmis_show_rev_compliance(&map);
|
||||
}
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 53cbb5f..c878e3b 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -100,7 +100,6 @@
|
||||
* that are unique to active modules and cable assemblies.
|
||||
* GlobalOffset = 2 * 0x80 + LocalOffset
|
||||
*/
|
||||
-#define PAG01H_UPPER_OFFSET (0x02 * 0x80)
|
||||
|
||||
/* Supported Link Length (Page 1) */
|
||||
#define CMIS_SMF_LEN_OFFSET 0x84
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,459 @@
|
||||
From 1bc52b04285906efcbdf7e9429ed668170ebf97a Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 7 Dec 2021 11:33:58 +0200
|
||||
Subject: [PATCH 24/26] ethtool: Add ability to control transceiver modules'
|
||||
power mode
|
||||
|
||||
Add ability to control transceiver modules' power mode over netlink.
|
||||
|
||||
Example output and usage:
|
||||
|
||||
# ip link set dev swp11 up
|
||||
|
||||
$ ethtool --show-module swp11
|
||||
Module parameters for swp11:
|
||||
power-mode-policy: high
|
||||
power-mode: high
|
||||
|
||||
$ ethtool --json --show-module swp11
|
||||
[ {
|
||||
"ifname": "swp11",
|
||||
"power-mode-policy": "high",
|
||||
"power-mode": "high"
|
||||
} ]
|
||||
|
||||
# ethtool --set-module swp11 power-mode-policy auto
|
||||
|
||||
$ ethtool --show-module swp11
|
||||
Module parameters for swp11:
|
||||
power-mode-policy: auto
|
||||
power-mode: high
|
||||
|
||||
# ethtool --set-module swp11 power-mode-policy auto
|
||||
|
||||
# ethtool --set-module swp11 power-mode-policy high
|
||||
|
||||
Despite three set commands, only two notifications were emitted, as the
|
||||
kernel only emits notifications when an attribute changes:
|
||||
|
||||
$ ethtool --monitor
|
||||
listening...
|
||||
|
||||
Module parameters for swp11:
|
||||
power-mode-policy: auto
|
||||
power-mode: high
|
||||
|
||||
Module parameters for swp11:
|
||||
power-mode-policy: high
|
||||
power-mode: high
|
||||
|
||||
commit: 2d4c5b7
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=2d4c5b7bb38b
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
ethtool.8.in | 25 +++++
|
||||
ethtool.c | 12 +++
|
||||
netlink/desc-ethtool.c | 11 +++
|
||||
netlink/extapi.h | 4 +
|
||||
netlink/module.c | 179 ++++++++++++++++++++++++++++++++++
|
||||
netlink/monitor.c | 4 +
|
||||
netlink/netlink.h | 1 +
|
||||
shell-completion/bash/ethtool | 23 +++++
|
||||
9 files changed, 260 insertions(+), 1 deletion(-)
|
||||
create mode 100644 netlink/module.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index a8f7a39..1ee6f13 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -39,7 +39,7 @@ ethtool_SOURCES += \
|
||||
netlink/eee.c netlink/tsinfo.c netlink/fec.c \
|
||||
netlink/stats.c \
|
||||
netlink/desc-ethtool.c netlink/desc-genlctrl.c \
|
||||
- netlink/module-eeprom.c \
|
||||
+ netlink/module-eeprom.c netlink/module.c \
|
||||
netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \
|
||||
uapi/linux/ethtool_netlink.h \
|
||||
uapi/linux/netlink.h uapi/linux/genetlink.h \
|
||||
diff --git a/ethtool.8.in b/ethtool.8.in
|
||||
index af1c5bc..7016c3a 100644
|
||||
--- a/ethtool.8.in
|
||||
+++ b/ethtool.8.in
|
||||
@@ -479,6 +479,14 @@ ethtool \- query or control network driver and hardware settings
|
||||
.HP
|
||||
.B ethtool \-\-show\-tunnels
|
||||
.I devname
|
||||
+.HP
|
||||
+.B ethtool \-\-show\-module
|
||||
+.I devname
|
||||
+.HP
|
||||
+.B ethtool \-\-set\-module
|
||||
+.I devname
|
||||
+.RB [ power\-mode\-policy
|
||||
+.BR high | auto ]
|
||||
.
|
||||
.\" Adjust lines (i.e. full justification) and hyphenate.
|
||||
.ad
|
||||
@@ -1468,6 +1476,23 @@ Show tunnel-related device capabilities and state.
|
||||
List UDP ports kernel has programmed the device to parse as VxLAN,
|
||||
or GENEVE tunnels.
|
||||
.RE
|
||||
+.TP
|
||||
+.B \-\-show\-module
|
||||
+Show the transceiver module's parameters.
|
||||
+.RE
|
||||
+.TP
|
||||
+.B \-\-set\-module
|
||||
+Set the transceiver module's parameters.
|
||||
+.RS 4
|
||||
+.TP
|
||||
+.A2 power-mode-policy high auto
|
||||
+Set the power mode policy for the module. When set to \fBhigh\fR, the module
|
||||
+always operates at high power mode. When set to \fBauto\fR, the module is
|
||||
+transitioned by the host to high power mode when the first port using it is put
|
||||
+administratively up and to low power mode when the last port using it is put
|
||||
+administratively down. The power mode policy can be set before a module is
|
||||
+plugged-in.
|
||||
+.RE
|
||||
.SH BUGS
|
||||
Not supported (in part or whole) on all network drivers.
|
||||
.SH AUTHOR
|
||||
diff --git a/ethtool.c b/ethtool.c
|
||||
index 461d1f2..2a13196 100644
|
||||
--- a/ethtool.c
|
||||
+++ b/ethtool.c
|
||||
@@ -6056,6 +6056,18 @@ static const struct option args[] = {
|
||||
.nlfunc = nl_gtunnels,
|
||||
.help = "Show NIC tunnel offload information",
|
||||
},
|
||||
+ {
|
||||
+ .opts = "--show-module",
|
||||
+ .json = true,
|
||||
+ .nlfunc = nl_gmodule,
|
||||
+ .help = "Show transceiver module settings",
|
||||
+ },
|
||||
+ {
|
||||
+ .opts = "--set-module",
|
||||
+ .nlfunc = nl_smodule,
|
||||
+ .help = "Set transceiver module settings",
|
||||
+ .xhelp = " [ power-mode-policy high|auto ]\n"
|
||||
+ },
|
||||
{
|
||||
.opts = "-h|--help",
|
||||
.no_dev = true,
|
||||
diff --git a/netlink/desc-ethtool.c b/netlink/desc-ethtool.c
|
||||
index 69f6561..2b27c32 100644
|
||||
--- a/netlink/desc-ethtool.c
|
||||
+++ b/netlink/desc-ethtool.c
|
||||
@@ -392,6 +392,13 @@ static const struct pretty_nla_desc __phc_vclocks_desc[] = {
|
||||
NLATTR_DESC_BINARY(ETHTOOL_A_PHC_VCLOCKS_INDEX),
|
||||
};
|
||||
|
||||
+static const struct pretty_nla_desc __module_desc[] = {
|
||||
+ NLATTR_DESC_INVALID(ETHTOOL_A_MODULE_UNSPEC),
|
||||
+ NLATTR_DESC_NESTED(ETHTOOL_A_MODULE_HEADER, header),
|
||||
+ NLATTR_DESC_U8(ETHTOOL_A_MODULE_POWER_MODE_POLICY),
|
||||
+ NLATTR_DESC_U8(ETHTOOL_A_MODULE_POWER_MODE),
|
||||
+};
|
||||
+
|
||||
const struct pretty_nlmsg_desc ethnl_umsg_desc[] = {
|
||||
NLMSG_DESC_INVALID(ETHTOOL_MSG_USER_NONE),
|
||||
NLMSG_DESC(ETHTOOL_MSG_STRSET_GET, strset),
|
||||
@@ -427,6 +434,8 @@ const struct pretty_nlmsg_desc ethnl_umsg_desc[] = {
|
||||
NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET, module_eeprom),
|
||||
NLMSG_DESC(ETHTOOL_MSG_STATS_GET, stats),
|
||||
NLMSG_DESC(ETHTOOL_MSG_PHC_VCLOCKS_GET, phc_vclocks),
|
||||
+ NLMSG_DESC(ETHTOOL_MSG_MODULE_GET, module),
|
||||
+ NLMSG_DESC(ETHTOOL_MSG_MODULE_SET, module),
|
||||
};
|
||||
|
||||
const unsigned int ethnl_umsg_n_desc = ARRAY_SIZE(ethnl_umsg_desc);
|
||||
@@ -467,6 +476,8 @@ const struct pretty_nlmsg_desc ethnl_kmsg_desc[] = {
|
||||
NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, module_eeprom),
|
||||
NLMSG_DESC(ETHTOOL_MSG_STATS_GET_REPLY, stats),
|
||||
NLMSG_DESC(ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY, phc_vclocks),
|
||||
+ NLMSG_DESC(ETHTOOL_MSG_MODULE_GET_REPLY, module),
|
||||
+ NLMSG_DESC(ETHTOOL_MSG_MODULE_NTF, module),
|
||||
};
|
||||
|
||||
const unsigned int ethnl_kmsg_n_desc = ARRAY_SIZE(ethnl_kmsg_desc);
|
||||
diff --git a/netlink/extapi.h b/netlink/extapi.h
|
||||
index 129e293..1bb580a 100644
|
||||
--- a/netlink/extapi.h
|
||||
+++ b/netlink/extapi.h
|
||||
@@ -43,6 +43,8 @@ int nl_gfec(struct cmd_context *ctx);
|
||||
int nl_sfec(struct cmd_context *ctx);
|
||||
bool nl_gstats_chk(struct cmd_context *ctx);
|
||||
int nl_gstats(struct cmd_context *ctx);
|
||||
+int nl_gmodule(struct cmd_context *ctx);
|
||||
+int nl_smodule(struct cmd_context *ctx);
|
||||
int nl_monitor(struct cmd_context *ctx);
|
||||
int nl_getmodule(struct cmd_context *ctx);
|
||||
|
||||
@@ -110,6 +112,8 @@ nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused,
|
||||
#define nl_gstats_chk NULL
|
||||
#define nl_gstats NULL
|
||||
#define nl_getmodule NULL
|
||||
+#define nl_gmodule NULL
|
||||
+#define nl_smodule NULL
|
||||
|
||||
#endif /* ETHTOOL_ENABLE_NETLINK */
|
||||
|
||||
diff --git a/netlink/module.c b/netlink/module.c
|
||||
new file mode 100644
|
||||
index 0000000..54aa6d0
|
||||
--- /dev/null
|
||||
+++ b/netlink/module.c
|
||||
@@ -0,0 +1,179 @@
|
||||
+/*
|
||||
+ * module.c - netlink implementation of module commands
|
||||
+ *
|
||||
+ * Implementation of "ethtool --show-module <dev>" and
|
||||
+ * "ethtool --set-module <dev> ..."
|
||||
+ */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <ctype.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include "../internal.h"
|
||||
+#include "../common.h"
|
||||
+#include "netlink.h"
|
||||
+#include "parser.h"
|
||||
+
|
||||
+/* MODULE_GET */
|
||||
+
|
||||
+static const char *module_power_mode_policy_name(u8 val)
|
||||
+{
|
||||
+ switch (val) {
|
||||
+ case ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH:
|
||||
+ return "high";
|
||||
+ case ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO:
|
||||
+ return "auto";
|
||||
+ default:
|
||||
+ return "unknown";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const char *module_power_mode_name(u8 val)
|
||||
+{
|
||||
+ switch (val) {
|
||||
+ case ETHTOOL_MODULE_POWER_MODE_LOW:
|
||||
+ return "low";
|
||||
+ case ETHTOOL_MODULE_POWER_MODE_HIGH:
|
||||
+ return "high";
|
||||
+ default:
|
||||
+ return "unknown";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int module_reply_cb(const struct nlmsghdr *nlhdr, void *data)
|
||||
+{
|
||||
+ const struct nlattr *tb[ETHTOOL_A_MODULE_MAX + 1] = {};
|
||||
+ struct nl_context *nlctx = data;
|
||||
+ DECLARE_ATTR_TB_INFO(tb);
|
||||
+ bool silent;
|
||||
+ int err_ret;
|
||||
+ int ret;
|
||||
+
|
||||
+ silent = nlctx->is_dump || nlctx->is_monitor;
|
||||
+ err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR;
|
||||
+ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
|
||||
+ if (ret < 0)
|
||||
+ return err_ret;
|
||||
+ nlctx->devname = get_dev_name(tb[ETHTOOL_A_MODULE_HEADER]);
|
||||
+ if (!dev_ok(nlctx))
|
||||
+ return err_ret;
|
||||
+
|
||||
+ if (silent)
|
||||
+ print_nl();
|
||||
+
|
||||
+ open_json_object(NULL);
|
||||
+
|
||||
+ print_string(PRINT_ANY, "ifname", "Module parameters for %s:\n",
|
||||
+ nlctx->devname);
|
||||
+
|
||||
+ if (tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]) {
|
||||
+ u8 val;
|
||||
+
|
||||
+ val = mnl_attr_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]);
|
||||
+ print_string(PRINT_ANY, "power-mode-policy",
|
||||
+ "power-mode-policy: %s\n",
|
||||
+ module_power_mode_policy_name(val));
|
||||
+ }
|
||||
+
|
||||
+ if (tb[ETHTOOL_A_MODULE_POWER_MODE]) {
|
||||
+ u8 val;
|
||||
+
|
||||
+ val = mnl_attr_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE]);
|
||||
+ print_string(PRINT_ANY, "power-mode",
|
||||
+ "power-mode: %s\n", module_power_mode_name(val));
|
||||
+ }
|
||||
+
|
||||
+ close_json_object();
|
||||
+
|
||||
+ return MNL_CB_OK;
|
||||
+}
|
||||
+
|
||||
+int nl_gmodule(struct cmd_context *ctx)
|
||||
+{
|
||||
+ struct nl_context *nlctx = ctx->nlctx;
|
||||
+ struct nl_socket *nlsk;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_GET, true))
|
||||
+ return -EOPNOTSUPP;
|
||||
+ if (ctx->argc > 0) {
|
||||
+ fprintf(stderr, "ethtool: unexpected parameter '%s'\n",
|
||||
+ *ctx->argp);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ nlsk = nlctx->ethnl_socket;
|
||||
+ ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_MODULE_GET,
|
||||
+ ETHTOOL_A_MODULE_HEADER, 0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ new_json_obj(ctx->json);
|
||||
+ ret = nlsock_send_get_request(nlsk, module_reply_cb);
|
||||
+ delete_json_obj();
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* MODULE_SET */
|
||||
+
|
||||
+static const struct lookup_entry_u8 power_mode_policy_values[] = {
|
||||
+ { .arg = "high", .val = ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH },
|
||||
+ { .arg = "auto", .val = ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+static const struct param_parser smodule_params[] = {
|
||||
+ {
|
||||
+ .arg = "power-mode-policy",
|
||||
+ .type = ETHTOOL_A_MODULE_POWER_MODE_POLICY,
|
||||
+ .handler = nl_parse_lookup_u8,
|
||||
+ .handler_data = power_mode_policy_values,
|
||||
+ .min_argc = 1,
|
||||
+ },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+int nl_smodule(struct cmd_context *ctx)
|
||||
+{
|
||||
+ struct nl_context *nlctx = ctx->nlctx;
|
||||
+ struct nl_msg_buff *msgbuff;
|
||||
+ struct nl_socket *nlsk;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_SET, false))
|
||||
+ return -EOPNOTSUPP;
|
||||
+ if (!ctx->argc) {
|
||||
+ fprintf(stderr, "ethtool (--set-module): parameters missing\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ nlctx->cmd = "--set-module";
|
||||
+ nlctx->argp = ctx->argp;
|
||||
+ nlctx->argc = ctx->argc;
|
||||
+ nlctx->devname = ctx->devname;
|
||||
+ nlsk = nlctx->ethnl_socket;
|
||||
+ msgbuff = &nlsk->msgbuff;
|
||||
+
|
||||
+ ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_MODULE_SET,
|
||||
+ NLM_F_REQUEST | NLM_F_ACK);
|
||||
+ if (ret < 0)
|
||||
+ return 2;
|
||||
+ if (ethnla_fill_header(msgbuff, ETHTOOL_A_MODULE_HEADER,
|
||||
+ ctx->devname, 0))
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ ret = nl_parser(nlctx, smodule_params, NULL, PARSER_GROUP_NONE, NULL);
|
||||
+ if (ret < 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ ret = nlsock_sendmsg(nlsk, NULL);
|
||||
+ if (ret < 0)
|
||||
+ return 83;
|
||||
+ ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx);
|
||||
+ if (ret == 0)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return nlctx->exit_code ?: 83;
|
||||
+}
|
||||
diff --git a/netlink/monitor.c b/netlink/monitor.c
|
||||
index 0c4df9e..d631907 100644
|
||||
--- a/netlink/monitor.c
|
||||
+++ b/netlink/monitor.c
|
||||
@@ -71,6 +71,10 @@ static struct {
|
||||
.cmd = ETHTOOL_MSG_FEC_NTF,
|
||||
.cb = fec_reply_cb,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = ETHTOOL_MSG_MODULE_NTF,
|
||||
+ .cb = module_reply_cb,
|
||||
+ },
|
||||
};
|
||||
|
||||
static void clear_filter(struct nl_context *nlctx)
|
||||
diff --git a/netlink/netlink.h b/netlink/netlink.h
|
||||
index 70fa666..f43c1bf 100644
|
||||
--- a/netlink/netlink.h
|
||||
+++ b/netlink/netlink.h
|
||||
@@ -91,6 +91,7 @@ int cable_test_ntf_cb(const struct nlmsghdr *nlhdr, void *data);
|
||||
int cable_test_tdr_reply_cb(const struct nlmsghdr *nlhdr, void *data);
|
||||
int cable_test_tdr_ntf_cb(const struct nlmsghdr *nlhdr, void *data);
|
||||
int fec_reply_cb(const struct nlmsghdr *nlhdr, void *data);
|
||||
+int module_reply_cb(const struct nlmsghdr *nlhdr, void *data);
|
||||
|
||||
/* dump helpers */
|
||||
|
||||
diff --git a/shell-completion/bash/ethtool b/shell-completion/bash/ethtool
|
||||
index 4557341..46334b5 100644
|
||||
--- a/shell-completion/bash/ethtool
|
||||
+++ b/shell-completion/bash/ethtool
|
||||
@@ -1137,6 +1137,27 @@ _ethtool_test()
|
||||
fi
|
||||
}
|
||||
|
||||
+# Completion for ethtool --set-module
|
||||
+_ethtool_set_module()
|
||||
+{
|
||||
+ local -A settings=(
|
||||
+ [power-mode-policy]=1
|
||||
+ )
|
||||
+
|
||||
+ case "$prev" in
|
||||
+ power-mode-policy)
|
||||
+ COMPREPLY=( $( compgen -W 'high auto' -- "$cur" ) )
|
||||
+ return ;;
|
||||
+ esac
|
||||
+
|
||||
+ # Remove settings which have been seen
|
||||
+ local word
|
||||
+ for word in "${words[@]:3:${#words[@]}-4}"; do
|
||||
+ unset "settings[$word]"
|
||||
+ done
|
||||
+
|
||||
+ COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
|
||||
+}
|
||||
|
||||
# Complete any ethtool command
|
||||
_ethtool()
|
||||
@@ -1189,6 +1210,8 @@ _ethtool()
|
||||
[--show-time-stamping]=devname
|
||||
[--statistics]=devname
|
||||
[--test]=test
|
||||
+ [--set-module]=set_module
|
||||
+ [--show-module]=devname
|
||||
)
|
||||
local -A other_funcs=(
|
||||
[--config-ntuple]=config_nfc
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
From f7d99859bc603649705e439472c8f79386a8b217 Mon Sep 17 00:00:00 2001
|
||||
From: Danielle Ratson <danieller@nvidia.com>
|
||||
Date: Mon, 7 Feb 2022 11:12:31 +0200
|
||||
Subject: [PATCH 25/26] ethtool: Add support for OSFP transceiver modules
|
||||
|
||||
OSFP transceiver modules use the same management interface specification
|
||||
(CMIS) as QSFP-DD and DSFP modules.
|
||||
|
||||
Allow ethtool to dump, parse and print their EEPROM contents by adding
|
||||
their SFF-8024 Identifier Value (0x19).
|
||||
|
||||
This is required for future NVIDIA Spectrum-4 based systems that will be
|
||||
equipped with OSFP transceivers.
|
||||
|
||||
While at it, add the DSFP identifier to the IOCTL path, as it was
|
||||
missing.
|
||||
|
||||
commit: b9f25ea
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=b9f25ea9058d
|
||||
|
||||
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
|
||||
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/module-eeprom.c | 1 +
|
||||
qsfp.c | 4 +++-
|
||||
sff-common.c | 3 +++
|
||||
sff-common.h | 1 +
|
||||
4 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index f359aee..49833a2 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -223,6 +223,7 @@ static int eeprom_parse(struct cmd_context *ctx)
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
return sff8636_show_all_nl(ctx);
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
+ case SFF8024_ID_OSFP:
|
||||
case SFF8024_ID_DSFP:
|
||||
return cmis_show_all_nl(ctx);
|
||||
#endif
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 57aac86..1fe5de1 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -947,7 +947,9 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
struct sff8636_memory_map map = {};
|
||||
|
||||
- if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
+ if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD ||
|
||||
+ id[SFF8636_ID_OFFSET] == SFF8024_ID_OSFP ||
|
||||
+ id[SFF8636_ID_OFFSET] == SFF8024_ID_DSFP) {
|
||||
cmis_show_all_ioctl(id);
|
||||
return;
|
||||
}
|
||||
diff --git a/sff-common.c b/sff-common.c
|
||||
index 2815951..e951cf1 100644
|
||||
--- a/sff-common.c
|
||||
+++ b/sff-common.c
|
||||
@@ -139,6 +139,9 @@ void sff8024_show_identifier(const __u8 *id, int id_offset)
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
printf(" (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))\n");
|
||||
break;
|
||||
+ case SFF8024_ID_OSFP:
|
||||
+ printf(" (OSFP 8X Pluggable Transceiver)\n");
|
||||
+ break;
|
||||
case SFF8024_ID_DSFP:
|
||||
printf(" (DSFP Dual Small Form Factor Pluggable Transceiver)\n");
|
||||
break;
|
||||
diff --git a/sff-common.h b/sff-common.h
|
||||
index 9e32300..dd12dda 100644
|
||||
--- a/sff-common.h
|
||||
+++ b/sff-common.h
|
||||
@@ -62,6 +62,7 @@
|
||||
#define SFF8024_ID_CDFP_S3 0x16
|
||||
#define SFF8024_ID_MICRO_QSFP 0x17
|
||||
#define SFF8024_ID_QSFP_DD 0x18
|
||||
+#define SFF8024_ID_OSFP 0x19
|
||||
#define SFF8024_ID_DSFP 0x1B
|
||||
#define SFF8024_ID_LAST SFF8024_ID_DSFP
|
||||
#define SFF8024_ID_UNALLOCATED_LAST 0x7F
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,205 @@
|
||||
From 176cd20c04800b4455521536f65408a076eb213d Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Mon, 30 Oct 2023 09:23:53 +0200
|
||||
Subject: [PATCH] ethtool: Add support for more CMIS transceiver modules
|
||||
|
||||
Add three more SFF-8024 Identifier Values that according to the standard
|
||||
support the Common Management Interface Specification (CMIS) memory map
|
||||
so that ethtool will be able to dump, parse and print their EEPROM
|
||||
contents.
|
||||
|
||||
commit: 8ad5035
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=8ad503517b45
|
||||
change log: change Makefile.in for openEuler CI building.
|
||||
|
||||
Reported-by: Mark Wang <markwang@nvidia.com>
|
||||
Tested-by: Mark Wang <markwang@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
Makefile.in | 39 +++++++++++++++++++++++++++++++++++----
|
||||
netlink/module-eeprom.c | 3 +++
|
||||
qsfp.c | 10 +++++++---
|
||||
sff-common.c | 9 +++++++++
|
||||
sff-common.h | 5 ++++-
|
||||
5 files changed, 58 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 0f035a9..f4515b3 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -109,7 +109,7 @@ sbin_PROGRAMS = ethtool$(EXEEXT)
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/eee.c netlink/tsinfo.c netlink/fec.c \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/stats.c \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-ethtool.c netlink/desc-genlctrl.c \
|
||||
-@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module-eeprom.c \
|
||||
+@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module-eeprom.c netlink/module.c \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ uapi/linux/ethtool_netlink.h \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ uapi/linux/netlink.h uapi/linux/genetlink.h \
|
||||
@@ -157,7 +157,7 @@ am__ethtool_SOURCES_DIST = ethtool.c uapi/linux/ethtool.h internal.h \
|
||||
netlink/rings.c netlink/channels.c netlink/coalesce.c \
|
||||
netlink/pause.c netlink/eee.c netlink/tsinfo.c netlink/fec.c \
|
||||
netlink/stats.c netlink/desc-ethtool.c netlink/desc-genlctrl.c \
|
||||
- netlink/module-eeprom.c netlink/desc-rtnl.c \
|
||||
+ netlink/module-eeprom.c netlink/module.c netlink/desc-rtnl.c \
|
||||
netlink/cable_test.c netlink/tunnels.c \
|
||||
uapi/linux/ethtool_netlink.h uapi/linux/netlink.h \
|
||||
uapi/linux/genetlink.h uapi/linux/rtnetlink.h \
|
||||
@@ -217,6 +217,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-ethtool.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-genlctrl.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module-eeprom.$(OBJEXT) \
|
||||
+@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-rtnl.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/cable_test.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/tunnels.$(OBJEXT)
|
||||
@@ -246,7 +247,7 @@ am__test_cmdline_SOURCES_DIST = test-cmdline.c test-common.c ethtool.c \
|
||||
netlink/channels.c netlink/coalesce.c netlink/pause.c \
|
||||
netlink/eee.c netlink/tsinfo.c netlink/fec.c netlink/stats.c \
|
||||
netlink/desc-ethtool.c netlink/desc-genlctrl.c \
|
||||
- netlink/module-eeprom.c netlink/desc-rtnl.c \
|
||||
+ netlink/module-eeprom.c netlink/module.c netlink/desc-rtnl.c \
|
||||
netlink/cable_test.c netlink/tunnels.c \
|
||||
uapi/linux/ethtool_netlink.h uapi/linux/netlink.h \
|
||||
uapi/linux/genetlink.h uapi/linux/rtnetlink.h \
|
||||
@@ -309,6 +310,7 @@ am__test_cmdline_SOURCES_DIST = test-cmdline.c test-common.c ethtool.c \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-desc-ethtool.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-desc-genlctrl.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-module-eeprom.$(OBJEXT) \
|
||||
+@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-module.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-desc-rtnl.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-cable_test.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-tunnels.$(OBJEXT)
|
||||
@@ -343,7 +345,7 @@ am__test_features_SOURCES_DIST = test-features.c test-common.c \
|
||||
netlink/rings.c netlink/channels.c netlink/coalesce.c \
|
||||
netlink/pause.c netlink/eee.c netlink/tsinfo.c netlink/fec.c \
|
||||
netlink/stats.c netlink/desc-ethtool.c netlink/desc-genlctrl.c \
|
||||
- netlink/module-eeprom.c netlink/desc-rtnl.c \
|
||||
+ netlink/module-eeprom.c netlink/module.c netlink/desc-rtnl.c \
|
||||
netlink/cable_test.c netlink/tunnels.c \
|
||||
uapi/linux/ethtool_netlink.h uapi/linux/netlink.h \
|
||||
uapi/linux/genetlink.h uapi/linux/rtnetlink.h \
|
||||
@@ -406,6 +408,7 @@ am__test_features_SOURCES_DIST = test-features.c test-common.c \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-desc-ethtool.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-desc-genlctrl.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-module-eeprom.$(OBJEXT) \
|
||||
+@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-module.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-desc-rtnl.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-cable_test.$(OBJEXT) \
|
||||
@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-tunnels.$(OBJEXT)
|
||||
@@ -2238,6 +2241,20 @@ netlink/test_cmdline-module-eeprom.obj: netlink/module-eeprom.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module-eeprom.obj `if test -f 'netlink/module-eeprom.c'; then $(CYGPATH_W) 'netlink/module-eeprom.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module-eeprom.c'; fi`
|
||||
|
||||
+netlink/test_cmdline-module.o: netlink/module.c
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-module.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-module.Tpo -c -o netlink/test_cmdline-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-module.Tpo netlink/$(DEPDIR)/test_cmdline-module.Po
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_cmdline-module.o' libtool=no @AMDEPBACKSLASH@
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c
|
||||
+
|
||||
+netlink/test_cmdline-module.obj: netlink/module.c
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-module.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-module.Tpo -c -o netlink/test_cmdline-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi`
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-module.Tpo netlink/$(DEPDIR)/test_cmdline-module.Po
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_cmdline-module.obj' libtool=no @AMDEPBACKSLASH@
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi`
|
||||
+
|
||||
netlink/test_cmdline-desc-rtnl.o: netlink/desc-rtnl.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-rtnl.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Tpo -c -o netlink/test_cmdline-desc-rtnl.o `test -f 'netlink/desc-rtnl.c' || echo '$(srcdir)/'`netlink/desc-rtnl.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Tpo netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Po
|
||||
@@ -3176,6 +3193,20 @@ netlink/test_features-module-eeprom.obj: netlink/module-eeprom.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module-eeprom.obj `if test -f 'netlink/module-eeprom.c'; then $(CYGPATH_W) 'netlink/module-eeprom.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module-eeprom.c'; fi`
|
||||
|
||||
+netlink/test_features-module.o: netlink/module.c
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-module.o -MD -MP -MF netlink/$(DEPDIR)/test_features-module.Tpo -c -o netlink/test_features-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-module.Tpo netlink/$(DEPDIR)/test_features-module.Po
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_features-module.o' libtool=no @AMDEPBACKSLASH@
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c
|
||||
+
|
||||
+netlink/test_features-module.obj: netlink/module.c
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-module.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-module.Tpo -c -o netlink/test_features-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi`
|
||||
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-module.Tpo netlink/$(DEPDIR)/test_features-module.Po
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_features-module.obj' libtool=no @AMDEPBACKSLASH@
|
||||
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi`
|
||||
+
|
||||
netlink/test_features-desc-rtnl.o: netlink/desc-rtnl.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-rtnl.o -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-rtnl.Tpo -c -o netlink/test_features-desc-rtnl.o `test -f 'netlink/desc-rtnl.c' || echo '$(srcdir)/'`netlink/desc-rtnl.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-rtnl.Tpo netlink/$(DEPDIR)/test_features-desc-rtnl.Po
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 49833a2..09ad580 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -225,6 +225,9 @@ static int eeprom_parse(struct cmd_context *ctx)
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_OSFP:
|
||||
case SFF8024_ID_DSFP:
|
||||
+ case SFF8024_ID_QSFP_PLUS_CMIS:
|
||||
+ case SFF8024_ID_SFP_DD_CMIS:
|
||||
+ case SFF8024_ID_SFP_PLUS_CMIS:
|
||||
return cmis_show_all_nl(ctx);
|
||||
#endif
|
||||
default:
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 1fe5de1..ae4a581 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -947,9 +947,13 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
struct sff8636_memory_map map = {};
|
||||
|
||||
- if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD ||
|
||||
- id[SFF8636_ID_OFFSET] == SFF8024_ID_OSFP ||
|
||||
- id[SFF8636_ID_OFFSET] == SFF8024_ID_DSFP) {
|
||||
+ switch (id[SFF8636_ID_OFFSET]) {
|
||||
+ case SFF8024_ID_QSFP_DD:
|
||||
+ case SFF8024_ID_OSFP:
|
||||
+ case SFF8024_ID_DSFP:
|
||||
+ case SFF8024_ID_QSFP_PLUS_CMIS:
|
||||
+ case SFF8024_ID_SFP_DD_CMIS:
|
||||
+ case SFF8024_ID_SFP_PLUS_CMIS:
|
||||
cmis_show_all_ioctl(id);
|
||||
return;
|
||||
}
|
||||
diff --git a/sff-common.c b/sff-common.c
|
||||
index e951cf1..9e4a89b 100644
|
||||
--- a/sff-common.c
|
||||
+++ b/sff-common.c
|
||||
@@ -145,6 +145,15 @@ void sff8024_show_identifier(const __u8 *id, int id_offset)
|
||||
case SFF8024_ID_DSFP:
|
||||
printf(" (DSFP Dual Small Form Factor Pluggable Transceiver)\n");
|
||||
break;
|
||||
+ case SFF8024_ID_QSFP_PLUS_CMIS:
|
||||
+ printf(" (QSFP+ or later with Common Management Interface Specification (CMIS))\n");
|
||||
+ break;
|
||||
+ case SFF8024_ID_SFP_DD_CMIS:
|
||||
+ printf(" (SFP-DD Double Density 2X Pluggable Transceiver with Common Management Interface Specification (CMIS))\n");
|
||||
+ break;
|
||||
+ case SFF8024_ID_SFP_PLUS_CMIS:
|
||||
+ printf(" (SFP+ and later with Common Management Interface Specification (CMIS))\n");
|
||||
+ break;
|
||||
default:
|
||||
printf(" (reserved or unknown)\n");
|
||||
break;
|
||||
diff --git a/sff-common.h b/sff-common.h
|
||||
index dd12dda..94827cc 100644
|
||||
--- a/sff-common.h
|
||||
+++ b/sff-common.h
|
||||
@@ -64,7 +64,10 @@
|
||||
#define SFF8024_ID_QSFP_DD 0x18
|
||||
#define SFF8024_ID_OSFP 0x19
|
||||
#define SFF8024_ID_DSFP 0x1B
|
||||
-#define SFF8024_ID_LAST SFF8024_ID_DSFP
|
||||
+#define SFF8024_ID_QSFP_PLUS_CMIS 0x1E
|
||||
+#define SFF8024_ID_SFP_DD_CMIS 0x1F
|
||||
+#define SFF8024_ID_SFP_PLUS_CMIS 0x20
|
||||
+#define SFF8024_ID_LAST SFF8024_ID_SFP_PLUS_CMIS
|
||||
#define SFF8024_ID_UNALLOCATED_LAST 0x7F
|
||||
#define SFF8024_ID_VENDOR_START 0x80
|
||||
#define SFF8024_ID_VENDOR_LAST 0xFF
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,431 @@
|
||||
From 48a99d9618acb40c5e9ea49623fe011c57367e18 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:25 +0300
|
||||
Subject: [PATCH 20/26] netlink: eeprom: Defer page requests to individual
|
||||
parsers
|
||||
|
||||
The individual EEPROM parsers (e.g., CMIS, SFF-8636) now request the
|
||||
EEPROM pages they intend to parse and populate their memory maps before
|
||||
parsing them.
|
||||
|
||||
Therefore, there is no need for the common netlink code to request
|
||||
potentially invalid pages and pass them as blobs to these parsers.
|
||||
|
||||
Instead, only query the SFF-8024 Identifier Value which is located at
|
||||
I2C address 0x50, byte 0 and dispatch to the relevant EEPROM parser.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
for SFF-8079, SFF-8636 and CMIS before and after the patch.
|
||||
|
||||
commit: 9538f38
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=9538f384b535
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/module-eeprom.c | 347 +++++++---------------------------------
|
||||
1 file changed, 59 insertions(+), 288 deletions(-)
|
||||
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 6d76b8a..f359aee 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "parser.h"
|
||||
|
||||
#define ETH_I2C_ADDRESS_LOW 0x50
|
||||
-#define ETH_I2C_ADDRESS_HIGH 0x51
|
||||
#define ETH_I2C_MAX_ADDRESS 0x7F
|
||||
|
||||
struct cmd_params {
|
||||
@@ -78,267 +77,6 @@ static const struct param_parser getmodule_params[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
-struct page_entry {
|
||||
- struct list_head link;
|
||||
- struct ethtool_module_eeprom *page;
|
||||
-};
|
||||
-
|
||||
-static struct list_head page_list = LIST_HEAD_INIT(page_list);
|
||||
-
|
||||
-static int cache_add(struct ethtool_module_eeprom *page)
|
||||
-{
|
||||
- struct page_entry *list_element;
|
||||
-
|
||||
- if (!page)
|
||||
- return -1;
|
||||
- list_element = malloc(sizeof(*list_element));
|
||||
- if (!list_element)
|
||||
- return -ENOMEM;
|
||||
- list_element->page = page;
|
||||
-
|
||||
- list_add(&list_element->link, &page_list);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void page_free(struct ethtool_module_eeprom *page)
|
||||
-{
|
||||
- free(page->data);
|
||||
- free(page);
|
||||
-}
|
||||
-
|
||||
-static void cache_del(struct ethtool_module_eeprom *page)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *entry;
|
||||
- struct list_head *head, *next;
|
||||
-
|
||||
- list_for_each_safe(head, next, &page_list) {
|
||||
- entry = ((struct page_entry *)head)->page;
|
||||
- if (entry == page) {
|
||||
- list_del(head);
|
||||
- free(head);
|
||||
- page_free(entry);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void cache_free(void)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *entry;
|
||||
- struct list_head *head, *next;
|
||||
-
|
||||
- list_for_each_safe(head, next, &page_list) {
|
||||
- entry = ((struct page_entry *)head)->page;
|
||||
- list_del(head);
|
||||
- free(head);
|
||||
- page_free(entry);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static struct ethtool_module_eeprom *page_join(struct ethtool_module_eeprom *page_a,
|
||||
- struct ethtool_module_eeprom *page_b)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *joined_page;
|
||||
- u32 total_length;
|
||||
-
|
||||
- if (!page_a || !page_b ||
|
||||
- page_a->page != page_b->page ||
|
||||
- page_a->bank != page_b->bank ||
|
||||
- page_a->i2c_address != page_b->i2c_address)
|
||||
- return NULL;
|
||||
-
|
||||
- total_length = page_a->length + page_b->length;
|
||||
- joined_page = calloc(1, sizeof(*joined_page));
|
||||
- joined_page->data = calloc(1, total_length);
|
||||
- joined_page->page = page_a->page;
|
||||
- joined_page->bank = page_a->bank;
|
||||
- joined_page->length = total_length;
|
||||
- joined_page->i2c_address = page_a->i2c_address;
|
||||
-
|
||||
- if (page_a->offset < page_b->offset) {
|
||||
- memcpy(joined_page->data, page_a->data, page_a->length);
|
||||
- memcpy(joined_page->data + page_a->length, page_b->data, page_b->length);
|
||||
- joined_page->offset = page_a->offset;
|
||||
- } else {
|
||||
- memcpy(joined_page->data, page_b->data, page_b->length);
|
||||
- memcpy(joined_page->data + page_b->length, page_a->data, page_a->length);
|
||||
- joined_page->offset = page_b->offset;
|
||||
- }
|
||||
-
|
||||
- return joined_page;
|
||||
-}
|
||||
-
|
||||
-static struct ethtool_module_eeprom *cache_get(u32 page, u32 bank, u8 i2c_address)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *entry;
|
||||
- struct list_head *head, *next;
|
||||
-
|
||||
- list_for_each_safe(head, next, &page_list) {
|
||||
- entry = ((struct page_entry *)head)->page;
|
||||
- if (entry->page == page && entry->bank == bank &&
|
||||
- entry->i2c_address == i2c_address)
|
||||
- return entry;
|
||||
- }
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
-static int getmodule_page_fetch_reply_cb(const struct nlmsghdr *nlhdr,
|
||||
- void *data)
|
||||
-{
|
||||
- const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {};
|
||||
- DECLARE_ATTR_TB_INFO(tb);
|
||||
- struct ethtool_module_eeprom *lower_page;
|
||||
- struct ethtool_module_eeprom *response;
|
||||
- struct ethtool_module_eeprom *request;
|
||||
- struct ethtool_module_eeprom *joined;
|
||||
- u8 *eeprom_data;
|
||||
- int ret;
|
||||
-
|
||||
- ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA]) {
|
||||
- fprintf(stderr, "Malformed netlink message (getmodule)\n");
|
||||
- return MNL_CB_ERROR;
|
||||
- }
|
||||
-
|
||||
- response = calloc(1, sizeof(*response));
|
||||
- if (!response)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- request = (struct ethtool_module_eeprom *)data;
|
||||
- response->offset = request->offset;
|
||||
- response->page = request->page;
|
||||
- response->bank = request->bank;
|
||||
- response->i2c_address = request->i2c_address;
|
||||
- response->length = mnl_attr_get_payload_len(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
|
||||
- eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
|
||||
-
|
||||
- response->data = malloc(response->length);
|
||||
- if (!response->data) {
|
||||
- free(response);
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
- memcpy(response->data, eeprom_data, response->length);
|
||||
-
|
||||
- if (!request->page) {
|
||||
- lower_page = cache_get(request->page, request->bank, response->i2c_address);
|
||||
- if (lower_page) {
|
||||
- joined = page_join(lower_page, response);
|
||||
- page_free(response);
|
||||
- cache_del(lower_page);
|
||||
- return cache_add(joined);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return cache_add(response);
|
||||
-}
|
||||
-
|
||||
-static int page_fetch(struct nl_context *nlctx, const struct ethtool_module_eeprom *request)
|
||||
-{
|
||||
- struct nl_socket *nlsock = nlctx->ethnl_socket;
|
||||
- struct nl_msg_buff *msg = &nlsock->msgbuff;
|
||||
- struct ethtool_module_eeprom *page;
|
||||
- int ret;
|
||||
-
|
||||
- if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- /* Satisfy request right away, if region is already in cache */
|
||||
- page = cache_get(request->page, request->bank, request->i2c_address);
|
||||
- if (page && page->offset <= request->offset &&
|
||||
- page->offset + page->length >= request->offset + request->length) {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET,
|
||||
- ETHTOOL_A_MODULE_EEPROM_HEADER, 0);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH, request->length) ||
|
||||
- ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET, request->offset) ||
|
||||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE, request->page) ||
|
||||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK, request->bank) ||
|
||||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, request->i2c_address))
|
||||
- return -EMSGSIZE;
|
||||
-
|
||||
- ret = nlsock_sendmsg(nlsock, NULL);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
- ret = nlsock_process_reply(nlsock, getmodule_page_fetch_reply_cb, (void *)request);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- return nlsock_process_reply(nlsock, nomsg_reply_cb, NULL);
|
||||
-}
|
||||
-
|
||||
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
-static int decoder_prefetch(struct nl_context *nlctx)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *page_zero_lower = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
- struct ethtool_module_eeprom request = {0};
|
||||
- u8 module_id = page_zero_lower->data[0];
|
||||
- int err = 0;
|
||||
-
|
||||
- /* Fetch rest of page 00 */
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.offset = 128;
|
||||
- request.length = 128;
|
||||
- err = page_fetch(nlctx, &request);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- switch (module_id) {
|
||||
- case SFF8024_ID_QSFP:
|
||||
- case SFF8024_ID_QSFP28:
|
||||
- case SFF8024_ID_QSFP_PLUS:
|
||||
- memset(&request, 0, sizeof(request));
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.offset = 128;
|
||||
- request.length = 128;
|
||||
- request.page = 3;
|
||||
- break;
|
||||
- case SFF8024_ID_QSFP_DD:
|
||||
- case SFF8024_ID_DSFP:
|
||||
- memset(&request, 0, sizeof(request));
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.offset = 128;
|
||||
- request.length = 128;
|
||||
- request.page = 1;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return page_fetch(nlctx, &request);
|
||||
-}
|
||||
-
|
||||
-static void decoder_print(struct cmd_context *ctx)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
- u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
||||
-
|
||||
- switch (module_id) {
|
||||
- case SFF8024_ID_SFP:
|
||||
- sff8079_show_all_nl(ctx);
|
||||
- break;
|
||||
- case SFF8024_ID_QSFP:
|
||||
- case SFF8024_ID_QSFP28:
|
||||
- case SFF8024_ID_QSFP_PLUS:
|
||||
- sff8636_show_all_nl(ctx);
|
||||
- break;
|
||||
- case SFF8024_ID_QSFP_DD:
|
||||
- case SFF8024_ID_DSFP:
|
||||
- cmis_show_all_nl(ctx);
|
||||
- break;
|
||||
- default:
|
||||
- dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
||||
- break;
|
||||
- }
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list);
|
||||
|
||||
struct eeprom_page_entry {
|
||||
@@ -443,14 +181,64 @@ int nl_get_eeprom_page(struct cmd_context *ctx,
|
||||
(void *)request);
|
||||
}
|
||||
|
||||
+static int eeprom_dump_hex(struct cmd_context *ctx)
|
||||
+{
|
||||
+ struct ethtool_module_eeprom request = {
|
||||
+ .length = 128,
|
||||
+ .i2c_address = ETH_I2C_ADDRESS_LOW,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ dump_hex(stdout, request.data, request.length, request.offset);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int eeprom_parse(struct cmd_context *ctx)
|
||||
+{
|
||||
+ struct ethtool_module_eeprom request = {
|
||||
+ .length = 1,
|
||||
+ .i2c_address = ETH_I2C_ADDRESS_LOW,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Fetch the SFF-8024 Identifier Value. For all supported standards, it
|
||||
+ * is located at I2C address 0x50, byte 0. See section 4.1 in SFF-8024,
|
||||
+ * revision 4.9.
|
||||
+ */
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (request.data[0]) {
|
||||
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
+ case SFF8024_ID_SFP:
|
||||
+ return sff8079_show_all_nl(ctx);
|
||||
+ case SFF8024_ID_QSFP:
|
||||
+ case SFF8024_ID_QSFP28:
|
||||
+ case SFF8024_ID_QSFP_PLUS:
|
||||
+ return sff8636_show_all_nl(ctx);
|
||||
+ case SFF8024_ID_QSFP_DD:
|
||||
+ case SFF8024_ID_DSFP:
|
||||
+ return cmis_show_all_nl(ctx);
|
||||
+#endif
|
||||
+ default:
|
||||
+ /* If we cannot recognize the memory map, default to dumping
|
||||
+ * the first 128 bytes in hex.
|
||||
+ */
|
||||
+ return eeprom_dump_hex(ctx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int nl_getmodule(struct cmd_context *ctx)
|
||||
{
|
||||
struct cmd_params getmodule_cmd_params = {};
|
||||
struct ethtool_module_eeprom request = {0};
|
||||
- struct ethtool_module_eeprom *reply_page;
|
||||
struct nl_context *nlctx = ctx->nlctx;
|
||||
- u32 dump_length;
|
||||
- u8 *eeprom_data;
|
||||
int ret;
|
||||
|
||||
if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_EEPROM_GET, false))
|
||||
@@ -479,12 +267,6 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.length = 128;
|
||||
- ret = page_fetch(nlctx, &request);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
-
|
||||
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
if (getmodule_cmd_params.page || getmodule_cmd_params.bank ||
|
||||
getmodule_cmd_params.offset || getmodule_cmd_params.length)
|
||||
@@ -501,33 +283,22 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
request.offset = 128;
|
||||
|
||||
if (getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) {
|
||||
- ret = page_fetch(nlctx, &request);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
- reply_page = cache_get(request.page, request.bank, request.i2c_address);
|
||||
- if (!reply_page) {
|
||||
- ret = -EINVAL;
|
||||
- goto cleanup;
|
||||
- }
|
||||
|
||||
- eeprom_data = reply_page->data + (request.offset - reply_page->offset);
|
||||
- dump_length = reply_page->length < request.length ? reply_page->length
|
||||
- : request.length;
|
||||
if (getmodule_cmd_params.dump_raw)
|
||||
- fwrite(eeprom_data, 1, request.length, stdout);
|
||||
+ fwrite(request.data, 1, request.length, stdout);
|
||||
else
|
||||
- dump_hex(stdout, eeprom_data, dump_length, request.offset);
|
||||
+ dump_hex(stdout, request.data, request.length,
|
||||
+ request.offset);
|
||||
} else {
|
||||
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
- ret = decoder_prefetch(nlctx);
|
||||
- if (ret)
|
||||
+ ret = eeprom_parse(ctx);
|
||||
+ if (ret < 0)
|
||||
goto cleanup;
|
||||
- decoder_print(ctx);
|
||||
-#endif
|
||||
}
|
||||
|
||||
cleanup:
|
||||
eeprom_page_list_flush();
|
||||
- cache_free();
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,177 @@
|
||||
From 508d443bfdc7e11f478b4d2361621ec90ee4da35 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:21 +0300
|
||||
Subject: [PATCH 16/26] netlink: eeprom: Export a function to request an EEPROM
|
||||
page
|
||||
|
||||
The function will be used by the EEPROM parsing code (e.g., cmis.c) to
|
||||
request a specific page for parsing.
|
||||
|
||||
All the data buffers used to store EEPROM page contents are stored on a
|
||||
linked list that is flushed on exit. This relieves callers from the need
|
||||
to explicitly free the requested pages.
|
||||
|
||||
commit: 2ccda25
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=2ccda2570d65
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/extapi.h | 11 +++++
|
||||
netlink/module-eeprom.c | 105 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 116 insertions(+)
|
||||
|
||||
diff --git a/netlink/extapi.h b/netlink/extapi.h
|
||||
index 91bf02b..129e293 100644
|
||||
--- a/netlink/extapi.h
|
||||
+++ b/netlink/extapi.h
|
||||
@@ -48,6 +48,9 @@ int nl_getmodule(struct cmd_context *ctx);
|
||||
|
||||
void nl_monitor_usage(void);
|
||||
|
||||
+int nl_get_eeprom_page(struct cmd_context *ctx,
|
||||
+ struct ethtool_module_eeprom *request);
|
||||
+
|
||||
#else /* ETHTOOL_ENABLE_NETLINK */
|
||||
|
||||
static inline void netlink_run_handler(struct cmd_context *ctx __maybe_unused,
|
||||
@@ -73,6 +76,14 @@ static inline void nl_monitor_usage(void)
|
||||
{
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused,
|
||||
+ struct ethtool_module_eeprom *request __maybe_unused)
|
||||
+{
|
||||
+ fprintf(stderr, "Netlink not supported by ethtool.\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
#define nl_gset NULL
|
||||
#define nl_sset NULL
|
||||
#define nl_permaddr NULL
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 101d594..ee55088 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -341,6 +341,110 @@ static void decoder_print(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
+static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list);
|
||||
+
|
||||
+struct eeprom_page_entry {
|
||||
+ struct list_head list; /* Member of eeprom_page_list */
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
+static int eeprom_page_list_add(void *data)
|
||||
+{
|
||||
+ struct eeprom_page_entry *entry;
|
||||
+
|
||||
+ entry = malloc(sizeof(*entry));
|
||||
+ if (!entry)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ entry->data = data;
|
||||
+ list_add(&entry->list, &eeprom_page_list);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void eeprom_page_list_flush(void)
|
||||
+{
|
||||
+ struct eeprom_page_entry *entry;
|
||||
+ struct list_head *head, *next;
|
||||
+
|
||||
+ list_for_each_safe(head, next, &eeprom_page_list) {
|
||||
+ entry = (struct eeprom_page_entry *) head;
|
||||
+ free(entry->data);
|
||||
+ list_del(head);
|
||||
+ free(entry);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int get_eeprom_page_reply_cb(const struct nlmsghdr *nlhdr, void *data)
|
||||
+{
|
||||
+ const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {};
|
||||
+ struct ethtool_module_eeprom *request = data;
|
||||
+ DECLARE_ATTR_TB_INFO(tb);
|
||||
+ u8 *eeprom_data;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA])
|
||||
+ return MNL_CB_ERROR;
|
||||
+
|
||||
+ eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
|
||||
+ request->data = malloc(request->length);
|
||||
+ if (!request->data)
|
||||
+ return MNL_CB_ERROR;
|
||||
+ memcpy(request->data, eeprom_data, request->length);
|
||||
+
|
||||
+ ret = eeprom_page_list_add(request->data);
|
||||
+ if (ret < 0)
|
||||
+ goto err_list_add;
|
||||
+
|
||||
+ return MNL_CB_OK;
|
||||
+
|
||||
+err_list_add:
|
||||
+ free(request->data);
|
||||
+ return MNL_CB_ERROR;
|
||||
+}
|
||||
+
|
||||
+int nl_get_eeprom_page(struct cmd_context *ctx,
|
||||
+ struct ethtool_module_eeprom *request)
|
||||
+{
|
||||
+ struct nl_context *nlctx = ctx->nlctx;
|
||||
+ struct nl_socket *nlsock;
|
||||
+ struct nl_msg_buff *msg;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ nlsock = nlctx->ethnl_socket;
|
||||
+ msg = &nlsock->msgbuff;
|
||||
+
|
||||
+ ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET,
|
||||
+ ETHTOOL_A_MODULE_EEPROM_HEADER, 0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH,
|
||||
+ request->length) ||
|
||||
+ ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET,
|
||||
+ request->offset) ||
|
||||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE,
|
||||
+ request->page) ||
|
||||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK,
|
||||
+ request->bank) ||
|
||||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS,
|
||||
+ request->i2c_address))
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ ret = nlsock_sendmsg(nlsock, NULL);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ return nlsock_process_reply(nlsock, get_eeprom_page_reply_cb,
|
||||
+ (void *)request);
|
||||
+}
|
||||
+
|
||||
int nl_getmodule(struct cmd_context *ctx)
|
||||
{
|
||||
struct cmd_params getmodule_cmd_params = {};
|
||||
@@ -425,6 +529,7 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
}
|
||||
|
||||
cleanup:
|
||||
+ eeprom_page_list_flush();
|
||||
cache_free();
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
From b5da70307ffb04f67db2114f62165875fb24cd92 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:24 +0300
|
||||
Subject: [PATCH 19/26] sff-8079: Request specific pages for parsing in netlink
|
||||
path
|
||||
|
||||
Convert the SFF-8079 code to request the required EEPROM contents in the
|
||||
netlink path as was done for CMIS and SFF-8636. It will allow us to
|
||||
remove standard-specific code from the netlink code (i.e.,
|
||||
netlink/module-eeprom.c).
|
||||
|
||||
In addition, in the future, it will allow the netlink path to support
|
||||
parsing of SFF-8472.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
before and after the patch.
|
||||
|
||||
commit: c2170d4
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=c2170d40b6a1
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
internal.h | 2 +-
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
sfpid.c | 20 ++++++++++++++++++--
|
||||
3 files changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/internal.h b/internal.h
|
||||
index 1646e25..c424ef9 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -388,7 +388,7 @@ int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
|
||||
|
||||
/* Module EEPROM parsing code */
|
||||
void sff8079_show_all_ioctl(const __u8 *id);
|
||||
-void sff8079_show_all_nl(const __u8 *id);
|
||||
+int sff8079_show_all_nl(struct cmd_context *ctx);
|
||||
|
||||
/* Optics diagnostics */
|
||||
void sff8472_show_all(const __u8 *id);
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index f04f8e1..6d76b8a 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -321,7 +321,7 @@ static void decoder_print(struct cmd_context *ctx)
|
||||
|
||||
switch (module_id) {
|
||||
case SFF8024_ID_SFP:
|
||||
- sff8079_show_all_nl(page_zero->data);
|
||||
+ sff8079_show_all_nl(ctx);
|
||||
break;
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
diff --git a/sfpid.c b/sfpid.c
|
||||
index c214820..621d1e8 100644
|
||||
--- a/sfpid.c
|
||||
+++ b/sfpid.c
|
||||
@@ -8,8 +8,13 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "sff-common.h"
|
||||
+#include "netlink/extapi.h"
|
||||
+
|
||||
+#define SFF8079_PAGE_SIZE 0x80
|
||||
+#define SFF8079_I2C_ADDRESS_LOW 0x50
|
||||
|
||||
static void sff8079_show_identifier(const __u8 *id)
|
||||
{
|
||||
@@ -445,7 +450,18 @@ void sff8079_show_all_ioctl(const __u8 *id)
|
||||
sff8079_show_all_common(id);
|
||||
}
|
||||
|
||||
-void sff8079_show_all_nl(const __u8 *id)
|
||||
+int sff8079_show_all_nl(struct cmd_context *ctx)
|
||||
{
|
||||
- sff8079_show_all_common(id);
|
||||
+ struct ethtool_module_eeprom request = {
|
||||
+ .length = SFF8079_PAGE_SIZE,
|
||||
+ .i2c_address = SFF8079_I2C_ADDRESS_LOW,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ sff8079_show_all_common(request.data);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
104
backport-sff-8079-Split-SFF-8079-parsing-function.patch
Normal file
104
backport-sff-8079-Split-SFF-8079-parsing-function.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From a9e34753118e1fea1cb5d7dc7ad09b8b66fa926f Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:20 +0300
|
||||
Subject: [PATCH 15/26] sff-8079: Split SFF-8079 parsing function
|
||||
|
||||
SFF-8079, unlike CMIS and SFF-8636, only has a single page and therefore
|
||||
its parsing function (i.e., sff8079_show_all()) is called from both the
|
||||
IOCTL and netlink paths with a buffer pointing to that single page.
|
||||
|
||||
In future patches, the netlink code (i.e., netlink/module-eeprom.c) will
|
||||
no longer call the SFF-8079 code with a buffer pointing to the first 128
|
||||
bytes of the EEPROM. Instead, the SFF-8079 code will need to request the
|
||||
needed EEPROM data, as will be done in CMIS and SFF-8636.
|
||||
|
||||
Therefore, as a preparation for this change, split the main parsing
|
||||
function into IOCTL and netlink variants.
|
||||
|
||||
No functional changes intended.
|
||||
|
||||
commit: 9fdf45c
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=9fdf45ca1726
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
ethtool.c | 4 ++--
|
||||
internal.h | 3 ++-
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
sfpid.c | 12 +++++++++++-
|
||||
4 files changed, 16 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ethtool.c b/ethtool.c
|
||||
index fa5a347..461d1f2 100644
|
||||
--- a/ethtool.c
|
||||
+++ b/ethtool.c
|
||||
@@ -4901,10 +4901,10 @@ static int do_getmodule(struct cmd_context *ctx)
|
||||
switch (modinfo.type) {
|
||||
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
case ETH_MODULE_SFF_8079:
|
||||
- sff8079_show_all(eeprom->data);
|
||||
+ sff8079_show_all_ioctl(eeprom->data);
|
||||
break;
|
||||
case ETH_MODULE_SFF_8472:
|
||||
- sff8079_show_all(eeprom->data);
|
||||
+ sff8079_show_all_ioctl(eeprom->data);
|
||||
sff8472_show_all(eeprom->data);
|
||||
break;
|
||||
case ETH_MODULE_SFF_8436:
|
||||
diff --git a/internal.h b/internal.h
|
||||
index ed4f180..aa033ca 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -387,7 +387,8 @@ int rxclass_rule_ins(struct cmd_context *ctx,
|
||||
int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
|
||||
|
||||
/* Module EEPROM parsing code */
|
||||
-void sff8079_show_all(const __u8 *id);
|
||||
+void sff8079_show_all_ioctl(const __u8 *id);
|
||||
+void sff8079_show_all_nl(const __u8 *id);
|
||||
|
||||
/* Optics diagnostics */
|
||||
void sff8472_show_all(const __u8 *id);
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 18b1abb..101d594 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -323,7 +323,7 @@ static void decoder_print(void)
|
||||
|
||||
switch (module_id) {
|
||||
case SFF8024_ID_SFP:
|
||||
- sff8079_show_all(page_zero->data);
|
||||
+ sff8079_show_all_nl(page_zero->data);
|
||||
break;
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
diff --git a/sfpid.c b/sfpid.c
|
||||
index da2b3f4..c214820 100644
|
||||
--- a/sfpid.c
|
||||
+++ b/sfpid.c
|
||||
@@ -396,7 +396,7 @@ static void sff8079_show_options(const __u8 *id)
|
||||
printf("%s Power level 3 requirement\n", pfx);
|
||||
}
|
||||
|
||||
-void sff8079_show_all(const __u8 *id)
|
||||
+static void sff8079_show_all_common(const __u8 *id)
|
||||
{
|
||||
sff8079_show_identifier(id);
|
||||
if (((id[0] == 0x02) || (id[0] == 0x03)) && (id[1] == 0x04)) {
|
||||
@@ -439,3 +439,13 @@ void sff8079_show_all(const __u8 *id)
|
||||
sff8079_show_ascii(id, 84, 91, "Date code");
|
||||
}
|
||||
}
|
||||
+
|
||||
+void sff8079_show_all_ioctl(const __u8 *id)
|
||||
+{
|
||||
+ sff8079_show_all_common(id);
|
||||
+}
|
||||
+
|
||||
+void sff8079_show_all_nl(const __u8 *id)
|
||||
+{
|
||||
+ sff8079_show_all_common(id);
|
||||
+}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
From f7cad168f8326cee8c9abdf5ed0156c537b057bb Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:19 +0300
|
||||
Subject: [PATCH 14/26] sff-8636: Consolidate code between IOCTL and netlink
|
||||
paths
|
||||
|
||||
Now that both the netlink and IOCTL paths use the same memory map
|
||||
structure for parsing, the code can be easily consolidated.
|
||||
|
||||
Note that the switch-case statement is not necessary for the netlink
|
||||
path, as the netlink code (i.e., netlink/module-eeprom.c) already
|
||||
performed the check, but it is required for the IOCTL path.
|
||||
|
||||
commit: 799572f
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=799572f86647
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 29 +++++++++++++++--------------
|
||||
1 file changed, 15 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 354b3b1..4aa4935 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -898,6 +898,19 @@ static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
|
||||
SFF8636_REV_COMPLIANCE_OFFSET);
|
||||
}
|
||||
|
||||
+static void sff8636_show_all_common(const struct sff8636_memory_map *map)
|
||||
+{
|
||||
+ sff8636_show_identifier(map);
|
||||
+ switch (map->lower_memory[SFF8636_ID_OFFSET]) {
|
||||
+ case SFF8024_ID_QSFP:
|
||||
+ case SFF8024_ID_QSFP_PLUS:
|
||||
+ case SFF8024_ID_QSFP28:
|
||||
+ sff8636_show_page_zero(map);
|
||||
+ sff8636_show_dom(map);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
|
||||
const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
@@ -931,16 +944,7 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
|
||||
sff8636_memory_map_init_buf(&map, id, eeprom_len);
|
||||
-
|
||||
- sff8636_show_identifier(&map);
|
||||
- switch (map.lower_memory[SFF8636_ID_OFFSET]) {
|
||||
- case SFF8024_ID_QSFP:
|
||||
- case SFF8024_ID_QSFP_PLUS:
|
||||
- case SFF8024_ID_QSFP28:
|
||||
- sff8636_show_page_zero(&map);
|
||||
- sff8636_show_dom(&map);
|
||||
- break;
|
||||
- }
|
||||
+ sff8636_show_all_common(&map);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -974,8 +978,5 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
struct sff8636_memory_map map = {};
|
||||
|
||||
sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
-
|
||||
- sff8636_show_identifier(&map);
|
||||
- sff8636_show_page_zero(&map);
|
||||
- sff8636_show_dom(&map);
|
||||
+ sff8636_show_all_common(&map);
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
140
backport-sff-8636-Initialize-SFF-8636-memory-map.patch
Normal file
140
backport-sff-8636-Initialize-SFF-8636-memory-map.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From 10337aa0fa92342e26f430cc50feb8948d55a2ac Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:17 +0300
|
||||
Subject: [PATCH 12/26] sff-8636: Initialize SFF-8636 memory map
|
||||
|
||||
The SFF-8636 memory map [1] consists of Lower Memory and Upper Memory.
|
||||
|
||||
The content of the Lower Memory is fixed and can be addressed using an
|
||||
offset between 0 and 127 (inclusive).
|
||||
|
||||
The Upper Memory is variable and optional and can be addressed by
|
||||
specifying a page number and an offset between 128 and 255 (inclusive).
|
||||
|
||||
Create a structure describing this memory map and initialize it with
|
||||
pointers to available pages.
|
||||
|
||||
In the IOCTL path, the structure holds pointers to regions of the
|
||||
continuous buffer passed to user space via the 'ETHTOOL_GMODULEEEPROM'
|
||||
command.
|
||||
|
||||
In the netlink path, the structure holds pointers to individual pages
|
||||
passed to user space via the 'MODULE_EEPROM_GET' message.
|
||||
|
||||
This structure will later allow us to consolidate the IOCTL and netlink
|
||||
parsing code paths and also easily support additional EEPROM pages, when
|
||||
needed.
|
||||
|
||||
[1] SFF-8636 Rev. 2.10a, pag. 30, section 6.1, Figure 6-1
|
||||
|
||||
commit: 4230597
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=4230597fe952
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 65 insertions(+)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index dc6407d..80000d4 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -60,6 +60,15 @@
|
||||
#include "qsfp.h"
|
||||
#include "cmis.h"
|
||||
|
||||
+struct sff8636_memory_map {
|
||||
+ const __u8 *lower_memory;
|
||||
+ const __u8 *upper_memory[4];
|
||||
+#define page_00h upper_memory[0x0]
|
||||
+#define page_03h upper_memory[0x3]
|
||||
+};
|
||||
+
|
||||
+#define SFF8636_PAGE_SIZE 0x80
|
||||
+
|
||||
#define MAX_DESC_SIZE 42
|
||||
|
||||
static struct sff8636_aw_flags {
|
||||
@@ -853,13 +862,40 @@ static void sff8636_show_page_zero(const __u8 *id)
|
||||
|
||||
}
|
||||
|
||||
+static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
|
||||
+ const __u8 *id, __u32 eeprom_len)
|
||||
+{
|
||||
+ /* Lower Memory and Page 00h are always present.
|
||||
+ *
|
||||
+ * Offset into Upper Memory is between page size and twice the page
|
||||
+ * size. Therefore, set the base address of each page to base address
|
||||
+ * plus page size multiplied by the page number.
|
||||
+ */
|
||||
+ map->lower_memory = id;
|
||||
+ map->page_00h = id;
|
||||
+
|
||||
+ /* Page 03h is only present when the module memory model is paged and
|
||||
+ * not flat and when we got a big enough buffer from the kernel.
|
||||
+ */
|
||||
+ if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
||||
+ SFF8636_STATUS_PAGE_3_PRESENT ||
|
||||
+ eeprom_len != ETH_MODULE_SFF_8636_MAX_LEN)
|
||||
+ return;
|
||||
+
|
||||
+ map->page_03h = id + 3 * SFF8636_PAGE_SIZE;
|
||||
+}
|
||||
+
|
||||
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
+ struct sff8636_memory_map map = {};
|
||||
+
|
||||
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
cmis_show_all_ioctl(id);
|
||||
return;
|
||||
}
|
||||
|
||||
+ sff8636_memory_map_init_buf(&map, id, eeprom_len);
|
||||
+
|
||||
sff8636_show_identifier(id);
|
||||
switch (id[SFF8636_ID_OFFSET]) {
|
||||
case SFF8024_ID_QSFP:
|
||||
@@ -871,9 +907,38 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
|
||||
+ const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_three)
|
||||
+{
|
||||
+ /* Lower Memory and Page 00h are always present.
|
||||
+ *
|
||||
+ * Offset into Upper Memory is between page size and twice the page
|
||||
+ * size. Therefore, set the base address of each page to its base
|
||||
+ * address minus page size. For Page 00h, this is the address of the
|
||||
+ * Lower Memory.
|
||||
+ */
|
||||
+ map->lower_memory = page_zero->data;
|
||||
+ map->page_00h = page_zero->data;
|
||||
+
|
||||
+ /* Page 03h is only present when the module memory model is paged and
|
||||
+ * not flat.
|
||||
+ */
|
||||
+ if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
||||
+ SFF8636_STATUS_PAGE_3_PRESENT)
|
||||
+ return;
|
||||
+
|
||||
+ map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
|
||||
+}
|
||||
+
|
||||
void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
const struct ethtool_module_eeprom *page_three)
|
||||
{
|
||||
+ struct sff8636_memory_map map = {};
|
||||
+
|
||||
+ sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
+
|
||||
sff8636_show_identifier(page_zero->data);
|
||||
sff8636_show_page_zero(page_zero->data);
|
||||
if (page_three)
|
||||
--
|
||||
2.30.0
|
||||
|
||||
111
backport-sff-8636-Print-Power-set-and-Power-override-bits.patch
Normal file
111
backport-sff-8636-Print-Power-set-and-Power-override-bits.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From d306db1bab15361f36d967800c4f8dd7e3f2ee3b Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:41:02 +0200
|
||||
Subject: [PATCH 23/26] sff-8636: Print Power set and Power override bits
|
||||
|
||||
Print the SFF-8636 Power set and Power override bits when dumping EEPROM
|
||||
contents via the '-m' option. They can be used to understand low power
|
||||
mode enforcement by the host.
|
||||
|
||||
The 'SFF8636_LOW_PWR_MODE' define is renamed to 'SFF8636_LOW_PWR_SET' to
|
||||
reflect its naming in the standard for QSFP+/QSFP28.
|
||||
|
||||
Example output:
|
||||
|
||||
# ethtool -m swp13
|
||||
Identifier : 0x11 (QSFP28)
|
||||
...
|
||||
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) enabled
|
||||
Power set : Off
|
||||
Power override : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.7633 mW / -1.17 dBm
|
||||
Transmit avg optical power (Channel 2) : 0.7649 mW / -1.16 dBm
|
||||
Transmit avg optical power (Channel 3) : 0.7696 mW / -1.14 dBm
|
||||
Transmit avg optical power (Channel 4) : 0.7739 mW / -1.11 dBm
|
||||
Rcvr signal avg optical power(Channel 1) : 0.9240 mW / -0.34 dBm
|
||||
Rcvr signal avg optical power(Channel 2) : 0.9129 mW / -0.40 dBm
|
||||
Rcvr signal avg optical power(Channel 3) : 0.9194 mW / -0.36 dBm
|
||||
Rcvr signal avg optical power(Channel 4) : 0.8708 mW / -0.60 dBm
|
||||
|
||||
# ethtool --set-module swp13 power-mode-policy auto
|
||||
|
||||
# ethtool -m swp13
|
||||
Identifier : 0x11 (QSFP28)
|
||||
...
|
||||
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) not enabled
|
||||
Power set : On
|
||||
Power override : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.0000 mW / -inf dBm
|
||||
Transmit avg optical power (Channel 2) : 0.0000 mW / -inf dBm
|
||||
Transmit avg optical power (Channel 3) : 0.0000 mW / -inf dBm
|
||||
Transmit avg optical power (Channel 4) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 1) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 2) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 3) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 4) : 0.0000 mW / -inf dBm
|
||||
|
||||
# ethtool --set-module swp13 power-mode-policy high
|
||||
|
||||
# ethtool -m swp13
|
||||
Identifier : 0x11 (QSFP28)
|
||||
...
|
||||
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) enabled
|
||||
Power set : Off
|
||||
Power override : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.7733 mW / -1.12 dBm
|
||||
Transmit avg optical power (Channel 2) : 0.7754 mW / -1.10 dBm
|
||||
Transmit avg optical power (Channel 3) : 0.7885 mW / -1.03 dBm
|
||||
Transmit avg optical power (Channel 4) : 0.7886 mW / -1.03 dBm
|
||||
Rcvr signal avg optical power(Channel 1) : 0.9248 mW / -0.34 dBm
|
||||
Rcvr signal avg optical power(Channel 2) : 0.9129 mW / -0.40 dBm
|
||||
Rcvr signal avg optical power(Channel 3) : 0.9187 mW / -0.37 dBm
|
||||
Rcvr signal avg optical power(Channel 4) : 0.8785 mW / -0.56 dBm
|
||||
|
||||
In the above example, the LPMode signal is ignored (Power override is
|
||||
always on) and low power mode is controlled via software only.
|
||||
|
||||
commit: d7b1007
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=d7b100713f73
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 6 ++++++
|
||||
qsfp.h | 2 +-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index b3c9e15..57aac86 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -268,6 +268,12 @@ static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
|
||||
printf(" High Power Class (> 3.5 W) enabled\n");
|
||||
else
|
||||
printf(" High Power Class (> 3.5 W) not enabled\n");
|
||||
+ printf("\t%-41s : ", "Power set");
|
||||
+ printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
|
||||
+ SFF8636_LOW_PWR_SET));
|
||||
+ printf("\t%-41s : ", "Power override");
|
||||
+ printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
|
||||
+ SFF8636_PWR_OVERRIDE));
|
||||
}
|
||||
|
||||
static void sff8636_show_connector(const struct sff8636_memory_map *map)
|
||||
diff --git a/qsfp.h b/qsfp.h
|
||||
index 1d8f24b..aabf09f 100644
|
||||
--- a/qsfp.h
|
||||
+++ b/qsfp.h
|
||||
@@ -180,7 +180,7 @@
|
||||
|
||||
#define SFF8636_PWR_MODE_OFFSET 0x5D
|
||||
#define SFF8636_HIGH_PWR_ENABLE (1 << 2)
|
||||
-#define SFF8636_LOW_PWR_MODE (1 << 1)
|
||||
+#define SFF8636_LOW_PWR_SET (1 << 1)
|
||||
#define SFF8636_PWR_OVERRIDE (1 << 0)
|
||||
|
||||
#define SFF8636_TX_APP_SELECT_4_OFFSET 0x5E
|
||||
--
|
||||
2.30.0
|
||||
|
||||
100
backport-sff-8636-Rename-SFF-8636-parsing-functions.patch
Normal file
100
backport-sff-8636-Rename-SFF-8636-parsing-functions.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From e54061aec49839249b00562b812f8dd6912bdef5 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:16 +0300
|
||||
Subject: [PATCH 11/26] sff-8636: Rename SFF-8636 parsing functions
|
||||
|
||||
Currently, there are two SFF-8636 parsing functions. sff8636_show_all()
|
||||
and sff8636_show_all_paged(). The former is called from the IOCTL path
|
||||
with a buffer containing EEPROM contents and the latter is called from
|
||||
the netlink path with pointer to individual EEPROM pages.
|
||||
|
||||
Rename them with '_ioctl' and '_nl' suffixes to make the distinction
|
||||
clear.
|
||||
|
||||
In subsequent patches, these two functions will only differ in the way
|
||||
they initialize the SFF-8636 memory map for parsing, while the parsing
|
||||
code itself will be shared between the two.
|
||||
|
||||
commit: d7d15f7
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=d7d15f737ab7
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
ethtool.c | 4 ++--
|
||||
internal.h | 6 +++---
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
qsfp.c | 6 +++---
|
||||
4 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/ethtool.c b/ethtool.c
|
||||
index 7652440..fa5a347 100644
|
||||
--- a/ethtool.c
|
||||
+++ b/ethtool.c
|
||||
@@ -4909,8 +4909,8 @@ static int do_getmodule(struct cmd_context *ctx)
|
||||
break;
|
||||
case ETH_MODULE_SFF_8436:
|
||||
case ETH_MODULE_SFF_8636:
|
||||
- sff8636_show_all(eeprom->data,
|
||||
- modinfo.eeprom_len);
|
||||
+ sff8636_show_all_ioctl(eeprom->data,
|
||||
+ modinfo.eeprom_len);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
diff --git a/internal.h b/internal.h
|
||||
index a30f76e..ed4f180 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -393,9 +393,9 @@ void sff8079_show_all(const __u8 *id);
|
||||
void sff8472_show_all(const __u8 *id);
|
||||
|
||||
/* QSFP Optics diagnostics */
|
||||
-void sff8636_show_all(const __u8 *id, __u32 eeprom_len);
|
||||
-void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three);
|
||||
+void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
|
||||
+void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_three);
|
||||
|
||||
/* 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 fc4ef1a..18b1abb 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -328,7 +328,7 @@ static void decoder_print(void)
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
- sff8636_show_all_paged(page_zero, page_three);
|
||||
+ sff8636_show_all_nl(page_zero, page_three);
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 27fdd3b..dc6407d 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -853,7 +853,7 @@ static void sff8636_show_page_zero(const __u8 *id)
|
||||
|
||||
}
|
||||
|
||||
-void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
+void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
cmis_show_all_ioctl(id);
|
||||
@@ -871,8 +871,8 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
}
|
||||
|
||||
-void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three)
|
||||
+void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_three)
|
||||
{
|
||||
sff8636_show_identifier(page_zero->data);
|
||||
sff8636_show_page_zero(page_zero->data);
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,184 @@
|
||||
From 25c34d626d39d80cb7abacddd81191c006dbe57c Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:23 +0300
|
||||
Subject: [PATCH 18/26] sff-8636: Request specific pages for parsing in netlink
|
||||
path
|
||||
|
||||
In the netlink path, unlike the IOCTL path, user space requests specific
|
||||
EEPROM pages from the kernel. The presence of optional pages is
|
||||
advertised via various bits in the EEPROM contents.
|
||||
|
||||
Currently, for SFF-8636, the Lower Memory, Page 00h and the optional
|
||||
Page 03h are requested by the netlink code (i.e.,
|
||||
netlink/module-eeprom.c) and passed to the SFF-8636 code (i.e., qsfp.c)
|
||||
as two arguments for parsing.
|
||||
|
||||
This is problematic for several reasons. First, this approach is not
|
||||
very scaleable as SFF-8636 supports a lot of optional pages. Passing
|
||||
them as separate arguments to the SFF-8636 code is not going to work.
|
||||
|
||||
Second, the knowledge of which optional pages are available is
|
||||
encapsulated in the SFF-8636 parsing code. As such, the common netlink
|
||||
code has no business of fetching optional pages that might be invalid.
|
||||
|
||||
Instead, pass the command context to the SFF-8636 parsing function and
|
||||
allow it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
|
||||
message.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
before and after the patch.
|
||||
|
||||
commit: 6e2b32a
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=6e2b32a0d0ea
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
internal.h | 3 +--
|
||||
netlink/module-eeprom.c | 3 +--
|
||||
qsfp.c | 60 ++++++++++++++++++++++++++++++++---------
|
||||
3 files changed, 49 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/internal.h b/internal.h
|
||||
index aa033ca..1646e25 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -395,8 +395,7 @@ void sff8472_show_all(const __u8 *id);
|
||||
|
||||
/* QSFP Optics diagnostics */
|
||||
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
|
||||
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three);
|
||||
+int sff8636_show_all_nl(struct cmd_context *ctx);
|
||||
|
||||
/* 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 a8e2662..f04f8e1 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -316,7 +316,6 @@ static int decoder_prefetch(struct nl_context *nlctx)
|
||||
|
||||
static void decoder_print(struct cmd_context *ctx)
|
||||
{
|
||||
- struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
|
||||
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
||||
|
||||
@@ -327,7 +326,7 @@ static void decoder_print(struct cmd_context *ctx)
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
- sff8636_show_all_nl(page_zero, page_three);
|
||||
+ sff8636_show_all_nl(ctx);
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 4aa4935..e7c2f51 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -55,10 +55,12 @@
|
||||
**/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
+#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "sff-common.h"
|
||||
#include "qsfp.h"
|
||||
#include "cmis.h"
|
||||
+#include "netlink/extapi.h"
|
||||
|
||||
struct sff8636_memory_map {
|
||||
const __u8 *lower_memory;
|
||||
@@ -68,6 +70,7 @@ struct sff8636_memory_map {
|
||||
};
|
||||
|
||||
#define SFF8636_PAGE_SIZE 0x80
|
||||
+#define SFF8636_I2C_ADDRESS 0x50
|
||||
|
||||
#define MAX_DESC_SIZE 42
|
||||
|
||||
@@ -947,36 +950,67 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
sff8636_show_all_common(&map);
|
||||
}
|
||||
|
||||
-static void
|
||||
-sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
|
||||
- const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three)
|
||||
+static void sff8636_request_init(struct ethtool_module_eeprom *request, u8 page,
|
||||
+ u32 offset)
|
||||
+{
|
||||
+ request->offset = offset;
|
||||
+ request->length = SFF8636_PAGE_SIZE;
|
||||
+ request->page = page;
|
||||
+ request->bank = 0;
|
||||
+ request->i2c_address = SFF8636_I2C_ADDRESS;
|
||||
+ request->data = NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sff8636_memory_map_init_pages(struct cmd_context *ctx,
|
||||
+ struct sff8636_memory_map *map)
|
||||
{
|
||||
+ struct ethtool_module_eeprom request;
|
||||
+ int ret;
|
||||
+
|
||||
/* Lower Memory and Page 00h are always present.
|
||||
*
|
||||
* Offset into Upper Memory is between page size and twice the page
|
||||
* size. Therefore, set the base address of each page to its base
|
||||
- * address minus page size. For Page 00h, this is the address of the
|
||||
- * Lower Memory.
|
||||
+ * address minus page size.
|
||||
*/
|
||||
- map->lower_memory = page_zero->data;
|
||||
- map->page_00h = page_zero->data;
|
||||
+ sff8636_request_init(&request, 0x0, 0);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->lower_memory = request.data;
|
||||
+
|
||||
+ sff8636_request_init(&request, 0x0, SFF8636_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_00h = request.data - SFF8636_PAGE_SIZE;
|
||||
|
||||
/* Page 03h is only present when the module memory model is paged and
|
||||
* not flat.
|
||||
*/
|
||||
if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
||||
SFF8636_STATUS_PAGE_3_PRESENT)
|
||||
- return;
|
||||
+ return 0;
|
||||
|
||||
- map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
|
||||
+ sff8636_request_init(&request, 0x3, SFF8636_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_03h = request.data - SFF8636_PAGE_SIZE;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three)
|
||||
+int sff8636_show_all_nl(struct cmd_context *ctx)
|
||||
{
|
||||
struct sff8636_memory_map map = {};
|
||||
+ int ret;
|
||||
|
||||
- sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
+ ret = sff8636_memory_map_init_pages(ctx, &map);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
sff8636_show_all_common(&map);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
From 57543639e3a8b10142726afc7e277d257f902283 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:40:55 +0200
|
||||
Subject: [PATCH 21/26] sff-8636: Use an SFF-8636 specific define for maximum
|
||||
number of channels
|
||||
|
||||
'MAX_CHANNEL_NUM' is defined in the common SFF code as 4 and used to set
|
||||
the size of the per-channel diagnostics array in the common 'sff_diags'
|
||||
structure.
|
||||
|
||||
The CMIS parsing code is also going to use the structure, but it can
|
||||
have up to 32 channels, unlike SFF-8636 that only has 4.
|
||||
|
||||
Therefore, set 'MAX_CHANNEL_NUM' to 32 and change the SFF-8636 code to
|
||||
use an SFF-8636 specific define instead of the common 'MAX_CHANNEL_NUM'.
|
||||
|
||||
commit: 73091cd
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=73091cd94023
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 9 +++++----
|
||||
sff-common.h | 2 +-
|
||||
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index e7c2f51..58c4c47 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -71,6 +71,7 @@ struct sff8636_memory_map {
|
||||
|
||||
#define SFF8636_PAGE_SIZE 0x80
|
||||
#define SFF8636_I2C_ADDRESS 0x50
|
||||
+#define SFF8636_MAX_CHANNEL_NUM 4
|
||||
|
||||
#define MAX_DESC_SIZE 42
|
||||
|
||||
@@ -761,7 +762,7 @@ static void sff8636_dom_parse(const struct sff8636_memory_map *map,
|
||||
|
||||
out:
|
||||
/* Channel Specific Data */
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
u8 rx_power_offset, tx_bias_offset;
|
||||
u8 tx_power_offset;
|
||||
|
||||
@@ -832,13 +833,13 @@ static void sff8636_show_dom(const struct sff8636_memory_map *map)
|
||||
printf("\t%-41s : %s\n", "Alarm/warning flags implemented",
|
||||
(sd.supports_alarms ? "Yes" : "No"));
|
||||
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)",
|
||||
"Laser tx bias current", i+1);
|
||||
PRINT_BIAS(power_string, sd.scd[i].bias_cur);
|
||||
}
|
||||
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)",
|
||||
"Transmit avg optical power", i+1);
|
||||
PRINT_xX_PWR(power_string, sd.scd[i].tx_power);
|
||||
@@ -849,7 +850,7 @@ static void sff8636_show_dom(const struct sff8636_memory_map *map)
|
||||
else
|
||||
rx_power_string = "Rcvr signal avg optical power";
|
||||
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
snprintf(power_string, MAX_DESC_SIZE, "%s(Channel %d)",
|
||||
rx_power_string, i+1);
|
||||
PRINT_xX_PWR(power_string, sd.scd[i].rx_power);
|
||||
diff --git a/sff-common.h b/sff-common.h
|
||||
index 2183f41..aab306e 100644
|
||||
--- a/sff-common.h
|
||||
+++ b/sff-common.h
|
||||
@@ -160,7 +160,7 @@ struct sff_channel_diags {
|
||||
/* Module Monitoring Fields */
|
||||
struct sff_diags {
|
||||
|
||||
-#define MAX_CHANNEL_NUM 4
|
||||
+#define MAX_CHANNEL_NUM 32
|
||||
#define LWARN 0
|
||||
#define HWARN 1
|
||||
#define LALRM 2
|
||||
--
|
||||
2.30.0
|
||||
|
||||
610
backport-sff-8636-Use-memory-map-during-parsing.patch
Normal file
610
backport-sff-8636-Use-memory-map-during-parsing.patch
Normal file
@ -0,0 +1,610 @@
|
||||
From 3926a20160a6c817df272e6ab443415a43c65470 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:18 +0300
|
||||
Subject: [PATCH 13/26] sff-8636: Use memory map during parsing
|
||||
|
||||
Instead of passing one large buffer to the individual parsing functions,
|
||||
use the memory map structure from the previous patch.
|
||||
|
||||
This has the added benefit of checking which optional pages are actually
|
||||
available and it will also allow us to consolidate the IOCTL and netlink
|
||||
parsing code paths.
|
||||
|
||||
Tested by making sure that there are no differences in output in both
|
||||
the IOCTL and netlink paths before and after the patch.
|
||||
|
||||
commit: b74c040
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=b74c040256de
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 368 +++++++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 201 insertions(+), 167 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 80000d4..354b3b1 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -205,20 +205,21 @@ static struct sff8636_aw_flags {
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
-static void sff8636_show_identifier(const __u8 *id)
|
||||
+static void sff8636_show_identifier(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8024_show_identifier(id, SFF8636_ID_OFFSET);
|
||||
+ sff8024_show_identifier(map->lower_memory, SFF8636_ID_OFFSET);
|
||||
}
|
||||
|
||||
-static void sff8636_show_ext_identifier(const __u8 *id)
|
||||
+static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
|
||||
{
|
||||
printf("\t%-41s : 0x%02x\n", "Extended identifier",
|
||||
- id[SFF8636_EXT_ID_OFFSET]);
|
||||
+ map->page_00h[SFF8636_EXT_ID_OFFSET]);
|
||||
|
||||
static const char *pfx =
|
||||
"\tExtended identifier description :";
|
||||
|
||||
- switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_PWR_CLASS_MASK) {
|
||||
+ switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
|
||||
+ SFF8636_EXT_ID_PWR_CLASS_MASK) {
|
||||
case SFF8636_EXT_ID_PWR_CLASS_1:
|
||||
printf("%s 1.5W max. Power consumption\n", pfx);
|
||||
break;
|
||||
@@ -233,17 +234,18 @@ static void sff8636_show_ext_identifier(const __u8 *id)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
|
||||
+ if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
|
||||
printf("%s CDR present in TX,", pfx);
|
||||
else
|
||||
printf("%s No CDR in TX,", pfx);
|
||||
|
||||
- if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
|
||||
+ if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
|
||||
printf(" CDR present in RX\n");
|
||||
else
|
||||
printf(" No CDR in RX\n");
|
||||
|
||||
- switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_EPWR_CLASS_MASK) {
|
||||
+ switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
|
||||
+ SFF8636_EXT_ID_EPWR_CLASS_MASK) {
|
||||
case SFF8636_EXT_ID_PWR_CLASS_LEGACY:
|
||||
printf("%s", pfx);
|
||||
break;
|
||||
@@ -257,18 +259,19 @@ static void sff8636_show_ext_identifier(const __u8 *id)
|
||||
printf("%s 5.0W max. Power consumption, ", pfx);
|
||||
break;
|
||||
}
|
||||
- if (id[SFF8636_PWR_MODE_OFFSET] & SFF8636_HIGH_PWR_ENABLE)
|
||||
+ if (map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
|
||||
+ SFF8636_HIGH_PWR_ENABLE)
|
||||
printf(" High Power Class (> 3.5 W) enabled\n");
|
||||
else
|
||||
printf(" High Power Class (> 3.5 W) not enabled\n");
|
||||
}
|
||||
|
||||
-static void sff8636_show_connector(const __u8 *id)
|
||||
+static void sff8636_show_connector(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8024_show_connector(id, SFF8636_CTOR_OFFSET);
|
||||
+ sff8024_show_connector(map->page_00h, SFF8636_CTOR_OFFSET);
|
||||
}
|
||||
|
||||
-static void sff8636_show_transceiver(const __u8 *id)
|
||||
+static void sff8636_show_transceiver(const struct sff8636_memory_map *map)
|
||||
{
|
||||
static const char *pfx =
|
||||
"\tTransceiver type :";
|
||||
@@ -276,33 +279,41 @@ static void sff8636_show_transceiver(const __u8 *id)
|
||||
printf("\t%-41s : 0x%02x 0x%02x 0x%02x " \
|
||||
"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
"Transceiver codes",
|
||||
- id[SFF8636_ETHERNET_COMP_OFFSET],
|
||||
- id[SFF8636_SONET_COMP_OFFSET],
|
||||
- id[SFF8636_SAS_COMP_OFFSET],
|
||||
- id[SFF8636_GIGE_COMP_OFFSET],
|
||||
- id[SFF8636_FC_LEN_OFFSET],
|
||||
- id[SFF8636_FC_TECH_OFFSET],
|
||||
- id[SFF8636_FC_TRANS_MEDIA_OFFSET],
|
||||
- id[SFF8636_FC_SPEED_OFFSET]);
|
||||
+ map->page_00h[SFF8636_ETHERNET_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_SONET_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_SAS_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_GIGE_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_LEN_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_TECH_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_SPEED_OFFSET]);
|
||||
|
||||
/* 10G/40G Ethernet Compliance Codes */
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LRM)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_10G_LRM)
|
||||
printf("%s 10G Ethernet: 10G Base-LRM\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LR)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_10G_LR)
|
||||
printf("%s 10G Ethernet: 10G Base-LR\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_SR)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_10G_SR)
|
||||
printf("%s 10G Ethernet: 10G Base-SR\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_CR4)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_CR4)
|
||||
printf("%s 40G Ethernet: 40G Base-CR4\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_SR4)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_SR4)
|
||||
printf("%s 40G Ethernet: 40G Base-SR4\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_LR4)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_LR4)
|
||||
printf("%s 40G Ethernet: 40G Base-LR4\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_ACTIVE)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_ACTIVE)
|
||||
printf("%s 40G Ethernet: 40G Active Cable (XLPPI)\n", pfx);
|
||||
/* Extended Specification Compliance Codes from SFF-8024 */
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_RSRVD) {
|
||||
- switch (id[SFF8636_OPTION_1_OFFSET]) {
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_RSRVD) {
|
||||
+ switch (map->page_00h[SFF8636_OPTION_1_OFFSET]) {
|
||||
case SFF8636_ETHERNET_UNSPECIFIED:
|
||||
printf("%s (reserved or unknown)\n", pfx);
|
||||
break;
|
||||
@@ -493,113 +504,122 @@ static void sff8636_show_transceiver(const __u8 *id)
|
||||
}
|
||||
|
||||
/* SONET Compliance Codes */
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_40G_OTN))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] &
|
||||
+ (SFF8636_SONET_40G_OTN))
|
||||
printf("%s 40G OTN (OTU3B/OTU3C)\n", pfx);
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
|
||||
printf("%s SONET: OC-48, long reach\n", pfx);
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
|
||||
printf("%s SONET: OC-48, intermediate reach\n", pfx);
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
|
||||
printf("%s SONET: OC-48, short reach\n", pfx);
|
||||
|
||||
/* SAS/SATA Compliance Codes */
|
||||
- if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
|
||||
+ if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
|
||||
printf("%s SAS 6.0G\n", pfx);
|
||||
- if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
|
||||
+ if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
|
||||
printf("%s SAS 3.0G\n", pfx);
|
||||
|
||||
/* Ethernet Compliance Codes */
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
|
||||
printf("%s Ethernet: 1000BASE-T\n", pfx);
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
|
||||
printf("%s Ethernet: 1000BASE-CX\n", pfx);
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
|
||||
printf("%s Ethernet: 1000BASE-LX\n", pfx);
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
|
||||
printf("%s Ethernet: 1000BASE-SX\n", pfx);
|
||||
|
||||
/* Fibre Channel link length */
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
|
||||
printf("%s FC: very long distance (V)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
|
||||
printf("%s FC: short distance (S)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
|
||||
printf("%s FC: intermediate distance (I)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
|
||||
printf("%s FC: long distance (L)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
|
||||
printf("%s FC: medium distance (M)\n", pfx);
|
||||
|
||||
/* Fibre Channel transmitter technology */
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
|
||||
printf("%s FC: Longwave laser (LC)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
|
||||
printf("%s FC: Electrical inter-enclosure (EL)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
|
||||
printf("%s FC: Electrical intra-enclosure (EL)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_WO_OFC)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] &
|
||||
+ SFF8636_FC_TECH_SHORT_WO_OFC)
|
||||
printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
|
||||
printf("%s FC: Shortwave laser with OFC (SL)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
|
||||
printf("%s FC: Longwave laser (LL)\n", pfx);
|
||||
|
||||
/* Fibre Channel transmission media */
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TW)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_TW)
|
||||
printf("%s FC: Twin Axial Pair (TW)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TP)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_TP)
|
||||
printf("%s FC: Twisted Pair (TP)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_MI)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_MI)
|
||||
printf("%s FC: Miniature Coax (MI)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TV)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_TV)
|
||||
printf("%s FC: Video Coax (TV)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M6)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_M6)
|
||||
printf("%s FC: Multimode, 62.5m (M6)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M5)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_M5)
|
||||
printf("%s FC: Multimode, 50m (M5)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_OM3)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_OM3)
|
||||
printf("%s FC: Multimode, 50um (OM3)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_SM)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_SM)
|
||||
printf("%s FC: Single Mode (SM)\n", pfx);
|
||||
|
||||
/* Fibre Channel speed */
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
|
||||
printf("%s FC: 1200 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
|
||||
printf("%s FC: 800 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
|
||||
printf("%s FC: 1600 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
|
||||
printf("%s FC: 400 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
|
||||
printf("%s FC: 200 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
|
||||
printf("%s FC: 100 MBytes/sec\n", pfx);
|
||||
}
|
||||
|
||||
-static void sff8636_show_encoding(const __u8 *id)
|
||||
+static void sff8636_show_encoding(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8024_show_encoding(id, SFF8636_ENCODING_OFFSET, ETH_MODULE_SFF_8636);
|
||||
+ sff8024_show_encoding(map->page_00h, SFF8636_ENCODING_OFFSET,
|
||||
+ ETH_MODULE_SFF_8636);
|
||||
}
|
||||
|
||||
-static void sff8636_show_rate_identifier(const __u8 *id)
|
||||
+static void sff8636_show_rate_identifier(const struct sff8636_memory_map *map)
|
||||
{
|
||||
/* TODO: Need to fix rate select logic */
|
||||
printf("\t%-41s : 0x%02x\n", "Rate identifier",
|
||||
- id[SFF8636_EXT_RS_OFFSET]);
|
||||
+ map->page_00h[SFF8636_EXT_RS_OFFSET]);
|
||||
}
|
||||
|
||||
-static void sff8636_show_oui(const __u8 *id, int id_offset)
|
||||
-{
|
||||
- sff8024_show_oui(id, id_offset);
|
||||
-}
|
||||
-
|
||||
-static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
|
||||
+static void
|
||||
+sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *map)
|
||||
{
|
||||
printf("\t%-41s : 0x%02x", "Transmitter technology",
|
||||
- (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK));
|
||||
+ map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
|
||||
+ SFF8636_TRANS_TECH_MASK);
|
||||
|
||||
- switch (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK) {
|
||||
+ switch (map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
|
||||
+ SFF8636_TRANS_TECH_MASK) {
|
||||
case SFF8636_TRANS_850_VCSEL:
|
||||
printf(" (850 nm VCSEL)\n");
|
||||
break;
|
||||
@@ -650,31 +670,26 @@ static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK)
|
||||
- >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
|
||||
+ if ((map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
|
||||
+ SFF8636_TRANS_TECH_MASK) >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 2.5GHz",
|
||||
- id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 5.0GHz",
|
||||
- id[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 7.0GHz",
|
||||
- id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
|
||||
- id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
|
||||
} else {
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
|
||||
- (((id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
|
||||
- id[SFF8636_WAVELEN_LOW_BYTE_OFFSET])*0.05));
|
||||
+ (((map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
|
||||
+ map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]) * 0.05));
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
|
||||
- (((id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
|
||||
- id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET])*0.005));
|
||||
+ (((map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
|
||||
+ map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]) * 0.005));
|
||||
}
|
||||
}
|
||||
|
||||
-static void sff8636_show_revision_compliance(const __u8 *id)
|
||||
-{
|
||||
- sff_show_revision_compliance(id, SFF8636_REV_COMPLIANCE_OFFSET);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* 2-byte internal temperature conversions:
|
||||
* First byte is a signed 8-bit integer, which is the temp decimal part
|
||||
@@ -683,39 +698,65 @@ static void sff8636_show_revision_compliance(const __u8 *id)
|
||||
#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
|
||||
#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
|
||||
|
||||
-static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff_diags *sd)
|
||||
+static void sff8636_dom_parse(const struct sff8636_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
{
|
||||
+ const __u8 *id = map->lower_memory;
|
||||
int i = 0;
|
||||
|
||||
/* Monitoring Thresholds for Alarms and Warnings */
|
||||
sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(id, SFF8636_VCC_CURR);
|
||||
- sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HALRM);
|
||||
- sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LALRM);
|
||||
- sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HWARN);
|
||||
- sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LWARN);
|
||||
-
|
||||
sd->sfp_temp[MCURR] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_CURR);
|
||||
- sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HALRM);
|
||||
- sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LALRM);
|
||||
- sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HWARN);
|
||||
- sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LWARN);
|
||||
-
|
||||
- sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HALRM);
|
||||
- sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LALRM);
|
||||
- sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HWARN);
|
||||
- sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LWARN);
|
||||
-
|
||||
- sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HALRM);
|
||||
- sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LALRM);
|
||||
- sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HWARN);
|
||||
- sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LWARN);
|
||||
-
|
||||
- sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HALRM);
|
||||
- sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LALRM);
|
||||
- sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HWARN);
|
||||
- sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LWARN);
|
||||
-
|
||||
|
||||
+ if (!map->page_03h)
|
||||
+ goto out;
|
||||
+
|
||||
+ sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_HALRM);
|
||||
+ sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_LALRM);
|
||||
+ sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_HWARN);
|
||||
+ sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_LWARN);
|
||||
+
|
||||
+ sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_HALRM);
|
||||
+ sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_LALRM);
|
||||
+ sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_HWARN);
|
||||
+ sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_LWARN);
|
||||
+
|
||||
+ sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_HALRM);
|
||||
+ sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_LALRM);
|
||||
+ sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_HWARN);
|
||||
+ sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_LWARN);
|
||||
+
|
||||
+ sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_HALRM);
|
||||
+ sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_LALRM);
|
||||
+ sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_HWARN);
|
||||
+ sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_LWARN);
|
||||
+
|
||||
+ sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_HALRM);
|
||||
+ sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_LALRM);
|
||||
+ sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_HWARN);
|
||||
+ sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_LWARN);
|
||||
+
|
||||
+out:
|
||||
/* Channel Specific Data */
|
||||
for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
u8 rx_power_offset, tx_bias_offset;
|
||||
@@ -749,7 +790,7 @@ static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff
|
||||
}
|
||||
}
|
||||
|
||||
-static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eeprom_len)
|
||||
+static void sff8636_show_dom(const struct sff8636_memory_map *map)
|
||||
{
|
||||
struct sff_diags sd = {0};
|
||||
char *rx_power_string = NULL;
|
||||
@@ -763,20 +804,15 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
* and thresholds
|
||||
* If pagging support exists, then supports_alarms is marked as 1
|
||||
*/
|
||||
+ if (map->page_03h)
|
||||
+ sd.supports_alarms = 1;
|
||||
|
||||
- if (eeprom_len == ETH_MODULE_SFF_8636_MAX_LEN) {
|
||||
- if (!(id[SFF8636_STATUS_2_OFFSET] &
|
||||
- SFF8636_STATUS_PAGE_3_PRESENT)) {
|
||||
- sd.supports_alarms = 1;
|
||||
- }
|
||||
- }
|
||||
+ sd.rx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
+ SFF8636_RX_PWR_TYPE_MASK;
|
||||
+ sd.tx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
+ SFF8636_RX_PWR_TYPE_MASK;
|
||||
|
||||
- sd.rx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
- SFF8636_RX_PWR_TYPE_MASK;
|
||||
- sd.tx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
- SFF8636_RX_PWR_TYPE_MASK;
|
||||
-
|
||||
- sff8636_dom_parse(id, page_three, &sd);
|
||||
+ sff8636_dom_parse(map, &sd);
|
||||
|
||||
PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]);
|
||||
PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]);
|
||||
@@ -819,7 +855,7 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
if (sd.supports_alarms) {
|
||||
for (i = 0; sff8636_aw_flags[i].str; ++i) {
|
||||
printf("\t%-41s : %s\n", sff8636_aw_flags[i].str,
|
||||
- id[sff8636_aw_flags[i].offset]
|
||||
+ map->lower_memory[sff8636_aw_flags[i].offset]
|
||||
& sff8636_aw_flags[i].value ? "On" : "Off");
|
||||
}
|
||||
|
||||
@@ -827,39 +863,39 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
}
|
||||
}
|
||||
|
||||
-static void sff8636_show_page_zero(const __u8 *id)
|
||||
+static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8636_show_ext_identifier(id);
|
||||
- sff8636_show_connector(id);
|
||||
- sff8636_show_transceiver(id);
|
||||
- sff8636_show_encoding(id);
|
||||
- sff_show_value_with_unit(id, SFF8636_BR_NOMINAL_OFFSET,
|
||||
- "BR, Nominal", 100, "Mbps");
|
||||
- sff8636_show_rate_identifier(id);
|
||||
- sff_show_value_with_unit(id, SFF8636_SM_LEN_OFFSET,
|
||||
- "Length (SMF,km)", 1, "km");
|
||||
- sff_show_value_with_unit(id, SFF8636_OM3_LEN_OFFSET,
|
||||
- "Length (OM3 50um)", 2, "m");
|
||||
- sff_show_value_with_unit(id, SFF8636_OM2_LEN_OFFSET,
|
||||
- "Length (OM2 50um)", 1, "m");
|
||||
- sff_show_value_with_unit(id, SFF8636_OM1_LEN_OFFSET,
|
||||
- "Length (OM1 62.5um)", 1, "m");
|
||||
- sff_show_value_with_unit(id, SFF8636_CBL_LEN_OFFSET,
|
||||
- "Length (Copper or Active cable)", 1, "m");
|
||||
- sff8636_show_wavelength_or_copper_compliance(id);
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_NAME_START_OFFSET,
|
||||
+ sff8636_show_ext_identifier(map);
|
||||
+ sff8636_show_connector(map);
|
||||
+ sff8636_show_transceiver(map);
|
||||
+ sff8636_show_encoding(map);
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_BR_NOMINAL_OFFSET,
|
||||
+ "BR, Nominal", 100, "Mbps");
|
||||
+ sff8636_show_rate_identifier(map);
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_SM_LEN_OFFSET,
|
||||
+ "Length (SMF,km)", 1, "km");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM3_LEN_OFFSET,
|
||||
+ "Length (OM3 50um)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM2_LEN_OFFSET,
|
||||
+ "Length (OM2 50um)", 1, "m");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM1_LEN_OFFSET,
|
||||
+ "Length (OM1 62.5um)", 1, "m");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_CBL_LEN_OFFSET,
|
||||
+ "Length (Copper or Active cable)", 1, "m");
|
||||
+ sff8636_show_wavelength_or_copper_compliance(map);
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_NAME_START_OFFSET,
|
||||
SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name");
|
||||
- sff8636_show_oui(id, SFF8636_VENDOR_OUI_OFFSET);
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_PN_START_OFFSET,
|
||||
+ sff8024_show_oui(map->page_00h, SFF8636_VENDOR_OUI_OFFSET);
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_PN_START_OFFSET,
|
||||
SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN");
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_REV_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_REV_START_OFFSET,
|
||||
SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev");
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_SN_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_SN_START_OFFSET,
|
||||
SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN");
|
||||
- sff_show_ascii(id, SFF8636_DATE_YEAR_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_DATE_YEAR_OFFSET,
|
||||
SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
|
||||
- sff8636_show_revision_compliance(id);
|
||||
-
|
||||
+ sff_show_revision_compliance(map->lower_memory,
|
||||
+ SFF8636_REV_COMPLIANCE_OFFSET);
|
||||
}
|
||||
|
||||
static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
|
||||
@@ -896,13 +932,13 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
|
||||
sff8636_memory_map_init_buf(&map, id, eeprom_len);
|
||||
|
||||
- sff8636_show_identifier(id);
|
||||
- switch (id[SFF8636_ID_OFFSET]) {
|
||||
+ sff8636_show_identifier(&map);
|
||||
+ switch (map.lower_memory[SFF8636_ID_OFFSET]) {
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
case SFF8024_ID_QSFP28:
|
||||
- sff8636_show_page_zero(id);
|
||||
- sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
|
||||
+ sff8636_show_page_zero(&map);
|
||||
+ sff8636_show_dom(&map);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -939,9 +975,7 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
|
||||
sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
|
||||
- sff8636_show_identifier(page_zero->data);
|
||||
- sff8636_show_page_zero(page_zero->data);
|
||||
- if (page_three)
|
||||
- sff8636_show_dom(page_zero->data, page_three->data - 0x80,
|
||||
- ETH_MODULE_SFF_8636_MAX_LEN);
|
||||
+ sff8636_show_identifier(&map);
|
||||
+ sff8636_show_page_zero(&map);
|
||||
+ sff8636_show_dom(&map);
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From 822d80bb0be204b9e970b193066ffcbd43960105 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:40:56 +0200
|
||||
Subject: [PATCH 22/26] sff-common: Move OFFSET_TO_U16_PTR() to common header
|
||||
file
|
||||
|
||||
The define is also useful for CMIS, so move it from SFF-8636 to the
|
||||
common header file.
|
||||
|
||||
commit: 837c166
|
||||
Reference: https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/commit/?id=837c1662ebd6
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 1 -
|
||||
sff-common.h | 4 ++--
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 58c4c47..b3c9e15 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -700,7 +700,6 @@ sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *ma
|
||||
* Second byte are 1/256th of degree, which are added to the dec part.
|
||||
*/
|
||||
#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
|
||||
-#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
|
||||
|
||||
static void sff8636_dom_parse(const struct sff8636_memory_map *map,
|
||||
struct sff_diags *sd)
|
||||
diff --git a/sff-common.h b/sff-common.h
|
||||
index aab306e..9e32300 100644
|
||||
--- a/sff-common.h
|
||||
+++ b/sff-common.h
|
||||
@@ -126,8 +126,8 @@
|
||||
#define SFF8024_ENCODING_PAM4 0x08
|
||||
|
||||
/* Most common case: 16-bit unsigned integer in a certain unit */
|
||||
-#define OFFSET_TO_U16(offset) \
|
||||
- (id[offset] << 8 | id[(offset) + 1])
|
||||
+#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
|
||||
+#define OFFSET_TO_U16(offset) OFFSET_TO_U16_PTR(id, offset)
|
||||
|
||||
# define PRINT_xX_PWR(string, var) \
|
||||
printf("\t%-41s : %.4f mW / %.2f dBm\n", (string), \
|
||||
--
|
||||
2.30.0
|
||||
|
||||
30
ethtool.spec
30
ethtool.spec
@ -1,19 +1,39 @@
|
||||
Name: ethtool
|
||||
Epoch: 2
|
||||
Version: 5.15
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: Settings tool for Ethernet NICs
|
||||
License: GPLv2
|
||||
URL: https://www.kernel.org/pub/software/network/ethtool
|
||||
Source0: https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.xz
|
||||
|
||||
Patch0: backport-ioctl-add-the-memory-free-operation-after-send_ioctl.patch
|
||||
Patch0: backport-ioctl-add-the-memory-free-operation-after-send_ioctl.patch
|
||||
Patch1: 0001-rings-add-support-to-set-get-rx-buf-len.patch
|
||||
Patch2: 0002-tunables-add-support-to-get-set-tx-copybreak-buf-siz.patch
|
||||
Patch3: 0003-update-UAPI-header-copies.patch
|
||||
Patch4: 0004-ethtool-add-support-to-get-set-tx-push-by-ethtool-G-.patch
|
||||
Patch5: 0005-ethtool-add-suppport-specifications-for-vxlan-by-eth.patch
|
||||
Patch6: 0006-hns3-add-support-dump-registers-for-hns3-driver.patch
|
||||
Patch7: backport-cmis-Rename-CMIS-parsing-functions.patch
|
||||
Patch8: backport-cmis-Initialize-CMIS-memory-map.patch
|
||||
Patch9: backport-cmis-Use-memory-map-during-parsing.patch
|
||||
Patch10: backport-cmis-Consolidate-code-between-IOCTL-and-netlink-path.patch
|
||||
Patch11: backport-sff-8636-Rename-SFF-8636-parsing-functions.patch
|
||||
Patch12: backport-sff-8636-Initialize-SFF-8636-memory-map.patch
|
||||
Patch13: backport-sff-8636-Use-memory-map-during-parsing.patch
|
||||
Patch14: backport-sff-8636-Consolidate-code-between-IOCTL-and-netlink-.patch
|
||||
Patch15: backport-sff-8079-Split-SFF-8079-parsing-function.patch
|
||||
Patch16: backport-netlink-eeprom-Export-a-function-to-request-an-EEPRO.patch
|
||||
Patch17: backport-cmis-Request-specific-pages-for-parsing-in-netlink-p.patch
|
||||
Patch18: backport-sff-8636-Request-specific-pages-for-parsing-in-netli.patch
|
||||
Patch19: backport-sff-8079-Request-specific-pages-for-parsing-in-netli.patch
|
||||
Patch20: backport-netlink-eeprom-Defer-page-requests-to-individual-par.patch
|
||||
Patch21: backport-sff-8636-Use-an-SFF-8636-specific-define-for-maximum.patch
|
||||
Patch22: backport-sff-common-Move-OFFSET_TO_U16_PTR-to-common-header-f.patch
|
||||
Patch23: backport-sff-8636-Print-Power-set-and-Power-override-bits.patch
|
||||
Patch24: backport-ethtool-Add-ability-to-control-transceiver-modules-p.patch
|
||||
Patch25: backport-ethtool-Add-support-for-OSFP-transceiver-modules.patch
|
||||
Patch26: backport-ethtool-Add-support-for-more-CMIS-transceiver-module.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: libmnl-devel
|
||||
@ -61,6 +81,12 @@ make check
|
||||
%{_mandir}/man8/%{name}.8*
|
||||
|
||||
%changelog
|
||||
* Fri Jun 7 2024 xiaojiantao <xiaojiantao1@h-partners.com> - 2:5.15-7
|
||||
- Type:requirement
|
||||
- Id:NA
|
||||
- SUG:NA
|
||||
- DESC:add support for more CMIS transceiver modules
|
||||
|
||||
* Tue Sep 26 2023 xiaojiantao <xiaojiantao1@h-partners.com> - 2:5.15-6
|
||||
- Type:requirement
|
||||
- Id:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user