public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH ath-next 0/4] wifi: ath12k: harden stats/rate handling for WCN785x stability
@ 2026-02-09  3:02 m.limarencko
  2026-02-09  3:02 ` [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found m.limarencko
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: m.limarencko @ 2026-02-09  3:02 UTC (permalink / raw)
  To: jjohnson; +Cc: linux-wireless, ath12k, linux-kernel, Mikhail Limarenko

From: Mikhail Limarenko <m.limarencko@yandex.ru>

Hi Jeff, all,

On QCNFA765/WCN785x (PCI, kernel 6.18.5) we observed three recurring
issues:

- chan info events with frequency not present in local survey range,
  producing invalid idx warnings;
- frequent VDEV_STAT polling can block for 3 seconds on fw_stats_done
  timeouts and cause visible hitches;
- occasional invalid MCS metadata (for example HE MCS=12) propagates
  into mac80211 status handling and correlates with ieee80211_rx_list
  warnings.

This series addresses those cases by:
1. returning -EINVAL from freq_to_idx() when no channel matches, and
   rejecting negative indexes in callers;
2. reducing the wait on VDEV_STAT fw_stats completion and skipping
   unnecessary waits for stats types that do not require it;
3. sanitizing invalid MCS metadata in both dp_rx and dp_mon paths by
   falling back to legacy metadata with ratelimited diagnostics.

Tested on:
- hardware: QCNFA765 (WCN785x)
- kernel: 6.18.5+deb13-amd64
- AP mode: 5 GHz (802.11ac)

Observed after applying this series:
- station dump polling no longer shows multi-second stalls in test runs;
- no fresh ieee80211_rx_list WARN was observed in the same windows.

If patch 1/4 is already present in ath-next or stable trees, please drop
it and keep the remaining fixes.

Thanks,
Mikhail Limarenko

Mikhail Limarenko (4):
  wifi: ath12k: validate survey index when frequency is not found
  wifi: ath12k: avoid long fw_stats waits on vdev stats hot path
  wifi: ath12k: sanitize invalid MCS metadata in rx path
  wifi: ath12k: sanitize invalid MCS metadata in monitor rx path

 drivers/net/wireless/ath/ath12k/dp_mon.c | 38 ++++++++++++++---------
 drivers/net/wireless/ath/ath12k/dp_rx.c  | 39 ++++++++++++++----------
 drivers/net/wireless/ath/ath12k/mac.c    | 22 +++++++++++--
 drivers/net/wireless/ath/ath12k/wmi.c    | 13 ++++----
 4 files changed, 73 insertions(+), 39 deletions(-)

-- 
2.47.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found
  2026-02-09  3:02 [PATCH ath-next 0/4] wifi: ath12k: harden stats/rate handling for WCN785x stability m.limarencko
@ 2026-02-09  3:02 ` m.limarencko
  2026-02-10  3:37   ` Baochen Qiang
  2026-02-09  3:02 ` [PATCH ath-next 2/4] wifi: ath12k: avoid long fw_stats waits on vdev stats hot path m.limarencko
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: m.limarencko @ 2026-02-09  3:02 UTC (permalink / raw)
  To: jjohnson; +Cc: linux-wireless, ath12k, linux-kernel, Mikhail Limarenko

From: Mikhail Limarenko <m.limarencko@yandex.ru>

freq_to_idx() currently returns a monotonic index even when the

frequency was never matched.

In chan info paths this can lead to out-of-bounds survey indexing

for unexpected frequency events.

Return -EINVAL on no match and make callers reject negative

indexes.

Tested-on: QCNFA765 (WCN785x), kernel 6.18.5+deb13-amd64
Signed-off-by: Mikhail Limarenko <m.limarencko@yandex.ru>
---
 drivers/net/wireless/ath/ath12k/wmi.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index e647b84..422e3f8 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -6520,7 +6520,7 @@ static int freq_to_idx(struct ath12k *ar, int freq)
 		if (!sband)
 			continue;
 
