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