From: Ivan Malov <ivan.malov@arknetworks.am>
To: dev@dpdk.org
Cc: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,
Andy Moreton <andy.moreton@amd.com>,
Pieter Jansen Van Vuuren <pieter.jansen-van-vuuren@amd.com>,
Viacheslav Galaktionov <viacheslav.galaktionov@arknetworks.am>,
stable@dpdk.org
Subject: [PATCH 7/9] net/sfc: rework the capability check that is done on FEC set
Date: Tue, 30 Dec 2025 01:35:25 +0400 [thread overview]
Message-ID: <20251229213527.37907-8-ivan.malov@arknetworks.am> (raw)
In-Reply-To: <20251229213527.37907-1-ivan.malov@arknetworks.am>
The current code that sets new FEC mode does not consult capabilities when
the ethdev is not started. This leads to accepting FEC flags that the last
configured link speed cannot handle. This is shown in 'testpmd' as follows:
port stop all
port config 0 speed 10000 duplex full
port start 0
port stop 0
set port 0 fec_mode rs
In the case of X4 adaptors, RS FEC cannot be supported for such low speeds
and the last command should print 'Function not implemented' error message,
but it doesn't. To fix this, enforce the proper checks in every port state.
Fixes: 5efa8fc1cfc0 ("net/sfc: support FEC feature")
Cc: stable@dpdk.org
Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <andy.moreton@amd.com>
---
drivers/net/sfc/sfc_ethdev.c | 96 ++++++++++++++++++++++--------------
1 file changed, 59 insertions(+), 37 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6d2349a999..fc759f52fe 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -7,6 +7,8 @@
* for Solarflare) and Solarflare Communications, Inc.
*/
+#include <stdbool.h>
+
#include <dev_driver.h>
#include <ethdev_driver.h>
#include <ethdev_pci.h>
@@ -14,6 +16,7 @@
#include <bus_pci_driver.h>
#include <rte_errno.h>
#include <rte_string_fns.h>
+#include <rte_bitops.h>
#include <rte_ether.h>
#include "efx.h"
@@ -2496,6 +2499,10 @@ sfc_rx_metadata_negotiate(struct rte_eth_dev *dev, uint64_t *features)
return 0;
}
+/*
+ * When adding support for new speeds/capabilities, make sure to adjust
+ * validity checks conducted by 'sfc_fec_capa_check' for user input.
+ */
static unsigned int
sfc_fec_get_capa_speed_to_fec(uint32_t supported_caps,
struct rte_eth_fec_capa *speed_fec_capa)
@@ -2721,60 +2728,75 @@ sfc_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
return -rc;
}
+/*
+ * When adding checks for new speeds and/or capabilities, keep that consistent
+ * with capabilities that 'sfc_fec_get_capa_speed_to_fec' reports to the user.
+ */
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;
+ unsigned int ncaps = rte_popcount32(fec_capa);
+ /* Set by 'sfc_phy_cap_from_link_speeds'. */
+ uint32_t speeds_cur = sa->port.phy_adv_cap;
+ uint32_t speeds_baser = 0;
+ uint32_t speeds_rs = 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 (ncaps == 1) {
+ /* Let the FW choose a best-effort setting. */
+ return 0;
+ } else {
+ /*
+ * Each requested FEC capability must be supported in
+ * general and at least one speed that supports this
+ * FEC mode must be currently advertised/configured.
+ */
+ }
+ } else if (ncaps != 1) {
+ /*
+ * Fixed FEC mode does not allow for multiple capabilities.
+ * Empty mask is invalid, as No-FEC has a capability bit.
+ */
+ return EINVAL;
+ } else if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC)) {
+ /* No-FEC is assumed to be always acceptable. */
+ return 0;
}
- /*
- * 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;
+ /* 25G BASE-R is accounted for separately below. */
+ speeds_baser |= (1U << EFX_PHY_CAP_50000FDX);
+ speeds_baser |= (1U << EFX_PHY_CAP_40000FDX);
+ speeds_baser |= (1U << EFX_PHY_CAP_10000FDX);
- sfc_dev_get_rte_link(dev, 1, ¤t_link);
+ speeds_rs |= (1U << EFX_PHY_CAP_200000FDX);
+ speeds_rs |= (1U << EFX_PHY_CAP_100000FDX);
+ speeds_rs |= (1U << EFX_PHY_CAP_50000FDX);
+ speeds_rs |= (1U << EFX_PHY_CAP_25000FDX);
- num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
- if (num_entries == 0)
- return ENOTSUP;
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER)) {
+ bool supported = false;
- 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);
+ if ((supported_caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC)) &&
+ (speeds_cur & (1U << EFX_PHY_CAP_25000FDX)))
+ supported = true;
- 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;
+ if ((supported_caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC)) &&
+ (speeds_cur & speeds_baser))
+ supported = true;
- break;
- }
+ if (!supported)
+ return ENOTSUP;
}
- rte_free(speed_fec_capa);
-
- if (is_supported)
- return 0;
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS)) {
+ if ((supported_caps & EFX_PHY_CAP_FEC_BIT(RS_FEC)) == 0 ||
+ (speeds_cur & speeds_rs) == 0)
+ return ENOTSUP;
+ }
- return ENOTSUP;
+ return 0;
}
static int
--
2.47.3
next prev parent reply other threads:[~2025-12-29 21:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20251229213527.37907-1-ivan.malov@arknetworks.am>
2025-12-29 21:35 ` [PATCH 2/9] common/sfc_efx/base: fix flow control setting on legacy MCDI Ivan Malov
2025-12-29 21:35 ` [PATCH 3/9] common/sfc_efx/base: fix indication of requestable FEC flags Ivan Malov
2025-12-29 21:35 ` [PATCH 6/9] net/sfc: avoid speed reset when setting FEC in started state Ivan Malov
2025-12-29 21:35 ` Ivan Malov [this message]
2025-12-29 21:35 ` [PATCH 8/9] net/sfc: drop AUTO from FEC capabilities and fix the comment Ivan Malov
2025-12-29 21:35 ` [PATCH 9/9] net/sfc: fix reporting status of autonegotiation to the user Ivan Malov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251229213527.37907-8-ivan.malov@arknetworks.am \
--to=ivan.malov@arknetworks.am \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=andy.moreton@amd.com \
--cc=dev@dpdk.org \
--cc=pieter.jansen-van-vuuren@amd.com \
--cc=stable@dpdk.org \
--cc=viacheslav.galaktionov@arknetworks.am \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).