The branch main has been updated by adrian:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b4c35d4622d522c92bb080ee51e4a351e9d71897

commit b4c35d4622d522c92bb080ee51e4a351e9d71897
Author:     Adrian Chadd <[email protected]>
AuthorDate: 2025-11-12 21:01:40 +0000
Commit:     Adrian Chadd <[email protected]>
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);
 }

Reply via email to