1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#include <linux/kernel.h>
68#include <linux/slab.h>
69#include <linux/skbuff.h>
70#include <linux/netdevice.h>
71#include <linux/etherdevice.h>
72#include <linux/ip.h>
73#include <linux/if_arp.h>
74#include <linux/time.h>
75#include <net/mac80211.h>
76#include <net/ieee80211_radiotap.h>
77#include <net/tcp.h>
78
79#include "iwl-op-mode.h"
80#include "iwl-io.h"
81#include "mvm.h"
82#include "sta.h"
83#include "time-event.h"
84#include "iwl-eeprom-parse.h"
85#include "iwl-phy-db.h"
86#include "testmode.h"
87#include "fw/error-dump.h"
88#include "iwl-prph.h"
89#include "iwl-nvm-parse.h"
90
91static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
92 {
93 .max = 1,
94 .types = BIT(NL80211_IFTYPE_STATION),
95 },
96 {
97 .max = 1,
98 .types = BIT(NL80211_IFTYPE_AP) |
99 BIT(NL80211_IFTYPE_P2P_CLIENT) |
100 BIT(NL80211_IFTYPE_P2P_GO),
101 },
102 {
103 .max = 1,
104 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
105 },
106};
107
108static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
109 {
110 .num_different_channels = 2,
111 .max_interfaces = 3,
112 .limits = iwl_mvm_limits,
113 .n_limits = ARRAY_SIZE(iwl_mvm_limits),
114 },
115};
116
117#ifdef CONFIG_PM_SLEEP
118static const struct nl80211_wowlan_tcp_data_token_feature
119iwl_mvm_wowlan_tcp_token_feature = {
120 .min_len = 0,
121 .max_len = 255,
122 .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
123};
124
125static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
126 .tok = &iwl_mvm_wowlan_tcp_token_feature,
127 .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
128 sizeof(struct ethhdr) -
129 sizeof(struct iphdr) -
130 sizeof(struct tcphdr),
131 .data_interval_max = 65535,
132 .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
133 sizeof(struct ethhdr) -
134 sizeof(struct iphdr) -
135 sizeof(struct tcphdr),
136 .seq = true,
137};
138#endif
139
140#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
141
142
143
144
145
146
147
148
149
150
151
152enum {
153 BC_FILTER_MAGIC_NONE = 0,
154 BC_FILTER_MAGIC_IP,
155 BC_FILTER_MAGIC_MAC,
156};
157
158static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
159 {
160
161 .discard = 0,
162 .frame_type = BCAST_FILTER_FRAME_TYPE_ALL,
163 .attrs = {
164 {
165
166 .offset_type =
167 BCAST_FILTER_OFFSET_PAYLOAD_START,
168 .offset = sizeof(rfc1042_header),
169 .val = cpu_to_be32(0x08060001),
170 .mask = cpu_to_be32(0xffffffff),
171 },
172 {
173
174 .offset_type =
175 BCAST_FILTER_OFFSET_PAYLOAD_START,
176 .offset = sizeof(rfc1042_header) + 2 +
177 sizeof(struct arphdr) +
178 ETH_ALEN + sizeof(__be32) +
179 ETH_ALEN,
180 .mask = cpu_to_be32(0xffffffff),
181
182 .reserved1 = cpu_to_le16(BC_FILTER_MAGIC_IP),
183 },
184 },
185 },
186 {
187
188 .discard = 0,
189 .frame_type = BCAST_FILTER_FRAME_TYPE_IPV4,
190 .attrs = {
191 {
192
193 .offset_type = BCAST_FILTER_OFFSET_IP_END,
194 .offset = offsetof(struct udphdr, dest),
195 .val = cpu_to_be32(0x00440000),
196 .mask = cpu_to_be32(0xffff0000),
197 },
198 {
199
200 .offset_type = BCAST_FILTER_OFFSET_IP_END,
201 .offset = 38,
202 .mask = cpu_to_be32(0xffffffff),
203
204 .reserved1 = cpu_to_le16(BC_FILTER_MAGIC_MAC),
205 },
206 },
207 },
208
209 {},
210};
211#endif
212
213void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
214{
215 if (!iwl_mvm_is_d0i3_supported(mvm))
216 return;
217
218 IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type);
219 spin_lock_bh(&mvm->refs_lock);
220 mvm->refs[ref_type]++;
221 spin_unlock_bh(&mvm->refs_lock);
222 iwl_trans_ref(mvm->trans);
223}
224
225void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
226{
227 if (!iwl_mvm_is_d0i3_supported(mvm))
228 return;
229
230 IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type);
231 spin_lock_bh(&mvm->refs_lock);
232 if (WARN_ON(!mvm->refs[ref_type])) {
233 spin_unlock_bh(&mvm->refs_lock);
234 return;
235 }
236 mvm->refs[ref_type]--;
237 spin_unlock_bh(&mvm->refs_lock);
238 iwl_trans_unref(mvm->trans);
239}
240
241static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm,
242 enum iwl_mvm_ref_type except_ref)
243{
244 int i, j;
245
246 if (!iwl_mvm_is_d0i3_supported(mvm))
247 return;
248
249 spin_lock_bh(&mvm->refs_lock);
250 for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
251 if (except_ref == i || !mvm->refs[i])
252 continue;
253
254 IWL_DEBUG_RPM(mvm, "Cleanup: remove mvm ref type %d (%d)\n",
255 i, mvm->refs[i]);
256 for (j = 0; j < mvm->refs[i]; j++)
257 iwl_trans_unref(mvm->trans);
258 mvm->refs[i] = 0;
259 }
260 spin_unlock_bh(&mvm->refs_lock);
261}
262
263bool iwl_mvm_ref_taken(struct iwl_mvm *mvm)
264{
265 int i;
266 bool taken = false;
267
268 if (!iwl_mvm_is_d0i3_supported(mvm))
269 return true;
270
271 spin_lock_bh(&mvm->refs_lock);
272 for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
273 if (mvm->refs[i]) {
274 taken = true;
275 break;
276 }
277 }
278 spin_unlock_bh(&mvm->refs_lock);
279
280 return taken;
281}
282
283int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
284{
285 iwl_mvm_ref(mvm, ref_type);
286
287 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
288 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status),
289 HZ)) {
290 WARN_ON_ONCE(1);
291 iwl_mvm_unref(mvm, ref_type);
292 return -EIO;
293 }
294
295 return 0;
296}
297
298static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
299{
300 int i;
301
302 memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
303 for (i = 0; i < NUM_PHY_CTX; i++) {
304 mvm->phy_ctxts[i].id = i;
305 mvm->phy_ctxts[i].ref = 0;
306 }
307}
308
309struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
310 const char *alpha2,
311 enum iwl_mcc_source src_id,
312 bool *changed)
313{
314 struct ieee80211_regdomain *regd = NULL;
315 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
316 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
317 struct iwl_mcc_update_resp *resp;
318
319 IWL_DEBUG_LAR(mvm, "Getting regdomain data for %s from FW\n", alpha2);
320
321 lockdep_assert_held(&mvm->mutex);
322
323 resp = iwl_mvm_update_mcc(mvm, alpha2, src_id);
324 if (IS_ERR_OR_NULL(resp)) {
325 IWL_DEBUG_LAR(mvm, "Could not get update from FW %d\n",
326 PTR_ERR_OR_ZERO(resp));
327 goto out;
328 }
329
330 if (changed)
331 *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE);
332
333 regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
334 __le32_to_cpu(resp->n_channels),
335 resp->channels,
336 __le16_to_cpu(resp->mcc),
337 __le16_to_cpu(resp->geo_info));
338
339 src_id = resp->source_id;
340 kfree(resp);
341 if (IS_ERR_OR_NULL(regd)) {
342 IWL_DEBUG_LAR(mvm, "Could not get parse update from FW %d\n",
343 PTR_ERR_OR_ZERO(regd));
344 goto out;
345 }
346
347 IWL_DEBUG_LAR(mvm, "setting alpha2 from FW to %s (0x%x, 0x%x) src=%d\n",
348 regd->alpha2, regd->alpha2[0], regd->alpha2[1], src_id);
349 mvm->lar_regdom_set = true;
350 mvm->mcc_src = src_id;
351
352out:
353 return regd;
354}
355
356void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm)
357{
358 bool changed;
359 struct ieee80211_regdomain *regd;
360
361 if (!iwl_mvm_is_lar_supported(mvm))
362 return;
363
364 regd = iwl_mvm_get_current_regdomain(mvm, &changed);
365 if (!IS_ERR_OR_NULL(regd)) {
366
367 if (changed)
368 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
369
370 kfree(regd);
371 }
372}
373
374struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
375 bool *changed)
376{
377 return iwl_mvm_get_regdomain(mvm->hw->wiphy, "ZZ",
378 iwl_mvm_is_wifi_mcc_supported(mvm) ?
379 MCC_SOURCE_GET_CURRENT :
380 MCC_SOURCE_OLD_FW, changed);
381}
382
383int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
384{
385 enum iwl_mcc_source used_src;
386 struct ieee80211_regdomain *regd;
387 int ret;
388 bool changed;
389 const struct ieee80211_regdomain *r =
390 rtnl_dereference(mvm->hw->wiphy->regd);
391
392 if (!r)
393 return -ENOENT;
394
395
396 used_src = mvm->mcc_src;
397 if (iwl_mvm_is_wifi_mcc_supported(mvm)) {
398
399 regd = iwl_mvm_get_current_regdomain(mvm, NULL);
400 if (!IS_ERR_OR_NULL(regd))
401 kfree(regd);
402 }
403
404
405 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src,
406 &changed);
407 if (IS_ERR_OR_NULL(regd))
408 return -EIO;
409
410
411 if (changed)
412 ret = regulatory_set_wiphy_regd_sync_rtnl(mvm->hw->wiphy, regd);
413 else
414 ret = 0;
415
416 kfree(regd);
417 return ret;
418}
419
420int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
421{
422 struct ieee80211_hw *hw = mvm->hw;
423 int num_mac, ret, i;
424 static const u32 mvm_ciphers[] = {
425 WLAN_CIPHER_SUITE_WEP40,
426 WLAN_CIPHER_SUITE_WEP104,
427 WLAN_CIPHER_SUITE_TKIP,
428 WLAN_CIPHER_SUITE_CCMP,
429 };
430
431
432 ieee80211_hw_set(hw, SIGNAL_DBM);
433 ieee80211_hw_set(hw, SPECTRUM_MGMT);
434 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
435 ieee80211_hw_set(hw, QUEUE_CONTROL);
436 ieee80211_hw_set(hw, WANT_MONITOR_VIF);
437 ieee80211_hw_set(hw, SUPPORTS_PS);
438 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
439 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
440 ieee80211_hw_set(hw, TIMING_BEACON_ONLY);
441 ieee80211_hw_set(hw, CONNECTION_MONITOR);
442 ieee80211_hw_set(hw, CHANCTX_STA_CSA);
443 ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
444 ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
445 ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
446 ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
447 if (iwl_mvm_has_new_rx_api(mvm))
448 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
449
450 if (fw_has_capa(&mvm->fw->ucode_capa,
451 IWL_UCODE_TLV_CAPA_STA_PM_NOTIF)) {
452 ieee80211_hw_set(hw, AP_LINK_PS);
453 } else if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) {
454
455
456
457
458
459 return -EINVAL;
460 }
461
462 if (mvm->trans->num_rx_queues > 1)
463 ieee80211_hw_set(hw, USES_RSS);
464
465 if (mvm->trans->max_skb_frags)
466 hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
467
468 hw->queues = IEEE80211_MAX_QUEUES;
469 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
470 hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
471 IEEE80211_RADIOTAP_MCS_HAVE_STBC;
472 hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC |
473 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED;
474
475 hw->radiotap_timestamp.units_pos =
476 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US |
477 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ;
478
479 hw->radiotap_timestamp.accuracy = 22;
480
481 hw->rate_control_algorithm = "iwl-mvm-rs";
482 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
483 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
484
485 BUILD_BUG_ON(ARRAY_SIZE(mvm->ciphers) < ARRAY_SIZE(mvm_ciphers) + 6);
486 memcpy(mvm->ciphers, mvm_ciphers, sizeof(mvm_ciphers));
487 hw->wiphy->n_cipher_suites = ARRAY_SIZE(mvm_ciphers);
488 hw->wiphy->cipher_suites = mvm->ciphers;
489
490 if (iwl_mvm_has_new_rx_api(mvm)) {
491 mvm->ciphers[hw->wiphy->n_cipher_suites] =
492 WLAN_CIPHER_SUITE_GCMP;
493 hw->wiphy->n_cipher_suites++;
494 mvm->ciphers[hw->wiphy->n_cipher_suites] =
495 WLAN_CIPHER_SUITE_GCMP_256;
496 hw->wiphy->n_cipher_suites++;
497 }
498
499
500
501
502
503 if (!iwlwifi_mod_params.swcrypto) {
504 ieee80211_hw_set(hw, MFP_CAPABLE);
505 mvm->ciphers[hw->wiphy->n_cipher_suites] =
506 WLAN_CIPHER_SUITE_AES_CMAC;
507 hw->wiphy->n_cipher_suites++;
508 if (iwl_mvm_has_new_rx_api(mvm)) {
509 mvm->ciphers[hw->wiphy->n_cipher_suites] =
510 WLAN_CIPHER_SUITE_BIP_GMAC_128;
511 hw->wiphy->n_cipher_suites++;
512 mvm->ciphers[hw->wiphy->n_cipher_suites] =
513 WLAN_CIPHER_SUITE_BIP_GMAC_256;
514 hw->wiphy->n_cipher_suites++;
515 }
516 }
517
518
519 if (mvm->fw->cs[0].cipher) {
520 const struct iwl_fw_cipher_scheme *fwcs = &mvm->fw->cs[0];
521 struct ieee80211_cipher_scheme *cs = &mvm->cs[0];
522
523 mvm->hw->n_cipher_schemes = 1;
524
525 cs->cipher = le32_to_cpu(fwcs->cipher);
526 cs->iftype = BIT(NL80211_IFTYPE_STATION);
527 cs->hdr_len = fwcs->hdr_len;
528 cs->pn_len = fwcs->pn_len;
529 cs->pn_off = fwcs->pn_off;
530 cs->key_idx_off = fwcs->key_idx_off;
531 cs->key_idx_mask = fwcs->key_idx_mask;
532 cs->key_idx_shift = fwcs->key_idx_shift;
533 cs->mic_len = fwcs->mic_len;
534
535 mvm->hw->cipher_schemes = mvm->cs;
536 mvm->ciphers[hw->wiphy->n_cipher_suites] = cs->cipher;
537 hw->wiphy->n_cipher_suites++;
538 }
539
540 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
541 hw->wiphy->features |=
542 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
543 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
544 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
545
546 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
547 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
548 hw->chanctx_data_size = sizeof(u16);
549
550 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
551 BIT(NL80211_IFTYPE_P2P_CLIENT) |
552 BIT(NL80211_IFTYPE_AP) |
553 BIT(NL80211_IFTYPE_P2P_GO) |
554 BIT(NL80211_IFTYPE_P2P_DEVICE) |
555 BIT(NL80211_IFTYPE_ADHOC);
556
557 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
558 hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
559 if (iwl_mvm_is_lar_supported(mvm))
560 hw->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
561 else
562 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
563 REGULATORY_DISABLE_BEACON_HINTS;
564
565 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
566 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
567
568 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
569 hw->wiphy->n_iface_combinations =
570 ARRAY_SIZE(iwl_mvm_iface_combinations);
571
572 hw->wiphy->max_remain_on_channel_duration = 10000;
573 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
574
575 hw->wiphy->max_adj_channel_rssi_comp = 3 * 5;
576
577
578 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
579 hw->wiphy->addresses = mvm->addresses;
580 hw->wiphy->n_addresses = 1;
581
582
583 num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
584 min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
585
586 for (i = 1; i < num_mac; i++) {
587 memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
588 ETH_ALEN);
589 mvm->addresses[i].addr[5]++;
590 hw->wiphy->n_addresses++;
591 }
592
593 iwl_mvm_reset_phy_ctxts(mvm);
594
595 hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
596
597 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
598
599 BUILD_BUG_ON(IWL_MVM_SCAN_STOPPING_MASK & IWL_MVM_SCAN_MASK);
600 BUILD_BUG_ON(IWL_MVM_MAX_UMAC_SCANS > HWEIGHT32(IWL_MVM_SCAN_MASK) ||
601 IWL_MVM_MAX_LMAC_SCANS > HWEIGHT32(IWL_MVM_SCAN_MASK));
602
603 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
604 mvm->max_scans = IWL_MVM_MAX_UMAC_SCANS;
605 else
606 mvm->max_scans = IWL_MVM_MAX_LMAC_SCANS;
607
608 if (mvm->nvm_data->bands[NL80211_BAND_2GHZ].n_channels)
609 hw->wiphy->bands[NL80211_BAND_2GHZ] =
610 &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
611 if (mvm->nvm_data->bands[NL80211_BAND_5GHZ].n_channels) {
612 hw->wiphy->bands[NL80211_BAND_5GHZ] =
613 &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
614
615 if (fw_has_capa(&mvm->fw->ucode_capa,
616 IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
617 fw_has_api(&mvm->fw->ucode_capa,
618 IWL_UCODE_TLV_API_LQ_SS_PARAMS))
619 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap |=
620 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
621 }
622
623 hw->wiphy->hw_version = mvm->trans->hw_id;
624
625 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
626 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
627 else
628 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
629
630 hw->wiphy->max_sched_scan_reqs = 1;
631 hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
632 hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
633
634 hw->wiphy->max_sched_scan_ie_len =
635 SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
636 hw->wiphy->max_sched_scan_plans = IWL_MAX_SCHED_SCAN_PLANS;
637 hw->wiphy->max_sched_scan_plan_interval = U16_MAX;
638
639
640
641
642
643 hw->wiphy->max_sched_scan_plan_iterations = 254;
644
645 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
646 NL80211_FEATURE_LOW_PRIORITY_SCAN |
647 NL80211_FEATURE_P2P_GO_OPPPS |
648 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
649 NL80211_FEATURE_DYNAMIC_SMPS |
650 NL80211_FEATURE_STATIC_SMPS |
651 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION;
652
653 if (fw_has_capa(&mvm->fw->ucode_capa,
654 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT))
655 hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION;
656 if (fw_has_capa(&mvm->fw->ucode_capa,
657 IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT))
658 hw->wiphy->features |= NL80211_FEATURE_QUIET;
659
660 if (fw_has_capa(&mvm->fw->ucode_capa,
661 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
662 hw->wiphy->features |=
663 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES;
664
665 if (fw_has_capa(&mvm->fw->ucode_capa,
666 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
667 hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES;
668
669 if (fw_has_api(&mvm->fw->ucode_capa,
670 IWL_UCODE_TLV_API_SCAN_TSF_REPORT)) {
671 wiphy_ext_feature_set(hw->wiphy,
672 NL80211_EXT_FEATURE_SCAN_START_TIME);
673 wiphy_ext_feature_set(hw->wiphy,
674 NL80211_EXT_FEATURE_BSS_PARENT_TSF);
675 wiphy_ext_feature_set(hw->wiphy,
676 NL80211_EXT_FEATURE_SET_SCAN_DWELL);
677 }
678
679 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
680
681#ifdef CONFIG_PM_SLEEP
682 if (iwl_mvm_is_d0i3_supported(mvm) &&
683 device_can_wakeup(mvm->trans->dev)) {
684 mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
685 hw->wiphy->wowlan = &mvm->wowlan;
686 }
687
688 if (mvm->fw->img[IWL_UCODE_WOWLAN].num_sec &&
689 mvm->trans->ops->d3_suspend &&
690 mvm->trans->ops->d3_resume &&
691 device_can_wakeup(mvm->trans->dev)) {
692 mvm->wowlan.flags |= WIPHY_WOWLAN_MAGIC_PKT |
693 WIPHY_WOWLAN_DISCONNECT |
694 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
695 WIPHY_WOWLAN_RFKILL_RELEASE |
696 WIPHY_WOWLAN_NET_DETECT;
697 if (!iwlwifi_mod_params.swcrypto)
698 mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
699 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
700 WIPHY_WOWLAN_4WAY_HANDSHAKE;
701
702 mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
703 mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
704 mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
705 mvm->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES;
706 mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
707 hw->wiphy->wowlan = &mvm->wowlan;
708 }
709#endif
710
711#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
712
713 mvm->bcast_filters = iwl_mvm_default_bcast_filters;
714#endif
715
716 ret = iwl_mvm_leds_init(mvm);
717 if (ret)
718 return ret;
719
720 if (fw_has_capa(&mvm->fw->ucode_capa,
721 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT)) {
722 IWL_DEBUG_TDLS(mvm, "TDLS supported\n");
723 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
724 ieee80211_hw_set(hw, TDLS_WIDER_BW);
725 }
726
727 if (fw_has_capa(&mvm->fw->ucode_capa,
728 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH)) {
729 IWL_DEBUG_TDLS(mvm, "TDLS channel switch supported\n");
730 hw->wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
731 }
732
733 hw->netdev_features |= mvm->cfg->features;
734 if (!iwl_mvm_is_csum_supported(mvm)) {
735 hw->netdev_features &= ~(IWL_TX_CSUM_NETIF_FLAGS |
736 NETIF_F_RXCSUM);
737
738 if (IWL_MVM_SW_TX_CSUM_OFFLOAD)
739 hw->netdev_features |= IWL_TX_CSUM_NETIF_FLAGS;
740 }
741
742 ret = ieee80211_register_hw(mvm->hw);
743 if (ret)
744 iwl_mvm_leds_exit(mvm);
745 mvm->init_status |= IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE;
746
747 if (mvm->cfg->vht_mu_mimo_supported)
748 wiphy_ext_feature_set(hw->wiphy,
749 NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
750
751 return ret;
752}
753
754static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm,
755 struct ieee80211_sta *sta,
756 struct sk_buff *skb)
757{
758 struct iwl_mvm_sta *mvmsta;
759 bool defer = false;
760
761
762
763
764
765
766 if (likely(!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)))
767 return false;
768
769 spin_lock(&mvm->d0i3_tx_lock);
770
771
772
773
774 if (!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))
775 goto out;
776
777 mvmsta = iwl_mvm_sta_from_mac80211(sta);
778 if (mvmsta->sta_id == IWL_MVM_INVALID_STA ||
779 mvmsta->sta_id != mvm->d0i3_ap_sta_id)
780 goto out;
781
782 __skb_queue_tail(&mvm->d0i3_tx, skb);
783 ieee80211_stop_queues(mvm->hw);
784
785
786 iwl_mvm_ref(mvm, IWL_MVM_REF_TX);
787 iwl_mvm_unref(mvm, IWL_MVM_REF_TX);
788
789 defer = true;
790out:
791 spin_unlock(&mvm->d0i3_tx_lock);
792 return defer;
793}
794
795static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
796 struct ieee80211_tx_control *control,
797 struct sk_buff *skb)
798{
799 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
800 struct ieee80211_sta *sta = control->sta;
801 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
802 struct ieee80211_hdr *hdr = (void *)skb->data;
803
804 if (iwl_mvm_is_radio_killed(mvm)) {
805 IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
806 goto drop;
807 }
808
809 if (info->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
810 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status) &&
811 !test_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
812 goto drop;
813
814
815 if ((info->control.vif->type == NL80211_IFTYPE_AP ||
816 info->control.vif->type == NL80211_IFTYPE_ADHOC) &&
817 ieee80211_is_mgmt(hdr->frame_control) &&
818 !ieee80211_is_bufferable_mmpdu(hdr->frame_control))
819 sta = NULL;
820
821 if (sta) {
822 if (iwl_mvm_defer_tx(mvm, sta, skb))
823 return;
824 if (iwl_mvm_tx_skb(mvm, skb, sta))
825 goto drop;
826 return;
827 }
828
829 if (iwl_mvm_tx_skb_non_sta(mvm, skb))
830 goto drop;
831 return;
832 drop:
833 ieee80211_free_txskb(hw, skb);
834}
835
836static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg)
837{
838 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG)
839 return false;
840 return true;
841}
842
843static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg)
844{
845 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
846 return false;
847 if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG)
848 return true;
849
850
851 return true;
852}
853
854#define CHECK_BA_TRIGGER(_mvm, _trig, _tid_bm, _tid, _fmt...) \
855 do { \
856 if (!(le16_to_cpu(_tid_bm) & BIT(_tid))) \
857 break; \
858 iwl_fw_dbg_collect_trig(&(_mvm)->fwrt, _trig, _fmt); \
859 } while (0)
860
861static void
862iwl_mvm_ampdu_check_trigger(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
863 struct ieee80211_sta *sta, u16 tid, u16 rx_ba_ssn,
864 enum ieee80211_ampdu_mlme_action action)
865{
866 struct iwl_fw_dbg_trigger_tlv *trig;
867 struct iwl_fw_dbg_trigger_ba *ba_trig;
868
869 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
870 return;
871
872 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
873 ba_trig = (void *)trig->data;
874
875 if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
876 ieee80211_vif_to_wdev(vif), trig))
877 return;
878
879 switch (action) {
880 case IEEE80211_AMPDU_TX_OPERATIONAL: {
881 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
882 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
883
884 CHECK_BA_TRIGGER(mvm, trig, ba_trig->tx_ba_start, tid,
885 "TX AGG START: MAC %pM tid %d ssn %d\n",
886 sta->addr, tid, tid_data->ssn);
887 break;
888 }
889 case IEEE80211_AMPDU_TX_STOP_CONT:
890 CHECK_BA_TRIGGER(mvm, trig, ba_trig->tx_ba_stop, tid,
891 "TX AGG STOP: MAC %pM tid %d\n",
892 sta->addr, tid);
893 break;
894 case IEEE80211_AMPDU_RX_START:
895 CHECK_BA_TRIGGER(mvm, trig, ba_trig->rx_ba_start, tid,
896 "RX AGG START: MAC %pM tid %d ssn %d\n",
897 sta->addr, tid, rx_ba_ssn);
898 break;
899 case IEEE80211_AMPDU_RX_STOP:
900 CHECK_BA_TRIGGER(mvm, trig, ba_trig->rx_ba_stop, tid,
901 "RX AGG STOP: MAC %pM tid %d\n",
902 sta->addr, tid);
903 break;
904 default:
905 break;
906 }
907}
908
909static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
910 struct ieee80211_vif *vif,
911 struct ieee80211_ampdu_params *params)
912{
913 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
914 int ret;
915 bool tx_agg_ref = false;
916 struct ieee80211_sta *sta = params->sta;
917 enum ieee80211_ampdu_mlme_action action = params->action;
918 u16 tid = params->tid;
919 u16 *ssn = ¶ms->ssn;
920 u8 buf_size = params->buf_size;
921 bool amsdu = params->amsdu;
922 u16 timeout = params->timeout;
923
924 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
925 sta->addr, tid, action);
926
927 if (!(mvm->nvm_data->sku_cap_11n_enable))
928 return -EACCES;
929
930
931 switch (action) {
932 case IEEE80211_AMPDU_TX_START:
933 case IEEE80211_AMPDU_TX_STOP_CONT:
934 case IEEE80211_AMPDU_TX_STOP_FLUSH:
935 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
936 case IEEE80211_AMPDU_TX_OPERATIONAL:
937
938
939
940
941
942
943
944
945 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG);
946 if (ret)
947 return ret;
948
949 tx_agg_ref = true;
950 break;
951 default:
952 break;
953 }
954
955 mutex_lock(&mvm->mutex);
956
957 switch (action) {
958 case IEEE80211_AMPDU_RX_START:
959 if (!iwl_enable_rx_ampdu(mvm->cfg)) {
960 ret = -EINVAL;
961 break;
962 }
963 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true, buf_size,
964 timeout);
965 break;
966 case IEEE80211_AMPDU_RX_STOP:
967 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false, buf_size,
968 timeout);
969 break;
970 case IEEE80211_AMPDU_TX_START:
971 if (!iwl_enable_tx_ampdu(mvm->cfg)) {
972 ret = -EINVAL;
973 break;
974 }
975 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
976 break;
977 case IEEE80211_AMPDU_TX_STOP_CONT:
978 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
979 break;
980 case IEEE80211_AMPDU_TX_STOP_FLUSH:
981 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
982 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
983 break;
984 case IEEE80211_AMPDU_TX_OPERATIONAL:
985 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid,
986 buf_size, amsdu);
987 break;
988 default:
989 WARN_ON_ONCE(1);
990 ret = -EINVAL;
991 break;
992 }
993
994 if (!ret) {
995 u16 rx_ba_ssn = 0;
996
997 if (action == IEEE80211_AMPDU_RX_START)
998 rx_ba_ssn = *ssn;
999
1000 iwl_mvm_ampdu_check_trigger(mvm, vif, sta, tid,
1001 rx_ba_ssn, action);
1002 }
1003 mutex_unlock(&mvm->mutex);
1004
1005
1006
1007
1008
1009 if (tx_agg_ref)
1010 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
1011
1012 return ret;
1013}
1014
1015static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
1016 struct ieee80211_vif *vif)
1017{
1018 struct iwl_mvm *mvm = data;
1019 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1020
1021 mvmvif->uploaded = false;
1022 mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
1023
1024 spin_lock_bh(&mvm->time_event_lock);
1025 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
1026 spin_unlock_bh(&mvm->time_event_lock);
1027
1028 mvmvif->phy_ctxt = NULL;
1029 memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data));
1030}
1031
1032static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1033{
1034
1035
1036
1037
1038 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) {
1039 mvm->fwrt.dump.desc = &iwl_dump_desc_assert;
1040 iwl_fw_error_dump(&mvm->fwrt);
1041 }
1042
1043
1044
1045
1046 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
1047
1048 iwl_mvm_stop_device(mvm);
1049
1050 mvm->scan_status = 0;
1051 mvm->ps_disabled = false;
1052 mvm->calibrating = false;
1053
1054
1055 iwl_mvm_cleanup_roc_te(mvm);
1056 ieee80211_remain_on_channel_expired(mvm->hw);
1057
1058
1059
1060
1061
1062 ieee80211_iterate_interfaces(mvm->hw, 0, iwl_mvm_cleanup_iterator, mvm);
1063
1064 mvm->p2p_device_vif = NULL;
1065 mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
1066
1067 iwl_mvm_reset_phy_ctxts(mvm);
1068 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
1069 memset(mvm->sta_deferred_frames, 0, sizeof(mvm->sta_deferred_frames));
1070 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
1071 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
1072
1073 ieee80211_wake_queues(mvm->hw);
1074
1075
1076 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
1077
1078 mvm->vif_count = 0;
1079 mvm->rx_ba_sessions = 0;
1080 mvm->fwrt.dump.conf = FW_DBG_INVALID;
1081 mvm->monitor_on = false;
1082
1083
1084 iwl_mvm_accu_radio_stats(mvm);
1085}
1086
1087int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
1088{
1089 int ret;
1090
1091 lockdep_assert_held(&mvm->mutex);
1092
1093 if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status)) {
1094
1095
1096
1097
1098 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1099 clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
1100
1101 iwl_mvm_restart_cleanup(mvm);
1102 } else {
1103
1104
1105
1106
1107
1108
1109 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
1110 }
1111 ret = iwl_mvm_up(mvm);
1112
1113 if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1114
1115
1116
1117
1118 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1119 iwl_mvm_d0i3_enable_tx(mvm, NULL);
1120 }
1121
1122 return ret;
1123}
1124
1125static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
1126{
1127 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1128 int ret;
1129
1130
1131 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1132
1133
1134
1135
1136
1137 wait_event_timeout(mvm->d0i3_exit_waitq,
1138 !test_bit(IWL_MVM_STATUS_IN_D0I3,
1139 &mvm->status),
1140 HZ);
1141 }
1142
1143 mutex_lock(&mvm->mutex);
1144 ret = __iwl_mvm_mac_start(mvm);
1145 mutex_unlock(&mvm->mutex);
1146
1147 return ret;
1148}
1149
1150static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
1151{
1152 int ret;
1153
1154 mutex_lock(&mvm->mutex);
1155
1156 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1157 iwl_mvm_d0i3_enable_tx(mvm, NULL);
1158 ret = iwl_mvm_update_quotas(mvm, true, NULL);
1159 if (ret)
1160 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
1161 ret);
1162
1163
1164 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
1165
1166
1167
1168
1169
1170 iwl_mvm_teardown_tdls_peers(mvm);
1171
1172 mutex_unlock(&mvm->mutex);
1173}
1174
1175static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
1176{
1177 if (iwl_mvm_is_d0i3_supported(mvm) &&
1178 iwl_mvm_enter_d0i3_on_suspend(mvm))
1179 WARN_ONCE(!wait_event_timeout(mvm->d0i3_exit_waitq,
1180 !test_bit(IWL_MVM_STATUS_IN_D0I3,
1181 &mvm->status),
1182 HZ),
1183 "D0i3 exit on resume timed out\n");
1184}
1185
1186static void
1187iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
1188 enum ieee80211_reconfig_type reconfig_type)
1189{
1190 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1191
1192 switch (reconfig_type) {
1193 case IEEE80211_RECONFIG_TYPE_RESTART:
1194 iwl_mvm_restart_complete(mvm);
1195 break;
1196 case IEEE80211_RECONFIG_TYPE_SUSPEND:
1197 iwl_mvm_resume_complete(mvm);
1198 break;
1199 }
1200}
1201
1202void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
1203{
1204 lockdep_assert_held(&mvm->mutex);
1205
1206
1207
1208
1209 memset(&mvm->accu_radio_stats, 0, sizeof(mvm->accu_radio_stats));
1210
1211
1212
1213
1214
1215
1216
1217 flush_work(&mvm->roc_done_wk);
1218
1219 iwl_mvm_stop_device(mvm);
1220
1221 iwl_mvm_async_handlers_purge(mvm);
1222
1223
1224
1225 iwl_mvm_del_aux_sta(mvm);
1226
1227
1228
1229
1230
1231
1232
1233 if (test_and_clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1234 ieee80211_iterate_interfaces(mvm->hw, 0,
1235 iwl_mvm_cleanup_iterator, mvm);
1236
1237
1238
1239
1240 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
1241 int i;
1242
1243 for (i = 0; i < mvm->max_scans; i++) {
1244 if (WARN_ONCE(mvm->scan_uid_status[i],
1245 "UMAC scan UID %d status was not cleaned\n",
1246 i))
1247 mvm->scan_uid_status[i] = 0;
1248 }
1249 }
1250}
1251
1252static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
1253{
1254 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1255
1256 flush_work(&mvm->d0i3_exit_work);
1257 flush_work(&mvm->async_handlers_wk);
1258 flush_work(&mvm->add_stream_wk);
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268 clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
1269
1270 iwl_fw_cancel_dump(&mvm->fwrt);
1271 cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork);
1272 cancel_delayed_work_sync(&mvm->scan_timeout_dwork);
1273 iwl_fw_free_dump_desc(&mvm->fwrt);
1274
1275 mutex_lock(&mvm->mutex);
1276 __iwl_mvm_mac_stop(mvm);
1277 mutex_unlock(&mvm->mutex);
1278
1279
1280
1281
1282
1283 cancel_work_sync(&mvm->async_handlers_wk);
1284}
1285
1286static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
1287{
1288 u16 i;
1289
1290 lockdep_assert_held(&mvm->mutex);
1291
1292 for (i = 0; i < NUM_PHY_CTX; i++)
1293 if (!mvm->phy_ctxts[i].ref)
1294 return &mvm->phy_ctxts[i];
1295
1296 IWL_ERR(mvm, "No available PHY context\n");
1297 return NULL;
1298}
1299
1300static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1301 s16 tx_power)
1302{
1303 struct iwl_dev_tx_power_cmd cmd = {
1304 .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
1305 .v3.mac_context_id =
1306 cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
1307 .v3.pwr_restriction = cpu_to_le16(8 * tx_power),
1308 };
1309 int len = sizeof(cmd);
1310
1311 if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
1312 cmd.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
1313
1314 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
1315 len = sizeof(cmd.v3);
1316
1317 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
1318}
1319
1320static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1321 struct ieee80211_vif *vif)
1322{
1323 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1324 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1325 int ret;
1326
1327 mvmvif->mvm = mvm;
1328
1329
1330
1331
1332
1333
1334 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF);
1335 if (ret)
1336 return ret;
1337
1338
1339
1340
1341
1342
1343
1344 mutex_lock(&mvm->mutex);
1345
1346
1347 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1348 mvmvif->beacon_stats.accu_num_beacons +=
1349 mvmvif->beacon_stats.num_beacons;
1350
1351
1352 ret = iwl_mvm_mac_ctxt_init(mvm, vif);
1353 if (ret)
1354 goto out_unlock;
1355
1356
1357 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
1358 mvm->vif_count++;
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371 if (vif->type == NL80211_IFTYPE_AP ||
1372 vif->type == NL80211_IFTYPE_ADHOC) {
1373 ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
1374 if (ret) {
1375 IWL_ERR(mvm, "Failed to allocate bcast sta\n");
1376 goto out_release;
1377 }
1378
1379
1380
1381
1382
1383 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->mcast_sta,
1384 0, vif->type,
1385 IWL_STA_MULTICAST);
1386 if (ret)
1387 goto out_release;
1388
1389 iwl_mvm_vif_dbgfs_register(mvm, vif);
1390 goto out_unlock;
1391 }
1392
1393 mvmvif->features |= hw->netdev_features;
1394
1395 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
1396 if (ret)
1397 goto out_release;
1398
1399 ret = iwl_mvm_power_update_mac(mvm);
1400 if (ret)
1401 goto out_remove_mac;
1402
1403
1404 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
1405 if (ret)
1406 goto out_remove_mac;
1407
1408 if (!mvm->bf_allowed_vif &&
1409 vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
1410 mvm->bf_allowed_vif = mvmvif;
1411 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
1412 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
1413 }
1414
1415
1416
1417
1418
1419
1420 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1421
1422 mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1423 if (!mvmvif->phy_ctxt) {
1424 ret = -ENOSPC;
1425 goto out_free_bf;
1426 }
1427
1428 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1429 ret = iwl_mvm_binding_add_vif(mvm, vif);
1430 if (ret)
1431 goto out_unref_phy;
1432
1433 ret = iwl_mvm_add_p2p_bcast_sta(mvm, vif);
1434 if (ret)
1435 goto out_unbind;
1436
1437
1438
1439 mvm->p2p_device_vif = vif;
1440 }
1441
1442 if (vif->type == NL80211_IFTYPE_MONITOR)
1443 mvm->monitor_on = true;
1444
1445 iwl_mvm_vif_dbgfs_register(mvm, vif);
1446 goto out_unlock;
1447
1448 out_unbind:
1449 iwl_mvm_binding_remove_vif(mvm, vif);
1450 out_unref_phy:
1451 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1452 out_free_bf:
1453 if (mvm->bf_allowed_vif == mvmvif) {
1454 mvm->bf_allowed_vif = NULL;
1455 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
1456 IEEE80211_VIF_SUPPORTS_CQM_RSSI);
1457 }
1458 out_remove_mac:
1459 mvmvif->phy_ctxt = NULL;
1460 iwl_mvm_mac_ctxt_remove(mvm, vif);
1461 out_release:
1462 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
1463 mvm->vif_count--;
1464 out_unlock:
1465 mutex_unlock(&mvm->mutex);
1466
1467 iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF);
1468
1469 return ret;
1470}
1471
1472static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
1473 struct ieee80211_vif *vif)
1474{
1475 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1476
1477
1478
1479
1480
1481 flush_work(&mvm->roc_done_wk);
1482 }
1483}
1484
1485static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
1486 struct ieee80211_vif *vif)
1487{
1488 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1489 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1490
1491 iwl_mvm_prepare_mac_removal(mvm, vif);
1492
1493 mutex_lock(&mvm->mutex);
1494
1495 if (mvm->bf_allowed_vif == mvmvif) {
1496 mvm->bf_allowed_vif = NULL;
1497 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
1498 IEEE80211_VIF_SUPPORTS_CQM_RSSI);
1499 }
1500
1501 iwl_mvm_vif_dbgfs_clean(mvm, vif);
1502
1503
1504
1505
1506
1507 if (vif->type == NL80211_IFTYPE_AP ||
1508 vif->type == NL80211_IFTYPE_ADHOC) {
1509#ifdef CONFIG_NL80211_TESTMODE
1510 if (vif == mvm->noa_vif) {
1511 mvm->noa_vif = NULL;
1512 mvm->noa_duration = 0;
1513 }
1514#endif
1515 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->mcast_sta);
1516 iwl_mvm_dealloc_bcast_sta(mvm, vif);
1517 goto out_release;
1518 }
1519
1520 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1521 mvm->p2p_device_vif = NULL;
1522 iwl_mvm_rm_p2p_bcast_sta(mvm, vif);
1523 iwl_mvm_binding_remove_vif(mvm, vif);
1524 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1525 mvmvif->phy_ctxt = NULL;
1526 }
1527
1528 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
1529 mvm->vif_count--;
1530
1531 iwl_mvm_power_update_mac(mvm);
1532 iwl_mvm_mac_ctxt_remove(mvm, vif);
1533
1534 if (vif->type == NL80211_IFTYPE_MONITOR)
1535 mvm->monitor_on = false;
1536
1537out_release:
1538 mutex_unlock(&mvm->mutex);
1539}
1540
1541static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
1542{
1543 return 0;
1544}
1545
1546struct iwl_mvm_mc_iter_data {
1547 struct iwl_mvm *mvm;
1548 int port_id;
1549};
1550
1551static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
1552 struct ieee80211_vif *vif)
1553{
1554 struct iwl_mvm_mc_iter_data *data = _data;
1555 struct iwl_mvm *mvm = data->mvm;
1556 struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
1557 struct iwl_host_cmd hcmd = {
1558 .id = MCAST_FILTER_CMD,
1559 .flags = CMD_ASYNC,
1560 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1561 };
1562 int ret, len;
1563
1564
1565 if (WARN_ON_ONCE(data->port_id >= MAX_PORT_ID_NUM))
1566 return;
1567
1568 if (vif->type != NL80211_IFTYPE_STATION ||
1569 !vif->bss_conf.assoc)
1570 return;
1571
1572 cmd->port_id = data->port_id++;
1573 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
1574 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
1575
1576 hcmd.len[0] = len;
1577 hcmd.data[0] = cmd;
1578
1579 ret = iwl_mvm_send_cmd(mvm, &hcmd);
1580 if (ret)
1581 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
1582}
1583
1584static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
1585{
1586 struct iwl_mvm_mc_iter_data iter_data = {
1587 .mvm = mvm,
1588 };
1589
1590 lockdep_assert_held(&mvm->mutex);
1591
1592 if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
1593 return;
1594
1595 ieee80211_iterate_active_interfaces_atomic(
1596 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1597 iwl_mvm_mc_iface_iterator, &iter_data);
1598}
1599
1600static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
1601 struct netdev_hw_addr_list *mc_list)
1602{
1603 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1604 struct iwl_mcast_filter_cmd *cmd;
1605 struct netdev_hw_addr *addr;
1606 int addr_count;
1607 bool pass_all;
1608 int len;
1609
1610 addr_count = netdev_hw_addr_list_count(mc_list);
1611 pass_all = addr_count > MAX_MCAST_FILTERING_ADDRESSES ||
1612 IWL_MVM_FW_MCAST_FILTER_PASS_ALL;
1613 if (pass_all)
1614 addr_count = 0;
1615
1616 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4);
1617 cmd = kzalloc(len, GFP_ATOMIC);
1618 if (!cmd)
1619 return 0;
1620
1621 if (pass_all) {
1622 cmd->pass_all = 1;
1623 return (u64)(unsigned long)cmd;
1624 }
1625
1626 netdev_hw_addr_list_for_each(addr, mc_list) {
1627 IWL_DEBUG_MAC80211(mvm, "mcast addr (%d): %pM\n",
1628 cmd->count, addr->addr);
1629 memcpy(&cmd->addr_list[cmd->count * ETH_ALEN],
1630 addr->addr, ETH_ALEN);
1631 cmd->count++;
1632 }
1633
1634 return (u64)(unsigned long)cmd;
1635}
1636
1637static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
1638 unsigned int changed_flags,
1639 unsigned int *total_flags,
1640 u64 multicast)
1641{
1642 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1643 struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast;
1644
1645 mutex_lock(&mvm->mutex);
1646
1647
1648 kfree(mvm->mcast_filter_cmd);
1649 mvm->mcast_filter_cmd = cmd;
1650
1651 if (!cmd)
1652 goto out;
1653
1654 if (changed_flags & FIF_ALLMULTI)
1655 cmd->pass_all = !!(*total_flags & FIF_ALLMULTI);
1656
1657 if (cmd->pass_all)
1658 cmd->count = 0;
1659
1660 iwl_mvm_recalc_multicast(mvm);
1661out:
1662 mutex_unlock(&mvm->mutex);
1663 *total_flags = 0;
1664}
1665
1666static void iwl_mvm_config_iface_filter(struct ieee80211_hw *hw,
1667 struct ieee80211_vif *vif,
1668 unsigned int filter_flags,
1669 unsigned int changed_flags)
1670{
1671 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1672
1673
1674 if (!(changed_flags & FIF_PROBE_REQ))
1675 return;
1676
1677
1678 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc ||
1679 !vif->p2p)
1680 return;
1681
1682 mutex_lock(&mvm->mutex);
1683 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
1684 mutex_unlock(&mvm->mutex);
1685}
1686
1687#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1688struct iwl_bcast_iter_data {
1689 struct iwl_mvm *mvm;
1690 struct iwl_bcast_filter_cmd *cmd;
1691 u8 current_filter;
1692};
1693
1694static void
1695iwl_mvm_set_bcast_filter(struct ieee80211_vif *vif,
1696 const struct iwl_fw_bcast_filter *in_filter,
1697 struct iwl_fw_bcast_filter *out_filter)
1698{
1699 struct iwl_fw_bcast_filter_attr *attr;
1700 int i;
1701
1702 memcpy(out_filter, in_filter, sizeof(*out_filter));
1703
1704 for (i = 0; i < ARRAY_SIZE(out_filter->attrs); i++) {
1705 attr = &out_filter->attrs[i];
1706
1707 if (!attr->mask)
1708 break;
1709
1710 switch (attr->reserved1) {
1711 case cpu_to_le16(BC_FILTER_MAGIC_IP):
1712 if (vif->bss_conf.arp_addr_cnt != 1) {
1713 attr->mask = 0;
1714 continue;
1715 }
1716
1717 attr->val = vif->bss_conf.arp_addr_list[0];
1718 break;
1719 case cpu_to_le16(BC_FILTER_MAGIC_MAC):
1720 attr->val = *(__be32 *)&vif->addr[2];
1721 break;
1722 default:
1723 break;
1724 }
1725 attr->reserved1 = 0;
1726 out_filter->num_attrs++;
1727 }
1728}
1729
1730static void iwl_mvm_bcast_filter_iterator(void *_data, u8 *mac,
1731 struct ieee80211_vif *vif)
1732{
1733 struct iwl_bcast_iter_data *data = _data;
1734 struct iwl_mvm *mvm = data->mvm;
1735 struct iwl_bcast_filter_cmd *cmd = data->cmd;
1736 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1737 struct iwl_fw_bcast_mac *bcast_mac;
1738 int i;
1739
1740 if (WARN_ON(mvmvif->id >= ARRAY_SIZE(cmd->macs)))
1741 return;
1742
1743 bcast_mac = &cmd->macs[mvmvif->id];
1744
1745
1746
1747
1748
1749 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p ||
1750 !vif->bss_conf.assoc)
1751 return;
1752
1753 bcast_mac->default_discard = 1;
1754
1755
1756 for (i = 0; mvm->bcast_filters[i].attrs[0].mask; i++) {
1757
1758
1759
1760
1761
1762 if (WARN_ON_ONCE(data->current_filter >=
1763 ARRAY_SIZE(cmd->filters))) {
1764 bcast_mac->default_discard = 0;
1765 bcast_mac->attached_filters = 0;
1766 break;
1767 }
1768
1769 iwl_mvm_set_bcast_filter(vif,
1770 &mvm->bcast_filters[i],
1771 &cmd->filters[data->current_filter]);
1772
1773
1774 if (!cmd->filters[data->current_filter].num_attrs)
1775 continue;
1776
1777
1778 bcast_mac->attached_filters |=
1779 cpu_to_le16(BIT(data->current_filter));
1780
1781 data->current_filter++;
1782 }
1783}
1784
1785bool iwl_mvm_bcast_filter_build_cmd(struct iwl_mvm *mvm,
1786 struct iwl_bcast_filter_cmd *cmd)
1787{
1788 struct iwl_bcast_iter_data iter_data = {
1789 .mvm = mvm,
1790 .cmd = cmd,
1791 };
1792
1793 if (IWL_MVM_FW_BCAST_FILTER_PASS_ALL)
1794 return false;
1795
1796 memset(cmd, 0, sizeof(*cmd));
1797 cmd->max_bcast_filters = ARRAY_SIZE(cmd->filters);
1798 cmd->max_macs = ARRAY_SIZE(cmd->macs);
1799
1800#ifdef CONFIG_IWLWIFI_DEBUGFS
1801
1802 if (mvm->dbgfs_bcast_filtering.override) {
1803 memcpy(cmd->filters, &mvm->dbgfs_bcast_filtering.cmd.filters,
1804 sizeof(cmd->filters));
1805 memcpy(cmd->macs, &mvm->dbgfs_bcast_filtering.cmd.macs,
1806 sizeof(cmd->macs));
1807 return true;
1808 }
1809#endif
1810
1811
1812 if (!mvm->bcast_filters)
1813 return false;
1814
1815
1816 ieee80211_iterate_active_interfaces(
1817 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1818 iwl_mvm_bcast_filter_iterator, &iter_data);
1819
1820 return true;
1821}
1822
1823static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
1824{
1825 struct iwl_bcast_filter_cmd cmd;
1826
1827 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING))
1828 return 0;
1829
1830 if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1831 return 0;
1832
1833 return iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1834 sizeof(cmd), &cmd);
1835}
1836#else
1837static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
1838{
1839 return 0;
1840}
1841#endif
1842
1843static int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm,
1844 struct ieee80211_vif *vif)
1845{
1846 struct iwl_mu_group_mgmt_cmd cmd = {};
1847
1848 memcpy(cmd.membership_status, vif->bss_conf.mu_group.membership,
1849 WLAN_MEMBERSHIP_LEN);
1850 memcpy(cmd.user_position, vif->bss_conf.mu_group.position,
1851 WLAN_USER_POSITION_LEN);
1852
1853 return iwl_mvm_send_cmd_pdu(mvm,
1854 WIDE_ID(DATA_PATH_GROUP,
1855 UPDATE_MU_GROUPS_CMD),
1856 0, sizeof(cmd), &cmd);
1857}
1858
1859static void iwl_mvm_mu_mimo_iface_iterator(void *_data, u8 *mac,
1860 struct ieee80211_vif *vif)
1861{
1862 if (vif->mu_mimo_owner) {
1863 struct iwl_mu_group_mgmt_notif *notif = _data;
1864
1865
1866
1867
1868
1869
1870 ieee80211_update_mu_groups(vif,
1871 (u8 *)¬if->membership_status,
1872 (u8 *)¬if->user_position);
1873 }
1874}
1875
1876void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
1877 struct iwl_rx_cmd_buffer *rxb)
1878{
1879 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1880 struct iwl_mu_group_mgmt_notif *notif = (void *)pkt->data;
1881
1882 ieee80211_iterate_active_interfaces_atomic(
1883 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1884 iwl_mvm_mu_mimo_iface_iterator, notif);
1885}
1886
1887static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1888 struct ieee80211_vif *vif,
1889 struct ieee80211_bss_conf *bss_conf,
1890 u32 changes)
1891{
1892 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1893 int ret;
1894
1895
1896
1897
1898
1899
1900 if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
1901 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
1902
1903 if (changes & BSS_CHANGED_ASSOC && !bss_conf->assoc &&
1904 mvmvif->lqm_active)
1905 iwl_mvm_send_lqm_cmd(vif, LQM_CMD_OPERATION_STOP_MEASUREMENT,
1906 0, 0);
1907
1908
1909
1910
1911
1912
1913
1914 if (changes & BSS_CHANGED_BSSID && !mvmvif->associated)
1915 memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
1916
1917 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid);
1918 if (ret)
1919 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1920
1921
1922 memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
1923 mvmvif->associated = bss_conf->assoc;
1924
1925 if (changes & BSS_CHANGED_ASSOC) {
1926 if (bss_conf->assoc) {
1927
1928 iwl_mvm_request_statistics(mvm, true);
1929 memset(&mvmvif->beacon_stats, 0,
1930 sizeof(mvmvif->beacon_stats));
1931
1932
1933 ret = iwl_mvm_update_quotas(mvm, true, NULL);
1934 if (ret) {
1935 IWL_ERR(mvm, "failed to update quotas\n");
1936 return;
1937 }
1938
1939 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
1940 &mvm->status)) {
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955 u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
1956 iwl_mvm_protect_session(mvm, vif, dur, dur,
1957 5 * dur, false);
1958 }
1959
1960 iwl_mvm_sf_update(mvm, vif, false);
1961 iwl_mvm_power_vif_assoc(mvm, vif);
1962 if (vif->p2p) {
1963 iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT);
1964 iwl_mvm_update_smps(mvm, vif,
1965 IWL_MVM_SMPS_REQ_PROT,
1966 IEEE80211_SMPS_DYNAMIC);
1967 }
1968 } else if (mvmvif->ap_sta_id != IWL_MVM_INVALID_STA) {
1969
1970
1971
1972
1973 WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false),
1974 "Failed to update SF upon disassociation\n");
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
1985 &mvm->status)) {
1986
1987
1988
1989
1990 ret = iwl_mvm_rm_sta_id(mvm, vif,
1991 mvmvif->ap_sta_id);
1992 if (ret)
1993 IWL_ERR(mvm,
1994 "failed to remove AP station\n");
1995
1996 if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
1997 mvm->d0i3_ap_sta_id =
1998 IWL_MVM_INVALID_STA;
1999 mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
2000 }
2001
2002
2003 ret = iwl_mvm_update_quotas(mvm, false, NULL);
2004 if (ret)
2005 IWL_ERR(mvm, "failed to update quotas\n");
2006
2007 if (vif->p2p)
2008 iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT);
2009
2010
2011 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2012 if (ret)
2013 IWL_ERR(mvm,
2014 "failed to update MAC %pM (clear after unassoc)\n",
2015 vif->addr);
2016 }
2017
2018
2019
2020
2021
2022 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
2023 (changes & BSS_CHANGED_MU_GROUPS) && vif->mu_mimo_owner) {
2024 ret = iwl_mvm_update_mu_groups(mvm, vif);
2025 if (ret)
2026 IWL_ERR(mvm,
2027 "failed to update VHT MU_MIMO groups\n");
2028 }
2029
2030 iwl_mvm_recalc_multicast(mvm);
2031 iwl_mvm_configure_bcast_filter(mvm);
2032
2033
2034 mvmvif->bf_data.ave_beacon_signal = 0;
2035
2036 iwl_mvm_bt_coex_vif_change(mvm);
2037 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
2038 IEEE80211_SMPS_AUTOMATIC);
2039 if (fw_has_capa(&mvm->fw->ucode_capa,
2040 IWL_UCODE_TLV_CAPA_UMAC_SCAN))
2041 iwl_mvm_config_scan(mvm);
2042 }
2043
2044 if (changes & BSS_CHANGED_BEACON_INFO) {
2045
2046
2047
2048
2049 iwl_mvm_stop_session_protection(mvm, vif);
2050
2051 iwl_mvm_sf_update(mvm, vif, false);
2052 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
2053 }
2054
2055 if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | BSS_CHANGED_QOS |
2056
2057
2058
2059
2060 BSS_CHANGED_BEACON_INFO)) {
2061 ret = iwl_mvm_power_update_mac(mvm);
2062 if (ret)
2063 IWL_ERR(mvm, "failed to update power mode\n");
2064 }
2065
2066 if (changes & BSS_CHANGED_TXPOWER) {
2067 IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
2068 bss_conf->txpower);
2069 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
2070 }
2071
2072 if (changes & BSS_CHANGED_CQM) {
2073 IWL_DEBUG_MAC80211(mvm, "cqm info_changed\n");
2074
2075 mvmvif->bf_data.last_cqm_event = 0;
2076 if (mvmvif->bf_data.bf_enabled) {
2077 ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
2078 if (ret)
2079 IWL_ERR(mvm,
2080 "failed to update CQM thresholds\n");
2081 }
2082 }
2083
2084 if (changes & BSS_CHANGED_ARP_FILTER) {
2085 IWL_DEBUG_MAC80211(mvm, "arp filter changed\n");
2086 iwl_mvm_configure_bcast_filter(mvm);
2087 }
2088}
2089
2090static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
2091 struct ieee80211_vif *vif)
2092{
2093 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2094 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2095 int ret;
2096
2097
2098
2099
2100
2101 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_START_AP);
2102 if (ret)
2103 return ret;
2104
2105 mutex_lock(&mvm->mutex);
2106
2107
2108 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
2109 if (ret)
2110 goto out_unlock;
2111
2112
2113
2114
2115
2116 if (vif->type == NL80211_IFTYPE_AP)
2117 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
2118
2119 mvmvif->ap_assoc_sta_count = 0;
2120
2121
2122 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
2123 if (ret)
2124 goto out_unlock;
2125
2126
2127 ret = iwl_mvm_binding_add_vif(mvm, vif);
2128 if (ret)
2129 goto out_remove;
2130
2131 ret = iwl_mvm_add_mcast_sta(mvm, vif);
2132 if (ret)
2133 goto out_unbind;
2134
2135
2136
2137 ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
2138 if (ret)
2139 goto out_rm_mcast;
2140
2141
2142 mvmvif->ap_ibss_active = true;
2143
2144
2145 iwl_mvm_power_update_mac(mvm);
2146
2147 ret = iwl_mvm_update_quotas(mvm, false, NULL);
2148 if (ret)
2149 goto out_quota_failed;
2150
2151
2152 if (vif->p2p && mvm->p2p_device_vif)
2153 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
2154
2155 iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS);
2156
2157 iwl_mvm_bt_coex_vif_change(mvm);
2158
2159
2160 if (iwl_mvm_phy_ctx_count(mvm) > 1)
2161 iwl_mvm_teardown_tdls_peers(mvm);
2162
2163 goto out_unlock;
2164
2165out_quota_failed:
2166 iwl_mvm_power_update_mac(mvm);
2167 mvmvif->ap_ibss_active = false;
2168 iwl_mvm_send_rm_bcast_sta(mvm, vif);
2169out_rm_mcast:
2170 iwl_mvm_rm_mcast_sta(mvm, vif);
2171out_unbind:
2172 iwl_mvm_binding_remove_vif(mvm, vif);
2173out_remove:
2174 iwl_mvm_mac_ctxt_remove(mvm, vif);
2175out_unlock:
2176 mutex_unlock(&mvm->mutex);
2177 iwl_mvm_unref(mvm, IWL_MVM_REF_START_AP);
2178 return ret;
2179}
2180
2181static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
2182 struct ieee80211_vif *vif)
2183{
2184 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2185 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2186
2187 iwl_mvm_prepare_mac_removal(mvm, vif);
2188
2189 mutex_lock(&mvm->mutex);
2190
2191
2192 if (rcu_access_pointer(mvm->csa_vif) == vif) {
2193 iwl_mvm_remove_time_event(mvm, mvmvif,
2194 &mvmvif->time_event_data);
2195 RCU_INIT_POINTER(mvm->csa_vif, NULL);
2196 mvmvif->csa_countdown = false;
2197 }
2198
2199 if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
2200 RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
2201 mvm->csa_tx_block_bcn_timeout = 0;
2202 }
2203
2204 mvmvif->ap_ibss_active = false;
2205 mvm->ap_last_beacon_gp2 = 0;
2206
2207 iwl_mvm_bt_coex_vif_change(mvm);
2208
2209 iwl_mvm_unref(mvm, IWL_MVM_REF_AP_IBSS);
2210
2211
2212 if (vif->p2p && mvm->p2p_device_vif)
2213 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
2214
2215 iwl_mvm_update_quotas(mvm, false, NULL);
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225 if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
2226 iwl_mvm_rm_mcast_sta(mvm, vif);
2227 iwl_mvm_send_rm_bcast_sta(mvm, vif);
2228 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
2229 iwl_mvm_rm_mcast_sta(mvm, vif);
2230 iwl_mvm_binding_remove_vif(mvm, vif);
2231
2232 iwl_mvm_power_update_mac(mvm);
2233
2234 iwl_mvm_mac_ctxt_remove(mvm, vif);
2235
2236 mutex_unlock(&mvm->mutex);
2237}
2238
2239static void
2240iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
2241 struct ieee80211_vif *vif,
2242 struct ieee80211_bss_conf *bss_conf,
2243 u32 changes)
2244{
2245 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2246
2247
2248 if (!mvmvif->ap_ibss_active)
2249 return;
2250
2251 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT |
2252 BSS_CHANGED_BANDWIDTH | BSS_CHANGED_QOS) &&
2253 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL))
2254 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
2255
2256
2257 if (changes & BSS_CHANGED_BEACON &&
2258 iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
2259 IWL_WARN(mvm, "Failed updating beacon data\n");
2260
2261 if (changes & BSS_CHANGED_TXPOWER) {
2262 IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
2263 bss_conf->txpower);
2264 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
2265 }
2266}
2267
2268static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
2269 struct ieee80211_vif *vif,
2270 struct ieee80211_bss_conf *bss_conf,
2271 u32 changes)
2272{
2273 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2274
2275
2276
2277
2278
2279
2280 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_BSS_CHANGED))
2281 return;
2282
2283 mutex_lock(&mvm->mutex);
2284
2285 if (changes & BSS_CHANGED_IDLE && !bss_conf->idle)
2286 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
2287
2288 switch (vif->type) {
2289 case NL80211_IFTYPE_STATION:
2290 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
2291 break;
2292 case NL80211_IFTYPE_AP:
2293 case NL80211_IFTYPE_ADHOC:
2294 iwl_mvm_bss_info_changed_ap_ibss(mvm, vif, bss_conf, changes);
2295 break;
2296 case NL80211_IFTYPE_MONITOR:
2297 if (changes & BSS_CHANGED_MU_GROUPS)
2298 iwl_mvm_update_mu_groups(mvm, vif);
2299 break;
2300 default:
2301
2302 WARN_ON_ONCE(1);
2303 }
2304
2305 mutex_unlock(&mvm->mutex);
2306 iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED);
2307}
2308
2309static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
2310 struct ieee80211_vif *vif,
2311 struct ieee80211_scan_request *hw_req)
2312{
2313 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2314 int ret;
2315
2316 if (hw_req->req.n_channels == 0 ||
2317 hw_req->req.n_channels > mvm->fw->ucode_capa.n_scan_channels)
2318 return -EINVAL;
2319
2320 mutex_lock(&mvm->mutex);
2321 ret = iwl_mvm_reg_scan_start(mvm, vif, &hw_req->req, &hw_req->ies);
2322 mutex_unlock(&mvm->mutex);
2323
2324 return ret;
2325}
2326
2327static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
2328 struct ieee80211_vif *vif)
2329{
2330 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2331
2332 mutex_lock(&mvm->mutex);
2333
2334
2335
2336
2337
2338
2339
2340
2341 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR)
2342 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
2343
2344 mutex_unlock(&mvm->mutex);
2345}
2346
2347static void
2348iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
2349 struct ieee80211_sta *sta, u16 tids,
2350 int num_frames,
2351 enum ieee80211_frame_release_type reason,
2352 bool more_data)
2353{
2354 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2355
2356
2357
2358 iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames,
2359 tids, more_data, false);
2360}
2361
2362static void
2363iwl_mvm_mac_release_buffered_frames(struct ieee80211_hw *hw,
2364 struct ieee80211_sta *sta, u16 tids,
2365 int num_frames,
2366 enum ieee80211_frame_release_type reason,
2367 bool more_data)
2368{
2369 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2370
2371
2372
2373 iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames,
2374 tids, more_data, true);
2375}
2376
2377static void __iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
2378 enum sta_notify_cmd cmd,
2379 struct ieee80211_sta *sta)
2380{
2381 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2382 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2383 unsigned long txqs = 0, tids = 0;
2384 int tid;
2385
2386
2387
2388
2389
2390
2391 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
2392 return;
2393
2394 spin_lock_bh(&mvmsta->lock);
2395 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
2396 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
2397
2398 if (tid_data->txq_id == IWL_MVM_INVALID_QUEUE)
2399 continue;
2400
2401 __set_bit(tid_data->txq_id, &txqs);
2402
2403 if (iwl_mvm_tid_queued(mvm, tid_data) == 0)
2404 continue;
2405
2406 __set_bit(tid, &tids);
2407 }
2408
2409 switch (cmd) {
2410 case STA_NOTIFY_SLEEP:
2411 for_each_set_bit(tid, &tids, IWL_MAX_TID_COUNT)
2412 ieee80211_sta_set_buffered(sta, tid, true);
2413
2414 if (txqs)
2415 iwl_trans_freeze_txq_timer(mvm->trans, txqs, true);
2416
2417
2418
2419
2420
2421 break;
2422 case STA_NOTIFY_AWAKE:
2423 if (WARN_ON(mvmsta->sta_id == IWL_MVM_INVALID_STA))
2424 break;
2425
2426 if (txqs)
2427 iwl_trans_freeze_txq_timer(mvm->trans, txqs, false);
2428 iwl_mvm_sta_modify_ps_wake(mvm, sta);
2429 break;
2430 default:
2431 break;
2432 }
2433 spin_unlock_bh(&mvmsta->lock);
2434}
2435
2436static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
2437 struct ieee80211_vif *vif,
2438 enum sta_notify_cmd cmd,
2439 struct ieee80211_sta *sta)
2440{
2441 __iwl_mvm_mac_sta_notify(hw, cmd, sta);
2442}
2443
2444void iwl_mvm_sta_pm_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
2445{
2446 struct iwl_rx_packet *pkt = rxb_addr(rxb);
2447 struct iwl_mvm_pm_state_notification *notif = (void *)pkt->data;
2448 struct ieee80211_sta *sta;
2449 struct iwl_mvm_sta *mvmsta;
2450 bool sleeping = (notif->type != IWL_MVM_PM_EVENT_AWAKE);
2451
2452 if (WARN_ON(notif->sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)))
2453 return;
2454
2455 rcu_read_lock();
2456 sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
2457 if (WARN_ON(IS_ERR_OR_NULL(sta))) {
2458 rcu_read_unlock();
2459 return;
2460 }
2461
2462 mvmsta = iwl_mvm_sta_from_mac80211(sta);
2463
2464 if (!mvmsta->vif ||
2465 mvmsta->vif->type != NL80211_IFTYPE_AP) {
2466 rcu_read_unlock();
2467 return;
2468 }
2469
2470 if (mvmsta->sleeping != sleeping) {
2471 mvmsta->sleeping = sleeping;
2472 __iwl_mvm_mac_sta_notify(mvm->hw,
2473 sleeping ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE,
2474 sta);
2475 ieee80211_sta_ps_transition(sta, sleeping);
2476 }
2477
2478 if (sleeping) {
2479 switch (notif->type) {
2480 case IWL_MVM_PM_EVENT_AWAKE:
2481 case IWL_MVM_PM_EVENT_ASLEEP:
2482 break;
2483 case IWL_MVM_PM_EVENT_UAPSD:
2484 ieee80211_sta_uapsd_trigger(sta, IEEE80211_NUM_TIDS);
2485 break;
2486 case IWL_MVM_PM_EVENT_PS_POLL:
2487 ieee80211_sta_pspoll(sta);
2488 break;
2489 default:
2490 break;
2491 }
2492 }
2493
2494 rcu_read_unlock();
2495}
2496
2497static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
2498 struct ieee80211_vif *vif,
2499 struct ieee80211_sta *sta)
2500{
2501 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2502 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512 mutex_lock(&mvm->mutex);
2513 if (sta == rcu_access_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id]))
2514 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
2515 ERR_PTR(-ENOENT));
2516
2517 mutex_unlock(&mvm->mutex);
2518}
2519
2520static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2521 const u8 *bssid)
2522{
2523 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT))
2524 return;
2525
2526 if (vif->p2p && !iwl_mvm_is_p2p_scm_uapsd_supported(mvm)) {
2527 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
2528 return;
2529 }
2530
2531 if (!vif->p2p &&
2532 (iwlwifi_mod_params.uapsd_disable & IWL_DISABLE_UAPSD_BSS)) {
2533 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
2534 return;
2535 }
2536
2537 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
2538}
2539
2540static void
2541iwl_mvm_tdls_check_trigger(struct iwl_mvm *mvm,
2542 struct ieee80211_vif *vif, u8 *peer_addr,
2543 enum nl80211_tdls_operation action)
2544{
2545 struct iwl_fw_dbg_trigger_tlv *trig;
2546 struct iwl_fw_dbg_trigger_tdls *tdls_trig;
2547
2548 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TDLS))
2549 return;
2550
2551 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TDLS);
2552 tdls_trig = (void *)trig->data;
2553 if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
2554 ieee80211_vif_to_wdev(vif), trig))
2555 return;
2556
2557 if (!(tdls_trig->action_bitmap & BIT(action)))
2558 return;
2559
2560 if (tdls_trig->peer_mode &&
2561 memcmp(tdls_trig->peer, peer_addr, ETH_ALEN) != 0)
2562 return;
2563
2564 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
2565 "TDLS event occurred, peer %pM, action %d",
2566 peer_addr, action);
2567}
2568
2569static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm,
2570 struct iwl_mvm_sta *mvm_sta)
2571{
2572 struct iwl_mvm_tid_data *tid_data;
2573 struct sk_buff *skb;
2574 int i;
2575
2576 spin_lock_bh(&mvm_sta->lock);
2577 for (i = 0; i <= IWL_MAX_TID_COUNT; i++) {
2578 tid_data = &mvm_sta->tid_data[i];
2579
2580 while ((skb = __skb_dequeue(&tid_data->deferred_tx_frames))) {
2581 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2582
2583
2584
2585
2586
2587
2588 iwl_mvm_start_mac_queues(mvm, BIT(info->hw_queue));
2589 ieee80211_free_txskb(mvm->hw, skb);
2590 }
2591 }
2592 spin_unlock_bh(&mvm_sta->lock);
2593}
2594
2595static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2596 struct ieee80211_vif *vif,
2597 struct ieee80211_sta *sta,
2598 enum ieee80211_sta_state old_state,
2599 enum ieee80211_sta_state new_state)
2600{
2601 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2602 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2603 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
2604 int ret;
2605
2606 IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
2607 sta->addr, old_state, new_state);
2608
2609
2610 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
2611 return -EINVAL;
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626 if (old_state == IEEE80211_STA_NONE &&
2627 new_state == IEEE80211_STA_NOTEXIST) {
2628 iwl_mvm_purge_deferred_tx_frames(mvm, mvm_sta);
2629 flush_work(&mvm->add_stream_wk);
2630
2631
2632
2633
2634
2635 }
2636
2637 mutex_lock(&mvm->mutex);
2638
2639 mvm_sta->associated = new_state >= IEEE80211_STA_ASSOC;
2640
2641 if (old_state == IEEE80211_STA_NOTEXIST &&
2642 new_state == IEEE80211_STA_NONE) {
2643
2644
2645
2646
2647
2648
2649
2650 if (vif->type == NL80211_IFTYPE_STATION &&
2651 vif->bss_conf.beacon_int < 16) {
2652 IWL_ERR(mvm,
2653 "AP %pM beacon interval is %d, refusing due to firmware bug!\n",
2654 sta->addr, vif->bss_conf.beacon_int);
2655 ret = -EINVAL;
2656 goto out_unlock;
2657 }
2658
2659 if (sta->tdls &&
2660 (vif->p2p ||
2661 iwl_mvm_tdls_sta_count(mvm, NULL) ==
2662 IWL_MVM_TDLS_STA_COUNT ||
2663 iwl_mvm_phy_ctx_count(mvm) > 1)) {
2664 IWL_DEBUG_MAC80211(mvm, "refusing TDLS sta\n");
2665 ret = -EBUSY;
2666 goto out_unlock;
2667 }
2668
2669 ret = iwl_mvm_add_sta(mvm, vif, sta);
2670 if (sta->tdls && ret == 0) {
2671 iwl_mvm_recalc_tdls_state(mvm, vif, true);
2672 iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
2673 NL80211_TDLS_SETUP);
2674 }
2675 } else if (old_state == IEEE80211_STA_NONE &&
2676 new_state == IEEE80211_STA_AUTH) {
2677
2678
2679
2680
2681 mvm->last_ebs_successful = true;
2682 iwl_mvm_check_uapsd(mvm, vif, sta->addr);
2683 ret = 0;
2684 } else if (old_state == IEEE80211_STA_AUTH &&
2685 new_state == IEEE80211_STA_ASSOC) {
2686 if (vif->type == NL80211_IFTYPE_AP) {
2687 mvmvif->ap_assoc_sta_count++;
2688 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2689 }
2690
2691 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
2692 true);
2693 ret = iwl_mvm_update_sta(mvm, vif, sta);
2694 } else if (old_state == IEEE80211_STA_ASSOC &&
2695 new_state == IEEE80211_STA_AUTHORIZED) {
2696
2697
2698 if (iwl_mvm_phy_ctx_count(mvm) > 1)
2699 iwl_mvm_teardown_tdls_peers(mvm);
2700
2701 if (sta->tdls)
2702 iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
2703 NL80211_TDLS_ENABLE_LINK);
2704
2705
2706 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
2707 ret = 0;
2708 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
2709 new_state == IEEE80211_STA_ASSOC) {
2710
2711 WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif, 0));
2712 ret = 0;
2713 } else if (old_state == IEEE80211_STA_ASSOC &&
2714 new_state == IEEE80211_STA_AUTH) {
2715 if (vif->type == NL80211_IFTYPE_AP) {
2716 mvmvif->ap_assoc_sta_count--;
2717 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2718 }
2719 ret = 0;
2720 } else if (old_state == IEEE80211_STA_AUTH &&
2721 new_state == IEEE80211_STA_NONE) {
2722 ret = 0;
2723 } else if (old_state == IEEE80211_STA_NONE &&
2724 new_state == IEEE80211_STA_NOTEXIST) {
2725 ret = iwl_mvm_rm_sta(mvm, vif, sta);
2726 if (sta->tdls) {
2727 iwl_mvm_recalc_tdls_state(mvm, vif, false);
2728 iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
2729 NL80211_TDLS_DISABLE_LINK);
2730 }
2731 } else {
2732 ret = -EIO;
2733 }
2734 out_unlock:
2735 mutex_unlock(&mvm->mutex);
2736
2737 if (sta->tdls && ret == 0) {
2738 if (old_state == IEEE80211_STA_NOTEXIST &&
2739 new_state == IEEE80211_STA_NONE)
2740 ieee80211_reserve_tid(sta, IWL_MVM_TDLS_FW_TID);
2741 else if (old_state == IEEE80211_STA_NONE &&
2742 new_state == IEEE80211_STA_NOTEXIST)
2743 ieee80211_unreserve_tid(sta, IWL_MVM_TDLS_FW_TID);
2744 }
2745
2746 return ret;
2747}
2748
2749static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
2750{
2751 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2752
2753 mvm->rts_threshold = value;
2754
2755 return 0;
2756}
2757
2758static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw,
2759 struct ieee80211_vif *vif,
2760 struct ieee80211_sta *sta, u32 changed)
2761{
2762 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2763
2764 if (vif->type == NL80211_IFTYPE_STATION &&
2765 changed & IEEE80211_RC_NSS_CHANGED)
2766 iwl_mvm_sf_update(mvm, vif, false);
2767}
2768
2769static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
2770 struct ieee80211_vif *vif, u16 ac,
2771 const struct ieee80211_tx_queue_params *params)
2772{
2773 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2774 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2775
2776 mvmvif->queue_params[ac] = *params;
2777
2778
2779
2780
2781
2782 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
2783 int ret;
2784
2785 mutex_lock(&mvm->mutex);
2786 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2787 mutex_unlock(&mvm->mutex);
2788 return ret;
2789 }
2790 return 0;
2791}
2792
2793static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
2794 struct ieee80211_vif *vif)
2795{
2796 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2797 u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
2798 u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
2799
2800 if (WARN_ON_ONCE(vif->bss_conf.assoc))
2801 return;
2802
2803
2804
2805
2806
2807 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX))
2808 return;
2809
2810 mutex_lock(&mvm->mutex);
2811
2812 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
2813 mutex_unlock(&mvm->mutex);
2814
2815 iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
2816}
2817
2818static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2819 struct ieee80211_vif *vif,
2820 struct cfg80211_sched_scan_request *req,
2821 struct ieee80211_scan_ies *ies)
2822{
2823 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2824
2825 int ret;
2826
2827 mutex_lock(&mvm->mutex);
2828
2829 if (!vif->bss_conf.idle) {
2830 ret = -EBUSY;
2831 goto out;
2832 }
2833
2834 ret = iwl_mvm_sched_scan_start(mvm, vif, req, ies, IWL_MVM_SCAN_SCHED);
2835
2836out:
2837 mutex_unlock(&mvm->mutex);
2838 return ret;
2839}
2840
2841static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
2842 struct ieee80211_vif *vif)
2843{
2844 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2845 int ret;
2846
2847 mutex_lock(&mvm->mutex);
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857 if (!(mvm->scan_status & IWL_MVM_SCAN_SCHED)) {
2858 mutex_unlock(&mvm->mutex);
2859 return 0;
2860 }
2861
2862 ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, false);
2863 mutex_unlock(&mvm->mutex);
2864 iwl_mvm_wait_for_async_handlers(mvm);
2865
2866 return ret;
2867}
2868
2869static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
2870 enum set_key_cmd cmd,
2871 struct ieee80211_vif *vif,
2872 struct ieee80211_sta *sta,
2873 struct ieee80211_key_conf *key)
2874{
2875 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2876 struct iwl_mvm_sta *mvmsta;
2877 struct iwl_mvm_key_pn *ptk_pn;
2878 int keyidx = key->keyidx;
2879 int ret;
2880 u8 key_offset;
2881
2882 if (iwlwifi_mod_params.swcrypto) {
2883 IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
2884 return -EOPNOTSUPP;
2885 }
2886
2887 switch (key->cipher) {
2888 case WLAN_CIPHER_SUITE_TKIP:
2889 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2890 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
2891 break;
2892 case WLAN_CIPHER_SUITE_CCMP:
2893 case WLAN_CIPHER_SUITE_GCMP:
2894 case WLAN_CIPHER_SUITE_GCMP_256:
2895 if (!iwl_mvm_has_new_tx_api(mvm))
2896 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
2897 break;
2898 case WLAN_CIPHER_SUITE_AES_CMAC:
2899 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
2900 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
2901 WARN_ON_ONCE(!ieee80211_hw_check(hw, MFP_CAPABLE));
2902 break;
2903 case WLAN_CIPHER_SUITE_WEP40:
2904 case WLAN_CIPHER_SUITE_WEP104:
2905
2906
2907
2908
2909
2910
2911
2912 if (vif->type != NL80211_IFTYPE_STATION)
2913 return 0;
2914 break;
2915 default:
2916
2917 if (hw->n_cipher_schemes &&
2918 hw->cipher_schemes->cipher == key->cipher)
2919 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
2920 else
2921 return -EOPNOTSUPP;
2922 }
2923
2924 mutex_lock(&mvm->mutex);
2925
2926 switch (cmd) {
2927 case SET_KEY:
2928 if ((vif->type == NL80211_IFTYPE_ADHOC ||
2929 vif->type == NL80211_IFTYPE_AP) && !sta) {
2930
2931
2932
2933
2934
2935
2936 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
2937 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
2938 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
2939 ret = -EOPNOTSUPP;
2940 else
2941 ret = 0;
2942
2943 if (key->cipher != WLAN_CIPHER_SUITE_GCMP &&
2944 key->cipher != WLAN_CIPHER_SUITE_GCMP_256 &&
2945 !iwl_mvm_has_new_tx_api(mvm)) {
2946 key->hw_key_idx = STA_KEY_IDX_INVALID;
2947 break;
2948 }
2949 }
2950
2951
2952
2953
2954 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
2955 key->hw_key_idx == STA_KEY_IDX_INVALID) {
2956 IWL_DEBUG_MAC80211(mvm,
2957 "skip invalid idx key programming during restart\n");
2958 ret = 0;
2959 break;
2960 }
2961
2962 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
2963 sta && iwl_mvm_has_new_rx_api(mvm) &&
2964 key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
2965 (key->cipher == WLAN_CIPHER_SUITE_CCMP ||
2966 key->cipher == WLAN_CIPHER_SUITE_GCMP ||
2967 key->cipher == WLAN_CIPHER_SUITE_GCMP_256)) {
2968 struct ieee80211_key_seq seq;
2969 int tid, q;
2970
2971 mvmsta = iwl_mvm_sta_from_mac80211(sta);
2972 WARN_ON(rcu_access_pointer(mvmsta->ptk_pn[keyidx]));
2973 ptk_pn = kzalloc(sizeof(*ptk_pn) +
2974 mvm->trans->num_rx_queues *
2975 sizeof(ptk_pn->q[0]),
2976 GFP_KERNEL);
2977 if (!ptk_pn) {
2978 ret = -ENOMEM;
2979 break;
2980 }
2981
2982 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
2983 ieee80211_get_key_rx_seq(key, tid, &seq);
2984 for (q = 0; q < mvm->trans->num_rx_queues; q++)
2985 memcpy(ptk_pn->q[q].pn[tid],
2986 seq.ccmp.pn,
2987 IEEE80211_CCMP_PN_LEN);
2988 }
2989
2990 rcu_assign_pointer(mvmsta->ptk_pn[keyidx], ptk_pn);
2991 }
2992
2993
2994 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
2995 key_offset = key->hw_key_idx;
2996 else
2997 key_offset = STA_KEY_IDX_INVALID;
2998
2999 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
3000 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, key_offset);
3001 if (ret) {
3002 IWL_WARN(mvm, "set key failed\n");
3003
3004
3005
3006
3007 key->hw_key_idx = STA_KEY_IDX_INVALID;
3008 ret = 0;
3009 }
3010
3011 break;
3012 case DISABLE_KEY:
3013 if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
3014 ret = 0;
3015 break;
3016 }
3017
3018 if (sta && iwl_mvm_has_new_rx_api(mvm) &&
3019 key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
3020 (key->cipher == WLAN_CIPHER_SUITE_CCMP ||
3021 key->cipher == WLAN_CIPHER_SUITE_GCMP ||
3022 key->cipher == WLAN_CIPHER_SUITE_GCMP_256)) {
3023 mvmsta = iwl_mvm_sta_from_mac80211(sta);
3024 ptk_pn = rcu_dereference_protected(
3025 mvmsta->ptk_pn[keyidx],
3026 lockdep_is_held(&mvm->mutex));
3027 RCU_INIT_POINTER(mvmsta->ptk_pn[keyidx], NULL);
3028 if (ptk_pn)
3029 kfree_rcu(ptk_pn, rcu_head);
3030 }
3031
3032 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
3033 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
3034 break;
3035 default:
3036 ret = -EINVAL;
3037 }
3038
3039 mutex_unlock(&mvm->mutex);
3040 return ret;
3041}
3042
3043static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
3044 struct ieee80211_vif *vif,
3045 struct ieee80211_key_conf *keyconf,
3046 struct ieee80211_sta *sta,
3047 u32 iv32, u16 *phase1key)
3048{
3049 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3050
3051 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
3052 return;
3053
3054 iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
3055}
3056
3057
3058static bool iwl_mvm_rx_aux_roc(struct iwl_notif_wait_data *notif_wait,
3059 struct iwl_rx_packet *pkt, void *data)
3060{
3061 struct iwl_mvm *mvm =
3062 container_of(notif_wait, struct iwl_mvm, notif_wait);
3063 struct iwl_hs20_roc_res *resp;
3064 int resp_len = iwl_rx_packet_payload_len(pkt);
3065 struct iwl_mvm_time_event_data *te_data = data;
3066
3067 if (WARN_ON(pkt->hdr.cmd != HOT_SPOT_CMD))
3068 return true;
3069
3070 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
3071 IWL_ERR(mvm, "Invalid HOT_SPOT_CMD response\n");
3072 return true;
3073 }
3074
3075 resp = (void *)pkt->data;
3076
3077 IWL_DEBUG_TE(mvm,
3078 "Aux ROC: Recieved response from ucode: status=%d uid=%d\n",
3079 resp->status, resp->event_unique_id);
3080
3081 te_data->uid = le32_to_cpu(resp->event_unique_id);
3082 IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
3083 te_data->uid);
3084
3085 spin_lock_bh(&mvm->time_event_lock);
3086 list_add_tail(&te_data->list, &mvm->aux_roc_te_list);
3087 spin_unlock_bh(&mvm->time_event_lock);
3088
3089 return true;
3090}
3091
3092#define AUX_ROC_MIN_DURATION MSEC_TO_TU(100)
3093#define AUX_ROC_MIN_DELAY MSEC_TO_TU(200)
3094#define AUX_ROC_MAX_DELAY MSEC_TO_TU(600)
3095#define AUX_ROC_SAFETY_BUFFER MSEC_TO_TU(20)
3096#define AUX_ROC_MIN_SAFETY_BUFFER MSEC_TO_TU(10)
3097static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm,
3098 struct ieee80211_channel *channel,
3099 struct ieee80211_vif *vif,
3100 int duration)
3101{
3102 int res, time_reg = DEVICE_SYSTEM_TIME_REG;
3103 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3104 struct iwl_mvm_time_event_data *te_data = &mvmvif->hs_time_event_data;
3105 static const u16 time_event_response[] = { HOT_SPOT_CMD };
3106 struct iwl_notification_wait wait_time_event;
3107 u32 dtim_interval = vif->bss_conf.dtim_period *
3108 vif->bss_conf.beacon_int;
3109 u32 req_dur, delay;
3110 struct iwl_hs20_roc_req aux_roc_req = {
3111 .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
3112 .id_and_color =
3113 cpu_to_le32(FW_CMD_ID_AND_COLOR(MAC_INDEX_AUX, 0)),
3114 .sta_id_and_color = cpu_to_le32(mvm->aux_sta.sta_id),
3115
3116 .channel_info.band = (channel->band == NL80211_BAND_2GHZ) ?
3117 PHY_BAND_24 : PHY_BAND_5,
3118 .channel_info.channel = channel->hw_value,
3119 .channel_info.width = PHY_VHT_CHANNEL_MODE20,
3120
3121 .apply_time = cpu_to_le32(iwl_read_prph(mvm->trans, time_reg)),
3122 };
3123
3124 delay = AUX_ROC_MIN_DELAY;
3125 req_dur = MSEC_TO_TU(duration);
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136 if (vif->bss_conf.assoc) {
3137 delay = min_t(u32, dtim_interval * 3, AUX_ROC_MAX_DELAY);
3138
3139 if (dtim_interval <= req_dur) {
3140 req_dur = dtim_interval - AUX_ROC_SAFETY_BUFFER;
3141 if (req_dur <= AUX_ROC_MIN_DURATION)
3142 req_dur = dtim_interval -
3143 AUX_ROC_MIN_SAFETY_BUFFER;
3144 }
3145 }
3146
3147 aux_roc_req.duration = cpu_to_le32(req_dur);
3148 aux_roc_req.apply_time_max_delay = cpu_to_le32(delay);
3149
3150 IWL_DEBUG_TE(mvm,
3151 "ROC: Requesting to remain on channel %u for %ums (requested = %ums, max_delay = %ums, dtim_interval = %ums)\n",
3152 channel->hw_value, req_dur, duration, delay,
3153 dtim_interval);
3154
3155 memcpy(aux_roc_req.node_addr, vif->addr, ETH_ALEN);
3156
3157 lockdep_assert_held(&mvm->mutex);
3158
3159 spin_lock_bh(&mvm->time_event_lock);
3160
3161 if (WARN_ON(te_data->id == HOT_SPOT_CMD)) {
3162 spin_unlock_bh(&mvm->time_event_lock);
3163 return -EIO;
3164 }
3165
3166 te_data->vif = vif;
3167 te_data->duration = duration;
3168 te_data->id = HOT_SPOT_CMD;
3169
3170 spin_unlock_bh(&mvm->time_event_lock);
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
3182 time_event_response,
3183 ARRAY_SIZE(time_event_response),
3184 iwl_mvm_rx_aux_roc, te_data);
3185
3186 res = iwl_mvm_send_cmd_pdu(mvm, HOT_SPOT_CMD, 0, sizeof(aux_roc_req),
3187 &aux_roc_req);
3188
3189 if (res) {
3190 IWL_ERR(mvm, "Couldn't send HOT_SPOT_CMD: %d\n", res);
3191 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
3192 goto out_clear_te;
3193 }
3194
3195
3196 res = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1);
3197
3198 WARN_ON_ONCE(res);
3199
3200 if (res) {
3201 out_clear_te:
3202 spin_lock_bh(&mvm->time_event_lock);
3203 iwl_mvm_te_clear_data(mvm, te_data);
3204 spin_unlock_bh(&mvm->time_event_lock);
3205 }
3206
3207 return res;
3208}
3209
3210static int iwl_mvm_roc(struct ieee80211_hw *hw,
3211 struct ieee80211_vif *vif,
3212 struct ieee80211_channel *channel,
3213 int duration,
3214 enum ieee80211_roc_type type)
3215{
3216 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3217 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3218 struct cfg80211_chan_def chandef;
3219 struct iwl_mvm_phy_ctxt *phy_ctxt;
3220 int ret, i;
3221
3222 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
3223 duration, type);
3224
3225 flush_work(&mvm->roc_done_wk);
3226
3227 mutex_lock(&mvm->mutex);
3228
3229 switch (vif->type) {
3230 case NL80211_IFTYPE_STATION:
3231 if (fw_has_capa(&mvm->fw->ucode_capa,
3232 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT)) {
3233
3234 ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
3235 vif, duration);
3236 goto out_unlock;
3237 }
3238 IWL_ERR(mvm, "hotspot not supported\n");
3239 ret = -EINVAL;
3240 goto out_unlock;
3241 case NL80211_IFTYPE_P2P_DEVICE:
3242
3243 break;
3244 default:
3245 IWL_ERR(mvm, "vif isn't P2P_DEVICE: %d\n", vif->type);
3246 ret = -EINVAL;
3247 goto out_unlock;
3248 }
3249
3250 for (i = 0; i < NUM_PHY_CTX; i++) {
3251 phy_ctxt = &mvm->phy_ctxts[i];
3252 if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
3253 continue;
3254
3255 if (phy_ctxt->ref && channel == phy_ctxt->channel) {
3256
3257
3258
3259
3260 ret = iwl_mvm_binding_remove_vif(mvm, vif);
3261 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
3262 goto out_unlock;
3263
3264 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
3265
3266
3267 mvmvif->phy_ctxt = phy_ctxt;
3268
3269 ret = iwl_mvm_binding_add_vif(mvm, vif);
3270 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
3271 goto out_unlock;
3272
3273 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
3274 goto schedule_time_event;
3275 }
3276 }
3277
3278
3279 if (channel == mvmvif->phy_ctxt->channel)
3280 goto schedule_time_event;
3281
3282 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
3283
3284
3285
3286
3287
3288 if (mvmvif->phy_ctxt->ref == 1) {
3289 ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
3290 &chandef, 1, 1);
3291 if (ret)
3292 goto out_unlock;
3293 } else {
3294
3295
3296
3297
3298
3299 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
3300 if (!phy_ctxt) {
3301 ret = -ENOSPC;
3302 goto out_unlock;
3303 }
3304
3305 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
3306 1, 1);
3307 if (ret) {
3308 IWL_ERR(mvm, "Failed to change PHY context\n");
3309 goto out_unlock;
3310 }
3311
3312
3313 ret = iwl_mvm_binding_remove_vif(mvm, vif);
3314 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
3315 goto out_unlock;
3316
3317 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
3318
3319
3320 mvmvif->phy_ctxt = phy_ctxt;
3321
3322 ret = iwl_mvm_binding_add_vif(mvm, vif);
3323 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
3324 goto out_unlock;
3325
3326 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
3327 }
3328
3329schedule_time_event:
3330
3331 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
3332
3333out_unlock:
3334 mutex_unlock(&mvm->mutex);
3335 IWL_DEBUG_MAC80211(mvm, "leave\n");
3336 return ret;
3337}
3338
3339static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
3340{
3341 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3342
3343 IWL_DEBUG_MAC80211(mvm, "enter\n");
3344
3345 mutex_lock(&mvm->mutex);
3346 iwl_mvm_stop_roc(mvm);
3347 mutex_unlock(&mvm->mutex);
3348
3349 IWL_DEBUG_MAC80211(mvm, "leave\n");
3350 return 0;
3351}
3352
3353static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
3354 struct ieee80211_chanctx_conf *ctx)
3355{
3356 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
3357 struct iwl_mvm_phy_ctxt *phy_ctxt;
3358 int ret;
3359
3360 lockdep_assert_held(&mvm->mutex);
3361
3362 IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
3363
3364 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
3365 if (!phy_ctxt) {
3366 ret = -ENOSPC;
3367 goto out;
3368 }
3369
3370 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
3371 ctx->rx_chains_static,
3372 ctx->rx_chains_dynamic);
3373 if (ret) {
3374 IWL_ERR(mvm, "Failed to add PHY context\n");
3375 goto out;
3376 }
3377
3378 iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
3379 *phy_ctxt_id = phy_ctxt->id;
3380out:
3381 return ret;
3382}
3383
3384static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
3385 struct ieee80211_chanctx_conf *ctx)
3386{
3387 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3388 int ret;
3389
3390 mutex_lock(&mvm->mutex);
3391 ret = __iwl_mvm_add_chanctx(mvm, ctx);
3392 mutex_unlock(&mvm->mutex);
3393
3394 return ret;
3395}
3396
3397static void __iwl_mvm_remove_chanctx(struct iwl_mvm *mvm,
3398 struct ieee80211_chanctx_conf *ctx)
3399{
3400 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
3401 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
3402
3403 lockdep_assert_held(&mvm->mutex);
3404
3405 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
3406}
3407
3408static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
3409 struct ieee80211_chanctx_conf *ctx)
3410{
3411 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3412
3413 mutex_lock(&mvm->mutex);
3414 __iwl_mvm_remove_chanctx(mvm, ctx);
3415 mutex_unlock(&mvm->mutex);
3416}
3417
3418static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
3419 struct ieee80211_chanctx_conf *ctx,
3420 u32 changed)
3421{
3422 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3423 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
3424 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
3425
3426 if (WARN_ONCE((phy_ctxt->ref > 1) &&
3427 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
3428 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
3429 IEEE80211_CHANCTX_CHANGE_RADAR |
3430 IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
3431 "Cannot change PHY. Ref=%d, changed=0x%X\n",
3432 phy_ctxt->ref, changed))
3433 return;
3434
3435 mutex_lock(&mvm->mutex);
3436 iwl_mvm_bt_coex_vif_change(mvm);
3437 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
3438 ctx->rx_chains_static,
3439 ctx->rx_chains_dynamic);
3440 mutex_unlock(&mvm->mutex);
3441}
3442
3443static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3444 struct ieee80211_vif *vif,
3445 struct ieee80211_chanctx_conf *ctx,
3446 bool switching_chanctx)
3447{
3448 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
3449 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
3450 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3451 int ret;
3452
3453 lockdep_assert_held(&mvm->mutex);
3454
3455 mvmvif->phy_ctxt = phy_ctxt;
3456
3457 switch (vif->type) {
3458 case NL80211_IFTYPE_AP:
3459
3460 if (switching_chanctx) {
3461 mvmvif->ap_ibss_active = true;
3462 break;
3463 }
3464 case NL80211_IFTYPE_ADHOC:
3465
3466
3467
3468
3469 ret = 0;
3470 goto out;
3471 case NL80211_IFTYPE_STATION:
3472 break;
3473 case NL80211_IFTYPE_MONITOR:
3474
3475 mvmvif->ps_disabled = true;
3476 break;
3477 default:
3478 ret = -EINVAL;
3479 goto out;
3480 }
3481
3482 ret = iwl_mvm_binding_add_vif(mvm, vif);
3483 if (ret)
3484 goto out;
3485
3486
3487
3488
3489
3490 iwl_mvm_power_update_mac(mvm);
3491
3492
3493
3494
3495
3496 if (vif->type == NL80211_IFTYPE_MONITOR) {
3497 mvmvif->monitor_active = true;
3498 ret = iwl_mvm_update_quotas(mvm, false, NULL);
3499 if (ret)
3500 goto out_remove_binding;
3501
3502 ret = iwl_mvm_add_snif_sta(mvm, vif);
3503 if (ret)
3504 goto out_remove_binding;
3505
3506 }
3507
3508
3509 if (vif->type == NL80211_IFTYPE_AP) {
3510 iwl_mvm_update_quotas(mvm, false, NULL);
3511 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
3512 }
3513
3514 if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
3515 u32 duration = 2 * vif->bss_conf.beacon_int;
3516
3517
3518
3519
3520
3521 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA);
3522 if (ret)
3523 goto out_remove_binding;
3524
3525
3526
3527
3528 iwl_mvm_protect_session(mvm, vif, duration, duration,
3529 vif->bss_conf.beacon_int / 2,
3530 true);
3531
3532 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA);
3533
3534 iwl_mvm_update_quotas(mvm, false, NULL);
3535 }
3536
3537 goto out;
3538
3539out_remove_binding:
3540 iwl_mvm_binding_remove_vif(mvm, vif);
3541 iwl_mvm_power_update_mac(mvm);
3542out:
3543 if (ret)
3544 mvmvif->phy_ctxt = NULL;
3545 return ret;
3546}
3547static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
3548 struct ieee80211_vif *vif,
3549 struct ieee80211_chanctx_conf *ctx)
3550{
3551 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3552 int ret;
3553
3554 mutex_lock(&mvm->mutex);
3555 ret = __iwl_mvm_assign_vif_chanctx(mvm, vif, ctx, false);
3556 mutex_unlock(&mvm->mutex);
3557
3558 return ret;
3559}
3560
3561static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
3562 struct ieee80211_vif *vif,
3563 struct ieee80211_chanctx_conf *ctx,
3564 bool switching_chanctx)
3565{
3566 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3567 struct ieee80211_vif *disabled_vif = NULL;
3568
3569 lockdep_assert_held(&mvm->mutex);
3570
3571 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
3572
3573 switch (vif->type) {
3574 case NL80211_IFTYPE_ADHOC:
3575 goto out;
3576 case NL80211_IFTYPE_MONITOR:
3577 mvmvif->monitor_active = false;
3578 mvmvif->ps_disabled = false;
3579 iwl_mvm_rm_snif_sta(mvm, vif);
3580 break;
3581 case NL80211_IFTYPE_AP:
3582
3583 if (!switching_chanctx || !mvmvif->ap_ibss_active)
3584 goto out;
3585
3586 mvmvif->csa_countdown = false;
3587
3588
3589 iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true);
3590
3591
3592 rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif);
3593
3594 mvmvif->ap_ibss_active = false;
3595 break;
3596 case NL80211_IFTYPE_STATION:
3597 if (!switching_chanctx)
3598 break;
3599
3600 disabled_vif = vif;
3601
3602 iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
3603 break;
3604 default:
3605 break;
3606 }
3607
3608 iwl_mvm_update_quotas(mvm, false, disabled_vif);
3609 iwl_mvm_binding_remove_vif(mvm, vif);
3610
3611out:
3612 mvmvif->phy_ctxt = NULL;
3613 iwl_mvm_power_update_mac(mvm);
3614}
3615
3616static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
3617 struct ieee80211_vif *vif,
3618 struct ieee80211_chanctx_conf *ctx)
3619{
3620 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3621
3622 mutex_lock(&mvm->mutex);
3623 __iwl_mvm_unassign_vif_chanctx(mvm, vif, ctx, false);
3624 mutex_unlock(&mvm->mutex);
3625}
3626
3627static int
3628iwl_mvm_switch_vif_chanctx_swap(struct iwl_mvm *mvm,
3629 struct ieee80211_vif_chanctx_switch *vifs)
3630{
3631 int ret;
3632
3633 mutex_lock(&mvm->mutex);
3634 __iwl_mvm_unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, true);
3635 __iwl_mvm_remove_chanctx(mvm, vifs[0].old_ctx);
3636
3637 ret = __iwl_mvm_add_chanctx(mvm, vifs[0].new_ctx);
3638 if (ret) {
3639 IWL_ERR(mvm, "failed to add new_ctx during channel switch\n");
3640 goto out_reassign;
3641 }
3642
3643 ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].new_ctx,
3644 true);
3645 if (ret) {
3646 IWL_ERR(mvm,
3647 "failed to assign new_ctx during channel switch\n");
3648 goto out_remove;
3649 }
3650
3651
3652 if (iwl_mvm_phy_ctx_count(mvm) > 1)
3653 iwl_mvm_teardown_tdls_peers(mvm);
3654
3655 goto out;
3656
3657out_remove:
3658 __iwl_mvm_remove_chanctx(mvm, vifs[0].new_ctx);
3659
3660out_reassign:
3661 if (__iwl_mvm_add_chanctx(mvm, vifs[0].old_ctx)) {
3662 IWL_ERR(mvm, "failed to add old_ctx back after failure.\n");
3663 goto out_restart;
3664 }
3665
3666 if (__iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx,
3667 true)) {
3668 IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n");
3669 goto out_restart;
3670 }
3671
3672 goto out;
3673
3674out_restart:
3675
3676 iwl_mvm_nic_restart(mvm, false);
3677
3678out:
3679 mutex_unlock(&mvm->mutex);
3680
3681 return ret;
3682}
3683
3684static int
3685iwl_mvm_switch_vif_chanctx_reassign(struct iwl_mvm *mvm,
3686 struct ieee80211_vif_chanctx_switch *vifs)
3687{
3688 int ret;
3689
3690 mutex_lock(&mvm->mutex);
3691 __iwl_mvm_unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, true);
3692
3693 ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].new_ctx,
3694 true);
3695 if (ret) {
3696 IWL_ERR(mvm,
3697 "failed to assign new_ctx during channel switch\n");
3698 goto out_reassign;
3699 }
3700
3701 goto out;
3702
3703out_reassign:
3704 if (__iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx,
3705 true)) {
3706 IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n");
3707 goto out_restart;
3708 }
3709
3710 goto out;
3711
3712out_restart:
3713
3714 iwl_mvm_nic_restart(mvm, false);
3715
3716out:
3717 mutex_unlock(&mvm->mutex);
3718
3719 return ret;
3720}
3721
3722static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw,
3723 struct ieee80211_vif_chanctx_switch *vifs,
3724 int n_vifs,
3725 enum ieee80211_chanctx_switch_mode mode)
3726{
3727 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3728 int ret;
3729
3730
3731 if (n_vifs > 1)
3732 return -EOPNOTSUPP;
3733
3734 switch (mode) {
3735 case CHANCTX_SWMODE_SWAP_CONTEXTS:
3736 ret = iwl_mvm_switch_vif_chanctx_swap(mvm, vifs);
3737 break;
3738 case CHANCTX_SWMODE_REASSIGN_VIF:
3739 ret = iwl_mvm_switch_vif_chanctx_reassign(mvm, vifs);
3740 break;
3741 default:
3742 ret = -EOPNOTSUPP;
3743 break;
3744 }
3745
3746 return ret;
3747}
3748
3749static int iwl_mvm_tx_last_beacon(struct ieee80211_hw *hw)
3750{
3751 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3752
3753 return mvm->ibss_manager;
3754}
3755
3756static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
3757 struct ieee80211_sta *sta,
3758 bool set)
3759{
3760 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3761 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
3762
3763 if (!mvm_sta || !mvm_sta->vif) {
3764 IWL_ERR(mvm, "Station is not associated to a vif\n");
3765 return -EINVAL;
3766 }
3767
3768 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
3769}
3770
3771#ifdef CONFIG_NL80211_TESTMODE
3772static const struct nla_policy iwl_mvm_tm_policy[IWL_MVM_TM_ATTR_MAX + 1] = {
3773 [IWL_MVM_TM_ATTR_CMD] = { .type = NLA_U32 },
3774 [IWL_MVM_TM_ATTR_NOA_DURATION] = { .type = NLA_U32 },
3775 [IWL_MVM_TM_ATTR_BEACON_FILTER_STATE] = { .type = NLA_U32 },
3776};
3777
3778static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
3779 struct ieee80211_vif *vif,
3780 void *data, int len)
3781{
3782 struct nlattr *tb[IWL_MVM_TM_ATTR_MAX + 1];
3783 int err;
3784 u32 noa_duration;
3785
3786 err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy,
3787 NULL);
3788 if (err)
3789 return err;
3790
3791 if (!tb[IWL_MVM_TM_ATTR_CMD])
3792 return -EINVAL;
3793
3794 switch (nla_get_u32(tb[IWL_MVM_TM_ATTR_CMD])) {
3795 case IWL_MVM_TM_CMD_SET_NOA:
3796 if (!vif || vif->type != NL80211_IFTYPE_AP || !vif->p2p ||
3797 !vif->bss_conf.enable_beacon ||
3798 !tb[IWL_MVM_TM_ATTR_NOA_DURATION])
3799 return -EINVAL;
3800
3801 noa_duration = nla_get_u32(tb[IWL_MVM_TM_ATTR_NOA_DURATION]);
3802 if (noa_duration >= vif->bss_conf.beacon_int)
3803 return -EINVAL;
3804
3805 mvm->noa_duration = noa_duration;
3806 mvm->noa_vif = vif;
3807
3808 return iwl_mvm_update_quotas(mvm, false, NULL);
3809 case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
3810
3811 if (!vif || vif->type != NL80211_IFTYPE_STATION ||
3812 !vif->bss_conf.assoc || !vif->bss_conf.dtim_period ||
3813 !tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE])
3814 return -EINVAL;
3815
3816 if (nla_get_u32(tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE]))
3817 return iwl_mvm_enable_beacon_filter(mvm, vif, 0);
3818 return iwl_mvm_disable_beacon_filter(mvm, vif, 0);
3819 }
3820
3821 return -EOPNOTSUPP;
3822}
3823
3824static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
3825 struct ieee80211_vif *vif,
3826 void *data, int len)
3827{
3828 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3829 int err;
3830
3831 mutex_lock(&mvm->mutex);
3832 err = __iwl_mvm_mac_testmode_cmd(mvm, vif, data, len);
3833 mutex_unlock(&mvm->mutex);
3834
3835 return err;
3836}
3837#endif
3838
3839static void iwl_mvm_channel_switch(struct ieee80211_hw *hw,
3840 struct ieee80211_vif *vif,
3841 struct ieee80211_channel_switch *chsw)
3842{
3843
3844
3845
3846
3847
3848
3849 IWL_DEBUG_MAC80211(IWL_MAC80211_GET_MVM(hw),
3850 "dummy channel switch op\n");
3851}
3852
3853static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
3854 struct ieee80211_vif *vif,
3855 struct ieee80211_channel_switch *chsw)
3856{
3857 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3858 struct ieee80211_vif *csa_vif;
3859 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3860 u32 apply_time;
3861 int ret;
3862
3863 mutex_lock(&mvm->mutex);
3864
3865 mvmvif->csa_failed = false;
3866
3867 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
3868 chsw->chandef.center_freq1);
3869
3870 iwl_fw_dbg_trigger_simple_stop(&mvm->fwrt,
3871 ieee80211_vif_to_wdev(vif),
3872 FW_DBG_TRIGGER_CHANNEL_SWITCH);
3873
3874 switch (vif->type) {
3875 case NL80211_IFTYPE_AP:
3876 csa_vif =
3877 rcu_dereference_protected(mvm->csa_vif,
3878 lockdep_is_held(&mvm->mutex));
3879 if (WARN_ONCE(csa_vif && csa_vif->csa_active,
3880 "Another CSA is already in progress")) {
3881 ret = -EBUSY;
3882 goto out_unlock;
3883 }
3884
3885
3886 if (rcu_dereference_protected(mvm->csa_tx_blocked_vif,
3887 lockdep_is_held(&mvm->mutex))) {
3888 ret = -EBUSY;
3889 goto out_unlock;
3890 }
3891
3892 rcu_assign_pointer(mvm->csa_vif, vif);
3893
3894 if (WARN_ONCE(mvmvif->csa_countdown,
3895 "Previous CSA countdown didn't complete")) {
3896 ret = -EBUSY;
3897 goto out_unlock;
3898 }
3899
3900 mvmvif->csa_target_freq = chsw->chandef.chan->center_freq;
3901
3902 break;
3903 case NL80211_IFTYPE_STATION:
3904 if (mvmvif->lqm_active)
3905 iwl_mvm_send_lqm_cmd(vif,
3906 LQM_CMD_OPERATION_STOP_MEASUREMENT,
3907 0, 0);
3908
3909
3910
3911
3912
3913
3914
3915 if (chsw->count <= 1)
3916 apply_time = 0;
3917 else
3918 apply_time = chsw->device_timestamp +
3919 ((vif->bss_conf.beacon_int * (chsw->count - 1) -
3920 IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
3921
3922 if (chsw->block_tx)
3923 iwl_mvm_csa_client_absent(mvm, vif);
3924
3925 iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
3926 apply_time);
3927 if (mvmvif->bf_data.bf_enabled) {
3928 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
3929 if (ret)
3930 goto out_unlock;
3931 }
3932
3933 break;
3934 default:
3935 break;
3936 }
3937
3938 mvmvif->ps_disabled = true;
3939
3940 ret = iwl_mvm_power_update_ps(mvm);
3941 if (ret)
3942 goto out_unlock;
3943
3944
3945 iwl_mvm_teardown_tdls_peers(mvm);
3946
3947out_unlock:
3948 mutex_unlock(&mvm->mutex);
3949
3950 return ret;
3951}
3952
3953static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
3954 struct ieee80211_vif *vif)
3955{
3956 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3957 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3958 int ret;
3959
3960 mutex_lock(&mvm->mutex);
3961
3962 if (mvmvif->csa_failed) {
3963 mvmvif->csa_failed = false;
3964 ret = -EIO;
3965 goto out_unlock;
3966 }
3967
3968 if (vif->type == NL80211_IFTYPE_STATION) {
3969 struct iwl_mvm_sta *mvmsta;
3970
3971 mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
3972 mvmvif->ap_sta_id);
3973
3974 if (WARN_ON(!mvmsta)) {
3975 ret = -EIO;
3976 goto out_unlock;
3977 }
3978
3979 iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
3980
3981 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
3982
3983 ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
3984 if (ret)
3985 goto out_unlock;
3986
3987 iwl_mvm_stop_session_protection(mvm, vif);
3988 }
3989
3990 mvmvif->ps_disabled = false;
3991
3992 ret = iwl_mvm_power_update_ps(mvm);
3993
3994out_unlock:
3995 mutex_unlock(&mvm->mutex);
3996
3997 return ret;
3998}
3999
4000static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
4001{
4002 if (drop) {
4003 if (iwl_mvm_has_new_tx_api(mvm))
4004
4005 WARN_ONCE(1,
4006 "Need to implement flush TX queue\n");
4007 else
4008 iwl_mvm_flush_tx_path(mvm,
4009 iwl_mvm_flushable_queues(mvm) & queues,
4010 0);
4011 } else {
4012 if (iwl_mvm_has_new_tx_api(mvm)) {
4013 struct ieee80211_sta *sta;
4014 int i;
4015
4016 mutex_lock(&mvm->mutex);
4017
4018 for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
4019 sta = rcu_dereference_protected(
4020 mvm->fw_id_to_mac_id[i],
4021 lockdep_is_held(&mvm->mutex));
4022 if (IS_ERR_OR_NULL(sta))
4023 continue;
4024
4025 iwl_mvm_wait_sta_queues_empty(mvm,
4026 iwl_mvm_sta_from_mac80211(sta));
4027 }
4028
4029 mutex_unlock(&mvm->mutex);
4030 } else {
4031 iwl_trans_wait_tx_queues_empty(mvm->trans,
4032 queues);
4033 }
4034 }
4035}
4036
4037static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
4038 struct ieee80211_vif *vif, u32 queues, bool drop)
4039{
4040 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4041 struct iwl_mvm_vif *mvmvif;
4042 struct iwl_mvm_sta *mvmsta;
4043 struct ieee80211_sta *sta;
4044 int i;
4045 u32 msk = 0;
4046
4047 if (!vif) {
4048 iwl_mvm_flush_no_vif(mvm, queues, drop);
4049 return;
4050 }
4051
4052 if (vif->type != NL80211_IFTYPE_STATION)
4053 return;
4054
4055
4056 flush_work(&mvm->add_stream_wk);
4057
4058 mutex_lock(&mvm->mutex);
4059 mvmvif = iwl_mvm_vif_from_mac80211(vif);
4060
4061
4062 for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
4063 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
4064 lockdep_is_held(&mvm->mutex));
4065 if (IS_ERR_OR_NULL(sta))
4066 continue;
4067
4068 mvmsta = iwl_mvm_sta_from_mac80211(sta);
4069 if (mvmsta->vif != vif)
4070 continue;
4071
4072
4073 WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls);
4074
4075 if (drop) {
4076 if (iwl_mvm_flush_sta(mvm, mvmsta, false, 0))
4077 IWL_ERR(mvm, "flush request fail\n");
4078 } else {
4079 msk |= mvmsta->tfd_queue_msk;
4080 if (iwl_mvm_has_new_tx_api(mvm))
4081 iwl_mvm_wait_sta_queues_empty(mvm, mvmsta);
4082 }
4083 }
4084
4085 mutex_unlock(&mvm->mutex);
4086
4087
4088
4089
4090 if (!drop && !iwl_mvm_has_new_tx_api(mvm))
4091 iwl_trans_wait_tx_queues_empty(mvm->trans, msk);
4092}
4093
4094static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
4095 struct survey_info *survey)
4096{
4097 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4098 int ret;
4099
4100 memset(survey, 0, sizeof(*survey));
4101
4102
4103 if (idx != 0)
4104 return -ENOENT;
4105
4106 if (!fw_has_capa(&mvm->fw->ucode_capa,
4107 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
4108 return -ENOENT;
4109
4110 mutex_lock(&mvm->mutex);
4111
4112 if (iwl_mvm_firmware_running(mvm)) {
4113 ret = iwl_mvm_request_statistics(mvm, false);
4114 if (ret)
4115 goto out;
4116 }
4117
4118 survey->filled = SURVEY_INFO_TIME |
4119 SURVEY_INFO_TIME_RX |
4120 SURVEY_INFO_TIME_TX |
4121 SURVEY_INFO_TIME_SCAN;
4122 survey->time = mvm->accu_radio_stats.on_time_rf +
4123 mvm->radio_stats.on_time_rf;
4124 do_div(survey->time, USEC_PER_MSEC);
4125
4126 survey->time_rx = mvm->accu_radio_stats.rx_time +
4127 mvm->radio_stats.rx_time;
4128 do_div(survey->time_rx, USEC_PER_MSEC);
4129
4130 survey->time_tx = mvm->accu_radio_stats.tx_time +
4131 mvm->radio_stats.tx_time;
4132 do_div(survey->time_tx, USEC_PER_MSEC);
4133
4134 survey->time_scan = mvm->accu_radio_stats.on_time_scan +
4135 mvm->radio_stats.on_time_scan;
4136 do_div(survey->time_scan, USEC_PER_MSEC);
4137
4138 ret = 0;
4139 out:
4140 mutex_unlock(&mvm->mutex);
4141 return ret;
4142}
4143
4144static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
4145 struct ieee80211_vif *vif,
4146 struct ieee80211_sta *sta,
4147 struct station_info *sinfo)
4148{
4149 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4150 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
4151 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
4152
4153 if (mvmsta->avg_energy) {
4154 sinfo->signal_avg = mvmsta->avg_energy;
4155 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL_AVG);
4156 }
4157
4158 if (!fw_has_capa(&mvm->fw->ucode_capa,
4159 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
4160 return;
4161
4162
4163 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
4164 return;
4165
4166 if (!vif->bss_conf.assoc)
4167 return;
4168
4169 mutex_lock(&mvm->mutex);
4170
4171 if (mvmvif->ap_sta_id != mvmsta->sta_id)
4172 goto unlock;
4173
4174 if (iwl_mvm_request_statistics(mvm, false))
4175 goto unlock;
4176
4177 sinfo->rx_beacon = mvmvif->beacon_stats.num_beacons +
4178 mvmvif->beacon_stats.accu_num_beacons;
4179 sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_RX);
4180 if (mvmvif->beacon_stats.avg_signal) {
4181
4182 sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal;
4183 sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG);
4184 }
4185 unlock:
4186 mutex_unlock(&mvm->mutex);
4187}
4188
4189static void iwl_mvm_event_mlme_callback(struct iwl_mvm *mvm,
4190 struct ieee80211_vif *vif,
4191 const struct ieee80211_event *event)
4192{
4193#define CHECK_MLME_TRIGGER(_cnt, _fmt...) \
4194 do { \
4195 if ((trig_mlme->_cnt) && --(trig_mlme->_cnt)) \
4196 break; \
4197 iwl_fw_dbg_collect_trig(&(mvm)->fwrt, trig, _fmt); \
4198 } while (0)
4199
4200 struct iwl_fw_dbg_trigger_tlv *trig;
4201 struct iwl_fw_dbg_trigger_mlme *trig_mlme;
4202
4203 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME))
4204 return;
4205
4206 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME);
4207 trig_mlme = (void *)trig->data;
4208 if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
4209 ieee80211_vif_to_wdev(vif), trig))
4210 return;
4211
4212 if (event->u.mlme.data == ASSOC_EVENT) {
4213 if (event->u.mlme.status == MLME_DENIED)
4214 CHECK_MLME_TRIGGER(stop_assoc_denied,
4215 "DENIED ASSOC: reason %d",
4216 event->u.mlme.reason);
4217 else if (event->u.mlme.status == MLME_TIMEOUT)
4218 CHECK_MLME_TRIGGER(stop_assoc_timeout,
4219 "ASSOC TIMEOUT");
4220 } else if (event->u.mlme.data == AUTH_EVENT) {
4221 if (event->u.mlme.status == MLME_DENIED)
4222 CHECK_MLME_TRIGGER(stop_auth_denied,
4223 "DENIED AUTH: reason %d",
4224 event->u.mlme.reason);
4225 else if (event->u.mlme.status == MLME_TIMEOUT)
4226 CHECK_MLME_TRIGGER(stop_auth_timeout,
4227 "AUTH TIMEOUT");
4228 } else if (event->u.mlme.data == DEAUTH_RX_EVENT) {
4229 CHECK_MLME_TRIGGER(stop_rx_deauth,
4230 "DEAUTH RX %d", event->u.mlme.reason);
4231 } else if (event->u.mlme.data == DEAUTH_TX_EVENT) {
4232 CHECK_MLME_TRIGGER(stop_tx_deauth,
4233 "DEAUTH TX %d", event->u.mlme.reason);
4234 }
4235#undef CHECK_MLME_TRIGGER
4236}
4237
4238static void iwl_mvm_event_bar_rx_callback(struct iwl_mvm *mvm,
4239 struct ieee80211_vif *vif,
4240 const struct ieee80211_event *event)
4241{
4242 struct iwl_fw_dbg_trigger_tlv *trig;
4243 struct iwl_fw_dbg_trigger_ba *ba_trig;
4244
4245 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
4246 return;
4247
4248 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
4249 ba_trig = (void *)trig->data;
4250 if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
4251 ieee80211_vif_to_wdev(vif), trig))
4252 return;
4253
4254 if (!(le16_to_cpu(ba_trig->rx_bar) & BIT(event->u.ba.tid)))
4255 return;
4256
4257 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
4258 "BAR received from %pM, tid %d, ssn %d",
4259 event->u.ba.sta->addr, event->u.ba.tid,
4260 event->u.ba.ssn);
4261}
4262
4263static void
4264iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
4265 struct ieee80211_vif *vif,
4266 const struct ieee80211_event *event)
4267{
4268 struct iwl_fw_dbg_trigger_tlv *trig;
4269 struct iwl_fw_dbg_trigger_ba *ba_trig;
4270
4271 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
4272 return;
4273
4274 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
4275 ba_trig = (void *)trig->data;
4276 if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
4277 ieee80211_vif_to_wdev(vif), trig))
4278 return;
4279
4280 if (!(le16_to_cpu(ba_trig->frame_timeout) & BIT(event->u.ba.tid)))
4281 return;
4282
4283 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
4284 "Frame from %pM timed out, tid %d",
4285 event->u.ba.sta->addr, event->u.ba.tid);
4286}
4287
4288static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
4289 struct ieee80211_vif *vif,
4290 const struct ieee80211_event *event)
4291{
4292 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4293
4294 switch (event->type) {
4295 case MLME_EVENT:
4296 iwl_mvm_event_mlme_callback(mvm, vif, event);
4297 break;
4298 case BAR_RX_EVENT:
4299 iwl_mvm_event_bar_rx_callback(mvm, vif, event);
4300 break;
4301 case BA_FRAME_TIMEOUT:
4302 iwl_mvm_event_frame_timeout_callback(mvm, vif, event);
4303 break;
4304 default:
4305 break;
4306 }
4307}
4308
4309void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
4310 struct iwl_mvm_internal_rxq_notif *notif,
4311 u32 size)
4312{
4313 u32 qmask = BIT(mvm->trans->num_rx_queues) - 1;
4314 int ret;
4315
4316 lockdep_assert_held(&mvm->mutex);
4317
4318
4319 if (!iwl_mvm_has_new_rx_api(mvm) ||
4320 mvm->trans->cfg->device_family == IWL_DEVICE_FAMILY_A000)
4321 return;
4322
4323 notif->cookie = mvm->queue_sync_cookie;
4324
4325 if (notif->sync)
4326 atomic_set(&mvm->queue_sync_counter,
4327 mvm->trans->num_rx_queues);
4328
4329 ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size);
4330 if (ret) {
4331 IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
4332 goto out;
4333 }
4334
4335 if (notif->sync) {
4336 ret = wait_event_timeout(mvm->rx_sync_waitq,
4337 atomic_read(&mvm->queue_sync_counter) == 0 ||
4338 iwl_mvm_is_radio_killed(mvm),
4339 HZ);
4340 WARN_ON_ONCE(!ret && !iwl_mvm_is_radio_killed(mvm));
4341 }
4342
4343out:
4344 atomic_set(&mvm->queue_sync_counter, 0);
4345 mvm->queue_sync_cookie++;
4346}
4347
4348static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
4349{
4350 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4351 struct iwl_mvm_internal_rxq_notif data = {
4352 .type = IWL_MVM_RXQ_EMPTY,
4353 .sync = 1,
4354 };
4355
4356 mutex_lock(&mvm->mutex);
4357 iwl_mvm_sync_rx_queues_internal(mvm, &data, sizeof(data));
4358 mutex_unlock(&mvm->mutex);
4359}
4360
4361const struct ieee80211_ops iwl_mvm_hw_ops = {
4362 .tx = iwl_mvm_mac_tx,
4363 .ampdu_action = iwl_mvm_mac_ampdu_action,
4364 .start = iwl_mvm_mac_start,
4365 .reconfig_complete = iwl_mvm_mac_reconfig_complete,
4366 .stop = iwl_mvm_mac_stop,
4367 .add_interface = iwl_mvm_mac_add_interface,
4368 .remove_interface = iwl_mvm_mac_remove_interface,
4369 .config = iwl_mvm_mac_config,
4370 .prepare_multicast = iwl_mvm_prepare_multicast,
4371 .configure_filter = iwl_mvm_configure_filter,
4372 .config_iface_filter = iwl_mvm_config_iface_filter,
4373 .bss_info_changed = iwl_mvm_bss_info_changed,
4374 .hw_scan = iwl_mvm_mac_hw_scan,
4375 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
4376 .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove,
4377 .sta_state = iwl_mvm_mac_sta_state,
4378 .sta_notify = iwl_mvm_mac_sta_notify,
4379 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
4380 .release_buffered_frames = iwl_mvm_mac_release_buffered_frames,
4381 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
4382 .sta_rc_update = iwl_mvm_sta_rc_update,
4383 .conf_tx = iwl_mvm_mac_conf_tx,
4384 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
4385 .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
4386 .flush = iwl_mvm_mac_flush,
4387 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
4388 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
4389 .set_key = iwl_mvm_mac_set_key,
4390 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
4391 .remain_on_channel = iwl_mvm_roc,
4392 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
4393 .add_chanctx = iwl_mvm_add_chanctx,
4394 .remove_chanctx = iwl_mvm_remove_chanctx,
4395 .change_chanctx = iwl_mvm_change_chanctx,
4396 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
4397 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
4398 .switch_vif_chanctx = iwl_mvm_switch_vif_chanctx,
4399
4400 .start_ap = iwl_mvm_start_ap_ibss,
4401 .stop_ap = iwl_mvm_stop_ap_ibss,
4402 .join_ibss = iwl_mvm_start_ap_ibss,
4403 .leave_ibss = iwl_mvm_stop_ap_ibss,
4404
4405 .tx_last_beacon = iwl_mvm_tx_last_beacon,
4406
4407 .set_tim = iwl_mvm_set_tim,
4408
4409 .channel_switch = iwl_mvm_channel_switch,
4410 .pre_channel_switch = iwl_mvm_pre_channel_switch,
4411 .post_channel_switch = iwl_mvm_post_channel_switch,
4412
4413 .tdls_channel_switch = iwl_mvm_tdls_channel_switch,
4414 .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch,
4415 .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch,
4416
4417 .event_callback = iwl_mvm_mac_event_callback,
4418
4419 .sync_rx_queues = iwl_mvm_sync_rx_queues,
4420
4421 CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd)
4422
4423#ifdef CONFIG_PM_SLEEP
4424
4425 .suspend = iwl_mvm_suspend,
4426 .resume = iwl_mvm_resume,
4427 .set_wakeup = iwl_mvm_set_wakeup,
4428 .set_rekey_data = iwl_mvm_set_rekey_data,
4429#if IS_ENABLED(CONFIG_IPV6)
4430 .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
4431#endif
4432 .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
4433#endif
4434 .get_survey = iwl_mvm_mac_get_survey,
4435 .sta_statistics = iwl_mvm_mac_sta_statistics,
4436};
4437