This source file includes following definitions.
- iwl_mvm_get_scan_req_umac_data
- iwl_mvm_get_scan_req_umac_channel
- iwl_mvm_scan_rx_ant
- iwl_mvm_scan_rx_chain
- iwl_mvm_scan_rxon_flags
- iwl_mvm_scan_rate_n_flags
- iwl_mvm_scan_condition_iterator
- iwl_mvm_get_traffic_load
- iwl_mvm_get_traffic_load_band
- iwl_mvm_is_dcm_with_go_iterator
- _iwl_mvm_get_scan_type
- iwl_mvm_get_scan_type
- iwl_mvm_get_scan_type_band
- iwl_mvm_get_measurement_dwell
- iwl_mvm_rrm_scan_needed
- iwl_mvm_max_scan_ie_fw_cmd_room
- iwl_mvm_max_scan_ie_len
- iwl_mvm_rx_lmac_scan_iter_complete_notif
- iwl_mvm_rx_scan_match_found
- iwl_mvm_ebs_status_str
- iwl_mvm_rx_lmac_scan_complete_notif
- iwl_ssid_exist
- iwl_scan_build_ssids
- iwl_mvm_config_sched_scan_profiles
- iwl_mvm_scan_pass_all
- iwl_mvm_lmac_scan_abort
- iwl_mvm_scan_fill_tx_cmd
- iwl_mvm_lmac_scan_cfg_channels
- iwl_mvm_copy_and_insert_ds_elem
- iwl_mvm_add_tpc_report_ie
- iwl_mvm_build_scan_probe
- iwl_mvm_scan_lmac_dwell
- iwl_mvm_scan_fits
- iwl_mvm_scan_use_ebs
- iwl_mvm_is_regular_scan
- iwl_mvm_is_scan_fragmented
- iwl_mvm_scan_lmac_flags
- iwl_mvm_scan_set_legacy_probe_req
- iwl_mvm_scan_lmac
- rate_to_scan_rate_flag
- iwl_mvm_scan_config_rates
- iwl_mvm_fill_scan_dwell
- iwl_mvm_fill_channels
- iwl_mvm_fill_scan_config_v1
- iwl_mvm_fill_scan_config_v2
- iwl_mvm_legacy_config_scan
- iwl_mvm_config_scan
- iwl_mvm_scan_uid_by_status
- iwl_mvm_scan_umac_dwell
- iwl_mvm_umac_scan_cfg_channels
- iwl_mvm_scan_umac_flags
- iwl_mvm_scan_umac
- iwl_mvm_num_scans
- iwl_mvm_check_running_scans
- iwl_mvm_scan_timeout_wk
- iwl_mvm_fill_scan_type
- iwl_mvm_reg_scan_start
- iwl_mvm_sched_scan_start
- iwl_mvm_rx_umac_scan_complete_notif
- iwl_mvm_rx_umac_scan_iter_complete_notif
- iwl_mvm_umac_scan_abort
- iwl_mvm_scan_stop_wait
- iwl_mvm_scan_size
- iwl_mvm_report_scan_aborted
- iwl_mvm_scan_stop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #include <linux/etherdevice.h>
66 #include <net/mac80211.h>
67
68 #include "mvm.h"
69 #include "fw/api/scan.h"
70 #include "iwl-io.h"
71
72 #define IWL_DENSE_EBS_SCAN_RATIO 5
73 #define IWL_SPARSE_EBS_SCAN_RATIO 1
74
75 #define IWL_SCAN_DWELL_ACTIVE 10
76 #define IWL_SCAN_DWELL_PASSIVE 110
77 #define IWL_SCAN_DWELL_FRAGMENTED 44
78 #define IWL_SCAN_DWELL_EXTENDED 90
79 #define IWL_SCAN_NUM_OF_FRAGS 3
80 #define IWL_SCAN_LAST_2_4_CHN 14
81
82 #define IWL_SCAN_BAND_5_2 0
83 #define IWL_SCAN_BAND_2_4 1
84
85
86 #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
87
88 #define IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
89
90 #define IWL_SCAN_ADWELL_DEFAULT_HB_N_APS 8
91
92 #define IWL_SCAN_ADWELL_DEFAULT_LB_N_APS 2
93
94 #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
95
96 struct iwl_mvm_scan_timing_params {
97 u32 suspend_time;
98 u32 max_out_time;
99 };
100
101 static struct iwl_mvm_scan_timing_params scan_timing[] = {
102 [IWL_SCAN_TYPE_UNASSOC] = {
103 .suspend_time = 0,
104 .max_out_time = 0,
105 },
106 [IWL_SCAN_TYPE_WILD] = {
107 .suspend_time = 30,
108 .max_out_time = 120,
109 },
110 [IWL_SCAN_TYPE_MILD] = {
111 .suspend_time = 120,
112 .max_out_time = 120,
113 },
114 [IWL_SCAN_TYPE_FRAGMENTED] = {
115 .suspend_time = 95,
116 .max_out_time = 44,
117 },
118 [IWL_SCAN_TYPE_FAST_BALANCE] = {
119 .suspend_time = 30,
120 .max_out_time = 37,
121 },
122 };
123
124 struct iwl_mvm_scan_params {
125
126 enum iwl_mvm_scan_type type;
127 enum iwl_mvm_scan_type hb_type;
128 u32 n_channels;
129 u16 delay;
130 int n_ssids;
131 struct cfg80211_ssid *ssids;
132 struct ieee80211_channel **channels;
133 u32 flags;
134 u8 *mac_addr;
135 u8 *mac_addr_mask;
136 bool no_cck;
137 bool pass_all;
138 int n_match_sets;
139 struct iwl_scan_probe_req preq;
140 struct cfg80211_match_set *match_sets;
141 int n_scan_plans;
142 struct cfg80211_sched_scan_plan *scan_plans;
143 u32 measurement_dwell;
144 };
145
146 static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm)
147 {
148 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
149
150 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
151 return (void *)&cmd->v8.data;
152
153 if (iwl_mvm_is_adaptive_dwell_supported(mvm))
154 return (void *)&cmd->v7.data;
155
156 if (iwl_mvm_cdb_scan_api(mvm))
157 return (void *)&cmd->v6.data;
158
159 return (void *)&cmd->v1.data;
160 }
161
162 static inline struct iwl_scan_umac_chan_param *
163 iwl_mvm_get_scan_req_umac_channel(struct iwl_mvm *mvm)
164 {
165 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
166
167 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
168 return &cmd->v8.channel;
169
170 if (iwl_mvm_is_adaptive_dwell_supported(mvm))
171 return &cmd->v7.channel;
172
173 if (iwl_mvm_cdb_scan_api(mvm))
174 return &cmd->v6.channel;
175
176 return &cmd->v1.channel;
177 }
178
179 static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
180 {
181 if (mvm->scan_rx_ant != ANT_NONE)
182 return mvm->scan_rx_ant;
183 return iwl_mvm_get_valid_rx_ant(mvm);
184 }
185
186 static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
187 {
188 u16 rx_chain;
189 u8 rx_ant;
190
191 rx_ant = iwl_mvm_scan_rx_ant(mvm);
192 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
193 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
194 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
195 rx_chain |= 0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS;
196 return cpu_to_le16(rx_chain);
197 }
198
199 static __le32 iwl_mvm_scan_rxon_flags(enum nl80211_band band)
200 {
201 if (band == NL80211_BAND_2GHZ)
202 return cpu_to_le32(PHY_BAND_24);
203 else
204 return cpu_to_le32(PHY_BAND_5);
205 }
206
207 static inline __le32
208 iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum nl80211_band band,
209 bool no_cck)
210 {
211 u32 tx_ant;
212
213 iwl_mvm_toggle_tx_ant(mvm, &mvm->scan_last_antenna_idx);
214 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
215
216 if (band == NL80211_BAND_2GHZ && !no_cck)
217 return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK |
218 tx_ant);
219 else
220 return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant);
221 }
222
223 static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
224 struct ieee80211_vif *vif)
225 {
226 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
227 int *global_cnt = data;
228
229 if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
230 mvmvif->phy_ctxt->id < NUM_PHY_CTX)
231 *global_cnt += 1;
232 }
233
234 static enum iwl_mvm_traffic_load iwl_mvm_get_traffic_load(struct iwl_mvm *mvm)
235 {
236 return mvm->tcm.result.global_load;
237 }
238
239 static enum iwl_mvm_traffic_load
240 iwl_mvm_get_traffic_load_band(struct iwl_mvm *mvm, enum nl80211_band band)
241 {
242 return mvm->tcm.result.band_load[band];
243 }
244
245 struct iwl_is_dcm_with_go_iterator_data {
246 struct ieee80211_vif *current_vif;
247 bool is_dcm_with_p2p_go;
248 };
249
250 static void iwl_mvm_is_dcm_with_go_iterator(void *_data, u8 *mac,
251 struct ieee80211_vif *vif)
252 {
253 struct iwl_is_dcm_with_go_iterator_data *data = _data;
254 struct iwl_mvm_vif *other_mvmvif = iwl_mvm_vif_from_mac80211(vif);
255 struct iwl_mvm_vif *curr_mvmvif =
256 iwl_mvm_vif_from_mac80211(data->current_vif);
257
258
259 if (vif == data->current_vif)
260 return;
261
262 if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
263 other_mvmvif->phy_ctxt && curr_mvmvif->phy_ctxt &&
264 other_mvmvif->phy_ctxt->id != curr_mvmvif->phy_ctxt->id)
265 data->is_dcm_with_p2p_go = true;
266 }
267
268 static enum
269 iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
270 struct ieee80211_vif *vif,
271 enum iwl_mvm_traffic_load load,
272 bool low_latency)
273 {
274 int global_cnt = 0;
275
276 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
277 IEEE80211_IFACE_ITER_NORMAL,
278 iwl_mvm_scan_condition_iterator,
279 &global_cnt);
280 if (!global_cnt)
281 return IWL_SCAN_TYPE_UNASSOC;
282
283 if (fw_has_api(&mvm->fw->ucode_capa,
284 IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
285 if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) &&
286 (!vif || vif->type != NL80211_IFTYPE_P2P_DEVICE))
287 return IWL_SCAN_TYPE_FRAGMENTED;
288
289
290
291
292 if (vif && vif->type == NL80211_IFTYPE_STATION &&
293 vif->bss_conf.dtim_period < 220) {
294 struct iwl_is_dcm_with_go_iterator_data data = {
295 .current_vif = vif,
296 .is_dcm_with_p2p_go = false,
297 };
298
299 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
300 IEEE80211_IFACE_ITER_NORMAL,
301 iwl_mvm_is_dcm_with_go_iterator,
302 &data);
303 if (data.is_dcm_with_p2p_go)
304 return IWL_SCAN_TYPE_FAST_BALANCE;
305 }
306 }
307
308 if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency)
309 return IWL_SCAN_TYPE_MILD;
310
311 return IWL_SCAN_TYPE_WILD;
312 }
313
314 static enum
315 iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
316 struct ieee80211_vif *vif)
317 {
318 enum iwl_mvm_traffic_load load;
319 bool low_latency;
320
321 load = iwl_mvm_get_traffic_load(mvm);
322 low_latency = iwl_mvm_low_latency(mvm);
323
324 return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
325 }
326
327 static enum
328 iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
329 struct ieee80211_vif *vif,
330 enum nl80211_band band)
331 {
332 enum iwl_mvm_traffic_load load;
333 bool low_latency;
334
335 load = iwl_mvm_get_traffic_load_band(mvm, band);
336 low_latency = iwl_mvm_low_latency_band(mvm, band);
337
338 return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
339 }
340
341 static int
342 iwl_mvm_get_measurement_dwell(struct iwl_mvm *mvm,
343 struct cfg80211_scan_request *req,
344 struct iwl_mvm_scan_params *params)
345 {
346 u32 duration = scan_timing[params->type].max_out_time;
347
348 if (!req->duration)
349 return 0;
350
351 if (iwl_mvm_is_cdb_supported(mvm)) {
352 u32 hb_time = scan_timing[params->hb_type].max_out_time;
353
354 duration = min_t(u32, duration, hb_time);
355 }
356
357 if (req->duration_mandatory && req->duration > duration) {
358 IWL_DEBUG_SCAN(mvm,
359 "Measurement scan - too long dwell %hu (max out time %u)\n",
360 req->duration,
361 duration);
362 return -EOPNOTSUPP;
363 }
364
365 return min_t(u32, (u32)req->duration, duration);
366 }
367
368 static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm)
369 {
370
371 return fw_has_capa(&mvm->fw->ucode_capa,
372 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT);
373 }
374
375 static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm)
376 {
377 int max_probe_len;
378
379 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
380
381
382 max_probe_len -= 24 + 2;
383
384
385 if (iwl_mvm_rrm_scan_needed(mvm))
386 max_probe_len -= 3;
387
388 return max_probe_len;
389 }
390
391 int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
392 {
393 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm);
394
395
396
397
398
399
400
401
402
403
404
405 return max_ie_len;
406 }
407
408 void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
409 struct iwl_rx_cmd_buffer *rxb)
410 {
411 struct iwl_rx_packet *pkt = rxb_addr(rxb);
412 struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data;
413
414 IWL_DEBUG_SCAN(mvm,
415 "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
416 notif->status, notif->scanned_channels);
417
418 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
419 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
420 ieee80211_sched_scan_results(mvm->hw);
421 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
422 }
423 }
424
425 void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
426 struct iwl_rx_cmd_buffer *rxb)
427 {
428 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
429 ieee80211_sched_scan_results(mvm->hw);
430 }
431
432 static const char *iwl_mvm_ebs_status_str(enum iwl_scan_ebs_status status)
433 {
434 switch (status) {
435 case IWL_SCAN_EBS_SUCCESS:
436 return "successful";
437 case IWL_SCAN_EBS_INACTIVE:
438 return "inactive";
439 case IWL_SCAN_EBS_FAILED:
440 case IWL_SCAN_EBS_CHAN_NOT_FOUND:
441 default:
442 return "failed";
443 }
444 }
445
446 void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
447 struct iwl_rx_cmd_buffer *rxb)
448 {
449 struct iwl_rx_packet *pkt = rxb_addr(rxb);
450 struct iwl_periodic_scan_complete *scan_notif = (void *)pkt->data;
451 bool aborted = (scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
452
453
454
455
456 if (WARN_ON_ONCE(fw_has_capa(&mvm->fw->ucode_capa,
457 IWL_UCODE_TLV_CAPA_UMAC_SCAN)))
458 return;
459
460
461 lockdep_assert_held(&mvm->mutex);
462
463
464
465
466
467
468
469
470
471
472
473 if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_SCHED) {
474 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR);
475
476 IWL_DEBUG_SCAN(mvm, "Scheduled scan %s, EBS status %s\n",
477 aborted ? "aborted" : "completed",
478 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
479 IWL_DEBUG_SCAN(mvm,
480 "Last line %d, Last iteration %d, Time after last iteration %d\n",
481 scan_notif->last_schedule_line,
482 scan_notif->last_schedule_iteration,
483 __le32_to_cpu(scan_notif->time_after_last_iter));
484
485 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_SCHED;
486 } else if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR) {
487 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s\n",
488 aborted ? "aborted" : "completed",
489 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
490
491 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_REGULAR;
492 } else if (mvm->scan_status & IWL_MVM_SCAN_SCHED) {
493 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_REGULAR);
494
495 IWL_DEBUG_SCAN(mvm, "Scheduled scan %s, EBS status %s\n",
496 aborted ? "aborted" : "completed",
497 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
498 IWL_DEBUG_SCAN(mvm,
499 "Last line %d, Last iteration %d, Time after last iteration %d (FW)\n",
500 scan_notif->last_schedule_line,
501 scan_notif->last_schedule_iteration,
502 __le32_to_cpu(scan_notif->time_after_last_iter));
503
504 mvm->scan_status &= ~IWL_MVM_SCAN_SCHED;
505 ieee80211_sched_scan_stopped(mvm->hw);
506 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
507 } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
508 struct cfg80211_scan_info info = {
509 .aborted = aborted,
510 };
511
512 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n",
513 aborted ? "aborted" : "completed",
514 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
515
516 mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
517 ieee80211_scan_completed(mvm->hw, &info);
518 cancel_delayed_work(&mvm->scan_timeout_dwork);
519 iwl_mvm_resume_tcm(mvm);
520 } else {
521 IWL_ERR(mvm,
522 "got scan complete notification but no scan is running\n");
523 }
524
525 mvm->last_ebs_successful =
526 scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ||
527 scan_notif->ebs_status == IWL_SCAN_EBS_INACTIVE;
528 }
529
530 static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
531 {
532 int i;
533
534 for (i = 0; i < PROBE_OPTION_MAX; i++) {
535 if (!ssid_list[i].len)
536 break;
537 if (ssid_list[i].len == ssid_len &&
538 !memcmp(ssid_list->ssid, ssid, ssid_len))
539 return i;
540 }
541 return -1;
542 }
543
544
545
546
547 static void iwl_scan_build_ssids(struct iwl_mvm_scan_params *params,
548 struct iwl_ssid_ie *ssids,
549 u32 *ssid_bitmap)
550 {
551 int i, j;
552 int index;
553
554
555
556
557
558
559 for (i = 0, j = params->n_match_sets - 1;
560 j >= 0 && i < PROBE_OPTION_MAX;
561 i++, j--) {
562
563 if (!params->match_sets[j].ssid.ssid_len)
564 continue;
565 ssids[i].id = WLAN_EID_SSID;
566 ssids[i].len = params->match_sets[j].ssid.ssid_len;
567 memcpy(ssids[i].ssid, params->match_sets[j].ssid.ssid,
568 ssids[i].len);
569 }
570
571
572 *ssid_bitmap = 0;
573 for (j = params->n_ssids - 1;
574 j >= 0 && i < PROBE_OPTION_MAX;
575 i++, j--) {
576 index = iwl_ssid_exist(params->ssids[j].ssid,
577 params->ssids[j].ssid_len,
578 ssids);
579 if (index < 0) {
580 ssids[i].id = WLAN_EID_SSID;
581 ssids[i].len = params->ssids[j].ssid_len;
582 memcpy(ssids[i].ssid, params->ssids[j].ssid,
583 ssids[i].len);
584 *ssid_bitmap |= BIT(i);
585 } else {
586 *ssid_bitmap |= BIT(index);
587 }
588 }
589 }
590
591 static int
592 iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
593 struct cfg80211_sched_scan_request *req)
594 {
595 struct iwl_scan_offload_profile *profile;
596 struct iwl_scan_offload_profile_cfg *profile_cfg;
597 struct iwl_scan_offload_blacklist *blacklist;
598 struct iwl_host_cmd cmd = {
599 .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD,
600 .len[1] = sizeof(*profile_cfg),
601 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
602 .dataflags[1] = IWL_HCMD_DFL_NOCOPY,
603 };
604 int blacklist_len;
605 int i;
606 int ret;
607
608 if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES))
609 return -EIO;
610
611 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
612 blacklist_len = IWL_SCAN_SHORT_BLACKLIST_LEN;
613 else
614 blacklist_len = IWL_SCAN_MAX_BLACKLIST_LEN;
615
616 blacklist = kcalloc(blacklist_len, sizeof(*blacklist), GFP_KERNEL);
617 if (!blacklist)
618 return -ENOMEM;
619
620 profile_cfg = kzalloc(sizeof(*profile_cfg), GFP_KERNEL);
621 if (!profile_cfg) {
622 ret = -ENOMEM;
623 goto free_blacklist;
624 }
625
626 cmd.data[0] = blacklist;
627 cmd.len[0] = sizeof(*blacklist) * blacklist_len;
628 cmd.data[1] = profile_cfg;
629
630
631
632 profile_cfg->num_profiles = req->n_match_sets;
633 profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN;
634 profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN;
635 profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN;
636 if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
637 profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
638
639 for (i = 0; i < req->n_match_sets; i++) {
640 profile = &profile_cfg->profiles[i];
641 profile->ssid_index = i;
642
643 profile->unicast_cipher = 0xff;
644 profile->auth_alg = 0xff;
645 profile->network_type = IWL_NETWORK_TYPE_ANY;
646 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY;
647 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN;
648 }
649
650 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n");
651
652 ret = iwl_mvm_send_cmd(mvm, &cmd);
653 kfree(profile_cfg);
654 free_blacklist:
655 kfree(blacklist);
656
657 return ret;
658 }
659
660 static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
661 struct cfg80211_sched_scan_request *req)
662 {
663 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
664 IWL_DEBUG_SCAN(mvm,
665 "Sending scheduled scan with filtering, n_match_sets %d\n",
666 req->n_match_sets);
667 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
668 return false;
669 }
670
671 IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n");
672
673 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
674 return true;
675 }
676
677 static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm)
678 {
679 int ret;
680 struct iwl_host_cmd cmd = {
681 .id = SCAN_OFFLOAD_ABORT_CMD,
682 };
683 u32 status = CAN_ABORT_STATUS;
684
685 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
686 if (ret)
687 return ret;
688
689 if (status != CAN_ABORT_STATUS) {
690
691
692
693
694
695
696
697 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status);
698 ret = -ENOENT;
699 }
700
701 return ret;
702 }
703
704 static void iwl_mvm_scan_fill_tx_cmd(struct iwl_mvm *mvm,
705 struct iwl_scan_req_tx_cmd *tx_cmd,
706 bool no_cck)
707 {
708 tx_cmd[0].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
709 TX_CMD_FLG_BT_DIS);
710 tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
711 NL80211_BAND_2GHZ,
712 no_cck);
713 tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
714
715 tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
716 TX_CMD_FLG_BT_DIS);
717 tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
718 NL80211_BAND_5GHZ,
719 no_cck);
720 tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
721 }
722
723 static void
724 iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm,
725 struct ieee80211_channel **channels,
726 int n_channels, u32 ssid_bitmap,
727 struct iwl_scan_req_lmac *cmd)
728 {
729 struct iwl_scan_channel_cfg_lmac *channel_cfg = (void *)&cmd->data;
730 int i;
731
732 for (i = 0; i < n_channels; i++) {
733 channel_cfg[i].channel_num =
734 cpu_to_le16(channels[i]->hw_value);
735 channel_cfg[i].iter_count = cpu_to_le16(1);
736 channel_cfg[i].iter_interval = 0;
737 channel_cfg[i].flags =
738 cpu_to_le32(IWL_UNIFIED_SCAN_CHANNEL_PARTIAL |
739 ssid_bitmap);
740 }
741 }
742
743 static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies,
744 size_t len, u8 *const pos)
745 {
746 static const u8 before_ds_params[] = {
747 WLAN_EID_SSID,
748 WLAN_EID_SUPP_RATES,
749 WLAN_EID_REQUEST,
750 WLAN_EID_EXT_SUPP_RATES,
751 };
752 size_t offs;
753 u8 *newpos = pos;
754
755 if (!iwl_mvm_rrm_scan_needed(mvm)) {
756 memcpy(newpos, ies, len);
757 return newpos + len;
758 }
759
760 offs = ieee80211_ie_split(ies, len,
761 before_ds_params,
762 ARRAY_SIZE(before_ds_params),
763 0);
764
765 memcpy(newpos, ies, offs);
766 newpos += offs;
767
768
769 *newpos++ = WLAN_EID_DS_PARAMS;
770 *newpos++ = 1;
771 *newpos++ = 0;
772
773 memcpy(newpos, ies + offs, len - offs);
774 newpos += len - offs;
775
776 return newpos;
777 }
778
779 #define WFA_TPC_IE_LEN 9
780
781 static void iwl_mvm_add_tpc_report_ie(u8 *pos)
782 {
783 pos[0] = WLAN_EID_VENDOR_SPECIFIC;
784 pos[1] = WFA_TPC_IE_LEN - 2;
785 pos[2] = (WLAN_OUI_MICROSOFT >> 16) & 0xff;
786 pos[3] = (WLAN_OUI_MICROSOFT >> 8) & 0xff;
787 pos[4] = WLAN_OUI_MICROSOFT & 0xff;
788 pos[5] = WLAN_OUI_TYPE_MICROSOFT_TPC;
789 pos[6] = 0;
790
791 pos[7] = 0;
792 pos[8] = 0;
793 }
794
795 static void
796 iwl_mvm_build_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
797 struct ieee80211_scan_ies *ies,
798 struct iwl_mvm_scan_params *params)
799 {
800 struct ieee80211_mgmt *frame = (void *)params->preq.buf;
801 u8 *pos, *newpos;
802 const u8 *mac_addr = params->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ?
803 params->mac_addr : NULL;
804
805
806
807
808
809
810
811 if (mac_addr)
812 get_random_mask_addr(frame->sa, mac_addr,
813 params->mac_addr_mask);
814 else
815 memcpy(frame->sa, vif->addr, ETH_ALEN);
816
817 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
818 eth_broadcast_addr(frame->da);
819 eth_broadcast_addr(frame->bssid);
820 frame->seq_ctrl = 0;
821
822 pos = frame->u.probe_req.variable;
823 *pos++ = WLAN_EID_SSID;
824 *pos++ = 0;
825
826 params->preq.mac_header.offset = 0;
827 params->preq.mac_header.len = cpu_to_le16(24 + 2);
828
829
830 newpos = iwl_mvm_copy_and_insert_ds_elem(mvm,
831 ies->ies[NL80211_BAND_2GHZ],
832 ies->len[NL80211_BAND_2GHZ],
833 pos);
834 params->preq.band_data[0].offset = cpu_to_le16(pos - params->preq.buf);
835 params->preq.band_data[0].len = cpu_to_le16(newpos - pos);
836 pos = newpos;
837
838 memcpy(pos, ies->ies[NL80211_BAND_5GHZ],
839 ies->len[NL80211_BAND_5GHZ]);
840 params->preq.band_data[1].offset = cpu_to_le16(pos - params->preq.buf);
841 params->preq.band_data[1].len =
842 cpu_to_le16(ies->len[NL80211_BAND_5GHZ]);
843 pos += ies->len[NL80211_BAND_5GHZ];
844
845 memcpy(pos, ies->common_ies, ies->common_ie_len);
846 params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf);
847
848 if (iwl_mvm_rrm_scan_needed(mvm) &&
849 !fw_has_capa(&mvm->fw->ucode_capa,
850 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)) {
851 iwl_mvm_add_tpc_report_ie(pos + ies->common_ie_len);
852 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len +
853 WFA_TPC_IE_LEN);
854 } else {
855 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len);
856 }
857 }
858
859 static void iwl_mvm_scan_lmac_dwell(struct iwl_mvm *mvm,
860 struct iwl_scan_req_lmac *cmd,
861 struct iwl_mvm_scan_params *params)
862 {
863 cmd->active_dwell = IWL_SCAN_DWELL_ACTIVE;
864 cmd->passive_dwell = IWL_SCAN_DWELL_PASSIVE;
865 cmd->fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
866 cmd->extended_dwell = IWL_SCAN_DWELL_EXTENDED;
867 cmd->max_out_time = cpu_to_le32(scan_timing[params->type].max_out_time);
868 cmd->suspend_time = cpu_to_le32(scan_timing[params->type].suspend_time);
869 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
870 }
871
872 static inline bool iwl_mvm_scan_fits(struct iwl_mvm *mvm, int n_ssids,
873 struct ieee80211_scan_ies *ies,
874 int n_channels)
875 {
876 return ((n_ssids <= PROBE_OPTION_MAX) &&
877 (n_channels <= mvm->fw->ucode_capa.n_scan_channels) &
878 (ies->common_ie_len +
879 ies->len[NL80211_BAND_2GHZ] +
880 ies->len[NL80211_BAND_5GHZ] <=
881 iwl_mvm_max_scan_ie_fw_cmd_room(mvm)));
882 }
883
884 static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm *mvm,
885 struct ieee80211_vif *vif)
886 {
887 const struct iwl_ucode_capabilities *capa = &mvm->fw->ucode_capa;
888 bool low_latency;
889
890 if (iwl_mvm_is_cdb_supported(mvm))
891 low_latency = iwl_mvm_low_latency_band(mvm, NL80211_BAND_5GHZ);
892 else
893 low_latency = iwl_mvm_low_latency(mvm);
894
895
896
897
898
899
900
901
902
903 return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
904 mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS &&
905 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
906 (!low_latency || iwl_mvm_is_frag_ebs_supported(mvm)));
907 }
908
909 static inline bool iwl_mvm_is_regular_scan(struct iwl_mvm_scan_params *params)
910 {
911 return params->n_scan_plans == 1 &&
912 params->scan_plans[0].iterations == 1;
913 }
914
915 static bool iwl_mvm_is_scan_fragmented(enum iwl_mvm_scan_type type)
916 {
917 return (type == IWL_SCAN_TYPE_FRAGMENTED ||
918 type == IWL_SCAN_TYPE_FAST_BALANCE);
919 }
920
921 static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
922 struct iwl_mvm_scan_params *params,
923 struct ieee80211_vif *vif)
924 {
925 int flags = 0;
926
927 if (params->n_ssids == 0)
928 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
929
930 if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
931 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
932
933 if (iwl_mvm_is_scan_fragmented(params->type))
934 flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
935
936 if (iwl_mvm_rrm_scan_needed(mvm) &&
937 fw_has_capa(&mvm->fw->ucode_capa,
938 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
939 flags |= IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED;
940
941 if (params->pass_all)
942 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
943 else
944 flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;
945
946 #ifdef CONFIG_IWLWIFI_DEBUGFS
947 if (mvm->scan_iter_notif_enabled)
948 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
949 #endif
950
951 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
952 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
953
954 if (iwl_mvm_is_regular_scan(params) &&
955 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
956 !iwl_mvm_is_scan_fragmented(params->type))
957 flags |= IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL;
958
959 return flags;
960 }
961
962 static void
963 iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req,
964 struct iwl_scan_probe_req *src_p_req)
965 {
966 int i;
967
968 p_req->mac_header = src_p_req->mac_header;
969 for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++)
970 p_req->band_data[i] = src_p_req->band_data[i];
971 p_req->common_data = src_p_req->common_data;
972 memcpy(p_req->buf, src_p_req->buf, sizeof(p_req->buf));
973 }
974
975 static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
976 struct iwl_mvm_scan_params *params)
977 {
978 struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
979 struct iwl_scan_probe_req_v1 *preq =
980 (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) *
981 mvm->fw->ucode_capa.n_scan_channels);
982 u32 ssid_bitmap = 0;
983 int i;
984
985 lockdep_assert_held(&mvm->mutex);
986
987 memset(cmd, 0, ksize(cmd));
988
989 if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
990 return -EINVAL;
991
992 iwl_mvm_scan_lmac_dwell(mvm, cmd, params);
993
994 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
995 cmd->iter_num = cpu_to_le32(1);
996 cmd->n_channels = (u8)params->n_channels;
997
998 cmd->delay = cpu_to_le32(params->delay);
999
1000 cmd->scan_flags = cpu_to_le32(iwl_mvm_scan_lmac_flags(mvm, params,
1001 vif));
1002
1003 cmd->flags = iwl_mvm_scan_rxon_flags(params->channels[0]->band);
1004 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
1005 MAC_FILTER_IN_BEACON);
1006 iwl_mvm_scan_fill_tx_cmd(mvm, cmd->tx_cmd, params->no_cck);
1007 iwl_scan_build_ssids(params, cmd->direct_scan, &ssid_bitmap);
1008
1009
1010 ssid_bitmap <<= 1;
1011
1012 for (i = 0; i < params->n_scan_plans; i++) {
1013 struct cfg80211_sched_scan_plan *scan_plan =
1014 ¶ms->scan_plans[i];
1015
1016 cmd->schedule[i].delay =
1017 cpu_to_le16(scan_plan->interval);
1018 cmd->schedule[i].iterations = scan_plan->iterations;
1019 cmd->schedule[i].full_scan_mul = 1;
1020 }
1021
1022
1023
1024
1025
1026
1027
1028 if (!cmd->schedule[i - 1].iterations)
1029 cmd->schedule[i - 1].iterations = 0xff;
1030
1031 if (iwl_mvm_scan_use_ebs(mvm, vif)) {
1032 cmd->channel_opt[0].flags =
1033 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1034 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1035 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1036 cmd->channel_opt[0].non_ebs_ratio =
1037 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1038 cmd->channel_opt[1].flags =
1039 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1040 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1041 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1042 cmd->channel_opt[1].non_ebs_ratio =
1043 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1044 }
1045
1046 iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
1047 params->n_channels, ssid_bitmap, cmd);
1048
1049 iwl_mvm_scan_set_legacy_probe_req(preq, ¶ms->preq);
1050
1051 return 0;
1052 }
1053
1054 static int rate_to_scan_rate_flag(unsigned int rate)
1055 {
1056 static const int rate_to_scan_rate[IWL_RATE_COUNT] = {
1057 [IWL_RATE_1M_INDEX] = SCAN_CONFIG_RATE_1M,
1058 [IWL_RATE_2M_INDEX] = SCAN_CONFIG_RATE_2M,
1059 [IWL_RATE_5M_INDEX] = SCAN_CONFIG_RATE_5M,
1060 [IWL_RATE_11M_INDEX] = SCAN_CONFIG_RATE_11M,
1061 [IWL_RATE_6M_INDEX] = SCAN_CONFIG_RATE_6M,
1062 [IWL_RATE_9M_INDEX] = SCAN_CONFIG_RATE_9M,
1063 [IWL_RATE_12M_INDEX] = SCAN_CONFIG_RATE_12M,
1064 [IWL_RATE_18M_INDEX] = SCAN_CONFIG_RATE_18M,
1065 [IWL_RATE_24M_INDEX] = SCAN_CONFIG_RATE_24M,
1066 [IWL_RATE_36M_INDEX] = SCAN_CONFIG_RATE_36M,
1067 [IWL_RATE_48M_INDEX] = SCAN_CONFIG_RATE_48M,
1068 [IWL_RATE_54M_INDEX] = SCAN_CONFIG_RATE_54M,
1069 };
1070
1071 return rate_to_scan_rate[rate];
1072 }
1073
1074 static __le32 iwl_mvm_scan_config_rates(struct iwl_mvm *mvm)
1075 {
1076 struct ieee80211_supported_band *band;
1077 unsigned int rates = 0;
1078 int i;
1079
1080 band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
1081 for (i = 0; i < band->n_bitrates; i++)
1082 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value);
1083 band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
1084 for (i = 0; i < band->n_bitrates; i++)
1085 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value);
1086
1087
1088 rates |= SCAN_CONFIG_SUPPORTED_RATE(rates);
1089
1090 return cpu_to_le32(rates);
1091 }
1092
1093 static void iwl_mvm_fill_scan_dwell(struct iwl_mvm *mvm,
1094 struct iwl_scan_dwell *dwell)
1095 {
1096 dwell->active = IWL_SCAN_DWELL_ACTIVE;
1097 dwell->passive = IWL_SCAN_DWELL_PASSIVE;
1098 dwell->fragmented = IWL_SCAN_DWELL_FRAGMENTED;
1099 dwell->extended = IWL_SCAN_DWELL_EXTENDED;
1100 }
1101
1102 static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels,
1103 u32 max_channels)
1104 {
1105 struct ieee80211_supported_band *band;
1106 int i, j = 0;
1107
1108 band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
1109 for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
1110 channels[j] = band->channels[i].hw_value;
1111 band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
1112 for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
1113 channels[j] = band->channels[i].hw_value;
1114 }
1115
1116 static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
1117 u32 flags, u8 channel_flags,
1118 u32 max_channels)
1119 {
1120 enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL);
1121 struct iwl_scan_config_v1 *cfg = config;
1122
1123 cfg->flags = cpu_to_le32(flags);
1124 cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1125 cfg->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1126 cfg->legacy_rates = iwl_mvm_scan_config_rates(mvm);
1127 cfg->out_of_channel_time = cpu_to_le32(scan_timing[type].max_out_time);
1128 cfg->suspend_time = cpu_to_le32(scan_timing[type].suspend_time);
1129
1130 iwl_mvm_fill_scan_dwell(mvm, &cfg->dwell);
1131
1132 memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
1133
1134 cfg->bcast_sta_id = mvm->aux_sta.sta_id;
1135 cfg->channel_flags = channel_flags;
1136
1137 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1138 }
1139
1140 static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config,
1141 u32 flags, u8 channel_flags,
1142 u32 max_channels)
1143 {
1144 struct iwl_scan_config_v2 *cfg = config;
1145
1146 cfg->flags = cpu_to_le32(flags);
1147 cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1148 cfg->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1149 cfg->legacy_rates = iwl_mvm_scan_config_rates(mvm);
1150
1151 if (iwl_mvm_is_cdb_supported(mvm)) {
1152 enum iwl_mvm_scan_type lb_type, hb_type;
1153
1154 lb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
1155 NL80211_BAND_2GHZ);
1156 hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
1157 NL80211_BAND_5GHZ);
1158
1159 cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
1160 cpu_to_le32(scan_timing[lb_type].max_out_time);
1161 cfg->suspend_time[SCAN_LB_LMAC_IDX] =
1162 cpu_to_le32(scan_timing[lb_type].suspend_time);
1163
1164 cfg->out_of_channel_time[SCAN_HB_LMAC_IDX] =
1165 cpu_to_le32(scan_timing[hb_type].max_out_time);
1166 cfg->suspend_time[SCAN_HB_LMAC_IDX] =
1167 cpu_to_le32(scan_timing[hb_type].suspend_time);
1168 } else {
1169 enum iwl_mvm_scan_type type =
1170 iwl_mvm_get_scan_type(mvm, NULL);
1171
1172 cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
1173 cpu_to_le32(scan_timing[type].max_out_time);
1174 cfg->suspend_time[SCAN_LB_LMAC_IDX] =
1175 cpu_to_le32(scan_timing[type].suspend_time);
1176 }
1177
1178 iwl_mvm_fill_scan_dwell(mvm, &cfg->dwell);
1179
1180 memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
1181
1182 cfg->bcast_sta_id = mvm->aux_sta.sta_id;
1183 cfg->channel_flags = channel_flags;
1184
1185 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1186 }
1187
1188 static int iwl_mvm_legacy_config_scan(struct iwl_mvm *mvm)
1189 {
1190 void *cfg;
1191 int ret, cmd_size;
1192 struct iwl_host_cmd cmd = {
1193 .id = iwl_cmd_id(SCAN_CFG_CMD, IWL_ALWAYS_LONG_GROUP, 0),
1194 };
1195 enum iwl_mvm_scan_type type;
1196 enum iwl_mvm_scan_type hb_type = IWL_SCAN_TYPE_NOT_SET;
1197 int num_channels =
1198 mvm->nvm_data->bands[NL80211_BAND_2GHZ].n_channels +
1199 mvm->nvm_data->bands[NL80211_BAND_5GHZ].n_channels;
1200 u32 flags;
1201 u8 channel_flags;
1202
1203 if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels))
1204 num_channels = mvm->fw->ucode_capa.n_scan_channels;
1205
1206 if (iwl_mvm_is_cdb_supported(mvm)) {
1207 type = iwl_mvm_get_scan_type_band(mvm, NULL,
1208 NL80211_BAND_2GHZ);
1209 hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
1210 NL80211_BAND_5GHZ);
1211 if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
1212 return 0;
1213 } else {
1214 type = iwl_mvm_get_scan_type(mvm, NULL);
1215 if (type == mvm->scan_type)
1216 return 0;
1217 }
1218
1219 if (iwl_mvm_cdb_scan_api(mvm))
1220 cmd_size = sizeof(struct iwl_scan_config_v2);
1221 else
1222 cmd_size = sizeof(struct iwl_scan_config_v1);
1223 cmd_size += mvm->fw->ucode_capa.n_scan_channels;
1224
1225 cfg = kzalloc(cmd_size, GFP_KERNEL);
1226 if (!cfg)
1227 return -ENOMEM;
1228
1229 flags = SCAN_CONFIG_FLAG_ACTIVATE |
1230 SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS |
1231 SCAN_CONFIG_FLAG_SET_TX_CHAINS |
1232 SCAN_CONFIG_FLAG_SET_RX_CHAINS |
1233 SCAN_CONFIG_FLAG_SET_AUX_STA_ID |
1234 SCAN_CONFIG_FLAG_SET_ALL_TIMES |
1235 SCAN_CONFIG_FLAG_SET_LEGACY_RATES |
1236 SCAN_CONFIG_FLAG_SET_MAC_ADDR |
1237 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS |
1238 SCAN_CONFIG_N_CHANNELS(num_channels) |
1239 (iwl_mvm_is_scan_fragmented(type) ?
1240 SCAN_CONFIG_FLAG_SET_FRAGMENTED :
1241 SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED);
1242
1243 channel_flags = IWL_CHANNEL_FLAG_EBS |
1244 IWL_CHANNEL_FLAG_ACCURATE_EBS |
1245 IWL_CHANNEL_FLAG_EBS_ADD |
1246 IWL_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
1247
1248
1249
1250
1251
1252 if (iwl_mvm_cdb_scan_api(mvm)) {
1253 if (iwl_mvm_is_cdb_supported(mvm))
1254 flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ?
1255 SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED :
1256 SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED;
1257 iwl_mvm_fill_scan_config_v2(mvm, cfg, flags, channel_flags,
1258 num_channels);
1259 } else {
1260 iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags,
1261 num_channels);
1262 }
1263
1264 cmd.data[0] = cfg;
1265 cmd.len[0] = cmd_size;
1266 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
1267
1268 IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
1269
1270 ret = iwl_mvm_send_cmd(mvm, &cmd);
1271 if (!ret) {
1272 mvm->scan_type = type;
1273 mvm->hb_scan_type = hb_type;
1274 }
1275
1276 kfree(cfg);
1277 return ret;
1278 }
1279
1280 int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1281 {
1282 struct iwl_scan_config cfg;
1283 struct iwl_host_cmd cmd = {
1284 .id = iwl_cmd_id(SCAN_CFG_CMD, IWL_ALWAYS_LONG_GROUP, 0),
1285 .len[0] = sizeof(cfg),
1286 .data[0] = &cfg,
1287 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1288 };
1289
1290 if (!iwl_mvm_is_reduced_config_scan_supported(mvm))
1291 return iwl_mvm_legacy_config_scan(mvm);
1292
1293 memset(&cfg, 0, sizeof(cfg));
1294
1295 cfg.bcast_sta_id = mvm->aux_sta.sta_id;
1296 cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1297 cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1298
1299 IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
1300
1301 return iwl_mvm_send_cmd(mvm, &cmd);
1302 }
1303
1304 static int iwl_mvm_scan_uid_by_status(struct iwl_mvm *mvm, int status)
1305 {
1306 int i;
1307
1308 for (i = 0; i < mvm->max_scans; i++)
1309 if (mvm->scan_uid_status[i] == status)
1310 return i;
1311
1312 return -ENOENT;
1313 }
1314
1315 static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm,
1316 struct iwl_scan_req_umac *cmd,
1317 struct iwl_mvm_scan_params *params)
1318 {
1319 struct iwl_mvm_scan_timing_params *timing, *hb_timing;
1320 u8 active_dwell, passive_dwell;
1321
1322 timing = &scan_timing[params->type];
1323 active_dwell = params->measurement_dwell ?
1324 params->measurement_dwell : IWL_SCAN_DWELL_ACTIVE;
1325 passive_dwell = params->measurement_dwell ?
1326 params->measurement_dwell : IWL_SCAN_DWELL_PASSIVE;
1327
1328 if (iwl_mvm_is_adaptive_dwell_supported(mvm)) {
1329 cmd->v7.adwell_default_n_aps_social =
1330 IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
1331 cmd->v7.adwell_default_n_aps =
1332 IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
1333
1334 if (iwl_mvm_is_adwell_hb_ap_num_supported(mvm))
1335 cmd->v9.adwell_default_hb_n_aps =
1336 IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;
1337
1338
1339 if (IWL_MVM_ADWELL_MAX_BUDGET)
1340 cmd->v7.adwell_max_budget =
1341 cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET);
1342 else if (params->ssids && params->ssids[0].ssid_len)
1343 cmd->v7.adwell_max_budget =
1344 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
1345 else
1346 cmd->v7.adwell_max_budget =
1347 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
1348
1349 cmd->v7.scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1350 cmd->v7.max_out_time[SCAN_LB_LMAC_IDX] =
1351 cpu_to_le32(timing->max_out_time);
1352 cmd->v7.suspend_time[SCAN_LB_LMAC_IDX] =
1353 cpu_to_le32(timing->suspend_time);
1354
1355 if (iwl_mvm_is_cdb_supported(mvm)) {
1356 hb_timing = &scan_timing[params->hb_type];
1357
1358 cmd->v7.max_out_time[SCAN_HB_LMAC_IDX] =
1359 cpu_to_le32(hb_timing->max_out_time);
1360 cmd->v7.suspend_time[SCAN_HB_LMAC_IDX] =
1361 cpu_to_le32(hb_timing->suspend_time);
1362 }
1363
1364 if (!iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
1365 cmd->v7.active_dwell = active_dwell;
1366 cmd->v7.passive_dwell = passive_dwell;
1367 cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
1368 } else {
1369 cmd->v8.active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
1370 cmd->v8.passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
1371 if (iwl_mvm_is_cdb_supported(mvm)) {
1372 cmd->v8.active_dwell[SCAN_HB_LMAC_IDX] =
1373 active_dwell;
1374 cmd->v8.passive_dwell[SCAN_HB_LMAC_IDX] =
1375 passive_dwell;
1376 }
1377 }
1378 } else {
1379 cmd->v1.extended_dwell = params->measurement_dwell ?
1380 params->measurement_dwell : IWL_SCAN_DWELL_EXTENDED;
1381 cmd->v1.active_dwell = active_dwell;
1382 cmd->v1.passive_dwell = passive_dwell;
1383 cmd->v1.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
1384
1385 if (iwl_mvm_is_cdb_supported(mvm)) {
1386 hb_timing = &scan_timing[params->hb_type];
1387
1388 cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] =
1389 cpu_to_le32(hb_timing->max_out_time);
1390 cmd->v6.suspend_time[SCAN_HB_LMAC_IDX] =
1391 cpu_to_le32(hb_timing->suspend_time);
1392 }
1393
1394 if (iwl_mvm_cdb_scan_api(mvm)) {
1395 cmd->v6.scan_priority =
1396 cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1397 cmd->v6.max_out_time[SCAN_LB_LMAC_IDX] =
1398 cpu_to_le32(timing->max_out_time);
1399 cmd->v6.suspend_time[SCAN_LB_LMAC_IDX] =
1400 cpu_to_le32(timing->suspend_time);
1401 } else {
1402 cmd->v1.scan_priority =
1403 cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1404 cmd->v1.max_out_time =
1405 cpu_to_le32(timing->max_out_time);
1406 cmd->v1.suspend_time =
1407 cpu_to_le32(timing->suspend_time);
1408 }
1409 }
1410
1411 if (iwl_mvm_is_regular_scan(params))
1412 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1413 else
1414 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
1415 }
1416
1417 static void
1418 iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
1419 struct ieee80211_channel **channels,
1420 int n_channels, u32 ssid_bitmap,
1421 struct iwl_scan_channel_cfg_umac *channel_cfg)
1422 {
1423 int i;
1424
1425 for (i = 0; i < n_channels; i++) {
1426 channel_cfg[i].flags = cpu_to_le32(ssid_bitmap);
1427 channel_cfg[i].v1.channel_num = channels[i]->hw_value;
1428 if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
1429 channel_cfg[i].v2.band =
1430 channels[i]->hw_value <= IWL_SCAN_LAST_2_4_CHN ?
1431 IWL_SCAN_BAND_2_4 : IWL_SCAN_BAND_5_2;
1432 channel_cfg[i].v2.iter_count = 1;
1433 channel_cfg[i].v2.iter_interval = 0;
1434 } else {
1435 channel_cfg[i].v1.iter_count = 1;
1436 channel_cfg[i].v1.iter_interval = 0;
1437 }
1438 }
1439 }
1440
1441 static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
1442 struct iwl_mvm_scan_params *params,
1443 struct ieee80211_vif *vif)
1444 {
1445 u16 flags = 0;
1446
1447 if (params->n_ssids == 0)
1448 flags = IWL_UMAC_SCAN_GEN_FLAGS_PASSIVE;
1449
1450 if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
1451 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT;
1452
1453 if (iwl_mvm_is_scan_fragmented(params->type))
1454 flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED;
1455
1456 if (iwl_mvm_is_cdb_supported(mvm) &&
1457 iwl_mvm_is_scan_fragmented(params->hb_type))
1458 flags |= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED;
1459
1460 if (iwl_mvm_rrm_scan_needed(mvm) &&
1461 fw_has_capa(&mvm->fw->ucode_capa,
1462 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
1463 flags |= IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED;
1464
1465 if (params->pass_all)
1466 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL;
1467 else
1468 flags |= IWL_UMAC_SCAN_GEN_FLAGS_MATCH;
1469
1470 if (!iwl_mvm_is_regular_scan(params))
1471 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PERIODIC;
1472
1473 if (params->measurement_dwell)
1474 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
1475
1476 #ifdef CONFIG_IWLWIFI_DEBUGFS
1477 if (mvm->scan_iter_notif_enabled)
1478 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
1479 #endif
1480
1481 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
1482 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
1483
1484 if (iwl_mvm_is_adaptive_dwell_supported(mvm) && IWL_MVM_ADWELL_ENABLE &&
1485 vif->type != NL80211_IFTYPE_P2P_DEVICE)
1486 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL;
1487
1488
1489
1490
1491
1492
1493 if (iwl_mvm_is_regular_scan(params) &&
1494 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
1495 !iwl_mvm_is_scan_fragmented(params->type) &&
1496 !iwl_mvm_is_adaptive_dwell_supported(mvm) &&
1497 !iwl_mvm_is_oce_supported(mvm))
1498 flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL;
1499
1500 if (iwl_mvm_is_oce_supported(mvm)) {
1501 if ((params->flags &
1502 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE))
1503 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_HIGH_TX_RATE;
1504
1505
1506
1507
1508
1509 if ((params->flags &
1510 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
1511 !WARN_ON_ONCE(!iwl_mvm_is_adaptive_dwell_supported(mvm)))
1512 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_DEFER_SUPP;
1513 if ((params->flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME))
1514 flags |= IWL_UMAC_SCAN_GEN_FLAGS_MAX_CHNL_TIME;
1515 }
1516
1517 return flags;
1518 }
1519
1520 static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1521 struct iwl_mvm_scan_params *params,
1522 int type)
1523 {
1524 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
1525 struct iwl_scan_umac_chan_param *chan_param;
1526 void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
1527 void *sec_part = cmd_data + sizeof(struct iwl_scan_channel_cfg_umac) *
1528 mvm->fw->ucode_capa.n_scan_channels;
1529 struct iwl_scan_req_umac_tail_v2 *tail_v2 =
1530 (struct iwl_scan_req_umac_tail_v2 *)sec_part;
1531 struct iwl_scan_req_umac_tail_v1 *tail_v1;
1532 struct iwl_ssid_ie *direct_scan;
1533 int uid, i;
1534 u32 ssid_bitmap = 0;
1535 u8 channel_flags = 0;
1536 u16 gen_flags;
1537 struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif);
1538
1539 chan_param = iwl_mvm_get_scan_req_umac_channel(mvm);
1540
1541 lockdep_assert_held(&mvm->mutex);
1542
1543 if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
1544 return -EINVAL;
1545
1546 uid = iwl_mvm_scan_uid_by_status(mvm, 0);
1547 if (uid < 0)
1548 return uid;
1549
1550 memset(cmd, 0, ksize(cmd));
1551
1552 iwl_mvm_scan_umac_dwell(mvm, cmd, params);
1553
1554 mvm->scan_uid_status[uid] = type;
1555
1556 cmd->uid = cpu_to_le32(uid);
1557 gen_flags = iwl_mvm_scan_umac_flags(mvm, params, vif);
1558 cmd->general_flags = cpu_to_le16(gen_flags);
1559 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
1560 if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED)
1561 cmd->v8.num_of_fragments[SCAN_LB_LMAC_IDX] =
1562 IWL_SCAN_NUM_OF_FRAGS;
1563 if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED)
1564 cmd->v8.num_of_fragments[SCAN_HB_LMAC_IDX] =
1565 IWL_SCAN_NUM_OF_FRAGS;
1566
1567 cmd->v8.general_flags2 =
1568 IWL_UMAC_SCAN_GEN_FLAGS2_ALLOW_CHNL_REORDER;
1569 }
1570
1571 cmd->scan_start_mac_id = scan_vif->id;
1572
1573 if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT)
1574 cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE);
1575
1576 if (iwl_mvm_scan_use_ebs(mvm, vif)) {
1577 channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS |
1578 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1579 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
1580
1581
1582 if (iwl_mvm_is_frag_ebs_supported(mvm)) {
1583 if (gen_flags &
1584 IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED ||
1585 (!iwl_mvm_is_cdb_supported(mvm) &&
1586 gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED))
1587 channel_flags |= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG;
1588 }
1589 }
1590
1591 chan_param->flags = channel_flags;
1592 chan_param->count = params->n_channels;
1593
1594 for (i = 0; i < params->n_scan_plans; i++) {
1595 struct cfg80211_sched_scan_plan *scan_plan =
1596 ¶ms->scan_plans[i];
1597
1598 tail_v2->schedule[i].iter_count = scan_plan->iterations;
1599 tail_v2->schedule[i].interval =
1600 cpu_to_le16(scan_plan->interval);
1601 }
1602
1603
1604
1605
1606
1607
1608
1609 if (!tail_v2->schedule[i - 1].iter_count)
1610 tail_v2->schedule[i - 1].iter_count = 0xff;
1611
1612 tail_v2->delay = cpu_to_le16(params->delay);
1613
1614 if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
1615 tail_v2->preq = params->preq;
1616 direct_scan = tail_v2->direct_scan;
1617 } else {
1618 tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part;
1619 iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq,
1620 ¶ms->preq);
1621 direct_scan = tail_v1->direct_scan;
1622 }
1623 iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap);
1624 iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
1625 params->n_channels, ssid_bitmap,
1626 cmd_data);
1627 return 0;
1628 }
1629
1630 static int iwl_mvm_num_scans(struct iwl_mvm *mvm)
1631 {
1632 return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK);
1633 }
1634
1635 static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
1636 {
1637 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1638 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651 if ((type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) &&
1652 mvm->scan_status & (IWL_MVM_SCAN_SCHED | IWL_MVM_SCAN_NETDETECT))
1653 return -EBUSY;
1654
1655 if (iwl_mvm_num_scans(mvm) < mvm->max_scans)
1656 return 0;
1657
1658
1659
1660
1661 switch (type) {
1662 case IWL_MVM_SCAN_REGULAR:
1663 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
1664 return -EBUSY;
1665 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
1666 case IWL_MVM_SCAN_SCHED:
1667 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
1668 return -EBUSY;
1669 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
1670 case IWL_MVM_SCAN_NETDETECT:
1671
1672
1673
1674
1675
1676 if (!unified_image)
1677 return 0;
1678
1679
1680
1681
1682
1683
1684
1685 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
1686 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR,
1687 true);
1688 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
1689 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED,
1690 true);
1691
1692
1693
1694
1695 default:
1696 WARN_ON(1);
1697 break;
1698 }
1699
1700 return -EIO;
1701 }
1702
1703 #define SCAN_TIMEOUT 20000
1704
1705 void iwl_mvm_scan_timeout_wk(struct work_struct *work)
1706 {
1707 struct delayed_work *delayed_work = to_delayed_work(work);
1708 struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm,
1709 scan_timeout_dwork);
1710
1711 IWL_ERR(mvm, "regular scan timed out\n");
1712
1713 iwl_force_nmi(mvm->trans);
1714 }
1715
1716 static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
1717 struct iwl_mvm_scan_params *params,
1718 struct ieee80211_vif *vif)
1719 {
1720 if (iwl_mvm_is_cdb_supported(mvm)) {
1721 params->type =
1722 iwl_mvm_get_scan_type_band(mvm, vif,
1723 NL80211_BAND_2GHZ);
1724 params->hb_type =
1725 iwl_mvm_get_scan_type_band(mvm, vif,
1726 NL80211_BAND_5GHZ);
1727 } else {
1728 params->type = iwl_mvm_get_scan_type(mvm, vif);
1729 }
1730 }
1731
1732 int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1733 struct cfg80211_scan_request *req,
1734 struct ieee80211_scan_ies *ies)
1735 {
1736 struct iwl_host_cmd hcmd = {
1737 .len = { iwl_mvm_scan_size(mvm), },
1738 .data = { mvm->scan_cmd, },
1739 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1740 };
1741 struct iwl_mvm_scan_params params = {};
1742 int ret;
1743 struct cfg80211_sched_scan_plan scan_plan = { .iterations = 1 };
1744
1745 lockdep_assert_held(&mvm->mutex);
1746
1747 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
1748 IWL_ERR(mvm, "scan while LAR regdomain is not set\n");
1749 return -EBUSY;
1750 }
1751
1752 ret = iwl_mvm_check_running_scans(mvm, IWL_MVM_SCAN_REGULAR);
1753 if (ret)
1754 return ret;
1755
1756
1757 if (WARN_ON(!mvm->scan_cmd))
1758 return -ENOMEM;
1759
1760 if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, req->n_channels))
1761 return -ENOBUFS;
1762
1763 params.n_ssids = req->n_ssids;
1764 params.flags = req->flags;
1765 params.n_channels = req->n_channels;
1766 params.delay = 0;
1767 params.ssids = req->ssids;
1768 params.channels = req->channels;
1769 params.mac_addr = req->mac_addr;
1770 params.mac_addr_mask = req->mac_addr_mask;
1771 params.no_cck = req->no_cck;
1772 params.pass_all = true;
1773 params.n_match_sets = 0;
1774 params.match_sets = NULL;
1775
1776 params.scan_plans = &scan_plan;
1777 params.n_scan_plans = 1;
1778
1779 iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
1780
1781 ret = iwl_mvm_get_measurement_dwell(mvm, req, ¶ms);
1782 if (ret < 0)
1783 return ret;
1784
1785 params.measurement_dwell = ret;
1786
1787 iwl_mvm_build_scan_probe(mvm, vif, ies, ¶ms);
1788
1789 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
1790 hcmd.id = iwl_cmd_id(SCAN_REQ_UMAC, IWL_ALWAYS_LONG_GROUP, 0);
1791 ret = iwl_mvm_scan_umac(mvm, vif, ¶ms,
1792 IWL_MVM_SCAN_REGULAR);
1793 } else {
1794 hcmd.id = SCAN_OFFLOAD_REQUEST_CMD;
1795 ret = iwl_mvm_scan_lmac(mvm, vif, ¶ms);
1796 }
1797
1798 if (ret)
1799 return ret;
1800
1801 iwl_mvm_pause_tcm(mvm, false);
1802
1803 ret = iwl_mvm_send_cmd(mvm, &hcmd);
1804 if (ret) {
1805
1806
1807
1808
1809 IWL_ERR(mvm, "Scan failed! ret %d\n", ret);
1810 iwl_mvm_resume_tcm(mvm);
1811 return ret;
1812 }
1813
1814 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
1815 mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
1816 mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
1817
1818 schedule_delayed_work(&mvm->scan_timeout_dwork,
1819 msecs_to_jiffies(SCAN_TIMEOUT));
1820
1821 return 0;
1822 }
1823
1824 int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1825 struct ieee80211_vif *vif,
1826 struct cfg80211_sched_scan_request *req,
1827 struct ieee80211_scan_ies *ies,
1828 int type)
1829 {
1830 struct iwl_host_cmd hcmd = {
1831 .len = { iwl_mvm_scan_size(mvm), },
1832 .data = { mvm->scan_cmd, },
1833 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1834 };
1835 struct iwl_mvm_scan_params params = {};
1836 int ret;
1837
1838 lockdep_assert_held(&mvm->mutex);
1839
1840 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
1841 IWL_ERR(mvm, "sched-scan while LAR regdomain is not set\n");
1842 return -EBUSY;
1843 }
1844
1845 ret = iwl_mvm_check_running_scans(mvm, type);
1846 if (ret)
1847 return ret;
1848
1849
1850 if (WARN_ON(!mvm->scan_cmd))
1851 return -ENOMEM;
1852
1853 if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, req->n_channels))
1854 return -ENOBUFS;
1855
1856 params.n_ssids = req->n_ssids;
1857 params.flags = req->flags;
1858 params.n_channels = req->n_channels;
1859 params.ssids = req->ssids;
1860 params.channels = req->channels;
1861 params.mac_addr = req->mac_addr;
1862 params.mac_addr_mask = req->mac_addr_mask;
1863 params.no_cck = false;
1864 params.pass_all = iwl_mvm_scan_pass_all(mvm, req);
1865 params.n_match_sets = req->n_match_sets;
1866 params.match_sets = req->match_sets;
1867 if (!req->n_scan_plans)
1868 return -EINVAL;
1869
1870 params.n_scan_plans = req->n_scan_plans;
1871 params.scan_plans = req->scan_plans;
1872
1873 iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
1874
1875
1876
1877
1878
1879
1880 if (req->delay > U16_MAX) {
1881 IWL_DEBUG_SCAN(mvm,
1882 "delay value is > 16-bits, set to max possible\n");
1883 params.delay = U16_MAX;
1884 } else {
1885 params.delay = req->delay;
1886 }
1887
1888 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1889 if (ret)
1890 return ret;
1891
1892 iwl_mvm_build_scan_probe(mvm, vif, ies, ¶ms);
1893
1894 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
1895 hcmd.id = iwl_cmd_id(SCAN_REQ_UMAC, IWL_ALWAYS_LONG_GROUP, 0);
1896 ret = iwl_mvm_scan_umac(mvm, vif, ¶ms, type);
1897 } else {
1898 hcmd.id = SCAN_OFFLOAD_REQUEST_CMD;
1899 ret = iwl_mvm_scan_lmac(mvm, vif, ¶ms);
1900 }
1901
1902 if (ret)
1903 return ret;
1904
1905 ret = iwl_mvm_send_cmd(mvm, &hcmd);
1906 if (!ret) {
1907 IWL_DEBUG_SCAN(mvm,
1908 "Sched scan request was sent successfully\n");
1909 mvm->scan_status |= type;
1910 } else {
1911
1912
1913
1914
1915 IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret);
1916 }
1917
1918 return ret;
1919 }
1920
1921 void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
1922 struct iwl_rx_cmd_buffer *rxb)
1923 {
1924 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1925 struct iwl_umac_scan_complete *notif = (void *)pkt->data;
1926 u32 uid = __le32_to_cpu(notif->uid);
1927 bool aborted = (notif->status == IWL_SCAN_OFFLOAD_ABORTED);
1928
1929 if (WARN_ON(!(mvm->scan_uid_status[uid] & mvm->scan_status)))
1930 return;
1931
1932
1933 if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
1934 struct cfg80211_scan_info info = {
1935 .aborted = aborted,
1936 .scan_start_tsf = mvm->scan_start,
1937 };
1938
1939 memcpy(info.tsf_bssid, mvm->scan_vif->bssid, ETH_ALEN);
1940 ieee80211_scan_completed(mvm->hw, &info);
1941 mvm->scan_vif = NULL;
1942 cancel_delayed_work(&mvm->scan_timeout_dwork);
1943 iwl_mvm_resume_tcm(mvm);
1944 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
1945 ieee80211_sched_scan_stopped(mvm->hw);
1946 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
1947 }
1948
1949 mvm->scan_status &= ~mvm->scan_uid_status[uid];
1950 IWL_DEBUG_SCAN(mvm,
1951 "Scan completed, uid %u type %u, status %s, EBS status %s\n",
1952 uid, mvm->scan_uid_status[uid],
1953 notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
1954 "completed" : "aborted",
1955 iwl_mvm_ebs_status_str(notif->ebs_status));
1956 IWL_DEBUG_SCAN(mvm,
1957 "Last line %d, Last iteration %d, Time from last iteration %d\n",
1958 notif->last_schedule, notif->last_iter,
1959 __le32_to_cpu(notif->time_from_last_iter));
1960
1961 if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS &&
1962 notif->ebs_status != IWL_SCAN_EBS_INACTIVE)
1963 mvm->last_ebs_successful = false;
1964
1965 mvm->scan_uid_status[uid] = 0;
1966 }
1967
1968 void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
1969 struct iwl_rx_cmd_buffer *rxb)
1970 {
1971 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1972 struct iwl_umac_scan_iter_complete_notif *notif = (void *)pkt->data;
1973
1974 mvm->scan_start = le64_to_cpu(notif->start_tsf);
1975
1976 IWL_DEBUG_SCAN(mvm,
1977 "UMAC Scan iteration complete: status=0x%x scanned_channels=%d\n",
1978 notif->status, notif->scanned_channels);
1979
1980 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
1981 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
1982 ieee80211_sched_scan_results(mvm->hw);
1983 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
1984 }
1985
1986 IWL_DEBUG_SCAN(mvm,
1987 "UMAC Scan iteration complete: scan started at %llu (TSF)\n",
1988 mvm->scan_start);
1989 }
1990
1991 static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
1992 {
1993 struct iwl_umac_scan_abort cmd = {};
1994 int uid, ret;
1995
1996 lockdep_assert_held(&mvm->mutex);
1997
1998
1999
2000
2001
2002 uid = iwl_mvm_scan_uid_by_status(mvm, type);
2003 if (WARN_ON_ONCE(uid < 0))
2004 return uid;
2005
2006 cmd.uid = cpu_to_le32(uid);
2007
2008 IWL_DEBUG_SCAN(mvm, "Sending scan abort, uid %u\n", uid);
2009
2010 ret = iwl_mvm_send_cmd_pdu(mvm,
2011 iwl_cmd_id(SCAN_ABORT_UMAC,
2012 IWL_ALWAYS_LONG_GROUP, 0),
2013 0, sizeof(cmd), &cmd);
2014 if (!ret)
2015 mvm->scan_uid_status[uid] = type << IWL_MVM_SCAN_STOPPING_SHIFT;
2016
2017 return ret;
2018 }
2019
2020 static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
2021 {
2022 struct iwl_notification_wait wait_scan_done;
2023 static const u16 scan_done_notif[] = { SCAN_COMPLETE_UMAC,
2024 SCAN_OFFLOAD_COMPLETE, };
2025 int ret;
2026
2027 lockdep_assert_held(&mvm->mutex);
2028
2029 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
2030 scan_done_notif,
2031 ARRAY_SIZE(scan_done_notif),
2032 NULL, NULL);
2033
2034 IWL_DEBUG_SCAN(mvm, "Preparing to stop scan, type %x\n", type);
2035
2036 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
2037 ret = iwl_mvm_umac_scan_abort(mvm, type);
2038 else
2039 ret = iwl_mvm_lmac_scan_abort(mvm);
2040
2041 if (ret) {
2042 IWL_DEBUG_SCAN(mvm, "couldn't stop scan type %d\n", type);
2043 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
2044 return ret;
2045 }
2046
2047 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_done,
2048 1 * HZ);
2049 }
2050
2051 int iwl_mvm_scan_size(struct iwl_mvm *mvm)
2052 {
2053 int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
2054 int tail_size;
2055
2056 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
2057 base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
2058 else if (iwl_mvm_is_adaptive_dwell_supported(mvm))
2059 base_size = IWL_SCAN_REQ_UMAC_SIZE_V7;
2060 else if (iwl_mvm_cdb_scan_api(mvm))
2061 base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;
2062
2063 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
2064 if (iwl_mvm_is_scan_ext_chan_supported(mvm))
2065 tail_size = sizeof(struct iwl_scan_req_umac_tail_v2);
2066 else
2067 tail_size = sizeof(struct iwl_scan_req_umac_tail_v1);
2068
2069 return base_size +
2070 sizeof(struct iwl_scan_channel_cfg_umac) *
2071 mvm->fw->ucode_capa.n_scan_channels +
2072 tail_size;
2073 }
2074 return sizeof(struct iwl_scan_req_lmac) +
2075 sizeof(struct iwl_scan_channel_cfg_lmac) *
2076 mvm->fw->ucode_capa.n_scan_channels +
2077 sizeof(struct iwl_scan_probe_req_v1);
2078 }
2079
2080
2081
2082
2083
2084 void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
2085 {
2086 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
2087 int uid, i;
2088
2089 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_REGULAR);
2090 if (uid >= 0) {
2091 struct cfg80211_scan_info info = {
2092 .aborted = true,
2093 };
2094
2095 ieee80211_scan_completed(mvm->hw, &info);
2096 mvm->scan_uid_status[uid] = 0;
2097 }
2098 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED);
2099 if (uid >= 0 && !mvm->fw_restart) {
2100 ieee80211_sched_scan_stopped(mvm->hw);
2101 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
2102 mvm->scan_uid_status[uid] = 0;
2103 }
2104
2105
2106
2107
2108
2109 for (i = 0; i < mvm->max_scans; i++) {
2110 if (WARN_ONCE(mvm->scan_uid_status[i],
2111 "UMAC scan UID %d status was not cleaned\n",
2112 i))
2113 mvm->scan_uid_status[i] = 0;
2114 }
2115 } else {
2116 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
2117 struct cfg80211_scan_info info = {
2118 .aborted = true,
2119 };
2120
2121 ieee80211_scan_completed(mvm->hw, &info);
2122 }
2123
2124
2125
2126
2127
2128 if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) &&
2129 !mvm->fw_restart) {
2130 ieee80211_sched_scan_stopped(mvm->hw);
2131 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
2132 }
2133 }
2134 }
2135
2136 int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
2137 {
2138 int ret;
2139
2140 if (!(mvm->scan_status & type))
2141 return 0;
2142
2143 if (iwl_mvm_is_radio_killed(mvm)) {
2144 ret = 0;
2145 goto out;
2146 }
2147
2148 ret = iwl_mvm_scan_stop_wait(mvm, type);
2149 if (!ret)
2150 mvm->scan_status |= type << IWL_MVM_SCAN_STOPPING_SHIFT;
2151 out:
2152
2153
2154
2155
2156
2157 mvm->scan_status &= ~type;
2158
2159 if (type == IWL_MVM_SCAN_REGULAR) {
2160 cancel_delayed_work(&mvm->scan_timeout_dwork);
2161 if (notify) {
2162 struct cfg80211_scan_info info = {
2163 .aborted = true,
2164 };
2165
2166 ieee80211_scan_completed(mvm->hw, &info);
2167 }
2168 } else if (notify) {
2169 ieee80211_sched_scan_stopped(mvm->hw);
2170 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
2171 }
2172
2173 return ret;
2174 }