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