diff --git a/package/kernel/mac80211/patches/ath11k/949-wifi-ath11k-fix-monitor-rx-pktlen.patch b/package/kernel/mac80211/patches/ath11k/949-wifi-ath11k-fix-monitor-rx-pktlen.patch new file mode 100644 index 0000000000..98d0db137c --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/949-wifi-ath11k-fix-monitor-rx-pktlen.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ruslan Isaev +Date: Sun, 1 Mar 2026 00:00:00 +0000 +Subject: [PATCH] wifi: ath11k: ipq807x; ipq60xx: fix monitor rx frame length (+8 tail) + +OpenWrt issue: +https://github.com/openwrt/openwrt/issues/16183 + +Problem summary: +On qualcommax (ipq60xx/ipq807x) with ath11k, monitor-mode captures contain +frames that are consistently longer than expected by 8 bytes. + +The symptom is visible in pcap/radiotap captures, and Wireshark parsing +becomes correct after manually cutting these 8 bytes from captured frames. + + +This patch: +- Remove merge-stage FCS/tail manipulations in ath11k_dp_rx_mon_merg_msdus(). +- add length fix in ath11k_dp_rx_mon_deliver(), trim 8 bytes right + before radiotap update and delivery to mac80211. + +This targets monitor capture length correctness only and keeps the fix scoped +to the monitor RX delivery path. + +Index: backports-6.18.7/drivers/net/wireless/ath/ath11k/dp_rx.c +=================================================================== +--- backports-6.18.7.orig/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ backports-6.18.7/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -4931,8 +4931,13 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 + } + + prev_buf->next = NULL; ++ /* REMOVED: skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN); ++ * Older code trimmed HAL_RX_FCS_LEN here from prev_buf. ++ * That only affects the last MSDU in the chain. ++ * Length correction is now done in ++ * ath11k_dp_rx_mon_deliver() for every delivered monitor skb. ++ */ + +- skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN); + } else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) { + u8 qos_pkt = 0; + +@@ -4958,10 +4963,13 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 + prev_buf = msdu; + msdu = msdu->next; + } +- dest = skb_put(prev_buf, HAL_RX_FCS_LEN); +- if (!dest) +- goto err_merge_fail; +- ++ /* REMOVED: skb_put(prev_buf, HAL_RX_FCS_LEN) ++ * Older code did skb_put(), effectively ++ * extending the payload tail from merge stage for the last MSDU. ++ * This is removed so merge path does not mutate capture length. ++ * We keep a single length-fix point in monitor deliver path ++ * (trim 8 bytes) right before mac80211 hand-off. ++ */ + ath11k_dbg(ab, ATH11K_DBG_DATA, + "mpdu_buf %p mpdu_buf->len %u", + prev_buf, prev_buf->len); +@@ -5086,12 +5094,27 @@ static int ath11k_dp_rx_mon_deliver(stru + + header = mon_skb; + +- rxs->flag = 0; ++ /* Do not clear rxs->flag here to preserve FCS presence information ++ * set during MSDU merge/trim. ++ */ ++ rxs->flag |= RX_FLAG_ONLY_MONITOR; + + if (fcs_err) +- rxs->flag = RX_FLAG_FAILED_FCS_CRC; ++ rxs->flag |= RX_FLAG_FAILED_FCS_CRC; + + do { ++ /* HW monitor path on ipq60xx/ipq807x may append FCS + 4-byte tail. ++ * Force trim 8 bytes right before delivery to mac80211 so ++ * userspace capture length reflects actual 802.11 frame size. ++ */ ++ if (mon_skb->len > (FCS_LEN * 2)) { ++ u32 old_len = mon_skb->len; ++ ++ skb_trim(mon_skb, old_len - (FCS_LEN * 2)); ++ ath11k_warn(ar->ab, "%s:%d DELIVER trim8 len %u -> %u\n", ++ __func__, __LINE__, old_len, mon_skb->len); ++ } ++ + skb_next = mon_skb->next; + if (!skb_next) + rxs->flag &= ~RX_FLAG_AMSDU_MORE;