Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH ath-current v2 0/8] wifi: ath12k: support firmware-allocated MLD peer ID
From: Rameshkumar Sundaram @ 2026-07-24  4:55 UTC (permalink / raw)
  To: Baochen Qiang, Jeff Johnson; +Cc: linux-wireless, ath12k
In-Reply-To: <20260720-ath12k-fw-allocated-ml-peer-id-v2-0-630632758a80@oss.qualcomm.com>

On 7/20/2026 12:13 PM, Baochen Qiang wrote:
> ath12k currently assumes the host allocates the MLD peer ID and passes
> it down to firmware via WMI_PEER_ASSOC_CMDID. This works on QCN9274
> but breaks WCN7850/QCC2072, whose firmware always picks the ID itself
> and reports it back through HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP. As a
> result dp_hw->dp_peers[] is never populated for MLO peers and the data
> path lookup fails. On QCC2072 the firmware additionally crashes on MLO
> disconnect when ATH12K_WMI_FLAG_MLO_PEER_ID_VALID was set in the peer
> assoc command.
> 
> Add a host_alloc_ml_id hw_param to branch behavior, defer the
> dp_peers[] publish to the HTT event for firmware-allocated chips, and
> propagate the firmware-assigned ID through the existing host
> bookkeeping when it arrives.
> 
> Patch summary:
> 
> 1: fix for an out-of-bounds clear_bit() in
>       ath12k_mac_dp_peer_cleanup().
>    2: group peer assoc send-and-wait into a helper
>    3: refactor, keep ATH12K_PEER_ML_ID_VALID set in ahsta->ml_peer_id
>       so later patches do not have to OR or mask it at every call site;
>    4: parse the HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP message;
>    5: introduce hw_param host_alloc_ml_id, set true on QCN9274 family
>       and false on WCN7850/QCC2072;
>    6: on host_alloc_ml_id == false, leave peer_id_valid unset and send
>       ml_peer_id == 0 in WMI_PEER_ASSOC_CMDID;
>    7: on host_alloc_ml_id == false, mark ahsta->ml_peer_id and
>       dp_peer->peer_id as ATH12K_MLO_PEER_ID_PENDING and skip the
>       dp_hw->dp_peers[] publish until the firmware reports the ID;
>    8: in the MLO_RX_PEER_MAP handler, propagate the firmware-assigned
>       ID into dp_peer->peer_id, every dp_link_peer in
>       dp_peer->link_peers[], and ahsta->ml_peer_id, all under
>       dp_hw->peer_lock.
> 
> ---
> Changes in v2:
> - patch 5/8: initialize ret before goto err handling in ath12k_mac_allocate()
> - Link to v1: https://lore.kernel.org/r/20260713-ath12k-fw-allocated-ml-peer-id-v1-0-d0a2a1a519eb@oss.qualcomm.com
> 
> ---
> Baochen Qiang (8):
>        wifi: ath12k: fix out-of-bounds clear_bit in ath12k_mac_dp_peer_cleanup()
>        wifi: ath12k: factor out peer assoc send-and-wait into a helper
>        wifi: ath12k: keep ATH12K_PEER_ML_ID_VALID set in ath12k_sta::ml_peer_id
>        wifi: ath12k: add support for HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP
>        wifi: ath12k: introduce host_alloc_ml_id hardware parameter
>        wifi: ath12k: do not advertise MLD peer ID for firmware-allocate devices
>        wifi: ath12k: defer dp_peer registration when firmware allocates MLD peer ID
>        wifi: ath12k: resolve PENDING ML peer ID from MLO_PEER_MAP HTT event
> 
>   drivers/net/wireless/ath/ath12k/core.c     |   2 +
>   drivers/net/wireless/ath/ath12k/core.h     |   3 +
>   drivers/net/wireless/ath/ath12k/dp_htt.c   |  49 +++++++++
>   drivers/net/wireless/ath/ath12k/dp_htt.h   |  12 +++
>   drivers/net/wireless/ath/ath12k/dp_peer.c  |  75 +++++++++++--
>   drivers/net/wireless/ath/ath12k/dp_peer.h  |   2 +
>   drivers/net/wireless/ath/ath12k/hw.h       |   2 +
>   drivers/net/wireless/ath/ath12k/mac.c      | 165 ++++++++++++++++++++---------
>   drivers/net/wireless/ath/ath12k/peer.c     |  31 +++++-
>   drivers/net/wireless/ath/ath12k/peer.h     |   1 +
>   drivers/net/wireless/ath/ath12k/wifi7/hw.c |  12 +++
>   11 files changed, 293 insertions(+), 61 deletions(-)
> ---
> base-commit: 951dc0a744e4dc8490935316d3b76e23990bde3c
> change-id: 20260527-ath12k-fw-allocated-ml-peer-id-2b456891157f
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH] wifi: rtw88: disable ASPM and deep PS on ASUS TUF Gaming A15 FA506II
From: Ping-Ke Shih @ 2026-07-24  3:46 UTC (permalink / raw)
  To: Mihail Dimoski, Ping-Ke Shih; +Cc: linux-wireless, Mihail Dimoski
In-Reply-To: <20260718124045.23493-1-mihaildimoski@gmail.com>

Mihail Dimoski <mihaildimoski@gmail.com> wrote:

> The RTL8822CE on the ASUS TUF Gaming A15 FA506II wedges during normal
> use. The driver watchdog toggles PCIe ASPM while leaving power save;
> the DBI read of the ASPM link-config register fails with -EIO, the PCIe
> link becomes unstable, and the device drops off the bus, taking Wi-Fi
> down until a cold power cycle:
> 
>   rtw88_8822ce 0000:03:00.0: failed to read ASPM, ret=-5
>   rtw88_8822ce 0000:03:00.0: firmware failed to leave lps state
>   rtw88_8822ce 0000:03:00.0: mac power on failed
> 
> This is the same platform ASPM inter-operability problem already
> handled for other machines through rtw_pci_quirks[]. Disabling PCI
> ASPM and deep power save on this model stops the failure. Add a DMI
> quirk so the workaround is applied automatically.
> 
> Signed-off-by: Mihail Dimoski <mihaildimoski@gmail.com>
> Acked-by: Ping-Ke Shih <pkshih@realtek.com>

1 patch(es) applied to rtw-next branch of rtw.git, thanks.

b0034a2e4156 wifi: rtw88: disable ASPM and deep PS on ASUS TUF Gaming A15 FA506II

---
https://github.com/pkshih/rtw.git


^ permalink raw reply

* Re: [PATCH rtw-next 01/13] wifi: rtw89: coex: Add version 107 TX/RX info for firmware feature
From: Ping-Ke Shih @ 2026-07-24  3:30 UTC (permalink / raw)
  To: Ping-Ke Shih, linux-wireless; +Cc: ku920601
In-Reply-To: <20260717065739.64124-2-pkshih@realtek.com>

Ping-Ke Shih <pkshih@realtek.com> wrote:

> From: Ching-Te Ku <ku920601@realtek.com>
> 
> The previous version 7 format is for Dual-Bluetooth using. This patch
> is for single Bluetooth solution using. Driver will summary Wi-Fi now
> status for firmware to train RF parameters & TDMA mechanism.
> 
> Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

13 patch(es) applied to rtw-next branch of rtw.git, thanks.

0427315a6ed1 wifi: rtw89: coex: Add version 107 TX/RX info for firmware feature
4bedf26e132c wifi: rtw89: coex: Add version 9 report control info
b5bfb43844e1 wifi: rtw89: coex: Fix unexpected grant-signal assignee
00961e2705b7 wifi: rtw89: coex: Branch out version 105 firmware report map index
49989a3fef37 wifi: rtw89: coex: Refine chip initial related structure
81d30a7be825 wifi: rtw89: coex: Add driver info H2C command index version 103
35b569b60aa0 wifi: rtw89: coex: Fix Wi-Fi role info H2C command header issue
58b1bde3712e wifi: rtw89: coex: Add firmware 0.29.133.X support for RTL8852B family
42a83b5f13e3 wifi: rtw89: coex: Add TDMA version 4
b87da03ee7e9 wifi: rtw89: coex: Add slots version 2
b8892add7e51 wifi: rtw89: coex: Add cycle status report version 105
236badaa50b3 wifi: rtw89: coex: Add wifi role info version 101
38c58d541cfe wifi: rtw89: coex: Add firmware 0.27.97.X support for RTL8852C

---
https://github.com/pkshih/rtw.git


^ permalink raw reply

* Re: [PATCH rtw-next 1/9] wifi: rtw89: add LED support to reflect the wireless association status
From: Ping-Ke Shih @ 2026-07-24  3:03 UTC (permalink / raw)
  To: Ping-Ke Shih, linux-wireless; +Cc: gary.chang, sc.lee, wenjie.tsai
In-Reply-To: <20260717061910.54466-2-pkshih@realtek.com>

Ping-Ke Shih <pkshih@realtek.com> wrote:

> From: Johnson Tsai <wenjie.tsai@realtek.com>
> 
> Add a new RTW89_LEDS Kconfig option, along with LED structures to describe
> flexible GPIO mappings for chip common LED definition. Core LED lifecycle
> and registration logic default to the mac80211 association trigger, and
> chips are wired up as the first user with a single-GPIO monochrome LED.
> 
> Usage:
> - Auto-triggered (default):
>   ON when connected, OFF when disconnected
> - Manual override:
>     echo <1|0> > /sys/class/leds/rtw89-phyX/brightness
> 
> Signed-off-by: Johnson Tsai <wenjie.tsai@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

9 patch(es) applied to rtw-next branch of rtw.git, thanks.

d910631ff352 wifi: rtw89: add LED support to reflect the wireless association status
721d90c8509a wifi: rtw89: add multicolor LED support for RTL8852CU valve board
355626a2c232 wifi: rtw89: 8852cu: add quirk to disable 2.4 GHz band
e92d5b02b456 wifi: rtw89: rfk: update TXIQK H2C command format to v1
89833570775a wifi: rtw89: 8922d: bypass TXIQK when scan
ce18a0cbc39b wifi: rtw89: wow: extend timeout unit to avoid SER false alarm
238bc3141cde wifi: rtw89: pci: set PCIe maximum TS1 for RTL8922DE
e738d2ac80c9 wifi: rtw89: 8922d: reduce IO in power-on function
b3dc0a37fd3a wifi: rtw89: phy: set CFR to manual mode for some 2GHz channels

