I just observed iwn(4) firmware reporting a missed beacon event
during a background scan:

Jan 24 18:24:50 laptop /bsd: iwn0: begin background scan
Jan 24 18:24:57 laptop /bsd: iwn0: sending probe_req to xx:xx:xx:xx:xx:xx on 
channel 10 mode 11g
Jan 24 18:24:59 laptop /bsd: iwn0: end background scan

Under normal conditions, a missed beacon event triggers a probe request
being sent to our current AP. If the AP does respond, all is good. If it
does not respond, we assume the AP has gone away and we go to SCAN state.

But in the above case the driver lost link and didn't recover (i.e. it
never came back out of SCAN state).

One obvious solution is to ignore missed beacon events while a
background scan is in progress. This should prevent both of these
mechanisms from interacting with each other in unfortunate ways.

ok?

Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.223
diff -u -p -r1.223 if_iwm.c
--- if_iwm.c    14 Jan 2018 11:51:34 -0000      1.223
+++ if_iwm.c    24 Jan 2018 17:27:08 -0000
@@ -3673,6 +3673,9 @@ iwm_rx_bmiss(struct iwm_softc *sc, struc
            (ic->ic_state != IEEE80211_S_RUN))
                return;
 
+       if (sc->sc_flags & IWM_FLAG_BGSCAN)
+               return;
+
        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*pkt),
            sizeof(*mbn), BUS_DMASYNC_POSTREAD);
 
Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.198
diff -u -p -r1.198 if_iwn.c
--- if_iwn.c    9 Jan 2018 10:00:12 -0000       1.198
+++ if_iwn.c    24 Jan 2018 17:26:24 -0000
@@ -2530,6 +2530,9 @@ iwn_notif_intr(struct iwn_softc *sc)
                            (ic->ic_state != IEEE80211_S_RUN))
                                break;
 
+                       if (ic->ic_flags & IWN_FLAG_BGSCAN)
+                               break;
+
                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                            sizeof (*miss), BUS_DMASYNC_POSTREAD);
                        missed = letoh32(miss->consecutive);

Reply via email to