aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/mac80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/mac80211.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c180
1 files changed, 157 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 7396b52262b5..302c8cc50f25 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -86,6 +86,7 @@
86#include "iwl-fw-error-dump.h" 86#include "iwl-fw-error-dump.h"
87#include "iwl-prph.h" 87#include "iwl-prph.h"
88#include "iwl-csr.h" 88#include "iwl-csr.h"
89#include "iwl-nvm-parse.h"
89 90
90static const struct ieee80211_iface_limit iwl_mvm_limits[] = { 91static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
91 { 92 {
@@ -301,6 +302,109 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
301 } 302 }
302} 303}
303 304
305struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
306 const char *alpha2,
307 enum iwl_mcc_source src_id,
308 bool *changed)
309{
310 struct ieee80211_regdomain *regd = NULL;
311 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
312 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
313 struct iwl_mcc_update_resp *resp;
314
315 IWL_DEBUG_LAR(mvm, "Getting regdomain data for %s from FW\n", alpha2);
316
317 lockdep_assert_held(&mvm->mutex);
318
319 resp = iwl_mvm_update_mcc(mvm, alpha2, src_id);
320 if (IS_ERR_OR_NULL(resp)) {
321 IWL_DEBUG_LAR(mvm, "Could not get update from FW %d\n",
322 PTR_RET(resp));
323 goto out;
324 }
325
326 if (changed)
327 *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE);
328
329 regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
330 __le32_to_cpu(resp->n_channels),
331 resp->channels,
332 __le16_to_cpu(resp->mcc));
333 /* Store the return source id */
334 src_id = resp->source_id;
335 kfree(resp);
336 if (IS_ERR_OR_NULL(regd)) {
337 IWL_DEBUG_LAR(mvm, "Could not get parse update from FW %d\n",
338 PTR_RET(regd));
339 goto out;
340 }
341
342 IWL_DEBUG_LAR(mvm, "setting alpha2 from FW to %s (0x%x, 0x%x) src=%d\n",
343 regd->alpha2, regd->alpha2[0], regd->alpha2[1], src_id);
344 mvm->lar_regdom_set = true;
345 mvm->mcc_src = src_id;
346
347out:
348 return regd;
349}
350
351void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm)
352{
353 bool changed;
354 struct ieee80211_regdomain *regd;
355
356 if (!iwl_mvm_is_lar_supported(mvm))
357 return;
358
359 regd = iwl_mvm_get_current_regdomain(mvm, &changed);
360 if (!IS_ERR_OR_NULL(regd)) {
361 /* only update the regulatory core if changed */
362 if (changed)
363 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
364
365 kfree(regd);
366 }
367}
368
369struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
370 bool *changed)
371{
372 return iwl_mvm_get_regdomain(mvm->hw->wiphy, "ZZ",
373 iwl_mvm_is_wifi_mcc_supported(mvm) ?
374 MCC_SOURCE_GET_CURRENT :
375 MCC_SOURCE_OLD_FW, changed);
376}
377
378int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
379{
380 enum iwl_mcc_source used_src;
381 struct ieee80211_regdomain *regd;
382 const struct ieee80211_regdomain *r =
383 rtnl_dereference(mvm->hw->wiphy->regd);
384
385 if (!r)
386 return 0;
387
388 /* save the last source in case we overwrite it below */
389 used_src = mvm->mcc_src;
390 if (iwl_mvm_is_wifi_mcc_supported(mvm)) {
391 /* Notify the firmware we support wifi location updates */
392 regd = iwl_mvm_get_current_regdomain(mvm, NULL);
393 if (!IS_ERR_OR_NULL(regd))
394 kfree(regd);
395 }
396
397 /* Now set our last stored MCC and source */
398 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, NULL);
399 if (IS_ERR_OR_NULL(regd))
400 return -EIO;
401
402 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
403 kfree(regd);
404
405 return 0;
406}
407
304int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 408int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
305{ 409{
306 struct ieee80211_hw *hw = mvm->hw; 410 struct ieee80211_hw *hw = mvm->hw;
@@ -356,8 +460,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
356 BIT(NL80211_IFTYPE_ADHOC); 460 BIT(NL80211_IFTYPE_ADHOC);
357 461
358 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 462 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
359 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 463 hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
360 REGULATORY_DISABLE_BEACON_HINTS; 464 if (iwl_mvm_is_lar_supported(mvm))
465 hw->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
466 else
467 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
468 REGULATORY_DISABLE_BEACON_HINTS;
361 469
362 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD) 470 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD)
363 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 471 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
@@ -1193,7 +1301,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
1193 1301
1194 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1302 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1195 iwl_mvm_d0i3_enable_tx(mvm, NULL); 1303 iwl_mvm_d0i3_enable_tx(mvm, NULL);
1196 ret = iwl_mvm_update_quotas(mvm, NULL); 1304 ret = iwl_mvm_update_quotas(mvm, false, NULL);
1197 if (ret) 1305 if (ret)
1198 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", 1306 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
1199 ret); 1307 ret);
@@ -1872,7 +1980,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1872 sizeof(mvmvif->beacon_stats)); 1980 sizeof(mvmvif->beacon_stats));
1873 1981
1874 /* add quota for this interface */ 1982 /* add quota for this interface */
1875 ret = iwl_mvm_update_quotas(mvm, NULL); 1983 ret = iwl_mvm_update_quotas(mvm, true, NULL);
1876 if (ret) { 1984 if (ret) {
1877 IWL_ERR(mvm, "failed to update quotas\n"); 1985 IWL_ERR(mvm, "failed to update quotas\n");
1878 return; 1986 return;
@@ -1924,7 +2032,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1924 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; 2032 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1925 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 2033 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
1926 /* remove quota for this interface */ 2034 /* remove quota for this interface */
1927 ret = iwl_mvm_update_quotas(mvm, NULL); 2035 ret = iwl_mvm_update_quotas(mvm, false, NULL);
1928 if (ret) 2036 if (ret)
1929 IWL_ERR(mvm, "failed to update quotas\n"); 2037 IWL_ERR(mvm, "failed to update quotas\n");
1930 2038
@@ -2043,7 +2151,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
2043 /* power updated needs to be done before quotas */ 2151 /* power updated needs to be done before quotas */
2044 iwl_mvm_power_update_mac(mvm); 2152 iwl_mvm_power_update_mac(mvm);
2045 2153
2046 ret = iwl_mvm_update_quotas(mvm, NULL); 2154 ret = iwl_mvm_update_quotas(mvm, false, NULL);
2047 if (ret) 2155 if (ret)
2048 goto out_quota_failed; 2156 goto out_quota_failed;
2049 2157
@@ -2109,7 +2217,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
2109 if (vif->p2p && mvm->p2p_device_vif) 2217 if (vif->p2p && mvm->p2p_device_vif)
2110 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); 2218 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
2111 2219
2112 iwl_mvm_update_quotas(mvm, NULL); 2220 iwl_mvm_update_quotas(mvm, false, NULL);
2113 iwl_mvm_send_rm_bcast_sta(mvm, vif); 2221 iwl_mvm_send_rm_bcast_sta(mvm, vif);
2114 iwl_mvm_binding_remove_vif(mvm, vif); 2222 iwl_mvm_binding_remove_vif(mvm, vif);
2115 2223
@@ -2248,6 +2356,12 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
2248 2356
2249 mutex_lock(&mvm->mutex); 2357 mutex_lock(&mvm->mutex);
2250 2358
2359 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
2360 IWL_ERR(mvm, "scan while LAR regdomain is not set\n");
2361 ret = -EBUSY;
2362 goto out;
2363 }
2364
2251 if (mvm->scan_status != IWL_MVM_SCAN_NONE) { 2365 if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
2252 ret = -EBUSY; 2366 ret = -EBUSY;
2253 goto out; 2367 goto out;
@@ -2328,25 +2442,35 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
2328{ 2442{
2329 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2443 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2330 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 2444 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2445 unsigned long txqs = 0, tids = 0;
2331 int tid; 2446 int tid;
2332 2447
2448 spin_lock_bh(&mvmsta->lock);
2449 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
2450 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
2451
2452 if (tid_data->state != IWL_AGG_ON &&
2453 tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA)
2454 continue;
2455
2456 __set_bit(tid_data->txq_id, &txqs);
2457
2458 if (iwl_mvm_tid_queued(tid_data) == 0)
2459 continue;
2460
2461 __set_bit(tid, &tids);
2462 }
2463
2333 switch (cmd) { 2464 switch (cmd) {
2334 case STA_NOTIFY_SLEEP: 2465 case STA_NOTIFY_SLEEP:
2335 if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0) 2466 if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
2336 ieee80211_sta_block_awake(hw, sta, true); 2467 ieee80211_sta_block_awake(hw, sta, true);
2337 spin_lock_bh(&mvmsta->lock);
2338 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
2339 struct iwl_mvm_tid_data *tid_data;
2340 2468
2341 tid_data = &mvmsta->tid_data[tid]; 2469 for_each_set_bit(tid, &tids, IWL_MAX_TID_COUNT)
2342 if (tid_data->state != IWL_AGG_ON &&
2343 tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA)
2344 continue;
2345 if (iwl_mvm_tid_queued(tid_data) == 0)
2346 continue;
2347 ieee80211_sta_set_buffered(sta, tid, true); 2470 ieee80211_sta_set_buffered(sta, tid, true);
2348 } 2471
2349 spin_unlock_bh(&mvmsta->lock); 2472 if (txqs)
2473 iwl_trans_freeze_txq_timer(mvm->trans, txqs, true);
2350 /* 2474 /*
2351 * The fw updates the STA to be asleep. Tx packets on the Tx 2475 * The fw updates the STA to be asleep. Tx packets on the Tx
2352 * queues to this station will not be transmitted. The fw will 2476 * queues to this station will not be transmitted. The fw will
@@ -2356,11 +2480,15 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
2356 case STA_NOTIFY_AWAKE: 2480 case STA_NOTIFY_AWAKE:
2357 if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) 2481 if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
2358 break; 2482 break;
2483
2484 if (txqs)
2485 iwl_trans_freeze_txq_timer(mvm->trans, txqs, false);
2359 iwl_mvm_sta_modify_ps_wake(mvm, sta); 2486 iwl_mvm_sta_modify_ps_wake(mvm, sta);
2360 break; 2487 break;
2361 default: 2488 default:
2362 break; 2489 break;
2363 } 2490 }
2491 spin_unlock_bh(&mvmsta->lock);
2364} 2492}
2365 2493
2366static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw, 2494static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
@@ -2598,6 +2726,12 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2598 2726
2599 mutex_lock(&mvm->mutex); 2727 mutex_lock(&mvm->mutex);
2600 2728
2729 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
2730 IWL_ERR(mvm, "sched-scan while LAR regdomain is not set\n");
2731 ret = -EBUSY;
2732 goto out;
2733 }
2734
2601 if (!vif->bss_conf.idle) { 2735 if (!vif->bss_conf.idle) {
2602 ret = -EBUSY; 2736 ret = -EBUSY;
2603 goto out; 2737 goto out;
@@ -3159,14 +3293,14 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3159 */ 3293 */
3160 if (vif->type == NL80211_IFTYPE_MONITOR) { 3294 if (vif->type == NL80211_IFTYPE_MONITOR) {
3161 mvmvif->monitor_active = true; 3295 mvmvif->monitor_active = true;
3162 ret = iwl_mvm_update_quotas(mvm, NULL); 3296 ret = iwl_mvm_update_quotas(mvm, false, NULL);
3163 if (ret) 3297 if (ret)
3164 goto out_remove_binding; 3298 goto out_remove_binding;
3165 } 3299 }
3166 3300
3167 /* Handle binding during CSA */ 3301 /* Handle binding during CSA */
3168 if (vif->type == NL80211_IFTYPE_AP) { 3302 if (vif->type == NL80211_IFTYPE_AP) {
3169 iwl_mvm_update_quotas(mvm, NULL); 3303 iwl_mvm_update_quotas(mvm, false, NULL);
3170 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); 3304 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
3171 } 3305 }
3172 3306
@@ -3190,7 +3324,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3190 3324
3191 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA); 3325 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA);
3192 3326
3193 iwl_mvm_update_quotas(mvm, NULL); 3327 iwl_mvm_update_quotas(mvm, false, NULL);
3194 } 3328 }
3195 3329
3196 goto out; 3330 goto out;
@@ -3263,7 +3397,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
3263 break; 3397 break;
3264 } 3398 }
3265 3399
3266 iwl_mvm_update_quotas(mvm, disabled_vif); 3400 iwl_mvm_update_quotas(mvm, false, disabled_vif);
3267 iwl_mvm_binding_remove_vif(mvm, vif); 3401 iwl_mvm_binding_remove_vif(mvm, vif);
3268 3402
3269out: 3403out:
@@ -3455,7 +3589,7 @@ static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
3455 mvm->noa_duration = noa_duration; 3589 mvm->noa_duration = noa_duration;
3456 mvm->noa_vif = vif; 3590 mvm->noa_vif = vif;
3457 3591
3458 return iwl_mvm_update_quotas(mvm, NULL); 3592 return iwl_mvm_update_quotas(mvm, false, NULL);
3459 case IWL_MVM_TM_CMD_SET_BEACON_FILTER: 3593 case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
3460 /* must be associated client vif - ignore authorized */ 3594 /* must be associated client vif - ignore authorized */
3461 if (!vif || vif->type != NL80211_IFTYPE_STATION || 3595 if (!vif || vif->type != NL80211_IFTYPE_STATION ||