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