1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
7 #include <linux/etherdevice.h>
8 #include <net/mac80211.h>
9 #include <linux/crc32.h>
12 #include "fw/api/scan.h"
15 #define IWL_DENSE_EBS_SCAN_RATIO 5
16 #define IWL_SPARSE_EBS_SCAN_RATIO 1
18 #define IWL_SCAN_DWELL_ACTIVE 10
19 #define IWL_SCAN_DWELL_PASSIVE 110
20 #define IWL_SCAN_DWELL_FRAGMENTED 44
21 #define IWL_SCAN_DWELL_EXTENDED 90
22 #define IWL_SCAN_NUM_OF_FRAGS 3
24 /* adaptive dwell max budget time [TU] for full scan */
25 #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
26 /* adaptive dwell max budget time [TU] for directed scan */
27 #define IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
28 /* adaptive dwell default high band APs number */
29 #define IWL_SCAN_ADWELL_DEFAULT_HB_N_APS 8
30 /* adaptive dwell default low band APs number */
31 #define IWL_SCAN_ADWELL_DEFAULT_LB_N_APS 2
32 /* adaptive dwell default APs number in social channels (1, 6, 11) */
33 #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
34 /* number of scan channels */
35 #define IWL_SCAN_NUM_CHANNELS 112
36 /* adaptive dwell number of APs override mask for p2p friendly GO */
37 #define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT BIT(20)
38 /* adaptive dwell number of APs override mask for social channels */
39 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT BIT(21)
40 /* adaptive dwell number of APs override for p2p friendly GO channels */
41 #define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
42 /* adaptive dwell number of APs override for social channels */
43 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
45 /* minimal number of 2GHz and 5GHz channels in the regular scan request */
46 #define IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS 4
48 /* Number of iterations on the channel for mei filtered scan */
49 #define IWL_MEI_SCAN_NUM_ITER 5U
51 #define WFA_TPC_IE_LEN 9
53 struct iwl_mvm_scan_timing_params
{
58 static struct iwl_mvm_scan_timing_params scan_timing
[] = {
59 [IWL_SCAN_TYPE_UNASSOC
] = {
63 [IWL_SCAN_TYPE_WILD
] = {
67 [IWL_SCAN_TYPE_MILD
] = {
71 [IWL_SCAN_TYPE_FRAGMENTED
] = {
75 [IWL_SCAN_TYPE_FAST_BALANCE
] = {
81 struct iwl_mvm_scan_params
{
82 /* For CDB this is low band scan type, for non-CDB - type. */
83 enum iwl_mvm_scan_type type
;
84 enum iwl_mvm_scan_type hb_type
;
88 struct cfg80211_ssid
*ssids
;
89 struct ieee80211_channel
**channels
;
96 struct iwl_scan_probe_req preq
;
97 struct cfg80211_match_set
*match_sets
;
99 struct cfg80211_sched_scan_plan
*scan_plans
;
101 struct cfg80211_scan_6ghz_params
*scan_6ghz_params
;
104 bool enable_6ghz_passive
;
105 bool respect_p2p_go
, respect_p2p_go_hb
;
106 s8 tsf_report_link_id
;
107 u8 bssid
[ETH_ALEN
] __aligned(2);
110 static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm
*mvm
)
112 struct iwl_scan_req_umac
*cmd
= mvm
->scan_cmd
;
114 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm
))
115 return (void *)&cmd
->v8
.data
;
117 if (iwl_mvm_is_adaptive_dwell_supported(mvm
))
118 return (void *)&cmd
->v7
.data
;
120 if (iwl_mvm_cdb_scan_api(mvm
))
121 return (void *)&cmd
->v6
.data
;
123 return (void *)&cmd
->v1
.data
;
126 static inline struct iwl_scan_umac_chan_param
*
127 iwl_mvm_get_scan_req_umac_channel(struct iwl_mvm
*mvm
)
129 struct iwl_scan_req_umac
*cmd
= mvm
->scan_cmd
;
131 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm
))
132 return &cmd
->v8
.channel
;
134 if (iwl_mvm_is_adaptive_dwell_supported(mvm
))
135 return &cmd
->v7
.channel
;
137 if (iwl_mvm_cdb_scan_api(mvm
))
138 return &cmd
->v6
.channel
;
140 return &cmd
->v1
.channel
;
143 static u8
iwl_mvm_scan_rx_ant(struct iwl_mvm
*mvm
)
145 if (mvm
->scan_rx_ant
!= ANT_NONE
)
146 return mvm
->scan_rx_ant
;
147 return iwl_mvm_get_valid_rx_ant(mvm
);
150 static inline __le16
iwl_mvm_scan_rx_chain(struct iwl_mvm
*mvm
)
155 rx_ant
= iwl_mvm_scan_rx_ant(mvm
);
156 rx_chain
= rx_ant
<< PHY_RX_CHAIN_VALID_POS
;
157 rx_chain
|= rx_ant
<< PHY_RX_CHAIN_FORCE_MIMO_SEL_POS
;
158 rx_chain
|= rx_ant
<< PHY_RX_CHAIN_FORCE_SEL_POS
;
159 rx_chain
|= 0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS
;
160 return cpu_to_le16(rx_chain
);
164 iwl_mvm_scan_rate_n_flags(struct iwl_mvm
*mvm
, enum nl80211_band band
,
169 iwl_mvm_toggle_tx_ant(mvm
, &mvm
->scan_last_antenna_idx
);
170 tx_ant
= BIT(mvm
->scan_last_antenna_idx
) << RATE_MCS_ANT_POS
;
172 if (band
== NL80211_BAND_2GHZ
&& !no_cck
)
173 return cpu_to_le32(IWL_RATE_1M_PLCP
| RATE_MCS_CCK_MSK_V1
|
176 return cpu_to_le32(IWL_RATE_6M_PLCP
| tx_ant
);
179 static enum iwl_mvm_traffic_load
iwl_mvm_get_traffic_load(struct iwl_mvm
*mvm
)
181 return mvm
->tcm
.result
.global_load
;
184 static enum iwl_mvm_traffic_load
185 iwl_mvm_get_traffic_load_band(struct iwl_mvm
*mvm
, enum nl80211_band band
)
187 return mvm
->tcm
.result
.band_load
[band
];
190 struct iwl_mvm_scan_iter_data
{
192 struct ieee80211_vif
*current_vif
;
193 bool is_dcm_with_p2p_go
;
196 static void iwl_mvm_scan_iterator(void *_data
, u8
*mac
,
197 struct ieee80211_vif
*vif
)
199 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
200 struct iwl_mvm_scan_iter_data
*data
= _data
;
201 struct iwl_mvm_vif
*curr_mvmvif
;
203 if (vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
&&
204 mvmvif
->deflink
.phy_ctxt
&&
205 mvmvif
->deflink
.phy_ctxt
->id
< NUM_PHY_CTX
)
206 data
->global_cnt
+= 1;
208 if (!data
->current_vif
|| vif
== data
->current_vif
)
211 curr_mvmvif
= iwl_mvm_vif_from_mac80211(data
->current_vif
);
213 if (ieee80211_vif_type_p2p(vif
) == NL80211_IFTYPE_P2P_GO
&&
214 mvmvif
->deflink
.phy_ctxt
&& curr_mvmvif
->deflink
.phy_ctxt
&&
215 mvmvif
->deflink
.phy_ctxt
->id
!= curr_mvmvif
->deflink
.phy_ctxt
->id
)
216 data
->is_dcm_with_p2p_go
= true;
220 iwl_mvm_scan_type
_iwl_mvm_get_scan_type(struct iwl_mvm
*mvm
,
221 struct ieee80211_vif
*vif
,
222 enum iwl_mvm_traffic_load load
,
225 struct iwl_mvm_scan_iter_data data
= {
227 .is_dcm_with_p2p_go
= false,
232 * A scanning AP interface probably wants to generate a survey to do
233 * ACS (automatic channel selection).
234 * Force a non-fragmented scan in that case.
236 if (vif
&& ieee80211_vif_type_p2p(vif
) == NL80211_IFTYPE_AP
)
237 return IWL_SCAN_TYPE_WILD
;
239 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
240 IEEE80211_IFACE_ITER_NORMAL
,
241 iwl_mvm_scan_iterator
,
244 if (!data
.global_cnt
)
245 return IWL_SCAN_TYPE_UNASSOC
;
247 if (fw_has_api(&mvm
->fw
->ucode_capa
,
248 IWL_UCODE_TLV_API_FRAGMENTED_SCAN
)) {
249 if ((load
== IWL_MVM_TRAFFIC_HIGH
|| low_latency
) &&
250 (!vif
|| vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
))
251 return IWL_SCAN_TYPE_FRAGMENTED
;
254 * in case of DCM with P2P GO set all scan requests as
257 if (vif
&& vif
->type
== NL80211_IFTYPE_STATION
&&
258 data
.is_dcm_with_p2p_go
)
259 return IWL_SCAN_TYPE_FAST_BALANCE
;
262 if (load
>= IWL_MVM_TRAFFIC_MEDIUM
|| low_latency
)
263 return IWL_SCAN_TYPE_MILD
;
265 return IWL_SCAN_TYPE_WILD
;
269 iwl_mvm_scan_type
iwl_mvm_get_scan_type(struct iwl_mvm
*mvm
,
270 struct ieee80211_vif
*vif
)
272 enum iwl_mvm_traffic_load load
;
275 load
= iwl_mvm_get_traffic_load(mvm
);
276 low_latency
= iwl_mvm_low_latency(mvm
);
278 return _iwl_mvm_get_scan_type(mvm
, vif
, load
, low_latency
);
282 iwl_mvm_scan_type
iwl_mvm_get_scan_type_band(struct iwl_mvm
*mvm
,
283 struct ieee80211_vif
*vif
,
284 enum nl80211_band band
)
286 enum iwl_mvm_traffic_load load
;
289 load
= iwl_mvm_get_traffic_load_band(mvm
, band
);
290 low_latency
= iwl_mvm_low_latency_band(mvm
, band
);
292 return _iwl_mvm_get_scan_type(mvm
, vif
, load
, low_latency
);
295 static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm
*mvm
)
297 /* require rrm scan whenever the fw supports it */
298 return fw_has_capa(&mvm
->fw
->ucode_capa
,
299 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT
);
302 static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm
*mvm
)
306 max_probe_len
= SCAN_OFFLOAD_PROBE_REQ_SIZE
;
308 /* we create the 802.11 header SSID element and WFA TPC element */
309 max_probe_len
-= 24 + 2 + WFA_TPC_IE_LEN
;
311 /* DS parameter set element is added on 2.4GHZ band if required */
312 if (iwl_mvm_rrm_scan_needed(mvm
))
315 return max_probe_len
;
318 int iwl_mvm_max_scan_ie_len(struct iwl_mvm
*mvm
)
320 int max_ie_len
= iwl_mvm_max_scan_ie_fw_cmd_room(mvm
);
322 /* TODO: [BUG] This function should return the maximum allowed size of
323 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
324 * in the same command. So the correct implementation of this function
325 * is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan
326 * command has only 512 bytes and it would leave us with about 240
327 * bytes for scan IEs, which is clearly not enough. So meanwhile
328 * we will report an incorrect value. This may result in a failure to
329 * issue a scan in unified_scan_lmac and unified_sched_scan_lmac
330 * functions with -ENOBUFS, if a large enough probe will be provided.
335 void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm
*mvm
,
336 struct iwl_rx_cmd_buffer
*rxb
)
338 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
339 struct iwl_lmac_scan_complete_notif
*notif
= (void *)pkt
->data
;
342 "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
343 notif
->status
, notif
->scanned_channels
);
345 if (mvm
->sched_scan_pass_all
== SCHED_SCAN_PASS_ALL_FOUND
) {
346 IWL_DEBUG_SCAN(mvm
, "Pass all scheduled scan results found\n");
347 ieee80211_sched_scan_results(mvm
->hw
);
348 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_ENABLED
;
352 void iwl_mvm_rx_scan_match_found(struct iwl_mvm
*mvm
,
353 struct iwl_rx_cmd_buffer
*rxb
)
355 IWL_DEBUG_SCAN(mvm
, "Scheduled scan results\n");
356 ieee80211_sched_scan_results(mvm
->hw
);
359 static const char *iwl_mvm_ebs_status_str(enum iwl_scan_ebs_status status
)
362 case IWL_SCAN_EBS_SUCCESS
:
364 case IWL_SCAN_EBS_INACTIVE
:
366 case IWL_SCAN_EBS_FAILED
:
367 case IWL_SCAN_EBS_CHAN_NOT_FOUND
:
373 void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm
*mvm
,
374 struct iwl_rx_cmd_buffer
*rxb
)
376 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
377 struct iwl_periodic_scan_complete
*scan_notif
= (void *)pkt
->data
;
378 bool aborted
= (scan_notif
->status
== IWL_SCAN_OFFLOAD_ABORTED
);
380 /* If this happens, the firmware has mistakenly sent an LMAC
381 * notification during UMAC scans -- warn and ignore it.
383 if (WARN_ON_ONCE(fw_has_capa(&mvm
->fw
->ucode_capa
,
384 IWL_UCODE_TLV_CAPA_UMAC_SCAN
)))
387 /* scan status must be locked for proper checking */
388 lockdep_assert_held(&mvm
->mutex
);
390 /* We first check if we were stopping a scan, in which case we
391 * just clear the stopping flag. Then we check if it was a
392 * firmware initiated stop, in which case we need to inform
394 * Note that we can have a stopping and a running scan
395 * simultaneously, but we can't have two different types of
396 * scans stopping or running at the same time (since LMAC
397 * doesn't support it).
400 if (mvm
->scan_status
& IWL_MVM_SCAN_STOPPING_SCHED
) {
401 WARN_ON_ONCE(mvm
->scan_status
& IWL_MVM_SCAN_STOPPING_REGULAR
);
403 IWL_DEBUG_SCAN(mvm
, "Scheduled scan %s, EBS status %s\n",
404 aborted
? "aborted" : "completed",
405 iwl_mvm_ebs_status_str(scan_notif
->ebs_status
));
407 "Last line %d, Last iteration %d, Time after last iteration %d\n",
408 scan_notif
->last_schedule_line
,
409 scan_notif
->last_schedule_iteration
,
410 __le32_to_cpu(scan_notif
->time_after_last_iter
));
412 mvm
->scan_status
&= ~IWL_MVM_SCAN_STOPPING_SCHED
;
413 } else if (mvm
->scan_status
& IWL_MVM_SCAN_STOPPING_REGULAR
) {
414 IWL_DEBUG_SCAN(mvm
, "Regular scan %s, EBS status %s\n",
415 aborted
? "aborted" : "completed",
416 iwl_mvm_ebs_status_str(scan_notif
->ebs_status
));
418 mvm
->scan_status
&= ~IWL_MVM_SCAN_STOPPING_REGULAR
;
419 } else if (mvm
->scan_status
& IWL_MVM_SCAN_SCHED
) {
420 WARN_ON_ONCE(mvm
->scan_status
& IWL_MVM_SCAN_REGULAR
);
422 IWL_DEBUG_SCAN(mvm
, "Scheduled scan %s, EBS status %s\n",
423 aborted
? "aborted" : "completed",
424 iwl_mvm_ebs_status_str(scan_notif
->ebs_status
));
426 "Last line %d, Last iteration %d, Time after last iteration %d (FW)\n",
427 scan_notif
->last_schedule_line
,
428 scan_notif
->last_schedule_iteration
,
429 __le32_to_cpu(scan_notif
->time_after_last_iter
));
431 mvm
->scan_status
&= ~IWL_MVM_SCAN_SCHED
;
432 ieee80211_sched_scan_stopped(mvm
->hw
);
433 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
434 } else if (mvm
->scan_status
& IWL_MVM_SCAN_REGULAR
) {
435 struct cfg80211_scan_info info
= {
439 IWL_DEBUG_SCAN(mvm
, "Regular scan %s, EBS status %s (FW)\n",
440 aborted
? "aborted" : "completed",
441 iwl_mvm_ebs_status_str(scan_notif
->ebs_status
));
443 mvm
->scan_status
&= ~IWL_MVM_SCAN_REGULAR
;
444 ieee80211_scan_completed(mvm
->hw
, &info
);
445 cancel_delayed_work(&mvm
->scan_timeout_dwork
);
446 iwl_mvm_resume_tcm(mvm
);
449 "got scan complete notification but no scan is running\n");
452 mvm
->last_ebs_successful
=
453 scan_notif
->ebs_status
== IWL_SCAN_EBS_SUCCESS
||
454 scan_notif
->ebs_status
== IWL_SCAN_EBS_INACTIVE
;
457 static int iwl_ssid_exist(u8
*ssid
, u8 ssid_len
, struct iwl_ssid_ie
*ssid_list
)
461 for (i
= 0; i
< PROBE_OPTION_MAX
; i
++) {
462 if (!ssid_list
[i
].len
)
464 if (ssid_list
[i
].len
== ssid_len
&&
465 !memcmp(ssid_list
->ssid
, ssid
, ssid_len
))
471 /* We insert the SSIDs in an inverted order, because the FW will
474 static void iwl_scan_build_ssids(struct iwl_mvm_scan_params
*params
,
475 struct iwl_ssid_ie
*ssids
,
483 * copy SSIDs from match list.
484 * iwl_config_sched_scan_profiles() uses the order of these ssids to
487 for (i
= 0, j
= params
->n_match_sets
- 1;
488 j
>= 0 && i
< PROBE_OPTION_MAX
;
490 /* skip empty SSID matchsets */
491 if (!params
->match_sets
[j
].ssid
.ssid_len
)
493 ssids
[i
].id
= WLAN_EID_SSID
;
494 ssids
[i
].len
= params
->match_sets
[j
].ssid
.ssid_len
;
495 memcpy(ssids
[i
].ssid
, params
->match_sets
[j
].ssid
.ssid
,
499 /* add SSIDs from scan SSID list */
500 for (j
= params
->n_ssids
- 1;
501 j
>= 0 && i
< PROBE_OPTION_MAX
;
503 index
= iwl_ssid_exist(params
->ssids
[j
].ssid
,
504 params
->ssids
[j
].ssid_len
,
507 ssids
[i
].id
= WLAN_EID_SSID
;
508 ssids
[i
].len
= params
->ssids
[j
].ssid_len
;
509 memcpy(ssids
[i
].ssid
, params
->ssids
[j
].ssid
,
511 tmp_bitmap
|= BIT(i
);
513 tmp_bitmap
|= BIT(index
);
517 *ssid_bitmap
= tmp_bitmap
;
521 iwl_mvm_config_sched_scan_profiles(struct iwl_mvm
*mvm
,
522 struct cfg80211_sched_scan_request
*req
)
524 struct iwl_scan_offload_profile
*profile
;
525 struct iwl_scan_offload_profile_cfg_v1
*profile_cfg_v1
;
526 struct iwl_scan_offload_blocklist
*blocklist
;
527 struct iwl_scan_offload_profile_cfg_data
*data
;
528 int max_profiles
= iwl_umac_scan_get_max_profiles(mvm
->fw
);
529 int profile_cfg_size
= sizeof(*data
) +
530 sizeof(*profile
) * max_profiles
;
531 struct iwl_host_cmd cmd
= {
532 .id
= SCAN_OFFLOAD_UPDATE_PROFILES_CMD
,
533 .len
[1] = profile_cfg_size
,
534 .dataflags
[0] = IWL_HCMD_DFL_NOCOPY
,
535 .dataflags
[1] = IWL_HCMD_DFL_NOCOPY
,
541 if (WARN_ON(req
->n_match_sets
> max_profiles
))
544 if (mvm
->fw
->ucode_capa
.flags
& IWL_UCODE_TLV_FLAGS_SHORT_BL
)
545 blocklist_len
= IWL_SCAN_SHORT_BLACKLIST_LEN
;
547 blocklist_len
= IWL_SCAN_MAX_BLACKLIST_LEN
;
549 blocklist
= kcalloc(blocklist_len
, sizeof(*blocklist
), GFP_KERNEL
);
553 profile_cfg_v1
= kzalloc(profile_cfg_size
, GFP_KERNEL
);
554 if (!profile_cfg_v1
) {
559 cmd
.data
[0] = blocklist
;
560 cmd
.len
[0] = sizeof(*blocklist
) * blocklist_len
;
561 cmd
.data
[1] = profile_cfg_v1
;
563 /* if max_profile is MAX_PROFILES_V2, we have the new API */
564 if (max_profiles
== IWL_SCAN_MAX_PROFILES_V2
) {
565 struct iwl_scan_offload_profile_cfg
*profile_cfg
=
566 (struct iwl_scan_offload_profile_cfg
*)profile_cfg_v1
;
568 data
= &profile_cfg
->data
;
570 data
= &profile_cfg_v1
->data
;
573 /* No blocklist configuration */
574 data
->num_profiles
= req
->n_match_sets
;
575 data
->active_clients
= SCAN_CLIENT_SCHED_SCAN
;
576 data
->pass_match
= SCAN_CLIENT_SCHED_SCAN
;
577 data
->match_notify
= SCAN_CLIENT_SCHED_SCAN
;
579 if (!req
->n_match_sets
|| !req
->match_sets
[0].ssid
.ssid_len
)
580 data
->any_beacon_notify
= SCAN_CLIENT_SCHED_SCAN
;
582 for (i
= 0; i
< req
->n_match_sets
; i
++) {
583 profile
= &profile_cfg_v1
->profiles
[i
];
584 profile
->ssid_index
= i
;
585 /* Support any cipher and auth algorithm */
586 profile
->unicast_cipher
= 0xff;
587 profile
->auth_alg
= IWL_AUTH_ALGO_UNSUPPORTED
|
588 IWL_AUTH_ALGO_NONE
| IWL_AUTH_ALGO_PSK
| IWL_AUTH_ALGO_8021X
|
589 IWL_AUTH_ALGO_SAE
| IWL_AUTH_ALGO_8021X_SHA384
| IWL_AUTH_ALGO_OWE
;
590 profile
->network_type
= IWL_NETWORK_TYPE_ANY
;
591 profile
->band_selection
= IWL_SCAN_OFFLOAD_SELECT_ANY
;
592 profile
->client_bitmap
= SCAN_CLIENT_SCHED_SCAN
;
595 IWL_DEBUG_SCAN(mvm
, "Sending scheduled scan profile config\n");
597 ret
= iwl_mvm_send_cmd(mvm
, &cmd
);
598 kfree(profile_cfg_v1
);
605 static bool iwl_mvm_scan_pass_all(struct iwl_mvm
*mvm
,
606 struct cfg80211_sched_scan_request
*req
)
608 if (req
->n_match_sets
&& req
->match_sets
[0].ssid
.ssid_len
) {
610 "Sending scheduled scan with filtering, n_match_sets %d\n",
612 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
616 IWL_DEBUG_SCAN(mvm
, "Sending Scheduled scan without filtering\n");
618 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_ENABLED
;
622 static int iwl_mvm_lmac_scan_abort(struct iwl_mvm
*mvm
)
625 struct iwl_host_cmd cmd
= {
626 .id
= SCAN_OFFLOAD_ABORT_CMD
,
628 u32 status
= CAN_ABORT_STATUS
;
630 ret
= iwl_mvm_send_cmd_status(mvm
, &cmd
, &status
);
634 if (status
!= CAN_ABORT_STATUS
) {
636 * The scan abort will return 1 for success or
637 * 2 for "failure". A failure condition can be
638 * due to simply not being in an active scan which
639 * can occur if we send the scan abort before the
640 * microcode has notified us that a scan is completed.
642 IWL_DEBUG_SCAN(mvm
, "SCAN OFFLOAD ABORT ret %d.\n", status
);
649 static void iwl_mvm_scan_fill_tx_cmd(struct iwl_mvm
*mvm
,
650 struct iwl_scan_req_tx_cmd
*tx_cmd
,
653 tx_cmd
[0].tx_flags
= cpu_to_le32(TX_CMD_FLG_SEQ_CTL
|
655 tx_cmd
[0].rate_n_flags
= iwl_mvm_scan_rate_n_flags(mvm
,
659 if (!iwl_mvm_has_new_station_api(mvm
->fw
)) {
660 tx_cmd
[0].sta_id
= mvm
->aux_sta
.sta_id
;
661 tx_cmd
[1].sta_id
= mvm
->aux_sta
.sta_id
;
664 * Fw doesn't use this sta anymore, pending deprecation via HOST API
668 tx_cmd
[0].sta_id
= 0xff;
669 tx_cmd
[1].sta_id
= 0xff;
672 tx_cmd
[1].tx_flags
= cpu_to_le32(TX_CMD_FLG_SEQ_CTL
|
675 tx_cmd
[1].rate_n_flags
= iwl_mvm_scan_rate_n_flags(mvm
,
681 iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm
*mvm
,
682 struct ieee80211_channel
**channels
,
683 int n_channels
, u32 ssid_bitmap
,
684 struct iwl_scan_req_lmac
*cmd
)
686 struct iwl_scan_channel_cfg_lmac
*channel_cfg
= (void *)&cmd
->data
;
689 for (i
= 0; i
< n_channels
; i
++) {
690 channel_cfg
[i
].channel_num
=
691 cpu_to_le16(channels
[i
]->hw_value
);
692 channel_cfg
[i
].iter_count
= cpu_to_le16(1);
693 channel_cfg
[i
].iter_interval
= 0;
694 channel_cfg
[i
].flags
=
695 cpu_to_le32(IWL_UNIFIED_SCAN_CHANNEL_PARTIAL
|
700 static u8
*iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm
*mvm
, const u8
*ies
,
701 size_t len
, u8
*const pos
)
703 static const u8 before_ds_params
[] = {
707 WLAN_EID_EXT_SUPP_RATES
,
712 if (!iwl_mvm_rrm_scan_needed(mvm
)) {
713 memcpy(newpos
, ies
, len
);
717 offs
= ieee80211_ie_split(ies
, len
,
719 ARRAY_SIZE(before_ds_params
),
722 memcpy(newpos
, ies
, offs
);
725 /* Add a placeholder for DS Parameter Set element */
726 *newpos
++ = WLAN_EID_DS_PARAMS
;
730 memcpy(newpos
, ies
+ offs
, len
- offs
);
731 newpos
+= len
- offs
;
736 static void iwl_mvm_add_tpc_report_ie(u8
*pos
)
738 pos
[0] = WLAN_EID_VENDOR_SPECIFIC
;
739 pos
[1] = WFA_TPC_IE_LEN
- 2;
740 pos
[2] = (WLAN_OUI_MICROSOFT
>> 16) & 0xff;
741 pos
[3] = (WLAN_OUI_MICROSOFT
>> 8) & 0xff;
742 pos
[4] = WLAN_OUI_MICROSOFT
& 0xff;
743 pos
[5] = WLAN_OUI_TYPE_MICROSOFT_TPC
;
745 /* pos[7] - tx power will be inserted by the FW */
751 iwl_mvm_build_scan_probe(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
752 struct ieee80211_scan_ies
*ies
,
753 struct iwl_mvm_scan_params
*params
)
755 struct ieee80211_mgmt
*frame
= (void *)params
->preq
.buf
;
757 const u8
*mac_addr
= params
->flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
?
758 params
->mac_addr
: NULL
;
761 * Unfortunately, right now the offload scan doesn't support randomising
762 * within the firmware, so until the firmware API is ready we implement
763 * it in the driver. This means that the scan iterations won't really be
764 * random, only when it's restarted, but at least that helps a bit.
767 get_random_mask_addr(frame
->sa
, mac_addr
,
768 params
->mac_addr_mask
);
770 memcpy(frame
->sa
, vif
->addr
, ETH_ALEN
);
772 frame
->frame_control
= cpu_to_le16(IEEE80211_STYPE_PROBE_REQ
);
773 eth_broadcast_addr(frame
->da
);
774 ether_addr_copy(frame
->bssid
, params
->bssid
);
777 pos
= frame
->u
.probe_req
.variable
;
778 *pos
++ = WLAN_EID_SSID
;
781 params
->preq
.mac_header
.offset
= 0;
782 params
->preq
.mac_header
.len
= cpu_to_le16(24 + 2);
784 /* Insert ds parameter set element on 2.4 GHz band */
785 newpos
= iwl_mvm_copy_and_insert_ds_elem(mvm
,
786 ies
->ies
[NL80211_BAND_2GHZ
],
787 ies
->len
[NL80211_BAND_2GHZ
],
789 params
->preq
.band_data
[0].offset
= cpu_to_le16(pos
- params
->preq
.buf
);
790 params
->preq
.band_data
[0].len
= cpu_to_le16(newpos
- pos
);
793 memcpy(pos
, ies
->ies
[NL80211_BAND_5GHZ
],
794 ies
->len
[NL80211_BAND_5GHZ
]);
795 params
->preq
.band_data
[1].offset
= cpu_to_le16(pos
- params
->preq
.buf
);
796 params
->preq
.band_data
[1].len
=
797 cpu_to_le16(ies
->len
[NL80211_BAND_5GHZ
]);
798 pos
+= ies
->len
[NL80211_BAND_5GHZ
];
800 memcpy(pos
, ies
->ies
[NL80211_BAND_6GHZ
],
801 ies
->len
[NL80211_BAND_6GHZ
]);
802 params
->preq
.band_data
[2].offset
= cpu_to_le16(pos
- params
->preq
.buf
);
803 params
->preq
.band_data
[2].len
=
804 cpu_to_le16(ies
->len
[NL80211_BAND_6GHZ
]);
805 pos
+= ies
->len
[NL80211_BAND_6GHZ
];
806 memcpy(pos
, ies
->common_ies
, ies
->common_ie_len
);
807 params
->preq
.common_data
.offset
= cpu_to_le16(pos
- params
->preq
.buf
);
809 if (iwl_mvm_rrm_scan_needed(mvm
) &&
810 !fw_has_capa(&mvm
->fw
->ucode_capa
,
811 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT
)) {
812 iwl_mvm_add_tpc_report_ie(pos
+ ies
->common_ie_len
);
813 params
->preq
.common_data
.len
= cpu_to_le16(ies
->common_ie_len
+
816 params
->preq
.common_data
.len
= cpu_to_le16(ies
->common_ie_len
);
820 static void iwl_mvm_scan_lmac_dwell(struct iwl_mvm
*mvm
,
821 struct iwl_scan_req_lmac
*cmd
,
822 struct iwl_mvm_scan_params
*params
)
824 cmd
->active_dwell
= IWL_SCAN_DWELL_ACTIVE
;
825 cmd
->passive_dwell
= IWL_SCAN_DWELL_PASSIVE
;
826 cmd
->fragmented_dwell
= IWL_SCAN_DWELL_FRAGMENTED
;
827 cmd
->extended_dwell
= IWL_SCAN_DWELL_EXTENDED
;
828 cmd
->max_out_time
= cpu_to_le32(scan_timing
[params
->type
].max_out_time
);
829 cmd
->suspend_time
= cpu_to_le32(scan_timing
[params
->type
].suspend_time
);
830 cmd
->scan_prio
= cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6
);
833 static inline bool iwl_mvm_scan_fits(struct iwl_mvm
*mvm
, int n_ssids
,
834 struct ieee80211_scan_ies
*ies
,
837 return ((n_ssids
<= PROBE_OPTION_MAX
) &&
838 (n_channels
<= mvm
->fw
->ucode_capa
.n_scan_channels
) &
839 (ies
->common_ie_len
+
840 ies
->len
[NL80211_BAND_2GHZ
] + ies
->len
[NL80211_BAND_5GHZ
] +
841 ies
->len
[NL80211_BAND_6GHZ
] <=
842 iwl_mvm_max_scan_ie_fw_cmd_room(mvm
)));
845 static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm
*mvm
,
846 struct ieee80211_vif
*vif
)
848 const struct iwl_ucode_capabilities
*capa
= &mvm
->fw
->ucode_capa
;
851 if (iwl_mvm_is_cdb_supported(mvm
))
852 low_latency
= iwl_mvm_low_latency_band(mvm
, NL80211_BAND_5GHZ
);
854 low_latency
= iwl_mvm_low_latency(mvm
);
856 /* We can only use EBS if:
857 * 1. the feature is supported;
858 * 2. the last EBS was successful;
859 * 3. if only single scan, the single scan EBS API is supported;
860 * 4. it's not a p2p find operation.
861 * 5. we are not in low latency mode,
862 * or if fragmented ebs is supported by the FW
863 * 6. the VIF is not an AP interface (scan wants survey results)
865 return ((capa
->flags
& IWL_UCODE_TLV_FLAGS_EBS_SUPPORT
) &&
866 mvm
->last_ebs_successful
&& IWL_MVM_ENABLE_EBS
&&
867 vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
&&
868 (!low_latency
|| iwl_mvm_is_frag_ebs_supported(mvm
)) &&
869 ieee80211_vif_type_p2p(vif
) != NL80211_IFTYPE_AP
);
872 static inline bool iwl_mvm_is_regular_scan(struct iwl_mvm_scan_params
*params
)
874 return params
->n_scan_plans
== 1 &&
875 params
->scan_plans
[0].iterations
== 1;
878 static bool iwl_mvm_is_scan_fragmented(enum iwl_mvm_scan_type type
)
880 return (type
== IWL_SCAN_TYPE_FRAGMENTED
||
881 type
== IWL_SCAN_TYPE_FAST_BALANCE
);
884 static int iwl_mvm_scan_lmac_flags(struct iwl_mvm
*mvm
,
885 struct iwl_mvm_scan_params
*params
,
886 struct ieee80211_vif
*vif
)
890 if (params
->n_ssids
== 0)
891 flags
|= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE
;
893 if (params
->n_ssids
== 1 && params
->ssids
[0].ssid_len
!= 0)
894 flags
|= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION
;
896 if (iwl_mvm_is_scan_fragmented(params
->type
))
897 flags
|= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED
;
899 if (iwl_mvm_rrm_scan_needed(mvm
) &&
900 fw_has_capa(&mvm
->fw
->ucode_capa
,
901 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT
))
902 flags
|= IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED
;
904 if (params
->pass_all
)
905 flags
|= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL
;
907 flags
|= IWL_MVM_LMAC_SCAN_FLAG_MATCH
;
909 #ifdef CONFIG_IWLWIFI_DEBUGFS
910 if (mvm
->scan_iter_notif_enabled
)
911 flags
|= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE
;
914 if (mvm
->sched_scan_pass_all
== SCHED_SCAN_PASS_ALL_ENABLED
)
915 flags
|= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE
;
917 if (iwl_mvm_is_regular_scan(params
) &&
918 vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
&&
919 !iwl_mvm_is_scan_fragmented(params
->type
))
920 flags
|= IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL
;
926 iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1
*p_req
,
927 struct iwl_scan_probe_req
*src_p_req
)
931 p_req
->mac_header
= src_p_req
->mac_header
;
932 for (i
= 0; i
< SCAN_NUM_BAND_PROBE_DATA_V_1
; i
++)
933 p_req
->band_data
[i
] = src_p_req
->band_data
[i
];
934 p_req
->common_data
= src_p_req
->common_data
;
935 memcpy(p_req
->buf
, src_p_req
->buf
, sizeof(p_req
->buf
));
938 static int iwl_mvm_scan_lmac(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
939 struct iwl_mvm_scan_params
*params
)
941 struct iwl_scan_req_lmac
*cmd
= mvm
->scan_cmd
;
942 struct iwl_scan_probe_req_v1
*preq
=
943 (void *)(cmd
->data
+ sizeof(struct iwl_scan_channel_cfg_lmac
) *
944 mvm
->fw
->ucode_capa
.n_scan_channels
);
949 if (WARN_ON(params
->n_scan_plans
> IWL_MAX_SCHED_SCAN_PLANS
))
952 iwl_mvm_scan_lmac_dwell(mvm
, cmd
, params
);
954 cmd
->rx_chain_select
= iwl_mvm_scan_rx_chain(mvm
);
955 cmd
->iter_num
= cpu_to_le32(1);
956 cmd
->n_channels
= (u8
)params
->n_channels
;
958 cmd
->delay
= cpu_to_le32(params
->delay
);
960 cmd
->scan_flags
= cpu_to_le32(iwl_mvm_scan_lmac_flags(mvm
, params
,
963 band
= iwl_mvm_phy_band_from_nl80211(params
->channels
[0]->band
);
964 cmd
->flags
= cpu_to_le32(band
);
965 cmd
->filter_flags
= cpu_to_le32(MAC_FILTER_ACCEPT_GRP
|
966 MAC_FILTER_IN_BEACON
);
967 iwl_mvm_scan_fill_tx_cmd(mvm
, cmd
->tx_cmd
, params
->no_cck
);
968 iwl_scan_build_ssids(params
, cmd
->direct_scan
, &ssid_bitmap
);
970 /* this API uses bits 1-20 instead of 0-19 */
973 for (i
= 0; i
< params
->n_scan_plans
; i
++) {
974 struct cfg80211_sched_scan_plan
*scan_plan
=
975 ¶ms
->scan_plans
[i
];
977 cmd
->schedule
[i
].delay
=
978 cpu_to_le16(scan_plan
->interval
);
979 cmd
->schedule
[i
].iterations
= scan_plan
->iterations
;
980 cmd
->schedule
[i
].full_scan_mul
= 1;
984 * If the number of iterations of the last scan plan is set to
985 * zero, it should run infinitely. However, this is not always the case.
986 * For example, when regular scan is requested the driver sets one scan
987 * plan with one iteration.
989 if (!cmd
->schedule
[i
- 1].iterations
)
990 cmd
->schedule
[i
- 1].iterations
= 0xff;
992 if (iwl_mvm_scan_use_ebs(mvm
, vif
)) {
993 cmd
->channel_opt
[0].flags
=
994 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS
|
995 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE
|
996 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD
);
997 cmd
->channel_opt
[0].non_ebs_ratio
=
998 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO
);
999 cmd
->channel_opt
[1].flags
=
1000 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS
|
1001 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE
|
1002 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD
);
1003 cmd
->channel_opt
[1].non_ebs_ratio
=
1004 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO
);
1007 iwl_mvm_lmac_scan_cfg_channels(mvm
, params
->channels
,
1008 params
->n_channels
, ssid_bitmap
, cmd
);
1010 iwl_mvm_scan_set_legacy_probe_req(preq
, ¶ms
->preq
);
1015 static int rate_to_scan_rate_flag(unsigned int rate
)
1017 static const int rate_to_scan_rate
[IWL_RATE_COUNT
] = {
1018 [IWL_RATE_1M_INDEX
] = SCAN_CONFIG_RATE_1M
,
1019 [IWL_RATE_2M_INDEX
] = SCAN_CONFIG_RATE_2M
,
1020 [IWL_RATE_5M_INDEX
] = SCAN_CONFIG_RATE_5M
,
1021 [IWL_RATE_11M_INDEX
] = SCAN_CONFIG_RATE_11M
,
1022 [IWL_RATE_6M_INDEX
] = SCAN_CONFIG_RATE_6M
,
1023 [IWL_RATE_9M_INDEX
] = SCAN_CONFIG_RATE_9M
,
1024 [IWL_RATE_12M_INDEX
] = SCAN_CONFIG_RATE_12M
,
1025 [IWL_RATE_18M_INDEX
] = SCAN_CONFIG_RATE_18M
,
1026 [IWL_RATE_24M_INDEX
] = SCAN_CONFIG_RATE_24M
,
1027 [IWL_RATE_36M_INDEX
] = SCAN_CONFIG_RATE_36M
,
1028 [IWL_RATE_48M_INDEX
] = SCAN_CONFIG_RATE_48M
,
1029 [IWL_RATE_54M_INDEX
] = SCAN_CONFIG_RATE_54M
,
1032 return rate_to_scan_rate
[rate
];
1035 static __le32
iwl_mvm_scan_config_rates(struct iwl_mvm
*mvm
)
1037 struct ieee80211_supported_band
*band
;
1038 unsigned int rates
= 0;
1041 band
= &mvm
->nvm_data
->bands
[NL80211_BAND_2GHZ
];
1042 for (i
= 0; i
< band
->n_bitrates
; i
++)
1043 rates
|= rate_to_scan_rate_flag(band
->bitrates
[i
].hw_value
);
1044 band
= &mvm
->nvm_data
->bands
[NL80211_BAND_5GHZ
];
1045 for (i
= 0; i
< band
->n_bitrates
; i
++)
1046 rates
|= rate_to_scan_rate_flag(band
->bitrates
[i
].hw_value
);
1048 /* Set both basic rates and supported rates */
1049 rates
|= SCAN_CONFIG_SUPPORTED_RATE(rates
);
1051 return cpu_to_le32(rates
);
1054 static void iwl_mvm_fill_scan_dwell(struct iwl_mvm
*mvm
,
1055 struct iwl_scan_dwell
*dwell
)
1057 dwell
->active
= IWL_SCAN_DWELL_ACTIVE
;
1058 dwell
->passive
= IWL_SCAN_DWELL_PASSIVE
;
1059 dwell
->fragmented
= IWL_SCAN_DWELL_FRAGMENTED
;
1060 dwell
->extended
= IWL_SCAN_DWELL_EXTENDED
;
1063 static void iwl_mvm_fill_channels(struct iwl_mvm
*mvm
, u8
*channels
,
1066 struct ieee80211_supported_band
*band
;
1069 band
= &mvm
->nvm_data
->bands
[NL80211_BAND_2GHZ
];
1070 for (i
= 0; i
< band
->n_channels
&& j
< max_channels
; i
++, j
++)
1071 channels
[j
] = band
->channels
[i
].hw_value
;
1072 band
= &mvm
->nvm_data
->bands
[NL80211_BAND_5GHZ
];
1073 for (i
= 0; i
< band
->n_channels
&& j
< max_channels
; i
++, j
++)
1074 channels
[j
] = band
->channels
[i
].hw_value
;
1077 static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm
*mvm
, void *config
,
1078 u32 flags
, u8 channel_flags
,
1081 enum iwl_mvm_scan_type type
= iwl_mvm_get_scan_type(mvm
, NULL
);
1082 struct iwl_scan_config_v1
*cfg
= config
;
1084 cfg
->flags
= cpu_to_le32(flags
);
1085 cfg
->tx_chains
= cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm
));
1086 cfg
->rx_chains
= cpu_to_le32(iwl_mvm_scan_rx_ant(mvm
));
1087 cfg
->legacy_rates
= iwl_mvm_scan_config_rates(mvm
);
1088 cfg
->out_of_channel_time
= cpu_to_le32(scan_timing
[type
].max_out_time
);
1089 cfg
->suspend_time
= cpu_to_le32(scan_timing
[type
].suspend_time
);
1091 iwl_mvm_fill_scan_dwell(mvm
, &cfg
->dwell
);
1093 memcpy(&cfg
->mac_addr
, &mvm
->addresses
[0].addr
, ETH_ALEN
);
1095 /* This function should not be called when using ADD_STA ver >=12 */
1096 WARN_ON_ONCE(iwl_mvm_has_new_station_api(mvm
->fw
));
1098 cfg
->bcast_sta_id
= mvm
->aux_sta
.sta_id
;
1099 cfg
->channel_flags
= channel_flags
;
1101 iwl_mvm_fill_channels(mvm
, cfg
->channel_array
, max_channels
);
1104 static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm
*mvm
, void *config
,
1105 u32 flags
, u8 channel_flags
,
1108 struct iwl_scan_config_v2
*cfg
= config
;
1110 cfg
->flags
= cpu_to_le32(flags
);
1111 cfg
->tx_chains
= cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm
));
1112 cfg
->rx_chains
= cpu_to_le32(iwl_mvm_scan_rx_ant(mvm
));
1113 cfg
->legacy_rates
= iwl_mvm_scan_config_rates(mvm
);
1115 if (iwl_mvm_is_cdb_supported(mvm
)) {
1116 enum iwl_mvm_scan_type lb_type
, hb_type
;
1118 lb_type
= iwl_mvm_get_scan_type_band(mvm
, NULL
,
1120 hb_type
= iwl_mvm_get_scan_type_band(mvm
, NULL
,
1123 cfg
->out_of_channel_time
[SCAN_LB_LMAC_IDX
] =
1124 cpu_to_le32(scan_timing
[lb_type
].max_out_time
);
1125 cfg
->suspend_time
[SCAN_LB_LMAC_IDX
] =
1126 cpu_to_le32(scan_timing
[lb_type
].suspend_time
);
1128 cfg
->out_of_channel_time
[SCAN_HB_LMAC_IDX
] =
1129 cpu_to_le32(scan_timing
[hb_type
].max_out_time
);
1130 cfg
->suspend_time
[SCAN_HB_LMAC_IDX
] =
1131 cpu_to_le32(scan_timing
[hb_type
].suspend_time
);
1133 enum iwl_mvm_scan_type type
=
1134 iwl_mvm_get_scan_type(mvm
, NULL
);
1136 cfg
->out_of_channel_time
[SCAN_LB_LMAC_IDX
] =
1137 cpu_to_le32(scan_timing
[type
].max_out_time
);
1138 cfg
->suspend_time
[SCAN_LB_LMAC_IDX
] =
1139 cpu_to_le32(scan_timing
[type
].suspend_time
);
1142 iwl_mvm_fill_scan_dwell(mvm
, &cfg
->dwell
);
1144 memcpy(&cfg
->mac_addr
, &mvm
->addresses
[0].addr
, ETH_ALEN
);
1146 /* This function should not be called when using ADD_STA ver >=12 */
1147 WARN_ON_ONCE(iwl_mvm_has_new_station_api(mvm
->fw
));
1149 cfg
->bcast_sta_id
= mvm
->aux_sta
.sta_id
;
1150 cfg
->channel_flags
= channel_flags
;
1152 iwl_mvm_fill_channels(mvm
, cfg
->channel_array
, max_channels
);
1155 static int iwl_mvm_legacy_config_scan(struct iwl_mvm
*mvm
)
1159 struct iwl_host_cmd cmd
= {
1160 .id
= WIDE_ID(IWL_ALWAYS_LONG_GROUP
, SCAN_CFG_CMD
),
1162 enum iwl_mvm_scan_type type
;
1163 enum iwl_mvm_scan_type hb_type
= IWL_SCAN_TYPE_NOT_SET
;
1165 mvm
->nvm_data
->bands
[NL80211_BAND_2GHZ
].n_channels
+
1166 mvm
->nvm_data
->bands
[NL80211_BAND_5GHZ
].n_channels
;
1170 if (WARN_ON(num_channels
> mvm
->fw
->ucode_capa
.n_scan_channels
))
1171 num_channels
= mvm
->fw
->ucode_capa
.n_scan_channels
;
1173 if (iwl_mvm_is_cdb_supported(mvm
)) {
1174 type
= iwl_mvm_get_scan_type_band(mvm
, NULL
,
1176 hb_type
= iwl_mvm_get_scan_type_band(mvm
, NULL
,
1178 if (type
== mvm
->scan_type
&& hb_type
== mvm
->hb_scan_type
)
1181 type
= iwl_mvm_get_scan_type(mvm
, NULL
);
1182 if (type
== mvm
->scan_type
)
1186 if (iwl_mvm_cdb_scan_api(mvm
))
1187 cmd_size
= sizeof(struct iwl_scan_config_v2
);
1189 cmd_size
= sizeof(struct iwl_scan_config_v1
);
1190 cmd_size
+= mvm
->fw
->ucode_capa
.n_scan_channels
;
1192 cfg
= kzalloc(cmd_size
, GFP_KERNEL
);
1196 flags
= SCAN_CONFIG_FLAG_ACTIVATE
|
1197 SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS
|
1198 SCAN_CONFIG_FLAG_SET_TX_CHAINS
|
1199 SCAN_CONFIG_FLAG_SET_RX_CHAINS
|
1200 SCAN_CONFIG_FLAG_SET_AUX_STA_ID
|
1201 SCAN_CONFIG_FLAG_SET_ALL_TIMES
|
1202 SCAN_CONFIG_FLAG_SET_LEGACY_RATES
|
1203 SCAN_CONFIG_FLAG_SET_MAC_ADDR
|
1204 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS
|
1205 SCAN_CONFIG_N_CHANNELS(num_channels
) |
1206 (iwl_mvm_is_scan_fragmented(type
) ?
1207 SCAN_CONFIG_FLAG_SET_FRAGMENTED
:
1208 SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED
);
1210 channel_flags
= IWL_CHANNEL_FLAG_EBS
|
1211 IWL_CHANNEL_FLAG_ACCURATE_EBS
|
1212 IWL_CHANNEL_FLAG_EBS_ADD
|
1213 IWL_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE
;
1216 * Check for fragmented scan on LMAC2 - high band.
1217 * LMAC1 - low band is checked above.
1219 if (iwl_mvm_cdb_scan_api(mvm
)) {
1220 if (iwl_mvm_is_cdb_supported(mvm
))
1221 flags
|= (iwl_mvm_is_scan_fragmented(hb_type
)) ?
1222 SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED
:
1223 SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED
;
1224 iwl_mvm_fill_scan_config_v2(mvm
, cfg
, flags
, channel_flags
,
1227 iwl_mvm_fill_scan_config_v1(mvm
, cfg
, flags
, channel_flags
,
1232 cmd
.len
[0] = cmd_size
;
1233 cmd
.dataflags
[0] = IWL_HCMD_DFL_NOCOPY
;
1235 IWL_DEBUG_SCAN(mvm
, "Sending UMAC scan config\n");
1237 ret
= iwl_mvm_send_cmd(mvm
, &cmd
);
1239 mvm
->scan_type
= type
;
1240 mvm
->hb_scan_type
= hb_type
;
1247 int iwl_mvm_config_scan(struct iwl_mvm
*mvm
)
1249 struct iwl_scan_config cfg
;
1250 struct iwl_host_cmd cmd
= {
1251 .id
= WIDE_ID(IWL_ALWAYS_LONG_GROUP
, SCAN_CFG_CMD
),
1252 .len
[0] = sizeof(cfg
),
1254 .dataflags
[0] = IWL_HCMD_DFL_NOCOPY
,
1257 if (!iwl_mvm_is_reduced_config_scan_supported(mvm
))
1258 return iwl_mvm_legacy_config_scan(mvm
);
1260 memset(&cfg
, 0, sizeof(cfg
));
1262 if (!iwl_mvm_has_new_station_api(mvm
->fw
)) {
1263 cfg
.bcast_sta_id
= mvm
->aux_sta
.sta_id
;
1264 } else if (iwl_fw_lookup_cmd_ver(mvm
->fw
, SCAN_CFG_CMD
, 0) < 5) {
1266 * Fw doesn't use this sta anymore. Deprecated on SCAN_CFG_CMD
1269 cfg
.bcast_sta_id
= 0xff;
1272 cfg
.tx_chains
= cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm
));
1273 cfg
.rx_chains
= cpu_to_le32(iwl_mvm_scan_rx_ant(mvm
));
1275 IWL_DEBUG_SCAN(mvm
, "Sending UMAC scan config\n");
1277 return iwl_mvm_send_cmd(mvm
, &cmd
);
1280 static int iwl_mvm_scan_uid_by_status(struct iwl_mvm
*mvm
, int status
)
1284 for (i
= 0; i
< mvm
->max_scans
; i
++)
1285 if (mvm
->scan_uid_status
[i
] == status
)
1291 static void iwl_mvm_scan_umac_dwell(struct iwl_mvm
*mvm
,
1292 struct iwl_scan_req_umac
*cmd
,
1293 struct iwl_mvm_scan_params
*params
)
1295 struct iwl_mvm_scan_timing_params
*timing
, *hb_timing
;
1296 u8 active_dwell
, passive_dwell
;
1298 timing
= &scan_timing
[params
->type
];
1299 active_dwell
= IWL_SCAN_DWELL_ACTIVE
;
1300 passive_dwell
= IWL_SCAN_DWELL_PASSIVE
;
1302 if (iwl_mvm_is_adaptive_dwell_supported(mvm
)) {
1303 cmd
->v7
.adwell_default_n_aps_social
=
1304 IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL
;
1305 cmd
->v7
.adwell_default_n_aps
=
1306 IWL_SCAN_ADWELL_DEFAULT_LB_N_APS
;
1308 if (iwl_mvm_is_adwell_hb_ap_num_supported(mvm
))
1309 cmd
->v9
.adwell_default_hb_n_aps
=
1310 IWL_SCAN_ADWELL_DEFAULT_HB_N_APS
;
1312 /* if custom max budget was configured with debugfs */
1313 if (IWL_MVM_ADWELL_MAX_BUDGET
)
1314 cmd
->v7
.adwell_max_budget
=
1315 cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET
);
1316 else if (params
->n_ssids
&& params
->ssids
[0].ssid_len
)
1317 cmd
->v7
.adwell_max_budget
=
1318 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN
);
1320 cmd
->v7
.adwell_max_budget
=
1321 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN
);
1323 cmd
->v7
.scan_priority
= cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6
);
1324 cmd
->v7
.max_out_time
[SCAN_LB_LMAC_IDX
] =
1325 cpu_to_le32(timing
->max_out_time
);
1326 cmd
->v7
.suspend_time
[SCAN_LB_LMAC_IDX
] =
1327 cpu_to_le32(timing
->suspend_time
);
1329 if (iwl_mvm_is_cdb_supported(mvm
)) {
1330 hb_timing
= &scan_timing
[params
->hb_type
];
1332 cmd
->v7
.max_out_time
[SCAN_HB_LMAC_IDX
] =
1333 cpu_to_le32(hb_timing
->max_out_time
);
1334 cmd
->v7
.suspend_time
[SCAN_HB_LMAC_IDX
] =
1335 cpu_to_le32(hb_timing
->suspend_time
);
1338 if (!iwl_mvm_is_adaptive_dwell_v2_supported(mvm
)) {
1339 cmd
->v7
.active_dwell
= active_dwell
;
1340 cmd
->v7
.passive_dwell
= passive_dwell
;
1341 cmd
->v7
.fragmented_dwell
= IWL_SCAN_DWELL_FRAGMENTED
;
1343 cmd
->v8
.active_dwell
[SCAN_LB_LMAC_IDX
] = active_dwell
;
1344 cmd
->v8
.passive_dwell
[SCAN_LB_LMAC_IDX
] = passive_dwell
;
1345 if (iwl_mvm_is_cdb_supported(mvm
)) {
1346 cmd
->v8
.active_dwell
[SCAN_HB_LMAC_IDX
] =
1348 cmd
->v8
.passive_dwell
[SCAN_HB_LMAC_IDX
] =
1353 cmd
->v1
.extended_dwell
= IWL_SCAN_DWELL_EXTENDED
;
1354 cmd
->v1
.active_dwell
= active_dwell
;
1355 cmd
->v1
.passive_dwell
= passive_dwell
;
1356 cmd
->v1
.fragmented_dwell
= IWL_SCAN_DWELL_FRAGMENTED
;
1358 if (iwl_mvm_is_cdb_supported(mvm
)) {
1359 hb_timing
= &scan_timing
[params
->hb_type
];
1361 cmd
->v6
.max_out_time
[SCAN_HB_LMAC_IDX
] =
1362 cpu_to_le32(hb_timing
->max_out_time
);
1363 cmd
->v6
.suspend_time
[SCAN_HB_LMAC_IDX
] =
1364 cpu_to_le32(hb_timing
->suspend_time
);
1367 if (iwl_mvm_cdb_scan_api(mvm
)) {
1368 cmd
->v6
.scan_priority
=
1369 cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6
);
1370 cmd
->v6
.max_out_time
[SCAN_LB_LMAC_IDX
] =
1371 cpu_to_le32(timing
->max_out_time
);
1372 cmd
->v6
.suspend_time
[SCAN_LB_LMAC_IDX
] =
1373 cpu_to_le32(timing
->suspend_time
);
1375 cmd
->v1
.scan_priority
=
1376 cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6
);
1377 cmd
->v1
.max_out_time
=
1378 cpu_to_le32(timing
->max_out_time
);
1379 cmd
->v1
.suspend_time
=
1380 cpu_to_le32(timing
->suspend_time
);
1384 if (iwl_mvm_is_regular_scan(params
))
1385 cmd
->ooc_priority
= cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6
);
1387 cmd
->ooc_priority
= cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2
);
1390 static u32
iwl_mvm_scan_umac_ooc_priority(int type
)
1392 if (type
== IWL_MVM_SCAN_REGULAR
)
1393 return IWL_SCAN_PRIORITY_EXT_6
;
1394 if (type
== IWL_MVM_SCAN_INT_MLO
)
1395 return IWL_SCAN_PRIORITY_EXT_4
;
1397 return IWL_SCAN_PRIORITY_EXT_2
;
1401 iwl_mvm_scan_umac_dwell_v11(struct iwl_mvm
*mvm
,
1402 struct iwl_scan_general_params_v11
*general_params
,
1403 struct iwl_mvm_scan_params
*params
)
1405 struct iwl_mvm_scan_timing_params
*timing
, *hb_timing
;
1406 u8 active_dwell
, passive_dwell
;
1408 timing
= &scan_timing
[params
->type
];
1409 active_dwell
= IWL_SCAN_DWELL_ACTIVE
;
1410 passive_dwell
= IWL_SCAN_DWELL_PASSIVE
;
1412 general_params
->adwell_default_social_chn
=
1413 IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL
;
1414 general_params
->adwell_default_2g
= IWL_SCAN_ADWELL_DEFAULT_LB_N_APS
;
1415 general_params
->adwell_default_5g
= IWL_SCAN_ADWELL_DEFAULT_HB_N_APS
;
1417 /* if custom max budget was configured with debugfs */
1418 if (IWL_MVM_ADWELL_MAX_BUDGET
)
1419 general_params
->adwell_max_budget
=
1420 cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET
);
1421 else if (params
->n_ssids
&& params
->ssids
[0].ssid_len
)
1422 general_params
->adwell_max_budget
=
1423 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN
);
1425 general_params
->adwell_max_budget
=
1426 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN
);
1428 general_params
->scan_priority
= cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6
);
1429 general_params
->max_out_of_time
[SCAN_LB_LMAC_IDX
] =
1430 cpu_to_le32(timing
->max_out_time
);
1431 general_params
->suspend_time
[SCAN_LB_LMAC_IDX
] =
1432 cpu_to_le32(timing
->suspend_time
);
1434 hb_timing
= &scan_timing
[params
->hb_type
];
1436 general_params
->max_out_of_time
[SCAN_HB_LMAC_IDX
] =
1437 cpu_to_le32(hb_timing
->max_out_time
);
1438 general_params
->suspend_time
[SCAN_HB_LMAC_IDX
] =
1439 cpu_to_le32(hb_timing
->suspend_time
);
1441 general_params
->active_dwell
[SCAN_LB_LMAC_IDX
] = active_dwell
;
1442 general_params
->passive_dwell
[SCAN_LB_LMAC_IDX
] = passive_dwell
;
1443 general_params
->active_dwell
[SCAN_HB_LMAC_IDX
] = active_dwell
;
1444 general_params
->passive_dwell
[SCAN_HB_LMAC_IDX
] = passive_dwell
;
1447 struct iwl_mvm_scan_channel_segment
{
1450 u8 first_channel_id
;
1452 u8 channel_spacing_shift
;
1456 static const struct iwl_mvm_scan_channel_segment scan_channel_segments
[] = {
1460 .first_channel_id
= 1,
1461 .last_channel_id
= 14,
1462 .channel_spacing_shift
= 0,
1468 .first_channel_id
= 36,
1469 .last_channel_id
= 144,
1470 .channel_spacing_shift
= 2,
1476 .first_channel_id
= 149,
1477 .last_channel_id
= 181,
1478 .channel_spacing_shift
= 2,
1484 .first_channel_id
= 1,
1485 .last_channel_id
= 241,
1486 .channel_spacing_shift
= 2,
1491 static int iwl_mvm_scan_ch_and_band_to_idx(u8 channel_id
, u8 band
)
1498 for (i
= 0; i
< ARRAY_SIZE(scan_channel_segments
); i
++) {
1499 const struct iwl_mvm_scan_channel_segment
*ch_segment
=
1500 &scan_channel_segments
[i
];
1503 if (ch_segment
->band
!= band
||
1504 ch_segment
->first_channel_id
> channel_id
||
1505 ch_segment
->last_channel_id
< channel_id
)
1508 ch_offset
= (channel_id
- ch_segment
->first_channel_id
) >>
1509 ch_segment
->channel_spacing_shift
;
1511 index
= scan_channel_segments
[i
].start_idx
+ ch_offset
;
1512 if (index
< IWL_SCAN_NUM_CHANNELS
)
1521 static const u8 p2p_go_friendly_chs
[] = {
1522 36, 40, 44, 48, 149, 153, 157, 161, 165,
1525 static const u8 social_chs
[] = {
1529 static void iwl_mvm_scan_ch_add_n_aps_override(enum nl80211_iftype vif_type
,
1530 u8 ch_id
, u8 band
, u8
*ch_bitmap
,
1531 size_t bitmap_n_entries
)
1535 if (vif_type
!= NL80211_IFTYPE_P2P_DEVICE
)
1538 for (i
= 0; i
< ARRAY_SIZE(p2p_go_friendly_chs
); i
++) {
1539 if (p2p_go_friendly_chs
[i
] == ch_id
) {
1540 int ch_idx
, bitmap_idx
;
1542 ch_idx
= iwl_mvm_scan_ch_and_band_to_idx(ch_id
, band
);
1546 bitmap_idx
= ch_idx
/ 8;
1547 if (bitmap_idx
>= bitmap_n_entries
)
1550 ch_idx
= ch_idx
% 8;
1551 ch_bitmap
[bitmap_idx
] |= BIT(ch_idx
);
1558 static u32
iwl_mvm_scan_ch_n_aps_flag(enum nl80211_iftype vif_type
, u8 ch_id
)
1563 if (vif_type
!= NL80211_IFTYPE_P2P_DEVICE
)
1566 for (i
= 0; i
< ARRAY_SIZE(p2p_go_friendly_chs
); i
++) {
1567 if (p2p_go_friendly_chs
[i
] == ch_id
) {
1568 flags
|= IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT
;
1576 for (i
= 0; i
< ARRAY_SIZE(social_chs
); i
++) {
1577 if (social_chs
[i
] == ch_id
) {
1578 flags
|= IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT
;
1588 iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm
*mvm
,
1589 struct ieee80211_channel
**channels
,
1590 int n_channels
, u32 flags
,
1591 struct iwl_scan_channel_cfg_umac
*channel_cfg
)
1595 for (i
= 0; i
< n_channels
; i
++) {
1596 channel_cfg
[i
].flags
= cpu_to_le32(flags
);
1597 channel_cfg
[i
].channel_num
= channels
[i
]->hw_value
;
1598 if (iwl_mvm_is_scan_ext_chan_supported(mvm
)) {
1599 enum nl80211_band band
= channels
[i
]->band
;
1601 channel_cfg
[i
].v2
.band
=
1602 iwl_mvm_phy_band_from_nl80211(band
);
1603 channel_cfg
[i
].v2
.iter_count
= 1;
1604 channel_cfg
[i
].v2
.iter_interval
= 0;
1606 channel_cfg
[i
].v1
.iter_count
= 1;
1607 channel_cfg
[i
].v1
.iter_interval
= 0;
1613 iwl_mvm_umac_scan_cfg_channels_v4(struct iwl_mvm
*mvm
,
1614 struct ieee80211_channel
**channels
,
1615 struct iwl_scan_channel_params_v4
*cp
,
1616 int n_channels
, u32 flags
,
1617 enum nl80211_iftype vif_type
)
1619 u8
*bitmap
= cp
->adwell_ch_override_bitmap
;
1620 size_t bitmap_n_entries
= ARRAY_SIZE(cp
->adwell_ch_override_bitmap
);
1623 for (i
= 0; i
< n_channels
; i
++) {
1624 enum nl80211_band band
= channels
[i
]->band
;
1625 struct iwl_scan_channel_cfg_umac
*cfg
=
1626 &cp
->channel_config
[i
];
1628 cfg
->flags
= cpu_to_le32(flags
);
1629 cfg
->channel_num
= channels
[i
]->hw_value
;
1630 cfg
->v2
.band
= iwl_mvm_phy_band_from_nl80211(band
);
1631 cfg
->v2
.iter_count
= 1;
1632 cfg
->v2
.iter_interval
= 0;
1634 iwl_mvm_scan_ch_add_n_aps_override(vif_type
,
1636 cfg
->v2
.band
, bitmap
,
1642 iwl_mvm_umac_scan_cfg_channels_v7(struct iwl_mvm
*mvm
,
1643 struct ieee80211_channel
**channels
,
1644 struct iwl_scan_channel_params_v7
*cp
,
1645 int n_channels
, u32 flags
,
1646 enum nl80211_iftype vif_type
, u32 version
)
1650 for (i
= 0; i
< n_channels
; i
++) {
1651 enum nl80211_band band
= channels
[i
]->band
;
1652 struct iwl_scan_channel_cfg_umac
*cfg
= &cp
->channel_config
[i
];
1654 iwl_mvm_scan_ch_n_aps_flag(vif_type
,
1655 channels
[i
]->hw_value
);
1656 u8 iwl_band
= iwl_mvm_phy_band_from_nl80211(band
);
1658 cfg
->flags
= cpu_to_le32(flags
| n_aps_flag
);
1659 cfg
->channel_num
= channels
[i
]->hw_value
;
1660 if (cfg80211_channel_is_psc(channels
[i
]))
1663 if (band
== NL80211_BAND_6GHZ
) {
1664 /* 6 GHz channels should only appear in a scan request
1665 * that has scan_6ghz set. The only exception is MLO
1666 * scan, which has to be passive.
1668 WARN_ON_ONCE(cfg
->flags
!= 0);
1670 cpu_to_le32(IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE
);
1673 cfg
->v2
.iter_count
= 1;
1674 cfg
->v2
.iter_interval
= 0;
1676 cfg
->v2
.band
= iwl_band
;
1678 cfg
->flags
|= cpu_to_le32((iwl_band
<<
1679 IWL_CHAN_CFG_FLAGS_BAND_POS
));
1684 iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm
*mvm
,
1685 struct iwl_mvm_scan_params
*params
,
1686 struct iwl_scan_probe_params_v4
*pp
)
1688 int j
, idex_s
= 0, idex_b
= 0;
1689 struct cfg80211_scan_6ghz_params
*scan_6ghz_params
=
1690 params
->scan_6ghz_params
;
1691 bool hidden_supported
= fw_has_capa(&mvm
->fw
->ucode_capa
,
1692 IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN
);
1694 for (j
= 0; j
< params
->n_ssids
&& idex_s
< SCAN_SHORT_SSID_MAX_SIZE
;
1696 if (!params
->ssids
[j
].ssid_len
)
1699 pp
->short_ssid
[idex_s
] =
1700 cpu_to_le32(~crc32_le(~0, params
->ssids
[j
].ssid
,
1701 params
->ssids
[j
].ssid_len
));
1703 if (hidden_supported
) {
1704 pp
->direct_scan
[idex_s
].id
= WLAN_EID_SSID
;
1705 pp
->direct_scan
[idex_s
].len
= params
->ssids
[j
].ssid_len
;
1706 memcpy(pp
->direct_scan
[idex_s
].ssid
, params
->ssids
[j
].ssid
,
1707 params
->ssids
[j
].ssid_len
);
1713 * Populate the arrays of the short SSIDs and the BSSIDs using the 6GHz
1714 * collocated parameters. This might not be optimal, as this processing
1715 * does not (yet) correspond to the actual channels, so it is possible
1716 * that some entries would be left out.
1718 * TODO: improve this logic.
1720 for (j
= 0; j
< params
->n_6ghz_params
; j
++) {
1723 /* First, try to place the short SSID */
1724 if (scan_6ghz_params
[j
].short_ssid_valid
) {
1725 for (k
= 0; k
< idex_s
; k
++) {
1726 if (pp
->short_ssid
[k
] ==
1727 cpu_to_le32(scan_6ghz_params
[j
].short_ssid
))
1731 if (k
== idex_s
&& idex_s
< SCAN_SHORT_SSID_MAX_SIZE
) {
1732 pp
->short_ssid
[idex_s
++] =
1733 cpu_to_le32(scan_6ghz_params
[j
].short_ssid
);
1737 /* try to place BSSID for the same entry */
1738 for (k
= 0; k
< idex_b
; k
++) {
1739 if (!memcmp(&pp
->bssid_array
[k
],
1740 scan_6ghz_params
[j
].bssid
, ETH_ALEN
))
1744 if (k
== idex_b
&& idex_b
< SCAN_BSSID_MAX_SIZE
&&
1745 !WARN_ONCE(!is_valid_ether_addr(scan_6ghz_params
[j
].bssid
),
1746 "scan: invalid BSSID at index %u, index_b=%u\n",
1748 memcpy(&pp
->bssid_array
[idex_b
++],
1749 scan_6ghz_params
[j
].bssid
, ETH_ALEN
);
1753 pp
->short_ssid_num
= idex_s
;
1754 pp
->bssid_num
= idex_b
;
1757 /* TODO: this function can be merged with iwl_mvm_scan_umac_fill_ch_p_v7 */
1759 iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm
*mvm
,
1760 struct iwl_mvm_scan_params
*params
,
1762 struct iwl_scan_probe_params_v4
*pp
,
1763 struct iwl_scan_channel_params_v7
*cp
,
1764 enum nl80211_iftype vif_type
,
1768 struct cfg80211_scan_6ghz_params
*scan_6ghz_params
=
1769 params
->scan_6ghz_params
;
1772 for (i
= 0, ch_cnt
= 0; i
< params
->n_channels
; i
++) {
1773 struct iwl_scan_channel_cfg_umac
*cfg
=
1774 &cp
->channel_config
[ch_cnt
];
1776 u32 s_ssid_bitmap
= 0, bssid_bitmap
= 0, flags
= 0;
1777 u8 k
, n_s_ssids
= 0, n_bssids
= 0;
1778 u8 max_s_ssids
, max_bssids
;
1779 bool force_passive
= false, found
= false, allow_passive
= true,
1780 unsolicited_probe_on_chan
= false, psc_no_listen
= false;
1781 s8 psd_20
= IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED
;
1784 * Avoid performing passive scan on non PSC channels unless the
1785 * scan is specifically a passive scan, i.e., no SSIDs
1786 * configured in the scan command.
1788 if (!cfg80211_channel_is_psc(params
->channels
[i
]) &&
1789 !params
->n_6ghz_params
&& params
->n_ssids
)
1792 cfg
->channel_num
= params
->channels
[i
]->hw_value
;
1794 cfg
->v2
.band
= PHY_BAND_6
;
1796 cfg
->flags
|= cpu_to_le32(PHY_BAND_6
<<
1797 IWL_CHAN_CFG_FLAGS_BAND_POS
);
1799 cfg
->v5
.iter_count
= 1;
1800 cfg
->v5
.iter_interval
= 0;
1802 for (u32 j
= 0; j
< params
->n_6ghz_params
; j
++) {
1805 if (!(scan_6ghz_params
[j
].channel_idx
== i
))
1808 unsolicited_probe_on_chan
|=
1809 scan_6ghz_params
[j
].unsolicited_probe
;
1811 /* Use the highest PSD value allowed as advertised by
1812 * APs for this channel
1814 tmp_psd_20
= scan_6ghz_params
[j
].psd_20
;
1816 IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED
&&
1818 IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED
||
1819 psd_20
< tmp_psd_20
))
1820 psd_20
= tmp_psd_20
;
1822 psc_no_listen
|= scan_6ghz_params
[j
].psc_no_listen
;
1826 * In the following cases apply passive scan:
1827 * 1. Non fragmented scan:
1828 * - PSC channel with NO_LISTEN_FLAG on should be treated
1829 * like non PSC channel
1830 * - Non PSC channel with more than 3 short SSIDs or more
1832 * - Non PSC Channel with unsolicited probe response and
1833 * more than 2 short SSIDs or more than 6 BSSIDs.
1834 * - PSC channel with more than 2 short SSIDs or more than
1836 * 3. Fragmented scan:
1837 * - PSC channel with more than 1 SSID or 3 BSSIDs.
1838 * - Non PSC channel with more than 2 SSIDs or 6 BSSIDs.
1839 * - Non PSC channel with unsolicited probe response and
1840 * more than 1 SSID or more than 3 BSSIDs.
1842 if (!iwl_mvm_is_scan_fragmented(params
->type
)) {
1843 if (!cfg80211_channel_is_psc(params
->channels
[i
]) ||
1845 if (unsolicited_probe_on_chan
) {
1856 } else if (cfg80211_channel_is_psc(params
->channels
[i
])) {
1860 if (unsolicited_probe_on_chan
) {
1870 * The optimize the scan time, i.e., reduce the scan dwell time
1871 * on each channel, the below logic tries to set 3 direct BSSID
1872 * probe requests for each broadcast probe request with a short
1874 * TODO: improve this logic
1876 for (u32 j
= 0; j
< params
->n_6ghz_params
; j
++) {
1877 if (!(scan_6ghz_params
[j
].channel_idx
== i
))
1883 k
< pp
->short_ssid_num
&& n_s_ssids
< max_s_ssids
;
1885 if (!scan_6ghz_params
[j
].unsolicited_probe
&&
1886 le32_to_cpu(pp
->short_ssid
[k
]) ==
1887 scan_6ghz_params
[j
].short_ssid
) {
1888 /* Relevant short SSID bit set */
1889 if (s_ssid_bitmap
& BIT(k
)) {
1895 * Prefer creating BSSID entries unless
1896 * the short SSID probe can be done in
1897 * the same channel dwell iteration.
1899 * We also need to create a short SSID
1900 * entry for any hidden AP.
1902 if (3 * n_s_ssids
> n_bssids
&&
1903 !pp
->direct_scan
[k
].len
)
1906 /* Hidden AP, cannot do passive scan */
1907 if (pp
->direct_scan
[k
].len
)
1908 allow_passive
= false;
1910 s_ssid_bitmap
|= BIT(k
);
1920 for (k
= 0; k
< pp
->bssid_num
; k
++) {
1921 if (!memcmp(&pp
->bssid_array
[k
],
1922 scan_6ghz_params
[j
].bssid
,
1924 if (!(bssid_bitmap
& BIT(k
))) {
1925 if (n_bssids
< max_bssids
) {
1926 bssid_bitmap
|= BIT(k
);
1929 force_passive
= TRUE
;
1937 if (cfg80211_channel_is_psc(params
->channels
[i
]) &&
1939 flags
|= IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN
;
1941 if (unsolicited_probe_on_chan
)
1942 flags
|= IWL_UHB_CHAN_CFG_FLAG_UNSOLICITED_PROBE_RES
;
1944 if ((allow_passive
&& force_passive
) ||
1945 (!(bssid_bitmap
| s_ssid_bitmap
) &&
1946 !cfg80211_channel_is_psc(params
->channels
[i
])))
1947 flags
|= IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE
;
1949 flags
|= bssid_bitmap
| (s_ssid_bitmap
<< 16);
1951 cfg
->flags
|= cpu_to_le32(flags
);
1953 cfg
->v5
.psd_20
= psd_20
;
1958 if (params
->n_channels
> ch_cnt
)
1960 "6GHz: reducing number channels: (%u->%u)\n",
1961 params
->n_channels
, ch_cnt
);
1966 static u8
iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm
*mvm
,
1967 struct iwl_mvm_scan_params
*params
,
1968 struct ieee80211_vif
*vif
)
1972 flags
|= IWL_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER
;
1974 if (iwl_mvm_scan_use_ebs(mvm
, vif
))
1975 flags
|= IWL_SCAN_CHANNEL_FLAG_EBS
|
1976 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE
|
1977 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD
;
1979 /* set fragmented ebs for fragmented scan on HB channels */
1980 if ((!iwl_mvm_is_cdb_supported(mvm
) &&
1981 iwl_mvm_is_scan_fragmented(params
->type
)) ||
1982 (iwl_mvm_is_cdb_supported(mvm
) &&
1983 iwl_mvm_is_scan_fragmented(params
->hb_type
)))
1984 flags
|= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG
;
1987 * force EBS in case the scan is a fragmented and there is a need to take P2P
1988 * GO operation into consideration during scan operation.
1990 if ((!iwl_mvm_is_cdb_supported(mvm
) &&
1991 iwl_mvm_is_scan_fragmented(params
->type
) && params
->respect_p2p_go
) ||
1992 (iwl_mvm_is_cdb_supported(mvm
) &&
1993 iwl_mvm_is_scan_fragmented(params
->hb_type
) &&
1994 params
->respect_p2p_go_hb
)) {
1995 IWL_DEBUG_SCAN(mvm
, "Respect P2P GO. Force EBS\n");
1996 flags
|= IWL_SCAN_CHANNEL_FLAG_FORCE_EBS
;
2002 static void iwl_mvm_scan_6ghz_passive_scan(struct iwl_mvm
*mvm
,
2003 struct iwl_mvm_scan_params
*params
,
2004 struct ieee80211_vif
*vif
)
2006 struct ieee80211_supported_band
*sband
=
2007 &mvm
->nvm_data
->bands
[NL80211_BAND_6GHZ
];
2010 params
->enable_6ghz_passive
= false;
2012 if (params
->scan_6ghz
)
2015 if (!fw_has_capa(&mvm
->fw
->ucode_capa
,
2016 IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN
)) {
2018 "6GHz passive scan: Not supported by FW\n");
2022 /* 6GHz passive scan allowed only on station interface */
2023 if (vif
->type
!= NL80211_IFTYPE_STATION
) {
2025 "6GHz passive scan: not station interface\n");
2030 * 6GHz passive scan is allowed in a defined time interval following HW
2031 * reset or resume flow, or while not associated and a large interval
2032 * has passed since the last 6GHz passive scan.
2034 if ((vif
->cfg
.assoc
||
2035 time_after(mvm
->last_6ghz_passive_scan_jiffies
+
2036 (IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT
* HZ
), jiffies
)) &&
2037 (time_before(mvm
->last_reset_or_resume_time_jiffies
+
2038 (IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT
* HZ
),
2040 IWL_DEBUG_SCAN(mvm
, "6GHz passive scan: %s\n",
2041 vif
->cfg
.assoc
? "associated" :
2042 "timeout did not expire");
2046 /* not enough channels in the regular scan request */
2047 if (params
->n_channels
< IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS
) {
2049 "6GHz passive scan: not enough channels\n");
2053 for (i
= 0; i
< params
->n_ssids
; i
++) {
2054 if (!params
->ssids
[i
].ssid_len
)
2058 /* not a wildcard scan, so cannot enable passive 6GHz scan */
2059 if (i
== params
->n_ssids
) {
2061 "6GHz passive scan: no wildcard SSID\n");
2065 if (!sband
|| !sband
->n_channels
) {
2067 "6GHz passive scan: no 6GHz channels\n");
2071 for (i
= 0, n_disabled
= 0; i
< sband
->n_channels
; i
++) {
2072 if (sband
->channels
[i
].flags
& (IEEE80211_CHAN_DISABLED
))
2077 * Not all the 6GHz channels are disabled, so no need for 6GHz passive
2080 if (n_disabled
!= sband
->n_channels
) {
2082 "6GHz passive scan: 6GHz channels enabled\n");
2086 /* all conditions to enable 6ghz passive scan are satisfied */
2087 IWL_DEBUG_SCAN(mvm
, "6GHz passive scan: can be enabled\n");
2088 params
->enable_6ghz_passive
= true;
2091 static u16
iwl_mvm_scan_umac_flags_v2(struct iwl_mvm
*mvm
,
2092 struct iwl_mvm_scan_params
*params
,
2093 struct ieee80211_vif
*vif
,
2099 * If no direct SSIDs are provided perform a passive scan. Otherwise,
2100 * if there is a single SSID which is not the broadcast SSID, assume
2101 * that the scan is intended for roaming purposes and thus enable Rx on
2102 * all chains to improve chances of hearing the beacons/probe responses.
2104 if (params
->n_ssids
== 0)
2105 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE
;
2106 else if (params
->n_ssids
== 1 && params
->ssids
[0].ssid_len
)
2107 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_USE_ALL_RX_CHAINS
;
2109 if (iwl_mvm_is_scan_fragmented(params
->type
))
2110 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1
;
2112 if (iwl_mvm_is_scan_fragmented(params
->hb_type
))
2113 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2
;
2115 if (params
->pass_all
)
2116 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL
;
2118 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_MATCH
;
2120 if (!iwl_mvm_is_regular_scan(params
))
2121 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC
;
2123 if (params
->iter_notif
||
2124 mvm
->sched_scan_pass_all
== SCHED_SCAN_PASS_ALL_ENABLED
)
2125 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE
;
2127 if (IWL_MVM_ADWELL_ENABLE
)
2128 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL
;
2130 if (type
== IWL_MVM_SCAN_SCHED
|| type
== IWL_MVM_SCAN_NETDETECT
)
2131 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_PREEMPTIVE
;
2133 if ((type
== IWL_MVM_SCAN_SCHED
|| type
== IWL_MVM_SCAN_NETDETECT
) &&
2134 params
->flags
& NL80211_SCAN_FLAG_COLOCATED_6GHZ
)
2135 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN
;
2137 if (params
->enable_6ghz_passive
)
2138 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN
;
2140 if (iwl_mvm_is_oce_supported(mvm
) &&
2141 (params
->flags
& (NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP
|
2142 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE
|
2143 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME
)))
2144 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_V2_OCE
;
2149 static u8
iwl_mvm_scan_umac_flags2(struct iwl_mvm
*mvm
,
2150 struct iwl_mvm_scan_params
*params
,
2151 struct ieee80211_vif
*vif
, int type
,
2156 if (iwl_mvm_is_cdb_supported(mvm
)) {
2157 if (params
->respect_p2p_go
)
2158 flags
|= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB
;
2159 if (params
->respect_p2p_go_hb
)
2160 flags
|= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB
;
2162 if (params
->respect_p2p_go
)
2163 flags
= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB
|
2164 IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB
;
2167 if (params
->scan_6ghz
&&
2168 fw_has_capa(&mvm
->fw
->ucode_capa
,
2169 IWL_UCODE_TLV_CAPA_SCAN_DONT_TOGGLE_ANT
))
2170 flags
|= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_DONT_TOGGLE_ANT
;
2172 /* Passive and AP interface -> ACS (automatic channel selection) */
2173 if (gen_flags
& IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE
&&
2174 ieee80211_vif_type_p2p(vif
) == NL80211_IFTYPE_AP
&&
2175 iwl_fw_lookup_notif_ver(mvm
->fw
, SCAN_GROUP
, CHANNEL_SURVEY_NOTIF
,
2177 flags
|= IWL_UMAC_SCAN_GEN_FLAGS2_COLLECT_CHANNEL_STATS
;
2182 static u16
iwl_mvm_scan_umac_flags(struct iwl_mvm
*mvm
,
2183 struct iwl_mvm_scan_params
*params
,
2184 struct ieee80211_vif
*vif
)
2188 if (params
->n_ssids
== 0)
2189 flags
= IWL_UMAC_SCAN_GEN_FLAGS_PASSIVE
;
2191 if (params
->n_ssids
== 1 && params
->ssids
[0].ssid_len
!= 0)
2192 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT
;
2194 if (iwl_mvm_is_scan_fragmented(params
->type
))
2195 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED
;
2197 if (iwl_mvm_is_cdb_supported(mvm
) &&
2198 iwl_mvm_is_scan_fragmented(params
->hb_type
))
2199 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED
;
2201 if (iwl_mvm_rrm_scan_needed(mvm
) &&
2202 fw_has_capa(&mvm
->fw
->ucode_capa
,
2203 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT
))
2204 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED
;
2206 if (params
->pass_all
)
2207 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL
;
2209 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_MATCH
;
2211 if (!iwl_mvm_is_regular_scan(params
))
2212 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_PERIODIC
;
2214 if (params
->iter_notif
)
2215 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE
;
2217 #ifdef CONFIG_IWLWIFI_DEBUGFS
2218 if (mvm
->scan_iter_notif_enabled
)
2219 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE
;
2222 if (mvm
->sched_scan_pass_all
== SCHED_SCAN_PASS_ALL_ENABLED
)
2223 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE
;
2225 if (iwl_mvm_is_adaptive_dwell_supported(mvm
) && IWL_MVM_ADWELL_ENABLE
)
2226 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL
;
2229 * Extended dwell is relevant only for low band to start with, as it is
2230 * being used for social channles only (1, 6, 11), so we can check
2231 * only scan type on low band also for CDB.
2233 if (iwl_mvm_is_regular_scan(params
) &&
2234 vif
->type
!= NL80211_IFTYPE_P2P_DEVICE
&&
2235 !iwl_mvm_is_scan_fragmented(params
->type
) &&
2236 !iwl_mvm_is_adaptive_dwell_supported(mvm
) &&
2237 !iwl_mvm_is_oce_supported(mvm
))
2238 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL
;
2240 if (iwl_mvm_is_oce_supported(mvm
)) {
2241 if ((params
->flags
&
2242 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE
))
2243 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_HIGH_TX_RATE
;
2244 /* Since IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL and
2245 * NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION shares
2246 * the same bit, we need to make sure that we use this bit here
2247 * only when IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL cannot be
2249 if ((params
->flags
&
2250 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION
) &&
2251 !WARN_ON_ONCE(!iwl_mvm_is_adaptive_dwell_supported(mvm
)))
2252 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_DEFER_SUPP
;
2253 if ((params
->flags
& NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME
))
2254 flags
|= IWL_UMAC_SCAN_GEN_FLAGS_MAX_CHNL_TIME
;
2261 iwl_mvm_fill_scan_sched_params(struct iwl_mvm_scan_params
*params
,
2262 struct iwl_scan_umac_schedule
*schedule
,
2266 if (WARN_ON(!params
->n_scan_plans
||
2267 params
->n_scan_plans
> IWL_MAX_SCHED_SCAN_PLANS
))
2270 for (i
= 0; i
< params
->n_scan_plans
; i
++) {
2271 struct cfg80211_sched_scan_plan
*scan_plan
=
2272 ¶ms
->scan_plans
[i
];
2274 schedule
[i
].iter_count
= scan_plan
->iterations
;
2275 schedule
[i
].interval
=
2276 cpu_to_le16(scan_plan
->interval
);
2280 * If the number of iterations of the last scan plan is set to
2281 * zero, it should run infinitely. However, this is not always the case.
2282 * For example, when regular scan is requested the driver sets one scan
2283 * plan with one iteration.
2285 if (!schedule
[params
->n_scan_plans
- 1].iter_count
)
2286 schedule
[params
->n_scan_plans
- 1].iter_count
= 0xff;
2288 *delay
= cpu_to_le16(params
->delay
);
2293 static int iwl_mvm_scan_umac(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2294 struct iwl_mvm_scan_params
*params
,
2297 struct iwl_scan_req_umac
*cmd
= mvm
->scan_cmd
;
2298 struct iwl_scan_umac_chan_param
*chan_param
;
2299 void *cmd_data
= iwl_mvm_get_scan_req_umac_data(mvm
);
2300 void *sec_part
= (u8
*)cmd_data
+ sizeof(struct iwl_scan_channel_cfg_umac
) *
2301 mvm
->fw
->ucode_capa
.n_scan_channels
;
2302 struct iwl_scan_req_umac_tail_v2
*tail_v2
=
2303 (struct iwl_scan_req_umac_tail_v2
*)sec_part
;
2304 struct iwl_scan_req_umac_tail_v1
*tail_v1
;
2305 struct iwl_ssid_ie
*direct_scan
;
2307 u32 ssid_bitmap
= 0;
2308 u8 channel_flags
= 0;
2310 struct iwl_mvm_vif
*scan_vif
= iwl_mvm_vif_from_mac80211(vif
);
2312 chan_param
= iwl_mvm_get_scan_req_umac_channel(mvm
);
2314 iwl_mvm_scan_umac_dwell(mvm
, cmd
, params
);
2316 cmd
->uid
= cpu_to_le32(uid
);
2317 gen_flags
= iwl_mvm_scan_umac_flags(mvm
, params
, vif
);
2318 cmd
->general_flags
= cpu_to_le16(gen_flags
);
2319 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm
)) {
2320 if (gen_flags
& IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED
)
2321 cmd
->v8
.num_of_fragments
[SCAN_LB_LMAC_IDX
] =
2322 IWL_SCAN_NUM_OF_FRAGS
;
2323 if (gen_flags
& IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED
)
2324 cmd
->v8
.num_of_fragments
[SCAN_HB_LMAC_IDX
] =
2325 IWL_SCAN_NUM_OF_FRAGS
;
2327 cmd
->v8
.general_flags2
=
2328 IWL_UMAC_SCAN_GEN_FLAGS2_ALLOW_CHNL_REORDER
;
2331 cmd
->scan_start_mac_id
= scan_vif
->id
;
2333 if (type
== IWL_MVM_SCAN_SCHED
|| type
== IWL_MVM_SCAN_NETDETECT
)
2334 cmd
->flags
= cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE
);
2336 if (iwl_mvm_scan_use_ebs(mvm
, vif
)) {
2337 channel_flags
= IWL_SCAN_CHANNEL_FLAG_EBS
|
2338 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE
|
2339 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD
;
2341 /* set fragmented ebs for fragmented scan on HB channels */
2342 if (iwl_mvm_is_frag_ebs_supported(mvm
)) {
2344 IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED
||
2345 (!iwl_mvm_is_cdb_supported(mvm
) &&
2346 gen_flags
& IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED
))
2347 channel_flags
|= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG
;
2351 chan_param
->flags
= channel_flags
;
2352 chan_param
->count
= params
->n_channels
;
2354 ret
= iwl_mvm_fill_scan_sched_params(params
, tail_v2
->schedule
,
2359 if (iwl_mvm_is_scan_ext_chan_supported(mvm
)) {
2360 tail_v2
->preq
= params
->preq
;
2361 direct_scan
= tail_v2
->direct_scan
;
2363 tail_v1
= (struct iwl_scan_req_umac_tail_v1
*)sec_part
;
2364 iwl_mvm_scan_set_legacy_probe_req(&tail_v1
->preq
,
2366 direct_scan
= tail_v1
->direct_scan
;
2368 iwl_scan_build_ssids(params
, direct_scan
, &ssid_bitmap
);
2369 iwl_mvm_umac_scan_cfg_channels(mvm
, params
->channels
,
2370 params
->n_channels
, ssid_bitmap
,
2376 iwl_mvm_scan_umac_fill_general_p_v12(struct iwl_mvm
*mvm
,
2377 struct iwl_mvm_scan_params
*params
,
2378 struct ieee80211_vif
*vif
,
2379 struct iwl_scan_general_params_v11
*gp
,
2380 u16 gen_flags
, u8 gen_flags2
,
2383 struct iwl_mvm_vif
*scan_vif
= iwl_mvm_vif_from_mac80211(vif
);
2385 iwl_mvm_scan_umac_dwell_v11(mvm
, gp
, params
);
2387 IWL_DEBUG_SCAN(mvm
, "General: flags=0x%x, flags2=0x%x\n",
2388 gen_flags
, gen_flags2
);
2390 gp
->flags
= cpu_to_le16(gen_flags
);
2391 gp
->flags2
= gen_flags2
;
2393 if (gen_flags
& IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1
)
2394 gp
->num_of_fragments
[SCAN_LB_LMAC_IDX
] = IWL_SCAN_NUM_OF_FRAGS
;
2395 if (gen_flags
& IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2
)
2396 gp
->num_of_fragments
[SCAN_HB_LMAC_IDX
] = IWL_SCAN_NUM_OF_FRAGS
;
2398 mvm
->scan_link_id
= 0;
2401 gp
->scan_start_mac_or_link_id
= scan_vif
->id
;
2403 struct iwl_mvm_vif_link_info
*link_info
=
2404 scan_vif
->link
[params
->tsf_report_link_id
];
2406 mvm
->scan_link_id
= params
->tsf_report_link_id
;
2407 if (!WARN_ON(!link_info
))
2408 gp
->scan_start_mac_or_link_id
= link_info
->fw_link_id
;
2413 iwl_mvm_scan_umac_fill_probe_p_v3(struct iwl_mvm_scan_params
*params
,
2414 struct iwl_scan_probe_params_v3
*pp
)
2416 pp
->preq
= params
->preq
;
2417 pp
->ssid_num
= params
->n_ssids
;
2418 iwl_scan_build_ssids(params
, pp
->direct_scan
, NULL
);
2422 iwl_mvm_scan_umac_fill_probe_p_v4(struct iwl_mvm_scan_params
*params
,
2423 struct iwl_scan_probe_params_v4
*pp
,
2426 pp
->preq
= params
->preq
;
2427 iwl_scan_build_ssids(params
, pp
->direct_scan
, bitmap_ssid
);
2431 iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm
*mvm
,
2432 struct iwl_mvm_scan_params
*params
,
2433 struct ieee80211_vif
*vif
,
2434 struct iwl_scan_channel_params_v4
*cp
,
2435 u32 channel_cfg_flags
)
2437 cp
->flags
= iwl_mvm_scan_umac_chan_flags_v2(mvm
, params
, vif
);
2438 cp
->count
= params
->n_channels
;
2439 cp
->num_of_aps_override
= IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY
;
2441 iwl_mvm_umac_scan_cfg_channels_v4(mvm
, params
->channels
, cp
,
2448 iwl_mvm_scan_umac_fill_ch_p_v7(struct iwl_mvm
*mvm
,
2449 struct iwl_mvm_scan_params
*params
,
2450 struct ieee80211_vif
*vif
,
2451 struct iwl_scan_channel_params_v7
*cp
,
2452 u32 channel_cfg_flags
,
2455 cp
->flags
= iwl_mvm_scan_umac_chan_flags_v2(mvm
, params
, vif
);
2456 cp
->count
= params
->n_channels
;
2457 cp
->n_aps_override
[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY
;
2458 cp
->n_aps_override
[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS
;
2460 iwl_mvm_umac_scan_cfg_channels_v7(mvm
, params
->channels
, cp
,
2463 vif
->type
, version
);
2465 if (params
->enable_6ghz_passive
) {
2466 struct ieee80211_supported_band
*sband
=
2467 &mvm
->nvm_data
->bands
[NL80211_BAND_6GHZ
];
2470 for (i
= 0; i
< sband
->n_channels
; i
++) {
2471 struct ieee80211_channel
*channel
=
2472 &sband
->channels
[i
];
2474 struct iwl_scan_channel_cfg_umac
*cfg
=
2475 &cp
->channel_config
[cp
->count
];
2477 if (!cfg80211_channel_is_psc(channel
))
2480 cfg
->channel_num
= channel
->hw_value
;
2481 cfg
->v5
.iter_count
= 1;
2482 cfg
->v5
.iter_interval
= 0;
2486 cfg
->v2
.band
= PHY_BAND_6
;
2488 cfg
->flags
= cpu_to_le32(PHY_BAND_6
<<
2489 IWL_CHAN_CFG_FLAGS_BAND_POS
);
2491 IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED
;
2498 static int iwl_mvm_scan_umac_v12(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2499 struct iwl_mvm_scan_params
*params
, int type
,
2502 struct iwl_scan_req_umac_v12
*cmd
= mvm
->scan_cmd
;
2503 struct iwl_scan_req_params_v12
*scan_p
= &cmd
->scan_params
;
2507 cmd
->ooc_priority
= cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type
));
2508 cmd
->uid
= cpu_to_le32(uid
);
2510 gen_flags
= iwl_mvm_scan_umac_flags_v2(mvm
, params
, vif
, type
);
2511 iwl_mvm_scan_umac_fill_general_p_v12(mvm
, params
, vif
,
2512 &scan_p
->general_params
,
2515 ret
= iwl_mvm_fill_scan_sched_params(params
,
2516 scan_p
->periodic_params
.schedule
,
2517 &scan_p
->periodic_params
.delay
);
2521 iwl_mvm_scan_umac_fill_probe_p_v3(params
, &scan_p
->probe_params
);
2522 iwl_mvm_scan_umac_fill_ch_p_v4(mvm
, params
, vif
,
2523 &scan_p
->channel_params
, 0);
2528 static int iwl_mvm_scan_umac_v14_and_above(struct iwl_mvm
*mvm
,
2529 struct ieee80211_vif
*vif
,
2530 struct iwl_mvm_scan_params
*params
,
2531 int type
, int uid
, u32 version
)
2533 struct iwl_scan_req_umac_v17
*cmd
= mvm
->scan_cmd
;
2534 struct iwl_scan_req_params_v17
*scan_p
= &cmd
->scan_params
;
2535 struct iwl_scan_channel_params_v7
*cp
= &scan_p
->channel_params
;
2536 struct iwl_scan_probe_params_v4
*pb
= &scan_p
->probe_params
;
2540 u32 bitmap_ssid
= 0;
2542 cmd
->ooc_priority
= cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type
));
2543 cmd
->uid
= cpu_to_le32(uid
);
2545 gen_flags
= iwl_mvm_scan_umac_flags_v2(mvm
, params
, vif
, type
);
2548 gen_flags2
= iwl_mvm_scan_umac_flags2(mvm
, params
, vif
, type
,
2553 iwl_mvm_scan_umac_fill_general_p_v12(mvm
, params
, vif
,
2554 &scan_p
->general_params
,
2555 gen_flags
, gen_flags2
, version
);
2557 ret
= iwl_mvm_fill_scan_sched_params(params
,
2558 scan_p
->periodic_params
.schedule
,
2559 &scan_p
->periodic_params
.delay
);
2563 if (!params
->scan_6ghz
) {
2564 iwl_mvm_scan_umac_fill_probe_p_v4(params
,
2565 &scan_p
->probe_params
,
2567 iwl_mvm_scan_umac_fill_ch_p_v7(mvm
, params
, vif
,
2568 &scan_p
->channel_params
,
2573 pb
->preq
= params
->preq
;
2576 cp
->flags
= iwl_mvm_scan_umac_chan_flags_v2(mvm
, params
, vif
);
2577 cp
->n_aps_override
[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY
;
2578 cp
->n_aps_override
[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS
;
2580 iwl_mvm_umac_scan_fill_6g_chan_list(mvm
, params
, pb
);
2582 cp
->count
= iwl_mvm_umac_scan_cfg_channels_v7_6g(mvm
, params
,
2589 if (!params
->n_ssids
||
2590 (params
->n_ssids
== 1 && !params
->ssids
[0].ssid_len
))
2591 cp
->flags
|= IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER
;
2596 static int iwl_mvm_scan_umac_v14(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2597 struct iwl_mvm_scan_params
*params
, int type
,
2600 return iwl_mvm_scan_umac_v14_and_above(mvm
, vif
, params
, type
, uid
, 14);
2603 static int iwl_mvm_scan_umac_v15(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2604 struct iwl_mvm_scan_params
*params
, int type
,
2607 return iwl_mvm_scan_umac_v14_and_above(mvm
, vif
, params
, type
, uid
, 15);
2610 static int iwl_mvm_scan_umac_v16(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2611 struct iwl_mvm_scan_params
*params
, int type
,
2614 return iwl_mvm_scan_umac_v14_and_above(mvm
, vif
, params
, type
, uid
, 16);
2617 static int iwl_mvm_scan_umac_v17(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2618 struct iwl_mvm_scan_params
*params
, int type
,
2621 return iwl_mvm_scan_umac_v14_and_above(mvm
, vif
, params
, type
, uid
, 17);
2624 static int iwl_mvm_num_scans(struct iwl_mvm
*mvm
)
2626 return hweight32(mvm
->scan_status
& IWL_MVM_SCAN_MASK
);
2629 static int iwl_mvm_check_running_scans(struct iwl_mvm
*mvm
, int type
)
2631 bool unified_image
= fw_has_capa(&mvm
->fw
->ucode_capa
,
2632 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
2634 /* This looks a bit arbitrary, but the idea is that if we run
2635 * out of possible simultaneous scans and the userspace is
2636 * trying to run a scan type that is already running, we
2637 * return -EBUSY. But if the userspace wants to start a
2638 * different type of scan, we stop the opposite type to make
2639 * space for the new request. The reason is backwards
2640 * compatibility with old wpa_supplicant that wouldn't stop a
2641 * scheduled scan before starting a normal scan.
2644 /* FW supports only a single periodic scan */
2645 if ((type
== IWL_MVM_SCAN_SCHED
|| type
== IWL_MVM_SCAN_NETDETECT
) &&
2646 mvm
->scan_status
& (IWL_MVM_SCAN_SCHED
| IWL_MVM_SCAN_NETDETECT
))
2649 if (iwl_mvm_num_scans(mvm
) < mvm
->max_scans
)
2652 /* Use a switch, even though this is a bitmask, so that more
2653 * than one bits set will fall in default and we will warn.
2656 case IWL_MVM_SCAN_REGULAR
:
2657 if (mvm
->scan_status
& IWL_MVM_SCAN_REGULAR_MASK
)
2659 return iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_SCHED
, true);
2660 case IWL_MVM_SCAN_SCHED
:
2661 if (mvm
->scan_status
& IWL_MVM_SCAN_SCHED_MASK
)
2663 return iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_REGULAR
, true);
2664 case IWL_MVM_SCAN_NETDETECT
:
2665 /* For non-unified images, there's no need to stop
2666 * anything for net-detect since the firmware is
2667 * restarted anyway. This way, any sched scans that
2668 * were running will be restarted when we resume.
2673 /* If this is a unified image and we ran out of scans,
2674 * we need to stop something. Prefer stopping regular
2675 * scans, because the results are useless at this
2676 * point, and we should be able to keep running
2677 * another scheduled scan while suspended.
2679 if (mvm
->scan_status
& IWL_MVM_SCAN_REGULAR_MASK
)
2680 return iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_REGULAR
,
2682 if (mvm
->scan_status
& IWL_MVM_SCAN_SCHED_MASK
)
2683 return iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_SCHED
,
2685 /* Something is wrong if no scan was running but we
2697 #define SCAN_TIMEOUT 30000
2699 void iwl_mvm_scan_timeout_wk(struct work_struct
*work
)
2701 struct delayed_work
*delayed_work
= to_delayed_work(work
);
2702 struct iwl_mvm
*mvm
= container_of(delayed_work
, struct iwl_mvm
,
2703 scan_timeout_dwork
);
2705 IWL_ERR(mvm
, "regular scan timed out\n");
2707 iwl_force_nmi(mvm
->trans
);
2710 static void iwl_mvm_fill_scan_type(struct iwl_mvm
*mvm
,
2711 struct iwl_mvm_scan_params
*params
,
2712 struct ieee80211_vif
*vif
)
2714 if (iwl_mvm_is_cdb_supported(mvm
)) {
2716 iwl_mvm_get_scan_type_band(mvm
, vif
,
2719 iwl_mvm_get_scan_type_band(mvm
, vif
,
2722 params
->type
= iwl_mvm_get_scan_type(mvm
, vif
);
2726 struct iwl_scan_umac_handler
{
2728 int (*handler
)(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
2729 struct iwl_mvm_scan_params
*params
, int type
, int uid
);
2732 #define IWL_SCAN_UMAC_HANDLER(_ver) { \
2734 .handler = iwl_mvm_scan_umac_v##_ver, \
2737 static const struct iwl_scan_umac_handler iwl_scan_umac_handlers
[] = {
2738 /* set the newest version first to shorten the list traverse time */
2739 IWL_SCAN_UMAC_HANDLER(17),
2740 IWL_SCAN_UMAC_HANDLER(16),
2741 IWL_SCAN_UMAC_HANDLER(15),
2742 IWL_SCAN_UMAC_HANDLER(14),
2743 IWL_SCAN_UMAC_HANDLER(12),
2746 static void iwl_mvm_mei_scan_work(struct work_struct
*wk
)
2748 struct iwl_mei_scan_filter
*scan_filter
=
2749 container_of(wk
, struct iwl_mei_scan_filter
, scan_work
);
2750 struct iwl_mvm
*mvm
=
2751 container_of(scan_filter
, struct iwl_mvm
, mei_scan_filter
);
2752 struct iwl_mvm_csme_conn_info
*info
;
2753 struct sk_buff
*skb
;
2756 mutex_lock(&mvm
->mutex
);
2757 info
= iwl_mvm_get_csme_conn_info(mvm
);
2758 memcpy(bssid
, info
->conn_info
.bssid
, ETH_ALEN
);
2759 mutex_unlock(&mvm
->mutex
);
2761 while ((skb
= skb_dequeue(&scan_filter
->scan_res
))) {
2762 struct ieee80211_mgmt
*mgmt
= (void *)skb
->data
;
2764 if (!memcmp(mgmt
->bssid
, bssid
, ETH_ALEN
))
2765 ieee80211_rx_irqsafe(mvm
->hw
, skb
);
2771 void iwl_mvm_mei_scan_filter_init(struct iwl_mei_scan_filter
*mei_scan_filter
)
2773 skb_queue_head_init(&mei_scan_filter
->scan_res
);
2774 INIT_WORK(&mei_scan_filter
->scan_work
, iwl_mvm_mei_scan_work
);
2777 /* In case CSME is connected and has link protection set, this function will
2778 * override the scan request to scan only the associated channel and only for
2779 * the associated SSID.
2781 static void iwl_mvm_mei_limited_scan(struct iwl_mvm
*mvm
,
2782 struct iwl_mvm_scan_params
*params
)
2784 struct iwl_mvm_csme_conn_info
*info
= iwl_mvm_get_csme_conn_info(mvm
);
2785 struct iwl_mei_conn_info
*conn_info
;
2786 struct ieee80211_channel
*chan
;
2790 IWL_DEBUG_SCAN(mvm
, "mei_limited_scan: no connection info\n");
2794 conn_info
= &info
->conn_info
;
2795 if (!info
->conn_info
.lp_state
|| !info
->conn_info
.ssid_len
)
2798 if (!params
->n_channels
|| !params
->n_ssids
)
2801 mvm
->mei_scan_filter
.is_mei_limited_scan
= true;
2803 chan
= ieee80211_get_channel(mvm
->hw
->wiphy
,
2804 ieee80211_channel_to_frequency(conn_info
->channel
,
2808 "Failed to get CSME channel (chan=%u band=%u)\n",
2809 conn_info
->channel
, conn_info
->band
);
2813 /* The mei filtered scan must find the AP, otherwise CSME will
2814 * take the NIC ownership. Add several iterations on the channel to
2815 * make the scan more robust.
2817 scan_iters
= min(IWL_MEI_SCAN_NUM_ITER
, params
->n_channels
);
2818 params
->n_channels
= scan_iters
;
2819 for (i
= 0; i
< scan_iters
; i
++)
2820 params
->channels
[i
] = chan
;
2822 IWL_DEBUG_SCAN(mvm
, "Mei scan: num iterations=%u\n", scan_iters
);
2824 params
->n_ssids
= 1;
2825 params
->ssids
[0].ssid_len
= conn_info
->ssid_len
;
2826 memcpy(params
->ssids
[0].ssid
, conn_info
->ssid
, conn_info
->ssid_len
);
2829 static int iwl_mvm_build_scan_cmd(struct iwl_mvm
*mvm
,
2830 struct ieee80211_vif
*vif
,
2831 struct iwl_host_cmd
*hcmd
,
2832 struct iwl_mvm_scan_params
*params
,
2838 lockdep_assert_held(&mvm
->mutex
);
2839 memset(mvm
->scan_cmd
, 0, mvm
->scan_cmd_size
);
2841 iwl_mvm_mei_limited_scan(mvm
, params
);
2843 if (!fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_UMAC_SCAN
)) {
2844 hcmd
->id
= SCAN_OFFLOAD_REQUEST_CMD
;
2846 return iwl_mvm_scan_lmac(mvm
, vif
, params
);
2849 uid
= iwl_mvm_scan_uid_by_status(mvm
, 0);
2853 hcmd
->id
= WIDE_ID(IWL_ALWAYS_LONG_GROUP
, SCAN_REQ_UMAC
);
2855 scan_ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
, SCAN_REQ_UMAC
,
2856 IWL_FW_CMD_VER_UNKNOWN
);
2858 for (i
= 0; i
< ARRAY_SIZE(iwl_scan_umac_handlers
); i
++) {
2859 const struct iwl_scan_umac_handler
*ver_handler
=
2860 &iwl_scan_umac_handlers
[i
];
2862 if (ver_handler
->version
!= scan_ver
)
2865 err
= ver_handler
->handler(mvm
, vif
, params
, type
, uid
);
2869 err
= iwl_mvm_scan_umac(mvm
, vif
, params
, type
, uid
);
2876 struct iwl_mvm_scan_respect_p2p_go_iter_data
{
2877 struct ieee80211_vif
*current_vif
;
2879 enum nl80211_band band
;
2882 static void iwl_mvm_scan_respect_p2p_go_iter(void *_data
, u8
*mac
,
2883 struct ieee80211_vif
*vif
)
2885 struct iwl_mvm_scan_respect_p2p_go_iter_data
*data
= _data
;
2886 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
2888 /* exclude the given vif */
2889 if (vif
== data
->current_vif
)
2892 if (ieee80211_vif_type_p2p(vif
) == NL80211_IFTYPE_P2P_GO
) {
2896 link_id
< ARRAY_SIZE(mvmvif
->link
);
2898 struct iwl_mvm_vif_link_info
*link
=
2899 mvmvif
->link
[link_id
];
2901 if (link
&& link
->phy_ctxt
->id
< NUM_PHY_CTX
&&
2902 (data
->band
== NUM_NL80211_BANDS
||
2903 link
->phy_ctxt
->channel
->band
== data
->band
)) {
2904 data
->p2p_go
= true;
2911 static bool _iwl_mvm_get_respect_p2p_go(struct iwl_mvm
*mvm
,
2912 struct ieee80211_vif
*vif
,
2914 enum nl80211_band band
)
2916 struct iwl_mvm_scan_respect_p2p_go_iter_data data
= {
2925 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
2926 IEEE80211_IFACE_ITER_NORMAL
,
2927 iwl_mvm_scan_respect_p2p_go_iter
,
2933 static bool iwl_mvm_get_respect_p2p_go_band(struct iwl_mvm
*mvm
,
2934 struct ieee80211_vif
*vif
,
2935 enum nl80211_band band
)
2937 bool low_latency
= iwl_mvm_low_latency_band(mvm
, band
);
2939 return _iwl_mvm_get_respect_p2p_go(mvm
, vif
, low_latency
, band
);
2942 static bool iwl_mvm_get_respect_p2p_go(struct iwl_mvm
*mvm
,
2943 struct ieee80211_vif
*vif
)
2945 bool low_latency
= iwl_mvm_low_latency(mvm
);
2947 return _iwl_mvm_get_respect_p2p_go(mvm
, vif
, low_latency
,
2951 static void iwl_mvm_fill_respect_p2p_go(struct iwl_mvm
*mvm
,
2952 struct iwl_mvm_scan_params
*params
,
2953 struct ieee80211_vif
*vif
)
2955 if (iwl_mvm_is_cdb_supported(mvm
)) {
2956 params
->respect_p2p_go
=
2957 iwl_mvm_get_respect_p2p_go_band(mvm
, vif
,
2959 params
->respect_p2p_go_hb
=
2960 iwl_mvm_get_respect_p2p_go_band(mvm
, vif
,
2963 params
->respect_p2p_go
= iwl_mvm_get_respect_p2p_go(mvm
, vif
);
2967 static int _iwl_mvm_single_scan_start(struct iwl_mvm
*mvm
,
2968 struct ieee80211_vif
*vif
,
2969 struct cfg80211_scan_request
*req
,
2970 struct ieee80211_scan_ies
*ies
,
2973 struct iwl_host_cmd hcmd
= {
2974 .len
= { iwl_mvm_scan_size(mvm
), },
2975 .data
= { mvm
->scan_cmd
, },
2976 .dataflags
= { IWL_HCMD_DFL_NOCOPY
, },
2978 struct iwl_mvm_scan_params params
= {};
2980 struct cfg80211_sched_scan_plan scan_plan
= { .iterations
= 1 };
2982 lockdep_assert_held(&mvm
->mutex
);
2984 if (iwl_mvm_is_lar_supported(mvm
) && !mvm
->lar_regdom_set
) {
2985 IWL_ERR(mvm
, "scan while LAR regdomain is not set\n");
2989 ret
= iwl_mvm_check_running_scans(mvm
, type
);
2993 /* we should have failed registration if scan_cmd was NULL */
2994 if (WARN_ON(!mvm
->scan_cmd
))
2997 if (!iwl_mvm_scan_fits(mvm
, req
->n_ssids
, ies
, req
->n_channels
))
3000 params
.n_ssids
= req
->n_ssids
;
3001 params
.flags
= req
->flags
;
3002 params
.n_channels
= req
->n_channels
;
3004 params
.ssids
= req
->ssids
;
3005 params
.channels
= req
->channels
;
3006 params
.mac_addr
= req
->mac_addr
;
3007 params
.mac_addr_mask
= req
->mac_addr_mask
;
3008 params
.no_cck
= req
->no_cck
;
3009 params
.pass_all
= true;
3010 params
.n_match_sets
= 0;
3011 params
.match_sets
= NULL
;
3012 ether_addr_copy(params
.bssid
, req
->bssid
);
3014 params
.scan_plans
= &scan_plan
;
3015 params
.n_scan_plans
= 1;
3017 params
.n_6ghz_params
= req
->n_6ghz_params
;
3018 params
.scan_6ghz_params
= req
->scan_6ghz_params
;
3019 params
.scan_6ghz
= req
->scan_6ghz
;
3020 iwl_mvm_fill_scan_type(mvm
, ¶ms
, vif
);
3021 iwl_mvm_fill_respect_p2p_go(mvm
, ¶ms
, vif
);
3024 params
.iter_notif
= true;
3026 params
.tsf_report_link_id
= req
->tsf_report_link_id
;
3027 if (params
.tsf_report_link_id
< 0) {
3028 if (vif
->active_links
)
3029 params
.tsf_report_link_id
= __ffs(vif
->active_links
);
3031 params
.tsf_report_link_id
= 0;
3034 iwl_mvm_build_scan_probe(mvm
, vif
, ies
, ¶ms
);
3036 iwl_mvm_scan_6ghz_passive_scan(mvm
, ¶ms
, vif
);
3038 uid
= iwl_mvm_build_scan_cmd(mvm
, vif
, &hcmd
, ¶ms
, type
);
3043 iwl_mvm_pause_tcm(mvm
, false);
3045 ret
= iwl_mvm_send_cmd(mvm
, &hcmd
);
3047 /* If the scan failed, it usually means that the FW was unable
3048 * to allocate the time events. Warn on it, but maybe we
3049 * should try to send the command again with different params.
3051 IWL_ERR(mvm
, "Scan failed! ret %d\n", ret
);
3052 iwl_mvm_resume_tcm(mvm
);
3056 IWL_DEBUG_SCAN(mvm
, "Scan request send success: type=%u, uid=%u\n",
3059 mvm
->scan_uid_status
[uid
] = type
;
3060 mvm
->scan_status
|= type
;
3062 if (type
== IWL_MVM_SCAN_REGULAR
) {
3063 mvm
->scan_vif
= iwl_mvm_vif_from_mac80211(vif
);
3064 schedule_delayed_work(&mvm
->scan_timeout_dwork
,
3065 msecs_to_jiffies(SCAN_TIMEOUT
));
3068 if (params
.enable_6ghz_passive
)
3069 mvm
->last_6ghz_passive_scan_jiffies
= jiffies
;
3074 int iwl_mvm_reg_scan_start(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
3075 struct cfg80211_scan_request
*req
,
3076 struct ieee80211_scan_ies
*ies
)
3078 return _iwl_mvm_single_scan_start(mvm
, vif
, req
, ies
,
3079 IWL_MVM_SCAN_REGULAR
);
3082 int iwl_mvm_sched_scan_start(struct iwl_mvm
*mvm
,
3083 struct ieee80211_vif
*vif
,
3084 struct cfg80211_sched_scan_request
*req
,
3085 struct ieee80211_scan_ies
*ies
,
3088 struct iwl_host_cmd hcmd
= {
3089 .len
= { iwl_mvm_scan_size(mvm
), },
3090 .data
= { mvm
->scan_cmd
, },
3091 .dataflags
= { IWL_HCMD_DFL_NOCOPY
, },
3093 struct iwl_mvm_scan_params params
= {};
3096 bool non_psc_included
= false;
3098 lockdep_assert_held(&mvm
->mutex
);
3100 if (iwl_mvm_is_lar_supported(mvm
) && !mvm
->lar_regdom_set
) {
3101 IWL_ERR(mvm
, "sched-scan while LAR regdomain is not set\n");
3105 ret
= iwl_mvm_check_running_scans(mvm
, type
);
3109 /* we should have failed registration if scan_cmd was NULL */
3110 if (WARN_ON(!mvm
->scan_cmd
))
3114 params
.n_ssids
= req
->n_ssids
;
3115 params
.flags
= req
->flags
;
3116 params
.n_channels
= req
->n_channels
;
3117 params
.ssids
= req
->ssids
;
3118 params
.channels
= req
->channels
;
3119 params
.mac_addr
= req
->mac_addr
;
3120 params
.mac_addr_mask
= req
->mac_addr_mask
;
3121 params
.no_cck
= false;
3122 params
.pass_all
= iwl_mvm_scan_pass_all(mvm
, req
);
3123 params
.n_match_sets
= req
->n_match_sets
;
3124 params
.match_sets
= req
->match_sets
;
3125 eth_broadcast_addr(params
.bssid
);
3126 if (!req
->n_scan_plans
)
3129 params
.n_scan_plans
= req
->n_scan_plans
;
3130 params
.scan_plans
= req
->scan_plans
;
3132 iwl_mvm_fill_scan_type(mvm
, ¶ms
, vif
);
3133 iwl_mvm_fill_respect_p2p_go(mvm
, ¶ms
, vif
);
3135 /* In theory, LMAC scans can handle a 32-bit delay, but since
3136 * waiting for over 18 hours to start the scan is a bit silly
3137 * and to keep it aligned with UMAC scans (which only support
3138 * 16-bit delays), trim it down to 16-bits.
3140 if (req
->delay
> U16_MAX
) {
3142 "delay value is > 16-bits, set to max possible\n");
3143 params
.delay
= U16_MAX
;
3145 params
.delay
= req
->delay
;
3148 ret
= iwl_mvm_config_sched_scan_profiles(mvm
, req
);
3152 iwl_mvm_build_scan_probe(mvm
, vif
, ies
, ¶ms
);
3154 /* for 6 GHZ band only PSC channels need to be added */
3155 for (i
= 0; i
< params
.n_channels
; i
++) {
3156 struct ieee80211_channel
*channel
= params
.channels
[i
];
3158 if (channel
->band
== NL80211_BAND_6GHZ
&&
3159 !cfg80211_channel_is_psc(channel
)) {
3160 non_psc_included
= true;
3165 if (non_psc_included
) {
3166 params
.channels
= kmemdup(params
.channels
,
3167 sizeof(params
.channels
[0]) *
3170 if (!params
.channels
)
3173 for (i
= j
= 0; i
< params
.n_channels
; i
++) {
3174 if (params
.channels
[i
]->band
== NL80211_BAND_6GHZ
&&
3175 !cfg80211_channel_is_psc(params
.channels
[i
]))
3177 params
.channels
[j
++] = params
.channels
[i
];
3179 params
.n_channels
= j
;
3182 if (!iwl_mvm_scan_fits(mvm
, req
->n_ssids
, ies
, params
.n_channels
)) {
3187 uid
= iwl_mvm_build_scan_cmd(mvm
, vif
, &hcmd
, ¶ms
, type
);
3193 ret
= iwl_mvm_send_cmd(mvm
, &hcmd
);
3196 "Sched scan request send success: type=%u, uid=%u\n",
3198 mvm
->scan_uid_status
[uid
] = type
;
3199 mvm
->scan_status
|= type
;
3201 /* If the scan failed, it usually means that the FW was unable
3202 * to allocate the time events. Warn on it, but maybe we
3203 * should try to send the command again with different params.
3205 IWL_ERR(mvm
, "Sched scan failed! ret %d\n", ret
);
3206 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
3210 if (non_psc_included
)
3211 kfree(params
.channels
);
3215 void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm
*mvm
,
3216 struct iwl_rx_cmd_buffer
*rxb
)
3218 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
3219 struct iwl_umac_scan_complete
*notif
= (void *)pkt
->data
;
3220 u32 uid
= __le32_to_cpu(notif
->uid
);
3221 bool aborted
= (notif
->status
== IWL_SCAN_OFFLOAD_ABORTED
);
3222 bool select_links
= false;
3224 mvm
->mei_scan_filter
.is_mei_limited_scan
= false;
3227 "Scan completed: uid=%u type=%u, status=%s, EBS=%s\n",
3228 uid
, mvm
->scan_uid_status
[uid
],
3229 notif
->status
== IWL_SCAN_OFFLOAD_COMPLETED
?
3230 "completed" : "aborted",
3231 iwl_mvm_ebs_status_str(notif
->ebs_status
));
3233 IWL_DEBUG_SCAN(mvm
, "Scan completed: scan_status=0x%x\n",
3237 "Scan completed: line=%u, iter=%u, elapsed time=%u\n",
3238 notif
->last_schedule
, notif
->last_iter
,
3239 __le32_to_cpu(notif
->time_from_last_iter
));
3241 if (WARN_ON(!(mvm
->scan_uid_status
[uid
] & mvm
->scan_status
)))
3244 /* if the scan is already stopping, we don't need to notify mac80211 */
3245 if (mvm
->scan_uid_status
[uid
] == IWL_MVM_SCAN_REGULAR
) {
3246 struct cfg80211_scan_info info
= {
3248 .scan_start_tsf
= mvm
->scan_start
,
3250 struct iwl_mvm_vif
*scan_vif
= mvm
->scan_vif
;
3251 struct iwl_mvm_vif_link_info
*link_info
=
3252 scan_vif
->link
[mvm
->scan_link_id
];
3254 /* It is possible that by the time the scan is complete the link
3255 * was already removed and is not valid.
3258 memcpy(info
.tsf_bssid
, link_info
->bssid
, ETH_ALEN
);
3260 IWL_DEBUG_SCAN(mvm
, "Scan link is no longer valid\n");
3262 ieee80211_scan_completed(mvm
->hw
, &info
);
3263 mvm
->scan_vif
= NULL
;
3264 cancel_delayed_work(&mvm
->scan_timeout_dwork
);
3265 iwl_mvm_resume_tcm(mvm
);
3266 } else if (mvm
->scan_uid_status
[uid
] == IWL_MVM_SCAN_SCHED
) {
3267 ieee80211_sched_scan_stopped(mvm
->hw
);
3268 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
3269 } else if (mvm
->scan_uid_status
[uid
] == IWL_MVM_SCAN_INT_MLO
) {
3270 IWL_DEBUG_SCAN(mvm
, "Internal MLO scan completed\n");
3272 * Other scan types won't necessarily scan for the MLD links channels.
3273 * Therefore, only select links after successful internal scan.
3275 select_links
= notif
->status
== IWL_SCAN_OFFLOAD_COMPLETED
;
3278 mvm
->scan_status
&= ~mvm
->scan_uid_status
[uid
];
3280 IWL_DEBUG_SCAN(mvm
, "Scan completed: after update: scan_status=0x%x\n",
3283 if (notif
->ebs_status
!= IWL_SCAN_EBS_SUCCESS
&&
3284 notif
->ebs_status
!= IWL_SCAN_EBS_INACTIVE
)
3285 mvm
->last_ebs_successful
= false;
3287 mvm
->scan_uid_status
[uid
] = 0;
3290 wiphy_work_queue(mvm
->hw
->wiphy
, &mvm
->trig_link_selection_wk
);
3293 void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm
*mvm
,
3294 struct iwl_rx_cmd_buffer
*rxb
)
3296 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
3297 struct iwl_umac_scan_iter_complete_notif
*notif
= (void *)pkt
->data
;
3299 mvm
->scan_start
= le64_to_cpu(notif
->start_tsf
);
3302 "UMAC Scan iteration complete: status=0x%x scanned_channels=%d\n",
3303 notif
->status
, notif
->scanned_channels
);
3305 if (mvm
->sched_scan_pass_all
== SCHED_SCAN_PASS_ALL_FOUND
) {
3306 IWL_DEBUG_SCAN(mvm
, "Pass all scheduled scan results found\n");
3307 ieee80211_sched_scan_results(mvm
->hw
);
3308 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_ENABLED
;
3312 "UMAC Scan iteration complete: scan started at %llu (TSF)\n",
3316 static int iwl_mvm_umac_scan_abort(struct iwl_mvm
*mvm
, int type
, bool *wait
)
3318 struct iwl_umac_scan_abort abort_cmd
= {};
3319 struct iwl_host_cmd cmd
= {
3320 .id
= WIDE_ID(IWL_ALWAYS_LONG_GROUP
, SCAN_ABORT_UMAC
),
3321 .len
= { sizeof(abort_cmd
), },
3322 .data
= { &abort_cmd
, },
3323 .flags
= CMD_SEND_IN_RFKILL
,
3327 u32 status
= IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND
;
3329 lockdep_assert_held(&mvm
->mutex
);
3333 /* We should always get a valid index here, because we already
3334 * checked that this type of scan was running in the generic
3337 uid
= iwl_mvm_scan_uid_by_status(mvm
, type
);
3338 if (WARN_ON_ONCE(uid
< 0))
3341 abort_cmd
.uid
= cpu_to_le32(uid
);
3343 IWL_DEBUG_SCAN(mvm
, "Sending scan abort, uid %u\n", uid
);
3345 ret
= iwl_mvm_send_cmd_status(mvm
, &cmd
, &status
);
3347 IWL_DEBUG_SCAN(mvm
, "Scan abort: ret=%d, status=%u\n", ret
, status
);
3349 mvm
->scan_uid_status
[uid
] = type
<< IWL_MVM_SCAN_STOPPING_SHIFT
;
3351 /* Handle the case that the FW is no longer familiar with the scan that
3352 * is to be stopped. In such a case, it is expected that the scan
3353 * complete notification was already received but not yet processed.
3354 * In such a case, there is no need to wait for a scan complete
3355 * notification and the flow should continue similar to the case that
3356 * the scan was really aborted.
3358 if (status
== IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND
) {
3359 mvm
->scan_uid_status
[uid
] = type
<< IWL_MVM_SCAN_STOPPING_SHIFT
;
3366 static int iwl_mvm_scan_stop_wait(struct iwl_mvm
*mvm
, int type
)
3368 struct iwl_notification_wait wait_scan_done
;
3369 static const u16 scan_done_notif
[] = { SCAN_COMPLETE_UMAC
,
3370 SCAN_OFFLOAD_COMPLETE
, };
3374 lockdep_assert_held(&mvm
->mutex
);
3376 iwl_init_notification_wait(&mvm
->notif_wait
, &wait_scan_done
,
3378 ARRAY_SIZE(scan_done_notif
),
3381 IWL_DEBUG_SCAN(mvm
, "Preparing to stop scan, type %x\n", type
);
3383 if (fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_UMAC_SCAN
))
3384 ret
= iwl_mvm_umac_scan_abort(mvm
, type
, &wait
);
3386 ret
= iwl_mvm_lmac_scan_abort(mvm
);
3389 IWL_DEBUG_SCAN(mvm
, "couldn't stop scan type %d\n", type
);
3390 iwl_remove_notification(&mvm
->notif_wait
, &wait_scan_done
);
3393 IWL_DEBUG_SCAN(mvm
, "no need to wait for scan type %d\n", type
);
3394 iwl_remove_notification(&mvm
->notif_wait
, &wait_scan_done
);
3398 return iwl_wait_notification(&mvm
->notif_wait
, &wait_scan_done
,
3402 static size_t iwl_scan_req_umac_get_size(u8 scan_ver
)
3406 return sizeof(struct iwl_scan_req_umac_v12
);
3411 return sizeof(struct iwl_scan_req_umac_v17
);
3417 size_t iwl_mvm_scan_size(struct iwl_mvm
*mvm
)
3419 int base_size
, tail_size
;
3420 u8 scan_ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
, SCAN_REQ_UMAC
,
3421 IWL_FW_CMD_VER_UNKNOWN
);
3423 base_size
= iwl_scan_req_umac_get_size(scan_ver
);
3428 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm
))
3429 base_size
= IWL_SCAN_REQ_UMAC_SIZE_V8
;
3430 else if (iwl_mvm_is_adaptive_dwell_supported(mvm
))
3431 base_size
= IWL_SCAN_REQ_UMAC_SIZE_V7
;
3432 else if (iwl_mvm_cdb_scan_api(mvm
))
3433 base_size
= IWL_SCAN_REQ_UMAC_SIZE_V6
;
3435 base_size
= IWL_SCAN_REQ_UMAC_SIZE_V1
;
3437 if (fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_UMAC_SCAN
)) {
3438 if (iwl_mvm_is_scan_ext_chan_supported(mvm
))
3439 tail_size
= sizeof(struct iwl_scan_req_umac_tail_v2
);
3441 tail_size
= sizeof(struct iwl_scan_req_umac_tail_v1
);
3444 sizeof(struct iwl_scan_channel_cfg_umac
) *
3445 mvm
->fw
->ucode_capa
.n_scan_channels
+
3448 return sizeof(struct iwl_scan_req_lmac
) +
3449 sizeof(struct iwl_scan_channel_cfg_lmac
) *
3450 mvm
->fw
->ucode_capa
.n_scan_channels
+
3451 sizeof(struct iwl_scan_probe_req_v1
);
3455 * This function is used in nic restart flow, to inform mac80211 about scans
3456 * that was aborted by restart flow or by an assert.
3458 void iwl_mvm_report_scan_aborted(struct iwl_mvm
*mvm
)
3460 if (fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_UMAC_SCAN
)) {
3463 uid
= iwl_mvm_scan_uid_by_status(mvm
, IWL_MVM_SCAN_REGULAR
);
3465 struct cfg80211_scan_info info
= {
3469 cancel_delayed_work(&mvm
->scan_timeout_dwork
);
3471 ieee80211_scan_completed(mvm
->hw
, &info
);
3472 mvm
->scan_uid_status
[uid
] = 0;
3474 uid
= iwl_mvm_scan_uid_by_status(mvm
, IWL_MVM_SCAN_SCHED
);
3476 /* Sched scan will be restarted by mac80211 in
3477 * restart_hw, so do not report if FW is about to be
3480 if (!mvm
->fw_restart
)
3481 ieee80211_sched_scan_stopped(mvm
->hw
);
3482 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
3483 mvm
->scan_uid_status
[uid
] = 0;
3485 uid
= iwl_mvm_scan_uid_by_status(mvm
, IWL_MVM_SCAN_INT_MLO
);
3487 IWL_DEBUG_SCAN(mvm
, "Internal MLO scan aborted\n");
3488 mvm
->scan_uid_status
[uid
] = 0;
3491 uid
= iwl_mvm_scan_uid_by_status(mvm
,
3492 IWL_MVM_SCAN_STOPPING_REGULAR
);
3494 mvm
->scan_uid_status
[uid
] = 0;
3496 uid
= iwl_mvm_scan_uid_by_status(mvm
,
3497 IWL_MVM_SCAN_STOPPING_SCHED
);
3499 mvm
->scan_uid_status
[uid
] = 0;
3501 uid
= iwl_mvm_scan_uid_by_status(mvm
,
3502 IWL_MVM_SCAN_STOPPING_INT_MLO
);
3504 mvm
->scan_uid_status
[uid
] = 0;
3506 /* We shouldn't have any UIDs still set. Loop over all the
3507 * UIDs to make sure there's nothing left there and warn if
3510 for (i
= 0; i
< mvm
->max_scans
; i
++) {
3511 if (WARN_ONCE(mvm
->scan_uid_status
[i
],
3512 "UMAC scan UID %d status was not cleaned\n",
3514 mvm
->scan_uid_status
[i
] = 0;
3517 if (mvm
->scan_status
& IWL_MVM_SCAN_REGULAR
) {
3518 struct cfg80211_scan_info info
= {
3522 cancel_delayed_work(&mvm
->scan_timeout_dwork
);
3523 ieee80211_scan_completed(mvm
->hw
, &info
);
3526 /* Sched scan will be restarted by mac80211 in
3527 * restart_hw, so do not report if FW is about to be
3530 if ((mvm
->scan_status
& IWL_MVM_SCAN_SCHED
) &&
3532 ieee80211_sched_scan_stopped(mvm
->hw
);
3533 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
3538 int iwl_mvm_scan_stop(struct iwl_mvm
*mvm
, int type
, bool notify
)
3543 "Request to stop scan: type=0x%x, status=0x%x\n",
3544 type
, mvm
->scan_status
);
3546 if (!(mvm
->scan_status
& type
))
3549 if (!test_bit(STATUS_DEVICE_ENABLED
, &mvm
->trans
->status
)) {
3554 ret
= iwl_mvm_scan_stop_wait(mvm
, type
);
3556 mvm
->scan_status
|= type
<< IWL_MVM_SCAN_STOPPING_SHIFT
;
3558 IWL_DEBUG_SCAN(mvm
, "Failed to stop scan\n");
3561 /* Clear the scan status so the next scan requests will
3562 * succeed and mark the scan as stopping, so that the Rx
3563 * handler doesn't do anything, as the scan was stopped from
3566 mvm
->scan_status
&= ~type
;
3568 if (type
== IWL_MVM_SCAN_REGULAR
) {
3569 cancel_delayed_work(&mvm
->scan_timeout_dwork
);
3571 struct cfg80211_scan_info info
= {
3575 ieee80211_scan_completed(mvm
->hw
, &info
);
3577 } else if (notify
) {
3578 ieee80211_sched_scan_stopped(mvm
->hw
);
3579 mvm
->sched_scan_pass_all
= SCHED_SCAN_PASS_ALL_DISABLED
;
3585 static int iwl_mvm_int_mlo_scan_start(struct iwl_mvm
*mvm
,
3586 struct ieee80211_vif
*vif
,
3587 struct ieee80211_channel
**channels
,
3590 struct cfg80211_scan_request
*req
= NULL
;
3591 struct ieee80211_scan_ies ies
= {};
3595 lockdep_assert_held(&mvm
->mutex
);
3597 IWL_DEBUG_SCAN(mvm
, "Starting Internal MLO scan: n_channels=%zu\n",
3600 if (!vif
->cfg
.assoc
|| !ieee80211_vif_is_mld(vif
) ||
3601 hweight16(vif
->valid_links
) == 1)
3604 size
= struct_size(req
, channels
, n_channels
);
3605 req
= kzalloc(size
, GFP_KERNEL
);
3609 /* set the requested channels */
3610 for (i
= 0; i
< n_channels
; i
++)
3611 req
->channels
[i
] = channels
[i
];
3613 req
->n_channels
= n_channels
;
3616 for (i
= 0; i
< NUM_NL80211_BANDS
; i
++)
3617 if (mvm
->hw
->wiphy
->bands
[i
])
3619 (1 << mvm
->hw
->wiphy
->bands
[i
]->n_bitrates
) - 1;
3621 req
->wdev
= ieee80211_vif_to_wdev(vif
);
3622 req
->wiphy
= mvm
->hw
->wiphy
;
3623 req
->scan_start
= jiffies
;
3624 req
->tsf_report_link_id
= -1;
3626 ret
= _iwl_mvm_single_scan_start(mvm
, vif
, req
, &ies
,
3627 IWL_MVM_SCAN_INT_MLO
);
3630 IWL_DEBUG_SCAN(mvm
, "Internal MLO scan: ret=%d\n", ret
);
3634 int iwl_mvm_int_mlo_scan(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
3636 struct ieee80211_channel
*channels
[IEEE80211_MLD_MAX_NUM_LINKS
];
3637 unsigned long usable_links
= ieee80211_vif_usable_links(vif
);
3638 size_t n_channels
= 0;
3641 lockdep_assert_held(&mvm
->mutex
);
3643 if (mvm
->scan_status
& IWL_MVM_SCAN_INT_MLO
) {
3644 IWL_DEBUG_SCAN(mvm
, "Internal MLO scan is already running\n");
3650 for_each_set_bit(link_id
, &usable_links
, IEEE80211_MLD_MAX_NUM_LINKS
) {
3651 struct ieee80211_bss_conf
*link_conf
=
3652 rcu_dereference(vif
->link_conf
[link_id
]);
3654 if (WARN_ON_ONCE(!link_conf
))
3657 channels
[n_channels
++] = link_conf
->chanreq
.oper
.chan
;
3665 return iwl_mvm_int_mlo_scan_start(mvm
, vif
, channels
, n_channels
);
3668 static int iwl_mvm_chanidx_from_phy(struct iwl_mvm
*mvm
,
3669 enum nl80211_band band
,
3672 struct ieee80211_supported_band
*sband
= mvm
->hw
->wiphy
->bands
[band
];
3675 if (WARN_ON_ONCE(!sband
))
3678 for (chan_idx
= 0; chan_idx
< sband
->n_channels
; chan_idx
++) {
3679 struct ieee80211_channel
*channel
= &sband
->channels
[chan_idx
];
3681 if (channel
->hw_value
== phy_chan_num
)
3688 static u32
iwl_mvm_div_by_db(u32 value
, u8 db
)
3691 * 2^32 * 10**(i / 10) for i = [1, 10], skipping 0 and simply stopping
3692 * at 10 dB and looping instead of using a much larger table.
3694 * Using 64 bit math is overkill, but means the helper does not require
3695 * a limit on the input range.
3697 static const u32 db_to_val
[] = {
3698 0xcb59185e, 0xa1866ba8, 0x804dce7a, 0x65ea59fe, 0x50f44d89,
3699 0x404de61f, 0x331426af, 0x2892c18b, 0x203a7e5b, 0x1999999a,
3702 while (value
&& db
> 0) {
3703 u8 change
= min_t(u8
, db
, ARRAY_SIZE(db_to_val
));
3705 value
= (((u64
)value
) * db_to_val
[change
- 1]) >> 32;
3713 VISIBLE_IF_IWLWIFI_KUNIT s8
3714 iwl_mvm_average_dbm_values(const struct iwl_umac_scan_channel_survey_notif
*notif
)
3716 s8 average_magnitude
;
3718 s8 sum_magnitude
= -128;
3723 * To properly average the decibel values (signal values given in dBm)
3724 * we need to do the math in linear space. Doing a linear average of
3725 * dB (dBm) values is a bit annoying though due to the large range of
3726 * at least -10 to -110 dBm that will not fit into a 32 bit integer.
3728 * A 64 bit integer should be sufficient, but then we still have the
3729 * problem that there are no directly usable utility functions
3732 * So, lets not deal with that and instead do much of the calculation
3733 * with a 16.16 fixed point integer along with a base in dBm. 16.16 bit
3734 * gives us plenty of head-room for adding up a few values and even
3735 * doing some math on it. And the tail should be accurate enough too
3736 * (1/2^16 is somewhere around -48 dB, so effectively zero).
3738 * i.e. the real value of sum is:
3739 * sum = sum_factor / 2^16 * 10^(sum_magnitude / 10) mW
3741 * However, that does mean we need to be able to bring two values to
3742 * a common base, so we need a helper for that.
3744 * Note that this function takes an input with unsigned negative dBm
3745 * values but returns a signed dBm (i.e. a negative value).
3748 for (i
= 0; i
< ARRAY_SIZE(notif
->noise
); i
++) {
3752 if (notif
->noise
[i
] == 0xff)
3755 val_factor
= 0x10000;
3756 val_magnitude
= -notif
->noise
[i
];
3758 if (val_magnitude
<= sum_magnitude
) {
3759 u8 div_db
= sum_magnitude
- val_magnitude
;
3761 val_factor
= iwl_mvm_div_by_db(val_factor
, div_db
);
3762 val_magnitude
= sum_magnitude
;
3764 u8 div_db
= val_magnitude
- sum_magnitude
;
3766 sum_factor
= iwl_mvm_div_by_db(sum_factor
, div_db
);
3767 sum_magnitude
= val_magnitude
;
3770 sum_factor
+= val_factor
;
3774 /* No valid noise measurement, return a very high noise level */
3778 average_magnitude
= sum_magnitude
;
3779 average_factor
= sum_factor
/ count
;
3782 * average_factor will be a number smaller than 1.0 (0x10000) at this
3783 * point. What we need to do now is to adjust average_magnitude so that
3784 * average_factor is between -0.5 dB and 0.5 dB.
3786 * Just do -1 dB steps and find the point where
3787 * -0.5 dB * -i dB = 0x10000 * 10^(-0.5/10) / i dB
3788 * = div_by_db(0xe429, i)
3789 * is smaller than average_factor.
3791 for (i
= 0; average_factor
< iwl_mvm_div_by_db(0xe429, i
); i
++) {
3795 return average_magnitude
- i
;
3797 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mvm_average_dbm_values
);
3799 void iwl_mvm_rx_channel_survey_notif(struct iwl_mvm
*mvm
,
3800 struct iwl_rx_cmd_buffer
*rxb
)
3802 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
3803 const struct iwl_umac_scan_channel_survey_notif
*notif
=
3805 struct iwl_mvm_acs_survey_channel
*info
;
3806 enum nl80211_band band
;
3809 lockdep_assert_held(&mvm
->mutex
);
3811 if (!mvm
->acs_survey
) {
3812 size_t n_channels
= 0;
3814 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
3815 if (!mvm
->hw
->wiphy
->bands
[band
])
3818 n_channels
+= mvm
->hw
->wiphy
->bands
[band
]->n_channels
;
3821 mvm
->acs_survey
= kzalloc(struct_size(mvm
->acs_survey
,
3822 channels
, n_channels
),
3825 if (!mvm
->acs_survey
)
3828 mvm
->acs_survey
->n_channels
= n_channels
;
3830 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
3831 if (!mvm
->hw
->wiphy
->bands
[band
])
3834 mvm
->acs_survey
->bands
[band
] =
3835 &mvm
->acs_survey
->channels
[n_channels
];
3836 n_channels
+= mvm
->hw
->wiphy
->bands
[band
]->n_channels
;
3840 band
= iwl_mvm_nl80211_band_from_phy(le32_to_cpu(notif
->band
));
3841 chan_idx
= iwl_mvm_chanidx_from_phy(mvm
, band
,
3842 le32_to_cpu(notif
->channel
));
3843 if (WARN_ON_ONCE(chan_idx
< 0))
3846 IWL_DEBUG_SCAN(mvm
, "channel survey received for freq %d\n",
3847 mvm
->hw
->wiphy
->bands
[band
]->channels
[chan_idx
].center_freq
);
3849 info
= &mvm
->acs_survey
->bands
[band
][chan_idx
];
3851 /* Times are all in ms */
3852 info
->time
= le32_to_cpu(notif
->active_time
);
3853 info
->time_busy
= le32_to_cpu(notif
->busy_time
);
3854 info
->time_rx
= le32_to_cpu(notif
->rx_time
);
3855 info
->time_tx
= le32_to_cpu(notif
->tx_time
);
3856 info
->noise
= iwl_mvm_average_dbm_values(notif
);