All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode
@ 2021-08-24 13:05 Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 1/6] Update UAPI header copies Ido Schimmel
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

Patch #1 updates the UAPI headers.

Patch #2 adds the actual implementation that allows user space to
control transceiver modules' power mode. See the commit message for
example output.

Patches #3-#5 parse more fields from SFF-8636 and CMIS EEPROMs to
provide better observability regarding the power mode of the modules.

Patch #6 adds support for two new extended link states in order to allow
user space to troubleshoot link down issues related to transceiver
modules. See the commit message for example output.

Ido Schimmel (6):
  Update UAPI header copies
  ethtool: Add ability to control transceiver modules' power mode
  ethtool: Print CMIS Module State
  ethtool: Print CMIS Module-Level Controls
  ethtool: Print SFF-8636 Power set and Power override bits
  ethtool: Add transceiver module extended states

 Makefile.am                   |   2 +-
 cmis.c                        |  87 +++++++++++++++++
 cmis.h                        |  20 ++++
 ethtool.8.in                  |  25 +++++
 ethtool.c                     |  11 +++
 netlink/desc-ethtool.c        |  11 +++
 netlink/extapi.h              |   4 +
 netlink/module.c              | 179 ++++++++++++++++++++++++++++++++++
 netlink/monitor.c             |   4 +
 netlink/netlink.h             |   1 +
 netlink/settings.c            |  12 +++
 qsfp.c                        |   6 ++
 qsfp.h                        |   2 +-
 shell-completion/bash/ethtool |  23 +++++
 uapi/linux/ethtool.h          |  36 ++++++-
 uapi/linux/ethtool_netlink.h  |  34 ++++++-
 uapi/linux/if_link.h          |  21 ++++
 uapi/linux/net_tstamp.h       |  17 +++-
 uapi/linux/netlink.h          |   5 +-
 19 files changed, 491 insertions(+), 9 deletions(-)
 create mode 100644 netlink/module.c

-- 
2.31.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH ethtool-next v3 1/6] Update UAPI header copies
  2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
