瀏覽代碼

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>
Rajkumar Manoharan 14 年之前
父節點
當前提交
8e22ad323f
共有 1 個文件被更改,包括 22 次插入14 次删除
  1. 22 14
      drivers/net/wireless/ath/ath9k/beacon.c

+ 22 - 14
drivers/net/wireless/ath/ath9k/beacon.c

@@ -746,6 +746,25 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
 	ath_set_beacon(sc);
 	ath_set_beacon(sc);
 }
 }
 
 
+static bool ath_has_valid_bslot(struct ath_softc *sc)
+{
+	struct ath_vif *avp;
+	int slot;
+	bool found = false;
+
+	for (slot = 0; slot < ATH_BCBUF; slot++) {
+		if (sc->beacon.bslot[slot]) {
+			avp = (void *)sc->beacon.bslot[slot]->drv_priv;
+			if (avp->is_bslot_active) {
+				found = true;
+				break;
+			}
+		}
+	}
+	return found;
+}
+
+
 void ath_set_beacon(struct ath_softc *sc)
 void ath_set_beacon(struct ath_softc *sc)
 {
 {
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -753,7 +772,8 @@ void ath_set_beacon(struct ath_softc *sc)
 
 
 	switch (sc->sc_ah->opmode) {
 	switch (sc->sc_ah->opmode) {
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_AP:
-		ath_beacon_config_ap(sc, cur_conf);
+		if (ath_has_valid_bslot(sc))
+			ath_beacon_config_ap(sc, cur_conf);
 		break;
 		break;
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_MESH_POINT:
@@ -780,20 +800,8 @@ void ath_set_beacon(struct ath_softc *sc)
 void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
 void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
 {
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_hw *ah = sc->sc_ah;
-	struct ath_vif *avp;
-	int slot;
-	bool found = false;
 
 
-	for (slot = 0; slot < ATH_BCBUF; slot++) {
-		if (sc->beacon.bslot[slot]) {
-			avp = (void *)sc->beacon.bslot[slot]->drv_priv;
-			if (avp->is_bslot_active) {
-				found = true;
-				break;
-			}
-		}
-	}
-	if (!found)
+	if (!ath_has_valid_bslot(sc))
 		return;
 		return;
 
 
 	ath9k_ps_wakeup(sc);
 	ath9k_ps_wakeup(sc);