]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
qualcommax: ipq807x: ipq6018: ath11k: fix monitor rx length 22244/head
authorRuslan Isaev <legale.legale@gmail.com>
Sat, 28 Feb 2026 15:59:38 +0000 (18:59 +0300)
committerRobert Marko <robimarko@gmail.com>
Thu, 5 Mar 2026 09:50:21 +0000 (10:50 +0100)
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.

Tested-on: ipq8072 yuncore,ax880; ipq6018 yuncore,ax840; yuncore,fap650
Signed-off-by: Ruslan Isaev <legale.legale@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22244
Signed-off-by: Robert Marko <robimarko@gmail.com>
package/kernel/mac80211/patches/ath11k/949-wifi-ath11k-fix-monitor-rx-pktlen.patch [new file with mode: 0644]

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 (file)
index 0000000..98d0db1
--- /dev/null
@@ -0,0 +1,91 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Ruslan Isaev <legale.legale@gmail.com>
+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;