aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/virtual.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-03-03 12:23:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-03-05 14:39:47 -0500
commit8089cc47ed45df8f5a44f92f53140e6fd0958409 (patch)
treefca7ceab8f501e906d84e56a4560dd764b841637 /drivers/net/wireless/ath9k/virtual.c
parent7ec3e514d9361596cbd8aa71ce41d6e5b0220103 (diff)
ath9k: Special processing for channel changes during scan
Allow mac80211-controlled channel changes on an active wiphy and especially during a scan. We need this as long as the scan is controlled by mac80211. Moving this control into the driver could allow some optimizations on scanning while using multiple virtual interfaces, but for now, try to work as well as possible with the current scan mechanism. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/virtual.c')
-rw-r--r--drivers/net/wireless/ath9k/virtual.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath9k/virtual.c
index 913d2043d23e..2b545319408d 100644
--- a/drivers/net/wireless/ath9k/virtual.c
+++ b/drivers/net/wireless/ath9k/virtual.c
@@ -244,6 +244,28 @@ static bool ath9k_wiphy_pausing(struct ath_softc *sc)
244 return ret; 244 return ret;
245} 245}
246 246
247static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
248{
249 int i;
250 if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
251 return true;
252 for (i = 0; i < sc->num_sec_wiphy; i++) {
253 if (sc->sec_wiphy[i] &&
254 sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
255 return true;
256 }
257 return false;
258}
259
260bool ath9k_wiphy_scanning(struct ath_softc *sc)
261{
262 bool ret;
263 spin_lock_bh(&sc->wiphy_lock);
264 ret = __ath9k_wiphy_scanning(sc);
265 spin_unlock_bh(&sc->wiphy_lock);
266 return ret;
267}
268
247static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy); 269static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
248 270
249/* caller must hold wiphy_lock */ 271/* caller must hold wiphy_lock */
@@ -463,6 +485,16 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
463 bool now; 485 bool now;
464 486
465 spin_lock_bh(&sc->wiphy_lock); 487 spin_lock_bh(&sc->wiphy_lock);
488 if (__ath9k_wiphy_scanning(sc)) {
489 /*
490 * For now, we are using mac80211 sw scan and it expects to
491 * have full control over channel changes, so avoid wiphy
492 * scheduling during a scan. This could be optimized if the
493 * scanning control were moved into the driver.
494 */
495 spin_unlock_bh(&sc->wiphy_lock);
496 return -EBUSY;
497 }
466 if (__ath9k_wiphy_pausing(sc)) { 498 if (__ath9k_wiphy_pausing(sc)) {
467 if (sc->wiphy_select_failures == 0) 499 if (sc->wiphy_select_failures == 0)
468 sc->wiphy_select_first_fail = jiffies; 500 sc->wiphy_select_first_fail = jiffies;
@@ -537,7 +569,14 @@ bool ath9k_wiphy_started(struct ath_softc *sc)
537static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy, 569static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
538 struct ath_wiphy *selected) 570 struct ath_wiphy *selected)
539{ 571{
540 if (aphy->chan_idx == selected->chan_idx) 572 if (selected->state == ATH_WIPHY_SCAN) {
573 if (aphy == selected)
574 return;
575 /*
576 * Pause all other wiphys for the duration of the scan even if
577 * they are on the current channel now.
578 */
579 } else if (aphy->chan_idx == selected->chan_idx)
541 return; 580 return;
542 aphy->state = ATH_WIPHY_PAUSED; 581 aphy->state = ATH_WIPHY_PAUSED;
543 ieee80211_stop_queues(aphy->hw); 582 ieee80211_stop_queues(aphy->hw);