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;
        }
 

Reply via email to