Currently, ath12k_core_pre_reconfigure_recovery() reconfigures all radios within the same group. During grouping and driver going for a recovery, this function is called as many times as there are devices in the group. Consequently, it performs the same reconfiguration multiple times, which is unnecessary. To prevent this, add a check to continue if the action has already been taken. To simplify the management of various flags, the reason for hardware queues being stopped is used as a check instead of introducing a new flag. While at it, also add missing wiphy locks. Wiphy lock is required since ath12k_mac_drain_tx() which is called by ath12k_core_pre_reconfigure_recovery() needs this lock to be held by the caller. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Signed-off-by: Aditya Kumar Singh <quic_adisi@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath12k/core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 72e6e3a0cf7be03b20b7421866c479dfcb8038ff..5700fc661ac380b6c01d0571595d27fb1ab7c8c5 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1279,6 +1279,18 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab) if (!ah || ah->state == ATH12K_HW_STATE_OFF) continue; + wiphy_lock(ah->hw->wiphy); + + /* If queue 0 is stopped, it is safe to assume that all + * other queues are stopped by driver via + * ieee80211_stop_queues() below. This means, there is + * no need to stop it again and hence continue + */ + if (ieee80211_queue_stopped(ah->hw, 0)) { + wiphy_unlock(ah->hw->wiphy); + continue; + } + ieee80211_stop_queues(ah->hw); for (j = 0; j < ah->num_radio; j++) { @@ -1301,6 +1313,8 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab) idr_destroy(&ar->txmgmt_idr); wake_up(&ar->txmgmt_empty_waitq); } + + wiphy_unlock(ah->hw->wiphy); } wake_up(&ab->wmi_ab.tx_credits_wq); -- 2.34.1