diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/mac.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 409 |
1 files changed, 346 insertions, 63 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index da5c333d0d4b..d0a776124f13 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
21 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
22 | 22 | ||
23 | #include "hif.h" | ||
23 | #include "core.h" | 24 | #include "core.h" |
24 | #include "debug.h" | 25 | #include "debug.h" |
25 | #include "wmi.h" | 26 | #include "wmi.h" |
@@ -43,6 +44,8 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
43 | .macaddr = macaddr, | 44 | .macaddr = macaddr, |
44 | }; | 45 | }; |
45 | 46 | ||
47 | lockdep_assert_held(&arvif->ar->conf_mutex); | ||
48 | |||
46 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) | 49 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) |
47 | arg.key_flags = WMI_KEY_PAIRWISE; | 50 | arg.key_flags = WMI_KEY_PAIRWISE; |
48 | else | 51 | else |
@@ -87,6 +90,8 @@ static int ath10k_install_key(struct ath10k_vif *arvif, | |||
87 | struct ath10k *ar = arvif->ar; | 90 | struct ath10k *ar = arvif->ar; |
88 | int ret; | 91 | int ret; |
89 | 92 | ||
93 | lockdep_assert_held(&ar->conf_mutex); | ||
94 | |||
90 | INIT_COMPLETION(ar->install_key_done); | 95 | INIT_COMPLETION(ar->install_key_done); |
91 | 96 | ||
92 | ret = ath10k_send_key(arvif, key, cmd, macaddr); | 97 | ret = ath10k_send_key(arvif, key, cmd, macaddr); |
@@ -327,6 +332,29 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr) | |||
327 | return 0; | 332 | return 0; |
328 | } | 333 | } |
329 | 334 | ||
335 | static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value) | ||
336 | { | ||
337 | if (value != 0xFFFFFFFF) | ||
338 | value = min_t(u32, arvif->ar->hw->wiphy->rts_threshold, | ||
339 | ATH10K_RTS_MAX); | ||
340 | |||
341 | return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, | ||
342 | WMI_VDEV_PARAM_RTS_THRESHOLD, | ||
343 | value); | ||
344 | } | ||
345 | |||
346 | static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value) | ||
347 | { | ||
348 | if (value != 0xFFFFFFFF) | ||
349 | value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold, | ||
350 | ATH10K_FRAGMT_THRESHOLD_MIN, | ||
351 | ATH10K_FRAGMT_THRESHOLD_MAX); | ||
352 | |||
353 | return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, | ||
354 | WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, | ||
355 | value); | ||
356 | } | ||
357 | |||
330 | static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) | 358 | static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) |
331 | { | 359 | { |
332 | int ret; | 360 | int ret; |
@@ -364,6 +392,20 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) | |||
364 | spin_unlock_bh(&ar->data_lock); | 392 | spin_unlock_bh(&ar->data_lock); |
365 | } | 393 | } |
366 | 394 | ||
395 | static void ath10k_peer_cleanup_all(struct ath10k *ar) | ||
396 | { | ||
397 | struct ath10k_peer *peer, *tmp; | ||
398 | |||
399 | lockdep_assert_held(&ar->conf_mutex); | ||
400 | |||
401 | spin_lock_bh(&ar->data_lock); | ||
402 | list_for_each_entry_safe(peer, tmp, &ar->peers, list) { | ||
403 | list_del(&peer->list); | ||
404 | kfree(peer); | ||
405 | } | ||
406 | spin_unlock_bh(&ar->data_lock); | ||
407 | } | ||
408 | |||
367 | /************************/ | 409 | /************************/ |
368 | /* Interface management */ | 410 | /* Interface management */ |
369 | /************************/ | 411 | /************************/ |
@@ -372,6 +414,8 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) | |||
372 | { | 414 | { |
373 | int ret; | 415 | int ret; |
374 | 416 | ||
417 | lockdep_assert_held(&ar->conf_mutex); | ||
418 | |||
375 | ret = wait_for_completion_timeout(&ar->vdev_setup_done, | 419 | ret = wait_for_completion_timeout(&ar->vdev_setup_done, |
376 | ATH10K_VDEV_SETUP_TIMEOUT_HZ); | 420 | ATH10K_VDEV_SETUP_TIMEOUT_HZ); |
377 | if (ret == 0) | 421 | if (ret == 0) |
@@ -605,6 +649,8 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, | |||
605 | { | 649 | { |
606 | int ret = 0; | 650 | int ret = 0; |
607 | 651 | ||
652 | lockdep_assert_held(&arvif->ar->conf_mutex); | ||
653 | |||
608 | if (!info->enable_beacon) { | 654 | if (!info->enable_beacon) { |
609 | ath10k_vdev_stop(arvif); | 655 | ath10k_vdev_stop(arvif); |
610 | return; | 656 | return; |
@@ -631,6 +677,8 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, | |||
631 | { | 677 | { |
632 | int ret = 0; | 678 | int ret = 0; |
633 | 679 | ||
680 | lockdep_assert_held(&arvif->ar->conf_mutex); | ||
681 | |||
634 | if (!info->ibss_joined) { | 682 | if (!info->ibss_joined) { |
635 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer); | 683 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer); |
636 | if (ret) | 684 | if (ret) |
@@ -680,6 +728,8 @@ static void ath10k_ps_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
680 | enum wmi_sta_ps_mode psmode; | 728 | enum wmi_sta_ps_mode psmode; |
681 | int ret; | 729 | int ret; |
682 | 730 | ||
731 | lockdep_assert_held(&arvif->ar->conf_mutex); | ||
732 | |||
683 | if (vif->type != NL80211_IFTYPE_STATION) | 733 | if (vif->type != NL80211_IFTYPE_STATION) |
684 | return; | 734 | return; |
685 | 735 | ||
@@ -722,6 +772,8 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar, | |||
722 | struct ieee80211_bss_conf *bss_conf, | 772 | struct ieee80211_bss_conf *bss_conf, |
723 | struct wmi_peer_assoc_complete_arg *arg) | 773 | struct wmi_peer_assoc_complete_arg *arg) |
724 | { | 774 | { |
775 | lockdep_assert_held(&ar->conf_mutex); | ||
776 | |||
725 | memcpy(arg->addr, sta->addr, ETH_ALEN); | 777 | memcpy(arg->addr, sta->addr, ETH_ALEN); |
726 | arg->vdev_id = arvif->vdev_id; | 778 | arg->vdev_id = arvif->vdev_id; |
727 | arg->peer_aid = sta->aid; | 779 | arg->peer_aid = sta->aid; |
@@ -764,6 +816,8 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar, | |||
764 | const u8 *rsnie = NULL; | 816 | const u8 *rsnie = NULL; |
765 | const u8 *wpaie = NULL; | 817 | const u8 *wpaie = NULL; |
766 | 818 | ||
819 | lockdep_assert_held(&ar->conf_mutex); | ||
820 | |||
767 | bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, | 821 | bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, |
768 | info->bssid, NULL, 0, 0, 0); | 822 | info->bssid, NULL, 0, 0, 0); |
769 | if (bss) { | 823 | if (bss) { |
@@ -804,6 +858,8 @@ static void ath10k_peer_assoc_h_rates(struct ath10k *ar, | |||
804 | u32 ratemask; | 858 | u32 ratemask; |
805 | int i; | 859 | int i; |
806 | 860 | ||
861 | lockdep_assert_held(&ar->conf_mutex); | ||
862 | |||
807 | sband = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; | 863 | sband = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; |
808 | ratemask = sta->supp_rates[ar->hw->conf.chandef.chan->band]; | 864 | ratemask = sta->supp_rates[ar->hw->conf.chandef.chan->band]; |
809 | rates = sband->bitrates; | 865 | rates = sband->bitrates; |
@@ -827,6 +883,8 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, | |||
827 | int smps; | 883 | int smps; |
828 | int i, n; | 884 | int i, n; |
829 | 885 | ||
886 | lockdep_assert_held(&ar->conf_mutex); | ||
887 | |||
830 | if (!ht_cap->ht_supported) | 888 | if (!ht_cap->ht_supported) |
831 | return; | 889 | return; |
832 | 890 | ||
@@ -905,6 +963,8 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar, | |||
905 | u32 uapsd = 0; | 963 | u32 uapsd = 0; |
906 | u32 max_sp = 0; | 964 | u32 max_sp = 0; |
907 | 965 | ||
966 | lockdep_assert_held(&ar->conf_mutex); | ||
967 | |||
908 | if (sta->wme) | 968 | if (sta->wme) |
909 | arg->peer_flags |= WMI_PEER_QOS; | 969 | arg->peer_flags |= WMI_PEER_QOS; |
910 | 970 | ||
@@ -1056,6 +1116,8 @@ static int ath10k_peer_assoc(struct ath10k *ar, | |||
1056 | { | 1116 | { |
1057 | struct wmi_peer_assoc_complete_arg arg; | 1117 | struct wmi_peer_assoc_complete_arg arg; |
1058 | 1118 | ||
1119 | lockdep_assert_held(&ar->conf_mutex); | ||
1120 | |||
1059 | memset(&arg, 0, sizeof(struct wmi_peer_assoc_complete_arg)); | 1121 | memset(&arg, 0, sizeof(struct wmi_peer_assoc_complete_arg)); |
1060 | 1122 | ||
1061 | ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, &arg); | 1123 | ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, &arg); |
@@ -1079,6 +1141,8 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, | |||
1079 | struct ieee80211_sta *ap_sta; | 1141 | struct ieee80211_sta *ap_sta; |
1080 | int ret; | 1142 | int ret; |
1081 | 1143 | ||
1144 | lockdep_assert_held(&ar->conf_mutex); | ||
1145 | |||
1082 | rcu_read_lock(); | 1146 | rcu_read_lock(); |
1083 | 1147 | ||
1084 | ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); | 1148 | ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); |
@@ -1119,6 +1183,8 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, | |||
1119 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 1183 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
1120 | int ret; | 1184 | int ret; |
1121 | 1185 | ||
1186 | lockdep_assert_held(&ar->conf_mutex); | ||
1187 | |||
1122 | /* | 1188 | /* |
1123 | * For some reason, calling VDEV-DOWN before VDEV-STOP | 1189 | * For some reason, calling VDEV-DOWN before VDEV-STOP |
1124 | * makes the FW to send frames via HTT after disassociation. | 1190 | * makes the FW to send frames via HTT after disassociation. |
@@ -1152,6 +1218,8 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1152 | { | 1218 | { |
1153 | int ret = 0; | 1219 | int ret = 0; |
1154 | 1220 | ||
1221 | lockdep_assert_held(&ar->conf_mutex); | ||
1222 | |||
1155 | ret = ath10k_peer_assoc(ar, arvif, sta, NULL); | 1223 | ret = ath10k_peer_assoc(ar, arvif, sta, NULL); |
1156 | if (ret) { | 1224 | if (ret) { |
1157 | ath10k_warn("WMI peer assoc failed for %pM\n", sta->addr); | 1225 | ath10k_warn("WMI peer assoc failed for %pM\n", sta->addr); |
@@ -1172,6 +1240,8 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1172 | { | 1240 | { |
1173 | int ret = 0; | 1241 | int ret = 0; |
1174 | 1242 | ||
1243 | lockdep_assert_held(&ar->conf_mutex); | ||
1244 | |||
1175 | ret = ath10k_clear_peer_keys(arvif, sta->addr); | 1245 | ret = ath10k_clear_peer_keys(arvif, sta->addr); |
1176 | if (ret) { | 1246 | if (ret) { |
1177 | ath10k_warn("could not clear all peer wep keys (%d)\n", ret); | 1247 | ath10k_warn("could not clear all peer wep keys (%d)\n", ret); |
@@ -1198,6 +1268,8 @@ static int ath10k_update_channel_list(struct ath10k *ar) | |||
1198 | int ret; | 1268 | int ret; |
1199 | int i; | 1269 | int i; |
1200 | 1270 | ||
1271 | lockdep_assert_held(&ar->conf_mutex); | ||
1272 | |||
1201 | bands = hw->wiphy->bands; | 1273 | bands = hw->wiphy->bands; |
1202 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 1274 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
1203 | if (!bands[band]) | 1275 | if (!bands[band]) |
@@ -1276,21 +1348,19 @@ static int ath10k_update_channel_list(struct ath10k *ar) | |||
1276 | return ret; | 1348 | return ret; |
1277 | } | 1349 | } |
1278 | 1350 | ||
1279 | static void ath10k_reg_notifier(struct wiphy *wiphy, | 1351 | static void ath10k_regd_update(struct ath10k *ar) |
1280 | struct regulatory_request *request) | ||
1281 | { | 1352 | { |
1282 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
1283 | struct reg_dmn_pair_mapping *regpair; | 1353 | struct reg_dmn_pair_mapping *regpair; |
1284 | struct ath10k *ar = hw->priv; | ||
1285 | int ret; | 1354 | int ret; |
1286 | 1355 | ||
1287 | ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); | 1356 | lockdep_assert_held(&ar->conf_mutex); |
1288 | 1357 | ||
1289 | ret = ath10k_update_channel_list(ar); | 1358 | ret = ath10k_update_channel_list(ar); |
1290 | if (ret) | 1359 | if (ret) |
1291 | ath10k_warn("could not update channel list (%d)\n", ret); | 1360 | ath10k_warn("could not update channel list (%d)\n", ret); |
1292 | 1361 | ||
1293 | regpair = ar->ath_common.regulatory.regpair; | 1362 | regpair = ar->ath_common.regulatory.regpair; |
1363 | |||
1294 | /* Target allows setting up per-band regdomain but ath_common provides | 1364 | /* Target allows setting up per-band regdomain but ath_common provides |
1295 | * a combined one only */ | 1365 | * a combined one only */ |
1296 | ret = ath10k_wmi_pdev_set_regdomain(ar, | 1366 | ret = ath10k_wmi_pdev_set_regdomain(ar, |
@@ -1303,6 +1373,20 @@ static void ath10k_reg_notifier(struct wiphy *wiphy, | |||
1303 | ath10k_warn("could not set pdev regdomain (%d)\n", ret); | 1373 | ath10k_warn("could not set pdev regdomain (%d)\n", ret); |
1304 | } | 1374 | } |
1305 | 1375 | ||
1376 | static void ath10k_reg_notifier(struct wiphy *wiphy, | ||
1377 | struct regulatory_request *request) | ||
1378 | { | ||
1379 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
1380 | struct ath10k *ar = hw->priv; | ||
1381 | |||
1382 | ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); | ||
1383 | |||
1384 | mutex_lock(&ar->conf_mutex); | ||
1385 | if (ar->state == ATH10K_STATE_ON) | ||
1386 | ath10k_regd_update(ar); | ||
1387 | mutex_unlock(&ar->conf_mutex); | ||
1388 | } | ||
1389 | |||
1306 | /***************/ | 1390 | /***************/ |
1307 | /* TX handlers */ | 1391 | /* TX handlers */ |
1308 | /***************/ | 1392 | /***************/ |
@@ -1397,15 +1481,15 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) | |||
1397 | int ret; | 1481 | int ret; |
1398 | 1482 | ||
1399 | if (ieee80211_is_mgmt(hdr->frame_control)) | 1483 | if (ieee80211_is_mgmt(hdr->frame_control)) |
1400 | ret = ath10k_htt_mgmt_tx(ar->htt, skb); | 1484 | ret = ath10k_htt_mgmt_tx(&ar->htt, skb); |
1401 | else if (ieee80211_is_nullfunc(hdr->frame_control)) | 1485 | else if (ieee80211_is_nullfunc(hdr->frame_control)) |
1402 | /* FW does not report tx status properly for NullFunc frames | 1486 | /* FW does not report tx status properly for NullFunc frames |
1403 | * unless they are sent through mgmt tx path. mac80211 sends | 1487 | * unless they are sent through mgmt tx path. mac80211 sends |
1404 | * those frames when it detects link/beacon loss and depends on | 1488 | * those frames when it detects link/beacon loss and depends on |
1405 | * the tx status to be correct. */ | 1489 | * the tx status to be correct. */ |
1406 | ret = ath10k_htt_mgmt_tx(ar->htt, skb); | 1490 | ret = ath10k_htt_mgmt_tx(&ar->htt, skb); |
1407 | else | 1491 | else |
1408 | ret = ath10k_htt_tx(ar->htt, skb); | 1492 | ret = ath10k_htt_tx(&ar->htt, skb); |
1409 | 1493 | ||
1410 | if (ret) { | 1494 | if (ret) { |
1411 | ath10k_warn("tx failed (%d). dropping packet.\n", ret); | 1495 | ath10k_warn("tx failed (%d). dropping packet.\n", ret); |
@@ -1552,6 +1636,10 @@ static int ath10k_abort_scan(struct ath10k *ar) | |||
1552 | ret = ath10k_wmi_stop_scan(ar, &arg); | 1636 | ret = ath10k_wmi_stop_scan(ar, &arg); |
1553 | if (ret) { | 1637 | if (ret) { |
1554 | ath10k_warn("could not submit wmi stop scan (%d)\n", ret); | 1638 | ath10k_warn("could not submit wmi stop scan (%d)\n", ret); |
1639 | spin_lock_bh(&ar->data_lock); | ||
1640 | ar->scan.in_progress = false; | ||
1641 | ath10k_offchan_tx_purge(ar); | ||
1642 | spin_unlock_bh(&ar->data_lock); | ||
1555 | return -EIO; | 1643 | return -EIO; |
1556 | } | 1644 | } |
1557 | 1645 | ||
@@ -1645,10 +1733,14 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
1645 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 1733 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
1646 | } | 1734 | } |
1647 | 1735 | ||
1648 | ath10k_tx_h_qos_workaround(hw, control, skb); | 1736 | /* it makes no sense to process injected frames like that */ |
1649 | ath10k_tx_h_update_wep_key(skb); | 1737 | if (info->control.vif && |
1650 | ath10k_tx_h_add_p2p_noa_ie(ar, skb); | 1738 | info->control.vif->type != NL80211_IFTYPE_MONITOR) { |
1651 | ath10k_tx_h_seq_no(skb); | 1739 | ath10k_tx_h_qos_workaround(hw, control, skb); |
1740 | ath10k_tx_h_update_wep_key(skb); | ||
1741 | ath10k_tx_h_add_p2p_noa_ie(ar, skb); | ||
1742 | ath10k_tx_h_seq_no(skb); | ||
1743 | } | ||
1652 | 1744 | ||
1653 | memset(ATH10K_SKB_CB(skb), 0, sizeof(*ATH10K_SKB_CB(skb))); | 1745 | memset(ATH10K_SKB_CB(skb), 0, sizeof(*ATH10K_SKB_CB(skb))); |
1654 | ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id; | 1746 | ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id; |
@@ -1673,10 +1765,57 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
1673 | /* | 1765 | /* |
1674 | * Initialize various parameters with default vaules. | 1766 | * Initialize various parameters with default vaules. |
1675 | */ | 1767 | */ |
1768 | void ath10k_halt(struct ath10k *ar) | ||
1769 | { | ||
1770 | lockdep_assert_held(&ar->conf_mutex); | ||
1771 | |||
1772 | del_timer_sync(&ar->scan.timeout); | ||
1773 | ath10k_offchan_tx_purge(ar); | ||
1774 | ath10k_peer_cleanup_all(ar); | ||
1775 | ath10k_core_stop(ar); | ||
1776 | ath10k_hif_power_down(ar); | ||
1777 | |||
1778 | spin_lock_bh(&ar->data_lock); | ||
1779 | if (ar->scan.in_progress) { | ||
1780 | del_timer(&ar->scan.timeout); | ||
1781 | ar->scan.in_progress = false; | ||
1782 | ieee80211_scan_completed(ar->hw, true); | ||
1783 | } | ||
1784 | spin_unlock_bh(&ar->data_lock); | ||
1785 | } | ||
1786 | |||
1676 | static int ath10k_start(struct ieee80211_hw *hw) | 1787 | static int ath10k_start(struct ieee80211_hw *hw) |
1677 | { | 1788 | { |
1678 | struct ath10k *ar = hw->priv; | 1789 | struct ath10k *ar = hw->priv; |
1679 | int ret; | 1790 | int ret = 0; |
1791 | |||
1792 | mutex_lock(&ar->conf_mutex); | ||
1793 | |||
1794 | if (ar->state != ATH10K_STATE_OFF && | ||
1795 | ar->state != ATH10K_STATE_RESTARTING) { | ||
1796 | ret = -EINVAL; | ||
1797 | goto exit; | ||
1798 | } | ||
1799 | |||
1800 | ret = ath10k_hif_power_up(ar); | ||
1801 | if (ret) { | ||
1802 | ath10k_err("could not init hif (%d)\n", ret); | ||
1803 | ar->state = ATH10K_STATE_OFF; | ||
1804 | goto exit; | ||
1805 | } | ||
1806 | |||
1807 | ret = ath10k_core_start(ar); | ||
1808 | if (ret) { | ||
1809 | ath10k_err("could not init core (%d)\n", ret); | ||
1810 | ath10k_hif_power_down(ar); | ||
1811 | ar->state = ATH10K_STATE_OFF; | ||
1812 | goto exit; | ||
1813 | } | ||
1814 | |||
1815 | if (ar->state == ATH10K_STATE_OFF) | ||
1816 | ar->state = ATH10K_STATE_ON; | ||
1817 | else if (ar->state == ATH10K_STATE_RESTARTING) | ||
1818 | ar->state = ATH10K_STATE_RESTARTED; | ||
1680 | 1819 | ||
1681 | ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1); | 1820 | ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1); |
1682 | if (ret) | 1821 | if (ret) |
@@ -1688,6 +1827,10 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
1688 | ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", | 1827 | ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", |
1689 | ret); | 1828 | ret); |
1690 | 1829 | ||
1830 | ath10k_regd_update(ar); | ||
1831 | |||
1832 | exit: | ||
1833 | mutex_unlock(&ar->conf_mutex); | ||
1691 | return 0; | 1834 | return 0; |
1692 | } | 1835 | } |
1693 | 1836 | ||
@@ -1695,18 +1838,48 @@ static void ath10k_stop(struct ieee80211_hw *hw) | |||
1695 | { | 1838 | { |
1696 | struct ath10k *ar = hw->priv; | 1839 | struct ath10k *ar = hw->priv; |
1697 | 1840 | ||
1698 | /* avoid leaks in case FW never confirms scan for offchannel */ | 1841 | mutex_lock(&ar->conf_mutex); |
1842 | if (ar->state == ATH10K_STATE_ON || | ||
1843 | ar->state == ATH10K_STATE_RESTARTED || | ||
1844 | ar->state == ATH10K_STATE_WEDGED) | ||
1845 | ath10k_halt(ar); | ||
1846 | |||
1847 | ar->state = ATH10K_STATE_OFF; | ||
1848 | mutex_unlock(&ar->conf_mutex); | ||
1849 | |||
1699 | cancel_work_sync(&ar->offchan_tx_work); | 1850 | cancel_work_sync(&ar->offchan_tx_work); |
1700 | ath10k_offchan_tx_purge(ar); | 1851 | cancel_work_sync(&ar->restart_work); |
1701 | } | 1852 | } |
1702 | 1853 | ||
1703 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | 1854 | static void ath10k_config_ps(struct ath10k *ar) |
1704 | { | 1855 | { |
1705 | struct ath10k_generic_iter ar_iter; | 1856 | struct ath10k_generic_iter ar_iter; |
1857 | |||
1858 | lockdep_assert_held(&ar->conf_mutex); | ||
1859 | |||
1860 | /* During HW reconfiguration mac80211 reports all interfaces that were | ||
1861 | * running until reconfiguration was started. Since FW doesn't have any | ||
1862 | * vdevs at this point we must not iterate over this interface list. | ||
1863 | * This setting will be updated upon add_interface(). */ | ||
1864 | if (ar->state == ATH10K_STATE_RESTARTED) | ||
1865 | return; | ||
1866 | |||
1867 | memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter)); | ||
1868 | ar_iter.ar = ar; | ||
1869 | |||
1870 | ieee80211_iterate_active_interfaces_atomic( | ||
1871 | ar->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
1872 | ath10k_ps_iter, &ar_iter); | ||
1873 | |||
1874 | if (ar_iter.ret) | ||
1875 | ath10k_warn("failed to set ps config (%d)\n", ar_iter.ret); | ||
1876 | } | ||
1877 | |||
1878 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | ||
1879 | { | ||
1706 | struct ath10k *ar = hw->priv; | 1880 | struct ath10k *ar = hw->priv; |
1707 | struct ieee80211_conf *conf = &hw->conf; | 1881 | struct ieee80211_conf *conf = &hw->conf; |
1708 | int ret = 0; | 1882 | int ret = 0; |
1709 | u32 flags; | ||
1710 | 1883 | ||
1711 | mutex_lock(&ar->conf_mutex); | 1884 | mutex_lock(&ar->conf_mutex); |
1712 | 1885 | ||
@@ -1718,18 +1891,8 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
1718 | spin_unlock_bh(&ar->data_lock); | 1891 | spin_unlock_bh(&ar->data_lock); |
1719 | } | 1892 | } |
1720 | 1893 | ||
1721 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 1894 | if (changed & IEEE80211_CONF_CHANGE_PS) |
1722 | memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter)); | 1895 | ath10k_config_ps(ar); |
1723 | ar_iter.ar = ar; | ||
1724 | flags = IEEE80211_IFACE_ITER_RESUME_ALL; | ||
1725 | |||
1726 | ieee80211_iterate_active_interfaces_atomic(hw, | ||
1727 | flags, | ||
1728 | ath10k_ps_iter, | ||
1729 | &ar_iter); | ||
1730 | |||
1731 | ret = ar_iter.ret; | ||
1732 | } | ||
1733 | 1896 | ||
1734 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 1897 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
1735 | if (conf->flags & IEEE80211_CONF_MONITOR) | 1898 | if (conf->flags & IEEE80211_CONF_MONITOR) |
@@ -1738,6 +1901,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
1738 | ret = ath10k_monitor_destroy(ar); | 1901 | ret = ath10k_monitor_destroy(ar); |
1739 | } | 1902 | } |
1740 | 1903 | ||
1904 | ath10k_wmi_flush_tx(ar); | ||
1741 | mutex_unlock(&ar->conf_mutex); | 1905 | mutex_unlock(&ar->conf_mutex); |
1742 | return ret; | 1906 | return ret; |
1743 | } | 1907 | } |
@@ -1859,6 +2023,16 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
1859 | ath10k_warn("Failed to set PSPOLL count: %d\n", ret); | 2023 | ath10k_warn("Failed to set PSPOLL count: %d\n", ret); |
1860 | } | 2024 | } |
1861 | 2025 | ||
2026 | ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold); | ||
2027 | if (ret) | ||
2028 | ath10k_warn("failed to set rts threshold for vdev %d (%d)\n", | ||
2029 | arvif->vdev_id, ret); | ||
2030 | |||
2031 | ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold); | ||
2032 | if (ret) | ||
2033 | ath10k_warn("failed to set frag threshold for vdev %d (%d)\n", | ||
2034 | arvif->vdev_id, ret); | ||
2035 | |||
1862 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) | 2036 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) |
1863 | ar->monitor_present = true; | 2037 | ar->monitor_present = true; |
1864 | 2038 | ||
@@ -2363,6 +2537,8 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif, | |||
2363 | u32 value = 0; | 2537 | u32 value = 0; |
2364 | int ret = 0; | 2538 | int ret = 0; |
2365 | 2539 | ||
2540 | lockdep_assert_held(&ar->conf_mutex); | ||
2541 | |||
2366 | if (arvif->vdev_type != WMI_VDEV_TYPE_STA) | 2542 | if (arvif->vdev_type != WMI_VDEV_TYPE_STA) |
2367 | return 0; | 2543 | return 0; |
2368 | 2544 | ||
@@ -2558,11 +2734,16 @@ static void ath10k_set_rts_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
2558 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 2734 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
2559 | u32 rts = ar_iter->ar->hw->wiphy->rts_threshold; | 2735 | u32 rts = ar_iter->ar->hw->wiphy->rts_threshold; |
2560 | 2736 | ||
2561 | rts = min_t(u32, rts, ATH10K_RTS_MAX); | 2737 | lockdep_assert_held(&arvif->ar->conf_mutex); |
2562 | 2738 | ||
2563 | ar_iter->ret = ath10k_wmi_vdev_set_param(ar_iter->ar, arvif->vdev_id, | 2739 | /* During HW reconfiguration mac80211 reports all interfaces that were |
2564 | WMI_VDEV_PARAM_RTS_THRESHOLD, | 2740 | * running until reconfiguration was started. Since FW doesn't have any |
2565 | rts); | 2741 | * vdevs at this point we must not iterate over this interface list. |
2742 | * This setting will be updated upon add_interface(). */ | ||
2743 | if (ar_iter->ar->state == ATH10K_STATE_RESTARTED) | ||
2744 | return; | ||
2745 | |||
2746 | ar_iter->ret = ath10k_mac_set_rts(arvif, rts); | ||
2566 | if (ar_iter->ret) | 2747 | if (ar_iter->ret) |
2567 | ath10k_warn("Failed to set RTS threshold for VDEV: %d\n", | 2748 | ath10k_warn("Failed to set RTS threshold for VDEV: %d\n", |
2568 | arvif->vdev_id); | 2749 | arvif->vdev_id); |
@@ -2581,8 +2762,9 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | |||
2581 | ar_iter.ar = ar; | 2762 | ar_iter.ar = ar; |
2582 | 2763 | ||
2583 | mutex_lock(&ar->conf_mutex); | 2764 | mutex_lock(&ar->conf_mutex); |
2584 | ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, | 2765 | ieee80211_iterate_active_interfaces_atomic( |
2585 | ath10k_set_rts_iter, &ar_iter); | 2766 | hw, IEEE80211_IFACE_ITER_NORMAL, |
2767 | ath10k_set_rts_iter, &ar_iter); | ||
2586 | mutex_unlock(&ar->conf_mutex); | 2768 | mutex_unlock(&ar->conf_mutex); |
2587 | 2769 | ||
2588 | return ar_iter.ret; | 2770 | return ar_iter.ret; |
@@ -2593,17 +2775,17 @@ static void ath10k_set_frag_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
2593 | struct ath10k_generic_iter *ar_iter = data; | 2775 | struct ath10k_generic_iter *ar_iter = data; |
2594 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 2776 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
2595 | u32 frag = ar_iter->ar->hw->wiphy->frag_threshold; | 2777 | u32 frag = ar_iter->ar->hw->wiphy->frag_threshold; |
2596 | int ret; | ||
2597 | 2778 | ||
2598 | frag = clamp_t(u32, frag, | 2779 | lockdep_assert_held(&arvif->ar->conf_mutex); |
2599 | ATH10K_FRAGMT_THRESHOLD_MIN, | ||
2600 | ATH10K_FRAGMT_THRESHOLD_MAX); | ||
2601 | 2780 | ||
2602 | ret = ath10k_wmi_vdev_set_param(ar_iter->ar, arvif->vdev_id, | 2781 | /* During HW reconfiguration mac80211 reports all interfaces that were |
2603 | WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, | 2782 | * running until reconfiguration was started. Since FW doesn't have any |
2604 | frag); | 2783 | * vdevs at this point we must not iterate over this interface list. |
2784 | * This setting will be updated upon add_interface(). */ | ||
2785 | if (ar_iter->ar->state == ATH10K_STATE_RESTARTED) | ||
2786 | return; | ||
2605 | 2787 | ||
2606 | ar_iter->ret = ret; | 2788 | ar_iter->ret = ath10k_mac_set_frag(arvif, frag); |
2607 | if (ar_iter->ret) | 2789 | if (ar_iter->ret) |
2608 | ath10k_warn("Failed to set frag threshold for VDEV: %d\n", | 2790 | ath10k_warn("Failed to set frag threshold for VDEV: %d\n", |
2609 | arvif->vdev_id); | 2791 | arvif->vdev_id); |
@@ -2622,8 +2804,9 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value) | |||
2622 | ar_iter.ar = ar; | 2804 | ar_iter.ar = ar; |
2623 | 2805 | ||
2624 | mutex_lock(&ar->conf_mutex); | 2806 | mutex_lock(&ar->conf_mutex); |
2625 | ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, | 2807 | ieee80211_iterate_active_interfaces_atomic( |
2626 | ath10k_set_frag_iter, &ar_iter); | 2808 | hw, IEEE80211_IFACE_ITER_NORMAL, |
2809 | ath10k_set_frag_iter, &ar_iter); | ||
2627 | mutex_unlock(&ar->conf_mutex); | 2810 | mutex_unlock(&ar->conf_mutex); |
2628 | 2811 | ||
2629 | return ar_iter.ret; | 2812 | return ar_iter.ret; |
@@ -2632,6 +2815,7 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value) | |||
2632 | static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | 2815 | static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
2633 | { | 2816 | { |
2634 | struct ath10k *ar = hw->priv; | 2817 | struct ath10k *ar = hw->priv; |
2818 | bool skip; | ||
2635 | int ret; | 2819 | int ret; |
2636 | 2820 | ||
2637 | /* mac80211 doesn't care if we really xmit queued frames or not | 2821 | /* mac80211 doesn't care if we really xmit queued frames or not |
@@ -2639,16 +2823,29 @@ static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
2639 | if (drop) | 2823 | if (drop) |
2640 | return; | 2824 | return; |
2641 | 2825 | ||
2642 | ret = wait_event_timeout(ar->htt->empty_tx_wq, ({ | 2826 | mutex_lock(&ar->conf_mutex); |
2827 | |||
2828 | if (ar->state == ATH10K_STATE_WEDGED) | ||
2829 | goto skip; | ||
2830 | |||
2831 | ret = wait_event_timeout(ar->htt.empty_tx_wq, ({ | ||
2643 | bool empty; | 2832 | bool empty; |
2644 | spin_lock_bh(&ar->htt->tx_lock); | 2833 | |
2645 | empty = bitmap_empty(ar->htt->used_msdu_ids, | 2834 | spin_lock_bh(&ar->htt.tx_lock); |
2646 | ar->htt->max_num_pending_tx); | 2835 | empty = bitmap_empty(ar->htt.used_msdu_ids, |
2647 | spin_unlock_bh(&ar->htt->tx_lock); | 2836 | ar->htt.max_num_pending_tx); |
2648 | (empty); | 2837 | spin_unlock_bh(&ar->htt.tx_lock); |
2838 | |||
2839 | skip = (ar->state == ATH10K_STATE_WEDGED); | ||
2840 | |||
2841 | (empty || skip); | ||
2649 | }), ATH10K_FLUSH_TIMEOUT_HZ); | 2842 | }), ATH10K_FLUSH_TIMEOUT_HZ); |
2650 | if (ret <= 0) | 2843 | |
2844 | if (ret <= 0 || skip) | ||
2651 | ath10k_warn("tx not flushed\n"); | 2845 | ath10k_warn("tx not flushed\n"); |
2846 | |||
2847 | skip: | ||
2848 | mutex_unlock(&ar->conf_mutex); | ||
2652 | } | 2849 | } |
2653 | 2850 | ||
2654 | /* TODO: Implement this function properly | 2851 | /* TODO: Implement this function properly |
@@ -2660,6 +2857,83 @@ static int ath10k_tx_last_beacon(struct ieee80211_hw *hw) | |||
2660 | return 1; | 2857 | return 1; |
2661 | } | 2858 | } |
2662 | 2859 | ||
2860 | #ifdef CONFIG_PM | ||
2861 | static int ath10k_suspend(struct ieee80211_hw *hw, | ||
2862 | struct cfg80211_wowlan *wowlan) | ||
2863 | { | ||
2864 | struct ath10k *ar = hw->priv; | ||
2865 | int ret; | ||
2866 | |||
2867 | ar->is_target_paused = false; | ||
2868 | |||
2869 | ret = ath10k_wmi_pdev_suspend_target(ar); | ||
2870 | if (ret) { | ||
2871 | ath10k_warn("could not suspend target (%d)\n", ret); | ||
2872 | return 1; | ||
2873 | } | ||
2874 | |||
2875 | ret = wait_event_interruptible_timeout(ar->event_queue, | ||
2876 | ar->is_target_paused == true, | ||
2877 | 1 * HZ); | ||
2878 | if (ret < 0) { | ||
2879 | ath10k_warn("suspend interrupted (%d)\n", ret); | ||
2880 | goto resume; | ||
2881 | } else if (ret == 0) { | ||
2882 | ath10k_warn("suspend timed out - target pause event never came\n"); | ||
2883 | goto resume; | ||
2884 | } | ||
2885 | |||
2886 | ret = ath10k_hif_suspend(ar); | ||
2887 | if (ret) { | ||
2888 | ath10k_warn("could not suspend hif (%d)\n", ret); | ||
2889 | goto resume; | ||
2890 | } | ||
2891 | |||
2892 | return 0; | ||
2893 | resume: | ||
2894 | ret = ath10k_wmi_pdev_resume_target(ar); | ||
2895 | if (ret) | ||
2896 | ath10k_warn("could not resume target (%d)\n", ret); | ||
2897 | return 1; | ||
2898 | } | ||
2899 | |||
2900 | static int ath10k_resume(struct ieee80211_hw *hw) | ||
2901 | { | ||
2902 | struct ath10k *ar = hw->priv; | ||
2903 | int ret; | ||
2904 | |||
2905 | ret = ath10k_hif_resume(ar); | ||
2906 | if (ret) { | ||
2907 | ath10k_warn("could not resume hif (%d)\n", ret); | ||
2908 | return 1; | ||
2909 | } | ||
2910 | |||
2911 | ret = ath10k_wmi_pdev_resume_target(ar); | ||
2912 | if (ret) { | ||
2913 | ath10k_warn("could not resume target (%d)\n", ret); | ||
2914 | return 1; | ||
2915 | } | ||
2916 | |||
2917 | return 0; | ||
2918 | } | ||
2919 | #endif | ||
2920 | |||
2921 | static void ath10k_restart_complete(struct ieee80211_hw *hw) | ||
2922 | { | ||
2923 | struct ath10k *ar = hw->priv; | ||
2924 | |||
2925 | mutex_lock(&ar->conf_mutex); | ||
2926 | |||
2927 | /* If device failed to restart it will be in a different state, e.g. | ||
2928 | * ATH10K_STATE_WEDGED */ | ||
2929 | if (ar->state == ATH10K_STATE_RESTARTED) { | ||
2930 | ath10k_info("device successfully recovered\n"); | ||
2931 | ar->state = ATH10K_STATE_ON; | ||
2932 | } | ||
2933 | |||
2934 | mutex_unlock(&ar->conf_mutex); | ||
2935 | } | ||
2936 | |||
2663 | static const struct ieee80211_ops ath10k_ops = { | 2937 | static const struct ieee80211_ops ath10k_ops = { |
2664 | .tx = ath10k_tx, | 2938 | .tx = ath10k_tx, |
2665 | .start = ath10k_start, | 2939 | .start = ath10k_start, |
@@ -2680,6 +2954,11 @@ static const struct ieee80211_ops ath10k_ops = { | |||
2680 | .set_frag_threshold = ath10k_set_frag_threshold, | 2954 | .set_frag_threshold = ath10k_set_frag_threshold, |
2681 | .flush = ath10k_flush, | 2955 | .flush = ath10k_flush, |
2682 | .tx_last_beacon = ath10k_tx_last_beacon, | 2956 | .tx_last_beacon = ath10k_tx_last_beacon, |
2957 | .restart_complete = ath10k_restart_complete, | ||
2958 | #ifdef CONFIG_PM | ||
2959 | .suspend = ath10k_suspend, | ||
2960 | .resume = ath10k_resume, | ||
2961 | #endif | ||
2683 | }; | 2962 | }; |
2684 | 2963 | ||
2685 | #define RATETAB_ENT(_rate, _rateid, _flags) { \ | 2964 | #define RATETAB_ENT(_rate, _rateid, _flags) { \ |
@@ -2948,8 +3227,10 @@ int ath10k_mac_register(struct ath10k *ar) | |||
2948 | channels = kmemdup(ath10k_2ghz_channels, | 3227 | channels = kmemdup(ath10k_2ghz_channels, |
2949 | sizeof(ath10k_2ghz_channels), | 3228 | sizeof(ath10k_2ghz_channels), |
2950 | GFP_KERNEL); | 3229 | GFP_KERNEL); |
2951 | if (!channels) | 3230 | if (!channels) { |
2952 | return -ENOMEM; | 3231 | ret = -ENOMEM; |
3232 | goto err_free; | ||
3233 | } | ||
2953 | 3234 | ||
2954 | band = &ar->mac.sbands[IEEE80211_BAND_2GHZ]; | 3235 | band = &ar->mac.sbands[IEEE80211_BAND_2GHZ]; |
2955 | band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels); | 3236 | band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels); |
@@ -2968,11 +3249,8 @@ int ath10k_mac_register(struct ath10k *ar) | |||
2968 | sizeof(ath10k_5ghz_channels), | 3249 | sizeof(ath10k_5ghz_channels), |
2969 | GFP_KERNEL); | 3250 | GFP_KERNEL); |
2970 | if (!channels) { | 3251 | if (!channels) { |
2971 | if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) { | 3252 | ret = -ENOMEM; |
2972 | band = &ar->mac.sbands[IEEE80211_BAND_2GHZ]; | 3253 | goto err_free; |
2973 | kfree(band->channels); | ||
2974 | } | ||
2975 | return -ENOMEM; | ||
2976 | } | 3254 | } |
2977 | 3255 | ||
2978 | band = &ar->mac.sbands[IEEE80211_BAND_5GHZ]; | 3256 | band = &ar->mac.sbands[IEEE80211_BAND_5GHZ]; |
@@ -3036,25 +3314,30 @@ int ath10k_mac_register(struct ath10k *ar) | |||
3036 | ath10k_reg_notifier); | 3314 | ath10k_reg_notifier); |
3037 | if (ret) { | 3315 | if (ret) { |
3038 | ath10k_err("Regulatory initialization failed\n"); | 3316 | ath10k_err("Regulatory initialization failed\n"); |
3039 | return ret; | 3317 | goto err_free; |
3040 | } | 3318 | } |
3041 | 3319 | ||
3042 | ret = ieee80211_register_hw(ar->hw); | 3320 | ret = ieee80211_register_hw(ar->hw); |
3043 | if (ret) { | 3321 | if (ret) { |
3044 | ath10k_err("ieee80211 registration failed: %d\n", ret); | 3322 | ath10k_err("ieee80211 registration failed: %d\n", ret); |
3045 | return ret; | 3323 | goto err_free; |
3046 | } | 3324 | } |
3047 | 3325 | ||
3048 | if (!ath_is_world_regd(&ar->ath_common.regulatory)) { | 3326 | if (!ath_is_world_regd(&ar->ath_common.regulatory)) { |
3049 | ret = regulatory_hint(ar->hw->wiphy, | 3327 | ret = regulatory_hint(ar->hw->wiphy, |
3050 | ar->ath_common.regulatory.alpha2); | 3328 | ar->ath_common.regulatory.alpha2); |
3051 | if (ret) | 3329 | if (ret) |
3052 | goto exit; | 3330 | goto err_unregister; |
3053 | } | 3331 | } |
3054 | 3332 | ||
3055 | return 0; | 3333 | return 0; |
3056 | exit: | 3334 | |
3335 | err_unregister: | ||
3057 | ieee80211_unregister_hw(ar->hw); | 3336 | ieee80211_unregister_hw(ar->hw); |
3337 | err_free: | ||
3338 | kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels); | ||
3339 | kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels); | ||
3340 | |||
3058 | return ret; | 3341 | return ret; |
3059 | } | 3342 | } |
3060 | 3343 | ||