From 43897a4e60deb0c61d0936b7e63a44e229bd693f Mon Sep 17 00:00:00 2001 From: Dean Sellers Date: Fri, 11 Oct 2024 10:49:20 +1000 Subject: [PATCH] drivers: ethernet: enc28j60: Fix carrier on race on init If there is a carrier (cable plugged in) on device initialisation there is a race between the interrupt service and the L2 init. Signed-off-by: Dean Sellers --- drivers/ethernet/eth_enc28j60.c | 16 ++++++++++++++-- drivers/ethernet/eth_enc28j60_priv.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/ethernet/eth_enc28j60.c b/drivers/ethernet/eth_enc28j60.c index e362435b2b1..d6e2b369198 100644 --- a/drivers/ethernet/eth_enc28j60.c +++ b/drivers/ethernet/eth_enc28j60.c @@ -713,7 +713,14 @@ static void eth_enc28j60_rx_thread(void *p1, void *p2, void *p3) eth_enc28j60_read_phy(dev, ENC28J60_PHY_PHSTAT2, &phstat2); if (phstat2 & ENC28J60_BIT_PHSTAT2_LSTAT) { LOG_INF("%s: Link up", dev->name); - net_eth_carrier_on(context->iface); + /* We may have been interrupted before L2 init complete + * If so flag that the carrier should be set on in init + */ + if (context->iface_initialized) { + net_eth_carrier_on(context->iface); + } else { + context->iface_carrier_on_init = true; + } } else { LOG_INF("%s: Link down", dev->name); @@ -751,7 +758,12 @@ static void eth_enc28j60_iface_init(struct net_if *iface) ethernet_init(iface); - net_if_carrier_off(iface); + /* The device may have already interrupted us to flag link UP */ + if (context->iface_carrier_on_init) { + net_if_carrier_on(iface); + } else { + net_if_carrier_off(iface); + } context->iface_initialized = true; } diff --git a/drivers/ethernet/eth_enc28j60_priv.h b/drivers/ethernet/eth_enc28j60_priv.h index 5e66990f5e1..f47efd601c2 100644 --- a/drivers/ethernet/eth_enc28j60_priv.h +++ b/drivers/ethernet/eth_enc28j60_priv.h @@ -240,6 +240,7 @@ struct eth_enc28j60_runtime { struct k_sem tx_rx_sem; struct k_sem int_sem; bool iface_initialized : 1; + bool iface_carrier_on_init : 1; }; #endif /*_ENC28J60_*/