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