---
https://github.com/pkshih/rtw.git


^ permalink raw reply

* Re: [PATCH v2] wifi: ath12k: restore country code during resume
From: Baochen Qiang @ 2026-07-24  2:51 UTC (permalink / raw)
  To: Jeff Johnson, Stian Knudsen, Jeff Johnson, ath12k; +Cc: linux-wireless
In-Reply-To: <bacea060-bae5-4136-841c-49db5b561b51@oss.qualcomm.com>



On 7/24/2026 8:15 AM, Jeff Johnson wrote:
> On 7/20/2026 5:09 AM, Stian Knudsen wrote:
>> The country code configured before suspend is lost after resume:
>> the device is powered down in suspend_late and powered back up in
>> resume_early, so firmware reboots with its default regulatory
>> settings and the previously set country code is no longer applied.
>>
>> On WCN7850 the firmware comes back in the world regulatory domain
>> (country 00) and takes ~7 seconds to rediscover the country code
>> from AP beacons, part of a ~16 second total delay before wifi
>> reconnects after resume.
>>
>> Restore it by resending WMI_SET_CURRENT_COUNTRY_CMDID during resume
>> if a country code was set before suspend, i.e. when ar->alpha2 is
>> valid. This follows the same approach as ath11k commit 7f0343b7b871
>> ("wifi: ath11k: restore country code during resume").
>>
>> Note that only single_pdev_only devices support suspend/resume (see
>> ath12k_core_continue_suspend_resume()), so handling the first and
>> only pdev is sufficient.
>>
>> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
>>
>> Fixes: 8d5f4da8d70b ("wifi: ath12k: support suspend/resume")
>> Suggested-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
>> Link: https://lore.kernel.org/r/-_iDJ_M5RrqACWB0qmtleg@pokerfj.es
>> Signed-off-by: Stian Knudsen <stian@pokerfj.es>
>> ---
>> v2:
>> - Add Fixes tag, per Baochen's review comment.
>> - Link to v1: https://lore.kernel.org/r/20260717130254.36732-1-stian@pokerfj.es
>> ---
>>  drivers/net/wireless/ath/ath12k/core.c | 21 +++++++++++++++++++++
>>  1 file changed, 21 insertions(+)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
>> --- a/drivers/net/wireless/ath/ath12k/core.c
>> +++ b/drivers/net/wireless/ath/ath12k/core.c
>> @@ -197,6 +197,7 @@ EXPORT_SYMBOL(ath12k_core_resume_early);
>>
>>  int ath12k_core_resume(struct ath12k_base *ab)
>>  {
>> +	struct ath12k *ar;
>>  	long time_left;
>>  	int ret;
>>
>> @@ -211,6 +212,26 @@ int ath12k_core_resume(struct ath12k_base *ab)
>>  		return -ETIMEDOUT;
>>  	}
>>
>> +	/* So far only single_pdev_only devices can reach here,
>> +	 * so it is valid to handle the first, and the only, pdev.
>> +	 */
>> +	ar = ab->pdevs[0].ar;
>> +	if (ab->hw_params->current_cc_support &&
>> +	    ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
>> +		struct wmi_set_current_country_arg arg = {};
>> +
>> +		memcpy(&arg.alpha2, ar->alpha2, 2);
>> +
>> +		reinit_completion(&ar->regd_update_completed);
>> +
>> +		ret = ath12k_wmi_send_set_current_country_cmd(ar, &arg);
>> +		if (ret) {
>> +			ath12k_warn(ab, "failed to set country code during resume: %d\n",
>> +				    ret);
>> +			return ret;
>> +		}
> 
> Baochen, can you remind me why we don't need to wait for completion here?
> (the ath11k change doesn't wait)

Technically we will wait, but asynchronously instead of synchronously. It works in a way:

1. reinit completion
2. send new cc to firmware, proceed with no sync wait.
3. in reg channel list event host process reg rules, queue regd update work and signals
completion.
4. regd update work calls ath12k_regd_update() where we wait for the completion.

But I am feeling this is not a good design. As you can see, ath12k_regd_update() is
reachable via the regd update work, which is queued in reg chan list event. However it is
the event itself signals the completion. That means ath12k_regd_update() never blocks, the
whole reinit-wait thing is a no-ops.

> 
> If that is legit, perhaps we should document it with a comment since
> reinit_completion() without waiting for it seems strange
> 
>> +	}
>> +
>>  	return 0;
>>  }
>>  EXPORT_SYMBOL(ath12k_core_resume);
>> --
>> 2.50.0
> 


^ permalink raw reply

* Re: [PATCH v2 1/2] PCI: Move Spacemit vendor and device IDs to linux/pci_ids.h
From: Ping-Ke Shih @ 2026-07-24  2:23 UTC (permalink / raw)
  To: Anirudh Srinivasan, Bjorn Helgaas, Yixun Lan, Ping-Ke Shih,
	Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Inochi Amaoto, Aurelien Jarno
  Cc: linux-pci, linux-kernel, linux-riscv, spacemit, linux-wireless,
	Anirudh Srinivasan
In-Reply-To: <20260716-rtw89-spacemit-k3-v2-1-392b577ebf75@oss.tenstorrent.com>

Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com> wrote:

> Move the vendor and device ID for the existing Spacemit K1 PCIe Root
> Complex to include/linux/pci_ids.h. Also add K3's Root Complex device ID
> to this header. This is done so that these values can be referenced in
> the rtw89 driver to enable 36-bit DMA ability in it for WiFi to function
> on the K3 Pico ITX board.
> 
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>

2 patch(es) applied to rtw-next branch of rtw.git, thanks.

888b1934642b PCI: Move Spacemit vendor and device IDs to linux/pci_ids.h
27a5046cc56e wifi: rtw89: pci: enable 36-bit DMA on spacemit K3

---
https://github.com/pkshih/rtw.git


^ permalink raw reply

* [PATCH ath-next 2/2] wifi: ath11k: fix overreads in ath11k_wmi_process_csa_switch_count_event()
From: Jeff Johnson @ 2026-07-24  1:31 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel, ath11k, Jeff Johnson
In-Reply-To: <20260723-ath12k_wmi_process_csa_switch_count_event-cleanup-v1-0-c01ef10bc6a3@oss.qualcomm.com>

There is no policy entry for WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT, so
the parse infrastructure does not enforce a minimum length for the event
struct. Additionally, the num_vdevs field is taken directly from firmware
and used as a loop bound over the vdev_ids array without checking that it
fits within the TLV payload. Either condition can cause an out-of-bounds
read.

Add a TLV policy entry for WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT so
the parse infrastructure enforces a minimum length for the fixed-size event
struct. Add a helper ath11k_wmi_tlv_data_len() to recover the payload
length of a parsed TLV from the header preceding its data pointer. Use it
in ath11k_wmi_process_csa_switch_count_event() to bound num_vdevs before
the loop.

Compile tested only.

Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath11k/wmi.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index dca6e011cc40..feb0a0b29c81 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -159,6 +159,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
 		.min_len = sizeof(struct ath11k_wmi_p2p_noa_info) },
 	[WMI_TAG_P2P_NOA_EVENT] = {
 		.min_len = sizeof(struct wmi_p2p_noa_event) },
+	[WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT] = {
+		.min_len = sizeof(struct wmi_pdev_csa_switch_ev) },
 };
 
 #define PRIMAP(_hw_mode_) \
@@ -262,6 +264,13 @@ const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab,
 	return tb;
 }
 
