When mac80211 does drv start/stop, apply the state change for all the radios within the wiphy in ath12k. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Sriram R <quic_srirrama@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath12k/mac.c | 57 +++++++++++++++++++++------ 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 2a70b7a486e3..7933d5993519 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -243,6 +243,7 @@ static const u32 ath12k_smps_map[] = { static int ath12k_start_vdev_delay(struct ath12k *ar, struct ath12k_vif *arvif); +static void ath12k_mac_stop(struct ath12k *ar); static const char *ath12k_mac_phymode_str(enum wmi_phy_mode mode) { @@ -5302,28 +5303,56 @@ static int ath12k_mac_start(struct ath12k *ar) return ret; } +static void ath12k_drain_tx(struct ath12k_hw *ah) +{ + int i; + struct ath12k *ar; + + ar = ah->radio; + + for (i = 0; i < ah->num_radio; i++) { + ath12k_mac_drain_tx(ar); + ar++; + } +} + static int ath12k_mac_op_start(struct ieee80211_hw *hw) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); - struct ath12k *ar = ath12k_ah_to_ar(ah, 0); - struct ath12k_base *ab = ar->ab; - int ret; + struct ath12k *ar; + struct ath12k_base *ab; + int ret = 0; + int i; + + ath12k_drain_tx(ah); - ath12k_mac_drain_tx(ar); + ar = ah->radio; + ab = ar->ab; mutex_lock(&ah->conf_mutex); - ret = ath12k_mac_start(ar); - if (ret) { - ath12k_err(ab, "fail to start mac operations in pdev idx %d ret %d\n", - ar->pdev_idx, ret); - mutex_unlock(&ah->conf_mutex); - return ret; + for (i = 0; i < ah->num_radio; i++) { + ret = ath12k_mac_start(ar); + if (ret) { + ath12k_err(ab, "fail to start mac operations in pdev idx %d ret %d\n", + ar->pdev_idx, ret); + goto fail; + } + ar++; + ab = ar->ab; } mutex_unlock(&ah->conf_mutex); return 0; +fail: + for (; i > 0; i--) { + ar--; + ath12k_mac_stop(ar); + } + + mutex_unlock(&ah->conf_mutex); + return ret; } int ath12k_mac_rfkill_config(struct ath12k *ar) @@ -5420,12 +5449,16 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar = ath12k_ah_to_ar(ah, 0); + int i; - ath12k_mac_drain_tx(ar); + ath12k_drain_tx(ah); mutex_lock(&ah->conf_mutex); - ath12k_mac_stop(ar); + for (i = 0; i < ah->num_radio; i++) { + ath12k_mac_stop(ar); + ar++; + } mutex_unlock(&ah->conf_mutex); } -- 2.17.1