@ 2021-08-24 13:05 ` Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 2/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

Update to kernel commit XXX.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 uapi/linux/ethtool.h         | 36 ++++++++++++++++++++++++++++++++++--
 uapi/linux/ethtool_netlink.h | 34 +++++++++++++++++++++++++++++++++-
 uapi/linux/if_link.h         | 21 +++++++++++++++++++++
 uapi/linux/net_tstamp.h      | 17 +++++++++++++++--
 uapi/linux/netlink.h         |  5 +++--
 5 files changed, 106 insertions(+), 7 deletions(-)

diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h
index c6ec1111ffa3..805f5559f433 100644
--- a/uapi/linux/ethtool.h
+++ b/uapi/linux/ethtool.h
@@ -231,7 +231,7 @@ enum tunable_id {
 	ETHTOOL_PFC_PREVENTION_TOUT, /* timeout in msecs */
 	/*
 	 * Add your fresh new tunable attribute above and remember to update
-	 * tunable_strings[] in net/core/ethtool.c
+	 * tunable_strings[] in net/ethtool/common.c
 	 */
 	__ETHTOOL_TUNABLE_COUNT,
 };
@@ -295,7 +295,7 @@ enum phy_tunable_id {
 	ETHTOOL_PHY_EDPD,
 	/*
 	 * Add your fresh new phy tunable attribute above and remember to update
-	 * phy_tunable_strings[] in net/core/ethtool.c
+	 * phy_tunable_strings[] in net/ethtool/common.c
 	 */
 	__ETHTOOL_PHY_TUNABLE_COUNT,
 };
@@ -601,6 +601,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. */
@@ -637,6 +638,8 @@ enum ethtool_link_ext_substate_link_logical_mismatch {
 enum ethtool_link_ext_substate_bad_signal_integrity {
 	ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 1,
 	ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE,
+	ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST,
+	ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS,
 };
 
 /* More information in addition to ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE. */
@@ -645,6 +648,12 @@ 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_LOW_POWER_MODE = 1,
+	ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY,
+};
+
 #define ETH_GSTRING_LEN		32
 
 /**
@@ -702,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,
+	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,
+	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 4653c4c79972..d706aa03925a 100644
--- a/uapi/linux/ethtool_netlink.h
+++ b/uapi/linux/ethtool_netlink.h
@@ -46,6 +46,9 @@ enum {
 	ETHTOOL_MSG_FEC_SET,
 	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,
@@ -88,6 +91,9 @@ enum {
 	ETHTOOL_MSG_FEC_NTF,
 	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,
@@ -440,6 +446,19 @@ enum {
 	ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
 };
 
+/* PHC VCLOCKS */
+
+enum {
+	ETHTOOL_A_PHC_VCLOCKS_UNSPEC,
+	ETHTOOL_A_PHC_VCLOCKS_HEADER,			/* nest - _A_HEADER_* */
+	ETHTOOL_A_PHC_VCLOCKS_NUM,			/* u32 */
+	ETHTOOL_A_PHC_VCLOCKS_INDEX,			/* array, s32 */
+
+	/* add new constants above here */
+	__ETHTOOL_A_PHC_VCLOCKS_CNT,
+	ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1)
+};
+
 /* CABLE TEST */
 
 enum {
@@ -675,7 +694,7 @@ enum {
 	ETHTOOL_A_MODULE_EEPROM_PAGE,			/* u8 */
 	ETHTOOL_A_MODULE_EEPROM_BANK,			/* u8 */
 	ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS,		/* u8 */
-	ETHTOOL_A_MODULE_EEPROM_DATA,			/* nested */
+	ETHTOOL_A_MODULE_EEPROM_DATA,			/* binary */
 
 	__ETHTOOL_A_MODULE_EEPROM_CNT,
 	ETHTOOL_A_MODULE_EEPROM_MAX = (__ETHTOOL_A_MODULE_EEPROM_CNT - 1)
@@ -816,6 +835,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 0e81707a9637..330a3c1e0035 100644
--- a/uapi/linux/if_link.h
+++ b/uapi/linux/if_link.h
@@ -341,6 +341,13 @@ enum {
 	IFLA_ALT_IFNAME, /* Alternative ifname */
 	IFLA_PERM_ADDRESS,
 	IFLA_PROTO_DOWN_REASON,
+
+	/* device (sysfs) name as parent, used instead
+	 * of IFLA_LINK where there's no parent netdev
+	 */
+	IFLA_PARENT_DEV_NAME,
+	IFLA_PARENT_DEV_BUS_NAME,
+
 	__IFLA_MAX
 };
 
@@ -470,6 +477,7 @@ enum {
 	IFLA_BR_MCAST_MLD_VERSION,
 	IFLA_BR_VLAN_STATS_PER_PORT,
 	IFLA_BR_MULTI_BOOLOPT,
+	IFLA_BR_MCAST_QUERIER_STATE,
 	__IFLA_BR_MAX,
 };
 
@@ -846,6 +854,7 @@ enum {
 	IFLA_BOND_AD_ACTOR_SYSTEM,
 	IFLA_BOND_TLB_DYNAMIC_LB,
 	IFLA_BOND_PEER_NOTIF_DELAY,
+	IFLA_BOND_AD_LACP_ACTIVE,
 	__IFLA_BOND_MAX,
 };
 
@@ -1234,6 +1243,8 @@ enum {
 #define RMNET_FLAGS_INGRESS_MAP_COMMANDS          (1U << 1)
 #define RMNET_FLAGS_INGRESS_MAP_CKSUMV4           (1U << 2)
 #define RMNET_FLAGS_EGRESS_MAP_CKSUMV4            (1U << 3)
+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5           (1U << 4)
+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5            (1U << 5)
 
 enum {
 	IFLA_RMNET_UNSPEC,
@@ -1249,4 +1260,14 @@ struct ifla_rmnet_flags {
 	__u32	mask;
 };
 
+/* MCTP section */
+
+enum {
+	IFLA_MCTP_UNSPEC,
+	IFLA_MCTP_NET,
+	__IFLA_MCTP_MAX,
+};
+
+#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
+
 #endif /* _LINUX_IF_LINK_H */
diff --git a/uapi/linux/net_tstamp.h b/uapi/linux/net_tstamp.h
index 7ed0b3d1c00a..fcc61c73a666 100644
--- a/uapi/linux/net_tstamp.h
+++ b/uapi/linux/net_tstamp.h
@@ -13,7 +13,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>   /* for SO_TIMESTAMPING */
 
-/* SO_TIMESTAMPING gets an integer bit field comprised of these values */
+/* SO_TIMESTAMPING flags */
 enum {
 	SOF_TIMESTAMPING_TX_HARDWARE = (1<<0),
 	SOF_TIMESTAMPING_TX_SOFTWARE = (1<<1),
@@ -30,8 +30,9 @@ enum {
 	SOF_TIMESTAMPING_OPT_STATS = (1<<12),
 	SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13),
 	SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14),
+	SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
 
-	SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
+	SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_BIND_PHC,
 	SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
 				 SOF_TIMESTAMPING_LAST
 };
@@ -46,6 +47,18 @@ enum {
 					 SOF_TIMESTAMPING_TX_SCHED | \
 					 SOF_TIMESTAMPING_TX_ACK)
 
+/**
+ * struct so_timestamping - SO_TIMESTAMPING parameter
+ *
+ * @flags:	SO_TIMESTAMPING flags
+ * @bind_phc:	Index of PTP virtual clock bound to sock. This is available
+ *		if flag SOF_TIMESTAMPING_BIND_PHC is set.
+ */
+struct so_timestamping {
+	int flags;
+	int bind_phc;
+};
+
 /**
  * struct hwtstamp_config - %SIOCGHWTSTAMP and %SIOCSHWTSTAMP parameter
  *
diff --git a/uapi/linux/netlink.h b/uapi/linux/netlink.h
index 5024c5435749..e83e2e300130 100644
--- a/uapi/linux/netlink.h
+++ b/uapi/linux/netlink.h
@@ -91,9 +91,10 @@ struct nlmsghdr {
 #define NLMSG_HDRLEN	 ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
 #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
 #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
-#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
+#define NLMSG_DATA(nlh)  ((void *)(((char *)nlh) + NLMSG_HDRLEN))
 #define NLMSG_NEXT(nlh,len)	 ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
-				  (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+				  (struct nlmsghdr *)(((char *)(nlh)) + \
+				  NLMSG_ALIGN((nlh)->nlmsg_len)))
 #define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
 			   (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
 			   (nlh)->nlmsg_len <= (len))
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH ethtool-next v3 2/6] ethtool: Add ability to control transceiver modules' power mode
  2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 1/6] Update UAPI header copies Ido Schimmel
@ 2021-08-24 13:05 ` Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 3/6] ethtool: Print CMIS Module State Ido Schimmel
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

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

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 Makefile.am                   |   2 +-
 ethtool.8.in                  |  25 +++++
 ethtool.c                     |  11 +++
 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, 259 insertions(+), 1 deletion(-)
 create mode 100644 netlink/module.c

diff --git a/Makefile.am b/Makefile.am
index dd357d0a158a..dc5fbec1e09d 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 f83d6d17ae41..0d0805bd0d3a 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -475,6 +475,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
@@ -1458,6 +1466,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
+.A3 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 33a0a492cb15..f3b6cb9484e9 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -6020,6 +6020,17 @@ static const struct option args[] = {
 		.nlfunc	= nl_gtunnels,
 		.help	= "Show NIC tunnel offload information",
 	},
+	{
+		.opts	= "--show-module",
+		.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 d6fc4e2d03df..721c8a393c85 100644
--- a/netlink/desc-ethtool.c
+++ b/netlink/desc-ethtool.c
@@ -374,6 +374,13 @@ const struct pretty_nla_desc __module_eeprom_desc[] = {
 	NLATTR_DESC_BINARY(ETHTOOL_A_MODULE_EEPROM_DATA)
 };
 
+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),
@@ -408,6 +415,8 @@ const struct pretty_nlmsg_desc ethnl_umsg_desc[] = {
 	NLMSG_DESC(ETHTOOL_MSG_FEC_SET, fec),
 	NLMSG_DESC(ETHTOOL_MSG_STATS_GET, stats),
 	NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET, module_eeprom),
+	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);
@@ -447,6 +456,8 @@ const struct pretty_nlmsg_desc ethnl_kmsg_desc[] = {
 	NLMSG_DESC(ETHTOOL_MSG_FEC_NTF, fec),
 	NLMSG_DESC(ETHTOOL_MSG_STATS_GET_REPLY, stats),
 	NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, module_eeprom),
