The AR9271 firmware reports a frame that failed its CRC as a CRC error even when the PHY error bit is set too, so spectral samples received under interference reach the host as CRC errors, and the host passes only PHY errors to the FFT parser. ath9k reordered the same check in commit 3a325565c7fa ("ath9k: reorder error codes for spectral"); the firmware never followed. While a scan is active, also pass a CRC error frame of FFT report size to the parser, with the PHY error code it expects. The parser rejects a frame without the spectral bit in its trailer. A monitor interface with FIF_FCSFAIL no longer sees those frames. Fixes: 83fb287ecd8a ("ath9k_htc: process rx spectral packets") Assisted-by: LLM Signed-off-by: Nerijus Bendžiūnas --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index bed7ea2425a0..23d1ef2407a4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -969,6 +969,25 @@ static void rx_status_htc_to_ath(struct ath_rx_status *rx_stats, convert_htc_flag(rx_stats, rxstatus); } +static bool ath9k_htc_is_spectral_sample_len(struct ath9k_htc_priv *priv, + u16 len) +{ + enum nl80211_channel_type chan_type; + u16 fft_len; + + if (priv->spec_priv.spectral_mode == SPECTRAL_DISABLED) + return false; + + chan_type = cfg80211_get_chandef_type(&priv->hw->conf.chandef); + if (chan_type == NL80211_CHAN_HT40MINUS || + chan_type == NL80211_CHAN_HT40PLUS) + fft_len = SPECTRAL_HT20_40_TOTAL_DATA_LEN; + else + fft_len = SPECTRAL_HT20_TOTAL_DATA_LEN; + + return len >= fft_len - 1 && len <= fft_len + 2; +} + static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, struct ath9k_htc_rxbuf *rxbuf, struct ieee80211_rx_status *rx_status) @@ -1052,6 +1071,16 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, goto rx_next; } + if (unlikely(rx_stats.rs_status & ATH9K_RXERR_CRC) && + ath9k_htc_is_spectral_sample_len(priv, rs_datalen)) { + struct ath_rx_status sample_rs = rx_stats; + + sample_rs.rs_phyerr = ATH9K_PHYERR_RADAR; + if (ath_cmn_process_fft(&priv->spec_priv, hdr, &sample_rs, + rx_status->mactime)) + goto rx_next; + } + if (!ath9k_cmn_rx_accept(common, hdr, rx_status, &rx_stats, &decrypt_error, priv->rxfilter)) goto rx_next; -- 2.55.0