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



Reply via email to