xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
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:" QDF_SSID_FMT,
552 		  QDF_MAC_ADDR_REF(bssid),
553 		  QDF_SSID_REF(ssid->length, ssid->ssid));
554 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid,
555 		     bssid, QDF_MAC_ADDR_SIZE);
556 	scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length;
557 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid,
558 		     ssid->ssid,
559 		     scan_obj->pdev_info[pdev_id].conf_ssid.length);
560 
561 	return QDF_STATUS_SUCCESS;
562 }
563 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */
564 
565 QDF_STATUS
566 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
567 {
568 	QDF_STATUS status;
569 	bool cancel_vdev = false, cancel_pdev = false;
570 	struct wlan_objmgr_vdev *vdev;
571 	struct wlan_objmgr_pdev *pdev;
572 	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
573 
574 	if (!req || !req->vdev) {
575 		scm_err("req or vdev within req is NULL");
576 		if (req)
577 			qdf_mem_free(req);
578 		return QDF_STATUS_E_NULL_VALUE;
579 	}
580 
581 	if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL)
582 		cancel_pdev = true;
583 	else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL ||
584 		 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL)
585 		cancel_vdev = true;
586 
587 	vdev = req->vdev;
588 	status = wlan_scan_cancel(req);
589 	if (QDF_IS_STATUS_ERROR(status))
590 		return status;
591 
592 	if (cancel_pdev) {
593 		pdev = wlan_vdev_get_pdev(vdev);
594 		while ((wlan_get_pdev_status(pdev) !=
595 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
596 			scm_debug("wait for all pdev scan to get complete");
597 			qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
598 			max_wait_iterations--;
599 		}
600 	} else if (cancel_vdev) {
601 		while ((wlan_get_vdev_status(vdev) !=
602 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
603 			scm_debug("wait for all vdev scan to get complete");
604 			qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
605 			max_wait_iterations--;
606 		}
607 	}
608 
609 	if (!max_wait_iterations) {
610 		scm_err("Failed to wait for scans to get complete");
611 		return QDF_STATUS_E_TIMEOUT;
612 	}
613 
614 	return status;
615 }
616 
617 uint8_t*
618 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
619 	wlan_scan_requester requester)
620 {
621 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
622 	struct wlan_scan_obj *scan;
623 	struct scan_requester_info *requesters;
624 
625 	if (!psoc) {
626 		scm_err("null psoc");
627 		return "null";
628 	}
629 	scan = wlan_psoc_get_scan_obj(psoc);
630 	if (!scan)
631 		return "null";
632 
633 	requesters = scan->requesters;
634 
635 	if ((idx < WLAN_MAX_REQUESTORS) &&
636 		(requesters[idx].requester == requester)) {
637 		return requesters[idx].module;
638 	}
639 
640 	return (uint8_t *)"unknown";
641 }
642 
643 static QDF_STATUS
644 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
645 	scan_event_handler event_cb, void *arg)
646 {
647 	struct cb_handler *cb_handler;
648 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
649 
650 	/* Assign next available slot to this registration request */
651 	cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
652 	cb_handler->func = event_cb;
653 	cb_handler->arg = arg;
654 	pdev_ev_handler->handler_cnt++;
655 
656 	return QDF_STATUS_SUCCESS;
657 }
658 
659 QDF_STATUS
660 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
661 	scan_event_handler event_cb, void *arg)
662 {
663 	uint32_t idx;
664 	struct wlan_scan_obj *scan;
665 	struct pdev_scan_ev_handler *pdev_ev_handler;
666 	struct cb_handler *cb_handler;
667 
668 	/* scan event handler call back can't be NULL */
669 	if (!pdev || !event_cb) {
670 		scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
671 		return QDF_STATUS_E_NULL_VALUE;
672 	}
673 
674 	scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
675 
676 	scan = wlan_pdev_get_scan_obj(pdev);
677 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
678 	if (!pdev_ev_handler) {
679 		scm_err("null pdev_ev_handler");
680 		return QDF_STATUS_E_NULL_VALUE;
681 	}
682 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
683 
684 	qdf_spin_lock_bh(&scan->lock);
685 	/* Ensure its not a duplicate registration request */
686 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
687 		idx++, cb_handler++) {
688 		if ((cb_handler->func == event_cb) &&
689 			(cb_handler->arg == arg)) {
690 			qdf_spin_unlock_bh(&scan->lock);
691 			scm_debug("func: %pK, arg: %pK already exists",
692 				  event_cb, arg);
693 			return QDF_STATUS_SUCCESS;
694 		}
695 	}
696 
697 	QDF_ASSERT(pdev_ev_handler->handler_cnt <
698 			MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
699 
700 	if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
701 		qdf_spin_unlock_bh(&scan->lock);
702 		scm_warn("No more registrations possible");
703 		return QDF_STATUS_E_NOMEM;
704 	}
705 
706 	scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
707 	qdf_spin_unlock_bh(&scan->lock);
708 
709 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
710 
711 	return QDF_STATUS_SUCCESS;
712 }
713 
714 static QDF_STATUS
715 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
716 		      struct wlan_scan_obj *scan_obj)
717 {
718 	scan_obj->scan_disabled = 0;
719 	scan_obj->drop_bcn_on_chan_mismatch =
720 			 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH);
721 	scan_obj->drop_bcn_on_invalid_freq =
722 			 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ);
723 	scan_obj->disable_timeout = false;
724 	scan_obj->obss_scan_offload = false;
725 	scan_obj->scan_def.active_dwell =
726 			 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
727 	/* the ini is disallow DFS channel scan if ini is 1, so negate that */
728 	scan_obj->scan_def.allow_dfs_chan_in_first_scan =
729 				!cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
730 	scan_obj->scan_def.allow_dfs_chan_in_scan =
731 				cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
732 	scan_obj->scan_def.skip_dfs_chan_in_p2p_search =
733 				cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH);
734 	scan_obj->scan_def.use_wake_lock_in_user_scan =
735 				cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN);
736 	scan_obj->scan_def.active_dwell_2g =
737 			 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
738 	scan_obj->scan_def.min_dwell_time_6g =
739 			cfg_get(psoc, CFG_MIN_6G_CHANNEL_TIME);
740 	scan_obj->scan_def.active_dwell_6g =
741 			 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME);
742 	scan_obj->scan_def.passive_dwell_6g =
743 			 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME);
744 	scan_obj->scan_def.active_dwell_time_6g_conc =
745 			 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME_CONC);
746 	scan_obj->scan_def.passive_dwell_time_6g_conc =
747 			 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME_CONC);
748 	scan_obj->scan_def.passive_dwell =
749 			 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME);
750 	scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
751 	scan_obj->scan_def.sta_miracast_mcc_rest_time =
752 					SCAN_STA_MIRACAST_MCC_REST_TIME;
753 	scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
754 	scan_obj->scan_def.conc_active_dwell =
755 			cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC);
756 	scan_obj->scan_def.conc_passive_dwell =
757 			cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC);
758 	scan_obj->scan_def.conc_max_rest_time =
759 			cfg_get(psoc, CFG_MAX_REST_TIME_CONC);
760 	scan_obj->scan_def.conc_min_rest_time =
761 			cfg_get(psoc, CFG_MIN_REST_TIME_CONC);
762 	scan_obj->scan_def.conc_idle_time =
763 			cfg_get(psoc, CFG_IDLE_TIME_CONC);
764 	scan_obj->scan_def.conc_chlist_trim =
765 			cfg_get(psoc, CFG_CHAN_LIST_TRIM_CONC);
766 	scan_obj->scan_def.repeat_probe_time =
767 			cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME);
768 	scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
769 	scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
770 	scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
771 	scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
772 	scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES);
773 	scan_obj->scan_def.scan_cache_aging_time =
774 			(cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000);
775 	scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
776 	scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
777 	scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
778 	scan_obj->scan_def.adaptive_dwell_time_mode =
779 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE);
780 	scan_obj->scan_def.adaptive_dwell_time_mode_nc =
781 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC);
782 	scan_obj->scan_def.honour_nl_scan_policy_flags =
783 			cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS);
784 	scan_obj->scan_def.enable_mac_spoofing =
785 			cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING);
786 	scan_obj->scan_def.extscan_adaptive_dwell_mode =
787 			cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
788 
789 	/* init burst durations */
790 	scan_obj->scan_def.sta_scan_burst_duration =
791 				cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION);
792 	scan_obj->scan_def.p2p_scan_burst_duration =
793 				cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION);
794 	scan_obj->scan_def.go_scan_burst_duration =
795 				cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION);
796 	scan_obj->scan_def.ap_scan_burst_duration =
797 				cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION);
798 	/* scan control flags */
799 	scan_obj->scan_def.scan_f_passive = true;
800 	scan_obj->scan_def.scan_f_ofdm_rates = true;
801 	scan_obj->scan_def.scan_f_2ghz = true;
802 	scan_obj->scan_def.scan_f_5ghz = true;
803 	scan_obj->scan_def.scan_f_chan_stat_evnt =
804 				cfg_get(psoc, CFG_ENABLE_SNR_MONITORING);
805 	/* scan event flags */
806 	scan_obj->scan_def.scan_ev_started = true;
807 	scan_obj->scan_def.scan_ev_completed = true;
808 	scan_obj->scan_def.scan_ev_bss_chan = true;
809 	scan_obj->scan_def.scan_ev_foreign_chan = true;
810 	scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
811 	scan_obj->scan_def.scan_ev_dequeued = true;
812 	scan_obj->scan_def.scan_ev_preempted = true;
813 	scan_obj->scan_def.scan_ev_start_failed = true;
814 	scan_obj->scan_def.scan_ev_restarted = true;
815 	scan_obj->scan_def.enable_connected_scan =
816 		cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN);
817 	scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE);
818 	scan_obj->scan_def.duty_cycle_6ghz =
819 		cfg_get(psoc, CFG_6GHZ_SCAN_MODE_DUTY_CYCLE);
820 	scan_obj->allow_bss_with_incomplete_ie =
821 		cfg_get(psoc, CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE);
822 
823 	scan_obj->scan_def.skip_6g_and_indoor_freq =
824 		cfg_get(psoc, CFG_SKIP_6GHZ_AND_INDOOR_FREQ_SCAN);
825 
826 	/* init scan id seed */
827 	qdf_atomic_init(&scan_obj->scan_ids);
828 
829 	/* init extscan */
830 	wlan_extscan_global_init(psoc, scan_obj);
831 
832 	return wlan_pno_global_init(psoc, scan_obj);
833 }
834 
835 static void
836 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc)
837 {
838 	struct wlan_scan_obj *scan_obj;
839 
840 	scan_obj = wlan_psoc_get_scan_obj(psoc);
841 	wlan_pno_global_deinit(scan_obj);
842 	wlan_extscan_global_deinit();
843 }
844 
845 static QDF_STATUS
846 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
847 	struct cb_handler *entry)
848 {
849 	struct cb_handler *last_entry;
850 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
851 
852 	/* Replace event handler being deleted
853 	 * with the last one in the list.
854 	 */
855 	last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
856 	entry->func = last_entry->func;
857 	entry->arg = last_entry->arg;
858 
859 	/* Clear our last entry */
860 	last_entry->func = NULL;
861 	last_entry->arg = NULL;
862 	pdev_ev_handler->handler_cnt--;
863 
864 	return QDF_STATUS_SUCCESS;
865 }
866 
867 void
868 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
869 	scan_event_handler event_cb, void *arg)
870 {
871 	uint8_t found = false;
872 	uint32_t idx;
873 	uint32_t handler_cnt;
874 	struct wlan_scan_obj *scan;
875 	struct cb_handler *cb_handler;
876 	struct pdev_scan_ev_handler *pdev_ev_handler;
877 
878 	scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb,
879 		  arg);
880 	if (!pdev) {
881 		scm_err("null pdev");
882 		return;
883 	}
884 	scan = wlan_pdev_get_scan_obj(pdev);
885 	if (!scan)
886 		return;
887 
888 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
889 	if (!pdev_ev_handler)
890 		return;
891 
892 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
893 
894 	qdf_spin_lock_bh(&scan->lock);
895 	handler_cnt = pdev_ev_handler->handler_cnt;
896 	if (!handler_cnt) {
897 		qdf_spin_unlock_bh(&scan->lock);
898 		scm_info("No event handlers registered");
899 		return;
900 	}
901 
902 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
903 		idx++, cb_handler++) {
904 		if ((cb_handler->func == event_cb) &&
905 			(cb_handler->arg == arg)) {
906 			/* Event handler found, remove it
907 			 * from event handler list.
908 			 */
909 			found = true;
910 			scm_remove_scan_event_handler(pdev_ev_handler,
911 				cb_handler);
912 			handler_cnt--;
913 			break;
914 		}
915 	}
916 	qdf_spin_unlock_bh(&scan->lock);
917 
918 	scm_debug("event handler %s, remaining handlers: %d",
919 		  (found ? "removed" : "not found"), handler_cnt);
920 }
921 
922 QDF_STATUS
923 ucfg_scan_init_ssid_params(struct scan_start_request *req,
924 		uint32_t num_ssid, struct wlan_ssid *ssid_list)
925 {
926 	uint32_t max_ssid = sizeof(req->scan_req.ssid) /
927 				sizeof(req->scan_req.ssid[0]);
928 
929 	if (!req) {
930 		scm_err("null request");
931 		return QDF_STATUS_E_NULL_VALUE;
932 	}
933 	if (!num_ssid) {
934 		/* empty channel list provided */
935 		req->scan_req.num_ssids = 0;
936 		qdf_mem_zero(&req->scan_req.ssid[0],
937 			sizeof(req->scan_req.ssid));
938 		return QDF_STATUS_SUCCESS;
939 	}
940 	if (!ssid_list) {
941 		scm_err("null ssid_list while num_ssid: %d", num_ssid);
942 		return QDF_STATUS_E_NULL_VALUE;
943 	}
944 	if (num_ssid > max_ssid) {
945 		/* got a big list. alert and continue */
946 		scm_warn("overflow: received %d, max supported : %d",
947 			num_ssid, max_ssid);
948 		return QDF_STATUS_E_E2BIG;
949 	}
950 
951 	if (max_ssid > num_ssid)
952 		max_ssid = num_ssid;
953 
954 	req->scan_req.num_ssids = max_ssid;
955 	qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
956 		(req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
957 
958 	return QDF_STATUS_SUCCESS;
959 }
960 
961 QDF_STATUS
962 ucfg_scan_init_bssid_params(struct scan_start_request *req,
963 		uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
964 {
965 	uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
966 				sizeof(req->scan_req.bssid_list[0]);
967 
968 	if (!req) {
969 		scm_err("null request");
970 		return QDF_STATUS_E_NULL_VALUE;
971 	}
972 	if (!num_bssid) {
973 		/* empty channel list provided */
974 		req->scan_req.num_bssid = 0;
975 		qdf_mem_zero(&req->scan_req.bssid_list[0],
976 			sizeof(req->scan_req.bssid_list));
977 		return QDF_STATUS_SUCCESS;
978 	}
979 	if (!bssid_list) {
980 		scm_err("null bssid_list while num_bssid: %d", num_bssid);
981 		return QDF_STATUS_E_NULL_VALUE;
982 	}
983 	if (num_bssid > max_bssid) {
984 		/* got a big list. alert and continue */
985 		scm_warn("overflow: received %d, max supported : %d",
986 			num_bssid, max_bssid);
987 		return QDF_STATUS_E_E2BIG;
988 	}
989 
990 	if (max_bssid > num_bssid)
991 		max_bssid = num_bssid;
992 
993 	req->scan_req.num_bssid = max_bssid;
994 	qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
995 		req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
996 
997 	return QDF_STATUS_SUCCESS;
998 }
999 
1000 /**
1001  * is_chan_enabled_for_scan() - helper API to check if a frequency
1002  * is allowed to scan.
1003  * @pdev: pointer to pdev
1004  * @reg_chan: regulatory_channel object
1005  * @low_2g: lower 2.4 GHz frequency threshold
1006  * @high_2g: upper 2.4 GHz frequency threshold
1007  * @low_5g: lower 5 GHz frequency threshold
1008  * @high_5g: upper 5 GHz frequency threshold
1009  *
1010  * Return: true if scan is allowed. false otherwise.
1011  */
1012 static bool
1013 is_chan_enabled_for_scan(struct wlan_objmgr_pdev *pdev,
1014 		struct regulatory_channel *reg_chan,
1015 		qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g,
1016 		qdf_freq_t high_5g)
1017 {
1018 	if (wlan_reg_is_disable_for_pwrmode(pdev,
1019 					    reg_chan->center_freq,
1020 					    REG_BEST_PWR_MODE))
1021 		return false;
1022 
1023 	if (reg_chan->nol_chan)
1024 		return false;
1025 
1026 	/* 2 GHz channel */
1027 	if ((util_scan_scm_freq_to_band(reg_chan->center_freq) ==
1028 			WLAN_BAND_2_4_GHZ) &&
1029 			((reg_chan->center_freq < low_2g) ||
1030 			(reg_chan->center_freq > high_2g)))
1031 		return false;
1032 	else if ((util_scan_scm_freq_to_band(reg_chan->center_freq) ==
1033 				WLAN_BAND_5_GHZ) &&
1034 		 ((reg_chan->center_freq < low_5g) ||
1035 		  (reg_chan->center_freq > high_5g)))
1036 		return false;
1037 
1038 	return true;
1039 }
1040 
1041 QDF_STATUS
1042 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1043 		uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1044 {
1045 	uint32_t idx;
1046 	QDF_STATUS status;
1047 	struct regulatory_channel *reg_chan_list = NULL;
1048 	qdf_freq_t low_2g, high_2g, low_5g, high_5g;
1049 	struct wlan_objmgr_pdev *pdev = NULL;
1050 	uint32_t *scan_freqs = NULL;
1051 	uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1052 				sizeof(req->scan_req.chan_list.chan[0]);
1053 	if (!req) {
1054 		scm_err("null request");
1055 		return QDF_STATUS_E_NULL_VALUE;
1056 	}
1057 
1058 	if (req->vdev)
1059 		pdev = wlan_vdev_get_pdev(req->vdev);
1060 	/*
1061 	 * If 0 channels are provided for scan and
1062 	 * wide band scan is enabled, scan all 20 mhz
1063 	 * available channels. This is required as FW
1064 	 * scans all channel/phy mode combinations
1065 	 * provided in scan channel list if 0 chans are
1066 	 * provided in scan request causing scan to take
1067 	 * too much time to complete.
1068 	 */
1069 	if (pdev && !num_chans) {
1070 		reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1071 				sizeof(struct regulatory_channel));
1072 		if (!reg_chan_list) {
1073 			status = QDF_STATUS_E_NOMEM;
1074 			goto end;
1075 		}
1076 		scan_freqs =
1077 			qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1078 		if (!scan_freqs) {
1079 			status = QDF_STATUS_E_NOMEM;
1080 			goto end;
1081 		}
1082 		status = wlan_reg_get_current_chan_list(pdev, reg_chan_list);
1083 		if (QDF_IS_STATUS_ERROR(status))
1084 			goto end;
1085 
1086 		status = wlan_reg_get_freq_range(pdev, &low_2g,
1087 				&high_2g, &low_5g, &high_5g);
1088 		if (QDF_IS_STATUS_ERROR(status))
1089 			goto end;
1090 
1091 		for (idx = 0, num_chans = 0;
1092 			(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1093 			if ((is_chan_enabled_for_scan(pdev,
1094 						      &reg_chan_list[idx],
1095 						      low_2g, high_2g,
1096 						      low_5g, high_5g)) &&
1097 			    ((req->scan_req.scan_f_2ghz &&
1098 			     WLAN_REG_IS_24GHZ_CH_FREQ(
1099 					reg_chan_list[idx].center_freq)) ||
1100 			     (req->scan_req.scan_f_5ghz &&
1101 			      (WLAN_REG_IS_5GHZ_CH_FREQ(
1102 					reg_chan_list[idx].center_freq) ||
1103 			       WLAN_REG_IS_49GHZ_FREQ(
1104 					reg_chan_list[idx].center_freq) ||
1105 			       WLAN_REG_IS_6GHZ_CHAN_FREQ(
1106 					reg_chan_list[idx].center_freq)))))
1107 				scan_freqs[num_chans++] =
1108 				reg_chan_list[idx].center_freq;
1109 
1110 		chan_list = scan_freqs;
1111 	}
1112 
1113 	if (!num_chans) {
1114 		/* empty channel list provided */
1115 		qdf_mem_zero(&req->scan_req.chan_list,
1116 			sizeof(req->scan_req.chan_list));
1117 		req->scan_req.chan_list.num_chan = 0;
1118 		status = QDF_STATUS_SUCCESS;
1119 		goto end;
1120 	}
1121 	if (!chan_list) {
1122 		scm_info("null chan_list while num_chans: %d", num_chans);
1123 		status = QDF_STATUS_E_NULL_VALUE;
1124 		goto end;
1125 	}
1126 
1127 	if (num_chans > max_chans) {
1128 		/* got a big list. alert and fail */
1129 		scm_warn("overflow: received %d, max supported : %d",
1130 			num_chans, max_chans);
1131 		status = QDF_STATUS_E_E2BIG;
1132 		goto end;
1133 	}
1134 
1135 	req->scan_req.chan_list.num_chan = num_chans;
1136 	for (idx = 0; idx < num_chans; idx++) {
1137 		req->scan_req.chan_list.chan[idx].freq =
1138 			(chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1139 			chan_list[idx] :
1140 			wlan_reg_legacy_chan_to_freq(pdev, chan_list[idx]);
1141 		if (phymode)
1142 			req->scan_req.chan_list.chan[idx].phymode =
1143 				phymode[idx];
1144 		else if (req->scan_req.chan_list.chan[idx].freq <=
1145 			WLAN_CHAN_15_FREQ)
1146 			req->scan_req.chan_list.chan[idx].phymode =
1147 				SCAN_PHY_MODE_11G;
1148 		else if (req->scan_req.chan_list.chan[idx].freq <=
1149 			 WLAN_REG_MAX_5GHZ_CHAN_FREQ)
1150 			req->scan_req.chan_list.chan[idx].phymode =
1151 				SCAN_PHY_MODE_11A;
1152 		else
1153 			req->scan_req.chan_list.chan[idx].phymode =
1154 				SCAN_PHY_MODE_11AX_HE20;
1155 	}
1156 
1157 end:
1158 	if (scan_freqs)
1159 		qdf_mem_free(scan_freqs);
1160 
1161 	if (reg_chan_list)
1162 		qdf_mem_free(reg_chan_list);
1163 
1164 	return QDF_STATUS_SUCCESS;
1165 }
1166 
1167 enum scm_scan_status
1168 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1169 {
1170 	return wlan_get_vdev_status(vdev);
1171 }
1172 
1173 enum scm_scan_status
1174 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1175 {
1176 	return wlan_get_pdev_status(pdev);
1177 }
1178 
1179 static void
1180 scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1181 				bool enable)
1182 {
1183 	QDF_STATUS status;
1184 	struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1185 
1186 	cb_info[0].frm_type = MGMT_PROBE_RESP;
1187 	cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1188 	cb_info[1].frm_type = MGMT_BEACON;
1189 	cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1190 
1191 	if (enable)
1192 		status = wlan_mgmt_txrx_register_rx_cb(psoc,
1193 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1194 	else
1195 		status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1196 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1197 	if (status != QDF_STATUS_SUCCESS)
1198 		scm_err("%s the Handle with MGMT TXRX layer has failed",
1199 			enable ? "Registering" : "Deregistering");
1200 }
1201 
1202 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1203 	struct scan_user_cfg *scan_cfg)
1204 {
1205 	struct wlan_scan_obj *scan_obj;
1206 	struct scan_default_params *scan_def;
1207 
1208 	if (!psoc) {
1209 		scm_err("null psoc");
1210 		return QDF_STATUS_E_FAILURE;
1211 	}
1212 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1213 	if (!scan_obj) {
1214 		scm_err("Failed to get scan object");
1215 		return QDF_STATUS_E_FAILURE;
1216 	}
1217 
1218 	scan_def = &scan_obj->scan_def;
1219 	scan_obj->ie_allowlist = scan_cfg->ie_allowlist;
1220 	scan_def->sta_miracast_mcc_rest_time =
1221 				scan_cfg->sta_miracast_mcc_rest_time;
1222 
1223 	return QDF_STATUS_SUCCESS;
1224 }
1225 
1226 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1227 static QDF_STATUS
1228 scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
1229 {
1230 	struct scan_cancel_request *req;
1231 	QDF_STATUS status;
1232 	struct wlan_objmgr_vdev *vdev;
1233 
1234 	req = qdf_mem_malloc_atomic(sizeof(*req));
1235 	if (!req) {
1236 		scm_err("Failed to allocate memory");
1237 		return QDF_STATUS_E_NOMEM;
1238 	}
1239 
1240 	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID);
1241 	if (!vdev) {
1242 		scm_err("Failed to get vdev");
1243 		qdf_mem_free(req);
1244 		return QDF_STATUS_E_INVAL;
1245 	}
1246 	req->vdev = vdev;
1247 	req->cancel_req.scan_id = INVAL_SCAN_ID;
1248 	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1249 	req->cancel_req.vdev_id = INVAL_VDEV_ID;
1250 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1251 	status = ucfg_scan_cancel_sync(req);
1252 	if (QDF_IS_STATUS_ERROR(status))
1253 		scm_err("Cancel scan request failed");
1254 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1255 
1256 	return status;
1257 }
1258 
1259 static QDF_STATUS
1260 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1261 {
1262 	struct wlan_objmgr_pdev *pdev = NULL;
1263 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1264 	int i;
1265 	wlan_scan_psoc_set_disable(psoc, REASON_SUSPEND);
1266 
1267 	/* Check all pdev */
1268 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
1269 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
1270 		if (!pdev)
1271 			continue;
1272 		if (wlan_get_pdev_status(pdev) != SCAN_NOT_IN_PROGRESS)
1273 			status = scan_cancel_pdev_scan(pdev);
1274 		scm_disable_obss_pdev_scan(psoc, pdev);
1275 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
1276 		if (QDF_IS_STATUS_ERROR(status)) {
1277 			scm_err("failed to cancel scan for pdev_id %d", i);
1278 			return status;
1279 		}
1280 	}
1281 
1282 	return QDF_STATUS_SUCCESS;
1283 }
1284 
1285 static QDF_STATUS
1286 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1287 {
1288 	wlan_scan_psoc_set_enable(psoc, REASON_SUSPEND);
1289 	return QDF_STATUS_SUCCESS;
1290 }
1291 
1292 static inline void
1293 scan_register_pmo_handler(void)
1294 {
1295 	pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
1296 		ucfg_scan_suspend_handler, NULL);
1297 	pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
1298 		ucfg_scan_resume_handler, NULL);
1299 }
1300 
1301 static inline void
1302 scan_unregister_pmo_handler(void)
1303 {
1304 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
1305 		ucfg_scan_suspend_handler);
1306 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
1307 		ucfg_scan_resume_handler);
1308 }
1309 
1310 #else
1311 static inline void
1312 scan_register_pmo_handler(void)
1313 {
1314 }
1315 
1316 static inline void
1317 scan_unregister_pmo_handler(void)
1318 {
1319 }
1320 #endif
1321 
1322 QDF_STATUS
1323 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
1324 {
1325 	struct wlan_scan_obj *scan_obj;
1326 
1327 	scm_debug("psoc open: 0x%pK", psoc);
1328 	if (!psoc) {
1329 		scm_err("null psoc");
1330 		return QDF_STATUS_E_FAILURE;
1331 	}
1332 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1333 	if (!scan_obj) {
1334 		scm_err("Failed to get scan object");
1335 		return QDF_STATUS_E_FAILURE;
1336 	}
1337 	/* Initialize the scan Globals */
1338 	wlan_scan_global_init(psoc, scan_obj);
1339 	qdf_spinlock_create(&scan_obj->lock);
1340 	scan_register_pmo_handler();
1341 	scm_db_init(psoc);
1342 	scm_channel_list_db_init(psoc);
1343 
1344 	return QDF_STATUS_SUCCESS;
1345 }
1346 
1347 QDF_STATUS
1348 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
1349 {
1350 	struct wlan_scan_obj *scan_obj;
1351 
1352 	scm_debug("psoc close: 0x%pK", psoc);
1353 	if (!psoc) {
1354 		scm_err("null psoc");
1355 		return QDF_STATUS_E_FAILURE;
1356 	}
1357 	scm_db_deinit(psoc);
1358 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1359 	if (!scan_obj) {
1360 		scm_err("Failed to get scan object");
1361 		return QDF_STATUS_E_FAILURE;
1362 	}
1363 	scan_unregister_pmo_handler();
1364 	qdf_spinlock_destroy(&scan_obj->lock);
1365 	wlan_scan_global_deinit(psoc);
1366 	scm_channel_list_db_deinit(psoc);
1367 
1368 	return QDF_STATUS_SUCCESS;
1369 }
1370 
1371 static bool scm_serialization_scan_rules_cb(
1372 		union wlan_serialization_rules_info *comp_info,
1373 		uint8_t comp_id)
1374 {
1375 	switch (comp_id) {
1376 	case WLAN_UMAC_COMP_TDLS:
1377 		if (comp_info->scan_info.is_tdls_in_progress) {
1378 			scm_debug("Cancel scan. Tdls in progress");
1379 			return false;
1380 		}
1381 		break;
1382 	case WLAN_UMAC_COMP_DFS:
1383 		if (comp_info->scan_info.is_cac_in_progress) {
1384 			scm_debug("Cancel scan. CAC in progress");
1385 			return false;
1386 		}
1387 		break;
1388 	case WLAN_UMAC_COMP_MLME:
1389 		if (comp_info->scan_info.is_scan_for_connect) {
1390 			scm_debug("Allow scan request from connect");
1391 			return true;
1392 		}
1393 
1394 		if (comp_info->scan_info.is_mlme_op_in_progress) {
1395 			scm_debug("Cancel scan. MLME operation in progress");
1396 			return false;
1397 		}
1398 		break;
1399 	default:
1400 		scm_debug("not handled comp_id %d", comp_id);
1401 		break;
1402 	}
1403 
1404 	return true;
1405 }
1406 
1407 QDF_STATUS
1408 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
1409 {
1410 	QDF_STATUS status;
1411 
1412 	scm_debug("psoc enable: 0x%pK", psoc);
1413 	if (!psoc) {
1414 		scm_err("null psoc");
1415 		return QDF_STATUS_E_FAILURE;
1416 	}
1417 	/* Subscribe for scan events from lmac layesr */
1418 	status = tgt_scan_register_ev_handler(psoc);
1419 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1420 	if (!wlan_reg_is_11d_offloaded(psoc))
1421 		scm_11d_cc_db_init(psoc);
1422 	scan_register_unregister_bcn_cb(psoc, true);
1423 	status = wlan_serialization_register_apply_rules_cb(psoc,
1424 				WLAN_SER_CMD_SCAN,
1425 				scm_serialization_scan_rules_cb);
1426 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1427 	return status;
1428 }
1429 
1430 QDF_STATUS
1431 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
1432 {
1433 	QDF_STATUS status;
1434 
1435 	scm_debug("psoc disable: 0x%pK", psoc);
1436 	if (!psoc) {
1437 		scm_err("null psoc");
1438 		return QDF_STATUS_E_FAILURE;
1439 	}
1440 	/* Unsubscribe for scan events from lmac layesr */
1441 	status = tgt_scan_unregister_ev_handler(psoc);
1442 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1443 	scan_register_unregister_bcn_cb(psoc, false);
1444 	if (!wlan_reg_is_11d_offloaded(psoc))
1445 		scm_11d_cc_db_deinit(psoc);
1446 
1447 	return status;
1448 }
1449 
1450 uint32_t
1451 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
1452 {
1453 	struct scan_default_params *scan_params = NULL;
1454 
1455 	if (!psoc) {
1456 		scm_err("null psoc");
1457 		return 0;
1458 	}
1459 	scan_params = wlan_scan_psoc_get_def_params(psoc);
1460 	if (!scan_params) {
1461 		scm_err("Failed to get scan object");
1462 		return 0;
1463 	}
1464 
1465 	return scan_params->max_active_scans_allowed;
1466 }
1467 
1468 bool ucfg_copy_ie_allowlist_attrs(struct wlan_objmgr_psoc *psoc,
1469 				  struct probe_req_allowlist_attr *ie_allowlist)
1470 {
1471 	struct wlan_scan_obj *scan_obj = NULL;
1472 
1473 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1474 	if (!scan_obj)
1475 		return false;
1476 
1477 	qdf_mem_copy(ie_allowlist, &scan_obj->ie_allowlist,
1478 		     sizeof(*ie_allowlist));
1479 
1480 	return true;
1481 }
1482 
1483 bool ucfg_ie_allowlist_enabled(struct wlan_objmgr_psoc *psoc,
1484 			       struct wlan_objmgr_vdev *vdev)
1485 {
1486 	struct wlan_scan_obj *scan_obj = NULL;
1487 
1488 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1489 	if (!scan_obj)
1490 		return false;
1491 
1492 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1493 	    wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
1494 		return false;
1495 
1496 	if (!scan_obj->ie_allowlist.allow_list)
1497 		return false;
1498 
1499 	return true;
1500 }
1501 
1502 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
1503 			       bool bt_a2dp_active)
1504 {
1505 	struct wlan_scan_obj *scan_obj;
1506 
1507 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1508 	if (!scan_obj) {
1509 		scm_err("Failed to get scan object");
1510 		return;
1511 	}
1512 	scan_obj->bt_a2dp_enabled = bt_a2dp_active;
1513 }
1514 
1515 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
1516 {
1517 	struct wlan_scan_obj *scan_obj;
1518 
1519 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1520 	if (!scan_obj) {
1521 		scm_err("Failed to get scan object");
1522 		return false;
1523 	}
1524 
1525 	return scan_obj->bt_a2dp_enabled;
1526 }
1527 
1528 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc)
1529 {
1530 	struct wlan_scan_obj *scan_obj;
1531 
1532 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1533 	if (!scan_obj)
1534 		return false;
1535 
1536 	return scan_obj->scan_def.use_wake_lock_in_user_scan;
1537 }
1538 
1539 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
1540 {
1541 	struct wlan_scan_obj *scan_obj;
1542 
1543 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1544 	if (!scan_obj) {
1545 		scm_err("Failed to get scan object");
1546 		return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
1547 	}
1548 
1549 	return scan_obj->scan_def.enable_connected_scan;
1550 }
1551 
1552 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc)
1553 {
1554 	struct wlan_scan_obj *scan_obj;
1555 
1556 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1557 	if (!scan_obj) {
1558 		scm_err("Failed to get scan object");
1559 		return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING);
1560 	}
1561 
1562 	return scan_obj->scan_def.enable_mac_spoofing;
1563 }
1564 
1565 enum scan_dwelltime_adaptive_mode
1566 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc)
1567 {
1568 	struct wlan_scan_obj *scan_obj;
1569 
1570 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1571 	if (!scan_obj) {
1572 		scm_err("Failed to get scan object");
1573 		return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
1574 	}
1575 
1576 	return scan_obj->scan_def.extscan_adaptive_dwell_mode;
1577 }
1578 
1579 QDF_STATUS
1580 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
1581 			       enum scan_config config, uint32_t val)
1582 {
1583 	struct wlan_scan_obj *scan_obj;
1584 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1585 
1586 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1587 	if (!scan_obj) {
1588 		scm_err("Failed to get scan object config:%d, val:%d",
1589 				config, val);
1590 		return QDF_STATUS_E_INVAL;
1591 	}
1592 	switch (config) {
1593 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1594 		scan_obj->disable_timeout = !!val;
1595 		break;
1596 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1597 		scan_obj->drop_bcn_on_chan_mismatch = !!val;
1598 		break;
1599 
1600 	default:
1601 		status = QDF_STATUS_E_INVAL;
1602 		break;
1603 	}
1604 
1605 	return status;
1606 }
1607 
1608 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
1609 		struct bss_info *bss_info, struct mlme_info *mlme)
1610 {
1611 	QDF_STATUS status;
1612 
1613 	status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme);
1614 
1615 	return status;
1616 }
1617 
1618 QDF_STATUS
1619 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
1620 			       enum scan_config config, uint32_t *val)
1621 {
1622 	struct wlan_scan_obj *scan_obj;
1623 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1624 
1625 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1626 	if (!scan_obj || !val) {
1627 		scm_err("scan object:%pK config:%d, val:0x%pK",
1628 				scan_obj, config, val);
1629 		return QDF_STATUS_E_INVAL;
1630 	}
1631 	switch (config) {
1632 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1633 		*val = scan_obj->disable_timeout;
1634 		break;
1635 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1636 		*val = scan_obj->drop_bcn_on_chan_mismatch;
1637 		break;
1638 
1639 	default:
1640 		status = QDF_STATUS_E_INVAL;
1641 		break;
1642 	}
1643 
1644 	return status;
1645 }
1646 
1647 void ucfg_scan_set_obss_scan_offload(struct wlan_objmgr_psoc *psoc, bool value)
1648 {
1649 	struct wlan_scan_obj *scan_obj;
1650 
1651 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1652 	if (!scan_obj) {
1653 		scm_err("NULL scan obj");
1654 		return;
1655 	}
1656 
1657 	scan_obj->obss_scan_offload = value;
1658 }
1659 
1660 #ifdef FEATURE_WLAN_SCAN_PNO
1661 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc)
1662 {
1663 	struct wlan_scan_obj *scan_obj;
1664 
1665 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1666 	if (!scan_obj) {
1667 		scm_err("NULL scan obj");
1668 		return false;
1669 	}
1670 
1671 	return scan_obj->pno_cfg.pno_offload_enabled;
1672 }
1673 
1674 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value)
1675 {
1676 	 struct wlan_scan_obj *scan_obj;
1677 
1678 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1679 	if (!scan_obj) {
1680 		scm_err("NULL scan obj");
1681 		return;
1682 	}
1683 
1684 	scan_obj->pno_cfg.pno_offload_enabled = value;
1685 }
1686 
1687 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
1688 {
1689 	struct wlan_scan_obj *scan_obj;
1690 
1691 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1692 	if (!scan_obj) {
1693 		scm_err("NULL scan obj");
1694 		return cfg_default(CFG_PNO_SCAN_SUPPORT);
1695 	}
1696 
1697 	return scan_obj->pno_cfg.scan_support_enabled;
1698 }
1699 
1700 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc)
1701 {
1702 	struct wlan_scan_obj *scan_obj;
1703 
1704 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1705 	if (!scan_obj) {
1706 		scm_err("NULL scan obj");
1707 		return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER);
1708 	}
1709 	return scan_obj->pno_cfg.scan_backoff_multiplier;
1710 }
1711 
1712 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc)
1713 {
1714 		struct wlan_scan_obj *scan_obj;
1715 
1716 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1717 		if (!scan_obj) {
1718 			scm_err("NULL scan obj");
1719 			return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN);
1720 		}
1721 		return scan_obj->pno_cfg.dfs_chnl_scan_enabled;
1722 }
1723 
1724 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc)
1725 {
1726 		struct wlan_scan_obj *scan_obj;
1727 
1728 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1729 		if (!scan_obj) {
1730 			scm_err("NULL scan obj");
1731 			return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
1732 		}
1733 		return scan_obj->pno_cfg.scan_timer_repeat_value;
1734 }
1735 
1736 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc)
1737 {
1738 		struct wlan_scan_obj *scan_obj;
1739 
1740 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1741 		if (!scan_obj) {
1742 			scm_err("NULL scan obj");
1743 			return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER);
1744 		}
1745 		return scan_obj->pno_cfg.slow_scan_multiplier;
1746 }
1747 
1748 uint32_t
1749 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc)
1750 {
1751 	struct wlan_scan_obj *scan_obj;
1752 
1753 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1754 	if (!scan_obj) {
1755 		scm_err("Failed to get scan object");
1756 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
1757 	}
1758 
1759 	return scan_obj->pno_cfg.max_sched_scan_plan_interval;
1760 }
1761 
1762 uint32_t
1763 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc)
1764 {
1765 	struct wlan_scan_obj *scan_obj;
1766 
1767 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1768 	if (!scan_obj) {
1769 		scm_err("Failed to get scan object");
1770 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
1771 	}
1772 
1773 	return scan_obj->pno_cfg.max_sched_scan_plan_iterations;
1774 }
1775 
1776 bool
1777 ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc)
1778 {
1779 	struct wlan_scan_obj *scan_obj;
1780 
1781 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1782 	if (!scan_obj) {
1783 		scm_err("Failed to get scan object");
1784 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
1785 	}
1786 
1787 	return scan_obj->pno_cfg.user_config_sched_scan_plan;
1788 }
1789 #endif
1790