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