When iwn(4) firmware reports missed beacons, send a probe request only
authorstsp <stsp@openbsd.org>
Fri, 2 Jun 2017 11:18:16 +0000 (11:18 +0000)
committerstsp <stsp@openbsd.org>
Fri, 2 Jun 2017 11:18:16 +0000 (11:18 +0000)
if ic_mgt_timer indicates that we're not already waiting for a response.
Fixes a flood of probe requests sent out while the interrupt kept firing.

Also, read the missed beacon counter value after DMA sync.

ok mpi@

sys/dev/pci/if_iwn.c

index 6e827c2..7cb8932 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwn.c,v 1.189 2017/05/31 16:12:39 stsp Exp $       */
+/*     $OpenBSD: if_iwn.c,v 1.190 2017/06/02 11:18:16 stsp Exp $       */
 
 /*-
  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -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;