1 /*
2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /*
19 * DOC: contains scan north bound interface definitions
20 */
21
22 #include <scheduler_api.h>
23 #include <wlan_scan_ucfg_api.h>
24 #include <wlan_objmgr_global_obj.h>
25 #include <wlan_objmgr_cmn.h>
26 #include <wlan_serialization_api.h>
27 #include <wlan_scan_tgt_api.h>
28 #include <wlan_scan_utils_api.h>
29 #include <wlan_reg_ucfg_api.h>
30 #include <wlan_reg_services_api.h>
31 #include <wlan_utility.h>
32 #include "../../core/src/wlan_scan_main.h"
33 #include "../../core/src/wlan_scan_manager.h"
34 #include "../../core/src/wlan_scan_cache_db.h"
35 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
36 #include <wlan_pmo_obj_mgmt_api.h>
37 #endif
38 #ifdef WLAN_POLICY_MGR_ENABLE
39 #include <wlan_dfs_utils_api.h>
40 #include <wlan_policy_mgr_api.h>
41 #endif
42 #include "cfg_ucfg_api.h"
43 #include "wlan_extscan_api.h"
44
ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc * psoc,update_beacon_cb cb,enum scan_cb_type type)45 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
46 update_beacon_cb cb, enum scan_cb_type type)
47 {
48 return scm_scan_register_bcn_cb(psoc, cb, type);
49 }
50
ucfg_scan_get_result(struct wlan_objmgr_pdev * pdev,struct scan_filter * filter)51 qdf_list_t *ucfg_scan_get_result(struct wlan_objmgr_pdev *pdev,
52 struct scan_filter *filter)
53 {
54 return scm_get_scan_result(pdev, filter);
55 }
56
ucfg_scan_db_iterate(struct wlan_objmgr_pdev * pdev,scan_iterator_func func,void * arg)57 QDF_STATUS ucfg_scan_db_iterate(struct wlan_objmgr_pdev *pdev,
58 scan_iterator_func func, void *arg)
59 {
60 return scm_iterate_scan_db(pdev, func, arg);
61 }
62
ucfg_scan_purge_results(qdf_list_t * scan_list)63 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list)
64 {
65 return scm_purge_scan_results(scan_list);
66 }
67
ucfg_scan_flush_results(struct wlan_objmgr_pdev * pdev,struct scan_filter * filter)68 QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev,
69 struct scan_filter *filter)
70 {
71 return scm_flush_results(pdev, filter);
72 }
73
ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev * pdev,uint32_t * chan_freq_list,uint32_t num_chan)74 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev,
75 uint32_t *chan_freq_list, uint32_t num_chan)
76 {
77 scm_filter_valid_channel(pdev, chan_freq_list, num_chan);
78 }
79
ucfg_scan_get_entry_frame_len(struct scan_cache_entry * scan_entry)80 uint32_t ucfg_scan_get_entry_frame_len(struct scan_cache_entry *scan_entry)
81 {
82 return util_scan_entry_frame_len(scan_entry);
83 }
84
ucfg_scan_init(void)85 QDF_STATUS ucfg_scan_init(void)
86 {
87 QDF_STATUS status;
88
89 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
90 wlan_scan_psoc_created_notification, NULL);
91 if (QDF_IS_STATUS_ERROR(status)) {
92 scm_err("Failed to register psoc create handler");
93 goto fail_create_psoc;
94 }
95
96 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
97 wlan_scan_psoc_destroyed_notification, NULL);
98 if (QDF_IS_STATUS_ERROR(status)) {
99 scm_err("Failed to create psoc delete handler");
100 goto fail_psoc_destroy;
101 }
102 scm_debug("scan psoc create and delete handler registered with objmgr");
103
104 status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
105 wlan_scan_vdev_created_notification, NULL);
106 if (QDF_IS_STATUS_ERROR(status)) {
107 scm_err("Failed to register vdev create handler");
108 goto fail_pdev_create;
109 }
110
111 status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN,
112 wlan_scan_vdev_destroyed_notification, NULL);
113 if (QDF_IS_STATUS_SUCCESS(status)) {
114 scm_debug("scan vdev create and delete handler registered with objmgr");
115 return QDF_STATUS_SUCCESS;
116 }
117
118 scm_err("Failed to destroy vdev delete handler");
119 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
120 wlan_scan_vdev_created_notification, NULL);
121 fail_pdev_create:
122 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
123 wlan_scan_psoc_destroyed_notification, NULL);
124 fail_psoc_destroy:
125 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
126 wlan_scan_psoc_created_notification, NULL);
127 fail_create_psoc:
128 return status;
129 }
130
ucfg_scan_deinit(void)131 QDF_STATUS ucfg_scan_deinit(void)
132 {
133 QDF_STATUS status;
134
135 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
136 wlan_scan_psoc_created_notification, NULL);
137 if (status != QDF_STATUS_SUCCESS)
138 scm_err("Failed to unregister psoc create handler");
139
140 status = wlan_objmgr_unregister_psoc_destroy_handler(
141 WLAN_UMAC_COMP_SCAN,
142 wlan_scan_psoc_destroyed_notification, NULL);
143 if (status != QDF_STATUS_SUCCESS)
144 scm_err("Failed to unregister psoc delete handler");
145
146 status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
147 wlan_scan_vdev_created_notification, NULL);
148 if (status != QDF_STATUS_SUCCESS)
149 scm_err("Failed to unregister vdev create handler");
150
151 status = wlan_objmgr_unregister_vdev_destroy_handler(
152 WLAN_UMAC_COMP_SCAN,
153 wlan_scan_vdev_destroyed_notification, NULL);
154 if (status != QDF_STATUS_SUCCESS)
155 scm_err("Failed to unregister vdev delete handler");
156
157 return status;
158 }
159
160 #ifdef FEATURE_WLAN_SCAN_PNO
161 bool
ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc * psoc)162 ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc *psoc)
163 {
164 return wlan_psoc_nif_fw_ext_cap_get(psoc,
165 WLAN_SOC_PNO_SCAN_CONFIG_PER_CHANNEL);
166 }
167
ucfg_scan_pno_start(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req)168 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
169 struct pno_scan_req_params *req)
170 {
171 struct scan_vdev_obj *scan_vdev_obj;
172 QDF_STATUS status;
173
174 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
175 if (!scan_vdev_obj) {
176 scm_err("null scan_vdev_obj");
177 return QDF_STATUS_E_INVAL;
178 }
179 if (scan_vdev_obj->pno_in_progress) {
180 scm_err("pno already in progress");
181 return QDF_STATUS_E_ALREADY;
182 }
183
184 status = tgt_scan_pno_start(vdev, req);
185 if (QDF_IS_STATUS_ERROR(status))
186 scm_err("pno start failed");
187 else
188 scan_vdev_obj->pno_in_progress = true;
189
190 return status;
191 }
192
ucfg_scan_add_flags_to_pno_chan_list(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req,uint8_t * num_chan,uint32_t short_ssid,int list_idx)193 void ucfg_scan_add_flags_to_pno_chan_list(struct wlan_objmgr_vdev *vdev,
194 struct pno_scan_req_params *req,
195 uint8_t *num_chan,
196 uint32_t short_ssid,
197 int list_idx)
198 {
199 struct chan_list *pno_chan_list =
200 &req->networks_list[list_idx].pno_chan_list;
201
202 /* Add RNR flags to channels based on scan_mode_6g ini */
203 scm_add_channel_flags(vdev, pno_chan_list, num_chan,
204 req->scan_policy_colocated_6ghz, true);
205 /* Filter RNR flags in pno channel list based on short ssid entry in
206 * RNR db cache.
207 */
208 scm_filter_rnr_flag_pno(vdev, short_ssid,
209 &req->networks_list[0].pno_chan_list);
210 }
211
ucfg_scan_pno_stop(struct wlan_objmgr_vdev * vdev)212 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)
213 {
214 struct scan_vdev_obj *scan_vdev_obj;
215 QDF_STATUS status;
216
217 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
218 if (!scan_vdev_obj) {
219 scm_err("null scan_vdev_obj");
220 return QDF_STATUS_E_INVAL;
221 }
222 if (!scan_vdev_obj->pno_in_progress) {
223 scm_debug("pno already stopped");
224 return QDF_STATUS_SUCCESS;
225 }
226
227 status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev));
228 if (QDF_IS_STATUS_ERROR(status))
229 scm_err("pno stop failed");
230 else
231 scan_vdev_obj->pno_in_progress = false;
232
233 return status;
234 }
235
ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev * vdev)236 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev)
237 {
238 struct scan_vdev_obj *scan_vdev_obj;
239
240 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
241 if (!scan_vdev_obj) {
242 scm_err("null scan_vdev_obj");
243 return false;
244 }
245
246 return scan_vdev_obj->pno_in_progress;
247 }
248
ucfg_scan_get_pno_match(struct wlan_objmgr_vdev * vdev)249 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
250 {
251 struct scan_vdev_obj *scan_vdev_obj;
252
253 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
254 if (!scan_vdev_obj) {
255 scm_err("null scan_vdev_obj");
256 return false;
257 }
258
259 return scan_vdev_obj->pno_match_evt_received;
260 }
261
262 static QDF_STATUS
wlan_pno_global_init(struct wlan_objmgr_psoc * psoc,struct wlan_scan_obj * scan_obj)263 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
264 struct wlan_scan_obj *scan_obj)
265 {
266 struct nlo_mawc_params *mawc_cfg;
267 struct pno_def_config *pno_def;
268
269 pno_def = &scan_obj->pno_cfg;
270 qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl");
271 qdf_runtime_lock_init(&pno_def->pno_runtime_pm_lock);
272 mawc_cfg = &pno_def->mawc_params;
273 pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION);
274 pno_def->top_k_num_of_channels =
275 cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS);
276 pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD);
277 pno_def->channel_prediction_full_scan =
278 cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER);
279 pno_def->adaptive_dwell_mode =
280 cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE);
281 pno_def->dfs_chnl_scan_enabled =
282 cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN);
283 pno_def->scan_support_enabled =
284 cfg_get(psoc, CFG_PNO_SCAN_SUPPORT);
285 pno_def->scan_timer_repeat_value =
286 cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
287 pno_def->slow_scan_multiplier =
288 cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER);
289 pno_def->scan_backoff_multiplier =
290 cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER);
291 pno_def->max_sched_scan_plan_interval =
292 cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
293 pno_def->max_sched_scan_plan_iterations =
294 cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
295 pno_def->user_config_sched_scan_plan =
296 cfg_get(psoc, CFG_USER_CONFIG_SCHED_SCAN_PLAN);
297
298 mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED);
299 mawc_cfg->exp_backoff_ratio =
300 cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO);
301 mawc_cfg->init_scan_interval =
302 cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL);
303 mawc_cfg->max_scan_interval =
304 cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL);
305
306 return QDF_STATUS_SUCCESS;
307 }
308
309 static QDF_STATUS
wlan_pno_global_deinit(struct wlan_scan_obj * scan_obj)310 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
311 {
312 qdf_runtime_lock_deinit(&scan_obj->pno_cfg.pno_runtime_pm_lock);
313 qdf_wake_lock_destroy(&scan_obj->pno_cfg.pno_wake_lock);
314
315 return QDF_STATUS_SUCCESS;
316 }
317
318 QDF_STATUS
ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req)319 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
320 struct pno_scan_req_params *req)
321 {
322 struct scan_default_params *scan_def;
323 struct wlan_scan_obj *scan;
324 struct pno_def_config *pno_def;
325
326 if (!vdev || !req) {
327 scm_err("vdev: 0x%pK, req: 0x%pK",
328 vdev, req);
329 return QDF_STATUS_E_INVAL;
330 }
331
332 scan = wlan_vdev_get_scan_obj(vdev);
333 if (!scan) {
334 scm_err("scan is NULL");
335 return QDF_STATUS_E_INVAL;
336 }
337 scan_def = wlan_vdev_get_def_scan_params(vdev);
338 if (!scan_def) {
339 scm_err("wlan_vdev_get_def_scan_params returned NULL");
340 return QDF_STATUS_E_NULL_VALUE;
341 }
342
343 pno_def = &scan->pno_cfg;
344 req->active_dwell_time = scan_def->active_dwell;
345 req->passive_dwell_time = scan_def->passive_dwell;
346 req->scan_random.randomize = scan_def->enable_mac_spoofing;
347
348 /*
349 * Update active and passive dwell time depending
350 * upon the present active concurrency mode
351 */
352 wlan_scan_update_pno_dwell_time(vdev, req, scan_def);
353 req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
354 req->pno_channel_prediction = pno_def->channel_prediction;
355 req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
356 req->stationary_thresh = pno_def->stationary_thresh;
357 req->channel_prediction_full_scan =
358 pno_def->channel_prediction_full_scan;
359 req->mawc_params.vdev_id = wlan_vdev_get_id(vdev);
360 qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params,
361 sizeof(req->mawc_params));
362
363 return QDF_STATUS_SUCCESS;
364 }
365
366 QDF_STATUS
ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc * psoc,scan_event_handler event_cb,void * arg)367 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
368 scan_event_handler event_cb, void *arg)
369 {
370 struct wlan_scan_obj *scan;
371
372 if (!psoc) {
373 scm_err("null psoc");
374 return QDF_STATUS_E_INVAL;
375 }
376
377 scan = wlan_psoc_get_scan_obj(psoc);
378 if (!scan) {
379 scm_err("scan object null");
380 return QDF_STATUS_E_INVAL;
381 }
382
383 qdf_spin_lock_bh(&scan->lock);
384 scan->pno_cfg.pno_cb.func = event_cb;
385 scan->pno_cfg.pno_cb.arg = arg;
386 qdf_spin_unlock_bh(&scan->lock);
387 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
388
389 return QDF_STATUS_SUCCESS;
390 }
391
392 #else
393
394 static inline QDF_STATUS
wlan_pno_global_init(struct wlan_objmgr_psoc * psoc,struct wlan_scan_obj * scan_obj)395 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
396 struct wlan_scan_obj *scan_obj)
397 {
398 return QDF_STATUS_SUCCESS;
399 }
400
401 static inline QDF_STATUS
wlan_pno_global_deinit(struct wlan_scan_obj * scan_obj)402 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
403 {
404 return QDF_STATUS_SUCCESS;
405 }
406
407 #endif
408
409 QDF_STATUS
ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev * pdev,struct chan_list * chan_list)410 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
411 struct chan_list *chan_list)
412 {
413 uint8_t pdev_id;
414 struct wlan_scan_obj *scan_obj;
415
416 if (!pdev || !chan_list) {
417 scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list);
418 return QDF_STATUS_E_NULL_VALUE;
419 }
420 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
421 scan_obj = wlan_pdev_get_scan_obj(pdev);
422
423 qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list,
424 chan_list, sizeof(*chan_list));
425
426 return QDF_STATUS_SUCCESS;
427 }
428
429 QDF_STATUS
ucfg_scm_scan_free_scan_request_mem(struct scan_start_request * req)430 ucfg_scm_scan_free_scan_request_mem(struct scan_start_request *req)
431 {
432 return scm_scan_free_scan_request_mem(req);
433 }
434
ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc * psoc,enum scan_disable_reason reason)435 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
436 enum scan_disable_reason reason)
437 {
438 return wlan_scan_psoc_set_enable(psoc, reason);
439 }
440
ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc * psoc,enum scan_disable_reason reason)441 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
442 enum scan_disable_reason reason)
443 {
444 return wlan_scan_psoc_set_disable(psoc, reason);
445 }
446
447
ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev * vdev,enum scan_disable_reason reason)448 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
449 enum scan_disable_reason reason)
450 {
451 struct scan_vdev_obj *scan_vdev_obj;
452
453 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
454 if (!scan_vdev_obj) {
455 scm_err("null scan_vdev_obj");
456 return QDF_STATUS_E_NULL_VALUE;
457 }
458
459 scan_vdev_obj->scan_disabled &= ~reason;
460
461 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
462
463 return QDF_STATUS_SUCCESS;
464 }
465
ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev * vdev,enum scan_disable_reason reason)466 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
467 enum scan_disable_reason reason)
468 {
469 struct scan_vdev_obj *scan_vdev_obj;
470
471 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
472 if (!scan_vdev_obj) {
473 scm_err("null scan_vdev_obj");
474 return QDF_STATUS_E_NULL_VALUE;
475 }
476
477 scan_vdev_obj->scan_disabled |= reason;
478
479 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
480
481 return QDF_STATUS_SUCCESS;
482 }
483
484
ucfg_scan_set_miracast(struct wlan_objmgr_psoc * psoc,bool enable)485 QDF_STATUS ucfg_scan_set_miracast(
486 struct wlan_objmgr_psoc *psoc, bool enable)
487 {
488 struct wlan_scan_obj *scan_obj;
489
490 scan_obj = wlan_psoc_get_scan_obj(psoc);
491 if (!scan_obj) {
492 scm_err("Failed to get scan object");
493 return QDF_STATUS_E_NULL_VALUE;
494 }
495 scan_obj->miracast_enabled = enable;
496 scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled);
497
498 return QDF_STATUS_SUCCESS;
499 }
500
501 QDF_STATUS
ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev * pdev,bool enable)502 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable)
503 {
504 uint8_t pdev_id;
505 struct wlan_scan_obj *scan_obj;
506
507 if (!pdev) {
508 scm_warn("null vdev");
509 return QDF_STATUS_E_NULL_VALUE;
510 }
511 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
512 scan_obj = wlan_pdev_get_scan_obj(pdev);
513 if (!scan_obj)
514 return QDF_STATUS_E_FAILURE;
515
516 scm_debug("set wide_band_scan to %d", enable);
517 scan_obj->pdev_info[pdev_id].wide_band_scan = enable;
518
519 return QDF_STATUS_SUCCESS;
520 }
521
ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev * pdev)522 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev)
523 {
524 uint8_t pdev_id;
525 struct wlan_scan_obj *scan_obj;
526
527 if (!pdev) {
528 scm_warn("null vdev");
529 return QDF_STATUS_E_NULL_VALUE;
530 }
531 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
532 scan_obj = wlan_pdev_get_scan_obj(pdev);
533 if (!scan_obj)
534 return QDF_STATUS_E_FAILURE;
535
536 return scan_obj->pdev_info[pdev_id].wide_band_scan;
537 }
538
539 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID
540 QDF_STATUS
ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev * pdev,uint8_t * bssid,struct wlan_ssid * ssid)541 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev,
542 uint8_t *bssid, struct wlan_ssid *ssid)
543 {
544 uint8_t pdev_id;
545 struct wlan_scan_obj *scan_obj;
546
547 if (!pdev) {
548 scm_warn("null vdev");
549 return QDF_STATUS_E_NULL_VALUE;
550 }
551 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
552 scan_obj = wlan_pdev_get_scan_obj(pdev);
553 if (!scan_obj)
554 return QDF_STATUS_E_FAILURE;
555
556 scm_debug("Configure bsssid:" QDF_MAC_ADDR_FMT " ssid:" QDF_SSID_FMT,
557 QDF_MAC_ADDR_REF(bssid),
558 QDF_SSID_REF(ssid->length, ssid->ssid));
559 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid,
560 bssid, QDF_MAC_ADDR_SIZE);
561 scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length;
562 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid,
563 ssid->ssid,
564 scan_obj->pdev_info[pdev_id].conf_ssid.length);
565
566 return QDF_STATUS_SUCCESS;
567 }
568 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */
569
570 QDF_STATUS
ucfg_scan_cancel_sync(struct scan_cancel_request * req)571 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
572 {
573 QDF_STATUS status;
574 bool cancel_vdev = false, cancel_pdev = false;
575 struct wlan_objmgr_vdev *vdev;
576 struct wlan_objmgr_pdev *pdev;
577 uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
578
579 if (!req || !req->vdev) {
580 scm_err("req or vdev within req is NULL");
581 if (req)
582 qdf_mem_free(req);
583 return QDF_STATUS_E_NULL_VALUE;
584 }
585
586 if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL)
587 cancel_pdev = true;
588 else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL ||
589 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL)
590 cancel_vdev = true;
591
592 vdev = req->vdev;
593 status = wlan_scan_cancel(req);
594 if (QDF_IS_STATUS_ERROR(status))
595 return status;
596
597 if (cancel_pdev) {
598 pdev = wlan_vdev_get_pdev(vdev);
599 while ((wlan_get_pdev_status(pdev) !=
600 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
601 scm_debug("wait for all pdev scan to get complete");
602 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
603 max_wait_iterations--;
604 }
605 } else if (cancel_vdev) {
606 while ((wlan_get_vdev_status(vdev) !=
607 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
608 scm_debug("wait for all vdev scan to get complete");
609 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
610 max_wait_iterations--;
611 }
612 }
613
614 if (!max_wait_iterations) {
615 scm_err("Failed to wait for scans to get complete");
616 return QDF_STATUS_E_TIMEOUT;
617 }
618
619 return status;
620 }
621
622 uint8_t*
ucfg_get_scan_requester_name(struct wlan_objmgr_psoc * psoc,wlan_scan_requester requester)623 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
624 wlan_scan_requester requester)
625 {
626 int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
627 struct wlan_scan_obj *scan;
628 struct scan_requester_info *requesters;
629
630 if (!psoc) {
631 scm_err("null psoc");
632 return "null";
633 }
634 scan = wlan_psoc_get_scan_obj(psoc);
635 if (!scan)
636 return "null";
637
638 requesters = scan->requesters;
639
640 if ((idx < WLAN_MAX_REQUESTORS) &&
641 (requesters[idx].requester == requester)) {
642 return requesters[idx].module;
643 }
644
645 return (uint8_t *)"unknown";
646 }
647
648 static QDF_STATUS
scm_add_scan_event_handler(struct pdev_scan_ev_handler * pdev_ev_handler,scan_event_handler event_cb,void * arg)649 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
650 scan_event_handler event_cb, void *arg)
651 {
652 struct cb_handler *cb_handler;
653 uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
654
655 /* Assign next available slot to this registration request */
656 cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
657 cb_handler->func = event_cb;
658 cb_handler->arg = arg;
659 pdev_ev_handler->handler_cnt++;
660
661 return QDF_STATUS_SUCCESS;
662 }
663
664 QDF_STATUS
ucfg_scan_register_event_handler(struct wlan_objmgr_pdev * pdev,scan_event_handler event_cb,void * arg)665 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
666 scan_event_handler event_cb, void *arg)
667 {
668 uint32_t idx;
669 struct wlan_scan_obj *scan;
670 struct pdev_scan_ev_handler *pdev_ev_handler;
671 struct cb_handler *cb_handler;
672
673 /* scan event handler call back can't be NULL */
674 if (!pdev || !event_cb) {
675 scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
676 return QDF_STATUS_E_NULL_VALUE;
677 }
678
679 scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
680
681 scan = wlan_pdev_get_scan_obj(pdev);
682 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
683 if (!pdev_ev_handler) {
684 scm_err("null pdev_ev_handler");
685 return QDF_STATUS_E_NULL_VALUE;
686 }
687 cb_handler = &(pdev_ev_handler->cb_handlers[0]);
688
689 qdf_spin_lock_bh(&scan->lock);
690 /* Ensure its not a duplicate registration request */
691 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
692 idx++, cb_handler++) {
693 if ((cb_handler->func == event_cb) &&
694 (cb_handler->arg == arg)) {
695 qdf_spin_unlock_bh(&scan->lock);
696 scm_debug("func: %pK, arg: %pK already exists",
697 event_cb, arg);
698 return QDF_STATUS_SUCCESS;
699 }
700 }
701
702 QDF_ASSERT(pdev_ev_handler->handler_cnt <
703 MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
704
705 if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
706 qdf_spin_unlock_bh(&scan->lock);
707 scm_warn("No more registrations possible");
708 return QDF_STATUS_E_NOMEM;
709 }
710
711 scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
712 qdf_spin_unlock_bh(&scan->lock);
713
714 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
715
716 return QDF_STATUS_SUCCESS;
717 }
718
719 static QDF_STATUS
wlan_scan_global_init(struct wlan_objmgr_psoc * psoc,struct wlan_scan_obj * scan_obj)720 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
721 struct wlan_scan_obj *scan_obj)
722 {
723 scan_obj->scan_disabled = 0;
724 scan_obj->drop_bcn_on_chan_mismatch =
725 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH);
726 scan_obj->drop_bcn_on_invalid_freq =
727 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ);
728 scan_obj->disable_timeout = false;
729 scan_obj->obss_scan_offload = false;
730 scan_obj->scan_def.active_dwell =
731 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
732 /* the ini is disallow DFS channel scan if ini is 1, so negate that */
733 scan_obj->scan_def.allow_dfs_chan_in_first_scan =
734 !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
735 scan_obj->scan_def.allow_dfs_chan_in_scan =
736 cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
737 scan_obj->scan_def.skip_dfs_chan_in_p2p_search =
738 cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH);
739 scan_obj->scan_def.use_wake_lock_in_user_scan =
740 cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN);
741 scan_obj->scan_def.active_dwell_2g =
742 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
743 scan_obj->scan_def.min_dwell_time_6g =
744 cfg_get(psoc, CFG_MIN_6G_CHANNEL_TIME);
745 scan_obj->scan_def.active_dwell_6g =
746 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME);
747 scan_obj->scan_def.passive_dwell_6g =
748 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME);
749 scan_obj->scan_def.active_dwell_time_6g_conc =
750 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME_CONC);
751 scan_obj->scan_def.passive_dwell_time_6g_conc =
752 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME_CONC);
753 scan_obj->scan_def.passive_dwell =
754 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME);
755 scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
756 scan_obj->scan_def.sta_miracast_mcc_rest_time =
757 SCAN_STA_MIRACAST_MCC_REST_TIME;
758 scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
759 scan_obj->scan_def.conc_active_dwell =
760 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC);
761 scan_obj->scan_def.conc_passive_dwell =
762 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC);
763 scan_obj->scan_def.conc_max_rest_time =
764 cfg_get(psoc, CFG_MAX_REST_TIME_CONC);
765 scan_obj->scan_def.conc_min_rest_time =
766 cfg_get(psoc, CFG_MIN_REST_TIME_CONC);
767 scan_obj->scan_def.conc_idle_time =
768 cfg_get(psoc, CFG_IDLE_TIME_CONC);
769 scan_obj->scan_def.conc_chlist_trim =
770 cfg_get(psoc, CFG_CHAN_LIST_TRIM_CONC);
771 scan_obj->scan_def.repeat_probe_time =
772 cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME);
773 scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
774 scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
775 scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
776 scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
777 scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES);
778 scan_obj->scan_def.scan_cache_aging_time =
779 (cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000);
780 scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
781 scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
782 scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
783 scan_obj->scan_def.adaptive_dwell_time_mode =
784 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE);
785 scan_obj->scan_def.adaptive_dwell_time_mode_nc =
786 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC);
787 scan_obj->scan_def.honour_nl_scan_policy_flags =
788 cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS);
789 scan_obj->scan_def.enable_mac_spoofing =
790 cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING);
791 scan_obj->scan_def.extscan_adaptive_dwell_mode =
792 cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
793
794 /* init burst durations */
795 scan_obj->scan_def.sta_scan_burst_duration =
796 cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION);
797 scan_obj->scan_def.p2p_scan_burst_duration =
798 cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION);
799 scan_obj->scan_def.go_scan_burst_duration =
800 cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION);
801 scan_obj->scan_def.ap_scan_burst_duration =
802 cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION);
803 /* scan control flags */
804 scan_obj->scan_def.scan_f_passive = true;
805 scan_obj->scan_def.scan_f_ofdm_rates = true;
806 scan_obj->scan_def.scan_f_2ghz = true;
807 scan_obj->scan_def.scan_f_5ghz = true;
808 scan_obj->scan_def.scan_f_chan_stat_evnt =
809 cfg_get(psoc, CFG_ENABLE_SNR_MONITORING);
810 /* scan event flags */
811 scan_obj->scan_def.scan_ev_started = true;
812 scan_obj->scan_def.scan_ev_completed = true;
813 scan_obj->scan_def.scan_ev_bss_chan = true;
814 scan_obj->scan_def.scan_ev_foreign_chan = true;
815 scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
816 scan_obj->scan_def.scan_ev_dequeued = true;
817 scan_obj->scan_def.scan_ev_preempted = true;
818 scan_obj->scan_def.scan_ev_start_failed = true;
819 scan_obj->scan_def.scan_ev_restarted = true;
820 scan_obj->scan_def.enable_connected_scan =
821 cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN);
822 scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE);
823 scan_obj->scan_def.duty_cycle_6ghz =
824 cfg_get(psoc, CFG_6GHZ_SCAN_MODE_DUTY_CYCLE);
825 scan_obj->allow_bss_with_incomplete_ie =
826 cfg_get(psoc, CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE);
827
828 scan_obj->scan_def.skip_6g_and_indoor_freq =
829 cfg_get(psoc, CFG_SKIP_6GHZ_AND_INDOOR_FREQ_SCAN);
830 scan_obj->scan_def.last_scan_ageout_time =
831 cfg_get(psoc, CFG_LAST_SCAN_AGEOUT_TIME);
832 scan_obj->aux_mac_support = false;
833
834 /* init scan id seed */
835 qdf_atomic_init(&scan_obj->scan_ids);
836
837 /* init extscan */
838 wlan_extscan_global_init(psoc, scan_obj);
839
840 return wlan_pno_global_init(psoc, scan_obj);
841 }
842
843 static void
wlan_scan_global_deinit(struct wlan_objmgr_psoc * psoc)844 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc)
845 {
846 struct wlan_scan_obj *scan_obj;
847
848 scan_obj = wlan_psoc_get_scan_obj(psoc);
849 wlan_pno_global_deinit(scan_obj);
850 wlan_extscan_global_deinit();
851 }
852
853 static QDF_STATUS
scm_remove_scan_event_handler(struct pdev_scan_ev_handler * pdev_ev_handler,struct cb_handler * entry)854 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
855 struct cb_handler *entry)
856 {
857 struct cb_handler *last_entry;
858 uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
859
860 /* Replace event handler being deleted
861 * with the last one in the list.
862 */
863 last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
864 entry->func = last_entry->func;
865 entry->arg = last_entry->arg;
866
867 /* Clear our last entry */
868 last_entry->func = NULL;
869 last_entry->arg = NULL;
870 pdev_ev_handler->handler_cnt--;
871
872 return QDF_STATUS_SUCCESS;
873 }
874
875 void
ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev * pdev,scan_event_handler event_cb,void * arg)876 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
877 scan_event_handler event_cb, void *arg)
878 {
879 uint8_t found = false;
880 uint32_t idx;
881 uint32_t handler_cnt;
882 struct wlan_scan_obj *scan;
883 struct cb_handler *cb_handler;
884 struct pdev_scan_ev_handler *pdev_ev_handler;
885
886 scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb,
887 arg);
888 if (!pdev) {
889 scm_err("null pdev");
890 return;
891 }
892 scan = wlan_pdev_get_scan_obj(pdev);
893 if (!scan)
894 return;
895
896 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
897 if (!pdev_ev_handler)
898 return;
899
900 cb_handler = &(pdev_ev_handler->cb_handlers[0]);
901
902 qdf_spin_lock_bh(&scan->lock);
903 handler_cnt = pdev_ev_handler->handler_cnt;
904 if (!handler_cnt) {
905 qdf_spin_unlock_bh(&scan->lock);
906 scm_info("No event handlers registered");
907 return;
908 }
909
910 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
911 idx++, cb_handler++) {
912 if ((cb_handler->func == event_cb) &&
913 (cb_handler->arg == arg)) {
914 /* Event handler found, remove it
915 * from event handler list.
916 */
917 found = true;
918 scm_remove_scan_event_handler(pdev_ev_handler,
919 cb_handler);
920 handler_cnt--;
921 break;
922 }
923 }
924 qdf_spin_unlock_bh(&scan->lock);
925
926 scm_debug("event handler %s, remaining handlers: %d",
927 (found ? "removed" : "not found"), handler_cnt);
928 }
929
930 QDF_STATUS
ucfg_scan_init_ssid_params(struct scan_start_request * req,uint32_t num_ssid,struct wlan_ssid * ssid_list)931 ucfg_scan_init_ssid_params(struct scan_start_request *req,
932 uint32_t num_ssid, struct wlan_ssid *ssid_list)
933 {
934 uint32_t max_ssid = sizeof(req->scan_req.ssid) /
935 sizeof(req->scan_req.ssid[0]);
936
937 if (!req) {
938 scm_err("null request");
939 return QDF_STATUS_E_NULL_VALUE;
940 }
941 if (!num_ssid) {
942 /* empty channel list provided */
943 req->scan_req.num_ssids = 0;
944 qdf_mem_zero(&req->scan_req.ssid[0],
945 sizeof(req->scan_req.ssid));
946 return QDF_STATUS_SUCCESS;
947 }
948 if (!ssid_list) {
949 scm_err("null ssid_list while num_ssid: %d", num_ssid);
950 return QDF_STATUS_E_NULL_VALUE;
951 }
952 if (num_ssid > max_ssid) {
953 /* got a big list. alert and continue */
954 scm_warn("overflow: received %d, max supported : %d",
955 num_ssid, max_ssid);
956 return QDF_STATUS_E_E2BIG;
957 }
958
959 if (max_ssid > num_ssid)
960 max_ssid = num_ssid;
961
962 req->scan_req.num_ssids = max_ssid;
963 qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
964 (req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
965
966 return QDF_STATUS_SUCCESS;
967 }
968
969 QDF_STATUS
ucfg_scan_init_bssid_params(struct scan_start_request * req,uint32_t num_bssid,struct qdf_mac_addr * bssid_list)970 ucfg_scan_init_bssid_params(struct scan_start_request *req,
971 uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
972 {
973 uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
974 sizeof(req->scan_req.bssid_list[0]);
975
976 if (!req) {
977 scm_err("null request");
978 return QDF_STATUS_E_NULL_VALUE;
979 }
980 if (!num_bssid) {
981 /* empty channel list provided */
982 req->scan_req.num_bssid = 0;
983 qdf_mem_zero(&req->scan_req.bssid_list[0],
984 sizeof(req->scan_req.bssid_list));
985 return QDF_STATUS_SUCCESS;
986 }
987 if (!bssid_list) {
988 scm_err("null bssid_list while num_bssid: %d", num_bssid);
989 return QDF_STATUS_E_NULL_VALUE;
990 }
991 if (num_bssid > max_bssid) {
992 /* got a big list. alert and continue */
993 scm_warn("overflow: received %d, max supported : %d",
994 num_bssid, max_bssid);
995 return QDF_STATUS_E_E2BIG;
996 }
997
998 if (max_bssid > num_bssid)
999 max_bssid = num_bssid;
1000
1001 req->scan_req.num_bssid = max_bssid;
1002 qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
1003 req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
1004
1005 return QDF_STATUS_SUCCESS;
1006 }
1007
1008 /**
1009 * is_chan_enabled_for_scan() - helper API to check if a frequency
1010 * is allowed to scan.
1011 * @pdev: pointer to pdev
1012 * @reg_chan: regulatory_channel object
1013 * @low_2g: lower 2.4 GHz frequency threshold
1014 * @high_2g: upper 2.4 GHz frequency threshold
1015 * @low_5g: lower 5 GHz frequency threshold
1016 * @high_5g: upper 5 GHz frequency threshold
1017 *
1018 * Return: true if scan is allowed. false otherwise.
1019 */
1020 static bool
is_chan_enabled_for_scan(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * reg_chan,qdf_freq_t low_2g,qdf_freq_t high_2g,qdf_freq_t low_5g,qdf_freq_t high_5g)1021 is_chan_enabled_for_scan(struct wlan_objmgr_pdev *pdev,
1022 struct regulatory_channel *reg_chan,
1023 qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g,
1024 qdf_freq_t high_5g)
1025 {
1026 if (wlan_reg_is_disable_for_pwrmode(pdev,
1027 reg_chan->center_freq,
1028 REG_BEST_PWR_MODE))
1029 return false;
1030
1031 if (reg_chan->nol_chan)
1032 return false;
1033
1034 /* 2 GHz channel */
1035 if ((util_scan_scm_freq_to_band(reg_chan->center_freq) ==
1036 WLAN_BAND_2_4_GHZ) &&
1037 ((reg_chan->center_freq < low_2g) ||
1038 (reg_chan->center_freq > high_2g)))
1039 return false;
1040 else if ((util_scan_scm_freq_to_band(reg_chan->center_freq) ==
1041 WLAN_BAND_5_GHZ) &&
1042 ((reg_chan->center_freq < low_5g) ||
1043 (reg_chan->center_freq > high_5g)))
1044 return false;
1045
1046 return true;
1047 }
1048
1049 QDF_STATUS
ucfg_scan_init_chanlist_params(struct scan_start_request * req,uint32_t num_chans,uint32_t * chan_list,uint32_t * phymode)1050 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1051 uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1052 {
1053 uint32_t idx;
1054 QDF_STATUS status;
1055 struct regulatory_channel *reg_chan_list = NULL;
1056 qdf_freq_t low_2g, high_2g, low_5g, high_5g;
1057 struct wlan_objmgr_pdev *pdev = NULL;
1058 uint32_t *scan_freqs = NULL;
1059 uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1060 sizeof(req->scan_req.chan_list.chan[0]);
1061 if (!req) {
1062 scm_err("null request");
1063 return QDF_STATUS_E_NULL_VALUE;
1064 }
1065
1066 if (req->vdev)
1067 pdev = wlan_vdev_get_pdev(req->vdev);
1068 /*
1069 * If 0 channels are provided for scan and
1070 * wide band scan is enabled, scan all 20 mhz
1071 * available channels. This is required as FW
1072 * scans all channel/phy mode combinations
1073 * provided in scan channel list if 0 chans are
1074 * provided in scan request causing scan to take
1075 * too much time to complete.
1076 */
1077 if (pdev && !num_chans) {
1078 reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1079 sizeof(struct regulatory_channel));
1080 if (!reg_chan_list) {
1081 status = QDF_STATUS_E_NOMEM;
1082 goto end;
1083 }
1084 scan_freqs =
1085 qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1086 if (!scan_freqs) {
1087 status = QDF_STATUS_E_NOMEM;
1088 goto end;
1089 }
1090 status = wlan_reg_get_current_chan_list(pdev, reg_chan_list);
1091 if (QDF_IS_STATUS_ERROR(status))
1092 goto end;
1093
1094 status = wlan_reg_get_freq_range(pdev, &low_2g,
1095 &high_2g, &low_5g, &high_5g);
1096 if (QDF_IS_STATUS_ERROR(status))
1097 goto end;
1098
1099 for (idx = 0, num_chans = 0;
1100 (idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1101 if ((is_chan_enabled_for_scan(pdev,
1102 ®_chan_list[idx],
1103 low_2g, high_2g,
1104 low_5g, high_5g)) &&
1105 ((req->scan_req.scan_f_2ghz &&
1106 WLAN_REG_IS_24GHZ_CH_FREQ(
1107 reg_chan_list[idx].center_freq)) ||
1108 (req->scan_req.scan_f_5ghz &&
1109 (WLAN_REG_IS_5GHZ_CH_FREQ(
1110 reg_chan_list[idx].center_freq) ||
1111 WLAN_REG_IS_49GHZ_FREQ(
1112 reg_chan_list[idx].center_freq) ||
1113 WLAN_REG_IS_6GHZ_CHAN_FREQ(
1114 reg_chan_list[idx].center_freq)))))
1115 scan_freqs[num_chans++] =
1116 reg_chan_list[idx].center_freq;
1117
1118 chan_list = scan_freqs;
1119 }
1120
1121 if (!num_chans) {
1122 /* empty channel list provided */
1123 qdf_mem_zero(&req->scan_req.chan_list,
1124 sizeof(req->scan_req.chan_list));
1125 req->scan_req.chan_list.num_chan = 0;
1126 status = QDF_STATUS_SUCCESS;
1127 goto end;
1128 }
1129 if (!chan_list) {
1130 scm_info("null chan_list while num_chans: %d", num_chans);
1131 status = QDF_STATUS_E_NULL_VALUE;
1132 goto end;
1133 }
1134
1135 if (num_chans > max_chans) {
1136 /* got a big list. alert and fail */
1137 scm_warn("overflow: received %d, max supported : %d",
1138 num_chans, max_chans);
1139 status = QDF_STATUS_E_E2BIG;
1140 goto end;
1141 }
1142
1143 req->scan_req.chan_list.num_chan = num_chans;
1144 for (idx = 0; idx < num_chans; idx++) {
1145 req->scan_req.chan_list.chan[idx].freq =
1146 (chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1147 chan_list[idx] :
1148 wlan_reg_legacy_chan_to_freq(pdev, chan_list[idx]);
1149 if (phymode)
1150 req->scan_req.chan_list.chan[idx].phymode =
1151 phymode[idx];
1152 else if (req->scan_req.chan_list.chan[idx].freq <=
1153 WLAN_CHAN_15_FREQ)
1154 req->scan_req.chan_list.chan[idx].phymode =
1155 SCAN_PHY_MODE_11G;
1156 else if (req->scan_req.chan_list.chan[idx].freq <=
1157 WLAN_REG_MAX_5GHZ_CHAN_FREQ)
1158 req->scan_req.chan_list.chan[idx].phymode =
1159 SCAN_PHY_MODE_11A;
1160 else
1161 req->scan_req.chan_list.chan[idx].phymode =
1162 SCAN_PHY_MODE_11AX_HE20;
1163 }
1164
1165 end:
1166 if (scan_freqs)
1167 qdf_mem_free(scan_freqs);
1168
1169 if (reg_chan_list)
1170 qdf_mem_free(reg_chan_list);
1171
1172 return QDF_STATUS_SUCCESS;
1173 }
1174
1175 enum scm_scan_status
ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev * vdev)1176 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1177 {
1178 return wlan_get_vdev_status(vdev);
1179 }
1180
1181 enum scm_scan_status
ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev * pdev)1182 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1183 {
1184 return wlan_get_pdev_status(pdev);
1185 }
1186
1187 static void
scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc * psoc,bool enable)1188 scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1189 bool enable)
1190 {
1191 QDF_STATUS status;
1192 struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1193
1194 cb_info[0].frm_type = MGMT_PROBE_RESP;
1195 cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1196 cb_info[1].frm_type = MGMT_BEACON;
1197 cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1198
1199 if (enable)
1200 status = wlan_mgmt_txrx_register_rx_cb(psoc,
1201 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1202 else
1203 status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1204 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1205 if (status != QDF_STATUS_SUCCESS)
1206 scm_err("%s the Handle with MGMT TXRX layer has failed",
1207 enable ? "Registering" : "Deregistering");
1208 }
1209
ucfg_scan_update_user_config(struct wlan_objmgr_psoc * psoc,struct scan_user_cfg * scan_cfg)1210 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1211 struct scan_user_cfg *scan_cfg)
1212 {
1213 struct wlan_scan_obj *scan_obj;
1214 struct scan_default_params *scan_def;
1215
1216 if (!psoc) {
1217 scm_err("null psoc");
1218 return QDF_STATUS_E_FAILURE;
1219 }
1220 scan_obj = wlan_psoc_get_scan_obj(psoc);
1221 if (!scan_obj) {
1222 scm_err("Failed to get scan object");
1223 return QDF_STATUS_E_FAILURE;
1224 }
1225
1226 scan_def = &scan_obj->scan_def;
1227 scan_obj->ie_allowlist = scan_cfg->ie_allowlist;
1228 scan_def->sta_miracast_mcc_rest_time =
1229 scan_cfg->sta_miracast_mcc_rest_time;
1230
1231 return QDF_STATUS_SUCCESS;
1232 }
1233
1234 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1235 static QDF_STATUS
scan_cancel_pdev_scan(struct wlan_objmgr_pdev * pdev)1236 scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
1237 {
1238 struct scan_cancel_request *req;
1239 QDF_STATUS status;
1240 struct wlan_objmgr_vdev *vdev;
1241
1242 req = qdf_mem_malloc_atomic(sizeof(*req));
1243 if (!req) {
1244 scm_err("Failed to allocate memory");
1245 return QDF_STATUS_E_NOMEM;
1246 }
1247
1248 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID);
1249 if (!vdev) {
1250 scm_err("Failed to get vdev");
1251 qdf_mem_free(req);
1252 return QDF_STATUS_E_INVAL;
1253 }
1254 req->vdev = vdev;
1255 req->cancel_req.scan_id = INVAL_SCAN_ID;
1256 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1257 req->cancel_req.vdev_id = INVAL_VDEV_ID;
1258 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1259 status = ucfg_scan_cancel_sync(req);
1260 if (QDF_IS_STATUS_ERROR(status))
1261 scm_err("Cancel scan request failed");
1262 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1263
1264 return status;
1265 }
1266
1267 static QDF_STATUS
ucfg_scan_suspend_handler(struct wlan_objmgr_psoc * psoc,void * arg)1268 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1269 {
1270 struct wlan_objmgr_pdev *pdev = NULL;
1271 QDF_STATUS status = QDF_STATUS_SUCCESS;
1272 int i;
1273 wlan_scan_psoc_set_disable(psoc, REASON_SUSPEND);
1274
1275 /* Check all pdev */
1276 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
1277 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
1278 if (!pdev)
1279 continue;
1280 if (wlan_get_pdev_status(pdev) != SCAN_NOT_IN_PROGRESS)
1281 status = scan_cancel_pdev_scan(pdev);
1282 scm_disable_obss_pdev_scan(psoc, pdev);
1283 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
1284 if (QDF_IS_STATUS_ERROR(status)) {
1285 scm_err("failed to cancel scan for pdev_id %d", i);
1286 return status;
1287 }
1288 }
1289
1290 return QDF_STATUS_SUCCESS;
1291 }
1292
1293 static QDF_STATUS
ucfg_scan_resume_handler(struct wlan_objmgr_psoc * psoc,void * arg)1294 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1295 {
1296 wlan_scan_psoc_set_enable(psoc, REASON_SUSPEND);
1297 return QDF_STATUS_SUCCESS;
1298 }
1299
1300 static inline void
scan_register_pmo_handler(void)1301 scan_register_pmo_handler(void)
1302 {
1303 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
1304 ucfg_scan_suspend_handler, NULL);
1305 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
1306 ucfg_scan_resume_handler, NULL);
1307 }
1308
1309 static inline void
scan_unregister_pmo_handler(void)1310 scan_unregister_pmo_handler(void)
1311 {
1312 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
1313 ucfg_scan_suspend_handler);
1314 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
1315 ucfg_scan_resume_handler);
1316 }
1317
1318 #else
1319 static inline void
scan_register_pmo_handler(void)1320 scan_register_pmo_handler(void)
1321 {
1322 }
1323
1324 static inline void
scan_unregister_pmo_handler(void)1325 scan_unregister_pmo_handler(void)
1326 {
1327 }
1328 #endif
1329
1330 QDF_STATUS
ucfg_scan_psoc_open(struct wlan_objmgr_psoc * psoc)1331 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
1332 {
1333 struct wlan_scan_obj *scan_obj;
1334
1335 scm_debug("psoc open: 0x%pK", psoc);
1336 if (!psoc) {
1337 scm_err("null psoc");
1338 return QDF_STATUS_E_FAILURE;
1339 }
1340 scan_obj = wlan_psoc_get_scan_obj(psoc);
1341 if (!scan_obj) {
1342 scm_err("Failed to get scan object");
1343 return QDF_STATUS_E_FAILURE;
1344 }
1345 /* Initialize the scan Globals */
1346 wlan_scan_global_init(psoc, scan_obj);
1347 qdf_spinlock_create(&scan_obj->lock);
1348 scan_register_pmo_handler();
1349 scm_db_init(psoc);
1350 scm_channel_list_db_init(psoc);
1351
1352 return QDF_STATUS_SUCCESS;
1353 }
1354
1355 QDF_STATUS
ucfg_scan_psoc_close(struct wlan_objmgr_psoc * psoc)1356 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
1357 {
1358 struct wlan_scan_obj *scan_obj;
1359
1360 scm_debug("psoc close: 0x%pK", psoc);
1361 if (!psoc) {
1362 scm_err("null psoc");
1363 return QDF_STATUS_E_FAILURE;
1364 }
1365 scm_db_deinit(psoc);
1366 scan_obj = wlan_psoc_get_scan_obj(psoc);
1367 if (!scan_obj) {
1368 scm_err("Failed to get scan object");
1369 return QDF_STATUS_E_FAILURE;
1370 }
1371 scan_unregister_pmo_handler();
1372 qdf_spinlock_destroy(&scan_obj->lock);
1373 wlan_scan_global_deinit(psoc);
1374 scm_channel_list_db_deinit(psoc);
1375
1376 return QDF_STATUS_SUCCESS;
1377 }
1378
scm_serialization_scan_rules_cb(union wlan_serialization_rules_info * comp_info,uint8_t comp_id)1379 static bool scm_serialization_scan_rules_cb(
1380 union wlan_serialization_rules_info *comp_info,
1381 uint8_t comp_id)
1382 {
1383 switch (comp_id) {
1384 case WLAN_UMAC_COMP_TDLS:
1385 if (comp_info->scan_info.is_tdls_in_progress) {
1386 scm_debug("Cancel scan. Tdls in progress");
1387 return false;
1388 }
1389 break;
1390 case WLAN_UMAC_COMP_DFS:
1391 if (comp_info->scan_info.is_cac_in_progress) {
1392 scm_debug("Cancel scan. CAC in progress");
1393 return false;
1394 }
1395 break;
1396 case WLAN_UMAC_COMP_MLME:
1397 if (comp_info->scan_info.is_scan_for_connect) {
1398 scm_debug("Allow scan request from connect");
1399 return true;
1400 }
1401
1402 if (comp_info->scan_info.is_mlme_op_in_progress) {
1403 scm_debug("Cancel scan. MLME operation in progress");
1404 return false;
1405 }
1406 break;
1407 default:
1408 scm_debug("not handled comp_id %d", comp_id);
1409 break;
1410 }
1411
1412 return true;
1413 }
1414
1415 QDF_STATUS
ucfg_scan_psoc_enable(struct wlan_objmgr_psoc * psoc)1416 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
1417 {
1418 QDF_STATUS status;
1419
1420 scm_debug("psoc enable: 0x%pK", psoc);
1421 if (!psoc) {
1422 scm_err("null psoc");
1423 return QDF_STATUS_E_FAILURE;
1424 }
1425 /* Subscribe for scan events from lmac layesr */
1426 status = tgt_scan_register_ev_handler(psoc);
1427 QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1428 if (!wlan_reg_is_11d_offloaded(psoc))
1429 scm_11d_cc_db_init(psoc);
1430 scan_register_unregister_bcn_cb(psoc, true);
1431 status = wlan_serialization_register_apply_rules_cb(psoc,
1432 WLAN_SER_CMD_SCAN,
1433 scm_serialization_scan_rules_cb);
1434 QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1435 return status;
1436 }
1437
1438 QDF_STATUS
ucfg_scan_psoc_disable(struct wlan_objmgr_psoc * psoc)1439 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
1440 {
1441 QDF_STATUS status;
1442
1443 scm_debug("psoc disable: 0x%pK", psoc);
1444 if (!psoc) {
1445 scm_err("null psoc");
1446 return QDF_STATUS_E_FAILURE;
1447 }
1448 /* Unsubscribe for scan events from lmac layesr */
1449 status = tgt_scan_unregister_ev_handler(psoc);
1450 QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1451 scan_register_unregister_bcn_cb(psoc, false);
1452 if (!wlan_reg_is_11d_offloaded(psoc))
1453 scm_11d_cc_db_deinit(psoc);
1454
1455 return status;
1456 }
1457
1458 uint32_t
ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc * psoc)1459 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
1460 {
1461 struct scan_default_params *scan_params = NULL;
1462
1463 if (!psoc) {
1464 scm_err("null psoc");
1465 return 0;
1466 }
1467 scan_params = wlan_scan_psoc_get_def_params(psoc);
1468 if (!scan_params) {
1469 scm_err("Failed to get scan object");
1470 return 0;
1471 }
1472
1473 return scan_params->max_active_scans_allowed;
1474 }
1475
ucfg_copy_ie_allowlist_attrs(struct wlan_objmgr_psoc * psoc,struct probe_req_allowlist_attr * ie_allowlist)1476 bool ucfg_copy_ie_allowlist_attrs(struct wlan_objmgr_psoc *psoc,
1477 struct probe_req_allowlist_attr *ie_allowlist)
1478 {
1479 struct wlan_scan_obj *scan_obj = NULL;
1480
1481 scan_obj = wlan_psoc_get_scan_obj(psoc);
1482 if (!scan_obj)
1483 return false;
1484
1485 qdf_mem_copy(ie_allowlist, &scan_obj->ie_allowlist,
1486 sizeof(*ie_allowlist));
1487
1488 return true;
1489 }
1490
ucfg_ie_allowlist_enabled(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)1491 bool ucfg_ie_allowlist_enabled(struct wlan_objmgr_psoc *psoc,
1492 struct wlan_objmgr_vdev *vdev)
1493 {
1494 struct wlan_scan_obj *scan_obj = NULL;
1495
1496 scan_obj = wlan_psoc_get_scan_obj(psoc);
1497 if (!scan_obj)
1498 return false;
1499
1500 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1501 wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
1502 return false;
1503
1504 if (!scan_obj->ie_allowlist.allow_list)
1505 return false;
1506
1507 return true;
1508 }
1509
ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc * psoc,bool bt_a2dp_active)1510 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
1511 bool bt_a2dp_active)
1512 {
1513 struct wlan_scan_obj *scan_obj;
1514
1515 scan_obj = wlan_psoc_get_scan_obj(psoc);
1516 if (!scan_obj) {
1517 scm_err("Failed to get scan object");
1518 return;
1519 }
1520 scan_obj->bt_a2dp_enabled = bt_a2dp_active;
1521 }
1522
ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc * psoc)1523 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
1524 {
1525 struct wlan_scan_obj *scan_obj;
1526
1527 scan_obj = wlan_psoc_get_scan_obj(psoc);
1528 if (!scan_obj) {
1529 scm_err("Failed to get scan object");
1530 return false;
1531 }
1532
1533 return scan_obj->bt_a2dp_enabled;
1534 }
1535
ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc * psoc)1536 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc)
1537 {
1538 struct wlan_scan_obj *scan_obj;
1539
1540 scan_obj = wlan_psoc_get_scan_obj(psoc);
1541 if (!scan_obj)
1542 return false;
1543
1544 return scan_obj->scan_def.use_wake_lock_in_user_scan;
1545 }
1546
ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc * psoc)1547 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
1548 {
1549 struct wlan_scan_obj *scan_obj;
1550
1551 scan_obj = wlan_psoc_get_scan_obj(psoc);
1552 if (!scan_obj) {
1553 scm_err("Failed to get scan object");
1554 return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
1555 }
1556
1557 return scan_obj->scan_def.enable_connected_scan;
1558 }
1559
ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc * psoc)1560 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc)
1561 {
1562 struct wlan_scan_obj *scan_obj;
1563
1564 scan_obj = wlan_psoc_get_scan_obj(psoc);
1565 if (!scan_obj) {
1566 scm_err("Failed to get scan object");
1567 return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING);
1568 }
1569
1570 return scan_obj->scan_def.enable_mac_spoofing;
1571 }
1572
1573 enum scan_dwelltime_adaptive_mode
ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc * psoc)1574 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc)
1575 {
1576 struct wlan_scan_obj *scan_obj;
1577
1578 scan_obj = wlan_psoc_get_scan_obj(psoc);
1579 if (!scan_obj) {
1580 scm_err("Failed to get scan object");
1581 return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
1582 }
1583
1584 return scan_obj->scan_def.extscan_adaptive_dwell_mode;
1585 }
1586
1587 QDF_STATUS
ucfg_scan_set_global_config(struct wlan_objmgr_psoc * psoc,enum scan_config config,uint32_t val)1588 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
1589 enum scan_config config, uint32_t val)
1590 {
1591 struct wlan_scan_obj *scan_obj;
1592 QDF_STATUS status = QDF_STATUS_SUCCESS;
1593
1594 scan_obj = wlan_psoc_get_scan_obj(psoc);
1595 if (!scan_obj) {
1596 scm_err("Failed to get scan object config:%d, val:%d",
1597 config, val);
1598 return QDF_STATUS_E_INVAL;
1599 }
1600 switch (config) {
1601 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1602 scan_obj->disable_timeout = !!val;
1603 break;
1604 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1605 scan_obj->drop_bcn_on_chan_mismatch = !!val;
1606 break;
1607
1608 default:
1609 status = QDF_STATUS_E_INVAL;
1610 break;
1611 }
1612
1613 return status;
1614 }
1615
1616 QDF_STATUS
ucfg_scan_get_global_config(struct wlan_objmgr_psoc * psoc,enum scan_config config,uint32_t * val)1617 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
1618 enum scan_config config, uint32_t *val)
1619 {
1620 struct wlan_scan_obj *scan_obj;
1621 QDF_STATUS status = QDF_STATUS_SUCCESS;
1622
1623 scan_obj = wlan_psoc_get_scan_obj(psoc);
1624 if (!scan_obj || !val) {
1625 scm_err("scan object:%pK config:%d, val:0x%pK",
1626 scan_obj, config, val);
1627 return QDF_STATUS_E_INVAL;
1628 }
1629 switch (config) {
1630 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1631 *val = scan_obj->disable_timeout;
1632 break;
1633 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1634 *val = scan_obj->drop_bcn_on_chan_mismatch;
1635 break;
1636
1637 default:
1638 status = QDF_STATUS_E_INVAL;
1639 break;
1640 }
1641
1642 return status;
1643 }
1644
ucfg_scan_set_obss_scan_offload(struct wlan_objmgr_psoc * psoc,bool value)1645 void ucfg_scan_set_obss_scan_offload(struct wlan_objmgr_psoc *psoc, bool value)
1646 {
1647 struct wlan_scan_obj *scan_obj;
1648
1649 scan_obj = wlan_psoc_get_scan_obj(psoc);
1650 if (!scan_obj) {
1651 scm_err("NULL scan obj");
1652 return;
1653 }
1654
1655 scan_obj->obss_scan_offload = value;
1656 }
1657
1658 #ifdef FEATURE_WLAN_SCAN_PNO
ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc * psoc)1659 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc)
1660 {
1661 struct wlan_scan_obj *scan_obj;
1662
1663 scan_obj = wlan_psoc_get_scan_obj(psoc);
1664 if (!scan_obj) {
1665 scm_err("NULL scan obj");
1666 return false;
1667 }
1668
1669 return scan_obj->pno_cfg.pno_offload_enabled;
1670 }
1671
ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc * psoc,bool value)1672 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value)
1673 {
1674 struct wlan_scan_obj *scan_obj;
1675
1676 scan_obj = wlan_psoc_get_scan_obj(psoc);
1677 if (!scan_obj) {
1678 scm_err("NULL scan obj");
1679 return;
1680 }
1681
1682 scan_obj->pno_cfg.pno_offload_enabled = value;
1683 }
1684
ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc * psoc)1685 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
1686 {
1687 struct wlan_scan_obj *scan_obj;
1688
1689 scan_obj = wlan_psoc_get_scan_obj(psoc);
1690 if (!scan_obj) {
1691 scm_err("NULL scan obj");
1692 return cfg_default(CFG_PNO_SCAN_SUPPORT);
1693 }
1694
1695 return scan_obj->pno_cfg.scan_support_enabled;
1696 }
1697
ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc * psoc)1698 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc)
1699 {
1700 struct wlan_scan_obj *scan_obj;
1701
1702 scan_obj = wlan_psoc_get_scan_obj(psoc);
1703 if (!scan_obj) {
1704 scm_err("NULL scan obj");
1705 return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER);
1706 }
1707 return scan_obj->pno_cfg.scan_backoff_multiplier;
1708 }
1709
ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc * psoc)1710 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc)
1711 {
1712 struct wlan_scan_obj *scan_obj;
1713
1714 scan_obj = wlan_psoc_get_scan_obj(psoc);
1715 if (!scan_obj) {
1716 scm_err("NULL scan obj");
1717 return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN);
1718 }
1719 return scan_obj->pno_cfg.dfs_chnl_scan_enabled;
1720 }
1721
ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc * psoc)1722 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc)
1723 {
1724 struct wlan_scan_obj *scan_obj;
1725
1726 scan_obj = wlan_psoc_get_scan_obj(psoc);
1727 if (!scan_obj) {
1728 scm_err("NULL scan obj");
1729 return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
1730 }
1731 return scan_obj->pno_cfg.scan_timer_repeat_value;
1732 }
1733
ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc * psoc)1734 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc)
1735 {
1736 struct wlan_scan_obj *scan_obj;
1737
1738 scan_obj = wlan_psoc_get_scan_obj(psoc);
1739 if (!scan_obj) {
1740 scm_err("NULL scan obj");
1741 return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER);
1742 }
1743 return scan_obj->pno_cfg.slow_scan_multiplier;
1744 }
1745
1746 uint32_t
ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc * psoc)1747 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc)
1748 {
1749 struct wlan_scan_obj *scan_obj;
1750
1751 scan_obj = wlan_psoc_get_scan_obj(psoc);
1752 if (!scan_obj) {
1753 scm_err("Failed to get scan object");
1754 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
1755 }
1756
1757 return scan_obj->pno_cfg.max_sched_scan_plan_interval;
1758 }
1759
1760 uint32_t
ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc * psoc)1761 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc)
1762 {
1763 struct wlan_scan_obj *scan_obj;
1764
1765 scan_obj = wlan_psoc_get_scan_obj(psoc);
1766 if (!scan_obj) {
1767 scm_err("Failed to get scan object");
1768 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
1769 }
1770
1771 return scan_obj->pno_cfg.max_sched_scan_plan_iterations;
1772 }
1773
1774 bool
ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc * psoc)1775 ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc)
1776 {
1777 struct wlan_scan_obj *scan_obj;
1778
1779 scan_obj = wlan_psoc_get_scan_obj(psoc);
1780 if (!scan_obj) {
1781 scm_err("Failed to get scan object");
1782 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
1783 }
1784
1785 return scan_obj->pno_cfg.user_config_sched_scan_plan;
1786 }
1787 #endif
1788