1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3 * Copyright (C) 2024-2025 Intel Corporation
4 */
5 #include <linux/crc32.h>
6
7 #include "iwl-utils.h"
8
9 #include "mld.h"
10 #include "scan.h"
11 #include "hcmd.h"
12 #include "iface.h"
13 #include "phy.h"
14 #include "mlo.h"
15
16 #include "fw/api/scan.h"
17 #include "fw/dbg.h"
18
19 #define IWL_SCAN_DWELL_ACTIVE 10
20 #define IWL_SCAN_DWELL_PASSIVE 110
21 #define IWL_SCAN_NUM_OF_FRAGS 3
22
23 /* adaptive dwell max budget time [TU] for full scan */
24 #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
25
26 /* adaptive dwell max budget time [TU] for directed scan */
27 #define IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
28
29 /* adaptive dwell default high band APs number */
30 #define IWL_SCAN_ADWELL_DEFAULT_HB_N_APS 8
31
32 /* adaptive dwell default low band APs number */
33 #define IWL_SCAN_ADWELL_DEFAULT_LB_N_APS 2
34
35 /* adaptive dwell default APs number for P2P social channels (1, 6, 11) */
36 #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
37
38 /* adaptive dwell number of APs override for P2P friendly GO channels */
39 #define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
40
41 /* adaptive dwell number of APs override for P2P social channels */
42 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
43
44 /* adaptive dwell number of APs override mask for p2p friendly GO */
45 #define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT BIT(20)
46
47 /* adaptive dwell number of APs override mask for social channels */
48 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT BIT(21)
49
50 /* minimal number of 2GHz and 5GHz channels in the regular scan request */
51 #define IWL_MLD_6GHZ_PASSIVE_SCAN_MIN_CHANS 4
52
53 enum iwl_mld_scan_type {
54 IWL_SCAN_TYPE_NOT_SET,
55 IWL_SCAN_TYPE_UNASSOC,
56 IWL_SCAN_TYPE_WILD,
57 IWL_SCAN_TYPE_MILD,
58 IWL_SCAN_TYPE_FRAGMENTED,
59 IWL_SCAN_TYPE_FAST_BALANCE,
60 };
61
62 struct iwl_mld_scan_timing_params {
63 u32 suspend_time;
64 u32 max_out_time;
65 };
66
67 static const struct iwl_mld_scan_timing_params scan_timing[] = {
68 [IWL_SCAN_TYPE_UNASSOC] = {
69 .suspend_time = 0,
70 .max_out_time = 0,
71 },
72 [IWL_SCAN_TYPE_WILD] = {
73 .suspend_time = 30,
74 .max_out_time = 120,
75 },
76 [IWL_SCAN_TYPE_MILD] = {
77 .suspend_time = 120,
78 .max_out_time = 120,
79 },
80 [IWL_SCAN_TYPE_FRAGMENTED] = {
81 .suspend_time = 95,
82 .max_out_time = 44,
83 },
84 [IWL_SCAN_TYPE_FAST_BALANCE] = {
85 .suspend_time = 30,
86 .max_out_time = 37,
87 },
88 };
89
90 struct iwl_mld_scan_params {
91 enum iwl_mld_scan_type type;
92 u32 n_channels;
93 u16 delay;
94 int n_ssids;
95 struct cfg80211_ssid *ssids;
96 struct ieee80211_channel **channels;
97 u32 flags;
98 u8 *mac_addr;
99 u8 *mac_addr_mask;
100 bool no_cck;
101 bool pass_all;
102 int n_match_sets;
103 struct iwl_scan_probe_req preq;
104 struct cfg80211_match_set *match_sets;
105 int n_scan_plans;
106 struct cfg80211_sched_scan_plan *scan_plans;
107 bool iter_notif;
108 bool respect_p2p_go;
109 u8 fw_link_id;
110 struct cfg80211_scan_6ghz_params *scan_6ghz_params;
111 u32 n_6ghz_params;
112 bool scan_6ghz;
113 bool enable_6ghz_passive;
114 u8 bssid[ETH_ALEN] __aligned(2);
115 };
116
117 struct iwl_scan_req_params_ptrs {
118 struct iwl_scan_general_params_v11 *general_params;
119 struct iwl_scan_channel_params_v8 *channel_params;
120 struct iwl_scan_periodic_parms_v1 *periodic_params;
121 struct iwl_scan_probe_params_v4 *probe_params;
122 };
123
124 struct iwl_mld_scan_respect_p2p_go_iter_data {
125 struct ieee80211_vif *current_vif;
126 bool p2p_go;
127 };
128
iwl_mld_scan_respect_p2p_go_iter(void * _data,u8 * mac,struct ieee80211_vif * vif)129 static void iwl_mld_scan_respect_p2p_go_iter(void *_data, u8 *mac,
130 struct ieee80211_vif *vif)
131 {
132 struct iwl_mld_scan_respect_p2p_go_iter_data *data = _data;
133
134 /* exclude the given vif */
135 if (vif == data->current_vif)
136 return;
137
138 /* TODO: CDB check the band of the GO */
139 if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_P2P_GO &&
140 iwl_mld_vif_from_mac80211(vif)->ap_ibss_active)
141 data->p2p_go = true;
142 }
143
iwl_mld_get_respect_p2p_go(struct iwl_mld * mld,struct ieee80211_vif * vif,bool low_latency)144 static bool iwl_mld_get_respect_p2p_go(struct iwl_mld *mld,
145 struct ieee80211_vif *vif,
146 bool low_latency)
147 {
148 struct iwl_mld_scan_respect_p2p_go_iter_data data = {
149 .current_vif = vif,
150 .p2p_go = false,
151 };
152
153 if (!low_latency)
154 return false;
155
156 ieee80211_iterate_active_interfaces_mtx(mld->hw,
157 IEEE80211_IFACE_ITER_NORMAL,
158 iwl_mld_scan_respect_p2p_go_iter,
159 &data);
160
161 return data.p2p_go;
162 }
163
164 struct iwl_mld_scan_iter_data {
165 struct ieee80211_vif *current_vif;
166 bool active_vif;
167 bool is_dcm_with_p2p_go;
168 bool global_low_latency;
169 };
170
iwl_mld_scan_iterator(void * _data,u8 * mac,struct ieee80211_vif * vif)171 static void iwl_mld_scan_iterator(void *_data, u8 *mac,
172 struct ieee80211_vif *vif)
173 {
174 struct iwl_mld_scan_iter_data *data = _data;
175 struct ieee80211_vif *curr_vif = data->current_vif;
176 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
177 struct iwl_mld_vif *curr_mld_vif;
178 unsigned long curr_vif_active_links;
179 u16 link_id;
180
181 data->global_low_latency |= iwl_mld_vif_low_latency(mld_vif);
182
183 if ((ieee80211_vif_is_mld(vif) && vif->active_links) ||
184 (vif->type != NL80211_IFTYPE_P2P_DEVICE &&
185 mld_vif->deflink.active))
186 data->active_vif = true;
187
188 if (vif == curr_vif)
189 return;
190
191 if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_P2P_GO)
192 return;
193
194 /* Currently P2P GO can't be AP MLD so the logic below assumes that */
195 WARN_ON_ONCE(ieee80211_vif_is_mld(vif));
196
197 curr_vif_active_links =
198 ieee80211_vif_is_mld(curr_vif) ? curr_vif->active_links : 1;
199
200 curr_mld_vif = iwl_mld_vif_from_mac80211(curr_vif);
201
202 for_each_set_bit(link_id, &curr_vif_active_links,
203 IEEE80211_MLD_MAX_NUM_LINKS) {
204 struct iwl_mld_link *curr_mld_link =
205 iwl_mld_link_dereference_check(curr_mld_vif, link_id);
206
207 if (WARN_ON(!curr_mld_link))
208 return;
209
210 if (rcu_access_pointer(curr_mld_link->chan_ctx) &&
211 rcu_access_pointer(mld_vif->deflink.chan_ctx) !=
212 rcu_access_pointer(curr_mld_link->chan_ctx)) {
213 data->is_dcm_with_p2p_go = true;
214 return;
215 }
216 }
217 }
218
219 static enum
iwl_mld_get_scan_type(struct iwl_mld * mld,struct ieee80211_vif * vif,struct iwl_mld_scan_iter_data * data)220 iwl_mld_scan_type iwl_mld_get_scan_type(struct iwl_mld *mld,
221 struct ieee80211_vif *vif,
222 struct iwl_mld_scan_iter_data *data)
223 {
224 enum iwl_mld_traffic_load load = mld->scan.traffic_load.status;
225
226 /* A scanning AP interface probably wants to generate a survey to do
227 * ACS (automatic channel selection).
228 * Force a non-fragmented scan in that case.
229 */
230 if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_AP)
231 return IWL_SCAN_TYPE_WILD;
232
233 if (!data->active_vif)
234 return IWL_SCAN_TYPE_UNASSOC;
235
236 if ((load == IWL_MLD_TRAFFIC_HIGH || data->global_low_latency) &&
237 vif->type != NL80211_IFTYPE_P2P_DEVICE)
238 return IWL_SCAN_TYPE_FRAGMENTED;
239
240 /* In case of DCM with P2P GO set all scan requests as
241 * fast-balance scan
242 */
243 if (vif->type == NL80211_IFTYPE_STATION &&
244 data->is_dcm_with_p2p_go)
245 return IWL_SCAN_TYPE_FAST_BALANCE;
246
247 if (load >= IWL_MLD_TRAFFIC_MEDIUM || data->global_low_latency)
248 return IWL_SCAN_TYPE_MILD;
249
250 return IWL_SCAN_TYPE_WILD;
251 }
252
253 static u8 *
iwl_mld_scan_add_2ghz_elems(struct iwl_mld * mld,const u8 * ies,size_t len,u8 * const pos)254 iwl_mld_scan_add_2ghz_elems(struct iwl_mld *mld, const u8 *ies,
255 size_t len, u8 *const pos)
256 {
257 static const u8 before_ds_params[] = {
258 WLAN_EID_SSID,
259 WLAN_EID_SUPP_RATES,
260 WLAN_EID_REQUEST,
261 WLAN_EID_EXT_SUPP_RATES,
262 };
263 size_t offs;
264 u8 *newpos = pos;
265
266 offs = ieee80211_ie_split(ies, len,
267 before_ds_params,
268 ARRAY_SIZE(before_ds_params),
269 0);
270
271 memcpy(newpos, ies, offs);
272 newpos += offs;
273
274 /* Add a placeholder for DS Parameter Set element */
275 *newpos++ = WLAN_EID_DS_PARAMS;
276 *newpos++ = 1;
277 *newpos++ = 0;
278
279 memcpy(newpos, ies + offs, len - offs);
280 newpos += len - offs;
281
282 return newpos;
283 }
284
285 static void
iwl_mld_scan_add_tpc_report_elem(u8 * pos)286 iwl_mld_scan_add_tpc_report_elem(u8 *pos)
287 {
288 pos[0] = WLAN_EID_VENDOR_SPECIFIC;
289 pos[1] = WFA_TPC_IE_LEN - 2;
290 pos[2] = (WLAN_OUI_MICROSOFT >> 16) & 0xff;
291 pos[3] = (WLAN_OUI_MICROSOFT >> 8) & 0xff;
292 pos[4] = WLAN_OUI_MICROSOFT & 0xff;
293 pos[5] = WLAN_OUI_TYPE_MICROSOFT_TPC;
294 pos[6] = 0;
295 /* pos[7] - tx power will be inserted by the FW */
296 pos[7] = 0;
297 pos[8] = 0;
298 }
299
300 static u32
iwl_mld_scan_ooc_priority(enum iwl_mld_scan_status scan_status)301 iwl_mld_scan_ooc_priority(enum iwl_mld_scan_status scan_status)
302 {
303 if (scan_status == IWL_MLD_SCAN_REGULAR)
304 return IWL_SCAN_PRIORITY_EXT_6;
305 if (scan_status == IWL_MLD_SCAN_INT_MLO)
306 return IWL_SCAN_PRIORITY_EXT_4;
307
308 return IWL_SCAN_PRIORITY_EXT_2;
309 }
310
311 static bool
iwl_mld_scan_is_regular(struct iwl_mld_scan_params * params)312 iwl_mld_scan_is_regular(struct iwl_mld_scan_params *params)
313 {
314 return params->n_scan_plans == 1 &&
315 params->scan_plans[0].iterations == 1;
316 }
317
318 static bool
iwl_mld_scan_is_fragmented(enum iwl_mld_scan_type type)319 iwl_mld_scan_is_fragmented(enum iwl_mld_scan_type type)
320 {
321 return (type == IWL_SCAN_TYPE_FRAGMENTED ||
322 type == IWL_SCAN_TYPE_FAST_BALANCE);
323 }
324
325 static int
iwl_mld_scan_uid_by_status(struct iwl_mld * mld,int status)326 iwl_mld_scan_uid_by_status(struct iwl_mld *mld, int status)
327 {
328 for (int i = 0; i < ARRAY_SIZE(mld->scan.uid_status); i++)
329 if (mld->scan.uid_status[i] == status)
330 return i;
331
332 return -ENOENT;
333 }
334
335 static const char *
iwl_mld_scan_ebs_status_str(enum iwl_scan_ebs_status status)336 iwl_mld_scan_ebs_status_str(enum iwl_scan_ebs_status status)
337 {
338 switch (status) {
339 case IWL_SCAN_EBS_SUCCESS:
340 return "successful";
341 case IWL_SCAN_EBS_INACTIVE:
342 return "inactive";
343 case IWL_SCAN_EBS_FAILED:
344 case IWL_SCAN_EBS_CHAN_NOT_FOUND:
345 default:
346 return "failed";
347 }
348 }
349
350 static int
iwl_mld_scan_ssid_exist(u8 * ssid,u8 ssid_len,struct iwl_ssid_ie * ssid_list)351 iwl_mld_scan_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
352 {
353 for (int i = 0; i < PROBE_OPTION_MAX; i++) {
354 if (!ssid_list[i].len)
355 return -1;
356 if (ssid_list[i].len == ssid_len &&
357 !memcmp(ssid_list[i].ssid, ssid, ssid_len))
358 return i;
359 }
360
361 return -1;
362 }
363
364 static bool
iwl_mld_scan_fits(struct iwl_mld * mld,int n_ssids,struct ieee80211_scan_ies * ies,int n_channels)365 iwl_mld_scan_fits(struct iwl_mld *mld, int n_ssids,
366 struct ieee80211_scan_ies *ies, int n_channels)
367 {
368 return ((n_ssids <= PROBE_OPTION_MAX) &&
369 (n_channels <= mld->fw->ucode_capa.n_scan_channels) &&
370 (ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] +
371 ies->len[NL80211_BAND_5GHZ] + ies->len[NL80211_BAND_6GHZ] <=
372 iwl_mld_scan_max_template_size()));
373 }
374
375 static void
iwl_mld_scan_build_probe_req(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_scan_ies * ies,struct iwl_mld_scan_params * params)376 iwl_mld_scan_build_probe_req(struct iwl_mld *mld, struct ieee80211_vif *vif,
377 struct ieee80211_scan_ies *ies,
378 struct iwl_mld_scan_params *params)
379 {
380 struct ieee80211_mgmt *frame = (void *)params->preq.buf;
381 u8 *pos, *newpos;
382 const u8 *mac_addr = params->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ?
383 params->mac_addr : NULL;
384
385 if (mac_addr)
386 get_random_mask_addr(frame->sa, mac_addr,
387 params->mac_addr_mask);
388 else
389 memcpy(frame->sa, vif->addr, ETH_ALEN);
390
391 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
392 eth_broadcast_addr(frame->da);
393 ether_addr_copy(frame->bssid, params->bssid);
394 frame->seq_ctrl = 0;
395
396 pos = frame->u.probe_req.variable;
397 *pos++ = WLAN_EID_SSID;
398 *pos++ = 0;
399
400 params->preq.mac_header.offset = 0;
401 params->preq.mac_header.len = cpu_to_le16(24 + 2);
402
403 /* Insert DS parameter set element on 2.4 GHz band */
404 newpos = iwl_mld_scan_add_2ghz_elems(mld,
405 ies->ies[NL80211_BAND_2GHZ],
406 ies->len[NL80211_BAND_2GHZ],
407 pos);
408 params->preq.band_data[0].offset = cpu_to_le16(pos - params->preq.buf);
409 params->preq.band_data[0].len = cpu_to_le16(newpos - pos);
410 pos = newpos;
411
412 memcpy(pos, ies->ies[NL80211_BAND_5GHZ],
413 ies->len[NL80211_BAND_5GHZ]);
414 params->preq.band_data[1].offset = cpu_to_le16(pos - params->preq.buf);
415 params->preq.band_data[1].len =
416 cpu_to_le16(ies->len[NL80211_BAND_5GHZ]);
417 pos += ies->len[NL80211_BAND_5GHZ];
418
419 memcpy(pos, ies->ies[NL80211_BAND_6GHZ],
420 ies->len[NL80211_BAND_6GHZ]);
421 params->preq.band_data[2].offset = cpu_to_le16(pos - params->preq.buf);
422 params->preq.band_data[2].len =
423 cpu_to_le16(ies->len[NL80211_BAND_6GHZ]);
424 pos += ies->len[NL80211_BAND_6GHZ];
425
426 memcpy(pos, ies->common_ies, ies->common_ie_len);
427 params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf);
428
429 iwl_mld_scan_add_tpc_report_elem(pos + ies->common_ie_len);
430 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len +
431 WFA_TPC_IE_LEN);
432 }
433
434 static u16
iwl_mld_scan_get_cmd_gen_flags(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif,enum iwl_mld_scan_status scan_status)435 iwl_mld_scan_get_cmd_gen_flags(struct iwl_mld *mld,
436 struct iwl_mld_scan_params *params,
437 struct ieee80211_vif *vif,
438 enum iwl_mld_scan_status scan_status)
439 {
440 u16 flags = 0;
441
442 /* If no direct SSIDs are provided perform a passive scan. Otherwise,
443 * if there is a single SSID which is not the broadcast SSID, assume
444 * that the scan is intended for roaming purposes and thus enable Rx on
445 * all chains to improve chances of hearing the beacons/probe responses.
446 */
447 if (params->n_ssids == 0)
448 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
449 else if (params->n_ssids == 1 && params->ssids[0].ssid_len)
450 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_USE_ALL_RX_CHAINS;
451
452 if (params->pass_all)
453 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL;
454 else
455 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_MATCH;
456
457 if (iwl_mld_scan_is_fragmented(params->type))
458 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1;
459
460 if (!iwl_mld_scan_is_regular(params))
461 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC;
462
463 if (params->iter_notif ||
464 mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_ENABLED)
465 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE;
466
467 if (scan_status == IWL_MLD_SCAN_SCHED ||
468 scan_status == IWL_MLD_SCAN_NETDETECT)
469 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_PREEMPTIVE;
470
471 if (params->flags & (NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP |
472 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE |
473 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME))
474 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_OCE;
475
476 if ((scan_status == IWL_MLD_SCAN_SCHED ||
477 scan_status == IWL_MLD_SCAN_NETDETECT) &&
478 params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ)
479 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN;
480
481 if (scan_status == IWL_MLD_SCAN_INT_MLO)
482 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_NTF_START;
483
484 if (params->enable_6ghz_passive)
485 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN;
486
487 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL;
488
489 return flags;
490 }
491
492 static u8
iwl_mld_scan_get_cmd_gen_flags2(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif,enum iwl_mld_scan_status scan_status,u16 gen_flags)493 iwl_mld_scan_get_cmd_gen_flags2(struct iwl_mld *mld,
494 struct iwl_mld_scan_params *params,
495 struct ieee80211_vif *vif,
496 enum iwl_mld_scan_status scan_status,
497 u16 gen_flags)
498 {
499 u8 flags = 0;
500
501 /* TODO: CDB */
502 if (params->respect_p2p_go)
503 flags |= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB |
504 IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB;
505
506 if (params->scan_6ghz)
507 flags |= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_DONT_TOGGLE_ANT;
508
509 /* For AP interfaces, request survey data for regular scans and if
510 * it is supported. For non-AP interfaces, EBS will be enabled and
511 * the results may be missing information for some channels.
512 */
513 if (scan_status == IWL_MLD_SCAN_REGULAR &&
514 ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_AP &&
515 gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE)
516 flags |= IWL_UMAC_SCAN_GEN_FLAGS2_COLLECT_CHANNEL_STATS;
517
518 return flags;
519 }
520
521 static void
iwl_mld_scan_cmd_set_dwell(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct iwl_scan_req_params_ptrs * scan_ptrs)522 iwl_mld_scan_cmd_set_dwell(struct iwl_mld *mld,
523 struct iwl_mld_scan_params *params,
524 struct iwl_scan_req_params_ptrs *scan_ptrs)
525 {
526 struct iwl_scan_general_params_v11 *gp = scan_ptrs->general_params;
527 const struct iwl_mld_scan_timing_params *timing =
528 &scan_timing[params->type];
529
530 gp->adwell_default_social_chn =
531 IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
532 gp->adwell_default_2g = IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
533 gp->adwell_default_5g = IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;
534
535 if (params->n_ssids && params->ssids[0].ssid_len)
536 gp->adwell_max_budget =
537 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
538 else
539 gp->adwell_max_budget =
540 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
541
542 gp->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
543
544 gp->max_out_of_time[SCAN_LB_LMAC_IDX] = cpu_to_le32(timing->max_out_time);
545 gp->suspend_time[SCAN_LB_LMAC_IDX] = cpu_to_le32(timing->suspend_time);
546
547 gp->active_dwell[SCAN_LB_LMAC_IDX] = IWL_SCAN_DWELL_ACTIVE;
548 gp->passive_dwell[SCAN_LB_LMAC_IDX] = IWL_SCAN_DWELL_PASSIVE;
549 gp->active_dwell[SCAN_HB_LMAC_IDX] = IWL_SCAN_DWELL_ACTIVE;
550 gp->passive_dwell[SCAN_HB_LMAC_IDX] = IWL_SCAN_DWELL_PASSIVE;
551
552 IWL_DEBUG_SCAN(mld,
553 "Scan: adwell_max_budget=%d max_out_of_time=%d suspend_time=%d\n",
554 gp->adwell_max_budget,
555 gp->max_out_of_time[SCAN_LB_LMAC_IDX],
556 gp->suspend_time[SCAN_LB_LMAC_IDX]);
557 }
558
559 static void
iwl_mld_scan_cmd_set_gen_params(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif,struct iwl_scan_req_params_ptrs * scan_ptrs,enum iwl_mld_scan_status scan_status)560 iwl_mld_scan_cmd_set_gen_params(struct iwl_mld *mld,
561 struct iwl_mld_scan_params *params,
562 struct ieee80211_vif *vif,
563 struct iwl_scan_req_params_ptrs *scan_ptrs,
564 enum iwl_mld_scan_status scan_status)
565 {
566 struct iwl_scan_general_params_v11 *gp = scan_ptrs->general_params;
567 u16 gen_flags = iwl_mld_scan_get_cmd_gen_flags(mld, params, vif,
568 scan_status);
569 u8 gen_flags2 = iwl_mld_scan_get_cmd_gen_flags2(mld, params, vif,
570 scan_status,
571 gen_flags);
572
573 IWL_DEBUG_SCAN(mld, "General: flags=0x%x, flags2=0x%x\n",
574 gen_flags, gen_flags2);
575
576 gp->flags = cpu_to_le16(gen_flags);
577 gp->flags2 = gen_flags2;
578
579 iwl_mld_scan_cmd_set_dwell(mld, params, scan_ptrs);
580
581 if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
582 gp->num_of_fragments[SCAN_LB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
583
584 if (params->fw_link_id != IWL_MLD_INVALID_FW_ID)
585 gp->scan_start_mac_or_link_id = params->fw_link_id;
586 }
587
588 static int
iwl_mld_scan_cmd_set_sched_params(struct iwl_mld_scan_params * params,struct iwl_scan_req_params_ptrs * scan_ptrs)589 iwl_mld_scan_cmd_set_sched_params(struct iwl_mld_scan_params *params,
590 struct iwl_scan_req_params_ptrs *scan_ptrs)
591 {
592 struct iwl_scan_umac_schedule *schedule =
593 scan_ptrs->periodic_params->schedule;
594 __le16 *delay = &scan_ptrs->periodic_params->delay;
595
596 if (WARN_ON(!params->n_scan_plans ||
597 params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
598 return -EINVAL;
599
600 for (int i = 0; i < params->n_scan_plans; i++) {
601 struct cfg80211_sched_scan_plan *scan_plan =
602 ¶ms->scan_plans[i];
603
604 schedule[i].iter_count = scan_plan->iterations;
605 schedule[i].interval =
606 cpu_to_le16(scan_plan->interval);
607 }
608
609 /* If the number of iterations of the last scan plan is set to zero,
610 * it should run infinitely. However, this is not always the case.
611 * For example, when regular scan is requested the driver sets one scan
612 * plan with one iteration.
613 */
614 if (!schedule[params->n_scan_plans - 1].iter_count)
615 schedule[params->n_scan_plans - 1].iter_count = 0xff;
616
617 *delay = cpu_to_le16(params->delay);
618
619 return 0;
620 }
621
622 /* We insert the SSIDs in an inverted order, because the FW will
623 * invert it back.
624 */
625 static void
iwl_mld_scan_cmd_build_ssids(struct iwl_mld_scan_params * params,struct iwl_ssid_ie * ssids,u32 * ssid_bitmap)626 iwl_mld_scan_cmd_build_ssids(struct iwl_mld_scan_params *params,
627 struct iwl_ssid_ie *ssids, u32 *ssid_bitmap)
628 {
629 int i, j;
630 int index;
631 u32 tmp_bitmap = 0;
632
633 /* copy SSIDs from match list. iwl_config_sched_scan_profiles()
634 * uses the order of these ssids to config match list.
635 */
636 for (i = 0, j = params->n_match_sets - 1;
637 j >= 0 && i < PROBE_OPTION_MAX;
638 i++, j--) {
639 /* skip empty SSID match_sets */
640 if (!params->match_sets[j].ssid.ssid_len)
641 continue;
642
643 ssids[i].id = WLAN_EID_SSID;
644 ssids[i].len = params->match_sets[j].ssid.ssid_len;
645 memcpy(ssids[i].ssid, params->match_sets[j].ssid.ssid,
646 ssids[i].len);
647 }
648
649 /* add SSIDs from scan SSID list */
650 for (j = params->n_ssids - 1;
651 j >= 0 && i < PROBE_OPTION_MAX;
652 i++, j--) {
653 index = iwl_mld_scan_ssid_exist(params->ssids[j].ssid,
654 params->ssids[j].ssid_len,
655 ssids);
656 if (index < 0) {
657 ssids[i].id = WLAN_EID_SSID;
658 ssids[i].len = params->ssids[j].ssid_len;
659 memcpy(ssids[i].ssid, params->ssids[j].ssid,
660 ssids[i].len);
661 tmp_bitmap |= BIT(i);
662 } else {
663 tmp_bitmap |= BIT(index);
664 }
665 }
666
667 if (ssid_bitmap)
668 *ssid_bitmap = tmp_bitmap;
669 }
670
671 static void
iwl_mld_scan_fill_6g_chan_list(struct iwl_mld_scan_params * params,struct iwl_scan_req_params_ptrs * scan_ptrs)672 iwl_mld_scan_fill_6g_chan_list(struct iwl_mld_scan_params *params,
673 struct iwl_scan_req_params_ptrs *scan_ptrs)
674 {
675 int j, idex_s = 0, idex_b = 0;
676 struct cfg80211_scan_6ghz_params *scan_6ghz_params =
677 params->scan_6ghz_params;
678 struct iwl_scan_probe_params_v4 *pp = scan_ptrs->probe_params;
679
680 for (j = 0;
681 j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE;
682 j++) {
683 if (!params->ssids[j].ssid_len)
684 continue;
685
686 pp->short_ssid[idex_s] =
687 cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
688 params->ssids[j].ssid_len));
689
690 /* hidden 6ghz scan */
691 pp->direct_scan[idex_s].id = WLAN_EID_SSID;
692 pp->direct_scan[idex_s].len = params->ssids[j].ssid_len;
693 memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid,
694 params->ssids[j].ssid_len);
695 idex_s++;
696 }
697
698 /* Populate the arrays of the short SSIDs and the BSSIDs using the 6GHz
699 * collocated parameters. This might not be optimal, as this processing
700 * does not (yet) correspond to the actual channels, so it is possible
701 * that some entries would be left out.
702 */
703 for (j = 0; j < params->n_6ghz_params; j++) {
704 int k;
705
706 /* First, try to place the short SSID */
707 if (scan_6ghz_params[j].short_ssid_valid) {
708 for (k = 0; k < idex_s; k++) {
709 if (pp->short_ssid[k] ==
710 cpu_to_le32(scan_6ghz_params[j].short_ssid))
711 break;
712 }
713
714 if (k == idex_s && idex_s < SCAN_SHORT_SSID_MAX_SIZE) {
715 pp->short_ssid[idex_s++] =
716 cpu_to_le32(scan_6ghz_params[j].short_ssid);
717 }
718 }
719
720 /* try to place BSSID for the same entry */
721 for (k = 0; k < idex_b; k++) {
722 if (!memcmp(&pp->bssid_array[k],
723 scan_6ghz_params[j].bssid, ETH_ALEN))
724 break;
725 }
726
727 if (k == idex_b && idex_b < SCAN_BSSID_MAX_SIZE &&
728 !WARN_ONCE(!is_valid_ether_addr(scan_6ghz_params[j].bssid),
729 "scan: invalid BSSID at index %u, index_b=%u\n",
730 j, idex_b)) {
731 memcpy(&pp->bssid_array[idex_b++],
732 scan_6ghz_params[j].bssid, ETH_ALEN);
733 }
734 }
735
736 pp->short_ssid_num = idex_s;
737 pp->bssid_num = idex_b;
738 }
739
740 static void
iwl_mld_scan_cmd_set_probe_params(struct iwl_mld_scan_params * params,struct iwl_scan_req_params_ptrs * scan_ptrs,u32 * bitmap_ssid)741 iwl_mld_scan_cmd_set_probe_params(struct iwl_mld_scan_params *params,
742 struct iwl_scan_req_params_ptrs *scan_ptrs,
743 u32 *bitmap_ssid)
744 {
745 struct iwl_scan_probe_params_v4 *pp = scan_ptrs->probe_params;
746
747 pp->preq = params->preq;
748
749 if (params->scan_6ghz) {
750 iwl_mld_scan_fill_6g_chan_list(params, scan_ptrs);
751 return;
752 }
753
754 /* relevant only for 2.4 GHz /5 GHz scan */
755 iwl_mld_scan_cmd_build_ssids(params, pp->direct_scan, bitmap_ssid);
756 }
757
758 static bool
iwl_mld_scan_use_ebs(struct iwl_mld * mld,struct ieee80211_vif * vif,bool low_latency)759 iwl_mld_scan_use_ebs(struct iwl_mld *mld, struct ieee80211_vif *vif,
760 bool low_latency)
761 {
762 const struct iwl_ucode_capabilities *capa = &mld->fw->ucode_capa;
763
764 /* We can only use EBS if:
765 * 1. the feature is supported.
766 * 2. the last EBS was successful.
767 * 3. it's not a p2p find operation.
768 * 4. we are not in low latency mode,
769 * or if fragmented ebs is supported by the FW
770 * 5. the VIF is not an AP interface (scan wants survey results)
771 */
772 return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
773 !mld->scan.last_ebs_failed &&
774 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
775 (!low_latency || fw_has_api(capa, IWL_UCODE_TLV_API_FRAG_EBS)) &&
776 ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_AP);
777 }
778
779 static u8
iwl_mld_scan_cmd_set_chan_flags(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif,bool low_latency)780 iwl_mld_scan_cmd_set_chan_flags(struct iwl_mld *mld,
781 struct iwl_mld_scan_params *params,
782 struct ieee80211_vif *vif,
783 bool low_latency)
784 {
785 u8 flags = 0;
786
787 flags |= IWL_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
788
789 if (iwl_mld_scan_use_ebs(mld, vif, low_latency))
790 flags |= IWL_SCAN_CHANNEL_FLAG_EBS |
791 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
792 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
793
794 /* set fragmented ebs for fragmented scan */
795 if (iwl_mld_scan_is_fragmented(params->type))
796 flags |= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG;
797
798 /* Force EBS in case the scan is a fragmented and there is a need
799 * to take P2P GO operation into consideration during scan operation.
800 */
801 /* TODO: CDB */
802 if (iwl_mld_scan_is_fragmented(params->type) &&
803 params->respect_p2p_go) {
804 IWL_DEBUG_SCAN(mld, "Respect P2P GO. Force EBS\n");
805 flags |= IWL_SCAN_CHANNEL_FLAG_FORCE_EBS;
806 }
807
808 return flags;
809 }
810
811 static const u8 p2p_go_friendly_chs[] = {
812 36, 40, 44, 48, 149, 153, 157, 161, 165,
813 };
814
815 static const u8 social_chs[] = {
816 1, 6, 11
817 };
818
iwl_mld_scan_ch_n_aps_flag(enum nl80211_iftype vif_type,u8 ch_id)819 static u32 iwl_mld_scan_ch_n_aps_flag(enum nl80211_iftype vif_type, u8 ch_id)
820 {
821 if (vif_type != NL80211_IFTYPE_P2P_DEVICE)
822 return 0;
823
824 for (int i = 0; i < ARRAY_SIZE(p2p_go_friendly_chs); i++) {
825 if (ch_id == p2p_go_friendly_chs[i])
826 return IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT;
827 }
828
829 for (int i = 0; i < ARRAY_SIZE(social_chs); i++) {
830 if (ch_id == social_chs[i])
831 return IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT;
832 }
833
834 return 0;
835 }
836
837 static void
iwl_mld_scan_cmd_set_channels(struct iwl_mld * mld,struct ieee80211_channel ** channels,struct iwl_scan_req_params_ptrs * scan_ptrs,int n_channels,u32 flags,enum nl80211_iftype vif_type)838 iwl_mld_scan_cmd_set_channels(struct iwl_mld *mld,
839 struct ieee80211_channel **channels,
840 struct iwl_scan_req_params_ptrs *scan_ptrs,
841 int n_channels, u32 flags,
842 enum nl80211_iftype vif_type)
843 {
844 struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
845
846 for (int i = 0; i < n_channels; i++) {
847 enum nl80211_band band = channels[i]->band;
848 struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i];
849 u8 iwl_band = iwl_mld_nl80211_band_to_fw(band);
850 u32 n_aps_flag =
851 iwl_mld_scan_ch_n_aps_flag(vif_type,
852 channels[i]->hw_value);
853
854 if (IWL_MLD_ADAPTIVE_DWELL_NUM_APS_OVERRIDE)
855 n_aps_flag = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT;
856
857 cfg->flags = cpu_to_le32(flags | n_aps_flag);
858 cfg->channel_num = channels[i]->hw_value;
859 if (cfg80211_channel_is_psc(channels[i]))
860 cfg->flags = 0;
861
862 if (band == NL80211_BAND_6GHZ) {
863 /* 6 GHz channels should only appear in a scan request
864 * that has scan_6ghz set. The only exception is MLO
865 * scan, which has to be passive.
866 */
867 WARN_ON_ONCE(cfg->flags != 0);
868 cfg->flags =
869 cpu_to_le32(IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE);
870 }
871
872 cfg->v2.iter_count = 1;
873 cfg->v2.iter_interval = 0;
874 cfg->flags |= cpu_to_le32(iwl_band <<
875 IWL_CHAN_CFG_FLAGS_BAND_POS);
876 }
877 }
878
879 static u8
iwl_mld_scan_cfg_channels_6g(struct iwl_mld * mld,struct iwl_mld_scan_params * params,u32 n_channels,struct iwl_scan_req_params_ptrs * scan_ptrs,enum nl80211_iftype vif_type)880 iwl_mld_scan_cfg_channels_6g(struct iwl_mld *mld,
881 struct iwl_mld_scan_params *params,
882 u32 n_channels,
883 struct iwl_scan_req_params_ptrs *scan_ptrs,
884 enum nl80211_iftype vif_type)
885 {
886 struct iwl_scan_probe_params_v4 *pp = scan_ptrs->probe_params;
887 struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
888 struct cfg80211_scan_6ghz_params *scan_6ghz_params =
889 params->scan_6ghz_params;
890 u32 i;
891 u8 ch_cnt;
892
893 for (i = 0, ch_cnt = 0; i < params->n_channels; i++) {
894 struct iwl_scan_channel_cfg_umac *cfg =
895 &cp->channel_config[ch_cnt];
896
897 u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0;
898 u8 k, n_s_ssids = 0, n_bssids = 0;
899 u8 max_s_ssids, max_bssids;
900 bool force_passive = false, found = false, allow_passive = true,
901 unsolicited_probe_on_chan = false, psc_no_listen = false;
902 s8 psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;
903
904 /* Avoid performing passive scan on non PSC channels unless the
905 * scan is specifically a passive scan, i.e., no SSIDs
906 * configured in the scan command.
907 */
908 if (!cfg80211_channel_is_psc(params->channels[i]) &&
909 !params->n_6ghz_params && params->n_ssids)
910 continue;
911
912 cfg->channel_num = params->channels[i]->hw_value;
913 cfg->flags |=
914 cpu_to_le32(PHY_BAND_6 << IWL_CHAN_CFG_FLAGS_BAND_POS);
915
916 cfg->v5.iter_count = 1;
917 cfg->v5.iter_interval = 0;
918
919 for (u32 j = 0; j < params->n_6ghz_params; j++) {
920 s8 tmp_psd_20;
921
922 if (!(scan_6ghz_params[j].channel_idx == i))
923 continue;
924
925 unsolicited_probe_on_chan |=
926 scan_6ghz_params[j].unsolicited_probe;
927
928 /* Use the highest PSD value allowed as advertised by
929 * APs for this channel
930 */
931 tmp_psd_20 = scan_6ghz_params[j].psd_20;
932 if (tmp_psd_20 !=
933 IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED &&
934 (psd_20 ==
935 IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED ||
936 psd_20 < tmp_psd_20))
937 psd_20 = tmp_psd_20;
938
939 psc_no_listen |= scan_6ghz_params[j].psc_no_listen;
940 }
941
942 /* In the following cases apply passive scan:
943 * 1. Non fragmented scan:
944 * - PSC channel with NO_LISTEN_FLAG on should be treated
945 * like non PSC channel
946 * - Non PSC channel with more than 3 short SSIDs or more
947 * than 9 BSSIDs.
948 * - Non PSC Channel with unsolicited probe response and
949 * more than 2 short SSIDs or more than 6 BSSIDs.
950 * - PSC channel with more than 2 short SSIDs or more than
951 * 6 BSSIDs.
952 * 2. Fragmented scan:
953 * - PSC channel with more than 1 SSID or 3 BSSIDs.
954 * - Non PSC channel with more than 2 SSIDs or 6 BSSIDs.
955 * - Non PSC channel with unsolicited probe response and
956 * more than 1 SSID or more than 3 BSSIDs.
957 */
958 if (!iwl_mld_scan_is_fragmented(params->type)) {
959 if (!cfg80211_channel_is_psc(params->channels[i]) ||
960 psc_no_listen) {
961 if (unsolicited_probe_on_chan) {
962 max_s_ssids = 2;
963 max_bssids = 6;
964 } else {
965 max_s_ssids = 3;
966 max_bssids = 9;
967 }
968 } else {
969 max_s_ssids = 2;
970 max_bssids = 6;
971 }
972 } else if (cfg80211_channel_is_psc(params->channels[i])) {
973 max_s_ssids = 1;
974 max_bssids = 3;
975 } else {
976 if (unsolicited_probe_on_chan) {
977 max_s_ssids = 1;
978 max_bssids = 3;
979 } else {
980 max_s_ssids = 2;
981 max_bssids = 6;
982 }
983 }
984
985 /* To optimize the scan time, i.e., reduce the scan dwell time
986 * on each channel, the below logic tries to set 3 direct BSSID
987 * probe requests for each broadcast probe request with a short
988 * SSID.
989 */
990 for (u32 j = 0; j < params->n_6ghz_params; j++) {
991 if (!(scan_6ghz_params[j].channel_idx == i))
992 continue;
993
994 found = false;
995
996 for (k = 0;
997 k < pp->short_ssid_num && n_s_ssids < max_s_ssids;
998 k++) {
999 if (!scan_6ghz_params[j].unsolicited_probe &&
1000 le32_to_cpu(pp->short_ssid[k]) ==
1001 scan_6ghz_params[j].short_ssid) {
1002 /* Relevant short SSID bit set */
1003 if (s_ssid_bitmap & BIT(k)) {
1004 found = true;
1005 break;
1006 }
1007
1008 /* Prefer creating BSSID entries unless
1009 * the short SSID probe can be done in
1010 * the same channel dwell iteration.
1011 *
1012 * We also need to create a short SSID
1013 * entry for any hidden AP.
1014 */
1015 if (3 * n_s_ssids > n_bssids &&
1016 !pp->direct_scan[k].len)
1017 break;
1018
1019 /* Hidden AP, cannot do passive scan */
1020 if (pp->direct_scan[k].len)
1021 allow_passive = false;
1022
1023 s_ssid_bitmap |= BIT(k);
1024 n_s_ssids++;
1025 found = true;
1026 break;
1027 }
1028 }
1029
1030 if (found)
1031 continue;
1032
1033 for (k = 0; k < pp->bssid_num; k++) {
1034 if (memcmp(&pp->bssid_array[k],
1035 scan_6ghz_params[j].bssid,
1036 ETH_ALEN))
1037 continue;
1038
1039 if (bssid_bitmap & BIT(k))
1040 break;
1041
1042 if (n_bssids < max_bssids) {
1043 bssid_bitmap |= BIT(k);
1044 n_bssids++;
1045 } else {
1046 force_passive = TRUE;
1047 }
1048
1049 break;
1050 }
1051 }
1052
1053 if (cfg80211_channel_is_psc(params->channels[i]) &&
1054 psc_no_listen)
1055 flags |= IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN;
1056
1057 if (unsolicited_probe_on_chan)
1058 flags |= IWL_UHB_CHAN_CFG_FLAG_UNSOLICITED_PROBE_RES;
1059
1060 if ((allow_passive && force_passive) ||
1061 (!(bssid_bitmap | s_ssid_bitmap) &&
1062 !cfg80211_channel_is_psc(params->channels[i])))
1063 flags |= IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE;
1064 else
1065 flags |= bssid_bitmap | (s_ssid_bitmap << 16);
1066
1067 cfg->flags |= cpu_to_le32(flags);
1068 cfg->v5.psd_20 = psd_20;
1069
1070 ch_cnt++;
1071 }
1072
1073 if (params->n_channels > ch_cnt)
1074 IWL_DEBUG_SCAN(mld,
1075 "6GHz: reducing number channels: (%u->%u)\n",
1076 params->n_channels, ch_cnt);
1077
1078 return ch_cnt;
1079 }
1080
1081 static int
iwl_mld_scan_cmd_set_6ghz_chan_params(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif,struct iwl_scan_req_params_ptrs * scan_ptrs)1082 iwl_mld_scan_cmd_set_6ghz_chan_params(struct iwl_mld *mld,
1083 struct iwl_mld_scan_params *params,
1084 struct ieee80211_vif *vif,
1085 struct iwl_scan_req_params_ptrs *scan_ptrs)
1086 {
1087 struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
1088
1089 /* Explicitly clear the flags since most of them are not
1090 * relevant for 6 GHz scan.
1091 */
1092 cp->flags = 0;
1093 cp->count = iwl_mld_scan_cfg_channels_6g(mld, params,
1094 params->n_channels,
1095 scan_ptrs, vif->type);
1096 if (!cp->count)
1097 return -EINVAL;
1098
1099 if (!params->n_ssids ||
1100 (params->n_ssids == 1 && !params->ssids[0].ssid_len))
1101 cp->flags |= IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER;
1102
1103 return 0;
1104 }
1105
1106 static int
iwl_mld_scan_cmd_set_chan_params(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif,struct iwl_scan_req_params_ptrs * scan_ptrs,bool low_latency,enum iwl_mld_scan_status scan_status,u32 channel_cfg_flags)1107 iwl_mld_scan_cmd_set_chan_params(struct iwl_mld *mld,
1108 struct iwl_mld_scan_params *params,
1109 struct ieee80211_vif *vif,
1110 struct iwl_scan_req_params_ptrs *scan_ptrs,
1111 bool low_latency,
1112 enum iwl_mld_scan_status scan_status,
1113 u32 channel_cfg_flags)
1114 {
1115 struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
1116 struct ieee80211_supported_band *sband =
1117 &mld->nvm_data->bands[NL80211_BAND_6GHZ];
1118
1119 cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
1120 cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
1121
1122 if (IWL_MLD_ADAPTIVE_DWELL_NUM_APS_OVERRIDE)
1123 cp->n_aps_override[0] = IWL_MLD_ADAPTIVE_DWELL_NUM_APS_OVERRIDE;
1124
1125 if (params->scan_6ghz)
1126 return iwl_mld_scan_cmd_set_6ghz_chan_params(mld, params,
1127 vif, scan_ptrs);
1128
1129 /* relevant only for 2.4 GHz/5 GHz scan */
1130 cp->flags = iwl_mld_scan_cmd_set_chan_flags(mld, params, vif,
1131 low_latency);
1132 cp->count = params->n_channels;
1133
1134 iwl_mld_scan_cmd_set_channels(mld, params->channels, scan_ptrs,
1135 params->n_channels, channel_cfg_flags,
1136 vif->type);
1137
1138 if (!params->enable_6ghz_passive)
1139 return 0;
1140
1141 /* fill 6 GHz passive scan cfg */
1142 for (int i = 0; i < sband->n_channels; i++) {
1143 struct ieee80211_channel *channel =
1144 &sband->channels[i];
1145 struct iwl_scan_channel_cfg_umac *cfg =
1146 &cp->channel_config[cp->count];
1147
1148 if (!cfg80211_channel_is_psc(channel))
1149 continue;
1150
1151 cfg->channel_num = channel->hw_value;
1152 cfg->v5.iter_count = 1;
1153 cfg->v5.iter_interval = 0;
1154 cfg->v5.psd_20 =
1155 IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;
1156 cfg->flags = cpu_to_le32(PHY_BAND_6 <<
1157 IWL_CHAN_CFG_FLAGS_BAND_POS);
1158 cp->count++;
1159 }
1160
1161 return 0;
1162 }
1163
1164 struct iwl_scan_umac_handler {
1165 u8 version;
1166 int (*handler)(struct iwl_mld *mld, struct ieee80211_vif *vif,
1167 struct iwl_mld_scan_params *params,
1168 enum iwl_mld_scan_status scan_status,
1169 int uid, u32 ooc_priority, bool low_latency);
1170 };
1171
1172 #define IWL_SCAN_UMAC_HANDLER(_ver) { \
1173 .version = _ver, \
1174 .handler = iwl_mld_scan_umac_v##_ver, \
1175 }
1176
iwl_mld_scan_umac_common(struct iwl_mld * mld,struct ieee80211_vif * vif,struct iwl_mld_scan_params * params,struct iwl_scan_req_params_ptrs * scan_ptrs,enum iwl_mld_scan_status scan_status,bool low_latency)1177 static int iwl_mld_scan_umac_common(struct iwl_mld *mld,
1178 struct ieee80211_vif *vif,
1179 struct iwl_mld_scan_params *params,
1180 struct iwl_scan_req_params_ptrs *scan_ptrs,
1181 enum iwl_mld_scan_status scan_status,
1182 bool low_latency)
1183 {
1184 u32 bitmap_ssid = 0;
1185 int ret;
1186
1187 iwl_mld_scan_cmd_set_gen_params(mld, params, vif, scan_ptrs,
1188 scan_status);
1189
1190 ret = iwl_mld_scan_cmd_set_sched_params(params, scan_ptrs);
1191 if (ret)
1192 return ret;
1193
1194 iwl_mld_scan_cmd_set_probe_params(params, scan_ptrs, &bitmap_ssid);
1195
1196 return iwl_mld_scan_cmd_set_chan_params(mld, params, vif, scan_ptrs,
1197 low_latency, scan_status,
1198 bitmap_ssid);
1199 }
1200
iwl_mld_scan_umac_v18(struct iwl_mld * mld,struct ieee80211_vif * vif,struct iwl_mld_scan_params * params,enum iwl_mld_scan_status scan_status,int uid,u32 ooc_priority,bool low_latency)1201 static int iwl_mld_scan_umac_v18(struct iwl_mld *mld, struct ieee80211_vif *vif,
1202 struct iwl_mld_scan_params *params,
1203 enum iwl_mld_scan_status scan_status,
1204 int uid, u32 ooc_priority, bool low_latency)
1205 {
1206 struct iwl_scan_req_umac_v18 *cmd = mld->scan.cmd;
1207 struct iwl_scan_req_params_ptrs scan_ptrs = {
1208 .general_params = &cmd->scan_params.general_params,
1209 .probe_params = &cmd->scan_params.probe_params,
1210 .channel_params = &cmd->scan_params.channel_params,
1211 .periodic_params = &cmd->scan_params.periodic_params
1212 };
1213 int ret;
1214
1215 if (WARN_ON(params->n_channels > SCAN_MAX_NUM_CHANS_V4))
1216 return -EINVAL;
1217
1218 cmd->uid = cpu_to_le32(uid);
1219 cmd->ooc_priority = cpu_to_le32(ooc_priority);
1220
1221 ret = iwl_mld_scan_umac_common(mld, vif, params, &scan_ptrs,
1222 scan_status, low_latency);
1223 if (ret)
1224 return ret;
1225
1226 return uid;
1227 }
1228
iwl_mld_scan_umac_v17(struct iwl_mld * mld,struct ieee80211_vif * vif,struct iwl_mld_scan_params * params,enum iwl_mld_scan_status scan_status,int uid,u32 ooc_priority,bool low_latency)1229 static int iwl_mld_scan_umac_v17(struct iwl_mld *mld, struct ieee80211_vif *vif,
1230 struct iwl_mld_scan_params *params,
1231 enum iwl_mld_scan_status scan_status,
1232 int uid, u32 ooc_priority, bool low_latency)
1233 {
1234 struct iwl_scan_req_umac_v17 *cmd = mld->scan.cmd;
1235 struct iwl_scan_req_params_ptrs scan_ptrs = {
1236 .general_params = &cmd->scan_params.general_params,
1237 .probe_params = &cmd->scan_params.probe_params,
1238
1239 /* struct iwl_scan_channel_params_v8 and struct
1240 * iwl_scan_channel_params_v7 are almost identical. The only
1241 * difference is that the newer version allows configuration of
1242 * more channels. So casting here is ok as long as we ensure
1243 * that we don't exceed the max number of channels supported by
1244 * the older version (see the WARN_ON below).
1245 */
1246 .channel_params = (struct iwl_scan_channel_params_v8 *)
1247 &cmd->scan_params.channel_params,
1248 .periodic_params = &cmd->scan_params.periodic_params
1249 };
1250 int ret;
1251
1252 if (WARN_ON(params->n_channels > SCAN_MAX_NUM_CHANS_V3))
1253 return -EINVAL;
1254
1255 cmd->uid = cpu_to_le32(uid);
1256 cmd->ooc_priority = cpu_to_le32(ooc_priority);
1257
1258 ret = iwl_mld_scan_umac_common(mld, vif, params, &scan_ptrs,
1259 scan_status, low_latency);
1260 if (ret)
1261 return ret;
1262
1263 return uid;
1264 }
1265
1266 static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = {
1267 /* set the newest version first to shorten the list traverse time */
1268 IWL_SCAN_UMAC_HANDLER(18),
1269 IWL_SCAN_UMAC_HANDLER(17),
1270 };
1271
1272 static int
iwl_mld_scan_build_cmd(struct iwl_mld * mld,struct ieee80211_vif * vif,struct iwl_mld_scan_params * params,enum iwl_mld_scan_status scan_status,bool low_latency)1273 iwl_mld_scan_build_cmd(struct iwl_mld *mld, struct ieee80211_vif *vif,
1274 struct iwl_mld_scan_params *params,
1275 enum iwl_mld_scan_status scan_status,
1276 bool low_latency)
1277 {
1278 int uid, err;
1279 u32 ooc_priority;
1280
1281 memset(mld->scan.cmd, 0, mld->scan.cmd_size);
1282 uid = iwl_mld_scan_uid_by_status(mld, IWL_MLD_SCAN_NONE);
1283 if (uid < 0)
1284 return uid;
1285
1286 ooc_priority = iwl_mld_scan_ooc_priority(scan_status);
1287
1288 for (size_t i = 0; i < ARRAY_SIZE(iwl_scan_umac_handlers); i++) {
1289 const struct iwl_scan_umac_handler *ver_handler =
1290 &iwl_scan_umac_handlers[i];
1291
1292 if (ver_handler->version != mld->scan.cmd_ver)
1293 continue;
1294
1295 err = ver_handler->handler(mld, vif, params, scan_status,
1296 uid, ooc_priority, low_latency);
1297 return err ? : uid;
1298 }
1299
1300 IWL_ERR(mld, "No handler for UMAC scan cmd version %d\n",
1301 mld->scan.cmd_ver);
1302
1303 return -EINVAL;
1304 }
1305
1306 static bool
iwl_mld_scan_pass_all(struct iwl_mld * mld,struct cfg80211_sched_scan_request * req)1307 iwl_mld_scan_pass_all(struct iwl_mld *mld,
1308 struct cfg80211_sched_scan_request *req)
1309 {
1310 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
1311 IWL_DEBUG_SCAN(mld,
1312 "Sending scheduled scan with filtering, n_match_sets %d\n",
1313 req->n_match_sets);
1314 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED;
1315 return false;
1316 }
1317
1318 IWL_DEBUG_SCAN(mld, "Sending Scheduled scan without filtering\n");
1319 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_ENABLED;
1320
1321 return true;
1322 }
1323
1324 static int
iwl_mld_config_sched_scan_profiles(struct iwl_mld * mld,struct cfg80211_sched_scan_request * req)1325 iwl_mld_config_sched_scan_profiles(struct iwl_mld *mld,
1326 struct cfg80211_sched_scan_request *req)
1327 {
1328 struct iwl_host_cmd hcmd = {
1329 .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD,
1330 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1331 };
1332 struct iwl_scan_offload_profile *profile;
1333 struct iwl_scan_offload_profile_cfg_data *cfg_data;
1334 struct iwl_scan_offload_profile_cfg *profile_cfg;
1335 struct iwl_scan_offload_blocklist *blocklist;
1336 u32 blocklist_size = IWL_SCAN_MAX_BLACKLIST_LEN * sizeof(*blocklist);
1337 u32 cmd_size = blocklist_size + sizeof(*profile_cfg);
1338 u8 *cmd;
1339 int ret;
1340
1341 if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES_V2))
1342 return -EIO;
1343
1344 cmd = kzalloc(cmd_size, GFP_KERNEL);
1345 if (!cmd)
1346 return -ENOMEM;
1347
1348 hcmd.data[0] = cmd;
1349 hcmd.len[0] = cmd_size;
1350
1351 blocklist = (struct iwl_scan_offload_blocklist *)cmd;
1352 profile_cfg = (struct iwl_scan_offload_profile_cfg *)(cmd + blocklist_size);
1353
1354 /* No blocklist configuration */
1355 cfg_data = &profile_cfg->data;
1356 cfg_data->num_profiles = req->n_match_sets;
1357 cfg_data->active_clients = SCAN_CLIENT_SCHED_SCAN;
1358 cfg_data->pass_match = SCAN_CLIENT_SCHED_SCAN;
1359 cfg_data->match_notify = SCAN_CLIENT_SCHED_SCAN;
1360
1361 if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
1362 cfg_data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
1363
1364 for (int i = 0; i < req->n_match_sets; i++) {
1365 profile = &profile_cfg->profiles[i];
1366
1367 /* Support any cipher and auth algorithm */
1368 profile->unicast_cipher = 0xff;
1369 profile->auth_alg = IWL_AUTH_ALGO_UNSUPPORTED |
1370 IWL_AUTH_ALGO_NONE | IWL_AUTH_ALGO_PSK |
1371 IWL_AUTH_ALGO_8021X | IWL_AUTH_ALGO_SAE |
1372 IWL_AUTH_ALGO_8021X_SHA384 | IWL_AUTH_ALGO_OWE;
1373 profile->network_type = IWL_NETWORK_TYPE_ANY;
1374 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY;
1375 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN;
1376 profile->ssid_index = i;
1377 }
1378
1379 IWL_DEBUG_SCAN(mld,
1380 "Sending scheduled scan profile config (n_match_sets=%u)\n",
1381 req->n_match_sets);
1382
1383 ret = iwl_mld_send_cmd(mld, &hcmd);
1384
1385 kfree(cmd);
1386
1387 return ret;
1388 }
1389
1390 static int
iwl_mld_sched_scan_handle_non_psc_channels(struct iwl_mld_scan_params * params,bool * non_psc_included)1391 iwl_mld_sched_scan_handle_non_psc_channels(struct iwl_mld_scan_params *params,
1392 bool *non_psc_included)
1393 {
1394 int i, j;
1395
1396 *non_psc_included = false;
1397 /* for 6 GHZ band only PSC channels need to be added */
1398 for (i = 0; i < params->n_channels; i++) {
1399 struct ieee80211_channel *channel = params->channels[i];
1400
1401 if (channel->band == NL80211_BAND_6GHZ &&
1402 !cfg80211_channel_is_psc(channel)) {
1403 *non_psc_included = true;
1404 break;
1405 }
1406 }
1407
1408 if (!*non_psc_included)
1409 return 0;
1410
1411 params->channels =
1412 kmemdup(params->channels,
1413 sizeof(params->channels[0]) * params->n_channels,
1414 GFP_KERNEL);
1415 if (!params->channels)
1416 return -ENOMEM;
1417
1418 for (i = j = 0; i < params->n_channels; i++) {
1419 if (params->channels[i]->band == NL80211_BAND_6GHZ &&
1420 !cfg80211_channel_is_psc(params->channels[i]))
1421 continue;
1422 params->channels[j++] = params->channels[i];
1423 }
1424
1425 params->n_channels = j;
1426
1427 return 0;
1428 }
1429
1430 static void
iwl_mld_scan_6ghz_passive_scan(struct iwl_mld * mld,struct iwl_mld_scan_params * params,struct ieee80211_vif * vif)1431 iwl_mld_scan_6ghz_passive_scan(struct iwl_mld *mld,
1432 struct iwl_mld_scan_params *params,
1433 struct ieee80211_vif *vif)
1434 {
1435 struct ieee80211_supported_band *sband =
1436 &mld->nvm_data->bands[NL80211_BAND_6GHZ];
1437 u32 n_disabled, i;
1438
1439 params->enable_6ghz_passive = false;
1440
1441 /* 6 GHz passive scan may be enabled in the first 2.4 GHz/5 GHz scan
1442 * phase to discover geo location if no AP's are found. Skip it when
1443 * we're in the 6 GHz scan phase.
1444 */
1445 if (params->scan_6ghz)
1446 return;
1447
1448 /* 6 GHz passive scan allowed only on station interface */
1449 if (vif->type != NL80211_IFTYPE_STATION) {
1450 IWL_DEBUG_SCAN(mld,
1451 "6GHz passive scan: not station interface\n");
1452 return;
1453 }
1454
1455 /* 6 GHz passive scan is allowed in a defined time interval following
1456 * HW reset or resume flow, or while not associated and a large
1457 * interval has passed since the last 6 GHz passive scan.
1458 */
1459 if ((vif->cfg.assoc ||
1460 time_after(mld->scan.last_6ghz_passive_jiffies +
1461 (IWL_MLD_6GHZ_PASSIVE_SCAN_TIMEOUT * HZ), jiffies)) &&
1462 (time_before(mld->scan.last_start_time_jiffies +
1463 (IWL_MLD_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT * HZ),
1464 jiffies))) {
1465 IWL_DEBUG_SCAN(mld, "6GHz passive scan: %s\n",
1466 vif->cfg.assoc ? "associated" :
1467 "timeout did not expire");
1468 return;
1469 }
1470
1471 /* not enough channels in the regular scan request */
1472 if (params->n_channels < IWL_MLD_6GHZ_PASSIVE_SCAN_MIN_CHANS) {
1473 IWL_DEBUG_SCAN(mld,
1474 "6GHz passive scan: not enough channels %d\n",
1475 params->n_channels);
1476 return;
1477 }
1478
1479 for (i = 0; i < params->n_ssids; i++) {
1480 if (!params->ssids[i].ssid_len)
1481 break;
1482 }
1483
1484 /* not a wildcard scan, so cannot enable passive 6 GHz scan */
1485 if (i == params->n_ssids) {
1486 IWL_DEBUG_SCAN(mld,
1487 "6GHz passive scan: no wildcard SSID\n");
1488 return;
1489 }
1490
1491 if (!sband || !sband->n_channels) {
1492 IWL_DEBUG_SCAN(mld,
1493 "6GHz passive scan: no 6GHz channels\n");
1494 return;
1495 }
1496
1497 for (i = 0, n_disabled = 0; i < sband->n_channels; i++) {
1498 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED))
1499 n_disabled++;
1500 }
1501
1502 /* Not all the 6 GHz channels are disabled, so no need for 6 GHz
1503 * passive scan
1504 */
1505 if (n_disabled != sband->n_channels) {
1506 IWL_DEBUG_SCAN(mld,
1507 "6GHz passive scan: 6GHz channels enabled\n");
1508 return;
1509 }
1510
1511 /* all conditions to enable 6 GHz passive scan are satisfied */
1512 IWL_DEBUG_SCAN(mld, "6GHz passive scan: can be enabled\n");
1513 params->enable_6ghz_passive = true;
1514 }
1515
1516 static void
iwl_mld_scan_set_link_id(struct iwl_mld * mld,struct ieee80211_vif * vif,struct iwl_mld_scan_params * params,s8 tsf_report_link_id,enum iwl_mld_scan_status scan_status)1517 iwl_mld_scan_set_link_id(struct iwl_mld *mld, struct ieee80211_vif *vif,
1518 struct iwl_mld_scan_params *params,
1519 s8 tsf_report_link_id,
1520 enum iwl_mld_scan_status scan_status)
1521 {
1522 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
1523 struct iwl_mld_link *link;
1524
1525 if (tsf_report_link_id < 0) {
1526 if (vif->active_links)
1527 tsf_report_link_id = __ffs(vif->active_links);
1528 else
1529 tsf_report_link_id = 0;
1530 }
1531
1532 link = iwl_mld_link_dereference_check(mld_vif, tsf_report_link_id);
1533 if (!WARN_ON(!link)) {
1534 params->fw_link_id = link->fw_id;
1535 /* we to store fw_link_id only for regular scan,
1536 * and use it in scan complete notif
1537 */
1538 if (scan_status == IWL_MLD_SCAN_REGULAR)
1539 mld->scan.fw_link_id = link->fw_id;
1540 } else {
1541 mld->scan.fw_link_id = IWL_MLD_INVALID_FW_ID;
1542 params->fw_link_id = IWL_MLD_INVALID_FW_ID;
1543 }
1544 }
1545
1546 static int
_iwl_mld_single_scan_start(struct iwl_mld * mld,struct ieee80211_vif * vif,struct cfg80211_scan_request * req,struct ieee80211_scan_ies * ies,enum iwl_mld_scan_status scan_status)1547 _iwl_mld_single_scan_start(struct iwl_mld *mld, struct ieee80211_vif *vif,
1548 struct cfg80211_scan_request *req,
1549 struct ieee80211_scan_ies *ies,
1550 enum iwl_mld_scan_status scan_status)
1551 {
1552 struct iwl_host_cmd hcmd = {
1553 .id = WIDE_ID(LONG_GROUP, SCAN_REQ_UMAC),
1554 .len = { mld->scan.cmd_size, },
1555 .data = { mld->scan.cmd, },
1556 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1557 };
1558 struct iwl_mld_scan_iter_data scan_iter_data = {
1559 .current_vif = vif,
1560 };
1561 struct cfg80211_sched_scan_plan scan_plan = {.iterations = 1};
1562 struct iwl_mld_scan_params params = {};
1563 int ret, uid;
1564
1565 /* we should have failed registration if scan_cmd was NULL */
1566 if (WARN_ON(!mld->scan.cmd))
1567 return -ENOMEM;
1568
1569 if (!iwl_mld_scan_fits(mld, req->n_ssids, ies, req->n_channels))
1570 return -ENOBUFS;
1571
1572 ieee80211_iterate_active_interfaces_mtx(mld->hw,
1573 IEEE80211_IFACE_ITER_NORMAL,
1574 iwl_mld_scan_iterator,
1575 &scan_iter_data);
1576
1577 params.type = iwl_mld_get_scan_type(mld, vif, &scan_iter_data);
1578 params.n_ssids = req->n_ssids;
1579 params.flags = req->flags;
1580 params.n_channels = req->n_channels;
1581 params.delay = 0;
1582 params.ssids = req->ssids;
1583 params.channels = req->channels;
1584 params.mac_addr = req->mac_addr;
1585 params.mac_addr_mask = req->mac_addr_mask;
1586 params.no_cck = req->no_cck;
1587 params.pass_all = true;
1588 params.n_match_sets = 0;
1589 params.match_sets = NULL;
1590 params.scan_plans = &scan_plan;
1591 params.n_scan_plans = 1;
1592
1593 params.n_6ghz_params = req->n_6ghz_params;
1594 params.scan_6ghz_params = req->scan_6ghz_params;
1595 params.scan_6ghz = req->scan_6ghz;
1596
1597 ether_addr_copy(params.bssid, req->bssid);
1598 /* TODO: CDB - per-band flag */
1599 params.respect_p2p_go =
1600 iwl_mld_get_respect_p2p_go(mld, vif,
1601 scan_iter_data.global_low_latency);
1602
1603 if (req->duration)
1604 params.iter_notif = true;
1605
1606 iwl_mld_scan_set_link_id(mld, vif, ¶ms, req->tsf_report_link_id,
1607 scan_status);
1608
1609 iwl_mld_scan_build_probe_req(mld, vif, ies, ¶ms);
1610
1611 iwl_mld_scan_6ghz_passive_scan(mld, ¶ms, vif);
1612
1613 uid = iwl_mld_scan_build_cmd(mld, vif, ¶ms, scan_status,
1614 scan_iter_data.global_low_latency);
1615 if (uid < 0)
1616 return uid;
1617
1618 ret = iwl_mld_send_cmd(mld, &hcmd);
1619 if (ret) {
1620 IWL_ERR(mld, "Scan failed! ret %d\n", ret);
1621 return ret;
1622 }
1623
1624 IWL_DEBUG_SCAN(mld, "Scan request send success: status=%u, uid=%u\n",
1625 scan_status, uid);
1626
1627 mld->scan.uid_status[uid] = scan_status;
1628 mld->scan.status |= scan_status;
1629
1630 if (params.enable_6ghz_passive)
1631 mld->scan.last_6ghz_passive_jiffies = jiffies;
1632
1633 return 0;
1634 }
1635
1636 static int
iwl_mld_scan_send_abort_cmd_status(struct iwl_mld * mld,int uid,u32 * status)1637 iwl_mld_scan_send_abort_cmd_status(struct iwl_mld *mld, int uid, u32 *status)
1638 {
1639 struct iwl_umac_scan_abort abort_cmd = {
1640 .uid = cpu_to_le32(uid),
1641 };
1642 struct iwl_host_cmd cmd = {
1643 .id = WIDE_ID(LONG_GROUP, SCAN_ABORT_UMAC),
1644 .flags = CMD_WANT_SKB,
1645 .data = { &abort_cmd },
1646 .len[0] = sizeof(abort_cmd),
1647 };
1648 struct iwl_rx_packet *pkt;
1649 struct iwl_cmd_response *resp;
1650 u32 resp_len;
1651 int ret;
1652
1653 ret = iwl_mld_send_cmd(mld, &cmd);
1654 if (ret)
1655 return ret;
1656
1657 pkt = cmd.resp_pkt;
1658
1659 resp_len = iwl_rx_packet_payload_len(pkt);
1660 if (IWL_FW_CHECK(mld, resp_len != sizeof(*resp),
1661 "Scan Abort: unexpected response length %d\n",
1662 resp_len)) {
1663 ret = -EIO;
1664 goto out;
1665 }
1666
1667 resp = (void *)pkt->data;
1668 *status = le32_to_cpu(resp->status);
1669
1670 out:
1671 iwl_free_resp(&cmd);
1672 return ret;
1673 }
1674
1675 static int
iwl_mld_scan_abort(struct iwl_mld * mld,int type,int uid,bool * wait)1676 iwl_mld_scan_abort(struct iwl_mld *mld, int type, int uid, bool *wait)
1677 {
1678 enum iwl_umac_scan_abort_status status;
1679 int ret;
1680
1681 *wait = true;
1682
1683 IWL_DEBUG_SCAN(mld, "Sending scan abort, uid %u\n", uid);
1684
1685 ret = iwl_mld_scan_send_abort_cmd_status(mld, uid, &status);
1686
1687 IWL_DEBUG_SCAN(mld, "Scan abort: ret=%d status=%u\n", ret, status);
1688
1689 /* We don't need to wait to scan complete in the following cases:
1690 * 1. Driver failed to send the scan abort cmd.
1691 * 2. The FW is no longer familiar with the scan that needs to be
1692 * stopped. It is expected that the scan complete notification was
1693 * already received but not yet processed.
1694 *
1695 * In both cases the flow should continue similar to the case that the
1696 * scan was really aborted.
1697 */
1698 if (ret || status == IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND)
1699 *wait = false;
1700
1701 return ret;
1702 }
1703
1704 static int
iwl_mld_scan_stop_wait(struct iwl_mld * mld,int type,int uid)1705 iwl_mld_scan_stop_wait(struct iwl_mld *mld, int type, int uid)
1706 {
1707 struct iwl_notification_wait wait_scan_done;
1708 static const u16 scan_comp_notif[] = { SCAN_COMPLETE_UMAC };
1709 bool wait = true;
1710 int ret;
1711
1712 iwl_init_notification_wait(&mld->notif_wait, &wait_scan_done,
1713 scan_comp_notif,
1714 ARRAY_SIZE(scan_comp_notif),
1715 NULL, NULL);
1716
1717 IWL_DEBUG_SCAN(mld, "Preparing to stop scan, type=%x\n", type);
1718
1719 ret = iwl_mld_scan_abort(mld, type, uid, &wait);
1720 if (ret) {
1721 IWL_DEBUG_SCAN(mld, "couldn't stop scan type=%d\n", type);
1722 goto return_no_wait;
1723 }
1724
1725 if (!wait) {
1726 IWL_DEBUG_SCAN(mld, "no need to wait for scan type=%d\n", type);
1727 goto return_no_wait;
1728 }
1729
1730 return iwl_wait_notification(&mld->notif_wait, &wait_scan_done, HZ);
1731
1732 return_no_wait:
1733 iwl_remove_notification(&mld->notif_wait, &wait_scan_done);
1734 return ret;
1735 }
1736
iwl_mld_sched_scan_start(struct iwl_mld * mld,struct ieee80211_vif * vif,struct cfg80211_sched_scan_request * req,struct ieee80211_scan_ies * ies,int type)1737 int iwl_mld_sched_scan_start(struct iwl_mld *mld,
1738 struct ieee80211_vif *vif,
1739 struct cfg80211_sched_scan_request *req,
1740 struct ieee80211_scan_ies *ies,
1741 int type)
1742 {
1743 struct iwl_host_cmd hcmd = {
1744 .id = WIDE_ID(LONG_GROUP, SCAN_REQ_UMAC),
1745 .len = { mld->scan.cmd_size, },
1746 .data = { mld->scan.cmd, },
1747 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1748 };
1749 struct iwl_mld_scan_params params = {};
1750 struct iwl_mld_scan_iter_data scan_iter_data = {
1751 .current_vif = vif,
1752 };
1753 bool non_psc_included = false;
1754 int ret, uid;
1755
1756 /* we should have failed registration if scan_cmd was NULL */
1757 if (WARN_ON(!mld->scan.cmd))
1758 return -ENOMEM;
1759
1760 /* FW supports only a single periodic scan */
1761 if (mld->scan.status & (IWL_MLD_SCAN_SCHED | IWL_MLD_SCAN_NETDETECT))
1762 return -EBUSY;
1763
1764 ieee80211_iterate_active_interfaces_mtx(mld->hw,
1765 IEEE80211_IFACE_ITER_NORMAL,
1766 iwl_mld_scan_iterator,
1767 &scan_iter_data);
1768
1769 params.type = iwl_mld_get_scan_type(mld, vif, &scan_iter_data);
1770 params.flags = req->flags;
1771 params.n_ssids = req->n_ssids;
1772 params.ssids = req->ssids;
1773 params.n_channels = req->n_channels;
1774 params.channels = req->channels;
1775 params.mac_addr = req->mac_addr;
1776 params.mac_addr_mask = req->mac_addr_mask;
1777 params.no_cck = false;
1778 params.pass_all = iwl_mld_scan_pass_all(mld, req);
1779 params.n_match_sets = req->n_match_sets;
1780 params.match_sets = req->match_sets;
1781 params.n_scan_plans = req->n_scan_plans;
1782 params.scan_plans = req->scan_plans;
1783 /* TODO: CDB - per-band flag */
1784 params.respect_p2p_go =
1785 iwl_mld_get_respect_p2p_go(mld, vif,
1786 scan_iter_data.global_low_latency);
1787
1788 /* UMAC scan supports up to 16-bit delays, trim it down to 16-bits */
1789 params.delay = req->delay > U16_MAX ? U16_MAX : req->delay;
1790
1791 eth_broadcast_addr(params.bssid);
1792
1793 ret = iwl_mld_config_sched_scan_profiles(mld, req);
1794 if (ret)
1795 return ret;
1796
1797 iwl_mld_scan_build_probe_req(mld, vif, ies, ¶ms);
1798
1799 ret = iwl_mld_sched_scan_handle_non_psc_channels(¶ms,
1800 &non_psc_included);
1801 if (ret)
1802 goto out;
1803
1804 if (!iwl_mld_scan_fits(mld, req->n_ssids, ies, params.n_channels)) {
1805 ret = -ENOBUFS;
1806 goto out;
1807 }
1808
1809 uid = iwl_mld_scan_build_cmd(mld, vif, ¶ms, type,
1810 scan_iter_data.global_low_latency);
1811 if (uid < 0) {
1812 ret = uid;
1813 goto out;
1814 }
1815
1816 ret = iwl_mld_send_cmd(mld, &hcmd);
1817 if (!ret) {
1818 IWL_DEBUG_SCAN(mld,
1819 "Sched scan request send success: type=%u, uid=%u\n",
1820 type, uid);
1821 mld->scan.uid_status[uid] = type;
1822 mld->scan.status |= type;
1823 } else {
1824 IWL_ERR(mld, "Sched scan failed! ret %d\n", ret);
1825 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED;
1826 }
1827
1828 out:
1829 if (non_psc_included)
1830 kfree(params.channels);
1831 return ret;
1832 }
1833
iwl_mld_scan_stop(struct iwl_mld * mld,int type,bool notify)1834 int iwl_mld_scan_stop(struct iwl_mld *mld, int type, bool notify)
1835 {
1836 int uid, ret;
1837
1838 IWL_DEBUG_SCAN(mld,
1839 "Request to stop scan: type=0x%x, status=0x%x\n",
1840 type, mld->scan.status);
1841
1842 if (!(mld->scan.status & type))
1843 return 0;
1844
1845 uid = iwl_mld_scan_uid_by_status(mld, type);
1846 /* must be valid, we just checked it's running */
1847 if (WARN_ON_ONCE(uid < 0))
1848 return uid;
1849
1850 ret = iwl_mld_scan_stop_wait(mld, type, uid);
1851 if (ret)
1852 IWL_DEBUG_SCAN(mld, "Failed to stop scan\n");
1853
1854 /* Clear the scan status so the next scan requests will
1855 * succeed and mark the scan as stopping, so that the Rx
1856 * handler doesn't do anything, as the scan was stopped from
1857 * above. Also remove the handler to not notify mac80211
1858 * erroneously after a new scan starts, for example.
1859 */
1860 mld->scan.status &= ~type;
1861 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE;
1862 iwl_mld_cancel_notifications_of_object(mld, IWL_MLD_OBJECT_TYPE_SCAN,
1863 uid);
1864
1865 if (type == IWL_MLD_SCAN_REGULAR) {
1866 if (notify) {
1867 struct cfg80211_scan_info info = {
1868 .aborted = true,
1869 };
1870
1871 ieee80211_scan_completed(mld->hw, &info);
1872 }
1873 } else if (notify) {
1874 ieee80211_sched_scan_stopped(mld->hw);
1875 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED;
1876 }
1877
1878 return ret;
1879 }
1880
iwl_mld_regular_scan_start(struct iwl_mld * mld,struct ieee80211_vif * vif,struct cfg80211_scan_request * req,struct ieee80211_scan_ies * ies)1881 int iwl_mld_regular_scan_start(struct iwl_mld *mld, struct ieee80211_vif *vif,
1882 struct cfg80211_scan_request *req,
1883 struct ieee80211_scan_ies *ies)
1884 {
1885 /* Clear survey data when starting the first part of a regular scan */
1886 if (req->first_part && mld->channel_survey)
1887 memset(mld->channel_survey->channels, 0,
1888 sizeof(mld->channel_survey->channels[0]) *
1889 mld->channel_survey->n_channels);
1890
1891 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
1892 iwl_mld_emlsr_block_tmp_non_bss(mld);
1893
1894 return _iwl_mld_single_scan_start(mld, vif, req, ies,
1895 IWL_MLD_SCAN_REGULAR);
1896 }
1897
iwl_mld_int_mlo_scan_start(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_channel ** channels,size_t n_channels)1898 static void iwl_mld_int_mlo_scan_start(struct iwl_mld *mld,
1899 struct ieee80211_vif *vif,
1900 struct ieee80211_channel **channels,
1901 size_t n_channels)
1902 {
1903 struct cfg80211_scan_request *req __free(kfree) = NULL;
1904 struct ieee80211_scan_ies ies = {};
1905 size_t size;
1906 int ret;
1907
1908 IWL_DEBUG_SCAN(mld, "Starting Internal MLO scan: n_channels=%zu\n",
1909 n_channels);
1910
1911 size = struct_size(req, channels, n_channels);
1912 req = kzalloc(size, GFP_KERNEL);
1913 if (!req)
1914 return;
1915
1916 /* set the requested channels */
1917 for (int i = 0; i < n_channels; i++)
1918 req->channels[i] = channels[i];
1919
1920 req->n_channels = n_channels;
1921
1922 /* set the rates */
1923 for (int i = 0; i < NUM_NL80211_BANDS; i++)
1924 if (mld->wiphy->bands[i])
1925 req->rates[i] =
1926 (1 << mld->wiphy->bands[i]->n_bitrates) - 1;
1927
1928 req->wdev = ieee80211_vif_to_wdev(vif);
1929 req->wiphy = mld->wiphy;
1930 req->scan_start = jiffies;
1931 req->tsf_report_link_id = -1;
1932
1933 ret = _iwl_mld_single_scan_start(mld, vif, req, &ies,
1934 IWL_MLD_SCAN_INT_MLO);
1935
1936 IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret);
1937 }
1938
1939 #define IWL_MLD_MLO_SCAN_BLOCKOUT_TIME 5 /* seconds */
1940
iwl_mld_int_mlo_scan(struct iwl_mld * mld,struct ieee80211_vif * vif)1941 void iwl_mld_int_mlo_scan(struct iwl_mld *mld, struct ieee80211_vif *vif)
1942 {
1943 struct ieee80211_channel *channels[IEEE80211_MLD_MAX_NUM_LINKS];
1944 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
1945 unsigned long usable_links = ieee80211_vif_usable_links(vif);
1946 size_t n_channels = 0;
1947 u8 link_id;
1948
1949 lockdep_assert_wiphy(mld->wiphy);
1950
1951 if (!IWL_MLD_AUTO_EML_ENABLE || !vif->cfg.assoc ||
1952 !ieee80211_vif_is_mld(vif) || hweight16(vif->valid_links) == 1)
1953 return;
1954
1955 if (mld->scan.status & IWL_MLD_SCAN_INT_MLO) {
1956 IWL_DEBUG_SCAN(mld, "Internal MLO scan is already running\n");
1957 return;
1958 }
1959
1960 if (mld_vif->last_link_activation_time > ktime_get_boottime_seconds() -
1961 IWL_MLD_MLO_SCAN_BLOCKOUT_TIME) {
1962 /* timing doesn't matter much, so use the blockout time */
1963 wiphy_delayed_work_queue(mld->wiphy,
1964 &mld_vif->mlo_scan_start_wk,
1965 IWL_MLD_MLO_SCAN_BLOCKOUT_TIME);
1966 return;
1967 }
1968
1969 for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) {
1970 struct ieee80211_bss_conf *link_conf =
1971 link_conf_dereference_check(vif, link_id);
1972
1973 if (WARN_ON_ONCE(!link_conf))
1974 continue;
1975
1976 channels[n_channels++] = link_conf->chanreq.oper.chan;
1977 }
1978
1979 if (!n_channels)
1980 return;
1981
1982 iwl_mld_int_mlo_scan_start(mld, vif, channels, n_channels);
1983 }
1984
iwl_mld_handle_scan_iter_complete_notif(struct iwl_mld * mld,struct iwl_rx_packet * pkt)1985 void iwl_mld_handle_scan_iter_complete_notif(struct iwl_mld *mld,
1986 struct iwl_rx_packet *pkt)
1987 {
1988 struct iwl_umac_scan_iter_complete_notif *notif = (void *)pkt->data;
1989 u32 uid = __le32_to_cpu(notif->uid);
1990
1991 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status),
1992 "FW reports out-of-range scan UID %d\n", uid))
1993 return;
1994
1995 if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_REGULAR)
1996 mld->scan.start_tsf = le64_to_cpu(notif->start_tsf);
1997
1998 IWL_DEBUG_SCAN(mld,
1999 "UMAC Scan iteration complete: status=0x%x scanned_channels=%d\n",
2000 notif->status, notif->scanned_channels);
2001
2002 if (mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_FOUND) {
2003 IWL_DEBUG_SCAN(mld, "Pass all scheduled scan results found\n");
2004 ieee80211_sched_scan_results(mld->hw);
2005 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_ENABLED;
2006 }
2007
2008 IWL_DEBUG_SCAN(mld,
2009 "UMAC Scan iteration complete: scan started at %llu (TSF)\n",
2010 le64_to_cpu(notif->start_tsf));
2011 }
2012
iwl_mld_handle_match_found_notif(struct iwl_mld * mld,struct iwl_rx_packet * pkt)2013 void iwl_mld_handle_match_found_notif(struct iwl_mld *mld,
2014 struct iwl_rx_packet *pkt)
2015 {
2016 IWL_DEBUG_SCAN(mld, "Scheduled scan results\n");
2017 ieee80211_sched_scan_results(mld->hw);
2018 }
2019
iwl_mld_handle_scan_start_notif(struct iwl_mld * mld,struct iwl_rx_packet * pkt)2020 void iwl_mld_handle_scan_start_notif(struct iwl_mld *mld,
2021 struct iwl_rx_packet *pkt)
2022 {
2023 struct iwl_umac_scan_complete *notif = (void *)pkt->data;
2024 u32 uid = le32_to_cpu(notif->uid);
2025
2026 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status),
2027 "FW reports out-of-range scan UID %d\n", uid))
2028 return;
2029
2030 if (IWL_FW_CHECK(mld, !(mld->scan.uid_status[uid] & mld->scan.status),
2031 "FW reports scan UID %d we didn't trigger\n", uid))
2032 return;
2033
2034 IWL_DEBUG_SCAN(mld, "Scan started: uid=%u type=%u\n", uid,
2035 mld->scan.uid_status[uid]);
2036 if (IWL_FW_CHECK(mld, mld->scan.uid_status[uid] != IWL_MLD_SCAN_INT_MLO,
2037 "FW reports scan start notification %d we didn't trigger\n",
2038 mld->scan.uid_status[uid]))
2039 return;
2040
2041 mld->scan.last_mlo_scan_start_time = ktime_get_boottime_ns();
2042 }
2043
iwl_mld_handle_scan_complete_notif(struct iwl_mld * mld,struct iwl_rx_packet * pkt)2044 void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld,
2045 struct iwl_rx_packet *pkt)
2046 {
2047 struct iwl_umac_scan_complete *notif = (void *)pkt->data;
2048 bool aborted = (notif->status == IWL_SCAN_OFFLOAD_ABORTED);
2049 u32 uid = __le32_to_cpu(notif->uid);
2050
2051 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status),
2052 "FW reports out-of-range scan UID %d\n", uid))
2053 return;
2054
2055 IWL_DEBUG_SCAN(mld,
2056 "Scan completed: uid=%u type=%u, status=%s, EBS=%s\n",
2057 uid, mld->scan.uid_status[uid],
2058 notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
2059 "completed" : "aborted",
2060 iwl_mld_scan_ebs_status_str(notif->ebs_status));
2061 IWL_DEBUG_SCAN(mld, "Scan completed: scan_status=0x%x\n",
2062 mld->scan.status);
2063 IWL_DEBUG_SCAN(mld,
2064 "Scan completed: line=%u, iter=%u, elapsed time=%u\n",
2065 notif->last_schedule, notif->last_iter,
2066 __le32_to_cpu(notif->time_from_last_iter));
2067
2068 if (IWL_FW_CHECK(mld, !(mld->scan.uid_status[uid] & mld->scan.status),
2069 "FW reports scan UID %d we didn't trigger\n", uid))
2070 return;
2071
2072 /* if the scan is already stopping, we don't need to notify mac80211 */
2073 if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_REGULAR) {
2074 struct cfg80211_scan_info info = {
2075 .aborted = aborted,
2076 .scan_start_tsf = mld->scan.start_tsf,
2077 };
2078 int fw_link_id = mld->scan.fw_link_id;
2079 struct ieee80211_bss_conf *link_conf = NULL;
2080
2081 if (fw_link_id != IWL_MLD_INVALID_FW_ID)
2082 link_conf = iwl_mld_fw_id_to_link_conf(mld, fw_link_id);
2083
2084 /* It is possible that by the time the scan is complete the
2085 * link was already removed and is not valid.
2086 */
2087 if (link_conf)
2088 ether_addr_copy(info.tsf_bssid, link_conf->bssid);
2089 else
2090 IWL_DEBUG_SCAN(mld, "Scan link is no longer valid\n");
2091
2092 ieee80211_scan_completed(mld->hw, &info);
2093
2094 /* Scan is over, we can check again the tpt counters */
2095 iwl_mld_stop_ignoring_tpt_updates(mld);
2096 } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_SCHED) {
2097 ieee80211_sched_scan_stopped(mld->hw);
2098 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED;
2099 } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_INT_MLO) {
2100 IWL_DEBUG_SCAN(mld, "Internal MLO scan completed\n");
2101
2102 /*
2103 * We limit link selection to internal MLO scans as otherwise
2104 * we do not know whether all channels were covered.
2105 */
2106 iwl_mld_select_links(mld);
2107 }
2108
2109 mld->scan.status &= ~mld->scan.uid_status[uid];
2110
2111 IWL_DEBUG_SCAN(mld, "Scan completed: after update: scan_status=0x%x\n",
2112 mld->scan.status);
2113
2114 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE;
2115
2116 if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS &&
2117 notif->ebs_status != IWL_SCAN_EBS_INACTIVE)
2118 mld->scan.last_ebs_failed = true;
2119 }
2120
2121 /* This function is used in nic restart flow, to inform mac80211 about scans
2122 * that were aborted by restart flow or by an assert.
2123 */
iwl_mld_report_scan_aborted(struct iwl_mld * mld)2124 void iwl_mld_report_scan_aborted(struct iwl_mld *mld)
2125 {
2126 int uid;
2127
2128 uid = iwl_mld_scan_uid_by_status(mld, IWL_MLD_SCAN_REGULAR);
2129 if (uid >= 0) {
2130 struct cfg80211_scan_info info = {
2131 .aborted = true,
2132 };
2133
2134 ieee80211_scan_completed(mld->hw, &info);
2135 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE;
2136 }
2137
2138 uid = iwl_mld_scan_uid_by_status(mld, IWL_MLD_SCAN_SCHED);
2139 if (uid >= 0) {
2140 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED;
2141 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE;
2142
2143 /* sched scan will be restarted by mac80211 in reconfig.
2144 * report to mac80211 that sched scan stopped only if we won't
2145 * restart the firmware.
2146 */
2147 if (!iwlwifi_mod_params.fw_restart)
2148 ieee80211_sched_scan_stopped(mld->hw);
2149 }
2150
2151 uid = iwl_mld_scan_uid_by_status(mld, IWL_MLD_SCAN_INT_MLO);
2152 if (uid >= 0) {
2153 IWL_DEBUG_SCAN(mld, "Internal MLO scan aborted\n");
2154 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE;
2155 }
2156
2157 BUILD_BUG_ON(IWL_MLD_SCAN_NONE != 0);
2158 memset(mld->scan.uid_status, 0, sizeof(mld->scan.uid_status));
2159 }
2160
iwl_mld_alloc_scan_cmd(struct iwl_mld * mld)2161 int iwl_mld_alloc_scan_cmd(struct iwl_mld *mld)
2162 {
2163 u8 scan_cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, SCAN_REQ_UMAC,
2164 IWL_FW_CMD_VER_UNKNOWN);
2165 size_t scan_cmd_size;
2166
2167 if (scan_cmd_ver == 17) {
2168 scan_cmd_size = sizeof(struct iwl_scan_req_umac_v17);
2169 } else if (scan_cmd_ver == 18) {
2170 scan_cmd_size = sizeof(struct iwl_scan_req_umac_v18);
2171 } else {
2172 IWL_ERR(mld, "Unexpected scan cmd version %d\n", scan_cmd_ver);
2173 return -EINVAL;
2174 }
2175
2176 mld->scan.cmd = kmalloc(scan_cmd_size, GFP_KERNEL);
2177 if (!mld->scan.cmd)
2178 return -ENOMEM;
2179
2180 mld->scan.cmd_size = scan_cmd_size;
2181 mld->scan.cmd_ver = scan_cmd_ver;
2182
2183 return 0;
2184 }
2185
iwl_mld_chanidx_from_phy(struct iwl_mld * mld,enum nl80211_band band,u16 phy_chan_num)2186 static int iwl_mld_chanidx_from_phy(struct iwl_mld *mld,
2187 enum nl80211_band band,
2188 u16 phy_chan_num)
2189 {
2190 struct ieee80211_supported_band *sband = mld->wiphy->bands[band];
2191
2192 if (WARN_ON_ONCE(!sband))
2193 return -EINVAL;
2194
2195 for (int chan_idx = 0; chan_idx < sband->n_channels; chan_idx++) {
2196 struct ieee80211_channel *channel = &sband->channels[chan_idx];
2197
2198 if (channel->hw_value == phy_chan_num)
2199 return chan_idx;
2200 }
2201
2202 return -EINVAL;
2203 }
2204
iwl_mld_handle_channel_survey_notif(struct iwl_mld * mld,struct iwl_rx_packet * pkt)2205 void iwl_mld_handle_channel_survey_notif(struct iwl_mld *mld,
2206 struct iwl_rx_packet *pkt)
2207 {
2208 const struct iwl_umac_scan_channel_survey_notif *notif =
2209 (void *)pkt->data;
2210 struct iwl_mld_survey_channel *info;
2211 enum nl80211_band band;
2212 int chan_idx;
2213
2214 if (!mld->channel_survey) {
2215 size_t n_channels = 0;
2216
2217 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2218 if (!mld->wiphy->bands[band])
2219 continue;
2220
2221 n_channels += mld->wiphy->bands[band]->n_channels;
2222 }
2223
2224 mld->channel_survey = kzalloc_flex(*mld->channel_survey,
2225 channels, n_channels);
2226
2227 if (!mld->channel_survey)
2228 return;
2229
2230 mld->channel_survey->n_channels = n_channels;
2231 n_channels = 0;
2232 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2233 if (!mld->wiphy->bands[band])
2234 continue;
2235
2236 mld->channel_survey->bands[band] =
2237 &mld->channel_survey->channels[n_channels];
2238 n_channels += mld->wiphy->bands[band]->n_channels;
2239 }
2240 }
2241
2242 band = iwl_mld_phy_band_to_nl80211(le32_to_cpu(notif->band));
2243 chan_idx = iwl_mld_chanidx_from_phy(mld, band,
2244 le32_to_cpu(notif->channel));
2245 if (WARN_ON_ONCE(chan_idx < 0))
2246 return;
2247
2248 IWL_DEBUG_SCAN(mld, "channel survey received for freq %d\n",
2249 mld->wiphy->bands[band]->channels[chan_idx].center_freq);
2250
2251 info = &mld->channel_survey->bands[band][chan_idx];
2252
2253 /* Times are all in ms */
2254 info->time = le32_to_cpu(notif->active_time);
2255 info->time_busy = le32_to_cpu(notif->busy_time);
2256 info->noise =
2257 iwl_average_neg_dbm(notif->noise, ARRAY_SIZE(notif->noise));
2258 }
2259
iwl_mld_mac80211_get_survey(struct ieee80211_hw * hw,int idx,struct survey_info * survey)2260 int iwl_mld_mac80211_get_survey(struct ieee80211_hw *hw, int idx,
2261 struct survey_info *survey)
2262 {
2263 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
2264 int curr_idx = 0;
2265
2266 if (!mld->channel_survey)
2267 return -ENOENT;
2268
2269 /* Iterate bands/channels to find the requested index.
2270 * Logically this returns the entry with index "idx" from a flattened
2271 * survey result array that only contains channels with information.
2272 * The current index into this flattened array is tracked in curr_idx.
2273 */
2274 for (enum nl80211_band band = 0; band < NUM_NL80211_BANDS; band++) {
2275 struct ieee80211_supported_band *sband =
2276 mld->wiphy->bands[band];
2277
2278 if (!sband)
2279 continue;
2280
2281 for (int per_band_idx = 0;
2282 per_band_idx < sband->n_channels;
2283 per_band_idx++) {
2284 struct iwl_mld_survey_channel *info =
2285 &mld->channel_survey->bands[band][per_band_idx];
2286
2287 /* Skip entry entirely, it was not reported/scanned,
2288 * do not increase curr_idx for this entry.
2289 */
2290 if (!info->time)
2291 continue;
2292
2293 /* Search did not reach the requested entry yet,
2294 * increment curr_idx and continue.
2295 */
2296 if (idx != curr_idx) {
2297 curr_idx++;
2298 continue;
2299 }
2300
2301 /* Found (the next) channel to report */
2302 survey->channel = &sband->channels[per_band_idx];
2303 survey->filled = SURVEY_INFO_TIME |
2304 SURVEY_INFO_TIME_BUSY;
2305 survey->time = info->time;
2306 survey->time_busy = info->time_busy;
2307 survey->noise = info->noise;
2308 if (survey->noise < 0)
2309 survey->filled |= SURVEY_INFO_NOISE_DBM;
2310
2311 return 0;
2312 }
2313 }
2314
2315 return -ENOENT;
2316 }
2317