xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c (revision a175314c51a4ce5cec2835cc8a8c7dc0c1810915)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * DOC: contains scan north bound interface definitions
21  */
22 
23 #include <scheduler_api.h>
24 #include <wlan_scan_ucfg_api.h>
25 #include <wlan_objmgr_global_obj.h>
26 #include <wlan_objmgr_cmn.h>
27 #include <wlan_serialization_api.h>
28 #include <wlan_scan_tgt_api.h>
29 #include <wlan_scan_utils_api.h>
30 #include <wlan_reg_ucfg_api.h>
31 #include <wlan_reg_services_api.h>
32 #include <wlan_utility.h>
33 #include "../../core/src/wlan_scan_main.h"
34 #include "../../core/src/wlan_scan_manager.h"
35 #include "../../core/src/wlan_scan_cache_db.h"
36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
37 #include <wlan_pmo_obj_mgmt_api.h>
38 #endif
39 #ifdef WLAN_POLICY_MGR_ENABLE
40 #include <wlan_dfs_utils_api.h>
41 #include <wlan_policy_mgr_api.h>
42 #endif
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_info("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_info("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_err("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 pno_def_config *pno_def)
233 {
234 	struct nlo_mawc_params *mawc_cfg;
235 
236 	qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl");
237 	mawc_cfg = &pno_def->mawc_params;
238 	pno_def->channel_prediction = SCAN_PNO_CHANNEL_PREDICTION;
239 	pno_def->top_k_num_of_channels = SCAN_TOP_K_NUM_OF_CHANNELS;
240 	pno_def->stationary_thresh = SCAN_STATIONARY_THRESHOLD;
241 	pno_def->channel_prediction_full_scan =
242 			SCAN_CHANNEL_PREDICTION_FULL_SCAN_MS;
243 	pno_def->adaptive_dwell_mode = SCAN_ADAPTIVE_PNOSCAN_DWELL_MODE;
244 	mawc_cfg->enable = SCAN_MAWC_NLO_ENABLED;
245 	mawc_cfg->exp_backoff_ratio = SCAN_MAWC_NLO_EXP_BACKOFF_RATIO;
246 	mawc_cfg->init_scan_interval = SCAN_MAWC_NLO_INIT_SCAN_INTERVAL;
247 	mawc_cfg->max_scan_interval = SCAN_MAWC_NLO_MAX_SCAN_INTERVAL;
248 
249 	return QDF_STATUS_SUCCESS;
250 }
251 
252 static QDF_STATUS
253 wlan_pno_global_deinit(struct pno_def_config *pno_def)
254 {
255 	qdf_wake_lock_destroy(&pno_def->pno_wake_lock);
256 
257 	return QDF_STATUS_SUCCESS;
258 }
259 
260 #ifdef WLAN_POLICY_MGR_ENABLE
261 /*
262  * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time
263  * depending on active concurrency modes
264  * @vdev: vdev object pointer
265  * @req: scan request
266  *
267  * Return: void
268  */
269 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
270 	struct pno_scan_req_params *req, struct scan_default_params *scan_def)
271 {
272 	bool sap_or_p2p_present;
273 	struct wlan_objmgr_psoc *psoc;
274 
275 	psoc = wlan_vdev_get_psoc(vdev);
276 
277 	if (!psoc)
278 		return;
279 
280 	sap_or_p2p_present = policy_mgr_mode_specific_connection_count(
281 				psoc, PM_SAP_MODE, NULL) ||
282 				policy_mgr_mode_specific_connection_count(
283 				psoc, PM_P2P_GO_MODE, NULL) ||
284 				policy_mgr_mode_specific_connection_count(
285 				psoc, PM_P2P_CLIENT_MODE, NULL);
286 
287 	if (sap_or_p2p_present) {
288 		req->active_dwell_time = scan_def->conc_active_dwell;
289 		req->passive_dwell_time = scan_def->conc_passive_dwell;
290 	}
291 
292 }
293 #else
294 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
295 	struct pno_scan_req_params *req, struct scan_default_params *scan_def){}
296 #endif
297 
298 QDF_STATUS
299 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
300 	struct pno_scan_req_params *req)
301 {
302 	struct scan_default_params *scan_def;
303 	struct wlan_scan_obj *scan;
304 	struct pno_def_config *pno_def;
305 
306 	if (!vdev || !req) {
307 		scm_err("vdev: 0x%pK, req: 0x%pK",
308 			vdev, req);
309 		return QDF_STATUS_E_INVAL;
310 	}
311 
312 	scan = wlan_vdev_get_scan_obj(vdev);
313 	if (!scan) {
314 		scm_err("scan is NULL");
315 		return QDF_STATUS_E_INVAL;
316 	}
317 	scan_def = wlan_vdev_get_def_scan_params(vdev);
318 	if (!scan_def) {
319 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
320 		return QDF_STATUS_E_NULL_VALUE;
321 	}
322 
323 	pno_def = &scan->pno_cfg;
324 	req->active_dwell_time = scan_def->active_dwell;
325 	req->passive_dwell_time = scan_def->passive_dwell;
326 
327 	/*
328 	 *  Update active and passive dwell time depending
329 	 *  upon the present active concurrency mode
330 	 */
331 	ucfg_scan_update_pno_dwell_time(vdev, req, scan_def);
332 	req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
333 	req->pno_channel_prediction = pno_def->channel_prediction;
334 	req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
335 	req->stationary_thresh = pno_def->stationary_thresh;
336 	req->channel_prediction_full_scan =
337 			pno_def->channel_prediction_full_scan;
338 	req->mawc_params.vdev_id = wlan_vdev_get_id(vdev);
339 	qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params,
340 			sizeof(req->mawc_params));
341 
342 	return QDF_STATUS_SUCCESS;
343 }
344 
345 static QDF_STATUS ucfg_scan_update_pno_config(struct pno_def_config *pno,
346 	struct pno_user_cfg *pno_cfg)
347 {
348 	pno->channel_prediction = pno_cfg->channel_prediction;
349 	pno->top_k_num_of_channels = pno_cfg->top_k_num_of_channels;
350 	pno->stationary_thresh = pno_cfg->stationary_thresh;
351 	pno->adaptive_dwell_mode = pno_cfg->adaptive_dwell_mode;
352 	pno->channel_prediction_full_scan =
353 		pno_cfg->channel_prediction_full_scan;
354 	qdf_mem_copy(&pno->mawc_params, &pno_cfg->mawc_params,
355 			sizeof(pno->mawc_params));
356 
357 	return QDF_STATUS_SUCCESS;
358 }
359 
360 QDF_STATUS
361 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
362 	scan_event_handler event_cb, void *arg)
363 {
364 	struct wlan_scan_obj *scan;
365 
366 	if (!psoc) {
367 		scm_err("null psoc");
368 		return QDF_STATUS_E_INVAL;
369 	}
370 	scan = wlan_psoc_get_scan_obj(psoc);
371 	qdf_spin_lock_bh(&scan->lock);
372 	scan->pno_cfg.pno_cb.func = event_cb;
373 	scan->pno_cfg.pno_cb.arg = arg;
374 	qdf_spin_unlock_bh(&scan->lock);
375 	scm_info("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
376 
377 	return QDF_STATUS_SUCCESS;
378 }
379 
380 #else
381 
382 static inline QDF_STATUS
383 wlan_pno_global_init(struct pno_def_config *pno_def)
384 {
385 	return QDF_STATUS_SUCCESS;
386 }
387 static inline QDF_STATUS
388 wlan_pno_global_deinit(struct pno_def_config *pno_def)
389 {
390 	return QDF_STATUS_SUCCESS;
391 }
392 
393 static inline QDF_STATUS
394 ucfg_scan_update_pno_config(struct pno_def_config *pno,
395 	struct pno_user_cfg *pno_cfg)
396 {
397 	return QDF_STATUS_SUCCESS;
398 }
399 
400 #endif
401 
402 #ifdef WLAN_POLICY_MGR_ENABLE
403 /**
404  * ucfg_scan_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags
405  * @req: pointer to scan request
406  *
407  * This function sets scan_ctrl_flags_ext value depending on the type of
408  * scan and the channel lists.
409  *
410  * Non-DBS scan is requested if any of the below case is met:
411  *     1. HW is DBS incapable
412  *     2. Directed scan
413  *     3. Channel list has only few channels
414  *     4. Channel list has single band channels
415  *     5. A high accuracy scan request is sent by kernel.
416  *
417  * DBS scan is enabled for these conditions:
418  *     1. A low power or low span scan request is sent by kernel.
419  * For remaining cases DBS is enabled by default.
420  * Return: void
421  */
422 static void
423 ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
424 {
425 	uint32_t num_chan;
426 	struct wlan_objmgr_psoc *psoc;
427 	uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
428 	uint32_t conn_cnt;
429 
430 	psoc = wlan_vdev_get_psoc(req->vdev);
431 
432 	if ((DISABLE_DBS_CXN_AND_SCAN ==
433 	     wlan_objmgr_psoc_get_dual_mac_disable(psoc)) ||
434 	    (ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN ==
435 	     wlan_objmgr_psoc_get_dual_mac_disable(psoc)))
436 		goto end;
437 
438 	if (req->scan_req.scan_policy_high_accuracy)
439 		goto end;
440 
441 	if ((req->scan_req.scan_policy_low_power) ||
442 	    (req->scan_req.scan_policy_low_span)) {
443 		scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY;
444 		goto end;
445 	}
446 
447 	conn_cnt = policy_mgr_get_connection_count(psoc);
448 	if (conn_cnt > 0) {
449 		scm_debug("%d active connections, go for DBS scan",
450 				conn_cnt);
451 		scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
452 		goto end;
453 	}
454 
455 	if (req->scan_req.num_ssids) {
456 		scm_debug("directed SSID");
457 		goto end;
458 	}
459 
460 	if (req->scan_req.num_bssid) {
461 		scm_debug("directed BSSID");
462 		goto end;
463 	}
464 
465 	num_chan = req->scan_req.chan_list.num_chan;
466 
467 	/* num_chan=0 means all channels */
468 	if (!num_chan)
469 		scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
470 
471 	if (num_chan < SCAN_MIN_CHAN_DBS_SCAN_THRESHOLD)
472 		goto end;
473 
474 	while (num_chan > 1) {
475 		if (!WLAN_REG_IS_SAME_BAND_CHANNELS(
476 			req->scan_req.chan_list.chan[0].freq,
477 			req->scan_req.chan_list.chan[num_chan-1].freq)) {
478 			scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
479 			break;
480 		}
481 		num_chan--;
482 	}
483 
484 end:
485 	req->scan_req.scan_ctrl_flags_ext |=
486 		((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT)
487 		 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK);
488 	scm_debug("scan_ctrl_flags_ext: 0x%x",
489 			req->scan_req.scan_ctrl_flags_ext);
490 }
491 
492 /**
493  * ucfg_update_passive_dwell_time() - update dwell passive time
494  * @vdev: vdev object
495  * @req: scan request
496  *
497  * Return: None
498  */
499 static void
500 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
501 					    struct scan_start_request *req)
502 {
503 	struct wlan_objmgr_psoc *psoc;
504 
505 	psoc = wlan_vdev_get_psoc(vdev);
506 	if (!psoc)
507 		return;
508 
509 	if (policy_mgr_is_sta_connected_2g(psoc) &&
510 	    !policy_mgr_is_hw_dbs_capable(psoc) &&
511 	    ucfg_scan_get_bt_activity(psoc))
512 		req->scan_req.dwell_time_passive =
513 				PASSIVE_DWELL_TIME_BT_A2DP_ENABLED;
514 }
515 
516 static const struct probe_time_dwell_time
517 	scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = {
518 	{28, 11},               /* 0 SSID */
519 	{28, 20},               /* 1 SSID */
520 	{28, 20},               /* 2 SSID */
521 	{28, 20},               /* 3 SSID */
522 	{28, 20},               /* 4 SSID */
523 	{28, 20},               /* 5 SSID */
524 	{28, 20},               /* 6 SSID */
525 	{28, 11},               /* 7 SSID */
526 	{28, 11},               /* 8 SSID */
527 	{28, 11},               /* 9 SSID */
528 	{28, 8}                 /* 10 SSID */
529 };
530 
531 /**
532  * ucfg_scan_get_burst_duration() - get burst duration depending on max chan
533  * and miracast.
534  * @max_ch_time: max channel time
535  * @miracast_enabled: if miracast is enabled
536  *
537  * Return: burst_duration
538  */
539 static inline
540 int ucfg_scan_get_burst_duration(int max_ch_time,
541 					     bool miracast_enabled)
542 {
543 	int burst_duration = 0;
544 
545 	if (miracast_enabled) {
546 		/*
547 		 * When miracast is running, burst
548 		 * duration needs to be minimum to avoid
549 		 * any stutter or glitch in miracast
550 		 * during station scan
551 		 */
552 		if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION)
553 			burst_duration = max_ch_time;
554 		else
555 			burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION;
556 	} else {
557 		/*
558 		 * If miracast is not running, accommodate max
559 		 * stations to make the scans faster
560 		 */
561 		burst_duration = SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS *
562 						max_ch_time;
563 		if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) {
564 			uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION /
565 								 max_ch_time;
566 
567 			if (channels)
568 				burst_duration = channels * max_ch_time;
569 			else
570 				burst_duration =
571 					 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION;
572 		}
573 	}
574 	return burst_duration;
575 }
576 
577 /**
578  * ucfg_scan_req_update_params() - update scan req params depending on
579  * concurrent mode present.
580  * @vdev: vdev object pointer
581  * @req: scan request
582  * @scan_obj: scan object
583  *
584  * Return: void
585  */
586 static void ucfg_scan_req_update_concurrency_params(
587 	struct wlan_objmgr_vdev *vdev, struct scan_start_request *req,
588 	struct wlan_scan_obj *scan_obj)
589 {
590 	bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present;
591 	struct wlan_objmgr_psoc *psoc;
592 
593 	psoc = wlan_vdev_get_psoc(vdev);
594 
595 	if (!psoc)
596 		return;
597 
598 	ap_present = policy_mgr_mode_specific_connection_count(
599 				psoc, PM_SAP_MODE, NULL);
600 	go_present = policy_mgr_mode_specific_connection_count(
601 				psoc, PM_P2P_GO_MODE, NULL);
602 	p2p_cli_present = policy_mgr_mode_specific_connection_count(
603 				psoc, PM_P2P_CLIENT_MODE, NULL);
604 	sta_active = policy_mgr_mode_specific_connection_count(
605 				psoc, PM_STA_MODE, NULL);
606 	ndi_present = policy_mgr_mode_specific_connection_count(
607 				psoc, PM_NDI_MODE, NULL);
608 
609 	if (policy_mgr_get_connection_count(psoc)) {
610 		if (req->scan_req.scan_f_passive)
611 			req->scan_req.dwell_time_passive =
612 				scan_obj->scan_def.conc_passive_dwell;
613 		else
614 			req->scan_req.dwell_time_active =
615 				scan_obj->scan_def.conc_active_dwell;
616 		req->scan_req.max_rest_time =
617 				scan_obj->scan_def.conc_max_rest_time;
618 		req->scan_req.min_rest_time =
619 			scan_obj->scan_def.conc_min_rest_time;
620 		req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time;
621 	}
622 
623 	/*
624 	 * If AP is active set min rest time same as max rest time, so that
625 	 * firmware spends more time on home channel which will increase the
626 	 * probability of sending beacon at TBTT
627 	 */
628 	if (ap_present || go_present)
629 		req->scan_req.min_rest_time = req->scan_req.max_rest_time;
630 
631 	if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) {
632 		/*
633 		 * Decide burst_duration and dwell_time_active based on
634 		 * what type of devices are active.
635 		 */
636 		do {
637 			if (ap_present && go_present && sta_active) {
638 				if (req->scan_req.dwell_time_active <=
639 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION)
640 					req->scan_req.burst_duration =
641 						req->scan_req.dwell_time_active;
642 				else
643 					req->scan_req.burst_duration =
644 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION;
645 
646 				break;
647 			}
648 
649 			if (scan_obj->miracast_enabled &&
650 			    policy_mgr_is_mcc_in_24G(psoc))
651 				req->scan_req.max_rest_time =
652 				  scan_obj->scan_def.sta_miracast_mcc_rest_time;
653 
654 			if (go_present) {
655 				/*
656 				 * Background scan while GO is sending beacons.
657 				 * Every off-channel transition has overhead of
658 				 * 2 beacon intervals for NOA. Maximize number
659 				 * of channels in every transition by using
660 				 * burst scan.
661 				 */
662 				req->scan_req.burst_duration =
663 					ucfg_scan_get_burst_duration(
664 						req->scan_req.dwell_time_active,
665 						scan_obj->miracast_enabled);
666 				break;
667 			}
668 			if ((sta_active || p2p_cli_present) &&
669 			    !req->scan_req.burst_duration) {
670 				/* Typical background scan.
671 				 * Disable burst scan for now.
672 				 */
673 				req->scan_req.burst_duration = 0;
674 				break;
675 			}
676 
677 			if (ndi_present) {
678 				req->scan_req.burst_duration =
679 					ucfg_scan_get_burst_duration(
680 						req->scan_req.dwell_time_active,
681 						scan_obj->miracast_enabled);
682 				break;
683 			}
684 		} while (0);
685 
686 		if (ap_present) {
687 			uint8_t ssid_num;
688 			ssid_num = req->scan_req.num_ssids *
689 					req->scan_req.num_bssid;
690 			req->scan_req.repeat_probe_time =
691 				scan_probe_time_dwell_time_map[
692 					QDF_MIN(ssid_num,
693 					SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE
694 					- 1)].probe_time;
695 			req->scan_req.n_probes =
696 				(req->scan_req.repeat_probe_time > 0) ?
697 				req->scan_req.dwell_time_active /
698 				req->scan_req.repeat_probe_time : 0;
699 		}
700 	}
701 
702 	if (ap_present) {
703 		uint8_t ap_chan;
704 		struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
705 
706 		ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL);
707 		/*
708 		 * P2P/STA scan while SoftAP is sending beacons.
709 		 * Max duration of CTS2self is 32 ms, which limits the
710 		 * dwell time. If DBS is supported and if SAP is on 2G channel
711 		 * then keep passive dwell time default.
712 		 */
713 		req->scan_req.dwell_time_active =
714 				QDF_MIN(req->scan_req.dwell_time_active,
715 					(SCAN_CTS_DURATION_MS_MAX -
716 					SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME));
717 		if (!policy_mgr_is_hw_dbs_capable(psoc) ||
718 		    (policy_mgr_is_hw_dbs_capable(psoc) &&
719 		     WLAN_CHAN_IS_5GHZ(ap_chan))) {
720 			req->scan_req.dwell_time_passive =
721 				req->scan_req.dwell_time_active;
722 		}
723 		req->scan_req.burst_duration = 0;
724 		if (utils_is_dfs_ch(pdev, ap_chan))
725 			req->scan_req.burst_duration =
726 				SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS *
727 				req->scan_req.dwell_time_active;
728 	}
729 }
730 
731 #else
732 static inline void ucfg_scan_req_update_concurrency_params(
733 	struct wlan_objmgr_vdev *vdev, struct scan_start_request *req,
734 	struct wlan_scan_obj *scan_obj)
735 {
736 }
737 static inline void
738 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
739 					    struct scan_start_request *req) {}
740 static inline void
741 ucfg_scan_update_dbs_scan_ctrl_ext_flag(
742 	struct scan_start_request *req) {}
743 #endif
744 
745 QDF_STATUS
746 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
747 		struct chan_list *chan_list)
748 {
749 	uint8_t pdev_id;
750 	struct wlan_scan_obj *scan_obj;
751 
752 	if (!pdev || !chan_list) {
753 		scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list);
754 		return QDF_STATUS_E_NULL_VALUE;
755 	}
756 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
757 	scan_obj = wlan_pdev_get_scan_obj(pdev);
758 
759 	qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list,
760 			chan_list, sizeof(*chan_list));
761 
762 	return QDF_STATUS_SUCCESS;
763 }
764 
765 /**
766  * ucfg_scan_req_update_params() - update scan req params depending on modes
767  * and scan type.
768  * @vdev: vdev object pointer
769  * @req: scan request
770  * @scan_obj: scan object
771  *
772  * Return: void
773  */
774 static void
775 ucfg_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
776 	struct scan_start_request *req, struct wlan_scan_obj *scan_obj)
777 {
778 	struct chan_list *custom_chan_list;
779 	struct wlan_objmgr_pdev *pdev;
780 	uint8_t pdev_id;
781 
782 	/* Ensure correct number of probes are sent on active channel */
783 	if (!req->scan_req.repeat_probe_time)
784 		req->scan_req.repeat_probe_time =
785 			req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT;
786 
787 	if (req->scan_req.scan_f_passive)
788 		req->scan_req.scan_ctrl_flags_ext |=
789 			SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME;
790 
791 	if (!req->scan_req.n_probes)
792 		req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ?
793 					  req->scan_req.dwell_time_active /
794 					  req->scan_req.repeat_probe_time : 0;
795 
796 	if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) {
797 		req->scan_req.scan_f_cck_rates = true;
798 		if (!req->scan_req.num_ssids)
799 			req->scan_req.scan_f_bcast_probe = true;
800 		req->scan_req.scan_f_add_ds_ie_in_probe = true;
801 		req->scan_req.scan_f_filter_prb_req = true;
802 		req->scan_req.scan_f_add_tpc_ie_in_probe = true;
803 	} else {
804 		req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC;
805 		if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) {
806 			req->scan_req.repeat_probe_time = 0;
807 		} else {
808 			req->scan_req.scan_f_filter_prb_req = true;
809 			if (!req->scan_req.num_ssids)
810 				req->scan_req.scan_f_bcast_probe = true;
811 
812 			req->scan_req.dwell_time_active +=
813 					P2P_SEARCH_DWELL_TIME_INC;
814 			/*
815 			 * 3 channels with default max dwell time 40 ms.
816 			 * Cap limit will be set by
817 			 * P2P_SCAN_MAX_BURST_DURATION. Burst duration
818 			 * should be such that no channel is scanned less
819 			 * than the dwell time in normal scenarios.
820 			 */
821 			if (req->scan_req.chan_list.num_chan ==
822 			    WLAN_P2P_SOCIAL_CHANNELS &&
823 			    !scan_obj->miracast_enabled)
824 				req->scan_req.repeat_probe_time =
825 					req->scan_req.dwell_time_active / 5;
826 			else
827 				req->scan_req.repeat_probe_time =
828 					req->scan_req.dwell_time_active / 3;
829 
830 			req->scan_req.burst_duration =
831 					BURST_SCAN_MAX_NUM_OFFCHANNELS *
832 					req->scan_req.dwell_time_active;
833 			if (req->scan_req.burst_duration >
834 			    P2P_SCAN_MAX_BURST_DURATION) {
835 				uint8_t channels =
836 					P2P_SCAN_MAX_BURST_DURATION /
837 					req->scan_req.dwell_time_active;
838 				if (channels)
839 					req->scan_req.burst_duration =
840 						channels *
841 						req->scan_req.dwell_time_active;
842 				else
843 					req->scan_req.burst_duration =
844 						P2P_SCAN_MAX_BURST_DURATION;
845 			}
846 			req->scan_req.scan_ev_bss_chan = false;
847 		}
848 	}
849 
850 	if (!req->scan_req.scan_f_passive)
851 		ucfg_update_passive_dwell_time(vdev, req);
852 	ucfg_scan_update_dbs_scan_ctrl_ext_flag(req);
853 
854 	/*
855 	 * No need to update conncurrency parmas if req is passive scan on
856 	 * single channel ie ROC, Preauth etc
857 	 */
858 	if (!(req->scan_req.scan_f_passive &&
859 	      req->scan_req.chan_list.num_chan == 1))
860 		ucfg_scan_req_update_concurrency_params(vdev, req, scan_obj);
861 
862 	/* Set wide band flag if enabled. This will cause
863 	 * phymode TLV being sent to FW.
864 	 */
865 	pdev = wlan_vdev_get_pdev(vdev);
866 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
867 	if (ucfg_scan_get_wide_band_scan(pdev))
868 		req->scan_req.scan_f_wide_band = true;
869 	else
870 		req->scan_req.scan_f_wide_band = false;
871 
872 	/* Overwrite scan channles with custom scan channel
873 	 * list if configured.
874 	 */
875 	custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list;
876 	if (custom_chan_list->num_chan)
877 		qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list,
878 				sizeof(struct chan_list));
879 	else if (req->scan_req.scan_f_wide_band &&
880 			!req->scan_req.chan_list.num_chan)
881 		ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
882 
883 	scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d "
884 			"n_probes %d flags_ext %x, wide_bw_scan: %d",
885 			req->scan_req.dwell_time_active,
886 			req->scan_req.dwell_time_passive,
887 			req->scan_req.repeat_probe_time, req->scan_req.n_probes,
888 			req->scan_req.scan_ctrl_flags_ext,
889 			req->scan_req.scan_f_wide_band);
890 }
891 
892 QDF_STATUS
893 ucfg_scan_start(struct scan_start_request *req)
894 {
895 	struct scheduler_msg msg = {0};
896 	QDF_STATUS status;
897 	struct wlan_scan_obj *scan_obj;
898 	struct wlan_objmgr_pdev *pdev;
899 	uint8_t idx;
900 
901 	if (!req || !req->vdev) {
902 		scm_err("req or vdev within req is NULL");
903 		if (req)
904 			scm_scan_free_scan_request_mem(req);
905 		return QDF_STATUS_E_NULL_VALUE;
906 	}
907 
908 	pdev = wlan_vdev_get_pdev(req->vdev);
909 	if (!pdev) {
910 		scm_err("Failed to get pdev object");
911 		scm_scan_free_scan_request_mem(req);
912 		return QDF_STATUS_E_NULL_VALUE;
913 	}
914 
915 	scan_obj = wlan_pdev_get_scan_obj(pdev);
916 	if (!scan_obj) {
917 		scm_err("Failed to get scan object");
918 		scm_scan_free_scan_request_mem(req);
919 		return QDF_STATUS_E_NULL_VALUE;
920 	}
921 
922 	if (!scan_obj->enable_scan) {
923 		scm_err("scan disabled, rejecting the scan req");
924 		scm_scan_free_scan_request_mem(req);
925 		return QDF_STATUS_E_AGAIN;
926 	}
927 
928 	scm_debug("reqid: %d, scanid: %d, vdevid: %d",
929 		req->scan_req.scan_req_id, req->scan_req.scan_id,
930 		req->scan_req.vdev_id);
931 
932 	ucfg_scan_req_update_params(req->vdev, req, scan_obj);
933 
934 	/* Try to get vdev reference. Return if reference could
935 	 * not be taken. Reference will be released once scan
936 	 * request handling completes along with free of @req.
937 	 */
938 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
939 	if (QDF_IS_STATUS_ERROR(status)) {
940 		scm_info("unable to get reference");
941 		scm_scan_free_scan_request_mem(req);
942 		return status;
943 	}
944 
945 	scm_info("request to scan %d channels",
946 		req->scan_req.chan_list.num_chan);
947 	for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++)
948 		scm_info("chan[%d]: freq:%d, phymode:%d", idx,
949 				req->scan_req.chan_list.chan[idx].freq,
950 				req->scan_req.chan_list.chan[idx].phymode);
951 
952 	msg.bodyptr = req;
953 	msg.callback = scm_scan_start_req;
954 	msg.flush_callback = scm_scan_start_flush_callback;
955 
956 	status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
957 	if (QDF_IS_STATUS_ERROR(status)) {
958 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
959 		scm_err("failed to post to QDF_MODULE_ID_OS_IF");
960 		scm_scan_free_scan_request_mem(req);
961 	}
962 
963 	return status;
964 }
965 
966 QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable)
967 {
968 	struct wlan_scan_obj *scan_obj;
969 
970 	scan_obj = wlan_psoc_get_scan_obj(psoc);
971 	if (!scan_obj) {
972 		scm_err("Failed to get scan object");
973 		return QDF_STATUS_E_NULL_VALUE;
974 	}
975 	scan_obj->enable_scan = enable;
976 	scm_debug("set enable_scan to %d", scan_obj->enable_scan);
977 
978 	return QDF_STATUS_SUCCESS;
979 }
980 
981 bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc)
982 {
983 	struct wlan_scan_obj *scan_obj;
984 
985 	scan_obj = wlan_psoc_get_scan_obj(psoc);
986 	if (!scan_obj) {
987 		scm_err("Failed to get scan object");
988 		return false;
989 	}
990 	return scan_obj->enable_scan;
991 }
992 
993 QDF_STATUS ucfg_scan_set_miracast(
994 	struct wlan_objmgr_psoc *psoc, bool enable)
995 {
996 	struct wlan_scan_obj *scan_obj;
997 
998 	scan_obj = wlan_psoc_get_scan_obj(psoc);
999 	if (!scan_obj) {
1000 		scm_err("Failed to get scan object");
1001 		return QDF_STATUS_E_NULL_VALUE;
1002 	}
1003 	scan_obj->miracast_enabled = enable;
1004 	scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled);
1005 
1006 	return QDF_STATUS_SUCCESS;
1007 }
1008 
1009 QDF_STATUS
1010 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable)
1011 {
1012 	uint8_t pdev_id;
1013 	struct wlan_scan_obj *scan_obj;
1014 
1015 	if (!pdev) {
1016 		scm_warn("null vdev");
1017 		return QDF_STATUS_E_NULL_VALUE;
1018 	}
1019 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1020 	scan_obj = wlan_pdev_get_scan_obj(pdev);
1021 
1022 	scm_debug("set wide_band_scan to %d", enable);
1023 	scan_obj->pdev_info[pdev_id].wide_band_scan = enable;
1024 
1025 	return QDF_STATUS_SUCCESS;
1026 }
1027 
1028 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev)
1029 {
1030 	uint8_t pdev_id;
1031 	struct wlan_scan_obj *scan_obj;
1032 
1033 	if (!pdev) {
1034 		scm_warn("null vdev");
1035 		return QDF_STATUS_E_NULL_VALUE;
1036 	}
1037 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1038 	scan_obj = wlan_pdev_get_scan_obj(pdev);
1039 
1040 	return scan_obj->pdev_info[pdev_id].wide_band_scan;
1041 }
1042 
1043 QDF_STATUS
1044 ucfg_scan_cancel(struct scan_cancel_request *req)
1045 {
1046 	struct scheduler_msg msg = {0};
1047 	QDF_STATUS status;
1048 
1049 	if (!req || !req->vdev) {
1050 		scm_err("req or vdev within req is NULL");
1051 		if (req)
1052 			qdf_mem_free(req);
1053 		return QDF_STATUS_E_NULL_VALUE;
1054 	}
1055 	scm_info("reqid: %d, scanid: %d, vdevid: %d, type: %d",
1056 		req->cancel_req.requester, req->cancel_req.scan_id,
1057 		req->cancel_req.vdev_id, req->cancel_req.req_type);
1058 
1059 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
1060 	if (QDF_IS_STATUS_ERROR(status)) {
1061 		scm_info("Failed to get vdev ref; status:%d", status);
1062 		goto req_free;
1063 	}
1064 
1065 	msg.bodyptr = req;
1066 	msg.callback = scm_scan_cancel_req;
1067 	msg.flush_callback = scm_scan_cancel_flush_callback;
1068 
1069 	status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
1070 	if (QDF_IS_STATUS_ERROR(status)) {
1071 		scm_err("failed to post to QDF_MODULE_ID_OS_IF");
1072 		goto vdev_put;
1073 	}
1074 
1075 	return QDF_STATUS_SUCCESS;
1076 
1077 vdev_put:
1078 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1079 
1080 req_free:
1081 	qdf_mem_free(req);
1082 
1083 	return status;
1084 }
1085 
1086 QDF_STATUS
1087 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
1088 {
1089 	QDF_STATUS status;
1090 	bool cancel_vdev = false, cancel_pdev = false;
1091 	struct wlan_objmgr_vdev *vdev;
1092 	struct wlan_objmgr_pdev *pdev;
1093 	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
1094 	qdf_event_t cancel_scan_event;
1095 
1096 	if (!req || !req->vdev) {
1097 		scm_err("req or vdev within req is NULL");
1098 		if (req)
1099 			qdf_mem_free(req);
1100 		return QDF_STATUS_E_NULL_VALUE;
1101 	}
1102 
1103 	if (req->cancel_req.req_type ==
1104 	   WLAN_SCAN_CANCEL_PDEV_ALL)
1105 		cancel_pdev = true;
1106 	else if (req->cancel_req.req_type ==
1107 	   WLAN_SCAN_CANCEL_VDEV_ALL)
1108 		cancel_vdev = true;
1109 
1110 	vdev = req->vdev;
1111 	status = ucfg_scan_cancel(req);
1112 	if (QDF_IS_STATUS_ERROR(status)) {
1113 		scm_err("failed to post to QDF_MODULE_ID_OS_IF");
1114 		return status;
1115 	}
1116 
1117 	/*
1118 	 * If cancel req is to cancel all scan of pdev or vdev
1119 	 * wait until all scan of pdev or vdev get cancelled
1120 	 */
1121 	qdf_event_create(&cancel_scan_event);
1122 	qdf_event_reset(&cancel_scan_event);
1123 
1124 	if (cancel_pdev) {
1125 		pdev = wlan_vdev_get_pdev(vdev);
1126 		while ((ucfg_scan_get_pdev_status(pdev) !=
1127 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
1128 			scm_debug("wait for all pdev scan to get complete");
1129 				qdf_wait_single_event(&cancel_scan_event,
1130 					qdf_system_msecs_to_ticks(
1131 					SCM_CANCEL_SCAN_WAIT_TIME));
1132 			max_wait_iterations--;
1133 		}
1134 	} else if (cancel_vdev) {
1135 		while ((ucfg_scan_get_vdev_status(vdev) !=
1136 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
1137 			scm_debug("wait for all vdev scan to get complete");
1138 				qdf_wait_single_event(&cancel_scan_event,
1139 					qdf_system_msecs_to_ticks(
1140 					SCM_CANCEL_SCAN_WAIT_TIME));
1141 			max_wait_iterations--;
1142 		}
1143 	}
1144 
1145 	qdf_event_destroy(&cancel_scan_event);
1146 
1147 	if (!max_wait_iterations) {
1148 		scm_err("Failed to wait for scans to get complete");
1149 		return QDF_STATUS_E_TIMEOUT;
1150 	}
1151 
1152 	return status;
1153 }
1154 
1155 wlan_scan_requester
1156 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc,
1157 	uint8_t *name, scan_event_handler event_cb, void *arg)
1158 {
1159 	int i, j;
1160 	struct wlan_scan_obj *scan;
1161 	struct scan_requester_info *requesters;
1162 	wlan_scan_requester requester = {0};
1163 
1164 	if (!psoc) {
1165 		scm_err("null psoc");
1166 		return 0;
1167 	}
1168 	scan = wlan_psoc_get_scan_obj(psoc);
1169 	requesters = scan->requesters;
1170 	qdf_spin_lock_bh(&scan->lock);
1171 	for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) {
1172 		if (requesters[i].requester == 0) {
1173 			requesters[i].requester =
1174 				WLAN_SCAN_REQUESTER_ID_PREFIX | i;
1175 			j = 0;
1176 			while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) {
1177 				requesters[i].module[j] = name[j];
1178 				++j;
1179 			}
1180 			requesters[i].module[j] = 0;
1181 			requesters[i].ev_handler.func = event_cb;
1182 			requesters[i].ev_handler.arg = arg;
1183 			requester = requesters[i].requester;
1184 			break;
1185 		}
1186 	}
1187 	qdf_spin_unlock_bh(&scan->lock);
1188 	scm_info("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d",
1189 		name, event_cb, arg, requester);
1190 
1191 	return requester;
1192 }
1193 
1194 void
1195 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
1196 	wlan_scan_requester requester)
1197 {
1198 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
1199 	struct wlan_scan_obj *scan;
1200 	struct scan_requester_info *requesters;
1201 
1202 	if (idx >= WLAN_MAX_REQUESTORS) {
1203 		scm_err("requester id invalid");
1204 		return;
1205 	}
1206 
1207 	if (!psoc) {
1208 		scm_err("null psoc");
1209 		return;
1210 	}
1211 	scan = wlan_psoc_get_scan_obj(psoc);
1212 	requesters = scan->requesters;
1213 	scm_info("reqid: %d", requester);
1214 
1215 	qdf_spin_lock_bh(&scan->lock);
1216 	requesters[idx].requester = 0;
1217 	requesters[idx].module[0] = 0;
1218 	requesters[idx].ev_handler.func = NULL;
1219 	requesters[idx].ev_handler.arg = NULL;
1220 	qdf_spin_unlock_bh(&scan->lock);
1221 }
1222 
1223 uint8_t*
1224 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
1225 	wlan_scan_requester requester)
1226 {
1227 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
1228 	struct wlan_scan_obj *scan;
1229 	struct scan_requester_info *requesters;
1230 
1231 	if (!psoc) {
1232 		scm_err("null psoc");
1233 		return "null";
1234 	}
1235 	scan = wlan_psoc_get_scan_obj(psoc);
1236 	requesters = scan->requesters;
1237 
1238 	if ((idx < WLAN_MAX_REQUESTORS) &&
1239 		(requesters[idx].requester == requester)) {
1240 		return requesters[idx].module;
1241 	}
1242 
1243 	return (uint8_t *)"unknown";
1244 }
1245 
1246 wlan_scan_id
1247 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
1248 {
1249 	wlan_scan_id id;
1250 	struct wlan_scan_obj *scan;
1251 
1252 	if (!psoc) {
1253 		QDF_ASSERT(0);
1254 		scm_err("null psoc");
1255 		return 0;
1256 	}
1257 	scan = wlan_psoc_get_scan_obj(psoc);
1258 
1259 	id = qdf_atomic_inc_return(&scan->scan_ids);
1260 	id =  id & WLAN_SCAN_ID_MASK;
1261 	/* Mark this scan request as triggered by host
1262 	 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag.
1263 	 */
1264 	id =  id | WLAN_HOST_SCAN_REQ_ID_PREFIX;
1265 	scm_info("scan_id: 0x%x", id);
1266 
1267 	return id;
1268 }
1269 
1270 static QDF_STATUS
1271 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
1272 	scan_event_handler event_cb, void *arg)
1273 {
1274 	struct cb_handler *cb_handler;
1275 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
1276 
1277 	/* Assign next available slot to this registration request */
1278 	cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
1279 	cb_handler->func = event_cb;
1280 	cb_handler->arg = arg;
1281 	pdev_ev_handler->handler_cnt++;
1282 
1283 	return QDF_STATUS_SUCCESS;
1284 }
1285 
1286 QDF_STATUS
1287 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
1288 	scan_event_handler event_cb, void *arg)
1289 {
1290 	uint32_t idx;
1291 	struct wlan_scan_obj *scan;
1292 	struct pdev_scan_ev_handler *pdev_ev_handler;
1293 	struct cb_handler *cb_handler;
1294 
1295 	/* scan event handler call back can't be NULL */
1296 	if (!pdev || !event_cb) {
1297 		scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
1298 		return QDF_STATUS_E_NULL_VALUE;
1299 	}
1300 
1301 	scm_info("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
1302 
1303 	scan = wlan_pdev_get_scan_obj(pdev);
1304 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
1305 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
1306 
1307 	qdf_spin_lock_bh(&scan->lock);
1308 	/* Ensure its not a duplicate registration request */
1309 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
1310 		idx++, cb_handler++) {
1311 		if ((cb_handler->func == event_cb) &&
1312 			(cb_handler->arg == arg)) {
1313 			qdf_spin_unlock_bh(&scan->lock);
1314 			scm_warn("func: %pK, arg: %pK already exists",
1315 				event_cb, arg);
1316 			return QDF_STATUS_SUCCESS;
1317 		}
1318 	}
1319 
1320 	QDF_ASSERT(pdev_ev_handler->handler_cnt <
1321 			MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
1322 
1323 	if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
1324 		qdf_spin_unlock_bh(&scan->lock);
1325 		scm_warn("No more registrations possible");
1326 		return QDF_STATUS_E_NOMEM;
1327 	}
1328 
1329 	scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
1330 	qdf_spin_unlock_bh(&scan->lock);
1331 
1332 	scm_info("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
1333 
1334 	return QDF_STATUS_SUCCESS;
1335 }
1336 
1337 static QDF_STATUS
1338 wlan_scan_global_init(struct wlan_scan_obj *scan_obj)
1339 {
1340 	scan_obj->enable_scan = true;
1341 	scan_obj->drop_bcn_on_chan_mismatch = true;
1342 	scan_obj->disable_timeout = false;
1343 	scan_obj->scan_def.active_dwell = SCAN_ACTIVE_DWELL_TIME;
1344 	scan_obj->scan_def.passive_dwell = SCAN_PASSIVE_DWELL_TIME;
1345 	scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
1346 	scan_obj->scan_def.sta_miracast_mcc_rest_time =
1347 					SCAN_STA_MIRACAST_MCC_REST_TIME;
1348 	scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
1349 	scan_obj->scan_def.conc_active_dwell = SCAN_CONC_ACTIVE_DWELL_TIME;
1350 	scan_obj->scan_def.conc_passive_dwell = SCAN_CONC_PASSIVE_DWELL_TIME;
1351 	scan_obj->scan_def.conc_max_rest_time = SCAN_CONC_MAX_REST_TIME;
1352 	scan_obj->scan_def.conc_min_rest_time = SCAN_CONC_MIN_REST_TIME;
1353 	scan_obj->scan_def.conc_idle_time = SCAN_CONC_IDLE_TIME;
1354 	scan_obj->scan_def.repeat_probe_time = SCAN_REPEAT_PROBE_TIME;
1355 	scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
1356 	scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
1357 	scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
1358 	scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
1359 	scan_obj->scan_def.num_probes = SCAN_NUM_PROBES;
1360 	scan_obj->scan_def.scan_cache_aging_time = SCAN_CACHE_AGING_TIME;
1361 	scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
1362 	scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
1363 	scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
1364 	scan_obj->scan_def.adaptive_dwell_time_mode = SCAN_DWELL_MODE_DEFAULT;
1365 	/* scan contrl flags */
1366 	scan_obj->scan_def.scan_f_passive = true;
1367 	scan_obj->scan_def.scan_f_ofdm_rates = true;
1368 	scan_obj->scan_def.scan_f_2ghz = true;
1369 	scan_obj->scan_def.scan_f_5ghz = true;
1370 	scan_obj->scan_def.scan_f_chan_stat_evnt = SCAN_CHAN_STATS_EVENT_ENAB;
1371 	/* scan event flags */
1372 	scan_obj->scan_def.scan_ev_started = true;
1373 	scan_obj->scan_def.scan_ev_completed = true;
1374 	scan_obj->scan_def.scan_ev_bss_chan = true;
1375 	scan_obj->scan_def.scan_ev_foreign_chan = true;
1376 	scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
1377 	scan_obj->scan_def.scan_ev_dequeued = true;
1378 	scan_obj->scan_def.scan_ev_preempted = true;
1379 	scan_obj->scan_def.scan_ev_start_failed = true;
1380 	scan_obj->scan_def.scan_ev_restarted = true;
1381 	/* init scan id seed */
1382 	qdf_atomic_init(&scan_obj->scan_ids);
1383 
1384 	return wlan_pno_global_init(&scan_obj->pno_cfg);
1385 }
1386 
1387 static QDF_STATUS
1388 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
1389 	struct cb_handler *entry)
1390 {
1391 	struct cb_handler *last_entry;
1392 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
1393 
1394 	/* Replace event handler being deleted
1395 	 * with the last one in the list.
1396 	 */
1397 	last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
1398 	entry->func = last_entry->func;
1399 	entry->arg = last_entry->arg;
1400 
1401 	/* Clear our last entry */
1402 	last_entry->func = NULL;
1403 	last_entry->arg = NULL;
1404 	pdev_ev_handler->handler_cnt--;
1405 
1406 	return QDF_STATUS_SUCCESS;
1407 }
1408 
1409 void
1410 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
1411 	scan_event_handler event_cb, void *arg)
1412 {
1413 	uint8_t found = false;
1414 	uint32_t idx;
1415 	uint32_t handler_cnt;
1416 	struct wlan_scan_obj *scan;
1417 	struct cb_handler *cb_handler;
1418 	struct pdev_scan_ev_handler *pdev_ev_handler;
1419 
1420 	scm_info("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb, arg);
1421 	if (!pdev) {
1422 		scm_err("null pdev");
1423 		return;
1424 	}
1425 	scan = wlan_pdev_get_scan_obj(pdev);
1426 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
1427 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
1428 
1429 	qdf_spin_lock_bh(&scan->lock);
1430 	handler_cnt = pdev_ev_handler->handler_cnt;
1431 	if (!handler_cnt) {
1432 		qdf_spin_unlock_bh(&scan->lock);
1433 		scm_info("No event handlers registered");
1434 		return;
1435 	}
1436 
1437 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
1438 		idx++, cb_handler++) {
1439 		if ((cb_handler->func == event_cb) &&
1440 			(cb_handler->arg == arg)) {
1441 			/* Event handler found, remove it
1442 			 * from event handler list.
1443 			 */
1444 			found = true;
1445 			scm_remove_scan_event_handler(pdev_ev_handler,
1446 				cb_handler);
1447 			handler_cnt--;
1448 			break;
1449 		}
1450 	}
1451 	qdf_spin_unlock_bh(&scan->lock);
1452 
1453 	scm_info("event handler %s, remaining handlers: %d",
1454 		(found ? "removed" : "not found"), handler_cnt);
1455 }
1456 
1457 QDF_STATUS
1458 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
1459 	struct scan_start_request *req)
1460 {
1461 	struct scan_default_params *def;
1462 
1463 	if (!vdev | !req) {
1464 		scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req);
1465 		return QDF_STATUS_E_INVAL;
1466 	}
1467 	def = wlan_vdev_get_def_scan_params(vdev);
1468 	if (!def) {
1469 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
1470 		return QDF_STATUS_E_NULL_VALUE;
1471 	}
1472 
1473 	/* Zero out everything and explicitly set fields as required */
1474 	qdf_mem_zero(req, sizeof(*req));
1475 
1476 	req->vdev = vdev;
1477 	req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
1478 	req->scan_req.p2p_scan_type = SCAN_NON_P2P_DEFAULT;
1479 	req->scan_req.scan_priority = def->scan_priority;
1480 	req->scan_req.dwell_time_active = def->active_dwell;
1481 	req->scan_req.dwell_time_passive = def->passive_dwell;
1482 	req->scan_req.min_rest_time = def->min_rest_time;
1483 	req->scan_req.max_rest_time = def->max_rest_time;
1484 	req->scan_req.repeat_probe_time = def->repeat_probe_time;
1485 	req->scan_req.probe_spacing_time = def->probe_spacing_time;
1486 	req->scan_req.idle_time = def->idle_time;
1487 	req->scan_req.max_scan_time = def->max_scan_time;
1488 	req->scan_req.probe_delay = def->probe_delay;
1489 	req->scan_req.burst_duration = def->burst_duration;
1490 	req->scan_req.n_probes = def->num_probes;
1491 	req->scan_req.adaptive_dwell_time_mode =
1492 		def->adaptive_dwell_time_mode;
1493 	req->scan_req.scan_flags = def->scan_flags;
1494 	req->scan_req.scan_events = def->scan_events;
1495 	req->scan_req.scan_random.randomize = def->enable_mac_spoofing;
1496 
1497 	return QDF_STATUS_SUCCESS;
1498 }
1499 
1500 QDF_STATUS
1501 ucfg_scan_init_ssid_params(struct scan_start_request *req,
1502 		uint32_t num_ssid, struct wlan_ssid *ssid_list)
1503 {
1504 	uint32_t max_ssid = sizeof(req->scan_req.ssid) /
1505 				sizeof(req->scan_req.ssid[0]);
1506 
1507 	if (!req) {
1508 		scm_err("null request");
1509 		return QDF_STATUS_E_NULL_VALUE;
1510 	}
1511 	if (!num_ssid) {
1512 		/* empty channel list provided */
1513 		req->scan_req.num_ssids = 0;
1514 		qdf_mem_zero(&req->scan_req.ssid[0],
1515 			sizeof(req->scan_req.ssid));
1516 		return QDF_STATUS_SUCCESS;
1517 	}
1518 	if (!ssid_list) {
1519 		scm_err("null ssid_list while num_ssid: %d", num_ssid);
1520 		return QDF_STATUS_E_NULL_VALUE;
1521 	}
1522 	if (num_ssid > max_ssid) {
1523 		/* got a big list. alert and continue */
1524 		scm_warn("overflow: received %d, max supported : %d",
1525 			num_ssid, max_ssid);
1526 		return QDF_STATUS_E_E2BIG;
1527 	}
1528 
1529 	if (max_ssid > num_ssid)
1530 		max_ssid = num_ssid;
1531 
1532 	req->scan_req.num_ssids = max_ssid;
1533 	qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
1534 		(req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
1535 
1536 	return QDF_STATUS_SUCCESS;
1537 }
1538 
1539 QDF_STATUS
1540 ucfg_scan_init_bssid_params(struct scan_start_request *req,
1541 		uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
1542 {
1543 	uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
1544 				sizeof(req->scan_req.bssid_list[0]);
1545 
1546 	if (!req) {
1547 		scm_err("null request");
1548 		return QDF_STATUS_E_NULL_VALUE;
1549 	}
1550 	if (!num_bssid) {
1551 		/* empty channel list provided */
1552 		req->scan_req.num_bssid = 0;
1553 		qdf_mem_zero(&req->scan_req.bssid_list[0],
1554 			sizeof(req->scan_req.bssid_list));
1555 		return QDF_STATUS_SUCCESS;
1556 	}
1557 	if (!bssid_list) {
1558 		scm_err("null bssid_list while num_bssid: %d", num_bssid);
1559 		return QDF_STATUS_E_NULL_VALUE;
1560 	}
1561 	if (num_bssid > max_bssid) {
1562 		/* got a big list. alert and continue */
1563 		scm_warn("overflow: received %d, max supported : %d",
1564 			num_bssid, max_bssid);
1565 		return QDF_STATUS_E_E2BIG;
1566 	}
1567 
1568 	if (max_bssid > num_bssid)
1569 		max_bssid = num_bssid;
1570 
1571 	req->scan_req.num_bssid = max_bssid;
1572 	qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
1573 		req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
1574 
1575 	return QDF_STATUS_SUCCESS;
1576 }
1577 
1578 /**
1579  * is_chan_enabled_for_scan() - helper API to check if a frequency
1580  * is allowed to scan.
1581  * @reg_chan: regulatory_channel object
1582  * @low_2g: lower 2.4 GHz frequency thresold
1583  * @high_2g: upper 2.4 GHz frequency thresold
1584  * @low_5g: lower 5 GHz frequency thresold
1585  * @high_5g: upper 5 GHz frequency thresold
1586  *
1587  * Return: true if scan is allowed. false otherwise.
1588  */
1589 static bool
1590 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan,
1591 		uint32_t low_2g, uint32_t high_2g, uint32_t low_5g,
1592 		uint32_t high_5g)
1593 {
1594 	if (reg_chan->state == CHANNEL_STATE_DISABLE)
1595 		return false;
1596 	if (reg_chan->nol_chan)
1597 		return false;
1598 	/* 2 GHz channel */
1599 	if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1600 			WLAN_BAND_2_4_GHZ) &&
1601 			((reg_chan->center_freq < low_2g) ||
1602 			(reg_chan->center_freq > high_2g)))
1603 		return false;
1604 	else if ((reg_chan->center_freq < low_5g) ||
1605 			(reg_chan->center_freq > high_5g))
1606 		return false;
1607 
1608 	return true;
1609 }
1610 
1611 QDF_STATUS
1612 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1613 		uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1614 {
1615 	uint32_t idx;
1616 	QDF_STATUS status;
1617 	struct regulatory_channel *reg_chan_list = NULL;
1618 	uint32_t low_2g, high_2g, low_5g, high_5g;
1619 	struct wlan_objmgr_pdev *pdev = NULL;
1620 	uint32_t *scan_freqs = NULL;
1621 	uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1622 				sizeof(req->scan_req.chan_list.chan[0]);
1623 	if (!req) {
1624 		scm_err("null request");
1625 		return QDF_STATUS_E_NULL_VALUE;
1626 	}
1627 
1628 	if (req->vdev)
1629 		pdev = wlan_vdev_get_pdev(req->vdev);
1630 	/*
1631 	 * If 0 channels are provided for scan and
1632 	 * wide band scan is enabled, scan all 20 mhz
1633 	 * available channels. This is required as FW
1634 	 * scans all channel/phy mode combinations
1635 	 * provided in scan channel list if 0 chans are
1636 	 * provided in scan request causing scan to take
1637 	 * too much time to complete.
1638 	 */
1639 	if (pdev && !num_chans && ucfg_scan_get_wide_band_scan(pdev)) {
1640 		reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1641 				sizeof(struct regulatory_channel));
1642 		if (!reg_chan_list) {
1643 			scm_err("Couldn't allocate reg_chan_list memory");
1644 			status = QDF_STATUS_E_NOMEM;
1645 			goto end;
1646 		}
1647 		scan_freqs =
1648 			qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1649 		if (!scan_freqs) {
1650 			scm_err("Couldn't allocate scan_freqs memory");
1651 			status = QDF_STATUS_E_NOMEM;
1652 			goto end;
1653 		}
1654 		status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list);
1655 		if (QDF_IS_STATUS_ERROR(status)) {
1656 			scm_err("Couldn't get current chan list");
1657 			goto end;
1658 		}
1659 		status = wlan_reg_get_freq_range(pdev, &low_2g,
1660 				&high_2g, &low_5g, &high_5g);
1661 		if (QDF_IS_STATUS_ERROR(status)) {
1662 			scm_err("Couldn't get frequency range");
1663 			goto end;
1664 		}
1665 
1666 		for (idx = 0, num_chans = 0;
1667 			(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1668 			if (is_chan_enabled_for_scan(&reg_chan_list[idx],
1669 					low_2g, high_2g, low_5g, high_5g))
1670 				scan_freqs[num_chans++] =
1671 				reg_chan_list[idx].center_freq;
1672 
1673 		chan_list = scan_freqs;
1674 	}
1675 
1676 	if (!num_chans) {
1677 		/* empty channel list provided */
1678 		qdf_mem_zero(&req->scan_req.chan_list,
1679 			sizeof(req->scan_req.chan_list));
1680 		req->scan_req.chan_list.num_chan = 0;
1681 		status = QDF_STATUS_SUCCESS;
1682 		goto end;
1683 	}
1684 	if (!chan_list) {
1685 		scm_err("null chan_list while num_chans: %d", num_chans);
1686 		status = QDF_STATUS_E_NULL_VALUE;
1687 		goto end;
1688 	}
1689 
1690 	if (num_chans > max_chans) {
1691 		/* got a big list. alert and fail */
1692 		scm_warn("overflow: received %d, max supported : %d",
1693 			num_chans, max_chans);
1694 		status = QDF_STATUS_E_E2BIG;
1695 		goto end;
1696 	}
1697 
1698 	req->scan_req.chan_list.num_chan = num_chans;
1699 	for (idx = 0; idx < num_chans; idx++) {
1700 		req->scan_req.chan_list.chan[idx].freq =
1701 			(chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1702 			chan_list[idx] :
1703 			wlan_reg_chan_to_freq(pdev, chan_list[idx]);
1704 		if (phymode)
1705 			req->scan_req.chan_list.chan[idx].phymode =
1706 				phymode[idx];
1707 		else if (req->scan_req.chan_list.chan[idx].freq <=
1708 			WLAN_CHAN_15_FREQ)
1709 			req->scan_req.chan_list.chan[idx].phymode =
1710 				SCAN_PHY_MODE_11G;
1711 		else
1712 			req->scan_req.chan_list.chan[idx].phymode =
1713 				SCAN_PHY_MODE_11A;
1714 
1715 		scm_debug("chan[%d]: freq:%d, phymode:%d", idx,
1716 			req->scan_req.chan_list.chan[idx].freq,
1717 			req->scan_req.chan_list.chan[idx].phymode);
1718 	}
1719 
1720 end:
1721 	if (scan_freqs)
1722 		qdf_mem_free(scan_freqs);
1723 
1724 	return QDF_STATUS_SUCCESS;
1725 }
1726 
1727 static inline enum scm_scan_status
1728 get_scan_status_from_serialization_status(
1729 	enum wlan_serialization_cmd_status status)
1730 {
1731 	enum scm_scan_status scan_status;
1732 
1733 	switch (status) {
1734 	case WLAN_SER_CMD_IN_PENDING_LIST:
1735 		scan_status = SCAN_IS_PENDING;
1736 		break;
1737 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1738 		scan_status = SCAN_IS_ACTIVE;
1739 		break;
1740 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1741 		scan_status = SCAN_IS_ACTIVE_AND_PENDING;
1742 		break;
1743 	case WLAN_SER_CMD_NOT_FOUND:
1744 		scan_status = SCAN_NOT_IN_PROGRESS;
1745 		break;
1746 	default:
1747 		scm_warn("invalid serialization status %d", status);
1748 		QDF_ASSERT(0);
1749 		scan_status = SCAN_NOT_IN_PROGRESS;
1750 		break;
1751 	}
1752 
1753 	return scan_status;
1754 }
1755 
1756 enum scm_scan_status
1757 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1758 {
1759 	enum wlan_serialization_cmd_status status;
1760 
1761 	if (!vdev) {
1762 		scm_err("null vdev");
1763 		return SCAN_NOT_IN_PROGRESS;
1764 	}
1765 	status = wlan_serialization_vdev_scan_status(vdev);
1766 
1767 	return get_scan_status_from_serialization_status(status);
1768 }
1769 
1770 enum scm_scan_status
1771 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1772 {
1773 	enum wlan_serialization_cmd_status status;
1774 
1775 	if (!pdev) {
1776 		scm_err("null pdev");
1777 		return SCAN_NOT_IN_PROGRESS;
1778 	}
1779 	status = wlan_serialization_pdev_scan_status(pdev);
1780 
1781 	return get_scan_status_from_serialization_status(status);
1782 }
1783 
1784 static void
1785 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1786 	bool enable)
1787 {
1788 	QDF_STATUS status;
1789 	struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1790 
1791 	cb_info[0].frm_type = MGMT_PROBE_RESP;
1792 	cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1793 	cb_info[1].frm_type = MGMT_BEACON;
1794 	cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1795 
1796 	if (enable)
1797 		status = wlan_mgmt_txrx_register_rx_cb(psoc,
1798 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1799 	else
1800 		status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1801 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1802 	if (status != QDF_STATUS_SUCCESS)
1803 		scm_err("%s the Handle with MGMT TXRX layer has failed",
1804 			enable ? "Registering" : "Deregistering");
1805 }
1806 
1807 static void ucfg_scan_assign_rssi_category(struct scan_default_params *params,
1808 	int32_t best_ap_rssi, uint32_t cat_offset)
1809 {
1810 	int i;
1811 
1812 	scm_info("best AP RSSI:%d, cat offset: %d", best_ap_rssi, cat_offset);
1813 	if (cat_offset)
1814 		for (i = 0; i < SCM_NUM_RSSI_CAT; i++) {
1815 			params->rssi_cat[SCM_NUM_RSSI_CAT - i - 1] =
1816 				(best_ap_rssi -
1817 				params->select_5ghz_margin -
1818 				(int)(i * cat_offset));
1819 		params->bss_prefer_val[i] = i;
1820 	}
1821 }
1822 
1823 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1824 	struct scan_user_cfg *scan_cfg)
1825 {
1826 	struct wlan_scan_obj *scan_obj;
1827 	struct scan_default_params *scan_def;
1828 
1829 	if (!psoc) {
1830 		scm_err("null psoc");
1831 		return QDF_STATUS_E_FAILURE;
1832 	}
1833 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1834 	if (scan_obj == NULL) {
1835 		scm_err("Failed to get scan object");
1836 		return QDF_STATUS_E_FAILURE;
1837 	}
1838 
1839 	scan_def = &scan_obj->scan_def;
1840 	scan_def->active_dwell = scan_cfg->active_dwell;
1841 	scan_def->passive_dwell = scan_cfg->passive_dwell;
1842 	scan_def->conc_active_dwell = scan_cfg->conc_active_dwell;
1843 	scan_def->conc_passive_dwell = scan_cfg->conc_passive_dwell;
1844 	scan_def->conc_max_rest_time = scan_cfg->conc_max_rest_time;
1845 	scan_def->conc_min_rest_time = scan_cfg->conc_min_rest_time;
1846 	scan_def->conc_idle_time = scan_cfg->conc_idle_time;
1847 	scan_def->scan_cache_aging_time = scan_cfg->scan_cache_aging_time;
1848 	scan_def->prefer_5ghz = scan_cfg->prefer_5ghz;
1849 	scan_def->select_5ghz_margin = scan_cfg->select_5ghz_margin;
1850 	scan_def->adaptive_dwell_time_mode = scan_cfg->scan_dwell_time_mode;
1851 	scan_def->scan_f_chan_stat_evnt = scan_cfg->is_snr_monitoring_enabled;
1852 	scan_obj->ie_whitelist = scan_cfg->ie_whitelist;
1853 	scan_def->repeat_probe_time = scan_cfg->usr_cfg_probe_rpt_time;
1854 	scan_def->num_probes = scan_cfg->usr_cfg_num_probes;
1855 	scan_def->is_bssid_hint_priority = scan_cfg->is_bssid_hint_priority;
1856 	scan_def->enable_mac_spoofing = scan_cfg->enable_mac_spoofing;
1857 	scan_def->sta_miracast_mcc_rest_time =
1858 				scan_cfg->sta_miracast_mcc_rest_time;
1859 
1860 	ucfg_scan_assign_rssi_category(scan_def,
1861 			scan_cfg->scan_bucket_threshold,
1862 			scan_cfg->rssi_cat_gap);
1863 
1864 	ucfg_scan_update_pno_config(&scan_obj->pno_cfg,
1865 		&scan_cfg->pno_cfg);
1866 
1867 	qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config,
1868 		sizeof(struct scoring_config));
1869 	scm_validate_scoring_config(&scan_def->score_config);
1870 
1871 	return QDF_STATUS_SUCCESS;
1872 }
1873 
1874 QDF_STATUS ucfg_scan_update_roam_params(struct wlan_objmgr_psoc *psoc,
1875 	struct roam_filter_params *roam_params)
1876 {
1877 	struct scan_default_params *scan_def;
1878 
1879 	if (!psoc) {
1880 		scm_err("null psoc");
1881 		return QDF_STATUS_E_FAILURE;
1882 	}
1883 	scan_def = wlan_scan_psoc_get_def_params(psoc);
1884 	if (!scan_def) {
1885 		scm_err("Failed to get scan object");
1886 		return QDF_STATUS_E_FAILURE;
1887 	}
1888 
1889 	qdf_mem_copy(&scan_def->roam_params, roam_params,
1890 		sizeof(struct roam_filter_params));
1891 
1892 	return QDF_STATUS_SUCCESS;
1893 }
1894 
1895 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1896 static QDF_STATUS
1897 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
1898 {
1899 	struct scan_cancel_request *req;
1900 	QDF_STATUS status;
1901 	struct wlan_objmgr_vdev *vdev;
1902 
1903 	req = qdf_mem_malloc_atomic(sizeof(*req));
1904 	if (!req) {
1905 		scm_err("Failed to allocate memory");
1906 		return QDF_STATUS_E_NOMEM;
1907 	}
1908 
1909 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, 0, WLAN_OSIF_ID);
1910 	if (!vdev) {
1911 		scm_err("Failed to get vdev");
1912 		return QDF_STATUS_E_INVAL;
1913 	}
1914 	req->vdev = vdev;
1915 	req->cancel_req.scan_id = INVAL_SCAN_ID;
1916 	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1917 	req->cancel_req.vdev_id = INVAL_VDEV_ID;
1918 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1919 	status = ucfg_scan_cancel_sync(req);
1920 	if (QDF_IS_STATUS_ERROR(status))
1921 		scm_err("Cancel scan request failed");
1922 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
1923 
1924 	return status;
1925 }
1926 
1927 static QDF_STATUS
1928 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1929 {
1930 	struct wlan_objmgr_pdev *pdev = NULL;
1931 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1932 	int i;
1933 
1934 	/* Check all pdev */
1935 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
1936 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
1937 		if (!pdev)
1938 			continue;
1939 		if (ucfg_scan_get_pdev_status(pdev) !=
1940 		    SCAN_NOT_IN_PROGRESS)
1941 			status = ucfg_scan_cancel_pdev_scan(pdev);
1942 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
1943 		if (QDF_IS_STATUS_ERROR(status)) {
1944 			scm_err("failed to cancel scan for pdev_id %d", i);
1945 			return status;
1946 		}
1947 	}
1948 
1949 	return QDF_STATUS_SUCCESS;
1950 }
1951 
1952 static QDF_STATUS
1953 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1954 {
1955 	return QDF_STATUS_SUCCESS;
1956 }
1957 
1958 static inline void
1959 ucfg_scan_register_pmo_handler(void)
1960 {
1961 	pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
1962 		ucfg_scan_suspend_handler, NULL);
1963 	pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
1964 		ucfg_scan_resume_handler, NULL);
1965 }
1966 
1967 static inline void
1968 ucfg_scan_unregister_pmo_handler(void)
1969 {
1970 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
1971 		ucfg_scan_suspend_handler);
1972 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
1973 		ucfg_scan_resume_handler);
1974 }
1975 
1976 #else
1977 static inline void
1978 ucfg_scan_register_pmo_handler(void)
1979 {
1980 }
1981 
1982 static inline void
1983 ucfg_scan_unregister_pmo_handler(void)
1984 {
1985 }
1986 #endif
1987 
1988 QDF_STATUS
1989 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
1990 {
1991 	struct wlan_scan_obj *scan_obj;
1992 
1993 	scm_info("psoc open: 0x%pK", psoc);
1994 	if (!psoc) {
1995 		scm_err("null psoc");
1996 		return QDF_STATUS_E_FAILURE;
1997 	}
1998 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1999 	if (scan_obj == NULL) {
2000 		scm_err("Failed to get scan object");
2001 		return QDF_STATUS_E_FAILURE;
2002 	}
2003 	/* Initialize the scan Globals */
2004 	wlan_scan_global_init(scan_obj);
2005 	qdf_spinlock_create(&scan_obj->lock);
2006 	ucfg_scan_register_pmo_handler();
2007 	scm_db_init(psoc);
2008 
2009 	return QDF_STATUS_SUCCESS;
2010 }
2011 
2012 QDF_STATUS
2013 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
2014 {
2015 	struct wlan_scan_obj *scan_obj;
2016 
2017 	scm_info("psoc close: 0x%pK", psoc);
2018 	if (!psoc) {
2019 		scm_err("null psoc");
2020 		return QDF_STATUS_E_FAILURE;
2021 	}
2022 	scm_db_deinit(psoc);
2023 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2024 	if (scan_obj == NULL) {
2025 		scm_err("Failed to get scan object");
2026 		return QDF_STATUS_E_FAILURE;
2027 	}
2028 	ucfg_scan_unregister_pmo_handler();
2029 	qdf_spinlock_destroy(&scan_obj->lock);
2030 	wlan_pno_global_deinit(&scan_obj->pno_cfg);
2031 
2032 	return QDF_STATUS_SUCCESS;
2033 }
2034 
2035 static bool scm_serialization_scan_rules_cb(
2036 		union wlan_serialization_rules_info *comp_info,
2037 		uint8_t comp_id)
2038 {
2039 	switch (comp_id) {
2040 	case WLAN_UMAC_COMP_TDLS:
2041 		if (comp_info->scan_info.is_tdls_in_progress) {
2042 			scm_info("Cancel scan. Tdls in progress");
2043 			return false;
2044 		}
2045 		break;
2046 	case WLAN_UMAC_COMP_DFS:
2047 		if (comp_info->scan_info.is_cac_in_progress) {
2048 			scm_info("Cancel scan. CAC in progress");
2049 			return false;
2050 		}
2051 		break;
2052 	default:
2053 		scm_info("not handled comp_id %d", comp_id);
2054 		break;
2055 	}
2056 
2057 	return true;
2058 }
2059 
2060 QDF_STATUS
2061 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
2062 {
2063 	QDF_STATUS status;
2064 
2065 	scm_info("psoc enable: 0x%pK", psoc);
2066 	if (!psoc) {
2067 		scm_err("null psoc");
2068 		return QDF_STATUS_E_FAILURE;
2069 	}
2070 	/* Subscribe for scan events from lmac layesr */
2071 	status = tgt_scan_register_ev_handler(psoc);
2072 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
2073 	if (wlan_reg_11d_original_enabled_on_host(psoc))
2074 		scm_11d_cc_db_init(psoc);
2075 	ucfg_scan_register_unregister_bcn_cb(psoc, true);
2076 	status = wlan_serialization_register_apply_rules_cb(psoc,
2077 				WLAN_SER_CMD_SCAN,
2078 				scm_serialization_scan_rules_cb);
2079 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
2080 	return status;
2081 }
2082 
2083 QDF_STATUS
2084 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
2085 {
2086 	QDF_STATUS status;
2087 
2088 	scm_info("psoc disable: 0x%pK", psoc);
2089 	if (!psoc) {
2090 		scm_err("null psoc");
2091 		return QDF_STATUS_E_FAILURE;
2092 	}
2093 	/* Unsubscribe for scan events from lmac layesr */
2094 	status = tgt_scan_unregister_ev_handler(psoc);
2095 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
2096 	ucfg_scan_register_unregister_bcn_cb(psoc, false);
2097 	if (wlan_reg_11d_original_enabled_on_host(psoc))
2098 		scm_11d_cc_db_deinit(psoc);
2099 
2100 	return status;
2101 }
2102 
2103 uint32_t
2104 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
2105 {
2106 	struct scan_default_params *scan_params = NULL;
2107 
2108 	if (!psoc) {
2109 		scm_err("null psoc");
2110 		return 0;
2111 	}
2112 	scan_params = wlan_scan_psoc_get_def_params(psoc);
2113 	if (!scan_params) {
2114 		scm_err("Failed to get scan object");
2115 		return 0;
2116 	}
2117 
2118 	return scan_params->max_active_scans_allowed;
2119 }
2120 
2121 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
2122 				  struct probe_req_whitelist_attr *ie_whitelist)
2123 {
2124 	struct wlan_scan_obj *scan_obj = NULL;
2125 
2126 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2127 	if (!scan_obj)
2128 		return false;
2129 
2130 	qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist,
2131 		     sizeof(*ie_whitelist));
2132 
2133 	return true;
2134 }
2135 
2136 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
2137 			       struct wlan_objmgr_vdev *vdev)
2138 {
2139 	struct wlan_scan_obj *scan_obj = NULL;
2140 
2141 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2142 	if (!scan_obj)
2143 		return false;
2144 
2145 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
2146 	    wlan_vdev_is_connected(vdev))
2147 		return false;
2148 
2149 	if (!scan_obj->ie_whitelist.white_list)
2150 		return false;
2151 
2152 	return true;
2153 }
2154 
2155 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
2156 			       bool bt_a2dp_active)
2157 {
2158 	struct wlan_scan_obj *scan_obj;
2159 
2160 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2161 	if (!scan_obj) {
2162 		scm_err("Failed to get scan object");
2163 		return;
2164 	}
2165 	scan_obj->bt_a2dp_enabled = bt_a2dp_active;
2166 }
2167 
2168 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
2169 {
2170 	struct wlan_scan_obj *scan_obj;
2171 
2172 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2173 	if (!scan_obj) {
2174 		scm_err("Failed to get scan object");
2175 		return false;
2176 	}
2177 
2178 	return scan_obj->bt_a2dp_enabled;
2179 }
2180 
2181 void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev)
2182 {
2183 	struct scan_vdev_obj *scan_vdev_obj;
2184 
2185 	if (!vdev) {
2186 		scm_err("invalid vdev");
2187 		return;
2188 	}
2189 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
2190 	if (!scan_vdev_obj) {
2191 		scm_err("null scan_vdev_obj");
2192 		return;
2193 	}
2194 	scan_vdev_obj->is_vdev_delete_in_progress = true;
2195 }
2196 
2197 void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev)
2198 {
2199 	struct scan_vdev_obj *scan_vdev_obj;
2200 
2201 	if (!vdev) {
2202 		scm_err("invalid vdev");
2203 		return;
2204 	}
2205 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
2206 	if (!scan_vdev_obj) {
2207 		scm_err("null scan_vdev_obj");
2208 		return;
2209 	}
2210 	scan_vdev_obj->is_vdev_delete_in_progress = false;
2211 }
2212 
2213 QDF_STATUS
2214 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
2215 			       enum scan_config config, uint32_t val)
2216 {
2217 	struct wlan_scan_obj *scan_obj;
2218 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2219 
2220 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2221 	if (!scan_obj) {
2222 		scm_err("Failed to get scan object config:%d, val:%d",
2223 				config, val);
2224 		return QDF_STATUS_E_INVAL;
2225 	}
2226 	switch (config) {
2227 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
2228 		scan_obj->disable_timeout = !!val;
2229 		break;
2230 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
2231 		scan_obj->drop_bcn_on_chan_mismatch = !!val;
2232 		break;
2233 
2234 	default:
2235 		status = QDF_STATUS_E_INVAL;
2236 		break;
2237 	}
2238 
2239 	return status;
2240 }
2241 
2242 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
2243 		struct bss_info *bss_info, struct mlme_info *mlme)
2244 {
2245 	QDF_STATUS status;
2246 
2247 	status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme);
2248 
2249 	return status;
2250 }
2251 
2252 QDF_STATUS
2253 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
2254 			       enum scan_config config, uint32_t *val)
2255 {
2256 	struct wlan_scan_obj *scan_obj;
2257 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2258 
2259 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2260 	if (!scan_obj || !val) {
2261 		scm_err("scan object:%pK config:%d, val:0x%pK",
2262 				scan_obj, config, val);
2263 		return QDF_STATUS_E_INVAL;
2264 	}
2265 	switch (config) {
2266 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
2267 		*val = scan_obj->disable_timeout;
2268 		break;
2269 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
2270 		*val = scan_obj->drop_bcn_on_chan_mismatch;
2271 		break;
2272 
2273 	default:
2274 		status = QDF_STATUS_E_INVAL;
2275 		break;
2276 	}
2277 
2278 	return status;
2279 }
2280