hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
....@@ -5,9 +5,9 @@
55 *
66 * GPL LICENSE SUMMARY
77 *
8
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
98 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
109 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
10
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
1111 *
1212 * This program is free software; you can redistribute it and/or modify
1313 * it under the terms of version 2 of the GNU General Public License as
....@@ -18,11 +18,6 @@
1818 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1919 * General Public License for more details.
2020 *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24
- * USA
25
- *
2621 * The full GNU General Public License is included in this distribution
2722 * in the file called COPYING.
2823 *
....@@ -32,9 +27,9 @@
3227 *
3328 * BSD LICENSE
3429 *
35
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3630 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
3731 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
32
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
3833 * All rights reserved.
3934 *
4035 * Redistribution and use in source and binary forms, with or without
....@@ -100,11 +95,6 @@
10095 bool found_vif;
10196 };
10297
103
-struct iwl_mvm_hw_queues_iface_iterator_data {
104
- struct ieee80211_vif *exclude_vif;
105
- unsigned long used_hw_queues;
106
-};
107
-
10898 static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
10999 struct ieee80211_vif *vif)
110100 {
....@@ -125,12 +115,12 @@
125115 * client in the system.
126116 *
127117 * The firmware will decide according to the MAC type which
128
- * will be the master and slave. Clients that need to sync
129
- * with a remote station will be the master, and an AP or GO
130
- * will be the slave.
118
+ * will be the leader and follower. Clients that need to sync
119
+ * with a remote station will be the leader, and an AP or GO
120
+ * will be the follower.
131121 *
132
- * Depending on the new interface type it can be slaved to
133
- * or become the master of an existing interface.
122
+ * Depending on the new interface type it can be following
123
+ * or become the leader of an existing interface.
134124 */
135125 switch (data->vif->type) {
136126 case NL80211_IFTYPE_STATION:
....@@ -211,61 +201,6 @@
211201 data->preferred_tsf = NUM_TSF_IDS;
212202 }
213203
214
-/*
215
- * Get the mask of the queues used by the vif
216
- */
217
-u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif)
218
-{
219
- u32 qmask = 0, ac;
220
-
221
- if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
222
- return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
223
-
224
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
225
- if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
226
- qmask |= BIT(vif->hw_queue[ac]);
227
- }
228
-
229
- if (vif->type == NL80211_IFTYPE_AP ||
230
- vif->type == NL80211_IFTYPE_ADHOC)
231
- qmask |= BIT(vif->cab_queue);
232
-
233
- return qmask;
234
-}
235
-
236
-static void iwl_mvm_iface_hw_queues_iter(void *_data, u8 *mac,
237
- struct ieee80211_vif *vif)
238
-{
239
- struct iwl_mvm_hw_queues_iface_iterator_data *data = _data;
240
-
241
- /* exclude the given vif */
242
- if (vif == data->exclude_vif)
243
- return;
244
-
245
- data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif);
246
-}
247
-
248
-unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
249
- struct ieee80211_vif *exclude_vif)
250
-{
251
- struct iwl_mvm_hw_queues_iface_iterator_data data = {
252
- .exclude_vif = exclude_vif,
253
- .used_hw_queues =
254
- BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
255
- BIT(mvm->aux_queue) |
256
- BIT(IWL_MVM_DQA_GCAST_QUEUE),
257
- };
258
-
259
- lockdep_assert_held(&mvm->mutex);
260
-
261
- /* mark all VIF used hw queues */
262
- ieee80211_iterate_active_interfaces_atomic(
263
- mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
264
- iwl_mvm_iface_hw_queues_iter, &data);
265
-
266
- return data.used_hw_queues;
267
-}
268
-
269204 static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
270205 struct ieee80211_vif *vif)
271206 {
....@@ -325,9 +260,7 @@
325260 .preferred_tsf = NUM_TSF_IDS,
326261 .found_vif = false,
327262 };
328
- u32 ac;
329
- int ret, i, queue_limit;
330
- unsigned long used_hw_queues;
263
+ int ret, i;
331264
332265 lockdep_assert_held(&mvm->mutex);
333266
....@@ -362,8 +295,6 @@
362295 ieee80211_iterate_active_interfaces_atomic(
363296 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
364297 iwl_mvm_mac_iface_iterator, &data);
365
-
366
- used_hw_queues = iwl_mvm_get_used_hw_queues(mvm, vif);
367298
368299 /*
369300 * In the case we're getting here during resume, it's similar to
....@@ -406,40 +337,9 @@
406337 INIT_LIST_HEAD(&mvmvif->time_event_data.list);
407338 mvmvif->time_event_data.id = TE_MAX;
408339
409
- /* No need to allocate data queues to P2P Device MAC.*/
410
- if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
411
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
412
- vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
413
-
340
+ /* No need to allocate data queues to P2P Device MAC and NAN.*/
341
+ if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
414342 return 0;
415
- }
416
-
417
- /*
418
- * queues in mac80211 almost entirely independent of
419
- * the ones here - no real limit
420
- */
421
- queue_limit = IEEE80211_MAX_QUEUES;
422
- BUILD_BUG_ON(IEEE80211_MAX_QUEUES >
423
- BITS_PER_BYTE *
424
- sizeof(mvm->hw_queue_to_mac80211[0]));
425
-
426
- /*
427
- * Find available queues, and allocate them to the ACs. When in
428
- * DQA-mode they aren't really used, and this is done only so the
429
- * mac80211 ieee80211_check_queues() function won't fail
430
- */
431
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
432
- u8 queue = find_first_zero_bit(&used_hw_queues, queue_limit);
433
-
434
- if (queue >= queue_limit) {
435
- IWL_ERR(mvm, "Failed to allocate queue\n");
436
- ret = -EIO;
437
- goto exit_fail;
438
- }
439
-
440
- __set_bit(queue, &used_hw_queues);
441
- vif->hw_queue[ac] = queue;
442
- }
443343
444344 /* Allocate the CAB queue for softAP and GO interfaces */
445345 if (vif->type == NL80211_IFTYPE_AP ||
....@@ -449,9 +349,6 @@
449349 * queue value (when queue is enabled).
450350 */
451351 mvmvif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
452
- vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
453
- } else {
454
- vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
455352 }
456353
457354 mvmvif->bcast_sta.sta_id = IWL_MVM_INVALID_STA;
....@@ -465,8 +362,6 @@
465362
466363 exit_fail:
467364 memset(mvmvif, 0, sizeof(struct iwl_mvm_vif));
468
- memset(vif->hw_queue, IEEE80211_INVAL_HW_QUEUE, sizeof(vif->hw_queue));
469
- vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
470365 return ret;
471366 }
472367
....@@ -657,19 +552,20 @@
657552 cpu_to_le32(vif->bss_conf.use_short_slot ?
658553 MAC_FLG_SHORT_SLOT : 0);
659554
660
- cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
555
+ cmd->filter_flags = 0;
661556
662557 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
663558 u8 txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, i);
559
+ u8 ucode_ac = iwl_mvm_mac80211_ac_to_ucode_ac(i);
664560
665
- cmd->ac[txf].cw_min =
561
+ cmd->ac[ucode_ac].cw_min =
666562 cpu_to_le16(mvmvif->queue_params[i].cw_min);
667
- cmd->ac[txf].cw_max =
563
+ cmd->ac[ucode_ac].cw_max =
668564 cpu_to_le16(mvmvif->queue_params[i].cw_max);
669
- cmd->ac[txf].edca_txop =
565
+ cmd->ac[ucode_ac].edca_txop =
670566 cpu_to_le16(mvmvif->queue_params[i].txop * 32);
671
- cmd->ac[txf].aifsn = mvmvif->queue_params[i].aifs;
672
- cmd->ac[txf].fifos_mask = BIT(txf);
567
+ cmd->ac[ucode_ac].aifsn = mvmvif->queue_params[i].aifs;
568
+ cmd->ac[ucode_ac].fifos_mask = BIT(txf);
673569 }
674570
675571 if (vif->bss_conf.qos)
....@@ -725,6 +621,8 @@
725621 /* We need the dtim_period to set the MAC as associated */
726622 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
727623 !force_assoc_off) {
624
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
625
+ u8 ap_sta_id = mvmvif->ap_sta_id;
728626 u32 dtim_offs;
729627
730628 /*
....@@ -760,6 +658,29 @@
760658 dtim_offs);
761659
762660 ctxt_sta->is_assoc = cpu_to_le32(1);
661
+
662
+ /*
663
+ * allow multicast data frames only as long as the station is
664
+ * authorized, i.e., GTK keys are already installed (if needed)
665
+ */
666
+ if (ap_sta_id < mvm->fw->ucode_capa.num_stations) {
667
+ struct ieee80211_sta *sta;
668
+
669
+ rcu_read_lock();
670
+
671
+ sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
672
+ if (!IS_ERR_OR_NULL(sta)) {
673
+ struct iwl_mvm_sta *mvmsta =
674
+ iwl_mvm_sta_from_mac80211(sta);
675
+
676
+ if (mvmsta->sta_state ==
677
+ IEEE80211_STA_AUTHORIZED)
678
+ cmd.filter_flags |=
679
+ cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
680
+ }
681
+
682
+ rcu_read_unlock();
683
+ }
763684 } else {
764685 ctxt_sta->is_assoc = cpu_to_le32(0);
765686
....@@ -770,13 +691,8 @@
770691 }
771692
772693 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
773
- ctxt_sta->bi_reciprocal =
774
- cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
775694 ctxt_sta->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
776695 vif->bss_conf.dtim_period);
777
- ctxt_sta->dtim_reciprocal =
778
- cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
779
- vif->bss_conf.dtim_period));
780696
781697 ctxt_sta->listen_interval = cpu_to_le32(mvm->hw->conf.listen_interval);
782698 ctxt_sta->assoc_id = cpu_to_le32(vif->bss_conf.aid);
....@@ -784,9 +700,16 @@
784700 if (vif->probe_req_reg && vif->bss_conf.assoc && vif->p2p)
785701 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
786702
787
- if (vif->bss_conf.assoc && vif->bss_conf.he_support &&
788
- !iwlwifi_mod_params.disable_11ax)
703
+ if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax) {
789704 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX);
705
+ if (vif->bss_conf.twt_requester && IWL_MVM_USE_TWT) {
706
+ ctxt_sta->data_policy |= cpu_to_le32(TWT_SUPPORTED);
707
+ if (vif->bss_conf.twt_protected)
708
+ ctxt_sta->data_policy |=
709
+ cpu_to_le32(PROTECTED_TWT_SUPPORTED);
710
+ }
711
+ }
712
+
790713
791714 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
792715 }
....@@ -807,7 +730,8 @@
807730 MAC_FILTER_IN_CONTROL_AND_MGMT |
808731 MAC_FILTER_IN_BEACON |
809732 MAC_FILTER_IN_PROBE_REQUEST |
810
- MAC_FILTER_IN_CRC32);
733
+ MAC_FILTER_IN_CRC32 |
734
+ MAC_FILTER_ACCEPT_GRP);
811735 ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS);
812736
813737 /* Allocate sniffer station */
....@@ -831,12 +755,11 @@
831755 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
832756
833757 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
834
- MAC_FILTER_IN_PROBE_REQUEST);
758
+ MAC_FILTER_IN_PROBE_REQUEST |
759
+ MAC_FILTER_ACCEPT_GRP);
835760
836761 /* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
837762 cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
838
- cmd.ibss.bi_reciprocal =
839
- cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
840763
841764 /* TODO: Assumes that the beacon id == mac context id */
842765 cmd.ibss.beacon_template = cpu_to_le32(mvmvif->id);
....@@ -869,8 +792,6 @@
869792
870793 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
871794
872
- cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
873
-
874795 /* Override the filter flags to accept only probe requests */
875796 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
876797
....@@ -890,9 +811,9 @@
890811 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
891812 }
892813
893
-static void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
894
- __le32 *tim_index, __le32 *tim_size,
895
- u8 *beacon, u32 frame_size)
814
+void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
815
+ __le32 *tim_index, __le32 *tim_size,
816
+ u8 *beacon, u32 frame_size)
896817 {
897818 u32 tim_idx;
898819 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
....@@ -932,15 +853,14 @@
932853 return ie - beacon;
933854 }
934855
935
-static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
936
- struct ieee80211_vif *vif)
856
+u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
857
+ struct ieee80211_vif *vif)
937858 {
938859 u8 rate;
939
-
940
- if (info->band == NL80211_BAND_5GHZ || vif->p2p)
941
- rate = IWL_FIRST_OFDM_RATE;
942
- else
860
+ if (info->band == NL80211_BAND_2GHZ && !vif->p2p)
943861 rate = IWL_FIRST_CCK_RATE;
862
+ else
863
+ rate = IWL_FIRST_OFDM_RATE;
944864
945865 return rate;
946866 }
....@@ -968,11 +888,8 @@
968888 tx->tx_flags = cpu_to_le32(tx_flags);
969889
970890 if (!fw_has_capa(&mvm->fw->ucode_capa,
971
- IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION)) {
972
- mvm->mgmt_last_antenna_idx =
973
- iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
974
- mvm->mgmt_last_antenna_idx);
975
- }
891
+ IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION))
892
+ iwl_mvm_toggle_tx_ant(mvm, &mvm->mgmt_last_antenna_idx);
976893
977894 tx->rate_n_flags =
978895 cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
....@@ -986,9 +903,9 @@
986903
987904 }
988905
989
-static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
990
- struct sk_buff *beacon,
991
- void *data, int len)
906
+int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
907
+ struct sk_buff *beacon,
908
+ void *data, int len)
992909 {
993910 struct iwl_host_cmd cmd = {
994911 .id = BEACON_TEMPLATE_CMD,
....@@ -1091,12 +1008,15 @@
10911008 sizeof(beacon_cmd));
10921009 }
10931010
1094
-static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
1095
- struct ieee80211_vif *vif,
1096
- struct sk_buff *beacon)
1011
+int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
1012
+ struct ieee80211_vif *vif,
1013
+ struct sk_buff *beacon)
10971014 {
10981015 if (WARN_ON(!beacon))
10991016 return -EINVAL;
1017
+
1018
+ if (IWL_MVM_NON_TRANSMITTING_AP)
1019
+ return 0;
11001020
11011021 if (!fw_has_capa(&mvm->fw->ucode_capa,
11021022 IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD))
....@@ -1122,6 +1042,13 @@
11221042 beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
11231043 if (!beacon)
11241044 return -ENOMEM;
1045
+
1046
+#ifdef CONFIG_IWLWIFI_DEBUGFS
1047
+ if (mvm->beacon_inject_active) {
1048
+ dev_kfree_skb(beacon);
1049
+ return -EBUSY;
1050
+ }
1051
+#endif
11251052
11261053 ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon);
11271054 dev_kfree_skb(beacon);
....@@ -1186,17 +1113,12 @@
11861113 }
11871114
11881115 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
1189
- ctxt_ap->bi_reciprocal =
1190
- cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
11911116 ctxt_ap->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
11921117 vif->bss_conf.dtim_period);
1193
- ctxt_ap->dtim_reciprocal =
1194
- cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
1195
- vif->bss_conf.dtim_period));
11961118
11971119 if (!fw_has_api(&mvm->fw->ucode_capa,
11981120 IWL_UCODE_TLV_API_STA_TYPE))
1199
- ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
1121
+ ctxt_ap->mcast_qid = cpu_to_le32(mvmvif->cab_queue);
12001122
12011123 /*
12021124 * Only set the beacon time when the MAC is being added, when we
....@@ -1219,9 +1141,7 @@
12191141 ieee80211_tu_to_usec(data.beacon_int * rand /
12201142 100);
12211143 } else {
1222
- mvmvif->ap_beacon_time =
1223
- iwl_read_prph(mvm->trans,
1224
- DEVICE_SYSTEM_TIME_REG);
1144
+ mvmvif->ap_beacon_time = iwl_mvm_get_systime(mvm);
12251145 }
12261146 }
12271147
....@@ -1384,8 +1304,8 @@
13841304
13851305 mvmvif->csa_countdown = true;
13861306
1387
- if (!ieee80211_csa_is_complete(csa_vif)) {
1388
- int c = ieee80211_csa_update_counter(csa_vif);
1307
+ if (!ieee80211_beacon_cntdwn_is_complete(csa_vif)) {
1308
+ int c = ieee80211_beacon_update_cntdwn(csa_vif);
13891309
13901310 iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif);
13911311 if (csa_vif->p2p &&
....@@ -1413,7 +1333,7 @@
14131333 {
14141334 struct iwl_rx_packet *pkt = rxb_addr(rxb);
14151335 struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
1416
- struct iwl_mvm_tx_resp *beacon_notify_hdr;
1336
+ struct iwl_extended_beacon_notif_v5 *beacon_v5 = (void *)pkt->data;
14171337 struct ieee80211_vif *csa_vif;
14181338 struct ieee80211_vif *tx_blocked_vif;
14191339 struct agg_tx_status *agg_status;
....@@ -1421,18 +1341,29 @@
14211341
14221342 lockdep_assert_held(&mvm->mutex);
14231343
1424
- beacon_notify_hdr = &beacon->beacon_notify_hdr;
14251344 mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
1426
- mvm->ibss_manager = beacon->ibss_mgr_status != 0;
14271345
1428
- agg_status = iwl_mvm_get_agg_status(mvm, beacon_notify_hdr);
1429
- status = le16_to_cpu(agg_status->status) & TX_STATUS_MSK;
1430
- IWL_DEBUG_RX(mvm,
1431
- "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n",
1432
- status, beacon_notify_hdr->failure_frame,
1433
- le64_to_cpu(beacon->tsf),
1434
- mvm->ap_last_beacon_gp2,
1435
- le32_to_cpu(beacon_notify_hdr->initial_rate));
1346
+ if (!iwl_mvm_is_short_beacon_notif_supported(mvm)) {
1347
+ struct iwl_mvm_tx_resp *beacon_notify_hdr =
1348
+ &beacon_v5->beacon_notify_hdr;
1349
+
1350
+ mvm->ibss_manager = beacon_v5->ibss_mgr_status != 0;
1351
+ agg_status = iwl_mvm_get_agg_status(mvm, beacon_notify_hdr);
1352
+ status = le16_to_cpu(agg_status->status) & TX_STATUS_MSK;
1353
+ IWL_DEBUG_RX(mvm,
1354
+ "beacon status %#x retries:%d tsf:0x%016llX gp2:0x%X rate:%d\n",
1355
+ status, beacon_notify_hdr->failure_frame,
1356
+ le64_to_cpu(beacon->tsf),
1357
+ mvm->ap_last_beacon_gp2,
1358
+ le32_to_cpu(beacon_notify_hdr->initial_rate));
1359
+ } else {
1360
+ mvm->ibss_manager = beacon->ibss_mgr_status != 0;
1361
+ status = le32_to_cpu(beacon->status) & TX_STATUS_MSK;
1362
+ IWL_DEBUG_RX(mvm,
1363
+ "beacon status %#x tsf:0x%016llX gp2:0x%X\n",
1364
+ status, le64_to_cpu(beacon->tsf),
1365
+ mvm->ap_last_beacon_gp2);
1366
+ }
14361367
14371368 csa_vif = rcu_dereference_protected(mvm->csa_vif,
14381369 lockdep_is_held(&mvm->mutex));
....@@ -1465,59 +1396,18 @@
14651396 }
14661397 }
14671398
1468
-static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1469
- struct ieee80211_vif *vif)
1470
-{
1471
- struct iwl_missed_beacons_notif *missed_beacons = _data;
1472
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1473
- struct iwl_mvm *mvm = mvmvif->mvm;
1474
- struct iwl_fw_dbg_trigger_missed_bcon *bcon_trig;
1475
- struct iwl_fw_dbg_trigger_tlv *trigger;
1476
- u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
1477
- u32 rx_missed_bcon, rx_missed_bcon_since_rx;
1478
-
1479
- if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
1480
- return;
1481
-
1482
- rx_missed_bcon = le32_to_cpu(missed_beacons->consec_missed_beacons);
1483
- rx_missed_bcon_since_rx =
1484
- le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx);
1485
- /*
1486
- * TODO: the threshold should be adjusted based on latency conditions,
1487
- * and/or in case of a CS flow on one of the other AP vifs.
1488
- */
1489
- if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
1490
- IWL_MVM_MISSED_BEACONS_THRESHOLD)
1491
- ieee80211_beacon_loss(vif);
1492
-
1493
- if (!iwl_fw_dbg_trigger_enabled(mvm->fw,
1494
- FW_DBG_TRIGGER_MISSED_BEACONS))
1495
- return;
1496
-
1497
- trigger = iwl_fw_dbg_get_trigger(mvm->fw,
1498
- FW_DBG_TRIGGER_MISSED_BEACONS);
1499
- bcon_trig = (void *)trigger->data;
1500
- stop_trig_missed_bcon = le32_to_cpu(bcon_trig->stop_consec_missed_bcon);
1501
- stop_trig_missed_bcon_since_rx =
1502
- le32_to_cpu(bcon_trig->stop_consec_missed_bcon_since_rx);
1503
-
1504
- /* TODO: implement start trigger */
1505
-
1506
- if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
1507
- ieee80211_vif_to_wdev(vif),
1508
- trigger))
1509
- return;
1510
-
1511
- if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx ||
1512
- rx_missed_bcon >= stop_trig_missed_bcon)
1513
- iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL);
1514
-}
1515
-
15161399 void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
15171400 struct iwl_rx_cmd_buffer *rxb)
15181401 {
15191402 struct iwl_rx_packet *pkt = rxb_addr(rxb);
15201403 struct iwl_missed_beacons_notif *mb = (void *)pkt->data;
1404
+ struct iwl_fw_dbg_trigger_missed_bcon *bcon_trig;
1405
+ struct iwl_fw_dbg_trigger_tlv *trigger;
1406
+ u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
1407
+ u32 rx_missed_bcon, rx_missed_bcon_since_rx;
1408
+ struct ieee80211_vif *vif;
1409
+ u32 id = le32_to_cpu(mb->mac_id);
1410
+ union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt };
15211411
15221412 IWL_DEBUG_INFO(mvm,
15231413 "missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
....@@ -1527,10 +1417,45 @@
15271417 le32_to_cpu(mb->num_recvd_beacons),
15281418 le32_to_cpu(mb->num_expected_beacons));
15291419
1530
- ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1531
- IEEE80211_IFACE_ITER_NORMAL,
1532
- iwl_mvm_beacon_loss_iterator,
1533
- mb);
1420
+ rcu_read_lock();
1421
+
1422
+ vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
1423
+ if (!vif)
1424
+ goto out;
1425
+
1426
+ rx_missed_bcon = le32_to_cpu(mb->consec_missed_beacons);
1427
+ rx_missed_bcon_since_rx =
1428
+ le32_to_cpu(mb->consec_missed_beacons_since_last_rx);
1429
+ /*
1430
+ * TODO: the threshold should be adjusted based on latency conditions,
1431
+ * and/or in case of a CS flow on one of the other AP vifs.
1432
+ */
1433
+ if (rx_missed_bcon > IWL_MVM_MISSED_BEACONS_THRESHOLD_LONG)
1434
+ iwl_mvm_connection_loss(mvm, vif, "missed beacons");
1435
+ else if (rx_missed_bcon_since_rx > IWL_MVM_MISSED_BEACONS_THRESHOLD)
1436
+ ieee80211_beacon_loss(vif);
1437
+
1438
+ iwl_dbg_tlv_time_point(&mvm->fwrt,
1439
+ IWL_FW_INI_TIME_POINT_MISSED_BEACONS, &tp_data);
1440
+
1441
+ trigger = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
1442
+ FW_DBG_TRIGGER_MISSED_BEACONS);
1443
+ if (!trigger)
1444
+ goto out;
1445
+
1446
+ bcon_trig = (void *)trigger->data;
1447
+ stop_trig_missed_bcon = le32_to_cpu(bcon_trig->stop_consec_missed_bcon);
1448
+ stop_trig_missed_bcon_since_rx =
1449
+ le32_to_cpu(bcon_trig->stop_consec_missed_bcon_since_rx);
1450
+
1451
+ /* TODO: implement start trigger */
1452
+
1453
+ if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx ||
1454
+ rx_missed_bcon >= stop_trig_missed_bcon)
1455
+ iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL);
1456
+
1457
+out:
1458
+ rcu_read_unlock();
15341459 }
15351460
15361461 void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
....@@ -1572,47 +1497,140 @@
15721497 ieee80211_rx_napi(mvm->hw, NULL, skb, NULL);
15731498 }
15741499
1500
+void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm,
1501
+ struct iwl_rx_cmd_buffer *rxb)
1502
+{
1503
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
1504
+ struct iwl_probe_resp_data_notif *notif = (void *)pkt->data;
1505
+ struct iwl_probe_resp_data *old_data, *new_data;
1506
+ int len = iwl_rx_packet_payload_len(pkt);
1507
+ u32 id = le32_to_cpu(notif->mac_id);
1508
+ struct ieee80211_vif *vif;
1509
+ struct iwl_mvm_vif *mvmvif;
1510
+
1511
+ if (WARN_ON_ONCE(len < sizeof(*notif)))
1512
+ return;
1513
+
1514
+ IWL_DEBUG_INFO(mvm, "Probe response data notif: noa %d, csa %d\n",
1515
+ notif->noa_active, notif->csa_counter);
1516
+
1517
+ vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false);
1518
+ if (!vif)
1519
+ return;
1520
+
1521
+ mvmvif = iwl_mvm_vif_from_mac80211(vif);
1522
+
1523
+ new_data = kzalloc(sizeof(*new_data), GFP_KERNEL);
1524
+ if (!new_data)
1525
+ return;
1526
+
1527
+ memcpy(&new_data->notif, notif, sizeof(new_data->notif));
1528
+
1529
+ /* noa_attr contains 1 reserved byte, need to substruct it */
1530
+ new_data->noa_len = sizeof(struct ieee80211_vendor_ie) +
1531
+ sizeof(new_data->notif.noa_attr) - 1;
1532
+
1533
+ /*
1534
+ * If it's a one time NoA, only one descriptor is needed,
1535
+ * adjust the length according to len_low.
1536
+ */
1537
+ if (new_data->notif.noa_attr.len_low ==
1538
+ sizeof(struct ieee80211_p2p_noa_desc) + 2)
1539
+ new_data->noa_len -= sizeof(struct ieee80211_p2p_noa_desc);
1540
+
1541
+ old_data = rcu_dereference_protected(mvmvif->probe_resp_data,
1542
+ lockdep_is_held(&mvmvif->mvm->mutex));
1543
+ rcu_assign_pointer(mvmvif->probe_resp_data, new_data);
1544
+
1545
+ if (old_data)
1546
+ kfree_rcu(old_data, rcu_head);
1547
+
1548
+ if (notif->csa_counter != IWL_PROBE_RESP_DATA_NO_CSA &&
1549
+ notif->csa_counter >= 1)
1550
+ ieee80211_beacon_set_cntdwn(vif, notif->csa_counter);
1551
+}
1552
+
15751553 void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
15761554 struct iwl_rx_cmd_buffer *rxb)
15771555 {
15781556 struct iwl_rx_packet *pkt = rxb_addr(rxb);
15791557 struct iwl_channel_switch_noa_notif *notif = (void *)pkt->data;
1580
- struct ieee80211_vif *csa_vif;
1558
+ struct ieee80211_vif *csa_vif, *vif;
15811559 struct iwl_mvm_vif *mvmvif;
15821560 int len = iwl_rx_packet_payload_len(pkt);
1583
- u32 id_n_color;
1561
+ u32 id_n_color, csa_id, mac_id;
15841562
15851563 if (WARN_ON_ONCE(len < sizeof(*notif)))
15861564 return;
15871565
1566
+ id_n_color = le32_to_cpu(notif->id_and_color);
1567
+ mac_id = id_n_color & FW_CTXT_ID_MSK;
1568
+
1569
+ if (WARN_ON_ONCE(mac_id >= NUM_MAC_INDEX_DRIVER))
1570
+ return;
1571
+
1572
+ rcu_read_lock();
1573
+ vif = rcu_dereference(mvm->vif_id_to_mac[mac_id]);
1574
+ mvmvif = iwl_mvm_vif_from_mac80211(vif);
1575
+
1576
+ switch (vif->type) {
1577
+ case NL80211_IFTYPE_AP:
1578
+ csa_vif = rcu_dereference(mvm->csa_vif);
1579
+ if (WARN_ON(!csa_vif || !csa_vif->csa_active ||
1580
+ csa_vif != vif))
1581
+ goto out_unlock;
1582
+
1583
+ csa_id = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
1584
+ if (WARN(csa_id != id_n_color,
1585
+ "channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
1586
+ csa_id, id_n_color))
1587
+ goto out_unlock;
1588
+
1589
+ IWL_DEBUG_INFO(mvm, "Channel Switch Started Notification\n");
1590
+
1591
+ schedule_delayed_work(&mvm->cs_tx_unblock_dwork,
1592
+ msecs_to_jiffies(IWL_MVM_CS_UNBLOCK_TX_TIMEOUT *
1593
+ csa_vif->bss_conf.beacon_int));
1594
+
1595
+ ieee80211_csa_finish(csa_vif);
1596
+
1597
+ rcu_read_unlock();
1598
+
1599
+ RCU_INIT_POINTER(mvm->csa_vif, NULL);
1600
+ return;
1601
+ case NL80211_IFTYPE_STATION:
1602
+ iwl_mvm_csa_client_absent(mvm, vif);
1603
+ cancel_delayed_work(&mvmvif->csa_work);
1604
+ ieee80211_chswitch_done(vif, true);
1605
+ break;
1606
+ default:
1607
+ /* should never happen */
1608
+ WARN_ON_ONCE(1);
1609
+ break;
1610
+ }
1611
+out_unlock:
1612
+ rcu_read_unlock();
1613
+}
1614
+
1615
+void iwl_mvm_rx_missed_vap_notif(struct iwl_mvm *mvm,
1616
+ struct iwl_rx_cmd_buffer *rxb)
1617
+{
1618
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
1619
+ struct iwl_missed_vap_notif *mb = (void *)pkt->data;
1620
+ struct ieee80211_vif *vif;
1621
+ u32 id = le32_to_cpu(mb->mac_id);
1622
+
1623
+ IWL_DEBUG_INFO(mvm,
1624
+ "missed_vap notify mac_id=%u, num_beacon_intervals_elapsed=%u, profile_periodicity=%u\n",
1625
+ le32_to_cpu(mb->mac_id),
1626
+ mb->num_beacon_intervals_elapsed,
1627
+ mb->profile_periodicity);
1628
+
15881629 rcu_read_lock();
15891630
1590
- csa_vif = rcu_dereference(mvm->csa_vif);
1591
- if (WARN_ON(!csa_vif || !csa_vif->csa_active))
1592
- goto out_unlock;
1631
+ vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
1632
+ if (vif)
1633
+ iwl_mvm_connection_loss(mvm, vif, "missed vap beacon");
15931634
1594
- id_n_color = le32_to_cpu(notif->id_and_color);
1595
-
1596
- mvmvif = iwl_mvm_vif_from_mac80211(csa_vif);
1597
- if (WARN(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color) != id_n_color,
1598
- "channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
1599
- FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color), id_n_color))
1600
- goto out_unlock;
1601
-
1602
- IWL_DEBUG_INFO(mvm, "Channel Switch Started Notification\n");
1603
-
1604
- schedule_delayed_work(&mvm->cs_tx_unblock_dwork,
1605
- msecs_to_jiffies(IWL_MVM_CS_UNBLOCK_TX_TIMEOUT *
1606
- csa_vif->bss_conf.beacon_int));
1607
-
1608
- ieee80211_csa_finish(csa_vif);
1609
-
1610
- rcu_read_unlock();
1611
-
1612
- RCU_INIT_POINTER(mvm->csa_vif, NULL);
1613
-
1614
- return;
1615
-
1616
-out_unlock:
16171635 rcu_read_unlock();
16181636 }