Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 13/14] wifi: ath12k: Switch to generic PAS TZ APIs
From: Sumit Garg @ 2026-03-06 10:50 UTC (permalink / raw)
  To: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
	netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	Sumit Garg
In-Reply-To: <20260306105027.290375-1-sumit.garg@kernel.org>

From: Sumit Garg <sumit.garg@oss.qualcomm.com>

Switch ath12k client driver over to generic PAS TZ APIs. Generic PAS TZ
service allows to support multiple TZ implementation backends like QTEE
based SCM PAS service, OP-TEE based PAS service and any further future TZ
backend service.

Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/ahb.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 9a4d34e49104..935f893d04ef 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -5,7 +5,7 @@
  */
 
 #include <linux/dma-mapping.h>
-#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_pas.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
@@ -415,7 +415,7 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
 	}
 
 	/* Authenticate FW image using peripheral ID */
-	ret = qcom_scm_pas_auth_and_reset(pasid);
+	ret = qcom_pas_auth_and_reset(pasid);
 	if (ret) {
 		ath12k_err(ab, "failed to boot the remote processor %d\n", ret);
 		goto err_fw2;
@@ -478,9 +478,9 @@ static void ath12k_ahb_power_down(struct ath12k_base *ab, bool is_suspend)
 	pasid = (u32_encode_bits(ab_ahb->userpd_id, ATH12K_USERPD_ID_MASK)) |
 		ATH12K_AHB_UPD_SWID;
 	/* Release the firmware */
-	ret = qcom_scm_pas_shutdown(pasid);
+	ret = qcom_pas_shutdown(pasid);
 	if (ret)
-		ath12k_err(ab, "scm pas shutdown failed for userPD%d: %d\n",
+		ath12k_err(ab, "pas shutdown failed for userPD%d: %d\n",
 			   ab_ahb->userpd_id, ret);
 }
 
-- 
2.51.0


^ permalink raw reply related

* [PATCH 14/14] firmware: qcom_scm: Remove SCM PAS wrappers
From: Sumit Garg @ 2026-03-06 10:50 UTC (permalink / raw)
  To: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
	netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	Sumit Garg
In-Reply-To: <20260306105027.290375-1-sumit.garg@kernel.org>

From: Sumit Garg <sumit.garg@oss.qualcomm.com>

Now since all the Qcom SCM client drivers have been migrated over to
generic PAS TZ service, let's drop the exported SCM PAS wrappers.

Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
---
 drivers/firmware/qcom/qcom_scm.c       | 84 --------------------------
 include/linux/firmware/qcom/qcom_scm.h | 29 ---------
 2 files changed, 113 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 2d7937ae7c8f..ce68ed294d78 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -554,26 +554,6 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
 		dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
 }
 
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
-							     u32 pas_id,
-							     phys_addr_t mem_phys,
-							     size_t mem_size)
-{
-	struct qcom_pas_context *ctx;
-
-	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
-	if (!ctx)
-		return ERR_PTR(-ENOMEM);
-
-	ctx->dev = dev;
-	ctx->pas_id = pas_id;
-	ctx->mem_phys = mem_phys;
-	ctx->mem_size = mem_size;
-
-	return (struct qcom_scm_pas_context *)ctx;
-}
-EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc);
-
 static int __qcom_scm_pas_init_image(struct device *dev, u32 pas_id,
 				     dma_addr_t mdata_phys,
 				     struct qcom_scm_res *res)
@@ -674,14 +654,6 @@ static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id,
 	return ret ? : res.result[0];
 }
 
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
-			    struct qcom_scm_pas_context *ctx)
-{
-	return __qcom_scm_pas_init_image2(__scm->dev, pas_id, metadata, size,
-					  (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
-
 static void __qcom_scm_pas_metadata_release(struct device *dev,
 					    struct qcom_pas_context *ctx)
 {
@@ -693,13 +665,6 @@ static void __qcom_scm_pas_metadata_release(struct device *dev,
 	ctx->ptr = NULL;
 }
 
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
-{
-	__qcom_scm_pas_metadata_release(__scm->dev,
-					(struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
-
 static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
 				    phys_addr_t addr, phys_addr_t size)
 {
@@ -732,12 +697,6 @@ static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
 	return ret ? : res.result[0];
 }
 
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
-{
-	return __qcom_scm_pas_mem_setup(__scm->dev, pas_id, addr, size);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup);
-
 static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id,
 					  void *input_rt_tzm,
 					  size_t input_rt_size,
@@ -867,18 +826,6 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
 	return ret ? ERR_PTR(ret) : tbl_ptr;
 }
 
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
-						  void *input_rt,
-						  size_t input_rt_size,
-						  size_t *output_rt_size)
-{
-	return __qcom_scm_pas_get_rsc_table2(__scm->dev,
-					     (struct qcom_pas_context *)ctx,
-					     input_rt, input_rt_size,
-					     output_rt_size);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table);
-
 static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
 {
 	int ret;
@@ -908,12 +855,6 @@ static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
 	return ret ? : res.result[0];
 }
 
-int qcom_scm_pas_auth_and_reset(u32 pas_id)
-{
-	return __qcom_scm_pas_auth_and_reset(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset);
-
 static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
 						 struct qcom_pas_context *ctx)
 {
@@ -942,13 +883,6 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
 	return ret;
 }
 
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
-{
-	return __qcom_scm_pas_prepare_and_auth_reset(__scm->dev,
-						     (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset);
-
 static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
 					   u32 pas_id)
 {
@@ -968,12 +902,6 @@ static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
 	return ret ? : res.result[0];
 }
 
-int qcom_scm_set_remote_state(u32 state, u32 id)
-{
-	return __qcom_scm_pas_set_remote_state(__scm->dev, state, id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
-
 static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
 {
 	int ret;
@@ -1003,12 +931,6 @@ static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
 	return ret ? : res.result[0];
 }
 
-int qcom_scm_pas_shutdown(u32 pas_id)
-{
-	return __qcom_scm_pas_shutdown(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown);
-
 static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
 {
 	int ret;
@@ -1030,12 +952,6 @@ static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
 	return ret ? false : !!res.result[0];
 }
 
-bool qcom_scm_pas_supported(u32 pas_id)
-{
-	return __qcom_scm_pas_supported(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_supported);
-
 static struct qcom_pas_ops qcom_pas_ops_scm = {
 	.drv_name		= "qcom_scm",
 	.supported		= __qcom_scm_pas_supported,
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 5747bd191bf1..a0a6bc0229c4 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -64,35 +64,6 @@ bool qcom_scm_is_available(void);
 int qcom_scm_set_cold_boot_addr(void *entry);
 int qcom_scm_set_warm_boot_addr(void *entry);
 void qcom_scm_cpu_power_down(u32 flags);
-int qcom_scm_set_remote_state(u32 state, u32 id);
-
-struct qcom_scm_pas_context {
-	struct device *dev;
-	u32 pas_id;
-	phys_addr_t mem_phys;
-	size_t mem_size;
-	void *ptr;
-	dma_addr_t phys;
-	ssize_t size;
-	bool use_tzmem;
-};
-
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
-							     u32 pas_id,
-							     phys_addr_t mem_phys,
-							     size_t mem_size);
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
-			    struct qcom_scm_pas_context *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 pas_id);
-int qcom_scm_pas_shutdown(u32 pas_id);
-bool qcom_scm_pas_supported(u32 pas_id);
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
-						  void *input_rt, size_t input_rt_size,
-						  size_t *output_rt_size);
-
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);
 
 int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
 int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
-- 
2.51.0


^ permalink raw reply related

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Krzysztof Kozlowski @ 2026-03-06 11:15 UTC (permalink / raw)
  To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	Sumit Garg
In-Reply-To: <20260306105027.290375-3-sumit.garg@kernel.org>

On 06/03/2026 11:50, Sumit Garg wrote:
> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> 
> Qcom platforms has the legacy of using non-standard SCM calls
> splintered over the various kernel drivers. These SCM calls aren't
> compliant with the standard SMC calling conventions which is a
> prerequisite to enable migration to the FF-A specifications from
> Arm.
> 
> OP-TEE as an alternative trusted OS to QTEE can't support these non-
> standard SCM calls. And even for newer architectures QTEE won't be able
> to support SCM calls either with FF-A requirements coming in. And with
> both OP-TEE and QTEE drivers well integrated in the TEE subsystem, it
> makes further sense to reuse the TEE bus client drivers infrastructure.
> 
> The added benefit of TEE bus infrastructure is that there is support
> for discoverable/enumerable services. With that client drivers don't
> have to manually invoke a special SCM call to know the service status.
> 
> So enable the generic Peripheral Authentication Service (PAS) provided
> by the firmware. It acts as the common layer with different TZ
> backends plugged in whether it's an SCM implementation or a proper
> TEE bus based PAS service implementation.
> 
> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> ---
>  drivers/firmware/qcom/Kconfig          |   8 +
>  drivers/firmware/qcom/Makefile         |   1 +
>  drivers/firmware/qcom/qcom_pas.c       | 295 +++++++++++++++++++++++++
>  drivers/firmware/qcom/qcom_pas.h       |  53 +++++
>  include/linux/firmware/qcom/qcom_pas.h |  41 ++++
>  5 files changed, 398 insertions(+)
>  create mode 100644 drivers/firmware/qcom/qcom_pas.c
>  create mode 100644 drivers/firmware/qcom/qcom_pas.h
>  create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index b477d54b495a..8653639d06db 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -6,6 +6,14 @@
>  
>  menu "Qualcomm firmware drivers"
>  
> +config QCOM_PAS
> +	tristate
> +	help
> +	  Enable the generic Peripheral Authentication Service (PAS) provided
> +	  by the firmware. It acts as the common layer with different TZ
> +	  backends plugged in whether it's an SCM implementation or a proper
> +	  TEE bus based PAS service implementation.
> +
>  config QCOM_SCM
>  	select QCOM_TZMEM
>  	tristate
> diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
> index 0be40a1abc13..dc5ab45f906a 100644
> --- a/drivers/firmware/qcom/Makefile
> +++ b/drivers/firmware/qcom/Makefile
> @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
>  obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
>  obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
>  obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
> +obj-$(CONFIG_QCOM_PAS)		+= qcom_pas.o
> diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> new file mode 100644
> index 000000000000..dc04ff1b6be0
> --- /dev/null
> +++ b/drivers/firmware/qcom/qcom_pas.c
> @@ -0,0 +1,295 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device/devres.h>
> +#include <linux/firmware/qcom/qcom_pas.h>
> +#include <linux/of.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +#include "qcom_pas.h"
> +#include "qcom_scm.h"
> +
> +static struct qcom_pas_ops *ops_ptr;

I really dislike this singleton design. And it is not even needed! If
you were storing here some allocated instance of SCM/PAS I could
understand, but singleton for only ops? Just implement one driver (so
SCM + whatever you have here) which will decide which ops to use,
through the probe. Really, this is neither needed nor beneficial.

It actually leads to more problems with this barrier handling, see
further comments.
...

> +
> +/**
> + * qcom_pas_shutdown() - Shut down the remote processor
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns 0 on success.
> + */
> +int qcom_pas_shutdown(u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->shutdown(ops_ptr->dev, pas_id);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_shutdown);
> +
> +/**
> + * qcom_pas_supported() - Check if the peripheral authentication service is
> + *			  available for the given peripheral
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns true if PAS is supported for this peripheral, otherwise false.
> + */
> +bool qcom_pas_supported(u32 pas_id)
> +{
> +	if (ops_ptr)

Lack of barriers here is not looking right. Existing/old code is not a
good example, I fixed only the obvious issue, but new code should be
correct from the beginning.

Barriers should normally be always paired, unless you have some clear
path no concurrent execution can happen here, but such explanation is
missing, look:

> +		return ops_ptr->supported(ops_ptr->dev, pas_id);
> +
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_supported);
> +
> +/**
> + * qcom_pas_is_available() - Check for PAS service
> + *
> + * Returns true on success.
> + */
> +bool qcom_pas_is_available(void)
> +{
> +	/* The barrier is needed to synchronize with client drivers. */


Here. This is pretty pointless/redundant comment. Obviously barriers are
to synchronize with whoever is calling this and only clients are calling.

You must say something useful, not just barrier is a barrier... It's
like documenting mutex "to synchronize".

> +	return !!smp_load_acquire(&ops_ptr);


Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH wireless-next v5 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver
From: Karthikeyan Kathirvel @ 2026-03-06 12:01 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath12k
In-Reply-To: <f256b3e7fa9227caf0bbd6696b81aa79b145945c.camel@sipsolutions.net>



On 3/4/2026 4:19 PM, Johannes Berg wrote:
> On Wed, 2026-03-04 at 14:23 +0530, Karthikeyan Kathirvel wrote:
>>
>> +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
>> @@ -4478,6 +4478,43 @@ static const struct ieee80211_sband_iftype_data sband_capa_2ghz[] = {
>>   			},
>>   			/* PPE threshold information is not supported */
>>   		},
>> +		.uhr_cap = {
> 
> Missing from the context, but this is non-AP side.
> 
>> +			.has_uhr = true,
>> +			.mac = {
>> +				.mac_cap[0] =
>> +					IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
>> +					IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
> 
> "Reserved for a non-AP STA."
> 

Yes it is applicable only for Mobile AP, neither supported for AP or 
non-AP STA, but I see only this I have missed it, remaining seems to be 
correct at to my knowledge.

> Maybe we're just better off doing this as we implement features?
>
Agree! I will leave this decision to you :)

> I've applied patch 1 with some minor edits.
> 
Thanks :)

> johannes


^ permalink raw reply

* BUG: rtw89_8852ce firmware crash (SER catches error) on kernel 6.18.13
From: Sergio @ 2026-03-06 12:31 UTC (permalink / raw)
  To: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 1158 bytes --]

Hi all,

I am experiencing frequent firmware crashes and micro-disconnects with
my RTL8852CE Wi-Fi card. The system seems to be repeatedly recovering
from internal errors (System Error Recovery), which causes lag spikes
and connection drops.

Here is my system and hardware information:

* Kernel: Linux fedora 6.18.13-200.fc43.x86_64 [cite: 1]
* Hardware: Realtek Semiconductor Co., Ltd. RTL8852CE PCIe 802.11ax
Wireless Network Controller [10ec:c852]
* Subsystem: Lenovo Device [17aa:5852]
* Firmware: loaded rtw89/rtw8852c_fw-2.bin [cite: 2]
* Firmware version: 0.27.129.4 (3f1a5302) [cite: 2]

Here is a brief snippet of the dmesg output during the crash:

[12391.222707] rtw89_8852ce 0000:02:00.0: SER catches error: 0x1001 [cite: 9]
[12391.223497] rtw89_8852ce 0000:02:00.0: FW status = 0x6a008108 [cite: 9]
[12391.223521] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x201465c8 [cite: 9]
[12391.223733] rtw89_8852ce 0000:02:00.0: SER catches error: 0x1002 [cite: 10]

I have attached the full dmesg crash log for your review.

Please let me know if there are any specific patches I should test or
if you need more debug information.

Best regards,
Padilla

[-- Attachment #2: rtw89_8852ce_dmesg_crash.txt --]
[-- Type: text/plain, Size: 11086 bytes --]

user@fedora:~$ uname -a
Linux fedora 6.18.13-200.fc43.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Feb 19 19:54:01 UTC 2026 x86_64 GNU/Linux
user@fedora:~$ sudo dmesg | grep rtw89
[sudo] password for user:
[   72.454949] rtw89_8852ce 0000:02:00.0: loaded firmware rtw89/rtw8852c_fw-2.bin
[   72.455625] rtw89_8852ce 0000:02:00.0: enabling device (0000 -> 0003)
[   72.464919] rtw89_8852ce 0000:02:00.0: Firmware version 0.27.129.4 (3f1a5302), cmd version 0, type 1
[   72.464929] rtw89_8852ce 0000:02:00.0: Firmware version 0.27.129.4 (3f1a5302), cmd version 0, type 3
[   72.724485] rtw89_8852ce 0000:02:00.0: chip rfe_type is 1
[   72.745925] rtw89_8852ce 0000:02:00.0: Firmware element BB version: 00 28 00 00
[   72.745955] rtw89_8852ce 0000:02:00.0: Firmware element radio A version: 00 63 00 00
[   72.745978] rtw89_8852ce 0000:02:00.0: Firmware element NCTL version: 00 11 00 00
[   72.746044] rtw89_8852ce 0000:02:00.0: Firmware element TXPWR version: 00 78 00 00
[   72.746049] rtw89_8852ce 0000:02:00.0: Firmware element PWR_TRK version: 00 26 00 00
[   72.746057] rtw89_8852ce 0000:02:00.0: Firmware element REGD version: 00 48 00 39
[   72.749818] rtw89_8852ce 0000:02:00.0: rfkill hardware state changed to enable
[   72.767438] rtw89_8852ce 0000:02:00.0 wlp2s0: renamed from wlan0
[ 8165.734738] rtw89_8852ce 0000:02:00.0: [RX_DCK] S1 RXDCK timeout
[12391.219224] rtw89_8852ce 0000:02:00.0: FW status = 0x6a001108
[12391.219238] rtw89_8852ce 0000:02:00.0: FW BADADDR = 0x18602f98
[12391.219245] rtw89_8852ce 0000:02:00.0: FW EPC/RA = 0x0
[12391.219251] rtw89_8852ce 0000:02:00.0: FW MISC = 0x1030000
[12391.219258] rtw89_8852ce 0000:02:00.0: R_AX_HALT_C2H = 0x999
[12391.219264] rtw89_8852ce 0000:02:00.0: R_AX_SER_DBG_INFO = 0x1000000
[12391.219273] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c944
[12391.219363] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2014670c
[12391.219381] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x20141d22
[12391.219398] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003b97c
[12391.219415] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x201466c6
[12391.219432] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c930
[12391.219449] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c930
[12391.219466] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2014bca0
[12391.219716] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x201466a6
[12391.219806] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2002e956
[12391.219823] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c934
[12391.219840] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c93e
[12391.219858] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x201465d4
[12391.219875] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2014fef6
[12391.219892] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x20141ad6
[12391.219908] rtw89_8852ce 0000:02:00.0: SER catches error: 0x999
[12391.220449] rtw89_8852ce 0000:02:00.0: FW status = 0x6a001108
[12391.220455] rtw89_8852ce 0000:02:00.0: FW BADADDR = 0x18602f98
[12391.220461] rtw89_8852ce 0000:02:00.0: FW EPC/RA = 0x0
[12391.220479] rtw89_8852ce 0000:02:00.0: FW MISC = 0x2070000
[12391.220558] rtw89_8852ce 0000:02:00.0: R_AX_HALT_C2H = 0x1000
[12391.220564] rtw89_8852ce 0000:02:00.0: R_AX_SER_DBG_INFO = 0x1000000
[12391.220573] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220613] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f4
[12391.220630] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fa
[12391.220647] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220664] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220682] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f8
[12391.220699] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ee
[12391.220716] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f4
[12391.220733] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220750] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220790] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f8
[12391.220808] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f8
[12391.220825] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ee
[12391.220842] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220859] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.220875] rtw89_8852ce 0000:02:00.0: --->
[12391.221100] rtw89_8852ce 0000:02:00.0: R_AX_SER_DBG_INFO =0x01000000
[12391.221104] rtw89_8852ce 0000:02:00.0: R_AX_SER_DBG_INFO =0x01000000
[12391.221107] rtw89_8852ce 0000:02:00.0: DBG Counter 1 (R_AX_DRV_FW_HSK_4)=0x00090009
[12391.221111] rtw89_8852ce 0000:02:00.0: DBG Counter 2 (R_AX_DRV_FW_HSK_5)=0x00f600f6
[12391.221116] rtw89_8852ce 0000:02:00.0: R_AX_DMAC_ERR_ISR=0x00000002
[12391.221119] rtw89_8852ce 0000:02:00.0: R_AX_DMAC_ERR_IMR=0x00000000
[12391.221122] rtw89_8852ce 0000:02:00.0: R_AX_WDE_ERR_FLAG_CFG=0x00000000
[12391.221126] rtw89_8852ce 0000:02:00.0: R_AX_PLE_ERR_FLAG_CFG=0x00000000
[12391.221129] rtw89_8852ce 0000:02:00.0: R_AX_PLE_ERRFLAG_MSG=0x00000000
[12391.221132] rtw89_8852ce 0000:02:00.0: R_AX_WDE_ERRFLAG_MSG=0x00000000
[12391.221135] rtw89_8852ce 0000:02:00.0: R_AX_PLE_DBGERR_LOCKEN=0x00000000
[12391.221138] rtw89_8852ce 0000:02:00.0: R_AX_PLE_DBGERR_STS=0x00000000
[12391.221142] rtw89_8852ce 0000:02:00.0: R_AX_SEC_ERR_IMR=0x00000003
[12391.221145] rtw89_8852ce 0000:02:00.0: R_AX_SEC_ERR_ISR=0x00000001
[12391.221148] rtw89_8852ce 0000:02:00.0: R_AX_SEC_ENG_CTRL=0x80001f3f
[12391.221151] rtw89_8852ce 0000:02:00.0: R_AX_SEC_MPDU_PROC=0x00000003
[12391.221154] rtw89_8852ce 0000:02:00.0: R_AX_SEC_CAM_ACCESS=0x00000000
[12391.221157] rtw89_8852ce 0000:02:00.0: R_AX_SEC_CAM_RDATA=0x00000000
[12391.221160] rtw89_8852ce 0000:02:00.0: R_AX_SEC_DEBUG1=0x04ca4c70
[12391.221164] rtw89_8852ce 0000:02:00.0: R_AX_SEC_TX_DEBUG=0x00808000
[12391.221167] rtw89_8852ce 0000:02:00.0: R_AX_SEC_RX_DEBUG=0x02023004
[12391.221178] rtw89_8852ce 0000:02:00.0: sel=0,R_AX_SEC_DEBUG2=0x02000006
[12391.221183] rtw89_8852ce 0000:02:00.0: sel=1,R_AX_SEC_DEBUG2=0x04004d30
[12391.221188] rtw89_8852ce 0000:02:00.0: sel=2,R_AX_SEC_DEBUG2=0x00000000
[12391.221192] rtw89_8852ce 0000:02:00.0: sel=3,R_AX_SEC_DEBUG2=0x00000000
[12391.221197] rtw89_8852ce 0000:02:00.0: sel=4,R_AX_SEC_DEBUG2=0x00404010
[12391.221202] rtw89_8852ce 0000:02:00.0: sel=5,R_AX_SEC_DEBUG2=0x00084800
[12391.221207] rtw89_8852ce 0000:02:00.0: sel=6,R_AX_SEC_DEBUG2=0x24f02b60
[12391.221211] rtw89_8852ce 0000:02:00.0: sel=7,R_AX_SEC_DEBUG2=0x4ca00000
[12391.221216] rtw89_8852ce 0000:02:00.0: sel=8,R_AX_SEC_DEBUG2=0x01010040
[12391.221221] rtw89_8852ce 0000:02:00.0: sel=9,R_AX_SEC_DEBUG2=0x00580401
[12391.221226] rtw89_8852ce 0000:02:00.0: sel=a,R_AX_SEC_DEBUG2=0x00000000
[12391.221230] rtw89_8852ce 0000:02:00.0: sel=b,R_AX_SEC_DEBUG2=0x00000308
[12391.221235] rtw89_8852ce 0000:02:00.0: sel=c,R_AX_SEC_DEBUG2=0x00000000
[12391.221240] rtw89_8852ce 0000:02:00.0: sel=d,R_AX_SEC_DEBUG2=0x00000000
[12391.221245] rtw89_8852ce 0000:02:00.0: sel=e,R_AX_SEC_DEBUG2=0x00000000
[12391.221249] rtw89_8852ce 0000:02:00.0: sel=f,R_AX_SEC_DEBUG2=0x00000000
[12391.221255] rtw89_8852ce 0000:02:00.0: R_AX_CMAC_ERR_ISR [0]=0x00000000
[12391.221259] rtw89_8852ce 0000:02:00.0: R_AX_CMAC_FUNC_EN [0]=0xf000803f
[12391.221262] rtw89_8852ce 0000:02:00.0: R_AX_CK_EN [0]=0xffffffff
[12391.221266] rtw89_8852ce 0000:02:00.0: R_AX_CMAC_ERR_IMR [0]=0x00000000
[12391.221270] rtw89_8852ce 0000:02:00.0: [CMAC] : CMAC1 not enabled
[12391.221273] rtw89_8852ce 0000:02:00.0: R_AX_DBG_ERR_FLAG=0x00000060
[12391.221276] rtw89_8852ce 0000:02:00.0: R_AX_LBC_WATCHDOG=0x0030d800
[12391.221279] rtw89_8852ce 0000:02:00.0: <---
[12391.221280] rtw89_8852ce 0000:02:00.0: SER catches error: 0x1000
[12391.222460] rtw89_8852ce 0000:02:00.0: FW status = 0x6a001108
[12391.222464] rtw89_8852ce 0000:02:00.0: FW BADADDR = 0x18602f98
[12391.222476] rtw89_8852ce 0000:02:00.0: FW EPC/RA = 0x0
[12391.222481] rtw89_8852ce 0000:02:00.0: FW MISC = 0x31f0000
[12391.222485] rtw89_8852ce 0000:02:00.0: R_AX_HALT_C2H = 0x1001
[12391.222488] rtw89_8852ce 0000:02:00.0: R_AX_SER_DBG_INFO = 0x1000000
[12391.222494] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ee
[12391.222509] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fa
[12391.222523] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f4
[12391.222537] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.222552] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ee
[12391.222566] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fc
[12391.222580] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fa
[12391.222594] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ee
[12391.222609] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f8
[12391.222623] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f4
[12391.222637] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ea
[12391.222651] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5fa
[12391.222666] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5f4
[12391.222680] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ee
[12391.222694] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2013f5ea
[12391.222707] rtw89_8852ce 0000:02:00.0: SER catches error: 0x1001
[12391.223497] rtw89_8852ce 0000:02:00.0: FW status = 0x6a008108
[12391.223501] rtw89_8852ce 0000:02:00.0: FW BADADDR = 0x18602f98
[12391.223504] rtw89_8852ce 0000:02:00.0: FW EPC/RA = 0x0
[12391.223508] rtw89_8852ce 0000:02:00.0: FW MISC = 0xff0000
[12391.223512] rtw89_8852ce 0000:02:00.0: R_AX_HALT_C2H = 0x1002
[12391.223515] rtw89_8852ce 0000:02:00.0: R_AX_SER_DBG_INFO = 0xf1000000
[12391.223521] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x201465c8
[12391.223535] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x20141d28
[12391.223550] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2002d976
[12391.223564] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2014661c
[12391.223578] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2014bd36
[12391.223592] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003b9c6
[12391.223607] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c994
[12391.223621] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003ba10
[12391.223635] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2002e974
[12391.223649] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003b98e
[12391.223664] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2014bef0
[12391.223678] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003b9c2
[12391.223692] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2002e98c
[12391.223706] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003ba14
[12391.223720] rtw89_8852ce 0000:02:00.0: [ERR]fw PC = 0x2003c944
[12391.223733] rtw89_8852ce 0000:02:00.0: SER catches error: 0x1002
user@fedora:~$ lspci -nnk | grep -iA2 net
pcilib: Error reading /sys/bus/pci/devices/0000:00:08.3/label: Operation not permitted
01:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 15)
        Subsystem: Lenovo Device [17aa:50ec]
        Kernel driver in use: r8169
--
02:00.0 Network controller [0280]: Realtek Semiconductor Co., Ltd. RTL8852CE PCIe 802.11ax Wireless Network Controller [10ec:c852] (rev 01)
        Subsystem: Lenovo Device [17aa:5852]
        Kernel driver in use: rtw89_8852ce
user@fedora:~$

^ permalink raw reply

* Re: [PATCH wireless-next v8 2/3] wifi: cfg80211: add initial UHR support
From: Johannes Berg @ 2026-03-06 12:43 UTC (permalink / raw)
  To: Harshitha Prem, linux-wireless
  Cc: Karthikeyan Kathirvel, vasanthakumar.thiagarajan,
	Lorenzo Bianconi, ath12k, Jeff Johnson, Ping-Ke Shih,
	Manish Dharanenthiran
In-Reply-To: <f3282007-a11a-4f68-86d8-0945e4979d65@oss.qualcomm.com>

Hi,

> Thank you very much for your patience, and apologies for the delayed
> response. We spent some time discussing this internally and wanted to
> follow up thoughtfully.

Hey, no worries, I'm clearly also not always able to respond quickly, a
lot of things are going on at any given time ...

> > This could get trickier than I imagined - you now have three periods of
> > time:
> > 
> >  - now
> >  - after CSA but before UHR update
> >  - after UHR update
> > 
> > and actually all three might need different UHR operation, since the CSA
> > can change the bandwidth and therefore e.g. DBE/NPCA. The intermediate
> > period ("after CSA but before UHR update") can be captured by the CSA
> > operation (given a template/UHR operation for after) easily.
> > 
> > But I was imagining we capture all this in the operations already, so I
> > guess to do that we would need a "NL80211_CMD_MODIFY_MLD_BSS_UPDATE"
> > command that takes the cookie and updates the post-operation values, so
> > that the changes due to the CSA could be taken into account in the
> > previously started UHR update.
> 
> The idea of introducing an NL80211_CMD_MODIFY_MLD_BSS_UPDATE command
> makes a lot of sense to us. In cases where
> NL80211_CMD_START_MLD_BSS_UPDATE is already in progress, having a modify
> path to update the current beacon seems easier to reason about and
> manage. From that perspective, a pairing such as
> NL80211_CMD_START_MLD_BSS_UPDATE together with
> NL80211_CMD_MODIFY_MLD_BSS_UPDATE feels quite natural.

Yeah, maybe, then it wouldn't ever really go to a normal SET_BEACON any
more, maybe?

I was thinking more for not having to change all the code in hostapd at
a given time, it might be more plausible to still allow SET_BEACON and
just keep giving the counter offsets etc., in case e.g. something "old"
like short-preamble changes.

But clearly hostapd would have to manage those offsets etc. anyway, so
perhaps there's really not going to be any reason to support SET_BEACON
while updates are in progress. But in that case I'd probably argue it
(SET_BEACON) should be disallowed by the kernel, to catch errors.

> Please find below the envisioned design flow for the UHR CU and CSA
> intersection.
> 
> Hostapd (User)          mac80211 (Kernel)           Air / Station
>    |                           |                           |
>  1 | CMD_START_AP [Adv Notif,  |                           |
>    |  Post Notif, Upd Int]     |                           |
>    |-------------------------->|                           |
>    |                           |                           |
>  2 | CMD_START_MLD_BSS_UPDATE  |                           |
>    | [Link:0, CurTmpl+Offset   |                           |
>    |  (All), Timer, PostTmpl   |                           |
>    |  (All), Type:UHR_CU,      |                           |
>    |  Post UHR Op element]     |                           |
>    |-------------------------->|                           |
>    |                           |                           |
>  3 |                           | [Set Tmpl, Timer: Adv=10, |
>    |                           |  Post=10, TIM Update]     |
>    |                           |                           |
>  4 |         Cookie X          |                           |
>    |<--------------------------|                           |
>    |                           |                           |
>  5 | EVENT_UHR_CU (CU_START)   |                           |
>    |<--------------------------|                           |

Not sure what the event does really, at this point? It kind of starts
immediately anyway, no? But it also doesn't matter for this high-level
discussion.

>    |                           |                           |
>  6 |                           | Beacons: 10, 9, 8...      |
>    |                           |-------------------------->|
>    |                           |                           |
>  7 | [CSA Triggered: Link0,    |                           |
>    |  Count 10. Sees Cookie X] |                           |
>    |                           |                           |
>  8 | CMD_START_MLD_BSS_UPDATE  |                           |
>    | [Type:CSA, Link:0, Tmpls, |                           |
>    |  Cookie X + Offset,       |                           |
>    |  Post Tmpl (No UHR ele)]  |                           |
>    |-------------------------->|                           |

Not sure I understand the "No UHR ele" part - surely the post template
still has UHR? Or did you mean "UHR parameter update"?

Not that there's a race here - "Sees Cookie X", but who knows the cookie
X is even still valid?

But I think we can pretty much solve that racy by marking a cookie X
invalid in the kernel (or even FW?) and rejecting the new
CMD_START_MLD_BSS_UPDATE operation that still refers to Cookie X -
hostapd would just have to know about that specific rejection reason (I
guess netlink extended status would point to the wrong cookie attr or
so) and then rebuild the templates without taking the update with cookie
X into account.

But with that race aside, yeah, seems reasonable.

>    |                           |                           |
>  9 |         Cookie Y          |                           |
>    |<--------------------------|                           |
>    |                           |                           |
> 10 | CMD_CH_SWITCH_STARTED_    |                           |
>    | NOTIFY                    |                           |
>    |<--------------------------|                           |

I don't know - this was started by CMD_START_MLD_BSS_UPDATE too, so
probably should be some generic notification about it, or like I said
above, maybe isn't even needed at all?

(I think a good chunk of the channel switch notification is code
unification between client and AP, does the AP even use the start
notification?)

>    |                           |                           |
> 11 |                           | Beacons: X=7, Y=10        |
>    |                           |-------------------------->|
>    |                           |                           |
> 12 | CMD_MODIFY_MLD_BSS_UPDATE |                           |
>    | (Cookie X Post Tmpl w/    |                           |
>    |  Chan Info, 3 Links)      |                           |
>    |-------------------------->|                           |
>    |                           |                           |
> 13 |                           | Beacons: X=1, Y=4         |
>    |                           |-------------------------->|
>    |                           |                           |
> 14 |                           | [X=0: Modify Cur Tmpl     |
>    |                           |  w/ Post UHR Op element]  |
>    |                           |                           |
> 15 | EVENT_UHR_CU              |                           |
>    | (CU_ADVANCE_COMPLETE)     |                           |
>    |<--------------------------|                           |

That should have Cookie X somehow as an attribute, of course :)

Really all the events should have, but here clearly you meant X since
the other operation isn't done yet.

>    |                           |                           |
> 16 | CMD_MODIFY_MLD_BSS_UPDATE |                           |
>    | (Cookie Y Post Tmpl w/    |                           |
>    |  UHR Op + Param elements) |                           |
>    |-------------------------->|                           |

What's this doing? Didn't we have post-Y templates already in the prior
command? Otherwise isn't this quite a bit racy? Though I guess we have a
whole beacon interval for hostapd to update everything, which really
ought to be sufficient (though hostapd may need to stop being single-
threaded ...)

>    |                           |                           |
> 17 |                           | Beacons: X=127, Y=3       |
>    |                           |-------------------------->|
>    |                           |                           |
> 18 |                           | Beacons: X=128/129,       |
>    |                           |          Y=2/1 (CSA done) |
>    |                           |-------------------------->|
>    |                           |                           |
> 19 |                           | [Y=0: Set Post Tmpl       |
>    |                           |  cookie Y, UHR Param      |
>    |                           |  Off, X=130]              |
>    |                           |                           |
> 20 | CMD_CH_SWITCH_NOTIFY      |                           |
>    |<--------------------------|                           |

(similar comment as above wrt. what notifications are needed)

>    |                           |                           |
> 21 | CMD_MLD_BSS_UPDATE_NOTIFY |                           |
>    | (Complete Cookie Y)       |                           |
>    |<--------------------------|                           |

Right.

>    |                           |                           |
> 22 | CMD_MODIFY_MLD_BSS_UPDATE |                           |
>    | (Cookie X Post Tmpl w/    |                           |
>    |  UpdatedChan Info)        |                           |
>    |-------------------------->|                           |

"X post" is a bit misleading ... it's still ongoing, because it's
changed now but not really _after_ the update X, it's still advertising
the update X has happened. So in some way the flow is still there.

But it does point out that we need basically three (additional)
templates for a UHR update:

 - announcing the upcoming update
 - announcing the update happened
 - back to normal state afterwards

Which, perhaps, is indeed a bit too much to offload all to the kernel
even in terms of the API, because if you mix another operation in (here
in your example the channel switch Y), you end up with even more
templates ...

So I'm coming around to the idea that you have a notification and
hostapd has to update the templates at that point.

>    |                           |                           |
> 23 |                           | Beacons Continue...       |
>    |                           |-------------------------->|
>    |                           |                           |
> 24 |                           | Probe Request             |
>    |                           |<--------------------------|
>    |                           | [Fetch TBTT]              |
>    |     send_mgmt (TBTT)      |                           |
>    |<--------------------------|                           |
>    |                           |                           |
> 25 | send_mgmt (Probe Resp     |                           |
>    |  w/ TBTT in UHR Param)    |                           |
>    |-------------------------->|                           |
>    |                           |                           |

Not sure I follow this part regarding the "TBTT" thing. Are you saying
the RX of the probe request would have a TBTT attached to it? But does
it matter, what matters is the TX? And that's probably impossible to get
right?

> The diagram uses a number of abbreviations, so an explanation is
> provided below for clarity.

Oops, sorry, didn't see that before starting to reply, so maybe I missed
something above. I'd go back and check, but I'll have to pick up my kids
soon.

> Step 14
> 	The driver/firmware can update the current beacon template with
> the post‑UHR operation element. Until the advance notification interval
> completes, the UHR operation element would not yet be updated.

Not sure I follow, are you envisioning the driver/firmware changing the
beacon contents? I was envisioning it basically always getting the right
template at the right time, and only filling the counters per their
offsets.

> A few potential concerns to consider:
> 
> 1. Carrying both the current and post‑beacon templates for all
> affiliated links of an MLD might make the NL message fairly large. we
> are not sure how well that fits with existing practice, since multipart
> handling seems to be used mostly for dump commands. As an alternate, can
> we have multiple commands with message id and reassemble it?

It's input into the kernel, so the size doesn't matter, I think? For
notifications that might be an issue, and dumpit is used for data going
_out_ of the kernel so userspace doesn't have to have arbitrarily large
buffers ready before it knows the data, but on input I don't see how it
matters.

> 2. There may be a small sequencing aspect worth thinking through. For
> example, if a UHR_CU operation is close to completion and we are about
> to apply its post‑beacon template, but before hostapd processes
> EVENT_UHR_CU with CU_POST_NOTIF_COMPLETE it issues a
> START_MLD_BSS_UPDATE for CSA, we could potentially end up using an
> unexpected version of the current beacon template. This may already be
> handled by the existing flow, but it seemed worth calling out for
> completeness.

Yes, I agree, it's something we need to think about. I mentioned that a
bit above, perhaps one way to solve the race is to have a reject built
in based on the cookie(s) being used, that could technically even be
pushed all the way down to the firmware if you really wanted to.

johannes

^ permalink raw reply

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Jeff Johnson @ 2026-03-06 15:40 UTC (permalink / raw)
  To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	Sumit Garg
In-Reply-To: <20260306105027.290375-3-sumit.garg@kernel.org>

On 3/6/2026 2:50 AM, Sumit Garg wrote:
>  drivers/firmware/qcom/Kconfig          |   8 +
>  drivers/firmware/qcom/Makefile         |   1 +
>  drivers/firmware/qcom/qcom_pas.c       | 295 +++++++++++++++++++++++++

kernel-doc is throwing some warnings in this file which I've listed below.
kernel-doc is also throwing warnings in some of the other files touched by
this series, but since those are presumably preexisting I didn't bother to
mention them. Just want to avoid adding new warnings.

>  drivers/firmware/qcom/qcom_pas.h       |  53 +++++
>  include/linux/firmware/qcom/qcom_pas.h |  41 ++++
>  5 files changed, 398 insertions(+)
>  create mode 100644 drivers/firmware/qcom/qcom_pas.c
>  create mode 100644 drivers/firmware/qcom/qcom_pas.h
>  create mode 100644 include/linux/firmware/qcom/qcom_pas.h
...
> +/**
> + * qcom_pas_mem_setup() - Prepare the memory related to a given peripheral
> + *			  for firmware loading
> + * @pas_id:	peripheral authentication service id
> + * @addr:	start address of memory area to prepare
> + * @size:	size of the memory area to prepare
> + *
> + * Returns 0 on success.

kernel-doc complains:
Warning: drivers/firmware/qcom/qcom_pas.c:103 No description found for return
value of 'qcom_pas_mem_setup'

should use the kernel-doc Return: tag

 * Return: 0 on success

(Returns: is also accepted although not documented)

> + */
...
> +/**
> + * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
> + *				   and reset the remote processor
> + * @pas_id:	peripheral authentication service id
> + *
> + * Return 0 on success.

hmmm, kernel-doc didn't complain about this one so the script must accept
'Return' without the ":" (but not 'Returns' without the ":").

Suggest changing to Return: to be conformant with the actual documentation:
<https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#function-documentation>

> + */
> +int qcom_pas_auth_and_reset(u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->auth_and_reset(ops_ptr->dev, pas_id);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_auth_and_reset);
...
> +/**
> + * qcom_pas_set_remote_state() - Set the remote processor state
> + * @state:	peripheral state
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns 0 on success.

Warning: drivers/firmware/qcom/qcom_pas.c:217 No description found for return
value of 'qcom_pas_set_remote_state'

> + */
...
> +/**
> + * qcom_pas_shutdown() - Shut down the remote processor
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns 0 on success.

Warning: drivers/firmware/qcom/qcom_pas.c:232 No description found for return
value of 'qcom_pas_shutdown'

> + */
...
> +/**
> + * qcom_pas_supported() - Check if the peripheral authentication service is
> + *			  available for the given peripheral
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns true if PAS is supported for this peripheral, otherwise false.

Warning: drivers/firmware/qcom/qcom_pas.c:248 No description found for return
value of 'qcom_pas_supported'

> + */
...
> +/**
> + * qcom_pas_is_available() - Check for PAS service
> + *
> + * Returns true on success.

Warning: drivers/firmware/qcom/qcom_pas.c:262 No description found for return
value of 'qcom_pas_is_available'

> + */

^ permalink raw reply

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Jeff Johnson @ 2026-03-06 15:49 UTC (permalink / raw)
  To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	Sumit Garg
In-Reply-To: <20260306105027.290375-3-sumit.garg@kernel.org>

On 3/6/2026 2:50 AM, Sumit Garg wrote:

I missed one k-doc warning...

> +/**
> + * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware

s/scm_//

Warning: drivers/firmware/qcom/qcom_pas.c:173 expecting prototype for
qcom_scm_pas_auth_and_reset(). Prototype was for qcom_pas_auth_and_reset() instead

> + *				   and reset the remote processor
> + * @pas_id:	peripheral authentication service id
> + *
> + * Return 0 on success.
> + */
> +int qcom_pas_auth_and_reset(u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->auth_and_reset(ops_ptr->dev, pas_id);
> +
> +	return -ENODEV;
> +}

^ permalink raw reply

* Re: [PATCH 13/14] wifi: ath12k: Switch to generic PAS TZ APIs
From: Jeff Johnson @ 2026-03-06 15:52 UTC (permalink / raw)
  To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	Sumit Garg
In-Reply-To: <20260306105027.290375-14-sumit.garg@kernel.org>

On 3/6/2026 2:50 AM, Sumit Garg wrote:
> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> 
> Switch ath12k client driver over to generic PAS TZ APIs. Generic PAS TZ
> service allows to support multiple TZ implementation backends like QTEE
> based SCM PAS service, OP-TEE based PAS service and any further future TZ
> backend service.
> 
> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>

Acked-by: Jeff Johnson <jjohnson@kernel.org>


^ permalink raw reply

* Re: [PATCH v3 3/3] wifi: wcn36xx: Add support for WCN3610
From: Kerigan Creighton @ 2026-03-06 18:05 UTC (permalink / raw)
  To: Loic Poulain
  Cc: linux-wireless, wcn36xx, andersson, mathieu.poirier,
	linux-remoteproc, linux-arm-msm, robh, krzk+dt, conor+dt,
	devicetree, linux-kernel
In-Reply-To: <CAFEp6-2MVFXfz4=_Em7YkH_Vx5VcryWMdDnrwe8C0=TnBmknZA@mail.gmail.com>

On Fri, Mar 6, 2026 at 2:41 AM Loic Poulain
<loic.poulain@oss.qualcomm.com> wrote:
>
> > STA_POWERSAVE resulted in BMPS errors and unstable
> > functionality, thus it has been disabled for just this
> > chip.
> >
> > Tested on an Anki Vector 1.0 and 2.0 robot with 3
> > different APs. Support for other WCN36xx chips has not
> > been affected.
> >
> > Signed-off-by: Kerigan Creighton <kerigancreighton@gmail.com>
>
> STA_POWERSAVE is disabled, but the interface still enters BMPS mode as
> controlled by mac80211. If you get the opportunity, It would be useful
> to air-capture the power‑save entry and exit events when this occurs,
> so we can verify that the transitions behave as expected.
>
> Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>

[re-sent with full cc list]
I only had the chance to test it with one AP, but wireshark does show
clean power-save entry and exit transitions. Once I do more testing,
I will make a v4 which:

 - Adds these power-save findings to the patch 3 commit message
 - Amends all commit messages so they are wrapped better
 - Amends patch 1 to include a better description of the hardware

Thanks for the review,
- Kerigan

On Fri, Mar 6, 2026 at 2:41 AM Loic Poulain
<loic.poulain@oss.qualcomm.com> wrote:
>
> On Fri, Mar 6, 2026 at 1:44 AM Kerigan Creighton
> <kerigancreighton@gmail.com> wrote:
> >
> > The WCN3610 has a lot in common with the other wcn36xx
> > chips, so much of that code was reused.
> >
> > The WCN3610 requires specific configuration values for
> > stable Wi-Fi. Without these values, there's packet loss.
> > An extra CFG table was made so other chips are not affected.
> >
> > ENABLE_DYNAMIC_RA_START_RATE=0 was discovered from the
> > downstream prima driver. That brought it from 95% to 5%
> > packet loss. The rest of the CFG values came from my own
> > observations and experimentation. The current settings
> > allow for 0% packet loss.
> >
> > STA_POWERSAVE resulted in BMPS errors and unstable
> > functionality, thus it has been disabled for just this
> > chip.
> >
> > Tested on an Anki Vector 1.0 and 2.0 robot with 3
> > different APs. Support for other WCN36xx chips has not
> > been affected.
> >
> > Signed-off-by: Kerigan Creighton <kerigancreighton@gmail.com>
>
> STA_POWERSAVE is disabled, but the interface still enters BMPS mode as
> controlled by mac80211. If you get the opportunity, It would be useful
> to air-capture the power‑save entry and exit events when this occurs,
> so we can verify that the transitions behave as expected.
>
> Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
>
>
>
> > ---
> > Changes in v2:
> >  - Move wcn36xx driver changes to the end of the patch set.
> >
> > Changes in v3:
> >  - Describe where the CFG values came from in the wcn36xx
> >    driver patch [Konrad].
> > ---
> >  drivers/net/wireless/ath/wcn36xx/main.c    |  4 +-
> >  drivers/net/wireless/ath/wcn36xx/smd.c     | 61 +++++++++++++++++++++-
> >  drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  1 +
> >  3 files changed, 64 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
> > index c3f0860873..6c90c13251 100644
> > --- a/drivers/net/wireless/ath/wcn36xx/main.c
> > +++ b/drivers/net/wireless/ath/wcn36xx/main.c
> > @@ -1438,7 +1438,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
> >                 BIT(NL80211_IFTYPE_MESH_POINT);
> >
> >         wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
> > -       if (wcn->rf_id != RF_IRIS_WCN3620)
> > +       if (wcn->rf_id != RF_IRIS_WCN3620 && wcn->rf_id != RF_IRIS_WCN3610)
> >                 wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
> >
> >         if (wcn->rf_id == RF_IRIS_WCN3680)
> > @@ -1535,6 +1535,8 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
> >         /* External RF module */
> >         iris_node = of_get_child_by_name(mmio_node, "iris");
> >         if (iris_node) {
> > +               if (of_device_is_compatible(iris_node, "qcom,wcn3610"))
> > +                       wcn->rf_id = RF_IRIS_WCN3610;
> >                 if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
> >                         wcn->rf_id = RF_IRIS_WCN3620;
> >                 if (of_device_is_compatible(iris_node, "qcom,wcn3660") ||
> > diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
> > index 813553edcb..8d5a746de7 100644
> > --- a/drivers/net/wireless/ath/wcn36xx/smd.c
> > +++ b/drivers/net/wireless/ath/wcn36xx/smd.c
> > @@ -83,6 +83,61 @@ static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = {
> >         WCN36XX_CFG_VAL(LINK_FAIL_TX_CNT, 1000),
> >  };
> >
> > +static struct wcn36xx_cfg_val wcn3610_cfg_vals[] = {
> > +       WCN36XX_CFG_VAL(CURRENT_TX_ANTENNA, 1),
> > +       WCN36XX_CFG_VAL(CURRENT_RX_ANTENNA, 1),
> > +       WCN36XX_CFG_VAL(LOW_GAIN_OVERRIDE, 0),
> > +       WCN36XX_CFG_VAL(POWER_STATE_PER_CHAIN, 785),
> > +       WCN36XX_CFG_VAL(CAL_PERIOD, 5),
> > +       WCN36XX_CFG_VAL(CAL_CONTROL, 1),
> > +       WCN36XX_CFG_VAL(PROXIMITY, 0),
> > +       WCN36XX_CFG_VAL(NETWORK_DENSITY, 3),
> > +       WCN36XX_CFG_VAL(MAX_MEDIUM_TIME, 6000),
> > +       WCN36XX_CFG_VAL(MAX_MPDUS_IN_AMPDU, 64),
> > +       WCN36XX_CFG_VAL(RTS_THRESHOLD, 2347),
> > +       WCN36XX_CFG_VAL(SHORT_RETRY_LIMIT, 15),
> > +       WCN36XX_CFG_VAL(LONG_RETRY_LIMIT, 15),
> > +       WCN36XX_CFG_VAL(FRAGMENTATION_THRESHOLD, 8000),
> > +       WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ZERO, 5),
> > +       WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ONE, 10),
> > +       WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_TWO, 15),
> > +       WCN36XX_CFG_VAL(FIXED_RATE, 0),
> > +       WCN36XX_CFG_VAL(RETRYRATE_POLICY, 4),
> > +       WCN36XX_CFG_VAL(RETRYRATE_SECONDARY, 131),
> > +       WCN36XX_CFG_VAL(RETRYRATE_TERTIARY, 129),
> > +       WCN36XX_CFG_VAL(FORCE_POLICY_PROTECTION, 5),
> > +       WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_24GHZ, 1),
> > +       WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_5GHZ, 5),
> > +       WCN36XX_CFG_VAL(DEFAULT_RATE_INDEX_5GHZ, 5),
> > +       WCN36XX_CFG_VAL(DEFAULT_RATE_INDEX_24GHZ, 6),
> > +       WCN36XX_CFG_VAL(MAX_BA_SESSIONS, 40),
> > +       WCN36XX_CFG_VAL(PS_DATA_INACTIVITY_TIMEOUT, 200),
> > +       WCN36XX_CFG_VAL(PS_ENABLE_BCN_FILTER, 1),
> > +       WCN36XX_CFG_VAL(PS_ENABLE_RSSI_MONITOR, 1),
> > +       WCN36XX_CFG_VAL(NUM_BEACON_PER_RSSI_AVERAGE, 20),
> > +       WCN36XX_CFG_VAL(STATS_PERIOD, 10),
> > +       WCN36XX_CFG_VAL(CFP_MAX_DURATION, 30000),
> > +       WCN36XX_CFG_VAL(FRAME_TRANS_ENABLED, 0),
> > +       WCN36XX_CFG_VAL(BA_THRESHOLD_HIGH, 128),
> > +       WCN36XX_CFG_VAL(MAX_BA_BUFFERS, 2560),
> > +       WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0),
> > +       WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
> > +       WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
> > +       WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
> > +       WCN36XX_CFG_VAL(BTC_EXECUTION_MODE, 2),
> > +       WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN, 90000),
> > +       WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN, 60000),
> > +       WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN, 30000),
> > +       WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_IDLE_BT_LEN, 120000),
> > +       WCN36XX_CFG_VAL(BTC_FAST_WLAN_CONN_PREF, 1),
> > +       WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 120000),
> > +       WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 30000),
> > +       WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
> > +       WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
> > +       WCN36XX_CFG_VAL(ENABLE_DYNAMIC_RA_START_RATE, 0),
> > +       WCN36XX_CFG_VAL(LINK_FAIL_TX_CNT, 1000),
> > +};
> > +
> >  static struct wcn36xx_cfg_val wcn3680_cfg_vals[] = {
> >         WCN36XX_CFG_VAL(CURRENT_TX_ANTENNA, 1),
> >         WCN36XX_CFG_VAL(CURRENT_RX_ANTENNA, 1),
> > @@ -632,6 +687,9 @@ int wcn36xx_smd_start(struct wcn36xx *wcn)
> >         if (wcn->rf_id == RF_IRIS_WCN3680) {
> >                 cfg_vals = wcn3680_cfg_vals;
> >                 cfg_elements = ARRAY_SIZE(wcn3680_cfg_vals);
> > +       } else if (wcn->rf_id == RF_IRIS_WCN3610) {
> > +               cfg_vals = wcn3610_cfg_vals;
> > +               cfg_elements = ARRAY_SIZE(wcn3610_cfg_vals);
> >         } else {
> >                 cfg_vals = wcn36xx_cfg_vals;
> >                 cfg_elements = ARRAY_SIZE(wcn36xx_cfg_vals);
> > @@ -2380,7 +2438,8 @@ int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn)
> >         mutex_lock(&wcn->hal_mutex);
> >         INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ);
> >
> > -       wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, STA_POWERSAVE);
> > +       if (wcn->rf_id != RF_IRIS_WCN3610)
> > +               wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, STA_POWERSAVE);
> >         if (wcn->rf_id == RF_IRIS_WCN3680) {
> >                 wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, DOT11AC);
> >                 wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, WLAN_CH144);
> > diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> > index 7ee79593cd..cb409d48f7 100644
> > --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> > +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> > @@ -96,6 +96,7 @@ enum wcn36xx_ampdu_state {
> >  #define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power)
> >
> >  #define RF_UNKNOWN     0x0000
> > +#define RF_IRIS_WCN3610        0x3610
> >  #define RF_IRIS_WCN3620        0x3620
> >  #define RF_IRIS_WCN3660        0x3660
> >  #define RF_IRIS_WCN3680        0x3680
> > --
> > 2.53.0
> >

^ permalink raw reply

* [PATCH] rtw88: add TX power limit support to 114 and 130 channels
From: Thadeu Lima de Souza Cascardo @ 2026-03-06 18:41 UTC (permalink / raw)
  To: Ping-Ke Shih, Kalle Valo, Yan-Hsuan Chuang
  Cc: linux-wireless, kernel-dev, Thadeu Lima de Souza Cascardo

Though 114 and 130 are not usual channels, they are found in the wild with
setups using 5350MHz as the center frequency of a 80MHz setup.

rtw88 supports that, but issues a WARNING because it cannot find the TX
power limit for those channels.

Fix this by using the lower TX power limit from adjacent 40MHz channels.

After that change, there is no WARNING and the 80MHz bandwidth is still
used.

[    9.980715] ------------[ cut here ]------------
[    9.980721] invalid arguments, band=1, bw=2, path=0, rate=44, ch=130
[    9.980726] WARNING: drivers/net/wireless/realtek/rtw88/phy.c:2213 at rtw_get_tx_power_params+0x541/0x920 [rtw88_core], CPU#0: iwd/1227
[    9.980755] Modules linked in: ccm algif_aead des3_ede_x86_64 cbc des_generic libdes md4 nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 cmac algif_hash algif_skcipher af_alg ramoops snd_soc_acp5x_mach nf_tables reed_solomon bnep joydev mousedev snd_acp5x_pcm_dma snd_acp5x_i2s amdgpu snd_sof_amd_acp63 rtw88_8822ce amd_atl snd_sof_amd_vangogh intel_rapl_msr rtw88_8822c snd_sof_amd_acp intel_rapl_common snd_sof_pci rtw88_pci amdxcp snd_sof kvm_amd rtw88_core i2c_algo_bit snd_sof_utils snd_hda_codec_atihdmi hid_multitouch drm_ttm_helper snd_hda_codec_hdmi snd_sof_xtensa_dsp snd_soc_cs35l41_spi kvm ttm mac80211 btusb snd_pci_ps snd_soc_cs35l41 snd_hda_intel snd_soc_acpi_amd_match btrtl drm_exec snd_soc_cs35l41_lib drm_panel_backlight_quirks snd_soc_acpi_amd_sdca_quirks btintel gpu_sched snd_hda_codec snd_soc_wm_adsp libarc4 snd_soc_sdca irqbypass drm_suballoc_helper btbcm snd_soc_nau8821 cs_dsp
[    9.980895]  snd_hwdep ghash_clmulni_intel drm_buddy btmtk spd5118 snd_pci_acp6x aesni_intel cfg80211 snd_soc_core snd_hda_core drm_display_helper atkbd rapl snd_pci_acp5x libps2 snd_intel_dspcfg bluetooth snd_compress snd_acp_config hid_steam snd_intel_sdw_acpi cdc_acm hid_generic vivaldi_fmap wdat_wdt snd_pcm pcspkr tpm_crb rfkill snd_soc_acpi snd_timer ccp cec video sp5100_tco ltrf216a wmi opt3001 tpm_tis i2c_hid_acpi snd i2c_hid industrialio tpm_tis_core soundcore 8250_dw k10temp i2c_piix4 i2c_smbus mac_hid pkcs8_key_parser ntsync hid_playstation led_class_multicolor hid_nintendo ff_memless i2c_dev crypto_user loop dm_mod nfnetlink zram tpm libaescfb overlay ext4 crc16 mbcache jbd2 vfat fat usbhid btrfs libblake2b xor raid6_pq sdhci_pci nvme serio_raw sdhci_uhs2 sdhci nvme_core cqhci nvme_keyring mmc_core i8042 nvme_auth hkdf serio spi_amd
[    9.981052] CPU: 0 UID: 0 PID: 1227 Comm: iwd Not tainted 6.19.0-08324-gf4457a734418 #15 PREEMPT(full)  d98827284d7dd170a54c85b32d8344cb5d6741ce
[    9.981058] Hardware name: Valve Jupiter/Jupiter, BIOS F7A0133 08/05/2024
[    9.981062] RIP: 0010:rtw_get_tx_power_params+0x553/0x920 [rtw88_core]
[    9.981079] Code: 5e 41 5f e9 6f 79 b2 e6 44 8b 5c 24 24 44 88 14 24 48 8d 3d 8f 72 40 00 44 8b 44 24 1c 8b 4c 24 18 89 f2 45 0f b6 cb 44 89 fe <67> 48 0f b9 3a 48 8b 43 38 44 0f b6 14 24 0f b6 68 45 41 88 6e 02
[    9.981083] RSP: 0018:ffffd0cd418f2f10 EFLAGS: 00010246
[    9.981087] RAX: 0000000000000031 RBX: ffff8f3b1ad72060 RCX: 0000000000000000
[    9.981090] RDX: 0000000000000002 RSI: 0000000000000001 RDI: ffffffffc13b41d0
[    9.981093] RBP: 00000000000000fa R08: 000000000000002c R09: 0000000000000082
[    9.981096] R10: 0000000000000004 R11: 0000000000000082 R12: 000000000000002c
[    9.981099] R13: 0000000000000000 R14: ffffd0cd418f2f8b R15: 0000000000000001
[    9.981102] FS:  00007f10c85edb80(0000) GS:ffff8f3e85c8f000(0000) knlGS:0000000000000000
[    9.981105] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    9.981108] CR2: 00007f8f50200270 CR3: 00000001244cc000 CR4: 0000000000350ef0
[    9.981111] Call Trace:
[    9.981116]  <TASK>
[    9.981125]  rtw_phy_get_tx_power_index+0x43/0x180 [rtw88_core da6d95ee8f8ea7f3fd6d7370ca8f98e1f6d9c5c7]
[    9.981147]  rtw_phy_set_tx_power_level+0xdc/0x140 [rtw88_core da6d95ee8f8ea7f3fd6d7370ca8f98e1f6d9c5c7]
[    9.981168]  rtw_set_channel+0xb7/0x130 [rtw88_core da6d95ee8f8ea7f3fd6d7370ca8f98e1f6d9c5c7]
[    9.981188]  rtw_ops_config+0x81/0xc0 [rtw88_core da6d95ee8f8ea7f3fd6d7370ca8f98e1f6d9c5c7]
[    9.981207]  drv_config+0x2b/0xd0 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981276]  ieee80211_add_chanctx+0x57/0x130 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981352]  ieee80211_new_chanctx+0x33/0xc0 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981432]  _ieee80211_link_use_channel+0x2da/0x360 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981550]  ieee80211_prep_channel+0x2ef/0x550 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981686]  ieee80211_prep_connection+0x20a/0x500 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981807]  ieee80211_mgd_auth+0x2c5/0x4f0 [mac80211 bbf26b8ca8c7853f2522289e0ff504e0b8b8a571]
[    9.981904]  ? srso_return_thunk+0x5/0x5f
[    9.981912]  ? srso_return_thunk+0x5/0x5f
[    9.981917]  ? __cfg80211_get_bss+0x1e9/0x2d0 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.981986]  cfg80211_mlme_auth+0xb7/0x1b0 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982052]  cfg80211_conn_do_work+0x449/0x490 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982147]  cfg80211_connect+0x3ac/0x7a0 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982209]  nl80211_connect+0x624/0x8a0 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982269]  ? srso_return_thunk+0x5/0x5f
[    9.982274]  ? _copy_to_iter+0x8d/0x5f0
[    9.982295]  genl_family_rcv_msg_doit+0x103/0x160
[    9.982309]  genl_rcv_msg+0x1b5/0x2c0
[    9.982315]  ? __pfx_nl80211_pre_doit+0x10/0x10 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982372]  ? __pfx_nl80211_connect+0x10/0x10 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982426]  ? __pfx_nl80211_post_doit+0x10/0x10 [cfg80211 6f7b2df30576ef94720b632aca066e9e39311de2]
[    9.982482]  ? __pfx_genl_rcv_msg+0x10/0x10
[    9.982488]  netlink_rcv_skb+0x52/0x100
[    9.982499]  genl_rcv+0x28/0x40
[    9.982504]  netlink_unicast+0x28a/0x3e0
[    9.982511]  netlink_sendmsg+0x228/0x480
[    9.982520]  __sys_sendto+0x1f1/0x200
[    9.982535]  __x64_sys_sendto+0x24/0x30
[    9.982539]  do_syscall_64+0x11b/0x7e0
[    9.982546]  ? srso_return_thunk+0x5/0x5f
[    9.982550]  ? do_syscall_64+0x11b/0x7e0
[    9.982556]  ? srso_return_thunk+0x5/0x5f
[    9.982560]  ? __sys_sendmsg+0x88/0xf0
[    9.982564]  ? __seccomp_filter+0x42/0x5d0
[    9.982574]  ? srso_return_thunk+0x5/0x5f
[    9.982578]  ? do_syscall_64+0x11b/0x7e0
[    9.982585]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[    9.982591] RIP: 0033:0x7f10c8681006
[    9.982596] Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08
[    9.982599] RSP: 002b:00007ffdebfc83a0 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
[    9.982605] RAX: ffffffffffffffda RBX: 00005596e451b8f0 RCX: 00007f10c8681006
[    9.982608] RDX: 0000000000000068 RSI: 00005596e453cc80 RDI: 0000000000000004
[    9.982611] RBP: 00007ffdebfc83c0 R08: 0000000000000000 R09: 0000000000000000
[    9.982613] R10: 0000000000000000 R11: 0000000000000202 R12: 00005596e453cc80
[    9.982616] R13: 00005596e453d040 R14: 0000000000000001 R15: 0000000000000000
[    9.982626]  </TASK>
[    9.982629] ---[ end trace 0000000000000000 ]---

Fixes: fa6dfe6bff24 ("rtw88: resolve order of tx power setting routines")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
 drivers/net/wireless/realtek/rtw88/main.h |  2 +-
 drivers/net/wireless/realtek/rtw88/phy.c  | 36 +++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 1ab70214ce36eb1785a6f642b83cc30748d9ec18..652120f7397f5a58ec2e7364fdf4e52f7340e63a 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -47,7 +47,7 @@ extern bool rtw_edcca_enabled;
 extern const struct ieee80211_ops rtw_ops;
 
 #define RTW_MAX_CHANNEL_NUM_2G 14
-#define RTW_MAX_CHANNEL_NUM_5G 49
+#define RTW_MAX_CHANNEL_NUM_5G 51
 
 struct rtw_dev;
 struct rtw_debugfs;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index e2ac5c6fd5002996534e061b6f45dfdd65728525..af9f7f3550890469f9dd58aa7aad8ec30ad596cf 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -1602,7 +1602,9 @@ static const u8 rtw_channel_idx_5g[RTW_MAX_CHANNEL_NUM_5G] = {
 	36,  38,  40,  42,  44,  46,  48, /* Band 1 */
 	52,  54,  56,  58,  60,  62,  64, /* Band 2 */
 	100, 102, 104, 106, 108, 110, 112, /* Band 3 */
+	114, /* Compute from adjacent center frequencies */
 	116, 118, 120, 122, 124, 126, 128, /* Band 3 */
+	130, /* Compute from adjacent center frequencies */
 	132, 134, 136, 138, 140, 142, 144, /* Band 3 */
 	149, 151, 153, 155, 157, 159, 161, /* Band 4 */
 	165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
@@ -1732,6 +1734,38 @@ static void rtw_xref_txpwr_lmt(struct rtw_dev *rtwdev)
 		rtw_xref_txpwr_lmt_by_bw(rtwdev, regd);
 }
 
+static void
+__cfg_txpwr_lmt_extra_channels(struct rtw_hal *hal, u8 regd, u8 bw, u8 rs)
+{
+	u8 channels[] = { 114, 130 };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(channels); i++) {
+		int idx, upper_idx, lower_idx;
+		int upper_limit, lower_limit;
+
+		idx = rtw_channel_to_idx(PHY_BAND_5G, channels[i]);
+		upper_idx = rtw_channel_to_idx(PHY_BAND_5G, channels[i] + 4);
+		lower_idx = rtw_channel_to_idx(PHY_BAND_5G, channels[i] - 4);
+		if (idx < 0 || upper_idx < 0 || lower_idx < 0)
+			WARN(1, "invalid channel index when computing TX power limit for extra channels");
+		upper_limit = hal->tx_pwr_limit_5g[regd][bw][rs][upper_idx];
+		lower_limit = hal->tx_pwr_limit_5g[regd][bw][rs][lower_idx];
+		hal->tx_pwr_limit_5g[regd][bw][rs][idx] = min(lower_limit, upper_limit);
+	}
+}
+
+static void
+rtw_cfg_twpwr_lmt_extra_channels(struct rtw_dev *rtwdev, u8 regd)
+{
+	u8 bw, rs;
+
+	for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
+		for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++)
+			__cfg_txpwr_lmt_extra_channels(&rtwdev->hal, regd,
+						       bw, rs);
+}
+
 static void
 __cfg_txpwr_lmt_by_alt(struct rtw_hal *hal, u8 regd, u8 regd_alt, u8 bw, u8 rs)
 {
@@ -1773,6 +1807,8 @@ void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev,
 	}
 
 	for (i = 0; i < RTW_REGD_MAX; i++) {
+		rtw_cfg_twpwr_lmt_extra_channels(rtwdev, i);
+
 		if (i == RTW_REGD_WW)
 			continue;
 

---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20260306-rtw88_channel130-3a33ec369249

Best regards,
-- 
Thadeu Lima de Souza Cascardo <cascardo@igalia.com>


^ permalink raw reply related

* Re: [BUG] wifi: mt76: mt7925u: probe with driver mt7925u failed with error -110
From: Nick @ 2026-03-06 19:23 UTC (permalink / raw)
  To: Sean Wang
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Deren Wu, Leon Yen
In-Reply-To: <CAGp9LzrTMALkJKrGANTCzeG4KUDGwC1YJc8SRKNRriH3a9bnRQ@mail.gmail.com>

> > Reference: https://github.com/morrownr/USB-WiFi/issues/688#issuecomment-3999038526
> >
> > The above thread is rather lengthy as we have been working on this
> > issue since Dec. 25.
> >
> > Testing with a Netgear A9000 USB WiFi adapter (mt7925u driver). Kernel
> > 7.0 rc2 and a x86_64 system. Additional testing with older kernels was
> > also performed with the same results.
> >
> > Problem description:
> >
> > Cold boot shows the adapter coming up and operating normally.
> >
> > Removing the adapter from the USB port and replacing it shows the
> > adapter coming up and operating normally.
> >
> > A warm reboot does not provide a WiFi interface and shows the
> > following in the system log:
> >
> > mt7925u 2-3.2:1.0: probe with driver mt7925u failed with error -110
> >
> > Using the commands rmmod and modeprobe do not provide a WiFi interface.
> >
> > Thoughts: The problem likely is not the module teardown. The problem
> > seems to be that the firmware (or the mt7925u driver) leaves the
> > adapter in a strange state such that a power cycle of the adapter
> > hardware is needed before the mt7925u driver can properly initialize
> > it a second time.
> >
>
> Hi Nick,
>
> Could you enable debug logs and check whether the driver can still
> read the correct chip ID after a warm reboot, and at which step the
> initialization fails before the -110 error? Thanks for continuing to
> test and gather this useful information.
>
>          Sean

Hi Sean,

Github user @exct has performed the testing requested and provides the
following report:

mt7925u Probe Failure Debug Report
Adapter: Netgear A9000 (USB ID 0846:9072, MediaTek MT7925)
Kernel: 6.19.6-2-cachyos

Summary
The driver can read the correct chip ID after a warm reload. The
failure occurs before firmware is loaded, inside
mt792xu_wfsys_reset(), which times out waiting for the WiFi subsystem
to reinitialize. -ETIMEDOUT (-110) is returned and the probe aborts.

Findings

Question: Chip ID readable after warm reload?
Answer: Yes — MT_HW_CHIPID = 0x7925, MT_HW_REV = 0x8a00

Question: Which step fails?
Answer: mt792xu_wfsys_reset() — WFSYS_INIT_DONE never asserted

Question: Does it reach mt792xu_mcu_power_on()?
Answer: No

Question: Does it reach mt7925_run_firmware()?
Answer: No

Probe Sequence Trace

mt7925u_probe()
  ├─ mt76_alloc_device()             OK
  ├─ __mt76u_init()                  OK
  ├─ read MT_HW_CHIPID (0x70010200)  → 0x00007925  ✓
  ├─ read MT_HW_REV    (0x70010204)  → 0x00008a00  ✓
  ├─ read MT_CONN_ON_MISC (0x7c0600f0) → 0x00000003  ← FW_N9_RDY is SET
  ├─ enters mt792xu_wfsys_reset()    ← triggered because FW_N9_RDY = 1
  │    ├─ write MT_CBTOP_RGU_WF_SUBSYS_RST  (assert reset)
  │    ├─ write MT_CBTOP_RGU_WF_SUBSYS_RST  (deassert reset)
  │    ├─ poll MT_UDMA_CONN_INFRA_STATUS (0x74000a20) → 0x00000000
  │    ├─ poll MT_UDMA_CONN_INFRA_STATUS (0x74000a20) → 0x00000000
  │    └─ ... timeout after ~212 ms → return -ETIMEDOUT
  └─ goto error:  (mt76u_queues_deinit + mt76_free_device)

Root Cause

After rmmod, the firmware leaves FW_N9_RDY asserted in
MT_CONN_ON_MISC. On re-probe, the driver correctly detects this and
calls mt792xu_wfsys_reset() to recover. However, the WiFi subsystem
never signals completion — WFSYS_INIT_DONE in
MT_UDMA_CONN_INFRA_STATUS (reg 0x74000a20) stays 0x00000000 throughout
the retry loop. The subsystem is stuck in a state that the software
reset path cannot recover from. Only a full USB power cycle clears it.

Hope this helps,

Nick

^ permalink raw reply

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Trilok Soni @ 2026-03-06 19:47 UTC (permalink / raw)
  To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, mukesh.ojha, pavan.kondeti, jorge.ramirez, tonyh,
	vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
	jens.wiklander, op-tee, apurupa, skare, Sumit Garg
In-Reply-To: <20260306105027.290375-3-sumit.garg@kernel.org>

On 3/6/2026 2:50 AM, Sumit Garg wrote:
> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> 
> Qcom platforms has the legacy of using non-standard SCM calls
> splintered over the various kernel drivers.

You are using multiple conflicting terminologies here. In the first statement
you have used "non-standard" and immediately you have used "aren't complaint".

Which ARM document dictates that "standard" and "compliance" here? Are these
SCM calls are using the vendor space per the spec, and if yes what does
non-standard means here. 

 These SCM calls aren't
> compliant with the standard SMC calling conventions which is a
> prerequisite to enable migration to the FF-A specifications from
> Arm.
> 
> OP-TEE as an alternative trusted OS to QTEE can't support these non-

What is QTEE? 

> standard SCM calls. And even for newer architectures QTEE won't be able

meaning of architecture please? Are you referring ARMv9.x or SOC architecture
or software architecture? What does "newer" means? Is there
any example available in public or are you ready to share? 

> to support SCM calls either with FF-A requirements coming in. And with
> both OP-TEE and QTEE drivers well integrated in the TEE subsystem, it
> makes further sense to reuse the TEE bus client drivers infrastructure.
> 
> The added benefit of TEE bus infrastructure is that there is support
> for discoverable/enumerable services. With that client drivers don't
> have to manually invoke a special SCM call to know the service status.
> 
> So enable the generic Peripheral Authentication Service (PAS) provided
> by the firmware. It acts as the common layer with different TZ
> backends plugged in whether it's an SCM implementation or a proper
> TEE bus based PAS service implementation.

I haven't checked cover letter in detail, but did you tested these patches
w/ the devices which doesn't support these new facilities? 

> 
> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> ---
>  drivers/firmware/qcom/Kconfig          |   8 +
>  drivers/firmware/qcom/Makefile         |   1 +
>  drivers/firmware/qcom/qcom_pas.c       | 295 +++++++++++++++++++++++++
>  drivers/firmware/qcom/qcom_pas.h       |  53 +++++
>  include/linux/firmware/qcom/qcom_pas.h |  41 ++++
>  5 files changed, 398 insertions(+)
>  create mode 100644 drivers/firmware/qcom/qcom_pas.c
>  create mode 100644 drivers/firmware/qcom/qcom_pas.h
>  create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index b477d54b495a..8653639d06db 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -6,6 +6,14 @@
>  
>  menu "Qualcomm firmware drivers"
>  
> +config QCOM_PAS
> +	tristate
> +	help
> +	  Enable the generic Peripheral Authentication Service (PAS) provided
> +	  by the firmware. It acts as the common layer with different TZ
> +	  backends plugged in whether it's an SCM implementation or a proper
> +	  TEE bus based PAS service implementation.
> +
>  config QCOM_SCM
>  	select QCOM_TZMEM
>  	tristate
> diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
> index 0be40a1abc13..dc5ab45f906a 100644
> --- a/drivers/firmware/qcom/Makefile
> +++ b/drivers/firmware/qcom/Makefile
> @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
>  obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
>  obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
>  obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
> +obj-$(CONFIG_QCOM_PAS)		+= qcom_pas.o
> diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> new file mode 100644
> index 000000000000..dc04ff1b6be0
> --- /dev/null
> +++ b/drivers/firmware/qcom/qcom_pas.c
> @@ -0,0 +1,295 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device/devres.h>
> +#include <linux/firmware/qcom/qcom_pas.h>
> +#include <linux/of.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>

are you sure you are using functionalities from these header files?

I couldn't find slab.h usage quickly and also qcom_scm.h. Can you please confirm?

> +
> +#include "qcom_pas.h"
> +#include "qcom_scm.h"
> +
> +static struct qcom_pas_ops *ops_ptr;
> +
> +/**
> + * devm_qcom_pas_context_alloc() - Allocate peripheral authentication service
> + *				   context for a given peripheral
> + *
> + * PAS context is device-resource managed, so the caller does not need
> + * to worry about freeing the context memory.
> + *
> + * @dev:	  PAS firmware device
> + * @pas_id:	  peripheral authentication service id
> + * @mem_phys:	  Subsystem reserve memory start address
> + * @mem_size:	  Subsystem reserve memory size
> + *
> + * Returns: The new PAS context, or ERR_PTR() on failure.
> + */
> +struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev,
> +						     u32 pas_id,
> +						     phys_addr_t mem_phys,
> +						     size_t mem_size)
> +{
> +	struct qcom_pas_context *ctx;
> +
> +	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> +	if (!ctx)
> +		return ERR_PTR(-ENOMEM);
> +
> +	ctx->dev = dev;
> +	ctx->pas_id = pas_id;
> +	ctx->mem_phys = mem_phys;
> +	ctx->mem_size = mem_size;
> +
> +	return ctx;
> +}
> +EXPORT_SYMBOL_GPL(devm_qcom_pas_context_alloc);
> +
> +/**
> + * qcom_pas_init_image() - Initialize peripheral authentication service state
> + *			   machine for a given peripheral, using the metadata
> + * @pas_id:	peripheral authentication service id
> + * @metadata:	pointer to memory containing ELF header, program header table
> + *		and optional blob of data used for authenticating the metadata
> + *		and the rest of the firmware
> + * @size:	size of the metadata
> + * @ctx:	optional pas context
> + *
> + * Return: 0 on success.
> + *
> + * Upon successful return, the PAS metadata context (@ctx) will be used to
> + * track the metadata allocation, this needs to be released by invoking
> + * qcom_pas_metadata_release() by the caller.
> + */
> +int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> +			struct qcom_pas_context *ctx)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->init_image(ops_ptr->dev, pas_id,
> +					   metadata, size, ctx);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_init_image);
> +
> +/**
> + * qcom_pas_metadata_release() - release metadata context
> + * @ctx:	pas context
> + */
> +void qcom_pas_metadata_release(struct qcom_pas_context *ctx)
> +{
> +	if (!ctx || !ctx->ptr)
> +		return;
> +
> +	if (ops_ptr)
> +		ops_ptr->metadata_release(ops_ptr->dev, ctx);
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_metadata_release);
> +
> +/**
> + * qcom_pas_mem_setup() - Prepare the memory related to a given peripheral
> + *			  for firmware loading
> + * @pas_id:	peripheral authentication service id
> + * @addr:	start address of memory area to prepare
> + * @size:	size of the memory area to prepare
> + *
> + * Returns 0 on success.
> + */
> +int qcom_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->mem_setup(ops_ptr->dev, pas_id, addr, size);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_mem_setup);
> +
> +/**
> + * qcom_pas_get_rsc_table() - Retrieve the resource table in passed output buffer
> + *			      for a given peripheral.
> + *
> + * Qualcomm remote processor may rely on both static and dynamic resources for
> + * its functionality. Static resources typically refer to memory-mapped
> + * addresses required by the subsystem and are often embedded within the
> + * firmware binary and dynamic resources, such as shared memory in DDR etc.,
> + * are determined at runtime during the boot process.
> + *
> + * On Qualcomm Technologies devices, it's possible that static resources are
> + * not embedded in the firmware binary and instead are provided by TrustZone.
> + * However, dynamic resources are always expected to come from TrustZone. This

Is it confirmed that it will always come from Trustzone? Is it not possible
that it can come from trusted controller - bypassing the trustzone? Assuming that
such controller is never modified by anyone else including final device makers and
blessed by the trust boundaries. 

Is this design going to scale if we put the MCU doing the heavy lifting instead? 


> + * indicates that for Qualcomm devices, all resources (static and dynamic) will
> + * be provided by TrustZone PAS service.
> + *
> + * If the remote processor firmware binary does contain static resources, they
> + * should be passed in input_rt. These will be forwarded to TrustZone for
> + * authentication. TrustZone will then append the dynamic resources and return
> + * the complete resource table in output_rt_tzm.
> + *
> + * If the remote processor firmware binary does not include a resource table,
> + * the caller of this function should set input_rt as NULL and input_rt_size
> + * as zero respectively.
> + *
> + * More about documentation on resource table data structures can be found in
> + * include/linux/remoteproc.h
> + *
> + * @ctx:	    PAS context
> + * @pas_id:	    peripheral authentication service id
> + * @input_rt:       resource table buffer which is present in firmware binary
> + * @input_rt_size:  size of the resource table present in firmware binary
> + * @output_rt_size: TrustZone expects caller should pass worst case size for
> + *		    the output_rt_tzm.
> + *
> + * Return:
> + *  On success, returns a pointer to the allocated buffer containing the final
> + *  resource table and output_rt_size will have actual resource table size from
> + *  TrustZone. The caller is responsible for freeing the buffer. On failure,
> + *  returns ERR_PTR(-errno).
> + */
> +struct resource_table *qcom_pas_get_rsc_table(struct qcom_pas_context *ctx,
> +					      void *input_rt,
> +					      size_t input_rt_size,
> +					      size_t *output_rt_size)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->get_rsc_table(ops_ptr->dev, ctx, input_rt,
> +					      input_rt_size, output_rt_size);
> +
> +	return ERR_PTR(-ENODEV);
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_get_rsc_table);
> +
> +/**
> + * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
> + *				   and reset the remote processor
> + * @pas_id:	peripheral authentication service id
> + *
> + * Return 0 on success.
> + */
> +int qcom_pas_auth_and_reset(u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->auth_and_reset(ops_ptr->dev, pas_id);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_auth_and_reset);
> +
> +/**
> + * qcom_pas_prepare_and_auth_reset() - Prepare, authenticate, and reset the
> + *				       remote processor
> + *
> + * @ctx:	Context saved during call to qcom_scm_pas_context_init()
> + *
> + * This function performs the necessary steps to prepare a PAS subsystem,
> + * authenticate it using the provided metadata, and initiate a reset sequence.
> + *
> + * It should be used when Linux is in control setting up the IOMMU hardware
> + * for remote subsystem during secure firmware loading processes. The
> + * preparation step sets up a shmbridge over the firmware memory before
> + * TrustZone accesses the firmware memory region for authentication. The
> + * authentication step verifies the integrity and authenticity of the firmware
> + * or configuration using secure metadata. Finally, the reset step ensures the
> + * subsystem starts in a clean and sane state.
> + *
> + * Return: 0 on success, negative errno on failure.
> + */
> +int qcom_pas_prepare_and_auth_reset(struct qcom_pas_context *ctx)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->prepare_and_auth_reset(ops_ptr->dev, ctx);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_prepare_and_auth_reset);
> +
> +/**
> + * qcom_pas_set_remote_state() - Set the remote processor state
> + * @state:	peripheral state
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns 0 on success.
> + */
> +int qcom_pas_set_remote_state(u32 state, u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->set_remote_state(ops_ptr->dev, state, pas_id);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_set_remote_state);
> +
> +/**
> + * qcom_pas_shutdown() - Shut down the remote processor
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns 0 on success.
> + */
> +int qcom_pas_shutdown(u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->shutdown(ops_ptr->dev, pas_id);
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_shutdown);
> +
> +/**
> + * qcom_pas_supported() - Check if the peripheral authentication service is
> + *			  available for the given peripheral
> + * @pas_id:	peripheral authentication service id
> + *
> + * Returns true if PAS is supported for this peripheral, otherwise false.
> + */
> +bool qcom_pas_supported(u32 pas_id)
> +{
> +	if (ops_ptr)
> +		return ops_ptr->supported(ops_ptr->dev, pas_id);
> +
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_supported);
> +
> +/**
> + * qcom_pas_is_available() - Check for PAS service
> + *
> + * Returns true on success.
> + */
> +bool qcom_pas_is_available(void)
> +{
> +	/* The barrier is needed to synchronize with client drivers. */
> +	return !!smp_load_acquire(&ops_ptr);
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_is_available);
> +
> +/**
> + * qcom_pas_ops_register() - Register PAS service ops
> + * @ops:	PAS service ops pointer
> + */
> +void qcom_pas_ops_register(struct qcom_pas_ops *ops)
> +{
> +	if (!qcom_pas_is_available())
> +		/* The barrier is needed to synchronize with client drivers. */
> +		smp_store_release(&ops_ptr, ops);
> +	else
> +		pr_err("qcom_pas: ops already registered\n");
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_ops_register);
> +
> +/**
> + * qcom_pas_ops_unregister() - Unregister PAS service ops
> + */
> +void qcom_pas_ops_unregister(void)
> +{
> +	/* The barrier is needed to synchronize with client drivers. */
> +	smp_store_release(&ops_ptr, NULL);
> +}
> +EXPORT_SYMBOL_GPL(qcom_pas_ops_unregister);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Sumit Garg <sumit.garg@oss.qualcomm.com>");

What is the convention for Qualcomm authored drivers? In some drivers
I find that Qualcomm doesn't add MODULE_AUTHOR. Can Qualcomm community
clarify it here. I prefer consistency here for the Qualcomm submissions. 

> +MODULE_DESCRIPTION("Qualcomm common TZ PAS driver");
> diff --git a/drivers/firmware/qcom/qcom_pas.h b/drivers/firmware/qcom/qcom_pas.h
> new file mode 100644
> index 000000000000..4ebed22178f8
> --- /dev/null
> +++ b/drivers/firmware/qcom/qcom_pas.h
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#ifndef __QCOM_PAS_INT_H
> +#define __QCOM_PAS_INT_H
> +
> +struct device;
> +
> +/**
> + * struct qcom_pas_ops - Qcom Peripheral Authentication Service (PAS) ops
> + * @drv_name:			PAS driver name.
> + * @dev:			PAS device pointer.
> + * @supported:			Peripheral supported callback.
> + * @init_image:			Peripheral image initialization callback.
> + * @mem_setup:			Peripheral memory setup callback.
> + * @get_rsc_table:		Peripheral get resource table callback.
> + * @prepare_and_auth_reset:	Peripheral prepare firmware authentication and
> + *				reset callback.
> + * @auth_and_reset:		Peripheral firmware authentication and reset
> + *				callback.
> + * @set_remote_state:		Peripheral set remote state callback.
> + * @shutdown:			Peripheral shutdown callback.
> + * @metadata_release:		Image metadata release callback.
> + */
> +struct qcom_pas_ops {
> +	const char *drv_name;
> +	struct device *dev;
> +	bool (*supported)(struct device *dev, u32 pas_id);
> +	int (*init_image)(struct device *dev, u32 pas_id,
> +			  const void *metadata, size_t size,
> +			  struct qcom_pas_context *ctx);
> +	int (*mem_setup)(struct device *dev, u32 pas_id,
> +			 phys_addr_t addr, phys_addr_t size);
> +	void *(*get_rsc_table)(struct device *dev,
> +			       struct qcom_pas_context *ctx,
> +			       void *input_rt,
> +			       size_t input_rt_size,
> +			       size_t *output_rt_size);

void * or resource_table * as return? 

> +	int (*prepare_and_auth_reset)(struct device *dev,
> +				      struct qcom_pas_context *ctx);
> +	int (*auth_and_reset)(struct device *dev, u32 pas_id);
> +	int (*set_remote_state)(struct device *dev, u32 state, u32 pas_id);
> +	int (*shutdown)(struct device *dev, u32 pas_id);
> +	void (*metadata_release)(struct device *dev,
> +				 struct qcom_pas_context *ctx);
> +};
> +
> +void qcom_pas_ops_register(struct qcom_pas_ops *ops);
> +void qcom_pas_ops_unregister(void);
> +
> +#endif /* __QCOM_PAS_INT_H */
> diff --git a/include/linux/firmware/qcom/qcom_pas.h b/include/linux/firmware/qcom/qcom_pas.h
> new file mode 100644
> index 000000000000..ef7328ecfa47
> --- /dev/null
> +++ b/include/linux/firmware/qcom/qcom_pas.h
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#ifndef __QCOM_PAS_H
> +#define __QCOM_PAS_H
> +
> +#include <linux/err.h>
> +#include <linux/types.h>
> +
> +struct qcom_pas_context {
> +	struct device *dev;
> +	u32 pas_id;
> +	phys_addr_t mem_phys;
> +	size_t mem_size;
> +	void *ptr;
> +	dma_addr_t phys;
> +	ssize_t size;
> +	bool use_tzmem;
> +};
> +
> +bool qcom_pas_is_available(void);
> +struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev,
> +						     u32 pas_id,
> +						     phys_addr_t mem_phys,
> +						     size_t mem_size);
> +int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> +			struct qcom_pas_context *ctx);
> +struct resource_table *qcom_pas_get_rsc_table(struct qcom_pas_context *ctx,
> +					      void *input_rt, size_t input_rt_size,
> +					      size_t *output_rt_size);
> +int qcom_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
> +int qcom_pas_auth_and_reset(u32 pas_id);
> +int qcom_pas_prepare_and_auth_reset(struct qcom_pas_context *ctx);
> +int qcom_pas_set_remote_state(u32 state, u32 pas_id);
> +int qcom_pas_shutdown(u32 pas_id);
> +bool qcom_pas_supported(u32 pas_id);
> +void qcom_pas_metadata_release(struct qcom_pas_context *ctx);
> +
> +#endif /* __QCOM_PAS_H */


^ permalink raw reply

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Trilok Soni @ 2026-03-06 20:00 UTC (permalink / raw)
  To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, mukesh.ojha, pavan.kondeti, jorge.ramirez, tonyh,
	vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
	jens.wiklander, op-tee, apurupa, skare, Sumit Garg
In-Reply-To: <e0a86461-c136-4371-99cf-c0b0d31443a3@oss.qualcomm.com>

On 3/6/2026 11:47 AM, Trilok Soni wrote:
>> diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
>> new file mode 100644
>> index 000000000000..dc04ff1b6be0
>> --- /dev/null
>> +++ b/drivers/firmware/qcom/qcom_pas.c
>> @@ -0,0 +1,295 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/device/devres.h>
>> +#include <linux/firmware/qcom/qcom_pas.h>
>> +#include <linux/of.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
> are you sure you are using functionalities from these header files?
> 
> I couldn't find slab.h usage quickly and also qcom_scm.h. Can you please confirm?


I scrolled this patch too fast. I can see slab.h usage, but not sure about qcom_scm.h. 

^ permalink raw reply

* [PATCH] wifi: mac80211: fix static key race condition in aql_enable_write()
From: Josh Poimboeuf @ 2026-03-06 20:01 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-kernel, Lorenzo Bianconi, Peter Zijlstra, linux-wireless,
	syzbot+feb9ce36a95341bb47a4

If multiple tasks are writing to the 'aql_enable' debugfs file, it may
incorrectly call static_branch_dec() for an already disabled static key,
resulting in the following warning:

  val == 0
  WARNING: kernel/jump_label.c:311 at __static_key_slow_dec_cpuslocked.part.0+0x107/0x120 kernel/jump_label.c:311, CPU#0: syz.1.3155/20288
  ...
  Call Trace:
   <TASK>
   __static_key_slow_dec_cpuslocked kernel/jump_label.c:297 [inline]
   __static_key_slow_dec kernel/jump_label.c:321 [inline]
   static_key_slow_dec+0x7c/0xc0 kernel/jump_label.c:336
   aql_enable_write+0x2b2/0x310 net/mac80211/debugfs.c:343
   short_proxy_write+0x133/0x1a0 fs/debugfs/file.c:383
   vfs_write+0x2aa/0x1070 fs/read_write.c:684
   ksys_pwrite64 fs/read_write.c:793 [inline]
   __do_sys_pwrite64 fs/read_write.c:801 [inline]
   __se_sys_pwrite64 fs/read_write.c:798 [inline]
   __x64_sys_pwrite64+0x1eb/0x250 fs/read_write.c:798
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0xc9/0xf80 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fix it by using the atomic static_branch_{enable,disable}() interfaces.

Fixes: e908435e402a ("mac80211: introduce aql_enable node in debugfs")
Reported-by: syzbot+feb9ce36a95341bb47a4@syzkaller.appspotmail.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 net/mac80211/debugfs.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index d02f07368c51..687a66cd4943 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -320,7 +320,6 @@ static ssize_t aql_enable_read(struct file *file, char __user *user_buf,
 static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
 				size_t count, loff_t *ppos)
 {
-	bool aql_disabled = static_key_false(&aql_disable.key);
 	char buf[3];
 	size_t len;
 
@@ -335,15 +334,12 @@ static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
 	if (len > 0 && buf[len - 1] == '\n')
 		buf[len - 1] = 0;
 
-	if (buf[0] == '0' && buf[1] == '\0') {
-		if (!aql_disabled)
-			static_branch_inc(&aql_disable);
-	} else if (buf[0] == '1' && buf[1] == '\0') {
-		if (aql_disabled)
-			static_branch_dec(&aql_disable);
-	} else {
+	if (buf[0] == '0' && buf[1] == '\0')
+		static_branch_enable(&aql_disable);
+	else if (buf[0] == '1' && buf[1] == '\0')
+		static_branch_disable(&aql_disable);
+	else
 		return -EINVAL;
-	}
 
 	return count;
 }
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH] wifi: mac80211: fix static key race condition in aql_enable_write()
From: Johannes Berg @ 2026-03-06 20:23 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: linux-kernel, Lorenzo Bianconi, Peter Zijlstra, linux-wireless,
	syzbot+feb9ce36a95341bb47a4
In-Reply-To: <890b1c1e0eec8f97426c1443745853250dc80737.1772827269.git.jpoimboe@kernel.org>

On Fri, 2026-03-06 at 12:01 -0800, Josh Poimboeuf wrote:
> If multiple tasks are writing to the 'aql_enable' debugfs file, it may
> incorrectly call static_branch_dec() for an already disabled static key,
> resulting in the following warning:
> 
>   val == 0
>   WARNING: kernel/jump_label.c:311 at __static_key_slow_dec_cpuslocked.part.0+0x107/0x120 kernel/jump_label.c:311, CPU#0: syz.1.3155/20288
>   ...
>   Call Trace:
>    <TASK>
>    __static_key_slow_dec_cpuslocked kernel/jump_label.c:297 [inline]
>    __static_key_slow_dec kernel/jump_label.c:321 [inline]
>    static_key_slow_dec+0x7c/0xc0 kernel/jump_label.c:336
>    aql_enable_write+0x2b2/0x310 net/mac80211/debugfs.c:343
>    short_proxy_write+0x133/0x1a0 fs/debugfs/file.c:383
>    vfs_write+0x2aa/0x1070 fs/read_write.c:684
>    ksys_pwrite64 fs/read_write.c:793 [inline]
>    __do_sys_pwrite64 fs/read_write.c:801 [inline]
>    __se_sys_pwrite64 fs/read_write.c:798 [inline]
>    __x64_sys_pwrite64+0x1eb/0x250 fs/read_write.c:798
>    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>    do_syscall_64+0xc9/0xf80 arch/x86/entry/syscall_64.c:94
>    entry_SYSCALL_64_after_hwframe+0x77/0x7f
> 
> Fix it by using the atomic static_branch_{enable,disable}() interfaces.

Heh, I just applied the same change:

https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git/commit/?id=b94ae8e0d5fe1bdbbfdc3854ff6ce98f6876a828

johannes

^ permalink raw reply

* Re: [PATCH] wifi: mac80211: fix static key race condition in aql_enable_write()
From: Josh Poimboeuf @ 2026-03-06 20:45 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-kernel, Lorenzo Bianconi, Peter Zijlstra, linux-wireless,
	syzbot+feb9ce36a95341bb47a4
In-Reply-To: <c1029770c99b9aa7e9603e666b6626197a5d1c9c.camel@sipsolutions.net>

On Fri, Mar 06, 2026 at 09:23:07PM +0100, Johannes Berg wrote:
> On Fri, 2026-03-06 at 12:01 -0800, Josh Poimboeuf wrote:
> > If multiple tasks are writing to the 'aql_enable' debugfs file, it may
> > incorrectly call static_branch_dec() for an already disabled static key,
> > resulting in the following warning:
> > 
> >   val == 0
> >   WARNING: kernel/jump_label.c:311 at __static_key_slow_dec_cpuslocked.part.0+0x107/0x120 kernel/jump_label.c:311, CPU#0: syz.1.3155/20288
> >   ...
> >   Call Trace:
> >    <TASK>
> >    __static_key_slow_dec_cpuslocked kernel/jump_label.c:297 [inline]
> >    __static_key_slow_dec kernel/jump_label.c:321 [inline]
> >    static_key_slow_dec+0x7c/0xc0 kernel/jump_label.c:336
> >    aql_enable_write+0x2b2/0x310 net/mac80211/debugfs.c:343
> >    short_proxy_write+0x133/0x1a0 fs/debugfs/file.c:383
> >    vfs_write+0x2aa/0x1070 fs/read_write.c:684
> >    ksys_pwrite64 fs/read_write.c:793 [inline]
> >    __do_sys_pwrite64 fs/read_write.c:801 [inline]
> >    __se_sys_pwrite64 fs/read_write.c:798 [inline]
> >    __x64_sys_pwrite64+0x1eb/0x250 fs/read_write.c:798
> >    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
> >    do_syscall_64+0xc9/0xf80 arch/x86/entry/syscall_64.c:94
> >    entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > 
> > Fix it by using the atomic static_branch_{enable,disable}() interfaces.
> 
> Heh, I just applied the same change:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git/commit/?id=b94ae8e0d5fe1bdbbfdc3854ff6ce98f6876a828

Ha, and the code looks identical.  I approve ;-)

-- 
Josh

^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: account TX stats only when ACK/BA status is present
From: Jeff Johnson @ 2026-03-06 21:18 UTC (permalink / raw)
  To: ath12k, Sarika Sharma; +Cc: linux-wireless
In-Reply-To: <20260226051947.1379716-1-sarika.sharma@oss.qualcomm.com>


On Thu, 26 Feb 2026 10:49:47 +0530, Sarika Sharma wrote:
> The fields tx_retry_failed, tx_retry_count, and tx_duration are
> currently updated outside the HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS
> flag check. In certain scenarios, firmware delivers multiple PPDU
> statistics for the same PPDU, first without BA/ACK information, and
> later with BA/ACK status once it becomes available. As the same PPDU
> is processed again, these counters are updated a second time,
> resulting in duplicate TX statistics.
> 
> [...]

Applied, thanks!

[1/1] wifi: ath12k: account TX stats only when ACK/BA status is present
      commit: 1635ecc61a24597f893d057d004051a535c1c643

Best regards,
-- 
Jeff Johnson <jeff.johnson@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: Fix the assignment of logical link index
From: Jeff Johnson @ 2026-03-06 21:18 UTC (permalink / raw)
  To: ath12k, Roopni Devanathan; +Cc: linux-wireless, Manish Dharanenthiran
In-Reply-To: <20260226041911.2434999-1-roopni.devanathan@oss.qualcomm.com>


On Thu, 26 Feb 2026 09:49:11 +0530, Roopni Devanathan wrote:
> Per-link logical index is assigned from the global counter,
> ahsta->num_peer. This logical index is sent to firmware during peer
> association. If there is a failure in creating a link station,
> ath12k_mac_free_unassign_link_sta() clears the link, but does not decrement
> the logical link index. This will result in a higher logical link index for
> the next link station created. Also, if there is a leak in logical link
> index as we assign the incremented num_peer, then the index can exceed the
> maximum valid value of 15.
> 
> [...]

Applied, thanks!

[1/1] wifi: ath12k: Fix the assignment of logical link index
      commit: aecb569d7fb689e3e5b0005ca7bd0a2ef28915e8

Best regards,
-- 
Jeff Johnson <jeff.johnson@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: Fix legacy rate mapping for monitor mode capture
From: Jeff Johnson @ 2026-03-06 21:18 UTC (permalink / raw)
  To: ath12k, Thiraviyam Mariyappan; +Cc: linux-wireless, P Praneesh
In-Reply-To: <20260209054924.2713072-1-thiraviyam.mariyappan@oss.qualcomm.com>


On Mon, 09 Feb 2026 11:19:24 +0530, Thiraviyam Mariyappan wrote:
> The current implementation incorrectly reports legacy CCK and OFDM rates
> in monitor mode radiotap headers. The rate field displays wrong values,
> for example showing 11 Mbps when the actual rate is 1 Mbps. This occurs
> because the HAL layer uses a unified enum for both CCK and OFDM rates
> without distinguishing between long/short preamble variants and proper
> rate mapping to hardware rate indices.
> 
> [...]

Applied, thanks!

[1/1] wifi: ath12k: Fix legacy rate mapping for monitor mode capture
      commit: 616217a989e09c55398db8555e5ef0c64504cb66

Best regards,
-- 
Jeff Johnson <jeff.johnson@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH v3][next] wifi: ath6kl: wmi: Avoid -Wflex-array-member-not-at-end warning
From: Jeff Johnson @ 2026-03-06 21:18 UTC (permalink / raw)
  To: Gustavo A. R. Silva; +Cc: linux-wireless, linux-kernel, linux-hardening
In-Reply-To: <aZ0tGZnmtGckKJzY@kspp>


On Tue, 24 Feb 2026 13:46:17 +0900, Gustavo A. R. Silva wrote:
> -Wflex-array-member-not-at-end was introduced in GCC-14, and we are
> getting ready to enable it, globally.
> 
> Remove unused structures bss_bias_info and bss_bias, and member
> bss in struct roam_ctrl_cmd.
> 
> After these changes, the size of struct roam_ctrl_cmd, along
> with its member's offsets remain the same, hence the memory layout
> doesn't change:
> 
> [...]

Applied, thanks!

[1/1] wifi: ath6kl: wmi: Avoid -Wflex-array-member-not-at-end warning
      commit: 8e0ab5b9adb7fec3149441621df1cf15325b7215

Best regards,
-- 
Jeff Johnson <jeff.johnson@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH v2 00/18] wifi: drop redundant USB device references
From: Jeff Johnson @ 2026-03-06 21:39 UTC (permalink / raw)
  To: Johan Hovold, linux-wireless, Johannes Berg
  Cc: Jeff Johnson, Toke Høiland-Jørgensen, Brian Norris,
	Francesco Dolcini, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Jakub Kicinski, Stanislaw Gruszka,
	Hin-Tak Leung, Jes Sorensen, Ping-Ke Shih, Nicolas Ferre,
	Alexandre Belloni, Claudiu Beznea, Matthias Brugger,
	AngeloGioacchino Del Regno, Greg Kroah-Hartman, libertas-dev,
	linux-kernel
In-Reply-To: <20260306085144.12064-1-johan@kernel.org>

On 3/6/2026 12:51 AM, Johan Hovold wrote:
> Driver core holds a reference to the USB interface and its parent USB
> device while the interface is bound to a driver and there is no need to
> take additional references unless the structures are needed after
> disconnect.
> 
> Drop redundant device references to reduce cargo culting, make it easier
> to spot drivers where an extra reference is needed, and reduce the risk
> of memory leaks when drivers fail to release them.
> 
> Note that I sent an ath9k patch separately here:
> 
> 	https://lore.kernel.org/all/20260305105803.17011-1-johan@kernel.org/
> 
> but I included it here in v2 for completeness.
> 
> Also note that Greg had already sent a fix for rtw88 which has been
> picked up by Ping-Ke, but who asked me to send a replacement. If an
> incremental patch is preferred I can instead send a follow up for that
> one later.
> 
> Johan
> 
> 
> Changes in v2:
>  - include ath9k, previously submitted separately
>  - include ath6kl and ath10k
>  - rename the ath6kl and ath10k disconnect callbacks
>  - fix a reference leak in rtw88 previously reported (and fixed
>    differently) by Greg
> 
> 
> Johan Hovold (18):
>   wifi: ath6kl: drop redundant device reference
>   wifi: ath6kl: rename disconnect callback
>   wifi: ath9k: drop redundant device reference
>   wifi: ath10k: drop redundant device reference
>   wifi: ath10k: rename disconnect callback
>   wifi: at76c50x: drop redundant device reference
>   wifi: libertas: drop redundant device reference
>   wifi: libertas_tf: drop redundant device reference
>   wifi: mwifiex: drop redundant device reference
>   wifi: mt76: drop redundant device reference
>   wifi: mt76x0u: drop redundant device reference
>   wifi: mt76x2u: drop redundant device reference
>   wifi: mt76: mt792xu: drop redundant device reference
>   wifi: mt7601u: drop redundant device reference
>   wifi: rt2x00: drop redundant device reference
>   wifi: rtl818x: drop redundant device reference
>   wifi: rtl8xxxu: drop redundant device reference
>   wifi: rtw88: fix device leak on probe failure
> 
>  drivers/net/wireless/ath/ath10k/usb.c            |  8 ++------
>  drivers/net/wireless/ath/ath6kl/usb.c            | 16 ++++------------
>  drivers/net/wireless/ath/ath9k/hif_usb.c         |  4 ----
>  drivers/net/wireless/atmel/at76c50x-usb.c        | 12 ++++--------
>  drivers/net/wireless/marvell/libertas/if_usb.c   |  3 ---
>  .../net/wireless/marvell/libertas_tf/if_usb.c    |  2 --
>  drivers/net/wireless/marvell/mwifiex/usb.c       |  4 ----
>  drivers/net/wireless/mediatek/mt76/mt7615/usb.c  |  3 ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/usb.c  |  3 ---
>  drivers/net/wireless/mediatek/mt76/mt76x2/usb.c  |  4 ----
>  drivers/net/wireless/mediatek/mt76/mt7921/usb.c  |  2 --
>  drivers/net/wireless/mediatek/mt76/mt7925/usb.c  |  2 --
>  drivers/net/wireless/mediatek/mt76/mt792x_usb.c  |  1 -
>  drivers/net/wireless/mediatek/mt7601u/usb.c      |  3 ---
>  drivers/net/wireless/ralink/rt2x00/rt2x00usb.c   | 12 +-----------
>  .../net/wireless/realtek/rtl818x/rtl8187/dev.c   |  4 ----
>  drivers/net/wireless/realtek/rtl8xxxu/core.c     | 11 +++--------
>  drivers/net/wireless/realtek/rtw88/usb.c         |  3 +--
>  18 files changed, 15 insertions(+), 82 deletions(-)
> 

Johannes, will you be taking the entire series via wireless-next?

Or should the individual wireless driver maintainers take their patches
through their individual trees? I'm OK either way.

/jeff

^ permalink raw reply

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Jeff Johnson @ 2026-03-06 22:00 UTC (permalink / raw)
  To: Trilok Soni, Sumit Garg, linux-arm-msm, devicetree, dri-devel,
	freedreno, linux-media, netdev, linux-wireless, ath12k,
	linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, mukesh.ojha, pavan.kondeti, jorge.ramirez, tonyh,
	vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
	jens.wiklander, op-tee, apurupa, skare, Sumit Garg
In-Reply-To: <e0a86461-c136-4371-99cf-c0b0d31443a3@oss.qualcomm.com>

On 3/6/2026 11:47 AM, Trilok Soni wrote:
> On 3/6/2026 2:50 AM, Sumit Garg wrote:
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Sumit Garg <sumit.garg@oss.qualcomm.com>");
> 
> What is the convention for Qualcomm authored drivers? In some drivers
> I find that Qualcomm doesn't add MODULE_AUTHOR. Can Qualcomm community
> clarify it here. I prefer consistency here for the Qualcomm submissions. 

WLAN team was told to not have MODULE_AUTHOR(), so ath10k was the last WLAN
driver that had a MODULE_AUTHOR() -- ath11k and ath12k do not have one.

And in reality it is very rare for a given module, over time, to only have a
single author. The git history contains the real authorship. So just for that
reason I'd drop it.

/jeff

^ permalink raw reply

* Re: [PATCH 02/14] firmware: qcom: Add a generic PAS service
From: Trilok Soni @ 2026-03-06 22:16 UTC (permalink / raw)
  To: Jeff Johnson, Sumit Garg, linux-arm-msm, devicetree, dri-devel,
	freedreno, linux-media, netdev, linux-wireless, ath12k,
	linux-remoteproc
  Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
	sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
	airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
	elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, mukesh.ojha, pavan.kondeti, jorge.ramirez, tonyh,
	vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
	jens.wiklander, op-tee, apurupa, skare, Sumit Garg
In-Reply-To: <13091f47-938d-43fb-a8c0-4b081818b557@oss.qualcomm.com>

On 3/6/2026 2:00 PM, Jeff Johnson wrote:
> On 3/6/2026 11:47 AM, Trilok Soni wrote:
>> On 3/6/2026 2:50 AM, Sumit Garg wrote:
>>> +MODULE_LICENSE("GPL");
>>> +MODULE_AUTHOR("Sumit Garg <sumit.garg@oss.qualcomm.com>");
>>
>> What is the convention for Qualcomm authored drivers? In some drivers
>> I find that Qualcomm doesn't add MODULE_AUTHOR. Can Qualcomm community
>> clarify it here. I prefer consistency here for the Qualcomm submissions. 
> 
> WLAN team was told to not have MODULE_AUTHOR(), so ath10k was the last WLAN
> driver that had a MODULE_AUTHOR() -- ath11k and ath12k do not have one.
> 
> And in reality it is very rare for a given module, over time, to only have a
> single author. The git history contains the real authorship. So just for that
> reason I'd drop it.

I agree and that is the same guideline I follow for the drivers we write
downstream. I just want to make sure that we discuss it here. We may not be able
to find one single solution, but I prefer to get consistency for Qualcomm
submissions. 

---Trilok Soni

^ permalink raw reply

* [PATCH 00/19] wifi: mt76: mt7925: fix up MLO link lifetime and error handling
From: Sean Wang @ 2026-03-06 23:22 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi; +Cc: linux-wireless, linux-mediatek, Sean Wang

From: Sean Wang <sean.wang@mediatek.com>

Hi,

This series fix up MLO link STA lifetime and error handling in mt7925.

The current add path may expose partially initialized links and does
not reliably release host resources when firmware commands fail (e.g.
MCU timeouts). In addition, several helpers internally look up mlink,
creating implicit dependencies on driver state and making the code
harder to reason about and maintain.

Switch link STA handling to RCU lifetime, align WCID publish/teardown
ordering, pass mlink explicitly to helpers, and add host-side unwind
logic to release resources when link add fails.

	Sean

Sean Wang (19):
  wifi: mt76: mt7925: pass mlink to sta_amsdu_tlv()
  wifi: mt76: mt7925: pass WCID indices to bss_basic_tlv()
  wifi: mt76: mt7925: pass mlink and mconf to sta_mld_tlv()
  wifi: mt76: mt7925: pass mlink to mcu_sta_update()
  wifi: mt76: mt7925: resolve primary mlink via def_wcid
  wifi: mt76: mt7925: pass mlink to mac_link_sta_remove()
  wifi: mt76: mt7925: pass mlink to sta_hdr_trans_tlv()
  wifi: mt76: mt7925: validate mlink in sta_hdr_trans_tlv()
  wifi: mt76: mt7925: pass mlink to wtbl_update_hdr_trans()
  wifi: mt76: mt7925: pass mlink to set_link_key()
  wifi: mt76: mt7925: resolve link after acquiring mt76 mutex
  wifi: mt76: mt7925: pass mconf and mlink to wtbl_update_hdr_trans()
  wifi: mt76: mt7925: make WCID cleanup unconditional in
    sta_remove_links()
  wifi: mt76: mt7925: unwind WCID setup on link STA add failure
  wifi: mt76: mt7925: drop WCID reinit after publish
  wifi: mt76: mt7925: move WCID teardown into link_sta_remove()
  wifi: mt76: mt7925: switch link STA allocation to RCU lifetime
  wifi: mt76: mt7925: publish msta->link after successful link add
  wifi: mt76: mt7925: host-only unwind published links on add failure

 .../net/wireless/mediatek/mt76/mt7925/mac.c   |   3 +-
 .../net/wireless/mediatek/mt76/mt7925/main.c  | 221 +++++++++++++-----
 .../net/wireless/mediatek/mt76/mt7925/mcu.c   | 180 +++++++-------
 .../net/wireless/mediatek/mt76/mt7925/mcu.h   |   7 +
 .../wireless/mediatek/mt76/mt7925/mt7925.h    |   8 +-
 drivers/net/wireless/mediatek/mt76/mt792x.h   |   1 +
 6 files changed, 280 insertions(+), 140 deletions(-)

-- 
2.43.0


^ permalink raw reply


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