xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c (revision bea437e2293c3d4fb1b5704fcf633aedac996962)
1 /*
2  * Copyright (c) 2017-2019 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_E_ALREADY;
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 start 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 	mawc_cfg = &pno_def->mawc_params;
241 	pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION);
242 	pno_def->top_k_num_of_channels =
243 			cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS);
244 	pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD);
245 	pno_def->channel_prediction_full_scan =
246 			cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER);
247 	pno_def->adaptive_dwell_mode =
248 			cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE);
249 	pno_def->dfs_chnl_scan_enabled =
250 			cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN);
251 	pno_def->scan_support_enabled =
252 			cfg_get(psoc, CFG_PNO_SCAN_SUPPORT);
253 	pno_def->scan_timer_repeat_value =
254 			cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
255 	pno_def->slow_scan_multiplier =
256 			cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER);
257 	pno_def->scan_backoff_multiplier =
258 			cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER);
259 	pno_def->max_sched_scan_plan_interval =
260 			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
261 	pno_def->max_sched_scan_plan_iterations =
262 			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
263 
264 	mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED);
265 	mawc_cfg->exp_backoff_ratio =
266 			cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO);
267 	mawc_cfg->init_scan_interval =
268 			cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL);
269 	mawc_cfg->max_scan_interval =
270 			cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL);
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 
275 static QDF_STATUS
276 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
277 {
278 	qdf_wake_lock_destroy(&scan_obj->pno_cfg.pno_wake_lock);
279 
280 	return QDF_STATUS_SUCCESS;
281 }
282 
283 #ifdef WLAN_POLICY_MGR_ENABLE
284 /*
285  * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time
286  * depending on active concurrency modes
287  * @vdev: vdev object pointer
288  * @req: scan request
289  *
290  * Return: void
291  */
292 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
293 	struct pno_scan_req_params *req, struct scan_default_params *scan_def)
294 {
295 	bool sap_or_p2p_present;
296 	struct wlan_objmgr_psoc *psoc;
297 
298 	psoc = wlan_vdev_get_psoc(vdev);
299 
300 	if (!psoc)
301 		return;
302 
303 	sap_or_p2p_present = policy_mgr_mode_specific_connection_count(
304 				psoc, PM_SAP_MODE, NULL) ||
305 				policy_mgr_mode_specific_connection_count(
306 				psoc, PM_P2P_GO_MODE, NULL) ||
307 				policy_mgr_mode_specific_connection_count(
308 				psoc, PM_P2P_CLIENT_MODE, NULL);
309 
310 	if (sap_or_p2p_present) {
311 		req->active_dwell_time = scan_def->conc_active_dwell;
312 		req->passive_dwell_time = scan_def->conc_passive_dwell;
313 	}
314 
315 }
316 #else
317 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
318 	struct pno_scan_req_params *req, struct scan_default_params *scan_def){}
319 #endif
320 
321 QDF_STATUS
322 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
323 	struct pno_scan_req_params *req)
324 {
325 	struct scan_default_params *scan_def;
326 	struct wlan_scan_obj *scan;
327 	struct pno_def_config *pno_def;
328 
329 	if (!vdev || !req) {
330 		scm_err("vdev: 0x%pK, req: 0x%pK",
331 			vdev, req);
332 		return QDF_STATUS_E_INVAL;
333 	}
334 
335 	scan = wlan_vdev_get_scan_obj(vdev);
336 	if (!scan) {
337 		scm_err("scan is NULL");
338 		return QDF_STATUS_E_INVAL;
339 	}
340 	scan_def = wlan_vdev_get_def_scan_params(vdev);
341 	if (!scan_def) {
342 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
343 		return QDF_STATUS_E_NULL_VALUE;
344 	}
345 
346 	pno_def = &scan->pno_cfg;
347 	req->active_dwell_time = scan_def->active_dwell;
348 	req->passive_dwell_time = scan_def->passive_dwell;
349 	req->scan_random.randomize = scan_def->enable_mac_spoofing;
350 
351 	/*
352 	 *  Update active and passive dwell time depending
353 	 *  upon the present active concurrency mode
354 	 */
355 	ucfg_scan_update_pno_dwell_time(vdev, req, scan_def);
356 	req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
357 	req->pno_channel_prediction = pno_def->channel_prediction;
358 	req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
359 	req->stationary_thresh = pno_def->stationary_thresh;
360 	req->channel_prediction_full_scan =
361 			pno_def->channel_prediction_full_scan;
362 	req->mawc_params.vdev_id = wlan_vdev_get_id(vdev);
363 	qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params,
364 			sizeof(req->mawc_params));
365 
366 	return QDF_STATUS_SUCCESS;
367 }
368 
369 QDF_STATUS
370 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
371 	scan_event_handler event_cb, void *arg)
372 {
373 	struct wlan_scan_obj *scan;
374 
375 	if (!psoc) {
376 		scm_err("null psoc");
377 		return QDF_STATUS_E_INVAL;
378 	}
379 
380 	scan = wlan_psoc_get_scan_obj(psoc);
381 	if (!scan) {
382 		scm_err("scan object null");
383 		return QDF_STATUS_E_INVAL;
384 	}
385 
386 	qdf_spin_lock_bh(&scan->lock);
387 	scan->pno_cfg.pno_cb.func = event_cb;
388 	scan->pno_cfg.pno_cb.arg = arg;
389 	qdf_spin_unlock_bh(&scan->lock);
390 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
391 
392 	return QDF_STATUS_SUCCESS;
393 }
394 
395 #else
396 
397 static inline QDF_STATUS
398 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
399 		     struct wlan_scan_obj *scan_obj)
400 {
401 	return QDF_STATUS_SUCCESS;
402 }
403 
404 static inline QDF_STATUS
405 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
406 {
407 	return QDF_STATUS_SUCCESS;
408 }
409 
410 #endif
411 
412 QDF_STATUS
413 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
414 				    struct chan_list *chan_list)
415 {
416 	uint8_t pdev_id;
417 	struct wlan_scan_obj *scan_obj;
418 
419 	if (!pdev || !chan_list) {
420 		scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list);
421 		return QDF_STATUS_E_NULL_VALUE;
422 	}
423 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
424 	scan_obj = wlan_pdev_get_scan_obj(pdev);
425 
426 	qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list,
427 			chan_list, sizeof(*chan_list));
428 
429 	return QDF_STATUS_SUCCESS;
430 }
431 
432 QDF_STATUS
433 ucfg_scan_start(struct scan_start_request *req)
434 {
435 	struct scheduler_msg msg = {0};
436 	QDF_STATUS status;
437 
438 	if (!req || !req->vdev) {
439 		scm_err("req or vdev within req is NULL");
440 		if (req)
441 			scm_scan_free_scan_request_mem(req);
442 		return QDF_STATUS_E_NULL_VALUE;
443 	}
444 
445 	if (!scm_is_scan_allowed(req->vdev)) {
446 		scm_err("scan disabled, rejecting the scan req");
447 		scm_scan_free_scan_request_mem(req);
448 		return QDF_STATUS_E_AGAIN;
449 	}
450 
451 	scm_debug("reqid: %d, scanid: %d, vdevid: %d",
452 		  req->scan_req.scan_req_id, req->scan_req.scan_id,
453 		  req->scan_req.vdev_id);
454 
455 	/* Try to get vdev reference. Return if reference could
456 	 * not be taken. Reference will be released once scan
457 	 * request handling completes along with free of @req.
458 	 */
459 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
460 	if (QDF_IS_STATUS_ERROR(status)) {
461 		scm_info("unable to get reference");
462 		scm_scan_free_scan_request_mem(req);
463 		return status;
464 	}
465 
466 	msg.bodyptr = req;
467 	msg.callback = scm_scan_start_req;
468 	msg.flush_callback = scm_scan_start_flush_callback;
469 
470 	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
471 					QDF_MODULE_ID_SCAN,
472 					QDF_MODULE_ID_OS_IF, &msg);
473 	if (QDF_IS_STATUS_ERROR(status)) {
474 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
475 		scm_scan_free_scan_request_mem(req);
476 	}
477 
478 	return status;
479 }
480 
481 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
482 				     enum scan_disable_reason reason)
483 {
484 	struct wlan_scan_obj *scan_obj;
485 
486 	scan_obj = wlan_psoc_get_scan_obj(psoc);
487 	if (!scan_obj) {
488 		scm_err("Failed to get scan object");
489 		return QDF_STATUS_E_NULL_VALUE;
490 	}
491 
492 	scan_obj->scan_disabled &= ~reason;
493 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
494 
495 	return QDF_STATUS_SUCCESS;
496 }
497 
498 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
499 				      enum scan_disable_reason reason)
500 {
501 	struct wlan_scan_obj *scan_obj;
502 
503 	scan_obj = wlan_psoc_get_scan_obj(psoc);
504 	if (!scan_obj) {
505 		scm_err("Failed to get scan object");
506 		return QDF_STATUS_E_NULL_VALUE;
507 	}
508 
509 	scan_obj->scan_disabled |= reason;
510 
511 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
512 
513 	return QDF_STATUS_SUCCESS;
514 }
515 
516 
517 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
518 				     enum scan_disable_reason reason)
519 {
520 	struct scan_vdev_obj *scan_vdev_obj;
521 
522 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
523 	if (!scan_vdev_obj) {
524 		scm_err("null scan_vdev_obj");
525 		return QDF_STATUS_E_NULL_VALUE;
526 	}
527 
528 	scan_vdev_obj->scan_disabled &= ~reason;
529 
530 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
531 
532 	return QDF_STATUS_SUCCESS;
533 }
534 
535 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
536 				      enum scan_disable_reason reason)
537 {
538 	struct scan_vdev_obj *scan_vdev_obj;
539 
540 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
541 	if (!scan_vdev_obj) {
542 		scm_err("null scan_vdev_obj");
543 		return QDF_STATUS_E_NULL_VALUE;
544 	}
545 
546 	scan_vdev_obj->scan_disabled |= reason;
547 
548 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
549 
550 	return QDF_STATUS_SUCCESS;
551 }
552 
553 
554 QDF_STATUS ucfg_scan_set_miracast(
555 	struct wlan_objmgr_psoc *psoc, bool enable)
556 {
557 	struct wlan_scan_obj *scan_obj;
558 
559 	scan_obj = wlan_psoc_get_scan_obj(psoc);
560 	if (!scan_obj) {
561 		scm_err("Failed to get scan object");
562 		return QDF_STATUS_E_NULL_VALUE;
563 	}
564 	scan_obj->miracast_enabled = enable;
565 	scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled);
566 
567 	return QDF_STATUS_SUCCESS;
568 }
569 
570 QDF_STATUS
571 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable)
572 {
573 	uint8_t pdev_id;
574 	struct wlan_scan_obj *scan_obj;
575 
576 	if (!pdev) {
577 		scm_warn("null vdev");
578 		return QDF_STATUS_E_NULL_VALUE;
579 	}
580 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
581 	scan_obj = wlan_pdev_get_scan_obj(pdev);
582 	if (!scan_obj)
583 		return QDF_STATUS_E_FAILURE;
584 
585 	scm_debug("set wide_band_scan to %d", enable);
586 	scan_obj->pdev_info[pdev_id].wide_band_scan = enable;
587 
588 	return QDF_STATUS_SUCCESS;
589 }
590 
591 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev)
592 {
593 	uint8_t pdev_id;
594 	struct wlan_scan_obj *scan_obj;
595 
596 	if (!pdev) {
597 		scm_warn("null vdev");
598 		return QDF_STATUS_E_NULL_VALUE;
599 	}
600 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
601 	scan_obj = wlan_pdev_get_scan_obj(pdev);
602 	if (!scan_obj)
603 		return QDF_STATUS_E_FAILURE;
604 
605 	return scan_obj->pdev_info[pdev_id].wide_band_scan;
606 }
607 
608 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID
609 QDF_STATUS
610 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev,
611 				       uint8_t *bssid, struct wlan_ssid *ssid)
612 {
613 	uint8_t pdev_id;
614 	struct wlan_scan_obj *scan_obj;
615 
616 	if (!pdev) {
617 		scm_warn("null vdev");
618 		return QDF_STATUS_E_NULL_VALUE;
619 	}
620 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
621 	scan_obj = wlan_pdev_get_scan_obj(pdev);
622 	if (!scan_obj)
623 		return QDF_STATUS_E_FAILURE;
624 
625 	scm_debug("Configure bsssid:%pM ssid:%.*s",
626 		  bssid, ssid->length, ssid->ssid);
627 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid,
628 		     bssid, QDF_MAC_ADDR_SIZE);
629 	scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length;
630 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid,
631 		     ssid->ssid,
632 		     scan_obj->pdev_info[pdev_id].conf_ssid.length);
633 
634 	return QDF_STATUS_SUCCESS;
635 }
636 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */
637 
638 QDF_STATUS
639 ucfg_scan_cancel(struct scan_cancel_request *req)
640 {
641 	struct scheduler_msg msg = {0};
642 	QDF_STATUS status;
643 
644 	if (!req || !req->vdev) {
645 		scm_err("req or vdev within req is NULL");
646 		if (req)
647 			qdf_mem_free(req);
648 		return QDF_STATUS_E_NULL_VALUE;
649 	}
650 	scm_debug("reqid: %d, scanid: %d, vdevid: %d, type: %d",
651 		  req->cancel_req.requester, req->cancel_req.scan_id,
652 		  req->cancel_req.vdev_id, req->cancel_req.req_type);
653 
654 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
655 	if (QDF_IS_STATUS_ERROR(status)) {
656 		scm_info("Failed to get vdev ref; status:%d", status);
657 		goto req_free;
658 	}
659 
660 	msg.bodyptr = req;
661 	msg.callback = scm_scan_cancel_req;
662 	msg.flush_callback = scm_scan_cancel_flush_callback;
663 
664 	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
665 					QDF_MODULE_ID_SCAN,
666 					QDF_MODULE_ID_OS_IF, &msg);
667 	if (QDF_IS_STATUS_ERROR(status))
668 		goto vdev_put;
669 
670 	return QDF_STATUS_SUCCESS;
671 
672 vdev_put:
673 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
674 
675 req_free:
676 	qdf_mem_free(req);
677 
678 	return status;
679 }
680 
681 QDF_STATUS
682 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
683 {
684 	QDF_STATUS status;
685 	bool cancel_vdev = false, cancel_pdev = false;
686 	struct wlan_objmgr_vdev *vdev;
687 	struct wlan_objmgr_pdev *pdev;
688 	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
689 	qdf_event_t cancel_scan_event;
690 
691 	if (!req || !req->vdev) {
692 		scm_err("req or vdev within req is NULL");
693 		if (req)
694 			qdf_mem_free(req);
695 		return QDF_STATUS_E_NULL_VALUE;
696 	}
697 
698 	if (req->cancel_req.req_type ==
699 	   WLAN_SCAN_CANCEL_PDEV_ALL)
700 		cancel_pdev = true;
701 	else if (req->cancel_req.req_type ==
702 	   WLAN_SCAN_CANCEL_VDEV_ALL)
703 		cancel_vdev = true;
704 
705 	vdev = req->vdev;
706 	status = ucfg_scan_cancel(req);
707 	if (QDF_IS_STATUS_ERROR(status))
708 		return status;
709 
710 	memset(&cancel_scan_event, 0, sizeof(cancel_scan_event));
711 	/*
712 	 * If cancel req is to cancel all scan of pdev or vdev
713 	 * wait until all scan of pdev or vdev get cancelled
714 	 */
715 	qdf_event_create(&cancel_scan_event);
716 	qdf_event_reset(&cancel_scan_event);
717 
718 	if (cancel_pdev) {
719 		pdev = wlan_vdev_get_pdev(vdev);
720 		while ((ucfg_scan_get_pdev_status(pdev) !=
721 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
722 			scm_debug("wait for all pdev scan to get complete");
723 				qdf_wait_single_event(&cancel_scan_event,
724 					SCM_CANCEL_SCAN_WAIT_TIME);
725 			max_wait_iterations--;
726 		}
727 	} else if (cancel_vdev) {
728 		while ((ucfg_scan_get_vdev_status(vdev) !=
729 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
730 			scm_debug("wait for all vdev scan to get complete");
731 				qdf_wait_single_event(&cancel_scan_event,
732 					SCM_CANCEL_SCAN_WAIT_TIME);
733 			max_wait_iterations--;
734 		}
735 	}
736 
737 	qdf_event_destroy(&cancel_scan_event);
738 
739 	if (!max_wait_iterations) {
740 		scm_err("Failed to wait for scans to get complete");
741 		return QDF_STATUS_E_TIMEOUT;
742 	}
743 
744 	return status;
745 }
746 
747 wlan_scan_requester
748 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc,
749 	uint8_t *name, scan_event_handler event_cb, void *arg)
750 {
751 	int i, j;
752 	struct wlan_scan_obj *scan;
753 	struct scan_requester_info *requesters;
754 	wlan_scan_requester requester = {0};
755 
756 	if (!psoc) {
757 		scm_err("null psoc");
758 		return 0;
759 	}
760 	scan = wlan_psoc_get_scan_obj(psoc);
761 	if (!scan)
762 		return 0;
763 
764 	requesters = scan->requesters;
765 	qdf_spin_lock_bh(&scan->lock);
766 	for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) {
767 		if (requesters[i].requester == 0) {
768 			requesters[i].requester =
769 				WLAN_SCAN_REQUESTER_ID_PREFIX | i;
770 			j = 0;
771 			while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) {
772 				requesters[i].module[j] = name[j];
773 				++j;
774 			}
775 			requesters[i].module[j] = 0;
776 			requesters[i].ev_handler.func = event_cb;
777 			requesters[i].ev_handler.arg = arg;
778 			requester = requesters[i].requester;
779 			break;
780 		}
781 	}
782 	qdf_spin_unlock_bh(&scan->lock);
783 	scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d",
784 		  name, event_cb, arg, requester);
785 
786 	return requester;
787 }
788 
789 void
790 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
791 	wlan_scan_requester requester)
792 {
793 	int idx;
794 	struct wlan_scan_obj *scan;
795 	struct scan_requester_info *requesters;
796 
797 	idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX;
798 	if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) {
799 		scm_err("prefix didn't match for requester id %d", requester);
800 		return;
801 	}
802 
803 	idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
804 	if (idx >= WLAN_MAX_REQUESTORS) {
805 		scm_err("requester id %d greater than max value", requester);
806 		return;
807 	}
808 
809 	if (!psoc) {
810 		scm_err("null psoc");
811 		return;
812 	}
813 	scan = wlan_psoc_get_scan_obj(psoc);
814 	if (!scan)
815 		return;
816 	requesters = scan->requesters;
817 	scm_debug("reqid: %d", requester);
818 
819 	qdf_spin_lock_bh(&scan->lock);
820 	requesters[idx].requester = 0;
821 	requesters[idx].module[0] = 0;
822 	requesters[idx].ev_handler.func = NULL;
823 	requesters[idx].ev_handler.arg = NULL;
824 	qdf_spin_unlock_bh(&scan->lock);
825 }
826 
827 uint8_t*
828 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
829 	wlan_scan_requester requester)
830 {
831 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
832 	struct wlan_scan_obj *scan;
833 	struct scan_requester_info *requesters;
834 
835 	if (!psoc) {
836 		scm_err("null psoc");
837 		return "null";
838 	}
839 	scan = wlan_psoc_get_scan_obj(psoc);
840 	if (!scan)
841 		return "null";
842 
843 	requesters = scan->requesters;
844 
845 	if ((idx < WLAN_MAX_REQUESTORS) &&
846 		(requesters[idx].requester == requester)) {
847 		return requesters[idx].module;
848 	}
849 
850 	return (uint8_t *)"unknown";
851 }
852 
853 wlan_scan_id
854 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
855 {
856 	wlan_scan_id id;
857 	struct wlan_scan_obj *scan;
858 
859 	if (!psoc) {
860 		QDF_ASSERT(0);
861 		scm_err("null psoc");
862 		return 0;
863 	}
864 
865 	scan = wlan_psoc_get_scan_obj(psoc);
866 	if (!scan) {
867 		scm_err("scan object null");
868 		return 0;
869 	}
870 
871 	id = qdf_atomic_inc_return(&scan->scan_ids);
872 	id =  id & WLAN_SCAN_ID_MASK;
873 	/* Mark this scan request as triggered by host
874 	 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag.
875 	 */
876 	id =  id | WLAN_HOST_SCAN_REQ_ID_PREFIX;
877 	scm_debug("scan_id: 0x%x", id);
878 
879 	return id;
880 }
881 
882 static QDF_STATUS
883 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
884 	scan_event_handler event_cb, void *arg)
885 {
886 	struct cb_handler *cb_handler;
887 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
888 
889 	/* Assign next available slot to this registration request */
890 	cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
891 	cb_handler->func = event_cb;
892 	cb_handler->arg = arg;
893 	pdev_ev_handler->handler_cnt++;
894 
895 	return QDF_STATUS_SUCCESS;
896 }
897 
898 QDF_STATUS
899 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
900 	scan_event_handler event_cb, void *arg)
901 {
902 	uint32_t idx;
903 	struct wlan_scan_obj *scan;
904 	struct pdev_scan_ev_handler *pdev_ev_handler;
905 	struct cb_handler *cb_handler;
906 
907 	/* scan event handler call back can't be NULL */
908 	if (!pdev || !event_cb) {
909 		scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
910 		return QDF_STATUS_E_NULL_VALUE;
911 	}
912 
913 	scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
914 
915 	scan = wlan_pdev_get_scan_obj(pdev);
916 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
917 	if (!pdev_ev_handler) {
918 		scm_err("null pdev_ev_handler");
919 		return QDF_STATUS_E_NULL_VALUE;
920 	}
921 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
922 
923 	qdf_spin_lock_bh(&scan->lock);
924 	/* Ensure its not a duplicate registration request */
925 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
926 		idx++, cb_handler++) {
927 		if ((cb_handler->func == event_cb) &&
928 			(cb_handler->arg == arg)) {
929 			qdf_spin_unlock_bh(&scan->lock);
930 			scm_debug("func: %pK, arg: %pK already exists",
931 				  event_cb, arg);
932 			return QDF_STATUS_SUCCESS;
933 		}
934 	}
935 
936 	QDF_ASSERT(pdev_ev_handler->handler_cnt <
937 			MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
938 
939 	if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
940 		qdf_spin_unlock_bh(&scan->lock);
941 		scm_warn("No more registrations possible");
942 		return QDF_STATUS_E_NOMEM;
943 	}
944 
945 	scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
946 	qdf_spin_unlock_bh(&scan->lock);
947 
948 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
949 
950 	return QDF_STATUS_SUCCESS;
951 }
952 
953 static QDF_STATUS
954 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
955 		      struct wlan_scan_obj *scan_obj)
956 {
957 	scan_obj->scan_disabled = 0;
958 	scan_obj->drop_bcn_on_chan_mismatch =
959 			 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH);
960 	scan_obj->disable_timeout = false;
961 	scan_obj->scan_def.active_dwell =
962 			 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
963 	/* the ini is disallow DFS channel scan if ini is 1, so negate that */
964 	scan_obj->scan_def.allow_dfs_chan_in_first_scan =
965 				!cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
966 	scan_obj->scan_def.allow_dfs_chan_in_scan =
967 				cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
968 	scan_obj->scan_def.skip_dfs_chan_in_p2p_search =
969 				cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH);
970 	scan_obj->scan_def.use_wake_lock_in_user_scan =
971 				cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN);
972 	scan_obj->scan_def.active_dwell_2g =
973 			 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
974 	scan_obj->scan_def.active_dwell_6g =
975 			 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME);
976 	scan_obj->scan_def.passive_dwell_6g =
977 			 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME);
978 	scan_obj->scan_def.passive_dwell =
979 			 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME);
980 	scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
981 	scan_obj->scan_def.sta_miracast_mcc_rest_time =
982 					SCAN_STA_MIRACAST_MCC_REST_TIME;
983 	scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
984 	scan_obj->scan_def.conc_active_dwell =
985 			cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC);
986 	scan_obj->scan_def.conc_passive_dwell =
987 			cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC);
988 	scan_obj->scan_def.conc_max_rest_time =
989 			cfg_get(psoc, CFG_MAX_REST_TIME_CONC);
990 	scan_obj->scan_def.conc_min_rest_time =
991 			cfg_get(psoc, CFG_MIN_REST_TIME_CONC);
992 	scan_obj->scan_def.conc_idle_time =
993 			cfg_get(psoc, CFG_IDLE_TIME_CONC);
994 	scan_obj->scan_def.repeat_probe_time =
995 			cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME);
996 	scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
997 	scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
998 	scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
999 	scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
1000 	scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES);
1001 	scan_obj->scan_def.scan_cache_aging_time =
1002 			(cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000);
1003 	scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
1004 	scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
1005 	scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
1006 	scan_obj->scan_def.adaptive_dwell_time_mode =
1007 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE);
1008 	scan_obj->scan_def.adaptive_dwell_time_mode_nc =
1009 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC);
1010 	scan_obj->scan_def.honour_nl_scan_policy_flags =
1011 			cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS);
1012 	scan_obj->scan_def.enable_mac_spoofing =
1013 			cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING);
1014 	scan_obj->scan_def.is_bssid_hint_priority =
1015 			cfg_get(psoc, CFG_IS_BSSID_HINT_PRIORITY);
1016 	scan_obj->scan_def.extscan_adaptive_dwell_mode =
1017 			cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
1018 
1019 	/* init burst durations */
1020 	scan_obj->scan_def.sta_scan_burst_duration =
1021 				cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION);
1022 	scan_obj->scan_def.p2p_scan_burst_duration =
1023 				cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION);
1024 	scan_obj->scan_def.go_scan_burst_duration =
1025 				cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION);
1026 	scan_obj->scan_def.ap_scan_burst_duration =
1027 				cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION);
1028 	/* scan contrl flags */
1029 	scan_obj->scan_def.scan_f_passive = true;
1030 	scan_obj->scan_def.scan_f_ofdm_rates = true;
1031 	scan_obj->scan_def.scan_f_2ghz = true;
1032 	scan_obj->scan_def.scan_f_5ghz = true;
1033 	scan_obj->scan_def.scan_f_chan_stat_evnt =
1034 				cfg_get(psoc, CFG_ENABLE_SNR_MONITORING);
1035 	/* scan event flags */
1036 	scan_obj->scan_def.scan_ev_started = true;
1037 	scan_obj->scan_def.scan_ev_completed = true;
1038 	scan_obj->scan_def.scan_ev_bss_chan = true;
1039 	scan_obj->scan_def.scan_ev_foreign_chan = true;
1040 	scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
1041 	scan_obj->scan_def.scan_ev_dequeued = true;
1042 	scan_obj->scan_def.scan_ev_preempted = true;
1043 	scan_obj->scan_def.scan_ev_start_failed = true;
1044 	scan_obj->scan_def.scan_ev_restarted = true;
1045 	scan_obj->scan_def.enable_connected_scan =
1046 		cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN);
1047 	scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE);
1048 	/* init scan id seed */
1049 	qdf_atomic_init(&scan_obj->scan_ids);
1050 
1051 	/* init extscan */
1052 	wlan_extscan_global_init(psoc, scan_obj);
1053 
1054 	return wlan_pno_global_init(psoc, scan_obj);
1055 }
1056 
1057 static void
1058 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc)
1059 {
1060 	struct wlan_scan_obj *scan_obj;
1061 
1062 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1063 	wlan_pno_global_deinit(scan_obj);
1064 	wlan_extscan_global_deinit();
1065 }
1066 
1067 static QDF_STATUS
1068 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
1069 	struct cb_handler *entry)
1070 {
1071 	struct cb_handler *last_entry;
1072 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
1073 
1074 	/* Replace event handler being deleted
1075 	 * with the last one in the list.
1076 	 */
1077 	last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
1078 	entry->func = last_entry->func;
1079 	entry->arg = last_entry->arg;
1080 
1081 	/* Clear our last entry */
1082 	last_entry->func = NULL;
1083 	last_entry->arg = NULL;
1084 	pdev_ev_handler->handler_cnt--;
1085 
1086 	return QDF_STATUS_SUCCESS;
1087 }
1088 
1089 void
1090 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
1091 	scan_event_handler event_cb, void *arg)
1092 {
1093 	uint8_t found = false;
1094 	uint32_t idx;
1095 	uint32_t handler_cnt;
1096 	struct wlan_scan_obj *scan;
1097 	struct cb_handler *cb_handler;
1098 	struct pdev_scan_ev_handler *pdev_ev_handler;
1099 
1100 	scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb,
1101 		  arg);
1102 	if (!pdev) {
1103 		scm_err("null pdev");
1104 		return;
1105 	}
1106 	scan = wlan_pdev_get_scan_obj(pdev);
1107 	if (!scan)
1108 		return;
1109 
1110 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
1111 	if (!pdev_ev_handler)
1112 		return;
1113 
1114 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
1115 
1116 	qdf_spin_lock_bh(&scan->lock);
1117 	handler_cnt = pdev_ev_handler->handler_cnt;
1118 	if (!handler_cnt) {
1119 		qdf_spin_unlock_bh(&scan->lock);
1120 		scm_info("No event handlers registered");
1121 		return;
1122 	}
1123 
1124 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
1125 		idx++, cb_handler++) {
1126 		if ((cb_handler->func == event_cb) &&
1127 			(cb_handler->arg == arg)) {
1128 			/* Event handler found, remove it
1129 			 * from event handler list.
1130 			 */
1131 			found = true;
1132 			scm_remove_scan_event_handler(pdev_ev_handler,
1133 				cb_handler);
1134 			handler_cnt--;
1135 			break;
1136 		}
1137 	}
1138 	qdf_spin_unlock_bh(&scan->lock);
1139 
1140 	scm_debug("event handler %s, remaining handlers: %d",
1141 		  (found ? "removed" : "not found"), handler_cnt);
1142 }
1143 
1144 QDF_STATUS
1145 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
1146 	struct scan_start_request *req)
1147 {
1148 	struct scan_default_params *def;
1149 
1150 	if (!vdev | !req) {
1151 		scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req);
1152 		return QDF_STATUS_E_INVAL;
1153 	}
1154 	def = wlan_vdev_get_def_scan_params(vdev);
1155 	if (!def) {
1156 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
1157 		return QDF_STATUS_E_NULL_VALUE;
1158 	}
1159 
1160 	/* Zero out everything and explicitly set fields as required */
1161 	qdf_mem_zero(req, sizeof(*req));
1162 
1163 	req->vdev = vdev;
1164 	req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
1165 	req->scan_req.scan_type = SCAN_TYPE_DEFAULT;
1166 	req->scan_req.scan_priority = def->scan_priority;
1167 	req->scan_req.dwell_time_active = def->active_dwell;
1168 	req->scan_req.dwell_time_active_2g = def->active_dwell_2g;
1169 	req->scan_req.dwell_time_active_6g = def->active_dwell_6g;
1170 	req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g;
1171 	req->scan_req.dwell_time_passive = def->passive_dwell;
1172 	req->scan_req.min_rest_time = def->min_rest_time;
1173 	req->scan_req.max_rest_time = def->max_rest_time;
1174 	req->scan_req.repeat_probe_time = def->repeat_probe_time;
1175 	req->scan_req.probe_spacing_time = def->probe_spacing_time;
1176 	req->scan_req.idle_time = def->idle_time;
1177 	req->scan_req.max_scan_time = def->max_scan_time;
1178 	req->scan_req.probe_delay = def->probe_delay;
1179 	req->scan_req.burst_duration = def->burst_duration;
1180 	req->scan_req.n_probes = def->num_probes;
1181 	req->scan_req.adaptive_dwell_time_mode =
1182 		def->adaptive_dwell_time_mode;
1183 	req->scan_req.scan_flags = def->scan_flags;
1184 	req->scan_req.scan_events = def->scan_events;
1185 	req->scan_req.scan_random.randomize = def->enable_mac_spoofing;
1186 
1187 	return QDF_STATUS_SUCCESS;
1188 }
1189 
1190 QDF_STATUS
1191 ucfg_scan_init_ssid_params(struct scan_start_request *req,
1192 		uint32_t num_ssid, struct wlan_ssid *ssid_list)
1193 {
1194 	uint32_t max_ssid = sizeof(req->scan_req.ssid) /
1195 				sizeof(req->scan_req.ssid[0]);
1196 
1197 	if (!req) {
1198 		scm_err("null request");
1199 		return QDF_STATUS_E_NULL_VALUE;
1200 	}
1201 	if (!num_ssid) {
1202 		/* empty channel list provided */
1203 		req->scan_req.num_ssids = 0;
1204 		qdf_mem_zero(&req->scan_req.ssid[0],
1205 			sizeof(req->scan_req.ssid));
1206 		return QDF_STATUS_SUCCESS;
1207 	}
1208 	if (!ssid_list) {
1209 		scm_err("null ssid_list while num_ssid: %d", num_ssid);
1210 		return QDF_STATUS_E_NULL_VALUE;
1211 	}
1212 	if (num_ssid > max_ssid) {
1213 		/* got a big list. alert and continue */
1214 		scm_warn("overflow: received %d, max supported : %d",
1215 			num_ssid, max_ssid);
1216 		return QDF_STATUS_E_E2BIG;
1217 	}
1218 
1219 	if (max_ssid > num_ssid)
1220 		max_ssid = num_ssid;
1221 
1222 	req->scan_req.num_ssids = max_ssid;
1223 	qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
1224 		(req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
1225 
1226 	return QDF_STATUS_SUCCESS;
1227 }
1228 
1229 QDF_STATUS
1230 ucfg_scan_init_bssid_params(struct scan_start_request *req,
1231 		uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
1232 {
1233 	uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
1234 				sizeof(req->scan_req.bssid_list[0]);
1235 
1236 	if (!req) {
1237 		scm_err("null request");
1238 		return QDF_STATUS_E_NULL_VALUE;
1239 	}
1240 	if (!num_bssid) {
1241 		/* empty channel list provided */
1242 		req->scan_req.num_bssid = 0;
1243 		qdf_mem_zero(&req->scan_req.bssid_list[0],
1244 			sizeof(req->scan_req.bssid_list));
1245 		return QDF_STATUS_SUCCESS;
1246 	}
1247 	if (!bssid_list) {
1248 		scm_err("null bssid_list while num_bssid: %d", num_bssid);
1249 		return QDF_STATUS_E_NULL_VALUE;
1250 	}
1251 	if (num_bssid > max_bssid) {
1252 		/* got a big list. alert and continue */
1253 		scm_warn("overflow: received %d, max supported : %d",
1254 			num_bssid, max_bssid);
1255 		return QDF_STATUS_E_E2BIG;
1256 	}
1257 
1258 	if (max_bssid > num_bssid)
1259 		max_bssid = num_bssid;
1260 
1261 	req->scan_req.num_bssid = max_bssid;
1262 	qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
1263 		req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
1264 
1265 	return QDF_STATUS_SUCCESS;
1266 }
1267 
1268 /**
1269  * is_chan_enabled_for_scan() - helper API to check if a frequency
1270  * is allowed to scan.
1271  * @reg_chan: regulatory_channel object
1272  * @low_2g: lower 2.4 GHz frequency thresold
1273  * @high_2g: upper 2.4 GHz frequency thresold
1274  * @low_5g: lower 5 GHz frequency thresold
1275  * @high_5g: upper 5 GHz frequency thresold
1276  *
1277  * Return: true if scan is allowed. false otherwise.
1278  */
1279 static bool
1280 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan,
1281 		qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g,
1282 		qdf_freq_t high_5g)
1283 {
1284 	if (reg_chan->state == CHANNEL_STATE_DISABLE)
1285 		return false;
1286 	if (reg_chan->nol_chan)
1287 		return false;
1288 	/* 2 GHz channel */
1289 	if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1290 			WLAN_BAND_2_4_GHZ) &&
1291 			((reg_chan->center_freq < low_2g) ||
1292 			(reg_chan->center_freq > high_2g)))
1293 		return false;
1294 	else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1295 				WLAN_BAND_5_GHZ) &&
1296 		 ((reg_chan->center_freq < low_5g) ||
1297 		  (reg_chan->center_freq > high_5g)))
1298 		return false;
1299 
1300 	return true;
1301 }
1302 
1303 QDF_STATUS
1304 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1305 		uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1306 {
1307 	uint32_t idx;
1308 	QDF_STATUS status;
1309 	struct regulatory_channel *reg_chan_list = NULL;
1310 	qdf_freq_t low_2g, high_2g, low_5g, high_5g;
1311 	struct wlan_objmgr_pdev *pdev = NULL;
1312 	uint32_t *scan_freqs = NULL;
1313 	uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1314 				sizeof(req->scan_req.chan_list.chan[0]);
1315 	if (!req) {
1316 		scm_err("null request");
1317 		return QDF_STATUS_E_NULL_VALUE;
1318 	}
1319 
1320 	if (req->vdev)
1321 		pdev = wlan_vdev_get_pdev(req->vdev);
1322 	/*
1323 	 * If 0 channels are provided for scan and
1324 	 * wide band scan is enabled, scan all 20 mhz
1325 	 * available channels. This is required as FW
1326 	 * scans all channel/phy mode combinations
1327 	 * provided in scan channel list if 0 chans are
1328 	 * provided in scan request causing scan to take
1329 	 * too much time to complete.
1330 	 */
1331 	if (pdev && !num_chans) {
1332 		reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1333 				sizeof(struct regulatory_channel));
1334 		if (!reg_chan_list) {
1335 			scm_err("Couldn't allocate reg_chan_list memory");
1336 			status = QDF_STATUS_E_NOMEM;
1337 			goto end;
1338 		}
1339 		scan_freqs =
1340 			qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1341 		if (!scan_freqs) {
1342 			scm_err("Couldn't allocate scan_freqs memory");
1343 			status = QDF_STATUS_E_NOMEM;
1344 			goto end;
1345 		}
1346 		status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list);
1347 		if (QDF_IS_STATUS_ERROR(status)) {
1348 			scm_err("Couldn't get current chan list");
1349 			goto end;
1350 		}
1351 		status = wlan_reg_get_freq_range(pdev, &low_2g,
1352 				&high_2g, &low_5g, &high_5g);
1353 		if (QDF_IS_STATUS_ERROR(status)) {
1354 			scm_err("Couldn't get frequency range");
1355 			goto end;
1356 		}
1357 
1358 		for (idx = 0, num_chans = 0;
1359 			(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1360 			if (is_chan_enabled_for_scan(&reg_chan_list[idx],
1361 					low_2g, high_2g, low_5g, high_5g))
1362 				scan_freqs[num_chans++] =
1363 				reg_chan_list[idx].center_freq;
1364 
1365 		chan_list = scan_freqs;
1366 	}
1367 
1368 	if (!num_chans) {
1369 		/* empty channel list provided */
1370 		qdf_mem_zero(&req->scan_req.chan_list,
1371 			sizeof(req->scan_req.chan_list));
1372 		req->scan_req.chan_list.num_chan = 0;
1373 		status = QDF_STATUS_SUCCESS;
1374 		goto end;
1375 	}
1376 	if (!chan_list) {
1377 		scm_err("null chan_list while num_chans: %d", num_chans);
1378 		status = QDF_STATUS_E_NULL_VALUE;
1379 		goto end;
1380 	}
1381 
1382 	if (num_chans > max_chans) {
1383 		/* got a big list. alert and fail */
1384 		scm_warn("overflow: received %d, max supported : %d",
1385 			num_chans, max_chans);
1386 		status = QDF_STATUS_E_E2BIG;
1387 		goto end;
1388 	}
1389 
1390 	req->scan_req.chan_list.num_chan = num_chans;
1391 	for (idx = 0; idx < num_chans; idx++) {
1392 		req->scan_req.chan_list.chan[idx].freq =
1393 			(chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1394 			chan_list[idx] :
1395 			wlan_reg_chan_to_freq(pdev, chan_list[idx]);
1396 		if (phymode)
1397 			req->scan_req.chan_list.chan[idx].phymode =
1398 				phymode[idx];
1399 		else if (req->scan_req.chan_list.chan[idx].freq <=
1400 			WLAN_CHAN_15_FREQ)
1401 			req->scan_req.chan_list.chan[idx].phymode =
1402 				SCAN_PHY_MODE_11G;
1403 		else
1404 			req->scan_req.chan_list.chan[idx].phymode =
1405 				SCAN_PHY_MODE_11A;
1406 
1407 		scm_debug("chan[%d]: freq:%d, phymode:%d", idx,
1408 			req->scan_req.chan_list.chan[idx].freq,
1409 			req->scan_req.chan_list.chan[idx].phymode);
1410 	}
1411 
1412 end:
1413 	if (scan_freqs)
1414 		qdf_mem_free(scan_freqs);
1415 
1416 	if (reg_chan_list)
1417 		qdf_mem_free(reg_chan_list);
1418 
1419 	return QDF_STATUS_SUCCESS;
1420 }
1421 
1422 static inline enum scm_scan_status
1423 get_scan_status_from_serialization_status(
1424 	enum wlan_serialization_cmd_status status)
1425 {
1426 	enum scm_scan_status scan_status;
1427 
1428 	switch (status) {
1429 	case WLAN_SER_CMD_IN_PENDING_LIST:
1430 		scan_status = SCAN_IS_PENDING;
1431 		break;
1432 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1433 		scan_status = SCAN_IS_ACTIVE;
1434 		break;
1435 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1436 		scan_status = SCAN_IS_ACTIVE_AND_PENDING;
1437 		break;
1438 	case WLAN_SER_CMD_NOT_FOUND:
1439 		scan_status = SCAN_NOT_IN_PROGRESS;
1440 		break;
1441 	default:
1442 		scm_warn("invalid serialization status %d", status);
1443 		QDF_ASSERT(0);
1444 		scan_status = SCAN_NOT_IN_PROGRESS;
1445 		break;
1446 	}
1447 
1448 	return scan_status;
1449 }
1450 
1451 enum scm_scan_status
1452 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1453 {
1454 	enum wlan_serialization_cmd_status status;
1455 
1456 	if (!vdev) {
1457 		scm_err("null vdev");
1458 		return SCAN_NOT_IN_PROGRESS;
1459 	}
1460 	status = wlan_serialization_vdev_scan_status(vdev);
1461 
1462 	return get_scan_status_from_serialization_status(status);
1463 }
1464 
1465 enum scm_scan_status
1466 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1467 {
1468 	enum wlan_serialization_cmd_status status;
1469 
1470 	if (!pdev) {
1471 		scm_err("null pdev");
1472 		return SCAN_NOT_IN_PROGRESS;
1473 	}
1474 	status = wlan_serialization_pdev_scan_status(pdev);
1475 
1476 	return get_scan_status_from_serialization_status(status);
1477 }
1478 
1479 static void
1480 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1481 	bool enable)
1482 {
1483 	QDF_STATUS status;
1484 	struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1485 
1486 	cb_info[0].frm_type = MGMT_PROBE_RESP;
1487 	cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1488 	cb_info[1].frm_type = MGMT_BEACON;
1489 	cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1490 
1491 	if (enable)
1492 		status = wlan_mgmt_txrx_register_rx_cb(psoc,
1493 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1494 	else
1495 		status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1496 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1497 	if (status != QDF_STATUS_SUCCESS)
1498 		scm_err("%s the Handle with MGMT TXRX layer has failed",
1499 			enable ? "Registering" : "Deregistering");
1500 }
1501 
1502 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1503 	struct scan_user_cfg *scan_cfg)
1504 {
1505 	struct wlan_scan_obj *scan_obj;
1506 	struct scan_default_params *scan_def;
1507 
1508 	if (!psoc) {
1509 		scm_err("null psoc");
1510 		return QDF_STATUS_E_FAILURE;
1511 	}
1512 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1513 	if (!scan_obj) {
1514 		scm_err("Failed to get scan object");
1515 		return QDF_STATUS_E_FAILURE;
1516 	}
1517 
1518 	scan_def = &scan_obj->scan_def;
1519 	scan_obj->ie_whitelist = scan_cfg->ie_whitelist;
1520 	scan_def->sta_miracast_mcc_rest_time =
1521 				scan_cfg->sta_miracast_mcc_rest_time;
1522 
1523 	qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config,
1524 		sizeof(struct scoring_config));
1525 	scm_validate_scoring_config(&scan_def->score_config);
1526 
1527 	return QDF_STATUS_SUCCESS;
1528 }
1529 
1530 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1531 static QDF_STATUS
1532 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
1533 {
1534 	struct scan_cancel_request *req;
1535 	QDF_STATUS status;
1536 	struct wlan_objmgr_vdev *vdev;
1537 
1538 	req = qdf_mem_malloc_atomic(sizeof(*req));
1539 	if (!req) {
1540 		scm_err("Failed to allocate memory");
1541 		return QDF_STATUS_E_NOMEM;
1542 	}
1543 
1544 	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID);
1545 	if (!vdev) {
1546 		scm_err("Failed to get vdev");
1547 		qdf_mem_free(req);
1548 		return QDF_STATUS_E_INVAL;
1549 	}
1550 	req->vdev = vdev;
1551 	req->cancel_req.scan_id = INVAL_SCAN_ID;
1552 	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1553 	req->cancel_req.vdev_id = INVAL_VDEV_ID;
1554 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1555 	status = ucfg_scan_cancel_sync(req);
1556 	if (QDF_IS_STATUS_ERROR(status))
1557 		scm_err("Cancel scan request failed");
1558 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1559 
1560 	return status;
1561 }
1562 
1563 static QDF_STATUS
1564 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1565 {
1566 	struct wlan_objmgr_pdev *pdev = NULL;
1567 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1568 	int i;
1569 
1570 	ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND);
1571 	/* Check all pdev */
1572 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
1573 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
1574 		if (!pdev)
1575 			continue;
1576 		if (ucfg_scan_get_pdev_status(pdev) !=
1577 		    SCAN_NOT_IN_PROGRESS)
1578 			status = ucfg_scan_cancel_pdev_scan(pdev);
1579 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
1580 		if (QDF_IS_STATUS_ERROR(status)) {
1581 			scm_err("failed to cancel scan for pdev_id %d", i);
1582 			return status;
1583 		}
1584 	}
1585 
1586 	return QDF_STATUS_SUCCESS;
1587 }
1588 
1589 static QDF_STATUS
1590 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1591 {
1592 	ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND);
1593 	return QDF_STATUS_SUCCESS;
1594 }
1595 
1596 static inline void
1597 ucfg_scan_register_pmo_handler(void)
1598 {
1599 	pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
1600 		ucfg_scan_suspend_handler, NULL);
1601 	pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
1602 		ucfg_scan_resume_handler, NULL);
1603 }
1604 
1605 static inline void
1606 ucfg_scan_unregister_pmo_handler(void)
1607 {
1608 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
1609 		ucfg_scan_suspend_handler);
1610 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
1611 		ucfg_scan_resume_handler);
1612 }
1613 
1614 #else
1615 static inline void
1616 ucfg_scan_register_pmo_handler(void)
1617 {
1618 }
1619 
1620 static inline void
1621 ucfg_scan_unregister_pmo_handler(void)
1622 {
1623 }
1624 #endif
1625 
1626 QDF_STATUS
1627 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
1628 {
1629 	struct wlan_scan_obj *scan_obj;
1630 
1631 	scm_debug("psoc open: 0x%pK", psoc);
1632 	if (!psoc) {
1633 		scm_err("null psoc");
1634 		return QDF_STATUS_E_FAILURE;
1635 	}
1636 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1637 	if (!scan_obj) {
1638 		scm_err("Failed to get scan object");
1639 		return QDF_STATUS_E_FAILURE;
1640 	}
1641 	/* Initialize the scan Globals */
1642 	wlan_scan_global_init(psoc, scan_obj);
1643 	qdf_spinlock_create(&scan_obj->lock);
1644 	ucfg_scan_register_pmo_handler();
1645 	scm_db_init(psoc);
1646 	scm_channel_list_db_init(psoc);
1647 
1648 	return QDF_STATUS_SUCCESS;
1649 }
1650 
1651 QDF_STATUS
1652 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
1653 {
1654 	struct wlan_scan_obj *scan_obj;
1655 
1656 	scm_debug("psoc close: 0x%pK", psoc);
1657 	if (!psoc) {
1658 		scm_err("null psoc");
1659 		return QDF_STATUS_E_FAILURE;
1660 	}
1661 	scm_db_deinit(psoc);
1662 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1663 	if (!scan_obj) {
1664 		scm_err("Failed to get scan object");
1665 		return QDF_STATUS_E_FAILURE;
1666 	}
1667 	ucfg_scan_unregister_pmo_handler();
1668 	qdf_spinlock_destroy(&scan_obj->lock);
1669 	wlan_scan_global_deinit(psoc);
1670 	scm_channel_list_db_deinit(psoc);
1671 
1672 	return QDF_STATUS_SUCCESS;
1673 }
1674 
1675 static bool scm_serialization_scan_rules_cb(
1676 		union wlan_serialization_rules_info *comp_info,
1677 		uint8_t comp_id)
1678 {
1679 	switch (comp_id) {
1680 	case WLAN_UMAC_COMP_TDLS:
1681 		if (comp_info->scan_info.is_tdls_in_progress) {
1682 			scm_debug("Cancel scan. Tdls in progress");
1683 			return false;
1684 		}
1685 		break;
1686 	case WLAN_UMAC_COMP_DFS:
1687 		if (comp_info->scan_info.is_cac_in_progress) {
1688 			scm_debug("Cancel scan. CAC in progress");
1689 			return false;
1690 		}
1691 		break;
1692 	case WLAN_UMAC_COMP_MLME:
1693 		if (comp_info->scan_info.is_mlme_op_in_progress) {
1694 			scm_debug("Cancel scan. MLME operation in progress");
1695 			return false;
1696 		}
1697 		break;
1698 	default:
1699 		scm_debug("not handled comp_id %d", comp_id);
1700 		break;
1701 	}
1702 
1703 	return true;
1704 }
1705 
1706 QDF_STATUS
1707 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
1708 {
1709 	QDF_STATUS status;
1710 
1711 	scm_debug("psoc enable: 0x%pK", psoc);
1712 	if (!psoc) {
1713 		scm_err("null psoc");
1714 		return QDF_STATUS_E_FAILURE;
1715 	}
1716 	/* Subscribe for scan events from lmac layesr */
1717 	status = tgt_scan_register_ev_handler(psoc);
1718 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1719 	if (!wlan_reg_is_11d_offloaded(psoc))
1720 		scm_11d_cc_db_init(psoc);
1721 	ucfg_scan_register_unregister_bcn_cb(psoc, true);
1722 	status = wlan_serialization_register_apply_rules_cb(psoc,
1723 				WLAN_SER_CMD_SCAN,
1724 				scm_serialization_scan_rules_cb);
1725 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1726 	return status;
1727 }
1728 
1729 QDF_STATUS
1730 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
1731 {
1732 	QDF_STATUS status;
1733 
1734 	scm_debug("psoc disable: 0x%pK", psoc);
1735 	if (!psoc) {
1736 		scm_err("null psoc");
1737 		return QDF_STATUS_E_FAILURE;
1738 	}
1739 	/* Unsubscribe for scan events from lmac layesr */
1740 	status = tgt_scan_unregister_ev_handler(psoc);
1741 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1742 	ucfg_scan_register_unregister_bcn_cb(psoc, false);
1743 	if (!wlan_reg_is_11d_offloaded(psoc))
1744 		scm_11d_cc_db_deinit(psoc);
1745 
1746 	return status;
1747 }
1748 
1749 uint32_t
1750 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
1751 {
1752 	struct scan_default_params *scan_params = NULL;
1753 
1754 	if (!psoc) {
1755 		scm_err("null psoc");
1756 		return 0;
1757 	}
1758 	scan_params = wlan_scan_psoc_get_def_params(psoc);
1759 	if (!scan_params) {
1760 		scm_err("Failed to get scan object");
1761 		return 0;
1762 	}
1763 
1764 	return scan_params->max_active_scans_allowed;
1765 }
1766 
1767 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
1768 				  struct probe_req_whitelist_attr *ie_whitelist)
1769 {
1770 	struct wlan_scan_obj *scan_obj = NULL;
1771 
1772 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1773 	if (!scan_obj)
1774 		return false;
1775 
1776 	qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist,
1777 		     sizeof(*ie_whitelist));
1778 
1779 	return true;
1780 }
1781 
1782 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
1783 			       struct wlan_objmgr_vdev *vdev)
1784 {
1785 	struct wlan_scan_obj *scan_obj = NULL;
1786 
1787 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1788 	if (!scan_obj)
1789 		return false;
1790 
1791 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1792 	    wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
1793 		return false;
1794 
1795 	if (!scan_obj->ie_whitelist.white_list)
1796 		return false;
1797 
1798 	return true;
1799 }
1800 
1801 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
1802 			       bool bt_a2dp_active)
1803 {
1804 	struct wlan_scan_obj *scan_obj;
1805 
1806 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1807 	if (!scan_obj) {
1808 		scm_err("Failed to get scan object");
1809 		return;
1810 	}
1811 	scan_obj->bt_a2dp_enabled = bt_a2dp_active;
1812 }
1813 
1814 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
1815 {
1816 	struct wlan_scan_obj *scan_obj;
1817 
1818 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1819 	if (!scan_obj) {
1820 		scm_err("Failed to get scan object");
1821 		return false;
1822 	}
1823 
1824 	return scan_obj->bt_a2dp_enabled;
1825 }
1826 
1827 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc)
1828 {
1829 	struct wlan_scan_obj *scan_obj;
1830 
1831 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1832 	if (!scan_obj)
1833 		return false;
1834 
1835 	return scan_obj->scan_def.use_wake_lock_in_user_scan;
1836 }
1837 
1838 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
1839 {
1840 	struct wlan_scan_obj *scan_obj;
1841 
1842 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1843 	if (!scan_obj) {
1844 		scm_err("Failed to get scan object");
1845 		return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
1846 	}
1847 
1848 	return scan_obj->scan_def.enable_connected_scan;
1849 }
1850 
1851 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc)
1852 {
1853 	struct wlan_scan_obj *scan_obj;
1854 
1855 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1856 	if (!scan_obj) {
1857 		scm_err("Failed to get scan object");
1858 		return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING);
1859 	}
1860 
1861 	return scan_obj->scan_def.enable_mac_spoofing;
1862 }
1863 
1864 enum scan_dwelltime_adaptive_mode
1865 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc)
1866 {
1867 	struct wlan_scan_obj *scan_obj;
1868 
1869 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1870 	if (!scan_obj) {
1871 		scm_err("Failed to get scan object");
1872 		return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
1873 	}
1874 
1875 	return scan_obj->scan_def.extscan_adaptive_dwell_mode;
1876 }
1877 
1878 QDF_STATUS
1879 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
1880 			       enum scan_config config, uint32_t val)
1881 {
1882 	struct wlan_scan_obj *scan_obj;
1883 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1884 
1885 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1886 	if (!scan_obj) {
1887 		scm_err("Failed to get scan object config:%d, val:%d",
1888 				config, val);
1889 		return QDF_STATUS_E_INVAL;
1890 	}
1891 	switch (config) {
1892 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1893 		scan_obj->disable_timeout = !!val;
1894 		break;
1895 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1896 		scan_obj->drop_bcn_on_chan_mismatch = !!val;
1897 		break;
1898 
1899 	default:
1900 		status = QDF_STATUS_E_INVAL;
1901 		break;
1902 	}
1903 
1904 	return status;
1905 }
1906 
1907 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
1908 		struct bss_info *bss_info, struct mlme_info *mlme)
1909 {
1910 	QDF_STATUS status;
1911 
1912 	status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme);
1913 
1914 	return status;
1915 }
1916 
1917 QDF_STATUS
1918 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
1919 			       enum scan_config config, uint32_t *val)
1920 {
1921 	struct wlan_scan_obj *scan_obj;
1922 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1923 
1924 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1925 	if (!scan_obj || !val) {
1926 		scm_err("scan object:%pK config:%d, val:0x%pK",
1927 				scan_obj, config, val);
1928 		return QDF_STATUS_E_INVAL;
1929 	}
1930 	switch (config) {
1931 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1932 		*val = scan_obj->disable_timeout;
1933 		break;
1934 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1935 		*val = scan_obj->drop_bcn_on_chan_mismatch;
1936 		break;
1937 
1938 	default:
1939 		status = QDF_STATUS_E_INVAL;
1940 		break;
1941 	}
1942 
1943 	return status;
1944 }
1945 
1946 #ifdef FEATURE_WLAN_SCAN_PNO
1947 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc)
1948 {
1949 	struct wlan_scan_obj *scan_obj;
1950 
1951 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1952 	if (!scan_obj) {
1953 		scm_err("NULL scan obj");
1954 		return false;
1955 	}
1956 
1957 	return scan_obj->pno_cfg.pno_offload_enabled;
1958 }
1959 
1960 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value)
1961 {
1962 	 struct wlan_scan_obj *scan_obj;
1963 
1964 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1965 	if (!scan_obj) {
1966 		scm_err("NULL scan obj");
1967 		return;
1968 	}
1969 
1970 	scan_obj->pno_cfg.pno_offload_enabled = value;
1971 }
1972 
1973 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
1974 {
1975 	struct wlan_scan_obj *scan_obj;
1976 
1977 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1978 	if (!scan_obj) {
1979 		scm_err("NULL scan obj");
1980 		return cfg_default(CFG_PNO_SCAN_SUPPORT);
1981 	}
1982 
1983 	return scan_obj->pno_cfg.scan_support_enabled;
1984 }
1985 
1986 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc)
1987 {
1988 	struct wlan_scan_obj *scan_obj;
1989 
1990 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1991 	if (!scan_obj) {
1992 		scm_err("NULL scan obj");
1993 		return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER);
1994 	}
1995 	return scan_obj->pno_cfg.scan_backoff_multiplier;
1996 }
1997 
1998 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc)
1999 {
2000 		struct wlan_scan_obj *scan_obj;
2001 
2002 		scan_obj = wlan_psoc_get_scan_obj(psoc);
2003 		if (!scan_obj) {
2004 			scm_err("NULL scan obj");
2005 			return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN);
2006 		}
2007 		return scan_obj->pno_cfg.dfs_chnl_scan_enabled;
2008 }
2009 
2010 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc)
2011 {
2012 		struct wlan_scan_obj *scan_obj;
2013 
2014 		scan_obj = wlan_psoc_get_scan_obj(psoc);
2015 		if (!scan_obj) {
2016 			scm_err("NULL scan obj");
2017 			return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
2018 		}
2019 		return scan_obj->pno_cfg.scan_timer_repeat_value;
2020 }
2021 
2022 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc)
2023 {
2024 		struct wlan_scan_obj *scan_obj;
2025 
2026 		scan_obj = wlan_psoc_get_scan_obj(psoc);
2027 		if (!scan_obj) {
2028 			scm_err("NULL scan obj");
2029 			return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER);
2030 		}
2031 		return scan_obj->pno_cfg.slow_scan_multiplier;
2032 }
2033 
2034 uint32_t
2035 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc)
2036 {
2037 	struct wlan_scan_obj *scan_obj;
2038 
2039 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2040 	if (!scan_obj) {
2041 		scm_err("Failed to get scan object");
2042 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
2043 	}
2044 
2045 	return scan_obj->pno_cfg.max_sched_scan_plan_interval;
2046 }
2047 
2048 uint32_t
2049 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc)
2050 {
2051 	struct wlan_scan_obj *scan_obj;
2052 
2053 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2054 	if (!scan_obj) {
2055 		scm_err("Failed to get scan object");
2056 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
2057 	}
2058 
2059 	return scan_obj->pno_cfg.max_sched_scan_plan_iterations;
2060 }
2061 
2062 #endif
2063