aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c54
1 files changed, 15 insertions, 39 deletions
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
255static void ath_edma_start_recv(struct ath_softc *sc) 255static 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
274static void ath_edma_stop_recv(struct ath_softc *sc) 270static 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
467static 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
476bool ath_stoprecv(struct ath_softc *sc) 474bool 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
502void 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
511static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) 500static 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 }
1256requeue: 1233requeue:
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);