ath11k: Move mac80211 hw allocation before wmi_init command
authorVasanthakumar Thiagarajan <vthiagar@codeaurora.org>
Thu, 28 Nov 2019 08:21:57 +0000 (08:21 +0000)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 29 Nov 2019 07:50:38 +0000 (09:50 +0200)
This is to prepare REO ring setup before sending wmi_init command.
Firmware expects all the required REO rings to be setup while processing
wmi_init command. But as per the current initialization sequence, REO ring
configurations are done only after wmi_init command is sent.
Also refactoring ath11k_mac_create() into ath11k_mac_alloc() and
ath11k_mac_register() to it mac80211 hw structure available before sending
wmi_init command.

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath11k/core.c
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath11k/mac.h

index 37d4ecb458db59ddea55803a68f9ec609218bc18..c9c9e4b5ef6bd22b431cc6c0417101c3ea4faf96 100644 (file)
@@ -378,23 +378,22 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
                return ret;
        }
 
-       ret = ath11k_mac_create(ab);
+       ret = ath11k_mac_register(ab);
        if (ret) {
-               ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
-                          ret);
+               ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
                goto err_pdev_debug;
        }
 
        ret = ath11k_dp_pdev_alloc(ab);
        if (ret) {
                ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
-               goto err_mac_destroy;
+               goto err_mac_unregister;
        }
 
        return 0;
 
-err_mac_destroy:
-       ath11k_mac_destroy(ab);
+err_mac_unregister:
+       ath11k_mac_unregister(ab);
 
 err_pdev_debug:
        ath11k_debug_pdev_destroy(ab);
@@ -470,28 +469,37 @@ static int ath11k_core_start(struct ath11k_base *ab,
                goto err_hif_stop;
        }
 
+       ret = ath11k_mac_allocate(ab);
+       if (ret) {
+               ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
+                          ret);
+               goto err_hif_stop;
+       }
+
        ret = ath11k_wmi_cmd_init(ab);
        if (ret) {
                ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
-               goto err_hif_stop;
+               goto err_mac_destroy;
        }
 
        ret = ath11k_wmi_wait_for_unified_ready(ab);
        if (ret) {
                ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
                           ret);
-               goto err_hif_stop;
+               goto err_mac_destroy;
        }
 
        ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
        if (ret) {
                ath11k_err(ab, "failed to send htt version request message: %d\n",
                           ret);
-               goto err_hif_stop;
+               goto err_mac_destroy;
        }
 
        return 0;
 
+err_mac_destroy:
+       ath11k_mac_destroy(ab);
 err_hif_stop:
        ath11k_ahb_stop(ab);
 err_wmi_detach:
@@ -537,6 +545,7 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
 
 err_core_stop:
        ath11k_core_stop(ab);
+       ath11k_mac_destroy(ab);
 err_dp_free:
        ath11k_dp_free(ab);
        mutex_unlock(&ab->core_lock);
index 624534d4c33ad8af590c25ce1be94896fbbef783..e4dfce6b63f0421970112a44f237d219e309ee98 100644 (file)
@@ -5513,7 +5513,38 @@ static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = {
        },
 };
 
-static int ath11k_mac_register(struct ath11k *ar)
+static void __ath11k_mac_unregister(struct ath11k *ar)
+{
+       cancel_work_sync(&ar->regd_update_work);
+
+       ieee80211_unregister_hw(ar->hw);
+
+       idr_for_each(&ar->txmgmt_idr, ath11k_mac_tx_mgmt_pending_free, ar);
+       idr_destroy(&ar->txmgmt_idr);
+
+       kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
+       kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
+
+       SET_IEEE80211_DEV(ar->hw, NULL);
+}
+
+void ath11k_mac_unregister(struct ath11k_base *ab)
+{
+       struct ath11k *ar;
+       struct ath11k_pdev *pdev;
+       int i;
+
+       for (i = 0; i < ab->num_radios; i++) {
+               pdev = &ab->pdevs[i];
+               ar = pdev->ar;
+               if (!ar)
+                       continue;
+
+               __ath11k_mac_unregister(ar);
+       }
+}
+
+static int __ath11k_mac_register(struct ath11k *ar)
 {
        struct ath11k_base *ab = ar->ab;
        struct ath11k_pdev_cap *cap = &ar->pdev->cap;
@@ -5657,32 +5688,48 @@ err_free:
        return ret;
 }
 
