From patchwork Wed Jun 23 07:59:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 12339259 X-Patchwork-Delegate: kuba@kernel.org 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.8 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,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 98920C4743C for ; Wed, 23 Jun 2021 08:01:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C9516128C for ; Wed, 23 Jun 2021 08:01:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230263AbhFWIDh (ORCPT ); Wed, 23 Jun 2021 04:03:37 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:58033 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230109AbhFWIDc (ORCPT ); Wed, 23 Jun 2021 04:03:32 -0400 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailnew.nyi.internal (Postfix) with ESMTP id 6477E58070E; Wed, 23 Jun 2021 04:01:15 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Wed, 23 Jun 2021 04:01:15 -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=MXmnEKvwlwdvA3DAlhcuaoIxaFThqGtxYqAmSLjeoDs=; b=kjY9xA83 2srl6VQrD9Hy+LqyVmiGRchtRL9gC9nOgOTAsvOhgqt8srY7PjZxUMz9TrrgAU9m P6QEkQG3fZG5x70X6sawDlgZwamdOtihtKrTXjTzsC3T8cCES+cus493HYORgJk9 UoRfFPKA6eai/KfzwKX6h/b0HMyfv/pwim48j5Z2BNzUJNyMrqbac4jbAKDioQ6p tUB7gQRND+nnTVenldP+n198FRMKkKbn5idyUfwHwlekDfqx/WmahbTOcjF6VG3j 2Hez3VvIfzxfVD2QE9FCUJf/g+d3W55Dn/l/4VJE2wNpNnzYw4qm2L+oz4FA0PzP EXVjhoIeB8OaXg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrfeegvddguddukecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtke ertdertddtnecuhfhrohhmpefkughoucfutghhihhmmhgvlhcuoehiughoshgthhesihgu ohhstghhrdhorhhgqeenucggtffrrghtthgvrhhnpeduteeiveffffevleekleejffekhf ekhefgtdfftefhledvjefggfehgfevjeekhfenucevlhhushhtvghrufhiiigvpedtnecu rfgrrhgrmhepmhgrihhlfhhrohhmpehiughoshgthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 23 Jun 2021 04:01:12 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, andrew@lunn.ch, vladyslavt@nvidia.com, moshe@nvidia.com, vadimp@nvidia.com, mkubecek@suse.cz, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next 1/4] ethtool: Extract module EEPROM attributes before validation Date: Wed, 23 Jun 2021 10:59:22 +0300 Message-Id: <20210623075925.2610908-2-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210623075925.2610908-1-idosch@idosch.org> References: <20210623075925.2610908-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC From: Ido Schimmel Move the extraction of the attributes before their validation, so that the validation could be easily split into a different function in the subsequent patch. No functional changes intended. Signed-off-by: Ido Schimmel Reviewed-by: Jiri Pirko --- net/ethtool/eeprom.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c index 7e6b37a54add..ed5f677f27cd 100644 --- a/net/ethtool/eeprom.c +++ b/net/ethtool/eeprom.c @@ -158,6 +158,9 @@ static int eeprom_parse_request(struct ethnl_req_info *req_info, struct nlattr * request->i2c_address = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS]); request->offset = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_OFFSET]); request->length = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_LENGTH]); + request->page = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_PAGE]); + if (tb[ETHTOOL_A_MODULE_EEPROM_BANK]) + request->bank = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_BANK]); /* The following set of conditions limit the API to only dump 1/2 * EEPROM page without crossing low page boundary located at offset 128. @@ -165,7 +168,6 @@ static int eeprom_parse_request(struct ethnl_req_info *req_info, struct nlattr * * either low 128 bytes or high 128 bytes. * For pages higher than 0 only high 128 bytes are accessible. */ - request->page = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_PAGE]); if (request->page && request->offset < ETH_MODULE_EEPROM_PAGE_LEN) { NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_PAGE], "reading from lower half page is allowed for page 0 only"); @@ -183,9 +185,6 @@ static int eeprom_parse_request(struct ethnl_req_info *req_info, struct nlattr * return -EINVAL; } - if (tb[ETHTOOL_A_MODULE_EEPROM_BANK]) - request->bank = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_BANK]); - return 0; } From patchwork Wed Jun 23 07:59:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 12339261 X-Patchwork-Delegate: kuba@kernel.org 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.8 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,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 2DD04C4743C for ; Wed, 23 Jun 2021 08:01:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 15A81611BF for ; Wed, 23 Jun 2021 08:01:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230225AbhFWIDw (ORCPT ); Wed, 23 Jun 2021 04:03:52 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:35409 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230151AbhFWIDf (ORCPT ); Wed, 23 Jun 2021 04:03:35 -0400 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 9A7C758070A; Wed, 23 Jun 2021 04:01:18 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Wed, 23 Jun 2021 04:01:18 -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=zS9tM4dmIwlbodz0mKkPhn3uk5Joo5/en22CRaNA/UU=; b=nXvE2Ofo 9Rl2jmU+xiEDio35Z8OkHvitRSOUXCwIvN/9EYAJoRlWhRodGRca7lcGTgz+XacZ xzf+CPZJMr6g9hYghWEa4rZjMoUzgFe+rtAxLkinjIJ2ITH1PT7R3ip8DO4fxIRW UShrJuGmvGdOwYhH3vw1IuHFG4E4TmjXj5nF5kQSwgQ1ocKBsdkHywiI2DIUDKYJ GMEKbQyUH46OJPPCBpr/elu4njyX3EMPWS19WQc7/7lMR0wHOcXe47/ZKoyPoTmF l068kBCPWrSvaTRuFSIFiRaOPAqPjZkCzN46Hdtzsrm3cX4M61DXryiA2YD2fo/P 5nbUJ3b3EBqikw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrfeegvddguddujecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtke ertdertddtnecuhfhrohhmpefkughoucfutghhihhmmhgvlhcuoehiughoshgthhesihgu ohhstghhrdhorhhgqeenucggtffrrghtthgvrhhnpeduteeiveffffevleekleejffekhf ekhefgtdfftefhledvjefggfehgfevjeekhfenucevlhhushhtvghrufhiiigvpedtnecu rfgrrhgrmhepmhgrihhlfhhrohhmpehiughoshgthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 23 Jun 2021 04:01:15 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, andrew@lunn.ch, vladyslavt@nvidia.com, moshe@nvidia.com, vadimp@nvidia.com, mkubecek@suse.cz, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next 2/4] ethtool: Split module EEPROM attributes validation to a function Date: Wed, 23 Jun 2021 10:59:23 +0300 Message-Id: <20210623075925.2610908-3-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210623075925.2610908-1-idosch@idosch.org> References: <20210623075925.2610908-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC From: Ido Schimmel The same validation will be needed for module EEPROM write access in the subsequent patch, so split it into a function. Modify the extack messages a bit to not be specific to read access. No functional changes intended. Signed-off-by: Ido Schimmel Reviewed-by: Jiri Pirko --- net/ethtool/eeprom.c | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c index ed5f677f27cd..945b95e64f0d 100644 --- a/net/ethtool/eeprom.c +++ b/net/ethtool/eeprom.c @@ -144,10 +144,41 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base, return ret; } +static int eeprom_validate(struct nlattr **tb, struct netlink_ext_ack *extack) +{ + u32 offset = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_OFFSET]); + u32 length = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_LENGTH]); + u8 page = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_PAGE]); + + /* The following set of conditions limit the API to only access 1/2 + * EEPROM page without crossing low page boundary located at offset + * 128. For pages higher than 0, only high 128 bytes are accessible. + */ + if (page && offset < ETH_MODULE_EEPROM_PAGE_LEN) { + NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_PAGE], + "access to lower half page is allowed for page 0 only"); + return -EINVAL; + } + + if (offset < ETH_MODULE_EEPROM_PAGE_LEN && + offset + length > ETH_MODULE_EEPROM_PAGE_LEN) { + NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_LENGTH], + "crossing half page boundary is illegal"); + return -EINVAL; + } else if (offset + length > ETH_MODULE_EEPROM_PAGE_LEN * 2) { + NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_LENGTH], + "crossing page boundary is illegal"); + return -EINVAL; + } + + return 0; +} + static int eeprom_parse_request(struct ethnl_req_info *req_info, struct nlattr **tb, struct netlink_ext_ack *extack) { struct eeprom_req_info *request = MODULE_EEPROM_REQINFO(req_info); + int err; if (!tb[ETHTOOL_A_MODULE_EEPROM_OFFSET] || !tb[ETHTOOL_A_MODULE_EEPROM_LENGTH] || @@ -155,6 +186,10 @@ static int eeprom_parse_request(struct ethnl_req_info *req_info, struct nlattr * !tb[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS]) return -EINVAL; + err = eeprom_validate(tb, extack); + if (err) + return err; + request->i2c_address = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS]); request->offset = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_OFFSET]); request->length = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_LENGTH]); @@ -162,29 +197,6 @@ static int eeprom_parse_request(struct ethnl_req_info *req_info, struct nlattr * if (tb[ETHTOOL_A_MODULE_EEPROM_BANK]) request->bank = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_BANK]); - /* The following set of conditions limit the API to only dump 1/2 - * EEPROM page without crossing low page boundary located at offset 128. - * This means user may only request dumps of length limited to 128 from - * either low 128 bytes or high 128 bytes. - * For pages higher than 0 only high 128 bytes are accessible. - */ - if (request->page && request->offset < ETH_MODULE_EEPROM_PAGE_LEN) { - NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_PAGE], - "reading from lower half page is allowed for page 0 only"); - return -EINVAL; - } - - if (request->offset < ETH_MODULE_EEPROM_PAGE_LEN && - request->offset + request->length > ETH_MODULE_EEPROM_PAGE_LEN) { - NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_LENGTH], - "reading cross half page boundary is illegal"); - return -EINVAL; - } else if (request->offset + request->length > ETH_MODULE_EEPROM_PAGE_LEN * 2) { - NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_LENGTH], - "reading cross page boundary is illegal"); - return -EINVAL; - } - return 0; } From patchwork Wed Jun 23 07:59:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 12339263 X-Patchwork-Delegate: kuba@kernel.org 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.8 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,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 95162C48BC2 for ; Wed, 23 Jun 2021 08:01:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7A0C560FEE for ; Wed, 23 Jun 2021 08:01:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230135AbhFWID5 (ORCPT ); Wed, 23 Jun 2021 04:03:57 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:53185 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230273AbhFWIDj (ORCPT ); Wed, 23 Jun 2021 04:03:39 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id EF63B580709; Wed, 23 Jun 2021 04:01:21 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Wed, 23 Jun 2021 04:01:21 -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=VIp+bhIp3mYonk/f1uQ5ROwnOm/7WKJ1lUe9jtFBXf0=; b=iEIvvNHW ibabgWcIzh3kkaIQ7guyvfzJAERwPhCreZPyQoQkhPiAOjoftbhB/t4qNxbdrnwJ TI7hKr2KXkWAWZ4HY9y68qYl+1e1mgjjZhg4w2bbhbOxg2pwUR5mac19NApwLGMK z66wCB0Ky7rHsibXMeF4jrVZiMbUsLU4h482mbk3vOY8bbXVp07u19WmKeQ8liFb D58/2XTnrUD3idPePqzBzMkyArWv1GctrX7Wuudb3xKzNc0yyLdxLJ8GR8c4Ftt6 ngQ183UvXXMHTJSejGoh8CnX83cYxONNNgn/IbvlkwcCJHRbPqccZPRFDW/cfFBj oEk2gSRMAdHoyg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrfeegvddguddukecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtke ertdertddtnecuhfhrohhmpefkughoucfutghhihhmmhgvlhcuoehiughoshgthhesihgu ohhstghhrdhorhhgqeenucggtffrrghtthgvrhhnpeduteeiveffffevleekleejffekhf ekhefgtdfftefhledvjefggfehgfevjeekhfenucevlhhushhtvghrufhiiigvpedtnecu rfgrrhgrmhepmhgrihhlfhhrohhmpehiughoshgthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 23 Jun 2021 04:01:18 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, andrew@lunn.ch, vladyslavt@nvidia.com, moshe@nvidia.com, vadimp@nvidia.com, mkubecek@suse.cz, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next 3/4] ethtool: Add ability to write to transceiver module EEPROM Date: Wed, 23 Jun 2021 10:59:24 +0300 Message-Id: <20210623075925.2610908-4-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210623075925.2610908-1-idosch@idosch.org> References: <20210623075925.2610908-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC From: Ido Schimmel In a similar fashion to read access to transceiver module EEPROM by page, add write access. This allows user space to configure various registers specified in the transceiver module EEPROM memory map (e.g., SFF-8636, CMIS). In the case of CMIS, this also allows user space to implement various Command Data Block (CDB) messages for interaction with the module. This is required for advanced functionality such as firmware update. The new generic netlink command (i.e., 'ETHTOOL_MSG_MODULE_EEPROM_SET') is fully described in Documentation/networking/ethtool-netlink.rst. Note that while the 'ETHTOOL_A_MODULE_EEPROM_LENGTH' attribute might seem redundant, it allows the kernel to validate 'ETHTOOL_MSG_MODULE_EEPROM_SET' messages in a similar fashion to 'ETHTOOL_MSG_MODULE_EEPROM_GET' messages. In addition, it adds another confirmation regarding the number of bytes to write to the module EEPROM. Signed-off-by: Ido Schimmel Reviewed-by: Jiri Pirko --- Documentation/networking/ethtool-netlink.rst | 47 +++++++ include/linux/ethtool.h | 21 ++- include/uapi/linux/ethtool_netlink.h | 2 + net/ethtool/eeprom.c | 133 +++++++++++++++++++ net/ethtool/netlink.c | 7 + net/ethtool/netlink.h | 2 + 6 files changed, 205 insertions(+), 7 deletions(-) diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index 6ea91e41593f..b7da1f5a9a9d 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -212,6 +212,7 @@ Userspace to kernel: ``ETHTOOL_MSG_FEC_SET`` set FEC settings ``ETHTOOL_MSG_MODULE_EEPROM_GET`` read SFP module EEPROM ``ETHTOOL_MSG_STATS_GET`` get standard statistics + ``ETHTOOL_MSG_MODULE_EEPROM_SET`` write to SFP module EEPROM ===================================== ================================ Kernel to userspace: @@ -250,6 +251,7 @@ Kernel to userspace: ``ETHTOOL_MSG_FEC_NTF`` FEC settings ``ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY`` read SFP module EEPROM ``ETHTOOL_MSG_STATS_GET_REPLY`` standard statistics + ``ETHTOOL_MSG_MODULE_EEPROM_NTF`` SFP module EEPROM settings ======================================== ================================= ``GET`` requests are sent by userspace applications to retrieve device @@ -1477,6 +1479,50 @@ Low and high bounds are inclusive, for example: etherStatsPkts512to1023Octets 512 1023 ============================= ==== ==== +MODULE_EEPROM_SET +================= + +Write to SFP module EEPROM. +This interface is designed to allow writes of at most 1/2 page at once. This +means only writes of 128 (or less) bytes are allowed, without crossing half +page boundary located at offset 128. For pages other than 0 only high 128 bytes +are accessible. + +Request contents: + + ======================================= ====== ========================== + ``ETHTOOL_A_MODULE_EEPROM_HEADER`` nested request header + ``ETHTOOL_A_MODULE_EEPROM_OFFSET`` u32 offset within a page + ``ETHTOOL_A_MODULE_EEPROM_LENGTH`` u32 amount of bytes to write + ``ETHTOOL_A_MODULE_EEPROM_PAGE`` u8 page number + ``ETHTOOL_A_MODULE_EEPROM_BANK`` u8 bank number + ``ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS`` u8 page I2C address + ``ETHTOOL_A_MODULE_EEPROM_DATA`` binary array of bytes to write + ======================================= ====== ========================== + +The amount of bytes to write encoded in ``ETHTOOL_A_MODULE_EEPROM_LENGTH`` must +match the length of the payload of ``ETHTOOL_A_MODULE_EEPROM_DATA``. + +If ``ETHTOOL_A_MODULE_EEPROM_BANK`` is not specified, bank 0 is assumed. + +Upon a successful write, a ``ETHTOOL_MSG_MODULE_EEPROM_NTF`` notification is +sent to user space. + +Notification contents: + + ======================================= ====== ========================== + ``ETHTOOL_A_MODULE_EEPROM_HEADER`` nested reply header + ``ETHTOOL_A_MODULE_EEPROM_OFFSET`` u32 offset within a page + ``ETHTOOL_A_MODULE_EEPROM_LENGTH`` u32 amount of bytes written + ``ETHTOOL_A_MODULE_EEPROM_PAGE`` u8 page number + ``ETHTOOL_A_MODULE_EEPROM_BANK`` u8 bank number + ``ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS`` u8 page I2C address + ======================================= ====== ========================== + +The notification does not include the ``ETHTOOL_A_MODULE_EEPROM_DATA`` +attribute in order to prevent exposing module EEPROM contents to users without +admin privileges. + Request translation =================== @@ -1575,4 +1621,5 @@ are netlink only. n/a ``ETHTOOL_MSG_CABLE_TEST_ACT`` n/a ``ETHTOOL_MSG_CABLE_TEST_TDR_ACT`` n/a ``ETHTOOL_MSG_TUNNEL_INFO_GET`` + n/a ``ETHTOOL_MSG_MODULE_EEPROM_SET`` =================================== ===================================== diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 29dbb603bc91..a91e31a1aeeb 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -388,17 +388,19 @@ struct ethtool_rmon_stats { #define ETH_MODULE_MAX_I2C_ADDRESS 0x7f /** - * struct ethtool_module_eeprom - EEPROM dump from specified page - * @offset: Offset within the specified EEPROM page to begin read, in bytes. - * @length: Number of bytes to read. - * @page: Page number to read from. - * @bank: Page bank number to read from, if applicable by EEPROM spec. + * struct ethtool_module_eeprom - EEPROM read / write from / to specified page + * @offset: Offset within the specified EEPROM page to begin read / write, + * in bytes. + * @length: Number of bytes to read / write. + * @page: Page number to read / write from / to. + * @bank: Page bank number to read / write from /to , if applicable by EEPROM + * spec. * @i2c_address: I2C address of a page. Value less than 0x7f expected. Most * EEPROMs use 0x50 or 0x51. * @data: Pointer to buffer with EEPROM data of @length size. * - * This can be used to manage pages during EEPROM dump in ethtool and pass - * required information to the driver. + * This can be used to manage pages during EEPROM read / write in ethtool and + * pass required information to the driver. */ struct ethtool_module_eeprom { u32 offset; @@ -574,6 +576,8 @@ 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. + * @set_module_eeprom_by_page: Write to a region of plug-in module EEPROM. + * Returns a negative error code or zero. * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -693,6 +697,9 @@ 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 (*set_module_eeprom_by_page)(struct net_device *dev, + const struct ethtool_module_eeprom *page, + struct netlink_ext_ack *extack); }; int ethtool_check_ops(const struct ethtool_ops *ops); diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index c7135c9c37a5..9cf2f5a860ba 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -46,6 +46,7 @@ enum { ETHTOOL_MSG_FEC_SET, ETHTOOL_MSG_MODULE_EEPROM_GET, ETHTOOL_MSG_STATS_GET, + ETHTOOL_MSG_MODULE_EEPROM_SET, /* add new constants above here */ __ETHTOOL_MSG_USER_CNT, @@ -88,6 +89,7 @@ enum { ETHTOOL_MSG_FEC_NTF, ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, ETHTOOL_MSG_STATS_GET_REPLY, + ETHTOOL_MSG_MODULE_EEPROM_NTF, /* add new constants above here */ __ETHTOOL_MSG_KERNEL_CNT, diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c index 945b95e64f0d..dc8ffa67b249 100644 --- a/net/ethtool/eeprom.c +++ b/net/ethtool/eeprom.c @@ -250,3 +250,136 @@ const struct nla_policy ethnl_module_eeprom_get_policy[] = { NLA_POLICY_RANGE(NLA_U8, 0, ETH_MODULE_MAX_I2C_ADDRESS), }; +const struct nla_policy ethnl_module_eeprom_set_policy[] = { + [ETHTOOL_A_MODULE_EEPROM_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), + [ETHTOOL_A_MODULE_EEPROM_OFFSET] = + NLA_POLICY_MAX(NLA_U32, ETH_MODULE_EEPROM_PAGE_LEN * 2 - 1), + [ETHTOOL_A_MODULE_EEPROM_LENGTH] = + NLA_POLICY_RANGE(NLA_U32, 1, ETH_MODULE_EEPROM_PAGE_LEN), + [ETHTOOL_A_MODULE_EEPROM_PAGE] = { .type = NLA_U8 }, + [ETHTOOL_A_MODULE_EEPROM_BANK] = { .type = NLA_U8 }, + [ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS] = + NLA_POLICY_RANGE(NLA_U8, 0, ETH_MODULE_MAX_I2C_ADDRESS), + [ETHTOOL_A_MODULE_EEPROM_DATA] = + NLA_POLICY_RANGE(NLA_BINARY, 1, ETH_MODULE_EEPROM_PAGE_LEN), +}; + +static int ethnl_module_eeprom_ntf(struct net_device *dev, + const struct ethtool_module_eeprom *page) +{ + struct sk_buff *skb; + void *ehdr; + int err; + + skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) { + err = -ENOMEM; + goto out; + } + + ehdr = ethnl_bcastmsg_put(skb, ETHTOOL_MSG_MODULE_EEPROM_NTF); + if (!ehdr) { + err = -EMSGSIZE; + goto out; + } + + err = ethnl_fill_reply_header(skb, dev, ETHTOOL_A_MODULE_EEPROM_HEADER); + if (err) + goto out; + + err = nla_put_u32(skb, ETHTOOL_A_MODULE_EEPROM_OFFSET, page->offset); + if (err) + goto out; + + err = nla_put_u32(skb, ETHTOOL_A_MODULE_EEPROM_LENGTH, page->length); + if (err) + goto out; + + err = nla_put_u8(skb, ETHTOOL_A_MODULE_EEPROM_PAGE, page->page); + if (err) + goto out; + + err = nla_put_u8(skb, ETHTOOL_A_MODULE_EEPROM_BANK, page->bank); + if (err) + goto out; + + err = nla_put_u8(skb, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, + page->i2c_address); + if (err) + goto out; + + genlmsg_end(skb, ehdr); + + return ethnl_multicast(skb, dev); + +out: + nlmsg_free(skb); + return err; +} + +int ethnl_set_module_eeprom(struct sk_buff *skb, struct genl_info *info) +{ + struct ethtool_module_eeprom page = {}; + struct ethnl_req_info req_info = {}; + struct nlattr **tb = info->attrs; + const struct ethtool_ops *ops; + struct net_device *dev; + int ret; + + if (!tb[ETHTOOL_A_MODULE_EEPROM_OFFSET] || + !tb[ETHTOOL_A_MODULE_EEPROM_LENGTH] || + !tb[ETHTOOL_A_MODULE_EEPROM_PAGE] || + !tb[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS] || + !tb[ETHTOOL_A_MODULE_EEPROM_DATA]) + return -EINVAL; + + if (nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_LENGTH]) != + nla_len(tb[ETHTOOL_A_MODULE_EEPROM_DATA])) + NL_SET_ERR_MSG_ATTR(info->extack, + tb[ETHTOOL_A_MODULE_EEPROM_LENGTH], + "data length does not match specified length"); + + ret = eeprom_validate(tb, info->extack); + if (ret < 0) + return ret; + + ret = ethnl_parse_header_dev_get(&req_info, + tb[ETHTOOL_A_MODULE_EEPROM_HEADER], + genl_info_net(info), info->extack, + true); + if (ret < 0) + return ret; + dev = req_info.dev; + ops = dev->ethtool_ops; + ret = -EOPNOTSUPP; + if (!ops->set_module_eeprom_by_page) + goto out_dev; + + page.offset = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_OFFSET]); + page.length = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_LENGTH]); + page.page = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_PAGE]); + page.i2c_address = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS]); + page.data = nla_data(tb[ETHTOOL_A_MODULE_EEPROM_DATA]); + if (tb[ETHTOOL_A_MODULE_EEPROM_BANK]) + page.bank = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_BANK]); + + rtnl_lock(); + ret = ethnl_ops_begin(dev); + if (ret < 0) + goto out_rtnl; + + ret = dev->ethtool_ops->set_module_eeprom_by_page(dev, &page, + info->extack); + if (ret < 0) + goto out_ops; + + ethnl_module_eeprom_ntf(dev, &page); + +out_ops: + ethnl_ops_complete(dev); +out_rtnl: + rtnl_unlock(); +out_dev: + dev_put(dev); + return ret; +} diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index a7346346114f..71afb80fda20 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -958,6 +958,13 @@ static const struct genl_ops ethtool_genl_ops[] = { .policy = ethnl_stats_get_policy, .maxattr = ARRAY_SIZE(ethnl_stats_get_policy) - 1, }, + { + .cmd = ETHTOOL_MSG_MODULE_EEPROM_SET, + .flags = GENL_UNS_ADMIN_PERM, + .doit = ethnl_set_module_eeprom, + .policy = ethnl_module_eeprom_set_policy, + .maxattr = ARRAY_SIZE(ethnl_module_eeprom_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 3e25a47fd482..5540d5713d33 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -382,6 +382,7 @@ extern const struct nla_policy ethnl_fec_get_policy[ETHTOOL_A_FEC_HEADER + 1]; 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_module_eeprom_set_policy[ETHTOOL_A_MODULE_EEPROM_DATA + 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); @@ -400,6 +401,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_eeprom(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 Wed Jun 23 07:59:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 12339265 X-Patchwork-Delegate: kuba@kernel.org 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.8 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,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 AB604C4743C for ; Wed, 23 Jun 2021 08:01:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9538461185 for ; Wed, 23 Jun 2021 08:01:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230298AbhFWIEB (ORCPT ); Wed, 23 Jun 2021 04:04:01 -0400 Received: from new3-smtp.messagingengine.com ([66.111.4.229]:44439 "EHLO new3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230290AbhFWIDl (ORCPT ); Wed, 23 Jun 2021 04:03:41 -0400 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailnew.nyi.internal (Postfix) with ESMTP id BB54658070C; Wed, 23 Jun 2021 04:01:24 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Wed, 23 Jun 2021 04:01:24 -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=23wsahIQosPUvOapAIZyoWqr8C8IjN+CjOMSeRFXJvA=; b=qJPdedD5 VyB8X9jtozadJ7GZk42fBhh9eJngIsPyfz7XvYA3l1MZOE/3XCc8wMoGNkfnZKYV aSpq7Rw2RF/ia7mK/C/jW8bFbnY2aCzpjD6GOUpaKdRphPSBoD0AXUj02KpHaqET Ih9+Vc0rbiZQU5kNyEMdiPE/BFzPpY0xKH63Jug2tOtu0moTpjDmpv8GO0DQ5s0t 7xE6PQNaKta/hf8bEtcC9QeiXkc6HePVKmqq34R/XxeDlQB87tlTWhe+ZfjzySL3 36S63BekcE48trDbiPSIYDCzwFAVe1vA1tbBuZwwyMVn03jLipFV2/0o8opNPDF+ MKSEduVseUu06Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrfeegvddguddukecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtke ertdertddtnecuhfhrohhmpefkughoucfutghhihhmmhgvlhcuoehiughoshgthhesihgu ohhstghhrdhorhhgqeenucggtffrrghtthgvrhhnpeduteeiveffffevleekleejffekhf ekhefgtdfftefhledvjefggfehgfevjeekhfenucevlhhushhtvghrufhiiigvpedtnecu rfgrrhgrmhepmhgrihhlfhhrohhmpehiughoshgthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 23 Jun 2021 04:01:22 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, andrew@lunn.ch, vladyslavt@nvidia.com, moshe@nvidia.com, vadimp@nvidia.com, mkubecek@suse.cz, mlxsw@nvidia.com, Ido Schimmel Subject: [RFC PATCH net-next 4/4] mlxsw: core: Add support for module EEPROM write by page Date: Wed, 23 Jun 2021 10:59:25 +0300 Message-Id: <20210623075925.2610908-5-idosch@idosch.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210623075925.2610908-1-idosch@idosch.org> References: <20210623075925.2610908-1-idosch@idosch.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC From: Ido Schimmel Add support for ethtool_ops::set_module_eeprom_by_page() which allows user space to write to transceiver module EEPROM based on passed parameters. The I2C address is not validated in order to avoid module-specific code. In case of wrong address, error will be returned from device's firmware. Tested by writing to page 3 (User EEPROM) on a QSFP-DD module: # ethtool -m swp11 offset 0x80 length 3 page 3 bank 0 i2c 0x50 Offset Values ------ ------ 0x0080: 00 00 00 # ethtool -M swp11 offset 0x80 page 3 bank 0 i2c 0x50 value 0x44 # ethtool -M swp11 offset 0x81 page 3 bank 0 i2c 0x50 value 0x41 # ethtool -M swp11 offset 0x82 page 3 bank 0 i2c 0x50 value 0x44 # ethtool -m swp11 offset 0x80 length 3 page 3 bank 0 i2c 0x50 Offset Values ------ ------ 0x0080: 44 41 44 Signed-off-by: Ido Schimmel Reviewed-by: Jiri Pirko --- .../net/ethernet/mellanox/mlxsw/core_env.c | 44 +++++++++++++++++++ .../net/ethernet/mellanox/mlxsw/core_env.h | 5 +++ drivers/net/ethernet/mellanox/mlxsw/minimal.c | 13 ++++++ .../mellanox/mlxsw/spectrum_ethtool.c | 14 ++++++ 4 files changed, 76 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c index 3713c45cfa1e..4cb69eddbd1e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c @@ -389,6 +389,50 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module, } EXPORT_SYMBOL(mlxsw_env_get_module_eeprom_by_page); +int +mlxsw_env_set_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module, + const struct ethtool_module_eeprom *page, + struct netlink_ext_ack *extack) +{ + u32 bytes_written = 0; + u16 device_addr; + + /* Offset cannot be larger than 2 * ETH_MODULE_EEPROM_PAGE_LEN */ + device_addr = page->offset; + + while (bytes_written < page->length) { + char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE] = {}; + char mcia_pl[MLXSW_REG_MCIA_LEN]; + u8 size; + int err; + + size = min_t(u8, page->length - bytes_written, + MLXSW_REG_MCIA_EEPROM_SIZE); + + mlxsw_reg_mcia_pack(mcia_pl, module, 0, page->page, + device_addr + bytes_written, size, + page->i2c_address); + mlxsw_reg_mcia_bank_number_set(mcia_pl, page->bank); + memcpy(eeprom_tmp, page->data + bytes_written, size); + mlxsw_reg_mcia_eeprom_memcpy_to(mcia_pl, eeprom_tmp); + + err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(mcia), mcia_pl); + if (err) { + NL_SET_ERR_MSG_MOD(extack, "Failed to access module's EEPROM"); + return err; + } + + err = mlxsw_env_mcia_status_process(mcia_pl, extack); + if (err) + return err; + + bytes_written += size; + } + + return 0; +} +EXPORT_SYMBOL(mlxsw_env_set_module_eeprom_by_page); + static int mlxsw_env_module_has_temp_sensor(struct mlxsw_core *mlxsw_core, u8 module, bool *p_has_temp_sensor) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.h b/drivers/net/ethernet/mellanox/mlxsw/core_env.h index 0bf5bd0f8a7e..e07f48ffbf2b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_env.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.h @@ -24,6 +24,11 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module, const struct ethtool_module_eeprom *page, struct netlink_ext_ack *extack); +int +mlxsw_env_set_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module, + const struct ethtool_module_eeprom *page, + struct netlink_ext_ack *extack); + int mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module, u64 *p_counter); diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c index d9d56c44e994..b795520566bb 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c +++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c @@ -124,11 +124,24 @@ mlxsw_m_get_module_eeprom_by_page(struct net_device *netdev, page, extack); } +static int +mlxsw_m_set_module_eeprom_by_page(struct net_device *netdev, + const struct ethtool_module_eeprom *page, + struct netlink_ext_ack *extack) +{ + struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev); + struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core; + + return mlxsw_env_set_module_eeprom_by_page(core, mlxsw_m_port->module, + page, extack); +} + static const struct ethtool_ops mlxsw_m_port_ethtool_ops = { .get_drvinfo = mlxsw_m_module_get_drvinfo, .get_module_info = mlxsw_m_get_module_info, .get_module_eeprom = mlxsw_m_get_module_eeprom, .get_module_eeprom_by_page = mlxsw_m_get_module_eeprom_by_page, + .set_module_eeprom_by_page = mlxsw_m_set_module_eeprom_by_page, }; static int diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c index 267590a0eee7..2e7f57a6fbb2 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c @@ -1063,6 +1063,19 @@ mlxsw_sp_get_module_eeprom_by_page(struct net_device *dev, extack); } +static int +mlxsw_sp_set_module_eeprom_by_page(struct net_device *dev, + const struct ethtool_module_eeprom *page, + struct netlink_ext_ack *extack) +{ + struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + u8 module = mlxsw_sp_port->mapping.module; + + return mlxsw_env_set_module_eeprom_by_page(mlxsw_sp->core, module, page, + extack); +} + static int mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info) { @@ -1213,6 +1226,7 @@ const struct ethtool_ops mlxsw_sp_port_ethtool_ops = { .get_module_info = mlxsw_sp_get_module_info, .get_module_eeprom = mlxsw_sp_get_module_eeprom, .get_module_eeprom_by_page = mlxsw_sp_get_module_eeprom_by_page, + .set_module_eeprom_by_page = mlxsw_sp_set_module_eeprom_by_page, .get_ts_info = mlxsw_sp_get_ts_info, .get_eth_phy_stats = mlxsw_sp_get_eth_phy_stats, .get_eth_mac_stats = mlxsw_sp_get_eth_mac_stats,