@@ -934,15 +934,13 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
for (i = 0; i < ab->num_hw; i++) {
ah = ab->ah[i];
- if (!ah)
+ if (!ah || ah->state == ATH12K_HW_STATE_OFF)
continue;
ieee80211_stop_queues(ah->hw);
for (j = 0; j < ah->num_radio; j++) {
ar = &ah->radio[j];
- if (!ar || ar->state == ATH12K_STATE_OFF)
- continue;
ath12k_mac_drain_tx(ar);
complete(&ar->scan.started);
@@ -971,49 +969,43 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab)
struct ath12k_hw *ah;
struct ath12k *ar;
int i, j;
- u8 restart_count;
for (i = 0; i < ab->num_hw; i++) {
ah = ab->ah[i];
- if (!ah)
+ if (!ah || ah->state == ATH12K_HW_STATE_OFF)
continue;
mutex_lock(&ah->conf_mutex);
- for (j = 0, restart_count = 0; j < ah->num_radio; j++) {
- ar = &ah->radio[j];
- if (ar->state == ATH12K_STATE_OFF)
- continue;
+ switch (ah->state) {
+ case ATH12K_HW_STATE_ON:
+ ah->state = ATH12K_HW_STATE_RESTARTING;
- mutex_lock(&ar->conf_mutex);
+ for (j = 0; j < ah->num_radio; j++) {
+ ar = &ah->radio[j];
- switch (ar->state) {
- case ATH12K_STATE_ON:
- ar->state = ATH12K_STATE_RESTARTING;
+ mutex_lock(&ar->conf_mutex);
ath12k_core_halt(ar);
- restart_count++;
- break;
- case ATH12K_STATE_OFF:
- ath12k_warn(ab,
- "cannot restart radio %d that hasn't been started\n",
- j);
- break;
- case ATH12K_STATE_RESTARTING:
- break;
- case ATH12K_STATE_RESTARTED:
- ar->state = ATH12K_STATE_WEDGED;
- fallthrough;
- case ATH12K_STATE_WEDGED:
- ath12k_warn(ab,
- "device is wedged, will not restart radio %d\n", j);
- break;
+ mutex_unlock(&ar->conf_mutex);
}
- mutex_unlock(&ar->conf_mutex);
- }
- /* Restart after all the link/radio got restart */
- if (restart_count == ah->num_radio)
ieee80211_restart_hw(ah->hw);
+ break;
+ case ATH12K_HW_STATE_OFF:
+ ath12k_warn(ab,
+ "cannot restart hw %d that hasn't been started\n",
+ i);
+ break;
+ case ATH12K_HW_STATE_RESTARTING:
+ break;
+ case ATH12K_HW_STATE_RESTARTED:
+ ah->state = ATH12K_HW_STATE_WEDGED;
+ fallthrough;
+ case ATH12K_HW_STATE_WEDGED:
+ ath12k_warn(ab,
+ "device is wedged, will not restart hw %d\n", i);
+ break;
+ }
mutex_unlock(&ah->conf_mutex);
}
@@ -430,12 +430,12 @@ struct ath12k_sta {
#define ATH12K_NUM_CHANS 100
#define ATH12K_MAX_5G_CHAN 173
-enum ath12k_state {
- ATH12K_STATE_OFF,
- ATH12K_STATE_ON,
- ATH12K_STATE_RESTARTING,
- ATH12K_STATE_RESTARTED,
- ATH12K_STATE_WEDGED,
+enum ath12k_hw_state {
+ ATH12K_HW_STATE_OFF,
+ ATH12K_HW_STATE_ON,
+ ATH12K_HW_STATE_RESTARTING,
+ ATH12K_HW_STATE_RESTARTED,
+ ATH12K_HW_STATE_WEDGED,
/* Add other states as required */
};
@@ -480,7 +480,6 @@ struct ath12k {
u32 ht_cap_info;
u32 vht_cap_info;
struct ath12k_he ar_he;
- enum ath12k_state state;
bool supports_6ghz;
struct {
struct completion started;
@@ -599,9 +598,11 @@ struct ath12k {
struct ath12k_hw {
struct ieee80211_hw *hw;
+ struct ath12k_base *ab;
/* To synchronize hardware restart operation */
struct mutex conf_mutex;
+ enum ath12k_hw_state state;
u8 num_radio;
@@ -934,6 +935,11 @@ static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah)
return ah->radio;
}
+static inline struct ath12k_hw *ath12k_ar_to_ah(struct ath12k *ar)
+{
+ return ar->ah;
+}
+
static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar)
{
return ar->ah->hw;
@@ -4808,6 +4808,7 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar,
static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant)
{
+ struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
int ret;
lockdep_assert_held(&ar->conf_mutex);
@@ -4821,8 +4822,8 @@ static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant)
ar->cfg_tx_chainmask = tx_ant;
ar->cfg_rx_chainmask = rx_ant;
- if (ar->state != ATH12K_STATE_ON &&
- ar->state != ATH12K_STATE_RESTARTED)
+ if (ah->state != ATH12K_HW_STATE_ON &&
+ ah->state != ATH12K_HW_STATE_RESTARTED)
return 0;
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_TX_CHAIN_MASK,
@@ -5120,7 +5121,7 @@ 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_hw *ah = ath12k_ar_to_ah(ar);
struct ath12k_base *ab = ar->ab;
struct ath12k_pdev *pdev = ar->pdev;
int ret;
@@ -5129,22 +5130,6 @@ static int ath12k_mac_start(struct ath12k *ar)
mutex_lock(&ar->conf_mutex);
- switch (ar->state) {
- case ATH12K_STATE_OFF:
- ar->state = ATH12K_STATE_ON;
- break;
- case ATH12K_STATE_RESTARTING:
- ar->state = ATH12K_STATE_RESTARTED;
- ath12k_mac_wait_reconfigure(ab);
- break;
- case ATH12K_STATE_RESTARTED:
- case ATH12K_STATE_WEDGED:
- case ATH12K_STATE_ON:
- WARN_ON(1);
- ret = -EINVAL;
- goto err;
- }
-
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS,
1, pdev->pdev_id);
@@ -5235,7 +5220,6 @@ static int ath12k_mac_start(struct ath12k *ar)
return 0;
err:
- ar->state = ATH12K_STATE_OFF;
mutex_unlock(&ar->conf_mutex);
return ret;
@@ -5252,11 +5236,33 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
mutex_lock(&ah->conf_mutex);
+ switch (ah->state) {
+ case ATH12K_HW_STATE_OFF:
+ ah->state = ATH12K_HW_STATE_ON;
+ break;
+ case ATH12K_HW_STATE_RESTARTING:
+ ah->state = ATH12K_HW_STATE_RESTARTED;
+ ath12k_mac_wait_reconfigure(ah->ab);
+ break;
+ case ATH12K_HW_STATE_RESTARTED:
+ case ATH12K_HW_STATE_WEDGED:
+ case ATH12K_HW_STATE_ON:
+ ah->state = ATH12K_HW_STATE_OFF;
+
+ WARN_ON(1);
+ ret = -EINVAL;
+ goto err;
+ }
+
ret = ath12k_mac_start(ar);
- if (ret)
+ if (ret) {
+ ah->state = ATH12K_HW_STATE_OFF;
+
ath12k_err(ab, "fail to start mac operations in pdev idx %d ret %d\n",
ar->pdev_idx, ret);
+ }
+err:
mutex_unlock(&ah->conf_mutex);
return ret;
@@ -5321,7 +5327,7 @@ 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 ath12k_hw *ah = ath12k_ar_to_ah(ar);
struct htt_ppdu_stats_info *ppdu_stats, *tmp;
int ret;
@@ -5334,7 +5340,6 @@ static void ath12k_mac_stop(struct ath12k *ar)
ret);
clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags);
- ar->state = ATH12K_STATE_OFF;
mutex_unlock(&ar->conf_mutex);
cancel_delayed_work_sync(&ar->scan.timeout);
@@ -5364,6 +5369,7 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
mutex_lock(&ah->conf_mutex);
+ ah->state = ATH12K_HW_STATE_OFF;
ath12k_mac_stop(ar);
mutex_unlock(&ah->conf_mutex);
@@ -7133,24 +7139,23 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
mutex_lock(&ah->conf_mutex);
+ if (ah->state != ATH12K_HW_STATE_RESTARTED) {
+ mutex_unlock(&ah->conf_mutex);
+ return;
+ }
+
+ ah->state = ATH12K_HW_STATE_ON;
+ ieee80211_wake_queues(hw);
+
for (i = 0; i < ah->num_radio; i++) {
ar = &ah->radio[i];
+ ab = ar->ab;
mutex_lock(&ar->conf_mutex);
- if (ar->state != ATH12K_STATE_RESTARTED) {
- mutex_unlock(&ar->conf_mutex);
- continue;
- }
-
- ab = ar->ab;
-
ath12k_warn(ar->ab, "pdev %d successfully recovered\n",
ar->pdev->pdev_id);
- ar->state = ATH12K_STATE_ON;
- ieee80211_wake_queues(hw);
-
if (ab->is_reset) {
recovery_count = atomic_inc_return(&ab->recovery_count);
@@ -7939,6 +7944,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
ah = ath12k_hw_to_ah(hw);
ah->hw = hw;
+ ah->ab = ab;
ah->num_radio = num_pdev_map;
mutex_init(&ah->conf_mutex);
@@ -200,7 +200,8 @@ static void ath12k_copy_regd(struct ieee80211_regdomain *regd_orig,
int ath12k_regd_update(struct ath12k *ar, bool init)
{
- struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
+ struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
+ struct ieee80211_hw *hw = ah->hw;
struct ieee80211_regdomain *regd, *regd_copy = NULL;
int ret, regd_len, pdev_id;
struct ath12k_base *ab;
@@ -258,7 +259,7 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
if (ret)
goto err;
- if (ar->state == ATH12K_STATE_ON) {
+ if (ah->state == ATH12K_HW_STATE_ON) {
ret = ath12k_reg_update_chan_list(ar);
if (ret)
goto err;
Currently, in multi wiphy models, the mac80211 hardware state is maintained within the radio/link structure. However, in single wiphy models, the mac80211 hardware state is needed at the hardware abstraction layer (ath12k_hw). Therefore, move the hardware state from the radio/link structure to the hardware abstraction layer (ath12k_hw). Additionally, update the naming convention of the state enums to enhance clarity and consistency. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com> --- drivers/net/wireless/ath/ath12k/core.c | 58 +++++++++------------ drivers/net/wireless/ath/ath12k/core.h | 20 ++++--- drivers/net/wireless/ath/ath12k/mac.c | 72 ++++++++++++++------------ drivers/net/wireless/ath/ath12k/reg.c | 5 +- 4 files changed, 80 insertions(+), 75 deletions(-)