+static u32 ath11k_wmi_tlv_data_len(const void *data)
+{
+	const struct wmi_tlv *tlv = (const struct wmi_tlv *)data - 1;
+
+	return FIELD_GET(WMI_TLV_LEN, tlv->header);
+}
+
 static int ath11k_wmi_cmd_send_nowait(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
 				      u32 cmd_id)
 {
@@ -8353,15 +8362,23 @@ ath11k_wmi_process_csa_switch_count_event(struct ath11k_base *ab,
 					  const struct wmi_pdev_csa_switch_ev *ev,
 					  const u32 *vdev_ids)
 {
-	int i;
+	u32 vdev_ids_len = ath11k_wmi_tlv_data_len(vdev_ids);
+	u32 num_vdevs = ev->num_vdevs;
 	struct ath11k_vif *arvif;
+	int i;
 
 	/* Finish CSA once the switch count becomes NULL */
 	if (ev->current_switch_count)
 		return;
 
+	if (num_vdevs > vdev_ids_len / sizeof(*vdev_ids)) {
+		ath11k_warn(ab, "csa switch count num_vdevs %u exceeds tlv array length %u\n",
+			    num_vdevs, vdev_ids_len);
+		return;
+	}
+
 	rcu_read_lock();
-	for (i = 0; i < ev->num_vdevs; i++) {
+	for (i = 0; i < num_vdevs; i++) {
 		arvif = ath11k_mac_get_arvif_by_vdev_id(ab, vdev_ids[i]);
 
 		if (!arvif) {

-- 
2.43.0


^ permalink raw reply related

* [PATCH ath-next 1/2] wifi: ath12k: fix overreads in ath12k_wmi_process_csa_switch_count_event()
From: Jeff Johnson @ 2026-07-24  1:31 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel, ath11k, Jeff Johnson
In-Reply-To: <20260723-ath12k_wmi_process_csa_switch_count_event-cleanup-v1-0-c01ef10bc6a3@oss.qualcomm.com>

There is no policy entry for WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT, so
the parse infrastructure does not enforce a minimum length for the event
struct. Additionally, the num_vdevs field is taken directly from firmware
and used as a loop bound over the vdev_ids array without checking that it
fits within the TLV payload. Either condition can cause an out-of-bounds
read.

Add a TLV policy entry for WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT so
the parse infrastructure enforces a minimum length for the fixed-size event
struct. Add a helper ath12k_wmi_tlv_data_len() to recover the payload
length of a parsed TLV from the header preceding its data pointer. Use it
in ath12k_wmi_process_csa_switch_count_event() to bound num_vdevs before
the loop.

Compile tested only.

Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/wmi.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index ad739bffcf88..62a86f2069f3 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -207,6 +207,8 @@ static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
 		.min_len = sizeof(struct wmi_per_chain_rssi_stat_params) },
 	[WMI_TAG_OBSS_COLOR_COLLISION_EVT] = {
 		.min_len = sizeof(struct wmi_obss_color_collision_event) },
+	[WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT] = {
+		.min_len = sizeof(struct ath12k_wmi_pdev_csa_event) },
 };
 
 __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len)
@@ -374,6 +376,13 @@ ath12k_wmi_tlv_parse(struct ath12k_base *ab, struct sk_buff *skb)
 	return tb;
 }
 
+static u32 ath12k_wmi_tlv_data_len(const void *data)
+{
+	const struct wmi_tlv *tlv = (const struct wmi_tlv *)data - 1;
+
+	return le32_get_bits(tlv->header, WMI_TLV_LEN);
+}
+
 static int ath12k_wmi_cmd_send_nowait(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb,
 				      u32 cmd_id)
 {
@@ -9057,12 +9066,19 @@ ath12k_wmi_process_csa_switch_count_event(struct ath12k_base *ab,
 					  const u32 *vdev_ids)
 {
 	u32 current_switch_count = le32_to_cpu(ev->current_switch_count);
+	u32 vdev_ids_len = ath12k_wmi_tlv_data_len(vdev_ids);
 	u32 num_vdevs = le32_to_cpu(ev->num_vdevs);
 	struct ieee80211_bss_conf *conf;
 	struct ath12k_link_vif *arvif;
 	struct ath12k_vif *ahvif;
 	int i;
 
+	if (num_vdevs > vdev_ids_len / sizeof(*vdev_ids)) {
+		ath12k_warn(ab, "csa switch count num_vdevs %u exceeds tlv array length %u\n",
+			    num_vdevs, vdev_ids_len);
+		return;
+	}
+
 	rcu_read_lock();
 	for (i = 0; i < num_vdevs; i++) {
 		arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_ids[i]);

-- 
2.43.0


^ permalink raw reply related

* [PATCH ath-next 0/2] wifi: ath: Fix buffer overreads in CSA switch count event processing
From: Jeff Johnson @ 2026-07-24  1:31 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel, ath11k, Jeff Johnson

Both ath11k and ath12k fail to properly sanitize the CSA switch count
event.

---
Jeff Johnson (2):
      wifi: ath12k: fix overreads in ath12k_wmi_process_csa_switch_count_event()
      wifi: ath11k: fix overreads in ath11k_wmi_process_csa_switch_count_event()

 drivers/net/wireless/ath/ath11k/wmi.c | 21 +++++++++++++++++++--
 drivers/net/wireless/ath/ath12k/wmi.c | 16 ++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)
---
base-commit: 0ceb105245b5e57f803bdc0e79dc077fc06ff384
change-id: 20260716-ath12k_wmi_process_csa_switch_count_event-cleanup-7fb191b7d7d3


^ permalink raw reply

* Re: [PATCH v3 1/2] wifi: ath11k: release QMI handle on late init failures
From: Jeff Johnson @ 2026-07-24  1:02 UTC (permalink / raw)
  To: Guangshuo Li, Jeff Johnson, Baochen Qiang, linux-wireless, ath11k,
	linux-kernel, ath12k
In-Reply-To: <20260718074026.3085688-2-lgs201920130244@gmail.com>

On 7/18/2026 12:40 AM, Guangshuo Li wrote:

(dropping obsolete @quicinc.com and @codeaurora.org e-mail addresses)

> ath11k_qmi_init_service() initializes the QMI handle before allocating
> the QMI event workqueue and registering the service lookup.
> 
> If either of these later initialization steps fails, the function
> returns without releasing the initialized QMI handle, leaking its
> resources.
> 
> Release the QMI handle on the late failure paths.
> 
> Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
>  drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
> index 410a7ee076a0..6e3f82169d24 100644
> --- a/drivers/net/wireless/ath/ath11k/qmi.c
> +++ b/drivers/net/wireless/ath/ath11k/qmi.c
> @@ -3329,7 +3329,8 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
>  	ab->qmi.event_wq = alloc_ordered_workqueue("ath11k_qmi_driver_event", 0);
>  	if (!ab->qmi.event_wq) {
>  		ath11k_err(ab, "failed to allocate workqueue\n");
> -		return -EFAULT;
> +		ret = -EFAULT;
> +		goto err_release_qmi_handle;
>  	}
>  
>  	INIT_LIST_HEAD(&ab->qmi.event_list);
> @@ -3342,9 +3343,14 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
>  	if (ret < 0) {
>  		ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);
>  		destroy_workqueue(ab->qmi.event_wq);

Since you are adding cleanup labels, it would be more idiomatic to have a
separate err_destroy_workqueue: label to perform this cleanup

> -		return ret;
> +		goto err_release_qmi_handle;
>  	}
>  
> +	return ret;
> +

so here have
err_destroy_workqueue:
	destroy_workqueue(ab->qmi.event_wq);

> +err_release_qmi_handle:
> +	qmi_handle_release(&ab->qmi.handle);
> +
>  	return ret;
>  }
>  

same comment applies to ath12k

^ permalink raw reply

* Re: [PATCH v3] wifi: ath11k: fix txpower in ap mode for 6 Ghz
From: Jeff Johnson @ 2026-07-24  0:43 UTC (permalink / raw)
  To: Baochen Qiang, Sebastian Gottschall, ath11k; +Cc: linux-wireless
In-Reply-To: <2c56c58d-4e04-427b-9309-8895ccddc03a@oss.qualcomm.com>

