[PATCH ath-next v2 3/8] wifi: ath10k: also wake remaining blocked waiters

From: Kang Yang

Date: Wed Oct 21 2026 - 05:11:37 EST


ath10k_core_wake_all_waiters() releases callers that would
otherwise remain blocked after the driver has given up on the
device.

However, peer_delete_done, target_suspend, wow.wakeup_completed,
peer_stats_info_complete and wmi.radar_confirm are not included
in that list. Callers waiting on any of them continue sleeping
until their individual timeouts expire, even though no further
progress can be made. The WoW and suspend waiters are on the
suspend/resume path, where these extra timeouts consume the
watchdog budget.

Add these completions to ath10k_core_wake_all_waiters() so
blocked callers are released immediately instead of waiting
for unnecessary timeout delays.

peer_delete_done is the only one of these that is never
reinitialized before its waiters run. A completion left over
from a wake during recovery would make the next peer delete
wait return immediately, so reinit it before each peer delete
command is sent.

Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1
Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189

Signed-off-by: Kang Yang <kang.yang@xxxxxxxxxxxxxxxx>
---
drivers/net/wireless/ath/ath10k/core.c | 5 +++++
drivers/net/wireless/ath/ath10k/mac.c | 3 +++
2 files changed, 8 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 93140f1ffb7b..677e582b87e4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2500,7 +2500,12 @@ static void ath10k_core_wake_all_waiters(struct ath10k *ar)
complete(&ar->install_key_done);
complete(&ar->vdev_setup_done);
complete(&ar->vdev_delete_done);
+ complete(&ar->peer_delete_done);
+ complete(&ar->target_suspend);
+ complete(&ar->wow.wakeup_completed);
+ complete(&ar->peer_stats_info_complete);
complete(&ar->thermal.wmi_sync);
+ complete(&ar->wmi.radar_confirm);
complete(&ar->bss_survey_done);
wake_up(&ar->htt.empty_tx_wq);
wake_up(&ar->wmi.tx_credits_wq);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 8e604697d6c2..45a3082d5a64 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -843,6 +843,7 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)

lockdep_assert_held(&ar->conf_mutex);

+ reinit_completion(&ar->peer_delete_done);
ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
if (ret)
return ret;
@@ -5890,6 +5891,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
err_peer_delete:
if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
+ reinit_completion(&ar->peer_delete_done);
ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id,
vif->addr);
@@ -5952,6 +5954,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,

if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
+ reinit_completion(&ar->peer_delete_done);
ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
vif->addr);
if (ret)

--
2.34.1