]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
wifi: ath12k: Refactor the hardware state
authorKarthikeyan Periyasamy <quic_periyasa@quicinc.com>
Fri, 3 May 2024 10:34:37 +0000 (13:34 +0300)
committerKalle Valo <quic_kvalo@quicinc.com>
Fri, 3 May 2024 13:12:14 +0000 (16:12 +0300)
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>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240425090307.3233434-3-quic_periyasa@quicinc.com
drivers/net/wireless/ath/ath12k/core.c
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/reg.c

index ae14614c3568a5bdace0d486e14c66d1bd9142f6..a685cfd6fd92f9aaabf96144fc8baae4369347e4 100644 (file)
@@ -1006,15 +1006,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->state == ATH12K_STATE_OFF)
-                               continue;
 
                        ath12k_mac_drain_tx(ar);
                        complete(&ar->scan.started);
@@ -1044,47 +1042,42 @@ 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;
 
-               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)
+                       /* Restart after all the link/radio halt */
                        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;
+               }
        }
 
        complete(&ab->driver_recovery);
index 47dde440121001cbfd54256b49f357631bd8b984..c4eb8b25398c05b8750513889f4a30d7903b3441 100644 (file)
@@ -457,12 +457,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 */
 };
 
@@ -511,7 +511,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;
@@ -636,10 +635,12 @@ struct ath12k {
 
 struct ath12k_hw {
        struct ieee80211_hw *hw;
+       struct ath12k_base *ab;
+       enum ath12k_hw_state state;
        bool regd_updated;
        bool use_6ghz_regd;
-
        u8 num_radio;
+
        struct ath12k radio[] __aligned(sizeof(void *));
 };
 
@@ -1037,6 +1038,11 @@ static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah, u8 hw_link_id
        return &ah->radio[hw_link_id];
 }
 
+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;
index 6d19b6003aea2cffe8828cad18b4a37eea416c91..0cb2e0435cc06524353035e356599b94f8971dfe 100644 (file)
@@ -5269,6 +5269,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);
@@ -5289,8 +5290,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,
@@ -5620,22 +5621,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);
 
@@ -5726,7 +5711,6 @@ static int ath12k_mac_start(struct ath12k *ar)
 
        return 0;
 err:
-       ar->state = ATH12K_STATE_OFF;
        mutex_unlock(&ar->conf_mutex);
 
        return ret;
@@ -5749,9 +5733,28 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
 
        ath12k_drain_tx(ah);
 
+       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);
+               return -EINVAL;
+       }
+
        for_each_ar(ah, ar, i) {
                ret = ath12k_mac_start(ar);
                if (ret) {
+                       ah->state = ATH12K_HW_STATE_OFF;
+
                        ath12k_err(ar->ab, "fail to start mac operations in pdev idx %d ret %d\n",
                                   ar->pdev_idx, ret);
                        goto fail_start;
@@ -5759,11 +5762,13 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
        }
 
        return 0;
+
 fail_start:
        for (; i > 0; i--) {
                ar = ath12k_ah_to_ar(ah, i - 1);
                ath12k_mac_stop(ar);
        }
+
        return ret;
 }
 
@@ -5836,7 +5841,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);
@@ -5865,6 +5869,8 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
 
        ath12k_drain_tx(ah);
 
+       ah->state = ATH12K_HW_STATE_OFF;
+
        for_each_ar(ah, ar, i)
                ath12k_mac_stop(ar);
 }
@@ -7925,22 +7931,20 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
        if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
                return;
 
+       if (ah->state != ATH12K_HW_STATE_RESTARTED)
+               return;
+
+       ah->state = ATH12K_HW_STATE_ON;
+       ieee80211_wake_queues(hw);
+
        for_each_ar(ah, ar, i) {
                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);
 
@@ -8926,6 +8930,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;
 
        for (i = 0; i < num_pdev_map; i++) {
index fbf38044938c6245230e88b399352bfcc77ca7da..439d61f284d89222e79c05d6cff8e85d0d315aad 100644 (file)
@@ -206,9 +206,9 @@ 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;
-       struct ath12k_hw *ah = ar->ah;
        int ret, regd_len, pdev_id;
        struct ath12k_base *ab;
        int i;
@@ -286,19 +286,20 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
        if (ret)
                goto err;
 
+       if (ah->state != ATH12K_HW_STATE_ON)
+               goto skip;
+
        ah->regd_updated = true;
        /* Apply the new regd to all the radios, this is expected to be received only once
         * since we check for ah->regd_updated and allow here only once.
         */
        for_each_ar(ah, ar, i) {
-               if (ar->state == ATH12K_STATE_ON) {
-                       ab = ar->ab;
-                       ret = ath12k_reg_update_chan_list(ar);
-                       if (ret)
-                               goto err;
-               }
+               ab = ar->ab;
+               ret = ath12k_reg_update_chan_list(ar);
+               if (ret)
+                       goto err;
        }
-
+skip:
        return 0;
 err:
        ath12k_warn(ab, "failed to perform regd update : %d\n", ret);