|
@@ -727,6 +727,13 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
|
|
|
ret = ath9k_hw_rxprocdesc(ah, tds, &trs);
|
|
|
if (ret == -EINPROGRESS)
|
|
|
return NULL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * mark descriptor as zero-length and set the 'more'
|
|
|
+ * flag to ensure that both buffers get discarded
|
|
|
+ */
|
|
|
+ rs->rs_datalen = 0;
|
|
|
+ rs->rs_more = true;
|
|
|
}
|
|
|
|
|
|
list_del(&bf->list);
|
|
@@ -933,14 +940,20 @@ static void ath9k_process_rssi(struct ath_common *common,
|
|
|
* up the frame up to let mac80211 handle the actual error case, be it no
|
|
|
* decryption key or real decryption error. This let us keep statistics there.
|
|
|
*/
|
|
|
-static int ath9k_rx_skb_preprocess(struct ath_common *common,
|
|
|
- struct ieee80211_hw *hw,
|
|
|
+static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
|
|
|
struct ieee80211_hdr *hdr,
|
|
|
struct ath_rx_status *rx_stats,
|
|
|
struct ieee80211_rx_status *rx_status,
|
|
|
bool *decrypt_error)
|
|
|
{
|
|
|
- struct ath_hw *ah = common->ah;
|
|
|
+ struct ieee80211_hw *hw = sc->hw;
|
|
|
+ struct ath_hw *ah = sc->sc_ah;
|
|
|
+ struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+ bool discard_current = sc->rx.discard_next;
|
|
|
+
|
|
|
+ sc->rx.discard_next = rx_stats->rs_more;
|
|
|
+ if (discard_current)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
/*
|
|
|
* everything but the rate is checked here, the rate check is done
|
|
@@ -966,6 +979,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
|
|
|
if (rx_stats->rs_moreaggr)
|
|
|
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
|
|
|
|
|
+ sc->rx.discard_next = false;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1243,8 +1257,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
|
|
|
- rxs, &decrypt_error);
|
|
|
+ retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs,
|
|
|
+ &decrypt_error);
|
|
|
if (retval)
|
|
|
goto requeue_drop_frag;
|
|
|
|