aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/rtwn/if_rtwn_rx.c15
1 files changed, 14 insertions, 1 deletions
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;