From aa0dbe028946f631084eafc6bf2b4899d33b8b78 Mon Sep 17 00:00:00 2001 From: stsp Date: Mon, 22 Nov 2021 10:23:42 +0000 Subject: [PATCH] Let iwm(4) resume directly in DVACT_WAKEUP instead of running the init task. Same change as made for iwx(4) some time ago. tested by myself and bket@ --- sys/dev/pci/if_iwm.c | 104 ++++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index 32d831f78f3..7fd6b5ce449 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.380 2021/11/19 13:05:19 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.381 2021/11/22 10:23:42 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -550,7 +550,8 @@ void iwm_attach_hook(struct device *); void iwm_attach(struct device *, struct device *, void *); void iwm_init_task(void *); int iwm_activate(struct device *, int); -int iwm_resume(struct iwm_softc *); +void iwm_resume(struct iwm_softc *); +int iwm_wakeup(struct iwm_softc *); #if NBPFILTER > 0 void iwm_radiotap_attach(struct iwm_softc *); @@ -1554,11 +1555,8 @@ int iwm_check_rfkill(struct iwm_softc *sc) { uint32_t v; - int s; int rv; - s = splnet(); - /* * "documentation" is not really helpful here: * 27: HW_RF_KILL_SW @@ -1574,7 +1572,6 @@ iwm_check_rfkill(struct iwm_softc *sc) sc->sc_flags &= ~IWM_FLAG_RFKILL; } - splx(s); return rv; } @@ -1622,8 +1619,6 @@ iwm_restore_interrupts(struct iwm_softc *sc) void iwm_disable_interrupts(struct iwm_softc *sc) { - int s = splnet(); - if (!sc->sc_msix) { IWM_WRITE(sc, IWM_CSR_INT_MASK, 0); @@ -1636,8 +1631,6 @@ iwm_disable_interrupts(struct iwm_softc *sc) IWM_WRITE(sc, IWM_CSR_MSIX_HW_INT_MASK_AD, sc->sc_hw_init_mask); } - - splx(s); } void @@ -9685,17 +9678,7 @@ int iwm_init_hw(struct iwm_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - int err, i, ac, qid; - - err = iwm_preinit(sc); - if (err) - return err; - - err = iwm_start_hw(sc); - if (err) { - printf("%s: could not initialize hardware\n", DEVNAME(sc)); - return err; - } + int err, i, ac, qid, s; err = iwm_run_init_mvm_ucode(sc, 0); if (err) @@ -9710,14 +9693,18 @@ iwm_init_hw(struct iwm_softc *sc) } /* Restart, this time with the regular firmware */ + s = splnet(); err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR); if (err) { printf("%s: could not load firmware\n", DEVNAME(sc)); - goto err; + splx(s); + return err; } - if (!iwm_nic_lock(sc)) + if (!iwm_nic_lock(sc)) { + splx(s); return EBUSY; + } err = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc)); if (err) { @@ -9744,20 +9731,20 @@ iwm_init_hw(struct iwm_softc *sc) if (err) { printf("%s: could not init bt coex (error %d)\n", DEVNAME(sc), err); - return err; + goto err; } if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT)) { err = iwm_send_soc_conf(sc); if (err) - return err; + goto err; } if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) { err = iwm_send_dqa_cmd(sc); if (err) - return err; + goto err; } /* Add auxiliary station for scanning */ @@ -9865,6 +9852,7 @@ iwm_init_hw(struct iwm_softc *sc) err: iwm_nic_unlock(sc); + splx(s); return err; } @@ -9908,6 +9896,16 @@ iwm_init(struct ifnet *ifp) KASSERT(sc->task_refs.refs == 0); refcnt_init(&sc->task_refs); + err = iwm_preinit(sc); + if (err) + return err; + + err = iwm_start_hw(sc); + if (err) { + printf("%s: could not initialize hardware\n", DEVNAME(sc)); + return err; + } + err = iwm_init_hw(sc); if (err) { if (generation == sc->sc_generation) @@ -11187,7 +11185,10 @@ iwm_attach(struct device *parent, struct device *self, void *aux) 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); @@ -11583,12 +11584,15 @@ iwm_init_task(void *arg1) splx(s); } -int +void iwm_resume(struct iwm_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); @@ -11603,8 +11607,34 @@ iwm_resume(struct iwm_softc *sc) } iwm_disable_interrupts(sc); +} + +int +iwm_wakeup(struct iwm_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = &sc->sc_ic.ic_if; + int err; - return iwm_start_hw(sc); + refcnt_init(&sc->task_refs); + + err = iwm_start_hw(sc); + if (err) + return err; + + err = iwm_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 @@ -11623,15 +11653,15 @@ iwm_activate(struct device *self, int act) } break; case DVACT_RESUME: - err = iwm_resume(sc); - if (err) - printf("%s: could not initialize hardware\n", - DEVNAME(sc)); + iwm_resume(sc); break; case DVACT_WAKEUP: - /* Hardware should be up at this point. */ - if (iwm_set_hw_ready(sc)) - task_add(systq, &sc->init_task); + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP) { + err = iwm_wakeup(sc); + if (err) + printf("%s: could not initialize hardware\n", + DEVNAME(sc)); + } break; } -- 2.20.1