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_scan_start(struct scan_start_request *req) 434 { 435 struct scheduler_msg msg = {0}; 436 QDF_STATUS status; 437 438 if (!req || !req->vdev) { 439 scm_err("req or vdev within req is NULL"); 440 if (req) 441 scm_scan_free_scan_request_mem(req); 442 return QDF_STATUS_E_NULL_VALUE; 443 } 444 445 if (!scm_is_scan_allowed(req->vdev)) { 446 scm_err_rl("scan disabled, rejecting the scan req"); 447 scm_scan_free_scan_request_mem(req); 448 return QDF_STATUS_E_AGAIN; 449 } 450 451 /* Try to get vdev reference. Return if reference could 452 * not be taken. Reference will be released once scan 453 * request handling completes along with free of @req. 454 */ 455 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 456 if (QDF_IS_STATUS_ERROR(status)) { 457 scm_info("unable to get reference"); 458 scm_scan_free_scan_request_mem(req); 459 return status; 460 } 461 462 msg.bodyptr = req; 463 msg.callback = scm_scan_start_req; 464 msg.flush_callback = scm_scan_start_flush_callback; 465 466 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 467 QDF_MODULE_ID_SCAN, 468 QDF_MODULE_ID_OS_IF, &msg); 469 if (QDF_IS_STATUS_ERROR(status)) { 470 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 471 scm_scan_free_scan_request_mem(req); 472 } 473 474 return status; 475 } 476 477 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, 478 enum scan_disable_reason reason) 479 { 480 struct wlan_scan_obj *scan_obj; 481 482 scan_obj = wlan_psoc_get_scan_obj(psoc); 483 if (!scan_obj) { 484 scm_err("Failed to get scan object"); 485 return QDF_STATUS_E_NULL_VALUE; 486 } 487 488 scan_obj->scan_disabled &= ~reason; 489 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 490 491 return QDF_STATUS_SUCCESS; 492 } 493 494 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, 495 enum scan_disable_reason reason) 496 { 497 struct wlan_scan_obj *scan_obj; 498 499 scan_obj = wlan_psoc_get_scan_obj(psoc); 500 if (!scan_obj) { 501 scm_err("Failed to get scan object"); 502 return QDF_STATUS_E_NULL_VALUE; 503 } 504 505 scan_obj->scan_disabled |= reason; 506 507 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 508 509 return QDF_STATUS_SUCCESS; 510 } 511 512 513 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, 514 enum scan_disable_reason reason) 515 { 516 struct scan_vdev_obj *scan_vdev_obj; 517 518 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 519 if (!scan_vdev_obj) { 520 scm_err("null scan_vdev_obj"); 521 return QDF_STATUS_E_NULL_VALUE; 522 } 523 524 scan_vdev_obj->scan_disabled &= ~reason; 525 526 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 527 528 return QDF_STATUS_SUCCESS; 529 } 530 531 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, 532 enum scan_disable_reason reason) 533 { 534 struct scan_vdev_obj *scan_vdev_obj; 535 536 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 537 if (!scan_vdev_obj) { 538 scm_err("null scan_vdev_obj"); 539 return QDF_STATUS_E_NULL_VALUE; 540 } 541 542 scan_vdev_obj->scan_disabled |= reason; 543 544 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 545 546 return QDF_STATUS_SUCCESS; 547 } 548 549 550 QDF_STATUS ucfg_scan_set_miracast( 551 struct wlan_objmgr_psoc *psoc, bool enable) 552 { 553 struct wlan_scan_obj *scan_obj; 554 555 scan_obj = wlan_psoc_get_scan_obj(psoc); 556 if (!scan_obj) { 557 scm_err("Failed to get scan object"); 558 return QDF_STATUS_E_NULL_VALUE; 559 } 560 scan_obj->miracast_enabled = enable; 561 scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled); 562 563 return QDF_STATUS_SUCCESS; 564 } 565 566 QDF_STATUS 567 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable) 568 { 569 uint8_t pdev_id; 570 struct wlan_scan_obj *scan_obj; 571 572 if (!pdev) { 573 scm_warn("null vdev"); 574 return QDF_STATUS_E_NULL_VALUE; 575 } 576 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 577 scan_obj = wlan_pdev_get_scan_obj(pdev); 578 if (!scan_obj) 579 return QDF_STATUS_E_FAILURE; 580 581 scm_debug("set wide_band_scan to %d", enable); 582 scan_obj->pdev_info[pdev_id].wide_band_scan = enable; 583 584 return QDF_STATUS_SUCCESS; 585 } 586 587 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev) 588 { 589 uint8_t pdev_id; 590 struct wlan_scan_obj *scan_obj; 591 592 if (!pdev) { 593 scm_warn("null vdev"); 594 return QDF_STATUS_E_NULL_VALUE; 595 } 596 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 597 scan_obj = wlan_pdev_get_scan_obj(pdev); 598 if (!scan_obj) 599 return QDF_STATUS_E_FAILURE; 600 601 return scan_obj->pdev_info[pdev_id].wide_band_scan; 602 } 603 604 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 605 QDF_STATUS 606 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev, 607 uint8_t *bssid, struct wlan_ssid *ssid) 608 { 609 uint8_t pdev_id; 610 struct wlan_scan_obj *scan_obj; 611 612 if (!pdev) { 613 scm_warn("null vdev"); 614 return QDF_STATUS_E_NULL_VALUE; 615 } 616 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 617 scan_obj = wlan_pdev_get_scan_obj(pdev); 618 if (!scan_obj) 619 return QDF_STATUS_E_FAILURE; 620 621 scm_debug("Configure bsssid:%pM ssid:%.*s", 622 bssid, ssid->length, ssid->ssid); 623 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid, 624 bssid, QDF_MAC_ADDR_SIZE); 625 scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length; 626 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid, 627 ssid->ssid, 628 scan_obj->pdev_info[pdev_id].conf_ssid.length); 629 630 return QDF_STATUS_SUCCESS; 631 } 632 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 633 634 QDF_STATUS 635 ucfg_scan_cancel(struct scan_cancel_request *req) 636 { 637 struct scheduler_msg msg = {0}; 638 QDF_STATUS status; 639 640 if (!req || !req->vdev) { 641 scm_err("req or vdev within req is NULL"); 642 if (req) 643 qdf_mem_free(req); 644 return QDF_STATUS_E_NULL_VALUE; 645 } 646 647 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 648 if (QDF_IS_STATUS_ERROR(status)) { 649 scm_info("Failed to get vdev ref; status:%d", status); 650 goto req_free; 651 } 652 653 msg.bodyptr = req; 654 msg.callback = scm_scan_cancel_req; 655 msg.flush_callback = scm_scan_cancel_flush_callback; 656 657 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 658 QDF_MODULE_ID_SCAN, 659 QDF_MODULE_ID_OS_IF, &msg); 660 if (QDF_IS_STATUS_ERROR(status)) 661 goto vdev_put; 662 663 return QDF_STATUS_SUCCESS; 664 665 vdev_put: 666 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 667 668 req_free: 669 qdf_mem_free(req); 670 671 return status; 672 } 673 674 QDF_STATUS 675 ucfg_scan_cancel_sync(struct scan_cancel_request *req) 676 { 677 QDF_STATUS status; 678 bool cancel_vdev = false, cancel_pdev = false; 679 struct wlan_objmgr_vdev *vdev; 680 struct wlan_objmgr_pdev *pdev; 681 uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION; 682 683 if (!req || !req->vdev) { 684 scm_err("req or vdev within req is NULL"); 685 if (req) 686 qdf_mem_free(req); 687 return QDF_STATUS_E_NULL_VALUE; 688 } 689 690 if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL) 691 cancel_pdev = true; 692 else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL || 693 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) 694 cancel_vdev = true; 695 696 vdev = req->vdev; 697 status = ucfg_scan_cancel(req); 698 if (QDF_IS_STATUS_ERROR(status)) 699 return status; 700 701 if (cancel_pdev) { 702 pdev = wlan_vdev_get_pdev(vdev); 703 while ((ucfg_scan_get_pdev_status(pdev) != 704 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 705 scm_debug("wait for all pdev scan to get complete"); 706 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME); 707 max_wait_iterations--; 708 } 709 } else if (cancel_vdev) { 710 while ((ucfg_scan_get_vdev_status(vdev) != 711 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 712 scm_debug("wait for all vdev scan to get complete"); 713 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME); 714 max_wait_iterations--; 715 } 716 } 717 718 if (!max_wait_iterations) { 719 scm_err("Failed to wait for scans to get complete"); 720 return QDF_STATUS_E_TIMEOUT; 721 } 722 723 return status; 724 } 725 726 wlan_scan_requester 727 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc, 728 uint8_t *name, scan_event_handler event_cb, void *arg) 729 { 730 int i, j; 731 struct wlan_scan_obj *scan; 732 struct scan_requester_info *requesters; 733 wlan_scan_requester requester = {0}; 734 735 if (!psoc) { 736 scm_err("null psoc"); 737 return 0; 738 } 739 scan = wlan_psoc_get_scan_obj(psoc); 740 if (!scan) 741 return 0; 742 743 requesters = scan->requesters; 744 qdf_spin_lock_bh(&scan->lock); 745 for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) { 746 if (requesters[i].requester == 0) { 747 requesters[i].requester = 748 WLAN_SCAN_REQUESTER_ID_PREFIX | i; 749 j = 0; 750 while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) { 751 requesters[i].module[j] = name[j]; 752 ++j; 753 } 754 requesters[i].module[j] = 0; 755 requesters[i].ev_handler.func = event_cb; 756 requesters[i].ev_handler.arg = arg; 757 requester = requesters[i].requester; 758 break; 759 } 760 } 761 qdf_spin_unlock_bh(&scan->lock); 762 scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d", 763 name, event_cb, arg, requester); 764 765 return requester; 766 } 767 768 void 769 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc, 770 wlan_scan_requester requester) 771 { 772 int idx; 773 struct wlan_scan_obj *scan; 774 struct scan_requester_info *requesters; 775 776 idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX; 777 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) { 778 scm_err("prefix didn't match for requester id %d", requester); 779 return; 780 } 781 782 idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 783 if (idx >= WLAN_MAX_REQUESTORS) { 784 scm_err("requester id %d greater than max value", requester); 785 return; 786 } 787 788 if (!psoc) { 789 scm_err("null psoc"); 790 return; 791 } 792 scan = wlan_psoc_get_scan_obj(psoc); 793 if (!scan) 794 return; 795 requesters = scan->requesters; 796 scm_debug("reqid: %d", requester); 797 798 qdf_spin_lock_bh(&scan->lock); 799 requesters[idx].requester = 0; 800 requesters[idx].module[0] = 0; 801 requesters[idx].ev_handler.func = NULL; 802 requesters[idx].ev_handler.arg = NULL; 803 qdf_spin_unlock_bh(&scan->lock); 804 } 805 806 uint8_t* 807 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc, 808 wlan_scan_requester requester) 809 { 810 int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 811 struct wlan_scan_obj *scan; 812 struct scan_requester_info *requesters; 813 814 if (!psoc) { 815 scm_err("null psoc"); 816 return "null"; 817 } 818 scan = wlan_psoc_get_scan_obj(psoc); 819 if (!scan) 820 return "null"; 821 822 requesters = scan->requesters; 823 824 if ((idx < WLAN_MAX_REQUESTORS) && 825 (requesters[idx].requester == requester)) { 826 return requesters[idx].module; 827 } 828 829 return (uint8_t *)"unknown"; 830 } 831 832 wlan_scan_id 833 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc) 834 { 835 wlan_scan_id id; 836 struct wlan_scan_obj *scan; 837 838 if (!psoc) { 839 QDF_ASSERT(0); 840 scm_err("null psoc"); 841 return 0; 842 } 843 844 scan = wlan_psoc_get_scan_obj(psoc); 845 if (!scan) { 846 scm_err("scan object null"); 847 return 0; 848 } 849 850 id = qdf_atomic_inc_return(&scan->scan_ids); 851 id = id & WLAN_SCAN_ID_MASK; 852 /* Mark this scan request as triggered by host 853 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag. 854 */ 855 id = id | WLAN_HOST_SCAN_REQ_ID_PREFIX; 856 scm_debug("scan_id: 0x%x", id); 857 858 return id; 859 } 860 861 static QDF_STATUS 862 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 863 scan_event_handler event_cb, void *arg) 864 { 865 struct cb_handler *cb_handler; 866 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 867 868 /* Assign next available slot to this registration request */ 869 cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]); 870 cb_handler->func = event_cb; 871 cb_handler->arg = arg; 872 pdev_ev_handler->handler_cnt++; 873 874 return QDF_STATUS_SUCCESS; 875 } 876 877 QDF_STATUS 878 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev, 879 scan_event_handler event_cb, void *arg) 880 { 881 uint32_t idx; 882 struct wlan_scan_obj *scan; 883 struct pdev_scan_ev_handler *pdev_ev_handler; 884 struct cb_handler *cb_handler; 885 886 /* scan event handler call back can't be NULL */ 887 if (!pdev || !event_cb) { 888 scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb); 889 return QDF_STATUS_E_NULL_VALUE; 890 } 891 892 scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg); 893 894 scan = wlan_pdev_get_scan_obj(pdev); 895 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 896 if (!pdev_ev_handler) { 897 scm_err("null pdev_ev_handler"); 898 return QDF_STATUS_E_NULL_VALUE; 899 } 900 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 901 902 qdf_spin_lock_bh(&scan->lock); 903 /* Ensure its not a duplicate registration request */ 904 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 905 idx++, cb_handler++) { 906 if ((cb_handler->func == event_cb) && 907 (cb_handler->arg == arg)) { 908 qdf_spin_unlock_bh(&scan->lock); 909 scm_debug("func: %pK, arg: %pK already exists", 910 event_cb, arg); 911 return QDF_STATUS_SUCCESS; 912 } 913 } 914 915 QDF_ASSERT(pdev_ev_handler->handler_cnt < 916 MAX_SCAN_EVENT_HANDLERS_PER_PDEV); 917 918 if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) { 919 qdf_spin_unlock_bh(&scan->lock); 920 scm_warn("No more registrations possible"); 921 return QDF_STATUS_E_NOMEM; 922 } 923 924 scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg); 925 qdf_spin_unlock_bh(&scan->lock); 926 927 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 928 929 return QDF_STATUS_SUCCESS; 930 } 931 932 static QDF_STATUS 933 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, 934 struct wlan_scan_obj *scan_obj) 935 { 936 scan_obj->scan_disabled = 0; 937 scan_obj->drop_bcn_on_chan_mismatch = 938 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH); 939 scan_obj->drop_bcn_on_invalid_freq = 940 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ); 941 scan_obj->disable_timeout = false; 942 scan_obj->scan_def.active_dwell = 943 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME); 944 /* the ini is disallow DFS channel scan if ini is 1, so negate that */ 945 scan_obj->scan_def.allow_dfs_chan_in_first_scan = 946 !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN); 947 scan_obj->scan_def.allow_dfs_chan_in_scan = 948 cfg_get(psoc, CFG_ENABLE_DFS_SCAN); 949 scan_obj->scan_def.skip_dfs_chan_in_p2p_search = 950 cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH); 951 scan_obj->scan_def.use_wake_lock_in_user_scan = 952 cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN); 953 scan_obj->scan_def.active_dwell_2g = 954 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME); 955 scan_obj->scan_def.active_dwell_6g = 956 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME); 957 scan_obj->scan_def.passive_dwell_6g = 958 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME); 959 scan_obj->scan_def.passive_dwell = 960 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME); 961 scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME; 962 scan_obj->scan_def.sta_miracast_mcc_rest_time = 963 SCAN_STA_MIRACAST_MCC_REST_TIME; 964 scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME; 965 scan_obj->scan_def.conc_active_dwell = 966 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC); 967 scan_obj->scan_def.conc_passive_dwell = 968 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC); 969 scan_obj->scan_def.conc_max_rest_time = 970 cfg_get(psoc, CFG_MAX_REST_TIME_CONC); 971 scan_obj->scan_def.conc_min_rest_time = 972 cfg_get(psoc, CFG_MIN_REST_TIME_CONC); 973 scan_obj->scan_def.conc_idle_time = 974 cfg_get(psoc, CFG_IDLE_TIME_CONC); 975 scan_obj->scan_def.repeat_probe_time = 976 cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME); 977 scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME; 978 scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY; 979 scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION; 980 scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME; 981 scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES); 982 scan_obj->scan_def.scan_cache_aging_time = 983 (cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000); 984 scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV; 985 scan_obj->scan_def.scan_priority = SCAN_PRIORITY; 986 scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT; 987 scan_obj->scan_def.adaptive_dwell_time_mode = 988 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE); 989 scan_obj->scan_def.adaptive_dwell_time_mode_nc = 990 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC); 991 scan_obj->scan_def.honour_nl_scan_policy_flags = 992 cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS); 993 scan_obj->scan_def.enable_mac_spoofing = 994 cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING); 995 scan_obj->scan_def.extscan_adaptive_dwell_mode = 996 cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 997 998 /* init burst durations */ 999 scan_obj->scan_def.sta_scan_burst_duration = 1000 cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION); 1001 scan_obj->scan_def.p2p_scan_burst_duration = 1002 cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION); 1003 scan_obj->scan_def.go_scan_burst_duration = 1004 cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION); 1005 scan_obj->scan_def.ap_scan_burst_duration = 1006 cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION); 1007 /* scan contrl flags */ 1008 scan_obj->scan_def.scan_f_passive = true; 1009 scan_obj->scan_def.scan_f_ofdm_rates = true; 1010 scan_obj->scan_def.scan_f_2ghz = true; 1011 scan_obj->scan_def.scan_f_5ghz = true; 1012 scan_obj->scan_def.scan_f_chan_stat_evnt = 1013 cfg_get(psoc, CFG_ENABLE_SNR_MONITORING); 1014 /* scan event flags */ 1015 scan_obj->scan_def.scan_ev_started = true; 1016 scan_obj->scan_def.scan_ev_completed = true; 1017 scan_obj->scan_def.scan_ev_bss_chan = true; 1018 scan_obj->scan_def.scan_ev_foreign_chan = true; 1019 scan_obj->scan_def.scan_ev_foreign_chn_exit = true; 1020 scan_obj->scan_def.scan_ev_dequeued = true; 1021 scan_obj->scan_def.scan_ev_preempted = true; 1022 scan_obj->scan_def.scan_ev_start_failed = true; 1023 scan_obj->scan_def.scan_ev_restarted = true; 1024 scan_obj->scan_def.enable_connected_scan = 1025 cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN); 1026 scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE); 1027 /* init scan id seed */ 1028 qdf_atomic_init(&scan_obj->scan_ids); 1029 1030 /* init extscan */ 1031 wlan_extscan_global_init(psoc, scan_obj); 1032 1033 return wlan_pno_global_init(psoc, scan_obj); 1034 } 1035 1036 static void 1037 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc) 1038 { 1039 struct wlan_scan_obj *scan_obj; 1040 1041 scan_obj = wlan_psoc_get_scan_obj(psoc); 1042 wlan_pno_global_deinit(scan_obj); 1043 wlan_extscan_global_deinit(); 1044 } 1045 1046 static QDF_STATUS 1047 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 1048 struct cb_handler *entry) 1049 { 1050 struct cb_handler *last_entry; 1051 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 1052 1053 /* Replace event handler being deleted 1054 * with the last one in the list. 1055 */ 1056 last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]); 1057 entry->func = last_entry->func; 1058 entry->arg = last_entry->arg; 1059 1060 /* Clear our last entry */ 1061 last_entry->func = NULL; 1062 last_entry->arg = NULL; 1063 pdev_ev_handler->handler_cnt--; 1064 1065 return QDF_STATUS_SUCCESS; 1066 } 1067 1068 void 1069 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev, 1070 scan_event_handler event_cb, void *arg) 1071 { 1072 uint8_t found = false; 1073 uint32_t idx; 1074 uint32_t handler_cnt; 1075 struct wlan_scan_obj *scan; 1076 struct cb_handler *cb_handler; 1077 struct pdev_scan_ev_handler *pdev_ev_handler; 1078 1079 scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb, 1080 arg); 1081 if (!pdev) { 1082 scm_err("null pdev"); 1083 return; 1084 } 1085 scan = wlan_pdev_get_scan_obj(pdev); 1086 if (!scan) 1087 return; 1088 1089 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 1090 if (!pdev_ev_handler) 1091 return; 1092 1093 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 1094 1095 qdf_spin_lock_bh(&scan->lock); 1096 handler_cnt = pdev_ev_handler->handler_cnt; 1097 if (!handler_cnt) { 1098 qdf_spin_unlock_bh(&scan->lock); 1099 scm_info("No event handlers registered"); 1100 return; 1101 } 1102 1103 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 1104 idx++, cb_handler++) { 1105 if ((cb_handler->func == event_cb) && 1106 (cb_handler->arg == arg)) { 1107 /* Event handler found, remove it 1108 * from event handler list. 1109 */ 1110 found = true; 1111 scm_remove_scan_event_handler(pdev_ev_handler, 1112 cb_handler); 1113 handler_cnt--; 1114 break; 1115 } 1116 } 1117 qdf_spin_unlock_bh(&scan->lock); 1118 1119 scm_debug("event handler %s, remaining handlers: %d", 1120 (found ? "removed" : "not found"), handler_cnt); 1121 } 1122 1123 QDF_STATUS 1124 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev, 1125 struct scan_start_request *req) 1126 { 1127 struct scan_default_params *def; 1128 1129 if (!vdev | !req) { 1130 scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req); 1131 return QDF_STATUS_E_INVAL; 1132 } 1133 def = wlan_vdev_get_def_scan_params(vdev); 1134 if (!def) { 1135 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 1136 return QDF_STATUS_E_NULL_VALUE; 1137 } 1138 1139 /* Zero out everything and explicitly set fields as required */ 1140 qdf_mem_zero(req, sizeof(*req)); 1141 1142 req->vdev = vdev; 1143 req->scan_req.vdev_id = wlan_vdev_get_id(vdev); 1144 req->scan_req.scan_type = SCAN_TYPE_DEFAULT; 1145 req->scan_req.scan_priority = def->scan_priority; 1146 req->scan_req.dwell_time_active = def->active_dwell; 1147 req->scan_req.dwell_time_active_2g = def->active_dwell_2g; 1148 req->scan_req.dwell_time_active_6g = def->active_dwell_6g; 1149 req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g; 1150 req->scan_req.dwell_time_passive = def->passive_dwell; 1151 req->scan_req.min_rest_time = def->min_rest_time; 1152 req->scan_req.max_rest_time = def->max_rest_time; 1153 req->scan_req.repeat_probe_time = def->repeat_probe_time; 1154 req->scan_req.probe_spacing_time = def->probe_spacing_time; 1155 req->scan_req.idle_time = def->idle_time; 1156 req->scan_req.max_scan_time = def->max_scan_time; 1157 req->scan_req.probe_delay = def->probe_delay; 1158 req->scan_req.burst_duration = def->burst_duration; 1159 req->scan_req.n_probes = def->num_probes; 1160 req->scan_req.adaptive_dwell_time_mode = 1161 def->adaptive_dwell_time_mode; 1162 req->scan_req.scan_flags = def->scan_flags; 1163 req->scan_req.scan_events = def->scan_events; 1164 req->scan_req.scan_random.randomize = def->enable_mac_spoofing; 1165 1166 return QDF_STATUS_SUCCESS; 1167 } 1168 1169 QDF_STATUS 1170 ucfg_scan_init_ssid_params(struct scan_start_request *req, 1171 uint32_t num_ssid, struct wlan_ssid *ssid_list) 1172 { 1173 uint32_t max_ssid = sizeof(req->scan_req.ssid) / 1174 sizeof(req->scan_req.ssid[0]); 1175 1176 if (!req) { 1177 scm_err("null request"); 1178 return QDF_STATUS_E_NULL_VALUE; 1179 } 1180 if (!num_ssid) { 1181 /* empty channel list provided */ 1182 req->scan_req.num_ssids = 0; 1183 qdf_mem_zero(&req->scan_req.ssid[0], 1184 sizeof(req->scan_req.ssid)); 1185 return QDF_STATUS_SUCCESS; 1186 } 1187 if (!ssid_list) { 1188 scm_err("null ssid_list while num_ssid: %d", num_ssid); 1189 return QDF_STATUS_E_NULL_VALUE; 1190 } 1191 if (num_ssid > max_ssid) { 1192 /* got a big list. alert and continue */ 1193 scm_warn("overflow: received %d, max supported : %d", 1194 num_ssid, max_ssid); 1195 return QDF_STATUS_E_E2BIG; 1196 } 1197 1198 if (max_ssid > num_ssid) 1199 max_ssid = num_ssid; 1200 1201 req->scan_req.num_ssids = max_ssid; 1202 qdf_mem_copy(&req->scan_req.ssid[0], ssid_list, 1203 (req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0]))); 1204 1205 return QDF_STATUS_SUCCESS; 1206 } 1207 1208 QDF_STATUS 1209 ucfg_scan_init_bssid_params(struct scan_start_request *req, 1210 uint32_t num_bssid, struct qdf_mac_addr *bssid_list) 1211 { 1212 uint32_t max_bssid = sizeof(req->scan_req.bssid_list) / 1213 sizeof(req->scan_req.bssid_list[0]); 1214 1215 if (!req) { 1216 scm_err("null request"); 1217 return QDF_STATUS_E_NULL_VALUE; 1218 } 1219 if (!num_bssid) { 1220 /* empty channel list provided */ 1221 req->scan_req.num_bssid = 0; 1222 qdf_mem_zero(&req->scan_req.bssid_list[0], 1223 sizeof(req->scan_req.bssid_list)); 1224 return QDF_STATUS_SUCCESS; 1225 } 1226 if (!bssid_list) { 1227 scm_err("null bssid_list while num_bssid: %d", num_bssid); 1228 return QDF_STATUS_E_NULL_VALUE; 1229 } 1230 if (num_bssid > max_bssid) { 1231 /* got a big list. alert and continue */ 1232 scm_warn("overflow: received %d, max supported : %d", 1233 num_bssid, max_bssid); 1234 return QDF_STATUS_E_E2BIG; 1235 } 1236 1237 if (max_bssid > num_bssid) 1238 max_bssid = num_bssid; 1239 1240 req->scan_req.num_bssid = max_bssid; 1241 qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list, 1242 req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0])); 1243 1244 return QDF_STATUS_SUCCESS; 1245 } 1246 1247 /** 1248 * is_chan_enabled_for_scan() - helper API to check if a frequency 1249 * is allowed to scan. 1250 * @reg_chan: regulatory_channel object 1251 * @low_2g: lower 2.4 GHz frequency thresold 1252 * @high_2g: upper 2.4 GHz frequency thresold 1253 * @low_5g: lower 5 GHz frequency thresold 1254 * @high_5g: upper 5 GHz frequency thresold 1255 * 1256 * Return: true if scan is allowed. false otherwise. 1257 */ 1258 static bool 1259 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan, 1260 qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g, 1261 qdf_freq_t high_5g) 1262 { 1263 if (reg_chan->state == CHANNEL_STATE_DISABLE) 1264 return false; 1265 if (reg_chan->nol_chan) 1266 return false; 1267 /* 2 GHz channel */ 1268 if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1269 WLAN_BAND_2_4_GHZ) && 1270 ((reg_chan->center_freq < low_2g) || 1271 (reg_chan->center_freq > high_2g))) 1272 return false; 1273 else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1274 WLAN_BAND_5_GHZ) && 1275 ((reg_chan->center_freq < low_5g) || 1276 (reg_chan->center_freq > high_5g))) 1277 return false; 1278 1279 return true; 1280 } 1281 1282 QDF_STATUS 1283 ucfg_scan_init_chanlist_params(struct scan_start_request *req, 1284 uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode) 1285 { 1286 uint32_t idx; 1287 QDF_STATUS status; 1288 struct regulatory_channel *reg_chan_list = NULL; 1289 qdf_freq_t low_2g, high_2g, low_5g, high_5g; 1290 struct wlan_objmgr_pdev *pdev = NULL; 1291 uint32_t *scan_freqs = NULL; 1292 uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / 1293 sizeof(req->scan_req.chan_list.chan[0]); 1294 if (!req) { 1295 scm_err("null request"); 1296 return QDF_STATUS_E_NULL_VALUE; 1297 } 1298 1299 if (req->vdev) 1300 pdev = wlan_vdev_get_pdev(req->vdev); 1301 /* 1302 * If 0 channels are provided for scan and 1303 * wide band scan is enabled, scan all 20 mhz 1304 * available channels. This is required as FW 1305 * scans all channel/phy mode combinations 1306 * provided in scan channel list if 0 chans are 1307 * provided in scan request causing scan to take 1308 * too much time to complete. 1309 */ 1310 if (pdev && !num_chans) { 1311 reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS * 1312 sizeof(struct regulatory_channel)); 1313 if (!reg_chan_list) { 1314 status = QDF_STATUS_E_NOMEM; 1315 goto end; 1316 } 1317 scan_freqs = 1318 qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans); 1319 if (!scan_freqs) { 1320 status = QDF_STATUS_E_NOMEM; 1321 goto end; 1322 } 1323 status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list); 1324 if (QDF_IS_STATUS_ERROR(status)) 1325 goto end; 1326 1327 status = wlan_reg_get_freq_range(pdev, &low_2g, 1328 &high_2g, &low_5g, &high_5g); 1329 if (QDF_IS_STATUS_ERROR(status)) 1330 goto end; 1331 1332 for (idx = 0, num_chans = 0; 1333 (idx < NUM_CHANNELS && num_chans < max_chans); idx++) 1334 if (is_chan_enabled_for_scan(®_chan_list[idx], 1335 low_2g, high_2g, low_5g, high_5g)) 1336 scan_freqs[num_chans++] = 1337 reg_chan_list[idx].center_freq; 1338 1339 chan_list = scan_freqs; 1340 } 1341 1342 if (!num_chans) { 1343 /* empty channel list provided */ 1344 qdf_mem_zero(&req->scan_req.chan_list, 1345 sizeof(req->scan_req.chan_list)); 1346 req->scan_req.chan_list.num_chan = 0; 1347 status = QDF_STATUS_SUCCESS; 1348 goto end; 1349 } 1350 if (!chan_list) { 1351 scm_info("null chan_list while num_chans: %d", num_chans); 1352 status = QDF_STATUS_E_NULL_VALUE; 1353 goto end; 1354 } 1355 1356 if (num_chans > max_chans) { 1357 /* got a big list. alert and fail */ 1358 scm_warn("overflow: received %d, max supported : %d", 1359 num_chans, max_chans); 1360 status = QDF_STATUS_E_E2BIG; 1361 goto end; 1362 } 1363 1364 req->scan_req.chan_list.num_chan = num_chans; 1365 for (idx = 0; idx < num_chans; idx++) { 1366 req->scan_req.chan_list.chan[idx].freq = 1367 (chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ? 1368 chan_list[idx] : 1369 wlan_reg_legacy_chan_to_freq(pdev, chan_list[idx]); 1370 if (phymode) 1371 req->scan_req.chan_list.chan[idx].phymode = 1372 phymode[idx]; 1373 else if (req->scan_req.chan_list.chan[idx].freq <= 1374 WLAN_CHAN_15_FREQ) 1375 req->scan_req.chan_list.chan[idx].phymode = 1376 SCAN_PHY_MODE_11G; 1377 else 1378 req->scan_req.chan_list.chan[idx].phymode = 1379 SCAN_PHY_MODE_11A; 1380 } 1381 1382 end: 1383 if (scan_freqs) 1384 qdf_mem_free(scan_freqs); 1385 1386 if (reg_chan_list) 1387 qdf_mem_free(reg_chan_list); 1388 1389 return QDF_STATUS_SUCCESS; 1390 } 1391 1392 static inline enum scm_scan_status 1393 get_scan_status_from_serialization_status( 1394 enum wlan_serialization_cmd_status status) 1395 { 1396 enum scm_scan_status scan_status; 1397 1398 switch (status) { 1399 case WLAN_SER_CMD_IN_PENDING_LIST: 1400 scan_status = SCAN_IS_PENDING; 1401 break; 1402 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1403 scan_status = SCAN_IS_ACTIVE; 1404 break; 1405 case WLAN_SER_CMDS_IN_ALL_LISTS: 1406 scan_status = SCAN_IS_ACTIVE_AND_PENDING; 1407 break; 1408 case WLAN_SER_CMD_NOT_FOUND: 1409 scan_status = SCAN_NOT_IN_PROGRESS; 1410 break; 1411 default: 1412 scm_warn("invalid serialization status %d", status); 1413 QDF_ASSERT(0); 1414 scan_status = SCAN_NOT_IN_PROGRESS; 1415 break; 1416 } 1417 1418 return scan_status; 1419 } 1420 1421 enum scm_scan_status 1422 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev) 1423 { 1424 enum wlan_serialization_cmd_status status; 1425 1426 if (!vdev) { 1427 scm_err("null vdev"); 1428 return SCAN_NOT_IN_PROGRESS; 1429 } 1430 status = wlan_serialization_vdev_scan_status(vdev); 1431 1432 return get_scan_status_from_serialization_status(status); 1433 } 1434 1435 enum scm_scan_status 1436 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev) 1437 { 1438 enum wlan_serialization_cmd_status status; 1439 1440 if (!pdev) { 1441 scm_err("null pdev"); 1442 return SCAN_NOT_IN_PROGRESS; 1443 } 1444 status = wlan_serialization_pdev_scan_status(pdev); 1445 1446 return get_scan_status_from_serialization_status(status); 1447 } 1448 1449 static void 1450 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc, 1451 bool enable) 1452 { 1453 QDF_STATUS status; 1454 struct mgmt_txrx_mgmt_frame_cb_info cb_info[2]; 1455 1456 cb_info[0].frm_type = MGMT_PROBE_RESP; 1457 cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1458 cb_info[1].frm_type = MGMT_BEACON; 1459 cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1460 1461 if (enable) 1462 status = wlan_mgmt_txrx_register_rx_cb(psoc, 1463 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1464 else 1465 status = wlan_mgmt_txrx_deregister_rx_cb(psoc, 1466 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1467 if (status != QDF_STATUS_SUCCESS) 1468 scm_err("%s the Handle with MGMT TXRX layer has failed", 1469 enable ? "Registering" : "Deregistering"); 1470 } 1471 1472 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc, 1473 struct scan_user_cfg *scan_cfg) 1474 { 1475 struct wlan_scan_obj *scan_obj; 1476 struct scan_default_params *scan_def; 1477 1478 if (!psoc) { 1479 scm_err("null psoc"); 1480 return QDF_STATUS_E_FAILURE; 1481 } 1482 scan_obj = wlan_psoc_get_scan_obj(psoc); 1483 if (!scan_obj) { 1484 scm_err("Failed to get scan object"); 1485 return QDF_STATUS_E_FAILURE; 1486 } 1487 1488 scan_def = &scan_obj->scan_def; 1489 scan_obj->ie_whitelist = scan_cfg->ie_whitelist; 1490 scan_def->sta_miracast_mcc_rest_time = 1491 scan_cfg->sta_miracast_mcc_rest_time; 1492 1493 return QDF_STATUS_SUCCESS; 1494 } 1495 1496 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 1497 static QDF_STATUS 1498 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) 1499 { 1500 struct scan_cancel_request *req; 1501 QDF_STATUS status; 1502 struct wlan_objmgr_vdev *vdev; 1503 1504 req = qdf_mem_malloc_atomic(sizeof(*req)); 1505 if (!req) { 1506 scm_err("Failed to allocate memory"); 1507 return QDF_STATUS_E_NOMEM; 1508 } 1509 1510 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID); 1511 if (!vdev) { 1512 scm_err("Failed to get vdev"); 1513 qdf_mem_free(req); 1514 return QDF_STATUS_E_INVAL; 1515 } 1516 req->vdev = vdev; 1517 req->cancel_req.scan_id = INVAL_SCAN_ID; 1518 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1519 req->cancel_req.vdev_id = INVAL_VDEV_ID; 1520 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 1521 status = ucfg_scan_cancel_sync(req); 1522 if (QDF_IS_STATUS_ERROR(status)) 1523 scm_err("Cancel scan request failed"); 1524 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1525 1526 return status; 1527 } 1528 1529 static QDF_STATUS 1530 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1531 { 1532 struct wlan_objmgr_pdev *pdev = NULL; 1533 QDF_STATUS status = QDF_STATUS_SUCCESS; 1534 int i; 1535 1536 ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND); 1537 /* Check all pdev */ 1538 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 1539 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); 1540 if (!pdev) 1541 continue; 1542 if (ucfg_scan_get_pdev_status(pdev) != 1543 SCAN_NOT_IN_PROGRESS) 1544 status = ucfg_scan_cancel_pdev_scan(pdev); 1545 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 1546 if (QDF_IS_STATUS_ERROR(status)) { 1547 scm_err("failed to cancel scan for pdev_id %d", i); 1548 return status; 1549 } 1550 } 1551 1552 return QDF_STATUS_SUCCESS; 1553 } 1554 1555 static QDF_STATUS 1556 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1557 { 1558 ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND); 1559 return QDF_STATUS_SUCCESS; 1560 } 1561 1562 static inline void 1563 ucfg_scan_register_pmo_handler(void) 1564 { 1565 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN, 1566 ucfg_scan_suspend_handler, NULL); 1567 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN, 1568 ucfg_scan_resume_handler, NULL); 1569 } 1570 1571 static inline void 1572 ucfg_scan_unregister_pmo_handler(void) 1573 { 1574 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN, 1575 ucfg_scan_suspend_handler); 1576 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN, 1577 ucfg_scan_resume_handler); 1578 } 1579 1580 #else 1581 static inline void 1582 ucfg_scan_register_pmo_handler(void) 1583 { 1584 } 1585 1586 static inline void 1587 ucfg_scan_unregister_pmo_handler(void) 1588 { 1589 } 1590 #endif 1591 1592 QDF_STATUS 1593 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) 1594 { 1595 struct wlan_scan_obj *scan_obj; 1596 1597 scm_debug("psoc open: 0x%pK", psoc); 1598 if (!psoc) { 1599 scm_err("null psoc"); 1600 return QDF_STATUS_E_FAILURE; 1601 } 1602 scan_obj = wlan_psoc_get_scan_obj(psoc); 1603 if (!scan_obj) { 1604 scm_err("Failed to get scan object"); 1605 return QDF_STATUS_E_FAILURE; 1606 } 1607 /* Initialize the scan Globals */ 1608 wlan_scan_global_init(psoc, scan_obj); 1609 qdf_spinlock_create(&scan_obj->lock); 1610 ucfg_scan_register_pmo_handler(); 1611 scm_db_init(psoc); 1612 scm_channel_list_db_init(psoc); 1613 1614 return QDF_STATUS_SUCCESS; 1615 } 1616 1617 QDF_STATUS 1618 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) 1619 { 1620 struct wlan_scan_obj *scan_obj; 1621 1622 scm_debug("psoc close: 0x%pK", psoc); 1623 if (!psoc) { 1624 scm_err("null psoc"); 1625 return QDF_STATUS_E_FAILURE; 1626 } 1627 scm_db_deinit(psoc); 1628 scan_obj = wlan_psoc_get_scan_obj(psoc); 1629 if (!scan_obj) { 1630 scm_err("Failed to get scan object"); 1631 return QDF_STATUS_E_FAILURE; 1632 } 1633 ucfg_scan_unregister_pmo_handler(); 1634 qdf_spinlock_destroy(&scan_obj->lock); 1635 wlan_scan_global_deinit(psoc); 1636 scm_channel_list_db_deinit(psoc); 1637 1638 return QDF_STATUS_SUCCESS; 1639 } 1640 1641 static bool scm_serialization_scan_rules_cb( 1642 union wlan_serialization_rules_info *comp_info, 1643 uint8_t comp_id) 1644 { 1645 switch (comp_id) { 1646 case WLAN_UMAC_COMP_TDLS: 1647 if (comp_info->scan_info.is_tdls_in_progress) { 1648 scm_debug("Cancel scan. Tdls in progress"); 1649 return false; 1650 } 1651 break; 1652 case WLAN_UMAC_COMP_DFS: 1653 if (comp_info->scan_info.is_cac_in_progress) { 1654 scm_debug("Cancel scan. CAC in progress"); 1655 return false; 1656 } 1657 break; 1658 case WLAN_UMAC_COMP_MLME: 1659 if (comp_info->scan_info.is_mlme_op_in_progress) { 1660 scm_debug("Cancel scan. MLME operation in progress"); 1661 return false; 1662 } 1663 break; 1664 default: 1665 scm_debug("not handled comp_id %d", comp_id); 1666 break; 1667 } 1668 1669 return true; 1670 } 1671 1672 QDF_STATUS 1673 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) 1674 { 1675 QDF_STATUS status; 1676 1677 scm_debug("psoc enable: 0x%pK", psoc); 1678 if (!psoc) { 1679 scm_err("null psoc"); 1680 return QDF_STATUS_E_FAILURE; 1681 } 1682 /* Subscribe for scan events from lmac layesr */ 1683 status = tgt_scan_register_ev_handler(psoc); 1684 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1685 if (!wlan_reg_is_11d_offloaded(psoc)) 1686 scm_11d_cc_db_init(psoc); 1687 ucfg_scan_register_unregister_bcn_cb(psoc, true); 1688 status = wlan_serialization_register_apply_rules_cb(psoc, 1689 WLAN_SER_CMD_SCAN, 1690 scm_serialization_scan_rules_cb); 1691 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1692 return status; 1693 } 1694 1695 QDF_STATUS 1696 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) 1697 { 1698 QDF_STATUS status; 1699 1700 scm_debug("psoc disable: 0x%pK", psoc); 1701 if (!psoc) { 1702 scm_err("null psoc"); 1703 return QDF_STATUS_E_FAILURE; 1704 } 1705 /* Unsubscribe for scan events from lmac layesr */ 1706 status = tgt_scan_unregister_ev_handler(psoc); 1707 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1708 ucfg_scan_register_unregister_bcn_cb(psoc, false); 1709 if (!wlan_reg_is_11d_offloaded(psoc)) 1710 scm_11d_cc_db_deinit(psoc); 1711 1712 return status; 1713 } 1714 1715 uint32_t 1716 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc) 1717 { 1718 struct scan_default_params *scan_params = NULL; 1719 1720 if (!psoc) { 1721 scm_err("null psoc"); 1722 return 0; 1723 } 1724 scan_params = wlan_scan_psoc_get_def_params(psoc); 1725 if (!scan_params) { 1726 scm_err("Failed to get scan object"); 1727 return 0; 1728 } 1729 1730 return scan_params->max_active_scans_allowed; 1731 } 1732 1733 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc, 1734 struct probe_req_whitelist_attr *ie_whitelist) 1735 { 1736 struct wlan_scan_obj *scan_obj = NULL; 1737 1738 scan_obj = wlan_psoc_get_scan_obj(psoc); 1739 if (!scan_obj) 1740 return false; 1741 1742 qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist, 1743 sizeof(*ie_whitelist)); 1744 1745 return true; 1746 } 1747 1748 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc, 1749 struct wlan_objmgr_vdev *vdev) 1750 { 1751 struct wlan_scan_obj *scan_obj = NULL; 1752 1753 scan_obj = wlan_psoc_get_scan_obj(psoc); 1754 if (!scan_obj) 1755 return false; 1756 1757 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || 1758 wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS) 1759 return false; 1760 1761 if (!scan_obj->ie_whitelist.white_list) 1762 return false; 1763 1764 return true; 1765 } 1766 1767 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, 1768 bool bt_a2dp_active) 1769 { 1770 struct wlan_scan_obj *scan_obj; 1771 1772 scan_obj = wlan_psoc_get_scan_obj(psoc); 1773 if (!scan_obj) { 1774 scm_err("Failed to get scan object"); 1775 return; 1776 } 1777 scan_obj->bt_a2dp_enabled = bt_a2dp_active; 1778 } 1779 1780 bool ucfg_scan_get_bt_activity(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 false; 1788 } 1789 1790 return scan_obj->bt_a2dp_enabled; 1791 } 1792 1793 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc) 1794 { 1795 struct wlan_scan_obj *scan_obj; 1796 1797 scan_obj = wlan_psoc_get_scan_obj(psoc); 1798 if (!scan_obj) 1799 return false; 1800 1801 return scan_obj->scan_def.use_wake_lock_in_user_scan; 1802 } 1803 1804 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc) 1805 { 1806 struct wlan_scan_obj *scan_obj; 1807 1808 scan_obj = wlan_psoc_get_scan_obj(psoc); 1809 if (!scan_obj) { 1810 scm_err("Failed to get scan object"); 1811 return cfg_default(CFG_ENABLE_CONNECTED_SCAN); 1812 } 1813 1814 return scan_obj->scan_def.enable_connected_scan; 1815 } 1816 1817 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc) 1818 { 1819 struct wlan_scan_obj *scan_obj; 1820 1821 scan_obj = wlan_psoc_get_scan_obj(psoc); 1822 if (!scan_obj) { 1823 scm_err("Failed to get scan object"); 1824 return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING); 1825 } 1826 1827 return scan_obj->scan_def.enable_mac_spoofing; 1828 } 1829 1830 enum scan_dwelltime_adaptive_mode 1831 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc) 1832 { 1833 struct wlan_scan_obj *scan_obj; 1834 1835 scan_obj = wlan_psoc_get_scan_obj(psoc); 1836 if (!scan_obj) { 1837 scm_err("Failed to get scan object"); 1838 return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 1839 } 1840 1841 return scan_obj->scan_def.extscan_adaptive_dwell_mode; 1842 } 1843 1844 QDF_STATUS 1845 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, 1846 enum scan_config config, uint32_t val) 1847 { 1848 struct wlan_scan_obj *scan_obj; 1849 QDF_STATUS status = QDF_STATUS_SUCCESS; 1850 1851 scan_obj = wlan_psoc_get_scan_obj(psoc); 1852 if (!scan_obj) { 1853 scm_err("Failed to get scan object config:%d, val:%d", 1854 config, val); 1855 return QDF_STATUS_E_INVAL; 1856 } 1857 switch (config) { 1858 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1859 scan_obj->disable_timeout = !!val; 1860 break; 1861 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1862 scan_obj->drop_bcn_on_chan_mismatch = !!val; 1863 break; 1864 1865 default: 1866 status = QDF_STATUS_E_INVAL; 1867 break; 1868 } 1869 1870 return status; 1871 } 1872 1873 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev, 1874 struct bss_info *bss_info, struct mlme_info *mlme) 1875 { 1876 QDF_STATUS status; 1877 1878 status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme); 1879 1880 return status; 1881 } 1882 1883 QDF_STATUS 1884 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc, 1885 enum scan_config config, uint32_t *val) 1886 { 1887 struct wlan_scan_obj *scan_obj; 1888 QDF_STATUS status = QDF_STATUS_SUCCESS; 1889 1890 scan_obj = wlan_psoc_get_scan_obj(psoc); 1891 if (!scan_obj || !val) { 1892 scm_err("scan object:%pK config:%d, val:0x%pK", 1893 scan_obj, config, val); 1894 return QDF_STATUS_E_INVAL; 1895 } 1896 switch (config) { 1897 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1898 *val = scan_obj->disable_timeout; 1899 break; 1900 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1901 *val = scan_obj->drop_bcn_on_chan_mismatch; 1902 break; 1903 1904 default: 1905 status = QDF_STATUS_E_INVAL; 1906 break; 1907 } 1908 1909 return status; 1910 } 1911 1912 #ifdef FEATURE_WLAN_SCAN_PNO 1913 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc) 1914 { 1915 struct wlan_scan_obj *scan_obj; 1916 1917 scan_obj = wlan_psoc_get_scan_obj(psoc); 1918 if (!scan_obj) { 1919 scm_err("NULL scan obj"); 1920 return false; 1921 } 1922 1923 return scan_obj->pno_cfg.pno_offload_enabled; 1924 } 1925 1926 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value) 1927 { 1928 struct wlan_scan_obj *scan_obj; 1929 1930 scan_obj = wlan_psoc_get_scan_obj(psoc); 1931 if (!scan_obj) { 1932 scm_err("NULL scan obj"); 1933 return; 1934 } 1935 1936 scan_obj->pno_cfg.pno_offload_enabled = value; 1937 } 1938 1939 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc) 1940 { 1941 struct wlan_scan_obj *scan_obj; 1942 1943 scan_obj = wlan_psoc_get_scan_obj(psoc); 1944 if (!scan_obj) { 1945 scm_err("NULL scan obj"); 1946 return cfg_default(CFG_PNO_SCAN_SUPPORT); 1947 } 1948 1949 return scan_obj->pno_cfg.scan_support_enabled; 1950 } 1951 1952 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc) 1953 { 1954 struct wlan_scan_obj *scan_obj; 1955 1956 scan_obj = wlan_psoc_get_scan_obj(psoc); 1957 if (!scan_obj) { 1958 scm_err("NULL scan obj"); 1959 return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER); 1960 } 1961 return scan_obj->pno_cfg.scan_backoff_multiplier; 1962 } 1963 1964 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc) 1965 { 1966 struct wlan_scan_obj *scan_obj; 1967 1968 scan_obj = wlan_psoc_get_scan_obj(psoc); 1969 if (!scan_obj) { 1970 scm_err("NULL scan obj"); 1971 return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN); 1972 } 1973 return scan_obj->pno_cfg.dfs_chnl_scan_enabled; 1974 } 1975 1976 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc) 1977 { 1978 struct wlan_scan_obj *scan_obj; 1979 1980 scan_obj = wlan_psoc_get_scan_obj(psoc); 1981 if (!scan_obj) { 1982 scm_err("NULL scan obj"); 1983 return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 1984 } 1985 return scan_obj->pno_cfg.scan_timer_repeat_value; 1986 } 1987 1988 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc) 1989 { 1990 struct wlan_scan_obj *scan_obj; 1991 1992 scan_obj = wlan_psoc_get_scan_obj(psoc); 1993 if (!scan_obj) { 1994 scm_err("NULL scan obj"); 1995 return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER); 1996 } 1997 return scan_obj->pno_cfg.slow_scan_multiplier; 1998 } 1999 2000 uint32_t 2001 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc) 2002 { 2003 struct wlan_scan_obj *scan_obj; 2004 2005 scan_obj = wlan_psoc_get_scan_obj(psoc); 2006 if (!scan_obj) { 2007 scm_err("Failed to get scan object"); 2008 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); 2009 } 2010 2011 return scan_obj->pno_cfg.max_sched_scan_plan_interval; 2012 } 2013 2014 uint32_t 2015 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc) 2016 { 2017 struct wlan_scan_obj *scan_obj; 2018 2019 scan_obj = wlan_psoc_get_scan_obj(psoc); 2020 if (!scan_obj) { 2021 scm_err("Failed to get scan object"); 2022 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 2023 } 2024 2025 return scan_obj->pno_cfg.max_sched_scan_plan_iterations; 2026 } 2027 2028 #endif 2029