On Fri, Sep 10, 2021 at 10:58:47AM +0200, Stefan Sperling wrote: > All those changes are shown below. My device is still happy with this. > I will reply with a new full diff against -current next.
Full diff: diff c9db663b670f8930f62c8f20c36e84d72697f036 refs/heads/iwx-resume2 blob - 51063c862bfc0cf2dc9fbe3f41628bbdbdf3486e blob + 66a6d4cc3f1d5b6f6cd4fa4350455ce1c117ee6c --- 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 *); @@ -1913,11 +1914,8 @@ int iwx_check_rfkill(struct iwx_softc *sc) { uint32_t v; - int s; int rv; - s = splnet(); - /* * "documentation" is not really helpful here: * 27: HW_RF_KILL_SW @@ -1933,7 +1931,6 @@ iwx_check_rfkill(struct iwx_softc *sc) sc->sc_flags &= ~IWX_FLAG_RFKILL; } - splx(s); return rv; } @@ -1986,8 +1983,6 @@ iwx_restore_interrupts(struct iwx_softc *sc) void iwx_disable_interrupts(struct iwx_softc *sc) { - int s = splnet(); - if (!sc->sc_msix) { IWX_WRITE(sc, IWX_CSR_INT_MASK, 0); @@ -2000,8 +1995,6 @@ iwx_disable_interrupts(struct iwx_softc *sc) IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, sc->sc_hw_init_mask); } - - splx(s); } void @@ -7822,16 +7815,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 +7967,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) @@ -9281,7 +9274,10 @@ iwx_attach(struct device *parent, struct device *self, return; } - /* Clear device-specific "PCI retry timeout" register (41h). */ + /* + * We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40); pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00); @@ -9573,7 +9569,10 @@ iwx_resume(struct iwx_softc *sc) { pcireg_t reg; - /* Clear device-specific "PCI retry timeout" register (41h). */ + /* + * We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40); pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00); @@ -9589,10 +9588,38 @@ iwx_resume(struct iwx_softc *sc) iwx_disable_interrupts(sc); - return iwx_start_hw(sc); + return 0; } 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_start_hw(sc); + if (err) + return err; + + 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 +9635,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; }