1 /* 2 * Copyright (c) 2017-2020 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 mawc_cfg = &pno_def->mawc_params; 241 pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION); 242 pno_def->top_k_num_of_channels = 243 cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS); 244 pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD); 245 pno_def->channel_prediction_full_scan = 246 cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER); 247 pno_def->adaptive_dwell_mode = 248 cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE); 249 pno_def->dfs_chnl_scan_enabled = 250 cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN); 251 pno_def->scan_support_enabled = 252 cfg_get(psoc, CFG_PNO_SCAN_SUPPORT); 253 pno_def->scan_timer_repeat_value = 254 cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 255 pno_def->slow_scan_multiplier = 256 cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER); 257 pno_def->scan_backoff_multiplier = 258 cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER); 259 pno_def->max_sched_scan_plan_interval = 260 cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); 261 pno_def->max_sched_scan_plan_iterations = 262 cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 263 264 mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED); 265 mawc_cfg->exp_backoff_ratio = 266 cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO); 267 mawc_cfg->init_scan_interval = 268 cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL); 269 mawc_cfg->max_scan_interval = 270 cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL); 271 272 return QDF_STATUS_SUCCESS; 273 } 274 275 static QDF_STATUS 276 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj) 277 { 278 qdf_wake_lock_destroy(&scan_obj->pno_cfg.pno_wake_lock); 279 280 return QDF_STATUS_SUCCESS; 281 } 282 283 #ifdef WLAN_POLICY_MGR_ENABLE 284 /* 285 * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time 286 * depending on active concurrency modes 287 * @vdev: vdev object pointer 288 * @req: scan request 289 * 290 * Return: void 291 */ 292 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 293 struct pno_scan_req_params *req, struct scan_default_params *scan_def) 294 { 295 bool sap_or_p2p_present; 296 struct wlan_objmgr_psoc *psoc; 297 298 psoc = wlan_vdev_get_psoc(vdev); 299 300 if (!psoc) 301 return; 302 303 sap_or_p2p_present = policy_mgr_mode_specific_connection_count( 304 psoc, PM_SAP_MODE, NULL) || 305 policy_mgr_mode_specific_connection_count( 306 psoc, PM_P2P_GO_MODE, NULL) || 307 policy_mgr_mode_specific_connection_count( 308 psoc, PM_P2P_CLIENT_MODE, NULL); 309 310 if (sap_or_p2p_present) { 311 req->active_dwell_time = scan_def->conc_active_dwell; 312 req->passive_dwell_time = scan_def->conc_passive_dwell; 313 } 314 315 } 316 #else 317 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 318 struct pno_scan_req_params *req, struct scan_default_params *scan_def){} 319 #endif 320 321 QDF_STATUS 322 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev, 323 struct pno_scan_req_params *req) 324 { 325 struct scan_default_params *scan_def; 326 struct wlan_scan_obj *scan; 327 struct pno_def_config *pno_def; 328 329 if (!vdev || !req) { 330 scm_err("vdev: 0x%pK, req: 0x%pK", 331 vdev, req); 332 return QDF_STATUS_E_INVAL; 333 } 334 335 scan = wlan_vdev_get_scan_obj(vdev); 336 if (!scan) { 337 scm_err("scan is NULL"); 338 return QDF_STATUS_E_INVAL; 339 } 340 scan_def = wlan_vdev_get_def_scan_params(vdev); 341 if (!scan_def) { 342 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 343 return QDF_STATUS_E_NULL_VALUE; 344 } 345 346 pno_def = &scan->pno_cfg; 347 req->active_dwell_time = scan_def->active_dwell; 348 req->passive_dwell_time = scan_def->passive_dwell; 349 req->scan_random.randomize = scan_def->enable_mac_spoofing; 350 351 /* 352 * Update active and passive dwell time depending 353 * upon the present active concurrency mode 354 */ 355 ucfg_scan_update_pno_dwell_time(vdev, req, scan_def); 356 req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode; 357 req->pno_channel_prediction = pno_def->channel_prediction; 358 req->top_k_num_of_channels = pno_def->top_k_num_of_channels; 359 req->stationary_thresh = pno_def->stationary_thresh; 360 req->channel_prediction_full_scan = 361 pno_def->channel_prediction_full_scan; 362 req->mawc_params.vdev_id = wlan_vdev_get_id(vdev); 363 qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params, 364 sizeof(req->mawc_params)); 365 366 return QDF_STATUS_SUCCESS; 367 } 368 369 QDF_STATUS 370 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc, 371 scan_event_handler event_cb, void *arg) 372 { 373 struct wlan_scan_obj *scan; 374 375 if (!psoc) { 376 scm_err("null psoc"); 377 return QDF_STATUS_E_INVAL; 378 } 379 380 scan = wlan_psoc_get_scan_obj(psoc); 381 if (!scan) { 382 scm_err("scan object null"); 383 return QDF_STATUS_E_INVAL; 384 } 385 386 qdf_spin_lock_bh(&scan->lock); 387 scan->pno_cfg.pno_cb.func = event_cb; 388 scan->pno_cfg.pno_cb.arg = arg; 389 qdf_spin_unlock_bh(&scan->lock); 390 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 391 392 return QDF_STATUS_SUCCESS; 393 } 394 395 #else 396 397 static inline QDF_STATUS 398 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc, 399 struct wlan_scan_obj *scan_obj) 400 { 401 return QDF_STATUS_SUCCESS; 402 } 403 404 static inline QDF_STATUS 405 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj) 406 { 407 return QDF_STATUS_SUCCESS; 408 } 409 410 #endif 411 412 QDF_STATUS 413 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev, 414 struct chan_list *chan_list) 415 { 416 uint8_t pdev_id; 417 struct wlan_scan_obj *scan_obj; 418 419 if (!pdev || !chan_list) { 420 scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list); 421 return QDF_STATUS_E_NULL_VALUE; 422 } 423 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 424 scan_obj = wlan_pdev_get_scan_obj(pdev); 425 426 qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list, 427 chan_list, sizeof(*chan_list)); 428 429 return QDF_STATUS_SUCCESS; 430 } 431 432 QDF_STATUS 433 ucfg_scm_scan_free_scan_request_mem(struct scan_start_request *req) 434 { 435 return scm_scan_free_scan_request_mem(req); 436 } 437 438 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, 439 enum scan_disable_reason reason) 440 { 441 struct wlan_scan_obj *scan_obj; 442 443 scan_obj = wlan_psoc_get_scan_obj(psoc); 444 if (!scan_obj) { 445 scm_err("Failed to get scan object"); 446 return QDF_STATUS_E_NULL_VALUE; 447 } 448 449 scan_obj->scan_disabled &= ~reason; 450 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 451 452 return QDF_STATUS_SUCCESS; 453 } 454 455 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, 456 enum scan_disable_reason reason) 457 { 458 struct wlan_scan_obj *scan_obj; 459 460 scan_obj = wlan_psoc_get_scan_obj(psoc); 461 if (!scan_obj) { 462 scm_err("Failed to get scan object"); 463 return QDF_STATUS_E_NULL_VALUE; 464 } 465 466 scan_obj->scan_disabled |= reason; 467 468 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 469 470 return QDF_STATUS_SUCCESS; 471 } 472 473 474 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, 475 enum scan_disable_reason reason) 476 { 477 struct scan_vdev_obj *scan_vdev_obj; 478 479 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 480 if (!scan_vdev_obj) { 481 scm_err("null scan_vdev_obj"); 482 return QDF_STATUS_E_NULL_VALUE; 483 } 484 485 scan_vdev_obj->scan_disabled &= ~reason; 486 487 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 488 489 return QDF_STATUS_SUCCESS; 490 } 491 492 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, 493 enum scan_disable_reason reason) 494 { 495 struct scan_vdev_obj *scan_vdev_obj; 496 497 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 498 if (!scan_vdev_obj) { 499 scm_err("null scan_vdev_obj"); 500 return QDF_STATUS_E_NULL_VALUE; 501 } 502 503 scan_vdev_obj->scan_disabled |= reason; 504 505 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 506 507 return QDF_STATUS_SUCCESS; 508 } 509 510 511 QDF_STATUS ucfg_scan_set_miracast( 512 struct wlan_objmgr_psoc *psoc, bool enable) 513 { 514 struct wlan_scan_obj *scan_obj; 515 516 scan_obj = wlan_psoc_get_scan_obj(psoc); 517 if (!scan_obj) { 518 scm_err("Failed to get scan object"); 519 return QDF_STATUS_E_NULL_VALUE; 520 } 521 scan_obj->miracast_enabled = enable; 522 scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled); 523 524 return QDF_STATUS_SUCCESS; 525 } 526 527 QDF_STATUS 528 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable) 529 { 530 uint8_t pdev_id; 531 struct wlan_scan_obj *scan_obj; 532 533 if (!pdev) { 534 scm_warn("null vdev"); 535 return QDF_STATUS_E_NULL_VALUE; 536 } 537 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 538 scan_obj = wlan_pdev_get_scan_obj(pdev); 539 if (!scan_obj) 540 return QDF_STATUS_E_FAILURE; 541 542 scm_debug("set wide_band_scan to %d", enable); 543 scan_obj->pdev_info[pdev_id].wide_band_scan = enable; 544 545 return QDF_STATUS_SUCCESS; 546 } 547 548 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev) 549 { 550 uint8_t pdev_id; 551 struct wlan_scan_obj *scan_obj; 552 553 if (!pdev) { 554 scm_warn("null vdev"); 555 return QDF_STATUS_E_NULL_VALUE; 556 } 557 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 558 scan_obj = wlan_pdev_get_scan_obj(pdev); 559 if (!scan_obj) 560 return QDF_STATUS_E_FAILURE; 561 562 return scan_obj->pdev_info[pdev_id].wide_band_scan; 563 } 564 565 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 566 QDF_STATUS 567 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev, 568 uint8_t *bssid, struct wlan_ssid *ssid) 569 { 570 uint8_t pdev_id; 571 struct wlan_scan_obj *scan_obj; 572 573 if (!pdev) { 574 scm_warn("null vdev"); 575 return QDF_STATUS_E_NULL_VALUE; 576 } 577 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 578 scan_obj = wlan_pdev_get_scan_obj(pdev); 579 if (!scan_obj) 580 return QDF_STATUS_E_FAILURE; 581 582 scm_debug("Configure bsssid:"QDF_MAC_ADDR_FMT" ssid:%.*s", 583 QDF_MAC_ADDR_REF(bssid), ssid->length, ssid->ssid); 584 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid, 585 bssid, QDF_MAC_ADDR_SIZE); 586 scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length; 587 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid, 588 ssid->ssid, 589 scan_obj->pdev_info[pdev_id].conf_ssid.length); 590 591 return QDF_STATUS_SUCCESS; 592 } 593 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 594 595 QDF_STATUS 596 ucfg_scan_cancel_sync(struct scan_cancel_request *req) 597 { 598 QDF_STATUS status; 599 bool cancel_vdev = false, cancel_pdev = false; 600 struct wlan_objmgr_vdev *vdev; 601 struct wlan_objmgr_pdev *pdev; 602 uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION; 603 604 if (!req || !req->vdev) { 605 scm_err("req or vdev within req is NULL"); 606 if (req) 607 qdf_mem_free(req); 608 return QDF_STATUS_E_NULL_VALUE; 609 } 610 611 if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL) 612 cancel_pdev = true; 613 else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL || 614 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) 615 cancel_vdev = true; 616 617 vdev = req->vdev; 618 status = ucfg_scan_cancel(req); 619 if (QDF_IS_STATUS_ERROR(status)) 620 return status; 621 622 if (cancel_pdev) { 623 pdev = wlan_vdev_get_pdev(vdev); 624 while ((ucfg_scan_get_pdev_status(pdev) != 625 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 626 scm_debug("wait for all pdev scan to get complete"); 627 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME); 628 max_wait_iterations--; 629 } 630 } else if (cancel_vdev) { 631 while ((ucfg_scan_get_vdev_status(vdev) != 632 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 633 scm_debug("wait for all vdev scan to get complete"); 634 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME); 635 max_wait_iterations--; 636 } 637 } 638 639 if (!max_wait_iterations) { 640 scm_err("Failed to wait for scans to get complete"); 641 return QDF_STATUS_E_TIMEOUT; 642 } 643 644 return status; 645 } 646 647 uint8_t* 648 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc, 649 wlan_scan_requester requester) 650 { 651 int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 652 struct wlan_scan_obj *scan; 653 struct scan_requester_info *requesters; 654 655 if (!psoc) { 656 scm_err("null psoc"); 657 return "null"; 658 } 659 scan = wlan_psoc_get_scan_obj(psoc); 660 if (!scan) 661 return "null"; 662 663 requesters = scan->requesters; 664 665 if ((idx < WLAN_MAX_REQUESTORS) && 666 (requesters[idx].requester == requester)) { 667 return requesters[idx].module; 668 } 669 670 return (uint8_t *)"unknown"; 671 } 672 673 static QDF_STATUS 674 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 675 scan_event_handler event_cb, void *arg) 676 { 677 struct cb_handler *cb_handler; 678 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 679 680 /* Assign next available slot to this registration request */ 681 cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]); 682 cb_handler->func = event_cb; 683 cb_handler->arg = arg; 684 pdev_ev_handler->handler_cnt++; 685 686 return QDF_STATUS_SUCCESS; 687 } 688 689 QDF_STATUS 690 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev, 691 scan_event_handler event_cb, void *arg) 692 { 693 uint32_t idx; 694 struct wlan_scan_obj *scan; 695 struct pdev_scan_ev_handler *pdev_ev_handler; 696 struct cb_handler *cb_handler; 697 698 /* scan event handler call back can't be NULL */ 699 if (!pdev || !event_cb) { 700 scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb); 701 return QDF_STATUS_E_NULL_VALUE; 702 } 703 704 scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg); 705 706 scan = wlan_pdev_get_scan_obj(pdev); 707 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 708 if (!pdev_ev_handler) { 709 scm_err("null pdev_ev_handler"); 710 return QDF_STATUS_E_NULL_VALUE; 711 } 712 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 713 714 qdf_spin_lock_bh(&scan->lock); 715 /* Ensure its not a duplicate registration request */ 716 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 717 idx++, cb_handler++) { 718 if ((cb_handler->func == event_cb) && 719 (cb_handler->arg == arg)) { 720 qdf_spin_unlock_bh(&scan->lock); 721 scm_debug("func: %pK, arg: %pK already exists", 722 event_cb, arg); 723 return QDF_STATUS_SUCCESS; 724 } 725 } 726 727 QDF_ASSERT(pdev_ev_handler->handler_cnt < 728 MAX_SCAN_EVENT_HANDLERS_PER_PDEV); 729 730 if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) { 731 qdf_spin_unlock_bh(&scan->lock); 732 scm_warn("No more registrations possible"); 733 return QDF_STATUS_E_NOMEM; 734 } 735 736 scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg); 737 qdf_spin_unlock_bh(&scan->lock); 738 739 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 740 741 return QDF_STATUS_SUCCESS; 742 } 743 744 static QDF_STATUS 745 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, 746 struct wlan_scan_obj *scan_obj) 747 { 748 scan_obj->scan_disabled = 0; 749 scan_obj->drop_bcn_on_chan_mismatch = 750 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH); 751 scan_obj->drop_bcn_on_invalid_freq = 752 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ); 753 scan_obj->disable_timeout = false; 754 scan_obj->scan_def.active_dwell = 755 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME); 756 /* the ini is disallow DFS channel scan if ini is 1, so negate that */ 757 scan_obj->scan_def.allow_dfs_chan_in_first_scan = 758 !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN); 759 scan_obj->scan_def.allow_dfs_chan_in_scan = 760 cfg_get(psoc, CFG_ENABLE_DFS_SCAN); 761 scan_obj->scan_def.skip_dfs_chan_in_p2p_search = 762 cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH); 763 scan_obj->scan_def.use_wake_lock_in_user_scan = 764 cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN); 765 scan_obj->scan_def.active_dwell_2g = 766 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME); 767 scan_obj->scan_def.active_dwell_6g = 768 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME); 769 scan_obj->scan_def.passive_dwell_6g = 770 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME); 771 scan_obj->scan_def.passive_dwell = 772 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME); 773 scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME; 774 scan_obj->scan_def.sta_miracast_mcc_rest_time = 775 SCAN_STA_MIRACAST_MCC_REST_TIME; 776 scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME; 777 scan_obj->scan_def.conc_active_dwell = 778 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC); 779 scan_obj->scan_def.conc_passive_dwell = 780 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC); 781 scan_obj->scan_def.conc_max_rest_time = 782 cfg_get(psoc, CFG_MAX_REST_TIME_CONC); 783 scan_obj->scan_def.conc_min_rest_time = 784 cfg_get(psoc, CFG_MIN_REST_TIME_CONC); 785 scan_obj->scan_def.conc_idle_time = 786 cfg_get(psoc, CFG_IDLE_TIME_CONC); 787 scan_obj->scan_def.repeat_probe_time = 788 cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME); 789 scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME; 790 scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY; 791 scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION; 792 scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME; 793 scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES); 794 scan_obj->scan_def.scan_cache_aging_time = 795 (cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000); 796 scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV; 797 scan_obj->scan_def.scan_priority = SCAN_PRIORITY; 798 scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT; 799 scan_obj->scan_def.adaptive_dwell_time_mode = 800 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE); 801 scan_obj->scan_def.adaptive_dwell_time_mode_nc = 802 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC); 803 scan_obj->scan_def.honour_nl_scan_policy_flags = 804 cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS); 805 scan_obj->scan_def.enable_mac_spoofing = 806 cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING); 807 scan_obj->scan_def.extscan_adaptive_dwell_mode = 808 cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 809 810 /* init burst durations */ 811 scan_obj->scan_def.sta_scan_burst_duration = 812 cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION); 813 scan_obj->scan_def.p2p_scan_burst_duration = 814 cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION); 815 scan_obj->scan_def.go_scan_burst_duration = 816 cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION); 817 scan_obj->scan_def.ap_scan_burst_duration = 818 cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION); 819 /* scan contrl flags */ 820 scan_obj->scan_def.scan_f_passive = true; 821 scan_obj->scan_def.scan_f_ofdm_rates = true; 822 scan_obj->scan_def.scan_f_2ghz = true; 823 scan_obj->scan_def.scan_f_5ghz = true; 824 scan_obj->scan_def.scan_f_chan_stat_evnt = 825 cfg_get(psoc, CFG_ENABLE_SNR_MONITORING); 826 /* scan event flags */ 827 scan_obj->scan_def.scan_ev_started = true; 828 scan_obj->scan_def.scan_ev_completed = true; 829 scan_obj->scan_def.scan_ev_bss_chan = true; 830 scan_obj->scan_def.scan_ev_foreign_chan = true; 831 scan_obj->scan_def.scan_ev_foreign_chn_exit = true; 832 scan_obj->scan_def.scan_ev_dequeued = true; 833 scan_obj->scan_def.scan_ev_preempted = true; 834 scan_obj->scan_def.scan_ev_start_failed = true; 835 scan_obj->scan_def.scan_ev_restarted = true; 836 scan_obj->scan_def.enable_connected_scan = 837 cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN); 838 scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE); 839 scan_obj->scan_def.duty_cycle_6ghz = 840 cfg_get(psoc, CFG_6GHZ_SCAN_MODE_DUTY_CYCLE); 841 scan_obj->allow_bss_with_incomplete_ie = 842 cfg_get(psoc, CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE); 843 /* init scan id seed */ 844 qdf_atomic_init(&scan_obj->scan_ids); 845 846 /* init extscan */ 847 wlan_extscan_global_init(psoc, scan_obj); 848 849 return wlan_pno_global_init(psoc, scan_obj); 850 } 851 852 static void 853 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc) 854 { 855 struct wlan_scan_obj *scan_obj; 856 857 scan_obj = wlan_psoc_get_scan_obj(psoc); 858 wlan_pno_global_deinit(scan_obj); 859 wlan_extscan_global_deinit(); 860 } 861 862 static QDF_STATUS 863 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 864 struct cb_handler *entry) 865 { 866 struct cb_handler *last_entry; 867 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 868 869 /* Replace event handler being deleted 870 * with the last one in the list. 871 */ 872 last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]); 873 entry->func = last_entry->func; 874 entry->arg = last_entry->arg; 875 876 /* Clear our last entry */ 877 last_entry->func = NULL; 878 last_entry->arg = NULL; 879 pdev_ev_handler->handler_cnt--; 880 881 return QDF_STATUS_SUCCESS; 882 } 883 884 void 885 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev, 886 scan_event_handler event_cb, void *arg) 887 { 888 uint8_t found = false; 889 uint32_t idx; 890 uint32_t handler_cnt; 891 struct wlan_scan_obj *scan; 892 struct cb_handler *cb_handler; 893 struct pdev_scan_ev_handler *pdev_ev_handler; 894 895 scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb, 896 arg); 897 if (!pdev) { 898 scm_err("null pdev"); 899 return; 900 } 901 scan = wlan_pdev_get_scan_obj(pdev); 902 if (!scan) 903 return; 904 905 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 906 if (!pdev_ev_handler) 907 return; 908 909 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 910 911 qdf_spin_lock_bh(&scan->lock); 912 handler_cnt = pdev_ev_handler->handler_cnt; 913 if (!handler_cnt) { 914 qdf_spin_unlock_bh(&scan->lock); 915 scm_info("No event handlers registered"); 916 return; 917 } 918 919 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 920 idx++, cb_handler++) { 921 if ((cb_handler->func == event_cb) && 922 (cb_handler->arg == arg)) { 923 /* Event handler found, remove it 924 * from event handler list. 925 */ 926 found = true; 927 scm_remove_scan_event_handler(pdev_ev_handler, 928 cb_handler); 929 handler_cnt--; 930 break; 931 } 932 } 933 qdf_spin_unlock_bh(&scan->lock); 934 935 scm_debug("event handler %s, remaining handlers: %d", 936 (found ? "removed" : "not found"), handler_cnt); 937 } 938 939 QDF_STATUS 940 ucfg_scan_init_ssid_params(struct scan_start_request *req, 941 uint32_t num_ssid, struct wlan_ssid *ssid_list) 942 { 943 uint32_t max_ssid = sizeof(req->scan_req.ssid) / 944 sizeof(req->scan_req.ssid[0]); 945 946 if (!req) { 947 scm_err("null request"); 948 return QDF_STATUS_E_NULL_VALUE; 949 } 950 if (!num_ssid) { 951 /* empty channel list provided */ 952 req->scan_req.num_ssids = 0; 953 qdf_mem_zero(&req->scan_req.ssid[0], 954 sizeof(req->scan_req.ssid)); 955 return QDF_STATUS_SUCCESS; 956 } 957 if (!ssid_list) { 958 scm_err("null ssid_list while num_ssid: %d", num_ssid); 959 return QDF_STATUS_E_NULL_VALUE; 960 } 961 if (num_ssid > max_ssid) { 962 /* got a big list. alert and continue */ 963 scm_warn("overflow: received %d, max supported : %d", 964 num_ssid, max_ssid); 965 return QDF_STATUS_E_E2BIG; 966 } 967 968 if (max_ssid > num_ssid) 969 max_ssid = num_ssid; 970 971 req->scan_req.num_ssids = max_ssid; 972 qdf_mem_copy(&req->scan_req.ssid[0], ssid_list, 973 (req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0]))); 974 975 return QDF_STATUS_SUCCESS; 976 } 977 978 QDF_STATUS 979 ucfg_scan_init_bssid_params(struct scan_start_request *req, 980 uint32_t num_bssid, struct qdf_mac_addr *bssid_list) 981 { 982 uint32_t max_bssid = sizeof(req->scan_req.bssid_list) / 983 sizeof(req->scan_req.bssid_list[0]); 984 985 if (!req) { 986 scm_err("null request"); 987 return QDF_STATUS_E_NULL_VALUE; 988 } 989 if (!num_bssid) { 990 /* empty channel list provided */ 991 req->scan_req.num_bssid = 0; 992 qdf_mem_zero(&req->scan_req.bssid_list[0], 993 sizeof(req->scan_req.bssid_list)); 994 return QDF_STATUS_SUCCESS; 995 } 996 if (!bssid_list) { 997 scm_err("null bssid_list while num_bssid: %d", num_bssid); 998 return QDF_STATUS_E_NULL_VALUE; 999 } 1000 if (num_bssid > max_bssid) { 1001 /* got a big list. alert and continue */ 1002 scm_warn("overflow: received %d, max supported : %d", 1003 num_bssid, max_bssid); 1004 return QDF_STATUS_E_E2BIG; 1005 } 1006 1007 if (max_bssid > num_bssid) 1008 max_bssid = num_bssid; 1009 1010 req->scan_req.num_bssid = max_bssid; 1011 qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list, 1012 req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0])); 1013 1014 return QDF_STATUS_SUCCESS; 1015 } 1016 1017 /** 1018 * is_chan_enabled_for_scan() - helper API to check if a frequency 1019 * is allowed to scan. 1020 * @reg_chan: regulatory_channel object 1021 * @low_2g: lower 2.4 GHz frequency thresold 1022 * @high_2g: upper 2.4 GHz frequency thresold 1023 * @low_5g: lower 5 GHz frequency thresold 1024 * @high_5g: upper 5 GHz frequency thresold 1025 * 1026 * Return: true if scan is allowed. false otherwise. 1027 */ 1028 static bool 1029 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan, 1030 qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g, 1031 qdf_freq_t high_5g) 1032 { 1033 if (reg_chan->state == CHANNEL_STATE_DISABLE) 1034 return false; 1035 if (reg_chan->nol_chan) 1036 return false; 1037 /* 2 GHz channel */ 1038 if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1039 WLAN_BAND_2_4_GHZ) && 1040 ((reg_chan->center_freq < low_2g) || 1041 (reg_chan->center_freq > high_2g))) 1042 return false; 1043 else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1044 WLAN_BAND_5_GHZ) && 1045 ((reg_chan->center_freq < low_5g) || 1046 (reg_chan->center_freq > high_5g))) 1047 return false; 1048 1049 return true; 1050 } 1051 1052 QDF_STATUS 1053 ucfg_scan_init_chanlist_params(struct scan_start_request *req, 1054 uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode) 1055 { 1056 uint32_t idx; 1057 QDF_STATUS status; 1058 struct regulatory_channel *reg_chan_list = NULL; 1059 qdf_freq_t low_2g, high_2g, low_5g, high_5g; 1060 struct wlan_objmgr_pdev *pdev = NULL; 1061 uint32_t *scan_freqs = NULL; 1062 uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / 1063 sizeof(req->scan_req.chan_list.chan[0]); 1064 if (!req) { 1065 scm_err("null request"); 1066 return QDF_STATUS_E_NULL_VALUE; 1067 } 1068 1069 if (req->vdev) 1070 pdev = wlan_vdev_get_pdev(req->vdev); 1071 /* 1072 * If 0 channels are provided for scan and 1073 * wide band scan is enabled, scan all 20 mhz 1074 * available channels. This is required as FW 1075 * scans all channel/phy mode combinations 1076 * provided in scan channel list if 0 chans are 1077 * provided in scan request causing scan to take 1078 * too much time to complete. 1079 */ 1080 if (pdev && !num_chans) { 1081 reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS * 1082 sizeof(struct regulatory_channel)); 1083 if (!reg_chan_list) { 1084 status = QDF_STATUS_E_NOMEM; 1085 goto end; 1086 } 1087 scan_freqs = 1088 qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans); 1089 if (!scan_freqs) { 1090 status = QDF_STATUS_E_NOMEM; 1091 goto end; 1092 } 1093 status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list); 1094 if (QDF_IS_STATUS_ERROR(status)) 1095 goto end; 1096 1097 status = wlan_reg_get_freq_range(pdev, &low_2g, 1098 &high_2g, &low_5g, &high_5g); 1099 if (QDF_IS_STATUS_ERROR(status)) 1100 goto end; 1101 1102 for (idx = 0, num_chans = 0; 1103 (idx < NUM_CHANNELS && num_chans < max_chans); idx++) 1104 if (is_chan_enabled_for_scan(®_chan_list[idx], 1105 low_2g, high_2g, low_5g, high_5g)) 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 static inline enum scm_scan_status 1167 get_scan_status_from_serialization_status( 1168 enum wlan_serialization_cmd_status status) 1169 { 1170 enum scm_scan_status scan_status; 1171 1172 switch (status) { 1173 case WLAN_SER_CMD_IN_PENDING_LIST: 1174 scan_status = SCAN_IS_PENDING; 1175 break; 1176 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1177 scan_status = SCAN_IS_ACTIVE; 1178 break; 1179 case WLAN_SER_CMDS_IN_ALL_LISTS: 1180 scan_status = SCAN_IS_ACTIVE_AND_PENDING; 1181 break; 1182 case WLAN_SER_CMD_NOT_FOUND: 1183 scan_status = SCAN_NOT_IN_PROGRESS; 1184 break; 1185 default: 1186 scm_warn("invalid serialization status %d", status); 1187 QDF_ASSERT(0); 1188 scan_status = SCAN_NOT_IN_PROGRESS; 1189 break; 1190 } 1191 1192 return scan_status; 1193 } 1194 1195 enum scm_scan_status 1196 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev) 1197 { 1198 enum wlan_serialization_cmd_status status; 1199 1200 if (!vdev) { 1201 scm_err("null vdev"); 1202 return SCAN_NOT_IN_PROGRESS; 1203 } 1204 status = wlan_serialization_vdev_scan_status(vdev); 1205 1206 return get_scan_status_from_serialization_status(status); 1207 } 1208 1209 enum scm_scan_status 1210 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev) 1211 { 1212 enum wlan_serialization_cmd_status status; 1213 1214 if (!pdev) { 1215 scm_err("null pdev"); 1216 return SCAN_NOT_IN_PROGRESS; 1217 } 1218 status = wlan_serialization_pdev_scan_status(pdev); 1219 1220 return get_scan_status_from_serialization_status(status); 1221 } 1222 1223 static void 1224 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc, 1225 bool enable) 1226 { 1227 QDF_STATUS status; 1228 struct mgmt_txrx_mgmt_frame_cb_info cb_info[2]; 1229 1230 cb_info[0].frm_type = MGMT_PROBE_RESP; 1231 cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1232 cb_info[1].frm_type = MGMT_BEACON; 1233 cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1234 1235 if (enable) 1236 status = wlan_mgmt_txrx_register_rx_cb(psoc, 1237 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1238 else 1239 status = wlan_mgmt_txrx_deregister_rx_cb(psoc, 1240 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1241 if (status != QDF_STATUS_SUCCESS) 1242 scm_err("%s the Handle with MGMT TXRX layer has failed", 1243 enable ? "Registering" : "Deregistering"); 1244 } 1245 1246 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc, 1247 struct scan_user_cfg *scan_cfg) 1248 { 1249 struct wlan_scan_obj *scan_obj; 1250 struct scan_default_params *scan_def; 1251 1252 if (!psoc) { 1253 scm_err("null psoc"); 1254 return QDF_STATUS_E_FAILURE; 1255 } 1256 scan_obj = wlan_psoc_get_scan_obj(psoc); 1257 if (!scan_obj) { 1258 scm_err("Failed to get scan object"); 1259 return QDF_STATUS_E_FAILURE; 1260 } 1261 1262 scan_def = &scan_obj->scan_def; 1263 scan_obj->ie_whitelist = scan_cfg->ie_whitelist; 1264 scan_def->sta_miracast_mcc_rest_time = 1265 scan_cfg->sta_miracast_mcc_rest_time; 1266 1267 return QDF_STATUS_SUCCESS; 1268 } 1269 1270 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 1271 static QDF_STATUS 1272 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) 1273 { 1274 struct scan_cancel_request *req; 1275 QDF_STATUS status; 1276 struct wlan_objmgr_vdev *vdev; 1277 1278 req = qdf_mem_malloc_atomic(sizeof(*req)); 1279 if (!req) { 1280 scm_err("Failed to allocate memory"); 1281 return QDF_STATUS_E_NOMEM; 1282 } 1283 1284 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID); 1285 if (!vdev) { 1286 scm_err("Failed to get vdev"); 1287 qdf_mem_free(req); 1288 return QDF_STATUS_E_INVAL; 1289 } 1290 req->vdev = vdev; 1291 req->cancel_req.scan_id = INVAL_SCAN_ID; 1292 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1293 req->cancel_req.vdev_id = INVAL_VDEV_ID; 1294 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 1295 status = ucfg_scan_cancel_sync(req); 1296 if (QDF_IS_STATUS_ERROR(status)) 1297 scm_err("Cancel scan request failed"); 1298 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1299 1300 return status; 1301 } 1302 1303 static QDF_STATUS 1304 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1305 { 1306 struct wlan_objmgr_pdev *pdev = NULL; 1307 QDF_STATUS status = QDF_STATUS_SUCCESS; 1308 int i; 1309 1310 ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND); 1311 /* Check all pdev */ 1312 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 1313 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); 1314 if (!pdev) 1315 continue; 1316 if (ucfg_scan_get_pdev_status(pdev) != 1317 SCAN_NOT_IN_PROGRESS) 1318 status = ucfg_scan_cancel_pdev_scan(pdev); 1319 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 1320 if (QDF_IS_STATUS_ERROR(status)) { 1321 scm_err("failed to cancel scan for pdev_id %d", i); 1322 return status; 1323 } 1324 } 1325 1326 return QDF_STATUS_SUCCESS; 1327 } 1328 1329 static QDF_STATUS 1330 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1331 { 1332 ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND); 1333 return QDF_STATUS_SUCCESS; 1334 } 1335 1336 static inline void 1337 ucfg_scan_register_pmo_handler(void) 1338 { 1339 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN, 1340 ucfg_scan_suspend_handler, NULL); 1341 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN, 1342 ucfg_scan_resume_handler, NULL); 1343 } 1344 1345 static inline void 1346 ucfg_scan_unregister_pmo_handler(void) 1347 { 1348 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN, 1349 ucfg_scan_suspend_handler); 1350 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN, 1351 ucfg_scan_resume_handler); 1352 } 1353 1354 #else 1355 static inline void 1356 ucfg_scan_register_pmo_handler(void) 1357 { 1358 } 1359 1360 static inline void 1361 ucfg_scan_unregister_pmo_handler(void) 1362 { 1363 } 1364 #endif 1365 1366 QDF_STATUS 1367 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) 1368 { 1369 struct wlan_scan_obj *scan_obj; 1370 1371 scm_debug("psoc open: 0x%pK", psoc); 1372 if (!psoc) { 1373 scm_err("null psoc"); 1374 return QDF_STATUS_E_FAILURE; 1375 } 1376 scan_obj = wlan_psoc_get_scan_obj(psoc); 1377 if (!scan_obj) { 1378 scm_err("Failed to get scan object"); 1379 return QDF_STATUS_E_FAILURE; 1380 } 1381 /* Initialize the scan Globals */ 1382 wlan_scan_global_init(psoc, scan_obj); 1383 qdf_spinlock_create(&scan_obj->lock); 1384 ucfg_scan_register_pmo_handler(); 1385 scm_db_init(psoc); 1386 scm_channel_list_db_init(psoc); 1387 1388 return QDF_STATUS_SUCCESS; 1389 } 1390 1391 QDF_STATUS 1392 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) 1393 { 1394 struct wlan_scan_obj *scan_obj; 1395 1396 scm_debug("psoc close: 0x%pK", psoc); 1397 if (!psoc) { 1398 scm_err("null psoc"); 1399 return QDF_STATUS_E_FAILURE; 1400 } 1401 scm_db_deinit(psoc); 1402 scan_obj = wlan_psoc_get_scan_obj(psoc); 1403 if (!scan_obj) { 1404 scm_err("Failed to get scan object"); 1405 return QDF_STATUS_E_FAILURE; 1406 } 1407 ucfg_scan_unregister_pmo_handler(); 1408 qdf_spinlock_destroy(&scan_obj->lock); 1409 wlan_scan_global_deinit(psoc); 1410 scm_channel_list_db_deinit(psoc); 1411 1412 return QDF_STATUS_SUCCESS; 1413 } 1414 1415 static bool scm_serialization_scan_rules_cb( 1416 union wlan_serialization_rules_info *comp_info, 1417 uint8_t comp_id) 1418 { 1419 switch (comp_id) { 1420 case WLAN_UMAC_COMP_TDLS: 1421 if (comp_info->scan_info.is_tdls_in_progress) { 1422 scm_debug("Cancel scan. Tdls in progress"); 1423 return false; 1424 } 1425 break; 1426 case WLAN_UMAC_COMP_DFS: 1427 if (comp_info->scan_info.is_cac_in_progress) { 1428 scm_debug("Cancel scan. CAC in progress"); 1429 return false; 1430 } 1431 break; 1432 case WLAN_UMAC_COMP_MLME: 1433 if (comp_info->scan_info.is_scan_for_connect) { 1434 scm_debug("Allow scan request from connect"); 1435 return true; 1436 } 1437 1438 if (comp_info->scan_info.is_mlme_op_in_progress) { 1439 scm_debug("Cancel scan. MLME operation in progress"); 1440 return false; 1441 } 1442 break; 1443 default: 1444 scm_debug("not handled comp_id %d", comp_id); 1445 break; 1446 } 1447 1448 return true; 1449 } 1450 1451 QDF_STATUS 1452 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) 1453 { 1454 QDF_STATUS status; 1455 1456 scm_debug("psoc enable: 0x%pK", psoc); 1457 if (!psoc) { 1458 scm_err("null psoc"); 1459 return QDF_STATUS_E_FAILURE; 1460 } 1461 /* Subscribe for scan events from lmac layesr */ 1462 status = tgt_scan_register_ev_handler(psoc); 1463 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1464 if (!wlan_reg_is_11d_offloaded(psoc)) 1465 scm_11d_cc_db_init(psoc); 1466 ucfg_scan_register_unregister_bcn_cb(psoc, true); 1467 status = wlan_serialization_register_apply_rules_cb(psoc, 1468 WLAN_SER_CMD_SCAN, 1469 scm_serialization_scan_rules_cb); 1470 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1471 return status; 1472 } 1473 1474 QDF_STATUS 1475 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) 1476 { 1477 QDF_STATUS status; 1478 1479 scm_debug("psoc disable: 0x%pK", psoc); 1480 if (!psoc) { 1481 scm_err("null psoc"); 1482 return QDF_STATUS_E_FAILURE; 1483 } 1484 /* Unsubscribe for scan events from lmac layesr */ 1485 status = tgt_scan_unregister_ev_handler(psoc); 1486 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1487 ucfg_scan_register_unregister_bcn_cb(psoc, false); 1488 if (!wlan_reg_is_11d_offloaded(psoc)) 1489 scm_11d_cc_db_deinit(psoc); 1490 1491 return status; 1492 } 1493 1494 uint32_t 1495 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc) 1496 { 1497 struct scan_default_params *scan_params = NULL; 1498 1499 if (!psoc) { 1500 scm_err("null psoc"); 1501 return 0; 1502 } 1503 scan_params = wlan_scan_psoc_get_def_params(psoc); 1504 if (!scan_params) { 1505 scm_err("Failed to get scan object"); 1506 return 0; 1507 } 1508 1509 return scan_params->max_active_scans_allowed; 1510 } 1511 1512 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc, 1513 struct probe_req_whitelist_attr *ie_whitelist) 1514 { 1515 struct wlan_scan_obj *scan_obj = NULL; 1516 1517 scan_obj = wlan_psoc_get_scan_obj(psoc); 1518 if (!scan_obj) 1519 return false; 1520 1521 qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist, 1522 sizeof(*ie_whitelist)); 1523 1524 return true; 1525 } 1526 1527 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc, 1528 struct wlan_objmgr_vdev *vdev) 1529 { 1530 struct wlan_scan_obj *scan_obj = NULL; 1531 1532 scan_obj = wlan_psoc_get_scan_obj(psoc); 1533 if (!scan_obj) 1534 return false; 1535 1536 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || 1537 wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS) 1538 return false; 1539 1540 if (!scan_obj->ie_whitelist.white_list) 1541 return false; 1542 1543 return true; 1544 } 1545 1546 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, 1547 bool bt_a2dp_active) 1548 { 1549 struct wlan_scan_obj *scan_obj; 1550 1551 scan_obj = wlan_psoc_get_scan_obj(psoc); 1552 if (!scan_obj) { 1553 scm_err("Failed to get scan object"); 1554 return; 1555 } 1556 scan_obj->bt_a2dp_enabled = bt_a2dp_active; 1557 } 1558 1559 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) 1560 { 1561 struct wlan_scan_obj *scan_obj; 1562 1563 scan_obj = wlan_psoc_get_scan_obj(psoc); 1564 if (!scan_obj) { 1565 scm_err("Failed to get scan object"); 1566 return false; 1567 } 1568 1569 return scan_obj->bt_a2dp_enabled; 1570 } 1571 1572 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc) 1573 { 1574 struct wlan_scan_obj *scan_obj; 1575 1576 scan_obj = wlan_psoc_get_scan_obj(psoc); 1577 if (!scan_obj) 1578 return false; 1579 1580 return scan_obj->scan_def.use_wake_lock_in_user_scan; 1581 } 1582 1583 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc) 1584 { 1585 struct wlan_scan_obj *scan_obj; 1586 1587 scan_obj = wlan_psoc_get_scan_obj(psoc); 1588 if (!scan_obj) { 1589 scm_err("Failed to get scan object"); 1590 return cfg_default(CFG_ENABLE_CONNECTED_SCAN); 1591 } 1592 1593 return scan_obj->scan_def.enable_connected_scan; 1594 } 1595 1596 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc) 1597 { 1598 struct wlan_scan_obj *scan_obj; 1599 1600 scan_obj = wlan_psoc_get_scan_obj(psoc); 1601 if (!scan_obj) { 1602 scm_err("Failed to get scan object"); 1603 return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING); 1604 } 1605 1606 return scan_obj->scan_def.enable_mac_spoofing; 1607 } 1608 1609 enum scan_dwelltime_adaptive_mode 1610 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc) 1611 { 1612 struct wlan_scan_obj *scan_obj; 1613 1614 scan_obj = wlan_psoc_get_scan_obj(psoc); 1615 if (!scan_obj) { 1616 scm_err("Failed to get scan object"); 1617 return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 1618 } 1619 1620 return scan_obj->scan_def.extscan_adaptive_dwell_mode; 1621 } 1622 1623 QDF_STATUS 1624 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, 1625 enum scan_config config, uint32_t val) 1626 { 1627 struct wlan_scan_obj *scan_obj; 1628 QDF_STATUS status = QDF_STATUS_SUCCESS; 1629 1630 scan_obj = wlan_psoc_get_scan_obj(psoc); 1631 if (!scan_obj) { 1632 scm_err("Failed to get scan object config:%d, val:%d", 1633 config, val); 1634 return QDF_STATUS_E_INVAL; 1635 } 1636 switch (config) { 1637 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1638 scan_obj->disable_timeout = !!val; 1639 break; 1640 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1641 scan_obj->drop_bcn_on_chan_mismatch = !!val; 1642 break; 1643 1644 default: 1645 status = QDF_STATUS_E_INVAL; 1646 break; 1647 } 1648 1649 return status; 1650 } 1651 1652 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev, 1653 struct bss_info *bss_info, struct mlme_info *mlme) 1654 { 1655 QDF_STATUS status; 1656 1657 status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme); 1658 1659 return status; 1660 } 1661 1662 QDF_STATUS 1663 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc, 1664 enum scan_config config, uint32_t *val) 1665 { 1666 struct wlan_scan_obj *scan_obj; 1667 QDF_STATUS status = QDF_STATUS_SUCCESS; 1668 1669 scan_obj = wlan_psoc_get_scan_obj(psoc); 1670 if (!scan_obj || !val) { 1671 scm_err("scan object:%pK config:%d, val:0x%pK", 1672 scan_obj, config, val); 1673 return QDF_STATUS_E_INVAL; 1674 } 1675 switch (config) { 1676 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1677 *val = scan_obj->disable_timeout; 1678 break; 1679 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1680 *val = scan_obj->drop_bcn_on_chan_mismatch; 1681 break; 1682 1683 default: 1684 status = QDF_STATUS_E_INVAL; 1685 break; 1686 } 1687 1688 return status; 1689 } 1690 1691 #ifdef FEATURE_WLAN_SCAN_PNO 1692 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc) 1693 { 1694 struct wlan_scan_obj *scan_obj; 1695 1696 scan_obj = wlan_psoc_get_scan_obj(psoc); 1697 if (!scan_obj) { 1698 scm_err("NULL scan obj"); 1699 return false; 1700 } 1701 1702 return scan_obj->pno_cfg.pno_offload_enabled; 1703 } 1704 1705 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value) 1706 { 1707 struct wlan_scan_obj *scan_obj; 1708 1709 scan_obj = wlan_psoc_get_scan_obj(psoc); 1710 if (!scan_obj) { 1711 scm_err("NULL scan obj"); 1712 return; 1713 } 1714 1715 scan_obj->pno_cfg.pno_offload_enabled = value; 1716 } 1717 1718 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc) 1719 { 1720 struct wlan_scan_obj *scan_obj; 1721 1722 scan_obj = wlan_psoc_get_scan_obj(psoc); 1723 if (!scan_obj) { 1724 scm_err("NULL scan obj"); 1725 return cfg_default(CFG_PNO_SCAN_SUPPORT); 1726 } 1727 1728 return scan_obj->pno_cfg.scan_support_enabled; 1729 } 1730 1731 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc) 1732 { 1733 struct wlan_scan_obj *scan_obj; 1734 1735 scan_obj = wlan_psoc_get_scan_obj(psoc); 1736 if (!scan_obj) { 1737 scm_err("NULL scan obj"); 1738 return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER); 1739 } 1740 return scan_obj->pno_cfg.scan_backoff_multiplier; 1741 } 1742 1743 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc) 1744 { 1745 struct wlan_scan_obj *scan_obj; 1746 1747 scan_obj = wlan_psoc_get_scan_obj(psoc); 1748 if (!scan_obj) { 1749 scm_err("NULL scan obj"); 1750 return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN); 1751 } 1752 return scan_obj->pno_cfg.dfs_chnl_scan_enabled; 1753 } 1754 1755 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc) 1756 { 1757 struct wlan_scan_obj *scan_obj; 1758 1759 scan_obj = wlan_psoc_get_scan_obj(psoc); 1760 if (!scan_obj) { 1761 scm_err("NULL scan obj"); 1762 return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 1763 } 1764 return scan_obj->pno_cfg.scan_timer_repeat_value; 1765 } 1766 1767 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc) 1768 { 1769 struct wlan_scan_obj *scan_obj; 1770 1771 scan_obj = wlan_psoc_get_scan_obj(psoc); 1772 if (!scan_obj) { 1773 scm_err("NULL scan obj"); 1774 return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER); 1775 } 1776 return scan_obj->pno_cfg.slow_scan_multiplier; 1777 } 1778 1779 uint32_t 1780 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc) 1781 { 1782 struct wlan_scan_obj *scan_obj; 1783 1784 scan_obj = wlan_psoc_get_scan_obj(psoc); 1785 if (!scan_obj) { 1786 scm_err("Failed to get scan object"); 1787 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); 1788 } 1789 1790 return scan_obj->pno_cfg.max_sched_scan_plan_interval; 1791 } 1792 1793 uint32_t 1794 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc) 1795 { 1796 struct wlan_scan_obj *scan_obj; 1797 1798 scan_obj = wlan_psoc_get_scan_obj(psoc); 1799 if (!scan_obj) { 1800 scm_err("Failed to get scan object"); 1801 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 1802 } 1803 1804 return scan_obj->pno_cfg.max_sched_scan_plan_iterations; 1805 } 1806 1807 #endif 1808