On 7/19/2026 11:31 PM, Baochen Qiang wrote:
> On 5/15/2026 4:27 AM, Sebastian Gottschall wrote:
>> fixes: 74ef2d05ede63fd6416aa635aa8972dff901325f
>> (wifi: ath11k: use WMI_VDEV_SET_TPC_POWER_CMDID when EXT_TPC_REG_SUPPORT for 6 GHz)
> 
> checkpatch errors on this. Three problems: (1) it must be Fixes: (capital F), not fixes:;
> (2) the SHA should be truncated to 12 chars with the title in parentheses on the same
> line, not split across two lines with the full 40-char SHA; (3) the tag belongs in the
> trailer block just above Signed-off-by, not buried in the body separated by a blank line.
> Correct form:
> 
> Fixes: 74ef2d05ede6 ("wifi: ath11k: use WMI_VDEV_SET_TPC_POWER_CMDID when
> EXT_TPC_REG_SUPPORT for 6 GHz")

I bet Baochen's e-mail client split this when it shouldn't have.

Should be:
Fixes: 74ef2d05ede6 ("wifi: ath11k: use WMI_VDEV_SET_TPC_POWER_CMDID when EXT_TPC_REG_SUPPORT for 6 GHz")

(The "Toggle Line Wrap" plugin for Thunderbird is invaluable)

/jeff

^ permalink raw reply

* Re: [PATCH v3] wifi: ath11k: fix txpower in ap mode for 6 Ghz
From: Jeff Johnson @ 2026-07-24  0:39 UTC (permalink / raw)
  To: Sebastian Gottschall, ath11k; +Cc: linux-wireless
In-Reply-To: <20260514202750.3040404-1-s.gottschall@dd-wrt.com>

On 5/14/2026 1:27 PM, Sebastian Gottschall wrote:
> there is an issue which has been discovered a while ago while testing
> which killed txpower to 0 dBm once scanning is triggered in AP mode
> on QCN9074 based chipsets if 6 GHz is in use.
> ath11k_wmi_send_vdev_set_tpc_power must be set in AP mode in the same
> way is it is for STA as it is implemented in ath12k and in the
> qsdk version for ath11k.
> this patch must be considered to be backported (i discovered that issue
> already 2 years ago)

In addition to Baochen's comments my comment is that this doesn't clearly
describe the problem and the solution.

The Submitting Patches document tells us to "Describe your changes [...] as if
you are giving orders to the codebase to change its behaviour."

Also a subject nit: s/Ghz/GHz/ for proper SI representation

/jeff

^ permalink raw reply

* RE: [PATCH 10/36] wifi: remove conditional return with no effect
From: Ping-Ke Shih @ 2026-07-24  0:37 UTC (permalink / raw)
  To: Sang-Heon Jeon, Julia.Lawall@inria.fr, Miri Korenblit
  Cc: cocci@inria.fr, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org
In-Reply-To: <20260723184538.3888637-11-ekffu200098@gmail.com>

Sang-Heon Jeon <ekffu200098@gmail.com> wrote:
> Both branches of the check return the same value, so the check has
> no effect. Remove it and return the value directly.
> 
> This is the result of running the Coccinelle script from
> scripts/coccinelle/misc/cond_return_no_effect.cocci.
> 
> Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
> ---
>  drivers/net/wireless/ath/ath6kl/init.c              | 6 +-----
>  drivers/net/wireless/intel/iwlwifi/mvm/link.c       | 6 +-----
>  drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 7 +------
>  drivers/net/wireless/realtek/rtw89/mac.c            | 6 +-----
>  drivers/net/wireless/realtek/rtw89/mac_be.c         | 6 +-----

Can you split into four patches for ath6k, iwlwifi, rtlwifi and rtw89?
Then we can apply the patch to individual tree. 

Ping-Ke


^ permalink raw reply

* Re: [PATCH v2] wifi: ath12k: restore country code during resume
From: Jeff Johnson @ 2026-07-24  0:15 UTC (permalink / raw)
  To: Stian Knudsen, Jeff Johnson, ath12k; +Cc: linux-wireless, Baochen Qiang
In-Reply-To: <20260720120913.100604-1-stian@pokerfj.es>

On 7/20/2026 5:09 AM, Stian Knudsen wrote:
> The country code configured before suspend is lost after resume:
> the device is powered down in suspend_late and powered back up in
> resume_early, so firmware reboots with its default regulatory
> settings and the previously set country code is no longer applied.
> 
> On WCN7850 the firmware comes back in the world regulatory domain
> (country 00) and takes ~7 seconds to rediscover the country code
> from AP beacons, part of a ~16 second total delay before wifi
> reconnects after resume.
> 
> Restore it by resending WMI_SET_CURRENT_COUNTRY_CMDID during resume
> if a country code was set before suspend, i.e. when ar->alpha2 is
> valid. This follows the same approach as ath11k commit 7f0343b7b871
> ("wifi: ath11k: restore country code during resume").
> 
> Note that only single_pdev_only devices support suspend/resume (see
> ath12k_core_continue_suspend_resume()), so handling the first and
> only pdev is sufficient.
> 
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
> 
> Fixes: 8d5f4da8d70b ("wifi: ath12k: support suspend/resume")
> Suggested-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
> Link: https://lore.kernel.org/r/-_iDJ_M5RrqACWB0qmtleg@pokerfj.es
> Signed-off-by: Stian Knudsen <stian@pokerfj.es>
> ---
> v2:
> - Add Fixes tag, per Baochen's review comment.
> - Link to v1: https://lore.kernel.org/r/20260717130254.36732-1-stian@pokerfj.es
> ---
>  drivers/net/wireless/ath/ath12k/core.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
> --- a/drivers/net/wireless/ath/ath12k/core.c
> +++ b/drivers/net/wireless/ath/ath12k/core.c
> @@ -197,6 +197,7 @@ EXPORT_SYMBOL(ath12k_core_resume_early);
> 
>  int ath12k_core_resume(struct ath12k_base *ab)
>  {
> +	struct ath12k *ar;
>  	long time_left;
>  	int ret;
> 
> @@ -211,6 +212,26 @@ int ath12k_core_resume(struct ath12k_base *ab)
>  		return -ETIMEDOUT;
>  	}
> 
> +	/* So far only single_pdev_only devices can reach here,
> +	 * so it is valid to handle the first, and the only, pdev.
> +	 */
> +	ar = ab->pdevs[0].ar;
> +	if (ab->hw_params->current_cc_support &&
> +	    ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
> +		struct wmi_set_current_country_arg arg = {};
> +
> +		memcpy(&arg.alpha2, ar->alpha2, 2);
> +
> +		reinit_completion(&ar->regd_update_completed);
> +
> +		ret = ath12k_wmi_send_set_current_country_cmd(ar, &arg);
> +		if (ret) {
> +			ath12k_warn(ab, "failed to set country code during resume: %d\n",
> +				    ret);
> +			return ret;
> +		}

Baochen, can you remind me why we don't need to wait for completion here?
(the ath11k change doesn't wait)

If that is legit, perhaps we should document it with a comment since
reinit_completion() without waiting for it seems strange

> +	}
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(ath12k_core_resume);
> --
> 2.50.0


^ permalink raw reply

* RE: [PATCH v2 1/2] PCI: Move Spacemit vendor and device IDs to linux/pci_ids.h
From: Ping-Ke Shih @ 2026-07-24  0:05 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Anirudh Srinivasan, Bjorn Helgaas, Yixun Lan, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Inochi Amaoto, Aurelien Jarno, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	spacemit@lists.linux.dev, linux-wireless@vger.kernel.org
In-Reply-To: <20260723220140.GA865834@bhelgaas>

Bjorn Helgaas <helgaas@kernel.org> wrote:
> On Thu, Jul 23, 2026 at 01:19:47AM +0000, Ping-Ke Shih wrote:
> > Hi PCI maintainers,
> >
> > Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com> wrote:
> > > Move the vendor and device ID for the existing Spacemit K1 PCIe Root
> > > Complex to include/linux/pci_ids.h. Also add K3's Root Complex device ID
> > > to this header. This is done so that these values can be referenced in
> > > the rtw89 driver to enable 36-bit DMA ability in it for WiFi to function
> > > on the K3 Pico ITX board.
> > >
> > > Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> > > Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> > > ---
> > >  drivers/pci/controller/dwc/pcie-spacemit-k1.c | 3 ---
> > >  include/linux/pci_ids.h                       | 4 ++++
> > >  2 files changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > > b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > > index be20a520255b6..f89c6d46c7684 100644
> > > --- a/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > > +++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > > @@ -21,9 +21,6 @@
> > >
> > >  #include "pcie-designware.h"
> > >
> > > -#define PCI_VENDOR_ID_SPACEMIT         0x201f
> > > -#define PCI_DEVICE_ID_SPACEMIT_K1      0x0001
> > > -
> > >  /* Offsets and field definitions for link management registers */
> > >  #define K1_PHY_AHB_IRQ_EN                      0x0000
> > >  #define PCIE_INTERRUPT_EN              BIT(0)
> > > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> > > index 1c9d40e09107d..d6f26cacc8e35 100644
> > > --- a/include/linux/pci_ids.h
> > > +++ b/include/linux/pci_ids.h
> > > @@ -2640,6 +2640,10 @@
> > >  #define PCI_VENDOR_ID_SUNIX            0x1fd4
> > >  #define PCI_DEVICE_ID_SUNIX_1999       0x1999
> > >
> > > +#define PCI_VENDOR_ID_SPACEMIT         0x201f
> > > +#define PCI_DEVICE_ID_SPACEMIT_K1      0x0001
> > > +#define PCI_DEVICE_ID_SPACEMIT_K3      0x0002
> > > +
> > >  #define PCI_VENDOR_ID_HINT             0x3388
> > >  #define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
> >
> > As patch 2/2 obviously goes to wireless-next tree, can I take this
> > dependency patch to my tree?
> 
> Yes, that's what my Acked-by at
> https://lore.kernel.org/all/20260716164336.GA40813@bhelgaas means.

Thanks for the confirmation. :)



^ permalink raw reply

* Re: [PATCH v2 1/2] PCI: Move Spacemit vendor and device IDs to linux/pci_ids.h
From: Bjorn Helgaas @ 2026-07-23 22:01 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: Anirudh Srinivasan, Bjorn Helgaas, Yixun Lan, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Inochi Amaoto, Aurelien Jarno, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	spacemit@lists.linux.dev, linux-wireless@vger.kernel.org
In-Reply-To: <073fbf4b41804285b2df6fbb4efce0ed@realtek.com>

On Thu, Jul 23, 2026 at 01:19:47AM +0000, Ping-Ke Shih wrote:
> Hi PCI maintainers,
> 
> Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com> wrote:
> > Move the vendor and device ID for the existing Spacemit K1 PCIe Root
> > Complex to include/linux/pci_ids.h. Also add K3's Root Complex device ID
> > to this header. This is done so that these values can be referenced in
> > the rtw89 driver to enable 36-bit DMA ability in it for WiFi to function
> > on the K3 Pico ITX board.
> > 
> > Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> > Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> > ---
> >  drivers/pci/controller/dwc/pcie-spacemit-k1.c | 3 ---
> >  include/linux/pci_ids.h                       | 4 ++++
> >  2 files changed, 4 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > index be20a520255b6..f89c6d46c7684 100644
> > --- a/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > +++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
> > @@ -21,9 +21,6 @@
> > 
> >  #include "pcie-designware.h"
> > 
> > -#define PCI_VENDOR_ID_SPACEMIT         0x201f
> > -#define PCI_DEVICE_ID_SPACEMIT_K1      0x0001
> > -
> >  /* Offsets and field definitions for link management registers */
> >  #define K1_PHY_AHB_IRQ_EN                      0x0000
> >  #define PCIE_INTERRUPT_EN              BIT(0)
> > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> > index 1c9d40e09107d..d6f26cacc8e35 100644
> > --- a/include/linux/pci_ids.h
> > +++ b/include/linux/pci_ids.h
> > @@ -2640,6 +2640,10 @@
> >  #define PCI_VENDOR_ID_SUNIX            0x1fd4
> >  #define PCI_DEVICE_ID_SUNIX_1999       0x1999
> > 
> > +#define PCI_VENDOR_ID_SPACEMIT         0x201f
> > +#define PCI_DEVICE_ID_SPACEMIT_K1      0x0001
> > +#define PCI_DEVICE_ID_SPACEMIT_K3      0x0002
> > +
> >  #define PCI_VENDOR_ID_HINT             0x3388
> >  #define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
> 
> As patch 2/2 obviously goes to wireless-next tree, can I take this 
> dependency patch to my tree? 

Yes, that's what my Acked-by at
https://lore.kernel.org/all/20260716164336.GA40813@bhelgaas means.

^ permalink raw reply

* [wireless:for-next] BUILD SUCCESS fec15bb3dab0c88dd513a5198173de66f830f289
From: kernel test robot @ 2026-07-23 21:42 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: Johannes Berg, linux-wireless

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git for-next
branch HEAD: fec15bb3dab0c88dd513a5198173de66f830f289  Merge tag 'wireless-2026-07-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

elapsed time: 803m

configs tested: 65
configs skipped: 7

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                            allnoconfig    gcc-16.1.0
alpha                           allyesconfig    gcc-16.1.0
alpha                              defconfig    gcc-16.1.0
arc                             allmodconfig    gcc-16.1.0
arc                             allyesconfig    gcc-16.1.0
arc                  randconfig-001-20260723    gcc-8.5.0
arc                  randconfig-002-20260723    gcc-11.5.0
arm                  randconfig-002-20260723    gcc-13.4.0
arm                  randconfig-003-20260723    gcc-8.5.0
arm                  randconfig-004-20260723    gcc-13.4.0
arm64                randconfig-002-20260723    gcc-15.2.0
arm64                randconfig-003-20260723    gcc-13.4.0
arm64                randconfig-004-20260723    gcc-8.5.0
csky                            allmodconfig    gcc-16.1.0
csky                 randconfig-001-20260723    gcc-15.2.0
csky                 randconfig-002-20260723    gcc-16.1.0
i386                            allmodconfig    gcc-14
loongarch                          defconfig    clang-24
loongarch            randconfig-002-20260723    gcc-16.1.0
nios2                           allmodconfig    gcc-11.5.0
nios2                            allnoconfig    gcc-11.5.0
nios2                randconfig-001-20260723    gcc-8.5.0
nios2                randconfig-002-20260723    gcc-11.5.0
parisc                          allmodconfig    gcc-16.1.0
parisc                          allyesconfig    gcc-16.1.0
parisc                             defconfig    gcc-16.1.0
parisc               randconfig-001-20260723    gcc-8.5.0
parisc               randconfig-002-20260723    gcc-10.5.0
powerpc              randconfig-001-20260723    gcc-8.5.0
powerpc              randconfig-002-20260723    clang-24
powerpc                        wii_defconfig    gcc-16.1.0
powerpc64            randconfig-001-20260723    gcc-10.5.0
powerpc64            randconfig-002-20260723    clang-18
riscv                randconfig-001-20260723    clang-24
riscv                randconfig-002-20260723    gcc-15.2.0
s390                 randconfig-001-20260723    gcc-8.5.0
s390                 randconfig-002-20260723    gcc-10.5.0
sh                                 defconfig    gcc-16.1.0
sh                   randconfig-001-20260723    gcc-15.2.0
sh                   randconfig-002-20260723    gcc-16.1.0
sparc                randconfig-001-20260723    gcc-8.5.0
sparc                randconfig-002-20260723    gcc-8.5.0
sparc64              randconfig-002-20260723    gcc-8.5.0
um                   randconfig-002-20260723    clang-24
x86_64     buildonly-randconfig-001-20260723    gcc-14
x86_64     buildonly-randconfig-002-20260723    gcc-14
x86_64     buildonly-randconfig-003-20260723    clang-22
x86_64     buildonly-randconfig-004-20260723    gcc-14
x86_64     buildonly-randconfig-005-20260723    gcc-14
x86_64     buildonly-randconfig-006-20260723    gcc-12
x86_64               randconfig-001-20260723    clang-22
x86_64               randconfig-002-20260723    clang-22
x86_64               randconfig-003-20260723    clang-22
x86_64               randconfig-004-20260723    clang-22
x86_64               randconfig-005-20260723    clang-22
x86_64               randconfig-006-20260723    gcc-14
x86_64                        randconfig-011    gcc-14
x86_64               randconfig-011-20260723    gcc-14
x86_64               randconfig-012-20260723    gcc-14
x86_64               randconfig-013-20260723    clang-22
x86_64               randconfig-014-20260723    gcc-14
x86_64               randconfig-015-20260723    gcc-14
x86_64               randconfig-016-20260723    gcc-14
xtensa               randconfig-001-20260723    gcc-8.5.0
xtensa               randconfig-002-20260723    gcc-8.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH v3] wifi: mwifiex: validate action frame fixed fields
From: Zhao Li @ 2026-07-23 20:22 UTC (permalink / raw)
  To: linux-wireless
  Cc: linux-kernel, johannes, briannorris, francesco, linville, patila,
	cluo, Zhao Li, stable
