From patchwork Tue Aug 24 13:03:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 502178 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97010C4338F for ; Tue, 24 Aug 2021 13:04:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7671A613B1 for ; Tue, 24 Aug 2021 13:04:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237414AbhHXNFU (ORCPT ); Tue, 24 Aug 2021 09:05:20 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:58475 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237405AbhHXNFT (ORCPT ); Tue, 24 Aug 2021 09:05:19 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id C6513580B17; Tue, 24 Aug 2021 09:04:34 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Tue, 24 Aug 2021 09:04:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=HCBHC7lsmj/Q/dtGbe8tY+DZ6WKPHDKlW8YdC017t6w=; b=XrTnYR9C ajUm0T/XtVS8Y2ydT64sEtZQXv/MCohooB7RCTORcpJcIHgEs8tGBkSttajb2an7 EKWrhNsFTPvHqNKAkz1eF47Z2AngxjT/CxDIo5DBhaRgKrONmlIqgCb/hVpROsAF ccDk/Pa+StrICbfnC40sgBUh5DX0O0FAUIJDoNV9HirNLpS8p4FZ2UPsy7LKpaT2 2ztnCY3Sf4wrZWAMmHgw443dDrgOIRuTsu/1BMwDVTbzIwTkWahCL3Sihpv6ExIl YWl2VoYidxAhcX69PnBL91lpCCUkILEAh5i7E8szgmcDAS+UPMWykcRDFGHt73xw TwF8x5x2tag5wQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecuvehluhhsthgvrhfuihiivgeptdenucfr rghrrghmpehmrghilhhfrhhomhepihguohhstghhsehiughoshgthhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 09:04:30 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch, mkubecek@suse.cz, pali@kernel.org, jacob.e.keller@intel.com, jiri@nvidia.com, vadimp@nvidia.com, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next v3 1/6] ethtool: Add ability to control transceiver modules' power mode Date: Tue, 24 Aug 2021 16:03:39 +0300 Message-Id: <20210824130344.1828076-2-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210824130344.1828076-1-idosch@idosch.org> References: <20210824130344.1828076-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Add a pair of new ethtool messages, 'ETHTOOL_MSG_MODULE_SET' and 'ETHTOOL_MSG_MODULE_GET', that can be used to control transceiver modules parameters and retrieve their status. The first parameter to control is the power mode of the module. It is only relevant for paged memory modules, as flat memory modules always operate in low power mode. When a paged memory module is in low power mode, its power consumption is reduced to the minimum, the management interface towards the host is available and the data path is deactivated. User space can choose to put modules that are not currently in use in low power mode and transition them to high power mode before putting the associated ports administratively up. This is useful for user space that favors reduced power consumption and lower temperatures over reduced link up times. In QSFP-DD modules the transition from low power mode to high power mode can take a few seconds and this transition is only expected to get longer with future / more complex modules. User space can control the power mode of the module via the power mode policy attribute ('ETHTOOL_A_MODULE_POWER_MODE_POLICY'). Possible values: * high: Module is always in high power mode. * 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. The operational power mode of the module is available to user space via the 'ETHTOOL_A_MODULE_POWER_MODE' attribute. The attribute is not reported to user space when a module is not plugged-in. The user API is designed to be generic enough so that it could be used for modules with different memory maps (e.g., SFF-8636, CMIS). The only implementation of the device driver API in this series is for a MAC driver (mlxsw) where the module is controlled by the device's firmware, but it is designed to be generic enough so that it could also be used by implementations where the module is controlled by the CPU. CMIS testing ============ # ethtool -m swp11 Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628)) ... Module State : 0x03 (ModuleReady) LowPwrAllowRequestHW : Off LowPwrRequestSW : Off The module is not in low power mode, as it is not forced by hardware (LowPwrAllowRequestHW is off) or by software (LowPwrRequestSW is off). The power mode can be queried from the kernel. In case LowPwrAllowRequestHW was on, the kernel would need to take into account the state of the LowPwrRequestHW signal, which is not visible to user space. $ ethtool --show-module swp11 Module parameters for swp11: power-mode-policy high power-mode high Change the power mode policy to 'auto': # ethtool --set-module swp11 power-mode-policy auto Query the power mode again: $ ethtool --show-module swp11 Module parameters for swp11: power-mode-policy auto power-mode low Verify with the data read from the EEPROM: # ethtool -m swp11 Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628)) ... Module State : 0x01 (ModuleLowPwr) LowPwrAllowRequestHW : Off LowPwrRequestSW : On Put the associated port administratively up which will instruct the host to transition the module to high power mode: # ip link set dev swp11 up Query the power mode again: $ ethtool --show-module swp11 Module parameters for swp11: power-mode-policy auto power-mode high Verify with the data read from the EEPROM: # ethtool -m swp11 Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628)) ... Module State : 0x03 (ModuleReady) LowPwrAllowRequestHW : Off LowPwrRequestSW : Off Put the associated port administratively down which will instruct the host to transition the module to low power mode: # ip link set dev swp11 down Query the power mode again: $ ethtool --show-module swp11 Module parameters for swp11: power-mode-policy auto power-mode low Verify with the data read from the EEPROM: # ethtool -m swp11 Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628)) ... Module State : 0x01 (ModuleLowPwr) LowPwrAllowRequestHW : Off LowPwrRequestSW : On SFF-8636 testing ================ # 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.7649 mW / -1.16 dBm Transmit avg optical power (Channel 3) : 0.7790 mW / -1.08 dBm Transmit avg optical power (Channel 4) : 0.7837 mW / -1.06 dBm Rcvr signal avg optical power(Channel 1) : 0.9302 mW / -0.31 dBm Rcvr signal avg optical power(Channel 2) : 0.9079 mW / -0.42 dBm Rcvr signal avg optical power(Channel 3) : 0.8993 mW / -0.46 dBm Rcvr signal avg optical power(Channel 4) : 0.8778 mW / -0.57 dBm The module is not in low power mode, as it is not forced by hardware (Power override is on) or by software (Power set is off). The power mode can be queried from the kernel. In case Power override was off, the kernel would need to take into account the state of the LPMode signal, which is not visible to user space. $ ethtool --show-module swp13 Module parameters for swp13: power-mode-policy high power-mode high Change the power mode policy to 'auto': # ethtool --set-module swp13 power-mode-policy auto Query the power mode again: $ ethtool --show-module swp13 Module parameters for swp13: power-mode-policy auto power-mode low Verify with the data read from the EEPROM: # 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 Put the associated port administratively up which will instruct the host to transition the module to high power mode: # ip link set dev swp13 up Query the power mode again: $ ethtool --show-module swp13 Module parameters for swp13: power-mode-policy auto power-mode high Verify with the data read from the EEPROM: # 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.7934 mW / -1.01 dBm Transmit avg optical power (Channel 2) : 0.7859 mW / -1.05 dBm Transmit avg optical power (Channel 3) : 0.7885 mW / -1.03 dBm Transmit avg optical power (Channel 4) : 0.7985 mW / -0.98 dBm Rcvr signal avg optical power(Channel 1) : 0.9325 mW / -0.30 dBm Rcvr signal avg optical power(Channel 2) : 0.9034 mW / -0.44 dBm Rcvr signal avg optical power(Channel 3) : 0.9086 mW / -0.42 dBm Rcvr signal avg optical power(Channel 4) : 0.8885 mW / -0.51 dBm Put the associated port administratively down which will instruct the host to transition the module to low power mode: # ip link set dev swp13 down Query the power mode again: $ ethtool --show-module swp13 Module parameters for swp13: power-mode-policy auto power-mode low Verify with the data read from the EEPROM: # 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 Signed-off-by: Ido Schimmel --- Documentation/networking/ethtool-netlink.rst | 64 ++++++- include/linux/ethtool.h | 25 +++ include/uapi/linux/ethtool.h | 23 +++ include/uapi/linux/ethtool_netlink.h | 17 ++ net/ethtool/Makefile | 2 +- net/ethtool/module.c | 184 +++++++++++++++++++ net/ethtool/netlink.c | 19 ++ net/ethtool/netlink.h | 4 + 8 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 net/ethtool/module.c diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index c690bb37430d..245ce2eab9a5 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -179,7 +179,7 @@ according to message purpose: Userspace to kernel: - ===================================== ================================ + ===================================== ================================= ``ETHTOOL_MSG_STRSET_GET`` get string set ``ETHTOOL_MSG_LINKINFO_GET`` get link settings ``ETHTOOL_MSG_LINKINFO_SET`` set link settings @@ -213,7 +213,9 @@ Userspace to kernel: ``ETHTOOL_MSG_MODULE_EEPROM_GET`` read SFP module EEPROM ``ETHTOOL_MSG_STATS_GET`` get standard statistics ``ETHTOOL_MSG_PHC_VCLOCKS_GET`` get PHC virtual clocks info - ===================================== ================================ + ``ETHTOOL_MSG_MODULE_SET`` set transceiver module parameters + ``ETHTOOL_MSG_MODULE_GET`` get transceiver module parameters + ===================================== ================================= Kernel to userspace: @@ -252,6 +254,7 @@ Kernel to userspace: ``ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY`` read SFP module EEPROM ``ETHTOOL_MSG_STATS_GET_REPLY`` standard statistics ``ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY`` PHC virtual clocks info + ``ETHTOOL_MSG_MODULE_GET_REPLY`` transceiver module parameters ======================================== ================================= ``GET`` requests are sent by userspace applications to retrieve device @@ -1506,6 +1509,61 @@ Kernel response contents: ``ETHTOOL_A_PHC_VCLOCKS_INDEX`` s32 PHC index array ==================================== ====== ========================== +MODULE_GET +========== + +Gets transceiver module parameters. + +Request contents: + + ===================================== ====== ========================== + ``ETHTOOL_A_MODULE_HEADER`` nested request header + ===================================== ====== ========================== + +Kernel response contents: + + ====================================== ====== ========================== + ``ETHTOOL_A_MODULE_HEADER`` nested reply header + ``ETHTOOL_A_MODULE_POWER_MODE_POLICY`` u8 power mode policy + ``ETHTOOL_A_MODULE_POWER_MODE`` u8 operational power mode + ====================================== ====== ========================== + +The optional ``ETHTOOL_A_MODULE_POWER_MODE_POLICY`` attribute encodes the +transceiver module power mode policy enforced by the host. The default policy +is driver-dependent and can be queried using this attribute. + +The optional ``ETHTHOOL_A_MODULE_POWER_MODE`` attribute encodes the operational +power mode policy of the transceiver module. It is only reported when a module +is plugged-in. Possible values are: + +.. kernel-doc:: include/uapi/linux/ethtool.h + :identifiers: ethtool_module_power_mode + +MODULE_SET +========== + +Sets transceiver module parameters. + +Request contents: + + ====================================== ====== ========================== + ``ETHTOOL_A_MODULE_HEADER`` nested request header + ``ETHTOOL_A_MODULE_POWER_MODE_POLICY`` u8 power mode policy + ====================================== ====== ========================== + +When set, the optional ``ETHTOOL_A_MODULE_POWER_MODE_POLICY`` attribute is used +to set the transceiver module power policy enforced by the host. Possible +values are: + +.. kernel-doc:: include/uapi/linux/ethtool.h + :identifiers: ethtool_module_power_mode_policy + +For SFF-8636 modules, low power mode is forced by the host according to table +6-10 in revision 2.10a of the specification. + +For CMIS modules, low power mode is forced by the host according to table 6-12 +in revision 5.0 of the specification. + Request translation =================== @@ -1605,4 +1663,6 @@ are netlink only. n/a ``ETHTOOL_MSG_CABLE_TEST_TDR_ACT`` n/a ``ETHTOOL_MSG_TUNNEL_INFO_GET`` n/a ``ETHTOOL_MSG_PHC_VCLOCKS_GET`` + n/a ``ETHTOOL_MSG_MODULE_GET`` + n/a ``ETHTOOL_MSG_MODULE_SET`` =================================== ===================================== diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 4711b96dae0c..07d40dc20ca4 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -405,6 +405,20 @@ struct ethtool_module_eeprom { u8 *data; }; +/** + * struct ethtool_module_power_mode_params - module power mode parameters + * @policy: The power mode policy enforced by the host for the plug-in module. + * @mode: The operational power mode of the plug-in module. Should be filled by + * device drivers on get operations. + * @mode_valid: Indicates the validity of the @mode field. Should be set by + * device drivers on get operations when a module is plugged-in. + */ +struct ethtool_module_power_mode_params { + enum ethtool_module_power_mode_policy policy; + enum ethtool_module_power_mode mode; + u8 mode_valid:1; +}; + /** * struct ethtool_ops - optional netdev operations * @cap_link_lanes_supported: indicates if the driver supports lanes @@ -570,6 +584,11 @@ struct ethtool_module_eeprom { * @get_eth_ctrl_stats: Query some of the IEEE 802.3 MAC Ctrl statistics. * @get_rmon_stats: Query some of the RMON (RFC 2819) statistics. * Set %ranges to a pointer to zero-terminated array of byte ranges. + * @get_module_power_mode: Get the power mode policy for the plug-in module + * used by the network device and its operational power mode, if + * plugged-in. + * @set_module_power_mode: Set the power mode policy for the plug-in module + * used by the network device. * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -689,6 +708,12 @@ struct ethtool_ops { void (*get_rmon_stats)(struct net_device *dev, struct ethtool_rmon_stats *rmon_stats, const struct ethtool_rmon_hist_range **ranges); + int (*get_module_power_mode)(struct net_device *dev, + struct ethtool_module_power_mode_params *params, + struct netlink_ext_ack *extack); + int (*set_module_power_mode)(struct net_device *dev, + const struct ethtool_module_power_mode_params *params, + struct netlink_ext_ack *extack); }; int ethtool_check_ops(const struct ethtool_ops *ops); diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index b6db6590baf0..8cc79811ee5d 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -706,6 +706,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/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index b3b93710eff7..c22f5c902060 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -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, @@ -831,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/net/ethtool/Makefile b/net/ethtool/Makefile index 0a19470efbfb..b76432e70e6b 100644 --- a/net/ethtool/Makefile +++ b/net/ethtool/Makefile @@ -7,4 +7,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \ linkstate.o debug.o wol.o features.o privflags.o rings.o \ channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \ - tunnels.o fec.o eeprom.o stats.o phc_vclocks.o + tunnels.o fec.o eeprom.o stats.o phc_vclocks.o module.o diff --git a/net/ethtool/module.c b/net/ethtool/module.c new file mode 100644 index 000000000000..ae9ade24f59a --- /dev/null +++ b/net/ethtool/module.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include "netlink.h" +#include "common.h" +#include "bitset.h" + +struct module_req_info { + struct ethnl_req_info base; +}; + +struct module_reply_data { + struct ethnl_reply_data base; + struct ethtool_module_power_mode_params power; + u8 power_valid:1; +}; + +#define MODULE_REPDATA(__reply_base) \ + container_of(__reply_base, struct module_reply_data, base) + +/* MODULE_GET */ + +const struct nla_policy ethnl_module_get_policy[ETHTOOL_A_MODULE_HEADER + 1] = { + [ETHTOOL_A_MODULE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), +}; + +static int module_get_power_mode(struct net_device *dev, + struct module_reply_data *data, + struct netlink_ext_ack *extack) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + int ret; + + if (!ops->get_module_power_mode) + return 0; + + ret = ops->get_module_power_mode(dev, &data->power, extack); + if (ret < 0) + return ret; + + data->power_valid = true; + + return 0; +} + +static int module_prepare_data(const struct ethnl_req_info *req_base, + struct ethnl_reply_data *reply_base, + struct genl_info *info) +{ + struct module_reply_data *data = MODULE_REPDATA(reply_base); + struct netlink_ext_ack *extack = info ? info->extack : NULL; + struct net_device *dev = reply_base->dev; + int ret; + + ret = ethnl_ops_begin(dev); + if (ret < 0) + return ret; + + ret = module_get_power_mode(dev, data, extack); + if (ret < 0) + goto out_complete; + +out_complete: + ethnl_ops_complete(dev); + return ret; +} + +static int module_reply_size(const struct ethnl_req_info *req_base, + const struct ethnl_reply_data *reply_base) +{ + struct module_reply_data *data = MODULE_REPDATA(reply_base); + int len = 0; + + if (data->power_valid) + len += nla_total_size(sizeof(u8)); /* _MODULE_POWER_MODE_POLICY */ + + if (data->power_valid && data->power.mode_valid) + len += nla_total_size(sizeof(u8)); /* _MODULE_POWER_MODE */ + + return len; +} + +static int module_fill_reply(struct sk_buff *skb, + const struct ethnl_req_info *req_base, + const struct ethnl_reply_data *reply_base) +{ + const struct module_reply_data *data = MODULE_REPDATA(reply_base); + + if (data->power_valid && + nla_put_u8(skb, ETHTOOL_A_MODULE_POWER_MODE_POLICY, + data->power.policy)) + return -EMSGSIZE; + + if (data->power_valid && data->power.mode_valid && + nla_put_u8(skb, ETHTOOL_A_MODULE_POWER_MODE, data->power.mode)) + return -EMSGSIZE; + + return 0; +} + +const struct ethnl_request_ops ethnl_module_request_ops = { + .request_cmd = ETHTOOL_MSG_MODULE_GET, + .reply_cmd = ETHTOOL_MSG_MODULE_GET_REPLY, + .hdr_attr = ETHTOOL_A_MODULE_HEADER, + .req_info_size = sizeof(struct module_req_info), + .reply_data_size = sizeof(struct module_reply_data), + + .prepare_data = module_prepare_data, + .reply_size = module_reply_size, + .fill_reply = module_fill_reply, +}; + +/* MODULE_SET */ + +const struct nla_policy ethnl_module_set_policy[ETHTOOL_A_MODULE_POWER_MODE_POLICY + 1] = { + [ETHTOOL_A_MODULE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), + [ETHTOOL_A_MODULE_POWER_MODE_POLICY] = + NLA_POLICY_MAX(NLA_U8, ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO), +}; + +static int module_set_power_mode(struct net_device *dev, struct nlattr **tb, + bool *p_mod, struct netlink_ext_ack *extack) +{ + struct ethtool_module_power_mode_params power = {}; + struct ethtool_module_power_mode_params power_new; + const struct ethtool_ops *ops = dev->ethtool_ops; + int ret; + + if (!tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]) + return 0; + + if (!ops->get_module_power_mode || !ops->set_module_power_mode) { + NL_SET_ERR_MSG_ATTR(extack, + tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY], + "Setting power mode policy is not supported by this device"); + return -EOPNOTSUPP; + } + + power_new.policy = nla_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]); + ret = ops->get_module_power_mode(dev, &power, extack); + if (ret < 0) + return ret; + *p_mod = power_new.policy != power.policy; + + return ops->set_module_power_mode(dev, &power_new, extack); +} + +int ethnl_set_module(struct sk_buff *skb, struct genl_info *info) +{ + struct ethnl_req_info req_info = {}; + struct nlattr **tb = info->attrs; + struct net_device *dev; + bool mod = false; + int ret; + + ret = ethnl_parse_header_dev_get(&req_info, tb[ETHTOOL_A_MODULE_HEADER], + genl_info_net(info), info->extack, + true); + if (ret < 0) + return ret; + dev = req_info.dev; + + rtnl_lock(); + ret = ethnl_ops_begin(dev); + if (ret < 0) + goto out_rtnl; + + ret = module_set_power_mode(dev, tb, &mod, info->extack); + if (ret < 0) + goto out_ops; + + if (!mod) + goto out_ops; + + ethtool_notify(dev, ETHTOOL_MSG_MODULE_NTF, NULL); + +out_ops: + ethnl_ops_complete(dev); +out_rtnl: + rtnl_unlock(); + dev_put(dev); + return ret; +} diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index 1797a0a90019..38b44c0291b1 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -282,6 +282,7 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = { [ETHTOOL_MSG_MODULE_EEPROM_GET] = ðnl_module_eeprom_request_ops, [ETHTOOL_MSG_STATS_GET] = ðnl_stats_request_ops, [ETHTOOL_MSG_PHC_VCLOCKS_GET] = ðnl_phc_vclocks_request_ops, + [ETHTOOL_MSG_MODULE_GET] = ðnl_module_request_ops, }; static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb) @@ -593,6 +594,7 @@ ethnl_default_notify_ops[ETHTOOL_MSG_KERNEL_MAX + 1] = { [ETHTOOL_MSG_PAUSE_NTF] = ðnl_pause_request_ops, [ETHTOOL_MSG_EEE_NTF] = ðnl_eee_request_ops, [ETHTOOL_MSG_FEC_NTF] = ðnl_fec_request_ops, + [ETHTOOL_MSG_MODULE_NTF] = ðnl_module_request_ops, }; /* default notification handler */ @@ -686,6 +688,7 @@ static const ethnl_notify_handler_t ethnl_notify_handlers[] = { [ETHTOOL_MSG_PAUSE_NTF] = ethnl_default_notify, [ETHTOOL_MSG_EEE_NTF] = ethnl_default_notify, [ETHTOOL_MSG_FEC_NTF] = ethnl_default_notify, + [ETHTOOL_MSG_MODULE_NTF] = ethnl_default_notify, }; void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data) @@ -999,6 +1002,22 @@ static const struct genl_ops ethtool_genl_ops[] = { .policy = ethnl_phc_vclocks_get_policy, .maxattr = ARRAY_SIZE(ethnl_phc_vclocks_get_policy) - 1, }, + { + .cmd = ETHTOOL_MSG_MODULE_GET, + .doit = ethnl_default_doit, + .start = ethnl_default_start, + .dumpit = ethnl_default_dumpit, + .done = ethnl_default_done, + .policy = ethnl_module_get_policy, + .maxattr = ARRAY_SIZE(ethnl_module_get_policy) - 1, + }, + { + .cmd = ETHTOOL_MSG_MODULE_SET, + .flags = GENL_UNS_ADMIN_PERM, + .doit = ethnl_set_module, + .policy = ethnl_module_set_policy, + .maxattr = ARRAY_SIZE(ethnl_module_set_policy) - 1, + }, }; static const struct genl_multicast_group ethtool_nl_mcgrps[] = { diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h index 077aac3929a8..1aafba5b67bb 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -337,6 +337,7 @@ extern const struct ethnl_request_ops ethnl_fec_request_ops; extern const struct ethnl_request_ops ethnl_module_eeprom_request_ops; extern const struct ethnl_request_ops ethnl_stats_request_ops; extern const struct ethnl_request_ops ethnl_phc_vclocks_request_ops; +extern const struct ethnl_request_ops ethnl_module_request_ops; extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1]; extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1]; @@ -373,6 +374,8 @@ extern const struct nla_policy ethnl_fec_set_policy[ETHTOOL_A_FEC_AUTO + 1]; extern const struct nla_policy ethnl_module_eeprom_get_policy[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS + 1]; extern const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1]; extern const struct nla_policy ethnl_phc_vclocks_get_policy[ETHTOOL_A_PHC_VCLOCKS_HEADER + 1]; +extern const struct nla_policy ethnl_module_get_policy[ETHTOOL_A_MODULE_HEADER + 1]; +extern const struct nla_policy ethnl_module_set_policy[ETHTOOL_A_MODULE_POWER_MODE_POLICY + 1]; int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info); int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info); @@ -391,6 +394,7 @@ int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info); int ethnl_tunnel_info_start(struct netlink_callback *cb); int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb); int ethnl_set_fec(struct sk_buff *skb, struct genl_info *info); +int ethnl_set_module(struct sk_buff *skb, struct genl_info *info); extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN]; extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN]; From patchwork Tue Aug 24 13:05:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 502174 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 132C6C4338F for ; Tue, 24 Aug 2021 13:05:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0E4A61374 for ; Tue, 24 Aug 2021 13:05:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237518AbhHXNG2 (ORCPT ); Tue, 24 Aug 2021 09:06:28 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:46431 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237506AbhHXNG1 (ORCPT ); Tue, 24 Aug 2021 09:06:27 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 0E822580B17; Tue, 24 Aug 2021 09:05:43 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 24 Aug 2021 09:05:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=k5cJ6SXeUq2uTmbWzFA0RdcXQKCRPO30VQ7JfNCXJNw=; b=ElkV/Frw gmZ6zCfZapgNKZW2r3P/5KcJ039HFCRs2yOA2m1UD0+gStHW7LPw7oian+TMEoLO etxRZHGeTPWBH8n+r12LZpYyke5BtWyyAIes5T7oy44KuZnHfxcsTRFcPYpanf3N dL+Gavcq7xPfG7666nz30SmVvron38Maal4XSqKPxdf9PTqXwsj2m9R/cYi7fEv8 6HWvw5UPJ/u92TaqjpJJX27JYBxcOZ9qKFWWzuN8N8ZVYkMf5iv2FduyWhltyiM7 G9UN4Fc7B1N93kYqjoX1PdBI+5nMO6Aqy6G2yuNFAAftwMhmXnprD8q0/iSqVhaD sjSXfg+Z8Goyug== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecuvehluhhsthgvrhfuihiivgepudenucfr rghrrghmpehmrghilhhfrhhomhepihguohhstghhsehiughoshgthhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 09:05:38 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch, mkubecek@suse.cz, pali@kernel.org, jacob.e.keller@intel.com, jiri@nvidia.com, vadimp@nvidia.com, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH ethtool-next v3 2/6] ethtool: Add ability to control transceiver modules' power mode Date: Tue, 24 Aug 2021 16:05:11 +0300 Message-Id: <20210824130515.1828270-3-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210824130515.1828270-1-idosch@idosch.org> References: <20210824130515.1828270-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel 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 --- 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 " and + * "ethtool --set-module ..." + */ + +#include +#include +#include +#include +#include + +#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 From patchwork Tue Aug 24 13:03:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 502177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46B61C4338F for ; Tue, 24 Aug 2021 13:04:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2EA55613BD for ; Tue, 24 Aug 2021 13:04:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237472AbhHXNF1 (ORCPT ); Tue, 24 Aug 2021 09:05:27 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:57823 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237463AbhHXNFZ (ORCPT ); Tue, 24 Aug 2021 09:05:25 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id A436C580B13; Tue, 24 Aug 2021 09:04:41 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Tue, 24 Aug 2021 09:04:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=uaH6gIO9jSc0rt1izId1IU5t4+RcSMjHQkMx39VP+HQ=; b=If67y3yu HpwkozQXTGgJcraSHTYpY3CrBbsWe2xipujTwcIkS12PvGrBfl+d4eA4RHGQCIQZ A8zjnorzJkzCVYHYQNBmkB+QzNQULdvyBPFFy0Lq+V54Z/wLagyPl7vtept8nZTm rnt4QeIFxj9fEPdS9+q1T6IpAFaGtBCsvjFgcLFn25SBXW6BnLTK+GPnXpiNPAjf ZiVXql15E90RcyTnH8/g04n2Pj+wsQwRYRBjtOe2seXXNwFeUUcl9zGjuskeZM5o WnLbrUeDWOgCOvQfBjQsGjIghXIXlQAuUo2/G5nK1yDah9KkJOQgWV8Mfy56/eCh X0wqqrT/4AG1ig== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecuvehluhhsthgvrhfuihiivgepudenucfr rghrrghmpehmrghilhhfrhhomhepihguohhstghhsehiughoshgthhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 09:04:38 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch, mkubecek@suse.cz, pali@kernel.org, jacob.e.keller@intel.com, jiri@nvidia.com, vadimp@nvidia.com, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next v3 3/6] mlxsw: reg: Add Management Cable IO and Notifications register Date: Tue, 24 Aug 2021 16:03:41 +0300 Message-Id: <20210824130344.1828076-4-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210824130344.1828076-1-idosch@idosch.org> References: <20210824130344.1828076-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Add the Management Cable IO and Notifications register. It will be used to retrieve the power mode status of a module in subsequent patches and whether a module is present in a cage or not. Signed-off-by: Ido Schimmel --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index fe9bf6ce3508..b862e56c1f9e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -10321,6 +10321,39 @@ static inline void mlxsw_reg_mlcr_pack(char *payload, u8 local_port, MLXSW_REG_MLCR_DURATION_MAX : 0); } +/* MCION - Management Cable IO and Notifications Register + * ------------------------------------------------------ + * The MCION register is used to query transceiver modules' IO pins and other + * notifications. + */ +#define MLXSW_REG_MCION_ID 0x9052 +#define MLXSW_REG_MCION_LEN 0x18 + +MLXSW_REG_DEFINE(mcion, MLXSW_REG_MCION_ID, MLXSW_REG_MCION_LEN); + +/* reg_mcion_module + * Module number. + * Access: Index + */ +MLXSW_ITEM32(reg, mcion, module, 0x00, 16, 8); + +enum { + MLXSW_REG_MCION_MODULE_STATUS_BITS_PRESENT_MASK = BIT(0), + MLXSW_REG_MCION_MODULE_STATUS_BITS_LOW_POWER_MASK = BIT(8), +}; + +/* reg_mcion_module_status_bits + * Module IO status as defined by SFF. + * Access: RO + */ +MLXSW_ITEM32(reg, mcion, module_status_bits, 0x04, 0, 16); + +static inline void mlxsw_reg_mcion_pack(char *payload, u8 module) +{ + MLXSW_REG_ZERO(mcion, payload); + mlxsw_reg_mcion_module_set(payload, module); +} + /* MTPPS - Management Pulse Per Second Register * -------------------------------------------- * This register provides the device PPS capabilities, configure the PPS in and @@ -12364,6 +12397,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { MLXSW_REG(mgir), MLXSW_REG(mrsr), MLXSW_REG(mlcr), + MLXSW_REG(mcion), MLXSW_REG(mtpps), MLXSW_REG(mtutc), MLXSW_REG(mpsc), From patchwork Tue Aug 24 13:05:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 502173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0FD22C4338F for ; Tue, 24 Aug 2021 13:05:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5AFC61371 for ; Tue, 24 Aug 2021 13:05:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237501AbhHXNGh (ORCPT ); Tue, 24 Aug 2021 09:06:37 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:52591 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237539AbhHXNGf (ORCPT ); Tue, 24 Aug 2021 09:06:35 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id AFF3C580B21; Tue, 24 Aug 2021 09:05:50 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 24 Aug 2021 09:05:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=DlZphT4WJkAFNXjv52U0aaeNvJwGwWQwNe2FmH2RQ7M=; b=DFGlOe4d sAnatNnZuqr2N1cNkXENyQtGdBQcl+BTNGYVH1SUENU6fRxXn9bGdtyB4Yojvska hcOWDlb1SnbhyVYQ6PQhnKaPqHM/0z4eiifj2w141TNsCHwWYXnI4itE1LZlG9fh ZQHaIecQrX87Quk1j/msXPi/OheB6jDPqDX2AI3xN9Lb13ps3+rhWKer1aPdE5QB HcxXuIdlpWFl4PdsTMdcvZI5qKjLZZCFozsXOPBZSuIKbG5+58sjSCUdWf8f9viZ 9sB+Dre+Vl4lpY+Qi9wk/B5k3J25uHycZYgs3wRk4+LL46gQL07e4cbjUgOLdLru yAYj+YMRxvKbPA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecuvehluhhsthgvrhfuihiivgepvdenucfr rghrrghmpehmrghilhhfrhhomhepihguohhstghhsehiughoshgthhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 09:05:46 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch, mkubecek@suse.cz, pali@kernel.org, jacob.e.keller@intel.com, jiri@nvidia.com, vadimp@nvidia.com, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH ethtool-next v3 4/6] ethtool: Print CMIS Module-Level Controls Date: Tue, 24 Aug 2021 16:05:13 +0300 Message-Id: <20210824130515.1828270-5-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210824130515.1828270-1-idosch@idosch.org> References: <20210824130515.1828270-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel 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 --- 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) */ From patchwork Tue Aug 24 13:03:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 502176 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A7A6C4338F for ; Tue, 24 Aug 2021 13:04:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4333E61371 for ; Tue, 24 Aug 2021 13:04:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237496AbhHXNFi (ORCPT ); Tue, 24 Aug 2021 09:05:38 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:48389 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237470AbhHXNFe (ORCPT ); Tue, 24 Aug 2021 09:05:34 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id C99515803E9; Tue, 24 Aug 2021 09:04:49 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Tue, 24 Aug 2021 09:04:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=PF6mVx16rimKKOC+b+uNYjnoT9ynubRMQrM0kk6CEOI=; b=rbeeLRiD 8gjPHNceCKVsY/53eoDyThzIhd98xYvpCRGge9IuebMX4XGZSsSgQH9FbyZkjO9k TS7zeor5u/6u0VT5zFNLIk75Wa2rKstGTDXBBVsnsf/t31ywByhkL/YYhdwJbZeP XnTnq9Hs3hcpR3/e1z9fp+EPR5FpFFro0GaaOpAIzTUEHx2gQ0T0p7YplfZiNgeI yk9zL7XpQ3hgorNf6jKrB1F6CwwWVewz3gP2arlJVAQzNyZ0iF9e1QKyYFKZZPR8 8yybcxN9zbDYcRKhYViPVvOPPmS+lgrh8bT7KMfgSnK3lsKs6wFjMvaUv7fYSBpp HmNkvfbWt9E4dA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecuvehluhhsthgvrhfuihiivgeptdenucfr rghrrghmpehmrghilhhfrhhomhepihguohhstghhsehiughoshgthhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 09:04:45 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch, mkubecek@suse.cz, pali@kernel.org, jacob.e.keller@intel.com, jiri@nvidia.com, vadimp@nvidia.com, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next v3 5/6] ethtool: Add transceiver module extended states Date: Tue, 24 Aug 2021 16:03:43 +0300 Message-Id: <20210824130344.1828076-6-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210824130344.1828076-1-idosch@idosch.org> References: <20210824130344.1828076-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Add an extended state and two extended sub-states to describe link issues related to transceiver modules. The first, 'ETHTOOL_LINK_EXT_SUBSTATE_MODULE_LOW_POWER_MODE', tells user space that port is unable to gain a carrier because the associated transceiver module is in low power mode where the data path is deactivated. This is applicable to both SFF-8636 and CMIS modules. Currently, user space cannot force a module to stay in low power mode while putting the associated port administratively up, so the extended sub-state is indicative of a problem in the module/driver. The second, 'ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY', tells user space that port is unable to gain a carrier because the CMIS Module State Machine did not reach the ModuleReady (Fully Operational) state. For example, if the module is stuck at ModuleFault state. In which case, user space can read the fault reason from the module's EEPROM and potentially reset it. For CMIS modules, the first extended sub-state is contained in the second, but has the added advantage of being applicable to more module types and being more specific about the nature of the problem. Signed-off-by: Ido Schimmel --- Documentation/networking/ethtool-netlink.rst | 12 ++++++++++++ include/linux/ethtool.h | 1 + include/uapi/linux/ethtool.h | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index 245ce2eab9a5..c258b3f30a2e 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -523,6 +523,8 @@ Link extended states: power required from cable or module ``ETHTOOL_LINK_EXT_STATE_OVERHEAT`` The module is overheated + + ``ETHTOOL_LINK_EXT_STATE_MODULE`` Transceiver module issue ================================================ ============================================ Link extended substates: @@ -616,6 +618,16 @@ Link extended substates: ``ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE`` Cable test failure =================================================== ============================================ + Transceiver module issue substates: + + =================================================== ============================================ + ``ETHTOOL_LINK_EXT_SUBSTATE_MODULE_LOW_POWER_MODE`` The transceiver module is in low power mode + + ``ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY`` The CMIS Module State Machine did not reach + the ModuleReady state. For example, if the + module is stuck at ModuleFault state + =================================================== ============================================ + DEBUG_GET ========= diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 07d40dc20ca4..1f71293011ca 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -93,6 +93,7 @@ struct ethtool_link_ext_state_info { enum ethtool_link_ext_substate_link_logical_mismatch link_logical_mismatch; enum ethtool_link_ext_substate_bad_signal_integrity bad_signal_integrity; enum ethtool_link_ext_substate_cable_issue cable_issue; + enum ethtool_link_ext_substate_module module; u8 __link_ext_substate; }; }; diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 8cc79811ee5d..7d453f0e993b 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -603,6 +603,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. */ @@ -649,6 +650,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 /** From patchwork Tue Aug 24 13:05:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 502172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E7EAC4320A for ; Tue, 24 Aug 2021 13:06:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5148B61371 for ; Tue, 24 Aug 2021 13:06:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237539AbhHXNGo (ORCPT ); Tue, 24 Aug 2021 09:06:44 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:35137 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237535AbhHXNGm (ORCPT ); Tue, 24 Aug 2021 09:06:42 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id 55C3B580B17; Tue, 24 Aug 2021 09:05:58 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 24 Aug 2021 09:05:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=GvFQ9hoooGgfsBfqutyn9AFFOLnjnbBbsrHhXSsgdoo=; b=gPKtLvJd PeOAOMAVoBeBpusi+2L0Yuga1MQ/k8NwHVwnEYsuPohiOVUJ292pVlxX1KLCJAyi pND+viD1ZericJgv5XmgAOrPqK8F0OI6WHus9lx0Mm7HMUGt/VnJ7gWPmDVLyiVs DB9ze4Wq7nmJgUCEeC3x/WPeMzxJSuFGPPxQd57ExPuRsp+7ba/DmE2Rpm6lpmen 6Y5lVG8qW2apUbYrlvUrytKFg/iZQLNIWaI8VZkO3cwNuu27udfcSWXiEfPug3LZ IiBwB8Pky7XcmWkpMoOFtYdGHNxAVXXncnEixuztwJ0YMkBO5c7qxiw+basZz81s xZWohFF/V/ZmaA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecuvehluhhsthgvrhfuihiivgepfeenucfr rghrrghmpehmrghilhhfrhhomhepihguohhstghhsehiughoshgthhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 09:05:55 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch, mkubecek@suse.cz, pali@kernel.org, jacob.e.keller@intel.com, jiri@nvidia.com, vadimp@nvidia.com, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH ethtool-next v3 6/6] ethtool: Add transceiver module extended states Date: Tue, 24 Aug 2021 16:05:15 +0300 Message-Id: <20210824130515.1828270-7-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210824130515.1828270-1-idosch@idosch.org> References: <20210824130515.1828270-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel 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 --- 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; }