Don't start a background scan while we're waiting for a response from
the AP to a management frame we have sent.

In particular, the logic which tries to detect dead APs might be waiting
for a probe response from the AP. Starting a background scan in this state
won't do any good. In case of iwn(4) it seems to result in an endless
scan command dance with the firwmare.

Associated:
Jun  6 10:37:03 jim /bsd: iwn0: missed beacon threshold set to 7 beacons, 
beacon interval is 100 TU

Got "beacon miss" interrupt from firmware; sending probe req to AP to check
if AP is still alive:
Jun  6 10:37:04 jim /bsd: iwn0: sending probe_req to 00:25:56:73:b7:a2 on 
channel 1 mode 11n

Meanwhile, low signal of received frames kicks off a background scan:
Jun  6 10:37:05 jim /bsd: iwn0: begin background scan

Response from AP never arrived; interface watchdog moves to SCAN state
while background scan isn't done yet:
Jun  6 10:37:09 jim /bsd: iwn0: RUN -> SCAN

Driver issues SCAN_ABORT and SCAN commands here.
Jun  6 10:37:09 jim /bsd: iwn0: end active scan
Jun  6 10:37:09 jim /bsd: iwn0: SCAN -> SCAN
Jun  6 10:37:09 jim /bsd: iwn0: end active scan
Driver issues SCAN command here.
Jun  6 10:37:09 jim /bsd: iwn0: SCAN -> SCAN
Jun  6 10:37:09 jim /bsd: iwn0: end passive scan
Driver issues SCAN command here.
Jun  6 10:37:09 jim /bsd: iwn0: SCAN -> SCAN
Jun  6 10:37:09 jim /bsd: iwn0: end passive scan
Driver issues SCAN command here.
Jun  6 10:37:09 jim /bsd: iwn0: SCAN -> SCAN
Jun  6 10:37:09 jim /bsd: iwn0: end passive scan
Driver issues SCAN command here.

These SCAN -> SCAN transitions go on forever until the interface is put down.
For some reason we never get scan results from firmware.

So this diff is merely masking an actual driver bug; but such bugs are
hard to fix without really understanding how firmware's SCAN, SCAN_ABORT
commands and "scan done" interrupts interact.
I suppose asking Intel for docs would be an exercise in futility...

Fortunately, it is easy to avoid this situation in the first place.
Note that the inverse case (ignore "missed beacon" events while a background
scan is in progress) must be fixed separately in the driver, not the stack.

OK?

diff c3669ebdb8dc5ae83ec861abde2c7a1cf357a580 /usr/src
blob - f0e9b2ba482a96a5d7deb442d094f6ecc63afec0
file + sys/net80211/ieee80211.c
--- sys/net80211/ieee80211.c
+++ sys/net80211/ieee80211.c
@@ -75,7 +75,7 @@ ieee80211_begin_bgscan(struct ifnet *ifp)
        struct ieee80211com *ic = (void *)ifp;
 
        if ((ic->ic_flags & IEEE80211_F_BGSCAN) ||
-           ic->ic_state != IEEE80211_S_RUN)
+           ic->ic_state != IEEE80211_S_RUN || ic->ic_mgt_timer != 0)
                return;
 
        if (ic->ic_bgscan_start != NULL && ic->ic_bgscan_start(ic) == 0) {

Reply via email to