In-Reply-To: <20260723011013.76968-1-enderaoelyther@gmail.com>

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 byte immediately after
that header and, for a public action frame, reads the following action
code byte without verifying that either field is present. A minimal frame
therefore reads one or two bytes beyond the RX buffer.

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/
Link: https://lore.kernel.org/all/20260723011013.76968-1-enderaoelyther@gmail.com/
Assisted-by: Codex:gpt-5
Assisted-by: Claude:opus-4.8
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
---
Changes in v3:
- Drop the redundant parser-local header check; the caller already
  guarantees the complete four-address header after removing the two-byte
  firmware prefix.

Changes in v2:
- Express the action-field sizes with IEEE80211_MIN_ACTION_SIZE(),
  accounting for the firmware four-address layout.
---
 drivers/net/wireless/marvell/mwifiex/util.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 7d3631d21223..e54a86ecaa33 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -317,9 +317,15 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
 
 	switch (stype) {
 	case IEEE80211_STYPE_ACTION:
+		if (len < IEEE80211_MIN_ACTION_SIZE(category) + ETH_ALEN)
+			return -1;
+
 		category = *(payload + sizeof(struct ieee80211_hdr));
 		switch (category) {
 		case WLAN_CATEGORY_PUBLIC:
+			if (len < IEEE80211_MIN_ACTION_SIZE(action_code) + ETH_ALEN)
+				return -1;
+
 			action_code = *(payload + sizeof(struct ieee80211_hdr)
 					+ 1);
 			if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCH v2] wifi: mwifiex: validate action frame fixed fields
From: Zhao Li @ 2026-07-23 20:22 UTC (permalink / raw)
  To: Francesco Dolcini
  Cc: linux-wireless, linux-kernel, Johannes Berg, Brian Norris, stable
In-Reply-To: <20260723144127.GA234631@francesco-nb>

On Thu, 23 Jul 2026 at 16:41:27 +0200, Francesco Dolcini wrote:
> I am confused, why is this check needed here, and not done in
> mwifiex_process_mgmt_packet()?

I double-checked the arithmetic and, yes, I made a mistake. The header
check is redundant while the other two checks are needed.

mwifiex_process_mgmt_packet() already validates:

	if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) {

After subtracting sizeof(pkt_len), the len passed into
mwifiex_parse_mgmt_packet() is at least sizeof(struct ieee80211_hdr).
So the if (len < sizeof(*ieee_hdr)) guard is redundant.

The remaining two guards check that the category and action_code bytes
are present beyond the header. Keeping these subtype-specific checks in
the parser places them next to the corresponding reads.

I will drop the redundant header check and resend as v3.

Thanks,
Zhao

^ permalink raw reply

* [PATCH v2] wifi: cfg80211: publish PMSR request before starting the driver
From: Zhao Li @ 2026-07-23 20:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: johannes, linux-kernel, Zhao Li
In-Reply-To: <20260723010916.76433-1-enderaoelyther@gmail.com>

nl80211_pmsr_start() assigns the request cookie, calls the driver's
->start_pmsr() callback, and only then adds the request to
wdev->pmsr_list, without holding pmsr_lock for the addition.

mac80211_hwsim saves the request in its start callback and returns. Since
nl80211 uses parallel_ops, an immediate REPORT_PMSR can then run before
nl80211_pmsr_start() reaches its post-start list_add_tail(). hwsim also
dispatches reports from its virtio receive workqueue. Completion removes
the request from wdev->pmsr_list under pmsr_lock and frees it.

Thus completion can precede publication, race the unlocked list mutation,
or free the request before nl80211_pmsr_start() reads req->cookie for the
netlink reply.

Add the request to wdev->pmsr_list under pmsr_lock before calling the
driver, and use a cookie value saved before the call so the request is not
dereferenced after a successful start. On an error return the driver has
not retained or completed the request, so remove it from the list under the
lock and free it.

Fixes: 9bb7e0f24e7e ("cfg80211: add peer measurement with FTM initiator API")
Link: https://lore.kernel.org/all/20260723010916.76433-1-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:
- Drop callback documentation that implied synchronous completion was
  supported.
- Reword the local comment as defensive handling for races or broken
  drivers that complete the request before ->start_pmsr() returns.
---
 net/wireless/pmsr.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
index d1e2fae5bc0e..97449bcb9a22 100644
--- a/net/wireless/pmsr.c
+++ b/net/wireless/pmsr.c
@@ -420,6 +420,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
 	const struct cfg80211_pmsr_capabilities *capa;
 	struct cfg80211_pmsr_request *req;
 	struct nlattr *peers, *peer;
+	u64 cookie;
 
 	capa = rdev->wiphy.pmsr_capa;
 
@@ -521,14 +522,27 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
 	}
 	req->cookie = cfg80211_assign_cookie(rdev);
 	req->nl_portid = info->snd_portid;
+	cookie = req->cookie;
+
+	/*
+	 * Add to the list before the driver call; under races or broken
+	 * drivers, completion may free the request before rdev_start_pmsr()
+	 * returns. Use the saved cookie below.
+	 */
+	spin_lock_bh(&wdev->pmsr_lock);
+	list_add_tail(&req->list, &wdev->pmsr_list);
+	spin_unlock_bh(&wdev->pmsr_lock);
 
 	err = rdev_start_pmsr(rdev, wdev, req);
-	if (err)
+	if (err) {
+		/* An error return leaves the request owned by this path. */
+		spin_lock_bh(&wdev->pmsr_lock);
+		list_del(&req->list);
+		spin_unlock_bh(&wdev->pmsr_lock);
 		goto out_err;
+	}
 
-	list_add_tail(&req->list, &wdev->pmsr_list);
-
-	nl_set_extack_cookie_u64(info->extack, req->cookie);
+	nl_set_extack_cookie_u64(info->extack, cookie);
 	return 0;
 out_err:
 	kfree(req);
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCH] wifi: cfg80211: publish PMSR request before starting the driver
From: Zhao Li @ 2026-07-23 20:22 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <3552acdf7839106b152edfd13502684306ea42a3.camel@sipsolutions.net>

On Thu, 23 Jul 2026 at 10:18:33 +0200, Johannes Berg wrote:
> 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.

Agreed. I'll drop the kernel-doc changes. Documenting it implies it's a
supported semantic when it's really just a locking side effect.

> 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.

Exactly. I'll reword the comment to frame it as defensive against races
and broken drivers, not as an intentional ordering.

Will send a v2.

Thanks,
Zhao

^ permalink raw reply

* Re: linux-next: manual merge of the wireless-next tree with the origin tree
From: Zhao Li @ 2026-07-23 20:21 UTC (permalink / raw)
  To: Mark Brown
  Cc: Johannes Berg, linux-wireless, Johannes Berg, linux-kernel,
	linux-next, Miri Korenblit, Pagadala Yesu Anjaneyulu
In-Reply-To: <ac48f782-3fbd-4c61-89d0-4dd032ca81b9@sirena.org.uk>

On Thu, Jul 23, 2026 at 7:51 PM Mark Brown <broonie@kernel.org> wrote:
> On Wed, Jul 22, 2026 at 03:53:59PM -0500, Enderaoe Lyther wrote:
>
> > I noticed one semantic conflict later in ieee80211_rx_mgmt_assoc_resp().
>
> I can't tell which bit of code you are talking about here.  I see there
> is a block at line 7274 of -next:
>
>         if (elems->aid_resp)
>                 aid = le16_to_cpu(elems->aid_resp->aid);
>         else if (!assoc_data->s1g)
>                 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
>         else if (status_code == WLAN_STATUS_SUCCESS)
>                 goto notify_driver;

