[PATCH v2 40/45] net/sfc: query link status on link change events on new NICs
Ivan Malov
ivan.malov at arknetworks.am
Wed Apr 23 17:59:57 CEST 2025
Link events signaled on new adaptors (Medford4 and later) do
not carry any specifics, so query the link status separately.
Signed-off-by: Ivan Malov <ivan.malov at arknetworks.am>
Reviewed-by: Andy Moreton <andy.moreton at amd.com>
Reviewed-by: Pieter Jansen Van Vuuren <pieter.jansen-van-vuuren at amd.com>
---
drivers/net/sfc/sfc.h | 2 ++
drivers/net/sfc/sfc_ethdev.c | 2 ++
drivers/net/sfc/sfc_ev.c | 51 +++++++++++++++++++++++++++++++++++-
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 2432a2307e..819ce52529 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -309,6 +309,8 @@ struct sfc_adapter {
uint32_t rxd_wait_timeout_ns;
bool switchdev;
+
+ bool link_ev_need_poll;
};
static inline struct sfc_adapter_shared *
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index bd0061f557..05933b1d39 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -3252,6 +3252,8 @@ sfc_eth_dev_init(struct rte_eth_dev *dev, void *init_params)
if (rc != 0)
goto fail_nic_dma_attach;
+ sa->link_ev_need_poll = encp->enc_link_ev_need_poll;
+
sfc_adapter_unlock(sa);
sfc_log_init(sa, "done");
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index c0d58c9554..1d1ee0671f 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -467,9 +467,58 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
{
struct sfc_evq *evq = arg;
struct sfc_adapter *sa = evq->sa;
- struct rte_eth_link new_link;
+ struct rte_eth_link new_link = {0};
+ if (sa->link_ev_need_poll) {
+ efx_link_mode_t new_mode;
+ bool poll_done = false;
+
+ /*
+ * The event provides only the general status. When the link is
+ * up, poll the port to get the speed, but it is not compulsory.
+ */
+ if (link_mode != EFX_LINK_DOWN) {
+ int ret = 0;
+
+ if (sfc_adapter_trylock(sa)) {
+ /* Never poll when the adaptor is going down. */
+ if (sa->state == SFC_ETHDEV_STARTED) {
+ ret = efx_port_poll(sa->nic, &new_mode);
+ poll_done = true;
+ }
+
+ sfc_adapter_unlock(sa);
+ }
+
+ if (ret != 0) {
+ sfc_warn(sa, "port poll failed on link event");
+ poll_done = false;
+ }
+ }
+
+ if (poll_done) {
+ link_mode = new_mode;
+ goto decode_comprehensive;
+ }
+
+ new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
+ new_link.link_autoneg = RTE_ETH_LINK_AUTONEG;
+
+ if (link_mode == EFX_LINK_DOWN) {
+ new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+ new_link.link_status = RTE_ETH_LINK_DOWN;
+ } else {
+ new_link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
+ new_link.link_status = RTE_ETH_LINK_UP;
+ }
+
+ goto set;
+ }
+
+decode_comprehensive:
sfc_port_link_mode_to_info(link_mode, &new_link);
+
+set:
if (rte_eth_linkstatus_set(sa->eth_dev, &new_link) == 0)
evq->sa->port.lsc_seq++;
--
2.39.5
More information about the dev
mailing list