Prevent both drivers from sending additional probe requests while we're
already waiting for some response from the AP. Check the ic_mgt_timer for
this purpose. Fixes misbehaviour when hardware sends many "missed beacon"
interrupts. We ended up flooding the AP with probe requests because the
ic_mgt_timer got reset faster than the AP could respond:

Jun  1 12:02:38 jim /bsd: iwn0: sending probe_req to xx:xx:xx:xx:xx:xx on 
channel 40 mode 11n
Jun  1 12:03:09 jim last message repeated 227 times

Additionally:
In iwn(4), read the missed beacon counter value after DMA sync.
In iwm(4), byteswap the missed beacon counter value when reading it.

Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.189
diff -u -p -r1.189 if_iwn.c
--- if_iwn.c    31 May 2017 16:12:39 -0000      1.189
+++ if_iwn.c    1 Jun 2017 10:07:07 -0000
@@ -2504,7 +2504,7 @@ iwn_notif_intr(struct iwn_softc *sc)
                {
                        struct iwn_beacon_missed *miss =
                            (struct iwn_beacon_missed *)(desc + 1);
-                       uint32_t missed = letoh32(miss->consecutive);
+                       uint32_t missed;
 
                        if ((ic->ic_opmode != IEEE80211_M_STA) ||
                            (ic->ic_state != IEEE80211_S_RUN))
@@ -2512,6 +2512,7 @@ iwn_notif_intr(struct iwn_softc *sc)
 
                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                            sizeof (*miss), BUS_DMASYNC_POSTREAD);
+                       missed = letoh32(miss->consecutive);
 
                        /*
                         * If more than 5 consecutive beacons are missed,
@@ -2526,7 +2527,7 @@ iwn_notif_intr(struct iwn_softc *sc)
                         * state machine will drop us into scanning after timing
                         * out waiting for a probe response.
                         */
-                       if (missed > ic->ic_bmissthres)
+                       if (missed > ic->ic_bmissthres && !ic->ic_mgt_timer)
                                IEEE80211_SEND_MGMT(ic, ic->ic_bss,
                                    IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
                        break;
Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.189
diff -u -p -r1.189 if_iwm.c
--- if_iwm.c    31 May 2017 13:22:16 -0000      1.189
+++ if_iwm.c    1 Jun 2017 10:08:49 -0000
@@ -3544,6 +3544,7 @@ iwm_rx_bmiss(struct iwm_softc *sc, struc
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct iwm_missed_beacons_notif *mbn = (void *)pkt->data;
+       uint32_t missed;
 
        if ((ic->ic_opmode != IEEE80211_M_STA) ||
            (ic->ic_state != IEEE80211_S_RUN))
@@ -3552,7 +3553,8 @@ iwm_rx_bmiss(struct iwm_softc *sc, struc
        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*pkt),
            sizeof(*mbn), BUS_DMASYNC_POSTREAD);
 
-       if (mbn->consec_missed_beacons_since_last_rx > ic->ic_bmissthres) {
+       missed = le32toh(mbn->consec_missed_beacons_since_last_rx);
+       if (missed > ic->ic_bmissthres && ic->ic_mgt_timer == 0) {
                /*
                 * Rather than go directly to scan state, try to send a
                 * directed probe request first. If that fails then the

Reply via email to