aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2014-09-05 00:20:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-09 15:27:22 -0400
commit367b341edbebc405d80fecd28ff973dfb7390d65 (patch)
tree3d467024f0df09bbb63bda62dbdb0adfa6aa2bd6
parentda0162f3f0012465cc6d77c4d416fabb182713ad (diff)
ath9k: Fix MCC scanning
Scanning is curently broken when two channel contexts are active. For example in a P2P-GO/STA setup, the offchannel timer allows HZ / 10 to elapse before initiating a switch to the next scan channel from the current operating channel, which in this case would be the P2P-GO context. But, the channel context timer might decide to switch to the STA context when an SWBA comes early and a beacon is sent out. Since pending offchannel requests are processed in EVENT_BEACON_PREPARE, this causes inconsistent scanning. Fix this by making sure that a context switch happens before processing the pending offchannel request. This also makes sure that active channel contexts will always have higher priority than offchannel operations and the scan sequence looks like this: p2p-go, sta, p2p-go, offchannel, p2p-go, sta, p2p-go, offchannel,..... The oper-channel is p2p-go, so the STA context has to switch to p2p-go again before switching offchannel. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c4
2 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 46a1d2e24dae..0c071b094010 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -378,6 +378,7 @@ enum ath_chanctx_state {
378struct ath_chanctx_sched { 378struct ath_chanctx_sched {
379 bool beacon_pending; 379 bool beacon_pending;
380 bool offchannel_pending; 380 bool offchannel_pending;
381 bool wait_switch;
381 enum ath_chanctx_state state; 382 enum ath_chanctx_state state;
382 u8 beacon_miss; 383 u8 beacon_miss;
383 384
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index a31f526ba852..522894ba727a 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -333,7 +333,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
333 break; 333 break;
334 } 334 }
335 335
336 if (sc->sched.offchannel_pending) { 336 if (sc->sched.offchannel_pending && !sc->sched.wait_switch) {
337 sc->sched.offchannel_pending = false; 337 sc->sched.offchannel_pending = false;
338 sc->next_chan = &sc->offchannel.chan; 338 sc->next_chan = &sc->offchannel.chan;
339 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; 339 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
@@ -490,6 +490,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
490 "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n"); 490 "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n");
491 491
492 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; 492 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
493 sc->sched.wait_switch = false;
493 494
494 tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2; 495 tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2;
495 if (sc->sched.beacon_miss >= 2) { 496 if (sc->sched.beacon_miss >= 2) {
@@ -588,6 +589,7 @@ static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
588 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) && 589 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) &&
589 (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) { 590 (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) {
590 sc->sched.offchannel_pending = true; 591 sc->sched.offchannel_pending = true;
592 sc->sched.wait_switch = true;
591 if (chandef) 593 if (chandef)
592 ctx->chandef = *chandef; 594 ctx->chandef = *chandef;
593 spin_unlock_bh(&sc->chan_lock); 595 spin_unlock_bh(&sc->chan_lock);