mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 04:56:13 +02:00
wifi: ath12k: Add lock to protect the hardware state
Currently, hardware state is not protected across the reconfigure operations. However, in single wiphy models, multiple radio/links is exposed as a MAC hardware (ieee80211_hw) through the driver hardware abstraction (ath12k_hw) layer. In such scenario, we need to protect hardware state across the multiple radio/link at the driver hardware abstraction (ath12k_hw) layer. Therefore, introduce a new mutex in the ath12k_hw layer. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://msgid.link/20240425090307.3233434-4-quic_periyasa@quicinc.com
This commit is contained in:
parent
9b4e5caaf5
commit
acaa84009f
|
|
@ -1048,6 +1048,8 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab)
|
|||
if (!ah || ah->state == ATH12K_HW_STATE_OFF)
|
||||
continue;
|
||||
|
||||
mutex_lock(&ah->hw_mutex);
|
||||
|
||||
switch (ah->state) {
|
||||
case ATH12K_HW_STATE_ON:
|
||||
ah->state = ATH12K_HW_STATE_RESTARTING;
|
||||
|
|
@ -1078,6 +1080,8 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab)
|
|||
"device is wedged, will not restart hw %d\n", i);
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&ah->hw_mutex);
|
||||
}
|
||||
|
||||
complete(&ab->driver_recovery);
|
||||
|
|
|
|||
|
|
@ -636,11 +636,17 @@ struct ath12k {
|
|||
struct ath12k_hw {
|
||||
struct ieee80211_hw *hw;
|
||||
struct ath12k_base *ab;
|
||||
|
||||
/* Protect the write operation of the hardware state ath12k_hw::state
|
||||
* between hardware start<=>reconfigure<=>stop transitions.
|
||||
*/
|
||||
struct mutex hw_mutex;
|
||||
enum ath12k_hw_state state;
|
||||
bool regd_updated;
|
||||
bool use_6ghz_regd;
|
||||
u8 num_radio;
|
||||
|
||||
/* Keep last */
|
||||
struct ath12k radio[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5615,10 +5615,13 @@ static void ath12k_mac_wait_reconfigure(struct ath12k_base *ab)
|
|||
|
||||
static int ath12k_mac_start(struct ath12k *ar)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ath12k_pdev *pdev = ar->pdev;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ah->hw_mutex);
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS,
|
||||
|
|
@ -5733,6 +5736,8 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
|
|||
|
||||
ath12k_drain_tx(ah);
|
||||
|
||||
guard(mutex)(&ah->hw_mutex);
|
||||
|
||||
switch (ah->state) {
|
||||
case ATH12K_HW_STATE_OFF:
|
||||
ah->state = ATH12K_HW_STATE_ON;
|
||||
|
|
@ -5831,9 +5836,12 @@ int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable)
|
|||
|
||||
static void ath12k_mac_stop(struct ath12k *ar)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct htt_ppdu_stats_info *ppdu_stats, *tmp;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ah->hw_mutex);
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
ret = ath12k_mac_config_mon_status_default(ar, false);
|
||||
if (ret && (ret != -EOPNOTSUPP))
|
||||
|
|
@ -5869,10 +5877,14 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
|
|||
|
||||
ath12k_drain_tx(ah);
|
||||
|
||||
mutex_lock(&ah->hw_mutex);
|
||||
|
||||
ah->state = ATH12K_HW_STATE_OFF;
|
||||
|
||||
for_each_ar(ah, ar, i)
|
||||
ath12k_mac_stop(ar);
|
||||
|
||||
mutex_unlock(&ah->hw_mutex);
|
||||
}
|
||||
|
||||
static u8
|
||||
|
|
@ -7931,6 +7943,8 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
|
|||
if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
|
||||
return;
|
||||
|
||||
guard(mutex)(&ah->hw_mutex);
|
||||
|
||||
if (ah->state != ATH12K_HW_STATE_RESTARTED)
|
||||
return;
|
||||
|
||||
|
|
@ -8933,6 +8947,8 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
|
|||
ah->ab = ab;
|
||||
ah->num_radio = num_pdev_map;
|
||||
|
||||
mutex_init(&ah->hw_mutex);
|
||||
|
||||
for (i = 0; i < num_pdev_map; i++) {
|
||||
ab = pdev_map[i].ab;
|
||||
pdev_idx = pdev_map[i].pdev_idx;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user