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