diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2010-07-15 11:52:20 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2010-07-15 11:52:20 +0000 |
commit | 85997188c81be18112ce42664ad712d852d77fd0 (patch) | |
tree | 1d93f22bb6b1ac86a708cd570f156369fc97eeaf /sys/dev/iwn | |
parent | 6ac2f4bf6024d6ca53d6ffb620b51c083419b088 (diff) | |
download | FreeBSD-src-85997188c81be18112ce42664ad712d852d77fd0.zip FreeBSD-src-85997188c81be18112ce42664ad712d852d77fd0.tar.gz |
Handle RUN->ASSOC->RUN transition correctly, as in not trigger a
firmware error. Convert if statements to a switch statement while
I'm here.
Tested by: Benjamin Kaduk <kaduk at mit.edu>
MFC after: 2 weeks
Diffstat (limited to 'sys/dev/iwn')
-rw-r--r-- | sys/dev/iwn/if_iwn.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 5b348bd..12d1bcd 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -1940,27 +1940,44 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) IWN_LOCK(sc); callout_stop(&sc->sc_timer_to); - if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) { - /* !AUTH -> AUTH requires adapter config */ - /* Reset state to handle reassociations correctly. */ + switch (nstate) { + case IEEE80211_S_ASSOC: + if (vap->iv_state != IEEE80211_S_RUN) + break; + /* FALLTHROUGH */ + case IEEE80211_S_AUTH: + if (vap->iv_state == IEEE80211_S_AUTH) + break; + + /* + * !AUTH -> AUTH transition requires state reset to handle + * reassociations correctly. + */ sc->rxon.associd = 0; sc->rxon.filter &= ~htole32(IWN_FILTER_BSS); iwn_calib_reset(sc); error = iwn_auth(sc, vap); - } - if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) { + break; + + case IEEE80211_S_RUN: + /* + * RUN -> RUN transition; Just restart the timers. + */ + if (vap->iv_state == IEEE80211_S_RUN) { + iwn_calib_reset(sc); + break; + } + /* * !RUN -> RUN requires setting the association id * which is done with a firmware cmd. We also defer * starting the timers until that work is done. */ error = iwn_run(sc, vap); - } - if (nstate == IEEE80211_S_RUN) { - /* - * RUN -> RUN transition; just restart the timers. - */ - iwn_calib_reset(sc); + break; + + default: + break; } IWN_UNLOCK(sc); IEEE80211_LOCK(ic); |