[PATCH ath-next 1/4] wifi: ath12k: signal regd update completion when reg event is dropped

Baochen Qiang <[email protected]>
Newsgroups org.kernel.vger.linux-wireless,org.infradead.lists.ath12k
Message-ID <20260729-ath12k-regd-wait-timeout-v1-1-504aa6e7e93c@oss.qualcomm.com>
During driver bring-up, ath12k_mac_hw_register() reinitializes
ar->regd_update_completed and sends a set current country command to
firmware. It then relies on the regulatory event from firmware to signal
that completion via ath12k_reg_chan_list_event().

However, when the country being set is identical to the one already
applied at boot time, ath12k_reg_validate_reg_info() returns
ATH12K_REG_STATUS_DROP through the "Avoid multiple overwrites to default
regd" path. In that case ath12k_reg_chan_list_event() jumps to mem_free
before assigning pdev_idx, so pdev_idx stays at its initial value of 255,
'ar' remains NULL and complete_all() is never called.

As a result the reinitialized completion is left unsignalled and the next
ath12k_regd_update() waits the full timeout, printing:

  Timeout while waiting for regulatory update

Fix this by assigning pdev_idx from the event's phy_id right after it is
extracted, before validation, so that the drop and fallback paths still
reach complete_all(). Change the guard at the end to check the index
against ab->num_radios so that an out-of-range phy_id does not lead to an
invalid pdevs[] access.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3

Fixes: 906619a00967 ("wifi: ath12k: handle regulatory hints during mac registration")
Signed-off-by: Baochen Qiang <[email protected]>
---
 drivers/net/wireless/ath/ath12k/wmi.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 2b707ffc1a20..e9ec56a0e8db 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -6964,6 +6964,14 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
 		goto mem_free;
 	}
 
+	/*
+	 * Set the valid pdev_idx before validating so that, even when the
+	 * event is dropped or falls back, the completion the caller in
+	 * ath12k_mac_hw_register() may be waiting on is still signalled at
+	 * the end and it does not time out.
+	 */
+	pdev_idx = reg_info->phy_id;
+
 	ret = ath12k_reg_validate_reg_info(ab, reg_info);
 	if (ret == ATH12K_REG_STATUS_FALLBACK) {
 		ath12k_warn(ab, "failed to validate reg info %d\n", ret);
@@ -6980,7 +6988,6 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
 	}
 
 	/* free old reg_info if it exist */
-	pdev_idx = reg_info->phy_id;
 	if (ab->reg_info[pdev_idx]) {
 		ath12k_reg_reset_reg_info(ab->reg_info[pdev_idx]);
 		kfree(ab->reg_info[pdev_idx]);
@@ -7019,7 +7026,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
 
 out:
 	/* In some error cases, even a valid pdev_idx might not be available */
-	if (pdev_idx != 255)
+	if (pdev_idx < ab->num_radios)
 		ar = ab->pdevs[pdev_idx].ar;
 
 	/* During the boot-time update, 'ar' might not be allocated,

-- 
2.25.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.