[PATCH 9/9] net/sfc: fix reporting status of autonegotiation to the user

Ivan Malov ivan.malov at arknetworks.am
Mon Dec 29 22:35:27 CET 2025


Currently, the driver always indicates speed autonegotiation to be enabled,
even when the user has disabled it. Fix the code to report the true status.

Fixes: 886f8d8a05bf ("net/sfc: retrieve link info")
Cc: stable at dpdk.org

Signed-off-by: Ivan Malov <ivan.malov at arknetworks.am>
Reviewed-by: Andy Moreton <andy.moreton at amd.com>
---
 drivers/net/sfc/sfc.h        | 2 +-
 drivers/net/sfc/sfc_ethdev.c | 5 +++--
 drivers/net/sfc/sfc_ev.c     | 7 ++++++-
 drivers/net/sfc/sfc_port.c   | 8 +++++---
 drivers/net/sfc/sfc_repr.c   | 2 +-
 5 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index af32ccfaa3..629578549f 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -417,7 +417,7 @@ int sfc_port_configure(struct sfc_adapter *sa);
 void sfc_port_close(struct sfc_adapter *sa);
 int sfc_port_start(struct sfc_adapter *sa);
 void sfc_port_stop(struct sfc_adapter *sa);
-void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
+void sfc_port_link_mode_to_info(efx_link_mode_t link_mode, uint32_t phy_cap_req,
 				struct rte_eth_link *link_info);
 int sfc_port_update_mac_stats(struct sfc_adapter *sa, boolean_t manual_update);
 int sfc_port_get_mac_stats(struct sfc_adapter *sa, struct rte_eth_xstat *xstats,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 7c2abaab6b..6be98c49d0 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -262,13 +262,14 @@ sfc_dev_get_rte_link(struct rte_eth_dev *dev, int wait_to_complete,
 	SFC_ASSERT(link != NULL);
 
 	if (sa->state != SFC_ETHDEV_STARTED) {
-		sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, link);
+		sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, 0, 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, link);
+		sfc_port_link_mode_to_info(link_mode, sa->port.phy_adv_cap,
+					   link);
 	} else {
 		sfc_ev_mgmt_qpoll(sa);
 		rte_eth_linkstatus_get(dev, link);
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 1d1ee0671f..f058b3cb9b 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -516,7 +516,12 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
 	}
 
 decode_comprehensive:
-	sfc_port_link_mode_to_info(link_mode, &new_link);
+	/*
+	 * Reading 'sa->port.phy_adv_cap' without acquiring adaptor lock may
+	 * render autonegotiation status inaccurate, but that's not critical,
+	 * as it's unlikely to happen often and may be a practical trade-off.
+	 */
+	sfc_port_link_mode_to_info(link_mode, sa->port.phy_adv_cap, &new_link);
 
 set:
 	if (rte_eth_linkstatus_set(sa->eth_dev, &new_link) == 0)
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index e5a7b8358d..33b53f7ac8 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -130,7 +130,8 @@ sfc_port_init_dev_link(struct sfc_adapter *sa)
 	if (rc != 0)
 		return rc;
 
-	sfc_port_link_mode_to_info(link_mode, &current_link);
+	sfc_port_link_mode_to_info(link_mode, sa->port.phy_adv_cap,
+				   &current_link);
 
 	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
 	rte_atomic64_set((rte_atomic64_t *)dev_link,
@@ -614,7 +615,7 @@ sfc_set_rx_mode(struct sfc_adapter *sa)
 }
 
 void
-sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
+sfc_port_link_mode_to_info(efx_link_mode_t link_mode, uint32_t phy_cap_req,
 			   struct rte_eth_link *link_info)
 {
 	SFC_ASSERT(link_mode < EFX_LINK_NMODES);
@@ -684,7 +685,8 @@ sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
 		break;
 	}
 
-	link_info->link_autoneg = RTE_ETH_LINK_AUTONEG;
+	if ((phy_cap_req & (1U << EFX_PHY_CAP_AN)) != 0)
+		link_info->link_autoneg = RTE_ETH_LINK_AUTONEG;
 }
 
 int
diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c
index 93da97387c..fbb5f58a8e 100644
--- a/drivers/net/sfc/sfc_repr.c
+++ b/drivers/net/sfc/sfc_repr.c
@@ -533,7 +533,7 @@ sfc_repr_dev_link_update(struct rte_eth_dev *dev,
 	struct rte_eth_link link;
 
 	if (sr->state != SFC_ETHDEV_STARTED) {
-		sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, &link);
+		sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, 0, &link);
 	} else {
 		memset(&link, 0, sizeof(link));
 		link.link_status = RTE_ETH_LINK_UP;
-- 
2.47.3



More information about the stable mailing list