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 ®_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