Don't pass our configured SSID to iwm(4) firmware during a background scan.
authorstsp <stsp@openbsd.org>
Sun, 25 Feb 2018 12:40:51 +0000 (12:40 +0000)
committerstsp <stsp@openbsd.org>
Sun, 25 Feb 2018 12:40:51 +0000 (12:40 +0000)
Apparently this can cause a firmware crash during a TX command on 7265 devices.
Why this happens is unclear.

Problem reported and workaround tested by trondd on bugs@
I have verified that hidden SSID APs still work, though we won't be able to
seamlessly roam between them anymore. Seems like a fair trade-off for now.

sys/dev/pci/if_iwm.c

index 8685fc5..476c61f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.224 2018/01/31 12:36:13 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.225 2018/02/25 12:40:51 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -418,7 +418,7 @@ int iwm_rm_sta_cmd(struct iwm_softc *, struct iwm_node *);
 uint16_t iwm_scan_rx_chain(struct iwm_softc *);
 uint32_t iwm_scan_rate_n_flags(struct iwm_softc *, int, int);
 uint8_t        iwm_lmac_scan_fill_channels(struct iwm_softc *,
-           struct iwm_scan_channel_cfg_lmac *, int);
+           struct iwm_scan_channel_cfg_lmac *, int, int);
 int    iwm_fill_probe_req(struct iwm_softc *, struct iwm_scan_probe_req *);
 int    iwm_lmac_scan(struct iwm_softc *, int);
 int    iwm_config_umac_scan(struct iwm_softc *);
@@ -4724,7 +4724,7 @@ iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
 
 uint8_t
 iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
-    struct iwm_scan_channel_cfg_lmac *chan, int n_ssids)
+    struct iwm_scan_channel_cfg_lmac *chan, int n_ssids, int bgscan)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_channel *c;
@@ -4741,7 +4741,7 @@ iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
                chan->iter_count = htole16(1);
                chan->iter_interval = 0;
                chan->flags = htole32(IWM_UNIFIED_SCAN_CHANNEL_PARTIAL);
-               if (n_ssids != 0)
+               if (n_ssids != 0 && !bgscan)
                        chan->flags |= htole32(1 << 1); /* select SSID 0 */
                chan++;
                nchan++;
@@ -4752,7 +4752,7 @@ iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
 
 uint8_t
 iwm_umac_scan_fill_channels(struct iwm_softc *sc,
-    struct iwm_scan_channel_cfg_umac *chan, int n_ssids)
+    struct iwm_scan_channel_cfg_umac *chan, int n_ssids, int bgscan)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_channel *c;
@@ -4768,7 +4768,7 @@ iwm_umac_scan_fill_channels(struct iwm_softc *sc,
                chan->channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
                chan->iter_count = 1;
                chan->iter_interval = htole16(0);
-               if (n_ssids != 0)
+               if (n_ssids != 0 && !bgscan)
                        chan->flags = htole32(1 << 0); /* select SSID 0 */
                chan++;
                nchan++;
@@ -4957,7 +4957,7 @@ iwm_lmac_scan(struct iwm_softc *sc, int bgscan)
 
        req->n_channels = iwm_lmac_scan_fill_channels(sc,
            (struct iwm_scan_channel_cfg_lmac *)req->data,
-           ic->ic_des_esslen != 0);
+           ic->ic_des_esslen != 0, bgscan);
 
        err = iwm_fill_probe_req(sc,
                            (struct iwm_scan_probe_req *)(req->data +
@@ -5104,7 +5104,7 @@ iwm_umac_scan(struct iwm_softc *sc, int bgscan)
 
        req->n_channels = iwm_umac_scan_fill_channels(sc,
            (struct iwm_scan_channel_cfg_umac *)req->data,
-           ic->ic_des_esslen != 0);
+           ic->ic_des_esslen != 0, bgscan);
 
        req->general_flags = htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
            IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE |