aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanoharan@atheros.com>2011-04-17 12:08:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-19 15:38:05 -0400
commit8e22ad323fb5b7cefb572bd8730e3abef95cdf90 (patch)
tree2c73200333b6069252b22d7face4adc803767482
parentdcf55fb5d43bd82e1e3bf94f065cfe8f75a4bc5a (diff)
ath9k: Fix beacon generation on foreign channel
While leaving the oper channel, beacon generation is stopped by mac80211 and beacon slots are marked as inactive. During the scan, ath9k configures beacon timers based on IEEE80211_CONF_OFFCHANNEL which inturn generates beacon alert even though bslot is inactive. ath9k fails to disable beacon alert while moving to offchannel if none of the beacon slot is active. This is causing beacon transmission on foreign channel. This patch enables swba based on active bslots. This issue was reported with two vifs (AP+STA) and triggered scan in STA vif in unassociated state. Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 9193a385ceb2..24f565ba9988 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -746,6 +746,25 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
746 ath_set_beacon(sc); 746 ath_set_beacon(sc);
747} 747}
748 748
749static bool ath_has_valid_bslot(struct ath_softc *sc)
750{
751 struct ath_vif *avp;
752 int slot;
753 bool found = false;
754
755 for (slot = 0; slot < ATH_BCBUF; slot++) {
756 if (sc->beacon.bslot[slot]) {
757 avp = (void *)sc->beacon.bslot[slot]->drv_priv;
758 if (avp->is_bslot_active) {
759 found = true;
760 break;
761 }
762 }
763 }
764 return found;
765}
766
767
749void ath_set_beacon(struct ath_softc *sc) 768void ath_set_beacon(struct ath_softc *sc)
750{ 769{
751 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 770 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -753,7 +772,8 @@ void ath_set_beacon(struct ath_softc *sc)
753 772
754 switch (sc->sc_ah->opmode) { 773 switch (sc->sc_ah->opmode) {
755 case NL80211_IFTYPE_AP: 774 case NL80211_IFTYPE_AP:
756 ath_beacon_config_ap(sc, cur_conf); 775 if (ath_has_valid_bslot(sc))
776 ath_beacon_config_ap(sc, cur_conf);
757 break; 777 break;
758 case NL80211_IFTYPE_ADHOC: 778 case NL80211_IFTYPE_ADHOC:
759 case NL80211_IFTYPE_MESH_POINT: 779 case NL80211_IFTYPE_MESH_POINT:
@@ -780,20 +800,8 @@ void ath_set_beacon(struct ath_softc *sc)
780void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) 800void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
781{ 801{
782 struct ath_hw *ah = sc->sc_ah; 802 struct ath_hw *ah = sc->sc_ah;
783 struct ath_vif *avp;
784 int slot;
785 bool found = false;
786 803
787 for (slot = 0; slot < ATH_BCBUF; slot++) { 804 if (!ath_has_valid_bslot(sc))
788 if (sc->beacon.bslot[slot]) {
789 avp = (void *)sc->beacon.bslot[slot]->drv_priv;
790 if (avp->is_bslot_active) {
791 found = true;
792 break;
793 }
794 }
795 }
796 if (!found)
797 return; 805 return;
798 806
799 ath9k_ps_wakeup(sc); 807 ath9k_ps_wakeup(sc);