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