Re: dwmac-motorcomm: RX dies after long s2idle, only wrapper SYS_RESET recovers
Giuseppe Nespolino <[email protected]>
| Newsgroups | gmane.linux.network,gmane.linux.kernel |
|---|---|
| Message-ID | <CAKx9m6OMQKufDpqGJewG1OyvZGBKGimSxxxGRDGWgFicSRoTGQ@mail.gmail.com> |
On Wed, Aug 12, 2026 at 09:14:56PM +0000, Yao Zi wrote: > This is quite unexpected. I found enabling OOB_WOL_CTRL blocks DMA > interrupts because it's the default state after resetting, without > clearing it, the MAC is non-operational. That fits what I see, and it explains the asymmetry: the write only takes effect in the window right after a reset. On an already-armed engine, writing the DIS bit back does nothing, which is exactly what I measured. > Have you tested the idea? We always call pci_wake_from_d3(pdev, true) but > from your description, broken RX only happens after s2idle is active for > some time, right? Right, and it's a fair objection; the wake is armed on every suspend, so it can't be what distinguishes a 30s cycle from an 18min one. I built and loaded that change here but haven't been through a long suspend with it yet, so I have no result either way yet. > From my own testing, with OOB WOL enabled, both DMA TX and RX interrupts > aren't delivered. So TX behavior when RX is broken might indicate what > has happened. I can't answer that from what I captured: between my two snapshots no frames were transmitted (mmc_tx_framecount_gb stayed at 98), so the frozen tx-0 vector count proves nothing. Worth noting that TX packets do leave the interface while RX is broken, but that is expected even with TX interrupts dead, since stmmac cleans the ring from the coalescing hrtimer. I've instrumented for it. Next occurrence I'll force TX traffic and report the tx-0 vector delta. > Anyway, please try figuring out state of the DIS bit when the problem > occurs before sending the patch, which would be a strong reason to > perform a reset in the resume hook. Already captured, from the last natural occurrence (s2idle 14:43 -> 15:01, 18 minutes, on AC): OOB_WOL_CTRL (BAR0+0x1010) while broken: 0x00000001 OOB_WOL_CTRL healthy baseline: 0x00000001 Identical, and motorcomm_init() had already run at resume and written that same value. So there is no software-visible state left to correct: the register claims DIS is set while interrupts are not being delivered, and nothing short of the reset recovers it. I'll send the reset-in-resume patch. One design question bef you want motorcomm_reset() followed by the eFuse settle delay and motorcomm_init(), i.e. the probe sequence minus the MAC addr would you rather keep resume lighter than that? One disclosure, per Documentation/process/generated-content.rst: this investigation was done with an AI coding assistant. It drove the register-level diagnosis and the experiment design; the measurements are all from this machine and I ran and verified them myself. Thanks, Giuseppe