ath10k: fix RX of frames with broken FCS in monitor mode
authorLinus Lüssing <ll@simonwunderlich.de>
Fri, 15 Nov 2019 10:56:12 +0000 (11:56 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 25 Nov 2019 12:13:25 +0000 (14:13 +0200)
So far, frames were forwarded regardless of the FCS correctness leading
to userspace applications listening on the monitor mode interface to
receive potentially broken frames, even with the "fcsfail" flag unset.

By default, with the "fcsfail" flag of a monitor mode interface
unset, frames with FCS errors should be dropped. With this patch, the
fcsfail flag is taken into account correctly.

Tested-on: QCA4019 firmware-5-ct-full-community-12.bin-lede.011

Cc: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Linus Lüssing <ll@simonwunderlich.de>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/htt_rx.c

index c5407f5080b27519df1a64e72c56412016ed7284..5101bf2b5b158e8e2541eb10f8f47ed8e1d38129 100644 (file)
@@ -1181,6 +1181,7 @@ struct ath10k {
 
        struct {
                /* protected by data_lock */
+               u32 rx_crc_err_drop;
                u32 fw_crash_counter;
                u32 fw_warm_reset_counter;
                u32 fw_cold_reset_counter;
index 04c50a26a4f47fdedf4b6983cbfce7c257460a45..e000677ac516b4f64226092451f6d69fadba26b6 100644 (file)
@@ -1094,6 +1094,7 @@ static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = {
        "d_rts_good",
        "d_tx_power", /* in .5 dbM I think */
        "d_rx_crc_err", /* fcs_bad */
+       "d_rx_crc_err_drop", /* frame with FCS error, dropped late in kernel */
        "d_no_beacon",
        "d_tx_mpdus_queued",
        "d_tx_msdu_queued",
@@ -1193,6 +1194,7 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
        data[i++] = pdev_stats->rts_good;
        data[i++] = pdev_stats->chan_tx_power;
        data[i++] = pdev_stats->fcs_bad;
+       data[i++] = ar->stats.rx_crc_err_drop;
        data[i++] = pdev_stats->no_beacons;
        data[i++] = pdev_stats->mpdu_enqued;
        data[i++] = pdev_stats->msdu_enqued;
index 0f1f71e43b9b5cb0580e7175362c6352d2c026aa..9faecfa5f9d7de3d93c9ca379f99abc159203274 100644 (file)
@@ -1285,6 +1285,13 @@ static void ath10k_process_rx(struct ath10k *ar, struct sk_buff *skb)
 
        status = IEEE80211_SKB_RXCB(skb);
 
+       if (!(ar->filter_flags & FIF_FCSFAIL) &&
+           status->flag & RX_FLAG_FAILED_FCS_CRC) {
+               ar->stats.rx_crc_err_drop++;
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
        ath10k_dbg(ar, ATH10K_DBG_DATA,
                   "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
                   skb,