This patch applies on top of all the other iwx(4) diffs I've sent today.
It makes iwx(4) initialize the device completely in the acpi thread.

We now prepare the device for loading firmware during DVACT_RESUME,
and load firmware from host memory into the device during DVACT_WAKEUP.

Previously, DVACT_WAKEUP would schedule the init_task which resets the
device, undoing work done during DVACT_RESUME, and starts all over again.

ok?

I plan to write a corresponding iwm(4) patch as well.

Tested on a "wise tiger" ax200 in an x250 thinkpad.

diff 055f053850bb0f3af81ea3aa7c4f705a85cfcb76 
ef7889d0664ce439e16df65b58a8d19ea0abefd2
blob - 51063c862bfc0cf2dc9fbe3f41628bbdbdf3486e
blob + a1ba4333d1417d9370344115be6abfb8e1378044
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -490,6 +490,7 @@ void        iwx_attach(struct device *, struct device *, 
void
 void   iwx_init_task(void *);
 int    iwx_activate(struct device *, int);
 int    iwx_resume(struct iwx_softc *);
+int    iwx_wakeup(struct iwx_softc *);
 
 #if NBPFILTER > 0
 void   iwx_radiotap_attach(struct iwx_softc *);
@@ -7822,16 +7823,6 @@ iwx_init_hw(struct iwx_softc *sc)
        struct ieee80211com *ic = &sc->sc_ic;
        int err, i;
 
-       err = iwx_preinit(sc);
-       if (err)
-               return err;
-
-       err = iwx_start_hw(sc);
-       if (err) {
-               printf("%s: could not initialize hardware\n", DEVNAME(sc));
-               return err;
-       }
-
        err = iwx_run_init_mvm_ucode(sc, 0);
        if (err)
                return err;
@@ -7984,6 +7975,16 @@ iwx_init(struct ifnet *ifp)
        KASSERT(sc->task_refs.refs == 0);
        refcnt_init(&sc->task_refs);
 
+       err = iwx_preinit(sc);
+       if (err)
+               return err;
+
+       err = iwx_start_hw(sc);
+       if (err) {
+               printf("%s: could not initialize hardware\n", DEVNAME(sc));
+               return err;
+       }
+
        err = iwx_init_hw(sc);
        if (err) {
                if (generation == sc->sc_generation)
@@ -9593,6 +9594,30 @@ iwx_resume(struct iwx_softc *sc)
 }
 
 int
+iwx_wakeup(struct iwx_softc *sc)
+{
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
+       int err;
+
+       refcnt_init(&sc->task_refs);
+
+       err = iwx_init_hw(sc);
+       if (err)
+               return err;
+
+       ifq_clr_oactive(&ifp->if_snd);
+       ifp->if_flags |= IFF_RUNNING;
+
+       if (ic->ic_opmode == IEEE80211_M_MONITOR)
+               ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+       else
+               ieee80211_begin_scan(ifp);
+
+       return 0;
+}
+
+int
 iwx_activate(struct device *self, int act)
 {
        struct iwx_softc *sc = (struct iwx_softc *)self;
@@ -9608,15 +9633,23 @@ iwx_activate(struct device *self, int act)
                }
                break;
        case DVACT_RESUME:
+               sc->sc_flags &= ~IWX_FLAG_SHUTDOWN;
                err = iwx_resume(sc);
-               if (err)
+               if (err) {
                        printf("%s: could not initialize hardware\n",
                            DEVNAME(sc));
+                       sc->sc_flags |= IWX_FLAG_SHUTDOWN;
+               }
                break;
        case DVACT_WAKEUP:
-               /* Hardware should be up at this point. */
-               if (iwx_set_hw_ready(sc))
-                       task_add(systq, &sc->init_task);
+               if (sc->sc_flags & IWX_FLAG_SHUTDOWN)
+                       sc->sc_flags &= ~IWX_FLAG_SHUTDOWN;
+               else {
+                       err = iwx_wakeup(sc);
+                       if (err)
+                               printf("%s: could not initialize hardware\n",
+                                   DEVNAME(sc));
+               }
                break;
        }
 

Reply via email to