aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch')
-rw-r--r--package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch104
1 files changed, 104 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch b/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch
new file mode 100644
index 0000000000..5bbf9e04a4
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch
@@ -0,0 +1,104 @@
+From a06bfb3c9f69f303692cdae87bc0899d2ae8b2a6 Mon Sep 17 00:00:00 2001
+From: Harshitha Prem <quic_hprem@quicinc.com>
+Date: Tue, 4 Apr 2023 00:11:54 +0530
+Subject: [PATCH] wifi: ath11k: Ignore frags from uninitialized peer in dp.
+
+When max virtual ap interfaces are configured in all the bands with
+ACS and hostapd restart is done every 60s, a crash is observed at
+random times.
+In this certain scenario, a fragmented packet is received for
+self peer, for which rx_tid and rx_frags are not initialized in
+datapath. While handling this fragment, crash is observed as the
+rx_frag list is uninitialised and when we walk in
+ath11k_dp_rx_h_sort_frags, skb null leads to exception.
+
+To address this, before processing received fragments we check
+dp_setup_done flag is set to ensure that peer has completed its
+dp peer setup for fragment queue, else ignore processing the
+fragments.
+
+Call trace:
+ ath11k_dp_process_rx_err+0x550/0x1084 [ath11k]
+ ath11k_dp_service_srng+0x70/0x370 [ath11k]
+ 0xffffffc009693a04
+ __napi_poll+0x30/0xa4
+ net_rx_action+0x118/0x270
+ __do_softirq+0x10c/0x244
+ irq_exit+0x64/0xb4
+ __handle_domain_irq+0x88/0xac
+ gic_handle_irq+0x74/0xbc
+ el1_irq+0xf0/0x1c0
+ arch_cpu_idle+0x10/0x18
+ do_idle+0x104/0x248
+ cpu_startup_entry+0x20/0x64
+ rest_init+0xd0/0xdc
+ arch_call_rest_init+0xc/0x14
+ start_kernel+0x480/0x4b8
+ Code: f9400281 f94066a2 91405021 b94a0023 (f9406401)
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Harshitha Prem <quic_hprem@quicinc.com>
+Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230403184155.8670-2-quic_nmaran@quicinc.com
+---
+ drivers/net/wireless/ath/ath11k/dp.c | 4 +++-
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++++++++
+ drivers/net/wireless/ath/ath11k/peer.h | 1 +
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath11k/dp.c
++++ b/drivers/net/wireless/ath/ath11k/dp.c
+@@ -36,6 +36,7 @@ void ath11k_dp_peer_cleanup(struct ath11
+ }
+
+ ath11k_peer_rx_tid_cleanup(ar, peer);
++ peer->dp_setup_done = false;
+ crypto_free_shash(peer->tfm_mmic);
+ spin_unlock_bh(&ab->base_lock);
+ }
+@@ -72,7 +73,8 @@ int ath11k_dp_peer_setup(struct ath11k *
+ ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
+ if (ret) {
+ ath11k_warn(ab, "failed to setup rx defrag context\n");
+- return ret;
++ tid--;
++ goto peer_clean;
+ }
+
+ /* TODO: Setup other peer specific resource used in data path */
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -3130,6 +3130,7 @@ int ath11k_peer_rx_frag_setup(struct ath
+ }
+
+ peer->tfm_mmic = tfm;
++ peer->dp_setup_done = true;
+ spin_unlock_bh(&ab->base_lock);
+
+ return 0;
+@@ -3575,6 +3576,13 @@ static int ath11k_dp_rx_frag_h_mpdu(stru
+ ret = -ENOENT;
+ goto out_unlock;
+ }
++ if (!peer->dp_setup_done) {
++ ath11k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
++ peer->addr, peer_id);
++ ret = -ENOENT;
++ goto out_unlock;
++ }
++
+ rx_tid = &peer->rx_tid[tid];
+
+ if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
+--- a/drivers/net/wireless/ath/ath11k/peer.h
++++ b/drivers/net/wireless/ath/ath11k/peer.h
+@@ -35,6 +35,7 @@ struct ath11k_peer {
+ u16 sec_type;
+ u16 sec_type_grp;
+ bool is_authorized;
++ bool dp_setup_done;
+ };
+
+ void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);