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 uint8_t *chan_list, uint32_t num_chan) 75 { 76 scm_filter_valid_channel(pdev, chan_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.extscan_adaptive_dwell_mode = 1015 cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 1016 1017 /* init burst durations */ 1018 scan_obj->scan_def.sta_scan_burst_duration = 1019 cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION); 1020 scan_obj->scan_def.p2p_scan_burst_duration = 1021 cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION); 1022 scan_obj->scan_def.go_scan_burst_duration = 1023 cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION); 1024 scan_obj->scan_def.ap_scan_burst_duration = 1025 cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION); 1026 /* scan contrl flags */ 1027 scan_obj->scan_def.scan_f_passive = true; 1028 scan_obj->scan_def.scan_f_ofdm_rates = true; 1029 scan_obj->scan_def.scan_f_2ghz = true; 1030 scan_obj->scan_def.scan_f_5ghz = true; 1031 scan_obj->scan_def.scan_f_chan_stat_evnt = 1032 cfg_get(psoc, CFG_ENABLE_SNR_MONITORING); 1033 /* scan event flags */ 1034 scan_obj->scan_def.scan_ev_started = true; 1035 scan_obj->scan_def.scan_ev_completed = true; 1036 scan_obj->scan_def.scan_ev_bss_chan = true; 1037 scan_obj->scan_def.scan_ev_foreign_chan = true; 1038 scan_obj->scan_def.scan_ev_foreign_chn_exit = true; 1039 scan_obj->scan_def.scan_ev_dequeued = true; 1040 scan_obj->scan_def.scan_ev_preempted = true; 1041 scan_obj->scan_def.scan_ev_start_failed = true; 1042 scan_obj->scan_def.scan_ev_restarted = true; 1043 scan_obj->scan_def.enable_connected_scan = 1044 cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN); 1045 scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE); 1046 /* init scan id seed */ 1047 qdf_atomic_init(&scan_obj->scan_ids); 1048 1049 /* init extscan */ 1050 wlan_extscan_global_init(psoc, scan_obj); 1051 1052 return wlan_pno_global_init(psoc, scan_obj); 1053 } 1054 1055 static void 1056 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc) 1057 { 1058 struct wlan_scan_obj *scan_obj; 1059 1060 scan_obj = wlan_psoc_get_scan_obj(psoc); 1061 wlan_pno_global_deinit(scan_obj); 1062 wlan_extscan_global_deinit(); 1063 } 1064 1065 static QDF_STATUS 1066 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 1067 struct cb_handler *entry) 1068 { 1069 struct cb_handler *last_entry; 1070 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 1071 1072 /* Replace event handler being deleted 1073 * with the last one in the list. 1074 */ 1075 last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]); 1076 entry->func = last_entry->func; 1077 entry->arg = last_entry->arg; 1078 1079 /* Clear our last entry */ 1080 last_entry->func = NULL; 1081 last_entry->arg = NULL; 1082 pdev_ev_handler->handler_cnt--; 1083 1084 return QDF_STATUS_SUCCESS; 1085 } 1086 1087 void 1088 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev, 1089 scan_event_handler event_cb, void *arg) 1090 { 1091 uint8_t found = false; 1092 uint32_t idx; 1093 uint32_t handler_cnt; 1094 struct wlan_scan_obj *scan; 1095 struct cb_handler *cb_handler; 1096 struct pdev_scan_ev_handler *pdev_ev_handler; 1097 1098 scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb, 1099 arg); 1100 if (!pdev) { 1101 scm_err("null pdev"); 1102 return; 1103 } 1104 scan = wlan_pdev_get_scan_obj(pdev); 1105 if (!scan) 1106 return; 1107 1108 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 1109 if (!pdev_ev_handler) 1110 return; 1111 1112 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 1113 1114 qdf_spin_lock_bh(&scan->lock); 1115 handler_cnt = pdev_ev_handler->handler_cnt; 1116 if (!handler_cnt) { 1117 qdf_spin_unlock_bh(&scan->lock); 1118 scm_info("No event handlers registered"); 1119 return; 1120 } 1121 1122 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 1123 idx++, cb_handler++) { 1124 if ((cb_handler->func == event_cb) && 1125 (cb_handler->arg == arg)) { 1126 /* Event handler found, remove it 1127 * from event handler list. 1128 */ 1129 found = true; 1130 scm_remove_scan_event_handler(pdev_ev_handler, 1131 cb_handler); 1132 handler_cnt--; 1133 break; 1134 } 1135 } 1136 qdf_spin_unlock_bh(&scan->lock); 1137 1138 scm_debug("event handler %s, remaining handlers: %d", 1139 (found ? "removed" : "not found"), handler_cnt); 1140 } 1141 1142 QDF_STATUS 1143 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev, 1144 struct scan_start_request *req) 1145 { 1146 struct scan_default_params *def; 1147 1148 if (!vdev | !req) { 1149 scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req); 1150 return QDF_STATUS_E_INVAL; 1151 } 1152 def = wlan_vdev_get_def_scan_params(vdev); 1153 if (!def) { 1154 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 1155 return QDF_STATUS_E_NULL_VALUE; 1156 } 1157 1158 /* Zero out everything and explicitly set fields as required */ 1159 qdf_mem_zero(req, sizeof(*req)); 1160 1161 req->vdev = vdev; 1162 req->scan_req.vdev_id = wlan_vdev_get_id(vdev); 1163 req->scan_req.scan_type = SCAN_TYPE_DEFAULT; 1164 req->scan_req.scan_priority = def->scan_priority; 1165 req->scan_req.dwell_time_active = def->active_dwell; 1166 req->scan_req.dwell_time_active_2g = def->active_dwell_2g; 1167 req->scan_req.dwell_time_active_6g = def->active_dwell_6g; 1168 req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g; 1169 req->scan_req.dwell_time_passive = def->passive_dwell; 1170 req->scan_req.min_rest_time = def->min_rest_time; 1171 req->scan_req.max_rest_time = def->max_rest_time; 1172 req->scan_req.repeat_probe_time = def->repeat_probe_time; 1173 req->scan_req.probe_spacing_time = def->probe_spacing_time; 1174 req->scan_req.idle_time = def->idle_time; 1175 req->scan_req.max_scan_time = def->max_scan_time; 1176 req->scan_req.probe_delay = def->probe_delay; 1177 req->scan_req.burst_duration = def->burst_duration; 1178 req->scan_req.n_probes = def->num_probes; 1179 req->scan_req.adaptive_dwell_time_mode = 1180 def->adaptive_dwell_time_mode; 1181 req->scan_req.scan_flags = def->scan_flags; 1182 req->scan_req.scan_events = def->scan_events; 1183 req->scan_req.scan_random.randomize = def->enable_mac_spoofing; 1184 1185 return QDF_STATUS_SUCCESS; 1186 } 1187 1188 QDF_STATUS 1189 ucfg_scan_init_ssid_params(struct scan_start_request *req, 1190 uint32_t num_ssid, struct wlan_ssid *ssid_list) 1191 { 1192 uint32_t max_ssid = sizeof(req->scan_req.ssid) / 1193 sizeof(req->scan_req.ssid[0]); 1194 1195 if (!req) { 1196 scm_err("null request"); 1197 return QDF_STATUS_E_NULL_VALUE; 1198 } 1199 if (!num_ssid) { 1200 /* empty channel list provided */ 1201 req->scan_req.num_ssids = 0; 1202 qdf_mem_zero(&req->scan_req.ssid[0], 1203 sizeof(req->scan_req.ssid)); 1204 return QDF_STATUS_SUCCESS; 1205 } 1206 if (!ssid_list) { 1207 scm_err("null ssid_list while num_ssid: %d", num_ssid); 1208 return QDF_STATUS_E_NULL_VALUE; 1209 } 1210 if (num_ssid > max_ssid) { 1211 /* got a big list. alert and continue */ 1212 scm_warn("overflow: received %d, max supported : %d", 1213 num_ssid, max_ssid); 1214 return QDF_STATUS_E_E2BIG; 1215 } 1216 1217 if (max_ssid > num_ssid) 1218 max_ssid = num_ssid; 1219 1220 req->scan_req.num_ssids = max_ssid; 1221 qdf_mem_copy(&req->scan_req.ssid[0], ssid_list, 1222 (req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0]))); 1223 1224 return QDF_STATUS_SUCCESS; 1225 } 1226 1227 QDF_STATUS 1228 ucfg_scan_init_bssid_params(struct scan_start_request *req, 1229 uint32_t num_bssid, struct qdf_mac_addr *bssid_list) 1230 { 1231 uint32_t max_bssid = sizeof(req->scan_req.bssid_list) / 1232 sizeof(req->scan_req.bssid_list[0]); 1233 1234 if (!req) { 1235 scm_err("null request"); 1236 return QDF_STATUS_E_NULL_VALUE; 1237 } 1238 if (!num_bssid) { 1239 /* empty channel list provided */ 1240 req->scan_req.num_bssid = 0; 1241 qdf_mem_zero(&req->scan_req.bssid_list[0], 1242 sizeof(req->scan_req.bssid_list)); 1243 return QDF_STATUS_SUCCESS; 1244 } 1245 if (!bssid_list) { 1246 scm_err("null bssid_list while num_bssid: %d", num_bssid); 1247 return QDF_STATUS_E_NULL_VALUE; 1248 } 1249 if (num_bssid > max_bssid) { 1250 /* got a big list. alert and continue */ 1251 scm_warn("overflow: received %d, max supported : %d", 1252 num_bssid, max_bssid); 1253 return QDF_STATUS_E_E2BIG; 1254 } 1255 1256 if (max_bssid > num_bssid) 1257 max_bssid = num_bssid; 1258 1259 req->scan_req.num_bssid = max_bssid; 1260 qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list, 1261 req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0])); 1262 1263 return QDF_STATUS_SUCCESS; 1264 } 1265 1266 /** 1267 * is_chan_enabled_for_scan() - helper API to check if a frequency 1268 * is allowed to scan. 1269 * @reg_chan: regulatory_channel object 1270 * @low_2g: lower 2.4 GHz frequency thresold 1271 * @high_2g: upper 2.4 GHz frequency thresold 1272 * @low_5g: lower 5 GHz frequency thresold 1273 * @high_5g: upper 5 GHz frequency thresold 1274 * 1275 * Return: true if scan is allowed. false otherwise. 1276 */ 1277 static bool 1278 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan, 1279 uint32_t low_2g, uint32_t high_2g, uint32_t low_5g, 1280 uint32_t high_5g) 1281 { 1282 if (reg_chan->state == CHANNEL_STATE_DISABLE) 1283 return false; 1284 if (reg_chan->nol_chan) 1285 return false; 1286 /* 2 GHz channel */ 1287 if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1288 WLAN_BAND_2_4_GHZ) && 1289 ((reg_chan->center_freq < low_2g) || 1290 (reg_chan->center_freq > high_2g))) 1291 return false; 1292 else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1293 WLAN_BAND_5_GHZ) && 1294 ((reg_chan->center_freq < low_5g) || 1295 (reg_chan->center_freq > high_5g))) 1296 return false; 1297 1298 return true; 1299 } 1300 1301 QDF_STATUS 1302 ucfg_scan_init_chanlist_params(struct scan_start_request *req, 1303 uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode) 1304 { 1305 uint32_t idx; 1306 QDF_STATUS status; 1307 struct regulatory_channel *reg_chan_list = NULL; 1308 uint32_t low_2g, high_2g, low_5g, high_5g; 1309 struct wlan_objmgr_pdev *pdev = NULL; 1310 uint32_t *scan_freqs = NULL; 1311 uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / 1312 sizeof(req->scan_req.chan_list.chan[0]); 1313 if (!req) { 1314 scm_err("null request"); 1315 return QDF_STATUS_E_NULL_VALUE; 1316 } 1317 1318 if (req->vdev) 1319 pdev = wlan_vdev_get_pdev(req->vdev); 1320 /* 1321 * If 0 channels are provided for scan and 1322 * wide band scan is enabled, scan all 20 mhz 1323 * available channels. This is required as FW 1324 * scans all channel/phy mode combinations 1325 * provided in scan channel list if 0 chans are 1326 * provided in scan request causing scan to take 1327 * too much time to complete. 1328 */ 1329 if (pdev && !num_chans) { 1330 reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS * 1331 sizeof(struct regulatory_channel)); 1332 if (!reg_chan_list) { 1333 scm_err("Couldn't allocate reg_chan_list memory"); 1334 status = QDF_STATUS_E_NOMEM; 1335 goto end; 1336 } 1337 scan_freqs = 1338 qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans); 1339 if (!scan_freqs) { 1340 scm_err("Couldn't allocate scan_freqs memory"); 1341 status = QDF_STATUS_E_NOMEM; 1342 goto end; 1343 } 1344 status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list); 1345 if (QDF_IS_STATUS_ERROR(status)) { 1346 scm_err("Couldn't get current chan list"); 1347 goto end; 1348 } 1349 status = wlan_reg_get_freq_range(pdev, &low_2g, 1350 &high_2g, &low_5g, &high_5g); 1351 if (QDF_IS_STATUS_ERROR(status)) { 1352 scm_err("Couldn't get frequency range"); 1353 goto end; 1354 } 1355 1356 for (idx = 0, num_chans = 0; 1357 (idx < NUM_CHANNELS && num_chans < max_chans); idx++) 1358 if (is_chan_enabled_for_scan(®_chan_list[idx], 1359 low_2g, high_2g, low_5g, high_5g)) 1360 scan_freqs[num_chans++] = 1361 reg_chan_list[idx].center_freq; 1362 1363 chan_list = scan_freqs; 1364 } 1365 1366 if (!num_chans) { 1367 /* empty channel list provided */ 1368 qdf_mem_zero(&req->scan_req.chan_list, 1369 sizeof(req->scan_req.chan_list)); 1370 req->scan_req.chan_list.num_chan = 0; 1371 status = QDF_STATUS_SUCCESS; 1372 goto end; 1373 } 1374 if (!chan_list) { 1375 scm_err("null chan_list while num_chans: %d", num_chans); 1376 status = QDF_STATUS_E_NULL_VALUE; 1377 goto end; 1378 } 1379 1380 if (num_chans > max_chans) { 1381 /* got a big list. alert and fail */ 1382 scm_warn("overflow: received %d, max supported : %d", 1383 num_chans, max_chans); 1384 status = QDF_STATUS_E_E2BIG; 1385 goto end; 1386 } 1387 1388 req->scan_req.chan_list.num_chan = num_chans; 1389 for (idx = 0; idx < num_chans; idx++) { 1390 req->scan_req.chan_list.chan[idx].freq = 1391 (chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ? 1392 chan_list[idx] : 1393 wlan_reg_chan_to_freq(pdev, chan_list[idx]); 1394 if (phymode) 1395 req->scan_req.chan_list.chan[idx].phymode = 1396 phymode[idx]; 1397 else if (req->scan_req.chan_list.chan[idx].freq <= 1398 WLAN_CHAN_15_FREQ) 1399 req->scan_req.chan_list.chan[idx].phymode = 1400 SCAN_PHY_MODE_11G; 1401 else 1402 req->scan_req.chan_list.chan[idx].phymode = 1403 SCAN_PHY_MODE_11A; 1404 1405 scm_debug("chan[%d]: freq:%d, phymode:%d", idx, 1406 req->scan_req.chan_list.chan[idx].freq, 1407 req->scan_req.chan_list.chan[idx].phymode); 1408 } 1409 1410 end: 1411 if (scan_freqs) 1412 qdf_mem_free(scan_freqs); 1413 1414 if (reg_chan_list) 1415 qdf_mem_free(reg_chan_list); 1416 1417 return QDF_STATUS_SUCCESS; 1418 } 1419 1420 static inline enum scm_scan_status 1421 get_scan_status_from_serialization_status( 1422 enum wlan_serialization_cmd_status status) 1423 { 1424 enum scm_scan_status scan_status; 1425 1426 switch (status) { 1427 case WLAN_SER_CMD_IN_PENDING_LIST: 1428 scan_status = SCAN_IS_PENDING; 1429 break; 1430 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1431 scan_status = SCAN_IS_ACTIVE; 1432 break; 1433 case WLAN_SER_CMDS_IN_ALL_LISTS: 1434 scan_status = SCAN_IS_ACTIVE_AND_PENDING; 1435 break; 1436 case WLAN_SER_CMD_NOT_FOUND: 1437 scan_status = SCAN_NOT_IN_PROGRESS; 1438 break; 1439 default: 1440 scm_warn("invalid serialization status %d", status); 1441 QDF_ASSERT(0); 1442 scan_status = SCAN_NOT_IN_PROGRESS; 1443 break; 1444 } 1445 1446 return scan_status; 1447 } 1448 1449 enum scm_scan_status 1450 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev) 1451 { 1452 enum wlan_serialization_cmd_status status; 1453 1454 if (!vdev) { 1455 scm_err("null vdev"); 1456 return SCAN_NOT_IN_PROGRESS; 1457 } 1458 status = wlan_serialization_vdev_scan_status(vdev); 1459 1460 return get_scan_status_from_serialization_status(status); 1461 } 1462 1463 enum scm_scan_status 1464 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev) 1465 { 1466 enum wlan_serialization_cmd_status status; 1467 1468 if (!pdev) { 1469 scm_err("null pdev"); 1470 return SCAN_NOT_IN_PROGRESS; 1471 } 1472 status = wlan_serialization_pdev_scan_status(pdev); 1473 1474 return get_scan_status_from_serialization_status(status); 1475 } 1476 1477 static void 1478 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc, 1479 bool enable) 1480 { 1481 QDF_STATUS status; 1482 struct mgmt_txrx_mgmt_frame_cb_info cb_info[2]; 1483 1484 cb_info[0].frm_type = MGMT_PROBE_RESP; 1485 cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1486 cb_info[1].frm_type = MGMT_BEACON; 1487 cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1488 1489 if (enable) 1490 status = wlan_mgmt_txrx_register_rx_cb(psoc, 1491 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1492 else 1493 status = wlan_mgmt_txrx_deregister_rx_cb(psoc, 1494 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1495 if (status != QDF_STATUS_SUCCESS) 1496 scm_err("%s the Handle with MGMT TXRX layer has failed", 1497 enable ? "Registering" : "Deregistering"); 1498 } 1499 1500 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc, 1501 struct scan_user_cfg *scan_cfg) 1502 { 1503 struct wlan_scan_obj *scan_obj; 1504 struct scan_default_params *scan_def; 1505 1506 if (!psoc) { 1507 scm_err("null psoc"); 1508 return QDF_STATUS_E_FAILURE; 1509 } 1510 scan_obj = wlan_psoc_get_scan_obj(psoc); 1511 if (!scan_obj) { 1512 scm_err("Failed to get scan object"); 1513 return QDF_STATUS_E_FAILURE; 1514 } 1515 1516 scan_def = &scan_obj->scan_def; 1517 scan_obj->ie_whitelist = scan_cfg->ie_whitelist; 1518 scan_def->sta_miracast_mcc_rest_time = 1519 scan_cfg->sta_miracast_mcc_rest_time; 1520 1521 qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config, 1522 sizeof(struct scoring_config)); 1523 scm_validate_scoring_config(&scan_def->score_config); 1524 1525 return QDF_STATUS_SUCCESS; 1526 } 1527 1528 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 1529 static QDF_STATUS 1530 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) 1531 { 1532 struct scan_cancel_request *req; 1533 QDF_STATUS status; 1534 struct wlan_objmgr_vdev *vdev; 1535 1536 req = qdf_mem_malloc_atomic(sizeof(*req)); 1537 if (!req) { 1538 scm_err("Failed to allocate memory"); 1539 return QDF_STATUS_E_NOMEM; 1540 } 1541 1542 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID); 1543 if (!vdev) { 1544 scm_err("Failed to get vdev"); 1545 qdf_mem_free(req); 1546 return QDF_STATUS_E_INVAL; 1547 } 1548 req->vdev = vdev; 1549 req->cancel_req.scan_id = INVAL_SCAN_ID; 1550 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1551 req->cancel_req.vdev_id = INVAL_VDEV_ID; 1552 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 1553 status = ucfg_scan_cancel_sync(req); 1554 if (QDF_IS_STATUS_ERROR(status)) 1555 scm_err("Cancel scan request failed"); 1556 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1557 1558 return status; 1559 } 1560 1561 static QDF_STATUS 1562 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1563 { 1564 struct wlan_objmgr_pdev *pdev = NULL; 1565 QDF_STATUS status = QDF_STATUS_SUCCESS; 1566 int i; 1567 1568 ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND); 1569 /* Check all pdev */ 1570 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 1571 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); 1572 if (!pdev) 1573 continue; 1574 if (ucfg_scan_get_pdev_status(pdev) != 1575 SCAN_NOT_IN_PROGRESS) 1576 status = ucfg_scan_cancel_pdev_scan(pdev); 1577 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 1578 if (QDF_IS_STATUS_ERROR(status)) { 1579 scm_err("failed to cancel scan for pdev_id %d", i); 1580 return status; 1581 } 1582 } 1583 1584 return QDF_STATUS_SUCCESS; 1585 } 1586 1587 static QDF_STATUS 1588 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1589 { 1590 ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND); 1591 return QDF_STATUS_SUCCESS; 1592 } 1593 1594 static inline void 1595 ucfg_scan_register_pmo_handler(void) 1596 { 1597 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN, 1598 ucfg_scan_suspend_handler, NULL); 1599 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN, 1600 ucfg_scan_resume_handler, NULL); 1601 } 1602 1603 static inline void 1604 ucfg_scan_unregister_pmo_handler(void) 1605 { 1606 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN, 1607 ucfg_scan_suspend_handler); 1608 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN, 1609 ucfg_scan_resume_handler); 1610 } 1611 1612 #else 1613 static inline void 1614 ucfg_scan_register_pmo_handler(void) 1615 { 1616 } 1617 1618 static inline void 1619 ucfg_scan_unregister_pmo_handler(void) 1620 { 1621 } 1622 #endif 1623 1624 QDF_STATUS 1625 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) 1626 { 1627 struct wlan_scan_obj *scan_obj; 1628 1629 scm_debug("psoc open: 0x%pK", psoc); 1630 if (!psoc) { 1631 scm_err("null psoc"); 1632 return QDF_STATUS_E_FAILURE; 1633 } 1634 scan_obj = wlan_psoc_get_scan_obj(psoc); 1635 if (!scan_obj) { 1636 scm_err("Failed to get scan object"); 1637 return QDF_STATUS_E_FAILURE; 1638 } 1639 /* Initialize the scan Globals */ 1640 wlan_scan_global_init(psoc, scan_obj); 1641 qdf_spinlock_create(&scan_obj->lock); 1642 ucfg_scan_register_pmo_handler(); 1643 scm_db_init(psoc); 1644 1645 return QDF_STATUS_SUCCESS; 1646 } 1647 1648 QDF_STATUS 1649 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) 1650 { 1651 struct wlan_scan_obj *scan_obj; 1652 1653 scm_debug("psoc close: 0x%pK", psoc); 1654 if (!psoc) { 1655 scm_err("null psoc"); 1656 return QDF_STATUS_E_FAILURE; 1657 } 1658 scm_db_deinit(psoc); 1659 scan_obj = wlan_psoc_get_scan_obj(psoc); 1660 if (!scan_obj) { 1661 scm_err("Failed to get scan object"); 1662 return QDF_STATUS_E_FAILURE; 1663 } 1664 ucfg_scan_unregister_pmo_handler(); 1665 qdf_spinlock_destroy(&scan_obj->lock); 1666 wlan_scan_global_deinit(psoc); 1667 1668 return QDF_STATUS_SUCCESS; 1669 } 1670 1671 static bool scm_serialization_scan_rules_cb( 1672 union wlan_serialization_rules_info *comp_info, 1673 uint8_t comp_id) 1674 { 1675 switch (comp_id) { 1676 case WLAN_UMAC_COMP_TDLS: 1677 if (comp_info->scan_info.is_tdls_in_progress) { 1678 scm_debug("Cancel scan. Tdls in progress"); 1679 return false; 1680 } 1681 break; 1682 case WLAN_UMAC_COMP_DFS: 1683 if (comp_info->scan_info.is_cac_in_progress) { 1684 scm_debug("Cancel scan. CAC in progress"); 1685 return false; 1686 } 1687 break; 1688 case WLAN_UMAC_COMP_MLME: 1689 if (comp_info->scan_info.is_mlme_op_in_progress) { 1690 scm_debug("Cancel scan. MLME operation in progress"); 1691 return false; 1692 } 1693 break; 1694 default: 1695 scm_debug("not handled comp_id %d", comp_id); 1696 break; 1697 } 1698 1699 return true; 1700 } 1701 1702 QDF_STATUS 1703 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) 1704 { 1705 QDF_STATUS status; 1706 1707 scm_debug("psoc enable: 0x%pK", psoc); 1708 if (!psoc) { 1709 scm_err("null psoc"); 1710 return QDF_STATUS_E_FAILURE; 1711 } 1712 /* Subscribe for scan events from lmac layesr */ 1713 status = tgt_scan_register_ev_handler(psoc); 1714 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1715 if (!wlan_reg_is_11d_offloaded(psoc)) 1716 scm_11d_cc_db_init(psoc); 1717 ucfg_scan_register_unregister_bcn_cb(psoc, true); 1718 status = wlan_serialization_register_apply_rules_cb(psoc, 1719 WLAN_SER_CMD_SCAN, 1720 scm_serialization_scan_rules_cb); 1721 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1722 return status; 1723 } 1724 1725 QDF_STATUS 1726 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) 1727 { 1728 QDF_STATUS status; 1729 1730 scm_debug("psoc disable: 0x%pK", psoc); 1731 if (!psoc) { 1732 scm_err("null psoc"); 1733 return QDF_STATUS_E_FAILURE; 1734 } 1735 /* Unsubscribe for scan events from lmac layesr */ 1736 status = tgt_scan_unregister_ev_handler(psoc); 1737 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1738 ucfg_scan_register_unregister_bcn_cb(psoc, false); 1739 if (!wlan_reg_is_11d_offloaded(psoc)) 1740 scm_11d_cc_db_deinit(psoc); 1741 1742 return status; 1743 } 1744 1745 uint32_t 1746 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc) 1747 { 1748 struct scan_default_params *scan_params = NULL; 1749 1750 if (!psoc) { 1751 scm_err("null psoc"); 1752 return 0; 1753 } 1754 scan_params = wlan_scan_psoc_get_def_params(psoc); 1755 if (!scan_params) { 1756 scm_err("Failed to get scan object"); 1757 return 0; 1758 } 1759 1760 return scan_params->max_active_scans_allowed; 1761 } 1762 1763 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc, 1764 struct probe_req_whitelist_attr *ie_whitelist) 1765 { 1766 struct wlan_scan_obj *scan_obj = NULL; 1767 1768 scan_obj = wlan_psoc_get_scan_obj(psoc); 1769 if (!scan_obj) 1770 return false; 1771 1772 qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist, 1773 sizeof(*ie_whitelist)); 1774 1775 return true; 1776 } 1777 1778 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc, 1779 struct wlan_objmgr_vdev *vdev) 1780 { 1781 struct wlan_scan_obj *scan_obj = NULL; 1782 1783 scan_obj = wlan_psoc_get_scan_obj(psoc); 1784 if (!scan_obj) 1785 return false; 1786 1787 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || 1788 wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS) 1789 return false; 1790 1791 if (!scan_obj->ie_whitelist.white_list) 1792 return false; 1793 1794 return true; 1795 } 1796 1797 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, 1798 bool bt_a2dp_active) 1799 { 1800 struct wlan_scan_obj *scan_obj; 1801 1802 scan_obj = wlan_psoc_get_scan_obj(psoc); 1803 if (!scan_obj) { 1804 scm_err("Failed to get scan object"); 1805 return; 1806 } 1807 scan_obj->bt_a2dp_enabled = bt_a2dp_active; 1808 } 1809 1810 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) 1811 { 1812 struct wlan_scan_obj *scan_obj; 1813 1814 scan_obj = wlan_psoc_get_scan_obj(psoc); 1815 if (!scan_obj) { 1816 scm_err("Failed to get scan object"); 1817 return false; 1818 } 1819 1820 return scan_obj->bt_a2dp_enabled; 1821 } 1822 1823 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc) 1824 { 1825 struct wlan_scan_obj *scan_obj; 1826 1827 scan_obj = wlan_psoc_get_scan_obj(psoc); 1828 if (!scan_obj) 1829 return false; 1830 1831 return scan_obj->scan_def.use_wake_lock_in_user_scan; 1832 } 1833 1834 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc) 1835 { 1836 struct wlan_scan_obj *scan_obj; 1837 1838 scan_obj = wlan_psoc_get_scan_obj(psoc); 1839 if (!scan_obj) { 1840 scm_err("Failed to get scan object"); 1841 return cfg_default(CFG_ENABLE_CONNECTED_SCAN); 1842 } 1843 1844 return scan_obj->scan_def.enable_connected_scan; 1845 } 1846 1847 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc) 1848 { 1849 struct wlan_scan_obj *scan_obj; 1850 1851 scan_obj = wlan_psoc_get_scan_obj(psoc); 1852 if (!scan_obj) { 1853 scm_err("Failed to get scan object"); 1854 return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING); 1855 } 1856 1857 return scan_obj->scan_def.enable_mac_spoofing; 1858 } 1859 1860 enum scan_dwelltime_adaptive_mode 1861 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc) 1862 { 1863 struct wlan_scan_obj *scan_obj; 1864 1865 scan_obj = wlan_psoc_get_scan_obj(psoc); 1866 if (!scan_obj) { 1867 scm_err("Failed to get scan object"); 1868 return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 1869 } 1870 1871 return scan_obj->scan_def.extscan_adaptive_dwell_mode; 1872 } 1873 1874 QDF_STATUS 1875 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, 1876 enum scan_config config, uint32_t val) 1877 { 1878 struct wlan_scan_obj *scan_obj; 1879 QDF_STATUS status = QDF_STATUS_SUCCESS; 1880 1881 scan_obj = wlan_psoc_get_scan_obj(psoc); 1882 if (!scan_obj) { 1883 scm_err("Failed to get scan object config:%d, val:%d", 1884 config, val); 1885 return QDF_STATUS_E_INVAL; 1886 } 1887 switch (config) { 1888 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1889 scan_obj->disable_timeout = !!val; 1890 break; 1891 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1892 scan_obj->drop_bcn_on_chan_mismatch = !!val; 1893 break; 1894 1895 default: 1896 status = QDF_STATUS_E_INVAL; 1897 break; 1898 } 1899 1900 return status; 1901 } 1902 1903 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev, 1904 struct bss_info *bss_info, struct mlme_info *mlme) 1905 { 1906 QDF_STATUS status; 1907 1908 status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme); 1909 1910 return status; 1911 } 1912 1913 QDF_STATUS 1914 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc, 1915 enum scan_config config, uint32_t *val) 1916 { 1917 struct wlan_scan_obj *scan_obj; 1918 QDF_STATUS status = QDF_STATUS_SUCCESS; 1919 1920 scan_obj = wlan_psoc_get_scan_obj(psoc); 1921 if (!scan_obj || !val) { 1922 scm_err("scan object:%pK config:%d, val:0x%pK", 1923 scan_obj, config, val); 1924 return QDF_STATUS_E_INVAL; 1925 } 1926 switch (config) { 1927 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1928 *val = scan_obj->disable_timeout; 1929 break; 1930 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1931 *val = scan_obj->drop_bcn_on_chan_mismatch; 1932 break; 1933 1934 default: 1935 status = QDF_STATUS_E_INVAL; 1936 break; 1937 } 1938 1939 return status; 1940 } 1941 1942 #ifdef FEATURE_WLAN_SCAN_PNO 1943 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc) 1944 { 1945 struct wlan_scan_obj *scan_obj; 1946 1947 scan_obj = wlan_psoc_get_scan_obj(psoc); 1948 if (!scan_obj) { 1949 scm_err("NULL scan obj"); 1950 return false; 1951 } 1952 1953 return scan_obj->pno_cfg.pno_offload_enabled; 1954 } 1955 1956 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value) 1957 { 1958 struct wlan_scan_obj *scan_obj; 1959 1960 scan_obj = wlan_psoc_get_scan_obj(psoc); 1961 if (!scan_obj) { 1962 scm_err("NULL scan obj"); 1963 return; 1964 } 1965 1966 scan_obj->pno_cfg.pno_offload_enabled = value; 1967 } 1968 1969 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc) 1970 { 1971 struct wlan_scan_obj *scan_obj; 1972 1973 scan_obj = wlan_psoc_get_scan_obj(psoc); 1974 if (!scan_obj) { 1975 scm_err("NULL scan obj"); 1976 return cfg_default(CFG_PNO_SCAN_SUPPORT); 1977 } 1978 1979 return scan_obj->pno_cfg.scan_support_enabled; 1980 } 1981 1982 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc) 1983 { 1984 struct wlan_scan_obj *scan_obj; 1985 1986 scan_obj = wlan_psoc_get_scan_obj(psoc); 1987 if (!scan_obj) { 1988 scm_err("NULL scan obj"); 1989 return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER); 1990 } 1991 return scan_obj->pno_cfg.scan_backoff_multiplier; 1992 } 1993 1994 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc) 1995 { 1996 struct wlan_scan_obj *scan_obj; 1997 1998 scan_obj = wlan_psoc_get_scan_obj(psoc); 1999 if (!scan_obj) { 2000 scm_err("NULL scan obj"); 2001 return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN); 2002 } 2003 return scan_obj->pno_cfg.dfs_chnl_scan_enabled; 2004 } 2005 2006 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc) 2007 { 2008 struct wlan_scan_obj *scan_obj; 2009 2010 scan_obj = wlan_psoc_get_scan_obj(psoc); 2011 if (!scan_obj) { 2012 scm_err("NULL scan obj"); 2013 return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 2014 } 2015 return scan_obj->pno_cfg.scan_timer_repeat_value; 2016 } 2017 2018 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc) 2019 { 2020 struct wlan_scan_obj *scan_obj; 2021 2022 scan_obj = wlan_psoc_get_scan_obj(psoc); 2023 if (!scan_obj) { 2024 scm_err("NULL scan obj"); 2025 return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER); 2026 } 2027 return scan_obj->pno_cfg.slow_scan_multiplier; 2028 } 2029 2030 uint32_t 2031 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc) 2032 { 2033 struct wlan_scan_obj *scan_obj; 2034 2035 scan_obj = wlan_psoc_get_scan_obj(psoc); 2036 if (!scan_obj) { 2037 scm_err("Failed to get scan object"); 2038 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); 2039 } 2040 2041 return scan_obj->pno_cfg.max_sched_scan_plan_interval; 2042 } 2043 2044 uint32_t 2045 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc) 2046 { 2047 struct wlan_scan_obj *scan_obj; 2048 2049 scan_obj = wlan_psoc_get_scan_obj(psoc); 2050 if (!scan_obj) { 2051 scm_err("Failed to get scan object"); 2052 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 2053 } 2054 2055 return scan_obj->pno_cfg.max_sched_scan_plan_iterations; 2056 } 2057 2058 #endif 2059