-		for (ch = 0; ch < sband->n_channels; ch++, idx++) {
+		for (ch = 0; ch < sband->n_channels; ch++) {
 			if (sband->channels[ch].center_freq <
 			    KHZ_TO_MHZ(ar->freq_range.start_freq) ||
 			    sband->channels[ch].center_freq >
@@ -6528,12 +6528,13 @@ static int freq_to_idx(struct ath12k *ar, int freq)
 				continue;
 
 			if (sband->channels[ch].center_freq == freq)
-				goto exit;
+				return idx;
+
+			idx++;
 		}
 	}
 
-exit:
-	return idx;
+	return -EINVAL;
 }
 
 static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
@@ -7475,7 +7476,7 @@ static void ath12k_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb)
 	}
 
 	idx = freq_to_idx(ar, le32_to_cpu(ch_info_ev.freq));
-	if (idx >= ARRAY_SIZE(ar->survey)) {
+	if (idx < 0 || idx >= ARRAY_SIZE(ar->survey)) {
 		ath12k_warn(ab, "chan info: invalid frequency %d (idx %d out of bounds)\n",
 			    ch_info_ev.freq, idx);
 		goto exit;
@@ -7550,7 +7551,7 @@ ath12k_pdev_bss_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb)
 
 	spin_lock_bh(&ar->data_lock);
 	idx = freq_to_idx(ar, le32_to_cpu(bss_ch_info_ev.freq));
-	if (idx >= ARRAY_SIZE(ar->survey)) {
+	if (idx < 0 || idx >= ARRAY_SIZE(ar->survey)) {
 		ath12k_warn(ab, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
 			    bss_ch_info_ev.freq, idx);
 		goto exit;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH ath-next 2/4] wifi: ath12k: avoid long fw_stats waits on vdev stats hot path
  2026-02-09  3:02 [PATCH ath-next 0/4] wifi: ath12k: harden stats/rate handling for WCN785x stability m.limarencko
  2026-02-09  3:02 ` [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found m.limarencko
@ 2026-02-09  3:02 ` m.limarencko
  2026-02-10  5:31   ` Baochen Qiang
  2026-02-09  3:02 ` [PATCH ath-next 3/4] wifi: ath12k: sanitize invalid MCS metadata in rx path m.limarencko
  2026-02-09  3:02 ` [PATCH ath-next 4/4] wifi: ath12k: sanitize invalid MCS metadata in monitor " m.limarencko
  3 siblings, 1 reply; 8+ messages in thread
From: m.limarencko @ 2026-02-09  3:02 UTC (permalink / raw)
  To: jjohnson; +Cc: linux-wireless, ath12k, linux-kernel, Mikhail Limarenko

From: Mikhail Limarenko <m.limarencko@yandex.ru>

Station info requests can trigger frequent VDEV stat pulls from

user space (iw/NM polling).

On affected firmware, waiting 3 seconds for fw_stats_done causes

repeated stalls and visible hitches.

Use a short timeout for VDEV_STAT requests and skip unnecessary

waits for stats types that do not need completion

synchronization.

Tested-on: QCNFA765 (WCN785x), kernel 6.18.5+deb13-amd64
Signed-off-by: Mikhail Limarenko <m.limarencko@yandex.ru>
---
 drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 095b49a..1b550e9 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -4829,6 +4829,7 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar,
 {
 	struct ath12k_base *ab = ar->ab;
 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
+	unsigned long done_timeout = 3 * HZ;
 	unsigned long time_left;
 	int ret;
 
@@ -4859,15 +4860,32 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar,
 		return -ETIMEDOUT;
 	}
 
+	/* VDEV stats are queried frequently from station info paths (e.g. iw/NM).
+	 * On buggy firmware this path can timeout repeatedly and block callers for
+	 * multiple seconds; keep the hot path responsive while preserving behavior
+	 * for other stats types.
+	 */
+	if (param->stats_id & WMI_REQUEST_VDEV_STAT)
+		done_timeout = msecs_to_jiffies(200);
+
+	/* Non-vdev/bcn stats are handled in a single event. */
+	if (!(param->stats_id & (WMI_REQUEST_VDEV_STAT | WMI_REQUEST_BCN_STAT)))
+		return 0;
+
 	/* Firmware sends WMI_UPDATE_STATS_EVENTID back-to-back
 	 * when stats data buffer limit is reached. fw_stats_complete
 	 * is completed once host receives first event from firmware, but
 	 * still there could be more events following. Below is to wait
 	 * until firmware completes sending all the events.
 	 */
-	time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
+	time_left = wait_for_completion_timeout(&ar->fw_stats_done, done_timeout);
 	if (!time_left) {
-		ath12k_warn(ab, "time out while waiting for fw stats done\n");
+		if (param->stats_id & WMI_REQUEST_VDEV_STAT)
+			ath12k_dbg(ab, ATH12K_DBG_WMI,
+				   "time out while waiting for fw stats done (stats_id 0x%x)\n",
+				   param->stats_id);
+		else
+			ath12k_warn(ab, "time out while waiting for fw stats done\n");
 		return -ETIMEDOUT;
 	}
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH ath-next 3/4] wifi: ath12k: sanitize invalid MCS metadata in rx path
  2026-02-09  3:02 [PATCH ath-next 0/4] wifi: ath12k: harden stats/rate handling for WCN785x stability m.limarencko
  2026-02-09  3:02 ` [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found m.limarencko
  2026-02-09  3:02 ` [PATCH ath-next 2/4] wifi: ath12k: avoid long fw_stats waits on vdev stats hot path m.limarencko
@ 2026-02-09  3:02 ` m.limarencko
  2026-02-09  3:02 ` [PATCH ath-next 4/4] wifi: ath12k: sanitize invalid MCS metadata in monitor " m.limarencko
  3 siblings, 0 replies; 8+ messages in thread
From: m.limarencko @ 2026-02-09  3:02 UTC (permalink / raw)
  To: jjohnson; +Cc: linux-wireless, ath12k, linux-kernel, Mikhail Limarenko

From: Mikhail Limarenko <m.limarencko@yandex.ru>

Malformed or unsupported rate metadata from firmware can carry

invalid MCS values into mac80211 status handling.

This was observed with HE MCS=12 and coincided with

ieee80211_rx_list warnings.

When MCS is out of range, fall back to legacy metadata and use

ratelimited diagnostics.

Tested-on: QCNFA765 (WCN785x), kernel 6.18.5+deb13-amd64
Signed-off-by: Mikhail Limarenko <m.limarencko@yandex.ru>
---
 drivers/net/wireless/ath/ath12k/dp_rx.c | 39 +++++++++++++++----------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 99d29ed..f0c56a9 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2534,9 +2534,11 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_
 	case RX_MSDU_START_PKT_TYPE_11N:
 		rx_status->encoding = RX_ENC_HT;
 		if (rate_mcs > ATH12K_HT_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in HT mode %d\n",
-				     rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid HT mcs %u, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
 		rx_status->rate_idx = rate_mcs + (8 * (nss - 1));
@@ -2546,42 +2548,47 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_
 		break;
 	case RX_MSDU_START_PKT_TYPE_11AC:
 		rx_status->encoding = RX_ENC_VHT;
-		rx_status->rate_idx = rate_mcs;
 		if (rate_mcs > ATH12K_VHT_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in VHT mode %d\n",
-				     rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid VHT mcs %u, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
+		rx_status->rate_idx = rate_mcs;
 		rx_status->nss = nss;
 		if (sgi)
 			rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 		rx_status->bw = ath12k_mac_bw_to_mac80211_bw(bw);
 		break;
 	case RX_MSDU_START_PKT_TYPE_11AX:
-		rx_status->rate_idx = rate_mcs;
 		if (rate_mcs > ATH12K_HE_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in HE mode %d\n",
-				    rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid HE mcs %u, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
 		rx_status->encoding = RX_ENC_HE;
+		rx_status->rate_idx = rate_mcs;
 		rx_status->nss = nss;
 		rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
 		rx_status->bw = ath12k_mac_bw_to_mac80211_bw(bw);
 		break;
 	case RX_MSDU_START_PKT_TYPE_11BE:
-		rx_status->rate_idx = rate_mcs;
-
 		if (rate_mcs > ATH12K_EHT_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in EHT mode %d\n",
-				    rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid EHT mcs %u, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
 
 		rx_status->encoding = RX_ENC_EHT;
+		rx_status->rate_idx = rate_mcs;
 		rx_status->nss = nss;
 		rx_status->eht.gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi);
 		rx_status->bw = ath12k_mac_bw_to_mac80211_bw(bw);
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH ath-next 4/4] wifi: ath12k: sanitize invalid MCS metadata in monitor rx path
  2026-02-09  3:02 [PATCH ath-next 0/4] wifi: ath12k: harden stats/rate handling for WCN785x stability m.limarencko
                   ` (2 preceding siblings ...)
  2026-02-09  3:02 ` [PATCH ath-next 3/4] wifi: ath12k: sanitize invalid MCS metadata in rx path m.limarencko
@ 2026-02-09  3:02 ` m.limarencko
  3 siblings, 0 replies; 8+ messages in thread
From: m.limarencko @ 2026-02-09  3:02 UTC (permalink / raw)
  To: jjohnson; +Cc: linux-wireless, ath12k, linux-kernel, Mikhail Limarenko

From: Mikhail Limarenko <m.limarencko@yandex.ru>

Apply the same invalid-MCS hardening in monitor path status

conversion to keep metadata handling consistent in both data and

monitor pipelines.

Tested-on: QCNFA765 (WCN785x), kernel 6.18.5+deb13-amd64
Signed-off-by: Mikhail Limarenko <m.limarencko@yandex.ru>
---
 drivers/net/wireless/ath/ath12k/dp_mon.c | 38 ++++++++++++++----------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index 009c495..6e894ef 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1922,9 +1922,11 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
 	case RX_MSDU_START_PKT_TYPE_11N:
 		rx_status->encoding = RX_ENC_HT;
 		if (rate_mcs > ATH12K_HT_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in HT mode %d\n",
-				     rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid HT mcs %u in monitor path, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
 		rx_status->rate_idx = rate_mcs + (8 * (nss - 1));
@@ -1933,35 +1935,41 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
 		break;
 	case RX_MSDU_START_PKT_TYPE_11AC:
 		rx_status->encoding = RX_ENC_VHT;
-		rx_status->rate_idx = rate_mcs;
 		if (rate_mcs > ATH12K_VHT_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in VHT mode %d\n",
-				     rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid VHT mcs %u in monitor path, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
+		rx_status->rate_idx = rate_mcs;
 		if (sgi)
 			rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 		break;
 	case RX_MSDU_START_PKT_TYPE_11AX:
-		rx_status->rate_idx = rate_mcs;
 		if (rate_mcs > ATH12K_HE_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in HE mode %d\n",
-				    rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid HE mcs %u in monitor path, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
+		rx_status->rate_idx = rate_mcs;
 		rx_status->encoding = RX_ENC_HE;
 		rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
 		break;
 	case RX_MSDU_START_PKT_TYPE_11BE:
-		rx_status->rate_idx = rate_mcs;
 		if (rate_mcs > ATH12K_EHT_MCS_MAX) {
-			ath12k_warn(ar->ab,
-				    "Received with invalid mcs in EHT mode %d\n",
-				    rate_mcs);
+			dev_warn_ratelimited(ar->ab->dev,
+					     "ath12k: invalid EHT mcs %u in monitor path, forcing legacy rate metadata\n",
+					     rate_mcs);
+			rx_status->encoding = RX_ENC_LEGACY;
+			rx_status->rate_idx = 0;
 			break;
 		}
+		rx_status->rate_idx = rate_mcs;
 		rx_status->encoding = RX_ENC_EHT;
 		rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
 		break;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found
  2026-02-09  3:02 ` [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found m.limarencko
@ 2026-02-10  3:37   ` Baochen Qiang
       [not found]     ` <1277331770898332@mail.yandex.ru>
  0 siblings, 1 reply; 8+ messages in thread
From: Baochen Qiang @ 2026-02-10  3:37 UTC (permalink / raw)
  To: m.limarencko, jjohnson; +Cc: linux-wireless, ath12k, linux-kernel



On 2/9/2026 11:02 AM, m.limarencko@yandex.ru wrote:
> From: Mikhail Limarenko <m.limarencko@yandex.ru>
> 
> freq_to_idx() currently returns a monotonic index even when the
> 
> frequency was never matched.
> 
> In chan info paths this can lead to out-of-bounds survey indexing

how can out-of-bound index happen? there is already the ARRAY_SIZE(ar->survey) check there
to prevent this, no?

> 
> for unexpected frequency events.
> 
> Return -EINVAL on no match and make callers reject negative
> 
> indexes.
> 
> Tested-on: QCNFA765 (WCN785x), kernel 6.18.5+deb13-amd64
> Signed-off-by: Mikhail Limarenko <m.limarencko@yandex.ru>
> ---
>  drivers/net/wireless/ath/ath12k/wmi.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
> index e647b84..422e3f8 100644
> --- a/drivers/net/wireless/ath/ath12k/wmi.c
> +++ b/drivers/net/wireless/ath/ath12k/wmi.c
> @@ -6520,7 +6520,7 @@ static int freq_to_idx(struct ath12k *ar, int freq)
>  		if (!sband)
>  			continue;
>  
> -		for (ch = 0; ch < sband->n_channels; ch++, idx++) {
> +		for (ch = 0; ch < sband->n_channels; ch++) {
>  			if (sband->channels[ch].center_freq <
>  			    KHZ_TO_MHZ(ar->freq_range.start_freq) ||
>  			    sband->channels[ch].center_freq >
> @@ -6528,12 +6528,13 @@ static int freq_to_idx(struct ath12k *ar, int freq)
>  				continue;
>  
>  			if (sband->channels[ch].center_freq == freq)
> -				goto exit;
> +				return idx;
> +
> +			idx++;
>  		}
>  	}
>  
> -exit:
> -	return idx;
> +	return -EINVAL;
>  }
>  
>  static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
> @@ -7475,7 +7476,7 @@ static void ath12k_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb)
>  	}
>  
>  	idx = freq_to_idx(ar, le32_to_cpu(ch_info_ev.freq));
> -	if (idx >= ARRAY_SIZE(ar->survey)) {
> +	if (idx < 0 || idx >= ARRAY_SIZE(ar->survey)) {
>  		ath12k_warn(ab, "chan info: invalid frequency %d (idx %d out of bounds)\n",
>  			    ch_info_ev.freq, idx);
>  		goto exit;
> @@ -7550,7 +7551,7 @@ ath12k_pdev_bss_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb)
>  
>  	spin_lock_bh(&ar->data_lock);
>  	idx = freq_to_idx(ar, le32_to_cpu(bss_ch_info_ev.freq));
> -	if (idx >= ARRAY_SIZE(ar->survey)) {
> +	if (idx < 0 || idx >= ARRAY_SIZE(ar->survey)) {
>  		ath12k_warn(ab, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
>  			    bss_ch_info_ev.freq, idx);
>  		goto exit;


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH ath-next 2/4] wifi: ath12k: avoid long fw_stats waits on vdev stats hot path
  2026-02-09  3:02 ` [PATCH ath-next 2/4] wifi: ath12k: avoid long fw_stats waits on vdev stats hot path m.limarencko
@ 2026-02-10  5:31   ` Baochen Qiang
  0 siblings, 0 replies; 8+ messages in thread
From: Baochen Qiang @ 2026-02-10  5:31 UTC (permalink / raw)
  To: m.limarencko, jjohnson; +Cc: linux-wireless, ath12k, linux-kernel



On 2/9/2026 11:02 AM, m.limarencko@yandex.ru wrote:
> From: Mikhail Limarenko <m.limarencko@yandex.ru>
> 
> Station info requests can trigger frequent VDEV stat pulls from
> 
> user space (iw/NM polling).
> 
> On affected firmware, waiting 3 seconds for fw_stats_done causes
> 
> repeated stalls and visible hitches.
> 
> Use a short timeout for VDEV_STAT requests and skip unnecessary
> 
> waits for stats types that do not need completion
> 
> synchronization.


can you please try

https://lore.kernel.org/ath12k/20260129-ath12k-fw-stats-fixes-v1-0-55d66064f4d5@oss.qualcomm.com/


> 
> Tested-on: QCNFA765 (WCN785x), kernel 6.18.5+deb13-amd64
> Signed-off-by: Mikhail Limarenko <m.limarencko@yandex.ru>
> ---
>  drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 095b49a..1b550e9 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -4829,6 +4829,7 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar,
>  {
>  	struct ath12k_base *ab = ar->ab;
>  	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
> +	unsigned long done_timeout = 3 * HZ;
>  	unsigned long time_left;
>  	int ret;
>  
> @@ -4859,15 +4860,32 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar,
>  		return -ETIMEDOUT;
>  	}
>  
> +	/* VDEV stats are queried frequently from station info paths (e.g. iw/NM).
> +	 * On buggy firmware this path can timeout repeatedly and block callers for
> +	 * multiple seconds; keep the hot path responsive while preserving behavior
> +	 * for other stats types.
> +	 */
> +	if (param->stats_id & WMI_REQUEST_VDEV_STAT)
> +		done_timeout = msecs_to_jiffies(200);
> +
> +	/* Non-vdev/bcn stats are handled in a single event. */
> +	if (!(param->stats_id & (WMI_REQUEST_VDEV_STAT | WMI_REQUEST_BCN_STAT)))
> +		return 0;
> +
>  	/* Firmware sends WMI_UPDATE_STATS_EVENTID back-to-back
>  	 * when stats data buffer limit is reached. fw_stats_complete
>  	 * is completed once host receives first event from firmware, but
>  	 * still there could be more events following. Below is to wait
>  	 * until firmware completes sending all the events.
>  	 */
> -	time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
> +	time_left = wait_for_completion_timeout(&ar->fw_stats_done, done_timeout);
>  	if (!time_left) {
> -		ath12k_warn(ab, "time out while waiting for fw stats done\n");
> +		if (param->stats_id & WMI_REQUEST_VDEV_STAT)
> +			ath12k_dbg(ab, ATH12K_DBG_WMI,
> +				   "time out while waiting for fw stats done (stats_id 0x%x)\n",
> +				   param->stats_id);
> +		else
> +			ath12k_warn(ab, "time out while waiting for fw stats done\n");
>  		return -ETIMEDOUT;
>  	}
>  


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found
       [not found]     ` <1277331770898332@mail.yandex.ru>
@ 2026-02-12 16:47       ` Jeff Johnson
  0 siblings, 0 replies; 8+ messages in thread
From: Jeff Johnson @ 2026-02-12 16:47 UTC (permalink / raw)
  To: Михаил Лимаренко,
	Baochen Qiang, jjohnson@kernel.org
  Cc: linux-wireless@vger.kernel.org, ath12k@lists.infradead.org,
	linux-kernel@vger.kernel.org

On 2/12/2026 4:12 AM, Михаил Лимаренко wrote:
> 
>  Hi Baochen,
> 
>  Thanks for the review, good point.
> 
>  You are right that the current callers already check
>  idx >= ARRAY_SIZE(ar->survey), so a direct OOB write is blocked there.
> 
>  My intent is to make the "frequency not found" case explicit in freq_to_idx(),
>  instead of returning a synthetic index, and have callers reject negative values.
>  I will respin v2 with corrected commit message/subject (no OOB claim).
> 
>  Thanks,
>  Mikhail

https://subspace.kernel.org/etiquette.html

Please don't top post and don't send HTML e-mail.

Note that lore.kernel.org doesn't archive HTML e-mails...
https://lore.kernel.org/all/1277331770898332@mail.yandex.ru/

/jeff

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-02-12 16:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-09  3:02 [PATCH ath-next 0/4] wifi: ath12k: harden stats/rate handling for WCN785x stability m.limarencko
2026-02-09  3:02 ` [PATCH ath-next 1/4] wifi: ath12k: validate survey index when frequency is not found m.limarencko
2026-02-10  3:37   ` Baochen Qiang
     [not found]     ` <1277331770898332@mail.yandex.ru>
2026-02-12 16:47       ` Jeff Johnson
2026-02-09  3:02 ` [PATCH ath-next 2/4] wifi: ath12k: avoid long fw_stats waits on vdev stats hot path m.limarencko
2026-02-10  5:31   ` Baochen Qiang
2026-02-09  3:02 ` [PATCH ath-next 3/4] wifi: ath12k: sanitize invalid MCS metadata in rx path m.limarencko
2026-02-09  3:02 ` [PATCH ath-next 4/4] wifi: ath12k: sanitize invalid MCS metadata in monitor " m.limarencko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox