From ac1f6e58cb77bb66b8811f7d98703e0f076a8f65 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 10 Oct 2026 00:00:11 -0700 Subject: [PATCH] net: bgmac: enable interrupts only after NAPI is ready bgmac_open() calls bgmac_chip_init(), which unmasks the interrupts and enables the MAC receiver, before request_irq() and napi_enable(). bgmac_enet_resume() also enables NAPI only after bgmac_chip_init(). When frames arrive in that window, the first RX interrupt masks all interrupts in bgmac_interrupt() and calls napi_schedule() on a NAPI instance that is still disabled, so nothing is scheduled. Nothing unmasks the interrupts again, the RX ring fills up and the interface stays deaf until it is brought down and up without traffic. On an Asus RT-N16 (BCM4716) a single "ip link set eth0 down/up" while a host sends UDP to the router left INT_MASK at 0, INT_STATUS with RX pending and the RX DMA idle on a full ring, with the RX packet and interrupt counters no longer moving. With this change, 10 of 10 such cycles recovered on their own. Request the IRQ and enable NAPI before the chip is initialized. Fixes: dd4544f05469 ("bgmac: driver for GBit MAC core on BCMA bus") Fixes: f3537b3494c0 ("net: ethernet: bgmac: driver power manangement") Cc: stable@vger.kernel.org Signed-off-by: Rosen Penev Reviewed-by: Daniel Machon Link: https://patch.msgid.link/20261010070011.60403-1-rosenp@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bgmac.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 3e9c57196a39..1835266fdd09 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1183,9 +1183,6 @@ static int bgmac_open(struct net_device *net_dev) if (err) return err; - /* Specs say about reclaiming rings here, but we do that in DMA init */ - bgmac_chip_init(bgmac); - err = request_irq(bgmac->irq, bgmac_interrupt, IRQF_SHARED, net_dev->name, net_dev); if (err < 0) { @@ -1195,6 +1192,9 @@ static int bgmac_open(struct net_device *net_dev) } napi_enable(&bgmac->napi); + /* Specs say about reclaiming rings here, but we do that in DMA init */ + bgmac_chip_init(bgmac); + phy_start(net_dev->phydev); netif_start_queue(net_dev); @@ -1608,10 +1608,10 @@ int bgmac_enet_resume(struct bgmac *bgmac) if (rc) return rc; - bgmac_chip_init(bgmac); - napi_enable(&bgmac->napi); + bgmac_chip_init(bgmac); + netif_tx_lock(bgmac->net_dev); netif_device_attach(bgmac->net_dev); netif_tx_unlock(bgmac->net_dev);