Sorry about the formatting in my earlier message. I should have quoted the
code inline instead of top-posting.

That last branch was introduced by 035ed430ce6a ("wifi: mac80211: avoid
non-S1G AID fallback for S1G assoc") as:

	else if (status_code == WLAN_STATUS_SUCCESS)
		goto abandon_assoc;

f13e573ab3f12 ("wifi: mac80211: notify driver before destroying assoc
link") consolidated terminal association cleanup at destroy_assoc_data
and removed abandon_assoc. The conflict resolution retargeted this branch
to notify_driver, but notify_driver only calls drv_mgd_complete_tx()
without destroying the association data.

Since assoc_status is initialized to ASSOC_ABANDON at function entry, the
equivalent target is destroy_assoc_data. A successful S1G association
response with no AID Response element otherwise leaves assoc_data live
instead of abandoning it.

> but that is immediately after another goto notify_driver, there's
> further notify_driver error handling afterwards and all the earlier
> error handling is return statements so it looks at least unclear what's
> supposed to be going on.

Other goto notify_driver targets are intentional:

  - "if (!elems) goto notify_driver" is a pre-existing allocation failure
    bail-out; so association timeout handles cleanup.

  - The comeback path WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY keeps
    assoc_data live deliberately for retry.

A successful S1G response without an AID Response element is terminal.
It needs to abandon association immediately, so the target should be
destroy_assoc_data rather than notify_driver.

> Please don't top post, reply in line with needed context.

Understood. Sorry for the unclear top-posted reply.

Zhao

^ permalink raw reply

* Re: [PATCH wireless-next] wifi: rt2x00: Use flexible array for hw_mode_spec channels
From: Rosen Penev @ 2026-07-23 19:26 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: linux-wireless, 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: <20260723075304.GA4577@wp.pl>

On Thu, Jul 23, 2026 at 12:53 AM Stanislaw Gruszka <stf_xl@wp.pl> wrote:
>
> Hi,
>
> On Sun, Jun 28, 2026 at 08:31:56PM -0700, Rosen Penev wrote:
> > struct hw_mode_spec stores channel information that is allocated by the
> > individual rt2x00 drivers during hardware probing.  The channel info
> > array has the same lifetime as the hardware mode specification, but it
> > is currently allocated separately and then freed through a separate
> > pointer.
> >
> > Make struct rt2x00_dev hold a pointer to the hardware mode
> > specification, store the channel info as a flexible array member, and
> > allocate both pieces together with kzalloc_flex().
> >
> > Assisted-by: Codex:GPT-5.5
> > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > ---
> >  .../net/wireless/ralink/rt2x00/rt2400pci.c    | 24 +++---
> >  .../net/wireless/ralink/rt2x00/rt2500pci.c    | 55 ++++++++------
> >  .../net/wireless/ralink/rt2x00/rt2500usb.c    | 55 ++++++++------
> >  .../net/wireless/ralink/rt2x00/rt2800lib.c    | 74 ++++++++++---------
> >  drivers/net/wireless/ralink/rt2x00/rt2x00.h   |  4 +-
> >  .../net/wireless/ralink/rt2x00/rt2x00config.c | 12 +--
> >  .../net/wireless/ralink/rt2x00/rt2x00dev.c    |  4 +-
> >  drivers/net/wireless/ralink/rt2x00/rt61pci.c  | 42 ++++++-----
> >  drivers/net/wireless/ralink/rt2x00/rt73usb.c  | 50 +++++++------
> >  9 files changed, 177 insertions(+), 143 deletions(-)
>
> This result in extra code. I do not see benefit of avoiding
> kzalloc calls at cost of adding more lines of code.
On runtime there's extra UBSAN analysis. Reducing allocations is always good.
>
> Regards
> Stanislaw
>
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
> > index cac191304bf5..3fb74dcbee63 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
> > @@ -1559,7 +1559,7 @@ static const struct rf_channel rf_vals_b[] = {
> >
> >  static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     struct hw_mode_spec *spec;
> >       struct channel_info *info;
> >       u8 *tx_power;
> >       unsigned int i;
> > @@ -1580,27 +1580,25 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Initialize hw_mode information.
> >        */
> > -     spec->supported_bands = SUPPORT_BAND_2GHZ;
> > -     spec->supported_rates = SUPPORT_RATE_CCK;
> > +     spec = kzalloc_flex(*spec, channels_info, ARRAY_SIZE(rf_vals_b));
> > +     if (!spec)
> > +             return -ENOMEM;
> >
> >       spec->num_channels = ARRAY_SIZE(rf_vals_b);
> >       spec->channels = rf_vals_b;
> >
> > -     /*
> > -      * Create channel information array
> > -      */
> > -     info = kzalloc_objs(*info, spec->num_channels);
> > -     if (!info)
> > -             return -ENOMEM;
> > -
> > -     spec->channels_info = info;
> > +     spec->supported_bands = SUPPORT_BAND_2GHZ;
> > +     spec->supported_rates = SUPPORT_RATE_CCK;
> >
> >       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
> >       for (i = 0; i < 14; i++) {
> > -             info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
> > -             info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> > +             info = &spec->channels_info[i];
> > +             info->max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
> > +             info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> >       }
> >
> > +     rt2x00dev->spec = spec;
> > +
> >       return 0;
> >  }
> >
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
> > index fc35b60e422c..4c85f401c091 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
> > @@ -1854,7 +1854,10 @@ static const struct rf_channel rf_vals_5222[] = {
> >
> >  static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     const struct rf_channel *channels;
> > +     unsigned int num_channels = 0;
> > +     unsigned int supported_bands;
> > +     struct hw_mode_spec *spec;
> >       struct channel_info *info;
> >       u8 *tx_power;
> >       unsigned int i;
> > @@ -1880,52 +1883,58 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Initialize hw_mode information.
> >        */
> > -     spec->supported_bands = SUPPORT_BAND_2GHZ;
> > -     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> > +     supported_bands = SUPPORT_BAND_2GHZ;
> >
> >       if (rt2x00_rf(rt2x00dev, RF2522)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
> > -             spec->channels = rf_vals_bg_2522;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2522);
> > +             channels = rf_vals_bg_2522;
> >       } else if (rt2x00_rf(rt2x00dev, RF2523)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
> > -             spec->channels = rf_vals_bg_2523;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2523);
> > +             channels = rf_vals_bg_2523;
> >       } else if (rt2x00_rf(rt2x00dev, RF2524)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
> > -             spec->channels = rf_vals_bg_2524;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2524);
> > +             channels = rf_vals_bg_2524;
> >       } else if (rt2x00_rf(rt2x00dev, RF2525)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
> > -             spec->channels = rf_vals_bg_2525;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2525);
> > +             channels = rf_vals_bg_2525;
> >       } else if (rt2x00_rf(rt2x00dev, RF2525E)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
> > -             spec->channels = rf_vals_bg_2525e;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
> > +             channels = rf_vals_bg_2525e;
> >       } else if (rt2x00_rf(rt2x00dev, RF5222)) {
> > -             spec->supported_bands |= SUPPORT_BAND_5GHZ;
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_5222);
> > -             spec->channels = rf_vals_5222;
> > +             supported_bands |= SUPPORT_BAND_5GHZ;
> > +             num_channels = ARRAY_SIZE(rf_vals_5222);
> > +             channels = rf_vals_5222;
> >       }
> >
> >       /*
> >        * Create channel information array
> >        */
> > -     info = kzalloc_objs(*info, spec->num_channels);
> > -     if (!info)
> > +     spec = kzalloc_flex(*spec, channels_info, num_channels);
> > +     if (!spec)
> >               return -ENOMEM;
> >
> > -     spec->channels_info = info;
> > +     spec->num_channels = num_channels;
> > +     spec->channels = channels;
> > +     spec->supported_bands = supported_bands;
> > +     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> >
> >       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
> >       for (i = 0; i < 14; i++) {
> > -             info[i].max_power = MAX_TXPOWER;
> > -             info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> > +             info = &spec->channels_info[i];
> > +             info->max_power = MAX_TXPOWER;
> > +             info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> >       }
> >
> >       if (spec->num_channels > 14) {
> >               for (i = 14; i < spec->num_channels; i++) {
> > -                     info[i].max_power = MAX_TXPOWER;
> > -                     info[i].default_power1 = DEFAULT_TXPOWER;
> > +                     info = &spec->channels_info[i];
> > +                     info->max_power = MAX_TXPOWER;
> > +                     info->default_power1 = DEFAULT_TXPOWER;
> >               }
> >       }
> >
> > +     rt2x00dev->spec = spec;
> > +
> >       return 0;
> >  }
> >
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
> > index 58728df6666c..cbc1c1399cc6 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
> > @@ -1661,7 +1661,10 @@ static const struct rf_channel rf_vals_5222[] = {
> >
> >  static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     const struct rf_channel *channels;
> > +     unsigned int num_channels = 0;
> > +     unsigned int supported_bands;
> > +     struct hw_mode_spec *spec;
> >       struct channel_info *info;
> >       u8 *tx_power;
> >       unsigned int i;
> > @@ -1693,52 +1696,58 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Initialize hw_mode information.
> >        */
> > -     spec->supported_bands = SUPPORT_BAND_2GHZ;
> > -     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> > +     supported_bands = SUPPORT_BAND_2GHZ;
> >
> >       if (rt2x00_rf(rt2x00dev, RF2522)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
> > -             spec->channels = rf_vals_bg_2522;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2522);
> > +             channels = rf_vals_bg_2522;
> >       } else if (rt2x00_rf(rt2x00dev, RF2523)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
> > -             spec->channels = rf_vals_bg_2523;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2523);
> > +             channels = rf_vals_bg_2523;
> >       } else if (rt2x00_rf(rt2x00dev, RF2524)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
> > -             spec->channels = rf_vals_bg_2524;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2524);
> > +             channels = rf_vals_bg_2524;
> >       } else if (rt2x00_rf(rt2x00dev, RF2525)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
> > -             spec->channels = rf_vals_bg_2525;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2525);
> > +             channels = rf_vals_bg_2525;
> >       } else if (rt2x00_rf(rt2x00dev, RF2525E)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
> > -             spec->channels = rf_vals_bg_2525e;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
> > +             channels = rf_vals_bg_2525e;
> >       } else if (rt2x00_rf(rt2x00dev, RF5222)) {
> > -             spec->supported_bands |= SUPPORT_BAND_5GHZ;
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_5222);
> > -             spec->channels = rf_vals_5222;
> > +             supported_bands |= SUPPORT_BAND_5GHZ;
> > +             num_channels = ARRAY_SIZE(rf_vals_5222);
> > +             channels = rf_vals_5222;
> >       }
> >
> >       /*
> >        * Create channel information array
> >        */
> > -     info = kzalloc_objs(*info, spec->num_channels);
> > -     if (!info)
> > +     spec = kzalloc_flex(*spec, channels_info, num_channels);
> > +     if (!spec)
> >               return -ENOMEM;
> >
> > -     spec->channels_info = info;
> > +     spec->num_channels = num_channels;
> > +     spec->channels = channels;
> > +     spec->supported_bands = supported_bands;
> > +     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> >
> >       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
> >       for (i = 0; i < 14; i++) {
> > -             info[i].max_power = MAX_TXPOWER;
> > -             info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> > +             info = &spec->channels_info[i];
> > +             info->max_power = MAX_TXPOWER;
> > +             info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> >       }
> >
> >       if (spec->num_channels > 14) {
> >               for (i = 14; i < spec->num_channels; i++) {
> > -                     info[i].max_power = MAX_TXPOWER;
> > -                     info[i].default_power1 = DEFAULT_TXPOWER;
> > +                     info = &spec->channels_info[i];
> > +                     info->max_power = MAX_TXPOWER;
> > +                     info->default_power1 = DEFAULT_TXPOWER;
> >               }
> >       }
> >
> > +     rt2x00dev->spec = spec;
> > +
> >       return 0;
> >  }
> >
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > index 97290899674e..7b7f6dcc9247 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > @@ -11778,7 +11778,9 @@ static const struct rf_channel rf_vals_7620[] = {
> >
> >  static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     const struct rf_channel *channels;
> > +     unsigned int num_channels = 0;
> > +     struct hw_mode_spec *spec;
> >       struct channel_info *info;
> >       s8 *default_power1;
> >       s8 *default_power2;
> > @@ -11840,19 +11842,17 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Initialize hw_mode information.
> >        */
> > -     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> > -
> >       switch (rt2x00dev->chip.rf) {
> >       case RF2720:
> >       case RF2820:
> > -             spec->num_channels = 14;
> > -             spec->channels = rf_vals;
> > +             num_channels = 14;
> > +             channels = rf_vals;
> >               break;
> >
> >       case RF2750:
> >       case RF2850:
> > -             spec->num_channels = ARRAY_SIZE(rf_vals);
> > -             spec->channels = rf_vals;
> > +             num_channels = ARRAY_SIZE(rf_vals);
> > +             channels = rf_vals;
> >               break;
> >
> >       case RF2020:
> > @@ -11870,44 +11870,52 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       case RF5372:
> >       case RF5390:
> >       case RF5392:
> > -             spec->num_channels = 14;
> > +             num_channels = 14;
> >               if (rt2800_clk_is_20mhz(rt2x00dev))
> > -                     spec->channels = rf_vals_3x_xtal20;
> > +                     channels = rf_vals_3x_xtal20;
> >               else
> > -                     spec->channels = rf_vals_3x;
> > +                     channels = rf_vals_3x;
> >               break;
> >
> >       case RF7620:
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_7620);
> > -             spec->channels = rf_vals_7620;
> > +             num_channels = ARRAY_SIZE(rf_vals_7620);
> > +             channels = rf_vals_7620;
> >               break;
> >
> >       case RF3052:
> >       case RF3053:
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_3x);
> > -             spec->channels = rf_vals_3x;
> > +             num_channels = ARRAY_SIZE(rf_vals_3x);
> > +             channels = rf_vals_3x;
> >               break;
> >
> >       case RF3853:
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_3853);
> > -             spec->channels = rf_vals_3853;
> > +             num_channels = ARRAY_SIZE(rf_vals_3853);
> > +             channels = rf_vals_3853;
> >               break;
> >
> >       case RF5592:
> >               reg = rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX);
> >               if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
> > -                     spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal40);
> > -                     spec->channels = rf_vals_5592_xtal40;
> > +                     num_channels = ARRAY_SIZE(rf_vals_5592_xtal40);
> > +                     channels = rf_vals_5592_xtal40;
> >               } else {
> > -                     spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal20);
> > -                     spec->channels = rf_vals_5592_xtal20;
> > +                     num_channels = ARRAY_SIZE(rf_vals_5592_xtal20);
> > +                     channels = rf_vals_5592_xtal20;
> >               }
> >               break;
> >       }
> >
> > -     if (WARN_ON_ONCE(!spec->channels))
> > +     if (WARN_ON_ONCE(!channels))
> >               return -ENODEV;
> >
> > +     spec = kzalloc_flex(*spec, channels_info, num_channels);
> > +     if (!spec)
> > +             return -ENOMEM;
> > +
> > +     spec->num_channels = num_channels;
> > +     spec->channels = channels;
> > +     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> > +
> >       spec->supported_bands = SUPPORT_BAND_2GHZ;
> >       if (spec->num_channels > 14)
> >               spec->supported_bands |= SUPPORT_BAND_5GHZ;
> > @@ -11959,19 +11967,13 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Create channel information and survey arrays
> >        */
> > -     info = kzalloc_objs(*info, spec->num_channels);
> > -     if (!info)
> > -             return -ENOMEM;
> > -
> >       rt2x00dev->chan_survey =
> >               kzalloc_objs(struct rt2x00_chan_survey, spec->num_channels);
> >       if (!rt2x00dev->chan_survey) {
> > -             kfree(info);
> > +             kfree(spec);
> >               return -ENOMEM;
> >       }
> >
> > -     spec->channels_info = info;
> > -
> >       default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
> >       default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
> >
> > @@ -11982,10 +11984,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >               default_power3 = NULL;
> >
> >       for (i = 0; i < 14; i++) {
> > -             info[i].default_power1 = default_power1[i];
> > -             info[i].default_power2 = default_power2[i];
> > +             info = &spec->channels_info[i];
> > +             info->default_power1 = default_power1[i];
> > +             info->default_power2 = default_power2[i];
> >               if (default_power3)
> > -                     info[i].default_power3 = default_power3[i];
> > +                     info->default_power3 = default_power3[i];
> >       }
> >
> >       if (spec->num_channels > 14) {
> > @@ -12002,10 +12005,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >                       default_power3 = NULL;
> >
> >               for (i = 14; i < spec->num_channels; i++) {
> > -                     info[i].default_power1 = default_power1[i - 14];
> > -                     info[i].default_power2 = default_power2[i - 14];
> > +                     info = &spec->channels_info[i];
> > +                     info->default_power1 = default_power1[i - 14];
> > +                     info->default_power2 = default_power2[i - 14];
> >                       if (default_power3)
> > -                             info[i].default_power3 = default_power3[i - 14];
> > +                             info->default_power3 = default_power3[i - 14];
> >               }
> >       }
> >
> > @@ -12033,6 +12037,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >               break;
> >       }
> >
> > +     rt2x00dev->spec = spec;
> > +
> >       return 0;
> >  }
> >
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
> > index 7d313e86d3f2..babc04210a65 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
> > @@ -404,9 +404,9 @@ struct hw_mode_spec {
> >
> >       unsigned int num_channels;
> >       const struct rf_channel *channels;
> > -     const struct channel_info *channels_info;
> >
> >       struct ieee80211_sta_ht_cap ht;
> > +     struct channel_info channels_info[] __counted_by(num_channels);
> >  };
> >
> >  /*
> > @@ -802,7 +802,7 @@ struct rt2x00_dev {
> >       /*
> >        * hw capability specifications.
> >        */
> > -     struct hw_mode_spec spec;
> > +     struct hw_mode_spec *spec;
> >
> >       /*
> >        * This is the default TX/RX antenna setup as indicated
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
> > index f895f560a185..b97cb67c4361 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
> > @@ -165,7 +165,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
> >  static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> >                                  struct ieee80211_conf *conf)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     struct hw_mode_spec *spec = rt2x00dev->spec;
> >       int center_channel;
> >       u16 i;
> >
> > @@ -194,6 +194,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
> >                     struct ieee80211_conf *conf,
> >                     unsigned int ieee80211_flags)
> >  {
> > +     struct hw_mode_spec *spec = rt2x00dev->spec;
> >       struct rt2x00lib_conf libconf;
> >       u16 hw_value;
> >       u16 autowake_timeout;
> > @@ -218,13 +219,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
> >                       hw_value = conf->chandef.chan->hw_value;
> >               }
> >
> > -             memcpy(&libconf.rf,
> > -                    &rt2x00dev->spec.channels[hw_value],
> > -                    sizeof(libconf.rf));
> > -
> > -             memcpy(&libconf.channel,
> > -                    &rt2x00dev->spec.channels_info[hw_value],
> > -                    sizeof(libconf.channel));
> > +             memcpy(&libconf.rf, &spec->channels[hw_value], sizeof(libconf.rf));
> > +             memcpy(&libconf.channel, &spec->channels_info[hw_value], sizeof(libconf.channel));
> >
> >               /* Used for VCO periodic calibration */
> >               rt2x00dev->rf_channel = libconf.rf.channel;
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
> > index edc1f8eac747..3ffbc8aabbae 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
> > @@ -1097,7 +1097,7 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
> >               rt2x00dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
> >       }
> >
> > -     kfree(rt2x00dev->spec.channels_info);
> > +     kfree(rt2x00dev->spec);
> >       kfree(rt2x00dev->chan_survey);
> >  }
> >
> > @@ -1116,7 +1116,7 @@ static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
> >
> >  static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     struct hw_mode_spec *spec = rt2x00dev->spec;
> >       int status;
> >
> >       if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
> > index 79e1fd0a1fbd..479825f8bba9 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
> > @@ -2654,7 +2654,10 @@ static const struct rf_channel rf_vals_seq[] = {
> >
> >  static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     const struct rf_channel *channels;
> > +     unsigned int num_channels = 0;
> > +     unsigned int supported_bands;
> > +     struct hw_mode_spec *spec;
> >       struct channel_info *info;
> >       u8 *tx_power;
> >       unsigned int i;
> > @@ -2693,46 +2696,51 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Initialize hw_mode information.
> >        */
> > -     spec->supported_bands = SUPPORT_BAND_2GHZ;
> > -     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> > +     supported_bands = SUPPORT_BAND_2GHZ;
> >
> >       if (!rt2x00_has_cap_rf_sequence(rt2x00dev)) {
> > -             spec->num_channels = 14;
> > -             spec->channels = rf_vals_noseq;
> > +             num_channels = 14;
> > +             channels = rf_vals_noseq;
> >       } else {
> > -             spec->num_channels = 14;
> > -             spec->channels = rf_vals_seq;
> > +             num_channels = 14;
> > +             channels = rf_vals_seq;
> >       }
> >
> >       if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) {
> > -             spec->supported_bands |= SUPPORT_BAND_5GHZ;
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_seq);
> > +             supported_bands |= SUPPORT_BAND_5GHZ;
> > +             num_channels = ARRAY_SIZE(rf_vals_seq);
> >       }
> >
> >       /*
> >        * Create channel information array
> >        */
> > -     info = kzalloc_objs(*info, spec->num_channels);
> > -     if (!info)
> > +     spec = kzalloc_flex(*spec, channels_info, num_channels);
> > +     if (!spec)
> >               return -ENOMEM;
> >
> > -     spec->channels_info = info;
> > +     spec->num_channels = num_channels;
> > +     spec->channels = channels;
> > +     spec->supported_bands = supported_bands;
> > +     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> >
> >       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
> >       for (i = 0; i < 14; i++) {
> > -             info[i].max_power = MAX_TXPOWER;
> > -             info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> > +             info = &spec->channels_info[i];
> > +             info->max_power = MAX_TXPOWER;
> > +             info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> >       }
> >
> >       if (spec->num_channels > 14) {
> >               tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
> >               for (i = 14; i < spec->num_channels; i++) {
> > -                     info[i].max_power = MAX_TXPOWER;
> > -                     info[i].default_power1 =
> > -                                     TXPOWER_FROM_DEV(tx_power[i - 14]);
> > +                     info = &spec->channels_info[i];
> > +                     info->max_power = MAX_TXPOWER;
> > +                     info->default_power1 = TXPOWER_FROM_DEV(tx_power[i - 14]);
> >               }
> >       }
> >
> > +     rt2x00dev->spec = spec;
> > +
> >       return 0;
> >  }
> >
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt73usb.c b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
> > index d6b7174d087a..17338378329b 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
> > @@ -2088,7 +2088,10 @@ static const struct rf_channel rf_vals_5225_2527[] = {
> >
> >  static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  {
> > -     struct hw_mode_spec *spec = &rt2x00dev->spec;
> > +     const struct rf_channel *channels;
> > +     unsigned int num_channels = 0;
> > +     unsigned int supported_bands;
> > +     struct hw_mode_spec *spec;
> >       struct channel_info *info;
> >       u8 *tx_power;
> >       unsigned int i;
> > @@ -2114,49 +2117,54 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >       /*
> >        * Initialize hw_mode information.
> >        */
> > -     spec->supported_bands = SUPPORT_BAND_2GHZ;
> > -     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> > +     supported_bands = SUPPORT_BAND_2GHZ;
> >
> >       if (rt2x00_rf(rt2x00dev, RF2528)) {
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
> > -             spec->channels = rf_vals_bg_2528;
> > +             num_channels = ARRAY_SIZE(rf_vals_bg_2528);
> > +             channels = rf_vals_bg_2528;
> >       } else if (rt2x00_rf(rt2x00dev, RF5226)) {
> > -             spec->supported_bands |= SUPPORT_BAND_5GHZ;
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_5226);
> > -             spec->channels = rf_vals_5226;
> > +             supported_bands |= SUPPORT_BAND_5GHZ;
> > +             num_channels = ARRAY_SIZE(rf_vals_5226);
> > +             channels = rf_vals_5226;
> >       } else if (rt2x00_rf(rt2x00dev, RF2527)) {
> > -             spec->num_channels = 14;
> > -             spec->channels = rf_vals_5225_2527;
> > +             num_channels = 14;
> > +             channels = rf_vals_5225_2527;
> >       } else if (rt2x00_rf(rt2x00dev, RF5225)) {
> > -             spec->supported_bands |= SUPPORT_BAND_5GHZ;
> > -             spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
> > -             spec->channels = rf_vals_5225_2527;
> > +             supported_bands |= SUPPORT_BAND_5GHZ;
> > +             num_channels = ARRAY_SIZE(rf_vals_5225_2527);
> > +             channels = rf_vals_5225_2527;
> >       }
> >
> >       /*
> >        * Create channel information array
> >        */
> > -     info = kzalloc_objs(*info, spec->num_channels);
> > -     if (!info)
> > +     spec = kzalloc_flex(*spec, channels_info, num_channels);
> > +     if (!spec)
> >               return -ENOMEM;
> >
> > -     spec->channels_info = info;
> > +     spec->num_channels = num_channels;
> > +     spec->channels = channels;
> > +     spec->supported_bands = supported_bands;
> > +     spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
> >
> >       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
> >       for (i = 0; i < 14; i++) {
> > -             info[i].max_power = MAX_TXPOWER;
> > -             info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> > +             info = &spec->channels_info[i];
> > +             info->max_power = MAX_TXPOWER;
> > +             info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> >       }
> >
> >       if (spec->num_channels > 14) {
> >               tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
> >               for (i = 14; i < spec->num_channels; i++) {
> > -                     info[i].max_power = MAX_TXPOWER;
> > -                     info[i].default_power1 =
> > -                                     TXPOWER_FROM_DEV(tx_power[i - 14]);
> > +                     info = &spec->channels_info[i];
> > +                     info->max_power = MAX_TXPOWER;
> > +                     info->default_power1 = TXPOWER_FROM_DEV(tx_power[i - 14]);
> >               }
> >       }
> >
> > +     rt2x00dev->spec = spec;
> > +
> >       return 0;
> >  }
> >
> > --
> > 2.54.0
> >

