git: b4c35d4622d5 - main - iwx: fix and clean up suspend/resume path
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 14 Nov 2025 02:37:35 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=b4c35d4622d522c92bb080ee51e4a351e9d71897
commit b4c35d4622d522c92bb080ee51e4a351e9d71897
Author: Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2025-11-12 21:01:40 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2025-11-14 02:36:25 +0000
iwx: fix and clean up suspend/resume path
I noticed a couple of things were happening:
* during suspend, I'd get a timeout in the NIC lock path (which
sets a bit on the NIC to say that the host wants to talk to it);
* resume wouldn't come back - scan commands would fail, and you'd have
to reinit the NIC again for it to work.
The thing is:
* the suspend path should already shut down the NIC by shutting down all
the VAPs (and the last VAP should call ic_parent to bring it down), and
* the resume path should already bring up the NIC by bringing up each VAP,
and the first VAP to be brought up calls ic_parent to bring it up.
So instead, I've shuffled around the code to just double check the
hardware state is consistent /before/ ieee80211_suspend_all() and
ieee80211_resume_all() is called.
This both fixes the errant hardware timeout during suspend, and it
fixes resume to work.
Locally tested:
* AX210, STA mode, both hardware ACPI suspend/resume and devctl suspend
and devctl resume
Differential Revision: https://reviews.freebsd.org/D53721
Reviewed by: thj
---
sys/dev/iwx/if_iwx.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/sys/dev/iwx/if_iwx.c b/sys/dev/iwx/if_iwx.c
index 91f5baee9680..dac1c563c593 100644
--- a/sys/dev/iwx/if_iwx.c
+++ b/sys/dev/iwx/if_iwx.c
@@ -10711,9 +10711,13 @@ iwx_suspend(device_t dev)
struct iwx_softc *sc = device_get_softc(dev);
struct ieee80211com *ic = &sc->sc_ic;
- if (sc->sc_flags & IWX_FLAG_HW_INITED) {
- ieee80211_suspend_all(ic);
+ /*
+ * Suspend everything first, then shutdown hardware if it's
+ * still up.
+ */
+ ieee80211_suspend_all(ic);
+ if (sc->sc_flags & IWX_FLAG_HW_INITED) {
iwx_stop(sc);
sc->sc_flags &= ~IWX_FLAG_HW_INITED;
}
@@ -10725,7 +10729,6 @@ iwx_resume(device_t dev)
{
struct iwx_softc *sc = device_get_softc(dev);
struct ieee80211com *ic = &sc->sc_ic;
- int err;
/*
* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -10735,15 +10738,15 @@ iwx_resume(device_t dev)
IWX_LOCK(sc);
- err = iwx_init(sc);
- if (err) {
- iwx_stop_device(sc);
- IWX_UNLOCK(sc);
- return err;
+ /* Stop the hardware here if it's still thought of as "up" */
+ if (sc->sc_flags & IWX_FLAG_HW_INITED) {
+ iwx_stop(sc);
+ sc->sc_flags &= ~IWX_FLAG_HW_INITED;
}
IWX_UNLOCK(sc);
+ /* Start the VAPs, which will bring the hardware back up again */
ieee80211_resume_all(ic);
return (0);
}