ath10k: fix IBSS scanning on wmi-tlv and qca6174
authorMichal Kazior <michal.kazior@tieto.com>
Tue, 24 Mar 2015 13:14:03 +0000 (13:14 +0000)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 1 Apr 2015 19:43:49 +0000 (22:43 +0300)
WLAN.RM.2.0-00073 firmware requires self-peer to
be created prior to issuing scan command. Without
this wmi-tlv with qca6174 firmware crashes after
submitting a scan request.

Creating the peer as soon as add_interface()
shouldn't be a problem.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/mac.c

index 339cb9addfb21b8312850c03403cf6b90147eb9c..6e04cbf4914b8c5a50eb886a293345a5192fe595 100644 (file)
@@ -1620,11 +1620,6 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
        lockdep_assert_held(&arvif->ar->conf_mutex);
 
        if (!info->ibss_joined) {
-               ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
-               if (ret)
-                       ath10k_warn(ar, "failed to delete IBSS self peer %pM for vdev %d: %d\n",
-                                   self_peer, arvif->vdev_id, ret);
-
                if (is_zero_ether_addr(arvif->bssid))
                        return;
 
@@ -1633,14 +1628,6 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
                return;
        }
 
-       ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer,
-                                WMI_PEER_TYPE_DEFAULT);
-       if (ret) {
-               ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n",
-                           self_peer, arvif->vdev_id, ret);
-               return;
-       }
-
        vdev_param = arvif->ar->wmi.vdev_param->atim_window;
        ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
                                        ATH10K_DEFAULT_ATIM);
@@ -4174,15 +4161,18 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
                }
        }
 
-       if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+       if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
+           arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
                ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
                                         WMI_PEER_TYPE_DEFAULT);
                if (ret) {
-                       ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
+                       ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
                                    arvif->vdev_id, ret);
                        goto err_vdev_delete;
                }
+       }
 
+       if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
                ret = ath10k_mac_set_kickout(arvif);
                if (ret) {
                        ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
@@ -4251,7 +4241,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
        return 0;
 
 err_peer_delete:
-       if (arvif->vdev_type == WMI_VDEV_TYPE_AP)
+       if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
+           arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
                ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
 
 err_vdev_delete:
@@ -4303,11 +4294,12 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
        ar->free_vdev_map |= 1LL << arvif->vdev_id;
        list_del(&arvif->list);
 
-       if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+       if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
+           arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
                ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
                                             vif->addr);
                if (ret)
-                       ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
+                       ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
                                    arvif->vdev_id, ret);
 
                kfree(arvif->u.ap.noa_data);
@@ -4324,7 +4316,8 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
        /* Some firmware revisions don't notify host about self-peer removal
         * until after associated vdev is deleted.
         */
-       if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+       if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
+           arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
                ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
                                                   vif->addr);
                if (ret)