xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /*
18  * DOC: contains scan north bound interface definitions
19  */
20 
21 #include <scheduler_api.h>
22 #include <wlan_scan_ucfg_api.h>
23 #include <wlan_objmgr_global_obj.h>
24 #include <wlan_objmgr_cmn.h>
25 #include <wlan_serialization_api.h>
26 #include <wlan_scan_tgt_api.h>
27 #include <wlan_scan_utils_api.h>
28 #include <wlan_reg_ucfg_api.h>
29 #include <wlan_reg_services_api.h>
30 #include <wlan_utility.h>
31 #include "../../core/src/wlan_scan_main.h"
32 #include "../../core/src/wlan_scan_manager.h"
33 #include "../../core/src/wlan_scan_cache_db.h"
34 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
35 #include <wlan_pmo_obj_mgmt_api.h>
36 #endif
37 #ifdef WLAN_POLICY_MGR_ENABLE
38 #include <wlan_dfs_utils_api.h>
39 #include <wlan_policy_mgr_api.h>
40 #endif
41 #include "cfg_ucfg_api.h"
42 #include "wlan_extscan_api.h"
43 
44 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
45 	update_beacon_cb cb, enum scan_cb_type type)
46 {
47 	return scm_scan_register_bcn_cb(psoc, cb, type);
48 }
49 
50 qdf_list_t *ucfg_scan_get_result(struct wlan_objmgr_pdev *pdev,
51 	struct scan_filter *filter)
52 {
53 	return scm_get_scan_result(pdev, filter);
54 }
55 
56 QDF_STATUS ucfg_scan_db_iterate(struct wlan_objmgr_pdev *pdev,
57 	scan_iterator_func func, void *arg)
58 {
59 	return scm_iterate_scan_db(pdev, func, arg);
60 }
61 
62 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list)
63 {
64 	return scm_purge_scan_results(scan_list);
65 }
66 
67 QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev,
68 	struct scan_filter *filter)
69 {
70 	return scm_flush_results(pdev, filter);
71 }
72 
73 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev,
74 	uint32_t *chan_freq_list, uint32_t num_chan)
75 {
76 	scm_filter_valid_channel(pdev, chan_freq_list, num_chan);
77 }
78 
79 QDF_STATUS ucfg_scan_init(void)
80 {
81 	QDF_STATUS status;
82 
83 	status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
84 		wlan_scan_psoc_created_notification, NULL);
85 	if (QDF_IS_STATUS_ERROR(status)) {
86 		scm_err("Failed to register psoc create handler");
87 		goto fail_create_psoc;
88 	}
89 
90 	status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
91 		wlan_scan_psoc_destroyed_notification, NULL);
92 	if (QDF_IS_STATUS_ERROR(status)) {
93 		scm_err("Failed to create psoc delete handler");
94 		goto fail_psoc_destroy;
95 	}
96 	scm_debug("scan psoc create and delete handler registered with objmgr");
97 
98 	status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
99 		wlan_scan_vdev_created_notification, NULL);
100 	if (QDF_IS_STATUS_ERROR(status)) {
101 		scm_err("Failed to register vdev create handler");
102 		goto fail_pdev_create;
103 	}
104 
105 	status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN,
106 		wlan_scan_vdev_destroyed_notification, NULL);
107 	if (QDF_IS_STATUS_SUCCESS(status)) {
108 		scm_debug("scan vdev create and delete handler registered with objmgr");
109 		return QDF_STATUS_SUCCESS;
110 	}
111 
112 	scm_err("Failed to destroy vdev delete handler");
113 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
114 				wlan_scan_vdev_created_notification, NULL);
115 fail_pdev_create:
116 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
117 				wlan_scan_psoc_destroyed_notification, NULL);
118 fail_psoc_destroy:
119 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
120 			wlan_scan_psoc_created_notification, NULL);
121 fail_create_psoc:
122 	return status;
123 }
124 
125 QDF_STATUS ucfg_scan_deinit(void)
126 {
127 	QDF_STATUS status;
128 
129 	status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
130 		wlan_scan_psoc_created_notification, NULL);
131 	if (status != QDF_STATUS_SUCCESS)
132 		scm_err("Failed to unregister psoc create handler");
133 
134 	status = wlan_objmgr_unregister_psoc_destroy_handler(
135 				WLAN_UMAC_COMP_SCAN,
136 				wlan_scan_psoc_destroyed_notification, NULL);
137 	if (status != QDF_STATUS_SUCCESS)
138 		scm_err("Failed to unregister psoc delete handler");
139 
140 	status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
141 		wlan_scan_vdev_created_notification, NULL);
142 	if (status != QDF_STATUS_SUCCESS)
143 		scm_err("Failed to unregister vdev create handler");
144 
145 	status = wlan_objmgr_unregister_vdev_destroy_handler(
146 			WLAN_UMAC_COMP_SCAN,
147 			wlan_scan_vdev_destroyed_notification, NULL);
148 	if (status != QDF_STATUS_SUCCESS)
149 		scm_err("Failed to unregister vdev delete handler");
150 
151 	return status;
152 }
153 
154 #ifdef FEATURE_WLAN_SCAN_PNO
155 
156 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
157 	struct pno_scan_req_params *req)
158 {
159 	struct scan_vdev_obj *scan_vdev_obj;
160 	QDF_STATUS status;
161 
162 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
163 	if (!scan_vdev_obj) {
164 		scm_err("null scan_vdev_obj");
165 		return QDF_STATUS_E_INVAL;
166 	}
167 	if (scan_vdev_obj->pno_in_progress) {
168 		scm_err("pno already in progress");
169 		return QDF_STATUS_E_ALREADY;
170 	}
171 
172 	status = tgt_scan_pno_start(vdev, req);
173 	if (QDF_IS_STATUS_ERROR(status))
174 		scm_err("pno start failed");
175 	else
176 		scan_vdev_obj->pno_in_progress = true;
177 
178 	return status;
179 }
180 
181 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)
182 {
183 	struct scan_vdev_obj *scan_vdev_obj;
184 	QDF_STATUS status;
185 
186 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
187 	if (!scan_vdev_obj) {
188 		scm_err("null scan_vdev_obj");
189 		return QDF_STATUS_E_INVAL;
190 	}
191 	if (!scan_vdev_obj->pno_in_progress) {
192 		scm_debug("pno already stopped");
193 		return QDF_STATUS_SUCCESS;
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 stop failed");
199 	else
200 		scan_vdev_obj->pno_in_progress = false;
201 
202 	return status;
203 }
204 
205 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev)
206 {
207 	struct scan_vdev_obj *scan_vdev_obj;
208 
209 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
210 	if (!scan_vdev_obj) {
211 		scm_err("null scan_vdev_obj");
212 		return false;
213 	}
214 
215 	return scan_vdev_obj->pno_in_progress;
216 }
217 
218 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
219 {
220 	struct scan_vdev_obj *scan_vdev_obj;
221 
222 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
223 	if (!scan_vdev_obj) {
224 		scm_err("null scan_vdev_obj");
225 		return false;
226 	}
227 
228 	return scan_vdev_obj->pno_match_evt_received;
229 }
230 
231 static QDF_STATUS
232 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
233 		     struct wlan_scan_obj *scan_obj)
234 {
235 	struct nlo_mawc_params *mawc_cfg;
236 	struct pno_def_config *pno_def;
237 
238 	pno_def = &scan_obj->pno_cfg;
239 	qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl");
240 	mawc_cfg = &pno_def->mawc_params;
241 	pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION);
242 	pno_def->top_k_num_of_channels =
243 			cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS);
244 	pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD);
245 	pno_def->channel_prediction_full_scan =
246 			cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER);
247 	pno_def->adaptive_dwell_mode =
248 			cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE);
249 	pno_def->dfs_chnl_scan_enabled =
250 			cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN);
251 	pno_def->scan_support_enabled =
252 			cfg_get(psoc, CFG_PNO_SCAN_SUPPORT);
253 	pno_def->scan_timer_repeat_value =
254 			cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
255 	pno_def->slow_scan_multiplier =
256 			cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER);
257 	pno_def->scan_backoff_multiplier =
258 			cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER);
259 	pno_def->max_sched_scan_plan_interval =
260 			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
261 	pno_def->max_sched_scan_plan_iterations =
262 			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
263 
264 	mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED);
265 	mawc_cfg->exp_backoff_ratio =
266 			cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO);
267 	mawc_cfg->init_scan_interval =
268 			cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL);
269 	mawc_cfg->max_scan_interval =
270 			cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL);
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 
275 static QDF_STATUS
276 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
277 {
278 	qdf_wake_lock_destroy(&scan_obj->pno_cfg.pno_wake_lock);
279 
280 	return QDF_STATUS_SUCCESS;
281 }
282 
283 #ifdef WLAN_POLICY_MGR_ENABLE
284 /*
285  * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time
286  * depending on active concurrency modes
287  * @vdev: vdev object pointer
288  * @req: scan request
289  *
290  * Return: void
291  */
292 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
293 	struct pno_scan_req_params *req, struct scan_default_params *scan_def)
294 {
295 	bool sap_or_p2p_present;
296 	struct wlan_objmgr_psoc *psoc;
297 
298 	psoc = wlan_vdev_get_psoc(vdev);
299 
300 	if (!psoc)
301 		return;
302 
303 	sap_or_p2p_present = policy_mgr_mode_specific_connection_count(
304 				psoc, PM_SAP_MODE, NULL) ||
305 				policy_mgr_mode_specific_connection_count(
306 				psoc, PM_P2P_GO_MODE, NULL) ||
307 				policy_mgr_mode_specific_connection_count(
308 				psoc, PM_P2P_CLIENT_MODE, NULL);
309 
310 	if (sap_or_p2p_present) {
311 		req->active_dwell_time = scan_def->conc_active_dwell;
312 		req->passive_dwell_time = scan_def->conc_passive_dwell;
313 	}
314 
315 }
316 #else
317 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
318 	struct pno_scan_req_params *req, struct scan_default_params *scan_def){}
319 #endif
320 
321 QDF_STATUS
322 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
323 	struct pno_scan_req_params *req)
324 {
325 	struct scan_default_params *scan_def;
326 	struct wlan_scan_obj *scan;
327 	struct pno_def_config *pno_def;
328 
329 	if (!vdev || !req) {
330 		scm_err("vdev: 0x%pK, req: 0x%pK",
331 			vdev, req);
332 		return QDF_STATUS_E_INVAL;
333 	}
334 
335 	scan = wlan_vdev_get_scan_obj(vdev);
336 	if (!scan) {
337 		scm_err("scan is NULL");
338 		return QDF_STATUS_E_INVAL;
339 	}
340 	scan_def = wlan_vdev_get_def_scan_params(vdev);
341 	if (!scan_def) {
342 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
343 		return QDF_STATUS_E_NULL_VALUE;
344 	}
345 
346 	pno_def = &scan->pno_cfg;
347 	req->active_dwell_time = scan_def->active_dwell;
348 	req->passive_dwell_time = scan_def->passive_dwell;
349 	req->scan_random.randomize = scan_def->enable_mac_spoofing;
350 
351 	/*
352 	 *  Update active and passive dwell time depending
353 	 *  upon the present active concurrency mode
354 	 */
355 	ucfg_scan_update_pno_dwell_time(vdev, req, scan_def);
356 	req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
357 	req->pno_channel_prediction = pno_def->channel_prediction;
358 	req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
359 	req->stationary_thresh = pno_def->stationary_thresh;
360 	req->channel_prediction_full_scan =
361 			pno_def->channel_prediction_full_scan;
362 	req->mawc_params.vdev_id = wlan_vdev_get_id(vdev);
363 	qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params,
364 			sizeof(req->mawc_params));
365 
366 	return QDF_STATUS_SUCCESS;
367 }
368 
369 QDF_STATUS
370 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
371 	scan_event_handler event_cb, void *arg)
372 {
373 	struct wlan_scan_obj *scan;
374 
375 	if (!psoc) {
376 		scm_err("null psoc");
377 		return QDF_STATUS_E_INVAL;
378 	}
379 
380 	scan = wlan_psoc_get_scan_obj(psoc);
381 	if (!scan) {
382 		scm_err("scan object null");
383 		return QDF_STATUS_E_INVAL;
384 	}
385 
386 	qdf_spin_lock_bh(&scan->lock);
387 	scan->pno_cfg.pno_cb.func = event_cb;
388 	scan->pno_cfg.pno_cb.arg = arg;
389 	qdf_spin_unlock_bh(&scan->lock);
390 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
391 
392 	return QDF_STATUS_SUCCESS;
393 }
394 
395 #else
396 
397 static inline QDF_STATUS
398 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
399 		     struct wlan_scan_obj *scan_obj)
400 {
401 	return QDF_STATUS_SUCCESS;
402 }
403 
404 static inline QDF_STATUS
405 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
406 {
407 	return QDF_STATUS_SUCCESS;
408 }
409 
410 #endif
411 
412 QDF_STATUS
413 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
414 				    struct chan_list *chan_list)
415 {
416 	uint8_t pdev_id;
417 	struct wlan_scan_obj *scan_obj;
418 
419 	if (!pdev || !chan_list) {
420 		scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list);
421 		return QDF_STATUS_E_NULL_VALUE;
422 	}
423 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
424 	scan_obj = wlan_pdev_get_scan_obj(pdev);
425 
426 	qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list,
427 			chan_list, sizeof(*chan_list));
428 
429 	return QDF_STATUS_SUCCESS;
430 }
431 
432 QDF_STATUS
433 ucfg_scan_start(struct scan_start_request *req)
434 {
435 	struct scheduler_msg msg = {0};
436 	QDF_STATUS status;
437 
438 	if (!req || !req->vdev) {
439 		scm_err("req or vdev within req is NULL");
440 		if (req)
441 			scm_scan_free_scan_request_mem(req);
442 		return QDF_STATUS_E_NULL_VALUE;
443 	}
444 
445 	if (!scm_is_scan_allowed(req->vdev)) {
446 		scm_err_rl("scan disabled, rejecting the scan req");
447 		scm_scan_free_scan_request_mem(req);
448 		return QDF_STATUS_E_AGAIN;
449 	}
450 
451 	/* Try to get vdev reference. Return if reference could
452 	 * not be taken. Reference will be released once scan
453 	 * request handling completes along with free of @req.
454 	 */
455 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
456 	if (QDF_IS_STATUS_ERROR(status)) {
457 		scm_info("unable to get reference");
458 		scm_scan_free_scan_request_mem(req);
459 		return status;
460 	}
461 
462 	msg.bodyptr = req;
463 	msg.callback = scm_scan_start_req;
464 	msg.flush_callback = scm_scan_start_flush_callback;
465 
466 	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
467 					QDF_MODULE_ID_SCAN,
468 					QDF_MODULE_ID_OS_IF, &msg);
469 	if (QDF_IS_STATUS_ERROR(status)) {
470 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
471 		scm_scan_free_scan_request_mem(req);
472 	}
473 
474 	return status;
475 }
476 
477 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
478 				     enum scan_disable_reason reason)
479 {
480 	struct wlan_scan_obj *scan_obj;
481 
482 	scan_obj = wlan_psoc_get_scan_obj(psoc);
483 	if (!scan_obj) {
484 		scm_err("Failed to get scan object");
485 		return QDF_STATUS_E_NULL_VALUE;
486 	}
487 
488 	scan_obj->scan_disabled &= ~reason;
489 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
490 
491 	return QDF_STATUS_SUCCESS;
492 }
493 
494 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
495 				      enum scan_disable_reason reason)
496 {
497 	struct wlan_scan_obj *scan_obj;
498 
499 	scan_obj = wlan_psoc_get_scan_obj(psoc);
500 	if (!scan_obj) {
501 		scm_err("Failed to get scan object");
502 		return QDF_STATUS_E_NULL_VALUE;
503 	}
504 
505 	scan_obj->scan_disabled |= reason;
506 
507 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
508 
509 	return QDF_STATUS_SUCCESS;
510 }
511 
512 
513 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
514 				     enum scan_disable_reason reason)
515 {
516 	struct scan_vdev_obj *scan_vdev_obj;
517 
518 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
519 	if (!scan_vdev_obj) {
520 		scm_err("null scan_vdev_obj");
521 		return QDF_STATUS_E_NULL_VALUE;
522 	}
523 
524 	scan_vdev_obj->scan_disabled &= ~reason;
525 
526 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
527 
528 	return QDF_STATUS_SUCCESS;
529 }
530 
531 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
532 				      enum scan_disable_reason reason)
533 {
534 	struct scan_vdev_obj *scan_vdev_obj;
535 
536 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
537 	if (!scan_vdev_obj) {
538 		scm_err("null scan_vdev_obj");
539 		return QDF_STATUS_E_NULL_VALUE;
540 	}
541 
542 	scan_vdev_obj->scan_disabled |= reason;
543 
544 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
545 
546 	return QDF_STATUS_SUCCESS;
547 }
548 
549 
550 QDF_STATUS ucfg_scan_set_miracast(
551 	struct wlan_objmgr_psoc *psoc, bool enable)
552 {
553 	struct wlan_scan_obj *scan_obj;
554 
555 	scan_obj = wlan_psoc_get_scan_obj(psoc);
556 	if (!scan_obj) {
557 		scm_err("Failed to get scan object");
558 		return QDF_STATUS_E_NULL_VALUE;
559 	}
560 	scan_obj->miracast_enabled = enable;
561 	scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled);
562 
563 	return QDF_STATUS_SUCCESS;
564 }
565 
566 QDF_STATUS
567 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable)
568 {
569 	uint8_t pdev_id;
570 	struct wlan_scan_obj *scan_obj;
571 
572 	if (!pdev) {
573 		scm_warn("null vdev");
574 		return QDF_STATUS_E_NULL_VALUE;
575 	}
576 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
577 	scan_obj = wlan_pdev_get_scan_obj(pdev);
578 	if (!scan_obj)
579 		return QDF_STATUS_E_FAILURE;
580 
581 	scm_debug("set wide_band_scan to %d", enable);
582 	scan_obj->pdev_info[pdev_id].wide_band_scan = enable;
583 
584 	return QDF_STATUS_SUCCESS;
585 }
586 
587 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev)
588 {
589 	uint8_t pdev_id;
590 	struct wlan_scan_obj *scan_obj;
591 
592 	if (!pdev) {
593 		scm_warn("null vdev");
594 		return QDF_STATUS_E_NULL_VALUE;
595 	}
596 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
597 	scan_obj = wlan_pdev_get_scan_obj(pdev);
598 	if (!scan_obj)
599 		return QDF_STATUS_E_FAILURE;
600 
601 	return scan_obj->pdev_info[pdev_id].wide_band_scan;
602 }
603 
604 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID
605 QDF_STATUS
606 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev,
607 				       uint8_t *bssid, struct wlan_ssid *ssid)
608 {
609 	uint8_t pdev_id;
610 	struct wlan_scan_obj *scan_obj;
611 
612 	if (!pdev) {
613 		scm_warn("null vdev");
614 		return QDF_STATUS_E_NULL_VALUE;
615 	}
616 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
617 	scan_obj = wlan_pdev_get_scan_obj(pdev);
618 	if (!scan_obj)
619 		return QDF_STATUS_E_FAILURE;
620 
621 	scm_debug("Configure bsssid:%pM ssid:%.*s",
622 		  bssid, ssid->length, ssid->ssid);
623 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid,
624 		     bssid, QDF_MAC_ADDR_SIZE);
625 	scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length;
626 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid,
627 		     ssid->ssid,
628 		     scan_obj->pdev_info[pdev_id].conf_ssid.length);
629 
630 	return QDF_STATUS_SUCCESS;
631 }
632 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */
633 
634 QDF_STATUS
635 ucfg_scan_cancel(struct scan_cancel_request *req)
636 {
637 	struct scheduler_msg msg = {0};
638 	QDF_STATUS status;
639 
640 	if (!req || !req->vdev) {
641 		scm_err("req or vdev within req is NULL");
642 		if (req)
643 			qdf_mem_free(req);
644 		return QDF_STATUS_E_NULL_VALUE;
645 	}
646 
647 	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
648 	if (QDF_IS_STATUS_ERROR(status)) {
649 		scm_info("Failed to get vdev ref; status:%d", status);
650 		goto req_free;
651 	}
652 
653 	msg.bodyptr = req;
654 	msg.callback = scm_scan_cancel_req;
655 	msg.flush_callback = scm_scan_cancel_flush_callback;
656 
657 	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
658 					QDF_MODULE_ID_SCAN,
659 					QDF_MODULE_ID_OS_IF, &msg);
660 	if (QDF_IS_STATUS_ERROR(status))
661 		goto vdev_put;
662 
663 	return QDF_STATUS_SUCCESS;
664 
665 vdev_put:
666 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
667 
668 req_free:
669 	qdf_mem_free(req);
670 
671 	return status;
672 }
673 
674 QDF_STATUS
675 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
676 {
677 	QDF_STATUS status;
678 	bool cancel_vdev = false, cancel_pdev = false;
679 	struct wlan_objmgr_vdev *vdev;
680 	struct wlan_objmgr_pdev *pdev;
681 	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
682 
683 	if (!req || !req->vdev) {
684 		scm_err("req or vdev within req is NULL");
685 		if (req)
686 			qdf_mem_free(req);
687 		return QDF_STATUS_E_NULL_VALUE;
688 	}
689 
690 	if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL)
691 		cancel_pdev = true;
692 	else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL ||
693 		 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL)
694 		cancel_vdev = true;
695 
696 	vdev = req->vdev;
697 	status = ucfg_scan_cancel(req);
698 	if (QDF_IS_STATUS_ERROR(status))
699 		return status;
700 
701 	if (cancel_pdev) {
702 		pdev = wlan_vdev_get_pdev(vdev);
703 		while ((ucfg_scan_get_pdev_status(pdev) !=
704 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
705 			scm_debug("wait for all pdev scan to get complete");
706 			qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
707 			max_wait_iterations--;
708 		}
709 	} else if (cancel_vdev) {
710 		while ((ucfg_scan_get_vdev_status(vdev) !=
711 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
712 			scm_debug("wait for all vdev scan to get complete");
713 			qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
714 			max_wait_iterations--;
715 		}
716 	}
717 
718 	if (!max_wait_iterations) {
719 		scm_err("Failed to wait for scans to get complete");
720 		return QDF_STATUS_E_TIMEOUT;
721 	}
722 
723 	return status;
724 }
725 
726 wlan_scan_requester
727 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc,
728 	uint8_t *name, scan_event_handler event_cb, void *arg)
729 {
730 	int i, j;
731 	struct wlan_scan_obj *scan;
732 	struct scan_requester_info *requesters;
733 	wlan_scan_requester requester = {0};
734 
735 	if (!psoc) {
736 		scm_err("null psoc");
737 		return 0;
738 	}
739 	scan = wlan_psoc_get_scan_obj(psoc);
740 	if (!scan)
741 		return 0;
742 
743 	requesters = scan->requesters;
744 	qdf_spin_lock_bh(&scan->lock);
745 	for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) {
746 		if (requesters[i].requester == 0) {
747 			requesters[i].requester =
748 				WLAN_SCAN_REQUESTER_ID_PREFIX | i;
749 			j = 0;
750 			while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) {
751 				requesters[i].module[j] = name[j];
752 				++j;
753 			}
754 			requesters[i].module[j] = 0;
755 			requesters[i].ev_handler.func = event_cb;
756 			requesters[i].ev_handler.arg = arg;
757 			requester = requesters[i].requester;
758 			break;
759 		}
760 	}
761 	qdf_spin_unlock_bh(&scan->lock);
762 	scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d",
763 		  name, event_cb, arg, requester);
764 
765 	return requester;
766 }
767 
768 void
769 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
770 	wlan_scan_requester requester)
771 {
772 	int idx;
773 	struct wlan_scan_obj *scan;
774 	struct scan_requester_info *requesters;
775 
776 	idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX;
777 	if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) {
778 		scm_err("prefix didn't match for requester id %d", requester);
779 		return;
780 	}
781 
782 	idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
783 	if (idx >= WLAN_MAX_REQUESTORS) {
784 		scm_err("requester id %d greater than max value", requester);
785 		return;
786 	}
787 
788 	if (!psoc) {
789 		scm_err("null psoc");
790 		return;
791 	}
792 	scan = wlan_psoc_get_scan_obj(psoc);
793 	if (!scan)
794 		return;
795 	requesters = scan->requesters;
796 	scm_debug("reqid: %d", requester);
797 
798 	qdf_spin_lock_bh(&scan->lock);
799 	requesters[idx].requester = 0;
800 	requesters[idx].module[0] = 0;
801 	requesters[idx].ev_handler.func = NULL;
802 	requesters[idx].ev_handler.arg = NULL;
803 	qdf_spin_unlock_bh(&scan->lock);
804 }
805 
806 uint8_t*
807 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
808 	wlan_scan_requester requester)
809 {
810 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
811 	struct wlan_scan_obj *scan;
812 	struct scan_requester_info *requesters;
813 
814 	if (!psoc) {
815 		scm_err("null psoc");
816 		return "null";
817 	}
818 	scan = wlan_psoc_get_scan_obj(psoc);
819 	if (!scan)
820 		return "null";
821 
822 	requesters = scan->requesters;
823 
824 	if ((idx < WLAN_MAX_REQUESTORS) &&
825 		(requesters[idx].requester == requester)) {
826 		return requesters[idx].module;
827 	}
828 
829 	return (uint8_t *)"unknown";
830 }
831 
832 wlan_scan_id
833 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
834 {
835 	wlan_scan_id id;
836 	struct wlan_scan_obj *scan;
837 
838 	if (!psoc) {
839 		QDF_ASSERT(0);
840 		scm_err("null psoc");
841 		return 0;
842 	}
843 
844 	scan = wlan_psoc_get_scan_obj(psoc);
845 	if (!scan) {
846 		scm_err("scan object null");
847 		return 0;
848 	}
849 
850 	id = qdf_atomic_inc_return(&scan->scan_ids);
851 	id =  id & WLAN_SCAN_ID_MASK;
852 	/* Mark this scan request as triggered by host
853 	 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag.
854 	 */
855 	id =  id | WLAN_HOST_SCAN_REQ_ID_PREFIX;
856 	scm_debug("scan_id: 0x%x", id);
857 
858 	return id;
859 }
860 
861 static QDF_STATUS
862 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
863 	scan_event_handler event_cb, void *arg)
864 {
865 	struct cb_handler *cb_handler;
866 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
867 
868 	/* Assign next available slot to this registration request */
869 	cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
870 	cb_handler->func = event_cb;
871 	cb_handler->arg = arg;
872 	pdev_ev_handler->handler_cnt++;
873 
874 	return QDF_STATUS_SUCCESS;
875 }
876 
877 QDF_STATUS
878 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
879 	scan_event_handler event_cb, void *arg)
880 {
881 	uint32_t idx;
882 	struct wlan_scan_obj *scan;
883 	struct pdev_scan_ev_handler *pdev_ev_handler;
884 	struct cb_handler *cb_handler;
885 
886 	/* scan event handler call back can't be NULL */
887 	if (!pdev || !event_cb) {
888 		scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
889 		return QDF_STATUS_E_NULL_VALUE;
890 	}
891 
892 	scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
893 
894 	scan = wlan_pdev_get_scan_obj(pdev);
895 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
896 	if (!pdev_ev_handler) {
897 		scm_err("null pdev_ev_handler");
898 		return QDF_STATUS_E_NULL_VALUE;
899 	}
900 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
901 
902 	qdf_spin_lock_bh(&scan->lock);
903 	/* Ensure its not a duplicate registration request */
904 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
905 		idx++, cb_handler++) {
906 		if ((cb_handler->func == event_cb) &&
907 			(cb_handler->arg == arg)) {
908 			qdf_spin_unlock_bh(&scan->lock);
909 			scm_debug("func: %pK, arg: %pK already exists",
910 				  event_cb, arg);
911 			return QDF_STATUS_SUCCESS;
912 		}
913 	}
914 
915 	QDF_ASSERT(pdev_ev_handler->handler_cnt <
916 			MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
917 
918 	if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
919 		qdf_spin_unlock_bh(&scan->lock);
920 		scm_warn("No more registrations possible");
921 		return QDF_STATUS_E_NOMEM;
922 	}
923 
924 	scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
925 	qdf_spin_unlock_bh(&scan->lock);
926 
927 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
928 
929 	return QDF_STATUS_SUCCESS;
930 }
931 
932 static QDF_STATUS
933 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
934 		      struct wlan_scan_obj *scan_obj)
935 {
936 	scan_obj->scan_disabled = 0;
937 	scan_obj->drop_bcn_on_chan_mismatch =
938 			 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH);
939 	scan_obj->drop_bcn_on_invalid_freq =
940 			 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ);
941 	scan_obj->disable_timeout = false;
942 	scan_obj->scan_def.active_dwell =
943 			 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
944 	/* the ini is disallow DFS channel scan if ini is 1, so negate that */
945 	scan_obj->scan_def.allow_dfs_chan_in_first_scan =
946 				!cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
947 	scan_obj->scan_def.allow_dfs_chan_in_scan =
948 				cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
949 	scan_obj->scan_def.skip_dfs_chan_in_p2p_search =
950 				cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH);
951 	scan_obj->scan_def.use_wake_lock_in_user_scan =
952 				cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN);
953 	scan_obj->scan_def.active_dwell_2g =
954 			 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
955 	scan_obj->scan_def.active_dwell_6g =
956 			 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME);
957 	scan_obj->scan_def.passive_dwell_6g =
958 			 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME);
959 	scan_obj->scan_def.passive_dwell =
960 			 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME);
961 	scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
962 	scan_obj->scan_def.sta_miracast_mcc_rest_time =
963 					SCAN_STA_MIRACAST_MCC_REST_TIME;
964 	scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
965 	scan_obj->scan_def.conc_active_dwell =
966 			cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC);
967 	scan_obj->scan_def.conc_passive_dwell =
968 			cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC);
969 	scan_obj->scan_def.conc_max_rest_time =
970 			cfg_get(psoc, CFG_MAX_REST_TIME_CONC);
971 	scan_obj->scan_def.conc_min_rest_time =
972 			cfg_get(psoc, CFG_MIN_REST_TIME_CONC);
973 	scan_obj->scan_def.conc_idle_time =
974 			cfg_get(psoc, CFG_IDLE_TIME_CONC);
975 	scan_obj->scan_def.repeat_probe_time =
976 			cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME);
977 	scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
978 	scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
979 	scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
980 	scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
981 	scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES);
982 	scan_obj->scan_def.scan_cache_aging_time =
983 			(cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000);
984 	scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
985 	scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
986 	scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
987 	scan_obj->scan_def.adaptive_dwell_time_mode =
988 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE);
989 	scan_obj->scan_def.adaptive_dwell_time_mode_nc =
990 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC);
991 	scan_obj->scan_def.honour_nl_scan_policy_flags =
992 			cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS);
993 	scan_obj->scan_def.enable_mac_spoofing =
994 			cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING);
995 	scan_obj->scan_def.extscan_adaptive_dwell_mode =
996 			cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
997 
998 	/* init burst durations */
999 	scan_obj->scan_def.sta_scan_burst_duration =
1000 				cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION);
1001 	scan_obj->scan_def.p2p_scan_burst_duration =
1002 				cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION);
1003 	scan_obj->scan_def.go_scan_burst_duration =
1004 				cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION);
1005 	scan_obj->scan_def.ap_scan_burst_duration =
1006 				cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION);
1007 	/* scan contrl flags */
1008 	scan_obj->scan_def.scan_f_passive = true;
1009 	scan_obj->scan_def.scan_f_ofdm_rates = true;
1010 	scan_obj->scan_def.scan_f_2ghz = true;
1011 	scan_obj->scan_def.scan_f_5ghz = true;
1012 	scan_obj->scan_def.scan_f_chan_stat_evnt =
1013 				cfg_get(psoc, CFG_ENABLE_SNR_MONITORING);
1014 	/* scan event flags */
1015 	scan_obj->scan_def.scan_ev_started = true;
1016 	scan_obj->scan_def.scan_ev_completed = true;
1017 	scan_obj->scan_def.scan_ev_bss_chan = true;
1018 	scan_obj->scan_def.scan_ev_foreign_chan = true;
1019 	scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
1020 	scan_obj->scan_def.scan_ev_dequeued = true;
1021 	scan_obj->scan_def.scan_ev_preempted = true;
1022 	scan_obj->scan_def.scan_ev_start_failed = true;
1023 	scan_obj->scan_def.scan_ev_restarted = true;
1024 	scan_obj->scan_def.enable_connected_scan =
1025 		cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN);
1026 	scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE);
1027 	/* init scan id seed */
1028 	qdf_atomic_init(&scan_obj->scan_ids);
1029 
1030 	/* init extscan */
1031 	wlan_extscan_global_init(psoc, scan_obj);
1032 
1033 	return wlan_pno_global_init(psoc, scan_obj);
1034 }
1035 
1036 static void
1037 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc)
1038 {
1039 	struct wlan_scan_obj *scan_obj;
1040 
1041 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1042 	wlan_pno_global_deinit(scan_obj);
1043 	wlan_extscan_global_deinit();
1044 }
1045 
1046 static QDF_STATUS
1047 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
1048 	struct cb_handler *entry)
1049 {
1050 	struct cb_handler *last_entry;
1051 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
1052 
1053 	/* Replace event handler being deleted
1054 	 * with the last one in the list.
1055 	 */
1056 	last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
1057 	entry->func = last_entry->func;
1058 	entry->arg = last_entry->arg;
1059 
1060 	/* Clear our last entry */
1061 	last_entry->func = NULL;
1062 	last_entry->arg = NULL;
1063 	pdev_ev_handler->handler_cnt--;
1064 
1065 	return QDF_STATUS_SUCCESS;
1066 }
1067 
1068 void
1069 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
1070 	scan_event_handler event_cb, void *arg)
1071 {
1072 	uint8_t found = false;
1073 	uint32_t idx;
1074 	uint32_t handler_cnt;
1075 	struct wlan_scan_obj *scan;
1076 	struct cb_handler *cb_handler;
1077 	struct pdev_scan_ev_handler *pdev_ev_handler;
1078 
1079 	scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb,
1080 		  arg);
1081 	if (!pdev) {
1082 		scm_err("null pdev");
1083 		return;
1084 	}
1085 	scan = wlan_pdev_get_scan_obj(pdev);
1086 	if (!scan)
1087 		return;
1088 
1089 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
1090 	if (!pdev_ev_handler)
1091 		return;
1092 
1093 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
1094 
1095 	qdf_spin_lock_bh(&scan->lock);
1096 	handler_cnt = pdev_ev_handler->handler_cnt;
1097 	if (!handler_cnt) {
1098 		qdf_spin_unlock_bh(&scan->lock);
1099 		scm_info("No event handlers registered");
1100 		return;
1101 	}
1102 
1103 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
1104 		idx++, cb_handler++) {
1105 		if ((cb_handler->func == event_cb) &&
1106 			(cb_handler->arg == arg)) {
1107 			/* Event handler found, remove it
1108 			 * from event handler list.
1109 			 */
1110 			found = true;
1111 			scm_remove_scan_event_handler(pdev_ev_handler,
1112 				cb_handler);
1113 			handler_cnt--;
1114 			break;
1115 		}
1116 	}
1117 	qdf_spin_unlock_bh(&scan->lock);
1118 
1119 	scm_debug("event handler %s, remaining handlers: %d",
1120 		  (found ? "removed" : "not found"), handler_cnt);
1121 }
1122 
1123 QDF_STATUS
1124 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
1125 	struct scan_start_request *req)
1126 {
1127 	struct scan_default_params *def;
1128 
1129 	if (!vdev | !req) {
1130 		scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req);
1131 		return QDF_STATUS_E_INVAL;
1132 	}
1133 	def = wlan_vdev_get_def_scan_params(vdev);
1134 	if (!def) {
1135 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
1136 		return QDF_STATUS_E_NULL_VALUE;
1137 	}
1138 
1139 	/* Zero out everything and explicitly set fields as required */
1140 	qdf_mem_zero(req, sizeof(*req));
1141 
1142 	req->vdev = vdev;
1143 	req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
1144 	req->scan_req.scan_type = SCAN_TYPE_DEFAULT;
1145 	req->scan_req.scan_priority = def->scan_priority;
1146 	req->scan_req.dwell_time_active = def->active_dwell;
1147 	req->scan_req.dwell_time_active_2g = def->active_dwell_2g;
1148 	req->scan_req.dwell_time_active_6g = def->active_dwell_6g;
1149 	req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g;
1150 	req->scan_req.dwell_time_passive = def->passive_dwell;
1151 	req->scan_req.min_rest_time = def->min_rest_time;
1152 	req->scan_req.max_rest_time = def->max_rest_time;
1153 	req->scan_req.repeat_probe_time = def->repeat_probe_time;
1154 	req->scan_req.probe_spacing_time = def->probe_spacing_time;
1155 	req->scan_req.idle_time = def->idle_time;
1156 	req->scan_req.max_scan_time = def->max_scan_time;
1157 	req->scan_req.probe_delay = def->probe_delay;
1158 	req->scan_req.burst_duration = def->burst_duration;
1159 	req->scan_req.n_probes = def->num_probes;
1160 	req->scan_req.adaptive_dwell_time_mode =
1161 		def->adaptive_dwell_time_mode;
1162 	req->scan_req.scan_flags = def->scan_flags;
1163 	req->scan_req.scan_events = def->scan_events;
1164 	req->scan_req.scan_random.randomize = def->enable_mac_spoofing;
1165 
1166 	return QDF_STATUS_SUCCESS;
1167 }
1168 
1169 QDF_STATUS
1170 ucfg_scan_init_ssid_params(struct scan_start_request *req,
1171 		uint32_t num_ssid, struct wlan_ssid *ssid_list)
1172 {
1173 	uint32_t max_ssid = sizeof(req->scan_req.ssid) /
1174 				sizeof(req->scan_req.ssid[0]);
1175 
1176 	if (!req) {
1177 		scm_err("null request");
1178 		return QDF_STATUS_E_NULL_VALUE;
1179 	}
1180 	if (!num_ssid) {
1181 		/* empty channel list provided */
1182 		req->scan_req.num_ssids = 0;
1183 		qdf_mem_zero(&req->scan_req.ssid[0],
1184 			sizeof(req->scan_req.ssid));
1185 		return QDF_STATUS_SUCCESS;
1186 	}
1187 	if (!ssid_list) {
1188 		scm_err("null ssid_list while num_ssid: %d", num_ssid);
1189 		return QDF_STATUS_E_NULL_VALUE;
1190 	}
1191 	if (num_ssid > max_ssid) {
1192 		/* got a big list. alert and continue */
1193 		scm_warn("overflow: received %d, max supported : %d",
1194 			num_ssid, max_ssid);
1195 		return QDF_STATUS_E_E2BIG;
1196 	}
1197 
1198 	if (max_ssid > num_ssid)
1199 		max_ssid = num_ssid;
1200 
1201 	req->scan_req.num_ssids = max_ssid;
1202 	qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
1203 		(req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
1204 
1205 	return QDF_STATUS_SUCCESS;
1206 }
1207 
1208 QDF_STATUS
1209 ucfg_scan_init_bssid_params(struct scan_start_request *req,
1210 		uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
1211 {
1212 	uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
1213 				sizeof(req->scan_req.bssid_list[0]);
1214 
1215 	if (!req) {
1216 		scm_err("null request");
1217 		return QDF_STATUS_E_NULL_VALUE;
1218 	}
1219 	if (!num_bssid) {
1220 		/* empty channel list provided */
1221 		req->scan_req.num_bssid = 0;
1222 		qdf_mem_zero(&req->scan_req.bssid_list[0],
1223 			sizeof(req->scan_req.bssid_list));
1224 		return QDF_STATUS_SUCCESS;
1225 	}
1226 	if (!bssid_list) {
1227 		scm_err("null bssid_list while num_bssid: %d", num_bssid);
1228 		return QDF_STATUS_E_NULL_VALUE;
1229 	}
1230 	if (num_bssid > max_bssid) {
1231 		/* got a big list. alert and continue */
1232 		scm_warn("overflow: received %d, max supported : %d",
1233 			num_bssid, max_bssid);
1234 		return QDF_STATUS_E_E2BIG;
1235 	}
1236 
1237 	if (max_bssid > num_bssid)
1238 		max_bssid = num_bssid;
1239 
1240 	req->scan_req.num_bssid = max_bssid;
1241 	qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
1242 		req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
1243 
1244 	return QDF_STATUS_SUCCESS;
1245 }
1246 
1247 /**
1248  * is_chan_enabled_for_scan() - helper API to check if a frequency
1249  * is allowed to scan.
1250  * @reg_chan: regulatory_channel object
1251  * @low_2g: lower 2.4 GHz frequency thresold
1252  * @high_2g: upper 2.4 GHz frequency thresold
1253  * @low_5g: lower 5 GHz frequency thresold
1254  * @high_5g: upper 5 GHz frequency thresold
1255  *
1256  * Return: true if scan is allowed. false otherwise.
1257  */
1258 static bool
1259 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan,
1260 		qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g,
1261 		qdf_freq_t high_5g)
1262 {
1263 	if (reg_chan->state == CHANNEL_STATE_DISABLE)
1264 		return false;
1265 	if (reg_chan->nol_chan)
1266 		return false;
1267 	/* 2 GHz channel */
1268 	if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1269 			WLAN_BAND_2_4_GHZ) &&
1270 			((reg_chan->center_freq < low_2g) ||
1271 			(reg_chan->center_freq > high_2g)))
1272 		return false;
1273 	else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1274 				WLAN_BAND_5_GHZ) &&
1275 		 ((reg_chan->center_freq < low_5g) ||
1276 		  (reg_chan->center_freq > high_5g)))
1277 		return false;
1278 
1279 	return true;
1280 }
1281 
1282 QDF_STATUS
1283 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1284 		uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1285 {
1286 	uint32_t idx;
1287 	QDF_STATUS status;
1288 	struct regulatory_channel *reg_chan_list = NULL;
1289 	qdf_freq_t low_2g, high_2g, low_5g, high_5g;
1290 	struct wlan_objmgr_pdev *pdev = NULL;
1291 	uint32_t *scan_freqs = NULL;
1292 	uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1293 				sizeof(req->scan_req.chan_list.chan[0]);
1294 	if (!req) {
1295 		scm_err("null request");
1296 		return QDF_STATUS_E_NULL_VALUE;
1297 	}
1298 
1299 	if (req->vdev)
1300 		pdev = wlan_vdev_get_pdev(req->vdev);
1301 	/*
1302 	 * If 0 channels are provided for scan and
1303 	 * wide band scan is enabled, scan all 20 mhz
1304 	 * available channels. This is required as FW
1305 	 * scans all channel/phy mode combinations
1306 	 * provided in scan channel list if 0 chans are
1307 	 * provided in scan request causing scan to take
1308 	 * too much time to complete.
1309 	 */
1310 	if (pdev && !num_chans) {
1311 		reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1312 				sizeof(struct regulatory_channel));
1313 		if (!reg_chan_list) {
1314 			status = QDF_STATUS_E_NOMEM;
1315 			goto end;
1316 		}
1317 		scan_freqs =
1318 			qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1319 		if (!scan_freqs) {
1320 			status = QDF_STATUS_E_NOMEM;
1321 			goto end;
1322 		}
1323 		status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list);
1324 		if (QDF_IS_STATUS_ERROR(status))
1325 			goto end;
1326 
1327 		status = wlan_reg_get_freq_range(pdev, &low_2g,
1328 				&high_2g, &low_5g, &high_5g);
1329 		if (QDF_IS_STATUS_ERROR(status))
1330 			goto end;
1331 
1332 		for (idx = 0, num_chans = 0;
1333 			(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1334 			if (is_chan_enabled_for_scan(&reg_chan_list[idx],
1335 					low_2g, high_2g, low_5g, high_5g))
1336 				scan_freqs[num_chans++] =
1337 				reg_chan_list[idx].center_freq;
1338 
1339 		chan_list = scan_freqs;
1340 	}
1341 
1342 	if (!num_chans) {
1343 		/* empty channel list provided */
1344 		qdf_mem_zero(&req->scan_req.chan_list,
1345 			sizeof(req->scan_req.chan_list));
1346 		req->scan_req.chan_list.num_chan = 0;
1347 		status = QDF_STATUS_SUCCESS;
1348 		goto end;
1349 	}
1350 	if (!chan_list) {
1351 		scm_info("null chan_list while num_chans: %d", num_chans);
1352 		status = QDF_STATUS_E_NULL_VALUE;
1353 		goto end;
1354 	}
1355 
1356 	if (num_chans > max_chans) {
1357 		/* got a big list. alert and fail */
1358 		scm_warn("overflow: received %d, max supported : %d",
1359 			num_chans, max_chans);
1360 		status = QDF_STATUS_E_E2BIG;
1361 		goto end;
1362 	}
1363 
1364 	req->scan_req.chan_list.num_chan = num_chans;
1365 	for (idx = 0; idx < num_chans; idx++) {
1366 		req->scan_req.chan_list.chan[idx].freq =
1367 			(chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1368 			chan_list[idx] :
1369 			wlan_reg_legacy_chan_to_freq(pdev, chan_list[idx]);
1370 		if (phymode)
1371 			req->scan_req.chan_list.chan[idx].phymode =
1372 				phymode[idx];
1373 		else if (req->scan_req.chan_list.chan[idx].freq <=
1374 			WLAN_CHAN_15_FREQ)
1375 			req->scan_req.chan_list.chan[idx].phymode =
1376 				SCAN_PHY_MODE_11G;
1377 		else
1378 			req->scan_req.chan_list.chan[idx].phymode =
1379 				SCAN_PHY_MODE_11A;
1380 	}
1381 
1382 end:
1383 	if (scan_freqs)
1384 		qdf_mem_free(scan_freqs);
1385 
1386 	if (reg_chan_list)
1387 		qdf_mem_free(reg_chan_list);
1388 
1389 	return QDF_STATUS_SUCCESS;
1390 }
1391 
1392 static inline enum scm_scan_status
1393 get_scan_status_from_serialization_status(
1394 	enum wlan_serialization_cmd_status status)
1395 {
1396 	enum scm_scan_status scan_status;
1397 
1398 	switch (status) {
1399 	case WLAN_SER_CMD_IN_PENDING_LIST:
1400 		scan_status = SCAN_IS_PENDING;
1401 		break;
1402 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1403 		scan_status = SCAN_IS_ACTIVE;
1404 		break;
1405 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1406 		scan_status = SCAN_IS_ACTIVE_AND_PENDING;
1407 		break;
1408 	case WLAN_SER_CMD_NOT_FOUND:
1409 		scan_status = SCAN_NOT_IN_PROGRESS;
1410 		break;
1411 	default:
1412 		scm_warn("invalid serialization status %d", status);
1413 		QDF_ASSERT(0);
1414 		scan_status = SCAN_NOT_IN_PROGRESS;
1415 		break;
1416 	}
1417 
1418 	return scan_status;
1419 }
1420 
1421 enum scm_scan_status
1422 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1423 {
1424 	enum wlan_serialization_cmd_status status;
1425 
1426 	if (!vdev) {
1427 		scm_err("null vdev");
1428 		return SCAN_NOT_IN_PROGRESS;
1429 	}
1430 	status = wlan_serialization_vdev_scan_status(vdev);
1431 
1432 	return get_scan_status_from_serialization_status(status);
1433 }
1434 
1435 enum scm_scan_status
1436 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1437 {
1438 	enum wlan_serialization_cmd_status status;
1439 
1440 	if (!pdev) {
1441 		scm_err("null pdev");
1442 		return SCAN_NOT_IN_PROGRESS;
1443 	}
1444 	status = wlan_serialization_pdev_scan_status(pdev);
1445 
1446 	return get_scan_status_from_serialization_status(status);
1447 }
1448 
1449 static void
1450 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1451 	bool enable)
1452 {
1453 	QDF_STATUS status;
1454 	struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1455 
1456 	cb_info[0].frm_type = MGMT_PROBE_RESP;
1457 	cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1458 	cb_info[1].frm_type = MGMT_BEACON;
1459 	cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1460 
1461 	if (enable)
1462 		status = wlan_mgmt_txrx_register_rx_cb(psoc,
1463 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1464 	else
1465 		status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1466 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1467 	if (status != QDF_STATUS_SUCCESS)
1468 		scm_err("%s the Handle with MGMT TXRX layer has failed",
1469 			enable ? "Registering" : "Deregistering");
1470 }
1471 
1472 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1473 	struct scan_user_cfg *scan_cfg)
1474 {
1475 	struct wlan_scan_obj *scan_obj;
1476 	struct scan_default_params *scan_def;
1477 
1478 	if (!psoc) {
1479 		scm_err("null psoc");
1480 		return QDF_STATUS_E_FAILURE;
1481 	}
1482 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1483 	if (!scan_obj) {
1484 		scm_err("Failed to get scan object");
1485 		return QDF_STATUS_E_FAILURE;
1486 	}
1487 
1488 	scan_def = &scan_obj->scan_def;
1489 	scan_obj->ie_whitelist = scan_cfg->ie_whitelist;
1490 	scan_def->sta_miracast_mcc_rest_time =
1491 				scan_cfg->sta_miracast_mcc_rest_time;
1492 
1493 	return QDF_STATUS_SUCCESS;
1494 }
1495 
1496 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1497 static QDF_STATUS
1498 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
1499 {
1500 	struct scan_cancel_request *req;
1501 	QDF_STATUS status;
1502 	struct wlan_objmgr_vdev *vdev;
1503 
1504 	req = qdf_mem_malloc_atomic(sizeof(*req));
1505 	if (!req) {
1506 		scm_err("Failed to allocate memory");
1507 		return QDF_STATUS_E_NOMEM;
1508 	}
1509 
1510 	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID);
1511 	if (!vdev) {
1512 		scm_err("Failed to get vdev");
1513 		qdf_mem_free(req);
1514 		return QDF_STATUS_E_INVAL;
1515 	}
1516 	req->vdev = vdev;
1517 	req->cancel_req.scan_id = INVAL_SCAN_ID;
1518 	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1519 	req->cancel_req.vdev_id = INVAL_VDEV_ID;
1520 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1521 	status = ucfg_scan_cancel_sync(req);
1522 	if (QDF_IS_STATUS_ERROR(status))
1523 		scm_err("Cancel scan request failed");
1524 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1525 
1526 	return status;
1527 }
1528 
1529 static QDF_STATUS
1530 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1531 {
1532 	struct wlan_objmgr_pdev *pdev = NULL;
1533 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1534 	int i;
1535 
1536 	ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND);
1537 	/* Check all pdev */
1538 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
1539 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
1540 		if (!pdev)
1541 			continue;
1542 		if (ucfg_scan_get_pdev_status(pdev) !=
1543 		    SCAN_NOT_IN_PROGRESS)
1544 			status = ucfg_scan_cancel_pdev_scan(pdev);
1545 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
1546 		if (QDF_IS_STATUS_ERROR(status)) {
1547 			scm_err("failed to cancel scan for pdev_id %d", i);
1548 			return status;
1549 		}
1550 	}
1551 
1552 	return QDF_STATUS_SUCCESS;
1553 }
1554 
1555 static QDF_STATUS
1556 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1557 {
1558 	ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND);
1559 	return QDF_STATUS_SUCCESS;
1560 }
1561 
1562 static inline void
1563 ucfg_scan_register_pmo_handler(void)
1564 {
1565 	pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
1566 		ucfg_scan_suspend_handler, NULL);
1567 	pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
1568 		ucfg_scan_resume_handler, NULL);
1569 }
1570 
1571 static inline void
1572 ucfg_scan_unregister_pmo_handler(void)
1573 {
1574 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
1575 		ucfg_scan_suspend_handler);
1576 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
1577 		ucfg_scan_resume_handler);
1578 }
1579 
1580 #else
1581 static inline void
1582 ucfg_scan_register_pmo_handler(void)
1583 {
1584 }
1585 
1586 static inline void
1587 ucfg_scan_unregister_pmo_handler(void)
1588 {
1589 }
1590 #endif
1591 
1592 QDF_STATUS
1593 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
1594 {
1595 	struct wlan_scan_obj *scan_obj;
1596 
1597 	scm_debug("psoc open: 0x%pK", psoc);
1598 	if (!psoc) {
1599 		scm_err("null psoc");
1600 		return QDF_STATUS_E_FAILURE;
1601 	}
1602 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1603 	if (!scan_obj) {
1604 		scm_err("Failed to get scan object");
1605 		return QDF_STATUS_E_FAILURE;
1606 	}
1607 	/* Initialize the scan Globals */
1608 	wlan_scan_global_init(psoc, scan_obj);
1609 	qdf_spinlock_create(&scan_obj->lock);
1610 	ucfg_scan_register_pmo_handler();
1611 	scm_db_init(psoc);
1612 	scm_channel_list_db_init(psoc);
1613 
1614 	return QDF_STATUS_SUCCESS;
1615 }
1616 
1617 QDF_STATUS
1618 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
1619 {
1620 	struct wlan_scan_obj *scan_obj;
1621 
1622 	scm_debug("psoc close: 0x%pK", psoc);
1623 	if (!psoc) {
1624 		scm_err("null psoc");
1625 		return QDF_STATUS_E_FAILURE;
1626 	}
1627 	scm_db_deinit(psoc);
1628 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1629 	if (!scan_obj) {
1630 		scm_err("Failed to get scan object");
1631 		return QDF_STATUS_E_FAILURE;
1632 	}
1633 	ucfg_scan_unregister_pmo_handler();
1634 	qdf_spinlock_destroy(&scan_obj->lock);
1635 	wlan_scan_global_deinit(psoc);
1636 	scm_channel_list_db_deinit(psoc);
1637 
1638 	return QDF_STATUS_SUCCESS;
1639 }
1640 
1641 static bool scm_serialization_scan_rules_cb(
1642 		union wlan_serialization_rules_info *comp_info,
1643 		uint8_t comp_id)
1644 {
1645 	switch (comp_id) {
1646 	case WLAN_UMAC_COMP_TDLS:
1647 		if (comp_info->scan_info.is_tdls_in_progress) {
1648 			scm_debug("Cancel scan. Tdls in progress");
1649 			return false;
1650 		}
1651 		break;
1652 	case WLAN_UMAC_COMP_DFS:
1653 		if (comp_info->scan_info.is_cac_in_progress) {
1654 			scm_debug("Cancel scan. CAC in progress");
1655 			return false;
1656 		}
1657 		break;
1658 	case WLAN_UMAC_COMP_MLME:
1659 		if (comp_info->scan_info.is_mlme_op_in_progress) {
1660 			scm_debug("Cancel scan. MLME operation in progress");
1661 			return false;
1662 		}
1663 		break;
1664 	default:
1665 		scm_debug("not handled comp_id %d", comp_id);
1666 		break;
1667 	}
1668 
1669 	return true;
1670 }
1671 
1672 QDF_STATUS
1673 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
1674 {
1675 	QDF_STATUS status;
1676 
1677 	scm_debug("psoc enable: 0x%pK", psoc);
1678 	if (!psoc) {
1679 		scm_err("null psoc");
1680 		return QDF_STATUS_E_FAILURE;
1681 	}
1682 	/* Subscribe for scan events from lmac layesr */
1683 	status = tgt_scan_register_ev_handler(psoc);
1684 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1685 	if (!wlan_reg_is_11d_offloaded(psoc))
1686 		scm_11d_cc_db_init(psoc);
1687 	ucfg_scan_register_unregister_bcn_cb(psoc, true);
1688 	status = wlan_serialization_register_apply_rules_cb(psoc,
1689 				WLAN_SER_CMD_SCAN,
1690 				scm_serialization_scan_rules_cb);
1691 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1692 	return status;
1693 }
1694 
1695 QDF_STATUS
1696 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
1697 {
1698 	QDF_STATUS status;
1699 
1700 	scm_debug("psoc disable: 0x%pK", psoc);
1701 	if (!psoc) {
1702 		scm_err("null psoc");
1703 		return QDF_STATUS_E_FAILURE;
1704 	}
1705 	/* Unsubscribe for scan events from lmac layesr */
1706 	status = tgt_scan_unregister_ev_handler(psoc);
1707 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1708 	ucfg_scan_register_unregister_bcn_cb(psoc, false);
1709 	if (!wlan_reg_is_11d_offloaded(psoc))
1710 		scm_11d_cc_db_deinit(psoc);
1711 
1712 	return status;
1713 }
1714 
1715 uint32_t
1716 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
1717 {
1718 	struct scan_default_params *scan_params = NULL;
1719 
1720 	if (!psoc) {
1721 		scm_err("null psoc");
1722 		return 0;
1723 	}
1724 	scan_params = wlan_scan_psoc_get_def_params(psoc);
1725 	if (!scan_params) {
1726 		scm_err("Failed to get scan object");
1727 		return 0;
1728 	}
1729 
1730 	return scan_params->max_active_scans_allowed;
1731 }
1732 
1733 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
1734 				  struct probe_req_whitelist_attr *ie_whitelist)
1735 {
1736 	struct wlan_scan_obj *scan_obj = NULL;
1737 
1738 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1739 	if (!scan_obj)
1740 		return false;
1741 
1742 	qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist,
1743 		     sizeof(*ie_whitelist));
1744 
1745 	return true;
1746 }
1747 
1748 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
1749 			       struct wlan_objmgr_vdev *vdev)
1750 {
1751 	struct wlan_scan_obj *scan_obj = NULL;
1752 
1753 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1754 	if (!scan_obj)
1755 		return false;
1756 
1757 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1758 	    wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
1759 		return false;
1760 
1761 	if (!scan_obj->ie_whitelist.white_list)
1762 		return false;
1763 
1764 	return true;
1765 }
1766 
1767 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
1768 			       bool bt_a2dp_active)
1769 {
1770 	struct wlan_scan_obj *scan_obj;
1771 
1772 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1773 	if (!scan_obj) {
1774 		scm_err("Failed to get scan object");
1775 		return;
1776 	}
1777 	scan_obj->bt_a2dp_enabled = bt_a2dp_active;
1778 }
1779 
1780 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
1781 {
1782 	struct wlan_scan_obj *scan_obj;
1783 
1784 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1785 	if (!scan_obj) {
1786 		scm_err("Failed to get scan object");
1787 		return false;
1788 	}
1789 
1790 	return scan_obj->bt_a2dp_enabled;
1791 }
1792 
1793 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc)
1794 {
1795 	struct wlan_scan_obj *scan_obj;
1796 
1797 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1798 	if (!scan_obj)
1799 		return false;
1800 
1801 	return scan_obj->scan_def.use_wake_lock_in_user_scan;
1802 }
1803 
1804 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
1805 {
1806 	struct wlan_scan_obj *scan_obj;
1807 
1808 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1809 	if (!scan_obj) {
1810 		scm_err("Failed to get scan object");
1811 		return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
1812 	}
1813 
1814 	return scan_obj->scan_def.enable_connected_scan;
1815 }
1816 
1817 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc)
1818 {
1819 	struct wlan_scan_obj *scan_obj;
1820 
1821 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1822 	if (!scan_obj) {
1823 		scm_err("Failed to get scan object");
1824 		return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING);
1825 	}
1826 
1827 	return scan_obj->scan_def.enable_mac_spoofing;
1828 }
1829 
1830 enum scan_dwelltime_adaptive_mode
1831 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc)
1832 {
1833 	struct wlan_scan_obj *scan_obj;
1834 
1835 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1836 	if (!scan_obj) {
1837 		scm_err("Failed to get scan object");
1838 		return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
1839 	}
1840 
1841 	return scan_obj->scan_def.extscan_adaptive_dwell_mode;
1842 }
1843 
1844 QDF_STATUS
1845 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
1846 			       enum scan_config config, uint32_t val)
1847 {
1848 	struct wlan_scan_obj *scan_obj;
1849 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1850 
1851 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1852 	if (!scan_obj) {
1853 		scm_err("Failed to get scan object config:%d, val:%d",
1854 				config, val);
1855 		return QDF_STATUS_E_INVAL;
1856 	}
1857 	switch (config) {
1858 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1859 		scan_obj->disable_timeout = !!val;
1860 		break;
1861 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1862 		scan_obj->drop_bcn_on_chan_mismatch = !!val;
1863 		break;
1864 
1865 	default:
1866 		status = QDF_STATUS_E_INVAL;
1867 		break;
1868 	}
1869 
1870 	return status;
1871 }
1872 
1873 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
1874 		struct bss_info *bss_info, struct mlme_info *mlme)
1875 {
1876 	QDF_STATUS status;
1877 
1878 	status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme);
1879 
1880 	return status;
1881 }
1882 
1883 QDF_STATUS
1884 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
1885 			       enum scan_config config, uint32_t *val)
1886 {
1887 	struct wlan_scan_obj *scan_obj;
1888 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1889 
1890 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1891 	if (!scan_obj || !val) {
1892 		scm_err("scan object:%pK config:%d, val:0x%pK",
1893 				scan_obj, config, val);
1894 		return QDF_STATUS_E_INVAL;
1895 	}
1896 	switch (config) {
1897 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1898 		*val = scan_obj->disable_timeout;
1899 		break;
1900 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1901 		*val = scan_obj->drop_bcn_on_chan_mismatch;
1902 		break;
1903 
1904 	default:
1905 		status = QDF_STATUS_E_INVAL;
1906 		break;
1907 	}
1908 
1909 	return status;
1910 }
1911 
1912 #ifdef FEATURE_WLAN_SCAN_PNO
1913 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc)
1914 {
1915 	struct wlan_scan_obj *scan_obj;
1916 
1917 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1918 	if (!scan_obj) {
1919 		scm_err("NULL scan obj");
1920 		return false;
1921 	}
1922 
1923 	return scan_obj->pno_cfg.pno_offload_enabled;
1924 }
1925 
1926 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value)
1927 {
1928 	 struct wlan_scan_obj *scan_obj;
1929 
1930 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1931 	if (!scan_obj) {
1932 		scm_err("NULL scan obj");
1933 		return;
1934 	}
1935 
1936 	scan_obj->pno_cfg.pno_offload_enabled = value;
1937 }
1938 
1939 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
1940 {
1941 	struct wlan_scan_obj *scan_obj;
1942 
1943 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1944 	if (!scan_obj) {
1945 		scm_err("NULL scan obj");
1946 		return cfg_default(CFG_PNO_SCAN_SUPPORT);
1947 	}
1948 
1949 	return scan_obj->pno_cfg.scan_support_enabled;
1950 }
1951 
1952 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc)
1953 {
1954 	struct wlan_scan_obj *scan_obj;
1955 
1956 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1957 	if (!scan_obj) {
1958 		scm_err("NULL scan obj");
1959 		return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER);
1960 	}
1961 	return scan_obj->pno_cfg.scan_backoff_multiplier;
1962 }
1963 
1964 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc)
1965 {
1966 		struct wlan_scan_obj *scan_obj;
1967 
1968 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1969 		if (!scan_obj) {
1970 			scm_err("NULL scan obj");
1971 			return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN);
1972 		}
1973 		return scan_obj->pno_cfg.dfs_chnl_scan_enabled;
1974 }
1975 
1976 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc)
1977 {
1978 		struct wlan_scan_obj *scan_obj;
1979 
1980 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1981 		if (!scan_obj) {
1982 			scm_err("NULL scan obj");
1983 			return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
1984 		}
1985 		return scan_obj->pno_cfg.scan_timer_repeat_value;
1986 }
1987 
1988 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc)
1989 {
1990 		struct wlan_scan_obj *scan_obj;
1991 
1992 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1993 		if (!scan_obj) {
1994 			scm_err("NULL scan obj");
1995 			return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER);
1996 		}
1997 		return scan_obj->pno_cfg.slow_scan_multiplier;
1998 }
1999 
2000 uint32_t
2001 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc)
2002 {
2003 	struct wlan_scan_obj *scan_obj;
2004 
2005 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2006 	if (!scan_obj) {
2007 		scm_err("Failed to get scan object");
2008 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
2009 	}
2010 
2011 	return scan_obj->pno_cfg.max_sched_scan_plan_interval;
2012 }
2013 
2014 uint32_t
2015 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc)
2016 {
2017 	struct wlan_scan_obj *scan_obj;
2018 
2019 	scan_obj = wlan_psoc_get_scan_obj(psoc);
2020 	if (!scan_obj) {
2021 		scm_err("Failed to get scan object");
2022 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
2023 	}
2024 
2025 	return scan_obj->pno_cfg.max_sched_scan_plan_iterations;
2026 }
2027 
2028 #endif
2029