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