From patchwork Thu Jun 1 22:23:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Pryazhennikov X-Patchwork-Id: 127936 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id A6A5642C08; Fri, 2 Jun 2023 00:24:02 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 995B9427E9; Fri, 2 Jun 2023 00:23:58 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 8FEA640693 for ; Fri, 2 Jun 2023 00:23:56 +0200 (CEST) Received: from localhost.localdomain (unknown [37.252.90.53]) (using TLSv1.3 with cipher TLS_CHACHA20_POLY1305_SHA256 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA512) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id E78C6E126C; Fri, 2 Jun 2023 02:23:55 +0400 (+04) From: Denis Pryazhennikov To: dev@dpdk.org Cc: Ferruh Yigit , Andrew Rybchenko , Ivan Malov , Andy Moreton Subject: [PATCH 1/3] net/sfc: split link update function Date: Fri, 2 Jun 2023 02:23:47 +0400 Message-Id: <20230601222349.28965-2-denis.pryazhennikov@arknetworks.am> X-Mailer: git-send-email 2.37.0 (Apple Git-136) In-Reply-To: <20230601222349.28965-1-denis.pryazhennikov@arknetworks.am> References: <20230601222349.28965-1-denis.pryazhennikov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Separate the original link update function into two functions: state retrieval and update. This improves code clarity and maintainability. Signed-off-by: Denis Pryazhennikov Reviewed-by: Ivan Malov Reviewed-by: Andy Moreton Acked-by: Andrew Rybchenko --- drivers/net/sfc/sfc_ethdev.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 320043145495..6d41eb000345 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -248,28 +248,38 @@ sfc_dev_start(struct rte_eth_dev *dev) return -rc; } -static int -sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) +static void +sfc_dev_get_rte_link(struct rte_eth_dev *dev, int wait_to_complete, + struct rte_eth_link *link) { struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); - struct rte_eth_link current_link; - int ret; - sfc_log_init(sa, "entry"); + SFC_ASSERT(link != NULL); if (sa->state != SFC_ETHDEV_STARTED) { - sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, ¤t_link); + sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, link); } else if (wait_to_complete) { efx_link_mode_t link_mode; if (efx_port_poll(sa->nic, &link_mode) != 0) link_mode = EFX_LINK_UNKNOWN; - sfc_port_link_mode_to_info(link_mode, ¤t_link); - + sfc_port_link_mode_to_info(link_mode, link); } else { sfc_ev_mgmt_qpoll(sa); - rte_eth_linkstatus_get(dev, ¤t_link); + rte_eth_linkstatus_get(dev, link); } +} + +static int +sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct rte_eth_link current_link; + int ret; + + sfc_log_init(sa, "entry"); + + sfc_dev_get_rte_link(dev, wait_to_complete, ¤t_link); ret = rte_eth_linkstatus_set(dev, ¤t_link); if (ret == 0) From patchwork Thu Jun 1 22:23:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Pryazhennikov X-Patchwork-Id: 127937 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E380142C08; Fri, 2 Jun 2023 00:24:09 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 272B442D0D; Fri, 2 Jun 2023 00:24:00 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 1A34B40693 for ; Fri, 2 Jun 2023 00:23:57 +0200 (CEST) Received: from localhost.localdomain (unknown [37.252.90.53]) (using TLSv1.3 with cipher TLS_CHACHA20_POLY1305_SHA256 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA512) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id 8461FE1273; Fri, 2 Jun 2023 02:23:56 +0400 (+04) From: Denis Pryazhennikov To: dev@dpdk.org Cc: Ferruh Yigit , Andrew Rybchenko , Andy Moreton Subject: [PATCH 2/3] common/sfc_efx/base: add FEC related macros Date: Fri, 2 Jun 2023 02:23:48 +0400 Message-Id: <20230601222349.28965-3-denis.pryazhennikov@arknetworks.am> X-Mailer: git-send-email 2.37.0 (Apple Git-136) In-Reply-To: <20230601222349.28965-1-denis.pryazhennikov@arknetworks.am> References: <20230601222349.28965-1-denis.pryazhennikov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Added new macros to simplify working with FEC bits Signed-off-by: Denis Pryazhennikov Reviewed-by: Andy Moreton Acked-by: Andrew Rybchenko --- drivers/common/sfc_efx/base/efx.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 49e29dcc1c69..10c412bcd7dc 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -3958,6 +3958,15 @@ typedef enum efx_phy_fec_type_e { EFX_PHY_FEC_RS } efx_phy_fec_type_t; +#define EFX_PHY_CAP_FEC_BIT(_fec_bit) (1U << EFX_PHY_CAP_##_fec_bit) +#define EFX_PHY_CAP_FEC_MASK \ + (EFX_PHY_CAP_FEC_BIT(BASER_FEC) | \ + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) | \ + EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED) | \ + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED) | \ + EFX_PHY_CAP_FEC_BIT(RS_FEC) | \ + EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED)) + LIBEFX_API extern __checkReturn efx_rc_t efx_phy_fec_type_get( From patchwork Thu Jun 1 22:23:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Pryazhennikov X-Patchwork-Id: 127938 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 85F3642C08; Fri, 2 Jun 2023 00:24:14 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4225942D31; Fri, 2 Jun 2023 00:24:01 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id B56F240F16 for ; Fri, 2 Jun 2023 00:23:57 +0200 (CEST) Received: from localhost.localdomain (unknown [37.252.90.53]) (using TLSv1.3 with cipher TLS_CHACHA20_POLY1305_SHA256 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA512) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id 29193E12C3; Fri, 2 Jun 2023 02:23:57 +0400 (+04) From: Denis Pryazhennikov To: dev@dpdk.org Cc: Ferruh Yigit , Andrew Rybchenko , Ivan Malov , Andy Moreton Subject: [PATCH 3/3] net/sfc: support FEC feature Date: Fri, 2 Jun 2023 02:23:49 +0400 Message-Id: <20230601222349.28965-4-denis.pryazhennikov@arknetworks.am> X-Mailer: git-send-email 2.37.0 (Apple Git-136) In-Reply-To: <20230601222349.28965-1-denis.pryazhennikov@arknetworks.am> References: <20230601222349.28965-1-denis.pryazhennikov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Support ethdev methods to query and set FEC information. Limitations: ignoring rte_eth_fec_get_capability() results can lead to NOFEC if the device is not strated. Signed-off-by: Denis Pryazhennikov Reviewed-by: Ivan Malov Reviewed-by: Andy Moreton Reviewed-by: Ferruh Yigit --- doc/guides/nics/features/sfc.ini | 1 + drivers/net/sfc/sfc.h | 2 + drivers/net/sfc/sfc_ethdev.c | 337 +++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_port.c | 24 ++- 4 files changed, 353 insertions(+), 11 deletions(-) diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini index f5ac644278ae..e0b9bfb7f7bf 100644 --- a/doc/guides/nics/features/sfc.ini +++ b/doc/guides/nics/features/sfc.ini @@ -24,6 +24,7 @@ RSS reta update = Y SR-IOV = Y Flow control = Y VLAN offload = P +FEC = Y L3 checksum offload = Y L4 checksum offload = Y Inner L3 checksum = Y diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 730d054aea74..e42abe42cb8a 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -68,6 +68,8 @@ struct sfc_port { uint32_t phy_adv_cap_mask; uint32_t phy_adv_cap; + uint32_t fec_cfg; + bool fec_auto; unsigned int flow_ctrl; boolean_t flow_ctrl_autoneg; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 6d41eb000345..05fc70541b10 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2343,6 +2343,340 @@ sfc_rx_metadata_negotiate(struct rte_eth_dev *dev, uint64_t *features) return 0; } +static unsigned int +sfc_fec_get_capa_speed_to_fec(uint32_t supported_caps, + struct rte_eth_fec_capa *speed_fec_capa) +{ + int num = 0; + + if (supported_caps & (1u << EFX_PHY_CAP_10000FDX)) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_10G; + speed_fec_capa[num].capa = + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(BASER); + } + num++; + } + if (supported_caps & (1u << EFX_PHY_CAP_25000FDX)) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_25G; + speed_fec_capa[num].capa = + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(BASER) | + RTE_ETH_FEC_MODE_CAPA_MASK(RS); + } + num++; + } + if (supported_caps & (1u << EFX_PHY_CAP_40000FDX)) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_40G; + speed_fec_capa[num].capa = + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(BASER); + } + num++; + } + if (supported_caps & (1u << EFX_PHY_CAP_50000FDX)) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_50G; + speed_fec_capa[num].capa = + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(BASER) | + RTE_ETH_FEC_MODE_CAPA_MASK(RS); + } + num++; + } + if (supported_caps & (1u << EFX_PHY_CAP_100000FDX)) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_100G; + speed_fec_capa[num].capa = + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(RS); + } + num++; + } + + return num; +} + +static int +sfc_fec_get_capability(struct rte_eth_dev *dev, + struct rte_eth_fec_capa *speed_fec_capa, + unsigned int num) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + unsigned int num_entries; + uint32_t supported_caps; + + sfc_adapter_lock(sa); + + efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps); + + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL); + if (!speed_fec_capa || num < num_entries) + goto adapter_unlock; + + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, + speed_fec_capa); + +adapter_unlock: + sfc_adapter_unlock(sa); + + return num_entries; +} + +static uint32_t +sfc_efx_caps_to_fec(uint32_t caps, bool is_25g) +{ + bool rs_req = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED); + bool rs = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC); + uint32_t fec_capa = 0; + bool baser_req; + bool baser; + + if (is_25g) { + baser = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC); + baser_req = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED); + } else { + baser = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC); + baser_req = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED); + } + + if (!baser && !rs) + return RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC); + + if (rs_req) + fec_capa |= RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS); + + if (baser_req) + fec_capa |= RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER); + + + return fec_capa; +} + +static int +sfc_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct sfc_port *port = &sa->port; + struct rte_eth_link current_link; + efx_phy_fec_type_t active_fec; + bool is_25g = false; + int rc = 0; + + sfc_adapter_lock(sa); + + sfc_dev_get_rte_link(dev, 1, ¤t_link); + + if (current_link.link_status == RTE_ETH_LINK_DOWN) { + uint32_t speed = current_link.link_speed; + + if (port->fec_auto) { + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO); + goto adapter_unlock; + } + + is_25g = (speed == RTE_ETH_SPEED_NUM_25G || + speed == RTE_ETH_SPEED_NUM_50G); + + *fec_capa = sfc_efx_caps_to_fec(port->fec_cfg, is_25g); + + goto adapter_unlock; + } + + rc = efx_phy_fec_type_get(sa->nic, &active_fec); + if (rc != 0) + goto adapter_unlock; + + switch (active_fec) { + case EFX_PHY_FEC_NONE: + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC); + break; + case EFX_PHY_FEC_BASER: + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER); + break; + case EFX_PHY_FEC_RS: + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS); + break; + default: + break; + } + +adapter_unlock: + sfc_adapter_unlock(sa); + + return rc; +} + +static int +sfc_fec_capa_check(struct rte_eth_dev *dev, uint32_t fec_capa, + uint32_t supported_caps) +{ + struct rte_eth_fec_capa *speed_fec_capa; + struct rte_eth_link current_link; + bool is_supported = false; + unsigned int num_entries; + bool auto_fec = false; + unsigned int i; + + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + + if (sa->state != SFC_ETHDEV_STARTED) + return 0; + + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) { + auto_fec = true; + fec_capa &= ~RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO); + } + + /* + * If only the AUTO bit is set, the decision on which FEC + * mode to use will be made by HW/FW or driver. + */ + if (auto_fec && fec_capa == 0) + return 0; + + sfc_dev_get_rte_link(dev, 1, ¤t_link); + + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL); + if (num_entries == 0) + return -ENOTSUP; + + speed_fec_capa = rte_calloc("fec_capa", num_entries, + sizeof(*speed_fec_capa), 0); + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, + speed_fec_capa); + + for (i = 0; i < num_entries; i++) { + if (speed_fec_capa[i].speed == current_link.link_speed) { + if ((fec_capa & speed_fec_capa[i].capa) != 0) + is_supported = true; + + break; + } + } + + rte_free(speed_fec_capa); + + if (is_supported) + return 0; + + return -ENOTSUP; +} + +static int +sfc_fec_capa_to_efx(uint32_t supported_caps, uint32_t fec_capa, + uint32_t *efx_fec_caps) +{ + bool fec_is_set = false; + bool auto_fec = false; + bool nofec = false; + uint32_t ret = 0; + + if (efx_fec_caps == NULL) + return -EINVAL; + + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) + auto_fec = true; + + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC)) + nofec = true; + + if (fec_capa == RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) { + ret |= (EFX_PHY_CAP_FEC_BIT(BASER_FEC) | + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) | + EFX_PHY_CAP_FEC_BIT(RS_FEC)) & supported_caps; + goto done; + } + + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS)) { + fec_is_set = true; + + if (supported_caps & EFX_PHY_CAP_FEC_BIT(RS_FEC)) { + ret |= EFX_PHY_CAP_FEC_BIT(RS_FEC) | + EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED); + } + } + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER)) { + if (!auto_fec && fec_is_set) + return -EINVAL; + + if (supported_caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC)) { + ret |= EFX_PHY_CAP_FEC_BIT(BASER_FEC) | + EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED); + } + if (supported_caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC)) { + ret |= EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) | + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED); + } + } + + if (ret == 0 && !nofec) + return -ENOTSUP; + +done: + *efx_fec_caps = ret; + return 0; +} + +static int +sfc_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct sfc_port *port = &sa->port; + uint32_t supported_caps; + uint32_t efx_fec_caps; + uint32_t updated_caps; + int rc = 0; + + sfc_adapter_lock(sa); + + efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps); + + rc = sfc_fec_capa_check(dev, fec_capa, supported_caps); + if (rc != 0) + goto adapter_unlock; + + rc = sfc_fec_capa_to_efx(supported_caps, fec_capa, &efx_fec_caps); + if (rc != 0) + goto adapter_unlock; + + if (sa->state == SFC_ETHDEV_STARTED) { + efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT, + &updated_caps); + updated_caps = updated_caps & ~EFX_PHY_CAP_FEC_MASK; + updated_caps |= efx_fec_caps; + + rc = efx_phy_adv_cap_set(sa->nic, updated_caps); + if (rc != 0) + goto adapter_unlock; + } + + port->fec_cfg = efx_fec_caps; + /* + * There is no chance to recognize AUTO mode from the + * saved FEC capabilities as AUTO mode can have the same + * set of bits as any other mode from the EFX point of view. + * Save it in the proper variable. + */ + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) + port->fec_auto = true; + else + port->fec_auto = false; + +adapter_unlock: + sfc_adapter_unlock(sa); + + return rc; +} + static const struct eth_dev_ops sfc_eth_dev_ops = { .dev_configure = sfc_dev_configure, .dev_start = sfc_dev_start, @@ -2392,6 +2726,9 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .pool_ops_supported = sfc_pool_ops_supported, .representor_info_get = sfc_representor_info_get, .rx_metadata_negotiate = sfc_rx_metadata_negotiate, + .fec_get_capability = sfc_fec_get_capability, + .fec_get = sfc_fec_get, + .fec_set = sfc_fec_set, }; struct sfc_ethdev_init_data { diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c index 5f312ab1ba83..0c887ddedb09 100644 --- a/drivers/net/sfc/sfc_port.c +++ b/drivers/net/sfc/sfc_port.c @@ -228,17 +228,8 @@ sfc_port_start(struct sfc_adapter *sa) /* Preserve pause capabilities set by above efx_mac_fcntl_set() */ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT, &phy_adv_cap); SFC_ASSERT((port->phy_adv_cap & phy_pause_caps) == 0); - phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps); - - /* - * No controls for FEC yet. Use default FEC mode. - * I.e. advertise everything supported (*_FEC=1), but do not request - * anything explicitly (*_FEC_REQUESTED=0). - */ - phy_adv_cap |= port->phy_adv_cap_mask & - (1u << EFX_PHY_CAP_BASER_FEC | - 1u << EFX_PHY_CAP_RS_FEC | - 1u << EFX_PHY_CAP_25G_BASER_FEC); + phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps) | + port->fec_cfg; sfc_log_init(sa, "set phy adv caps to %#x", phy_adv_cap); rc = efx_phy_adv_cap_set(sa->nic, phy_adv_cap); @@ -469,6 +460,17 @@ sfc_port_attach(struct sfc_adapter *sa) port->mac_stats_update_period_ms = kvarg_stats_update_period_ms; + /* + * Set default FEC mode. + * I.e. advertise everything supported (*_FEC=1), but do not request + * anything explicitly (*_FEC_REQUESTED=0). + */ + port->fec_cfg = port->phy_adv_cap_mask & + (EFX_PHY_CAP_FEC_BIT(BASER_FEC) | + EFX_PHY_CAP_FEC_BIT(RS_FEC) | + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC)); + port->fec_auto = true; + sfc_log_init(sa, "done"); return 0;