|
@@ -254,8 +254,6 @@ rx_init_fail:
|
|
|
|
|
|
static void ath_edma_start_recv(struct ath_softc *sc)
|
|
|
{
|
|
|
- spin_lock_bh(&sc->rx.rxbuflock);
|
|
|
-
|
|
|
ath9k_hw_rxena(sc->sc_ah);
|
|
|
|
|
|
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
|
|
@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
|
|
|
ath_opmode_init(sc);
|
|
|
|
|
|
ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
|
|
|
-
|
|
|
- spin_unlock_bh(&sc->rx.rxbuflock);
|
|
|
}
|
|
|
|
|
|
static void ath_edma_stop_recv(struct ath_softc *sc)
|
|
@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
|
|
int error = 0;
|
|
|
|
|
|
spin_lock_init(&sc->sc_pcu_lock);
|
|
|
- spin_lock_init(&sc->rx.rxbuflock);
|
|
|
- clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
|
|
|
|
|
common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
|
|
|
sc->sc_ah->caps.rx_status_len;
|
|
@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- spin_lock_bh(&sc->rx.rxbuflock);
|
|
|
if (list_empty(&sc->rx.rxbuf))
|
|
|
goto start_recv;
|
|
|
|
|
@@ -468,26 +461,31 @@ start_recv:
|
|
|
ath_opmode_init(sc);
|
|
|
ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
|
|
|
|
|
|
- spin_unlock_bh(&sc->rx.rxbuflock);
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void ath_flushrecv(struct ath_softc *sc)
|
|
|
+{
|
|
|
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
|
|
+ ath_rx_tasklet(sc, 1, true);
|
|
|
+ ath_rx_tasklet(sc, 1, false);
|
|
|
+}
|
|
|
+
|
|
|
bool ath_stoprecv(struct ath_softc *sc)
|
|
|
{
|
|
|
struct ath_hw *ah = sc->sc_ah;
|
|
|
bool stopped, reset = false;
|
|
|
|
|
|
- spin_lock_bh(&sc->rx.rxbuflock);
|
|
|
ath9k_hw_abortpcurecv(ah);
|
|
|
ath9k_hw_setrxfilter(ah, 0);
|
|
|
stopped = ath9k_hw_stopdmarecv(ah, &reset);
|
|
|
|
|
|
+ ath_flushrecv(sc);
|
|
|
+
|
|
|
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
|
|
ath_edma_stop_recv(sc);
|
|
|
else
|
|
|
sc->rx.rxlink = NULL;
|
|
|
- spin_unlock_bh(&sc->rx.rxbuflock);
|
|
|
|
|
|
if (!(ah->ah_flags & AH_UNPLUGGED) &&
|
|
|
unlikely(!stopped)) {
|
|
@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
|
|
|
return stopped && !reset;
|
|
|
}
|
|
|
|
|
|
-void ath_flushrecv(struct ath_softc *sc)
|
|
|
-{
|
|
|
- set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
|
|
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
|
|
- ath_rx_tasklet(sc, 1, true);
|
|
|
- ath_rx_tasklet(sc, 1, false);
|
|
|
- clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
|
|
-}
|
|
|
-
|
|
|
static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
|
|
|
{
|
|
|
/* 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,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ list_del(&bf->list);
|
|
|
if (!bf->bf_mpdu)
|
|
|
return bf;
|
|
|
|
|
@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
|
|
dma_type = DMA_FROM_DEVICE;
|
|
|
|
|
|
qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
|
|
|
- spin_lock_bh(&sc->rx.rxbuflock);
|
|
|
|
|
|
tsf = ath9k_hw_gettsf64(ah);
|
|
|
tsf_lower = tsf & 0xffffffff;
|
|
|
|
|
|
do {
|
|
|
bool decrypt_error = false;
|
|
|
- /* If handling rx interrupt and flush is in progress => exit */
|
|
|
- if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
|
|
|
- break;
|
|
|
|
|
|
memset(&rs, 0, sizeof(rs));
|
|
|
if (edma)
|
|
@@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
|
|
|
|
|
ath_debug_stat_rx(sc, &rs);
|
|
|
|
|
|
- /*
|
|
|
- * If we're asked to flush receive queue, directly
|
|
|
- * chain it back at the queue without processing it.
|
|
|
- */
|
|
|
- if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
|
|
|
- RX_STAT_INC(rx_drop_rxflush);
|
|
|
- goto requeue_drop_frag;
|
|
|
- }
|
|
|
-
|
|
|
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
|
|
|
|
|
|
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
|
|
@@ -1254,19 +1231,18 @@ requeue_drop_frag:
|
|
|
sc->rx.frag = NULL;
|
|
|
}
|
|
|
requeue:
|
|
|
+ list_add_tail(&bf->list, &sc->rx.rxbuf);
|
|
|
+ if (flush)
|
|
|
+ continue;
|
|
|
+
|
|
|
if (edma) {
|
|
|
- list_add_tail(&bf->list, &sc->rx.rxbuf);
|
|
|
ath_rx_edma_buf_link(sc, qtype);
|
|
|
} else {
|
|
|
- list_move_tail(&bf->list, &sc->rx.rxbuf);
|
|
|
ath_rx_buf_link(sc, bf);
|
|
|
- if (!flush)
|
|
|
- ath9k_hw_rxena(ah);
|
|
|
+ ath9k_hw_rxena(ah);
|
|
|
}
|
|
|
} while (1);
|
|
|
|
|
|
- spin_unlock_bh(&sc->rx.rxbuflock);
|
|
|
-
|
|
|
if (!(ah->imask & ATH9K_INT_RXEOL)) {
|
|
|
ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
|
|
ath9k_hw_set_interrupts(ah);
|