1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
5 * Copyright (C) 2015-2017 Intel Deutschland GmbH
7 #include <linux/etherdevice.h>
8 #include <linux/crc32.h>
9 #include <net/mac80211.h>
14 #include "time-event.h"
16 const u8 iwl_mvm_ac_to_tx_fifo
[] = {
23 const u8 iwl_mvm_ac_to_gen2_tx_fifo
[] = {
24 IWL_GEN2_EDCA_TX_FIFO_VO
,
25 IWL_GEN2_EDCA_TX_FIFO_VI
,
26 IWL_GEN2_EDCA_TX_FIFO_BE
,
27 IWL_GEN2_EDCA_TX_FIFO_BK
,
28 IWL_GEN2_TRIG_TX_FIFO_VO
,
29 IWL_GEN2_TRIG_TX_FIFO_VI
,
30 IWL_GEN2_TRIG_TX_FIFO_BE
,
31 IWL_GEN2_TRIG_TX_FIFO_BK
,
34 const u8 iwl_mvm_ac_to_bz_tx_fifo
[] = {
35 IWL_BZ_EDCA_TX_FIFO_VO
,
36 IWL_BZ_EDCA_TX_FIFO_VI
,
37 IWL_BZ_EDCA_TX_FIFO_BE
,
38 IWL_BZ_EDCA_TX_FIFO_BK
,
39 IWL_BZ_TRIG_TX_FIFO_VO
,
40 IWL_BZ_TRIG_TX_FIFO_VI
,
41 IWL_BZ_TRIG_TX_FIFO_BE
,
42 IWL_BZ_TRIG_TX_FIFO_BK
,
45 struct iwl_mvm_mac_iface_iterator_data
{
47 struct ieee80211_vif
*vif
;
48 unsigned long available_mac_ids
[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER
)];
49 unsigned long available_tsf_ids
[BITS_TO_LONGS(NUM_TSF_IDS
)];
50 enum iwl_tsf_id preferred_tsf
;
54 static void iwl_mvm_mac_tsf_id_iter(void *_data
, u8
*mac
,
55 struct ieee80211_vif
*vif
)
57 struct iwl_mvm_mac_iface_iterator_data
*data
= _data
;
58 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
61 /* Skip the interface for which we are trying to assign a tsf_id */
66 * The TSF is a hardware/firmware resource, there are 4 and
67 * the driver should assign and free them as needed. However,
68 * there are cases where 2 MACs should share the same TSF ID
69 * for the purpose of clock sync, an optimization to avoid
70 * clock drift causing overlapping TBTTs/DTIMs for a GO and
71 * client in the system.
73 * The firmware will decide according to the MAC type which
74 * will be the leader and follower. Clients that need to sync
75 * with a remote station will be the leader, and an AP or GO
76 * will be the follower.
78 * Depending on the new interface type it can be following
79 * or become the leader of an existing interface.
81 switch (data
->vif
->type
) {
82 case NL80211_IFTYPE_STATION
:
84 * The new interface is a client, so if the one we're iterating
85 * is an AP, and the beacon interval of the AP is a multiple or
86 * divisor of the beacon interval of the client, the same TSF
87 * should be used to avoid drift between the new client and
88 * existing AP. The existing AP will get drift updates from the
89 * new client context in this case.
91 if (vif
->type
!= NL80211_IFTYPE_AP
||
92 data
->preferred_tsf
!= NUM_TSF_IDS
||
93 !test_bit(mvmvif
->tsf_id
, data
->available_tsf_ids
))
96 min_bi
= min(data
->vif
->bss_conf
.beacon_int
,
97 vif
->bss_conf
.beacon_int
);
102 if ((data
->vif
->bss_conf
.beacon_int
-
103 vif
->bss_conf
.beacon_int
) % min_bi
== 0) {
104 data
->preferred_tsf
= mvmvif
->tsf_id
;
109 case NL80211_IFTYPE_AP
:
111 * The new interface is AP/GO, so if its beacon interval is a
112 * multiple or a divisor of the beacon interval of an existing
113 * interface, it should get drift updates from an existing
114 * client or use the same TSF as an existing GO. There's no
115 * drift between TSFs internally but if they used different
116 * TSFs then a new client MAC could update one of them and
117 * cause drift that way.
119 if ((vif
->type
!= NL80211_IFTYPE_AP
&&
120 vif
->type
!= NL80211_IFTYPE_STATION
) ||
121 data
->preferred_tsf
!= NUM_TSF_IDS
||
122 !test_bit(mvmvif
->tsf_id
, data
->available_tsf_ids
))
125 min_bi
= min(data
->vif
->bss_conf
.beacon_int
,
126 vif
->bss_conf
.beacon_int
);
131 if ((data
->vif
->bss_conf
.beacon_int
-
132 vif
->bss_conf
.beacon_int
) % min_bi
== 0) {
133 data
->preferred_tsf
= mvmvif
->tsf_id
;
139 * For all other interface types there's no need to
140 * take drift into account. Either they're exclusive
141 * like IBSS and monitor, or we don't care much about
142 * their TSF (like P2P Device), but we won't be able
143 * to share the TSF resource.
149 * Unless we exited above, we can't share the TSF resource
150 * that the virtual interface we're iterating over is using
151 * with the new one, so clear the available bit and if this
152 * was the preferred one, reset that as well.
154 __clear_bit(mvmvif
->tsf_id
, data
->available_tsf_ids
);
156 if (data
->preferred_tsf
== mvmvif
->tsf_id
)
157 data
->preferred_tsf
= NUM_TSF_IDS
;
160 static void iwl_mvm_mac_iface_iterator(void *_data
, u8
*mac
,
161 struct ieee80211_vif
*vif
)
163 struct iwl_mvm_mac_iface_iterator_data
*data
= _data
;
164 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
166 /* Iterator may already find the interface being added -- skip it */
167 if (vif
== data
->vif
) {
168 data
->found_vif
= true;
172 /* Mark MAC IDs as used by clearing the available bit, and
173 * (below) mark TSFs as used if their existing use is not
174 * compatible with the new interface type.
175 * No locking or atomic bit operations are needed since the
176 * data is on the stack of the caller function.
178 __clear_bit(mvmvif
->id
, data
->available_mac_ids
);
180 /* find a suitable tsf_id */
181 iwl_mvm_mac_tsf_id_iter(_data
, mac
, vif
);
184 void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm
*mvm
,
185 struct ieee80211_vif
*vif
)
187 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
188 struct iwl_mvm_mac_iface_iterator_data data
= {
191 .available_tsf_ids
= { (1 << NUM_TSF_IDS
) - 1 },
192 /* no preference yet */
193 .preferred_tsf
= NUM_TSF_IDS
,
196 ieee80211_iterate_active_interfaces_atomic(
197 mvm
->hw
, IEEE80211_IFACE_ITER_RESUME_ALL
,
198 iwl_mvm_mac_tsf_id_iter
, &data
);
200 if (data
.preferred_tsf
!= NUM_TSF_IDS
)
201 mvmvif
->tsf_id
= data
.preferred_tsf
;
202 else if (!test_bit(mvmvif
->tsf_id
, data
.available_tsf_ids
))
203 mvmvif
->tsf_id
= find_first_bit(data
.available_tsf_ids
,
207 int iwl_mvm_mac_ctxt_init(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
209 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
210 struct iwl_mvm_mac_iface_iterator_data data
= {
213 .available_mac_ids
= { (1 << NUM_MAC_INDEX_DRIVER
) - 1 },
214 .available_tsf_ids
= { (1 << NUM_TSF_IDS
) - 1 },
215 /* no preference yet */
216 .preferred_tsf
= NUM_TSF_IDS
,
221 lockdep_assert_held(&mvm
->mutex
);
224 * Allocate a MAC ID and a TSF for this MAC, along with the queues
225 * and other resources.
229 * Before the iterator, we start with all MAC IDs and TSFs available.
231 * During iteration, all MAC IDs are cleared that are in use by other
232 * virtual interfaces, and all TSF IDs are cleared that can't be used
233 * by this new virtual interface because they're used by an interface
234 * that can't share it with the new one.
235 * At the same time, we check if there's a preferred TSF in the case
236 * that we should share it with another interface.
239 /* MAC ID 0 should be used only for the managed/IBSS vif with non-MLO
242 if (!mvm
->mld_api_is_used
) {
244 case NL80211_IFTYPE_ADHOC
:
246 case NL80211_IFTYPE_STATION
:
251 __clear_bit(0, data
.available_mac_ids
);
255 ieee80211_iterate_active_interfaces_atomic(
256 mvm
->hw
, IEEE80211_IFACE_ITER_RESUME_ALL
,
257 iwl_mvm_mac_iface_iterator
, &data
);
260 * In the case we're getting here during resume, it's similar to
261 * firmware restart, and with RESUME_ALL the iterator will find
262 * the vif being added already.
263 * We don't want to reassign any IDs in either case since doing
264 * so would probably assign different IDs (as interfaces aren't
265 * necessarily added in the same order), but the old IDs were
266 * preserved anyway, so skip ID assignment for both resume and
272 /* Therefore, in recovery, we can't get here */
273 if (WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART
, &mvm
->status
)))
276 mvmvif
->id
= find_first_bit(data
.available_mac_ids
,
277 NUM_MAC_INDEX_DRIVER
);
278 if (mvmvif
->id
== NUM_MAC_INDEX_DRIVER
) {
279 IWL_ERR(mvm
, "Failed to init MAC context - no free ID!\n");
284 if (data
.preferred_tsf
!= NUM_TSF_IDS
)
285 mvmvif
->tsf_id
= data
.preferred_tsf
;
287 mvmvif
->tsf_id
= find_first_bit(data
.available_tsf_ids
,
289 if (mvmvif
->tsf_id
== NUM_TSF_IDS
) {
290 IWL_ERR(mvm
, "Failed to init MAC context - no free TSF!\n");
297 INIT_LIST_HEAD(&mvmvif
->time_event_data
.list
);
298 mvmvif
->time_event_data
.id
= TE_MAX
;
299 mvmvif
->roc_activity
= ROC_NUM_ACTIVITIES
;
301 iwl_mvm_init_link(&mvmvif
->deflink
);
303 /* No need to allocate data queues to P2P Device MAC and NAN.*/
304 if (vif
->type
== NL80211_IFTYPE_P2P_DEVICE
)
307 /* Allocate the CAB queue for softAP and GO interfaces */
308 if (vif
->type
== NL80211_IFTYPE_AP
||
309 vif
->type
== NL80211_IFTYPE_ADHOC
) {
311 * For TVQM this will be overwritten later with the FW assigned
312 * queue value (when queue is enabled).
314 mvmvif
->deflink
.cab_queue
= IWL_MVM_DQA_GCAST_QUEUE
;
320 memset(mvmvif
, 0, sizeof(struct iwl_mvm_vif
));
324 static void iwl_mvm_ack_rates(struct iwl_mvm
*mvm
,
325 struct ieee80211_vif
*vif
,
326 enum nl80211_band band
,
327 u8
*cck_rates
, u8
*ofdm_rates
)
329 struct ieee80211_supported_band
*sband
;
330 unsigned long basic
= vif
->bss_conf
.basic_rates
;
331 int lowest_present_ofdm
= 100;
332 int lowest_present_cck
= 100;
337 sband
= mvm
->hw
->wiphy
->bands
[band
];
339 for_each_set_bit(i
, &basic
, BITS_PER_LONG
) {
340 int hw
= sband
->bitrates
[i
].hw_value
;
341 if (hw
>= IWL_FIRST_OFDM_RATE
) {
342 ofdm
|= BIT(hw
- IWL_FIRST_OFDM_RATE
);
343 if (lowest_present_ofdm
> hw
)
344 lowest_present_ofdm
= hw
;
346 BUILD_BUG_ON(IWL_FIRST_CCK_RATE
!= 0);
349 if (lowest_present_cck
> hw
)
350 lowest_present_cck
= hw
;
355 * Now we've got the basic rates as bitmaps in the ofdm and cck
356 * variables. This isn't sufficient though, as there might not
357 * be all the right rates in the bitmap. E.g. if the only basic
358 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
359 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
361 * [...] a STA responding to a received frame shall transmit
362 * its Control Response frame [...] at the highest rate in the
363 * BSSBasicRateSet parameter that is less than or equal to the
364 * rate of the immediately previous frame in the frame exchange
365 * sequence ([...]) and that is of the same modulation class
366 * ([...]) as the received frame. If no rate contained in the
367 * BSSBasicRateSet parameter meets these conditions, then the
368 * control frame sent in response to a received frame shall be
369 * transmitted at the highest mandatory rate of the PHY that is
370 * less than or equal to the rate of the received frame, and
371 * that is of the same modulation class as the received frame.
373 * As a consequence, we need to add all mandatory rates that are
374 * lower than all of the basic rates to these bitmaps.
377 if (IWL_RATE_24M_INDEX
< lowest_present_ofdm
)
378 ofdm
|= IWL_RATE_BIT_MSK(24) >> IWL_FIRST_OFDM_RATE
;
379 if (IWL_RATE_12M_INDEX
< lowest_present_ofdm
)
380 ofdm
|= IWL_RATE_BIT_MSK(12) >> IWL_FIRST_OFDM_RATE
;
381 /* 6M already there or needed so always add */
382 ofdm
|= IWL_RATE_BIT_MSK(6) >> IWL_FIRST_OFDM_RATE
;
385 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
387 * - if no CCK rates are basic, it must be ERP since there must
388 * be some basic rates at all, so they're OFDM => ERP PHY
389 * (or we're in 5 GHz, and the cck bitmap will never be used)
390 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M
391 * - if 5.5M is basic, 1M and 2M are mandatory
392 * - if 2M is basic, 1M is mandatory
393 * - if 1M is basic, that's the only valid ACK rate.
394 * As a consequence, it's not as complicated as it sounds, just add
395 * any lower rates to the ACK rate bitmap.
397 if (IWL_RATE_11M_INDEX
< lowest_present_cck
)
398 cck
|= IWL_RATE_BIT_MSK(11) >> IWL_FIRST_CCK_RATE
;
399 if (IWL_RATE_5M_INDEX
< lowest_present_cck
)
400 cck
|= IWL_RATE_BIT_MSK(5) >> IWL_FIRST_CCK_RATE
;
401 if (IWL_RATE_2M_INDEX
< lowest_present_cck
)
402 cck
|= IWL_RATE_BIT_MSK(2) >> IWL_FIRST_CCK_RATE
;
403 /* 1M already there or needed so always add */
404 cck
|= IWL_RATE_BIT_MSK(1) >> IWL_FIRST_CCK_RATE
;
410 void iwl_mvm_set_fw_basic_rates(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
411 struct iwl_mvm_vif_link_info
*link_info
,
412 __le32
*cck_rates
, __le32
*ofdm_rates
)
414 struct iwl_mvm_phy_ctxt
*phy_ctxt
;
415 u8 cck_ack_rates
= 0, ofdm_ack_rates
= 0;
416 enum nl80211_band band
= NL80211_BAND_2GHZ
;
418 phy_ctxt
= link_info
->phy_ctxt
;
419 if (phy_ctxt
&& phy_ctxt
->channel
)
420 band
= phy_ctxt
->channel
->band
;
422 iwl_mvm_ack_rates(mvm
, vif
, band
, &cck_ack_rates
, &ofdm_ack_rates
);
424 *cck_rates
= cpu_to_le32((u32
)cck_ack_rates
);
425 *ofdm_rates
= cpu_to_le32((u32
)ofdm_ack_rates
);
428 void iwl_mvm_set_fw_protection_flags(struct iwl_mvm
*mvm
,
429 struct ieee80211_vif
*vif
,
430 struct ieee80211_bss_conf
*link_conf
,
431 __le32
*protection_flags
, u32 ht_flag
,
434 /* for both sta and ap, ht_operation_mode hold the protection_mode */
435 u8 protection_mode
= link_conf
->ht_operation_mode
&
436 IEEE80211_HT_OP_MODE_PROTECTION
;
437 bool ht_enabled
= !!(link_conf
->ht_operation_mode
&
438 IEEE80211_HT_OP_MODE_PROTECTION
);
440 if (link_conf
->use_cts_prot
)
441 *protection_flags
|= cpu_to_le32(tgg_flag
);
443 IWL_DEBUG_RATE(mvm
, "use_cts_prot %d, ht_operation_mode %d\n",
444 link_conf
->use_cts_prot
,
445 link_conf
->ht_operation_mode
);
450 IWL_DEBUG_RATE(mvm
, "protection mode set to %d\n", protection_mode
);
452 * See section 9.23.3.1 of IEEE 80211-2012.
453 * Nongreenfield HT STAs Present is not supported.
455 switch (protection_mode
) {
456 case IEEE80211_HT_OP_MODE_PROTECTION_NONE
:
458 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER
:
459 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED
:
460 *protection_flags
|= cpu_to_le32(ht_flag
);
462 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ
:
463 /* Protect when channel wider than 20MHz */
464 if (link_conf
->chanreq
.oper
.width
> NL80211_CHAN_WIDTH_20
)
465 *protection_flags
|= cpu_to_le32(ht_flag
);
468 IWL_ERR(mvm
, "Illegal protection mode %d\n",
474 void iwl_mvm_set_fw_qos_params(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
475 struct ieee80211_bss_conf
*link_conf
,
476 struct iwl_ac_qos
*ac
, __le32
*qos_flags
)
478 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
479 struct iwl_mvm_vif_link_info
*mvm_link
=
480 mvmvif
->link
[link_conf
->link_id
];
486 for (i
= 0; i
< IEEE80211_NUM_ACS
; i
++) {
487 u8 txf
= iwl_mvm_mac_ac_to_tx_fifo(mvm
, i
);
488 u8 ucode_ac
= iwl_mvm_mac80211_ac_to_ucode_ac(i
);
490 ac
[ucode_ac
].cw_min
=
491 cpu_to_le16(mvm_link
->queue_params
[i
].cw_min
);
492 ac
[ucode_ac
].cw_max
=
493 cpu_to_le16(mvm_link
->queue_params
[i
].cw_max
);
494 ac
[ucode_ac
].edca_txop
=
495 cpu_to_le16(mvm_link
->queue_params
[i
].txop
* 32);
496 ac
[ucode_ac
].aifsn
= mvm_link
->queue_params
[i
].aifs
;
497 ac
[ucode_ac
].fifos_mask
= BIT(txf
);
501 *qos_flags
|= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA
);
503 if (link_conf
->chanreq
.oper
.width
!= NL80211_CHAN_WIDTH_20_NOHT
)
504 *qos_flags
|= cpu_to_le32(MAC_QOS_FLG_TGN
);
507 int iwl_mvm_get_mac_type(struct ieee80211_vif
*vif
)
509 u32 mac_type
= FW_MAC_TYPE_BSS_STA
;
512 case NL80211_IFTYPE_STATION
:
514 mac_type
= FW_MAC_TYPE_P2P_STA
;
516 mac_type
= FW_MAC_TYPE_BSS_STA
;
518 case NL80211_IFTYPE_AP
:
519 mac_type
= FW_MAC_TYPE_GO
;
521 case NL80211_IFTYPE_MONITOR
:
522 mac_type
= FW_MAC_TYPE_LISTENER
;
524 case NL80211_IFTYPE_P2P_DEVICE
:
525 mac_type
= FW_MAC_TYPE_P2P_DEVICE
;
527 case NL80211_IFTYPE_ADHOC
:
528 mac_type
= FW_MAC_TYPE_IBSS
;
536 static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm
*mvm
,
537 struct ieee80211_vif
*vif
,
538 struct iwl_mac_ctx_cmd
*cmd
,
539 const u8
*bssid_override
,
542 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
543 const u8
*bssid
= bssid_override
?: vif
->bss_conf
.bssid
;
546 cmd
->id_and_color
= cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
548 cmd
->action
= cpu_to_le32(action
);
549 cmd
->mac_type
= cpu_to_le32(iwl_mvm_get_mac_type(vif
));
551 cmd
->tsf_id
= cpu_to_le32(mvmvif
->tsf_id
);
553 memcpy(cmd
->node_addr
, vif
->addr
, ETH_ALEN
);
556 memcpy(cmd
->bssid_addr
, bssid
, ETH_ALEN
);
558 eth_broadcast_addr(cmd
->bssid_addr
);
560 iwl_mvm_set_fw_basic_rates(mvm
, vif
, &mvmvif
->deflink
, &cmd
->cck_rates
,
563 cmd
->cck_short_preamble
=
564 cpu_to_le32(vif
->bss_conf
.use_short_preamble
?
565 MAC_FLG_SHORT_PREAMBLE
: 0);
567 cpu_to_le32(vif
->bss_conf
.use_short_slot
?
568 MAC_FLG_SHORT_SLOT
: 0);
570 cmd
->filter_flags
= 0;
572 iwl_mvm_set_fw_qos_params(mvm
, vif
, &vif
->bss_conf
, cmd
->ac
,
575 /* The fw does not distinguish between ht and fat */
576 ht_flag
= MAC_PROT_FLG_HT_PROT
| MAC_PROT_FLG_FAT_PROT
;
577 iwl_mvm_set_fw_protection_flags(mvm
, vif
, &vif
->bss_conf
,
578 &cmd
->protection_flags
,
579 ht_flag
, MAC_PROT_FLG_TGG_PROTECT
);
582 static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm
*mvm
,
583 struct iwl_mac_ctx_cmd
*cmd
)
585 int ret
= iwl_mvm_send_cmd_pdu(mvm
, MAC_CONTEXT_CMD
, 0,
588 IWL_ERR(mvm
, "Failed to send MAC_CONTEXT_CMD (action:%d): %d\n",
589 le32_to_cpu(cmd
->action
), ret
);
593 void iwl_mvm_set_fw_dtim_tbtt(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
594 struct ieee80211_bss_conf
*link_conf
,
595 __le64
*dtim_tsf
, __le32
*dtim_time
,
596 __le32
*assoc_beacon_arrive_time
)
601 * The DTIM count counts down, so when it is N that means N
602 * more beacon intervals happen until the DTIM TBTT. Therefore
603 * add this to the current time. If that ends up being in the
604 * future, the firmware will handle it.
606 * Also note that the system_timestamp (which we get here as
607 * "sync_device_ts") and TSF timestamp aren't at exactly the
608 * same offset in the frame -- the TSF is at the first symbol
609 * of the TSF, the system timestamp is at signal acquisition
610 * time. This means there's an offset between them of at most
611 * a few hundred microseconds (24 * 8 bits + PLCP time gives
612 * 384us in the longest case), this is currently not relevant
613 * as the firmware wakes up around 2ms before the TBTT.
615 dtim_offs
= link_conf
->sync_dtim_count
*
616 link_conf
->beacon_int
;
617 /* convert TU to usecs */
621 cpu_to_le64(link_conf
->sync_tsf
+ dtim_offs
);
623 cpu_to_le32(link_conf
->sync_device_ts
+ dtim_offs
);
624 *assoc_beacon_arrive_time
=
625 cpu_to_le32(link_conf
->sync_device_ts
);
627 IWL_DEBUG_INFO(mvm
, "DTIM TBTT is 0x%llx/0x%x, offset %d\n",
628 le64_to_cpu(*dtim_tsf
),
629 le32_to_cpu(*dtim_time
),
633 __le32
iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(struct iwl_mvm
*mvm
,
634 struct ieee80211_vif
*vif
)
636 struct ieee80211_p2p_noa_attr
*noa
=
637 &vif
->bss_conf
.p2p_noa_attr
;
639 return cpu_to_le32(noa
->oppps_ctwindow
&
640 IEEE80211_P2P_OPPPS_CTWINDOW_MASK
);
643 u32
iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(struct iwl_mvm
*mvm
,
644 struct ieee80211_vif
*vif
)
648 if (vif
->bss_conf
.twt_requester
&& IWL_MVM_USE_TWT
)
649 twt_policy
|= TWT_SUPPORTED
;
650 if (vif
->bss_conf
.twt_protected
)
651 twt_policy
|= PROTECTED_TWT_SUPPORTED
;
652 if (vif
->bss_conf
.twt_broadcast
)
653 twt_policy
|= BROADCAST_TWT_SUPPORTED
;
658 static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm
*mvm
,
659 struct ieee80211_vif
*vif
,
660 u32 action
, bool force_assoc_off
,
661 const u8
*bssid_override
)
663 struct iwl_mac_ctx_cmd cmd
= {};
664 struct iwl_mac_data_sta
*ctxt_sta
;
666 WARN_ON(vif
->type
!= NL80211_IFTYPE_STATION
);
668 /* Fill the common data for all mac context types */
669 iwl_mvm_mac_ctxt_cmd_common(mvm
, vif
, &cmd
, bssid_override
, action
);
672 * We always want to hear MCAST frames, if we're not authorized yet,
675 cmd
.filter_flags
|= cpu_to_le32(MAC_FILTER_ACCEPT_GRP
);
679 iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(mvm
, vif
);
681 ctxt_sta
= &cmd
.p2p_sta
.sta
;
686 /* We need the dtim_period to set the MAC as associated */
687 if (vif
->cfg
.assoc
&& vif
->bss_conf
.dtim_period
&&
689 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
691 iwl_mvm_set_fw_dtim_tbtt(mvm
, vif
, &vif
->bss_conf
,
693 &ctxt_sta
->dtim_time
,
694 &ctxt_sta
->assoc_beacon_arrive_time
);
696 ctxt_sta
->is_assoc
= cpu_to_le32(1);
698 if (!mvmvif
->authorized
&&
699 fw_has_capa(&mvm
->fw
->ucode_capa
,
700 IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO
))
701 ctxt_sta
->data_policy
|=
702 cpu_to_le32(COEX_HIGH_PRIORITY_ENABLE
);
704 ctxt_sta
->is_assoc
= cpu_to_le32(0);
706 /* Allow beacons to pass through as long as we are not
707 * associated, or we do not have dtim period information.
709 cmd
.filter_flags
|= cpu_to_le32(MAC_FILTER_IN_BEACON
);
712 ctxt_sta
->bi
= cpu_to_le32(vif
->bss_conf
.beacon_int
);
713 ctxt_sta
->dtim_interval
= cpu_to_le32(vif
->bss_conf
.beacon_int
*
714 vif
->bss_conf
.dtim_period
);
716 ctxt_sta
->listen_interval
= cpu_to_le32(mvm
->hw
->conf
.listen_interval
);
717 ctxt_sta
->assoc_id
= cpu_to_le32(vif
->cfg
.aid
);
719 if (vif
->probe_req_reg
&& vif
->cfg
.assoc
&& vif
->p2p
)
720 cmd
.filter_flags
|= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST
);
722 if (vif
->bss_conf
.he_support
&& !iwlwifi_mod_params
.disable_11ax
) {
723 cmd
.filter_flags
|= cpu_to_le32(MAC_FILTER_IN_11AX
);
724 ctxt_sta
->data_policy
|=
725 cpu_to_le32(iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm
, vif
));
729 return iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
732 static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm
*mvm
,
733 struct ieee80211_vif
*vif
,
736 struct iwl_mac_ctx_cmd cmd
= {};
737 u32 tfd_queue_msk
= 0;
740 WARN_ON(vif
->type
!= NL80211_IFTYPE_MONITOR
);
742 iwl_mvm_mac_ctxt_cmd_common(mvm
, vif
, &cmd
, NULL
, action
);
744 cmd
.filter_flags
= cpu_to_le32(MAC_FILTER_IN_PROMISC
|
745 MAC_FILTER_IN_CONTROL_AND_MGMT
|
746 MAC_FILTER_IN_BEACON
|
747 MAC_FILTER_IN_PROBE_REQUEST
|
748 MAC_FILTER_IN_CRC32
|
749 MAC_FILTER_ACCEPT_GRP
);
750 ieee80211_hw_set(mvm
->hw
, RX_INCLUDES_FCS
);
753 * the queue mask is only relevant for old TX API, and
754 * mvm->snif_queue isn't set here (it's still set to
755 * IWL_MVM_INVALID_QUEUE so the BIT() of it is UB)
757 if (!iwl_mvm_has_new_tx_api(mvm
))
758 tfd_queue_msk
= BIT(mvm
->snif_queue
);
760 /* Allocate sniffer station */
761 ret
= iwl_mvm_allocate_int_sta(mvm
, &mvm
->snif_sta
, tfd_queue_msk
,
762 vif
->type
, IWL_STA_GENERAL_PURPOSE
);
766 return iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
769 static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm
*mvm
,
770 struct ieee80211_vif
*vif
,
773 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
774 struct iwl_mac_ctx_cmd cmd
= {};
776 WARN_ON(vif
->type
!= NL80211_IFTYPE_ADHOC
);
778 iwl_mvm_mac_ctxt_cmd_common(mvm
, vif
, &cmd
, NULL
, action
);
780 cmd
.filter_flags
= cpu_to_le32(MAC_FILTER_IN_BEACON
|
781 MAC_FILTER_IN_PROBE_REQUEST
|
782 MAC_FILTER_ACCEPT_GRP
);
784 /* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
785 cmd
.ibss
.bi
= cpu_to_le32(vif
->bss_conf
.beacon_int
);
787 /* TODO: Assumes that the beacon id == mac context id */
788 cmd
.ibss
.beacon_template
= cpu_to_le32(mvmvif
->id
);
790 return iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
793 struct iwl_mvm_go_iterator_data
{
797 static void iwl_mvm_go_iterator(void *_data
, u8
*mac
, struct ieee80211_vif
*vif
)
799 struct iwl_mvm_go_iterator_data
*data
= _data
;
800 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
802 if (vif
->type
== NL80211_IFTYPE_AP
&& vif
->p2p
&&
803 mvmvif
->ap_ibss_active
)
804 data
->go_active
= true;
807 __le32
iwl_mac_ctxt_p2p_dev_has_extended_disc(struct iwl_mvm
*mvm
,
808 struct ieee80211_vif
*vif
)
810 struct iwl_mvm_go_iterator_data data
= {};
813 * This flag should be set to true when the P2P Device is
814 * discoverable and there is at least another active P2P GO. Settings
815 * this flag will allow the P2P Device to be discoverable on other
816 * channels in addition to its listen channel.
817 * Note that this flag should not be set in other cases as it opens the
818 * Rx filters on all MAC and increases the number of interrupts.
820 ieee80211_iterate_active_interfaces_atomic(
821 mvm
->hw
, IEEE80211_IFACE_ITER_RESUME_ALL
,
822 iwl_mvm_go_iterator
, &data
);
824 return cpu_to_le32(data
.go_active
? 1 : 0);
827 static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm
*mvm
,
828 struct ieee80211_vif
*vif
,
831 struct iwl_mac_ctx_cmd cmd
= {};
833 WARN_ON(vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
);
835 iwl_mvm_mac_ctxt_cmd_common(mvm
, vif
, &cmd
, NULL
, action
);
837 cmd
.p2p_dev
.is_disc_extended
=
838 iwl_mac_ctxt_p2p_dev_has_extended_disc(mvm
, vif
);
840 /* Override the filter flags to accept only probe requests */
841 cmd
.filter_flags
= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST
);
843 return iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
846 void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm
*mvm
,
847 __le32
*tim_index
, __le32
*tim_size
,
848 u8
*beacon
, u32 frame_size
)
851 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)beacon
;
853 /* The index is relative to frame start but we start looking at the
854 * variable-length part of the beacon. */
855 tim_idx
= mgmt
->u
.beacon
.variable
- beacon
;
857 /* Parse variable-length elements of beacon to find WLAN_EID_TIM */
858 while ((tim_idx
< (frame_size
- 2)) &&
859 (beacon
[tim_idx
] != WLAN_EID_TIM
))
860 tim_idx
+= beacon
[tim_idx
+1] + 2;
862 /* If TIM field was found, set variables */
863 if ((tim_idx
< (frame_size
- 1)) && (beacon
[tim_idx
] == WLAN_EID_TIM
)) {
864 *tim_index
= cpu_to_le32(tim_idx
);
865 *tim_size
= cpu_to_le32((u32
)beacon
[tim_idx
+ 1]);
867 IWL_WARN(mvm
, "Unable to find TIM Element in beacon\n");
871 u32
iwl_mvm_find_ie_offset(u8
*beacon
, u8 eid
, u32 frame_size
)
873 struct ieee80211_mgmt
*mgmt
= (void *)beacon
;
876 if (WARN_ON_ONCE(frame_size
<= (mgmt
->u
.beacon
.variable
- beacon
)))
879 frame_size
-= mgmt
->u
.beacon
.variable
- beacon
;
881 ie
= cfg80211_find_ie(eid
, mgmt
->u
.beacon
.variable
, frame_size
);
888 u8
iwl_mvm_mac_ctxt_get_lowest_rate(struct iwl_mvm
*mvm
,
889 struct ieee80211_tx_info
*info
,
890 struct ieee80211_vif
*vif
)
892 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
893 struct ieee80211_supported_band
*sband
;
894 unsigned long basic
= vif
->bss_conf
.basic_rates
;
895 u16 lowest_cck
= IWL_RATE_COUNT
, lowest_ofdm
= IWL_RATE_COUNT
;
896 u32 link_id
= u32_get_bits(info
->control
.flags
,
897 IEEE80211_TX_CTRL_MLO_LINK
);
898 u8 band
= info
->band
;
902 if (link_id
== IEEE80211_LINK_UNSPECIFIED
&& ieee80211_vif_is_mld(vif
)) {
903 for (i
= 0; i
< ARRAY_SIZE(mvmvif
->link
); i
++) {
904 if (!mvmvif
->link
[i
])
906 /* shouldn't do this when >1 link is active */
907 WARN_ON_ONCE(link_id
!= IEEE80211_LINK_UNSPECIFIED
);
912 if (link_id
< IEEE80211_LINK_UNSPECIFIED
) {
913 struct ieee80211_bss_conf
*link_conf
;
916 link_conf
= rcu_dereference(vif
->link_conf
[link_id
]);
918 basic
= link_conf
->basic_rates
;
919 if (link_conf
->chanreq
.oper
.chan
)
920 band
= link_conf
->chanreq
.oper
.chan
->band
;
925 sband
= mvm
->hw
->wiphy
->bands
[band
];
926 for_each_set_bit(i
, &basic
, BITS_PER_LONG
) {
927 u16 hw
= sband
->bitrates
[i
].hw_value
;
929 if (hw
>= IWL_FIRST_OFDM_RATE
) {
930 if (lowest_ofdm
> hw
)
932 } else if (lowest_cck
> hw
) {
937 if (band
== NL80211_BAND_2GHZ
&& !vif
->p2p
&&
938 vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
&&
939 !(info
->flags
& IEEE80211_TX_CTL_NO_CCK_RATE
)) {
940 if (lowest_cck
!= IWL_RATE_COUNT
)
942 else if (lowest_ofdm
!= IWL_RATE_COUNT
)
945 rate
= IWL_RATE_1M_INDEX
;
946 } else if (lowest_ofdm
!= IWL_RATE_COUNT
) {
949 rate
= IWL_RATE_6M_INDEX
;
955 u16
iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw
*fw
, u8 rate_idx
)
957 u16 flags
= iwl_mvm_mac80211_idx_to_hwrate(fw
, rate_idx
);
958 bool is_new_rate
= iwl_fw_lookup_cmd_ver(fw
, BEACON_TEMPLATE_CMD
, 0) > 10;
960 if (rate_idx
<= IWL_FIRST_CCK_RATE
)
961 flags
|= is_new_rate
? IWL_MAC_BEACON_CCK
962 : IWL_MAC_BEACON_CCK_V1
;
967 u8
iwl_mvm_mac_ctxt_get_beacon_rate(struct iwl_mvm
*mvm
,
968 struct ieee80211_tx_info
*info
,
969 struct ieee80211_vif
*vif
)
971 struct ieee80211_supported_band
*sband
=
972 mvm
->hw
->wiphy
->bands
[info
->band
];
973 u32 legacy
= vif
->bss_conf
.beacon_tx_rate
.control
[info
->band
].legacy
;
975 /* if beacon rate was configured try using it */
976 if (hweight32(legacy
) == 1) {
977 u32 rate
= ffs(legacy
) - 1;
979 return sband
->bitrates
[rate
].hw_value
;
982 return iwl_mvm_mac_ctxt_get_lowest_rate(mvm
, info
, vif
);
985 static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm
*mvm
,
986 struct ieee80211_vif
*vif
,
987 struct sk_buff
*beacon
,
988 struct iwl_tx_cmd
*tx
)
990 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
991 struct ieee80211_tx_info
*info
;
995 info
= IEEE80211_SKB_CB(beacon
);
997 /* Set up TX command fields */
998 tx
->len
= cpu_to_le16((u16
)beacon
->len
);
999 tx
->sta_id
= mvmvif
->deflink
.bcast_sta
.sta_id
;
1000 tx
->life_time
= cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE
);
1001 tx_flags
= TX_CMD_FLG_SEQ_CTL
| TX_CMD_FLG_TSF
;
1003 iwl_mvm_bt_coex_tx_prio(mvm
, (void *)beacon
->data
, info
, 0) <<
1004 TX_CMD_FLG_BT_PRIO_POS
;
1005 tx
->tx_flags
= cpu_to_le32(tx_flags
);
1007 if (!fw_has_capa(&mvm
->fw
->ucode_capa
,
1008 IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION
)) {
1009 iwl_mvm_toggle_tx_ant(mvm
, &mvm
->mgmt_last_antenna_idx
);
1012 cpu_to_le32(BIT(mvm
->mgmt_last_antenna_idx
) <<
1016 rate
= iwl_mvm_mac_ctxt_get_beacon_rate(mvm
, info
, vif
);
1019 cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(mvm
->fw
, rate
));
1020 if (rate
== IWL_FIRST_CCK_RATE
)
1021 tx
->rate_n_flags
|= cpu_to_le32(RATE_MCS_CCK_MSK_V1
);
1025 int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm
*mvm
,
1026 struct sk_buff
*beacon
,
1027 void *data
, int len
)
1029 struct iwl_host_cmd cmd
= {
1030 .id
= BEACON_TEMPLATE_CMD
,
1036 cmd
.dataflags
[0] = 0;
1037 cmd
.len
[1] = beacon
->len
;
1038 cmd
.data
[1] = beacon
->data
;
1039 cmd
.dataflags
[1] = IWL_HCMD_DFL_DUP
;
1041 return iwl_mvm_send_cmd(mvm
, &cmd
);
1044 static int iwl_mvm_mac_ctxt_send_beacon_v6(struct iwl_mvm
*mvm
,
1045 struct ieee80211_vif
*vif
,
1046 struct sk_buff
*beacon
)
1048 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1049 struct iwl_mac_beacon_cmd_v6 beacon_cmd
= {};
1051 iwl_mvm_mac_ctxt_set_tx(mvm
, vif
, beacon
, &beacon_cmd
.tx
);
1053 beacon_cmd
.template_id
= cpu_to_le32((u32
)mvmvif
->id
);
1055 if (vif
->type
== NL80211_IFTYPE_AP
)
1056 iwl_mvm_mac_ctxt_set_tim(mvm
, &beacon_cmd
.tim_idx
,
1057 &beacon_cmd
.tim_size
,
1058 beacon
->data
, beacon
->len
);
1060 return iwl_mvm_mac_ctxt_send_beacon_cmd(mvm
, beacon
, &beacon_cmd
,
1061 sizeof(beacon_cmd
));
1064 static int iwl_mvm_mac_ctxt_send_beacon_v7(struct iwl_mvm
*mvm
,
1065 struct ieee80211_vif
*vif
,
1066 struct sk_buff
*beacon
)
1068 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1069 struct iwl_mac_beacon_cmd_v7 beacon_cmd
= {};
1071 iwl_mvm_mac_ctxt_set_tx(mvm
, vif
, beacon
, &beacon_cmd
.tx
);
1073 beacon_cmd
.template_id
= cpu_to_le32((u32
)mvmvif
->id
);
1075 if (vif
->type
== NL80211_IFTYPE_AP
)
1076 iwl_mvm_mac_ctxt_set_tim(mvm
, &beacon_cmd
.tim_idx
,
1077 &beacon_cmd
.tim_size
,
1078 beacon
->data
, beacon
->len
);
1080 beacon_cmd
.csa_offset
=
1081 cpu_to_le32(iwl_mvm_find_ie_offset(beacon
->data
,
1082 WLAN_EID_CHANNEL_SWITCH
,
1084 beacon_cmd
.ecsa_offset
=
1085 cpu_to_le32(iwl_mvm_find_ie_offset(beacon
->data
,
1086 WLAN_EID_EXT_CHANSWITCH_ANN
,
1089 return iwl_mvm_mac_ctxt_send_beacon_cmd(mvm
, beacon
, &beacon_cmd
,
1090 sizeof(beacon_cmd
));
1093 bool iwl_mvm_enable_fils(struct iwl_mvm
*mvm
,
1094 struct ieee80211_chanctx_conf
*ctx
)
1096 if (IWL_MVM_DISABLE_AP_FILS
)
1099 if (cfg80211_channel_is_psc(ctx
->def
.chan
))
1102 return (ctx
->def
.chan
->band
== NL80211_BAND_6GHZ
&&
1103 ctx
->def
.width
>= NL80211_CHAN_WIDTH_80
);
1106 static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm
*mvm
,
1107 struct ieee80211_vif
*vif
,
1108 struct sk_buff
*beacon
,
1109 struct ieee80211_bss_conf
*link_conf
)
1111 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1112 struct ieee80211_tx_info
*info
= IEEE80211_SKB_CB(beacon
);
1113 struct iwl_mac_beacon_cmd beacon_cmd
= {};
1114 u8 rate
= iwl_mvm_mac_ctxt_get_beacon_rate(mvm
, info
, vif
);
1116 struct ieee80211_chanctx_conf
*ctx
;
1118 flags
= iwl_mvm_mac_ctxt_get_beacon_flags(mvm
->fw
, rate
);
1120 /* Enable FILS on PSC channels only */
1122 ctx
= rcu_dereference(link_conf
->chanctx_conf
);
1123 channel
= ieee80211_frequency_to_channel(ctx
->def
.chan
->center_freq
);
1124 WARN_ON(channel
== 0);
1125 if (iwl_mvm_enable_fils(mvm
, ctx
)) {
1126 flags
|= iwl_fw_lookup_cmd_ver(mvm
->fw
, BEACON_TEMPLATE_CMD
,
1128 IWL_MAC_BEACON_FILS
:
1129 IWL_MAC_BEACON_FILS_V1
;
1130 beacon_cmd
.short_ssid
=
1131 cpu_to_le32(~crc32_le(~0, vif
->cfg
.ssid
,
1132 vif
->cfg
.ssid_len
));
1136 beacon_cmd
.flags
= cpu_to_le16(flags
);
1137 beacon_cmd
.byte_cnt
= cpu_to_le16((u16
)beacon
->len
);
1139 if (WARN_ON(!mvmvif
->link
[link_conf
->link_id
]))
1142 if (iwl_fw_lookup_cmd_ver(mvm
->fw
, BEACON_TEMPLATE_CMD
, 0) > 12)
1143 beacon_cmd
.link_id
=
1144 cpu_to_le32(mvmvif
->link
[link_conf
->link_id
]->fw_link_id
);
1146 beacon_cmd
.link_id
= cpu_to_le32((u32
)mvmvif
->id
);
1148 if (vif
->type
== NL80211_IFTYPE_AP
)
1149 iwl_mvm_mac_ctxt_set_tim(mvm
, &beacon_cmd
.tim_idx
,
1150 &beacon_cmd
.tim_size
,
1151 beacon
->data
, beacon
->len
);
1153 beacon_cmd
.csa_offset
=
1154 cpu_to_le32(iwl_mvm_find_ie_offset(beacon
->data
,
1155 WLAN_EID_CHANNEL_SWITCH
,
1157 beacon_cmd
.ecsa_offset
=
1158 cpu_to_le32(iwl_mvm_find_ie_offset(beacon
->data
,
1159 WLAN_EID_EXT_CHANSWITCH_ANN
,
1162 if (vif
->type
== NL80211_IFTYPE_AP
&&
1163 iwl_fw_lookup_cmd_ver(mvm
->fw
, BEACON_TEMPLATE_CMD
, 0) >= 14)
1164 beacon_cmd
.btwt_offset
=
1165 cpu_to_le32(iwl_mvm_find_ie_offset(beacon
->data
,
1169 return iwl_mvm_mac_ctxt_send_beacon_cmd(mvm
, beacon
, &beacon_cmd
,
1170 sizeof(beacon_cmd
));
1173 static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm
*mvm
,
1174 struct ieee80211_vif
*vif
,
1175 struct sk_buff
*beacon
,
1176 struct ieee80211_bss_conf
*link_conf
)
1178 if (WARN_ON(!beacon
))
1181 if (IWL_MVM_NON_TRANSMITTING_AP
)
1184 if (!fw_has_capa(&mvm
->fw
->ucode_capa
,
1185 IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD
))
1186 return iwl_mvm_mac_ctxt_send_beacon_v6(mvm
, vif
, beacon
);
1188 if (fw_has_api(&mvm
->fw
->ucode_capa
,
1189 IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE
))
1190 return iwl_mvm_mac_ctxt_send_beacon_v9(mvm
, vif
, beacon
,
1193 return iwl_mvm_mac_ctxt_send_beacon_v7(mvm
, vif
, beacon
);
1196 /* The beacon template for the AP/GO/IBSS has changed and needs update */
1197 int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm
*mvm
,
1198 struct ieee80211_vif
*vif
,
1199 struct ieee80211_bss_conf
*link_conf
)
1201 struct sk_buff
*beacon
;
1204 WARN_ON(vif
->type
!= NL80211_IFTYPE_AP
&&
1205 vif
->type
!= NL80211_IFTYPE_ADHOC
);
1207 beacon
= ieee80211_beacon_get_template(mvm
->hw
, vif
, NULL
,
1208 link_conf
->link_id
);
1212 #ifdef CONFIG_IWLWIFI_DEBUGFS
1213 if (mvm
->beacon_inject_active
) {
1214 dev_kfree_skb(beacon
);
1219 ret
= iwl_mvm_mac_ctxt_send_beacon(mvm
, vif
, beacon
, link_conf
);
1220 dev_kfree_skb(beacon
);
1224 struct iwl_mvm_mac_ap_iterator_data
{
1225 struct iwl_mvm
*mvm
;
1226 struct ieee80211_vif
*vif
;
1227 u32 beacon_device_ts
;
1231 /* Find the beacon_device_ts and beacon_int for a managed interface */
1232 static void iwl_mvm_mac_ap_iterator(void *_data
, u8
*mac
,
1233 struct ieee80211_vif
*vif
)
1235 struct iwl_mvm_mac_ap_iterator_data
*data
= _data
;
1237 if (vif
->type
!= NL80211_IFTYPE_STATION
|| !vif
->cfg
.assoc
)
1240 /* Station client has higher priority over P2P client*/
1241 if (vif
->p2p
&& data
->beacon_device_ts
)
1244 data
->beacon_device_ts
= vif
->bss_conf
.sync_device_ts
;
1245 data
->beacon_int
= vif
->bss_conf
.beacon_int
;
1249 * Fill the filter flags for mac context of type AP or P2P GO.
1251 void iwl_mvm_mac_ctxt_cmd_ap_set_filter_flags(struct iwl_mvm
*mvm
,
1252 struct iwl_mvm_vif
*mvmvif
,
1253 __le32
*filter_flags
,
1254 int accept_probe_req_flag
,
1255 int accept_beacon_flag
)
1258 * in AP mode, pass probe requests and beacons from other APs
1259 * (needed for ht protection); when there're no any associated
1260 * station don't ask FW to pass beacons to prevent unnecessary
1263 *filter_flags
|= cpu_to_le32(accept_probe_req_flag
);
1264 if (mvmvif
->ap_assoc_sta_count
|| !mvm
->drop_bcn_ap_mode
) {
1265 *filter_flags
|= cpu_to_le32(accept_beacon_flag
);
1266 IWL_DEBUG_HC(mvm
, "Asking FW to pass beacons\n");
1268 IWL_DEBUG_HC(mvm
, "No need to receive beacons\n");
1273 * Fill the specific data for mac context of type AP of P2P GO
1275 static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm
*mvm
,
1276 struct ieee80211_vif
*vif
,
1277 struct iwl_mac_ctx_cmd
*cmd
,
1278 struct iwl_mac_data_ap
*ctxt_ap
,
1281 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1282 struct iwl_mvm_mac_ap_iterator_data data
= {
1285 .beacon_device_ts
= 0
1288 /* in AP mode, the MCAST FIFO takes the EDCA params from VO */
1289 cmd
->ac
[IWL_MVM_TX_FIFO_VO
].fifos_mask
|= BIT(IWL_MVM_TX_FIFO_MCAST
);
1291 iwl_mvm_mac_ctxt_cmd_ap_set_filter_flags(mvm
, mvmvif
,
1293 MAC_FILTER_IN_PROBE_REQUEST
,
1294 MAC_FILTER_IN_BEACON
);
1296 ctxt_ap
->bi
= cpu_to_le32(vif
->bss_conf
.beacon_int
);
1297 ctxt_ap
->dtim_interval
= cpu_to_le32(vif
->bss_conf
.beacon_int
*
1298 vif
->bss_conf
.dtim_period
);
1300 if (!fw_has_api(&mvm
->fw
->ucode_capa
,
1301 IWL_UCODE_TLV_API_STA_TYPE
))
1302 ctxt_ap
->mcast_qid
= cpu_to_le32(mvmvif
->deflink
.cab_queue
);
1305 * Only set the beacon time when the MAC is being added, when we
1306 * just modify the MAC then we should keep the time -- the firmware
1307 * can otherwise have a "jumping" TBTT.
1311 * If there is a station/P2P client interface which is
1312 * associated, set the AP's TBTT far enough from the station's
1313 * TBTT. Otherwise, set it to the current system time
1315 ieee80211_iterate_active_interfaces_atomic(
1316 mvm
->hw
, IEEE80211_IFACE_ITER_RESUME_ALL
,
1317 iwl_mvm_mac_ap_iterator
, &data
);
1319 if (data
.beacon_device_ts
) {
1320 u32 rand
= get_random_u32_inclusive(36, 63);
1321 mvmvif
->ap_beacon_time
= data
.beacon_device_ts
+
1322 ieee80211_tu_to_usec(data
.beacon_int
* rand
/
1325 mvmvif
->ap_beacon_time
= iwl_mvm_get_systime(mvm
);
1329 ctxt_ap
->beacon_time
= cpu_to_le32(mvmvif
->ap_beacon_time
);
1330 ctxt_ap
->beacon_tsf
= 0; /* unused */
1332 /* TODO: Assume that the beacon id == mac context id */
1333 ctxt_ap
->beacon_template
= cpu_to_le32(mvmvif
->id
);
1336 static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm
*mvm
,
1337 struct ieee80211_vif
*vif
,
1340 struct iwl_mac_ctx_cmd cmd
= {};
1342 WARN_ON(vif
->type
!= NL80211_IFTYPE_AP
|| vif
->p2p
);
1344 /* Fill the common data for all mac context types */
1345 iwl_mvm_mac_ctxt_cmd_common(mvm
, vif
, &cmd
, NULL
, action
);
1347 /* Fill the data specific for ap mode */
1348 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm
, vif
, &cmd
, &cmd
.ap
,
1349 action
== FW_CTXT_ACTION_ADD
);
1351 return iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
1354 static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm
*mvm
,
1355 struct ieee80211_vif
*vif
,
1358 struct iwl_mac_ctx_cmd cmd
= {};
1359 struct ieee80211_p2p_noa_attr
*noa
= &vif
->bss_conf
.p2p_noa_attr
;
1361 WARN_ON(vif
->type
!= NL80211_IFTYPE_AP
|| !vif
->p2p
);
1363 /* Fill the common data for all mac context types */
1364 iwl_mvm_mac_ctxt_cmd_common(mvm
, vif
, &cmd
, NULL
, action
);
1366 /* Fill the data specific for GO mode */
1367 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm
, vif
, &cmd
, &cmd
.go
.ap
,
1368 action
== FW_CTXT_ACTION_ADD
);
1370 cmd
.go
.ctwin
= cpu_to_le32(noa
->oppps_ctwindow
&
1371 IEEE80211_P2P_OPPPS_CTWINDOW_MASK
);
1372 cmd
.go
.opp_ps_enabled
=
1373 cpu_to_le32(!!(noa
->oppps_ctwindow
&
1374 IEEE80211_P2P_OPPPS_ENABLE_BIT
));
1376 return iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
1379 static int iwl_mvm_mac_ctx_send(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
1380 u32 action
, bool force_assoc_off
,
1381 const u8
*bssid_override
)
1383 switch (vif
->type
) {
1384 case NL80211_IFTYPE_STATION
:
1385 return iwl_mvm_mac_ctxt_cmd_sta(mvm
, vif
, action
,
1388 case NL80211_IFTYPE_AP
:
1390 return iwl_mvm_mac_ctxt_cmd_ap(mvm
, vif
, action
);
1392 return iwl_mvm_mac_ctxt_cmd_go(mvm
, vif
, action
);
1393 case NL80211_IFTYPE_MONITOR
:
1394 return iwl_mvm_mac_ctxt_cmd_listener(mvm
, vif
, action
);
1395 case NL80211_IFTYPE_P2P_DEVICE
:
1396 return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm
, vif
, action
);
1397 case NL80211_IFTYPE_ADHOC
:
1398 return iwl_mvm_mac_ctxt_cmd_ibss(mvm
, vif
, action
);
1406 int iwl_mvm_mac_ctxt_add(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
1408 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1411 if (WARN_ONCE(mvmvif
->uploaded
, "Adding active MAC %pM/%d\n",
1412 vif
->addr
, ieee80211_vif_type_p2p(vif
)))
1415 ret
= iwl_mvm_mac_ctx_send(mvm
, vif
, FW_CTXT_ACTION_ADD
,
1420 /* will only do anything at resume from D3 time */
1421 iwl_mvm_set_last_nonqos_seq(mvm
, vif
);
1423 mvmvif
->uploaded
= true;
1427 int iwl_mvm_mac_ctxt_changed(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
1428 bool force_assoc_off
, const u8
*bssid_override
)
1430 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1432 if (WARN_ONCE(!mvmvif
->uploaded
, "Changing inactive MAC %pM/%d\n",
1433 vif
->addr
, ieee80211_vif_type_p2p(vif
)))
1436 return iwl_mvm_mac_ctx_send(mvm
, vif
, FW_CTXT_ACTION_MODIFY
,
1437 force_assoc_off
, bssid_override
);
1440 int iwl_mvm_mac_ctxt_remove(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
1442 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1443 struct iwl_mac_ctx_cmd cmd
;
1446 if (WARN_ONCE(!mvmvif
->uploaded
, "Removing inactive MAC %pM/%d\n",
1447 vif
->addr
, ieee80211_vif_type_p2p(vif
)))
1450 memset(&cmd
, 0, sizeof(cmd
));
1452 cmd
.id_and_color
= cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
1454 cmd
.action
= cpu_to_le32(FW_CTXT_ACTION_REMOVE
);
1456 ret
= iwl_mvm_mac_ctxt_send_cmd(mvm
, &cmd
);
1460 mvmvif
->uploaded
= false;
1462 if (vif
->type
== NL80211_IFTYPE_MONITOR
) {
1463 __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS
, mvm
->hw
->flags
);
1464 iwl_mvm_dealloc_snif_sta(mvm
);
1470 static void iwl_mvm_csa_count_down(struct iwl_mvm
*mvm
,
1471 struct ieee80211_vif
*csa_vif
, u32 gp2
,
1474 struct iwl_mvm_vif
*mvmvif
=
1475 iwl_mvm_vif_from_mac80211(csa_vif
);
1477 /* Don't start to countdown from a failed beacon */
1478 if (!tx_success
&& !mvmvif
->csa_countdown
)
1481 mvmvif
->csa_countdown
= true;
1483 if (!ieee80211_beacon_cntdwn_is_complete(csa_vif
, 0)) {
1484 int c
= ieee80211_beacon_update_cntdwn(csa_vif
, 0);
1486 iwl_mvm_mac_ctxt_beacon_changed(mvm
, csa_vif
,
1487 &csa_vif
->bss_conf
);
1489 !iwl_mvm_te_scheduled(&mvmvif
->time_event_data
) && gp2
&&
1491 u32 rel_time
= (c
+ 1) *
1492 csa_vif
->bss_conf
.beacon_int
-
1493 IWL_MVM_CHANNEL_SWITCH_TIME_GO
;
1494 u32 apply_time
= gp2
+ rel_time
* 1024;
1496 iwl_mvm_schedule_csa_period(mvm
, csa_vif
,
1497 IWL_MVM_CHANNEL_SWITCH_TIME_GO
-
1498 IWL_MVM_CHANNEL_SWITCH_MARGIN
,
1501 } else if (!iwl_mvm_te_scheduled(&mvmvif
->time_event_data
)) {
1502 /* we don't have CSA NoA scheduled yet, switch now */
1503 ieee80211_csa_finish(csa_vif
, 0);
1504 RCU_INIT_POINTER(mvm
->csa_vif
, NULL
);
1508 void iwl_mvm_rx_beacon_notif(struct iwl_mvm
*mvm
,
1509 struct iwl_rx_cmd_buffer
*rxb
)
1511 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1512 unsigned int pkt_len
= iwl_rx_packet_payload_len(pkt
);
1513 struct iwl_extended_beacon_notif
*beacon
= (void *)pkt
->data
;
1514 struct iwl_extended_beacon_notif_v5
*beacon_v5
= (void *)pkt
->data
;
1515 struct ieee80211_vif
*csa_vif
;
1516 struct ieee80211_vif
*tx_blocked_vif
;
1517 struct agg_tx_status
*agg_status
;
1520 lockdep_assert_held(&mvm
->mutex
);
1522 mvm
->ap_last_beacon_gp2
= le32_to_cpu(beacon
->gp2
);
1524 if (!iwl_mvm_is_short_beacon_notif_supported(mvm
)) {
1525 struct iwl_tx_resp
*beacon_notify_hdr
=
1526 &beacon_v5
->beacon_notify_hdr
;
1528 if (unlikely(pkt_len
< sizeof(*beacon_v5
)))
1531 mvm
->ibss_manager
= beacon_v5
->ibss_mgr_status
!= 0;
1532 agg_status
= iwl_mvm_get_agg_status(mvm
, beacon_notify_hdr
);
1533 status
= le16_to_cpu(agg_status
->status
) & TX_STATUS_MSK
;
1535 "beacon status %#x retries:%d tsf:0x%016llX gp2:0x%X rate:%d\n",
1536 status
, beacon_notify_hdr
->failure_frame
,
1537 le64_to_cpu(beacon
->tsf
),
1538 mvm
->ap_last_beacon_gp2
,
1539 le32_to_cpu(beacon_notify_hdr
->initial_rate
));
1541 if (unlikely(pkt_len
< sizeof(*beacon
)))
1544 mvm
->ibss_manager
= beacon
->ibss_mgr_status
!= 0;
1545 status
= le32_to_cpu(beacon
->status
) & TX_STATUS_MSK
;
1547 "beacon status %#x tsf:0x%016llX gp2:0x%X\n",
1548 status
, le64_to_cpu(beacon
->tsf
),
1549 mvm
->ap_last_beacon_gp2
);
1552 csa_vif
= rcu_dereference_protected(mvm
->csa_vif
,
1553 lockdep_is_held(&mvm
->mutex
));
1554 if (unlikely(csa_vif
&& csa_vif
->bss_conf
.csa_active
))
1555 iwl_mvm_csa_count_down(mvm
, csa_vif
, mvm
->ap_last_beacon_gp2
,
1556 (status
== TX_STATUS_SUCCESS
));
1558 tx_blocked_vif
= rcu_dereference_protected(mvm
->csa_tx_blocked_vif
,
1559 lockdep_is_held(&mvm
->mutex
));
1560 if (unlikely(tx_blocked_vif
)) {
1561 struct iwl_mvm_vif
*mvmvif
=
1562 iwl_mvm_vif_from_mac80211(tx_blocked_vif
);
1565 * The channel switch is started and we have blocked the
1566 * stations. If this is the first beacon (the timeout wasn't
1567 * set), set the unblock timeout, otherwise countdown
1569 if (!mvm
->csa_tx_block_bcn_timeout
)
1570 mvm
->csa_tx_block_bcn_timeout
=
1571 IWL_MVM_CS_UNBLOCK_TX_TIMEOUT
;
1573 mvm
->csa_tx_block_bcn_timeout
--;
1575 /* Check if the timeout is expired, and unblock tx */
1576 if (mvm
->csa_tx_block_bcn_timeout
== 0) {
1577 iwl_mvm_modify_all_sta_disable_tx(mvm
, mvmvif
, false);
1578 RCU_INIT_POINTER(mvm
->csa_tx_blocked_vif
, NULL
);
1584 iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm
*mvm
,
1585 const struct iwl_missed_beacons_notif
*mb
,
1586 struct iwl_rx_packet
*pkt
)
1588 struct iwl_fw_dbg_trigger_missed_bcon
*bcon_trig
;
1589 struct iwl_fw_dbg_trigger_tlv
*trigger
;
1590 u32 stop_trig_missed_bcon
, stop_trig_missed_bcon_since_rx
;
1591 u32 rx_missed_bcon
, rx_missed_bcon_since_rx
;
1592 struct ieee80211_vif
*vif
;
1593 /* Id can be mac/link id depending on the notification version */
1594 u32 id
= le32_to_cpu(mb
->link_id
);
1595 union iwl_dbg_tlv_tp_data tp_data
= { .fw_pkt
= pkt
};
1598 u8 notif_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
, LEGACY_GROUP
,
1599 MISSED_BEACONS_NOTIFICATION
,
1601 u8 new_notif_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
, MAC_CONF_GROUP
,
1602 MISSED_BEACONS_NOTIF
, 0);
1603 struct ieee80211_bss_conf
*bss_conf
;
1605 /* If the firmware uses the new notification (from MAC_CONF_GROUP),
1606 * refer to that notification's version.
1607 * Note that the new notification from MAC_CONF_GROUP starts from
1611 notif_ver
= new_notif_ver
;
1613 /* before version four the ID in the notification refers to mac ID */
1614 if (notif_ver
< 4) {
1615 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, id
, false);
1616 bss_conf
= &vif
->bss_conf
;
1618 bss_conf
= iwl_mvm_rcu_fw_link_id_to_link_conf(mvm
, id
, false);
1623 vif
= bss_conf
->vif
;
1624 link_id
= bss_conf
->link_id
;
1628 "missed bcn %s_id=%u, consecutive=%u (%u)\n",
1629 notif_ver
< 4 ? "mac" : "link",
1631 le32_to_cpu(mb
->consec_missed_beacons
),
1632 le32_to_cpu(mb
->consec_missed_beacons_since_last_rx
));
1637 mac_type
= iwl_mvm_get_mac_type(vif
);
1639 IWL_DEBUG_INFO(mvm
, "missed beacon mac_type=%u,\n", mac_type
);
1641 mvm
->trans
->dbg
.dump_file_name_ext_valid
= true;
1642 snprintf(mvm
->trans
->dbg
.dump_file_name_ext
, IWL_FW_INI_MAX_NAME
,
1643 "MacId_%d_MacType_%d", id
, mac_type
);
1645 rx_missed_bcon
= le32_to_cpu(mb
->consec_missed_beacons
);
1646 rx_missed_bcon_since_rx
=
1647 le32_to_cpu(mb
->consec_missed_beacons_since_last_rx
);
1649 * TODO: the threshold should be adjusted based on latency conditions,
1650 * and/or in case of a CS flow on one of the other AP vifs.
1652 if (rx_missed_bcon
>= IWL_MVM_MISSED_BEACONS_THRESHOLD_LONG
) {
1653 if (rx_missed_bcon_since_rx
>= IWL_MVM_MISSED_BEACONS_SINCE_RX_THOLD
) {
1654 iwl_mvm_connection_loss(mvm
, vif
, "missed beacons");
1657 "missed beacons exceeds threshold, but receiving data. Stay connected, Expect bugs.\n");
1659 "missed_beacons:%d, missed_beacons_since_rx:%d\n",
1660 rx_missed_bcon
, rx_missed_bcon_since_rx
);
1662 } else if (link_id
>= 0 && hweight16(vif
->active_links
) > 1) {
1663 u32 bss_param_ch_cnt_link_id
=
1664 bss_conf
->bss_param_ch_cnt_link_id
;
1665 u32 scnd_lnk_bcn_lost
= 0;
1667 if (notif_ver
>= 5 &&
1669 le32_to_cpu(mb
->other_link_id
) == IWL_MVM_FW_LINK_ID_INVALID
,
1670 "No data for other link id but we are in EMLSR active_links: 0x%x\n",
1673 le32_to_cpu(mb
->consec_missed_beacons_other_link
);
1675 /* Exit EMLSR if we lost more than
1676 * IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH beacons on boths links
1677 * OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH on any link.
1678 * OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED
1679 * and the link's bss_param_ch_count has changed.
1681 if ((rx_missed_bcon
>= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS
&&
1682 scnd_lnk_bcn_lost
>= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS
) ||
1683 rx_missed_bcon
>= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH
||
1684 (bss_param_ch_cnt_link_id
!= link_id
&&
1685 rx_missed_bcon
>= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED
))
1686 iwl_mvm_exit_esr(mvm
, vif
,
1687 IWL_MVM_ESR_EXIT_MISSED_BEACON
,
1688 iwl_mvm_get_primary_link(vif
));
1689 } else if (rx_missed_bcon_since_rx
> IWL_MVM_MISSED_BEACONS_THRESHOLD
) {
1690 if (!iwl_mvm_has_new_tx_api(mvm
))
1691 ieee80211_beacon_loss(vif
);
1693 ieee80211_cqm_beacon_loss_notify(vif
, GFP_ATOMIC
);
1695 /* try to switch links, no-op if we don't have MLO */
1696 iwl_mvm_int_mlo_scan(mvm
, vif
);
1699 iwl_dbg_tlv_time_point(&mvm
->fwrt
,
1700 IWL_FW_INI_TIME_POINT_MISSED_BEACONS
, &tp_data
);
1702 trigger
= iwl_fw_dbg_trigger_on(&mvm
->fwrt
, ieee80211_vif_to_wdev(vif
),
1703 FW_DBG_TRIGGER_MISSED_BEACONS
);
1707 bcon_trig
= (void *)trigger
->data
;
1708 stop_trig_missed_bcon
= le32_to_cpu(bcon_trig
->stop_consec_missed_bcon
);
1709 stop_trig_missed_bcon_since_rx
=
1710 le32_to_cpu(bcon_trig
->stop_consec_missed_bcon_since_rx
);
1712 /* TODO: implement start trigger */
1714 if (rx_missed_bcon_since_rx
>= stop_trig_missed_bcon_since_rx
||
1715 rx_missed_bcon
>= stop_trig_missed_bcon
)
1716 iwl_fw_dbg_collect_trig(&mvm
->fwrt
, trigger
, NULL
);
1719 void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm
*mvm
,
1720 struct iwl_rx_cmd_buffer
*rxb
)
1722 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1724 iwl_mvm_handle_missed_beacons_notif(mvm
, (const void *)pkt
->data
, pkt
);
1727 void iwl_mvm_rx_missed_beacons_notif_legacy(struct iwl_mvm
*mvm
,
1728 struct iwl_rx_cmd_buffer
*rxb
)
1730 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1731 const struct iwl_missed_beacons_notif_v4
*mb_v4
=
1732 (const void *)pkt
->data
;
1733 struct iwl_missed_beacons_notif mb
= {
1734 .link_id
= mb_v4
->link_id
,
1735 .consec_missed_beacons
= mb_v4
->consec_missed_beacons
,
1736 .consec_missed_beacons_since_last_rx
=
1737 mb_v4
->consec_missed_beacons_since_last_rx
,
1738 .other_link_id
= cpu_to_le32(IWL_MVM_FW_LINK_ID_INVALID
),
1741 iwl_mvm_handle_missed_beacons_notif(mvm
, &mb
, pkt
);
1744 void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm
*mvm
,
1745 struct iwl_rx_cmd_buffer
*rxb
)
1747 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1748 unsigned int pkt_len
= iwl_rx_packet_payload_len(pkt
);
1749 struct iwl_stored_beacon_notif_common
*sb
= (void *)pkt
->data
;
1750 struct ieee80211_rx_status rx_status
;
1751 struct sk_buff
*skb
;
1753 u32 size
= le32_to_cpu(sb
->byte_count
);
1754 int ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
,
1755 WIDE_ID(PROT_OFFLOAD_GROUP
, STORED_BEACON_NTF
),
1761 /* handle per-version differences */
1763 struct iwl_stored_beacon_notif_v2
*sb_v2
= (void *)pkt
->data
;
1765 if (pkt_len
< struct_size(sb_v2
, data
, size
))
1770 struct iwl_stored_beacon_notif_v3
*sb_v3
= (void *)pkt
->data
;
1772 if (pkt_len
< struct_size(sb_v3
, data
, size
))
1778 skb
= alloc_skb(size
, GFP_ATOMIC
);
1780 IWL_ERR(mvm
, "alloc_skb failed\n");
1784 /* update rx_status according to the notification's metadata */
1785 memset(&rx_status
, 0, sizeof(rx_status
));
1786 rx_status
.mactime
= le64_to_cpu(sb
->tsf
);
1787 /* TSF as indicated by the firmware is at INA time */
1788 rx_status
.flag
|= RX_FLAG_MACTIME_PLCP_START
;
1789 rx_status
.device_timestamp
= le32_to_cpu(sb
->system_time
);
1791 (sb
->band
& cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24
)) ?
1792 NL80211_BAND_2GHZ
: NL80211_BAND_5GHZ
;
1794 ieee80211_channel_to_frequency(le16_to_cpu(sb
->channel
),
1798 skb_put_data(skb
, data
, size
);
1799 memcpy(IEEE80211_SKB_RXCB(skb
), &rx_status
, sizeof(rx_status
));
1801 /* pass it as regular rx to mac80211 */
1802 ieee80211_rx_napi(mvm
->hw
, NULL
, skb
, NULL
);
1805 void iwl_mvm_probe_resp_data_notif(struct iwl_mvm
*mvm
,
1806 struct iwl_rx_cmd_buffer
*rxb
)
1808 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1809 struct iwl_probe_resp_data_notif
*notif
= (void *)pkt
->data
;
1810 struct iwl_probe_resp_data
*old_data
, *new_data
;
1811 u32 id
= le32_to_cpu(notif
->mac_id
);
1812 struct ieee80211_vif
*vif
;
1813 struct iwl_mvm_vif
*mvmvif
;
1815 IWL_DEBUG_INFO(mvm
, "Probe response data notif: noa %d, csa %d\n",
1816 notif
->noa_active
, notif
->csa_counter
);
1818 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, id
, false);
1822 mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1824 new_data
= kzalloc(sizeof(*new_data
), GFP_KERNEL
);
1828 memcpy(&new_data
->notif
, notif
, sizeof(new_data
->notif
));
1830 /* noa_attr contains 1 reserved byte, need to substruct it */
1831 new_data
->noa_len
= sizeof(struct ieee80211_vendor_ie
) +
1832 sizeof(new_data
->notif
.noa_attr
) - 1;
1835 * If it's a one time NoA, only one descriptor is needed,
1836 * adjust the length according to len_low.
1838 if (new_data
->notif
.noa_attr
.len_low
==
1839 sizeof(struct ieee80211_p2p_noa_desc
) + 2)
1840 new_data
->noa_len
-= sizeof(struct ieee80211_p2p_noa_desc
);
1842 old_data
= rcu_dereference_protected(mvmvif
->deflink
.probe_resp_data
,
1843 lockdep_is_held(&mvmvif
->mvm
->mutex
));
1844 rcu_assign_pointer(mvmvif
->deflink
.probe_resp_data
, new_data
);
1847 kfree_rcu(old_data
, rcu_head
);
1849 if (notif
->csa_counter
!= IWL_PROBE_RESP_DATA_NO_CSA
&&
1850 notif
->csa_counter
>= 1)
1851 ieee80211_beacon_set_cntdwn(vif
, notif
->csa_counter
);
1854 void iwl_mvm_channel_switch_start_notif(struct iwl_mvm
*mvm
,
1855 struct iwl_rx_cmd_buffer
*rxb
)
1857 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1858 struct ieee80211_vif
*csa_vif
, *vif
;
1859 struct iwl_mvm_vif
*mvmvif
, *csa_mvmvif
;
1860 u32 id_n_color
, csa_id
;
1861 /* save mac_id or link_id to use later to cancel csa if needed */
1863 u32 mac_link_id
= 0;
1864 u8 notif_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
, MAC_CONF_GROUP
,
1865 CHANNEL_SWITCH_START_NOTIF
, 0);
1870 if (notif_ver
< 3) {
1871 struct iwl_channel_switch_start_notif_v1
*notif
= (void *)pkt
->data
;
1874 id_n_color
= le32_to_cpu(notif
->id_and_color
);
1875 mac_id
= id_n_color
& FW_CTXT_ID_MSK
;
1877 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, mac_id
, true);
1882 csa_active
= vif
->bss_conf
.csa_active
;
1884 struct iwl_channel_switch_start_notif
*notif
= (void *)pkt
->data
;
1885 u32 link_id
= le32_to_cpu(notif
->link_id
);
1886 struct ieee80211_bss_conf
*bss_conf
=
1887 iwl_mvm_rcu_fw_link_id_to_link_conf(mvm
, link_id
, true);
1893 mac_link_id
= bss_conf
->link_id
;
1894 vif
= bss_conf
->vif
;
1895 csa_active
= bss_conf
->csa_active
;
1898 mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1900 id_n_color
= FW_CMD_ID_AND_COLOR(mvmvif
->id
, mvmvif
->color
);
1902 switch (vif
->type
) {
1903 case NL80211_IFTYPE_AP
:
1904 csa_vif
= rcu_dereference(mvm
->csa_vif
);
1905 if (WARN_ON(!csa_vif
|| !csa_vif
->bss_conf
.csa_active
||
1909 csa_mvmvif
= iwl_mvm_vif_from_mac80211(csa_vif
);
1910 csa_id
= FW_CMD_ID_AND_COLOR(csa_mvmvif
->id
, csa_mvmvif
->color
);
1911 if (WARN(csa_id
!= id_n_color
,
1912 "channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
1913 csa_id
, id_n_color
))
1916 IWL_DEBUG_INFO(mvm
, "Channel Switch Started Notification\n");
1918 schedule_delayed_work(&mvm
->cs_tx_unblock_dwork
,
1919 msecs_to_jiffies(IWL_MVM_CS_UNBLOCK_TX_TIMEOUT
*
1920 csa_vif
->bss_conf
.beacon_int
));
1922 ieee80211_csa_finish(csa_vif
, 0);
1926 RCU_INIT_POINTER(mvm
->csa_vif
, NULL
);
1928 case NL80211_IFTYPE_STATION
:
1930 * if we don't know about an ongoing channel switch,
1931 * make sure FW cancels it
1933 if (iwl_fw_lookup_notif_ver(mvm
->fw
, MAC_CONF_GROUP
,
1934 CHANNEL_SWITCH_ERROR_NOTIF
,
1935 0) && !csa_active
) {
1936 IWL_DEBUG_INFO(mvm
, "Channel Switch was canceled\n");
1937 iwl_mvm_cancel_channel_switch(mvm
, vif
, id
);
1941 iwl_mvm_csa_client_absent(mvm
, vif
);
1942 cancel_delayed_work(&mvmvif
->csa_work
);
1943 ieee80211_chswitch_done(vif
, true, mac_link_id
);
1946 /* should never happen */
1954 void iwl_mvm_channel_switch_error_notif(struct iwl_mvm
*mvm
,
1955 struct iwl_rx_cmd_buffer
*rxb
)
1957 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1958 struct iwl_channel_switch_error_notif
*notif
= (void *)pkt
->data
;
1959 struct ieee80211_vif
*vif
;
1960 u32 id
= le32_to_cpu(notif
->link_id
);
1961 u32 csa_err_mask
= le32_to_cpu(notif
->csa_err_mask
);
1964 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, id
, true);
1970 IWL_DEBUG_INFO(mvm
, "FW reports CSA error: id=%u, csa_err_mask=%u\n",
1972 if (csa_err_mask
& (CS_ERR_COUNT_ERROR
|
1973 CS_ERR_LONG_DELAY_AFTER_CS
|
1974 CS_ERR_TX_BLOCK_TIMER_EXPIRED
))
1975 ieee80211_channel_switch_disconnect(vif
, true);
1979 void iwl_mvm_rx_missed_vap_notif(struct iwl_mvm
*mvm
,
1980 struct iwl_rx_cmd_buffer
*rxb
)
1982 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
1983 struct iwl_missed_vap_notif
*mb
= (void *)pkt
->data
;
1984 struct ieee80211_vif
*vif
;
1985 u32 id
= le32_to_cpu(mb
->mac_id
);
1988 "missed_vap notify mac_id=%u, num_beacon_intervals_elapsed=%u, profile_periodicity=%u\n",
1989 le32_to_cpu(mb
->mac_id
),
1990 mb
->num_beacon_intervals_elapsed
,
1991 mb
->profile_periodicity
);
1995 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, id
, true);
1997 iwl_mvm_connection_loss(mvm
, vif
, "missed vap beacon");