aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-01-28 13:54:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-01-28 13:54:03 -0500
commit9ebea3829fac7505e0cd2642fbd13cfa9c038831 (patch)
treeed690568a27b7231b8a507e8ba07c1ae34868e5c /drivers/net/wireless/ath/ath9k
parentc5e818ef081c4144177fdbdeed154332cd7e4d7a (diff)
parent83f0c6d1f502bd75bb4a9e31e8d64e59c6894ad1 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/ath/ath9k/main.c drivers/net/wireless/iwlwifi/dvm/tx.c
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c54
12 files changed, 41 insertions, 82 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 5fc15bf8be09..7647ed6b73d7 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -2,6 +2,7 @@ config ATH9K_HW
2 tristate 2 tristate
3config ATH9K_COMMON 3config ATH9K_COMMON
4 tristate 4 tristate
5 select ATH_COMMON
5config ATH9K_DFS_DEBUGFS 6config ATH9K_DFS_DEBUGFS
6 def_bool y 7 def_bool y
7 depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED 8 depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
@@ -17,7 +18,6 @@ config ATH9K_BTCOEX_SUPPORT
17config ATH9K 18config ATH9K
18 tristate "Atheros 802.11n wireless cards support" 19 tristate "Atheros 802.11n wireless cards support"
19 depends on MAC80211 20 depends on MAC80211
20 select ATH_COMMON
21 select ATH9K_HW 21 select ATH9K_HW
22 select MAC80211_LEDS 22 select MAC80211_LEDS
23 select LEDS_CLASS 23 select LEDS_CLASS
@@ -56,7 +56,8 @@ config ATH9K_AHB
56 56
57config ATH9K_DEBUGFS 57config ATH9K_DEBUGFS
58 bool "Atheros ath9k debugging" 58 bool "Atheros ath9k debugging"
59 depends on ATH9K && DEBUG_FS 59 depends on ATH9K
60 select MAC80211_DEBUGFS
60 ---help--- 61 ---help---
61 Say Y, if you need access to ath9k's statistics for 62 Say Y, if you need access to ath9k's statistics for
62 interrupts, rate control, etc. 63 interrupts, rate control, etc.
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 9221f32a322e..4cc13940c895 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1023,6 +1023,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
1023 AR_PHY_AGC_CONTROL_FLTR_CAL | 1023 AR_PHY_AGC_CONTROL_FLTR_CAL |
1024 AR_PHY_AGC_CONTROL_PKDET_CAL; 1024 AR_PHY_AGC_CONTROL_PKDET_CAL;
1025 1025
1026 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1027
1026 if (rtt) { 1028 if (rtt) {
1027 if (!ar9003_hw_rtt_restore(ah, chan)) 1029 if (!ar9003_hw_rtt_restore(ah, chan))
1028 run_rtt_cal = true; 1030 run_rtt_cal = true;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 6fcd6e989c55..a3523c969a3a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -575,7 +575,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
575 ar9340Common_rx_gain_table_1p0); 575 ar9340Common_rx_gain_table_1p0);
576 else if (AR_SREV_9485_11(ah)) 576 else if (AR_SREV_9485_11(ah))
577 INIT_INI_ARRAY(&ah->iniModesRxGain, 577 INIT_INI_ARRAY(&ah->iniModesRxGain,
578 ar9485Common_wo_xlna_rx_gain_1_1); 578 ar9485_common_rx_gain_1_1);
579 else if (AR_SREV_9550(ah)) { 579 else if (AR_SREV_9550(ah)) {
580 INIT_INI_ARRAY(&ah->iniModesRxGain, 580 INIT_INI_ARRAY(&ah->iniModesRxGain,
581 ar955x_1p0_common_rx_gain_table); 581 ar955x_1p0_common_rx_gain_table);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index bf119a5f865a..2bf6548dd143 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -589,32 +589,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
589 ath9k_hw_synth_delay(ah, chan, synthDelay); 589 ath9k_hw_synth_delay(ah, chan, synthDelay);
590} 590}
591 591
592static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) 592void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
593{ 593{
594 switch (rx) { 594 if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
595 case 0x5:
596 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 595 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
597 AR_PHY_SWAP_ALT_CHAIN); 596 AR_PHY_SWAP_ALT_CHAIN);
598 case 0x3: 597
599 case 0x1: 598 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
600 case 0x2: 599 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
601 case 0x7:
602 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
603 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
604 break;
605 default:
606 break;
607 }
608 600
609 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) 601 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
610 REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); 602 tx = 3;
611 else
612 REG_WRITE(ah, AR_SELFGEN_MASK, tx);
613 603
614 if (tx == 0x5) { 604 REG_WRITE(ah, AR_SELFGEN_MASK, tx);
615 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
616 AR_PHY_SWAP_ALT_CHAIN);
617 }
618} 605}
619 606
620/* 607/*
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 885affd28f6e..b2d6c18d1678 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -314,7 +314,6 @@ struct ath_rx {
314 u32 *rxlink; 314 u32 *rxlink;
315 u32 num_pkts; 315 u32 num_pkts;
316 unsigned int rxfilter; 316 unsigned int rxfilter;
317 spinlock_t rxbuflock;
318 struct list_head rxbuf; 317 struct list_head rxbuf;
319 struct ath_descdma rxdma; 318 struct ath_descdma rxdma;
320 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; 319 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
@@ -324,7 +323,6 @@ struct ath_rx {
324 323
325int ath_startrecv(struct ath_softc *sc); 324int ath_startrecv(struct ath_softc *sc);
326bool ath_stoprecv(struct ath_softc *sc); 325bool ath_stoprecv(struct ath_softc *sc);
327void ath_flushrecv(struct ath_softc *sc);
328u32 ath_calcrxfilter(struct ath_softc *sc); 326u32 ath_calcrxfilter(struct ath_softc *sc);
329int ath_rx_init(struct ath_softc *sc, int nbufs); 327int ath_rx_init(struct ath_softc *sc, int nbufs);
330void ath_rx_cleanup(struct ath_softc *sc); 328void ath_rx_cleanup(struct ath_softc *sc);
@@ -640,7 +638,6 @@ void ath_ant_comb_update(struct ath_softc *sc);
640enum sc_op_flags { 638enum sc_op_flags {
641 SC_OP_INVALID, 639 SC_OP_INVALID,
642 SC_OP_BEACONS, 640 SC_OP_BEACONS,
643 SC_OP_RXFLUSH,
644 SC_OP_ANI_RUN, 641 SC_OP_ANI_RUN,
645 SC_OP_PRIM_STA_VIF, 642 SC_OP_PRIM_STA_VIF,
646 SC_OP_HW_RESET, 643 SC_OP_HW_RESET,
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index a129f83806f3..dd3771954bd7 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 75b504ba3b3f..6c5d313ebcb7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -862,7 +862,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
862 RXS_ERR("RX-LENGTH-ERR", rx_len_err); 862 RXS_ERR("RX-LENGTH-ERR", rx_len_err);
863 RXS_ERR("RX-OOM-ERR", rx_oom_err); 863 RXS_ERR("RX-OOM-ERR", rx_oom_err);
864 RXS_ERR("RX-RATE-ERR", rx_rate_err); 864 RXS_ERR("RX-RATE-ERR", rx_rate_err);
865 RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
866 RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); 865 RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
867 866
868 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); 867 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 b19bed7f74c2..a22c0d780700 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -217,7 +217,6 @@ struct ath_tx_stats {
217 * @rx_oom_err: No. of frames dropped due to OOM issues. 217 * @rx_oom_err: No. of frames dropped due to OOM issues.
218 * @rx_rate_err: No. of frames dropped due to rate errors. 218 * @rx_rate_err: No. of frames dropped due to rate errors.
219 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. 219 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
220 * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
221 * @rx_beacons: No. of beacons received. 220 * @rx_beacons: No. of beacons received.
222 * @rx_frags: No. of rx-fragements received. 221 * @rx_frags: No. of rx-fragements received.
223 */ 222 */
@@ -236,7 +235,6 @@ struct ath_rx_stats {
236 u32 rx_oom_err; 235 u32 rx_oom_err;
237 u32 rx_rate_err; 236 u32 rx_rate_err;
238 u32 rx_too_many_frags_err; 237 u32 rx_too_many_frags_err;
239 u32 rx_drop_rxflush;
240 u32 rx_beacons; 238 u32 rx_beacons;
241 u32 rx_frags; 239 u32 rx_frags;
242}; 240};
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 0a3a1af007f7..784e81ccb903 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1096,6 +1096,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
1096int ar9003_paprd_init_table(struct ath_hw *ah); 1096int ar9003_paprd_init_table(struct ath_hw *ah);
1097bool ar9003_paprd_is_done(struct ath_hw *ah); 1097bool ar9003_paprd_is_done(struct ath_hw *ah);
1098bool ar9003_is_paprd_enabled(struct ath_hw *ah); 1098bool ar9003_is_paprd_enabled(struct ath_hw *ah);
1099void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
1099 1100
1100/* Hardware family op attach helpers */ 1101/* Hardware family op attach helpers */
1101int ar5008_hw_attach_phy_ops(struct ath_hw *ah); 1102int 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 3e5082c5f5f0..4b72b660f180 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
185static bool ath_prepare_reset(struct ath_softc *sc, bool flush) 185static bool ath_prepare_reset(struct ath_softc *sc)
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 flush)
202 if (!ath_stoprecv(sc)) 202 if (!ath_stoprecv(sc))
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
@@ -261,11 +253,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
261 struct ath_common *common = ath9k_hw_common(ah); 253 struct ath_common *common = ath9k_hw_common(ah);
262 struct ath9k_hw_cal_data *caldata = NULL; 254 struct ath9k_hw_cal_data *caldata = NULL;
263 bool fastcc = true; 255 bool fastcc = true;
264 bool flush = false;
265 int r; 256 int r;
266 257
267 __ath_cancel_work(sc); 258 __ath_cancel_work(sc);
268 259
260 tasklet_disable(&sc->intr_tq);
269 spin_lock_bh(&sc->sc_pcu_lock); 261 spin_lock_bh(&sc->sc_pcu_lock);
270 262
271 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { 263 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
@@ -275,11 +267,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
275 267
276 if (!hchan) { 268 if (!hchan) {
277 fastcc = false; 269 fastcc = false;
278 flush = true;
279 hchan = ah->curchan; 270 hchan = ah->curchan;
280 } 271 }
281 272
282 if (!ath_prepare_reset(sc, flush)) 273 if (!ath_prepare_reset(sc))
283 fastcc = false; 274 fastcc = false;
284 275
285 ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", 276 ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
@@ -301,6 +292,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
301 292
302out: 293out:
303 spin_unlock_bh(&sc->sc_pcu_lock); 294 spin_unlock_bh(&sc->sc_pcu_lock);
295 tasklet_enable(&sc->intr_tq);
296
304 return r; 297 return r;
305} 298}
306 299
@@ -801,7 +794,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
801 ath9k_hw_cfg_gpio_input(ah, ah->led_pin); 794 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
802 } 795 }
803 796
804 ath_prepare_reset(sc, true); 797 ath_prepare_reset(sc);
805 798
806 if (sc->rx.frag) { 799 if (sc->rx.frag) {
807 dev_kfree_skb_any(sc->rx.frag); 800 dev_kfree_skb_any(sc->rx.frag);
@@ -1917,6 +1910,9 @@ static u32 fill_chainmask(u32 cap, u32 new)
1917 1910
1918static bool validate_antenna_mask(struct ath_hw *ah, u32 val) 1911static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
1919{ 1912{
1913 if (AR_SREV_9300_20_OR_LATER(ah))
1914 return true;
1915
1920 switch (val & 0x7) { 1916 switch (val & 0x7) {
1921 case 0x1: 1917 case 0x1:
1922 case 0x3: 1918 case 0x3:
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 45f2d475ac1a..d7c129bb571b 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -249,8 +249,6 @@ rx_init_fail:
249 249
250static void ath_edma_start_recv(struct ath_softc *sc) 250static void ath_edma_start_recv(struct ath_softc *sc)
251{ 251{
252 spin_lock_bh(&sc->rx.rxbuflock);
253
254 ath9k_hw_rxena(sc->sc_ah); 252 ath9k_hw_rxena(sc->sc_ah);
255 253
256 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, 254 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
@@ -262,8 +260,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
262 ath_opmode_init(sc); 260 ath_opmode_init(sc);
263 261
264 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 262 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
265
266 spin_unlock_bh(&sc->rx.rxbuflock);
267} 263}
268 264
269static void ath_edma_stop_recv(struct ath_softc *sc) 265static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -280,8 +276,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
280 int error = 0; 276 int error = 0;
281 277
282 spin_lock_init(&sc->sc_pcu_lock); 278 spin_lock_init(&sc->sc_pcu_lock);
283 spin_lock_init(&sc->rx.rxbuflock);
284 clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
285 279
286 common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + 280 common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
287 sc->sc_ah->caps.rx_status_len; 281 sc->sc_ah->caps.rx_status_len;
@@ -439,7 +433,6 @@ int ath_startrecv(struct ath_softc *sc)
439 return 0; 433 return 0;
440 } 434 }
441 435
442 spin_lock_bh(&sc->rx.rxbuflock);
443 if (list_empty(&sc->rx.rxbuf)) 436 if (list_empty(&sc->rx.rxbuf))
444 goto start_recv; 437 goto start_recv;
445 438
@@ -460,26 +453,31 @@ start_recv:
460 ath_opmode_init(sc); 453 ath_opmode_init(sc);
461 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 454 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
462 455
463 spin_unlock_bh(&sc->rx.rxbuflock);
464
465 return 0; 456 return 0;
466} 457}
467 458
459static void ath_flushrecv(struct ath_softc *sc)
460{
461 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
462 ath_rx_tasklet(sc, 1, true);
463 ath_rx_tasklet(sc, 1, false);
464}
465
468bool ath_stoprecv(struct ath_softc *sc) 466bool ath_stoprecv(struct ath_softc *sc)
469{ 467{
470 struct ath_hw *ah = sc->sc_ah; 468 struct ath_hw *ah = sc->sc_ah;
471 bool stopped, reset = false; 469 bool stopped, reset = false;
472 470
473 spin_lock_bh(&sc->rx.rxbuflock);
474 ath9k_hw_abortpcurecv(ah); 471 ath9k_hw_abortpcurecv(ah);
475 ath9k_hw_setrxfilter(ah, 0); 472 ath9k_hw_setrxfilter(ah, 0);
476 stopped = ath9k_hw_stopdmarecv(ah, &reset); 473 stopped = ath9k_hw_stopdmarecv(ah, &reset);
477 474
475 ath_flushrecv(sc);
476
478 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 477 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
479 ath_edma_stop_recv(sc); 478 ath_edma_stop_recv(sc);
480 else 479 else
481 sc->rx.rxlink = NULL; 480 sc->rx.rxlink = NULL;
482 spin_unlock_bh(&sc->rx.rxbuflock);
483 481
484 if (!(ah->ah_flags & AH_UNPLUGGED) && 482 if (!(ah->ah_flags & AH_UNPLUGGED) &&
485 unlikely(!stopped)) { 483 unlikely(!stopped)) {
@@ -491,15 +489,6 @@ bool ath_stoprecv(struct ath_softc *sc)
491 return stopped && !reset; 489 return stopped && !reset;
492} 490}
493 491
494void ath_flushrecv(struct ath_softc *sc)
495{
496 set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
497 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
498 ath_rx_tasklet(sc, 1, true);
499 ath_rx_tasklet(sc, 1, false);
500 clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
501}
502
503static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) 492static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
504{ 493{
505 /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ 494 /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
@@ -736,6 +725,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
736 return NULL; 725 return NULL;
737 } 726 }
738 727
728 list_del(&bf->list);
739 if (!bf->bf_mpdu) 729 if (!bf->bf_mpdu)
740 return bf; 730 return bf;
741 731
@@ -1153,16 +1143,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1153 dma_type = DMA_FROM_DEVICE; 1143 dma_type = DMA_FROM_DEVICE;
1154 1144
1155 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; 1145 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
1156 spin_lock_bh(&sc->rx.rxbuflock);
1157 1146
1158 tsf = ath9k_hw_gettsf64(ah); 1147 tsf = ath9k_hw_gettsf64(ah);
1159 tsf_lower = tsf & 0xffffffff; 1148 tsf_lower = tsf & 0xffffffff;
1160 1149
1161 do { 1150 do {
1162 bool decrypt_error = false; 1151 bool decrypt_error = false;
1163 /* If handling rx interrupt and flush is in progress => exit */
1164 if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
1165 break;
1166 1152
1167 memset(&rs, 0, sizeof(rs)); 1153 memset(&rs, 0, sizeof(rs));
1168 if (edma) 1154 if (edma)
@@ -1205,15 +1191,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1205 1191
1206 ath_debug_stat_rx(sc, &rs); 1192 ath_debug_stat_rx(sc, &rs);
1207 1193
1208 /*
1209 * If we're asked to flush receive queue, directly
1210 * chain it back at the queue without processing it.
1211 */
1212 if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
1213 RX_STAT_INC(rx_drop_rxflush);
1214 goto requeue_drop_frag;
1215 }
1216
1217 memset(rxs, 0, sizeof(struct ieee80211_rx_status)); 1194 memset(rxs, 0, sizeof(struct ieee80211_rx_status));
1218 1195
1219 rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; 1196 rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
@@ -1351,19 +1328,18 @@ requeue_drop_frag:
1351 sc->rx.frag = NULL; 1328 sc->rx.frag = NULL;
1352 } 1329 }
1353requeue: 1330requeue:
1331 list_add_tail(&bf->list, &sc->rx.rxbuf);
1332 if (flush)
1333 continue;
1334
1354 if (edma) { 1335 if (edma) {
1355 list_add_tail(&bf->list, &sc->rx.rxbuf);
1356 ath_rx_edma_buf_link(sc, qtype); 1336 ath_rx_edma_buf_link(sc, qtype);
1357 } else { 1337 } else {
1358 list_move_tail(&bf->list, &sc->rx.rxbuf);
1359 ath_rx_buf_link(sc, bf); 1338 ath_rx_buf_link(sc, bf);
1360 if (!flush) 1339 ath9k_hw_rxena(ah);
1361 ath9k_hw_rxena(ah);
1362 } 1340 }
1363 } while (1); 1341 } while (1);
1364 1342
1365 spin_unlock_bh(&sc->rx.rxbuflock);
1366
1367 if (!(ah->imask & ATH9K_INT_RXEOL)) { 1343 if (!(ah->imask & ATH9K_INT_RXEOL)) {
1368 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); 1344 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
1369 ath9k_hw_set_interrupts(ah); 1345 ath9k_hw_set_interrupts(ah);