Fix a corner case in STA beacon processing when a CSA is received but
the AP doesn't transmit beacons. If the AP requests a CSA (ie, a channel switch) and then enters CAC (channel availability check) for 60 seconds, it doesn't send beacons and it just listens for radar events (and other things which we don't do yet.) Now, ath_newstate() was not resetting the beacon timer config on a transition to the RUN state when in STA mode - it was setting sc_syncbeacon, which simply updates the beacon config from the contents of the next received beacon. This means the STA never generates beacon miss events. If the AP goes into CAC for 60 seconds and recovers, the STA will happily receive the first beacon and reconfigure timers. But if it gets a radar event after that, it'll change channel again, not notify the station that it's changed channel.. and since the station is happily waiting for the first beacon to configure the beacon timer details from, it won't ever generate a beacon miss interrupt and it'll sit there forever (or until the AP appears on that channel once again.) This change forces the last known beacon timer config to be written to hardware on a transition from CSA->RUN in STA mode. This forces bmiss events to occur and the STA will eventually (after a handful of beacon miss events) begin scanning for another access point.
This commit is contained in:
parent
70d5775697
commit
f52efb6d38
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=223671
@ -4693,6 +4693,7 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
struct ieee80211_node *ni = NULL;
|
||||
int i, error, stamode;
|
||||
u_int32_t rfilt;
|
||||
int csa_run_transition = 0;
|
||||
static const HAL_LED_STATE leds[] = {
|
||||
HAL_LED_INIT, /* IEEE80211_S_INIT */
|
||||
HAL_LED_SCAN, /* IEEE80211_S_SCAN */
|
||||
@ -4708,6 +4709,9 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
ieee80211_state_name[vap->iv_state],
|
||||
ieee80211_state_name[nstate]);
|
||||
|
||||
if (vap->iv_state == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
|
||||
csa_run_transition = 1;
|
||||
|
||||
callout_drain(&sc->sc_cal_ch);
|
||||
ath_hal_setledstate(ah, leds[nstate]); /* set LED */
|
||||
|
||||
@ -4814,8 +4818,14 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
* Defer beacon timer configuration to the next
|
||||
* beacon frame so we have a current TSF to use
|
||||
* (any TSF collected when scanning is likely old).
|
||||
* However if it's due to a CSA -> RUN transition,
|
||||
* force a beacon update so we pick up a lack of
|
||||
* beacons from an AP in CAC and thus force a
|
||||
* scan.
|
||||
*/
|
||||
sc->sc_syncbeacon = 1;
|
||||
if (csa_run_transition)
|
||||
ath_beacon_config(sc, vap);
|
||||
break;
|
||||
case IEEE80211_M_MONITOR:
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user