Thread (16 messages) 16 messages, 4 authors, 1d ago

Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")

From: Andrew Lunn <andrew@lunn.ch>
Date: 2026-07-18 00:17:00
Also in: regressions

quoted hunk ↗ jump to hunk
It seems your assumptions are correct. If i do
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index a0249715fafa..487efc746b20 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -129,6 +129,8 @@ void dwmac4_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
        const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
        u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
 
+       value &= ~DMA_CHAN_INTR_ENA_RPS;
+
        if (rx)
                value &= ~DMA_CHAN_INTR_ENA_RIE;
        if (tx)
I can suspend and resume!
Cool. So we might be going in the correct direction.
Could it be sufficient to just do this and reenable on dwmac4_enable_dma_irq?
Unfortunately, it is not as simple as that.

The driver implements NAPI. Interrupts are expensive, so what NAPI
does is after there is an interrupt indicating there are received
packets, and there are more than 64 packets to be received, it
disables interrupts, and goes into polling made. Whenever it polls, if
there are packets available it keeps on polling. Only when polling
indicates there are no more packets, are interrupts re-enabled and
polling stopped.

You can see parts of this logic in stmmac_napi_poll_rx().

This means it cannot be done here. We need a function which is only
called on suspend, and probably release.

The interrupt is being enabled in the init_chan call in
stmmac_dma_ops. Ideally, it should be disabled in a mirror function,
which currently does not exist. So maybe deinit_chan() needs
adding. But where to call it from? init_chan() is called from
stmmac_init_dma_engine(), from stmmac_hw_setup(). stmmac_resume() does
call this. So we need something in stmmac_suspend(). Maybe in
stmmac_stop_all_dma()?

stmmac is messy, there are often not mirror functions. If there is a
stmmac_init_dma_engine() there should be
stmmac_deinit_dma_engine(). If there is stmmac_hw_setup() there should
be stmmac_hw_tairdown(). But none of these seem to exist. 

Anyway, do you want to try to implement deinit_chan() and call it from
stmmac_stop_all_dma()?

   Andrew
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help