* [PATCH] rfkill: repair malformed kernel-doc and add some descriptions
From: Randy Dunlap @ 2026-07-23 16:27 UTC (permalink / raw)
To: linux-wireless; +Cc: Randy Dunlap, Johannes Berg
Use kernel-doc format for function descriptions and add the missing
function parameter descriptions to avoid kernel-doc warnings:
Warning: ../include/linux/rfkill.h:102 This comment starts with '/**',
but isn't a kernel-doc comment.
* rfkill_pause_polling(struct rfkill *rfkill)
Warning: include/linux/rfkill.h:109 function parameter 'rfkill' not
described in 'rfkill_pause_polling'
Warning: ../include/linux/rfkill.h:112 This comment starts with '/**',
but isn't a kernel-doc comment.
* rfkill_resume_polling(struct rfkill *rfkill)
Warning: include/linux/rfkill.h:117 function parameter 'rfkill' not
described in 'rfkill_resume_polling'
Warning: ../include/linux/rfkill.h:330 function parameter 'rfkill' not
described in 'rfkill_get_led_trigger_name'
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
---
Cc: Johannes Berg <johannes@sipsolutions.net>
include/linux/rfkill.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- linux-next-20260722.orig/include/linux/rfkill.h
+++ linux-next-20260722/include/linux/rfkill.h
@@ -100,7 +100,8 @@ struct rfkill * __must_check rfkill_allo
int __must_check rfkill_register(struct rfkill *rfkill);
/**
- * rfkill_pause_polling(struct rfkill *rfkill)
+ * rfkill_pause_polling - Pause polling
+ * @rfkill: rfkill struct
*
* Pause polling -- say transmitter is off for other reasons.
* NOTE: not necessary for suspend/resume -- in that case the
@@ -110,9 +111,9 @@ int __must_check rfkill_register(struct
void rfkill_pause_polling(struct rfkill *rfkill);
/**
- * rfkill_resume_polling(struct rfkill *rfkill)
+ * rfkill_resume_polling - Resume polling
+ * @rfkill: rfkill struct
*
- * Resume polling
* NOTE: not necessary for suspend/resume -- in that case the
* core stops polling anyway
*/
@@ -325,6 +326,8 @@ static inline enum rfkill_type rfkill_fi
#ifdef CONFIG_RFKILL_LEDS
/**
* rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED.
+ * @rfkill: rfkill struct
+ *
* This function might return a NULL pointer if registering of the
* LED trigger failed. Use this as "default_trigger" for the LED.
*/
^ permalink raw reply
* Re: [PATCH ath-current v2 1/8] wifi: ath12k: fix out-of-bounds clear_bit in ath12k_mac_dp_peer_cleanup()
From: Jeff Johnson @ 2026-07-23 15:50 UTC (permalink / raw)
To: Baochen Qiang, Jeff Johnson; +Cc: linux-wireless, ath12k
In-Reply-To: <21084de4-cdf5-4a99-9e0c-da4db067e4f9@oss.qualcomm.com>
On 7/23/2026 8:45 AM, Jeff Johnson wrote:
>> + clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map);
>> + ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID;
>
> so this now matches the code at the end of ath12k_mac_ml_station_remove() and
> in the cleanup section of ath12k_mac_op_sta_state(), so perhaps that should be
> refactored into a helper function in the future
which I now see in patch 3/8 :)
^ permalink raw reply
* Re: [PATCH ath-current v2 1/8] wifi: ath12k: fix out-of-bounds clear_bit in ath12k_mac_dp_peer_cleanup()
From: Jeff Johnson @ 2026-07-23 15:45 UTC (permalink / raw)
To: Baochen Qiang, Jeff Johnson; +Cc: linux-wireless, ath12k
In-Reply-To: <20260720-ath12k-fw-allocated-ml-peer-id-v2-1-630632758a80@oss.qualcomm.com>
On 7/19/2026 11:43 PM, Baochen Qiang wrote:
> ath12k_mac_dp_peer_cleanup() clears the ML peer ID slot on the
> free_ml_peer_id_map bitmap by indexing it with dp_peer->peer_id. That is
> wrong: dp_peer->peer_id for an MLO peer always carries the
> ATH12K_PEER_ML_ID_VALID bit (BIT(13)), so clear_bit() is invoked with
> index >= 0x2000, which is far outside the bitmap of ATH12K_MAX_MLO_PEERS
> (256) bits and corrupts memory adjacent to ah->free_ml_peer_id_map. The
> intended bitmap entry also never gets cleared, so subsequent
> ath12k_peer_ml_alloc() calls eventually run out of IDs.
>
> The ID without the VALID bit is what ath12k_peer_ml_alloc() returned and
> is stored in ahsta->ml_peer_id. Use that instead.
>
> While there, also reset ahsta->ml_peer_id to ATH12K_MLO_PEER_ID_INVALID so
> the bitmap and ahsta->ml_peer_id stay in sync;
nit s/;/./
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
>
> Fixes: ee16dcf573d5 ("wifi: ath12k: Define ath12k_dp_peer structure & APIs for create & delete")
> Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
> ---
> drivers/net/wireless/ath/ath12k/mac.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 490c134c1f29..b7eba8ea981b 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -1283,8 +1283,11 @@ void ath12k_mac_dp_peer_cleanup(struct ath12k_hw *ah)
> spin_lock_bh(&dp_hw->peer_lock);
> list_for_each_entry_safe(dp_peer, tmp, &dp_hw->dp_peers_list, list) {
> if (dp_peer->is_mlo) {
> + struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(dp_peer->sta);
> +
> rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], NULL);
> - clear_bit(dp_peer->peer_id, ah->free_ml_peer_id_map);
> + clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map);
> + ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID;
so this now matches the code at the end of ath12k_mac_ml_station_remove() and
in the cleanup section of ath12k_mac_op_sta_state(), so perhaps that should be
refactored into a helper function in the future
> }
>
> list_move(&dp_peer->list, &peers);
>
^ permalink raw reply
* Re: [PATCH wireless-next] wifi: mwifiex: Use flexible array for RX reorder table
From: Francesco Dolcini @ 2026-07-23 14:55 UTC (permalink / raw)
To: Johannes Berg
Cc: Rosen Penev, linux-wireless, Brian Norris, Francesco Dolcini,
Kees Cook, Gustavo A. R. Silva, open list,
open list:KERNEL HARDENING (not covered by other areas):Keyword:\b__counted_by(_le|_be|_ptr)?\b
In-Reply-To: <1e77da9180ee82bf1b0d122f0ddf137949d4278e.camel@sipsolutions.net>
Hello Johannes,
On Tue, May 19, 2026 at 08:47:00AM +0200, Johannes Berg wrote:
> On Mon, 2026-05-18 at 14:18 -0700, Rosen Penev wrote:
> > Embed the RX reorder pointer array in struct mwifiex_rx_reorder_tbl
> > instead of allocating it separately.
>
> Others might disagree, but personally, I think you should stop doing
> this. Sure, it *might* (I've been bitten too much by __counted_by) be a
> border-line improvement, but it's not _really_ all that useful,
> especially on these older drivers.
>
> Did you even test it at all?
>
...
> If you _really_ want to help, please help review changes rather than
> producing more noise. Maybe even take over maintenance of some specific
> driver that you can test.
I also do not see any specific reason to take this, as of now I have not
enough brain cycles available to properly review this, and if this is
not even tested we should just reject it.
Francesco
^ permalink raw reply
* Re: [PATCH v2] wifi: mwifiex: validate HT/VHT capability and operation IE lengths
From: Francesco Dolcini @ 2026-07-23 14:51 UTC (permalink / raw)
To: Doruk Tan Ozturk
Cc: briannorris, francesco, kees, linux-wireless, linux-kernel,
stable
In-Reply-To: <20260715185543.14478-1-doruk@0sec.ai>
On Wed, Jul 15, 2026 at 08:55:43PM +0200, Doruk Tan Ozturk wrote:
> mwifiex_update_bss_desc_with_ie() records raw pointers to the HT
> Capabilities, HT Operation, VHT Capabilities, VHT Operation, 20/40 BSS
> Coexistence and Operating Mode Notification elements taken straight out
> of a beacon/probe-response buffer, without checking that each element is
> long enough for the fixed-size structure that later consumers read. The
> buffer is a tight kmemdup() of the on-air IEs (beacon_buf_size ==
> ies->len), so a truncated element placed last leaves the stored pointer
> one past the end of the allocation.
>
> At association time these pointers are dereferenced at fixed offsets
> regardless of the on-air length: mwifiex_cmd_append_11n_tlv() memcpy()s
> sizeof(struct ieee80211_ht_cap) (26 bytes) from bcn_ht_cap and reads
> bcn_ht_oper->ht_param, and mwifiex_cmd_append_11ac_tlv() memcpy()s
> sizeof(struct ieee80211_vht_cap) (12 bytes) from bcn_vht_cap and reads
> bcn_vht_oper->chan_width. A nearby AP (rogue / evil-twin; an open SSID
> needs no credentials) advertising a BSS with a truncated HT/VHT cap
> element therefore triggers a slab out-of-bounds read on the victim's
> association attempt. This out-of-bounds read is the primary issue.
>
> For the HT-Cap copy the over-read bytes are additionally placed into the
> outgoing association request, so a limited amount of adjacent heap memory
> can leak over the air. In station mode this is small (single-digit
> bytes), because mwifiex_fill_cap_info() rewrites most of the copied
> HT-Cap before transmission; the leak is a secondary effect.
>
> mwifiex_set_sta_ht_cap() has the same missing-length pattern: in uAP mode
> it reads two bytes of ieee80211_ht_cap.cap_info from a
> cfg80211_find_ie(WLAN_EID_HT_CAPABILITY) result in a client association
> request without checking the element length, a 1-2 byte out-of-bounds
> read (used only to select an A-MSDU size, not leaked).
>
> Reject the frame with -EINVAL when any of these elements is shorter than
> the structure the driver later reads, matching the length validation the
> FH/DS/CF/IBSS parameter-set cases in the same beacon parser already
> perform. mwifiex_set_sta_ht_cap() returns void, so there the too-short
> element is skipped instead.
>
> Found by 0sec automated security-research tooling (https://0sec.ai).
>
> Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
> Cc: stable@vger.kernel.org
> Assisted-by: 0sec:multi-model
> Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
> ---
...
> diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
> index 7d3631d21223..844223c04e2e 100644
> --- a/drivers/net/wireless/marvell/mwifiex/util.c
> +++ b/drivers/net/wireless/marvell/mwifiex/util.c
> @@ -721,7 +721,7 @@ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
>
> ht_cap_ie = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies,
> ies_len);
> - if (ht_cap_ie) {
> + if (ht_cap_ie && ht_cap_ie->len >= sizeof(struct ieee80211_ht_cap)) {
> ht_cap = (void *)(ht_cap_ie + 1);
> node->is_11n_enabled = 1;
> node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
Can we trust ht_cap_ie->len here? Who is writing this field?
Francesco
^ permalink raw reply
* Re: [PATCH v2] wifi: mwifiex: validate action frame fixed fields
From: Francesco Dolcini @ 2026-07-23 14:41 UTC (permalink / raw)
To: Zhao Li
Cc: linux-wireless, linux-kernel, johannes, briannorris, francesco,
stable
In-Reply-To: <20260723011013.76968-1-enderaoelyther@gmail.com>
On Thu, Jul 23, 2026 at 09:10:13AM +0800, Zhao Li wrote:
> mwifiex_process_mgmt_packet() accepts an rx_pkt_length as small as a
> four-address struct ieee80211_hdr plus the two-byte firmware length prefix.
> After stripping the prefix, mwifiex_parse_mgmt_packet() can receive a
> buffer equal to sizeof(struct ieee80211_hdr).
>
> For action frames, the parser reads the category immediately after that
> header and, for a public action frame, reads the following action code
> without verifying that either field is present. A minimal frame therefore
> reads one or two bytes beyond the RX buffer.
>
> Validate the header and require the category and public action-code fields
> before reading them. mwifiex parses the firmware four-address layout before
> removing addr4, so add ETH_ALEN to the standard
> IEEE80211_MIN_ACTION_SIZE() offsets.
>
> Suggested-by: Johannes Berg <johannes@sipsolutions.net>
> Fixes: 72e5aa8d2a6d ("mwifiex: support for parsing TDLS discovery frames")
> Cc: stable@vger.kernel.org
> Link: https://lore.kernel.org/all/66f148d83eb9f0970b9abbccc85d1b61244e54ad.camel@sipsolutions.net/
> Link: https://lore.kernel.org/all/20260708195911.84365-8-enderaoelyther@gmail.com/
> Assisted-by: Codex:gpt-5
> Assisted-by: Claude:opus-4.8
> Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
> ---
> Changes in v2:
> - Add a local header check and express the action field sizes with
> IEEE80211_MIN_ACTION_SIZE(), accounting for the firmware layout.
>
> drivers/net/wireless/marvell/mwifiex/util.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
> index 7d3631d212236..4043590137391 100644
> --- a/drivers/net/wireless/marvell/mwifiex/util.c
> +++ b/drivers/net/wireless/marvell/mwifiex/util.c
> @@ -313,13 +313,22 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
> u8 category, action_code, *addr2;
> struct ieee80211_hdr *ieee_hdr = (void *)payload;
>
> + if (len < sizeof(*ieee_hdr))
> + return -1;
> +
I am confused, why is this check needed here, and not done in
mwifiex_process_mgmt_packet()?
^ permalink raw reply
* Re: [PATCH v3] wifi: mwifiex: validate event lengths before copying bodies
From: Francesco Dolcini @ 2026-07-23 14:31 UTC (permalink / raw)
To: Pengpeng Hou, Jeff Chen
Cc: Brian Norris, Francesco Dolcini, linux-wireless, linux-kernel
In-Reply-To: <amHdiy0tuh55F0ug@nxpwireless-Inspiron-14-Plus-7440>
On Thu, Jul 23, 2026 at 05:23:23PM +0800, Jeff Chen wrote:
> On Thu, Jul 23, 2026 at 10:40:05 AM +0800, Pengpeng Hou wrote:
> > mwifiex event packets contain a four-byte event cause followed by the
> > event body. The USB and SDIO paths copy from data after that header using
> > the full packet length, so the source range extends four bytes beyond the
> > skb. The SDIO path also reads the event cause before validating the
> > packet and publishes oversized events without a copied body.
> >
> > Reject SDIO events that are shorter than the header or larger than the
> > event buffer limit. Discard them through the same free-and-break contract
> > used for unknown upload types. Retain USB's existing error path and copy
> > only the bytes after the event header in both paths.
> >
> > Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> > ---
> > Changes since v2: https://lore.kernel.org/all/20260720115119.80059-1-pengpeng@iscas.ac.cn/
> > - replace the new SDIO return -1 with free plus break as requested
> > - preserve USB's established error return contract
> > - rebase onto the current wireless tree
> >
> > diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
> > index f039d6f19183..3588c36f64cf 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/sdio.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
> > @@ -1712,12 +1712,19 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
> > case MWIFIEX_TYPE_EVENT:
> > mwifiex_dbg(adapter, EVENT,
> > "info: --- Rx: Event ---\n");
> > + if (skb->len < MWIFIEX_EVENT_HEADER_LEN ||
> > + skb->len > MAX_EVENT_SIZE) {
> > + mwifiex_dbg(adapter, ERROR,
> > + "EVENT: invalid skb->len %u\n", skb->len);
> > + dev_kfree_skb_any(skb);
> > + break;
> > + }
>
> skb->len includes the 4-byte header, so the body size is
> skb->len - MWIFIEX_EVENT_HEADER_LEN. The upper bound should be:
> skb->len - MWIFIEX_EVENT_HEADER_LEN > MAX_EVENT_SIZE
>
> Otherwise packets with a full MAX_EVENT_SIZE body are incorrectly
> rejected.
Agree.
Please send a v4 With that fixed, and with that feel free to add
Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
^ permalink raw reply
* [PATCH v2] wifi: cfg80211: change mesh_setup::ie_len to size_t
From: Srinivas Achary @ 2026-07-23 13:45 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel, ramakrishnan, Srinivas Achary
The ie_len field in struct mesh_setup stores the length of the
information elements (IEs) buffer. It is currently defined as u8,
which limits the maximum supported length to 255 bytes.
The IE length is derived from memory buffers whose size is naturally
represented by size_t. Using u8 may truncate larger values and can
result in incorrect length handling.
Change ie_len to size_t so it can represent the full buffer length and
match the type commonly used for memory sizes throughout the kernel.
Signed-off-by: Ramakrishnan Rathinasamy <ramakrishnan@aerlync.com>
Signed-off-by: Srinivas Achary <srinivas@aerlync.com>
---
Changes in v2:
- Add the "wifi: cfg80211:" subsystem prefix.
- Replace the non-standard Co-authored-by trailer with Signed-off-by.
include/net/cfg80211.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f5abf1db7558..c9af5abdec1f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2803,7 +2803,7 @@ struct mesh_setup {
u8 path_metric;
u8 auth_id;
const u8 *ie;
- u8 ie_len;
+ size_t ie_len;
bool is_authenticated;
bool is_secure;
bool user_mpm;
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 8/8] wifi: ath12k: add WBM SW desc fallback counter
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Aniruddha Mishra, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com>
When HW CC is not done, the WBM RX error path falls back to
cookie-based descriptor retrieval via ath12k_dp_get_rx_desc(). This
fallback path is taken before knowing whether the retrieval will
succeed, so it is not a drop event and should not be counted in the
drop[] array.
Add a dedicated sw_desc_fallback counter in
ath12k_device_dp_rx_wbm_err_stats to track how often the HW CC
fallback path is taken, distinct from actual packet drops. Expose
the counter in the device_dp_stats debugfs file as a separate line.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/debugfs.c | 4 ++++
drivers/net/wireless/ath/ath12k/dp.h | 1 +
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 1 +
3 files changed, 6 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index 4176c837a6ef..534e7d13e66b 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1122,6 +1122,10 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "%s: %u\n",
wbm_rx_drop[i], device_stats->wbm_err.drop[i]);
+ len += scnprintf(buf + len, size - len,
+ "\nWBM SW desc fallback (HW CC not done): %u\n",
+ device_stats->wbm_err.sw_desc_fallback);
+
len += scnprintf(buf + len, size - len, "\nREO sent to stack\n");
for (i = 0; i < DP_REO_DST_RING_MAX; i++)
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 298b65142a0e..af176ee7d89f 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -441,6 +441,7 @@ struct ath12k_device_dp_rx_wbm_err_stats {
u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
u32 drop[WBM_ERR_DROP_MAX];
+ u32 sw_desc_fallback;
};
struct ath12k_device_dp_stats {
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index 33c4c89eefb5..9b6d04783c6b 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -1968,6 +1968,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
/* retry manual desc retrieval if hw cc is not done */
if (!desc_info) {
+ dp->device_stats.wbm_err.sw_desc_fallback++;
desc_info = ath12k_dp_get_rx_desc(dp, err_info.cookie);
if (!desc_info) {
dp->device_stats.wbm_err.drop[WBM_ERR_GET_SW_DESC]++;
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 7/8] wifi: ath12k: fix 1-based ring index in REO Rx Received debugfs output
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
The REO Rx Received section in device_dp_stats debugfs uses a 1-based
ring index ("Ring1:", "Ring2:", ...) which is inconsistent with the rest
of ath12k where rings are indexed from 0. Fix it to use 0-based indexing
and lowercase "ring%d:" to match the style used by all other ring counters
in the same function.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Fixes: 84873d542e95 ("wifi: ath12k: print device dp stats in debugfs")
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/debugfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index 9a8d07bfb848..4176c837a6ef 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1210,7 +1210,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n");
for (i = 0; i < DP_REO_DST_RING_MAX; i++) {
- len += scnprintf(buf + len, size - len, "Ring%d:", i + 1);
+ len += scnprintf(buf + len, size - len, "ring%d:", i);
for (j = 0; j < ab->ag->num_devices; j++) {
len += scnprintf(buf + len, size - len,
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 6/8] wifi: ath12k: track per-ring RX sent-to-stack count
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
The device DP stats provide visibility into RX errors and drops but
lack a counter for successfully delivered packets. Without this, it is
difficult to correlate REO ring activity with actual stack delivery
during debugging or performance analysis.
Add sent_to_stack[DP_REO_DST_RING_MAX] to ath12k_device_dp_stats to
track successful deliveries per REO ring. A per-device dimension is not
needed because partner_dp is already resolved at the increment point,
so the counter is incremented directly in partner_dp->device_stats,
attributing it to the correct device without an extra index.
Increment the counter just before each MSDU is handed off to the stack
via ath12k_dp_rx_deliver_msdu(). Add a likely()/WARN_ON_ONCE() bounds
check on ring_id before indexing sent_to_stack[], consistent with all
other new stat arrays in this series.
Expose the per-ring counts in the device_dp_stats debugfs file under a
new 'REO sent to stack' section.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/debugfs.c | 5 +++++
drivers/net/wireless/ath/ath12k/dp.h | 1 +
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 5 ++++-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index 5020d9608535..9a8d07bfb848 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1122,6 +1122,11 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "%s: %u\n",
wbm_rx_drop[i], device_stats->wbm_err.drop[i]);
+ len += scnprintf(buf + len, size - len, "\nREO sent to stack\n");
+ for (i = 0; i < DP_REO_DST_RING_MAX; i++)
+ len += scnprintf(buf + len, size - len, "ring%d: %u\n",
+ i, device_stats->sent_to_stack[i]);
+
len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
for (i = 0; i < DP_REO_DST_RING_MAX; i++)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 563aa24ea55a..298b65142a0e 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -457,6 +457,7 @@ struct ath12k_device_dp_stats {
u32 tx_enqueued[DP_TCL_NUM_RING_MAX];
u32 tx_completed[DP_TCL_NUM_RING_MAX];
u32 reo_excep_msdu_buf_type;
+ u32 sent_to_stack[DP_REO_DST_RING_MAX];
};
struct ath12k_dp {
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index b203513d63cc..33c4c89eefb5 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -651,7 +651,10 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp,
dev_kfree_skb_any(msdu);
continue;
}
-
+ if (likely(ring_id < DP_REO_DST_RING_MAX))
+ partner_dp->device_stats.sent_to_stack[ring_id]++;
+ else
+ WARN_ON_ONCE(1);
ath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, &rx_info);
}
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 5/8] wifi: ath12k: add WBM RX error drop statistics
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Aniruddha Mishra, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com>
Without fine-grained drop counters, diagnosing RX failures in the
WBM error path requires intrusive debugging. Introduce per-drop-reason
counters to track exactly where and why packets are dropped during
WBM RX error handling.
Introduce a new dp_stats.h header and define ath12k_wbm_err_drop_reason
enum there covering all drop points in the WBM RX error path: descriptor
parse failures, SW descriptor retrieval errors, null partner DP,
invalid HW link ID, null pdev/ar, CAC running, scatter-gather drops,
and invalid NWifi header length. The new header is included by dp.h
which is already included by all consumers.
Add ath12k_device_dp_rx_wbm_err_stats struct grouping rxdma_error[],
reo_error[], and the new drop[] counters, replacing the flat arrays
previously in ath12k_device_dp_stats.
Add bounds checks before indexing rxdma_error[] and reo_error[] with
hardware-supplied err_code values to prevent out-of-bounds writes, using
the same likely/WARN_ON_ONCE pattern as the TX stats bounds fixes.
Add ath12k_wifi7_dp_rx_wbm_err_free_skb() helper to combine drop stat
increment and skb free at each drop site, reducing repetition. Define
the helper at the top of dp_rx.c before its first use.
Increment WBM_ERR_DROP_RXDMA_GENERIC only inside rxdma_err()'s
default: branch so it counts only unhandled RXDMA errors, not every
RXDMA drop - consistent with how WBM_ERR_DROP_REO_GENERIC is counted.
Expose WBM RX drop counts in the device_dp_stats debugfs file under a
new 'WBM Rx Drop Count' section.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/debugfs.c | 23 +++++++++-
drivers/net/wireless/ath/ath12k/dp.h | 10 +++-
drivers/net/wireless/ath/ath12k/dp_stats.h | 25 ++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 46 +++++++++++++++----
.../net/wireless/ath/ath12k/wifi7/hal_rx.c | 5 +-
5 files changed, 95 insertions(+), 14 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/dp_stats.h
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index e9eaa23ee63e..5020d9608535 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1071,6 +1071,20 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
[HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err",
[HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"};
+ static const char *wbm_rx_drop[WBM_ERR_DROP_MAX] = {
+ [WBM_ERR_GET_SW_DESC] = "SW desc error",
+ [WBM_ERR_DESC_PARSE] = "Desc parse error",
+ [WBM_ERR_DROP_INV_HW_ID] = "Invalid hw id",
+ [WBM_ERR_DROP_NULL_PRTNR_DP] = "Null Partner dp",
+ [WBM_ERR_DROP_NULL_PROC_DP] = "Process Null Partner dp",
+ [WBM_ERR_DROP_NULL_PDEV] = "Null Pdev",
+ [WBM_ERR_DROP_NULL_AR] = "Null ar",
+ [WBM_ERR_DROP_CAC_RUNNING] = "CAC Running",
+ [WBM_ERR_DROP_SG] = "Scatter Gather",
+ [WBM_ERR_DROP_INV_NWIFI_HDR] = "Invalid NWifi Hdr len",
+ [WBM_ERR_DROP_REO_GENERIC] = "REO Generic",
+ [WBM_ERR_DROP_RXDMA_GENERIC] = "RXDMA Generic"};
+
static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = {
[HAL_WBM_REL_SRC_MODULE_TQM] = "TQM",
[HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma",
@@ -1095,13 +1109,18 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
len += scnprintf(buf + len, size - len, "%s: %u\n",
- rxdma_err[i], device_stats->rxdma_error[i]);
+ rxdma_err[i], device_stats->wbm_err.rxdma_error[i]);
len += scnprintf(buf + len, size - len, "\nREO errors:\n");
for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
len += scnprintf(buf + len, size - len, "%s: %u\n",
- reo_err[i], device_stats->reo_error[i]);
+ reo_err[i], device_stats->wbm_err.reo_error[i]);
+
+ len += scnprintf(buf + len, size - len, "\nWBM Rx Drop Count:\n");
+ for (i = 0; i < WBM_ERR_DROP_MAX; i++)
+ len += scnprintf(buf + len, size - len, "%s: %u\n",
+ wbm_rx_drop[i], device_stats->wbm_err.drop[i]);
len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index ac125adde258..563aa24ea55a 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -7,6 +7,7 @@
#ifndef ATH12K_DP_H
#define ATH12K_DP_H
+#include "dp_stats.h"
#include "hw.h"
#include "dp_htt.h"
#include "dp_cmn.h"
@@ -436,13 +437,18 @@ struct ath12k_device_dp_tx_err_stats {
atomic_t misc_fail;
};
+struct ath12k_device_dp_rx_wbm_err_stats {
+ u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
+ u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
+ u32 drop[WBM_ERR_DROP_MAX];
+};
+
struct ath12k_device_dp_stats {
u32 err_ring_pkts;
u32 invalid_rbm;
- u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
- u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
u32 hal_reo_error[DP_REO_DST_RING_MAX];
struct ath12k_device_dp_tx_err_stats tx_err;
+ struct ath12k_device_dp_rx_wbm_err_stats wbm_err;
u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES];
u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES];
u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON];
diff --git a/drivers/net/wireless/ath/ath12k/dp_stats.h b/drivers/net/wireless/ath/ath12k/dp_stats.h
new file mode 100644
index 000000000000..04d3892acff3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/dp_stats.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef ATH12K_DP_STATS_H
+#define ATH12K_DP_STATS_H
+
+enum ath12k_wbm_err_drop_reason {
+ WBM_ERR_GET_SW_DESC,
+ WBM_ERR_DESC_PARSE,
+ WBM_ERR_DROP_INV_HW_ID,
+ WBM_ERR_DROP_NULL_PRTNR_DP,
+ WBM_ERR_DROP_NULL_PROC_DP,
+ WBM_ERR_DROP_NULL_PDEV,
+ WBM_ERR_DROP_NULL_AR,
+ WBM_ERR_DROP_CAC_RUNNING,
+ WBM_ERR_DROP_SG,
+ WBM_ERR_DROP_INV_NWIFI_HDR,
+ WBM_ERR_DROP_REO_GENERIC,
+ WBM_ERR_DROP_RXDMA_GENERIC,
+ WBM_ERR_DROP_MAX,
+};
+
+#endif /* ATH12K_DP_STATS_H */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index 95d87dd67872..b203513d63cc 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -12,6 +12,15 @@
#include "hal_wcn7850.h"
#include "hal_qcc2072.h"
+static void
+ath12k_wifi7_dp_rx_wbm_err_free_skb(struct ath12k_dp *dp,
+ struct sk_buff *msdu,
+ enum ath12k_wbm_err_drop_reason drop_reason)
+{
+ dp->device_stats.wbm_err.drop[drop_reason]++;
+ dev_kfree_skb_any(msdu);
+}
+
static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp,
enum ath12k_peer_metadata_version ver,
__le32 peer_metadata)
@@ -1614,6 +1623,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev,
/* First buffer will be freed by the caller, so deduct it's length */
msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz);
ath12k_wifi7_dp_rx_null_q_desc_sg_drop(dp, msdu_len, msdu_list);
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_SG]++;
return -EINVAL;
}
@@ -1649,8 +1659,10 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev,
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
}
- if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu, rx_info)))
+ if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu, rx_info))) {
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_INV_NWIFI_HDR]++;
return -EINVAL;
+ }
ath12k_dp_rx_h_ppdu(dp_pdev, rx_info);
ret = ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, rx_info);
@@ -1763,7 +1775,10 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
bool drop = false;
- dp->device_stats.rxdma_error[rxcb->err_code]++;
+ if (likely(rxcb->err_code < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX))
+ dp->device_stats.wbm_err.rxdma_error[rxcb->err_code]++;
+ else
+ WARN_ON_ONCE(1);
switch (rxcb->err_code) {
case HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR:
@@ -1780,6 +1795,7 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,
/* TODO: Review other rxdma error code to check if anything is
* worth reporting to mac80211
*/
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_RXDMA_GENERIC]++;
drop = true;
break;
}
@@ -1796,7 +1812,10 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev,
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
bool drop = false;
- dp->device_stats.reo_error[rxcb->err_code]++;
+ if (likely(rxcb->err_code < HAL_REO_DEST_RING_ERROR_CODE_MAX))
+ dp->device_stats.wbm_err.reo_error[rxcb->err_code]++;
+ else
+ WARN_ON_ONCE(1);
switch (rxcb->err_code) {
case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
@@ -1813,6 +1832,7 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev,
/* TODO: Review other errors and process them to mac80211
* as appropriate.
*/
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_REO_GENERIC]++;
drop = true;
break;
}
@@ -1935,6 +1955,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
ret = ath12k_wifi7_hal_wbm_desc_parse_err(dp, rx_desc,
&err_info);
if (ret) {
+ dp->device_stats.wbm_err.drop[WBM_ERR_DESC_PARSE]++;
ath12k_warn(ab, "failed to parse rx error in wbm_rel ring desc %d\n",
ret);
continue;
@@ -1946,6 +1967,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
if (!desc_info) {
desc_info = ath12k_dp_get_rx_desc(dp, err_info.cookie);
if (!desc_info) {
+ dp->device_stats.wbm_err.drop[WBM_ERR_GET_SW_DESC]++;
ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n",
err_info.cookie);
continue;
@@ -1961,7 +1983,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
device_id = desc_info->device_id;
partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);
if (unlikely(!partner_dp)) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_PRTNR_DP);
/* In any case continuation bit is set
* in the previous record, cleanup scatter_msdu_list
@@ -2007,7 +2030,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->hal,
msdu_data);
if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_INV_HW_ID);
/* In any case continuation bit is set
* in the previous record, cleanup scatter_msdu_list
@@ -2068,7 +2092,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
ath12k_dbg(ab, ATH12K_DBG_DATA,
"Unable to process WBM error msdu due to invalid hw link id %d device id %d\n",
hw_link_id, device_id);
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_PROC_DP);
continue;
}
@@ -2077,18 +2102,21 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
dp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx);
if (!dp_pdev) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_PDEV);
continue;
}
ar = ath12k_pdev_dp_to_ar(dp_pdev);
if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_idx])) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_AR);
continue;
}
if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_CAC_RUNNING);
continue;
}
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
index 49c693289709..60e7a36097f1 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
@@ -329,7 +329,10 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp,
HAL_REO_DEST_RING_INFO0_PUSH_REASON);
err_code = le32_get_bits(desc->info0,
HAL_REO_DEST_RING_INFO0_ERROR_CODE);
- dp->device_stats.reo_error[err_code]++;
+ if (likely(err_code < HAL_REO_DEST_RING_ERROR_CODE_MAX))
+ dp->device_stats.wbm_err.reo_error[err_code]++;
+ else
+ WARN_ON_ONCE(1);
if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED &&
push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 4/8] wifi: ath12k: add device DP stats reset support via debugfs
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
There is no way to reset device DP stats counters without reloading
the driver, making it difficult to isolate issues to a specific time
window during debugging.
Add a write handler to the device_dp_stats debugfs file so that
writing 'reset' clears all device DP stats counters. Change the file
mode from 0400 to 0600 to allow write access. Use strcmp() with
newline stripping to match the input, consistent with the existing
pattern in debugfs.c. Return -EINVAL on unrecognised input.
No lock is taken around the memset since the counters are updated
locklessly in the datapath; taking dp_lock would be misleading as it
does not protect device_stats updates.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/debugfs.c | 35 ++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index 0f8b458200a8..e9eaa23ee63e 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1220,8 +1220,41 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
return ret;
}
+static ssize_t
+ath12k_debugfs_write_device_dp_stats(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath12k_base *ab = file->private_data;
+ struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
+ struct ath12k_device_dp_stats *device_stats = &dp->device_stats;
+ char buf[20] = {};
+ int ret;
+
+ if (count >= sizeof(buf))
+ return -EINVAL;
+
+ ret = copy_from_user(buf, user_buf, count);
+ if (ret)
+ return -EFAULT;
+
+ /* drop the possible '\n' from the end */
+ if (count > 0 && buf[count - 1] == '\n')
+ buf[count - 1] = '\0';
+
+ if (!strcmp(buf, "reset")) {
+ memset(device_stats, 0, sizeof(*device_stats));
+ return count;
+ }
+
+ ath12k_warn(ab, "unsupported command: %s\n", buf);
+
+ return -EINVAL;
+}
+
static const struct file_operations fops_device_dp_stats = {
.read = ath12k_debugfs_dump_device_dp_stats,
+ .write = ath12k_debugfs_write_device_dp_stats,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
@@ -1232,7 +1265,7 @@ void ath12k_debugfs_pdev_create(struct ath12k_base *ab)
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
&fops_simulate_fw_crash);
- debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab,
+ debugfs_create_file("device_dp_stats", 0600, ab->debugfs_soc, ab,
&fops_device_dp_stats);
}
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 3/8] wifi: ath12k: add TCL ring TX buffer allocation failure counter
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
When ath12k_dp_tx_assign_buffer() fails, the TX path returns -ENOMEM
silently with no per-ring visibility into how often this occurs.
Without a counter, buffer pool exhaustion on a specific TCL ring is
invisible during debugging.
Add txbuf_na[] to ath12k_device_dp_tx_err_stats to track per-ring TX
buffer allocation failures and increment it on assign failure in the
TX path. Expose the per-ring counts in debugfs under a new 'TCL Ring
Buffer Alloc Failures' section.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/debugfs.c | 5 +++++
drivers/net/wireless/ath/ath12k/dp.h | 2 ++
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 4 +++-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index d54995b7adb2..0f8b458200a8 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1117,6 +1117,11 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
i, device_stats->tx_err.desc_na[i]);
+ len += scnprintf(buf + len, size - len, "\nTCL Ring Buffer Alloc Failures:\n");
+ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
+ len += scnprintf(buf + len, size - len, "ring%d: %u\n",
+ i, device_stats->tx_err.txbuf_na[i]);
+
len += scnprintf(buf + len, size - len,
"\nMisc Transmit Failures: %d\n",
atomic_read(&device_stats->tx_err.misc_fail));
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index a94bbc337df4..ac125adde258 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -428,6 +428,8 @@ struct ath12k_dp_arch_ops {
struct ath12k_device_dp_tx_err_stats {
/* TCL Ring Descriptor unavailable */
u32 desc_na[DP_TCL_NUM_RING_MAX];
+ /* TCL Ring Buffers unavailable */
+ u32 txbuf_na[DP_TCL_NUM_RING_MAX];
/* Other failures during dp_tx due to mem allocation failure
* idr unavailable etc.
*/
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
index a0e409452a19..ca0e1369af21 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -123,8 +123,10 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
tx_ring = &dp->tx_ring[ti.ring_id];
tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id);
- if (!tx_desc)
+ if (!tx_desc) {
+ dp->device_stats.tx_err.txbuf_na[ti.ring_id]++;
return -ENOMEM;
+ }
dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id);
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 2/8] wifi: ath12k: rename wbm_status to htt_status in HTT TX completion
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
The variable wbm_status in ath12k_dp_tx_process_htt_tx_complete()
holds a value from the HTT TX WBM completion status field, not a
generic WBM status. Rename it to htt_status to accurately reflect
the field origin and improve code clarity.
Also fix ts.acked assignment inside the HAL_WBM_REL_HTT_TX_COMP_STATUS_OK
case to use true directly since the condition is always true within
that case branch.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
index 1d55ccacbff4..a0e409452a19 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -513,21 +513,21 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,
{
struct htt_tx_wbm_completion *status_desc;
struct ath12k_dp_htt_wbm_tx_status ts = {};
- enum hal_wbm_htt_tx_comp_status wbm_status;
+ enum hal_wbm_htt_tx_comp_status htt_status;
u16 peer_id;
status_desc = desc;
- wbm_status = le32_get_bits(status_desc->info0,
+ htt_status = le32_get_bits(status_desc->info0,
HTT_TX_WBM_COMP_INFO0_STATUS);
- if (likely(wbm_status < MAX_FW_TX_STATUS))
- dp->device_stats.fw_tx_status[wbm_status]++;
+ if (likely(htt_status < MAX_FW_TX_STATUS))
+ dp->device_stats.fw_tx_status[htt_status]++;
else
WARN_ON_ONCE(1);
- switch (wbm_status) {
+ switch (htt_status) {
case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
- ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
+ ts.acked = true;
ts.ack_rssi = le32_get_bits(status_desc->info2,
HTT_TX_WBM_COMP_INFO2_ACK_RSSI);
@@ -549,7 +549,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,
*/
break;
default:
- ath12k_warn(dp->ab, "Unknown htt wbm tx status %d\n", wbm_status);
+ ath12k_warn(dp->ab, "Unknown htt tx status %d\n", htt_status);
break;
}
}
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 1/8] wifi: ath12k: fix out-of-bounds access on TX stats arrays
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Pardeep Kaur
In-Reply-To: <20260723125448.922361-1-pardeep.kaur@oss.qualcomm.com>
From: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
The fw_tx_status[], tx_wbm_rel_source[], and tqm_rel_reason[] arrays
are indexed directly by values read from hardware without bounds checks.
Values at or beyond MAX_FW_TX_STATUS, HAL_WBM_REL_SRC_MODULE_MAX, or
MAX_TQM_RELEASE_REASON respectively would write past the end of the
arrays causing memory corruption.
Add bounds checks using likely() and WARN_ON_ONCE() before incrementing
each counter, consistent with the existing pattern used elsewhere in
the ath12k codebase.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Fixes: c5c62287e690 ("wifi: ath12k: Add device dp stats support")
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
index d2749de44553..1d55ccacbff4 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -520,7 +520,10 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,
wbm_status = le32_get_bits(status_desc->info0,
HTT_TX_WBM_COMP_INFO0_STATUS);
- dp->device_stats.fw_tx_status[wbm_status]++;
+ if (likely(wbm_status < MAX_FW_TX_STATUS))
+ dp->device_stats.fw_tx_status[wbm_status]++;
+ else
+ WARN_ON_ONCE(1);
switch (wbm_status) {
case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
@@ -922,11 +925,17 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id)
/* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */
buf_rel_source = le32_get_bits(tx_status->info0,
HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);
- dp->device_stats.tx_wbm_rel_source[buf_rel_source]++;
+ if (likely(buf_rel_source < HAL_WBM_REL_SRC_MODULE_MAX))
+ dp->device_stats.tx_wbm_rel_source[buf_rel_source]++;
+ else
+ WARN_ON_ONCE(1);
rel_status = le32_get_bits(tx_status->info0,
HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
- dp->device_stats.tqm_rel_reason[rel_status]++;
+ if (likely(rel_status < MAX_TQM_RELEASE_REASON))
+ dp->device_stats.tqm_rel_reason[rel_status]++;
+ else
+ WARN_ON_ONCE(1);
/* Release descriptor as soon as extracting necessary info
* to reduce contention
base-commit: 32f39e331f889a0424f7a0a82893f628e2705727
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next 0/8] wifi: ath12k: extend device DP stats for TX and RX observability
From: Pardeep Kaur @ 2026-07-23 12:54 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Pardeep Kaur
From: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Extend ath12k device DP stats for TX and RX path observability.
Patch 1 fixes out-of-bounds array access on TX stats arrays
fw_tx_status[], tx_wbm_rel_source[] and tqm_rel_reason[] by adding
likely()/WARN_ON_ONCE() bounds checks before each increment.
Patch 2 renames the local variable wbm_status to htt_status in
ath12k_dp_tx_process_htt_tx_complete() to accurately reflect the field
origin, and simplifies ts.acked to use true directly.
Patch 3 adds a per-TCL-ring TX buffer allocation failure counter
txbuf_na[] to track how often ath12k_dp_tx_assign_buffer() fails, and
exposes it in device_dp_stats debugfs.
Patch 4 adds a write handler to device_dp_stats debugfs so that writing
'reset' clears all device DP stats counters without reloading the driver.
Patch 5 introduces a new dp_stats.h header with the
ath12k_wbm_err_drop_reason enum, adds per-drop-reason counters in the
WBM RX error path, and exposes them in device_dp_stats debugfs.
Patch 6 adds a per-REO-ring sent_to_stack[] counter to track successful
MSDU deliveries to the network stack, and exposes it in device_dp_stats
debugfs.
Patch 7 fixes the REO Rx Received debugfs output to use 0-based ring
indexing and lowercase "ring%d:" consistent with other ring counters.
Patch 8 adds a dedicated sw_desc_fallback counter to track how often the
WBM RX error path falls back to SW descriptor retrieval when HW CC is
not done, distinct from actual packet drops.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
Aniruddha Mishra (2):
wifi: ath12k: add WBM RX error drop statistics
wifi: ath12k: add WBM SW desc fallback counter
Hariharan Ramanathan (4):
wifi: ath12k: rename wbm_status to htt_status in HTT TX completion
wifi: ath12k: add TCL ring TX buffer allocation failure counter
wifi: ath12k: add device DP stats reset support via debugfs
wifi: ath12k: track per-ring RX sent-to-stack count
Pardeep Kaur (2):
wifi: ath12k: fix out-of-bounds access on TX stats arrays
wifi: ath12k: fix 1-based ring index in REO Rx Received debugfs output
drivers/net/wireless/ath/ath12k/debugfs.c | 74 ++++++++++++++++++-
drivers/net/wireless/ath/ath12k/dp.h | 14 +++-
drivers/net/wireless/ath/ath12k/dp_stats.h | 25 +++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 52 ++++++++++---
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 29 +++++---
.../net/wireless/ath/ath12k/wifi7/hal_rx.c | 5 +-
6 files changed, 173 insertions(+), 26 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/dp_stats.h
base-commit: 32f39e331f889a0424f7a0a82893f628e2705727
--
2.34.1
^ permalink raw reply
* Re: short description of GeoNetworking
From: Johannes Berg @ 2026-07-23 12:37 UTC (permalink / raw)
To: Andrew Lunn, Simon Dietz
Cc: andrew+netdev, davem, dietz23838, edumazet, kuniyu,
linux-wireless, netdev
In-Reply-To: <70e14ff7-fa2f-42a9-b880-a6adf5713c10@lunn.ch>
On Thu, 2026-07-23 at 02:30 +0200, Andrew Lunn wrote:
>
>
> Closest to the target. Opposite to how i interpreted it. I still think
> a device in the middle might be better, but that needs a true WiFi
> person to comment on it.
I didn't really want to comment much on this, but I guess you're calling
me out ;-)
I _think_ in 11p there isn't much notion of being able to do rate
adaptation, so it probably doesn't matter (much) from an airtime usage
POV (if the frame makes it through at all). From a robustness POV it
might matter more, but then it also depends how you select which
stations you consider to be reachable at all.
As for the user-space vs. kernel-space split: clearly, only highly
specialised applications are going to be able to use this socket family
at all, not only because it's a special socket family, but also because
they're going to have to figure out where to send a packet?
Or put another way: for each packet, you need to know _where_ (as in
physical location) it's going to go, so you can pick which peer to send
it to, no? Is this really a *per-packet* property? If not, then I don't
think the shape calculations etc. would really need to be in the kernel?
In fact I'm sort of asking myself if - since the applications are so
specialized - it even makes sense to have a socket family for it? Not
sure, lacking the high-level design context I guess.
A bigger issue with this might be that it's clearly a small piece of a
large overall puzzle - Simon, you mentioned a modified driver somewhere
I think (can't find that mention right now), which may be using the OCB
support in the stack, perhaps, but also isn't upstream.
> So looking at it from this perspective, how does the Linux Foundation
> Automotive Grade Linux fit in? Does it have a V2V stack? Is it kernel
> or user space? If they have a full implementation, which is open
> source, but just out of tree, with a range of applications, would it
> be better to spend some time to clean up and merge their code?
And then also related to that - it seems these would be very specialized
applications to start with, how do we get anything useful out of a
socket family without them?
johannes
^ permalink raw reply
* Re: [PATCH v3] wifi: mwifiex: validate event lengths before copying bodies
From: Jeff Chen @ 2026-07-23 9:23 UTC (permalink / raw)
To: Pengpeng Hou
Cc: Brian Norris, Francesco Dolcini, linux-wireless, linux-kernel
In-Reply-To: <20260723103510.3-mwifiex-event-v3-pengpeng@iscas.ac.cn>
On Thu, Jul 23, 2026 at 10:40:05 AM +0800, Pengpeng Hou wrote:
> mwifiex event packets contain a four-byte event cause followed by the
> event body. The USB and SDIO paths copy from data after that header using
> the full packet length, so the source range extends four bytes beyond the
> skb. The SDIO path also reads the event cause before validating the
> packet and publishes oversized events without a copied body.
>
> Reject SDIO events that are shorter than the header or larger than the
> event buffer limit. Discard them through the same free-and-break contract
> used for unknown upload types. Retain USB's existing error path and copy
> only the bytes after the event header in both paths.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> Changes since v2: https://lore.kernel.org/all/20260720115119.80059-1-pengpeng@iscas.ac.cn/
> - replace the new SDIO return -1 with free plus break as requested
> - preserve USB's established error return contract
> - rebase onto the current wireless tree
>
> diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
> index f039d6f19183..3588c36f64cf 100644
> --- a/drivers/net/wireless/marvell/mwifiex/sdio.c
> +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
> @@ -1712,12 +1712,19 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
> case MWIFIEX_TYPE_EVENT:
> mwifiex_dbg(adapter, EVENT,
> "info: --- Rx: Event ---\n");
> + if (skb->len < MWIFIEX_EVENT_HEADER_LEN ||
> + skb->len > MAX_EVENT_SIZE) {
> + mwifiex_dbg(adapter, ERROR,
> + "EVENT: invalid skb->len %u\n", skb->len);
> + dev_kfree_skb_any(skb);
> + break;
> + }
skb->len includes the 4-byte header, so the body size is
skb->len - MWIFIEX_EVENT_HEADER_LEN. The upper bound should be:
skb->len - MWIFIEX_EVENT_HEADER_LEN > MAX_EVENT_SIZE
Otherwise packets with a full MAX_EVENT_SIZE body are incorrectly
rejected.
^ permalink raw reply
* Re: [PATCH] wifi: mac80211: reject station association if AP is not started
From: Johannes Berg @ 2026-07-23 9:14 UTC (permalink / raw)
To: syzbot, syzkaller-bugs, Slawomir Stepien, linux-wireless
Cc: linux-kernel, syzbot
In-Reply-To: <373210a9-4365-4cac-823a-0eec391858e7@mail.kernel.org>
On Thu, 2026-07-23 at 08:11 +0000, syzbot wrote:
> From: Slawomir Stepien <sst@poczta.fm>
I'm a bit confused? Did syzbot just pick up another patch?
> dereferences the NULL chanctx_conf, triggering a WARN_ON:
That can't be right?
> Fix this by rejecting the addition or modification of a station to the
> associated state if the AP has not been started (chanctx_conf is NULL).
That's a proxy for "AP is started", but not a good one, I think we
actually have a flag or so somewhere? Maybe even reject it in cfg80211?
> Exempt Multi-Link Operation (MLO) interfaces from this check, as they
> handle chanctx_conf per-link rather than globally on the VIF.
Feels like that's only necessary because the proxy is bad.
Also maybe a similar issue arises if an MLO AP is only half-started, and
stations are added to all links, or so?
johannes
^ permalink raw reply
* Re: [RFC PATCH wireless-next v2 0/4] wifi: aic: add AIC8800 SDIO FullMAC driver
From: Johannes Berg @ 2026-07-23 8:48 UTC (permalink / raw)
To: Yanli Yang, linux-wireless; +Cc: Zhirun Liu, Dijia Xu, Chunqiu Liu, Liheng Wei
In-Reply-To: <ef855527f564086a498e95d31a35935762fa60e1.camel@sipsolutions.net>
On Thu, 2026-07-23 at 10:42 +0200, Johannes Berg wrote:
>
> etc. Using "struct task_struct" in a driver, really?!
That caught my eye, but actually it's just excessively so perhaps - some
other wireless drivers _do_ use it. Feels a bit outdated though vs. work
structs (especially wiphy work.)
Since I had the LLM review anyway, I pasted it below. I'm not saying
this is correct or complete, but it may give you a hint as to why I'm
not really taking this submission seriously at all.
-------
Quick review done. Here's a prioritized list of the most obvious
upstream blockers in drivers/net/wireless/aic/ (~66k lines, forked from
the RivieraWaves/rwnx BSP).
Custom/duplicate userspace ABIs (hard blockers)
* Private generic-netlink interface — aic8800_fdrv/aicwf_genl.c +
aicwf_genl.h (AIC8800_GENL). A whole string-parsed genl family for
"manufacturing and driver debugging." This is the one you mentioned —
must be deleted; use nl80211 + (sparingly) cfg80211 testmode/vendor
cmds.
* Android priv_cmd ioctl interpreter — aic8800_fdrv/aic_priv_cmd.c,
android_priv_cmd()/aic_priv_cmd.c:1731. ~2000 lines of
android_wifi_priv_cmd string commands over ifr_data. Classic
downstream vendor ABI, not upstreamable.
* cfg80211 internals re-implementation / GKI shim —
aic8800_fdrv/rwnx_gki.c does #include "net/wireless/core.h" (private
in-tree header), defines its own rwnx_nl80211_fam and reimplements
cfg80211_rx_spurious_frame() etc. Also has a bogus #include
<include/linux/types.h>. Reaching into cfg80211 internals is a hard
no.
* Legacy Wireless Extensions layer — aic8800_fdrv/aicwf_wext_linux.c
(AIC8800_USE_WIRELESS_EXT). New drivers are nl80211-only.
* procfs suspend control — proc_create("suspend", …) in
aicwf_sdio.c:105 (AIC8800_WIFI_SUSPEND_FOR_LINUX). Use standard
PM/cfg80211.
* Vendor-HAL grab-bag with stubs — aic8800_fdrv/aic_vendor.c
(mkeep_alive, APF, ring buffers, wake-reason counters). Several are
fake/no-op, e.g. aic_dev_start_mkeep_alive() builds a packet then
just kfrees it.
Kconfig / Makefile
* Config explosion — ~50+ options across Kconfig, aic8800_bsp/Kconfig,
aic8800_fdrv/Kconfig. Many are porting/downstream knobs hidden behind
depends on BROKEN (*_FOR_OLD_KERNEL, RWNX_TL4, RWNX_OLD_IPC,
AIC8800_GKI, AIC8800_BR_SUPPORT, AIC8800_SDIO_BT, …). Upstream wants
these deleted, not gated behind BROKEN.
* ccflags-$(CONFIG_x) += -DCONFIG_y anti-pattern — Makefile launders
Kconfig into re-defined CONFIG_* macros to drive #ifdef soup. Use the
real CONFIG_ symbols / IS_ENABLED().
Structural
* BSP + fdrv split glued by EXPORT_SYMBOL_GPL — two modules with a
private exported ABI (aicbsp_set_subsys, aicbsp_get_feature,
aicbsp_resv_mem_*, get_sdio_func, set_irq_handler,
btchr_external_write). Should be one cleanly-layered driver.
* Bluetooth-over-SDIO reimplemented — aic8800_fdrv/aic_btsdio.c with
its own char device instead of the kernel BT HCI/btsdio framework.
* Bridge "br_ext" repeater hack — aic8800_fdrv/aic_br_ext.c
(AIC8800_BR_SUPPORT).
* Reinvented in-tree infra — bundled md5.c in both subdirs (use
crypto/lib); own 2772-line regdb.c instead of kernel regulatory; own
rwnx_wakelock.c, aicwf_tcp_ack.c (TCP-ACK filtering is stack policy,
not a driver's job), Android-style prealloc/reserved-mem pools.
Portability / style
* Kernel-version + Android compat shims — aic8800_fdrv/rwnx_compat.h
(LINUX_VERSION_CODE, HIGH_KERNEL_VERSION*, ANDROID_PLATFORM). In-tree
code targets current kernel only.
* Private _l typedefs — aic8800_fdrv/lmac_types.h redefines
u8_l/u16_l/bool_l. Worse, under CONFIG_RWNX_TL4 it does typedef u16
u8_l; (an 8-bit type aliased to 16-bit). Use kernel types.
* Too many module_params — debug levels, thread priorities, TX/RX
tuning, plus country_code, ccode_channels, saved_sdk_ver, testmode as
module params. Runtime config belongs in nl80211/DT, not module
params.
* Checked-in generated version headers — rwnx_version_gen.h ("241c091M
(master)", RELEASE_VERSION "2.0.14"), duplicated across subdirs.
* Dead/commented code & busy-waits — commented module_param/mdelay,
mdelay(100) spins in the msg-tx path, msleep(2000) in priv-cmd.
-------
johannes
^ permalink raw reply
* Re: [RFC PATCH wireless-next v2 0/4] wifi: aic: add AIC8800 SDIO FullMAC driver
From: Johannes Berg @ 2026-07-23 8:42 UTC (permalink / raw)
To: Yanli Yang, linux-wireless; +Cc: Zhirun Liu, Dijia Xu, Chunqiu Liu, Liheng Wei
In-Reply-To: <cover.1784724170.git.yanli.yang@bedmex.com>
On Thu, 2026-07-23 at 10:13 +0800, Yanli Yang wrote:
>
> Known limitations of this RFC are:
Known to you ;-)
You're not going to go *anywhere* with this if you just resend it more
or less as-is without every looking at upstream yourself.
This driver does just about everything that we don't want upstream. I
plugged this into an LLM and asked it to do a brief review wrt. things
that this does and upstream doesn't like, and it very quickly came up
with a huge list, but you really need to do even that work yourself,
nobody is going to review the driver in this shape, it's just too awful
to even start.
Familiarize yourself with other drivers in the tree first, start much
smaller in terms of feature set and especially Android-specific stuff,
etc. Using "struct task_struct" in a driver, really?!
So you have a very very long road ahead of you, which quite likely
involves more or less rewriting this driver, if you really want to see
it upstream.
johannes
^ permalink raw reply
* Re: [PATCH wireless-next] wifi: rt2x00: Use device-managed register buffers
From: Stanislaw Gruszka @ 2026-07-23 8:33 UTC (permalink / raw)
To: Rosen Penev; +Cc: linux-wireless, open list
In-Reply-To: <20260717220052.824624-1-rosenp@gmail.com>
On Fri, Jul 17, 2026 at 03:00:52PM -0700, Rosen Penev wrote:
> The rt2x00 PCI and USB probe paths allocate EEPROM and RF storage with
> plain kzalloc() and then free it from bus-specific teardown helpers. The
> USB path also manages the CSR cache the same way. These buffers are
> tied to the device lifetime, so the explicit free paths add probe and
> disconnect cleanup without providing separate ownership.
>
> Allocate the buffers with devm_kzalloc() before the mac80211 hardware is
> allocated, then attach the resulting storage to struct rt2x00_dev after
> the driver-private state exists. This lets driver detach and probe
> failure rely on device-managed cleanup and removes the duplicated
> bus-specific buffer freeing.
>
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
> int rt2x00usb_probe(struct usb_interface *usb_intf,
> const struct rt2x00_ops *ops)
> {
> struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
> - struct ieee80211_hw *hw;
> struct rt2x00_dev *rt2x00dev;
> + struct ieee80211_hw *hw;
> + __le16 *eeprom;
> + void *cache;
> int retval;
> + u32* rf;
Nit, u32 *rf;
Regards
Stanislaw
^ permalink raw reply
* Re: [PATCH] wifi: cfg80211: publish PMSR request before starting the driver
From: Johannes Berg @ 2026-07-23 8:18 UTC (permalink / raw)
To: Zhao Li; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260723010916.76433-1-enderaoelyther@gmail.com>
On Thu, 2026-07-23 at 09:09 +0800, Zhao Li wrote:
>
> This ordering also permits a successful driver callback to complete the
> request synchronously. Document the resulting start_pmsr lifetime contract.
From a locking perspective perhaps yes, but cfg80211_pmsr_complete()
sends the results to userspace immediately, so userspace might see a
completion with a cookie before it even got the cookie as the request
response, which (semantically) makes no sense.
Given that measurement requests are always going to take some time, I
don't think this is an issue in practice that we really need to work
hard to prevent (we'd have to do something like attaching the result to
the request on the list, pivot to a wiphy locked worker, etc.)
However, I don't think it makes sense to actually *document* that it's
now possible - it's only possible from the kernel's locking POV, from
userspace's POV it's still highly confusing at best, and it makes no
sense semantically either.
At best the documentation would be something like "the kernel doesn't
crash if the request is completed before returning success" but that's
not useful either :)
> + /*
> + * Publish before the driver can complete the request. Completion may free
> + * it before rdev_start_pmsr() returns, so use the cookie snapshot below.
> + */
That comment then should call out how it's really about preventing races
with drivers from doing UAF (we could technically be preempted here
too), rather than making that sound like a reasonable order - just
saying "Under races and/or broken drivers immediate completion might
free it ..." or something along those lines would be better I think.
johannes
^ permalink raw reply
* [PATCH] wifi: mac80211: reject station association if AP is not started
From: syzbot @ 2026-07-23 8:11 UTC (permalink / raw)
To: syzkaller-bugs, Slawomir Stepien, Johannes Berg, linux-wireless
Cc: linux-kernel, syzbot
From: Slawomir Stepien <sst@poczta.fm>
If an interface is changed to AP mode but not started, its channel context
configuration (chanctx_conf) remains NULL. If a station is then added to
this interface, the kernel may automatically set the
NL80211_STA_FLAG_ASSOCIATED flag for compatibility with older userspace
applications.
When this flag is set, sta_apply_auth_flags() attempts to initialize rate
control for the station by calling rate_control_rate_init_all_links(). This
eventually leads to rate_control_rate_init(), which dereferences the NULL
chanctx_conf, triggering a WARN_ON:
WARNING: net/mac80211/rate.c:51 at rate_control_rate_init+0x5a6/0x630
...
Call Trace:
<TASK>
rate_control_rate_init_all_links+0xf4/0x190 net/mac80211/rate.c:84
sta_apply_auth_flags+0x1bc/0x430 net/mac80211/cfg.c:2152
sta_apply_parameters+0x126d/0x1b10 net/mac80211/cfg.c:2618
ieee80211_add_station+0x3de/0x700 net/mac80211/cfg.c:2684
rdev_add_station+0xfc/0x290 net/wireless/rdev-ops.h:201
nl80211_new_station+0x1b4e/0x1fd0 net/wireless/nl80211.c:9505
Fix this by rejecting the addition or modification of a station to the
associated state if the AP has not been started (chanctx_conf is NULL).
Exempt Multi-Link Operation (MLO) interfaces from this check, as they
handle chanctx_conf per-link rather than globally on the VIF.
Fixes: 55de908ab292 ("mac80211: use channel contexts")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+9bdc0c5998ab45b05030@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9bdc0c5998ab45b05030
Link: https://syzkaller.appspot.com/ai_job?id=64f3e3ae-e43e-4917-b403-f9b7799fe1bc
Signed-off-by: Slawomir Stepien <sst@poczta.fm>
---
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 3b58af59f..830c9fc95 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2148,8 +2148,13 @@ static int sta_apply_auth_flags(struct ieee80211_local *local,
* well. Some drivers require rate control initialized
* before drv_sta_state() is called.
*/
- if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
+ if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
+ if (!ieee80211_vif_is_mld(&sta->sdata->vif) &&
+ !rcu_access_pointer(sta->sdata->vif.bss_conf.chanctx_conf))
+ return -EINVAL;
+
rate_control_rate_init_all_links(sta);
+ }
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
if (ret)
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
--
See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
You can comment on the patch as usual, syzbot will try to address
the comments and send a new version of the patch if necessary.
syzbot engineers can be reached at syzkaller@googlegroups.com.
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox