Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH ath-next] wifi: ath12k: reset REOQ LUT addresses before firmware stop
From: Aishwarya R @ 2026-06-19 12:07 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aishwarya R, P Praneesh

During module removal, REOQ LUT cleanup writes 0 to the REOQ/ML-REOQ
LUT address registers. That cleanup runs from ath12k_core_stop(),
after ath12k_qmi_firmware_stop() has already stopped the
firmware (mode OFF), so the register writes can hit an invalid target
access.

Move the REOQ LUT register reset before ath12k_qmi_firmware_stop(),
so the registers are cleared before stopping the firmware,
while register access is still valid.

Additionally, handle the error path where firmware-ready setup fails
after LUT programming but before core_stop() is reached, ensuring the
registers are properly reset in that case as well.

On the crash-recovery path, ath12k_core_reconfigure_on_crash() calls
ath12k_core_qmi_firmware_ready(), which re-enters ath12k_dp_setup()
and ath12k_dp_reoq_lut_setup(), so the LUT registers are reprogrammed
before use and stale values do not persist across recovery.

There is a brief window between the crash and when the LUT registers
are reprogrammed during recovery, during which the registers still hold
the freed DMA memory addresses. This is safe because the device is
non-functional in that window and will not initiate any DMA access
until firmware is restarted and the registers are reprogrammed.

No functional issue has been observed so far due to this sequence.
However, this change proactively avoids potential issues such as
invalid register accesses after firmware stop during module
removal and error handling.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1

Co-developed-by: P Praneesh <praneesh.p@oss.qualcomm.com>
Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
Signed-off-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/core.c |  5 ++++-
 drivers/net/wireless/ath/ath12k/dp.c   | 14 ++++++++++++--
 drivers/net/wireless/ath/ath12k/dp.h   |  1 +
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 742d4fd1b598..efe37dc91afd 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -708,8 +708,10 @@ static void ath12k_core_stop(struct ath12k_base *ab)
 
 	ath12k_core_to_group_ref_put(ab);
 
-	if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
+	if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) {
+		ath12k_dp_reoq_lut_addr_reset(ath12k_ab_to_dp(ab));
 		ath12k_qmi_firmware_stop(ab);
+	}
 
 	ath12k_acpi_stop(ab);
 
@@ -1371,6 +1373,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
 	goto exit;
 
 err_deinit:
+	ath12k_dp_reoq_lut_addr_reset(ath12k_ab_to_dp(ab));
 	ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab));
 	mutex_unlock(&ab->core_lock);
 	mutex_unlock(&ag->mutex);
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index af5f11fc1d84..fbc0788b37a0 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -1097,7 +1097,6 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
 		return;
 
 	if (dp->reoq_lut.vaddr_unaligned) {
-		ath12k_hal_write_reoq_lut_addr(ab, 0);
 		dma_free_coherent(ab->dev, dp->reoq_lut.size,
 				  dp->reoq_lut.vaddr_unaligned,
 				  dp->reoq_lut.paddr_unaligned);
@@ -1105,7 +1104,6 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
 	}
 
 	if (dp->ml_reoq_lut.vaddr_unaligned) {
-		ath12k_hal_write_ml_reoq_lut_addr(ab, 0);
 		dma_free_coherent(ab->dev, dp->ml_reoq_lut.size,
 				  dp->ml_reoq_lut.vaddr_unaligned,
 				  dp->ml_reoq_lut.paddr_unaligned);
@@ -1568,6 +1566,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab)
 	ath12k_dp_rx_free(ab);
 
 fail_cmn_reoq_cleanup:
+	ath12k_dp_reoq_lut_addr_reset(dp);
 	ath12k_dp_reoq_lut_cleanup(ab);
 
 fail_cmn_srng_cleanup:
@@ -1627,3 +1626,14 @@ void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp,
 	dp->device_id = ab->device_id;
 	dp_hw_grp->dp[dp->device_id] = dp;
 }
+
+void ath12k_dp_reoq_lut_addr_reset(struct ath12k_dp *dp)
+{
+	struct ath12k_base *ab = dp->ab;
+
+	if (dp->reoq_lut.vaddr_unaligned)
+		ath12k_hal_write_reoq_lut_addr(ab, 0);
+
+	if (dp->ml_reoq_lut.vaddr_unaligned)
+		ath12k_hal_write_ml_reoq_lut_addr(ab, 0);
+}
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index f8cfc7bb29dd..9b39146e65e1 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -701,4 +701,5 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp,
 						  u32 cookie);
 struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp,
 						  u32 desc_id);
+void ath12k_dp_reoq_lut_addr_reset(struct ath12k_dp *dp);
 #endif

base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH ath-next] ath9k: eeprom: alias vpdTableI onto vpdTableL to shrink stack frame
From: Toke Høiland-Jørgensen @ 2026-06-19 10:23 UTC (permalink / raw)
  To: Rosen Penev, Rosen Penev, linux-wireless
  Cc: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	open list,
	open list:CLANG/LLVM BUILD SUPPORT:Keyword:b(?i:clang|llvm)b
In-Reply-To: <DJCF38062Q69.1WQ853JSRMFQ9@gmail.com>

"Rosen Penev" <rosenp@gmail.com> writes:

> On Thu Jun 18, 2026 at 2:51 AM PDT, Toke Høiland-Jørgensen wrote:
>> Rosen Penev <rosenp@gmail.com> writes:
>>
>>> vpdTableL, vpdTableR, and vpdTableI are never live simultaneously.
>>> vpdTableL and vpdTableR are consumed during the frequency-interpolation
>>> step that writes vpdTableI; after the if/else they are never read
>>> again.  Reuse vpdTableL for the interpolated result (what was
>>> vpdTableI), reducing the stack frame by one 256-byte array.
>>>
>>> The read-via-write in the else branch is safe: ath9k_hw_interpolate()
>>> receives vpdTableL[i][j] by value as a function argument before the
>>> return value is written back to vpdTableL[i][j].
>>>
>>> Stack frame size change (x86_64, clang):
>>>   before: 0x440 (1088 B)
>>>   after:  0x330 (816 B)
>>
>> Huh? These are static variables, how is this affecting stack usage?
>> I assume this is against your previous (broken) patch?
> It's only broken on ARM + GCC. GCC + anything else and Clang + anything
> else is fine.

That's still broken, though :)

>> Anyway, adding this kind of aliasing to fix a problem that you
>> introduced by changing working code with no real benefit is not an
>> improvement. I'm OK with fixing actual bugs, but this is just mindless
>> churn...
> Fixing actual bugs is the goal yes. It makes sense to split up into
> multiple parts IMO.

If you're fixing an actual bug, include that in the patch description,
and if it requires multiple patches include them in a series. Sending
these out of context patches that just shuffle code around is just
churn...

-Toke

^ permalink raw reply

* [PATCH wireless] wifi: rt2x00: avoid full teardown before work setup in probe
From: Runyu Xiao @ 2026-06-19  7:31 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Gertjan van Wingerde, John W . Linville, Ivo van Doorn,
	linux-wireless, linux-kernel, Runyu Xiao, stable

rt2x00lib_probe_dev() uses the full rt2x00lib_remove_dev() teardown for
all probe failures. However, drv_data allocation and workqueue allocation
can fail before intf_work, autowakeup_work and sleep_work have been
initialized.

Do not enter the full remove path until the probe has reached the point
where those work items are set up. Return directly for drv_data allocation
failure, and use a small early cleanup path for workqueue allocation
failure.

This issue was found by our static analysis tool and then confirmed by
manual review of rt2x00lib_probe_dev() and rt2x00lib_remove_dev(). The
early probe exits should not call a common teardown path that assumes the
later work setup has already completed.

A QEMU PoC forced alloc_ordered_workqueue() to fail before the work
initializers are reached. The resulting fail path entered
rt2x00lib_remove_dev(), and DEBUG_OBJECTS reported invalid work drains with
rt2x00lib_probe_dev() and rt2x00lib_remove_dev() in the stack.

Fixes: 1ebbc48520a0 ("rt2x00: Introduce concept of driver data in struct rt2x00_dev.")
Fixes: 0439f5367c8d ("rt2x00: Move TX/RX work into dedicated workqueue")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
 drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index f8a6f9c968a1..847b64e586f6 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1382,7 +1382,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 			                      GFP_KERNEL);
 		if (!rt2x00dev->drv_data) {
 			retval = -ENOMEM;
-			goto exit;
+			return retval;
 		}
 	}
 
@@ -1416,7 +1416,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 	    alloc_ordered_workqueue("%s", 0, wiphy_name(rt2x00dev->hw->wiphy));
 	if (!rt2x00dev->workqueue) {
 		retval = -ENOMEM;
-		goto exit;
+		goto exit_free_drv_data;
 	}
 
 	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
@@ -1488,6 +1488,14 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 exit:
 	rt2x00lib_remove_dev(rt2x00dev);
 
+	return retval;
+
+exit_free_drv_data:
+	clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+
+	kfree(rt2x00dev->drv_data);
+	rt2x00dev->drv_data = NULL;
+
 	return retval;
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_probe_dev);
-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v2] wifi: ath12k: add QMI capability negotiation for dynamic memory mode
From: Aaradhana Sahu @ 2026-06-19  6:58 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu

On AHB platforms, firmware operates in two modes: fixed-memory mode where
firmware uses hardcoded addresses for memory regions such as BDF and does
not request HOST_DDR memory from the host, and dynamic-memory mode where
firmware expects the host to provide memory addresses including HOST_DDR
after the Q6 read-only region and relies on host allocation for all memory
types.

Introduce QMI capability negotiation to support both modes. Add a new QMI
PHY capability flag dynamic_ddr_support which is advertised by firmware to
indicate it supports dynamic memory mode. When the host detects this
capability, set the dynamic_mem_support flag in the host capability message
to signal the host is ready to provide dynamic memory allocation. This
triggers firmware to send the HOST_DDR memory request and use the
host-provided address.

For backward compatibility, if firmware doesn't advertise
dynamic_ddr_support, the firmware continues to operate in fixed-memory mode
where firmware uses predefined addresses.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
v2:
  -Dropped QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN and QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN changes.
  -Used %u instead of %d in the debug log.
---
 drivers/net/wireless/ath/ath12k/qmi.c | 50 +++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath12k/qmi.h |  6 +++-
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb5..e15a0c0120d3 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -506,6 +506,24 @@ static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 					   feature_list),
 	},
+	{
+		.data_type	= QMI_OPT_FLAG,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u8),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x33,
+		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
+					   dynamic_mem_support_valid),
+	},
+	{
+		.data_type	= QMI_UNSIGNED_1_BYTE,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u8),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x33,
+		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
+					   dynamic_mem_support),
+	},
 	{
 		.data_type	= QMI_EOTI,
 		.array_type	= NO_ARRAY,
@@ -602,6 +620,24 @@ static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
 		.offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 					   single_chip_mlo_support),
 	},
+	{
+		.data_type	= QMI_OPT_FLAG,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u8),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x17,
+		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
+					   dynamic_ddr_support_valid),
+	},
+	{
+		.data_type	= QMI_UNSIGNED_1_BYTE,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u8),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x17,
+		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
+					   dynamic_ddr_support),
+	},
 	{
 		.data_type	= QMI_EOTI,
 		.array_type	= NO_ARRAY,
@@ -2248,6 +2284,11 @@ int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
 	if (ret < 0)
 		goto out;
 
+	if (ab->qmi.dynamic_ddr_support) {
+		req.dynamic_mem_support_valid = 1;
+		req.dynamic_mem_support = 1;
+	}
+
 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
 			   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
 	if (ret < 0)
@@ -2319,11 +2360,14 @@ static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
 
 	ab->qmi.num_radios = resp.num_phy;
 
+	if (resp.dynamic_ddr_support_valid)
+		ab->qmi.dynamic_ddr_support = resp.dynamic_ddr_support;
+
 	ath12k_dbg(ab, ATH12K_DBG_QMI,
-		   "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
+		   "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d dynamic_ddr_valid %u dynamic_ddr_support %u\n",
 		   resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
-		   resp.num_phy_valid, resp.num_phy,
-		   resp.board_id_valid, resp.board_id);
+		   resp.num_phy_valid, resp.num_phy, resp.board_id_valid, resp.board_id,
+		   resp.dynamic_ddr_support_valid, resp.dynamic_ddr_support);
 
 	return;
 
diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
index 2a63e214eb42..08225242d30a 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.h
+++ b/drivers/net/wireless/ath/ath12k/qmi.h
@@ -156,6 +156,7 @@ struct ath12k_qmi {
 	struct m3_mem_region aux_uc_mem;
 	unsigned int service_ins_id;
 	struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01];
+	u8 dynamic_ddr_support;
 };
 
 #define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN		261
@@ -258,7 +259,8 @@ struct qmi_wlanfw_host_cap_req_msg_v01 {
 	struct wlfw_host_mlo_chip_info_s_v01 mlo_chip_info[QMI_WLFW_MAX_NUM_MLO_CHIPS_V01];
 	u8 feature_list_valid;
 	u64 feature_list;
-
+	u8 dynamic_mem_support_valid;
+	u8 dynamic_mem_support;
 };
 
 struct qmi_wlanfw_host_cap_resp_msg_v01 {
@@ -281,6 +283,8 @@ struct qmi_wlanfw_phy_cap_resp_msg_v01 {
 	u32 board_id;
 	u8 single_chip_mlo_support_valid;
 	u8 single_chip_mlo_support;
+	u8 dynamic_ddr_support_valid;
+	u8 dynamic_ddr_support;
 };
 
 #define QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN		54

base-commit: 83f028be15fe071efbee8e27837538d6cca77e87
-- 
2.34.1


^ permalink raw reply related

* [PATCH wireless] wifi: brcmfmac: initialize SDIO data work before cleanup
From: Runyu Xiao @ 2026-06-19  6:44 UTC (permalink / raw)
  To: Arend van Spriel, Kalle Valo
  Cc: Pieter-Paul Giesberts, Hante Meuleman, Daniel Kim, Franky Lin,
	linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel,
	Runyu Xiao, stable

brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
allocating the ordered workqueue. If that allocation fails, the function
jumps to fail and calls brcmf_sdio_remove().

brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
work item before the first failure path that can reach brcmf_sdio_remove(),
so the cleanup path always observes a valid work object.

This issue was found by our static analysis tool and then confirmed by
manual review of the probe error path and the remove-time work drain. The
problem pattern is an early setup failure that reaches a cleanup helper
which cancels an embedded work item before its initializer has run.

A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
the stack.

Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 4e6ed02c1591..a7d84ad6ed54 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4464,6 +4464,7 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
 	bus->sdiodev = sdiodev;
 	sdiodev->bus = bus;
 	skb_queue_head_init(&bus->glom);
+	INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
 	bus->txbound = BRCMF_TXBOUND;
 	bus->rxbound = BRCMF_RXBOUND;
 	bus->txminmax = BRCMF_TXMINMAX;
@@ -4478,7 +4479,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
 		goto fail;
 	}
 	brcmf_sdiod_freezer_count(sdiodev);
-	INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
 	bus->brcmf_wq = wq;
 
 	/* attempt to attach to the dongle */
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
From: Andy Shevchenko @ 2026-06-19  6:45 UTC (permalink / raw)
  To: Kees Cook
  Cc: Johannes Berg, linux-hardening, linux-kernel, linux-wireless,
	Gustavo A. R. Silva, Johannes Berg
In-Reply-To: <202606182046.AE5F6A241@keescook>

On Thu, Jun 18, 2026 at 08:47:34PM -0700, Kees Cook wrote:
> On Wed, Jun 17, 2026 at 01:12:36PM +0200, Andy Shevchenko wrote:
> > Convert size_add() to take variadic argument, so we can simplify users
> > with using a macro only once.
> 
> Oh, this is fun. I like it. :)

He-he :-)

...

> > +#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
> > +	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)
> 
> Is 4 the max seen in practice?

In patch 2 there are 5! In cover letter I also mentioned a new user
(there are actually three). And I remember seeing 3 somewhere else.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: add QMI capability negotiation for dynamic memory mode
From: Aaradhana Sahu @ 2026-06-19  6:21 UTC (permalink / raw)
  To: Jeff Johnson, Rameshkumar Sundaram, ath12k, Jeff Johnson; +Cc: linux-wireless
In-Reply-To: <17927ece-f0e3-4014-9143-891a15344bef@oss.qualcomm.com>



On 6/19/2026 4:55 AM, Jeff Johnson wrote:
> On 6/18/2026 2:29 AM, Rameshkumar Sundaram wrote:
>> On 6/18/2026 2:22 PM, Aaradhana Sahu wrote:
>>>
>>>
>>> On 6/18/2026 12:18 PM, Rameshkumar Sundaram wrote:
>>>> On 6/1/2026 8:48 AM, Aaradhana Sahu wrote:
>>>>> On AHB platforms, firmware operates in two modes: fixed-memory mode where
>>>>> firmware uses hardcoded addresses for memory regions such as BDF and does
>>>>> not request HOST_DDR memory from the host, and dynamic-memory mode where
>>>>> firmware expects the host to provide memory addresses including HOST_DDR
>>>>> after the Q6 read-only region and relies on host allocation for all memory
>>>>> types.
>>>>>
>>>>> Introduce QMI capability negotiation to support both modes. Add a new QMI
>>>>> PHY capability flag dynamic_ddr_support which is advertised by firmware to
>>>>> indicate it supports dynamic memory mode. When the host detects this
>>>>> capability, set the dynamic_mem_support flag in the host capability message
>>>>> to signal the host is ready to provide dynamic memory allocation. This
>>>>> triggers firmware to send the HOST_DDR memory request and use the
>>>>> host-provided address.
>>>>>
>>>>> For backward compatibility, if firmware doesn't advertise
>>>>> dynamic_ddr_support, the firmware continues to operate in fixed-memory mode
>>>>> where firmware uses predefined addresses.
>>>>>
>>>>> Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
>>>>>
>>>>> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
>>>>> ---
>>>>>    drivers/net/wireless/ath/ath12k/qmi.c | 50 +++++++++++++++++++++++++--
>>>>>    drivers/net/wireless/ath/ath12k/qmi.h | 10 ++++--
>>>>>    2 files changed, 54 insertions(+), 6 deletions(-)
>>>>>
>>>>> diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
>>>>> index fd762b5d7bb5..85406d6e6da1 100644
>>>>> --- a/drivers/net/wireless/ath/ath12k/qmi.c
>>>>> +++ b/drivers/net/wireless/ath/ath12k/qmi.c
>>>>> @@ -506,6 +506,24 @@ static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
>>>>>            .offset        = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
>>>>>                           feature_list),
>>>>>        },
>>>>> +    {
>>>>> +        .data_type    = QMI_OPT_FLAG,
>>>>> +        .elem_len    = 1,
>>>>> +        .elem_size    = sizeof(u8),
>>>>> +        .array_type    = NO_ARRAY,
>>>>> +        .tlv_type    = 0x33,
>>>>> +        .offset        = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
>>>>> +                       dynamic_mem_support_valid),
>>>>> +    },
>>>>> +    {
>>>>> +        .data_type    = QMI_UNSIGNED_1_BYTE,
>>>>> +        .elem_len    = 1,
>>>>> +        .elem_size    = sizeof(u8),
>>>>> +        .array_type    = NO_ARRAY,
>>>>> +        .tlv_type    = 0x33,
>>>>> +        .offset        = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
>>>>> +                       dynamic_mem_support),
>>>>> +    },
>>>>>        {
>>>>>            .data_type    = QMI_EOTI,
>>>>>            .array_type    = NO_ARRAY,
>>>>> @@ -602,6 +620,24 @@ static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
>>>>>            .offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
>>>>>                           single_chip_mlo_support),
>>>>>        },
>>>>> +    {
>>>>> +        .data_type      = QMI_OPT_FLAG,
>>>>> +        .elem_len       = 1,
>>>>> +        .elem_size      = sizeof(u8),
>>>>> +        .array_type     = NO_ARRAY,
>>>>> +        .tlv_type       = 0x17,
>>>>> +        .offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
>>>>> +                       dynamic_ddr_support_valid),
>>>>> +    },
>>>>> +    {
>>>>> +        .data_type      = QMI_UNSIGNED_1_BYTE,
>>>>> +        .elem_len       = 1,
>>>>> +        .elem_size      = sizeof(u8),
>>>>> +        .array_type     = NO_ARRAY,
>>>>> +        .tlv_type       = 0x17,
>>>>> +        .offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
>>>>> +                       dynamic_ddr_support),
>>>>> +    },
>>>>>        {
>>>>>            .data_type    = QMI_EOTI,
>>>>>            .array_type    = NO_ARRAY,
>>>>> @@ -2248,6 +2284,11 @@ int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
>>>>>        if (ret < 0)
>>>>>            goto out;
>>>>>    +    if (ab->qmi.dynamic_ddr_support) {
>>>>> +        req.dynamic_mem_support_valid = 1;
>>>>> +        req.dynamic_mem_support = 1;
>>>>> +    }
>>>>> +
>>>>>        ret = qmi_txn_init(&ab->qmi.handle, &txn,
>>>>>                   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
>>>>>        if (ret < 0)
>>>>> @@ -2319,11 +2360,14 @@ static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
>>>>>          ab->qmi.num_radios = resp.num_phy;
>>>>>    +    if (resp.dynamic_ddr_support_valid)
>>>>> +        ab->qmi.dynamic_ddr_support = resp.dynamic_ddr_support;
>>>>> +
>>>>>        ath12k_dbg(ab, ATH12K_DBG_QMI,
>>>>> -           "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
>>>>> +           "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d dynamic_ddr_valid %d dynamic_ddr_support %d\n",
>>>>>               resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
>>>>> -           resp.num_phy_valid, resp.num_phy,
>>>>> -           resp.board_id_valid, resp.board_id);
>>>>> +           resp.num_phy_valid, resp.num_phy, resp.board_id_valid, resp.board_id,
>>>>> +           resp.dynamic_ddr_support_valid, resp.dynamic_ddr_support);
>>>>>          return;
>>>>>    diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
>>>>> index 2a63e214eb42..dbde76e5a78d 100644
>>>>> --- a/drivers/net/wireless/ath/ath12k/qmi.h
>>>>> +++ b/drivers/net/wireless/ath/ath12k/qmi.h
>>>>> @@ -156,9 +156,10 @@ struct ath12k_qmi {
>>>>>        struct m3_mem_region aux_uc_mem;
>>>>>        unsigned int service_ins_id;
>>>>>        struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01];
>>>>> +    u8 dynamic_ddr_support;
>>>>>    };
>>>>>    -#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN        261
>>>>> +#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN        265
>>>>>    #define QMI_WLANFW_HOST_CAP_REQ_V01            0x0034
>>>>>    #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN    7
>>>>>    #define QMI_WLFW_HOST_CAP_RESP_V01            0x0034
>>>>> @@ -258,7 +259,8 @@ struct qmi_wlanfw_host_cap_req_msg_v01 {
>>>>>        struct wlfw_host_mlo_chip_info_s_v01 mlo_chip_info[QMI_WLFW_MAX_NUM_MLO_CHIPS_V01];
>>>>>        u8 feature_list_valid;
>>>>>        u64 feature_list;
>>>>> -
>>>>> +    u8 dynamic_mem_support_valid;
>>>>> +    u8 dynamic_mem_support;
>>>>>    };
>>>>>      struct qmi_wlanfw_host_cap_resp_msg_v01 {
>>>>> @@ -267,7 +269,7 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 {
>>>>>      #define QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN        0
>>>>>    #define QMI_WLANFW_PHY_CAP_REQ_V01            0x0057
>>>>> -#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN        18
>>>>> +#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN        22
>>>>
>>>> this is not used anywhere, but since you're touching it should this be 26 ? response TLV 7, num_phy 4, board_id 7, existing single_chip_mlo_support 4, and new dynamic_ddr_support 4
>>>>
>>>>
>>>> -- 
>>>> Ramesh
>>>
>>> I checked the driver and found there are several unused QMI_*_RESP_MSG_LEN macros.
>>> Since this macro is not used anywhere, I think it is better to remove this
>>> change from the current patch.
>>> I will send a separate cleanup patch to remove all unused QMI macros.
>>>
>>> Hope that’s fine with you.
>>>
>>
>>
>> I couldn’t trace the history either.
>> My guess is that the response-length macro was retained either as schema 
>> documentation or to keep it consistent with the generated QMI definitions.
>>
>> Jeff may be able to confirm the original intent.
> 
> I suspect this was from the code generator and was just pulled in.
> Concur we should just drop this (and have a cleanup patch to remove any others
> that are unused).
> 
> And this V01 naming convention seems broken since we've regularly extended
> messages and yet still call them V01. I would have expected each extension
> would have incremented the version number...
> 
> And I also think it is strange to pass the message length anyway since the
> serializer should be able to figure that out -- having the clients pass that
> means the clients must know the details of the serialization algorithm which
> is a layering violation. But that is a preexisting issue with the QMI interface.
> 
> /jeff
> 
> /jeff
>>
> 

Thanks for the clarification. I will drop this change in the next version and
send a separate cleanup patch to remove the unused QMI response length macros.


^ permalink raw reply

* [PATCH ath-next] wifi: ath12k: advertise ieee_link_id in vdev start MLO params
From: Manish Dharanenthiran @ 2026-06-19  5:55 UTC (permalink / raw)
  To: ath12k
  Cc: linux-wireless, Hari Naraayana Desikan Kannan, Karthik M,
	Manish Dharanenthiran

Firmware builds the AP MLD partner profile from the hw_link_id passed in
the vdev start parameters. However, hw_link_id is not always the same as
the logical per-MLD ieee_link_id, since ieee_link_id is assigned per MLD
and not per pdev.

This matters in mixed MLO and SLO setups. For example:

  MLD 1 - 5 GHz + 6 GHz (2-link MLO): ieee_link_id 0 and 1
  MLD 2 - 6 GHz only    (1-link SLO): ieee_link_id 0
  MLD 3 - 5 GHz only    (1-link SLO): ieee_link_id 0

The same physical 6 GHz radio can use ieee_link_id 1 for one
MLD and ieee_link_id 0 for another. Pass the correct ieee_link_id to
firmware so it can build accurate per-STA profile elements.

Add ieee_link_id to wmi_vdev_start_mlo_params for the self link and to
wmi_partner_link_info for each partner link. Populate these fields in
ath12k_mac_mlo_get_vdev_args() from the corresponding vdev link_id
before encoding the WMI command.

Introduce two new flags in ML params to indicate to firmware when
the new fields are valid:

  ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID         BIT(18) for the self link
  ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19) for partner links

Firmware parses ieee_link_id only when the matching flag is set.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1

Co-developed-by: Hari Naraayana Desikan Kannan <hari.kannan@oss.qualcomm.com>
Signed-off-by: Hari Naraayana Desikan Kannan <hari.kannan@oss.qualcomm.com>
Co-developed-by: Karthik M <karthik.m@oss.qualcomm.com>
Signed-off-by: Karthik M <karthik.m@oss.qualcomm.com>
Signed-off-by: Manish Dharanenthiran <manish.dharanenthiran@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/mac.c |  3 +++
 drivers/net/wireless/ath/ath12k/wmi.c | 32 ++++++++++++++++++++------------
 drivers/net/wireless/ath/ath12k/wmi.h |  7 +++++++
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index af354bef5c0d..773ecd6da8e5 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -11253,6 +11253,8 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
 
 	ml_arg->assoc_link = arvif->is_sta_assoc_link;
 
+	ml_arg->ieee_link_id = arvif->link_id;
+
 	partner_info = ml_arg->partner_info;
 
 	links = ahvif->links_map;
@@ -11276,6 +11278,7 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
 
 		partner_info->vdev_id = arvif_p->vdev_id;
 		partner_info->hw_link_id = arvif_p->ar->pdev->hw_link_id;
+		partner_info->ieee_link_id = arvif_p->link_id;
 		ether_addr_copy(partner_info->addr, link_conf->addr);
 		ml_arg->num_partner_links++;
 		partner_info++;
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 84a31b953db8..a0e8b5678ae3 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1228,10 +1228,14 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
 				   le32_encode_bits(arg->ml.mcast_link,
 						    ATH12K_WMI_FLAG_MLO_MCAST_VDEV) |
 				   le32_encode_bits(arg->ml.link_add,
-						    ATH12K_WMI_FLAG_MLO_LINK_ADD);
+						    ATH12K_WMI_FLAG_MLO_LINK_ADD) |
+				   cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID);
 
-		ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start ml flags 0x%x\n",
-			   arg->vdev_id, ml_params->flags);
+		ml_params->ieee_link_id = cpu_to_le32(arg->ml.ieee_link_id);
+
+		ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start link_id %d ml flags 0x%x\n",
+			   arg->vdev_id, arg->ml.ieee_link_id,
+			   le32_to_cpu(ml_params->flags));
 
 		ptr += sizeof(*ml_params);
 
@@ -1244,19 +1248,23 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
 		partner_info = ptr;
 
 		for (i = 0; i < arg->ml.num_partner_links; i++) {
+			struct wmi_ml_partner_info *pinfo = &arg->ml.partner_info[i];
+
 			partner_info->tlv_header =
 				ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PARTNER_LINK_PARAMS,
 						       sizeof(*partner_info));
-			partner_info->vdev_id =
-				cpu_to_le32(arg->ml.partner_info[i].vdev_id);
-			partner_info->hw_link_id =
-				cpu_to_le32(arg->ml.partner_info[i].hw_link_id);
+			partner_info->vdev_id = cpu_to_le32(pinfo->vdev_id);
+			partner_info->hw_link_id = cpu_to_le32(pinfo->hw_link_id);
 			ether_addr_copy(partner_info->vdev_addr.addr,
-					arg->ml.partner_info[i].addr);
-
-			ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d hw_link_id %d macaddr%pM\n",
-				   partner_info->vdev_id, partner_info->hw_link_id,
-				   partner_info->vdev_addr.addr);
+					pinfo->addr);
+			partner_info->flags =
+				cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER);
+			partner_info->ieee_link_id = cpu_to_le32(pinfo->ieee_link_id);
+
+			ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d hw_link_id %d macaddr %pM link_id %d ml flags 0x%x\n",
+				   pinfo->vdev_id, pinfo->hw_link_id,
+				   pinfo->addr, pinfo->ieee_link_id,
+				   le32_to_cpu(partner_info->flags));
 
 			partner_info++;
 		}
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index c452e3d57a29..51f3426e1fcd 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2954,10 +2954,13 @@ struct wmi_vdev_create_mlo_params {
 #define ATH12K_WMI_FLAG_MLO_EMLSR_SUPPORT		BIT(6)
 #define ATH12K_WMI_FLAG_MLO_FORCED_INACTIVE		BIT(7)
 #define ATH12K_WMI_FLAG_MLO_LINK_ADD			BIT(8)
+#define ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID		BIT(18)
+#define ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER	BIT(19)
 
 struct wmi_vdev_start_mlo_params {
 	__le32 tlv_header;
 	__le32 flags;
+	__le32 ieee_link_id;
 } __packed;
 
 struct wmi_partner_link_info {
@@ -2965,6 +2968,8 @@ struct wmi_partner_link_info {
 	__le32 vdev_id;
 	__le32 hw_link_id;
 	struct ath12k_wmi_mac_addr_params vdev_addr;
+	__le32 flags;
+	__le32 ieee_link_id;
 } __packed;
 
 struct wmi_vdev_delete_cmd {
@@ -3120,6 +3125,7 @@ struct wmi_ml_partner_info {
 	bool primary_umac;
 	bool logical_link_idx_valid;
 	u32 logical_link_idx;
+	u32 ieee_link_id;
 };
 
 struct wmi_ml_arg {
@@ -3127,6 +3133,7 @@ struct wmi_ml_arg {
 	bool assoc_link;
 	bool mcast_link;
 	bool link_add;
+	u32 ieee_link_id;
 	u8 num_partner_links;
 	struct wmi_ml_partner_info partner_info[ATH12K_WMI_MLO_MAX_LINKS];
 };

---
base-commit: 63abe299b12b317dfee5bcd09037da4668a4431a
change-id: 20260610-ieee_link_id-3424c332b216


^ permalink raw reply related

* Re: [stable request] mt7921e: backport two mt76 fixes to 6.12.y
From: Sasha Levin @ 2026-06-19  4:06 UTC (permalink / raw)
  To: Sasha Levin, stable
  Cc: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
	Sean Wang, linux-wireless, Ajrat Makhmutov
In-Reply-To: <66552f9d-f5cc-4070-bde5-6417a41eed96@altlinux.org>

> Please backport the following mt76/mt7921 fixes to 6.12.y:
>   - avoid undesired changes of the preset regulatory domain
>   - fix a potential scan no APs
>   - fix potential deadlock in mt7921_roc_abort_sync

All three are now queued for 6.12, thanks. The roc_abort_sync fix was
adapted to keep del_timer_sync(), since the timer rename is absent in
6.12.

--
Thanks,
Sasha

^ permalink raw reply

* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
From: Kees Cook @ 2026-06-19  3:47 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Johannes Berg, linux-hardening, linux-kernel, linux-wireless,
	Gustavo A. R. Silva, Johannes Berg
In-Reply-To: <20260617112250.2791461-2-andriy.shevchenko@linux.intel.com>

On Wed, Jun 17, 2026 at 01:12:36PM +0200, Andy Shevchenko wrote:
> Convert size_add() to take variadic argument, so we can simplify users
> with using a macro only once.

Oh, this is fun. I like it. :)

> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  include/linux/overflow.h | 37 ++++++++++++++++++++++++++-----------
>  1 file changed, 26 insertions(+), 11 deletions(-)
> 
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index a8cb6319b4fb..a8b0325e73f3 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -2,9 +2,10 @@
>  #ifndef __LINUX_OVERFLOW_H
>  #define __LINUX_OVERFLOW_H
>  
> +#include <linux/args.h>
>  #include <linux/compiler.h>
> -#include <linux/limits.h>
>  #include <linux/const.h>
> +#include <linux/limits.h>
>  
>  /*
>   * We need to compute the minimum and maximum values representable in a given
> @@ -337,16 +338,7 @@ static __always_inline size_t __must_check size_mul(size_t factor1, size_t facto
>  	return bytes;
>  }
>  
> -/**
> - * size_add() - Calculate size_t addition with saturation at SIZE_MAX
> - * @addend1: first addend
> - * @addend2: second addend
> - *
> - * Returns: calculate @addend1 + @addend2, both promoted to size_t,
> - * with any overflow causing the return value to be SIZE_MAX. The
> - * lvalue must be size_t to avoid implicit type conversion.
> - */
> -static __always_inline size_t __must_check size_add(size_t addend1, size_t addend2)
> +static __always_inline size_t __must_check __size_add(size_t addend1, size_t addend2)
>  {
>  	size_t bytes;
>  
> @@ -356,6 +348,29 @@ static __always_inline size_t __must_check size_add(size_t addend1, size_t adden
>  	return bytes;
>  }
>  
> +#define __size_add0(addend1, ...)						\
> +	__size_add(addend1, 0)
> +#define __size_add1(addend1, addend2, ...)					\
> +	__size_add(addend1,  addend2)
> +#define __size_add2(addend1, addend2, addend3, ...)				\
> +	__size_add(__size_add(addend1,  addend2), addend3)
> +#define __size_add3(addend1, addend2, addend3, addend4, ...)			\
> +	__size_add(__size_add2(addend1,  addend2, addend3), addend4)
> +#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
> +	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)

Is 4 the max seen in practice?


-- 
Kees Cook

^ permalink raw reply

* Re: [PATCH wireless-next] wifi: mt76: fix of_get_mac_address error handling
From: Rosen Penev @ 2026-06-19  1:50 UTC (permalink / raw)
  To: Klara Modin, Rosen Penev
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <ajSDtsJCmYnMNJSD@parmesan.int.kasm.eu>

On Thu Jun 18, 2026 at 4:51 PM PDT, Klara Modin wrote:
> On 2026-06-18 16:01:45 -0700, Rosen Penev wrote:
>> On Thu, Jun 18, 2026 at 2:47 PM Klara Modin <klarasmodin@gmail.com> wrote:
>> >
>> > Hi,
>> >
>> > On 2026-04-26 22:17:46 -0700, Rosen Penev wrote:
>> > > Check return value instead of is_valid_ether_addr. The latter is handled
>> > > by the former.
>> > >
>> > > Signed-off-by: Rosen Penev <rosenp@gmail.com>
>> > > ---
>> > >  drivers/net/wireless/mediatek/mt76/eeprom.c | 2 +-
>> > >  1 file changed, 1 insertion(+), 1 deletion(-)
>> > >
>> > > diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
>> > > index 93d91264687f..0f6ccf6ed53d 100644
>> > > --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
>> > > +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
>> > > @@ -93,7 +93,7 @@ mt76_eeprom_override(struct mt76_phy *phy)
>> > >       if (err == -EPROBE_DEFER)
>> > >               return err;
>> > >
>> > > -     if (!is_valid_ether_addr(phy->macaddr)) {
>> > > +     if (err) {
>> > >               eth_random_addr(phy->macaddr);
>> > >               dev_info(dev->dev,
>> > >                        "Invalid MAC address, using random address %pM\n",
>> > > --
>> > > 2.54.0
>> > >
>> >
>> > Recently I have started to see randomized MAC-addresses on my x86 laptop
>> > with a MT7922 and the above message printed in the kernel log. I have
>> > CONFIG_OF turned on, but since this is an ACPI system the device is not
>> > described by any device tree and the earlier of_get_mac_address() likely
>> > fails with -ENODEV. Looking at the !CONFIG_OF stub for
>> > of_get_mac_address it always returns -ENODEV, meaning this will always
>> > randomize the mac in that case too.
>
>> IIRC, the normal device_get_mac_address supports nvmem now. Does that
>> fix your use case?
>
> I tried this:
>
> diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> index b99d7452800f..243a8f2c7bda 100644
> --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> @@ -174,10 +174,9 @@ int
>  mt76_eeprom_override(struct mt76_phy *phy)
>  {
>  	struct mt76_dev *dev = phy->dev;
> -	struct device_node *np = dev->dev->of_node;
>  	int err;
>
> -	err = of_get_mac_address(np, phy->macaddr);
> +	err = device_get_mac_address(dev->dev, phy->macaddr);
>  	if (err == -EPROBE_DEFER)
>  		return err;
>
>
> but I still get a random MAC.
Then the original patch should be reverted. Unfortunate that it doesn't
workq
>
>> >
>> > Reverting this patch fixes the issue and the correct MAC address is
>> > used. I'm not sure if there is any case where of_get_mac_addres() could
>> > fail in a way that results in a valid MAC address but it seems unlikely
>> > to me.
>> >
>> > Regards,
>> > Klara Modin


^ permalink raw reply

* Re: [PATCH wireless-next] wifi: mt76: fix of_get_mac_address error handling
From: Klara Modin @ 2026-06-18 23:51 UTC (permalink / raw)
  To: Rosen Penev
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <CAKxU2N-gfH8Tq29-j2MArogLZuO7JEqtN5LNPVygJzrAERa3cg@mail.gmail.com>

On 2026-06-18 16:01:45 -0700, Rosen Penev wrote:
> On Thu, Jun 18, 2026 at 2:47 PM Klara Modin <klarasmodin@gmail.com> wrote:
> >
> > Hi,
> >
> > On 2026-04-26 22:17:46 -0700, Rosen Penev wrote:
> > > Check return value instead of is_valid_ether_addr. The latter is handled
> > > by the former.
> > >
> > > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > > ---
> > >  drivers/net/wireless/mediatek/mt76/eeprom.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > index 93d91264687f..0f6ccf6ed53d 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > @@ -93,7 +93,7 @@ mt76_eeprom_override(struct mt76_phy *phy)
> > >       if (err == -EPROBE_DEFER)
> > >               return err;
> > >
> > > -     if (!is_valid_ether_addr(phy->macaddr)) {
> > > +     if (err) {
> > >               eth_random_addr(phy->macaddr);
> > >               dev_info(dev->dev,
> > >                        "Invalid MAC address, using random address %pM\n",
> > > --
> > > 2.54.0
> > >
> >
> > Recently I have started to see randomized MAC-addresses on my x86 laptop
> > with a MT7922 and the above message printed in the kernel log. I have
> > CONFIG_OF turned on, but since this is an ACPI system the device is not
> > described by any device tree and the earlier of_get_mac_address() likely
> > fails with -ENODEV. Looking at the !CONFIG_OF stub for
> > of_get_mac_address it always returns -ENODEV, meaning this will always
> > randomize the mac in that case too.

> IIRC, the normal device_get_mac_address supports nvmem now. Does that
> fix your use case?

I tried this:

diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index b99d7452800f..243a8f2c7bda 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -174,10 +174,9 @@ int
 mt76_eeprom_override(struct mt76_phy *phy)
 {
 	struct mt76_dev *dev = phy->dev;
-	struct device_node *np = dev->dev->of_node;
 	int err;
 
-	err = of_get_mac_address(np, phy->macaddr);
+	err = device_get_mac_address(dev->dev, phy->macaddr);
 	if (err == -EPROBE_DEFER)
 		return err;
 

but I still get a random MAC.

> >
> > Reverting this patch fixes the issue and the correct MAC address is
> > used. I'm not sure if there is any case where of_get_mac_addres() could
> > fail in a way that results in a valid MAC address but it seems unlikely
> > to me.
> >
> > Regards,
> > Klara Modin

^ permalink raw reply related

* Re: [PATCH ath-next] wifi: ath12k: add QMI capability negotiation for dynamic memory mode
From: Jeff Johnson @ 2026-06-18 23:25 UTC (permalink / raw)
  To: Rameshkumar Sundaram, Aaradhana Sahu, ath12k, Jeff Johnson; +Cc: linux-wireless
In-Reply-To: <96953b10-379b-41d9-a151-68982b9a9854@oss.qualcomm.com>

On 6/18/2026 2:29 AM, Rameshkumar Sundaram wrote:
> On 6/18/2026 2:22 PM, Aaradhana Sahu wrote:
>>
>>
>> On 6/18/2026 12:18 PM, Rameshkumar Sundaram wrote:
>>> On 6/1/2026 8:48 AM, Aaradhana Sahu wrote:
>>>> On AHB platforms, firmware operates in two modes: fixed-memory mode where
>>>> firmware uses hardcoded addresses for memory regions such as BDF and does
>>>> not request HOST_DDR memory from the host, and dynamic-memory mode where
>>>> firmware expects the host to provide memory addresses including HOST_DDR
>>>> after the Q6 read-only region and relies on host allocation for all memory
>>>> types.
>>>>
>>>> Introduce QMI capability negotiation to support both modes. Add a new QMI
>>>> PHY capability flag dynamic_ddr_support which is advertised by firmware to
>>>> indicate it supports dynamic memory mode. When the host detects this
>>>> capability, set the dynamic_mem_support flag in the host capability message
>>>> to signal the host is ready to provide dynamic memory allocation. This
>>>> triggers firmware to send the HOST_DDR memory request and use the
>>>> host-provided address.
>>>>
>>>> For backward compatibility, if firmware doesn't advertise
>>>> dynamic_ddr_support, the firmware continues to operate in fixed-memory mode
>>>> where firmware uses predefined addresses.
>>>>
>>>> Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
>>>>
>>>> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
>>>> ---
>>>>    drivers/net/wireless/ath/ath12k/qmi.c | 50 +++++++++++++++++++++++++--
>>>>    drivers/net/wireless/ath/ath12k/qmi.h | 10 ++++--
>>>>    2 files changed, 54 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
>>>> index fd762b5d7bb5..85406d6e6da1 100644
>>>> --- a/drivers/net/wireless/ath/ath12k/qmi.c
>>>> +++ b/drivers/net/wireless/ath/ath12k/qmi.c
>>>> @@ -506,6 +506,24 @@ static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
>>>>            .offset        = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
>>>>                           feature_list),
>>>>        },
>>>> +    {
>>>> +        .data_type    = QMI_OPT_FLAG,
>>>> +        .elem_len    = 1,
>>>> +        .elem_size    = sizeof(u8),
>>>> +        .array_type    = NO_ARRAY,
>>>> +        .tlv_type    = 0x33,
>>>> +        .offset        = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
>>>> +                       dynamic_mem_support_valid),
>>>> +    },
>>>> +    {
>>>> +        .data_type    = QMI_UNSIGNED_1_BYTE,
>>>> +        .elem_len    = 1,
>>>> +        .elem_size    = sizeof(u8),
>>>> +        .array_type    = NO_ARRAY,
>>>> +        .tlv_type    = 0x33,
>>>> +        .offset        = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
>>>> +                       dynamic_mem_support),
>>>> +    },
>>>>        {
>>>>            .data_type    = QMI_EOTI,
>>>>            .array_type    = NO_ARRAY,
>>>> @@ -602,6 +620,24 @@ static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
>>>>            .offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
>>>>                           single_chip_mlo_support),
>>>>        },
>>>> +    {
>>>> +        .data_type      = QMI_OPT_FLAG,
>>>> +        .elem_len       = 1,
>>>> +        .elem_size      = sizeof(u8),
>>>> +        .array_type     = NO_ARRAY,
>>>> +        .tlv_type       = 0x17,
>>>> +        .offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
>>>> +                       dynamic_ddr_support_valid),
>>>> +    },
>>>> +    {
>>>> +        .data_type      = QMI_UNSIGNED_1_BYTE,
>>>> +        .elem_len       = 1,
>>>> +        .elem_size      = sizeof(u8),
>>>> +        .array_type     = NO_ARRAY,
>>>> +        .tlv_type       = 0x17,
>>>> +        .offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
>>>> +                       dynamic_ddr_support),
>>>> +    },
>>>>        {
>>>>            .data_type    = QMI_EOTI,
>>>>            .array_type    = NO_ARRAY,
>>>> @@ -2248,6 +2284,11 @@ int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
>>>>        if (ret < 0)
>>>>            goto out;
>>>>    +    if (ab->qmi.dynamic_ddr_support) {
>>>> +        req.dynamic_mem_support_valid = 1;
>>>> +        req.dynamic_mem_support = 1;
>>>> +    }
>>>> +
>>>>        ret = qmi_txn_init(&ab->qmi.handle, &txn,
>>>>                   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
>>>>        if (ret < 0)
>>>> @@ -2319,11 +2360,14 @@ static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
>>>>          ab->qmi.num_radios = resp.num_phy;
>>>>    +    if (resp.dynamic_ddr_support_valid)
>>>> +        ab->qmi.dynamic_ddr_support = resp.dynamic_ddr_support;
>>>> +
>>>>        ath12k_dbg(ab, ATH12K_DBG_QMI,
>>>> -           "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
>>>> +           "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d dynamic_ddr_valid %d dynamic_ddr_support %d\n",
>>>>               resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
>>>> -           resp.num_phy_valid, resp.num_phy,
>>>> -           resp.board_id_valid, resp.board_id);
>>>> +           resp.num_phy_valid, resp.num_phy, resp.board_id_valid, resp.board_id,
>>>> +           resp.dynamic_ddr_support_valid, resp.dynamic_ddr_support);
>>>>          return;
>>>>    diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
>>>> index 2a63e214eb42..dbde76e5a78d 100644
>>>> --- a/drivers/net/wireless/ath/ath12k/qmi.h
>>>> +++ b/drivers/net/wireless/ath/ath12k/qmi.h
>>>> @@ -156,9 +156,10 @@ struct ath12k_qmi {
>>>>        struct m3_mem_region aux_uc_mem;
>>>>        unsigned int service_ins_id;
>>>>        struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01];
>>>> +    u8 dynamic_ddr_support;
>>>>    };
>>>>    -#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN        261
>>>> +#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN        265
>>>>    #define QMI_WLANFW_HOST_CAP_REQ_V01            0x0034
>>>>    #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN    7
>>>>    #define QMI_WLFW_HOST_CAP_RESP_V01            0x0034
>>>> @@ -258,7 +259,8 @@ struct qmi_wlanfw_host_cap_req_msg_v01 {
>>>>        struct wlfw_host_mlo_chip_info_s_v01 mlo_chip_info[QMI_WLFW_MAX_NUM_MLO_CHIPS_V01];
>>>>        u8 feature_list_valid;
>>>>        u64 feature_list;
>>>> -
>>>> +    u8 dynamic_mem_support_valid;
>>>> +    u8 dynamic_mem_support;
>>>>    };
>>>>      struct qmi_wlanfw_host_cap_resp_msg_v01 {
>>>> @@ -267,7 +269,7 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 {
>>>>      #define QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN        0
>>>>    #define QMI_WLANFW_PHY_CAP_REQ_V01            0x0057
>>>> -#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN        18
>>>> +#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN        22
>>>
>>> this is not used anywhere, but since you're touching it should this be 26 ? response TLV 7, num_phy 4, board_id 7, existing single_chip_mlo_support 4, and new dynamic_ddr_support 4
>>>
>>>
>>> -- 
>>> Ramesh
>>
>> I checked the driver and found there are several unused QMI_*_RESP_MSG_LEN macros.
>> Since this macro is not used anywhere, I think it is better to remove this
>> change from the current patch.
>> I will send a separate cleanup patch to remove all unused QMI macros.
>>
>> Hope that’s fine with you.
>>
> 
> 
> I couldn’t trace the history either.
> My guess is that the response-length macro was retained either as schema 
> documentation or to keep it consistent with the generated QMI definitions.
> 
> Jeff may be able to confirm the original intent.

I suspect this was from the code generator and was just pulled in.
Concur we should just drop this (and have a cleanup patch to remove any others
that are unused).

And this V01 naming convention seems broken since we've regularly extended
messages and yet still call them V01. I would have expected each extension
would have incremented the version number...

And I also think it is strange to pass the message length anyway since the
serializer should be able to figure that out -- having the clients pass that
means the clients must know the details of the serialization algorithm which
is a layering violation. But that is a preexisting issue with the QMI interface.

/jeff

/jeff
> 


^ permalink raw reply

* Re: [PATCH wireless-next] wifi: mt76: fix of_get_mac_address error handling
From: Rosen Penev @ 2026-06-18 23:01 UTC (permalink / raw)
  To: Klara Modin
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <ajRmlyx_AEGybykL@soda.int.kasm.eu>

On Thu, Jun 18, 2026 at 2:47 PM Klara Modin <klarasmodin@gmail.com> wrote:
>
> Hi,
>
> On 2026-04-26 22:17:46 -0700, Rosen Penev wrote:
> > Check return value instead of is_valid_ether_addr. The latter is handled
> > by the former.
> >
> > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > ---
> >  drivers/net/wireless/mediatek/mt76/eeprom.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > index 93d91264687f..0f6ccf6ed53d 100644
> > --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> > +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > @@ -93,7 +93,7 @@ mt76_eeprom_override(struct mt76_phy *phy)
> >       if (err == -EPROBE_DEFER)
> >               return err;
> >
> > -     if (!is_valid_ether_addr(phy->macaddr)) {
> > +     if (err) {
> >               eth_random_addr(phy->macaddr);
> >               dev_info(dev->dev,
> >                        "Invalid MAC address, using random address %pM\n",
> > --
> > 2.54.0
> >
>
> Recently I have started to see randomized MAC-addresses on my x86 laptop
> with a MT7922 and the above message printed in the kernel log. I have
> CONFIG_OF turned on, but since this is an ACPI system the device is not
> described by any device tree and the earlier of_get_mac_address() likely
> fails with -ENODEV. Looking at the !CONFIG_OF stub for
> of_get_mac_address it always returns -ENODEV, meaning this will always
> randomize the mac in that case too.
IIRC, the normal device_get_mac_address supports nvmem now. Does that
fix your use case?
>
> Reverting this patch fixes the issue and the correct MAC address is
> used. I'm not sure if there is any case where of_get_mac_addres() could
> fail in a way that results in a valid MAC address but it seems unlikely
> to me.
>
> Regards,
> Klara Modin

^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath9k: mark PN9Data as const
From: Rosen Penev @ 2026-06-18 22:58 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: linux-wireless, Toke Høiland-Jørgensen, open list
In-Reply-To: <9c08b419-7180-4ecf-8a9d-026a80cbb98a@oss.qualcomm.com>

On Thu, Jun 18, 2026 at 2:55 PM Jeff Johnson
<jeff.johnson@oss.qualcomm.com> wrote:
>
> On 6/15/2026 8:06 PM, Rosen Penev wrote:
> > PN9Data is a read-only lookup table and is never modified.  Adding const
> > lets the compiler place it in .rodata and prevents accidental writes.
> >
> > Assisted-by: opencode:big-pickle
> > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > ---
> >  drivers/net/wireless/ath/ath9k/tx99.c | 16 ++++++++--------
> >  drivers/net/wireless/ath/ath9k/xmit.c |  2 +-
> >  2 files changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
> > index f2144fd39093..b52d84f6cbc9 100644
> > --- a/drivers/net/wireless/ath/ath9k/tx99.c
> > +++ b/drivers/net/wireless/ath/ath9k/tx99.c
> > @@ -39,14 +39,14 @@ static void ath9k_tx99_stop(struct ath_softc *sc)
> >
> >  static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
> >  {
> > -     static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
> > -                            0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
> > -                            0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
> > -                            0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
> > -                            0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
> > -                            0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
> > -                            0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
> > -                            0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
> > +     static const u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
> > +                                  0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
> > +                                  0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
> > +                                  0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
> > +                                  0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
> > +                                  0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
> > +                                  0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
> > +                                  0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
> >       u32 len = 1200;
> >       struct ieee80211_tx_rate *rate;
> >       struct ieee80211_hw *hw = sc->hw;
> > diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
> > index 89d8b3178784..57e451548958 100644
> > --- a/drivers/net/wireless/ath/ath9k/xmit.c
> > +++ b/drivers/net/wireless/ath/ath9k/xmit.c
> > @@ -41,7 +41,7 @@
> >  #define ATH9K_PWRTBL_11NG_HT_SHIFT      12
> >
> >
> > -static u16 bits_per_symbol[][2] = {
> > +static const u16 bits_per_symbol[][2] = {
>
> unrelated change not mentioned in the commit text?
Yeah. Will do in v2.
>
> >       /* 20MHz 40MHz */
> >       {    26,   54 },     /*  0: BPSK */
> >       {    52,  108 },     /*  1: QPSK 1/2 */
> > --
> > 2.54.0
>

^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath9k: mark PN9Data as const
From: Jeff Johnson @ 2026-06-18 21:55 UTC (permalink / raw)
  To: Rosen Penev, linux-wireless; +Cc: Toke Høiland-Jørgensen, open list
In-Reply-To: <20260616030652.635121-1-rosenp@gmail.com>

On 6/15/2026 8:06 PM, Rosen Penev wrote:
> PN9Data is a read-only lookup table and is never modified.  Adding const
> lets the compiler place it in .rodata and prevents accidental writes.
> 
> Assisted-by: opencode:big-pickle
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  drivers/net/wireless/ath/ath9k/tx99.c | 16 ++++++++--------
>  drivers/net/wireless/ath/ath9k/xmit.c |  2 +-
>  2 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
> index f2144fd39093..b52d84f6cbc9 100644
> --- a/drivers/net/wireless/ath/ath9k/tx99.c
> +++ b/drivers/net/wireless/ath/ath9k/tx99.c
> @@ -39,14 +39,14 @@ static void ath9k_tx99_stop(struct ath_softc *sc)
> 
>  static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
>  {
> -	static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
> -			       0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
> -			       0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
> -			       0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
> -			       0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
> -			       0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
> -			       0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
> -			       0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
> +	static const u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
> +			             0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
> +			             0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
> +			             0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
> +			             0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
> +			             0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
> +			             0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
> +			             0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
>  	u32 len = 1200;
>  	struct ieee80211_tx_rate *rate;
>  	struct ieee80211_hw *hw = sc->hw;
> diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
> index 89d8b3178784..57e451548958 100644
> --- a/drivers/net/wireless/ath/ath9k/xmit.c
> +++ b/drivers/net/wireless/ath/ath9k/xmit.c
> @@ -41,7 +41,7 @@
>  #define ATH9K_PWRTBL_11NG_HT_SHIFT      12
> 
> 
> -static u16 bits_per_symbol[][2] = {
> +static const u16 bits_per_symbol[][2] = {

unrelated change not mentioned in the commit text?

>  	/* 20MHz 40MHz */
>  	{    26,   54 },     /*  0: BPSK */
>  	{    52,  108 },     /*  1: QPSK 1/2 */
> --
> 2.54.0


^ permalink raw reply

* Re: [PATCH wireless-next] wifi: mt76: fix of_get_mac_address error handling
From: Klara Modin @ 2026-06-18 21:47 UTC (permalink / raw)
  To: Rosen Penev
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <20260427051746.954704-1-rosenp@gmail.com>

Hi,

On 2026-04-26 22:17:46 -0700, Rosen Penev wrote:
> Check return value instead of is_valid_ether_addr. The latter is handled
> by the former.
> 
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  drivers/net/wireless/mediatek/mt76/eeprom.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> index 93d91264687f..0f6ccf6ed53d 100644
> --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> @@ -93,7 +93,7 @@ mt76_eeprom_override(struct mt76_phy *phy)
>  	if (err == -EPROBE_DEFER)
>  		return err;
>  
> -	if (!is_valid_ether_addr(phy->macaddr)) {
> +	if (err) {
>  		eth_random_addr(phy->macaddr);
>  		dev_info(dev->dev,
>  			 "Invalid MAC address, using random address %pM\n",
> -- 
> 2.54.0
> 

Recently I have started to see randomized MAC-addresses on my x86 laptop
with a MT7922 and the above message printed in the kernel log. I have
CONFIG_OF turned on, but since this is an ACPI system the device is not
described by any device tree and the earlier of_get_mac_address() likely
fails with -ENODEV. Looking at the !CONFIG_OF stub for
of_get_mac_address it always returns -ENODEV, meaning this will always
randomize the mac in that case too.

Reverting this patch fixes the issue and the correct MAC address is
used. I'm not sure if there is any case where of_get_mac_addres() could
fail in a way that results in a valid MAC address but it seems unlikely
to me.

Regards,
Klara Modin

^ permalink raw reply

* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
From: David Laight @ 2026-06-18 21:36 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Andy Shevchenko, linux-hardening, linux-kernel, linux-wireless,
	Kees Cook, Gustavo A. R. Silva
In-Reply-To: <37fcf7c0b1a330a40005fc5ddbe075267b93851e.camel@sipsolutions.net>

On Thu, 18 Jun 2026 20:53:37 +0200
Johannes Berg <johannes@sipsolutions.net> wrote:

> (hah, just found this window open from this morning ...)
> 
> On Thu, 2026-06-18 at 09:39 +0300, Andy Shevchenko wrote:
> > On Wed, Jun 17, 2026 at 10:30:56PM +0100, David Laight wrote:  
> > > On Wed, 17 Jun 2026 14:56:09 +0200
> > > Johannes Berg <johannes@sipsolutions.net> wrote:  
> > > > On Wed, 2026-06-17 at 13:12 +0200, Andy Shevchenko wrote:  
> > > > > Convert size_add() to take variadic argument, so we can simplify users
> > > > > with using a macro only once.    
> > > >   
> > > > > +#define __size_add3(addend1, addend2, addend3, addend4, ...)			\
> > > > > +	__size_add(__size_add2(addend1,  addend2, addend3), addend4)
> > > > > +#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
> > > > > +	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)    
> > > > 
> > > > I guess it's not going to really matter, but it would generate fewer
> > > > calls to have something more like
> > > > 
> > > > #define __size_add3(a1, a2, a3, a4) \
> > > > 	size_add(size_add(a1, a2), size_add(a3, a4))
> > > > #define __size_add4(a1, a2, a3, a4, a5) \
> > > > 	size_add(size_add(a1, a2), size_add(a3, a4, a5))
> > > > 
> > > > as a binary tree, rather than only cutting one off every time. Not sure
> > > > that results in hugely different code though - maybe fewer overflow
> > > > checks?  
> > 
> > Good question. I'm also thinking that one-by-one may expand in too much of
> > preprocessor code (haven't checked myself).  
> 
> No. I was confused, and managed to confuse you too perhaps, sorry!
> 
> We have to have the same number of operations (__size_add calls)
> regardless, since you have to add it all up: 1 + 2 + 3 + 4 + 5 has a
> fixed number of + signs regardless of how you parenthesise it.
> 
> I guess actual CPU execution would have a better data dependency tree if
> we balance it,

Absolutely.
Intel Haswell onwards and zen1-4 can execute 4 independent add/sub/and/or
(etc) every clock. 

zen5 wins with 6 arithmetic ops or 4 cmov (and 2 alu) per clock.

> but ... if our hotpath depends on size_add() we've lost already.

I've no idea what the compiler generates, but a cmovc to copy in ~0
when the add sets carry stands a good chance of being pretty near the best.
What you don't want is a conditional jump.
The add, cmov pair will take two clocks, but the pairs are independent of
each other (the carry flag isn't a limitation).
The cpu should be able to execute two add and two cmov every clock.
So with 4 values the 'tree' version is 4 clocks
The other problem with ((a + b) + c) + d is that execution can't start
until both a and b are available; with (a + b) + (c + d) it is much
more likely that one of the adds can be executed early.

Trying to guess the performance of modern cpu is non-trivial.

	David

> 
> johannes


^ permalink raw reply

* Re: [PATCH ath-next] ath9k: eeprom: alias vpdTableI onto vpdTableL to shrink stack frame
From: Rosen Penev @ 2026-06-18 19:20 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Rosen Penev, linux-wireless
  Cc: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	open list,
	open list:CLANG/LLVM BUILD SUPPORT:Keyword:b(?i:clang|llvm)b
In-Reply-To: <87pl1ofa6t.fsf@toke.dk>

On Thu Jun 18, 2026 at 2:51 AM PDT, Toke Høiland-Jørgensen wrote:
> Rosen Penev <rosenp@gmail.com> writes:
>
>> vpdTableL, vpdTableR, and vpdTableI are never live simultaneously.
>> vpdTableL and vpdTableR are consumed during the frequency-interpolation
>> step that writes vpdTableI; after the if/else they are never read
>> again.  Reuse vpdTableL for the interpolated result (what was
>> vpdTableI), reducing the stack frame by one 256-byte array.
>>
>> The read-via-write in the else branch is safe: ath9k_hw_interpolate()
>> receives vpdTableL[i][j] by value as a function argument before the
>> return value is written back to vpdTableL[i][j].
>>
>> Stack frame size change (x86_64, clang):
>>   before: 0x440 (1088 B)
>>   after:  0x330 (816 B)
>
> Huh? These are static variables, how is this affecting stack usage?
> I assume this is against your previous (broken) patch?
It's only broken on ARM + GCC. GCC + anything else and Clang + anything
else is fine.
>
> Anyway, adding this kind of aliasing to fix a problem that you
> introduced by changing working code with no real benefit is not an
> improvement. I'm OK with fixing actual bugs, but this is just mindless
> churn...
Fixing actual bugs is the goal yes. It makes sense to split up into
multiple parts IMO.
>
> -Toke


^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath9k: drop static from local pdadc and vpdTable arrays
From: Rosen Penev @ 2026-06-18 19:18 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Rosen Penev, linux-wireless; +Cc: open list
In-Reply-To: <87se6kfa9b.fsf@toke.dk>

On Thu Jun 18, 2026 at 2:50 AM PDT, Toke Høiland-Jørgensen wrote:
> Rosen Penev <rosenp@gmail.com> writes:
>
>> Remove the static qualifier from mutable local arrays in three EEPROM
>> power-calibration functions.  These arrays are written to during normal
>> operation, so static storage is both unnecessary and misleading: it
>> implies sharing across calls when no such sharing is intended, and it
>> makes the code subtly non-reentrant.  The sibling function in
>> eeprom_9287.c already uses an automatic (stack-local) pdadcValues,
>> confirming this is the correct pattern.
>>
>> This keeps ~1 KB of data off the static data section at the cost of
>> stack usage, consistent with the rest of the driver's coding style.
>
> As pointed out by the test robot, putting this much data on the stack is
> a bad idea. Pretty sure it's static for exactly this reason in the first
> place.
Sashiko points out the opposite:

This is a pre-existing issue, but by declaring vpdTableL and vpdTableR as
static local variables, doesn't this create thread-unsafe global state?
If a system contains multiple ath9k wireless adapters, or if operations
like background scans trigger ath9k_hw_reset() concurrently, threads could
race to read and write these shared arrays. Could this potentially corrupt
the EEPROM calibration data and PDADC hardware configurations across devices?
>
> -Toke


^ permalink raw reply

* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
From: Johannes Berg @ 2026-06-18 18:53 UTC (permalink / raw)
  To: Andy Shevchenko, David Laight
  Cc: linux-hardening, linux-kernel, linux-wireless, Kees Cook,
	Gustavo A. R. Silva
In-Reply-To: <ajOSqWpYUhFTVqP-@ashevche-desk.local>

(hah, just found this window open from this morning ...)

On Thu, 2026-06-18 at 09:39 +0300, Andy Shevchenko wrote:
> On Wed, Jun 17, 2026 at 10:30:56PM +0100, David Laight wrote:
> > On Wed, 17 Jun 2026 14:56:09 +0200
> > Johannes Berg <johannes@sipsolutions.net> wrote:
> > > On Wed, 2026-06-17 at 13:12 +0200, Andy Shevchenko wrote:
> > > > Convert size_add() to take variadic argument, so we can simplify users
> > > > with using a macro only once.  
> > > 
> > > > +#define __size_add3(addend1, addend2, addend3, addend4, ...)			\
> > > > +	__size_add(__size_add2(addend1,  addend2, addend3), addend4)
> > > > +#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
> > > > +	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)  
> > > 
> > > I guess it's not going to really matter, but it would generate fewer
> > > calls to have something more like
> > > 
> > > #define __size_add3(a1, a2, a3, a4) \
> > > 	size_add(size_add(a1, a2), size_add(a3, a4))
> > > #define __size_add4(a1, a2, a3, a4, a5) \
> > > 	size_add(size_add(a1, a2), size_add(a3, a4, a5))
> > > 
> > > as a binary tree, rather than only cutting one off every time. Not sure
> > > that results in hugely different code though - maybe fewer overflow
> > > checks?
> 
> Good question. I'm also thinking that one-by-one may expand in too much of
> preprocessor code (haven't checked myself).

No. I was confused, and managed to confuse you too perhaps, sorry!

We have to have the same number of operations (__size_add calls)
regardless, since you have to add it all up: 1 + 2 + 3 + 4 + 5 has a
fixed number of + signs regardless of how you parenthesise it.

I guess actual CPU execution would have a better data dependency tree if
we balance it, but ... if our hotpath depends on size_add() we've lost
already.

johannes

^ permalink raw reply

* Re: [PATCH 1/4] bcma: host_pci: add BCM4352 device ID 0x43b3
From: Michael Büsch @ 2026-06-18 17:57 UTC (permalink / raw)
  To: Alessio Ferri
  Cc: Rafał Miłecki, linux-wireless, linux-kernel, b43-dev,
	Alessio Ferri
In-Reply-To: <20260617-b43-add-4352-wip-v1-1-c81323496720@gmail.com>

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

On Wed, 17 Jun 2026 23:42:08 +0200
Alessio Ferri <alessio.ferri@mythread.it> wrote:

> From: Alessio Ferri <alessio.ferri.3012@gmail.com>
> 
> The BCM4352 is an AC PHY. It is missing from bcma_pci_bridge_tbl[],
> so bcma-pci-bridge does not bind. Add the ID.
> 
> The chip identifies as BCM4352 (chip rev 3, PHY type AC); b43 with AC-PHY
> support handles it once bcma reaches the D11 core.
> 
> Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
> ---
>  drivers/bcma/host_pci.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
> index 3dc2985063f1..f6cf722a3798 100644
> --- a/drivers/bcma/host_pci.c
> +++ b/drivers/bcma/host_pci.c
> @@ -298,6 +298,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
>  	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
>  	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
>  	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) },
> +	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b3) },
>  	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
>  	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) },	/* 0xa8db, BCM43217 (sic!) */
>  	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) },	/* 0xa8dc */
> 

Please submit this patch last, after the driver is expected to actually work
on the device.

-- 
Michael Büsch
https://bues.ch/

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: NIPA/wifibot disappeared
From: Johannes Berg @ 2026-06-18 11:50 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <a5615f2658fe31a32836d02aa0f2d69027782bea.camel@sipsolutions.net>

On Wed, 2026-05-27 at 12:52 +0200, Johannes Berg wrote:
> Hi,
> 
> Due to a mistake, the machine that was running our checks was
> decommissioned and redeployed about two days ago.
> 
> I'd been planning to move the service to the servers that we have at the
> netdev foundation for NIPA, but hadn't actually started doing that
> because I've just been too busy with other things.

Good news :-)

Thanks to Matthieu (who did all the hard work) and the Netdev Foundation
(sponsoring the work and the server time), the bot has been back for
about a day or so, running on Netdev Foundation infrastructure (rather
than an Intel server I had to maintain personally.)

It's on the netdev config, so perhaps a little pickier than it used to
be.

johannes

^ permalink raw reply

* Re: [PATCH ath-next] ath9k: eeprom: alias vpdTableI onto vpdTableL to shrink stack frame
From: Toke Høiland-Jørgensen @ 2026-06-18  9:51 UTC (permalink / raw)
  To: Rosen Penev, linux-wireless
  Cc: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	open list,
	open list:CLANG/LLVM BUILD SUPPORT:Keyword:b(?i:clang|llvm)b
In-Reply-To: <20260617234105.284358-1-rosenp@gmail.com>

Rosen Penev <rosenp@gmail.com> writes:

> vpdTableL, vpdTableR, and vpdTableI are never live simultaneously.
> vpdTableL and vpdTableR are consumed during the frequency-interpolation
> step that writes vpdTableI; after the if/else they are never read
> again.  Reuse vpdTableL for the interpolated result (what was
> vpdTableI), reducing the stack frame by one 256-byte array.
>
> The read-via-write in the else branch is safe: ath9k_hw_interpolate()
> receives vpdTableL[i][j] by value as a function argument before the
> return value is written back to vpdTableL[i][j].
>
> Stack frame size change (x86_64, clang):
>   before: 0x440 (1088 B)
>   after:  0x330 (816 B)

Huh? These are static variables, how is this affecting stack usage?
I assume this is against your previous (broken) patch?

Anyway, adding this kind of aliasing to fix a problem that you
introduced by changing working code with no real benefit is not an
improvement. I'm OK with fixing actual bugs, but this is just mindless
churn...

-Toke

^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath9k: drop static from local pdadc and vpdTable arrays
From: Toke Høiland-Jørgensen @ 2026-06-18  9:50 UTC (permalink / raw)
  To: Rosen Penev, linux-wireless; +Cc: open list
In-Reply-To: <20260616030828.655310-1-rosenp@gmail.com>

Rosen Penev <rosenp@gmail.com> writes:

> Remove the static qualifier from mutable local arrays in three EEPROM
> power-calibration functions.  These arrays are written to during normal
> operation, so static storage is both unnecessary and misleading: it
> implies sharing across calls when no such sharing is intended, and it
> makes the code subtly non-reentrant.  The sibling function in
> eeprom_9287.c already uses an automatic (stack-local) pdadcValues,
> confirming this is the correct pattern.
>
> This keeps ~1 KB of data off the static data section at the cost of
> stack usage, consistent with the rest of the driver's coding style.

As pointed out by the test robot, putting this much data on the stack is
a bad idea. Pretty sure it's static for exactly this reason in the first
place.

-Toke

^ 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