On Wed, Sep 08, 2021 at 02:19:00PM +0200, Stefan Sperling wrote: > 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?
The previous version had a bug: It resumed the device even while the interface was marked down. Fixed patch below. diff 055f053850bb0f3af81ea3aa7c4f705a85cfcb76 c734175f035f120197d6be7df1987cb81e535d3e blob - 51063c862bfc0cf2dc9fbe3f41628bbdbdf3486e blob + 26f8a7fa85aa48a054d79e7a175e35bfe96a447b --- 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,27 @@ iwx_activate(struct device *self, int act) } break; case DVACT_RESUME: + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) != IFF_UP) + break; + 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 ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) != IFF_UP) + break; + 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; }