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