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