aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanoharan@atheros.com>2011-02-09 07:16:39 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-14 15:51:20 -0500
commit014cf3bb1e19a61c53666d7f990f584f1b7af364 (patch)
treeb6a35202046c00e8f8289196042d046399fcd74e /drivers/net/wireless/ath/ath9k/main.c
parentd76dfc612b40b6a9de0a3fe57fe1fa3db7a1ae3b (diff)
ath9k: disable beaconing before stopping beacon queue
Beaconing should be disabled before stopping beacon queue. Not doing so could queue up beacons in hw that causes failure to stop Tx DMA, due to pending frames in hw and also unnecessary beacon tasklet schedule. Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c35
1 files changed, 14 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 8469d7c8744a..31f0fad72391 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1293,24 +1293,10 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc,
1293{ 1293{
1294 struct ath_vif *avp = (void *)vif->drv_priv; 1294 struct ath_vif *avp = (void *)vif->drv_priv;
1295 1295
1296 /* Disable SWBA interrupt */ 1296 ath9k_set_beaconing_status(sc, false);
1297 sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
1298 ath9k_ps_wakeup(sc);
1299 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
1300 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1301 tasklet_kill(&sc->bcon_tasklet);
1302 ath9k_ps_restore(sc);
1303
1304 ath_beacon_return(sc, avp); 1297 ath_beacon_return(sc, avp);
1298 ath9k_set_beaconing_status(sc, true);
1305 sc->sc_flags &= ~SC_OP_BEACONS; 1299 sc->sc_flags &= ~SC_OP_BEACONS;
1306
1307 if (sc->nbcnvifs > 0) {
1308 /* Re-enable beaconing */
1309 sc->sc_ah->imask |= ATH9K_INT_SWBA;
1310 ath9k_ps_wakeup(sc);
1311 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
1312 ath9k_ps_restore(sc);
1313 }
1314} 1300}
1315 1301
1316static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) 1302static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -1438,16 +1424,17 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
1438 1424
1439 if (ath9k_uses_beacons(vif->type)) { 1425 if (ath9k_uses_beacons(vif->type)) {
1440 int error; 1426 int error;
1441 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1442 /* This may fail because upper levels do not have beacons 1427 /* This may fail because upper levels do not have beacons
1443 * properly configured yet. That's OK, we assume it 1428 * properly configured yet. That's OK, we assume it
1444 * will be properly configured and then we will be notified 1429 * will be properly configured and then we will be notified
1445 * in the info_changed method and set up beacons properly 1430 * in the info_changed method and set up beacons properly
1446 * there. 1431 * there.
1447 */ 1432 */
1433 ath9k_set_beaconing_status(sc, false);
1448 error = ath_beacon_alloc(sc, vif); 1434 error = ath_beacon_alloc(sc, vif);
1449 if (!error) 1435 if (!error)
1450 ath_beacon_config(sc, vif); 1436 ath_beacon_config(sc, vif);
1437 ath9k_set_beaconing_status(sc, true);
1451 } 1438 }
1452} 1439}
1453 1440
@@ -1920,10 +1907,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1920 /* Enable transmission of beacons (AP, IBSS, MESH) */ 1907 /* Enable transmission of beacons (AP, IBSS, MESH) */
1921 if ((changed & BSS_CHANGED_BEACON) || 1908 if ((changed & BSS_CHANGED_BEACON) ||
1922 ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { 1909 ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
1923 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 1910 ath9k_set_beaconing_status(sc, false);
1924 error = ath_beacon_alloc(sc, vif); 1911 error = ath_beacon_alloc(sc, vif);
1925 if (!error) 1912 if (!error)
1926 ath_beacon_config(sc, vif); 1913 ath_beacon_config(sc, vif);
1914 ath9k_set_beaconing_status(sc, true);
1927 } 1915 }
1928 1916
1929 if (changed & BSS_CHANGED_ERP_SLOT) { 1917 if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -1946,8 +1934,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1946 } 1934 }
1947 1935
1948 /* Disable transmission of beacons */ 1936 /* Disable transmission of beacons */
1949 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) 1937 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1950 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 1938 !bss_conf->enable_beacon) {
1939 ath9k_set_beaconing_status(sc, false);
1940 avp->is_bslot_active = false;
1941 ath9k_set_beaconing_status(sc, true);
1942 }
1951 1943
1952 if (changed & BSS_CHANGED_BEACON_INT) { 1944 if (changed & BSS_CHANGED_BEACON_INT) {
1953 cur_conf->beacon_interval = bss_conf->beacon_int; 1945 cur_conf->beacon_interval = bss_conf->beacon_int;
@@ -1957,10 +1949,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1957 */ 1949 */
1958 if (vif->type == NL80211_IFTYPE_AP) { 1950 if (vif->type == NL80211_IFTYPE_AP) {
1959 sc->sc_flags |= SC_OP_TSF_RESET; 1951 sc->sc_flags |= SC_OP_TSF_RESET;
1960 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 1952 ath9k_set_beaconing_status(sc, false);
1961 error = ath_beacon_alloc(sc, vif); 1953 error = ath_beacon_alloc(sc, vif);
1962 if (!error) 1954 if (!error)
1963 ath_beacon_config(sc, vif); 1955 ath_beacon_config(sc, vif);
1956 ath9k_set_beaconing_status(sc, true);
1964 } else { 1957 } else {
1965 ath_beacon_config(sc, vif); 1958 ath_beacon_config(sc, vif);
1966 } 1959 }