1de34f860e
to awake transition as well as handle waking up a VAP in STA powersave mode if it's in bgscan. This was a reasonably hairy bug to try and figure out and it became more obvious because of stuff I've done. Specifically: * a NIC would go into bgscan mode - either because of a bgscan timer or wpa_supplicant asked it to; * the AP would indicate there's traffic for the STA by setting the TIM bitmap bit for it; * mindwell would be met during scan, so it'd wake up and break out of the scan loop in scan_task(), but * because the scan wasn't completed, it wouldn't bring the VAP out of STA mode powersave (so it wouldn't tell the AP about it and it would block VAP TX); * .. but because we kept seeing the TIM bit set, ic->ic_lastdata was being constantly updated, and .. * bgscancont() would thus never say "yes we can continue a bgscan" so the bgscan would hang and never make progress. Now, I do see this particular state occur on iwn(4) - /however/ - this NIC has the firmware call ieee80211_scan_next() once the firmware scan for that channel has completed. This has the effect of moving the scan along to the next channel. I do see the debug that I'm adding where we see a beacon with a TIM bit set whilst we're in bgscan, so the condition about waking up to receive traffic is triggering. It just won't cause a hang. For other NICs - all of the USB ones and at least ath(4) - ieee80211_scan_next() / ieee80211_scan_done() isn't called. So it relies upon the mindwell timer, the beacon receive and the beacon / probe response -> ieee80211_add_scan() to move along the scan state. In the above case, mindwell triggered, there's no beacons triggering the scan_add code to move things along, and we weren't waking things up when seeing the TIM set for us. So it just hung until the interface was dropped. So, the short-term fix here is to do what the comment in scan_task() says - if we are in bgscan mode and we see our TIM bit set, just wake up the VAP. If it's already awake then it's a nop. If we're awake then we transition to awake and handle the traffic. Once there's no TX or RX traffic going on, ic->ic_lastdata won't be updated anymore and bgscancont() will continue. This was triggered more often after my initial SLEEP state handling for software sleep states - because now I update ic->ic_lastdata upon seeing a TIM bit set, not just the RX of the subsequent traffic. That's needed so the thing doesn't ping-pong up and down between seeing the TIM bit set, sending the "I'm awake" NULL data frame, and starting to receive data from the AP. I'd like to subsequently split ic_lastdata into two - one for TX and one for RX - so it becomes easier to use the correct one (or both!) when making decisions like whether to scan, go to sleep, etc. I'd appreciate this getting some further testing. Tested: * rsu(4), STA mode, bgscan on * iwn(4), STA mode, bgscan on |
||
---|---|---|
.. | ||
_ieee80211.h | ||
ieee80211_acl.c | ||
ieee80211_action.c | ||
ieee80211_action.h | ||
ieee80211_adhoc.c | ||
ieee80211_adhoc.h | ||
ieee80211_ageq.c | ||
ieee80211_ageq.h | ||
ieee80211_alq.c | ||
ieee80211_alq.h | ||
ieee80211_amrr.c | ||
ieee80211_amrr.h | ||
ieee80211_crypto_ccmp.c | ||
ieee80211_crypto_none.c | ||
ieee80211_crypto_tkip.c | ||
ieee80211_crypto_wep.c | ||
ieee80211_crypto.c | ||
ieee80211_crypto.h | ||
ieee80211_ddb.c | ||
ieee80211_dfs.c | ||
ieee80211_dfs.h | ||
ieee80211_freebsd.c | ||
ieee80211_freebsd.h | ||
ieee80211_hostap.c | ||
ieee80211_hostap.h | ||
ieee80211_ht.c | ||
ieee80211_ht.h | ||
ieee80211_hwmp.c | ||
ieee80211_input.c | ||
ieee80211_input.h | ||
ieee80211_ioctl.c | ||
ieee80211_ioctl.h | ||
ieee80211_mesh.c | ||
ieee80211_mesh.h | ||
ieee80211_monitor.c | ||
ieee80211_monitor.h | ||
ieee80211_node.c | ||
ieee80211_node.h | ||
ieee80211_output.c | ||
ieee80211_phy.c | ||
ieee80211_phy.h | ||
ieee80211_power.c | ||
ieee80211_power.h | ||
ieee80211_proto.c | ||
ieee80211_proto.h | ||
ieee80211_radiotap.c | ||
ieee80211_radiotap.h | ||
ieee80211_ratectl_none.c | ||
ieee80211_ratectl.c | ||
ieee80211_ratectl.h | ||
ieee80211_regdomain.c | ||
ieee80211_regdomain.h | ||
ieee80211_rssadapt.c | ||
ieee80211_rssadapt.h | ||
ieee80211_scan_sta.c | ||
ieee80211_scan.c | ||
ieee80211_scan.h | ||
ieee80211_sta.c | ||
ieee80211_sta.h | ||
ieee80211_superg.c | ||
ieee80211_superg.h | ||
ieee80211_tdma.c | ||
ieee80211_tdma.h | ||
ieee80211_var.h | ||
ieee80211_wds.c | ||
ieee80211_wds.h | ||
ieee80211_xauth.c | ||
ieee80211.c | ||
ieee80211.h |