+	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 91bf02b5e3be..2ab4c6bc2f8d 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);
 
@@ -99,6 +101,8 @@ static inline void nl_monitor_usage(void)
 #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 000000000000..a614b7fe0718
--- /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 0c4df9e78ee3..d631907817e2 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 70fa666b20e5..f43c1bff6a58 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 45573413985d..46334b525e2b 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.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH ethtool-next v3 3/6] ethtool: Print CMIS Module State
  2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 1/6] Update UAPI header copies Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 2/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
@ 2021-08-24 13:05 ` Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 4/6] ethtool: Print CMIS Module-Level Controls Ido Schimmel
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

Print the CMIS Module State when dumping EEPROM contents via the '-m'
option. It can be used, for example, to test module power mode settings.

Example output:

 # ethtool -m swp11
 Identifier                                : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
 ...
 Module State                              : 0x03 (ModuleReady)

 # ethtool --set-module swp11 power-mode-policy auto

 # ethtool -m swp11
 Identifier                                : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
 ...
 Module State                              : 0x01 (ModuleLowPwr)

In case the module is in fault state, print the CMIS Module Fault Cause.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 cmis.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 cmis.h | 15 +++++++++++++
 2 files changed, 86 insertions(+)

diff --git a/cmis.c b/cmis.c
index 361b721f332f..c5c1f02398f6 100644
--- a/cmis.c
+++ b/cmis.c
@@ -42,6 +42,73 @@ static void cmis_show_rev_compliance(const __u8 *id)
 	printf("\t%-41s : Rev. %d.%d\n", "Revision compliance", major, minor);
 }
 
+/**
+ * Print the current Module State. Relevant documents:
+ * [1] CMIS Rev. 5, pag. 57, section 6.3.2.2, Figure 6-3
+ * [2] CMIS Rev. 5, pag. 60, section 6.3.2.3, Figure 6-4
+ * [3] CMIS Rev. 5, pag. 107, section 8.2.2, Table 8-6
+ */
+static void cmis_show_mod_state(const __u8 *id)
+{
+	__u8 mod_state = (id[CMIS_MODULE_STATE_OFFSET] >> 1) & 0x07;
+
+	printf("\t%-41s : 0x%02x", "Module State", mod_state);
+	switch (mod_state) {
+	case CMIS_MODULE_STATE_MODULE_LOW_PWR:
+		printf(" (ModuleLowPwr)\n");
+		break;
+	case CMIS_MODULE_STATE_MODULE_PWR_UP:
+		printf(" (ModulePwrUp)\n");
+		break;
+	case CMIS_MODULE_STATE_MODULE_READY:
+		printf(" (ModuleReady)\n");
+		break;
+	case CMIS_MODULE_STATE_MODULE_PWR_DN:
+		printf(" (ModulePwrDn)\n");
+		break;
+	case CMIS_MODULE_STATE_MODULE_FAULT:
+		printf(" (ModuleFault)\n");
+		break;
+	default:
+		printf(" (reserved or unknown)\n");
+		break;
+	}
+}
+
+/**
+ * Print the Module Fault Information. Relevant documents:
+ * [1] CMIS Rev. 5, pag. 64, section 6.3.2.12
+ * [2] CMIS Rev. 5, pag. 115, section 8.2.10, Table 8-15
+ */
+static void cmis_show_mod_fault_cause(const __u8 *id)
+{
+	__u8 mod_state = (id[CMIS_MODULE_STATE_OFFSET] >> 1) & 0x07;
+	__u8 fault_cause = id[CMIS_MODULE_FAULT_OFFSET];
+
+	if (mod_state != CMIS_MODULE_STATE_MODULE_FAULT)
+		return;
+
+	printf("\t%-41s : 0x%02x", "Module Fault Cause", fault_cause);
+	switch (fault_cause) {
+	case CMIS_MODULE_FAULT_NO_FAULT:
+		printf(" (No fault detected / not supported)\n");
+		break;
+	case CMIS_MODULE_FAULT_TEC_RUNAWAY:
+		printf(" (TEC runaway)\n");
+		break;
+	case CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED:
+		printf(" (Data memory corrupted)\n");
+		break;
+	case CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED:
+		printf(" (Program memory corrupted)\n");
+		break;
+	default:
+		printf(" (reserved or unknown)\n");
+		break;
+	}
+}
+
+
 /**
  * Print information about the device's power consumption.
  * Relevant documents:
@@ -336,6 +403,8 @@ void qsfp_dd_show_all(const __u8 *id)
 	cmis_show_link_len(id);
 	cmis_show_vendor_info(id);
 	cmis_show_rev_compliance(id);
+	cmis_show_mod_state(id);
+	cmis_show_mod_fault_cause(id);
 }
 
 void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
@@ -356,4 +425,6 @@ void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
 
 	cmis_show_vendor_info(page_zero_data);
 	cmis_show_rev_compliance(page_zero_data);
+	cmis_show_mod_state(page_zero_data);
+	cmis_show_mod_fault_cause(page_zero_data);
 }
diff --git a/cmis.h b/cmis.h
index 78ee1495bc33..41383132cf8e 100644
--- a/cmis.h
+++ b/cmis.h
@@ -5,6 +5,21 @@
 #define CMIS_ID_OFFSET				0x00
 #define CMIS_REV_COMPLIANCE_OFFSET		0x01
 
+/* Module State (Page 0) */
+#define CMIS_MODULE_STATE_OFFSET		0x03
+#define CMIS_MODULE_STATE_MODULE_LOW_PWR	0x01
+#define CMIS_MODULE_STATE_MODULE_PWR_UP		0x02
+#define CMIS_MODULE_STATE_MODULE_READY		0x03
+#define CMIS_MODULE_STATE_MODULE_PWR_DN		0x04
+#define CMIS_MODULE_STATE_MODULE_FAULT		0x05
+
+/* Module Fault Information (Page 0) */
+#define CMIS_MODULE_FAULT_OFFSET		0x29
+#define CMIS_MODULE_FAULT_NO_FAULT		0
+#define CMIS_MODULE_FAULT_TEC_RUNAWAY		1
+#define CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED	2
+#define CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED	3
+
 #define CMIS_MODULE_TYPE_OFFSET			0x55
 #define CMIS_MT_MMF				0x01
 #define CMIS_MT_SMF				0x02
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH ethtool-next v3 4/6] ethtool: Print CMIS Module-Level Controls
  2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
                   ` (2 preceding siblings ...)
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 3/6] ethtool: Print CMIS Module State Ido Schimmel
@ 2021-08-24 13:05 ` Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 5/6] ethtool: Print SFF-8636 Power set and Power override bits Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 6/6] ethtool: Add transceiver module extended states Ido Schimmel
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

Print the CMIS Module-Level Controls when dumping EEPROM contents via
the '-m' option. It can be used to understand low power mode enforcement
by the host.

Example output:

 # ethtool -m swp11
 Identifier                                : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
 ...
 Module State                              : 0x03 (ModuleReady)
 LowPwrAllowRequestHW                      : Off
 LowPwrRequestSW                           : Off

 # ethtool --set-module swp11 power-mode-policy auto

 # ethtool -m swp11
 Identifier                                : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
 ...
 Module State                              : 0x01 (ModuleLowPwr)
 LowPwrAllowRequestHW                      : Off
 LowPwrRequestSW                           : On

 # ethtool --set-module swp11 power-mode-policy high

 # ethtool -m swp11
 Identifier                                : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
 ...
 Module State                              : 0x03 (ModuleReady)
 LowPwrAllowRequestHW                      : Off
 LowPwrRequestSW                           : Off

In the above example, the LowPwrRequestHW signal is ignored and low
power mode is controlled via software only.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 cmis.c | 16 ++++++++++++++++
 cmis.h |  5 +++++
 2 files changed, 21 insertions(+)

diff --git a/cmis.c b/cmis.c
index c5c1f02398f6..cd1c7d6e83c9 100644
--- a/cmis.c
+++ b/cmis.c
@@ -108,6 +108,20 @@ static void cmis_show_mod_fault_cause(const __u8 *id)
 	}
 }
 
+/*
+ * Print the current Module-Level Controls. Relevant documents:
+ * [1] CMIS Rev. 5, pag. 58, section 6.3.2.2, Table 6-12
+ * [2] CMIS Rev. 5, pag. 111, section 8.2.6, Table 8-10
+ */
+static void cmis_show_mod_lvl_controls(const __u8 *id)
+{
+	printf("\t%-41s : ", "LowPwrAllowRequestHW");
+	printf("%s\n", ONOFF(id[CMIS_MODULE_CONTROL_OFFSET] &
+			     CMIS_LOW_PWR_ALLOW_REQUEST_HW));
+	printf("\t%-41s : ", "LowPwrRequestSW");
+	printf("%s\n", ONOFF(id[CMIS_MODULE_CONTROL_OFFSET] &
+			     CMIS_LOW_PWR_REQUEST_SW));
+}
 
 /**
  * Print information about the device's power consumption.
@@ -405,6 +419,7 @@ void qsfp_dd_show_all(const __u8 *id)
 	cmis_show_rev_compliance(id);
 	cmis_show_mod_state(id);
 	cmis_show_mod_fault_cause(id);
+	cmis_show_mod_lvl_controls(id);
 }
 
 void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
@@ -427,4 +442,5 @@ void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
 	cmis_show_rev_compliance(page_zero_data);
 	cmis_show_mod_state(page_zero_data);
 	cmis_show_mod_fault_cause(page_zero_data);
+	cmis_show_mod_lvl_controls(page_zero_data);
 }
diff --git a/cmis.h b/cmis.h
index 41383132cf8e..41288d4e88bc 100644
--- a/cmis.h
+++ b/cmis.h
@@ -28,6 +28,11 @@
 #define CMIS_CURR_TEMP_OFFSET			0x0E
 #define CMIS_CURR_CURR_OFFSET			0x10
 
+/* Module-Level Controls (Page 0) */
+#define CMIS_MODULE_CONTROL_OFFSET		0x1A
+#define CMIS_LOW_PWR_ALLOW_REQUEST_HW		(1 << 6)
+#define CMIS_LOW_PWR_REQUEST_SW			(1 << 4)
+
 #define CMIS_CTOR_OFFSET			0xCB
 
 /* Vendor related information (Page 0) */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH ethtool-next v3 5/6] ethtool: Print SFF-8636 Power set and Power override bits
  2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
                   ` (3 preceding siblings ...)
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 4/6] ethtool: Print CMIS Module-Level Controls Ido Schimmel
@ 2021-08-24 13:05 ` Ido Schimmel
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 6/6] ethtool: Add transceiver module extended states Ido Schimmel
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

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.

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 644fe148a5aa..08ffb90447f3 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -252,6 +252,12 @@ static void sff8636_show_ext_identifier(const __u8 *id)
 		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(id[SFF8636_PWR_MODE_OFFSET] &
+			     SFF8636_LOW_PWR_SET));
+	printf("\t%-41s : ", "Power override");
+	printf("%s\n", ONOFF(id[SFF8636_PWR_MODE_OFFSET] &
+			     SFF8636_PWR_OVERRIDE));
 }
 
 static void sff8636_show_connector(const __u8 *id)
diff --git a/qsfp.h b/qsfp.h
index 1d8f24b5cbc2..aabf09fdc623 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.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH ethtool-next v3 6/6] ethtool: Add transceiver module extended states
  2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
                   ` (4 preceding siblings ...)
  2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 5/6] ethtool: Print SFF-8636 Power set and Power override bits Ido Schimmel
