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 --- 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