^ permalink raw reply

* Re: [PATCH wireless-next] wifi: rt2x00: Use device-managed register buffers
From: Rosen Penev @ 2026-07-23 19:11 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, open list
In-Reply-To: <20260723083310.GC4577@wp.pl>

On Thu, Jul 23, 2026 at 1:33 AM Stanislaw Gruszka <stf_xl@wp.pl> wrote:
>
> 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;
whoops. Should I resend?
>
> Regards
> Stanislaw

^ permalink raw reply

* [PATCH 10/36] wifi: remove conditional return with no effect
From: Sang-Heon Jeon @ 2026-07-23 18:45 UTC (permalink / raw)
  To: Julia.Lawall, Miri Korenblit, Ping-Ke Shih
  Cc: cocci, linux-kernel, linux-wireless
In-Reply-To: <20260723184538.3888637-1-ekffu200098@gmail.com>

Both branches of the check return the same value, so the check has
no effect. Remove it and return the value directly.

This is the result of running the Coccinelle script from
scripts/coccinelle/misc/cond_return_no_effect.cocci.

Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
---
 drivers/net/wireless/ath/ath6kl/init.c              | 6 +-----
 drivers/net/wireless/intel/iwlwifi/mvm/link.c       | 6 +-----
 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 7 +------
 drivers/net/wireless/realtek/rtw89/mac.c            | 6 +-----
 drivers/net/wireless/realtek/rtw89/mac_be.c         | 6 +-----
 5 files changed, 5 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 782209dcb782..61fa10d88714 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1566,11 +1566,7 @@ static int ath6kl_init_upload(struct ath6kl *ar)
 
 	address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
 	param = options | 0x20;
