diff options
author | Jouni Malinen <jouni.malinen@atheros.com> | 2009-03-03 12:23:38 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-05 14:39:47 -0500 |
commit | 8089cc47ed45df8f5a44f92f53140e6fd0958409 (patch) | |
tree | fca7ceab8f501e906d84e56a4560dd764b841637 /drivers/net/wireless/ath9k/virtual.c | |
parent | 7ec3e514d9361596cbd8aa71ce41d6e5b0220103 (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.c | 41 |
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 | ||
247 | static 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 | |||
260 | bool 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 | |||
247 | static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy); | 269 | static 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) | |||
537 | static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy, | 569 | static 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); |