* [PATCH 1/4] common/sfc_efx/base: fix autoneg detection with netport MCDI
2025-09-05 14:45 [PATCH 0/4] common/sfc_efx/base: link stability improvements for X4 NICs Ivan Malov
@ 2025-09-05 14:45 ` Ivan Malov
2025-09-05 14:45 ` [PATCH 2/4] common/sfc_efx/base: default to auto fcntl " Ivan Malov
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ivan Malov @ 2025-09-05 14:45 UTC (permalink / raw)
To: dev
Cc: Andrew Rybchenko, Andy Moreton, Pieter Jansen Van Vuuren,
Viacheslav Galaktionov, stable
Currently, the code consults both local AN support status, which is stable,
and the dynamic AN status on the link partner, which is flaky. Exclude the
latter, as the client should have the opportunity to re-initiate AN afresh.
Fixes: 2a5cf77e6de8 ("common/sfc_efx/base: provide PHY link get method on Medford4")
Cc: stable@dpdk.org
Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <andy.moreton@amd.com>
---
drivers/common/sfc_efx/base/efx_np.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/common/sfc_efx/base/efx_np.c b/drivers/common/sfc_efx/base/efx_np.c
index a19c986691..599daa7a60 100644
--- a/drivers/common/sfc_efx/base/efx_np.c
+++ b/drivers/common/sfc_efx/base/efx_np.c
@@ -397,8 +397,7 @@ efx_np_link_state(
v3_flags = MCDI_OUT_DWORD(req, LINK_STATE_OUT_V3_FLAGS);
memset(lsp, 0, sizeof (*lsp));
- if (status_flags & (1U << MC_CMD_LINK_STATUS_FLAGS_AN_ABLE) &&
- MCDI_OUT_DWORD(req, LINK_STATE_OUT_V2_LOCAL_AN_SUPPORT) !=
+ if (MCDI_OUT_DWORD(req, LINK_STATE_OUT_V2_LOCAL_AN_SUPPORT) !=
MC_CMD_AN_NONE)
lsp->enls_an_supported = B_TRUE;
@@ -437,7 +436,7 @@ efx_np_link_state(
MCDI_OUT2(req, const uint8_t, LINK_STATE_OUT_ADVERTISED_ABILITIES),
&lsp->enls_adv_cap_mask);
- if (lsp->enls_an_supported != B_FALSE)
+ if (status_flags & (1U << MC_CMD_LINK_STATUS_FLAGS_AN_ABLE))
lsp->enls_lp_cap_mask |= 1U << EFX_PHY_CAP_AN;
efx_np_cap_hw_data_to_sw_mask(
--
2.47.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/4] common/sfc_efx/base: use saved netport FEC choice by default
2025-09-05 14:45 [PATCH 0/4] common/sfc_efx/base: link stability improvements for X4 NICs Ivan Malov
` (2 preceding siblings ...)
2025-09-05 14:45 ` [PATCH 3/4] common/sfc_efx/base: fix auto FEC selection for " Ivan Malov
@ 2025-09-05 14:45 ` Ivan Malov
3 siblings, 0 replies; 5+ messages in thread
From: Ivan Malov @ 2025-09-05 14:45 UTC (permalink / raw)
To: dev
Cc: Andrew Rybchenko, Andy Moreton, Pieter Jansen Van Vuuren,
Viacheslav Galaktionov
When the client driver starts the port, it invokes 'efx_port_init' API. At
this stage, libefx has no way of knowing whether the driver will prefer to
keep the existing link or revise, say, FEC mode. So if the current link is
up, it is better to leave it alone. This way, if the driver does not tweak
FEC mode with 'efx_phy_adv_cap_set' later on, the link will likely stay up.
Save the last FEC choice (select 'AUTO' on attach) and apply it by default.
Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
---
drivers/common/sfc_efx/base/efx_impl.h | 6 ++++
drivers/common/sfc_efx/base/efx_np.c | 42 ++++++++++++++++++----
drivers/common/sfc_efx/base/efx_phy.c | 4 +++
drivers/common/sfc_efx/base/efx_port.c | 1 +
drivers/common/sfc_efx/base/medford4_phy.c | 1 +
5 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h
index 69268546d2..c91fbbb61b 100644
--- a/drivers/common/sfc_efx/base/efx_impl.h
+++ b/drivers/common/sfc_efx/base/efx_impl.h
@@ -398,6 +398,10 @@ typedef struct efx_port_s {
efx_np_stat_t ep_np_mac_stat_lut[EFX_MAC_NSTATS];
/* Client-requested lane count for the physical link. */
efx_phy_lane_count_t ep_np_lane_count_req;
+ /* If 'B_TRUE', the client has not invoked 'efx_phy_adv_cap_set' yet. */
+ boolean_t ep_np_keep_prev_fec_ctrl;
+ /* It's 'AUTO' on driver attach. Updated on each 'LINK_CTRL' call. */
+ uint8_t ep_np_prev_fec_ctrl;
} efx_port_t;
typedef struct efx_mon_ops_s {
@@ -1957,6 +1961,8 @@ efx_np_link_ctrl(
__in efx_link_mode_t loopback_link_mode,
__in efx_loopback_type_t loopback_mode,
__in efx_phy_lane_count_t lane_count,
+ __in boolean_t keep_prev_fec_ctrl,
+ __inout uint8_t *prev_fec_ctrlp,
__in uint32_t cap_mask_sw,
__in boolean_t fcntl_an);
diff --git a/drivers/common/sfc_efx/base/efx_np.c b/drivers/common/sfc_efx/base/efx_np.c
index 54305ee61e..327981f0db 100644
--- a/drivers/common/sfc_efx/base/efx_np.c
+++ b/drivers/common/sfc_efx/base/efx_np.c
@@ -1026,6 +1026,12 @@ efx_np_attach(
/* For faster link up, use autoneg. flow control by default. */
epp->ep_fcntl_autoneg = B_TRUE;
+ /*
+ * We have no way of knowing which 'FEC_MODE' choice the previous
+ * client driver passed via 'LINK_CTRL'. Assume 'AUTO' by default.
+ */
+ epp->ep_np_prev_fec_ctrl = MC_CMD_FEC_AUTO;
+
/* Subscribe to link change events. */
rc = efx_np_set_event_mask(enp, epp->ep_np_handle, B_TRUE);
if (rc != 0)
@@ -1277,6 +1283,8 @@ efx_np_link_ctrl(
__in efx_link_mode_t loopback_link_mode,
__in efx_loopback_type_t loopback_mode,
__in efx_phy_lane_count_t lane_count,
+ __in boolean_t keep_prev_fec_ctrl,
+ __inout uint8_t *prev_fec_ctrlp,
__in uint32_t cap_mask_sw,
__in boolean_t fcntl_an)
{
@@ -1380,13 +1388,34 @@ efx_np_link_ctrl(
*
* No requested FEC bits in the original mask gives supported=TRUE.
*/
- EFX_NP_CAP_SW_MASK_TO_HW_ENUM(efx_np_cap_map_fec_req,
- ETH_AN_FIELDS_FEC_REQ, cap_data_raw, cap_mask_sw,
- NULL, NULL, &supported, &cap_enum_hw);
+ if (keep_prev_fec_ctrl == B_FALSE) {
+ /*
+ * Enforce what the user has asked for. If the mask has got
+ * no 'FEC_REQUESTED' bits, use 'NONE' or 'AUTO' from above.
+ */
+ EFX_NP_CAP_SW_MASK_TO_HW_ENUM(efx_np_cap_map_fec_req,
+ ETH_AN_FIELDS_FEC_REQ, cap_data_raw, cap_mask_sw,
+ NULL, NULL, &supported, &cap_enum_hw);
- if ((cap_mask_sw & EFX_PHY_CAP_FEC_MASK) != 0 && supported == B_FALSE) {
- rc = ENOTSUP;
- goto fail5;
+ if ((cap_mask_sw & EFX_PHY_CAP_FEC_MASK) != 0
+ && supported == B_FALSE) {
+ rc = ENOTSUP;
+ goto fail5;
+ }
+ } else {
+ /*
+ * At this stage, the FEC mask does not draw any input from
+ * the client driver. If the active link was autonegotiated,
+ * it might contain 'FEC_REQUESTED' bits translated earlier
+ * from 'ADVERTISED_ABILITIES_FEC_REQ' of 'LINK_STATE' MCDI.
+ * If the link is fixed, it does not have any of these bits.
+ *
+ * Either way, translating it into a fixed enum will result
+ * in a fixed FEC choice. If that does not match the choice
+ * of the previous user, a lengthy link renegotiation might
+ * follow. Pass previous choice to avoid long link-up times.
+ */
+ cap_enum_hw = *prev_fec_ctrlp;
}
EFSYS_ASSERT(cap_enum_hw <= UINT8_MAX);
@@ -1404,6 +1433,7 @@ efx_np_link_ctrl(
goto fail6;
}
+ *prev_fec_ctrlp = fec;
return (0);
fail6:
diff --git a/drivers/common/sfc_efx/base/efx_phy.c b/drivers/common/sfc_efx/base/efx_phy.c
index 1f99c72e62..1f1552ce1f 100644
--- a/drivers/common/sfc_efx/base/efx_phy.c
+++ b/drivers/common/sfc_efx/base/efx_phy.c
@@ -251,6 +251,7 @@ efx_phy_adv_cap_set(
{
efx_port_t *epp = &(enp->en_port);
const efx_phy_ops_t *epop = epp->ep_epop;
+ boolean_t old_np_keep_prev_fec_ctrl;
uint32_t old_mask;
efx_rc_t rc;
@@ -271,6 +272,8 @@ efx_phy_adv_cap_set(
if (epp->ep_adv_cap_mask == mask)
goto done;
+ old_np_keep_prev_fec_ctrl = epp->ep_np_keep_prev_fec_ctrl;
+ epp->ep_np_keep_prev_fec_ctrl = B_FALSE;
old_mask = epp->ep_adv_cap_mask;
epp->ep_adv_cap_mask = mask;
@@ -283,6 +286,7 @@ efx_phy_adv_cap_set(
fail3:
EFSYS_PROBE(fail3);
+ epp->ep_np_keep_prev_fec_ctrl = old_np_keep_prev_fec_ctrl;
epp->ep_adv_cap_mask = old_mask;
/* Reconfigure for robustness */
if (epop->epo_reconfigure(enp) != 0) {
diff --git a/drivers/common/sfc_efx/base/efx_port.c b/drivers/common/sfc_efx/base/efx_port.c
index 7e514e92dd..5ae5e144bd 100644
--- a/drivers/common/sfc_efx/base/efx_port.c
+++ b/drivers/common/sfc_efx/base/efx_port.c
@@ -27,6 +27,7 @@ efx_port_init(
enp->en_mod_flags |= EFX_MOD_PORT;
epp->ep_np_lane_count_req = EFX_PHY_LANE_COUNT_DEFAULT;
+ epp->ep_np_keep_prev_fec_ctrl = B_TRUE;
epp->ep_mac_type = EFX_MAC_INVALID;
epp->ep_link_mode = EFX_LINK_UNKNOWN;
epp->ep_mac_drain = B_TRUE;
diff --git a/drivers/common/sfc_efx/base/medford4_phy.c b/drivers/common/sfc_efx/base/medford4_phy.c
index 9ba6dfbc10..ef7e4e5bac 100644
--- a/drivers/common/sfc_efx/base/medford4_phy.c
+++ b/drivers/common/sfc_efx/base/medford4_phy.c
@@ -117,6 +117,7 @@ medford4_phy_reconfigure(
rc = efx_np_link_ctrl(enp, epp->ep_np_handle, epp->ep_np_cap_data_raw,
loopback_link_mode, loopback, epp->ep_np_lane_count_req,
+ epp->ep_np_keep_prev_fec_ctrl, &epp->ep_np_prev_fec_ctrl,
epp->ep_adv_cap_mask, epp->ep_fcntl_autoneg);
if (rc != 0)
goto fail2;
--
2.47.2
^ permalink raw reply [flat|nested] 5+ messages in thread