1 /*
2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * DOC: This file contains all SCAN component's APIs
22 */
23
24 #include "cfg_ucfg_api.h"
25 #include "wlan_scan_api.h"
26 #include "../../core/src/wlan_scan_manager.h"
27 #ifdef WLAN_POLICY_MGR_ENABLE
28 #include <wlan_policy_mgr_api.h>
29 #include "wlan_policy_mgr_public_struct.h"
30 #endif
31
wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)32 void wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
33 uint32_t *dwell_time)
34 {
35 struct wlan_scan_obj *scan_obj;
36
37 scan_obj = wlan_psoc_get_scan_obj(psoc);
38 if (!scan_obj)
39 return;
40 *dwell_time = scan_obj->scan_def.passive_dwell;
41 }
42
wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)43 void wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
44 uint32_t dwell_time)
45 {
46 struct wlan_scan_obj *scan_obj;
47
48 scan_obj = wlan_psoc_get_scan_obj(psoc);
49 if (!scan_obj)
50 return;
51 scan_obj->scan_def.passive_dwell = dwell_time;
52 }
53
wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)54 void wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc *psoc,
55 uint32_t *dwell_time)
56 {
57 struct wlan_scan_obj *scan_obj;
58
59 scan_obj = wlan_psoc_get_scan_obj(psoc);
60 if (!scan_obj)
61 return;
62 *dwell_time = scan_obj->scan_def.active_dwell;
63 }
64
wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)65 void wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc *psoc,
66 uint32_t dwell_time)
67 {
68 struct wlan_scan_obj *scan_obj;
69
70 scan_obj = wlan_psoc_get_scan_obj(psoc);
71 if (!scan_obj)
72 return;
73 scan_obj->scan_def.active_dwell = dwell_time;
74 }
75
wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)76 void wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
77 uint32_t *dwell_time)
78 {
79 struct wlan_scan_obj *scan_obj;
80
81 scan_obj = wlan_psoc_get_scan_obj(psoc);
82 if (!scan_obj)
83 return;
84
85 *dwell_time = scan_obj->scan_def.active_dwell_2g;
86 }
87
wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)88 void wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
89 uint32_t dwell_time)
90 {
91 struct wlan_scan_obj *scan_obj;
92
93 scan_obj = wlan_psoc_get_scan_obj(psoc);
94 if (!scan_obj)
95 return;
96 scan_obj->scan_def.active_dwell_2g = dwell_time;
97 }
98
99 #ifdef CONFIG_BAND_6GHZ
wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)100 QDF_STATUS wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
101 uint32_t *dwell_time)
102 {
103 struct wlan_scan_obj *scan_obj;
104
105 scan_obj = wlan_psoc_get_scan_obj(psoc);
106 if (!scan_obj)
107 return QDF_STATUS_E_INVAL;
108
109 *dwell_time = scan_obj->scan_def.active_dwell_6g;
110
111 return QDF_STATUS_SUCCESS;
112 }
113
wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)114 QDF_STATUS wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
115 uint32_t dwell_time)
116 {
117 struct wlan_scan_obj *scan_obj;
118
119 scan_obj = wlan_psoc_get_scan_obj(psoc);
120 if (!scan_obj)
121 return QDF_STATUS_E_INVAL;
122
123 scan_obj->scan_def.active_dwell_6g = dwell_time;
124
125 return QDF_STATUS_SUCCESS;
126 }
127
wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)128 QDF_STATUS wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
129 uint32_t *dwell_time)
130 {
131 struct wlan_scan_obj *scan_obj;
132
133 scan_obj = wlan_psoc_get_scan_obj(psoc);
134 if (!scan_obj)
135 return QDF_STATUS_E_INVAL;
136
137 *dwell_time = scan_obj->scan_def.passive_dwell_6g;
138
139 return QDF_STATUS_SUCCESS;
140 }
141
wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)142 QDF_STATUS wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
143 uint32_t dwell_time)
144 {
145 struct wlan_scan_obj *scan_obj;
146
147 scan_obj = wlan_psoc_get_scan_obj(psoc);
148 if (!scan_obj)
149 return QDF_STATUS_E_INVAL;
150
151 scan_obj->scan_def.passive_dwell_6g = dwell_time;
152
153 return QDF_STATUS_SUCCESS;
154 }
155
wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc * psoc,uint32_t * min_dwell_time_6ghz)156 void wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc *psoc,
157 uint32_t *min_dwell_time_6ghz)
158 {
159 struct wlan_scan_obj *scan_obj;
160
161 scan_obj = wlan_psoc_get_scan_obj(psoc);
162 if (!scan_obj)
163 return;
164 *min_dwell_time_6ghz = scan_obj->scan_def.min_dwell_time_6g;
165 }
166
wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc * psoc,enum scan_mode_6ghz scan_mode_6g)167 QDF_STATUS wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc *psoc,
168 enum scan_mode_6ghz scan_mode_6g)
169 {
170 struct wlan_scan_obj *scan_obj;
171
172 scan_obj = wlan_psoc_get_scan_obj(psoc);
173 if (!scan_obj)
174 return QDF_STATUS_E_INVAL;
175
176 scan_obj->scan_def.scan_mode_6g = scan_mode_6g;
177
178 return QDF_STATUS_SUCCESS;
179 }
180 #endif
181
182 #ifdef WLAN_POLICY_MGR_ENABLE
wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req,struct scan_default_params * scan_def)183 void wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
184 struct pno_scan_req_params *req,
185 struct scan_default_params *scan_def)
186 {
187 bool sap_or_p2p_present;
188 struct wlan_objmgr_psoc *psoc;
189
190 psoc = wlan_vdev_get_psoc(vdev);
191
192 if (!psoc)
193 return;
194
195 sap_or_p2p_present = policy_mgr_get_beaconing_mode_count(psoc, NULL) ||
196 policy_mgr_mode_specific_connection_count
197 (psoc,
198 PM_P2P_CLIENT_MODE, NULL);
199
200 if (sap_or_p2p_present) {
201 req->active_dwell_time = scan_def->conc_active_dwell;
202 req->passive_dwell_time = scan_def->conc_passive_dwell;
203 }
204 }
205 #endif
206
wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)207 void wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
208 uint32_t *dwell_time)
209 {
210 struct wlan_scan_obj *scan_obj;
211
212 scan_obj = wlan_psoc_get_scan_obj(psoc);
213 if (!scan_obj)
214 return;
215
216 *dwell_time = scan_obj->scan_def.conc_active_dwell;
217 }
218
wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)219 void wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
220 uint32_t dwell_time)
221 {
222 struct wlan_scan_obj *scan_obj;
223
224 scan_obj = wlan_psoc_get_scan_obj(psoc);
225 if (!scan_obj)
226 return;
227
228 scan_obj->scan_def.conc_active_dwell = dwell_time;
229 }
230
wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)231 void wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
232 uint32_t *dwell_time)
233 {
234 struct wlan_scan_obj *scan_obj;
235
236 scan_obj = wlan_psoc_get_scan_obj(psoc);
237 if (!scan_obj)
238 return;
239
240 *dwell_time = scan_obj->scan_def.conc_passive_dwell;
241 }
242
wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)243 void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
244 uint32_t dwell_time)
245 {
246 struct wlan_scan_obj *scan_obj;
247
248 scan_obj = wlan_psoc_get_scan_obj(psoc);
249 if (!scan_obj)
250 return;
251
252 scan_obj->scan_def.conc_passive_dwell = dwell_time;
253 }
254
255 void
wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc * psoc,bool * enable_dfs_scan)256 wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
257 bool *enable_dfs_scan)
258 {
259 struct wlan_scan_obj *scan_obj;
260
261 scan_obj = wlan_psoc_get_scan_obj(psoc);
262 if (!scan_obj)
263 return;
264
265 *enable_dfs_scan = scan_obj->scan_def.allow_dfs_chan_in_scan;
266 }
267
268 void
wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc * psoc,bool enable_dfs_scan)269 wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
270 bool enable_dfs_scan)
271 {
272 struct wlan_scan_obj *scan_obj;
273
274 scan_obj = wlan_psoc_get_scan_obj(psoc);
275 if (!scan_obj)
276 return;
277
278 scan_obj->scan_def.allow_dfs_chan_in_scan = enable_dfs_scan;
279 }
280
wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc * psoc)281 bool wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc *psoc)
282 {
283 struct wlan_scan_obj *scan_obj;
284
285 scan_obj = wlan_psoc_get_scan_obj(psoc);
286 if (!scan_obj)
287 return false;
288
289 return scan_obj->scan_def.honour_nl_scan_policy_flags;
290 }
291
wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc * psoc,uint32_t * rest_time)292 void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc,
293 uint32_t *rest_time)
294 {
295 struct wlan_scan_obj *scan_obj;
296
297 scan_obj = wlan_psoc_get_scan_obj(psoc);
298 if (!scan_obj)
299 return;
300
301 *rest_time = scan_obj->scan_def.conc_max_rest_time;
302 }
303
wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc * psoc,uint32_t * rest_time)304 void wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc *psoc,
305 uint32_t *rest_time)
306 {
307 struct wlan_scan_obj *scan_obj;
308
309 scan_obj = wlan_psoc_get_scan_obj(psoc);
310 if (!scan_obj)
311 return;
312
313 *rest_time = scan_obj->scan_def.conc_min_rest_time;
314 }
315
wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc * psoc)316 bool wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc *psoc)
317 {
318 struct wlan_scan_obj *scan_obj;
319
320 scan_obj = wlan_psoc_get_scan_obj(psoc);
321 if (!scan_obj)
322 return cfg_default(CFG_ENABLE_SNR_MONITORING);
323
324 return scan_obj->scan_def.scan_f_chan_stat_evnt;
325 }
326
327 QDF_STATUS
wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc * psoc,qdf_nbuf_t buf,struct mgmt_rx_event_params * rx_param,enum mgmt_frame_type frm_type)328 wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc,
329 qdf_nbuf_t buf,
330 struct mgmt_rx_event_params *rx_param,
331 enum mgmt_frame_type frm_type)
332 {
333 struct scan_bcn_probe_event *bcn = NULL;
334 QDF_STATUS status;
335
336 if ((frm_type != MGMT_PROBE_RESP) &&
337 (frm_type != MGMT_BEACON)) {
338 scm_err("frame is not beacon or probe resp");
339 status = QDF_STATUS_E_INVAL;
340 goto free;
341 }
342
343 bcn = qdf_mem_malloc_atomic(sizeof(*bcn));
344 if (!bcn) {
345 status = QDF_STATUS_E_NOMEM;
346 goto free;
347 }
348 bcn->rx_data =
349 qdf_mem_malloc_atomic(sizeof(*rx_param));
350 if (!bcn->rx_data) {
351 status = QDF_STATUS_E_NOMEM;
352 goto free;
353 }
354
355 if (frm_type == MGMT_PROBE_RESP)
356 bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP;
357 else
358 bcn->frm_type = MGMT_SUBTYPE_BEACON;
359
360 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID);
361 if (QDF_IS_STATUS_ERROR(status)) {
362 scm_info("unable to get reference");
363 goto free;
364 }
365
366 bcn->psoc = psoc;
367 bcn->buf = buf;
368
369 /*
370 * Save the rnr entries from the frame into rnr db.
371 * The RNR entry would have the partner links as well.
372 * If the partner link is a non-tx profile, and if there
373 * is no MBSSID info for that partner link, then look up
374 * into the rnr db will help to identify if that partner
375 * is a non-tx profile.
376 */
377 bcn->save_rnr_info = true;
378 qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param));
379
380 return __scm_handle_bcn_probe(bcn);
381 free:
382 if (bcn && bcn->rx_data)
383 qdf_mem_free(bcn->rx_data);
384 if (bcn)
385 qdf_mem_free(bcn);
386 if (buf)
387 qdf_nbuf_free(buf);
388
389 return status;
390 }
391
wlan_scan_get_aging_time(struct wlan_objmgr_psoc * psoc)392 qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc)
393 {
394 struct wlan_scan_obj *scan_obj;
395
396 scan_obj = wlan_psoc_get_scan_obj(psoc);
397 if (!scan_obj)
398 return cfg_default(CFG_SCAN_AGING_TIME) * 1000;
399
400 return scan_obj->scan_def.scan_cache_aging_time;
401 }
402
wlan_scan_set_aging_time(struct wlan_objmgr_psoc * psoc,qdf_time_t time)403 QDF_STATUS wlan_scan_set_aging_time(struct wlan_objmgr_psoc *psoc,
404 qdf_time_t time)
405 {
406 struct wlan_scan_obj *scan_obj;
407 QDF_STATUS status = QDF_STATUS_E_FAILURE;
408
409 scan_obj = wlan_psoc_get_scan_obj(psoc);
410 if (!scan_obj)
411 return status;
412
413 if (!cfg_in_range(CFG_SCAN_AGING_TIME, time / 1000)) {
414 status = QDF_STATUS_E_RANGE;
415 return status;
416 }
417
418 scan_obj->scan_def.scan_cache_aging_time = time;
419 status = QDF_STATUS_SUCCESS;
420 return status;
421 }
422
wlan_scan_start(struct scan_start_request * req)423 QDF_STATUS wlan_scan_start(struct scan_start_request *req)
424 {
425 struct scheduler_msg msg = {0};
426 QDF_STATUS status;
427
428 if (!req || !req->vdev) {
429 scm_err("req or vdev within req is NULL");
430 scm_scan_free_scan_request_mem(req);
431 return QDF_STATUS_E_NULL_VALUE;
432 }
433
434 if (!scm_is_scan_allowed(req->vdev)) {
435 scm_err_rl("scan disabled, rejecting the scan req");
436 scm_scan_free_scan_request_mem(req);
437 return QDF_STATUS_E_AGAIN;
438 }
439
440 /*
441 * Try to get vdev reference. Return if reference could
442 * not be taken. Reference will be released once scan
443 * request handling completes along with free of @req.
444 */
445 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
446 if (QDF_IS_STATUS_ERROR(status)) {
447 scm_info("unable to get reference");
448 scm_scan_free_scan_request_mem(req);
449 return status;
450 }
451
452 msg.bodyptr = req;
453 msg.callback = scm_scan_start_req;
454 msg.flush_callback = scm_scan_start_flush_callback;
455
456 status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
457 QDF_MODULE_ID_SCAN,
458 QDF_MODULE_ID_OS_IF, &msg);
459 if (QDF_IS_STATUS_ERROR(status)) {
460 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
461 scm_scan_free_scan_request_mem(req);
462 }
463
464 return status;
465 }
466
wlan_scan_cancel(struct scan_cancel_request * req)467 QDF_STATUS wlan_scan_cancel(struct scan_cancel_request *req)
468 {
469 struct scheduler_msg msg = {0};
470 QDF_STATUS status;
471
472 if (!req || !req->vdev) {
473 scm_err("req or vdev within req is NULL");
474 if (req)
475 qdf_mem_free(req);
476 return QDF_STATUS_E_NULL_VALUE;
477 }
478
479 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
480 if (QDF_IS_STATUS_ERROR(status)) {
481 scm_info("Failed to get vdev ref; status:%d", status);
482 goto req_free;
483 }
484
485 msg.bodyptr = req;
486 msg.callback = scm_scan_cancel_req;
487 msg.flush_callback = scm_scan_cancel_flush_callback;
488
489 status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
490 QDF_MODULE_ID_SCAN,
491 QDF_MODULE_ID_OS_IF, &msg);
492 if (QDF_IS_STATUS_ERROR(status))
493 goto vdev_put;
494
495 return QDF_STATUS_SUCCESS;
496
497 vdev_put:
498 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
499
500 req_free:
501 qdf_mem_free(req);
502
503 return status;
504 }
505
506 wlan_scan_id
wlan_scan_get_scan_id(struct wlan_objmgr_psoc * psoc)507 wlan_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
508 {
509 wlan_scan_id id;
510 struct wlan_scan_obj *scan;
511
512 if (!psoc) {
513 QDF_ASSERT(0);
514 scm_err("null psoc");
515 return 0;
516 }
517
518 scan = wlan_psoc_get_scan_obj(psoc);
519 if (!scan) {
520 scm_err("scan object null");
521 return 0;
522 }
523
524 id = qdf_atomic_inc_return(&scan->scan_ids);
525 id = id & WLAN_SCAN_ID_MASK;
526 /* Mark this scan request as triggered by host
527 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag.
528 */
529 id = id | WLAN_HOST_SCAN_REQ_ID_PREFIX;
530 scm_debug("scan_id: 0x%x", id);
531
532 return id;
533 }
534
535 QDF_STATUS
wlan_scan_init_default_params(struct wlan_objmgr_vdev * vdev,struct scan_start_request * req)536 wlan_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
537 struct scan_start_request *req)
538 {
539 struct scan_default_params *def;
540
541 if (!vdev | !req) {
542 scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req);
543 return QDF_STATUS_E_INVAL;
544 }
545 def = wlan_vdev_get_def_scan_params(vdev);
546 if (!def) {
547 scm_err("wlan_vdev_get_def_scan_params returned NULL");
548 return QDF_STATUS_E_NULL_VALUE;
549 }
550
551 /* Zero out everything and explicitly set fields as required */
552 qdf_mem_zero(req, sizeof(*req));
553
554 req->vdev = vdev;
555 req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
556 req->scan_req.scan_type = SCAN_TYPE_DEFAULT;
557 req->scan_req.scan_priority = def->scan_priority;
558 req->scan_req.dwell_time_active = def->active_dwell;
559 req->scan_req.dwell_time_active_2g = def->active_dwell_2g;
560 req->scan_req.min_dwell_time_6g = def->min_dwell_time_6g;
561 req->scan_req.dwell_time_active_6g = def->active_dwell_6g;
562 req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g;
563 req->scan_req.dwell_time_passive = def->passive_dwell;
564 req->scan_req.min_rest_time = def->min_rest_time;
565 req->scan_req.max_rest_time = def->max_rest_time;
566 req->scan_req.repeat_probe_time = def->repeat_probe_time;
567 req->scan_req.probe_spacing_time = def->probe_spacing_time;
568 req->scan_req.idle_time = def->idle_time;
569 req->scan_req.max_scan_time = def->max_scan_time;
570 req->scan_req.probe_delay = def->probe_delay;
571 req->scan_req.burst_duration = def->burst_duration;
572 req->scan_req.n_probes = def->num_probes;
573 req->scan_req.adaptive_dwell_time_mode =
574 def->adaptive_dwell_time_mode;
575 req->scan_req.scan_flags = def->scan_flags;
576 req->scan_req.scan_events = def->scan_events;
577 req->scan_req.scan_random.randomize = def->enable_mac_spoofing;
578
579 return QDF_STATUS_SUCCESS;
580 }
581
582 wlan_scan_requester
wlan_scan_register_requester(struct wlan_objmgr_psoc * psoc,uint8_t * name,scan_event_handler event_cb,void * arg)583 wlan_scan_register_requester(struct wlan_objmgr_psoc *psoc,
584 uint8_t *name,
585 scan_event_handler event_cb,
586 void *arg)
587 {
588 int i, j;
589 struct wlan_scan_obj *scan;
590 struct scan_requester_info *requesters;
591 wlan_scan_requester requester = {0};
592
593 if (!psoc) {
594 scm_err("null psoc");
595 return 0;
596 }
597 scan = wlan_psoc_get_scan_obj(psoc);
598 if (!scan)
599 return 0;
600
601 requesters = scan->requesters;
602 qdf_spin_lock_bh(&scan->lock);
603 for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) {
604 if (requesters[i].requester == 0) {
605 requesters[i].requester =
606 WLAN_SCAN_REQUESTER_ID_PREFIX | i;
607 j = 0;
608 while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) {
609 requesters[i].module[j] = name[j];
610 ++j;
611 }
612 requesters[i].module[j] = 0;
613 requesters[i].ev_handler.func = event_cb;
614 requesters[i].ev_handler.arg = arg;
615 requester = requesters[i].requester;
616 break;
617 }
618 }
619 qdf_spin_unlock_bh(&scan->lock);
620 scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d",
621 name, event_cb, arg, requester);
622
623 return requester;
624 }
625
626 void
wlan_scan_unregister_requester(struct wlan_objmgr_psoc * psoc,wlan_scan_requester requester)627 wlan_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
628 wlan_scan_requester requester)
629 {
630 int idx;
631 struct wlan_scan_obj *scan;
632 struct scan_requester_info *requesters;
633
634 idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX;
635 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) {
636 scm_err("prefix didn't match for requester id %d", requester);
637 return;
638 }
639
640 idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
641 if (idx >= WLAN_MAX_REQUESTORS) {
642 scm_err("requester id %d greater than max value", requester);
643 return;
644 }
645
646 if (!psoc) {
647 scm_err("null psoc");
648 return;
649 }
650 scan = wlan_psoc_get_scan_obj(psoc);
651 if (!scan)
652 return;
653 requesters = scan->requesters;
654 scm_debug("reqid: %d", requester);
655
656 qdf_spin_lock_bh(&scan->lock);
657 requesters[idx].requester = 0;
658 requesters[idx].module[0] = 0;
659 requesters[idx].ev_handler.func = NULL;
660 requesters[idx].ev_handler.arg = NULL;
661 qdf_spin_unlock_bh(&scan->lock);
662 }
663
wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc * psoc)664 bool wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc *psoc)
665 {
666 struct wlan_scan_obj *scan_obj;
667
668 scan_obj = wlan_psoc_get_scan_obj(psoc);
669 if (!scan_obj)
670 return false;
671
672 return scan_obj->scan_def.skip_6g_and_indoor_freq;
673 }
674
wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc * psoc,uint32_t * last_scan_ageout_time)675 void wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc *psoc,
676 uint32_t *last_scan_ageout_time)
677 {
678 struct wlan_scan_obj *scan_obj;
679
680 scan_obj = wlan_psoc_get_scan_obj(psoc);
681 if (!scan_obj) {
682 *last_scan_ageout_time = 0;
683 return;
684 }
685 *last_scan_ageout_time =
686 scan_obj->scan_def.last_scan_ageout_time;
687 }
688
689 #ifdef FEATURE_SET
690 /**
691 * wlan_scan_get_pno_scan_support() - Check if pno scan support is enabled
692 * @psoc: pointer to psoc object
693 *
694 * Return: pno scan_support_enabled flag
695 */
wlan_scan_get_pno_scan_support(struct wlan_objmgr_psoc * psoc)696 static bool wlan_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
697 {
698 struct wlan_scan_obj *scan_obj;
699
700 scan_obj = wlan_psoc_get_scan_obj(psoc);
701 if (!scan_obj) {
702 scm_err("NULL scan obj");
703 return cfg_default(CFG_PNO_SCAN_SUPPORT);
704 }
705
706 return scan_obj->pno_cfg.scan_support_enabled;
707 }
708
709 /**
710 * wlan_scan_is_connected_scan_enabled() - API to get scan enabled after connect
711 * @psoc: pointer to psoc object
712 *
713 * Return: value.
714 */
wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc * psoc)715 static bool wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
716 {
717 struct wlan_scan_obj *scan_obj;
718
719 scan_obj = wlan_psoc_get_scan_obj(psoc);
720 if (!scan_obj) {
721 scm_err("Failed to get scan object");
722 return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
723 }
724
725 return scan_obj->scan_def.enable_connected_scan;
726 }
727
wlan_scan_get_feature_info(struct wlan_objmgr_psoc * psoc,struct wlan_scan_features * scan_feature_set)728 void wlan_scan_get_feature_info(struct wlan_objmgr_psoc *psoc,
729 struct wlan_scan_features *scan_feature_set)
730 {
731 scan_feature_set->pno_in_unassoc_state =
732 wlan_scan_get_pno_scan_support(psoc);
733 if (scan_feature_set->pno_in_unassoc_state)
734 scan_feature_set->pno_in_assoc_state =
735 wlan_scan_is_connected_scan_enabled(psoc);
736 }
737 #endif
738
739 #ifdef WLAN_POLICY_MGR_ENABLE
740 /**
741 * wlan_scan_update_hint_bssid() - Update rnr hint bssid info
742 * @psoc: objmgr psoc
743 * @req: Scan request
744 * @ll_sap_freq: ll sap freq
745 *
746 * Use to update hint_bssid if low latency Sap is UP
747 *
748 * Return: void
749 */
750 static void
wlan_scan_update_hint_bssid(struct wlan_objmgr_psoc * psoc,struct scan_start_request * req,qdf_freq_t ll_sap_freq)751 wlan_scan_update_hint_bssid(struct wlan_objmgr_psoc *psoc,
752 struct scan_start_request *req,
753 qdf_freq_t ll_sap_freq)
754 {
755 struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID] = {0};
756 uint32_t i;
757 uint32_t count = 0;
758 qdf_freq_t freq;
759
760 if (!req->scan_req.num_hint_bssid)
761 return;
762
763 for (i = 0; i < req->scan_req.num_hint_bssid; i++) {
764 freq = req->scan_req.hint_bssid[i].freq_flags >> 16;
765 if (!freq)
766 continue;
767 if (!policy_mgr_2_freq_always_on_same_mac(psoc,
768 ll_sap_freq,
769 freq)) {
770 qdf_mem_copy(
771 &hint_bssid[count].bssid,
772 &req->scan_req.hint_bssid[i].bssid,
773 sizeof(hint_bssid[i].bssid));
774 hint_bssid[count].freq_flags =
775 req->scan_req.hint_bssid[i].freq_flags;
776 count++;
777 }
778 }
779 qdf_mem_zero(req->scan_req.hint_bssid,
780 sizeof(req->scan_req.hint_bssid));
781 if (count)
782 qdf_mem_copy(req->scan_req.hint_bssid, hint_bssid,
783 sizeof(hint_bssid));
784 req->scan_req.num_hint_bssid = count;
785 }
786
787 /**
788 * wlan_scan_update_hint_s_ssid() - Update rnr hint short ssid info
789 * @psoc: objmgr psoc
790 * @req: Scan request
791 * @ll_sap_freq: ll sap freq
792 *
793 * Use to update hint_s_ssid if low latency Sap is UP
794 *
795 * Return: void
796 */
797 static
wlan_scan_update_hint_s_ssid(struct wlan_objmgr_psoc * psoc,struct scan_start_request * req,qdf_freq_t ll_sap_freq)798 void wlan_scan_update_hint_s_ssid(struct wlan_objmgr_psoc *psoc,
799 struct scan_start_request *req,
800 qdf_freq_t ll_sap_freq)
801 {
802 struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_BSSID] = {0};
803 uint32_t i;
804 uint32_t count = 0;
805 qdf_freq_t freq;
806
807 if (!req->scan_req.num_hint_s_ssid)
808 return;
809
810 for (i = 0; i < req->scan_req.num_hint_s_ssid; i++) {
811 freq = req->scan_req.hint_s_ssid[i].freq_flags >> 16;
812 if (!freq)
813 continue;
814 if (!policy_mgr_2_freq_always_on_same_mac(psoc,
815 ll_sap_freq,
816 freq)) {
817 qdf_mem_copy(
818 &hint_s_ssid[count].short_ssid,
819 &req->scan_req.hint_s_ssid[i].short_ssid,
820 sizeof(hint_s_ssid[i].short_ssid));
821 hint_s_ssid[count].freq_flags =
822 req->scan_req.hint_s_ssid[i].freq_flags;
823 count++;
824 }
825 }
826 qdf_mem_zero(req->scan_req.hint_s_ssid,
827 sizeof(req->scan_req.hint_s_ssid));
828 if (count)
829 qdf_mem_copy(req->scan_req.hint_s_ssid, hint_s_ssid,
830 sizeof(hint_s_ssid));
831 req->scan_req.num_hint_s_ssid = count;
832 }
833
wlan_scan_update_low_latency_profile_chnlist(struct wlan_objmgr_vdev * vdev,struct scan_start_request * req)834 void wlan_scan_update_low_latency_profile_chnlist(
835 struct wlan_objmgr_vdev *vdev,
836 struct scan_start_request *req)
837 {
838 uint32_t num_scan_channels = 0, i;
839 struct wlan_objmgr_psoc *psoc;
840 qdf_freq_t freq, ll_sap_freq;
841
842 psoc = wlan_vdev_get_psoc(vdev);
843 if (!psoc) {
844 scm_err("psoc is null");
845 return;
846 }
847
848 /*
849 * Get ll_sap freq api will be cleaned up once macro is enabled
850 */
851 #ifndef WLAN_FEATURE_LL_LT_SAP
852 ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc);
853 #else
854 ll_sap_freq = policy_mgr_get_ll_ht_sap_freq(psoc);
855 #endif
856
857 if (!ll_sap_freq)
858 return;
859
860 wlan_scan_update_hint_bssid(psoc, req, ll_sap_freq);
861 wlan_scan_update_hint_s_ssid(psoc, req, ll_sap_freq);
862 /*
863 * Scenario: LL SAP is present and scan is requested.
864 * Allow scan on freq on mutually exclusive mac.
865 */
866 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
867 freq = req->scan_req.chan_list.chan[i].freq;
868 if (policy_mgr_2_freq_always_on_same_mac(psoc,
869 ll_sap_freq,
870 freq))
871 continue;
872
873 req->scan_req.chan_list.chan[num_scan_channels++] =
874 req->scan_req.chan_list.chan[i];
875 }
876 if (num_scan_channels < req->scan_req.chan_list.num_chan)
877 scm_debug("For DBS: only 2.4Ghz chan and for SBS: mutually exclusive ll-sap 5GHz chan allowed, total-chan %d, remaining-chan %d, ll-sap chan %d",
878 req->scan_req.chan_list.num_chan,
879 num_scan_channels,
880 ll_sap_freq);
881 req->scan_req.chan_list.num_chan = num_scan_channels;
882 }
883 #endif
884
885 QDF_STATUS
wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,struct element_info * frame)886 wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev *pdev,
887 struct qdf_mac_addr *bssid,
888 struct element_info *frame)
889 {
890 return scm_scan_get_entry_by_mac_addr(pdev, bssid, frame);
891 }
892
wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc * psoc,update_mbssid_bcn_prb_rsp cb)893 QDF_STATUS wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc *psoc,
894 update_mbssid_bcn_prb_rsp cb)
895 {
896 return scm_scan_register_mbssid_cb(psoc, cb);
897 }
898
899 struct scan_cache_entry *
wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid)900 wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev *pdev,
901 struct qdf_mac_addr *bssid)
902 {
903 return scm_scan_get_entry_by_bssid(pdev, bssid);
904 }
905
906 QDF_STATUS
wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * link_addr,struct qdf_mac_addr * mld_mac_addr)907 wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev *pdev,
908 struct qdf_mac_addr *link_addr,
909 struct qdf_mac_addr *mld_mac_addr)
910 {
911 return scm_get_mld_addr_by_link_addr(pdev, link_addr, mld_mac_addr);
912 }
913
914 struct scan_cache_entry *
wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,uint16_t freq)915 wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev *pdev,
916 struct qdf_mac_addr *bssid,
917 uint16_t freq)
918 {
919 return scm_scan_get_scan_entry_by_mac_freq(pdev, bssid, freq);
920 }
921
wlan_scan_get_aux_support(struct wlan_objmgr_psoc * psoc)922 bool wlan_scan_get_aux_support(struct wlan_objmgr_psoc *psoc)
923
924 {
925 struct wlan_scan_obj *scan_obj;
926
927 scan_obj = wlan_psoc_get_scan_obj(psoc);
928 if (!scan_obj)
929 return false;
930
931 if (scan_obj->aux_mac_support)
932 scm_debug("aux mac support: %d", scan_obj->aux_mac_support);
933 else
934 scm_debug("aux mac not supported");
935
936 return scan_obj->aux_mac_support;
937 }
938
939