* 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
* [PATCH 00/36] treewide: remove conditional returns with no effect
From: Sang-Heon Jeon @ 2026-07-23 18:45 UTC (permalink / raw)
To: Julia.Lawall, Alex Deucher, Alexander Shishkin, Alexandre Belloni,
Andrew Lunn, Andrew Morton, Arkadiusz Kubalewski, Borislav Petkov,
Christian König, Daniel Lezcano, David Airlie,
David S. Miller, Dmitry Torokhov, Eric Dumazet, Florian Westphal,
Greg Kroah-Hartman, Hans de Goede, Hans Verkuil, Heikki Krogerus,
Herbert Xu, Ilpo Järvinen, Jakub Kicinski,
James E.J. Bottomley, Jani Nikula, Jaroslav Kysela,
Jason Gunthorpe, Jiri Pirko, Joerg Roedel (AMD), Johan Hovold,
Jonathan Cameron, Joonas Lahtinen, Julian Anastasov,
Leon Romanovsky, Liam Girdwood, Linus Walleij, Maarten Lankhorst,
Mark Brown, Martin K. Petersen, Matthew Sakai,
Mauro Carvalho Chehab, Maxime Ripard, Michael Turquette,
Mike Rapoport, Miri Korenblit, Nicolas Palix, Pablo Neira Ayuso,
Paolo Abeni, Ping-Ke Shih, Rafael J. Wysocki, Rodrigo Vivi,
Sebastian Reichel, Shuah Khan, Simona Vetter, Simon Horman,
Stephen Boyd, Steve French, Takashi Iwai, Thomas Renninger,
Thomas Zimmermann, Tony Luck, Tvrtko Ursulin, Vadim Fedorenko,
Vinod Koul, Will Deacon, Yazen Ghannam
Cc: cocci, amd-gfx, dmaengine, dm-devel, dri-devel, intel-gfx,
intel-wired-lan, iommu, linux-cifs, linux-clk, linux-crypto,
linux-edac, linux-gpio, linux-iio, linux-input, linux-kernel,
linux-media, linux-mm, linux-pm, linux-rdma, linux-rtc,
linux-s390, linux-scsi, linux-sound, linux-usb, linux-wireless,
lvs-devel, netdev, netfilter-devel, nouveau, platform-driver-x86
Hello,
While reading mm/memblock, I found a conditional return where both
branches return the same value:
err = do_something();
if (err)
return err;
return err;
Such code is usually a leftover from removing a statement between
the two returns, and the tree has about a hundred of these.
Patch 1 adds a Coccinelle script that matches the pattern, including
negation and constant-comparison variants. Where a local variable is
assigned right before the check, the assignment and the two returns
turn into a single return of the assigned expression.
Patches 2-36 are generated by the script, with hand fixes to restore
unexpectedly removed comments and to fix the formatting checkpatch.pl
complained about.
The patches are grouped by subsystem instead of split per file. If
you would rather split, merge or drop your part, just let me know
and I will address it in the next version.
All patches are independent and can be applied separately, but for
everyone's convenience, it would be nice if they were merged through
a single tree.
The series is based on next-20260721.
Sang-Heon Jeon (36):
coccinelle: misc: add cond_return_no_effect.cocci
drm/amd: remove conditional return with no effect
drm/radeon: remove conditional return with no effect
dpll: zl3073x: remove conditional return with no effect
drm/i915: remove conditional return with no effect
drm: remove conditional return with no effect
net: ethernet: remove conditional return with no effect
net: remove conditional return with no effect
net: intel: remove conditional return with no effect
wifi: remove conditional return with no effect
ipvs: remove conditional return with no effect
media: remove conditional return with no effect
ALSA: remove conditional return with no effect
ASoC: remove conditional return with no effect
iio: remove conditional return with no effect
Input: remove conditional return with no effect
clk: remove conditional return with no effect
crypto: drivers - remove conditional return with no effect
dmaengine: qcom_hidma: remove conditional return with no effect
stm class: remove conditional return with no effect
RDMA/ocrdma: remove conditional return with no effect
iommu/s390: remove conditional return with no effect
dm vdo: remove conditional return with no effect
pinctrl: mediatek: remove conditional return with no effect
platform/x86: toshiba_haps: remove conditional return with no effect
power: supply: pm8916_lbc: remove conditional return with no effect
RAS/AMD/ATL: remove conditional return with no effect
regulator: wm831x-isink: remove conditional return with no effect
rtc: pcf2127: remove conditional return with no effect
scsi: mpt3sas: remove conditional return with no effect
thermal/drivers/k3_bandgap: remove conditional return with no effect
USB: serial: ch341: remove conditional return with no effect
usb: typec: fusb302: remove conditional return with no effect
smb: client: remove conditional return with no effect
cpupower: remove conditional return with no effect
memblock: remove conditional return with no effect
drivers/clk/clk-cs2000-cp.c | 6 +-
drivers/clk/clk-lmk04832.c | 12 +-
.../intel/qat/qat_common/adf_gen2_config.c | 8 +-
.../marvell/octeontx2/otx2_cpt_mbox_common.c | 7 +-
drivers/dma/qcom/hidma_ll.c | 6 +-
drivers/dpll/zl3073x/dpll.c | 6 +-
drivers/dpll/zl3073x/out.c | 8 +-
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 6 +-
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 6 +-
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 6 +-
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 6 +-
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 6 +-
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 6 +-
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 6 +-
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 6 +-
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 6 +-
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 6 +-
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 6 +-
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c | 32 ++---
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 6 +-
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 19 +--
.../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 7 +-
.../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 7 +-
.../drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 19 +--
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 6 +-
.../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 10 +-
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c | 19 +--
.../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c | 9 +-
.../drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c | 16 +--
drivers/gpu/drm/i915/display/intel_hdmi.c | 7 +-
drivers/gpu/drm/i915/gvt/gtt.c | 8 +-
drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 6 +-
drivers/gpu/drm/nouveau/dispnv50/disp.c | 14 +-
.../drm/panel/panel-osd-osd101t2587-53ts.c | 7 +-
drivers/gpu/drm/radeon/ci_dpm.c | 6 +-
drivers/gpu/drm/radeon/kv_dpm.c | 30 ++---
drivers/gpu/drm/radeon/si_dpm.c | 14 +-
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 6 +-
drivers/hwtracing/stm/core.c | 8 +-
drivers/iio/light/isl29028.c | 6 +-
drivers/iio/light/tsl2583.c | 14 +-
drivers/iio/magnetometer/ak8974.c | 6 +-
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 7 +-
drivers/input/keyboard/pmic8xxx-keypad.c | 8 +-
drivers/input/mouse/synaptics_i2c.c | 6 +-
drivers/input/rmi4/rmi_smbus.c | 7 +-
drivers/iommu/s390-iommu.c | 8 +-
drivers/md/dm-vdo/encodings.c | 8 +-
drivers/media/i2c/mt9p031.c | 6 +-
.../microchip/microchip-sama7g5-isc.c | 7 +-
.../media/platform/qcom/iris/iris_resources.c | 6 +-
.../media/platform/qcom/venus/pm_helpers.c | 7 +-
drivers/media/platform/renesas/rcar-csi2.c | 6 +-
.../platform/samsung/s3c-camif/camif-core.c | 7 +-
drivers/media/usb/dvb-usb-v2/mxl111sf.c | 12 +-
drivers/media/usb/gspca/jl2005bcd.c | 7 +-
drivers/net/ethernet/amazon/ena/ena_netdev.c | 6 +-
.../ethernet/aquantia/atlantic/aq_macsec.c | 6 +-
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 6 +-
drivers/net/ethernet/freescale/gianfar.c | 6 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 8 +-
drivers/net/ethernet/intel/igb/e1000_i210.c | 6 +-
drivers/net/ethernet/intel/igc/igc_phy.c | 6 +-
.../ethernet/qlogic/netxen/netxen_nic_hw.c | 7 +-
.../ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 6 +-
drivers/net/ethernet/renesas/rtsn.c | 7 +-
drivers/net/phy/microchip_t1.c | 6 +-
drivers/net/pse-pd/tps23881.c | 6 +-
drivers/net/wireless/ath/ath6kl/init.c | 6 +-
drivers/net/wireless/intel/iwlwifi/mvm/link.c | 6 +-
.../wireless/realtek/rtlwifi/rtl8821ae/hw.c | 7 +-
drivers/net/wireless/realtek/rtw89/mac.c | 6 +-
drivers/net/wireless/realtek/rtw89/mac_be.c | 6 +-
.../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 6 +-
drivers/platform/x86/toshiba_haps.c | 6 +-
drivers/power/supply/pm8916_lbc.c | 8 +-
drivers/ras/amd/atl/map.c | 6 +-
drivers/regulator/wm831x-isink.c | 6 +-
drivers/rtc/rtc-pcf2127.c | 7 +-
drivers/scsi/mpt3sas/mpt3sas_base.c | 6 +-
drivers/thermal/k3_bandgap.c | 7 +-
drivers/usb/serial/ch341.c | 8 +-
drivers/usb/typec/tcpm/fusb302.c | 14 +-
fs/smb/client/smb1maperror.c | 6 +-
mm/memblock.c | 7 +-
net/netfilter/ipvs/ip_vs_sync.c | 7 +-
.../misc/cond_return_no_effect.cocci | 121 ++++++++++++++++++
sound/pci/echoaudio/echoaudio_dsp.c | 6 +-
sound/pci/echoaudio/layla24_dsp.c | 6 +-
sound/pci/riptide/riptide.c | 5 +-
sound/soc/amd/acp/acp-mach-common.c | 11 +-
sound/soc/intel/atom/sst-mfld-platform-pcm.c | 7 +-
sound/soc/samsung/smdk_spdif.c | 8 +-
sound/soc/sof/intel/hda-dsp.c | 6 +-
sound/usb/mixer_scarlett.c | 26 ++--
tools/power/cpupower/utils/powercap-info.c | 2 -
102 files changed, 295 insertions(+), 643 deletions(-)
create mode 100644 scripts/coccinelle/misc/cond_return_no_effect.cocci
--
2.43.0
^ permalink raw reply
* [PATCH] mt76: mt7915: simplify mt7915_sys_recovery_set()
From: Dmitry Antipov @ 2026-07-23 18:04 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi, Ryder Lee; +Cc: linux-wireless, Dmitry Antipov
Use convenient ' kstrtou16_from_user()'
to simplify 'mt7915_sys_recovery_set()'.
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
.../net/wireless/mediatek/mt76/mt7915/debugfs.c | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 4d0854fe785b..0413b4fd2d9c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -52,23 +52,12 @@ mt7915_sys_recovery_set(struct file *file, const char __user *user_buf,
struct mt7915_phy *phy = file->private_data;
struct mt7915_dev *dev = phy->dev;
bool band = phy->mt76->band_idx;
- char buf[16];
int ret = 0;
u16 val;
- if (count >= sizeof(buf))
- return -EINVAL;
-
- if (copy_from_user(buf, user_buf, count))
- return -EFAULT;
-
- if (count && buf[count - 1] == '\n')
- buf[count - 1] = '\0';
- else
- buf[count] = '\0';
-
- if (kstrtou16(buf, 0, &val))
- return -EINVAL;
+ ret = kstrtou16_from_user(user_buf, count, 0, &val);
+ if (ret)
+ return ret;
switch (val) {
/*
--
2.55.0
^ permalink raw reply related
* pull-request: wifi: iwlwifi: updates - 2026-07-23
From: Korenblit, Miriam Rachel @ 2026-07-23 17:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Berg, Johannes
The following changes since commit ac798f757d6475dc6fee2ec899980d6740714596:
wifi: mac80211: Route (Re)association req/response to per-STA queue (2026-07-07 10:16:31 +0200)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git/ tags/iwlwifi-next-2026-07-23
for you to fetch changes up to 4a2610a5a9fcf77eaad82bb030ec77ec5e381db8:
wifi: iwlwifi: bump core version for BZ/SC/DR (2026-07-23 20:26:32 +0300)
----------------------------------------------------------------
wifi: iwlwifi: updates - 2026-07-23
This comtains the usual features, fixes and cleanups. Notably:
- Small fixes of bugs reported by LLMs
- LARI command version 14 and 15
- MCC command version 10
- Support for core 107
----------------------------------------------------------------
Avinash Bhatt (1):
wifi: iwlwifi: fw: move SAR defines from acpi.h to regulatory.h
Avraham Stern (4):
wifi: iwlwifi: mld: support aborting an ongoing ftm request
wifi: iwlwifi: mei: check SAP message length before reading it
wifi: iwlwifi: mei: skip data read if length is too short
wifi: iwlwifi: mei: pass correct argument to function
Ayala Beker (1):
wifi: iwlwifi: mld: drop connection on D3 resume failure
Ben Greear (1):
wifi: iwlwifi: Clean dangling pointer in tx path
Dawei Feng (1):
wifi: iwlwifi: dvm: fix memory leak in iwl_op_mode_dvm_start()
Emmanuel Grumbach (16):
wifi: iwlwifi: mvm: fix the FCS truncation logic in d3
wifi: iwlwifi: mld: treat valid BAID without STA as a FW error
wifi: iwlwifi: mvm: validate monitor notif link_id
wifi: iwlwifi: mld: validate D3_END notif size
wifi: iwlwifi: pcie: validate txq_id in txq_enable
wifi: iwlwifi: mvm: reset the smart fifo state upon FW stop
wifi: iwlwifi: mvm: cleanup the driver state after device_powered_off
wifi: iwlwifi: mld: reset the driver state upon firmware recovery
wifi: iwlwifi: mld: validate WoWLAN notif header
wifi: iwlwifi: fix counter type in iwl_fwrt_dump_error_logs
wifi: iwlwifi: mld: fix validation fallback in iwl_mld_notif_is_valid
wifi: iwlwifi: mvm: fix off-by-one in TXF key sanitiser
wifi: iwlwifi: guard against division by zero in iwl_dbg_tlv_alloc_fragments
wifi: iwlwifi: mld: validate wake packet crypto overhead
wifi: iwlwifi: mld: initialize scan-abort status
wifi: iwlwifi: mvm: ignore sync frames when sync is disabled
Haoxiang Li (1):
iwlwifi: dvm: add missing cleaup for on error path
Ilan Peer (1):
wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead
Johannes Berg (3):
wifi: iwlwifi: mvm: remove iwl_mvm_recalc_tcm()
wifi: iwlwifi: claim UHR DBE capability for UHR devices
wifi: iwlwifi: mvm/mld: fix PPE threshold debug print loop
Miri Korenblit (6):
wifi: iwlwifi: add a compile time check for too long hcmds
wifi: iwlwifi: support TTL platform device ID
wifi: iwlwifi: mld: cancel wiphy work before freeing wiphy
wifi: iwlwifi: mld: add PNVM_INIT_COMPLETE_NTFY to the hcmd names
wifi: iwlwifi: mld: move BIOS reading code to where it belongs
wifi: iwlwifi: bump core version for BZ/SC/DR
Pagadala Yesu Anjaneyulu (7):
wifi: iwlwifi: ignore raw-DSM TLV for LARI cmd version 13 and above
wifi: iwlwifi: regulatory: add LARI_CONFIG_CHANGE command v14 support
wifi: iwlwifi: mld: honor FW puncturing capability in MCC response
wifi: iwlwifi: mvm: add LARI_CONFIG_EXTENSION command
wifi: iwlwifi: mld: support update_mcc notification v2
wifi: iwlwifi: mld: add debug log after AP type command
wifi: iwlwifi: regulatory: add LARI v15 DSM support bitmap
Pengpeng Hou (2):
wifi: iwlwifi: validate PNVM SKU TLV length
wifi: iwlwifi: validate UEFI reduced-power SKU TLV length
Praveen Rajendran (1):
wifi: iwlwifi: fw: Fix spelling typo in error-dump.h
Shahar Tzarfati (1):
wifi: iwlwifi: mld: fix read in wake packet notification handler
drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 2 +-
drivers/net/wireless/intel/iwlwifi/cfg/dr.c | 2 +-
drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 2 +-
drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 +-
drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 4 +-
drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 7 +-
drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 5 +-
.../net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 51 +++++++-
drivers/net/wireless/intel/iwlwifi/fw/dump.c | 2 +-
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h | 2 +-
drivers/net/wireless/intel/iwlwifi/fw/file.h | 5 +-
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 6 +
drivers/net/wireless/intel/iwlwifi/fw/regulatory.h | 3 +-
drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 13 +-
drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 28 +++--
drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 4 +-
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 8 +-
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 33 ++++-
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h | 22 +++-
drivers/net/wireless/intel/iwlwifi/mei/main.c | 28 +++--
drivers/net/wireless/intel/iwlwifi/mld/agg.c | 9 +-
drivers/net/wireless/intel/iwlwifi/mld/d3.c | 136 +++++++++++++++++----
.../net/wireless/intel/iwlwifi/mld/ftm-initiator.c | 21 ++++
.../net/wireless/intel/iwlwifi/mld/ftm-initiator.h | 1 +
drivers/net/wireless/intel/iwlwifi/mld/hcmd.h | 9 +-
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 19 ++-
drivers/net/wireless/intel/iwlwifi/mld/mac80211.h | 2 +
drivers/net/wireless/intel/iwlwifi/mld/mcc.c | 26 ++--
drivers/net/wireless/intel/iwlwifi/mld/mld.c | 7 +-
drivers/net/wireless/intel/iwlwifi/mld/mld.h | 2 -
drivers/net/wireless/intel/iwlwifi/mld/notif.c | 5 +-
.../net/wireless/intel/iwlwifi/mld/regulatory.c | 90 +++++++++++---
drivers/net/wireless/intel/iwlwifi/mld/scan.c | 3 +-
drivers/net/wireless/intel/iwlwifi/mld/sta.c | 5 +-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 36 ++++++
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 9 +-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 23 ++--
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 10 +-
drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h | 4 +
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 54 ++------
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 +
.../wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c | 2 +
.../net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c | 11 +-
44 files changed, 536 insertions(+), 182 deletions(-)
^ permalink raw reply
* Re: [PATCH ath-current v2 0/8] wifi: ath12k: support firmware-allocated MLD peer ID
From: Jeff Johnson @ 2026-07-23 17:21 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/19/2026 11:43 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
>
> Best regards,
This version LGTM other than the one commit text nit I can fix.
Will wait for Ramesh's RB tag to pick it up
^ permalink raw reply
* [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
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