Implement support for missed beacon notifications in iwn(4).
authorstsp <stsp@openbsd.org>
Wed, 31 May 2017 16:12:39 +0000 (16:12 +0000)
committerstsp <stsp@openbsd.org>
Wed, 31 May 2017 16:12:39 +0000 (16:12 +0000)
Works with WIFIonICE.
ok phessler@

sys/dev/pci/if_iwn.c

index bc51f0a..6e827c2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwn.c,v 1.188 2017/05/30 16:21:55 stsp Exp $       */
+/*     $OpenBSD: if_iwn.c,v 1.189 2017/05/31 16:12:39 stsp Exp $       */
 
 /*-
  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -2504,18 +2504,31 @@ iwn_notif_intr(struct iwn_softc *sc)
                {
                        struct iwn_beacon_missed *miss =
                            (struct iwn_beacon_missed *)(desc + 1);
+                       uint32_t missed = letoh32(miss->consecutive);
+
+                       if ((ic->ic_opmode != IEEE80211_M_STA) ||
+                           (ic->ic_state != IEEE80211_S_RUN))
+                               break;
 
                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                            sizeof (*miss), BUS_DMASYNC_POSTREAD);
+
                        /*
                         * If more than 5 consecutive beacons are missed,
                         * reinitialize the sensitivity state machine.
                         */
-                       DPRINTFN(2, ("beacons missed %d/%d\n",
-                           letoh32(miss->consecutive), letoh32(miss->total)));
-                       if (ic->ic_state == IEEE80211_S_RUN &&
-                           letoh32(miss->consecutive) > 5)
+                       if (missed > 5)
                                (void)iwn_init_sensitivity(sc);
+
+                       /*
+                        * Rather than go directly to scan state, try to send a
+                        * directed probe request first. If that fails then the
+                        * state machine will drop us into scanning after timing
+                        * out waiting for a probe response.
+                        */
+                       if (missed > ic->ic_bmissthres)
+                               IEEE80211_SEND_MGMT(ic, ic->ic_bss,
+                                   IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
                        break;
                }
                case IWN_UC_READY: