aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2025-11-12 21:01:40 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2025-11-14 02:36:25 +0000
commitb4c35d4622d522c92bb080ee51e4a351e9d71897 (patch)
treed634c461594a2d2380a9b70ec09752084f42b431
parent7d88ac0eb2d2e81ac121dd4a32229494594ec44c (diff)
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
-rw-r--r--sys/dev/iwx/if_iwx.c19
1 files 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);
}