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