xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c (revision fa47688f04ef001a6dcafaebdcc3c031f15ee75e)
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_objmgr_vdev_obj.h>
39 #include <wlan_dfs_utils_api.h>
40 #include <wlan_policy_mgr_api.h>
41 #endif
42 #include "cfg_ucfg_api.h"
43 #include "wlan_extscan_api.h"
44 
45 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
46 	update_beacon_cb cb, enum scan_cb_type type)
47 {
48 	return scm_scan_register_bcn_cb(psoc, cb, type);
49 }
50 
51 qdf_list_t *ucfg_scan_get_result(struct wlan_objmgr_pdev *pdev,
52 	struct scan_filter *filter)
53 {
54 	return scm_get_scan_result(pdev, filter);
55 }
56 
57 QDF_STATUS ucfg_scan_db_iterate(struct wlan_objmgr_pdev *pdev,
58 	scan_iterator_func func, void *arg)
59 {
60 	return scm_iterate_scan_db(pdev, func, arg);
61 }
62 
63 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list)
64 {
65 	return scm_purge_scan_results(scan_list);
66 }
67 
68 QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev,
69 	struct scan_filter *filter)
70 {
71 	return scm_flush_results(pdev, filter);
72 }
73 
74 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev,
75 	uint8_t *chan_list, uint32_t num_chan)
76 {
77 	scm_filter_valid_channel(pdev, chan_list, num_chan);
78 }
79 
80 QDF_STATUS ucfg_scan_init(void)
81 {
82 	QDF_STATUS status;
83 
84 	status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
85 		wlan_scan_psoc_created_notification, NULL);
86 	if (QDF_IS_STATUS_ERROR(status)) {
87 		scm_err("Failed to register psoc create handler");
88 		goto fail_create_psoc;
89 	}
90 
91 	status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
92 		wlan_scan_psoc_destroyed_notification, NULL);
93 	if (QDF_IS_STATUS_ERROR(status)) {
94 		scm_err("Failed to create psoc delete handler");
95 		goto fail_psoc_destroy;
96 	}
97 	scm_debug("scan psoc create and delete handler registered with objmgr");
98 
99 	status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
100 		wlan_scan_vdev_created_notification, NULL);
101 	if (QDF_IS_STATUS_ERROR(status)) {
102 		scm_err("Failed to register vdev create handler");
103 		goto fail_pdev_create;
104 	}
105 
106 	status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN,
107 		wlan_scan_vdev_destroyed_notification, NULL);
108 	if (QDF_IS_STATUS_SUCCESS(status)) {
109 		scm_debug("scan vdev create and delete handler registered with objmgr");
110 		return QDF_STATUS_SUCCESS;
111 	}
112 
113 	scm_err("Failed to destroy vdev delete handler");
114 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
115 				wlan_scan_vdev_created_notification, NULL);
116 fail_pdev_create:
117 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
118 				wlan_scan_psoc_destroyed_notification, NULL);
119 fail_psoc_destroy:
120 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
121 			wlan_scan_psoc_created_notification, NULL);
122 fail_create_psoc:
123 	return status;
124 }
125 
126 QDF_STATUS ucfg_scan_deinit(void)
127 {
128 	QDF_STATUS status;
129 
130 	status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
131 		wlan_scan_psoc_created_notification, NULL);
132 	if (status != QDF_STATUS_SUCCESS)
133 		scm_err("Failed to unregister psoc create handler");
134 
135 	status = wlan_objmgr_unregister_psoc_destroy_handler(
136 				WLAN_UMAC_COMP_SCAN,
137 				wlan_scan_psoc_destroyed_notification, NULL);
138 	if (status != QDF_STATUS_SUCCESS)
139 		scm_err("Failed to unregister psoc delete handler");
140 
141 	status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
142 		wlan_scan_vdev_created_notification, NULL);
143 	if (status != QDF_STATUS_SUCCESS)
144 		scm_err("Failed to unregister vdev create handler");
145 
146 	status = wlan_objmgr_unregister_vdev_destroy_handler(
147 			WLAN_UMAC_COMP_SCAN,
148 			wlan_scan_vdev_destroyed_notification, NULL);
149 	if (status != QDF_STATUS_SUCCESS)
150 		scm_err("Failed to unregister vdev delete handler");
151 
152 	return status;
153 }
154 
155 #ifdef FEATURE_WLAN_SCAN_PNO
156 
157 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
158 	struct pno_scan_req_params *req)
159 {
160 	struct scan_vdev_obj *scan_vdev_obj;
161 	QDF_STATUS status;
162 
163 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
164 	if (!scan_vdev_obj) {
165 		scm_err("null scan_vdev_obj");
166 		return QDF_STATUS_E_INVAL;
167 	}
168 	if (scan_vdev_obj->pno_in_progress) {
169 		scm_err("pno already in progress");
170 		return QDF_STATUS_E_ALREADY;
171 	}
172 
173 	status = tgt_scan_pno_start(vdev, req);
174 	if (QDF_IS_STATUS_ERROR(status))
175 		scm_err("pno start failed");
176 	else
177 		scan_vdev_obj->pno_in_progress = true;
178 
179 	return status;
180 }
181 
182 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)
183 {
184 	struct scan_vdev_obj *scan_vdev_obj;
185 	QDF_STATUS status;
186 
187 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
188 	if (!scan_vdev_obj) {
189 		scm_err("null scan_vdev_obj");
190 		return QDF_STATUS_E_INVAL;
191 	}
192 	if (!scan_vdev_obj->pno_in_progress) {
193 		scm_debug("pno already stopped");
194 		return QDF_STATUS_E_ALREADY;
195 	}
196 
197 	status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev));
198 	if (QDF_IS_STATUS_ERROR(status))
199 		scm_err("pno start failed");
200 	else
201 		scan_vdev_obj->pno_in_progress = false;
202 
203 	return status;
204 }
205 
206 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev)
207 {
208 	struct scan_vdev_obj *scan_vdev_obj;
209 
210 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
211 	if (!scan_vdev_obj) {
212 		scm_err("null scan_vdev_obj");
213 		return false;
214 	}
215 
216 	return scan_vdev_obj->pno_in_progress;
217 }
218 
219 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
220 {
221 	struct scan_vdev_obj *scan_vdev_obj;
222 
223 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
224 	if (!scan_vdev_obj) {
225 		scm_err("null scan_vdev_obj");
226 		return false;
227 	}
228 
229 	return scan_vdev_obj->pno_match_evt_received;
230 }
231 
232 static QDF_STATUS
233 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
234 		     struct pno_def_config *pno_def)
235 {
236 	struct nlo_mawc_params *mawc_cfg;
237 
238 	qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl");
239 	mawc_cfg = &pno_def->mawc_params;
240 	pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION);
241 	pno_def->top_k_num_of_channels =
242 			cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS);
243 	pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD);
244 	pno_def->channel_prediction_full_scan =
245 			cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER);
246 	pno_def->adaptive_dwell_mode =
247 			cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE);
248 	pno_def->dfs_chnl_scan_enabled =
249 			cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN);
250 	pno_def->scan_support_enabled =
251 			cfg_get(psoc, CFG_PNO_SCAN_SUPPORT);
252 	pno_def->scan_timer_repeat_value =
253 			cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
254 	pno_def->slow_scan_multiplier =
255 			cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER);
256 	pno_def->scan_backoff_multiplier =
257 			cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER);
258 
259 	mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED);
260 	mawc_cfg->exp_backoff_ratio =
261 			cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO);
262 	mawc_cfg->init_scan_interval =
263 			cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL);
264 	mawc_cfg->max_scan_interval =
265 			cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL);
266 
267 	return QDF_STATUS_SUCCESS;
268 }
269 
270 static QDF_STATUS
271 wlan_pno_global_deinit(struct pno_def_config *pno_def)
272 {
273 	qdf_wake_lock_destroy(&pno_def->pno_wake_lock);
274 
275 	return QDF_STATUS_SUCCESS;
276 }
277 
278 #ifdef WLAN_POLICY_MGR_ENABLE
279 /*
280  * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time
281  * depending on active concurrency modes
282  * @vdev: vdev object pointer
283  * @req: scan request
284  *
285  * Return: void
286  */
287 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
288 	struct pno_scan_req_params *req, struct scan_default_params *scan_def)
289 {
290 	bool sap_or_p2p_present;
291 	struct wlan_objmgr_psoc *psoc;
292 
293 	psoc = wlan_vdev_get_psoc(vdev);
294 
295 	if (!psoc)
296 		return;
297 
298 	sap_or_p2p_present = policy_mgr_mode_specific_connection_count(
299 				psoc, PM_SAP_MODE, NULL) ||
300 				policy_mgr_mode_specific_connection_count(
301 				psoc, PM_P2P_GO_MODE, NULL) ||
302 				policy_mgr_mode_specific_connection_count(
303 				psoc, PM_P2P_CLIENT_MODE, NULL);
304 
305 	if (sap_or_p2p_present) {
306 		req->active_dwell_time = scan_def->conc_active_dwell;
307 		req->passive_dwell_time = scan_def->conc_passive_dwell;
308 	}
309 
310 }
311 #else
312 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
313 	struct pno_scan_req_params *req, struct scan_default_params *scan_def){}
314 #endif
315 
316 QDF_STATUS
317 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
318 	struct pno_scan_req_params *req)
319 {
320 	struct scan_default_params *scan_def;
321 	struct wlan_scan_obj *scan;
322 	struct pno_def_config *pno_def;
323 
324 	if (!vdev || !req) {
325 		scm_err("vdev: 0x%pK, req: 0x%pK",
326 			vdev, req);
327 		return QDF_STATUS_E_INVAL;
328 	}
329 
330 	scan = wlan_vdev_get_scan_obj(vdev);
331 	if (!scan) {
332 		scm_err("scan is NULL");
333 		return QDF_STATUS_E_INVAL;
334 	}
335 	scan_def = wlan_vdev_get_def_scan_params(vdev);
336 	if (!scan_def) {
337 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
338 		return QDF_STATUS_E_NULL_VALUE;
339 	}
340 
341 	pno_def = &scan->pno_cfg;
342 	req->active_dwell_time = scan_def->active_dwell;
343 	req->passive_dwell_time = scan_def->passive_dwell;
344 	req->scan_random.randomize = scan_def->enable_mac_spoofing;
345 
346 	/*
347 	 *  Update active and passive dwell time depending
348 	 *  upon the present active concurrency mode
349 	 */
350 	ucfg_scan_update_pno_dwell_time(vdev, req, scan_def);
351 	req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
352 	req->pno_channel_prediction = pno_def->channel_prediction;
353 	req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
354 	req->stationary_thresh = pno_def->stationary_thresh;
355 	req->channel_prediction_full_scan =
356 			pno_def->channel_prediction_full_scan;
357 	req->mawc_params.vdev_id = wlan_vdev_get_id(vdev);
358 	qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params,
359 			sizeof(req->mawc_params));
360 
361 	return QDF_STATUS_SUCCESS;
362 }
363 
364 QDF_STATUS
365 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
366 	scan_event_handler event_cb, void *arg)
367 {
368 	struct wlan_scan_obj *scan;
369 
370 	if (!psoc) {
371 		scm_err("null psoc");
372 		return QDF_STATUS_E_INVAL;
373 	}
374 	scan = wlan_psoc_get_scan_obj(psoc);
375 	qdf_spin_lock_bh(&scan->lock);
376 	scan->pno_cfg.pno_cb.func = event_cb;
377 	scan->pno_cfg.pno_cb.arg = arg;
378 	qdf_spin_unlock_bh(&scan->lock);
379 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
380 
381 	return QDF_STATUS_SUCCESS;
382 }
383 
384 #else
385 
386 static inline QDF_STATUS
387 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
388 		     struct pno_def_config *pno_def)
389 {
390 	return QDF_STATUS_SUCCESS;
391 }
392 static inline QDF_STATUS
393 wlan_pno_global_deinit(struct pno_def_config *pno_def)
394 {
395 	return QDF_STATUS_SUCCESS;
396 }
397 
398 #endif
399 
400 #ifdef WLAN_POLICY_MGR_ENABLE
401 /**
402  * ucfg_scan_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags
403  * @req: pointer to scan request
404  *
405  * This function sets scan_ctrl_flags_ext value depending on the type of
406  * scan and the channel lists.
407  *
408  * Non-DBS scan is requested if any of the below case is met:
409  *     1. HW is DBS incapable
410  *     2. A high accuracy scan request is sent by kernel.
411  *
412  * DBS scan is enabled for these conditions:
413  *     1. A low power or low span scan request is sent by kernel.
414  * For remaining cases DBS is enabled by default.
415  * Return: void
416  */
417 static void
418 ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
419 {
420 	struct wlan_objmgr_psoc *psoc;
421 	uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
422 
423 	psoc = wlan_vdev_get_psoc(req->vdev);
424 
425 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
426 		scm_debug("dbs disabled, going for non-dbs scan");
427 		scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
428 		goto end;
429 	}
430 
431 	if (req->scan_req.scan_policy_high_accuracy) {
432 		scm_debug("high accuracy scan received, going for non-dbs scan");
433 		scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
434 		goto end;
435 	}
436 	if ((req->scan_req.scan_policy_low_power) ||
437 	    (req->scan_req.scan_policy_low_span)) {
438 		scm_debug("low power/span scan received, going for dbs scan");
439 		scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY;
440 		goto end;
441 	}
442 
443 end:
444 	req->scan_req.scan_ctrl_flags_ext |=
445 		((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT)
446 		 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK);
447 	scm_debug("scan_ctrl_flags_ext: 0x%x",
448 			req->scan_req.scan_ctrl_flags_ext);
449 }
450 
451 /**
452  * ucfg_update_passive_dwell_time() - update dwell passive time
453  * @vdev: vdev object
454  * @req: scan request
455  *
456  * Return: None
457  */
458 static void
459 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
460 					    struct scan_start_request *req)
461 {
462 	struct wlan_objmgr_psoc *psoc;
463 
464 	psoc = wlan_vdev_get_psoc(vdev);
465 	if (!psoc)
466 		return;
467 
468 	if (policy_mgr_is_sta_connected_2g(psoc) &&
469 	    !policy_mgr_is_hw_dbs_capable(psoc) &&
470 	    ucfg_scan_get_bt_activity(psoc))
471 		req->scan_req.dwell_time_passive =
472 				PASSIVE_DWELL_TIME_BT_A2DP_ENABLED;
473 }
474 
475 static const struct probe_time_dwell_time
476 	scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = {
477 	{28, 11},               /* 0 SSID */
478 	{28, 20},               /* 1 SSID */
479 	{28, 20},               /* 2 SSID */
480 	{28, 20},               /* 3 SSID */
481 	{28, 20},               /* 4 SSID */
482 	{28, 20},               /* 5 SSID */
483 	{28, 20},               /* 6 SSID */
484 	{28, 11},               /* 7 SSID */
485 	{28, 11},               /* 8 SSID */
486 	{28, 11},               /* 9 SSID */
487 	{28, 8}                 /* 10 SSID */
488 };
489 
490 /**
491  * ucfg_scan_get_burst_duration() - get burst duration depending on max chan
492  * and miracast.
493  * @max_ch_time: max channel time
494  * @miracast_enabled: if miracast is enabled
495  *
496  * Return: burst_duration
497  */
498 static inline
499 int ucfg_scan_get_burst_duration(int max_ch_time,
500 					     bool miracast_enabled)
501 {
502 	int burst_duration = 0;
503 
504 	if (miracast_enabled) {
505 		/*
506 		 * When miracast is running, burst
507 		 * duration needs to be minimum to avoid
508 		 * any stutter or glitch in miracast
509 		 * during station scan
510 		 */
511 		if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION)
512 			burst_duration = max_ch_time;
513 		else
514 			burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION;
515 	} else {
516 		/*
517 		 * If miracast is not running, accommodate max
518 		 * stations to make the scans faster
519 		 */
520 		burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS *
521 							max_ch_time;
522 
523 		if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) {
524 			uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION /
525 								 max_ch_time;
526 
527 			if (channels)
528 				burst_duration = channels * max_ch_time;
529 			else
530 				burst_duration =
531 					 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION;
532 		}
533 	}
534 	return burst_duration;
535 }
536 
537 /**
538  * ucfg_scan_req_update_params() - update scan req params depending on
539  * concurrent mode present.
540  * @vdev: vdev object pointer
541  * @req: scan request
542  * @scan_obj: scan object
543  *
544  * Return: void
545  */
546 static void ucfg_scan_req_update_concurrency_params(
547 	struct wlan_objmgr_vdev *vdev, struct scan_start_request *req,
548 	struct wlan_scan_obj *scan_obj)
549 {
550 	bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present;
551 	struct wlan_objmgr_psoc *psoc;
552 
553 	psoc = wlan_vdev_get_psoc(vdev);
554 
555 	if (!psoc)
556 		return;
557 
558 	ap_present = policy_mgr_mode_specific_connection_count(
559 				psoc, PM_SAP_MODE, NULL);
560 	go_present = policy_mgr_mode_specific_connection_count(
561 				psoc, PM_P2P_GO_MODE, NULL);
562 	p2p_cli_present = policy_mgr_mode_specific_connection_count(
563 				psoc, PM_P2P_CLIENT_MODE, NULL);
564 	sta_active = policy_mgr_mode_specific_connection_count(
565 				psoc, PM_STA_MODE, NULL);
566 	ndi_present = policy_mgr_mode_specific_connection_count(
567 				psoc, PM_NDI_MODE, NULL);
568 
569 	if (policy_mgr_get_connection_count(psoc)) {
570 		if (req->scan_req.scan_f_passive)
571 			req->scan_req.dwell_time_passive =
572 				scan_obj->scan_def.conc_passive_dwell;
573 		else
574 			req->scan_req.dwell_time_active =
575 				scan_obj->scan_def.conc_active_dwell;
576 		req->scan_req.max_rest_time =
577 				scan_obj->scan_def.conc_max_rest_time;
578 		req->scan_req.min_rest_time =
579 			scan_obj->scan_def.conc_min_rest_time;
580 		req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time;
581 	}
582 
583 	if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS)
584 		req->scan_req.adaptive_dwell_time_mode =
585 			scan_obj->scan_def.adaptive_dwell_time_mode_nc;
586 	/*
587 	 * If AP is active set min rest time same as max rest time, so that
588 	 * firmware spends more time on home channel which will increase the
589 	 * probability of sending beacon at TBTT
590 	 */
591 	if (ap_present || go_present) {
592 		req->scan_req.dwell_time_active_2g = 0;
593 		req->scan_req.min_rest_time = req->scan_req.max_rest_time;
594 	}
595 
596 	/*
597 	 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell
598 	 * time for 2g channels instead of dwell_time_active_2g
599 	 */
600 	if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) {
601 		req->scan_req.dwell_time_active_2g = 0;
602 	}
603 
604 	if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) {
605 		/*
606 		 * Decide burst_duration and dwell_time_active based on
607 		 * what type of devices are active.
608 		 */
609 		do {
610 			if (ap_present && go_present && sta_active) {
611 				if (req->scan_req.dwell_time_active <=
612 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION)
613 					req->scan_req.burst_duration =
614 						req->scan_req.dwell_time_active;
615 				else
616 					req->scan_req.burst_duration =
617 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION;
618 
619 				break;
620 			}
621 
622 			if (scan_obj->miracast_enabled &&
623 			    policy_mgr_is_mcc_in_24G(psoc))
624 				req->scan_req.max_rest_time =
625 				  scan_obj->scan_def.sta_miracast_mcc_rest_time;
626 
627 			if (go_present) {
628 				/*
629 				 * Background scan while GO is sending beacons.
630 				 * Every off-channel transition has overhead of
631 				 * 2 beacon intervals for NOA. Maximize number
632 				 * of channels in every transition by using
633 				 * burst scan.
634 				 */
635 				req->scan_req.burst_duration =
636 					ucfg_scan_get_burst_duration(
637 						req->scan_req.dwell_time_active,
638 						scan_obj->miracast_enabled);
639 				break;
640 			}
641 			if ((sta_active || p2p_cli_present) &&
642 			    !req->scan_req.burst_duration) {
643 				/* Typical background scan.
644 				 * Disable burst scan for now.
645 				 */
646 				req->scan_req.burst_duration = 0;
647 				break;
648 			}
649 
650 			if (ndi_present) {
651 				req->scan_req.burst_duration =
652 					ucfg_scan_get_burst_duration(
653 						req->scan_req.dwell_time_active,
654 						scan_obj->miracast_enabled);
655 				break;
656 			}
657 		} while (0);
658 
659 		if (ap_present) {
660 			uint8_t ssid_num;
661 			ssid_num = req->scan_req.num_ssids *
662 					req->scan_req.num_bssid;
663 			req->scan_req.repeat_probe_time =
664 				scan_probe_time_dwell_time_map[
665 					QDF_MIN(ssid_num,
666 					SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE
667 					- 1)].probe_time;
668 			req->scan_req.n_probes =
669 				(req->scan_req.repeat_probe_time > 0) ?
670 				req->scan_req.dwell_time_active /
671 				req->scan_req.repeat_probe_time : 0;
672 		}
673 	}
674 
675 	if (ap_present) {
676 		uint8_t ap_chan;
677 		struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
678 
679 		ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL);
680 		/*
681 		 * P2P/STA scan while SoftAP is sending beacons.
682 		 * Max duration of CTS2self is 32 ms, which limits the
683 		 * dwell time. If DBS is supported and if SAP is on 2G channel
684 		 * then keep passive dwell time default.
685 		 */
686 		req->scan_req.dwell_time_active =
687 				QDF_MIN(req->scan_req.dwell_time_active,
688 					(SCAN_CTS_DURATION_MS_MAX -
689 					SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME));
690 		if (!policy_mgr_is_hw_dbs_capable(psoc) ||
691 		    (policy_mgr_is_hw_dbs_capable(psoc) &&
692 		     WLAN_CHAN_IS_5GHZ(ap_chan))) {
693 			req->scan_req.dwell_time_passive =
694 				req->scan_req.dwell_time_active;
695 		}
696 		req->scan_req.burst_duration = 0;
697 		if (utils_is_dfs_ch(pdev, ap_chan))
698 			req->scan_req.burst_duration =
699 				SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS *
700 				req->scan_req.dwell_time_active;
701 	}
702 }
703 
704 #else
705 static inline void ucfg_scan_req_update_concurrency_params(
706 	struct wlan_objmgr_vdev *vdev, struct scan_start_request *req,
707 	struct wlan_scan_obj *scan_obj)
708 {
709 }
710 static inline void
711 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
712 					    struct scan_start_request *req) {}
713 static inline void
714 ucfg_scan_update_dbs_scan_ctrl_ext_flag(
715 	struct scan_start_request *req) {}
716 #endif
717 
718 QDF_STATUS
719 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
720 		struct chan_list *chan_list)
721 {
722 	uint8_t pdev_id;
723 	struct wlan_scan_obj *scan_obj;
724 
725 	if (!pdev || !chan_list) {
726 		scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list);
727 		return QDF_STATUS_E_NULL_VALUE;
728 	}
729 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
730 	scan_obj = wlan_pdev_get_scan_obj(pdev);
731 
732 	qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list,
733 			chan_list, sizeof(*chan_list));
734 
735 	return QDF_STATUS_SUCCESS;
736 }
737 
738 /**
739  * ucfg_update_channel_list() - update scan req params depending on dfs inis
740  * and initial scan request.
741  * @req: scan request
742  * @scan_obj: scan object
743  *
744  * Return: void
745  */
746 static void
747 ucfg_update_channel_list(struct scan_start_request *req,
748 			 struct wlan_scan_obj *scan_obj)
749 {
750 	uint8_t i;
751 	uint8_t num_scan_channels = 0;
752 	struct scan_vdev_obj *scan_vdev_obj;
753 	struct wlan_objmgr_pdev *pdev;
754 	bool first_scan_done = true;
755 
756 	pdev = wlan_vdev_get_pdev(req->vdev);
757 
758 	scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev);
759 	if (!scan_vdev_obj) {
760 		scm_err("null scan_vdev_obj");
761 		return;
762 	}
763 
764 	if (!scan_vdev_obj->first_scan_done) {
765 		first_scan_done = false;
766 		scan_vdev_obj->first_scan_done = true;
767 	}
768 
769 	/*
770 	 * No need to update channels if req is passive scan and single channel
771 	 * ie ROC, Preauth etc
772 	 */
773 	if (req->scan_req.scan_f_passive &&
774 	    req->scan_req.chan_list.num_chan == 1)
775 		return;
776 
777 	/* do this only for STA and P2P-CLI mode */
778 	if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) &&
779 	    !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE))
780 		return;
781 
782 	if (scan_obj->scan_def.allow_dfs_chan_in_scan &&
783 	    (scan_obj->scan_def.allow_dfs_chan_in_first_scan ||
784 	     first_scan_done))
785 		return;
786 
787 	for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
788 		if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev,
789 							req->scan_req.chan_list.
790 							chan[i].freq)))
791 			continue;
792 		req->scan_req.chan_list.chan[num_scan_channels++] =
793 				req->scan_req.chan_list.chan[i];
794 	}
795 	req->scan_req.chan_list.num_chan = num_scan_channels;
796 }
797 
798 /**
799  * ucfg_scan_req_update_params() - update scan req params depending on modes
800  * and scan type.
801  * @vdev: vdev object pointer
802  * @req: scan request
803  * @scan_obj: scan object
804  *
805  * Return: void
806  */
807 static void
808 ucfg_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
809 	struct scan_start_request *req, struct wlan_scan_obj *scan_obj)
810 {
811 	struct chan_list *custom_chan_list;
812 	struct wlan_objmgr_pdev *pdev;
813 	uint8_t pdev_id;
814 
815 	/* Ensure correct number of probes are sent on active channel */
816 	if (!req->scan_req.repeat_probe_time)
817 		req->scan_req.repeat_probe_time =
818 			req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT;
819 
820 	if (req->scan_req.scan_f_passive)
821 		req->scan_req.scan_ctrl_flags_ext |=
822 			SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME;
823 
824 	if (!req->scan_req.n_probes)
825 		req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ?
826 					  req->scan_req.dwell_time_active /
827 					  req->scan_req.repeat_probe_time : 0;
828 
829 	if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) {
830 		req->scan_req.scan_f_cck_rates = true;
831 		if (!req->scan_req.num_ssids)
832 			req->scan_req.scan_f_bcast_probe = true;
833 		req->scan_req.scan_f_add_ds_ie_in_probe = true;
834 		req->scan_req.scan_f_filter_prb_req = true;
835 		req->scan_req.scan_f_add_tpc_ie_in_probe = true;
836 	} else {
837 		req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC;
838 		req->scan_req.dwell_time_active_2g = 0;
839 		if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) {
840 			req->scan_req.repeat_probe_time = 0;
841 		} else {
842 			req->scan_req.scan_f_filter_prb_req = true;
843 			if (!req->scan_req.num_ssids)
844 				req->scan_req.scan_f_bcast_probe = true;
845 
846 			req->scan_req.dwell_time_active +=
847 					P2P_SEARCH_DWELL_TIME_INC;
848 			/*
849 			 * 3 channels with default max dwell time 40 ms.
850 			 * Cap limit will be set by
851 			 * P2P_SCAN_MAX_BURST_DURATION. Burst duration
852 			 * should be such that no channel is scanned less
853 			 * than the dwell time in normal scenarios.
854 			 */
855 			if (req->scan_req.chan_list.num_chan ==
856 			    WLAN_P2P_SOCIAL_CHANNELS &&
857 			    !scan_obj->miracast_enabled)
858 				req->scan_req.repeat_probe_time =
859 					req->scan_req.dwell_time_active / 5;
860 			else
861 				req->scan_req.repeat_probe_time =
862 					req->scan_req.dwell_time_active / 3;
863 
864 			req->scan_req.burst_duration =
865 					BURST_SCAN_MAX_NUM_OFFCHANNELS *
866 					req->scan_req.dwell_time_active;
867 			if (req->scan_req.burst_duration >
868 			    P2P_SCAN_MAX_BURST_DURATION) {
869 				uint8_t channels =
870 					P2P_SCAN_MAX_BURST_DURATION /
871 					req->scan_req.dwell_time_active;
872 				if (channels)
873 					req->scan_req.burst_duration =
874 						channels *
875 						req->scan_req.dwell_time_active;
876 				else
877 					req->scan_req.burst_duration =
878 						P2P_SCAN_MAX_BURST_DURATION;
879 			}
880 			req->scan_req.scan_ev_bss_chan = false;
881 		}
882 	}
883 
884 	if (!req->scan_req.scan_f_passive)
885 		ucfg_update_passive_dwell_time(vdev, req);
886 	ucfg_scan_update_dbs_scan_ctrl_ext_flag(req);
887 
888 	/*
889 	 * No need to update conncurrency parmas if req is passive scan on
890 	 * single channel ie ROC, Preauth etc
891 	 */
892 	if (!(req->scan_req.scan_f_passive &&
893 	      req->scan_req.chan_list.num_chan == 1))
894 		ucfg_scan_req_update_concurrency_params(vdev, req, scan_obj);
895 
896 	/* Set wide band flag if enabled. This will cause
897 	 * phymode TLV being sent to FW.
898 	 */
899 	pdev = wlan_vdev_get_pdev(vdev);
900 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
901 	if (ucfg_scan_get_wide_band_scan(pdev))
902 		req->scan_req.scan_f_wide_band = true;
903 	else
904 		req->scan_req.scan_f_wide_band = false;
905 
906 	/* Overwrite scan channles with custom scan channel
907 	 * list if configured.
908 	 */
909 	custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list;
910 	if (custom_chan_list->num_chan)
911 		qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list,
912 				sizeof(struct chan_list));
913 	else if (!req->scan_req.chan_list.num_chan)
914 		ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
915 
916 	ucfg_update_channel_list(req, scan_obj);
917 	scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d "
918 			"n_probes %d flags_ext %x, wide_bw_scan: %d",
919 			req->scan_req.dwell_time_active,
920 			req->scan_req.dwell_time_passive,
921 			req->scan_req.repeat_probe_time, req->scan_req.n_probes,
922 			req->scan_req.scan_ctrl_flags_ext,
923 			req->scan_req.scan_f_wide_band);
924 }
925 
926 QDF_STATUS
927 ucfg_scan_start(struct scan_start_request *req)
928 {
929 	struct scheduler_msg msg = {0};
930 	QDF_STATUS status;
931 	struct wlan_scan_obj *scan_obj;
932 	struct wlan_objmgr_pdev *pdev;
933 	uint8_t idx;
934 
935 	if (!req || !req->vdev) {
936 		scm_err("req or vdev within req is NULL");
937 		if (req)
938 			scm_scan_free_scan_request_mem(req);
939 		return QDF_STATUS_E_NULL_VALUE;
940 	}
941 
942 	pdev = wlan_vdev_get_pdev(req->vdev);
943 	if (!pdev) {
944 		scm_err("Failed to get pdev object");
945 		scm_scan_free_scan_request_mem(req);
946 		return QDF_STATUS_E_NULL_VALUE;
947 	}
948 
949 	if (!scm_is_scan_allowed(req->vdev)) {
950 		scm_err("scan disabled, rejecting the scan req");
951 		scm_scan_free_scan_request_mem(req);
952 		return QDF_STATUS_E_AGAIN;
953 	}
954 
955 	scan_obj = wlan_pdev_get_scan_obj(pdev);
956 	if (!scan_obj) {
957 		scm_err("Failed to get scan object");
958 		scm_scan_free_scan_request_mem(req);
959 		return QDF_STATUS_E_NULL_VALUE;
960 	}
961 
962 	scm_debug("reqid: %d, scanid: %d, vdevid: %d",
963 		req->scan_req.scan_req_id, req->scan_req.scan_id,
964 		req->scan_req.vdev_id);
965 
966 	ucfg_scan_req_update_params(req->vdev, req, scan_obj);
967 
968 	/* Try to get vdev reference. Return if reference could
969 	 * not be taken. Reference will be released once scan
970 	 * request handling completes along with free of @req.
971 	 */
972 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
973 	if (QDF_IS_STATUS_ERROR(status)) {
974 		scm_info("unable to get reference");
975 		scm_scan_free_scan_request_mem(req);
976 		return status;
977 	}
978 
979 	scm_info("request to scan %d channels",
980 		 req->scan_req.chan_list.num_chan);
981 	for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++)
982 		scm_debug("chan[%d]: freq:%d, phymode:%d", idx,
983 			  req->scan_req.chan_list.chan[idx].freq,
984 			  req->scan_req.chan_list.chan[idx].phymode);
985 
986 	msg.bodyptr = req;
987 	msg.callback = scm_scan_start_req;
988 	msg.flush_callback = scm_scan_start_flush_callback;
989 
990 	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
991 					QDF_MODULE_ID_SCAN,
992 					QDF_MODULE_ID_OS_IF, &msg);
993 	if (QDF_IS_STATUS_ERROR(status)) {
994 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
995 		scm_scan_free_scan_request_mem(req);
996 	}
997 
998 	return status;
999 }
1000 
1001 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
1002 				     enum scan_disable_reason reason)
1003 {
1004 	struct wlan_scan_obj *scan_obj;
1005 
1006 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1007 	if (!scan_obj) {
1008 		scm_err("Failed to get scan object");
1009 		return QDF_STATUS_E_NULL_VALUE;
1010 	}
1011 
1012 	scan_obj->scan_disabled &= ~reason;
1013 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
1014 
1015 	return QDF_STATUS_SUCCESS;
1016 }
1017 
1018 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
1019 				      enum scan_disable_reason reason)
1020 {
1021 	struct wlan_scan_obj *scan_obj;
1022 
1023 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1024 	if (!scan_obj) {
1025 		scm_err("Failed to get scan object");
1026 		return QDF_STATUS_E_NULL_VALUE;
1027 	}
1028 
1029 	scan_obj->scan_disabled |= reason;
1030 
1031 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
1032 
1033 	return QDF_STATUS_SUCCESS;
1034 }
1035 
1036 
1037 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
1038 				     enum scan_disable_reason reason)
1039 {
1040 	struct scan_vdev_obj *scan_vdev_obj;
1041 
1042 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
1043 	if (!scan_vdev_obj) {
1044 		scm_err("null scan_vdev_obj");
1045 		return QDF_STATUS_E_NULL_VALUE;
1046 	}
1047 
1048 	scan_vdev_obj->scan_disabled &= ~reason;
1049 
1050 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
1051 
1052 	return QDF_STATUS_SUCCESS;
1053 }
1054 
1055 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
1056 				      enum scan_disable_reason reason)
1057 {
1058 	struct scan_vdev_obj *scan_vdev_obj;
1059 
1060 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
1061 	if (!scan_vdev_obj) {
1062 		scm_err("null scan_vdev_obj");
1063 		return QDF_STATUS_E_NULL_VALUE;
1064 	}
1065 
1066 	scan_vdev_obj->scan_disabled |= reason;
1067 
1068 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
1069 
1070 	return QDF_STATUS_SUCCESS;
1071 }
1072 
1073 
1074 QDF_STATUS ucfg_scan_set_miracast(
1075 	struct wlan_objmgr_psoc *psoc, bool enable)
1076 {
1077 	struct wlan_scan_obj *scan_obj;
1078 
1079 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1080 	if (!scan_obj) {
1081 		scm_err("Failed to get scan object");
1082 		return QDF_STATUS_E_NULL_VALUE;
1083 	}
1084 	scan_obj->miracast_enabled = enable;
1085 	scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled);
1086 
1087 	return QDF_STATUS_SUCCESS;
1088 }
1089 
1090 QDF_STATUS
1091 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable)
1092 {
1093 	uint8_t pdev_id;
1094 	struct wlan_scan_obj *scan_obj;
1095 
1096 	if (!pdev) {
1097 		scm_warn("null vdev");
1098 		return QDF_STATUS_E_NULL_VALUE;
1099 	}
1100 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1101 	scan_obj = wlan_pdev_get_scan_obj(pdev);
1102 	if (!scan_obj)
1103 		return QDF_STATUS_E_FAILURE;
1104 
1105 	scm_debug("set wide_band_scan to %d", enable);
1106 	scan_obj->pdev_info[pdev_id].wide_band_scan = enable;
1107 
1108 	return QDF_STATUS_SUCCESS;
1109 }
1110 
1111 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev)
1112 {
1113 	uint8_t pdev_id;
1114 	struct wlan_scan_obj *scan_obj;
1115 
1116 	if (!pdev) {
1117 		scm_warn("null vdev");
1118 		return QDF_STATUS_E_NULL_VALUE;
1119 	}
1120 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1121 	scan_obj = wlan_pdev_get_scan_obj(pdev);
1122 	if (!scan_obj)
1123 		return QDF_STATUS_E_FAILURE;
1124 
1125 	return scan_obj->pdev_info[pdev_id].wide_band_scan;
1126 }
1127 
1128 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID
1129 QDF_STATUS
1130 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev,
1131 				       uint8_t *bssid, struct wlan_ssid *ssid)
1132 {
1133 	uint8_t pdev_id;
1134 	struct wlan_scan_obj *scan_obj;
1135 
1136 	if (!pdev) {
1137 		scm_warn("null vdev");
1138 		return QDF_STATUS_E_NULL_VALUE;
1139 	}
1140 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1141 	scan_obj = wlan_pdev_get_scan_obj(pdev);
1142 	if (!scan_obj)
1143 		return QDF_STATUS_E_FAILURE;
1144 
1145 	scm_debug("Configure bsssid:%pM ssid:%.*s",
1146 		  bssid, ssid->length, ssid->ssid);
1147 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid,
1148 		     bssid, QDF_MAC_ADDR_SIZE);
1149 	scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length;
1150 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid,
1151 		     ssid->ssid,
1152 		     scan_obj->pdev_info[pdev_id].conf_ssid.length);
1153 
1154 	return QDF_STATUS_SUCCESS;
1155 }
1156 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */
1157 
1158 QDF_STATUS
1159 ucfg_scan_cancel(struct scan_cancel_request *req)
1160 {
1161 	struct scheduler_msg msg = {0};
1162 	QDF_STATUS status;
1163 
1164 	if (!req || !req->vdev) {
1165 		scm_err("req or vdev within req is NULL");
1166 		if (req)
1167 			qdf_mem_free(req);
1168 		return QDF_STATUS_E_NULL_VALUE;
1169 	}
1170 	scm_debug("reqid: %d, scanid: %d, vdevid: %d, type: %d",
1171 		  req->cancel_req.requester, req->cancel_req.scan_id,
1172 		  req->cancel_req.vdev_id, req->cancel_req.req_type);
1173 
1174 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
1175 	if (QDF_IS_STATUS_ERROR(status)) {
1176 		scm_info("Failed to get vdev ref; status:%d", status);
1177 		goto req_free;
1178 	}
1179 
1180 	msg.bodyptr = req;
1181 	msg.callback = scm_scan_cancel_req;
1182 	msg.flush_callback = scm_scan_cancel_flush_callback;
1183 
1184 	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
1185 					QDF_MODULE_ID_SCAN,
1186 					QDF_MODULE_ID_OS_IF, &msg);
1187 	if (QDF_IS_STATUS_ERROR(status))
1188 		goto vdev_put;
1189 
1190 	return QDF_STATUS_SUCCESS;
1191 
1192 vdev_put:
1193 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1194 
1195 req_free:
1196 	qdf_mem_free(req);
1197 
1198 	return status;
1199 }
1200 
1201 QDF_STATUS
1202 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
1203 {
1204 	QDF_STATUS status;
1205 	bool cancel_vdev = false, cancel_pdev = false;
1206 	struct wlan_objmgr_vdev *vdev;
1207 	struct wlan_objmgr_pdev *pdev;
1208 	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
1209 	qdf_event_t cancel_scan_event;
1210 
1211 	if (!req || !req->vdev) {
1212 		scm_err("req or vdev within req is NULL");
1213 		if (req)
1214 			qdf_mem_free(req);
1215 		return QDF_STATUS_E_NULL_VALUE;
1216 	}
1217 
1218 	if (req->cancel_req.req_type ==
1219 	   WLAN_SCAN_CANCEL_PDEV_ALL)
1220 		cancel_pdev = true;
1221 	else if (req->cancel_req.req_type ==
1222 	   WLAN_SCAN_CANCEL_VDEV_ALL)
1223 		cancel_vdev = true;
1224 
1225 	vdev = req->vdev;
1226 	status = ucfg_scan_cancel(req);
1227 	if (QDF_IS_STATUS_ERROR(status))
1228 		return status;
1229 
1230 	memset(&cancel_scan_event, 0, sizeof(cancel_scan_event));
1231 	/*
1232 	 * If cancel req is to cancel all scan of pdev or vdev
1233 	 * wait until all scan of pdev or vdev get cancelled
1234 	 */
1235 	qdf_event_create(&cancel_scan_event);
1236 	qdf_event_reset(&cancel_scan_event);
1237 
1238 	if (cancel_pdev) {
1239 		pdev = wlan_vdev_get_pdev(vdev);
1240 		while ((ucfg_scan_get_pdev_status(pdev) !=
1241 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
1242 			scm_debug("wait for all pdev scan to get complete");
1243 				qdf_wait_single_event(&cancel_scan_event,
1244 					qdf_system_msecs_to_ticks(
1245 					SCM_CANCEL_SCAN_WAIT_TIME));
1246 			max_wait_iterations--;
1247 		}
1248 	} else if (cancel_vdev) {
1249 		while ((ucfg_scan_get_vdev_status(vdev) !=
1250 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
1251 			scm_debug("wait for all vdev scan to get complete");
1252 				qdf_wait_single_event(&cancel_scan_event,
1253 					qdf_system_msecs_to_ticks(
1254 					SCM_CANCEL_SCAN_WAIT_TIME));
1255 			max_wait_iterations--;
1256 		}
1257 	}
1258 
1259 	qdf_event_destroy(&cancel_scan_event);
1260 
1261 	if (!max_wait_iterations) {
1262 		scm_err("Failed to wait for scans to get complete");
1263 		return QDF_STATUS_E_TIMEOUT;
1264 	}
1265 
1266 	return status;
1267 }
1268 
1269 wlan_scan_requester
1270 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc,
1271 	uint8_t *name, scan_event_handler event_cb, void *arg)
1272 {
1273 	int i, j;
1274 	struct wlan_scan_obj *scan;
1275 	struct scan_requester_info *requesters;
1276 	wlan_scan_requester requester = {0};
1277 
1278 	if (!psoc) {
1279 		scm_err("null psoc");
1280 		return 0;
1281 	}
1282 	scan = wlan_psoc_get_scan_obj(psoc);
1283 	if (!scan)
1284 		return 0;
1285 
1286 	requesters = scan->requesters;
1287 	qdf_spin_lock_bh(&scan->lock);
1288 	for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) {
1289 		if (requesters[i].requester == 0) {
1290 			requesters[i].requester =
1291 				WLAN_SCAN_REQUESTER_ID_PREFIX | i;
1292 			j = 0;
1293 			while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) {
1294 				requesters[i].module[j] = name[j];
1295 				++j;
1296 			}
1297 			requesters[i].module[j] = 0;
1298 			requesters[i].ev_handler.func = event_cb;
1299 			requesters[i].ev_handler.arg = arg;
1300 			requester = requesters[i].requester;
1301 			break;
1302 		}
1303 	}
1304 	qdf_spin_unlock_bh(&scan->lock);
1305 	scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d",
1306 		  name, event_cb, arg, requester);
1307 
1308 	return requester;
1309 }
1310 
1311 void
1312 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
1313 	wlan_scan_requester requester)
1314 {
1315 	int idx;
1316 	struct wlan_scan_obj *scan;
1317 	struct scan_requester_info *requesters;
1318 
1319 	idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX;
1320 	if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) {
1321 		scm_err("prefix didn't match for requester id %d", requester);
1322 		return;
1323 	}
1324 
1325 	idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
1326 	if (idx >= WLAN_MAX_REQUESTORS) {
1327 		scm_err("requester id %d greater than max value", requester);
1328 		return;
1329 	}
1330 
1331 	if (!psoc) {
1332 		scm_err("null psoc");
1333 		return;
1334 	}
1335 	scan = wlan_psoc_get_scan_obj(psoc);
1336 	if (!scan)
1337 		return;
1338 	requesters = scan->requesters;
1339 	scm_debug("reqid: %d", requester);
1340 
1341 	qdf_spin_lock_bh(&scan->lock);
1342 	requesters[idx].requester = 0;
1343 	requesters[idx].module[0] = 0;
1344 	requesters[idx].ev_handler.func = NULL;
1345 	requesters[idx].ev_handler.arg = NULL;
1346 	qdf_spin_unlock_bh(&scan->lock);
1347 }
1348 
1349 uint8_t*
1350 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
1351 	wlan_scan_requester requester)
1352 {
1353 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
1354 	struct wlan_scan_obj *scan;
1355 	struct scan_requester_info *requesters;
1356 
1357 	if (!psoc) {
1358 		scm_err("null psoc");
1359 		return "null";
1360 	}
1361 	scan = wlan_psoc_get_scan_obj(psoc);
1362 	if (!scan)
1363 		return "null";
1364 
1365 	requesters = scan->requesters;
1366 
1367 	if ((idx < WLAN_MAX_REQUESTORS) &&
1368 		(requesters[idx].requester == requester)) {
1369 		return requesters[idx].module;
1370 	}
1371 
1372 	return (uint8_t *)"unknown";
1373 }
1374 
1375 wlan_scan_id
1376 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
1377 {
1378 	wlan_scan_id id;
1379 	struct wlan_scan_obj *scan;
1380 
1381 	if (!psoc) {
1382 		QDF_ASSERT(0);
1383 		scm_err("null psoc");
1384 		return 0;
1385 	}
1386 	scan = wlan_psoc_get_scan_obj(psoc);
1387 
1388 	id = qdf_atomic_inc_return(&scan->scan_ids);
1389 	id =  id & WLAN_SCAN_ID_MASK;
1390 	/* Mark this scan request as triggered by host
1391 	 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag.
1392 	 */
1393 	id =  id | WLAN_HOST_SCAN_REQ_ID_PREFIX;
1394 	scm_debug("scan_id: 0x%x", id);
1395 
1396 	return id;
1397 }
1398 
1399 static QDF_STATUS
1400 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
1401 	scan_event_handler event_cb, void *arg)
1402 {
1403 	struct cb_handler *cb_handler;
1404 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
1405 
1406 	/* Assign next available slot to this registration request */
1407 	cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
1408 	cb_handler->func = event_cb;
1409 	cb_handler->arg = arg;
1410 	pdev_ev_handler->handler_cnt++;
1411 
1412 	return QDF_STATUS_SUCCESS;
1413 }
1414 
1415 QDF_STATUS
1416 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
1417 	scan_event_handler event_cb, void *arg)
1418 {
1419 	uint32_t idx;
1420 	struct wlan_scan_obj *scan;
1421 	struct pdev_scan_ev_handler *pdev_ev_handler;
1422 	struct cb_handler *cb_handler;
1423 
1424 	/* scan event handler call back can't be NULL */
1425 	if (!pdev || !event_cb) {
1426 		scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
1427 		return QDF_STATUS_E_NULL_VALUE;
1428 	}
1429 
1430 	scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
1431 
1432 	scan = wlan_pdev_get_scan_obj(pdev);
1433 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
1434 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
1435 
1436 	qdf_spin_lock_bh(&scan->lock);
1437 	/* Ensure its not a duplicate registration request */
1438 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
1439 		idx++, cb_handler++) {
1440 		if ((cb_handler->func == event_cb) &&
1441 			(cb_handler->arg == arg)) {
1442 			qdf_spin_unlock_bh(&scan->lock);
1443 			scm_debug("func: %pK, arg: %pK already exists",
1444 				  event_cb, arg);
1445 			return QDF_STATUS_SUCCESS;
1446 		}
1447 	}
1448 
1449 	QDF_ASSERT(pdev_ev_handler->handler_cnt <
1450 			MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
1451 
1452 	if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
1453 		qdf_spin_unlock_bh(&scan->lock);
1454 		scm_warn("No more registrations possible");
1455 		return QDF_STATUS_E_NOMEM;
1456 	}
1457 
1458 	scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
1459 	qdf_spin_unlock_bh(&scan->lock);
1460 
1461 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
1462 
1463 	return QDF_STATUS_SUCCESS;
1464 }
1465 
1466 static QDF_STATUS
1467 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
1468 		      struct wlan_scan_obj *scan_obj)
1469 {
1470 	scan_obj->scan_disabled = 0;
1471 	scan_obj->drop_bcn_on_chan_mismatch =
1472 			 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH);
1473 	scan_obj->disable_timeout = false;
1474 	scan_obj->scan_def.active_dwell =
1475 			 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
1476 	/* the ini is disallow DFS channel scan if ini is 1, so negate that */
1477 	scan_obj->scan_def.allow_dfs_chan_in_first_scan =
1478 				!cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
1479 	scan_obj->scan_def.allow_dfs_chan_in_scan =
1480 				cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
1481 	scan_obj->scan_def.use_wake_lock_in_user_scan =
1482 				cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN);
1483 	scan_obj->scan_def.active_dwell_2g =
1484 			 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
1485 	scan_obj->scan_def.passive_dwell =
1486 			 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME);
1487 	scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
1488 	scan_obj->scan_def.sta_miracast_mcc_rest_time =
1489 					SCAN_STA_MIRACAST_MCC_REST_TIME;
1490 	scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
1491 	scan_obj->scan_def.conc_active_dwell =
1492 			cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC);
1493 	scan_obj->scan_def.conc_passive_dwell =
1494 			cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC);
1495 	scan_obj->scan_def.conc_max_rest_time =
1496 			cfg_get(psoc, CFG_MAX_REST_TIME_CONC);
1497 	scan_obj->scan_def.conc_min_rest_time =
1498 			cfg_get(psoc, CFG_MIN_REST_TIME_CONC);
1499 	scan_obj->scan_def.conc_idle_time =
1500 			cfg_get(psoc, CFG_IDLE_TIME_CONC);
1501 	scan_obj->scan_def.repeat_probe_time =
1502 			cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME);
1503 	scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
1504 	scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
1505 	scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
1506 	scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
1507 	scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES);
1508 	scan_obj->scan_def.scan_cache_aging_time = SCAN_CACHE_AGING_TIME;
1509 	scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
1510 	scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
1511 	scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
1512 	scan_obj->scan_def.adaptive_dwell_time_mode =
1513 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE);
1514 	scan_obj->scan_def.adaptive_dwell_time_mode_nc =
1515 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC);
1516 	scan_obj->scan_def.is_bssid_hint_priority =
1517 			cfg_get(psoc, CFG_IS_BSSID_HINT_PRIORITY);
1518 	/* scan contrl flags */
1519 	scan_obj->scan_def.scan_f_passive = true;
1520 	scan_obj->scan_def.scan_f_ofdm_rates = true;
1521 	scan_obj->scan_def.scan_f_2ghz = true;
1522 	scan_obj->scan_def.scan_f_5ghz = true;
1523 	scan_obj->scan_def.scan_f_chan_stat_evnt = SCAN_CHAN_STATS_EVENT_ENAB;
1524 	/* scan event flags */
1525 	scan_obj->scan_def.scan_ev_started = true;
1526 	scan_obj->scan_def.scan_ev_completed = true;
1527 	scan_obj->scan_def.scan_ev_bss_chan = true;
1528 	scan_obj->scan_def.scan_ev_foreign_chan = true;
1529 	scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
1530 	scan_obj->scan_def.scan_ev_dequeued = true;
1531 	scan_obj->scan_def.scan_ev_preempted = true;
1532 	scan_obj->scan_def.scan_ev_start_failed = true;
1533 	scan_obj->scan_def.scan_ev_restarted = true;
1534 	/* init scan id seed */
1535 	qdf_atomic_init(&scan_obj->scan_ids);
1536 
1537 	/* init extscan */
1538 	wlan_extscan_global_init(psoc, scan_obj);
1539 
1540 	return wlan_pno_global_init(psoc, &scan_obj->pno_cfg);
1541 }
1542 
1543 static void
1544 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc)
1545 {
1546 	struct wlan_scan_obj *scan_obj;
1547 
1548 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1549 	wlan_pno_global_deinit(&scan_obj->pno_cfg);
1550 	wlan_extscan_global_deinit();
1551 }
1552 
1553 static QDF_STATUS
1554 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
1555 	struct cb_handler *entry)
1556 {
1557 	struct cb_handler *last_entry;
1558 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
1559 
1560 	/* Replace event handler being deleted
1561 	 * with the last one in the list.
1562 	 */
1563 	last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
1564 	entry->func = last_entry->func;
1565 	entry->arg = last_entry->arg;
1566 
1567 	/* Clear our last entry */
1568 	last_entry->func = NULL;
1569 	last_entry->arg = NULL;
1570 	pdev_ev_handler->handler_cnt--;
1571 
1572 	return QDF_STATUS_SUCCESS;
1573 }
1574 
1575 void
1576 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
1577 	scan_event_handler event_cb, void *arg)
1578 {
1579 	uint8_t found = false;
1580 	uint32_t idx;
1581 	uint32_t handler_cnt;
1582 	struct wlan_scan_obj *scan;
1583 	struct cb_handler *cb_handler;
1584 	struct pdev_scan_ev_handler *pdev_ev_handler;
1585 
1586 	scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb,
1587 		  arg);
1588 	if (!pdev) {
1589 		scm_err("null pdev");
1590 		return;
1591 	}
1592 	scan = wlan_pdev_get_scan_obj(pdev);
1593 	if (!scan)
1594 		return;
1595 
1596 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
1597 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
1598 
1599 	qdf_spin_lock_bh(&scan->lock);
1600 	handler_cnt = pdev_ev_handler->handler_cnt;
1601 	if (!handler_cnt) {
1602 		qdf_spin_unlock_bh(&scan->lock);
1603 		scm_info("No event handlers registered");
1604 		return;
1605 	}
1606 
1607 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
1608 		idx++, cb_handler++) {
1609 		if ((cb_handler->func == event_cb) &&
1610 			(cb_handler->arg == arg)) {
1611 			/* Event handler found, remove it
1612 			 * from event handler list.
1613 			 */
1614 			found = true;
1615 			scm_remove_scan_event_handler(pdev_ev_handler,
1616 				cb_handler);
1617 			handler_cnt--;
1618 			break;
1619 		}
1620 	}
1621 	qdf_spin_unlock_bh(&scan->lock);
1622 
1623 	scm_debug("event handler %s, remaining handlers: %d",
1624 		  (found ? "removed" : "not found"), handler_cnt);
1625 }
1626 
1627 QDF_STATUS
1628 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
1629 	struct scan_start_request *req)
1630 {
1631 	struct scan_default_params *def;
1632 
1633 	if (!vdev | !req) {
1634 		scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req);
1635 		return QDF_STATUS_E_INVAL;
1636 	}
1637 	def = wlan_vdev_get_def_scan_params(vdev);
1638 	if (!def) {
1639 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
1640 		return QDF_STATUS_E_NULL_VALUE;
1641 	}
1642 
1643 	/* Zero out everything and explicitly set fields as required */
1644 	qdf_mem_zero(req, sizeof(*req));
1645 
1646 	req->vdev = vdev;
1647 	req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
1648 	req->scan_req.p2p_scan_type = SCAN_NON_P2P_DEFAULT;
1649 	req->scan_req.scan_priority = def->scan_priority;
1650 	req->scan_req.dwell_time_active = def->active_dwell;
1651 	req->scan_req.dwell_time_active_2g = def->active_dwell_2g;
1652 	req->scan_req.dwell_time_passive = def->passive_dwell;
1653 	req->scan_req.min_rest_time = def->min_rest_time;
1654 	req->scan_req.max_rest_time = def->max_rest_time;
1655 	req->scan_req.repeat_probe_time = def->repeat_probe_time;
1656 	req->scan_req.probe_spacing_time = def->probe_spacing_time;
1657 	req->scan_req.idle_time = def->idle_time;
1658 	req->scan_req.max_scan_time = def->max_scan_time;
1659 	req->scan_req.probe_delay = def->probe_delay;
1660 	req->scan_req.burst_duration = def->burst_duration;
1661 	req->scan_req.n_probes = def->num_probes;
1662 	req->scan_req.adaptive_dwell_time_mode =
1663 		def->adaptive_dwell_time_mode;
1664 	req->scan_req.scan_flags = def->scan_flags;
1665 	req->scan_req.scan_events = def->scan_events;
1666 	req->scan_req.scan_random.randomize = def->enable_mac_spoofing;
1667 
1668 	return QDF_STATUS_SUCCESS;
1669 }
1670 
1671 QDF_STATUS
1672 ucfg_scan_init_ssid_params(struct scan_start_request *req,
1673 		uint32_t num_ssid, struct wlan_ssid *ssid_list)
1674 {
1675 	uint32_t max_ssid = sizeof(req->scan_req.ssid) /
1676 				sizeof(req->scan_req.ssid[0]);
1677 
1678 	if (!req) {
1679 		scm_err("null request");
1680 		return QDF_STATUS_E_NULL_VALUE;
1681 	}
1682 	if (!num_ssid) {
1683 		/* empty channel list provided */
1684 		req->scan_req.num_ssids = 0;
1685 		qdf_mem_zero(&req->scan_req.ssid[0],
1686 			sizeof(req->scan_req.ssid));
1687 		return QDF_STATUS_SUCCESS;
1688 	}
1689 	if (!ssid_list) {
1690 		scm_err("null ssid_list while num_ssid: %d", num_ssid);
1691 		return QDF_STATUS_E_NULL_VALUE;
1692 	}
1693 	if (num_ssid > max_ssid) {
1694 		/* got a big list. alert and continue */
1695 		scm_warn("overflow: received %d, max supported : %d",
1696 			num_ssid, max_ssid);
1697 		return QDF_STATUS_E_E2BIG;
1698 	}
1699 
1700 	if (max_ssid > num_ssid)
1701 		max_ssid = num_ssid;
1702 
1703 	req->scan_req.num_ssids = max_ssid;
1704 	qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
1705 		(req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
1706 
1707 	return QDF_STATUS_SUCCESS;
1708 }
1709 
1710 QDF_STATUS
1711 ucfg_scan_init_bssid_params(struct scan_start_request *req,
1712 		uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
1713 {
1714 	uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
1715 				sizeof(req->scan_req.bssid_list[0]);
1716 
1717 	if (!req) {
1718 		scm_err("null request");
1719 		return QDF_STATUS_E_NULL_VALUE;
1720 	}
1721 	if (!num_bssid) {
1722 		/* empty channel list provided */
1723 		req->scan_req.num_bssid = 0;
1724 		qdf_mem_zero(&req->scan_req.bssid_list[0],
1725 			sizeof(req->scan_req.bssid_list));
1726 		return QDF_STATUS_SUCCESS;
1727 	}
1728 	if (!bssid_list) {
1729 		scm_err("null bssid_list while num_bssid: %d", num_bssid);
1730 		return QDF_STATUS_E_NULL_VALUE;
1731 	}
1732 	if (num_bssid > max_bssid) {
1733 		/* got a big list. alert and continue */
1734 		scm_warn("overflow: received %d, max supported : %d",
1735 			num_bssid, max_bssid);
1736 		return QDF_STATUS_E_E2BIG;
1737 	}
1738 
1739 	if (max_bssid > num_bssid)
1740 		max_bssid = num_bssid;
1741 
1742 	req->scan_req.num_bssid = max_bssid;
1743 	qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
1744 		req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
1745 
1746 	return QDF_STATUS_SUCCESS;
1747 }
1748 
1749 /**
1750  * is_chan_enabled_for_scan() - helper API to check if a frequency
1751  * is allowed to scan.
1752  * @reg_chan: regulatory_channel object
1753  * @low_2g: lower 2.4 GHz frequency thresold
1754  * @high_2g: upper 2.4 GHz frequency thresold
1755  * @low_5g: lower 5 GHz frequency thresold
1756  * @high_5g: upper 5 GHz frequency thresold
1757  *
1758  * Return: true if scan is allowed. false otherwise.
1759  */
1760 static bool
1761 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan,
1762 		uint32_t low_2g, uint32_t high_2g, uint32_t low_5g,
1763 		uint32_t high_5g)
1764 {
1765 	if (reg_chan->state == CHANNEL_STATE_DISABLE)
1766 		return false;
1767 	if (reg_chan->nol_chan)
1768 		return false;
1769 	/* 2 GHz channel */
1770 	if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1771 			WLAN_BAND_2_4_GHZ) &&
1772 			((reg_chan->center_freq < low_2g) ||
1773 			(reg_chan->center_freq > high_2g)))
1774 		return false;
1775 	else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1776 				WLAN_BAND_5_GHZ) &&
1777 		 ((reg_chan->center_freq < low_5g) ||
1778 		  (reg_chan->center_freq > high_5g)))
1779 		return false;
1780 
1781 	return true;
1782 }
1783 
1784 QDF_STATUS
1785 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1786 		uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1787 {
1788 	uint32_t idx;
1789 	QDF_STATUS status;
1790 	struct regulatory_channel *reg_chan_list = NULL;
1791 	uint32_t low_2g, high_2g, low_5g, high_5g;
1792 	struct wlan_objmgr_pdev *pdev = NULL;
1793 	uint32_t *scan_freqs = NULL;
1794 	uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1795 				sizeof(req->scan_req.chan_list.chan[0]);
1796 	if (!req) {
1797 		scm_err("null request");
1798 		return QDF_STATUS_E_NULL_VALUE;
1799 	}
1800 
1801 	if (req->vdev)
1802 		pdev = wlan_vdev_get_pdev(req->vdev);
1803 	/*
1804 	 * If 0 channels are provided for scan and
1805 	 * wide band scan is enabled, scan all 20 mhz
1806 	 * available channels. This is required as FW
1807 	 * scans all channel/phy mode combinations
1808 	 * provided in scan channel list if 0 chans are
1809 	 * provided in scan request causing scan to take
1810 	 * too much time to complete.
1811 	 */
1812 	if (pdev && !num_chans) {
1813 		reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1814 				sizeof(struct regulatory_channel));
1815 		if (!reg_chan_list) {
1816 			scm_err("Couldn't allocate reg_chan_list memory");
1817 			status = QDF_STATUS_E_NOMEM;
1818 			goto end;
1819 		}
1820 		scan_freqs =
1821 			qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1822 		if (!scan_freqs) {
1823 			scm_err("Couldn't allocate scan_freqs memory");
1824 			status = QDF_STATUS_E_NOMEM;
1825 			goto end;
1826 		}
1827 		status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list);
1828 		if (QDF_IS_STATUS_ERROR(status)) {
1829 			scm_err("Couldn't get current chan list");
1830 			goto end;
1831 		}
1832 		status = wlan_reg_get_freq_range(pdev, &low_2g,
1833 				&high_2g, &low_5g, &high_5g);
1834 		if (QDF_IS_STATUS_ERROR(status)) {
1835 			scm_err("Couldn't get frequency range");
1836 			goto end;
1837 		}
1838 
1839 		for (idx = 0, num_chans = 0;
1840 			(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1841 			if (is_chan_enabled_for_scan(&reg_chan_list[idx],
1842 					low_2g, high_2g, low_5g, high_5g))
1843 				scan_freqs[num_chans++] =
1844 				reg_chan_list[idx].center_freq;
1845 
1846 		chan_list = scan_freqs;
1847 	}
1848 
1849 	if (!num_chans) {
1850 		/* empty channel list provided */
1851 		qdf_mem_zero(&req->scan_req.chan_list,
1852 			sizeof(req->scan_req.chan_list));
1853 		req->scan_req.chan_list.num_chan = 0;
1854 		status = QDF_STATUS_SUCCESS;
1855 		goto end;
1856 	}
1857 	if (!chan_list) {
1858 		scm_err("null chan_list while num_chans: %d", num_chans);
1859 		status = QDF_STATUS_E_NULL_VALUE;
1860 		goto end;
1861 	}
1862 
1863 	if (num_chans > max_chans) {
1864 		/* got a big list. alert and fail */
1865 		scm_warn("overflow: received %d, max supported : %d",
1866 			num_chans, max_chans);
1867 		status = QDF_STATUS_E_E2BIG;
1868 		goto end;
1869 	}
1870 
1871 	req->scan_req.chan_list.num_chan = num_chans;
1872 	for (idx = 0; idx < num_chans; idx++) {
1873 		req->scan_req.chan_list.chan[idx].freq =
1874 			(chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1875 			chan_list[idx] :
1876 			wlan_reg_chan_to_freq(pdev, chan_list[idx]);
1877 		if (phymode)
1878 			req->scan_req.chan_list.chan[idx].phymode =
1879 				phymode[idx];
1880 		else if (req->scan_req.chan_list.chan[idx].freq <=
1881 			WLAN_CHAN_15_FREQ)
1882 			req->scan_req.chan_list.chan[idx].phymode =
1883 				SCAN_PHY_MODE_11G;
1884 		else
1885 			req->scan_req.chan_list.chan[idx].phymode =
1886 				SCAN_PHY_MODE_11A;
1887 
1888 		scm_debug("chan[%d]: freq:%d, phymode:%d", idx,
1889 			req->scan_req.chan_list.chan[idx].freq,
1890 			req->scan_req.chan_list.chan[idx].phymode);
1891 	}
1892 
1893 end:
1894 	if (scan_freqs)
1895 		qdf_mem_free(scan_freqs);
1896 
1897 	if (reg_chan_list)
1898 		qdf_mem_free(reg_chan_list);
1899 
1900 	return QDF_STATUS_SUCCESS;
1901 }
1902 
1903 static inline enum scm_scan_status
1904 get_scan_status_from_serialization_status(
1905 	enum wlan_serialization_cmd_status status)
1906 {
1907 	enum scm_scan_status scan_status;
1908 
1909 	switch (status) {
1910 	case WLAN_SER_CMD_IN_PENDING_LIST:
1911 		scan_status = SCAN_IS_PENDING;
1912 		break;
1913 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1914 		scan_status = SCAN_IS_ACTIVE;
1915 		break;
1916 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1917 		scan_status = SCAN_IS_ACTIVE_AND_PENDING;
1918 		break;
1919 	case WLAN_SER_CMD_NOT_FOUND:
1920 		scan_status = SCAN_NOT_IN_PROGRESS;
1921 		break;
1922 	default:
1923 		scm_warn("invalid serialization status %d", status);
1924 		QDF_ASSERT(0);
1925 		scan_status = SCAN_NOT_IN_PROGRESS;
1926 		break;
1927 	}
1928 
1929 	return scan_status;
1930 }
1931 
1932 enum scm_scan_status
1933 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1934 {
1935 	enum wlan_serialization_cmd_status status;
1936 
1937 	if (!vdev) {
1938 		scm_err("null vdev");
1939 		return SCAN_NOT_IN_PROGRESS;
1940 	}
1941 	status = wlan_serialization_vdev_scan_status(vdev);
1942 
1943 	return get_scan_status_from_serialization_status(status);
1944 }
1945 
1946 enum scm_scan_status
1947 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1948 {
1949 	enum wlan_serialization_cmd_status status;
1950 
1951 	if (!pdev) {
1952 		scm_err("null pdev");
1953 		return SCAN_NOT_IN_PROGRESS;
1954 	}
1955 	status = wlan_serialization_pdev_scan_status(pdev);
1956 
1957 	return get_scan_status_from_serialization_status(status);
1958 }
1959 
1960 static void
1961 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1962 	bool enable)
1963 {
1964 	QDF_STATUS status;
1965 	struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1966 
1967 	cb_info[0].frm_type = MGMT_PROBE_RESP;
1968 	cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1969 	cb_info[1].frm_type = MGMT_BEACON;
1970 	cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1971 
1972 	if (enable)
1973 		status = wlan_mgmt_txrx_register_rx_cb(psoc,
1974 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1975 	else
1976 		status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1977 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1978 	if (status != QDF_STATUS_SUCCESS)
1979 		scm_err("%s the Handle with MGMT TXRX layer has failed",
1980 			enable ? "Registering" : "Deregistering");
1981 }
1982 
1983 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1984 	struct scan_user_cfg *scan_cfg)
1985 {
1986 	struct wlan_scan_obj *scan_obj;
1987 	struct scan_default_params *scan_def;
1988 
1989 	if (!psoc) {
1990 		scm_err("null psoc");
1991 		return QDF_STATUS_E_FAILURE;
1992 	}
1993 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1994 	if (scan_obj == NULL) {
1995 		scm_err("Failed to get scan object");
1996 		return QDF_STATUS_E_FAILURE;
1997 	}
1998 
1999 	scan_def = &scan_obj->scan_def;
2000 	scan_def->scan_cache_aging_time = scan_cfg->scan_cache_aging_time;
2001 	scan_def->scan_f_chan_stat_evnt = scan_cfg->is_snr_monitoring_enabled;
2002 	scan_obj->ie_whitelist = scan_cfg->ie_whitelist;
2003 	scan_def->enable_mac_spoofing = scan_cfg->enable_mac_spoofing;
2004 	scan_def->sta_miracast_mcc_rest_time =
2005 				scan_cfg->sta_miracast_mcc_rest_time;
2006 
2007 	qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config,
2008 		sizeof(struct scoring_config));
2009 	scm_validate_scoring_config(&scan_def->score_config);
2010 
2011 	return QDF_STATUS_SUCCESS;
2012 }
2013 
2014 QDF_STATUS ucfg_scan_update_roam_params(struct wlan_objmgr_psoc *psoc,
2015 	struct roam_filter_params *roam_params)
2016 {
2017 	struct scan_default_params *scan_def;
2018 
2019 	if (!psoc) {
2020 		scm_err("null psoc");
2021 		return QDF_STATUS_E_FAILURE;
2022 	}
2023 	scan_def = wlan_scan_psoc_get_def_params(psoc);
2024 	if (!scan_def) {
2025 		scm_err("Failed to get scan object");
2026 		return QDF_STATUS_E_FAILURE;
2027 	}
2028 
2029 	qdf_mem_copy(&scan_def->roam_params, roam_params,
2030 		sizeof(struct roam_filter_params));
2031 
2032 	return QDF_STATUS_SUCCESS;
2033 }
2034 
2035 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
2036 static QDF_STATUS
2037 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
2038 {
2039 	struct scan_cancel_request *req;
2040 	QDF_STATUS status;
2041 	struct wlan_objmgr_vdev *vdev;
2042 
2043 	req = qdf_mem_malloc_atomic(sizeof(*req));
2044 	if (!req) {
2045 		scm_err("Failed to allocate memory");
2046 		return QDF_STATUS_E_NOMEM;
2047 	}
2048 
2049 	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID);
2050 	if (!vdev) {
2051 		scm_err("Failed to get vdev");
2052 		qdf_mem_free(req);
2053 		return QDF_STATUS_E_INVAL;
2054 	}
2055 	req->vdev = vdev;
2056 	req->cancel_req.scan_id = INVAL_SCAN_ID;
2057 	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
2058 	req->cancel_req.vdev_id = INVAL_VDEV_ID;
2059 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
2060 	status = ucfg_scan_cancel_sync(req);
2061 	if (QDF_IS_STATUS_ERROR(status))
2062 		scm_err("Cancel scan request failed");
2063 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
2064 
2065 	return status;
2066 }
2067 
2068 static QDF_STATUS
2069 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
2070 {
2071 	struct wlan_objmgr_pdev *pdev = NULL;
2072 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2073 	int i;
2074 
2075 	ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND);
2076 	/* Check all pdev */
2077 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
2078 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
2079 		if (!pdev)
2080 			continue;
2081 		if (ucfg_scan_get_pdev_status(pdev) !=
2082 		    SCAN_NOT_IN_PROGRESS)
2083 			status = ucfg_scan_cancel_pdev_scan(pdev);
2084 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
2085 		if (QDF_IS_STATUS_ERROR(status)) {
2086 			scm_err("failed to cancel scan for pdev_id %d", i);
2087 			return status;
2088 		}
2089 	}
2090 
2091 	return QDF_STATUS_SUCCESS;
2092 }
2093 
2094 static QDF_STATUS
2095 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
2096 {
2097 	ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND);
2098 	return QDF_STATUS_SUCCESS;
2099 }
2100 
2101 static inline void
2102 ucfg_scan_register_pmo_handler(void)
2103 {
2104 	pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
2105 		ucfg_scan_suspend_handler, NULL);
2106 	pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
2107 		ucfg_scan_resume_handler, NULL);
2108 }
2109 
2110 static inline void
2111 ucfg_scan_unregister_pmo_handler(void)
2112 {
2113 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
2114 		ucfg_scan_suspend_handler);
2115 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
2116 		ucfg_scan_resume_handler);
2117 }
2118 
2119 #else
2120 static inline void
2121 ucfg_scan_register_pmo_handler(void)
2122 {
2123 }
2124 
2125 static inline void
2126 ucfg_scan_unregister_pmo_handler(void)
2127 {
2128 }
2129 #endif
2130 
2131 QDF_STATUS
2132 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
2133 {
2134 	struct wlan_scan_obj *scan_obj;
2135 
2136 	scm_debug("psoc open: 0x%pK", psoc);
2137 	if (!psoc) {
2138 		scm_err("null psoc");
2139 		return QDF_STATUS_E_FAILURE;
2140 	}
2141 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2142 	if (scan_obj == NULL) {
2143 		scm_err("Failed to get scan object");
2144 		return QDF_STATUS_E_FAILURE;
2145 	}
2146 	/* Initialize the scan Globals */
2147 	wlan_scan_global_init(psoc, scan_obj);
2148 	qdf_spinlock_create(&scan_obj->lock);
2149 	ucfg_scan_register_pmo_handler();
2150 	scm_db_init(psoc);
2151 
2152 	return QDF_STATUS_SUCCESS;
2153 }
2154 
2155 QDF_STATUS
2156 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
2157 {
2158 	struct wlan_scan_obj *scan_obj;
2159 
2160 	scm_debug("psoc close: 0x%pK", psoc);
2161 	if (!psoc) {
2162 		scm_err("null psoc");
2163 		return QDF_STATUS_E_FAILURE;
2164 	}
2165 	scm_db_deinit(psoc);
2166 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2167 	if (scan_obj == NULL) {
2168 		scm_err("Failed to get scan object");
2169 		return QDF_STATUS_E_FAILURE;
2170 	}
2171 	ucfg_scan_unregister_pmo_handler();
2172 	qdf_spinlock_destroy(&scan_obj->lock);
2173 	wlan_scan_global_deinit(psoc);
2174 
2175 	return QDF_STATUS_SUCCESS;
2176 }
2177 
2178 static bool scm_serialization_scan_rules_cb(
2179 		union wlan_serialization_rules_info *comp_info,
2180 		uint8_t comp_id)
2181 {
2182 	switch (comp_id) {
2183 	case WLAN_UMAC_COMP_TDLS:
2184 		if (comp_info->scan_info.is_tdls_in_progress) {
2185 			scm_debug("Cancel scan. Tdls in progress");
2186 			return false;
2187 		}
2188 		break;
2189 	case WLAN_UMAC_COMP_DFS:
2190 		if (comp_info->scan_info.is_cac_in_progress) {
2191 			scm_debug("Cancel scan. CAC in progress");
2192 			return false;
2193 		}
2194 		break;
2195 	case WLAN_UMAC_COMP_MLME:
2196 		if (comp_info->scan_info.is_mlme_op_in_progress) {
2197 			scm_debug("Cancel scan. MLME operation in progress");
2198 			return false;
2199 		}
2200 		break;
2201 	default:
2202 		scm_debug("not handled comp_id %d", comp_id);
2203 		break;
2204 	}
2205 
2206 	return true;
2207 }
2208 
2209 QDF_STATUS
2210 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
2211 {
2212 	QDF_STATUS status;
2213 
2214 	scm_debug("psoc enable: 0x%pK", psoc);
2215 	if (!psoc) {
2216 		scm_err("null psoc");
2217 		return QDF_STATUS_E_FAILURE;
2218 	}
2219 	/* Subscribe for scan events from lmac layesr */
2220 	status = tgt_scan_register_ev_handler(psoc);
2221 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
2222 	if (!wlan_reg_is_11d_offloaded(psoc))
2223 		scm_11d_cc_db_init(psoc);
2224 	ucfg_scan_register_unregister_bcn_cb(psoc, true);
2225 	status = wlan_serialization_register_apply_rules_cb(psoc,
2226 				WLAN_SER_CMD_SCAN,
2227 				scm_serialization_scan_rules_cb);
2228 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
2229 	return status;
2230 }
2231 
2232 QDF_STATUS
2233 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
2234 {
2235 	QDF_STATUS status;
2236 
2237 	scm_debug("psoc disable: 0x%pK", psoc);
2238 	if (!psoc) {
2239 		scm_err("null psoc");
2240 		return QDF_STATUS_E_FAILURE;
2241 	}
2242 	/* Unsubscribe for scan events from lmac layesr */
2243 	status = tgt_scan_unregister_ev_handler(psoc);
2244 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
2245 	ucfg_scan_register_unregister_bcn_cb(psoc, false);
2246 	if (!wlan_reg_is_11d_offloaded(psoc))
2247 		scm_11d_cc_db_deinit(psoc);
2248 
2249 	return status;
2250 }
2251 
2252 uint32_t
2253 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
2254 {
2255 	struct scan_default_params *scan_params = NULL;
2256 
2257 	if (!psoc) {
2258 		scm_err("null psoc");
2259 		return 0;
2260 	}
2261 	scan_params = wlan_scan_psoc_get_def_params(psoc);
2262 	if (!scan_params) {
2263 		scm_err("Failed to get scan object");
2264 		return 0;
2265 	}
2266 
2267 	return scan_params->max_active_scans_allowed;
2268 }
2269 
2270 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
2271 				  struct probe_req_whitelist_attr *ie_whitelist)
2272 {
2273 	struct wlan_scan_obj *scan_obj = NULL;
2274 
2275 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2276 	if (!scan_obj)
2277 		return false;
2278 
2279 	qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist,
2280 		     sizeof(*ie_whitelist));
2281 
2282 	return true;
2283 }
2284 
2285 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
2286 			       struct wlan_objmgr_vdev *vdev)
2287 {
2288 	struct wlan_scan_obj *scan_obj = NULL;
2289 
2290 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2291 	if (!scan_obj)
2292 		return false;
2293 
2294 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
2295 	    wlan_vdev_is_connected(vdev))
2296 		return false;
2297 
2298 	if (!scan_obj->ie_whitelist.white_list)
2299 		return false;
2300 
2301 	return true;
2302 }
2303 
2304 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
2305 			       bool bt_a2dp_active)
2306 {
2307 	struct wlan_scan_obj *scan_obj;
2308 
2309 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2310 	if (!scan_obj) {
2311 		scm_err("Failed to get scan object");
2312 		return;
2313 	}
2314 	scan_obj->bt_a2dp_enabled = bt_a2dp_active;
2315 }
2316 
2317 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
2318 {
2319 	struct wlan_scan_obj *scan_obj;
2320 
2321 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2322 	if (!scan_obj) {
2323 		scm_err("Failed to get scan object");
2324 		return false;
2325 	}
2326 
2327 	return scan_obj->bt_a2dp_enabled;
2328 }
2329 
2330 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc)
2331 {
2332 	struct wlan_scan_obj *scan_obj;
2333 
2334 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2335 	if (!scan_obj)
2336 		return false;
2337 
2338 	return scan_obj->scan_def.use_wake_lock_in_user_scan;
2339 }
2340 
2341 QDF_STATUS
2342 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
2343 			       enum scan_config config, uint32_t val)
2344 {
2345 	struct wlan_scan_obj *scan_obj;
2346 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2347 
2348 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2349 	if (!scan_obj) {
2350 		scm_err("Failed to get scan object config:%d, val:%d",
2351 				config, val);
2352 		return QDF_STATUS_E_INVAL;
2353 	}
2354 	switch (config) {
2355 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
2356 		scan_obj->disable_timeout = !!val;
2357 		break;
2358 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
2359 		scan_obj->drop_bcn_on_chan_mismatch = !!val;
2360 		break;
2361 
2362 	default:
2363 		status = QDF_STATUS_E_INVAL;
2364 		break;
2365 	}
2366 
2367 	return status;
2368 }
2369 
2370 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
2371 		struct bss_info *bss_info, struct mlme_info *mlme)
2372 {
2373 	QDF_STATUS status;
2374 
2375 	status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme);
2376 
2377 	return status;
2378 }
2379 
2380 QDF_STATUS
2381 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
2382 			       enum scan_config config, uint32_t *val)
2383 {
2384 	struct wlan_scan_obj *scan_obj;
2385 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2386 
2387 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2388 	if (!scan_obj || !val) {
2389 		scm_err("scan object:%pK config:%d, val:0x%pK",
2390 				scan_obj, config, val);
2391 		return QDF_STATUS_E_INVAL;
2392 	}
2393 	switch (config) {
2394 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
2395 		*val = scan_obj->disable_timeout;
2396 		break;
2397 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
2398 		*val = scan_obj->drop_bcn_on_chan_mismatch;
2399 		break;
2400 
2401 	default:
2402 		status = QDF_STATUS_E_INVAL;
2403 		break;
2404 	}
2405 
2406 	return status;
2407 }
2408 
2409 #ifdef FEATURE_WLAN_SCAN_PNO
2410 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc)
2411 {
2412 	struct wlan_scan_obj *scan_obj;
2413 
2414 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2415 	if (!scan_obj) {
2416 		scm_err("NULL scan obj");
2417 		return false;
2418 	}
2419 
2420 	return scan_obj->pno_cfg.pno_offload_enabled;
2421 }
2422 
2423 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value)
2424 {
2425 	 struct wlan_scan_obj *scan_obj;
2426 
2427 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2428 	if (!scan_obj) {
2429 		scm_err("NULL scan obj");
2430 		return;
2431 	}
2432 
2433 	scan_obj->pno_cfg.pno_offload_enabled = value;
2434 }
2435 
2436 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
2437 {
2438 	struct wlan_scan_obj *scan_obj;
2439 
2440 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2441 	if (!scan_obj) {
2442 		scm_err("NULL scan obj");
2443 		return cfg_default(CFG_PNO_SCAN_SUPPORT);
2444 	}
2445 
2446 	return scan_obj->pno_cfg.scan_support_enabled;
2447 }
2448 
2449 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc)
2450 {
2451 	struct wlan_scan_obj *scan_obj;
2452 
2453 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2454 	if (!scan_obj) {
2455 		scm_err("NULL scan obj");
2456 		return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER);
2457 	}
2458 	return scan_obj->pno_cfg.scan_backoff_multiplier;
2459 }
2460 
2461 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc)
2462 {
2463 		struct wlan_scan_obj *scan_obj;
2464 
2465 		scan_obj = wlan_psoc_get_scan_obj(psoc);
2466 		if (!scan_obj) {
2467 			scm_err("NULL scan obj");
2468 			return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN);
2469 		}
2470 		return scan_obj->pno_cfg.dfs_chnl_scan_enabled;
2471 }
2472 
2473 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc)
2474 {
2475 		struct wlan_scan_obj *scan_obj;
2476 
2477 		scan_obj = wlan_psoc_get_scan_obj(psoc);
2478 		if (!scan_obj) {
2479 			scm_err("NULL scan obj");
2480 			return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
2481 		}
2482 		return scan_obj->pno_cfg.scan_timer_repeat_value;
2483 }
2484 
2485 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc)
2486 {
2487 		struct wlan_scan_obj *scan_obj;
2488 
2489 		scan_obj = wlan_psoc_get_scan_obj(psoc);
2490 		if (!scan_obj) {
2491 			scm_err("NULL scan obj");
2492 			return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER);
2493 		}
2494 		return scan_obj->pno_cfg.slow_scan_multiplier;
2495 }
2496 #endif
2497