diff options
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_calib.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_hst.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 54 |
10 files changed, 37 insertions, 79 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8b0d8dcd7625..56317b0fb6b6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
976 | AR_PHY_CL_TAB_1, | 976 | AR_PHY_CL_TAB_1, |
977 | AR_PHY_CL_TAB_2 }; | 977 | AR_PHY_CL_TAB_2 }; |
978 | 978 | ||
979 | ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); | ||
980 | |||
979 | if (rtt) { | 981 | if (rtt) { |
980 | if (!ar9003_hw_rtt_restore(ah, chan)) | 982 | if (!ar9003_hw_rtt_restore(ah, chan)) |
981 | run_rtt_cal = true; | 983 | run_rtt_cal = true; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ce19c09fa8e8..3afc24bde6d6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, | |||
586 | ath9k_hw_synth_delay(ah, chan, synthDelay); | 586 | ath9k_hw_synth_delay(ah, chan, synthDelay); |
587 | } | 587 | } |
588 | 588 | ||
589 | static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | 589 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) |
590 | { | 590 | { |
591 | switch (rx) { | 591 | if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5) |
592 | case 0x5: | ||
593 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | 592 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, |
594 | AR_PHY_SWAP_ALT_CHAIN); | 593 | AR_PHY_SWAP_ALT_CHAIN); |
595 | case 0x3: | 594 | |
596 | case 0x1: | 595 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); |
597 | case 0x2: | 596 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); |
598 | case 0x7: | ||
599 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); | ||
600 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); | ||
601 | break; | ||
602 | default: | ||
603 | break; | ||
604 | } | ||
605 | 597 | ||
606 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) | 598 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) |
607 | REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); | 599 | tx = 3; |
608 | else | ||
609 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); | ||
610 | 600 | ||
611 | if (tx == 0x5) { | 601 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); |
612 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
613 | AR_PHY_SWAP_ALT_CHAIN); | ||
614 | } | ||
615 | } | 602 | } |
616 | 603 | ||
617 | /* | 604 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 86e26a19efda..42794c546a40 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -317,7 +317,6 @@ struct ath_rx { | |||
317 | u32 *rxlink; | 317 | u32 *rxlink; |
318 | u32 num_pkts; | 318 | u32 num_pkts; |
319 | unsigned int rxfilter; | 319 | unsigned int rxfilter; |
320 | spinlock_t rxbuflock; | ||
321 | struct list_head rxbuf; | 320 | struct list_head rxbuf; |
322 | struct ath_descdma rxdma; | 321 | struct ath_descdma rxdma; |
323 | struct ath_buf *rx_bufptr; | 322 | struct ath_buf *rx_bufptr; |
@@ -328,7 +327,6 @@ struct ath_rx { | |||
328 | 327 | ||
329 | int ath_startrecv(struct ath_softc *sc); | 328 | int ath_startrecv(struct ath_softc *sc); |
330 | bool ath_stoprecv(struct ath_softc *sc); | 329 | bool ath_stoprecv(struct ath_softc *sc); |
331 | void ath_flushrecv(struct ath_softc *sc); | ||
332 | u32 ath_calcrxfilter(struct ath_softc *sc); | 330 | u32 ath_calcrxfilter(struct ath_softc *sc); |
333 | int ath_rx_init(struct ath_softc *sc, int nbufs); | 331 | int ath_rx_init(struct ath_softc *sc, int nbufs); |
334 | void ath_rx_cleanup(struct ath_softc *sc); | 332 | void ath_rx_cleanup(struct ath_softc *sc); |
@@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc); | |||
646 | enum sc_op_flags { | 644 | enum sc_op_flags { |
647 | SC_OP_INVALID, | 645 | SC_OP_INVALID, |
648 | SC_OP_BEACONS, | 646 | SC_OP_BEACONS, |
649 | SC_OP_RXFLUSH, | ||
650 | SC_OP_ANI_RUN, | 647 | SC_OP_ANI_RUN, |
651 | SC_OP_PRIM_STA_VIF, | 648 | SC_OP_PRIM_STA_VIF, |
652 | SC_OP_HW_RESET, | 649 | SC_OP_HW_RESET, |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 531fffd801a3..2ca355e94da6 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | |||
147 | skb->len, DMA_TO_DEVICE); | 147 | skb->len, DMA_TO_DEVICE); |
148 | dev_kfree_skb_any(skb); | 148 | dev_kfree_skb_any(skb); |
149 | bf->bf_buf_addr = 0; | 149 | bf->bf_buf_addr = 0; |
150 | bf->bf_mpdu = NULL; | ||
150 | } | 151 | } |
151 | 152 | ||
152 | skb = ieee80211_beacon_get(hw, vif); | 153 | skb = ieee80211_beacon_get(hw, vif); |
@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
359 | return; | 360 | return; |
360 | 361 | ||
361 | bf = ath9k_beacon_generate(sc->hw, vif); | 362 | bf = ath9k_beacon_generate(sc->hw, vif); |
362 | WARN_ON(!bf); | ||
363 | 363 | ||
364 | if (sc->beacon.bmisscnt != 0) { | 364 | if (sc->beacon.bmisscnt != 0) { |
365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", | 365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 13ff9edc2401..e585fc827c50 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
861 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); | 861 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); |
862 | RXS_ERR("RX-OOM-ERR", rx_oom_err); | 862 | RXS_ERR("RX-OOM-ERR", rx_oom_err); |
863 | RXS_ERR("RX-RATE-ERR", rx_rate_err); | 863 | RXS_ERR("RX-RATE-ERR", rx_rate_err); |
864 | RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush); | ||
865 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); | 864 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); |
866 | 865 | ||
867 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); | 866 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 375c3b46411e..6df2ab62dcb7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -216,7 +216,6 @@ struct ath_tx_stats { | |||
216 | * @rx_oom_err: No. of frames dropped due to OOM issues. | 216 | * @rx_oom_err: No. of frames dropped due to OOM issues. |
217 | * @rx_rate_err: No. of frames dropped due to rate errors. | 217 | * @rx_rate_err: No. of frames dropped due to rate errors. |
218 | * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. | 218 | * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. |
219 | * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH. | ||
220 | * @rx_beacons: No. of beacons received. | 219 | * @rx_beacons: No. of beacons received. |
221 | * @rx_frags: No. of rx-fragements received. | 220 | * @rx_frags: No. of rx-fragements received. |
222 | */ | 221 | */ |
@@ -235,7 +234,6 @@ struct ath_rx_stats { | |||
235 | u32 rx_oom_err; | 234 | u32 rx_oom_err; |
236 | u32 rx_rate_err; | 235 | u32 rx_rate_err; |
237 | u32 rx_too_many_frags_err; | 236 | u32 rx_too_many_frags_err; |
238 | u32 rx_drop_rxflush; | ||
239 | u32 rx_beacons; | 237 | u32 rx_beacons; |
240 | u32 rx_frags; | 238 | u32 rx_frags; |
241 | }; | 239 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 4a9570dfba72..aac4a406a513 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | |||
344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, | 344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, |
345 | skb, htc_hdr->endpoint_id, | 345 | skb, htc_hdr->endpoint_id, |
346 | txok); | 346 | txok); |
347 | } else { | ||
348 | kfree_skb(skb); | ||
347 | } | 349 | } |
348 | } | 350 | } |
349 | 351 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7f1a8e91c908..9d26fc56ca56 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); | |||
1066 | int ar9003_paprd_init_table(struct ath_hw *ah); | 1066 | int ar9003_paprd_init_table(struct ath_hw *ah); |
1067 | bool ar9003_paprd_is_done(struct ath_hw *ah); | 1067 | bool ar9003_paprd_is_done(struct ath_hw *ah); |
1068 | bool ar9003_is_paprd_enabled(struct ath_hw *ah); | 1068 | bool ar9003_is_paprd_enabled(struct ath_hw *ah); |
1069 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | ||
1069 | 1070 | ||
1070 | /* Hardware family op attach helpers */ | 1071 | /* Hardware family op attach helpers */ |
1071 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); | 1072 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index be30a9af1528..dd91f8fdc01c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc) | |||
182 | ath_start_ani(sc); | 182 | ath_start_ani(sc); |
183 | } | 183 | } |
184 | 184 | ||
185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx) |
186 | { | 186 | { |
187 | struct ath_hw *ah = sc->sc_ah; | 187 | struct ath_hw *ah = sc->sc_ah; |
188 | bool ret = true; | 188 | bool ret = true; |
@@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | |||
202 | if (!ath_drain_all_txq(sc, retry_tx)) | 202 | if (!ath_drain_all_txq(sc, retry_tx)) |
203 | ret = false; | 203 | ret = false; |
204 | 204 | ||
205 | if (!flush) { | ||
206 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
207 | ath_rx_tasklet(sc, 1, true); | ||
208 | ath_rx_tasklet(sc, 1, false); | ||
209 | } else { | ||
210 | ath_flushrecv(sc); | ||
211 | } | ||
212 | |||
213 | return ret; | 205 | return ret; |
214 | } | 206 | } |
215 | 207 | ||
@@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
262 | struct ath_common *common = ath9k_hw_common(ah); | 254 | struct ath_common *common = ath9k_hw_common(ah); |
263 | struct ath9k_hw_cal_data *caldata = NULL; | 255 | struct ath9k_hw_cal_data *caldata = NULL; |
264 | bool fastcc = true; | 256 | bool fastcc = true; |
265 | bool flush = false; | ||
266 | int r; | 257 | int r; |
267 | 258 | ||
268 | __ath_cancel_work(sc); | 259 | __ath_cancel_work(sc); |
269 | 260 | ||
261 | tasklet_disable(&sc->intr_tq); | ||
270 | spin_lock_bh(&sc->sc_pcu_lock); | 262 | spin_lock_bh(&sc->sc_pcu_lock); |
271 | 263 | ||
272 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { | 264 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { |
@@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
276 | 268 | ||
277 | if (!hchan) { | 269 | if (!hchan) { |
278 | fastcc = false; | 270 | fastcc = false; |
279 | flush = true; | ||
280 | hchan = ah->curchan; | 271 | hchan = ah->curchan; |
281 | } | 272 | } |
282 | 273 | ||
283 | if (!ath_prepare_reset(sc, retry_tx, flush)) | 274 | if (!ath_prepare_reset(sc, retry_tx)) |
284 | fastcc = false; | 275 | fastcc = false; |
285 | 276 | ||
286 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", | 277 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", |
@@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
302 | 293 | ||
303 | out: | 294 | out: |
304 | spin_unlock_bh(&sc->sc_pcu_lock); | 295 | spin_unlock_bh(&sc->sc_pcu_lock); |
296 | tasklet_enable(&sc->intr_tq); | ||
297 | |||
305 | return r; | 298 | return r; |
306 | } | 299 | } |
307 | 300 | ||
@@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
804 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); | 797 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); |
805 | } | 798 | } |
806 | 799 | ||
807 | ath_prepare_reset(sc, false, true); | 800 | ath_prepare_reset(sc, false); |
808 | 801 | ||
809 | if (sc->rx.frag) { | 802 | if (sc->rx.frag) { |
810 | dev_kfree_skb_any(sc->rx.frag); | 803 | dev_kfree_skb_any(sc->rx.frag); |
@@ -1833,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new) | |||
1833 | 1826 | ||
1834 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) | 1827 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) |
1835 | { | 1828 | { |
1829 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
1830 | return true; | ||
1831 | |||
1836 | switch (val & 0x7) { | 1832 | switch (val & 0x7) { |
1837 | case 0x1: | 1833 | case 0x1: |
1838 | case 0x3: | 1834 | case 0x3: |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index d4df98a938bf..90752f246970 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -254,8 +254,6 @@ rx_init_fail: | |||
254 | 254 | ||
255 | static void ath_edma_start_recv(struct ath_softc *sc) | 255 | static void ath_edma_start_recv(struct ath_softc *sc) |
256 | { | 256 | { |
257 | spin_lock_bh(&sc->rx.rxbuflock); | ||
258 | |||
259 | ath9k_hw_rxena(sc->sc_ah); | 257 | ath9k_hw_rxena(sc->sc_ah); |
260 | 258 | ||
261 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, | 259 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, |
@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc) | |||
267 | ath_opmode_init(sc); | 265 | ath_opmode_init(sc); |
268 | 266 | ||
269 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 267 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
270 | |||
271 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
272 | } | 268 | } |
273 | 269 | ||
274 | static void ath_edma_stop_recv(struct ath_softc *sc) | 270 | static void ath_edma_stop_recv(struct ath_softc *sc) |
@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
285 | int error = 0; | 281 | int error = 0; |
286 | 282 | ||
287 | spin_lock_init(&sc->sc_pcu_lock); | 283 | spin_lock_init(&sc->sc_pcu_lock); |
288 | spin_lock_init(&sc->rx.rxbuflock); | ||
289 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
290 | 284 | ||
291 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | 285 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + |
292 | sc->sc_ah->caps.rx_status_len; | 286 | sc->sc_ah->caps.rx_status_len; |
@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc) | |||
447 | return 0; | 441 | return 0; |
448 | } | 442 | } |
449 | 443 | ||
450 | spin_lock_bh(&sc->rx.rxbuflock); | ||
451 | if (list_empty(&sc->rx.rxbuf)) | 444 | if (list_empty(&sc->rx.rxbuf)) |
452 | goto start_recv; | 445 | goto start_recv; |
453 | 446 | ||
@@ -468,26 +461,31 @@ start_recv: | |||
468 | ath_opmode_init(sc); | 461 | ath_opmode_init(sc); |
469 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 462 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
470 | 463 | ||
471 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
472 | |||
473 | return 0; | 464 | return 0; |
474 | } | 465 | } |
475 | 466 | ||
467 | static void ath_flushrecv(struct ath_softc *sc) | ||
468 | { | ||
469 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
470 | ath_rx_tasklet(sc, 1, true); | ||
471 | ath_rx_tasklet(sc, 1, false); | ||
472 | } | ||
473 | |||
476 | bool ath_stoprecv(struct ath_softc *sc) | 474 | bool ath_stoprecv(struct ath_softc *sc) |
477 | { | 475 | { |
478 | struct ath_hw *ah = sc->sc_ah; | 476 | struct ath_hw *ah = sc->sc_ah; |
479 | bool stopped, reset = false; | 477 | bool stopped, reset = false; |
480 | 478 | ||
481 | spin_lock_bh(&sc->rx.rxbuflock); | ||
482 | ath9k_hw_abortpcurecv(ah); | 479 | ath9k_hw_abortpcurecv(ah); |
483 | ath9k_hw_setrxfilter(ah, 0); | 480 | ath9k_hw_setrxfilter(ah, 0); |
484 | stopped = ath9k_hw_stopdmarecv(ah, &reset); | 481 | stopped = ath9k_hw_stopdmarecv(ah, &reset); |
485 | 482 | ||
483 | ath_flushrecv(sc); | ||
484 | |||
486 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 485 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
487 | ath_edma_stop_recv(sc); | 486 | ath_edma_stop_recv(sc); |
488 | else | 487 | else |
489 | sc->rx.rxlink = NULL; | 488 | sc->rx.rxlink = NULL; |
490 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
491 | 489 | ||
492 | if (!(ah->ah_flags & AH_UNPLUGGED) && | 490 | if (!(ah->ah_flags & AH_UNPLUGGED) && |
493 | unlikely(!stopped)) { | 491 | unlikely(!stopped)) { |
@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
499 | return stopped && !reset; | 497 | return stopped && !reset; |
500 | } | 498 | } |
501 | 499 | ||
502 | void ath_flushrecv(struct ath_softc *sc) | ||
503 | { | ||
504 | set_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
505 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
506 | ath_rx_tasklet(sc, 1, true); | ||
507 | ath_rx_tasklet(sc, 1, false); | ||
508 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
509 | } | ||
510 | |||
511 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | 500 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) |
512 | { | 501 | { |
513 | /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ | 502 | /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ |
@@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
744 | return NULL; | 733 | return NULL; |
745 | } | 734 | } |
746 | 735 | ||
736 | list_del(&bf->list); | ||
747 | if (!bf->bf_mpdu) | 737 | if (!bf->bf_mpdu) |
748 | return bf; | 738 | return bf; |
749 | 739 | ||
@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1059 | dma_type = DMA_FROM_DEVICE; | 1049 | dma_type = DMA_FROM_DEVICE; |
1060 | 1050 | ||
1061 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; | 1051 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; |
1062 | spin_lock_bh(&sc->rx.rxbuflock); | ||
1063 | 1052 | ||
1064 | tsf = ath9k_hw_gettsf64(ah); | 1053 | tsf = ath9k_hw_gettsf64(ah); |
1065 | tsf_lower = tsf & 0xffffffff; | 1054 | tsf_lower = tsf & 0xffffffff; |
1066 | 1055 | ||
1067 | do { | 1056 | do { |
1068 | bool decrypt_error = false; | 1057 | bool decrypt_error = false; |
1069 | /* If handling rx interrupt and flush is in progress => exit */ | ||
1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) | ||
1071 | break; | ||
1072 | 1058 | ||
1073 | memset(&rs, 0, sizeof(rs)); | 1059 | memset(&rs, 0, sizeof(rs)); |
1074 | if (edma) | 1060 | if (edma) |
@@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1111 | 1097 | ||
1112 | ath_debug_stat_rx(sc, &rs); | 1098 | ath_debug_stat_rx(sc, &rs); |
1113 | 1099 | ||
1114 | /* | ||
1115 | * If we're asked to flush receive queue, directly | ||
1116 | * chain it back at the queue without processing it. | ||
1117 | */ | ||
1118 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { | ||
1119 | RX_STAT_INC(rx_drop_rxflush); | ||
1120 | goto requeue_drop_frag; | ||
1121 | } | ||
1122 | |||
1123 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); | 1100 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); |
1124 | 1101 | ||
1125 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1102 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
@@ -1254,19 +1231,18 @@ requeue_drop_frag: | |||
1254 | sc->rx.frag = NULL; | 1231 | sc->rx.frag = NULL; |
1255 | } | 1232 | } |
1256 | requeue: | 1233 | requeue: |
1234 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
1235 | if (flush) | ||
1236 | continue; | ||
1237 | |||
1257 | if (edma) { | 1238 | if (edma) { |
1258 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
1259 | ath_rx_edma_buf_link(sc, qtype); | 1239 | ath_rx_edma_buf_link(sc, qtype); |
1260 | } else { | 1240 | } else { |
1261 | list_move_tail(&bf->list, &sc->rx.rxbuf); | ||
1262 | ath_rx_buf_link(sc, bf); | 1241 | ath_rx_buf_link(sc, bf); |
1263 | if (!flush) | 1242 | ath9k_hw_rxena(ah); |
1264 | ath9k_hw_rxena(ah); | ||
1265 | } | 1243 | } |
1266 | } while (1); | 1244 | } while (1); |
1267 | 1245 | ||
1268 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
1269 | |||
1270 | if (!(ah->imask & ATH9K_INT_RXEOL)) { | 1246 | if (!(ah->imask & ATH9K_INT_RXEOL)) { |
1271 | ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 1247 | ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
1272 | ath9k_hw_set_interrupts(ah); | 1248 | ath9k_hw_set_interrupts(ah); |