[PATCH net-next] net: stmmac: mask the MAC interrupt while resume resets the MAC
From: Igor Velkov via B4 Relay
Date: Wed Sep 30 2026 - 18:09:41 EST
From: Igor Velkov <iav@xxxxxx>
stmmac_resume() resets the MAC in stmmac_hw_setup(). On dwmac1000 the
reset clears the interrupt mask, and all core interrupts stay unmasked
until dwmac1000_core_init() writes it again. A link change in that
window raises an RGMII interrupt, and no handler clears it since
commit 2e2c878a3141 ("net: stmmac: remove SGMII/RGMII/SMII interrupt handling").
The line storms:
dwmac_dma_interrupt: unexpected status 04000000
The message repeats every few milliseconds and the network stays down
until a power cycle or a watchdog reset. A register dump at the first
message on ODROID-HC4 showed the pending link change with a zero mask:
core int_status 00000001 int_mask 00000000 pmt 00000000 rgsmiiis 0000000d
Disable the interrupt line for the whole resume and enable it again on
every exit path. The line is IRQF_SHARED, so leave it enabled during
suspend, where another user of the line may wake the system.
Wake-on-LAN resume on two boards:
- ODROID-HC4 (dwmac-meson8b, 7.2): the storm on resume, none in 5
resumes with this patch.
- Helios64 (dwmac-rk, 7.3-rc5): the storm in 2 of 3 resumes, none in
26 resumes with this patch.
Assisted-by: LLM
Signed-off-by: Igor Velkov <iav@xxxxxx>
---
Ported to net-next, where stmmac_resume() gained error labels. Tested
on hardware with 7.2 and 7.3-rc5; build-tested on net-next.
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 24 ++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3ad9252bf6ae..6e0415538327 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -8356,16 +8356,26 @@ int stmmac_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
+ bool irq_off;
int ret;
+ /* Resume resets the MAC, leaving every core interrupt unmasked until
+ * the mask is written again: a link change in that window would storm.
+ */
+ irq_off = netif_running(ndev);
+ if (irq_off)
+ disable_irq(ndev->irq);
+
if (priv->plat->resume) {
ret = priv->plat->resume(dev, priv->plat->bsp_priv);
if (ret)
- return ret;
+ goto out;
}
- if (!netif_running(ndev))
- return 0;
+ if (!netif_running(ndev)) {
+ ret = 0;
+ goto out;
+ }
/* Power Down bit, into the PM register, is cleared
* automatically as soon as a magic packet or a Wake-up frame
@@ -8388,7 +8398,7 @@ int stmmac_resume(struct device *dev)
if (!(priv->plat->flags & STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP)) {
ret = stmmac_legacy_serdes_power_up(priv);
if (ret < 0)
- return ret;
+ goto out;
}
rtnl_lock();
@@ -8442,7 +8452,8 @@ int stmmac_resume(struct device *dev)
netif_device_attach(ndev);
- return 0;
+ ret = 0;
+ goto out;
error_stop_dma:
stmmac_stop_all_dma(priv);
@@ -8451,6 +8462,9 @@ int stmmac_resume(struct device *dev)
stmmac_legacy_serdes_power_down(priv);
mutex_unlock(&priv->lock);
rtnl_unlock();
+out:
+ if (irq_off)
+ enable_irq(ndev->irq);
return ret;
}
---
base-commit: 47a1446725732cd3996edf607e8739334bbf4d78
change-id: 20260930-stmmac-irq-shut-03bac57ae0bb
Best regards,
--
Igor Velkov <iav@xxxxxx>