[PATCH v3 3/3] common/sfc_efx/base: fix reading advertised autoneg ability
From: Ivan Malov <hidden>
Date: 2026-08-14 12:56:43
Subsystem:
the rest · Maintainer:
Linus Torvalds
The issue is that when the user disables auto-negotiation by removing
the capability bit from the 'advertised mask' (set method) and then
reads the resulting capabilities, which involves querying MCDI, the
bit reappears in the mask irrespective of the user's intent.
Fix this by remembering the user's intent before any link-state queries.
Depends-on: series-38976 ("common/sfc_efx/base: fix code analysis issues")
Fixes: 2a5cf77e6de8 ("common/sfc_efx/base: provide PHY link get method on Medford4")
Fixes: 06f569de6c06 ("common/sfc_efx/base: decode netport link state on probe path")
Cc: stable@dpdk.org
Suggested-by: Andy Moreton <redacted>
Signed-off-by: Ivan Malov <redacted>
Reviewed-by: Viacheslav Galaktionov <redacted>
Reviewed-by: Andy Moreton <redacted>
---
drivers/common/sfc_efx/base/efx_np.c | 11 +++++------
drivers/common/sfc_efx/base/medford4_phy.c | 5 ++++-
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/common/sfc_efx/base/efx_np.c b/drivers/common/sfc_efx/base/efx_np.c
index 06cb33e39b..6dba75f23d 100644
--- a/drivers/common/sfc_efx/base/efx_np.c
+++ b/drivers/common/sfc_efx/base/efx_np.c@@ -436,9 +436,6 @@ 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) - lsp->enls_adv_cap_mask |= 1U << EFX_PHY_CAP_AN; - efx_np_cap_hw_data_to_sw_mask( MCDI_OUT2(req, const uint8_t, LINK_STATE_OUT_LINK_PARTNER_ABILITIES),
@@ -1030,11 +1027,13 @@ efx_np_attach( if (rc != 0) goto fail3; - if (ls.enls_an_supported != B_FALSE) - epp->ep_phy_cap_mask |= 1U << EFX_PHY_CAP_AN; - epp->ep_adv_cap_mask = ls.enls_adv_cap_mask; + if (ls.enls_an_supported != B_FALSE) { + epp->ep_adv_cap_mask |= 1U << EFX_PHY_CAP_AN; + epp->ep_phy_cap_mask |= 1U << EFX_PHY_CAP_AN; + } + #if EFSYS_OPT_LOOPBACK efx_np_assign_loopback_props(enp); #endif /* EFSYS_OPT_LOOPBACK */
diff --git a/drivers/common/sfc_efx/base/medford4_phy.c b/drivers/common/sfc_efx/base/medford4_phy.c
index 7b456c9b8a..17aa068041 100644
--- a/drivers/common/sfc_efx/base/medford4_phy.c
+++ b/drivers/common/sfc_efx/base/medford4_phy.c@@ -34,13 +34,16 @@ medford4_phy_get_link( efx_np_handle_t nph = enp->en_port.ep_np_handle; efx_np_link_state_t ls; efx_np_mac_state_t ms; + uint32_t preserve_an; efx_rc_t rc; + preserve_an = enp->en_port.ep_adv_cap_mask & (1U << EFX_PHY_CAP_AN); + rc = efx_np_link_state(enp, nph, &ls); if (rc != 0) goto fail1; - elsp->epls.epls_adv_cap_mask = ls.enls_adv_cap_mask; + elsp->epls.epls_adv_cap_mask = ls.enls_adv_cap_mask | preserve_an; elsp->epls.epls_lp_cap_mask = ls.enls_lp_cap_mask; elsp->epls.epls_lane_count = ls.enls_lane_count; elsp->els_loopback = ls.enls_loopback;
--
2.47.3