-	status = ath6kl_bmi_reg_write(ar, address, param);
-	if (status)
-		return status;
-
-	return status;
+	return ath6kl_bmi_reg_write(ar, address, param);
 }
 
 int ath6kl_init_hw_params(struct ath6kl *ar)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
index b5d252ece2d9..76a548f9aea2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
@@ -278,11 +278,7 @@ int iwl_mvm_disable_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	if (ret)
 		return ret;
 
-	ret = iwl_mvm_remove_link(mvm, vif, link_conf);
-	if (ret)
-		return ret;
-
-	return ret;
+	return iwl_mvm_remove_link(mvm, vif, link_conf);
 }
 
 void iwl_mvm_init_link(struct iwl_mvm_vif_link_info *link)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
index 9b119a51bc30..1ba53e671207 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
@@ -1462,12 +1462,7 @@ static bool _rtl8821ae_init_llt_table(struct ieee80211_hw *hw, u32 boundary)
 			return status;
 	}
 
-	status = _rtl8821ae_llt_write(hw, last_entry_of_txpktbuf,
-				      txpktbuf_bndy);
-	if (!status)
-		return status;
-
-	return status;
+	return _rtl8821ae_llt_write(hw, last_entry_of_txpktbuf, txpktbuf_bndy);
 }
 
 static bool _rtl8821ae_dynamic_rqpn(struct ieee80211_hw *hw, u32 boundary,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 8c395517bd2f..967b42f2b6fb 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -1706,11 +1706,7 @@ static int sys_init_ax(struct rtw89_dev *rtwdev)
 	if (ret)
 		return ret;
 
-	ret = chip_func_en_ax(rtwdev);
-	if (ret)
-		return ret;
-
-	return ret;
+	return chip_func_en_ax(rtwdev);
 }
 
 const struct rtw89_mac_size_set rtw89_mac_size = {
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index f24c119b99f1..b7ba8de9cc78 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -924,11 +924,7 @@ static int sys_init_be(struct rtw89_dev *rtwdev)
 	if (ret)
 		return ret;
 
-	ret = chip_func_en_be(rtwdev);
-	if (ret)
-		return ret;
-
-	return ret;
+	return chip_func_en_be(rtwdev);
 }
 
 static int mac_func_en_be(struct rtw89_dev *rtwdev)
-- 
2.43.0


^ permalink raw reply related


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