diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 96 |
1 files changed, 64 insertions, 32 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3caa32316e7b..9790d3a86535 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -213,6 +213,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
213 | */ | 213 | */ |
214 | ath9k_hw_set_interrupts(ah, 0); | 214 | ath9k_hw_set_interrupts(ah, 0); |
215 | ath_drain_all_txq(sc, false); | 215 | ath_drain_all_txq(sc, false); |
216 | |||
217 | spin_lock_bh(&sc->sc_pcu_lock); | ||
218 | |||
216 | stopped = ath_stoprecv(sc); | 219 | stopped = ath_stoprecv(sc); |
217 | 220 | ||
218 | /* XXX: do not flush receive queue here. We don't want | 221 | /* XXX: do not flush receive queue here. We don't want |
@@ -230,34 +233,35 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
230 | sc->sc_ah->curchan->channel, | 233 | sc->sc_ah->curchan->channel, |
231 | channel->center_freq, conf_is_ht40(conf)); | 234 | channel->center_freq, conf_is_ht40(conf)); |
232 | 235 | ||
233 | spin_lock_bh(&sc->sc_resetlock); | ||
234 | |||
235 | r = ath9k_hw_reset(ah, hchan, caldata, fastcc); | 236 | r = ath9k_hw_reset(ah, hchan, caldata, fastcc); |
236 | if (r) { | 237 | if (r) { |
237 | ath_print(common, ATH_DBG_FATAL, | 238 | ath_print(common, ATH_DBG_FATAL, |
238 | "Unable to reset channel (%u MHz), " | 239 | "Unable to reset channel (%u MHz), " |
239 | "reset status %d\n", | 240 | "reset status %d\n", |
240 | channel->center_freq, r); | 241 | channel->center_freq, r); |
241 | spin_unlock_bh(&sc->sc_resetlock); | 242 | spin_unlock_bh(&sc->sc_pcu_lock); |
242 | goto ps_restore; | 243 | goto ps_restore; |
243 | } | 244 | } |
244 | spin_unlock_bh(&sc->sc_resetlock); | ||
245 | 245 | ||
246 | if (ath_startrecv(sc) != 0) { | 246 | if (ath_startrecv(sc) != 0) { |
247 | ath_print(common, ATH_DBG_FATAL, | 247 | ath_print(common, ATH_DBG_FATAL, |
248 | "Unable to restart recv logic\n"); | 248 | "Unable to restart recv logic\n"); |
249 | r = -EIO; | 249 | r = -EIO; |
250 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
250 | goto ps_restore; | 251 | goto ps_restore; |
251 | } | 252 | } |
252 | 253 | ||
254 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
255 | |||
253 | ath_cache_conf_rate(sc, &hw->conf); | 256 | ath_cache_conf_rate(sc, &hw->conf); |
254 | ath_update_txpow(sc); | 257 | ath_update_txpow(sc); |
255 | ath9k_hw_set_interrupts(ah, ah->imask); | 258 | ath9k_hw_set_interrupts(ah, ah->imask); |
256 | 259 | ||
257 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { | 260 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { |
258 | ath_start_ani(common); | 261 | if (sc->sc_flags & SC_OP_BEACONS) |
262 | ath_beacon_config(sc, NULL); | ||
259 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 263 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
260 | ath_beacon_config(sc, NULL); | 264 | ath_start_ani(common); |
261 | } | 265 | } |
262 | 266 | ||
263 | ps_restore: | 267 | ps_restore: |
@@ -269,6 +273,7 @@ static void ath_paprd_activate(struct ath_softc *sc) | |||
269 | { | 273 | { |
270 | struct ath_hw *ah = sc->sc_ah; | 274 | struct ath_hw *ah = sc->sc_ah; |
271 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 275 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
276 | struct ath_common *common = ath9k_hw_common(ah); | ||
272 | int chain; | 277 | int chain; |
273 | 278 | ||
274 | if (!caldata || !caldata->paprd_done) | 279 | if (!caldata || !caldata->paprd_done) |
@@ -277,7 +282,7 @@ static void ath_paprd_activate(struct ath_softc *sc) | |||
277 | ath9k_ps_wakeup(sc); | 282 | ath9k_ps_wakeup(sc); |
278 | ar9003_paprd_enable(ah, false); | 283 | ar9003_paprd_enable(ah, false); |
279 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | 284 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
280 | if (!(ah->caps.tx_chainmask & BIT(chain))) | 285 | if (!(common->tx_chainmask & BIT(chain))) |
281 | continue; | 286 | continue; |
282 | 287 | ||
283 | ar9003_paprd_populate_single_table(ah, caldata, chain); | 288 | ar9003_paprd_populate_single_table(ah, caldata, chain); |
@@ -299,6 +304,7 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
299 | struct ieee80211_supported_band *sband = &sc->sbands[band]; | 304 | struct ieee80211_supported_band *sband = &sc->sbands[band]; |
300 | struct ath_tx_control txctl; | 305 | struct ath_tx_control txctl; |
301 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 306 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
307 | struct ath_common *common = ath9k_hw_common(ah); | ||
302 | int qnum, ftype; | 308 | int qnum, ftype; |
303 | int chain_ok = 0; | 309 | int chain_ok = 0; |
304 | int chain; | 310 | int chain; |
@@ -332,7 +338,7 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
332 | ath9k_ps_wakeup(sc); | 338 | ath9k_ps_wakeup(sc); |
333 | ar9003_paprd_init_table(ah); | 339 | ar9003_paprd_init_table(ah); |
334 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | 340 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
335 | if (!(ah->caps.tx_chainmask & BIT(chain))) | 341 | if (!(common->tx_chainmask & BIT(chain))) |
336 | continue; | 342 | continue; |
337 | 343 | ||
338 | chain_ok = 0; | 344 | chain_ok = 0; |
@@ -550,7 +556,7 @@ void ath_hw_check(struct work_struct *work) | |||
550 | 556 | ||
551 | msleep(1); | 557 | msleep(1); |
552 | } | 558 | } |
553 | ath_reset(sc, false); | 559 | ath_reset(sc, true); |
554 | 560 | ||
555 | out: | 561 | out: |
556 | ath9k_ps_restore(sc); | 562 | ath9k_ps_restore(sc); |
@@ -568,7 +574,7 @@ void ath9k_tasklet(unsigned long data) | |||
568 | ath9k_ps_wakeup(sc); | 574 | ath9k_ps_wakeup(sc); |
569 | 575 | ||
570 | if (status & ATH9K_INT_FATAL) { | 576 | if (status & ATH9K_INT_FATAL) { |
571 | ath_reset(sc, false); | 577 | ath_reset(sc, true); |
572 | ath9k_ps_restore(sc); | 578 | ath9k_ps_restore(sc); |
573 | return; | 579 | return; |
574 | } | 580 | } |
@@ -583,7 +589,7 @@ void ath9k_tasklet(unsigned long data) | |||
583 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 589 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
584 | 590 | ||
585 | if (status & rxmask) { | 591 | if (status & rxmask) { |
586 | spin_lock_bh(&sc->rx.rxflushlock); | 592 | spin_lock_bh(&sc->sc_pcu_lock); |
587 | 593 | ||
588 | /* Check for high priority Rx first */ | 594 | /* Check for high priority Rx first */ |
589 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 595 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && |
@@ -591,7 +597,7 @@ void ath9k_tasklet(unsigned long data) | |||
591 | ath_rx_tasklet(sc, 0, true); | 597 | ath_rx_tasklet(sc, 0, true); |
592 | 598 | ||
593 | ath_rx_tasklet(sc, 0, false); | 599 | ath_rx_tasklet(sc, 0, false); |
594 | spin_unlock_bh(&sc->rx.rxflushlock); | 600 | spin_unlock_bh(&sc->sc_pcu_lock); |
595 | } | 601 | } |
596 | 602 | ||
597 | if (status & ATH9K_INT_TX) { | 603 | if (status & ATH9K_INT_TX) { |
@@ -838,7 +844,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
838 | if (!ah->curchan) | 844 | if (!ah->curchan) |
839 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 845 | ah->curchan = ath_get_curchannel(sc, sc->hw); |
840 | 846 | ||
841 | spin_lock_bh(&sc->sc_resetlock); | 847 | spin_lock_bh(&sc->sc_pcu_lock); |
842 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | 848 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
843 | if (r) { | 849 | if (r) { |
844 | ath_print(common, ATH_DBG_FATAL, | 850 | ath_print(common, ATH_DBG_FATAL, |
@@ -846,14 +852,15 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
846 | "reset status %d\n", | 852 | "reset status %d\n", |
847 | channel->center_freq, r); | 853 | channel->center_freq, r); |
848 | } | 854 | } |
849 | spin_unlock_bh(&sc->sc_resetlock); | ||
850 | 855 | ||
851 | ath_update_txpow(sc); | 856 | ath_update_txpow(sc); |
852 | if (ath_startrecv(sc) != 0) { | 857 | if (ath_startrecv(sc) != 0) { |
853 | ath_print(common, ATH_DBG_FATAL, | 858 | ath_print(common, ATH_DBG_FATAL, |
854 | "Unable to restart recv logic\n"); | 859 | "Unable to restart recv logic\n"); |
860 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
855 | return; | 861 | return; |
856 | } | 862 | } |
863 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
857 | 864 | ||
858 | if (sc->sc_flags & SC_OP_BEACONS) | 865 | if (sc->sc_flags & SC_OP_BEACONS) |
859 | ath_beacon_config(sc, NULL); /* restart beacons */ | 866 | ath_beacon_config(sc, NULL); /* restart beacons */ |
@@ -892,13 +899,15 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
892 | ath9k_hw_set_interrupts(ah, 0); | 899 | ath9k_hw_set_interrupts(ah, 0); |
893 | 900 | ||
894 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ | 901 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ |
902 | |||
903 | spin_lock_bh(&sc->sc_pcu_lock); | ||
904 | |||
895 | ath_stoprecv(sc); /* turn off frame recv */ | 905 | ath_stoprecv(sc); /* turn off frame recv */ |
896 | ath_flushrecv(sc); /* flush recv queue */ | 906 | ath_flushrecv(sc); /* flush recv queue */ |
897 | 907 | ||
898 | if (!ah->curchan) | 908 | if (!ah->curchan) |
899 | ah->curchan = ath_get_curchannel(sc, hw); | 909 | ah->curchan = ath_get_curchannel(sc, hw); |
900 | 910 | ||
901 | spin_lock_bh(&sc->sc_resetlock); | ||
902 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | 911 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
903 | if (r) { | 912 | if (r) { |
904 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 913 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
@@ -906,9 +915,11 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
906 | "reset status %d\n", | 915 | "reset status %d\n", |
907 | channel->center_freq, r); | 916 | channel->center_freq, r); |
908 | } | 917 | } |
909 | spin_unlock_bh(&sc->sc_resetlock); | ||
910 | 918 | ||
911 | ath9k_hw_phy_disable(ah); | 919 | ath9k_hw_phy_disable(ah); |
920 | |||
921 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
922 | |||
912 | ath9k_hw_configpcipowersave(ah, 1, 1); | 923 | ath9k_hw_configpcipowersave(ah, 1, 1); |
913 | ath9k_ps_restore(sc); | 924 | ath9k_ps_restore(sc); |
914 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 925 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
@@ -928,20 +939,23 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
928 | 939 | ||
929 | ath9k_hw_set_interrupts(ah, 0); | 940 | ath9k_hw_set_interrupts(ah, 0); |
930 | ath_drain_all_txq(sc, retry_tx); | 941 | ath_drain_all_txq(sc, retry_tx); |
942 | |||
943 | spin_lock_bh(&sc->sc_pcu_lock); | ||
944 | |||
931 | ath_stoprecv(sc); | 945 | ath_stoprecv(sc); |
932 | ath_flushrecv(sc); | 946 | ath_flushrecv(sc); |
933 | 947 | ||
934 | spin_lock_bh(&sc->sc_resetlock); | ||
935 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); | 948 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); |
936 | if (r) | 949 | if (r) |
937 | ath_print(common, ATH_DBG_FATAL, | 950 | ath_print(common, ATH_DBG_FATAL, |
938 | "Unable to reset hardware; reset status %d\n", r); | 951 | "Unable to reset hardware; reset status %d\n", r); |
939 | spin_unlock_bh(&sc->sc_resetlock); | ||
940 | 952 | ||
941 | if (ath_startrecv(sc) != 0) | 953 | if (ath_startrecv(sc) != 0) |
942 | ath_print(common, ATH_DBG_FATAL, | 954 | ath_print(common, ATH_DBG_FATAL, |
943 | "Unable to start recv logic\n"); | 955 | "Unable to start recv logic\n"); |
944 | 956 | ||
957 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
958 | |||
945 | /* | 959 | /* |
946 | * We may be doing a reset in response to a request | 960 | * We may be doing a reset in response to a request |
947 | * that changes the channel so update any state that | 961 | * that changes the channel so update any state that |
@@ -951,7 +965,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
951 | 965 | ||
952 | ath_update_txpow(sc); | 966 | ath_update_txpow(sc); |
953 | 967 | ||
954 | if (sc->sc_flags & SC_OP_BEACONS) | 968 | if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) |
955 | ath_beacon_config(sc, NULL); /* restart beacons */ | 969 | ath_beacon_config(sc, NULL); /* restart beacons */ |
956 | 970 | ||
957 | ath9k_hw_set_interrupts(ah, ah->imask); | 971 | ath9k_hw_set_interrupts(ah, ah->imask); |
@@ -1106,17 +1120,16 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1106 | * be followed by initialization of the appropriate bits | 1120 | * be followed by initialization of the appropriate bits |
1107 | * and then setup of the interrupt mask. | 1121 | * and then setup of the interrupt mask. |
1108 | */ | 1122 | */ |
1109 | spin_lock_bh(&sc->sc_resetlock); | 1123 | spin_lock_bh(&sc->sc_pcu_lock); |
1110 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); | 1124 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
1111 | if (r) { | 1125 | if (r) { |
1112 | ath_print(common, ATH_DBG_FATAL, | 1126 | ath_print(common, ATH_DBG_FATAL, |
1113 | "Unable to reset hardware; reset status %d " | 1127 | "Unable to reset hardware; reset status %d " |
1114 | "(freq %u MHz)\n", r, | 1128 | "(freq %u MHz)\n", r, |
1115 | curchan->center_freq); | 1129 | curchan->center_freq); |
1116 | spin_unlock_bh(&sc->sc_resetlock); | 1130 | spin_unlock_bh(&sc->sc_pcu_lock); |
1117 | goto mutex_unlock; | 1131 | goto mutex_unlock; |
1118 | } | 1132 | } |
1119 | spin_unlock_bh(&sc->sc_resetlock); | ||
1120 | 1133 | ||
1121 | /* | 1134 | /* |
1122 | * This is needed only to setup initial state | 1135 | * This is needed only to setup initial state |
@@ -1135,8 +1148,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1135 | ath_print(common, ATH_DBG_FATAL, | 1148 | ath_print(common, ATH_DBG_FATAL, |
1136 | "Unable to start recv logic\n"); | 1149 | "Unable to start recv logic\n"); |
1137 | r = -EIO; | 1150 | r = -EIO; |
1151 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1138 | goto mutex_unlock; | 1152 | goto mutex_unlock; |
1139 | } | 1153 | } |
1154 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1140 | 1155 | ||
1141 | /* Setup our intr mask. */ | 1156 | /* Setup our intr mask. */ |
1142 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | | 1157 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | |
@@ -1340,18 +1355,24 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1340 | 1355 | ||
1341 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1356 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
1342 | ath_drain_all_txq(sc, false); | 1357 | ath_drain_all_txq(sc, false); |
1358 | spin_lock_bh(&sc->sc_pcu_lock); | ||
1343 | ath_stoprecv(sc); | 1359 | ath_stoprecv(sc); |
1344 | ath9k_hw_phy_disable(ah); | 1360 | ath9k_hw_phy_disable(ah); |
1345 | } else | 1361 | spin_unlock_bh(&sc->sc_pcu_lock); |
1362 | } else { | ||
1363 | spin_lock_bh(&sc->sc_pcu_lock); | ||
1346 | sc->rx.rxlink = NULL; | 1364 | sc->rx.rxlink = NULL; |
1365 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1366 | } | ||
1347 | 1367 | ||
1348 | /* disable HAL and put h/w to sleep */ | 1368 | /* disable HAL and put h/w to sleep */ |
1349 | ath9k_hw_disable(ah); | 1369 | ath9k_hw_disable(ah); |
1350 | ath9k_hw_configpcipowersave(ah, 1, 1); | 1370 | ath9k_hw_configpcipowersave(ah, 1, 1); |
1351 | ath9k_ps_restore(sc); | 1371 | ath9k_ps_restore(sc); |
1352 | 1372 | ||
1353 | /* Finally, put the chip in FULL SLEEP mode */ | 1373 | sc->ps_idle = true; |
1354 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 1374 | ath9k_set_wiphy_idle(aphy, true); |
1375 | ath_radio_disable(sc, hw); | ||
1355 | 1376 | ||
1356 | sc->sc_flags |= SC_OP_INVALID; | 1377 | sc->sc_flags |= SC_OP_INVALID; |
1357 | 1378 | ||
@@ -1455,6 +1476,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1455 | struct ath_softc *sc = aphy->sc; | 1476 | struct ath_softc *sc = aphy->sc; |
1456 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1477 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1457 | struct ath_vif *avp = (void *)vif->drv_priv; | 1478 | struct ath_vif *avp = (void *)vif->drv_priv; |
1479 | bool bs_valid = false; | ||
1458 | int i; | 1480 | int i; |
1459 | 1481 | ||
1460 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1482 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
@@ -1483,7 +1505,15 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1483 | "slot\n", __func__); | 1505 | "slot\n", __func__); |
1484 | sc->beacon.bslot[i] = NULL; | 1506 | sc->beacon.bslot[i] = NULL; |
1485 | sc->beacon.bslot_aphy[i] = NULL; | 1507 | sc->beacon.bslot_aphy[i] = NULL; |
1486 | } | 1508 | } else if (sc->beacon.bslot[i]) |
1509 | bs_valid = true; | ||
1510 | } | ||
1511 | if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) { | ||
1512 | /* Disable SWBA interrupt */ | ||
1513 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1514 | ath9k_ps_wakeup(sc); | ||
1515 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1516 | ath9k_ps_restore(sc); | ||
1487 | } | 1517 | } |
1488 | 1518 | ||
1489 | sc->nvifs--; | 1519 | sc->nvifs--; |
@@ -1556,6 +1586,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1556 | * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode. | 1586 | * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode. |
1557 | */ | 1587 | */ |
1558 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 1588 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
1589 | unsigned long flags; | ||
1590 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1559 | if (conf->flags & IEEE80211_CONF_PS) { | 1591 | if (conf->flags & IEEE80211_CONF_PS) { |
1560 | sc->ps_flags |= PS_ENABLED; | 1592 | sc->ps_flags |= PS_ENABLED; |
1561 | /* | 1593 | /* |
@@ -1570,7 +1602,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1570 | sc->ps_enabled = false; | 1602 | sc->ps_enabled = false; |
1571 | sc->ps_flags &= ~(PS_ENABLED | | 1603 | sc->ps_flags &= ~(PS_ENABLED | |
1572 | PS_NULLFUNC_COMPLETED); | 1604 | PS_NULLFUNC_COMPLETED); |
1573 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 1605 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); |
1574 | if (!(ah->caps.hw_caps & | 1606 | if (!(ah->caps.hw_caps & |
1575 | ATH9K_HW_CAP_AUTOSLEEP)) { | 1607 | ATH9K_HW_CAP_AUTOSLEEP)) { |
1576 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1608 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
@@ -1585,6 +1617,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1585 | } | 1617 | } |
1586 | } | 1618 | } |
1587 | } | 1619 | } |
1620 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1588 | } | 1621 | } |
1589 | 1622 | ||
1590 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 1623 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
@@ -1968,8 +2001,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1968 | break; | 2001 | break; |
1969 | case IEEE80211_AMPDU_TX_START: | 2002 | case IEEE80211_AMPDU_TX_START: |
1970 | ath9k_ps_wakeup(sc); | 2003 | ath9k_ps_wakeup(sc); |
1971 | ath_tx_aggr_start(sc, sta, tid, ssn); | 2004 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); |
1972 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 2005 | if (!ret) |
2006 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
1973 | ath9k_ps_restore(sc); | 2007 | ath9k_ps_restore(sc); |
1974 | break; | 2008 | break; |
1975 | case IEEE80211_AMPDU_TX_STOP: | 2009 | case IEEE80211_AMPDU_TX_STOP: |
@@ -2032,7 +2066,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
2032 | 2066 | ||
2033 | aphy->state = ATH_WIPHY_SCAN; | 2067 | aphy->state = ATH_WIPHY_SCAN; |
2034 | ath9k_wiphy_pause_all_forced(sc, aphy); | 2068 | ath9k_wiphy_pause_all_forced(sc, aphy); |
2035 | sc->sc_flags |= SC_OP_SCANNING; | ||
2036 | mutex_unlock(&sc->mutex); | 2069 | mutex_unlock(&sc->mutex); |
2037 | } | 2070 | } |
2038 | 2071 | ||
@@ -2047,7 +2080,6 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
2047 | 2080 | ||
2048 | mutex_lock(&sc->mutex); | 2081 | mutex_lock(&sc->mutex); |
2049 | aphy->state = ATH_WIPHY_ACTIVE; | 2082 | aphy->state = ATH_WIPHY_ACTIVE; |
2050 | sc->sc_flags &= ~SC_OP_SCANNING; | ||
2051 | mutex_unlock(&sc->mutex); | 2083 | mutex_unlock(&sc->mutex); |
2052 | } | 2084 | } |
2053 | 2085 | ||