diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2010-12-06 19:05:44 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2010-12-06 19:05:44 +0000 |
commit | 1620fca5f4940c286bfd68e28578b6e9f6ef2977 (patch) | |
tree | 54af7285d3214012647f0f4244e7816631c9a2f0 | |
parent | 80d6042924d0209b35eeab9c93b06b3d8bb44c35 (diff) | |
download | FreeBSD-src-1620fca5f4940c286bfd68e28578b6e9f6ef2977.zip FreeBSD-src-1620fca5f4940c286bfd68e28578b6e9f6ef2977.tar.gz |
Fix scanning after loosing a connection. The firmware assumes that as long
as an association ID is set any scan is supposed to be a background scan.
This implies that the firmware will switch back to the associated channel
after a certain threshold, though, we are not notified about that. We
currently catch this case by a timer which will reset the firmware after
a 'scan timeout', though, upper layers are not notified about that and
will simply hang until manual intervention. Fix this by resetting the
firmware's knowledge about any association on RUN -> ASSOC and
!INIT -> SCAN transitions.
Tested by: Zhihao Yuan <lichray at gmail.com>
MFC after: 1 week
-rw-r--r-- | sys/dev/wpi/if_wpi.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index f6edc91..72d5910 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -1248,8 +1248,25 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) IEEE80211_UNLOCK(ic); WPI_LOCK(sc); - if (nstate == IEEE80211_S_AUTH) { - /* The node must be registered in the firmware before auth */ + if (nstate == IEEE80211_S_SCAN && vap->iv_state != IEEE80211_S_INIT) { + /* + * On !INIT -> SCAN transitions, we need to clear any possible + * knowledge about associations. + */ + error = wpi_config(sc); + if (error != 0) { + device_printf(sc->sc_dev, + "%s: device config failed, error %d\n", + __func__, error); + } + } + if (nstate == IEEE80211_S_AUTH || + (nstate == IEEE80211_S_ASSOC && vap->iv_state == IEEE80211_S_RUN)) { + /* + * The node must be registered in the firmware before auth. + * Also the associd must be cleared on RUN -> ASSOC + * transitions. + */ error = wpi_auth(sc, vap); if (error != 0) { device_printf(sc->sc_dev, |