-void ath11k_mac_unregister(struct ath11k_base *ab)
+int ath11k_mac_register(struct ath11k_base *ab)
 {
        struct ath11k *ar;
        struct ath11k_pdev *pdev;
        int i;
+       int ret;
 
        for (i = 0; i < ab->num_radios; i++) {
                pdev = &ab->pdevs[i];
                ar = pdev->ar;
-               if (!ar)
-                       continue;
-               cancel_work_sync(&ar->regd_update_work);
+               if (ab->pdevs_macaddr_valid) {
+                       ether_addr_copy(ar->mac_addr, pdev->mac_addr);
+               } else {
+                       ether_addr_copy(ar->mac_addr, ab->mac_addr);
+                       ar->mac_addr[4] += i;
+               }
 
-               ieee80211_unregister_hw(ar->hw);
+               ret = __ath11k_mac_register(ar);
+               if (ret)
+                       goto err_cleanup;
 
-               idr_for_each(&ar->txmgmt_idr, ath11k_mac_tx_mgmt_pending_free, ar);
-               idr_destroy(&ar->txmgmt_idr);
+               idr_init(&ar->txmgmt_idr);
+               spin_lock_init(&ar->txmgmt_idr_lock);
+       }
 
-               kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
-               kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
+       /* Initialize channel counters frequency value in hertz */
+       ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ;
+       ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
+
+       return 0;
 
-               SET_IEEE80211_DEV(ar->hw, NULL);
+err_cleanup:
+       for (i = i - 1; i >= 0; i--) {
+               pdev = &ab->pdevs[i];
+               ar = pdev->ar;
+               __ath11k_mac_unregister(ar);
        }
+
+       return ret;
 }
 
-int ath11k_mac_create(struct ath11k_base *ab)
+int ath11k_mac_allocate(struct ath11k_base *ab)
 {
        struct ieee80211_hw *hw;
        struct ath11k *ar;
@@ -5699,7 +5746,7 @@ int ath11k_mac_create(struct ath11k_base *ab)
                if (!hw) {
                        ath11k_warn(ab, "failed to allocate mac80211 hw device\n");
                        ret = -ENOMEM;
-                       goto err_destroy_mac;
+                       goto err_free_mac;
                }
 
                ar = hw->priv;
@@ -5720,13 +5767,6 @@ int ath11k_mac_create(struct ath11k_base *ab)
                ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask);
                ar->num_rx_chains = get_num_chains(pdev->cap.rx_chain_mask);
 
-               if (ab->pdevs_macaddr_valid) {
-                       ether_addr_copy(ar->mac_addr, pdev->mac_addr);
-               } else {
-                       ether_addr_copy(ar->mac_addr, ab->mac_addr);
-                       ar->mac_addr[4] += i;
-               }
-
                pdev->ar = ar;
                spin_lock_init(&ar->data_lock);
                INIT_LIST_HEAD(&ar->arvifs);
@@ -5744,26 +5784,11 @@ int ath11k_mac_create(struct ath11k_base *ab)
                INIT_WORK(&ar->wmi_mgmt_tx_work, ath11k_mgmt_over_wmi_tx_work);
                skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
                clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
-
-               ret = ath11k_mac_register(ar);
-               if (ret) {
-                       ath11k_warn(ab, "failed to register hw device\n");
-                       pdev->ar = NULL;
-                       ieee80211_free_hw(hw);
-                       goto err_destroy_mac;
-               }
-
-               idr_init(&ar->txmgmt_idr);
-               spin_lock_init(&ar->txmgmt_idr_lock);
        }
 
-       /* Initialize channel counters frequency value in hertz */
-       ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ;
-       ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
-
        return 0;
 
-err_destroy_mac:
+err_free_mac:
        ath11k_mac_destroy(ab);
 
        return ret;
index 8c37573ae5dc68e6ddbc25afb744c22488970fd9..f286531cdd78aff6cb73aaee27427a6524155400 100644 (file)
@@ -118,9 +118,10 @@ struct ath11k_generic_iter {
 
 extern const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default;
 
-int ath11k_mac_create(struct ath11k_base *ab);
 void ath11k_mac_destroy(struct ath11k_base *ab);
 void ath11k_mac_unregister(struct ath11k_base *ab);
+int ath11k_mac_register(struct ath11k_base *ab);
+int ath11k_mac_allocate(struct ath11k_base *ab);
 int ath11k_mac_hw_ratecode_to_legacy_rate(u8 hw_rc, u8 preamble, u8 *rateidx,
                                          u16 *rate);
 u8 ath11k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,