@ 2021-08-24 13:05 ` Ido Schimmel
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2021-08-24 13:05 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, andrew, mkubecek, pali, jacob.e.keller, jiri,
	vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

Add support for an extended state and two extended sub-states to
describe link issues related to transceiver modules.

In case "CMIS transceiver module is not in ModuleReady state" and the
module is in ModuleFault state, it is possible to read the fault reason
from the EEPROM dump.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 netlink/settings.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/netlink/settings.c b/netlink/settings.c
index e47a38f3058f..515b9302c09d 100644
--- a/netlink/settings.c
+++ b/netlink/settings.c
@@ -593,6 +593,7 @@ static const char *const names_link_ext_state[] = {
 	[ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE]	= "Calibration failure",
 	[ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED]	= "Power budget exceeded",
 	[ETHTOOL_LINK_EXT_STATE_OVERHEAT]		= "Overheat",
+	[ETHTOOL_LINK_EXT_STATE_MODULE]			= "Module",
 };
 
 static const char *const names_autoneg_link_ext_substate[] = {
@@ -648,6 +649,13 @@ static const char *const names_cable_issue_link_ext_substate[] = {
 		"Cable test failure",
 };
 
+static const char *const names_module_link_ext_substate[] = {
+	[ETHTOOL_LINK_EXT_SUBSTATE_MODULE_LOW_POWER_MODE]	=
+		"Module is in low power mode",
+	[ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY]	=
+		"CMIS module is not in ModuleReady state",
+};
+
 static const char *link_ext_substate_get(uint8_t link_ext_state_val, uint8_t link_ext_substate_val)
 {
 	switch (link_ext_state_val) {
@@ -671,6 +679,10 @@ static const char *link_ext_substate_get(uint8_t link_ext_state_val, uint8_t lin
 		return get_enum_string(names_cable_issue_link_ext_substate,
 				       ARRAY_SIZE(names_cable_issue_link_ext_substate),
 				       link_ext_substate_val);
+	case ETHTOOL_LINK_EXT_STATE_MODULE:
+		return get_enum_string(names_module_link_ext_substate,
+				       ARRAY_SIZE(names_module_link_ext_substate),
+				       link_ext_substate_val);
 	default:
 		return NULL;
 	}
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-08-24 13:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-24 13:05 [RFC PATCH ethtool-next v3 0/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 1/6] Update UAPI header copies Ido Schimmel
2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 2/6] ethtool: Add ability to control transceiver modules' power mode Ido Schimmel
2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 3/6] ethtool: Print CMIS Module State Ido Schimmel
2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 4/6] ethtool: Print CMIS Module-Level Controls Ido Schimmel
2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 5/6] ethtool: Print SFF-8636 Power set and Power override bits Ido Schimmel
2021-08-24 13:05 ` [RFC PATCH ethtool-next v3 6/6] ethtool: Add transceiver module extended states Ido Schimmel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.