aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c59
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h1
2 files changed, 20 insertions, 40 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 87ebc461d74a..482932979c9b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2093,13 +2093,6 @@ err_unmap:
2093 return ret; 2093 return ret;
2094} 2094}
2095 2095
2096static void ath5k_beacon_disable(struct ath5k_softc *sc)
2097{
2098 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
2099 ath5k_hw_set_imr(sc->ah, sc->imask);
2100 ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
2101}
2102
2103/* 2096/*
2104 * Transmit a beacon frame at SWBA. Dynamic updates to the 2097 * Transmit a beacon frame at SWBA. Dynamic updates to the
2105 * frame contents are done as needed and the slot time is 2098 * frame contents are done as needed and the slot time is
@@ -2293,13 +2286,11 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2293 struct ath5k_hw *ah = sc->ah; 2286 struct ath5k_hw *ah = sc->ah;
2294 unsigned long flags; 2287 unsigned long flags;
2295 2288
2296 ath5k_hw_set_imr(ah, 0); 2289 spin_lock_irqsave(&sc->block, flags);
2297 sc->bmisscount = 0; 2290 sc->bmisscount = 0;
2298 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); 2291 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
2299 2292
2300 if (sc->opmode == NL80211_IFTYPE_ADHOC || 2293 if (sc->enable_beacon) {
2301 sc->opmode == NL80211_IFTYPE_MESH_POINT ||
2302 sc->opmode == NL80211_IFTYPE_AP) {
2303 /* 2294 /*
2304 * In IBSS mode we use a self-linked tx descriptor and let the 2295 * In IBSS mode we use a self-linked tx descriptor and let the
2305 * hardware send the beacons automatically. We have to load it 2296 * hardware send the beacons automatically. We have to load it
@@ -2312,16 +2303,17 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2312 sc->imask |= AR5K_INT_SWBA; 2303 sc->imask |= AR5K_INT_SWBA;
2313 2304
2314 if (sc->opmode == NL80211_IFTYPE_ADHOC) { 2305 if (sc->opmode == NL80211_IFTYPE_ADHOC) {
2315 if (ath5k_hw_hasveol(ah)) { 2306 if (ath5k_hw_hasveol(ah))
2316 spin_lock_irqsave(&sc->block, flags);
2317 ath5k_beacon_send(sc); 2307 ath5k_beacon_send(sc);
2318 spin_unlock_irqrestore(&sc->block, flags);
2319 }
2320 } else 2308 } else
2321 ath5k_beacon_update_timers(sc, -1); 2309 ath5k_beacon_update_timers(sc, -1);
2310 } else {
2311 ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
2322 } 2312 }
2323 2313
2324 ath5k_hw_set_imr(ah, sc->imask); 2314 ath5k_hw_set_imr(ah, sc->imask);
2315 mmiowb();
2316 spin_unlock_irqrestore(&sc->block, flags);
2325} 2317}
2326 2318
2327static void ath5k_tasklet_beacon(unsigned long data) 2319static void ath5k_tasklet_beacon(unsigned long data)
@@ -2806,7 +2798,6 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
2806 goto end; 2798 goto end;
2807 2799
2808 ath5k_hw_set_lladdr(sc->ah, mac); 2800 ath5k_hw_set_lladdr(sc->ah, mac);
2809 ath5k_beacon_disable(sc);
2810 sc->vif = NULL; 2801 sc->vif = NULL;
2811end: 2802end:
2812 mutex_unlock(&sc->lock); 2803 mutex_unlock(&sc->lock);
@@ -3135,25 +3126,6 @@ out:
3135 return ret; 3126 return ret;
3136} 3127}
3137 3128
3138/*
3139 * Update the beacon and reconfigure the beacon queues.
3140 */
3141static void
3142ath5k_beacon_reconfig(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3143{
3144 int ret;
3145 unsigned long flags;
3146 struct ath5k_softc *sc = hw->priv;
3147
3148 spin_lock_irqsave(&sc->block, flags);
3149 ret = ath5k_beacon_update(hw, vif);
3150 spin_unlock_irqrestore(&sc->block, flags);
3151 if (ret == 0) {
3152 ath5k_beacon_config(sc);
3153 mmiowb();
3154 }
3155}
3156
3157static void 3129static void
3158set_beacon_filter(struct ieee80211_hw *hw, bool enable) 3130set_beacon_filter(struct ieee80211_hw *hw, bool enable)
3159{ 3131{
@@ -3176,6 +3148,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3176{ 3148{
3177 struct ath5k_softc *sc = hw->priv; 3149 struct ath5k_softc *sc = hw->priv;
3178 struct ath5k_hw *ah = sc->ah; 3150 struct ath5k_hw *ah = sc->ah;
3151 unsigned long flags;
3179 3152
3180 mutex_lock(&sc->lock); 3153 mutex_lock(&sc->lock);
3181 if (WARN_ON(sc->vif != vif)) 3154 if (WARN_ON(sc->vif != vif))
@@ -3201,13 +3174,19 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3201 AR5K_LED_ASSOC : AR5K_LED_INIT); 3174 AR5K_LED_ASSOC : AR5K_LED_INIT);
3202 } 3175 }
3203 3176
3204 if (changes & BSS_CHANGED_BEACON && 3177 if (changes & BSS_CHANGED_BEACON) {
3205 (vif->type == NL80211_IFTYPE_ADHOC || 3178 spin_lock_irqsave(&sc->block, flags);
3206 vif->type == NL80211_IFTYPE_MESH_POINT || 3179 ath5k_beacon_update(hw, vif);
3207 vif->type == NL80211_IFTYPE_AP)) { 3180 spin_unlock_irqrestore(&sc->block, flags);
3208 ath5k_beacon_reconfig(hw, vif);
3209 } 3181 }
3210 3182
3183 if (changes & BSS_CHANGED_BEACON_ENABLED)
3184 sc->enable_beacon = bss_conf->enable_beacon;
3185
3186 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
3187 BSS_CHANGED_BEACON_INT))
3188 ath5k_beacon_config(sc);
3189
3211 unlock: 3190 unlock:
3212 mutex_unlock(&sc->lock); 3191 mutex_unlock(&sc->lock);
3213} 3192}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 65e75fb54482..778e422946ab 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -190,6 +190,7 @@ struct ath5k_softc {
190 struct timer_list calib_tim; /* calibration timer */ 190 struct timer_list calib_tim; /* calibration timer */
191 int power_level; /* Requested tx power in dbm */ 191 int power_level; /* Requested tx power in dbm */
192 bool assoc; /* assocate state */ 192 bool assoc; /* assocate state */
193 bool enable_beacon; /* true if beacons are on */
193}; 194};
194 195
195#define ath5k_hw_hasbssidmask(_ah) \ 196#define ath5k_hw_hasbssidmask(_ah) \