git: d76247e801de - main - rtwn: enable FCS in the recive config to work around truncated frames

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Thu, 05 Dec 2024 07:30:15 UTC
The branch main has been updated by adrian:

URL: https://cgit.FreeBSD.org/src/commit/?id=d76247e801dec95600a068fa1bb09f4f57e00031

commit d76247e801dec95600a068fa1bb09f4f57e00031
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2024-11-27 00:59:15 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2024-12-05 07:27:03 +0000

    rtwn: enable FCS in the recive config to work around truncated frames
    
    I noticed that on RTL8812AU/RTL8821AU receiving VHT frames that
    I'd occasionally see frames missing the last 4 bytes.  I can
    easily reproduce it with a ping sweep and fast (10ms) between frames.
    
    There's also a report of an earlier NIC (RTL8188EU) doing the same
    thing with HT frames but not with OFDM (11g) frames.
    
    After a bunch of poking, it turns out a driver where things DID work
    properly for the other report kept FCS enabled, and trimmed it from
    the frame before pushing it up to the network layer.
    
    I did the same and it also worked fine.
    
    The other solution was to disable PHYSTATUS notifications, but then
    we'd get no per packet RX notifications (RX rate, RSSI, etc.)
    
    Locally tested:
    
    * RTL8192EU, STA mode (HT)
    * RTL8812AU, STA mode (HT, VHT)
    * RTL8821AU, STA mode (HT, VHT)
    
    Differential Revision:  https://reviews.freebsd.org/D47775
---
 sys/dev/rtwn/if_rtwn_rx.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/sys/dev/rtwn/if_rtwn_rx.c b/sys/dev/rtwn/if_rtwn_rx.c
index 762472eca440..ebfb8e67ec6d 100644
--- a/sys/dev/rtwn/if_rtwn_rx.c
+++ b/sys/dev/rtwn/if_rtwn_rx.c
@@ -318,6 +318,10 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
 	/* Drop PHY descriptor. */
 	m_adj(m, infosz + shift);
 
+	/* If APPFCS, drop FCS */
+	if (sc->rcr & R92C_RCR_APPFCS)
+		m_adj(m, -IEEE80211_CRC_LEN);
+
 	return (ni);
 }
 
@@ -456,6 +460,15 @@ rtwn_rxfilter_init(struct rtwn_softc *sc)
 	    R92C_RCR_HTC_LOC_CTRL | R92C_RCR_APP_PHYSTS |
 	    R92C_RCR_APP_ICV | R92C_RCR_APP_MIC;
 
+	/*
+	 * Add FCS, to work around occasional 4 byte truncation
+	 * with some frames.  This is more problematic on RTL8812/
+	 * RTL8821 because they're also doing L3/L4 checksum offload
+	 * and hardware encryption, so both are tagged as "passed"
+	 * before the frame is truncated.
+	 */
+	sc->rcr |= R92C_RCR_APPFCS;
+
 	/* Update dynamic Rx filter parts. */
 	rtwn_rxfilter_update(sc);
 }
@@ -487,7 +500,7 @@ rtwn_set_promisc(struct rtwn_softc *sc)
 	RTWN_ASSERT_LOCKED(sc);
 
 	mask_all = R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | R92C_RCR_AAP;
-	mask_min = R92C_RCR_APM;
+	mask_min = R92C_RCR_APM | R92C_RCR_APPFCS;
 
 	if (sc->bcn_vaps == 0)
 		mask_min |= R92C_RCR_CBSSID_BCN;