summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravos <avos@FreeBSD.org>2016-02-29 21:09:09 +0000
committeravos <avos@FreeBSD.org>2016-02-29 21:09:09 +0000
commitc6e60153b0b0f8eae92858998051efe884549ff9 (patch)
tree724db4fc425ab31748d0e549c2fae141536ef45c
parentf0bc9a635efb74ac834f0014597b9aea77891178 (diff)
downloadFreeBSD-src-c6e60153b0b0f8eae92858998051efe884549ff9.zip
FreeBSD-src-c6e60153b0b0f8eae92858998051efe884549ff9.tar.gz
net80211: fix scanning after D5145 (PR 197498 related)
- In case, when we are doing <smth> -> INIT (FEXT_REINIT) -> <smth2> state transition, cancel_scan() may be called in the first transition. Reenqueue second state transition, so things will be executed in order. - Discard any AUTH+ state transition request when INIT -> SCAN transition is not done. - Allow to track discarded state transitions via 'state' debugging category. Tested with: * RTL8188EU, HOSTAP mode. * RTL8188CUS, STA mode. * Intel 3945BG, IBSS and STA modes. PR: 197498 Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D5482
-rw-r--r--sys/net80211/ieee80211_proto.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index c2b50af..3bc3141 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1800,13 +1800,19 @@ ieee80211_newstate_cb(void *xvap, int npending)
* We have been requested to drop back to the INIT before
* proceeding to the new state.
*/
+ /* Deny any state changes while we are here. */
+ vap->iv_nstate = IEEE80211_S_INIT;
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
"%s: %s -> %s arg %d\n", __func__,
ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[IEEE80211_S_INIT], arg);
- vap->iv_newstate(vap, IEEE80211_S_INIT, arg);
+ ieee80211_state_name[vap->iv_nstate], arg);
+ vap->iv_newstate(vap, vap->iv_nstate, 0);
IEEE80211_LOCK_ASSERT(ic);
- vap->iv_flags_ext &= ~IEEE80211_FEXT_REINIT;
+ vap->iv_flags_ext &= ~(IEEE80211_FEXT_REINIT |
+ IEEE80211_FEXT_STATEWAIT);
+ /* enqueue new state transition after cancel_scan() task */
+ ieee80211_new_state_locked(vap, nstate, arg);
+ goto done;
}
ostate = vap->iv_state;
@@ -1917,11 +1923,22 @@ ieee80211_new_state_locked(struct ieee80211vap *vap,
IEEE80211_LOCK_ASSERT(ic);
if (vap->iv_flags_ext & IEEE80211_FEXT_STATEWAIT) {
- if (vap->iv_nstate == IEEE80211_S_INIT) {
+ if (vap->iv_nstate == IEEE80211_S_INIT ||
+ ((vap->iv_state == IEEE80211_S_INIT ||
+ (vap->iv_flags_ext & IEEE80211_FEXT_REINIT)) &&
+ vap->iv_nstate == IEEE80211_S_SCAN &&
+ nstate > IEEE80211_S_SCAN)) {
/*
- * XXX The vap is being stopped, do no allow any other
- * state changes until this is completed.
+ * XXX The vap is being stopped/started,
+ * do not allow any other state changes
+ * until this is completed.
*/
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
+ "%s: %s -> %s (%s) transition discarded\n",
+ __func__,
+ ieee80211_state_name[vap->iv_state],
+ ieee80211_state_name[nstate],
+ ieee80211_state_name[vap->iv_nstate]);
return -1;
} else if (vap->iv_state != vap->iv_nstate) {
#if 0
OpenPOWER on IntegriCloud