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_objmgr_vdev_obj.h> 39 #include <wlan_dfs_utils_api.h> 40 #include <wlan_policy_mgr_api.h> 41 #endif 42 #include "cfg_ucfg_api.h" 43 #include "wlan_extscan_api.h" 44 45 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc, 46 update_beacon_cb cb, enum scan_cb_type type) 47 { 48 return scm_scan_register_bcn_cb(psoc, cb, type); 49 } 50 51 qdf_list_t *ucfg_scan_get_result(struct wlan_objmgr_pdev *pdev, 52 struct scan_filter *filter) 53 { 54 return scm_get_scan_result(pdev, filter); 55 } 56 57 QDF_STATUS ucfg_scan_db_iterate(struct wlan_objmgr_pdev *pdev, 58 scan_iterator_func func, void *arg) 59 { 60 return scm_iterate_scan_db(pdev, func, arg); 61 } 62 63 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list) 64 { 65 return scm_purge_scan_results(scan_list); 66 } 67 68 QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev, 69 struct scan_filter *filter) 70 { 71 return scm_flush_results(pdev, filter); 72 } 73 74 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev, 75 uint8_t *chan_list, uint32_t num_chan) 76 { 77 scm_filter_valid_channel(pdev, chan_list, num_chan); 78 } 79 80 QDF_STATUS ucfg_scan_init(void) 81 { 82 QDF_STATUS status; 83 84 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 85 wlan_scan_psoc_created_notification, NULL); 86 if (QDF_IS_STATUS_ERROR(status)) { 87 scm_err("Failed to register psoc create handler"); 88 goto fail_create_psoc; 89 } 90 91 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN, 92 wlan_scan_psoc_destroyed_notification, NULL); 93 if (QDF_IS_STATUS_ERROR(status)) { 94 scm_err("Failed to create psoc delete handler"); 95 goto fail_psoc_destroy; 96 } 97 scm_debug("scan psoc create and delete handler registered with objmgr"); 98 99 status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 100 wlan_scan_vdev_created_notification, NULL); 101 if (QDF_IS_STATUS_ERROR(status)) { 102 scm_err("Failed to register vdev create handler"); 103 goto fail_pdev_create; 104 } 105 106 status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN, 107 wlan_scan_vdev_destroyed_notification, NULL); 108 if (QDF_IS_STATUS_SUCCESS(status)) { 109 scm_debug("scan vdev create and delete handler registered with objmgr"); 110 return QDF_STATUS_SUCCESS; 111 } 112 113 scm_err("Failed to destroy vdev delete handler"); 114 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 115 wlan_scan_vdev_created_notification, NULL); 116 fail_pdev_create: 117 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN, 118 wlan_scan_psoc_destroyed_notification, NULL); 119 fail_psoc_destroy: 120 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 121 wlan_scan_psoc_created_notification, NULL); 122 fail_create_psoc: 123 return status; 124 } 125 126 QDF_STATUS ucfg_scan_deinit(void) 127 { 128 QDF_STATUS status; 129 130 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 131 wlan_scan_psoc_created_notification, NULL); 132 if (status != QDF_STATUS_SUCCESS) 133 scm_err("Failed to unregister psoc create handler"); 134 135 status = wlan_objmgr_unregister_psoc_destroy_handler( 136 WLAN_UMAC_COMP_SCAN, 137 wlan_scan_psoc_destroyed_notification, NULL); 138 if (status != QDF_STATUS_SUCCESS) 139 scm_err("Failed to unregister psoc delete handler"); 140 141 status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 142 wlan_scan_vdev_created_notification, NULL); 143 if (status != QDF_STATUS_SUCCESS) 144 scm_err("Failed to unregister vdev create handler"); 145 146 status = wlan_objmgr_unregister_vdev_destroy_handler( 147 WLAN_UMAC_COMP_SCAN, 148 wlan_scan_vdev_destroyed_notification, NULL); 149 if (status != QDF_STATUS_SUCCESS) 150 scm_err("Failed to unregister vdev delete handler"); 151 152 return status; 153 } 154 155 #ifdef FEATURE_WLAN_SCAN_PNO 156 157 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev, 158 struct pno_scan_req_params *req) 159 { 160 struct scan_vdev_obj *scan_vdev_obj; 161 QDF_STATUS status; 162 163 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 164 if (!scan_vdev_obj) { 165 scm_err("null scan_vdev_obj"); 166 return QDF_STATUS_E_INVAL; 167 } 168 if (scan_vdev_obj->pno_in_progress) { 169 scm_err("pno already in progress"); 170 return QDF_STATUS_E_ALREADY; 171 } 172 173 status = tgt_scan_pno_start(vdev, req); 174 if (QDF_IS_STATUS_ERROR(status)) 175 scm_err("pno start failed"); 176 else 177 scan_vdev_obj->pno_in_progress = true; 178 179 return status; 180 } 181 182 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev) 183 { 184 struct scan_vdev_obj *scan_vdev_obj; 185 QDF_STATUS status; 186 187 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 188 if (!scan_vdev_obj) { 189 scm_err("null scan_vdev_obj"); 190 return QDF_STATUS_E_INVAL; 191 } 192 if (!scan_vdev_obj->pno_in_progress) { 193 scm_debug("pno already stopped"); 194 return QDF_STATUS_E_ALREADY; 195 } 196 197 status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev)); 198 if (QDF_IS_STATUS_ERROR(status)) 199 scm_err("pno start failed"); 200 else 201 scan_vdev_obj->pno_in_progress = false; 202 203 return status; 204 } 205 206 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev) 207 { 208 struct scan_vdev_obj *scan_vdev_obj; 209 210 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 211 if (!scan_vdev_obj) { 212 scm_err("null scan_vdev_obj"); 213 return false; 214 } 215 216 return scan_vdev_obj->pno_in_progress; 217 } 218 219 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev) 220 { 221 struct scan_vdev_obj *scan_vdev_obj; 222 223 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 224 if (!scan_vdev_obj) { 225 scm_err("null scan_vdev_obj"); 226 return false; 227 } 228 229 return scan_vdev_obj->pno_match_evt_received; 230 } 231 232 static QDF_STATUS 233 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc, 234 struct pno_def_config *pno_def) 235 { 236 struct nlo_mawc_params *mawc_cfg; 237 238 qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl"); 239 mawc_cfg = &pno_def->mawc_params; 240 pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION); 241 pno_def->top_k_num_of_channels = 242 cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS); 243 pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD); 244 pno_def->channel_prediction_full_scan = 245 cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER); 246 pno_def->adaptive_dwell_mode = 247 cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE); 248 pno_def->dfs_chnl_scan_enabled = 249 cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN); 250 pno_def->scan_support_enabled = 251 cfg_get(psoc, CFG_PNO_SCAN_SUPPORT); 252 pno_def->scan_timer_repeat_value = 253 cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 254 pno_def->slow_scan_multiplier = 255 cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER); 256 pno_def->scan_backoff_multiplier = 257 cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER); 258 259 mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED); 260 mawc_cfg->exp_backoff_ratio = 261 cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO); 262 mawc_cfg->init_scan_interval = 263 cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL); 264 mawc_cfg->max_scan_interval = 265 cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL); 266 267 return QDF_STATUS_SUCCESS; 268 } 269 270 static QDF_STATUS 271 wlan_pno_global_deinit(struct pno_def_config *pno_def) 272 { 273 qdf_wake_lock_destroy(&pno_def->pno_wake_lock); 274 275 return QDF_STATUS_SUCCESS; 276 } 277 278 #ifdef WLAN_POLICY_MGR_ENABLE 279 /* 280 * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time 281 * depending on active concurrency modes 282 * @vdev: vdev object pointer 283 * @req: scan request 284 * 285 * Return: void 286 */ 287 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 288 struct pno_scan_req_params *req, struct scan_default_params *scan_def) 289 { 290 bool sap_or_p2p_present; 291 struct wlan_objmgr_psoc *psoc; 292 293 psoc = wlan_vdev_get_psoc(vdev); 294 295 if (!psoc) 296 return; 297 298 sap_or_p2p_present = policy_mgr_mode_specific_connection_count( 299 psoc, PM_SAP_MODE, NULL) || 300 policy_mgr_mode_specific_connection_count( 301 psoc, PM_P2P_GO_MODE, NULL) || 302 policy_mgr_mode_specific_connection_count( 303 psoc, PM_P2P_CLIENT_MODE, NULL); 304 305 if (sap_or_p2p_present) { 306 req->active_dwell_time = scan_def->conc_active_dwell; 307 req->passive_dwell_time = scan_def->conc_passive_dwell; 308 } 309 310 } 311 #else 312 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 313 struct pno_scan_req_params *req, struct scan_default_params *scan_def){} 314 #endif 315 316 QDF_STATUS 317 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev, 318 struct pno_scan_req_params *req) 319 { 320 struct scan_default_params *scan_def; 321 struct wlan_scan_obj *scan; 322 struct pno_def_config *pno_def; 323 324 if (!vdev || !req) { 325 scm_err("vdev: 0x%pK, req: 0x%pK", 326 vdev, req); 327 return QDF_STATUS_E_INVAL; 328 } 329 330 scan = wlan_vdev_get_scan_obj(vdev); 331 if (!scan) { 332 scm_err("scan is NULL"); 333 return QDF_STATUS_E_INVAL; 334 } 335 scan_def = wlan_vdev_get_def_scan_params(vdev); 336 if (!scan_def) { 337 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 338 return QDF_STATUS_E_NULL_VALUE; 339 } 340 341 pno_def = &scan->pno_cfg; 342 req->active_dwell_time = scan_def->active_dwell; 343 req->passive_dwell_time = scan_def->passive_dwell; 344 req->scan_random.randomize = scan_def->enable_mac_spoofing; 345 346 /* 347 * Update active and passive dwell time depending 348 * upon the present active concurrency mode 349 */ 350 ucfg_scan_update_pno_dwell_time(vdev, req, scan_def); 351 req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode; 352 req->pno_channel_prediction = pno_def->channel_prediction; 353 req->top_k_num_of_channels = pno_def->top_k_num_of_channels; 354 req->stationary_thresh = pno_def->stationary_thresh; 355 req->channel_prediction_full_scan = 356 pno_def->channel_prediction_full_scan; 357 req->mawc_params.vdev_id = wlan_vdev_get_id(vdev); 358 qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params, 359 sizeof(req->mawc_params)); 360 361 return QDF_STATUS_SUCCESS; 362 } 363 364 QDF_STATUS 365 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc, 366 scan_event_handler event_cb, void *arg) 367 { 368 struct wlan_scan_obj *scan; 369 370 if (!psoc) { 371 scm_err("null psoc"); 372 return QDF_STATUS_E_INVAL; 373 } 374 scan = wlan_psoc_get_scan_obj(psoc); 375 qdf_spin_lock_bh(&scan->lock); 376 scan->pno_cfg.pno_cb.func = event_cb; 377 scan->pno_cfg.pno_cb.arg = arg; 378 qdf_spin_unlock_bh(&scan->lock); 379 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 380 381 return QDF_STATUS_SUCCESS; 382 } 383 384 #else 385 386 static inline QDF_STATUS 387 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc, 388 struct pno_def_config *pno_def) 389 { 390 return QDF_STATUS_SUCCESS; 391 } 392 static inline QDF_STATUS 393 wlan_pno_global_deinit(struct pno_def_config *pno_def) 394 { 395 return QDF_STATUS_SUCCESS; 396 } 397 398 #endif 399 400 #ifdef WLAN_POLICY_MGR_ENABLE 401 /** 402 * ucfg_scan_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags 403 * @req: pointer to scan request 404 * 405 * This function sets scan_ctrl_flags_ext value depending on the type of 406 * scan and the channel lists. 407 * 408 * Non-DBS scan is requested if any of the below case is met: 409 * 1. HW is DBS incapable 410 * 2. A high accuracy scan request is sent by kernel. 411 * 412 * DBS scan is enabled for these conditions: 413 * 1. A low power or low span scan request is sent by kernel. 414 * For remaining cases DBS is enabled by default. 415 * Return: void 416 */ 417 static void 418 ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 419 { 420 struct wlan_objmgr_psoc *psoc; 421 uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; 422 423 psoc = wlan_vdev_get_psoc(req->vdev); 424 425 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 426 scm_debug("dbs disabled, going for non-dbs scan"); 427 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 428 goto end; 429 } 430 431 if (req->scan_req.scan_policy_high_accuracy) { 432 scm_debug("high accuracy scan received, going for non-dbs scan"); 433 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 434 goto end; 435 } 436 if ((req->scan_req.scan_policy_low_power) || 437 (req->scan_req.scan_policy_low_span)) { 438 scm_debug("low power/span scan received, going for dbs scan"); 439 scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; 440 goto end; 441 } 442 443 end: 444 req->scan_req.scan_ctrl_flags_ext |= 445 ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) 446 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); 447 scm_debug("scan_ctrl_flags_ext: 0x%x", 448 req->scan_req.scan_ctrl_flags_ext); 449 } 450 451 /** 452 * ucfg_update_passive_dwell_time() - update dwell passive time 453 * @vdev: vdev object 454 * @req: scan request 455 * 456 * Return: None 457 */ 458 static void 459 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 460 struct scan_start_request *req) 461 { 462 struct wlan_objmgr_psoc *psoc; 463 464 psoc = wlan_vdev_get_psoc(vdev); 465 if (!psoc) 466 return; 467 468 if (policy_mgr_is_sta_connected_2g(psoc) && 469 !policy_mgr_is_hw_dbs_capable(psoc) && 470 ucfg_scan_get_bt_activity(psoc)) 471 req->scan_req.dwell_time_passive = 472 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 473 } 474 475 static const struct probe_time_dwell_time 476 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 477 {28, 11}, /* 0 SSID */ 478 {28, 20}, /* 1 SSID */ 479 {28, 20}, /* 2 SSID */ 480 {28, 20}, /* 3 SSID */ 481 {28, 20}, /* 4 SSID */ 482 {28, 20}, /* 5 SSID */ 483 {28, 20}, /* 6 SSID */ 484 {28, 11}, /* 7 SSID */ 485 {28, 11}, /* 8 SSID */ 486 {28, 11}, /* 9 SSID */ 487 {28, 8} /* 10 SSID */ 488 }; 489 490 /** 491 * ucfg_scan_get_burst_duration() - get burst duration depending on max chan 492 * and miracast. 493 * @max_ch_time: max channel time 494 * @miracast_enabled: if miracast is enabled 495 * 496 * Return: burst_duration 497 */ 498 static inline 499 int ucfg_scan_get_burst_duration(int max_ch_time, 500 bool miracast_enabled) 501 { 502 int burst_duration = 0; 503 504 if (miracast_enabled) { 505 /* 506 * When miracast is running, burst 507 * duration needs to be minimum to avoid 508 * any stutter or glitch in miracast 509 * during station scan 510 */ 511 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 512 burst_duration = max_ch_time; 513 else 514 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 515 } else { 516 /* 517 * If miracast is not running, accommodate max 518 * stations to make the scans faster 519 */ 520 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 521 max_ch_time; 522 523 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 524 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 525 max_ch_time; 526 527 if (channels) 528 burst_duration = channels * max_ch_time; 529 else 530 burst_duration = 531 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 532 } 533 } 534 return burst_duration; 535 } 536 537 /** 538 * ucfg_scan_req_update_params() - update scan req params depending on 539 * concurrent mode present. 540 * @vdev: vdev object pointer 541 * @req: scan request 542 * @scan_obj: scan object 543 * 544 * Return: void 545 */ 546 static void ucfg_scan_req_update_concurrency_params( 547 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req, 548 struct wlan_scan_obj *scan_obj) 549 { 550 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 551 struct wlan_objmgr_psoc *psoc; 552 553 psoc = wlan_vdev_get_psoc(vdev); 554 555 if (!psoc) 556 return; 557 558 ap_present = policy_mgr_mode_specific_connection_count( 559 psoc, PM_SAP_MODE, NULL); 560 go_present = policy_mgr_mode_specific_connection_count( 561 psoc, PM_P2P_GO_MODE, NULL); 562 p2p_cli_present = policy_mgr_mode_specific_connection_count( 563 psoc, PM_P2P_CLIENT_MODE, NULL); 564 sta_active = policy_mgr_mode_specific_connection_count( 565 psoc, PM_STA_MODE, NULL); 566 ndi_present = policy_mgr_mode_specific_connection_count( 567 psoc, PM_NDI_MODE, NULL); 568 569 if (policy_mgr_get_connection_count(psoc)) { 570 if (req->scan_req.scan_f_passive) 571 req->scan_req.dwell_time_passive = 572 scan_obj->scan_def.conc_passive_dwell; 573 else 574 req->scan_req.dwell_time_active = 575 scan_obj->scan_def.conc_active_dwell; 576 req->scan_req.max_rest_time = 577 scan_obj->scan_def.conc_max_rest_time; 578 req->scan_req.min_rest_time = 579 scan_obj->scan_def.conc_min_rest_time; 580 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 581 } 582 583 if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) 584 req->scan_req.adaptive_dwell_time_mode = 585 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 586 /* 587 * If AP is active set min rest time same as max rest time, so that 588 * firmware spends more time on home channel which will increase the 589 * probability of sending beacon at TBTT 590 */ 591 if (ap_present || go_present) { 592 req->scan_req.dwell_time_active_2g = 0; 593 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 594 } 595 596 /* 597 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell 598 * time for 2g channels instead of dwell_time_active_2g 599 */ 600 if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) { 601 req->scan_req.dwell_time_active_2g = 0; 602 } 603 604 if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { 605 /* 606 * Decide burst_duration and dwell_time_active based on 607 * what type of devices are active. 608 */ 609 do { 610 if (ap_present && go_present && sta_active) { 611 if (req->scan_req.dwell_time_active <= 612 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 613 req->scan_req.burst_duration = 614 req->scan_req.dwell_time_active; 615 else 616 req->scan_req.burst_duration = 617 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 618 619 break; 620 } 621 622 if (scan_obj->miracast_enabled && 623 policy_mgr_is_mcc_in_24G(psoc)) 624 req->scan_req.max_rest_time = 625 scan_obj->scan_def.sta_miracast_mcc_rest_time; 626 627 if (go_present) { 628 /* 629 * Background scan while GO is sending beacons. 630 * Every off-channel transition has overhead of 631 * 2 beacon intervals for NOA. Maximize number 632 * of channels in every transition by using 633 * burst scan. 634 */ 635 req->scan_req.burst_duration = 636 ucfg_scan_get_burst_duration( 637 req->scan_req.dwell_time_active, 638 scan_obj->miracast_enabled); 639 break; 640 } 641 if ((sta_active || p2p_cli_present) && 642 !req->scan_req.burst_duration) { 643 /* Typical background scan. 644 * Disable burst scan for now. 645 */ 646 req->scan_req.burst_duration = 0; 647 break; 648 } 649 650 if (ndi_present) { 651 req->scan_req.burst_duration = 652 ucfg_scan_get_burst_duration( 653 req->scan_req.dwell_time_active, 654 scan_obj->miracast_enabled); 655 break; 656 } 657 } while (0); 658 659 if (ap_present) { 660 uint8_t ssid_num; 661 ssid_num = req->scan_req.num_ssids * 662 req->scan_req.num_bssid; 663 req->scan_req.repeat_probe_time = 664 scan_probe_time_dwell_time_map[ 665 QDF_MIN(ssid_num, 666 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 667 - 1)].probe_time; 668 req->scan_req.n_probes = 669 (req->scan_req.repeat_probe_time > 0) ? 670 req->scan_req.dwell_time_active / 671 req->scan_req.repeat_probe_time : 0; 672 } 673 } 674 675 if (ap_present) { 676 uint8_t ap_chan; 677 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 678 679 ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 680 /* 681 * P2P/STA scan while SoftAP is sending beacons. 682 * Max duration of CTS2self is 32 ms, which limits the 683 * dwell time. If DBS is supported and if SAP is on 2G channel 684 * then keep passive dwell time default. 685 */ 686 req->scan_req.dwell_time_active = 687 QDF_MIN(req->scan_req.dwell_time_active, 688 (SCAN_CTS_DURATION_MS_MAX - 689 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 690 if (!policy_mgr_is_hw_dbs_capable(psoc) || 691 (policy_mgr_is_hw_dbs_capable(psoc) && 692 WLAN_CHAN_IS_5GHZ(ap_chan))) { 693 req->scan_req.dwell_time_passive = 694 req->scan_req.dwell_time_active; 695 } 696 req->scan_req.burst_duration = 0; 697 if (utils_is_dfs_ch(pdev, ap_chan)) 698 req->scan_req.burst_duration = 699 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 700 req->scan_req.dwell_time_active; 701 } 702 } 703 704 #else 705 static inline void ucfg_scan_req_update_concurrency_params( 706 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req, 707 struct wlan_scan_obj *scan_obj) 708 { 709 } 710 static inline void 711 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 712 struct scan_start_request *req) {} 713 static inline void 714 ucfg_scan_update_dbs_scan_ctrl_ext_flag( 715 struct scan_start_request *req) {} 716 #endif 717 718 QDF_STATUS 719 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev, 720 struct chan_list *chan_list) 721 { 722 uint8_t pdev_id; 723 struct wlan_scan_obj *scan_obj; 724 725 if (!pdev || !chan_list) { 726 scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list); 727 return QDF_STATUS_E_NULL_VALUE; 728 } 729 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 730 scan_obj = wlan_pdev_get_scan_obj(pdev); 731 732 qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list, 733 chan_list, sizeof(*chan_list)); 734 735 return QDF_STATUS_SUCCESS; 736 } 737 738 /** 739 * ucfg_update_channel_list() - update scan req params depending on dfs inis 740 * and initial scan request. 741 * @req: scan request 742 * @scan_obj: scan object 743 * 744 * Return: void 745 */ 746 static void 747 ucfg_update_channel_list(struct scan_start_request *req, 748 struct wlan_scan_obj *scan_obj) 749 { 750 uint8_t i; 751 uint8_t num_scan_channels = 0; 752 struct scan_vdev_obj *scan_vdev_obj; 753 struct wlan_objmgr_pdev *pdev; 754 bool first_scan_done = true; 755 756 pdev = wlan_vdev_get_pdev(req->vdev); 757 758 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 759 if (!scan_vdev_obj) { 760 scm_err("null scan_vdev_obj"); 761 return; 762 } 763 764 if (!scan_vdev_obj->first_scan_done) { 765 first_scan_done = false; 766 scan_vdev_obj->first_scan_done = true; 767 } 768 769 /* 770 * No need to update channels if req is passive scan and single channel 771 * ie ROC, Preauth etc 772 */ 773 if (req->scan_req.scan_f_passive && 774 req->scan_req.chan_list.num_chan == 1) 775 return; 776 777 /* do this only for STA and P2P-CLI mode */ 778 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 779 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 780 return; 781 782 if (scan_obj->scan_def.allow_dfs_chan_in_scan && 783 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 784 first_scan_done)) 785 return; 786 787 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 788 if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev, 789 req->scan_req.chan_list. 790 chan[i].freq))) 791 continue; 792 req->scan_req.chan_list.chan[num_scan_channels++] = 793 req->scan_req.chan_list.chan[i]; 794 } 795 req->scan_req.chan_list.num_chan = num_scan_channels; 796 } 797 798 /** 799 * ucfg_scan_req_update_params() - update scan req params depending on modes 800 * and scan type. 801 * @vdev: vdev object pointer 802 * @req: scan request 803 * @scan_obj: scan object 804 * 805 * Return: void 806 */ 807 static void 808 ucfg_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 809 struct scan_start_request *req, struct wlan_scan_obj *scan_obj) 810 { 811 struct chan_list *custom_chan_list; 812 struct wlan_objmgr_pdev *pdev; 813 uint8_t pdev_id; 814 815 /* Ensure correct number of probes are sent on active channel */ 816 if (!req->scan_req.repeat_probe_time) 817 req->scan_req.repeat_probe_time = 818 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 819 820 if (req->scan_req.scan_f_passive) 821 req->scan_req.scan_ctrl_flags_ext |= 822 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 823 824 if (!req->scan_req.n_probes) 825 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 826 req->scan_req.dwell_time_active / 827 req->scan_req.repeat_probe_time : 0; 828 829 if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { 830 req->scan_req.scan_f_cck_rates = true; 831 if (!req->scan_req.num_ssids) 832 req->scan_req.scan_f_bcast_probe = true; 833 req->scan_req.scan_f_add_ds_ie_in_probe = true; 834 req->scan_req.scan_f_filter_prb_req = true; 835 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 836 } else { 837 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 838 req->scan_req.dwell_time_active_2g = 0; 839 if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) { 840 req->scan_req.repeat_probe_time = 0; 841 } else { 842 req->scan_req.scan_f_filter_prb_req = true; 843 if (!req->scan_req.num_ssids) 844 req->scan_req.scan_f_bcast_probe = true; 845 846 req->scan_req.dwell_time_active += 847 P2P_SEARCH_DWELL_TIME_INC; 848 /* 849 * 3 channels with default max dwell time 40 ms. 850 * Cap limit will be set by 851 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 852 * should be such that no channel is scanned less 853 * than the dwell time in normal scenarios. 854 */ 855 if (req->scan_req.chan_list.num_chan == 856 WLAN_P2P_SOCIAL_CHANNELS && 857 !scan_obj->miracast_enabled) 858 req->scan_req.repeat_probe_time = 859 req->scan_req.dwell_time_active / 5; 860 else 861 req->scan_req.repeat_probe_time = 862 req->scan_req.dwell_time_active / 3; 863 864 req->scan_req.burst_duration = 865 BURST_SCAN_MAX_NUM_OFFCHANNELS * 866 req->scan_req.dwell_time_active; 867 if (req->scan_req.burst_duration > 868 P2P_SCAN_MAX_BURST_DURATION) { 869 uint8_t channels = 870 P2P_SCAN_MAX_BURST_DURATION / 871 req->scan_req.dwell_time_active; 872 if (channels) 873 req->scan_req.burst_duration = 874 channels * 875 req->scan_req.dwell_time_active; 876 else 877 req->scan_req.burst_duration = 878 P2P_SCAN_MAX_BURST_DURATION; 879 } 880 req->scan_req.scan_ev_bss_chan = false; 881 } 882 } 883 884 if (!req->scan_req.scan_f_passive) 885 ucfg_update_passive_dwell_time(vdev, req); 886 ucfg_scan_update_dbs_scan_ctrl_ext_flag(req); 887 888 /* 889 * No need to update conncurrency parmas if req is passive scan on 890 * single channel ie ROC, Preauth etc 891 */ 892 if (!(req->scan_req.scan_f_passive && 893 req->scan_req.chan_list.num_chan == 1)) 894 ucfg_scan_req_update_concurrency_params(vdev, req, scan_obj); 895 896 /* Set wide band flag if enabled. This will cause 897 * phymode TLV being sent to FW. 898 */ 899 pdev = wlan_vdev_get_pdev(vdev); 900 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 901 if (ucfg_scan_get_wide_band_scan(pdev)) 902 req->scan_req.scan_f_wide_band = true; 903 else 904 req->scan_req.scan_f_wide_band = false; 905 906 /* Overwrite scan channles with custom scan channel 907 * list if configured. 908 */ 909 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 910 if (custom_chan_list->num_chan) 911 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 912 sizeof(struct chan_list)); 913 else if (!req->scan_req.chan_list.num_chan) 914 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 915 916 ucfg_update_channel_list(req, scan_obj); 917 scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d " 918 "n_probes %d flags_ext %x, wide_bw_scan: %d", 919 req->scan_req.dwell_time_active, 920 req->scan_req.dwell_time_passive, 921 req->scan_req.repeat_probe_time, req->scan_req.n_probes, 922 req->scan_req.scan_ctrl_flags_ext, 923 req->scan_req.scan_f_wide_band); 924 } 925 926 QDF_STATUS 927 ucfg_scan_start(struct scan_start_request *req) 928 { 929 struct scheduler_msg msg = {0}; 930 QDF_STATUS status; 931 struct wlan_scan_obj *scan_obj; 932 struct wlan_objmgr_pdev *pdev; 933 uint8_t idx; 934 935 if (!req || !req->vdev) { 936 scm_err("req or vdev within req is NULL"); 937 if (req) 938 scm_scan_free_scan_request_mem(req); 939 return QDF_STATUS_E_NULL_VALUE; 940 } 941 942 pdev = wlan_vdev_get_pdev(req->vdev); 943 if (!pdev) { 944 scm_err("Failed to get pdev object"); 945 scm_scan_free_scan_request_mem(req); 946 return QDF_STATUS_E_NULL_VALUE; 947 } 948 949 if (!scm_is_scan_allowed(req->vdev)) { 950 scm_err("scan disabled, rejecting the scan req"); 951 scm_scan_free_scan_request_mem(req); 952 return QDF_STATUS_E_AGAIN; 953 } 954 955 scan_obj = wlan_pdev_get_scan_obj(pdev); 956 if (!scan_obj) { 957 scm_err("Failed to get scan object"); 958 scm_scan_free_scan_request_mem(req); 959 return QDF_STATUS_E_NULL_VALUE; 960 } 961 962 scm_debug("reqid: %d, scanid: %d, vdevid: %d", 963 req->scan_req.scan_req_id, req->scan_req.scan_id, 964 req->scan_req.vdev_id); 965 966 ucfg_scan_req_update_params(req->vdev, req, scan_obj); 967 968 /* Try to get vdev reference. Return if reference could 969 * not be taken. Reference will be released once scan 970 * request handling completes along with free of @req. 971 */ 972 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 973 if (QDF_IS_STATUS_ERROR(status)) { 974 scm_info("unable to get reference"); 975 scm_scan_free_scan_request_mem(req); 976 return status; 977 } 978 979 scm_info("request to scan %d channels", 980 req->scan_req.chan_list.num_chan); 981 for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++) 982 scm_debug("chan[%d]: freq:%d, phymode:%d", idx, 983 req->scan_req.chan_list.chan[idx].freq, 984 req->scan_req.chan_list.chan[idx].phymode); 985 986 msg.bodyptr = req; 987 msg.callback = scm_scan_start_req; 988 msg.flush_callback = scm_scan_start_flush_callback; 989 990 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 991 QDF_MODULE_ID_SCAN, 992 QDF_MODULE_ID_OS_IF, &msg); 993 if (QDF_IS_STATUS_ERROR(status)) { 994 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 995 scm_scan_free_scan_request_mem(req); 996 } 997 998 return status; 999 } 1000 1001 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, 1002 enum scan_disable_reason reason) 1003 { 1004 struct wlan_scan_obj *scan_obj; 1005 1006 scan_obj = wlan_psoc_get_scan_obj(psoc); 1007 if (!scan_obj) { 1008 scm_err("Failed to get scan object"); 1009 return QDF_STATUS_E_NULL_VALUE; 1010 } 1011 1012 scan_obj->scan_disabled &= ~reason; 1013 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 1014 1015 return QDF_STATUS_SUCCESS; 1016 } 1017 1018 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, 1019 enum scan_disable_reason reason) 1020 { 1021 struct wlan_scan_obj *scan_obj; 1022 1023 scan_obj = wlan_psoc_get_scan_obj(psoc); 1024 if (!scan_obj) { 1025 scm_err("Failed to get scan object"); 1026 return QDF_STATUS_E_NULL_VALUE; 1027 } 1028 1029 scan_obj->scan_disabled |= reason; 1030 1031 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 1032 1033 return QDF_STATUS_SUCCESS; 1034 } 1035 1036 1037 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, 1038 enum scan_disable_reason reason) 1039 { 1040 struct scan_vdev_obj *scan_vdev_obj; 1041 1042 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1043 if (!scan_vdev_obj) { 1044 scm_err("null scan_vdev_obj"); 1045 return QDF_STATUS_E_NULL_VALUE; 1046 } 1047 1048 scan_vdev_obj->scan_disabled &= ~reason; 1049 1050 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 1051 1052 return QDF_STATUS_SUCCESS; 1053 } 1054 1055 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, 1056 enum scan_disable_reason reason) 1057 { 1058 struct scan_vdev_obj *scan_vdev_obj; 1059 1060 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1061 if (!scan_vdev_obj) { 1062 scm_err("null scan_vdev_obj"); 1063 return QDF_STATUS_E_NULL_VALUE; 1064 } 1065 1066 scan_vdev_obj->scan_disabled |= reason; 1067 1068 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 1069 1070 return QDF_STATUS_SUCCESS; 1071 } 1072 1073 1074 QDF_STATUS ucfg_scan_set_miracast( 1075 struct wlan_objmgr_psoc *psoc, bool enable) 1076 { 1077 struct wlan_scan_obj *scan_obj; 1078 1079 scan_obj = wlan_psoc_get_scan_obj(psoc); 1080 if (!scan_obj) { 1081 scm_err("Failed to get scan object"); 1082 return QDF_STATUS_E_NULL_VALUE; 1083 } 1084 scan_obj->miracast_enabled = enable; 1085 scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled); 1086 1087 return QDF_STATUS_SUCCESS; 1088 } 1089 1090 QDF_STATUS 1091 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable) 1092 { 1093 uint8_t pdev_id; 1094 struct wlan_scan_obj *scan_obj; 1095 1096 if (!pdev) { 1097 scm_warn("null vdev"); 1098 return QDF_STATUS_E_NULL_VALUE; 1099 } 1100 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1101 scan_obj = wlan_pdev_get_scan_obj(pdev); 1102 if (!scan_obj) 1103 return QDF_STATUS_E_FAILURE; 1104 1105 scm_debug("set wide_band_scan to %d", enable); 1106 scan_obj->pdev_info[pdev_id].wide_band_scan = enable; 1107 1108 return QDF_STATUS_SUCCESS; 1109 } 1110 1111 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev) 1112 { 1113 uint8_t pdev_id; 1114 struct wlan_scan_obj *scan_obj; 1115 1116 if (!pdev) { 1117 scm_warn("null vdev"); 1118 return QDF_STATUS_E_NULL_VALUE; 1119 } 1120 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1121 scan_obj = wlan_pdev_get_scan_obj(pdev); 1122 if (!scan_obj) 1123 return QDF_STATUS_E_FAILURE; 1124 1125 return scan_obj->pdev_info[pdev_id].wide_band_scan; 1126 } 1127 1128 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 1129 QDF_STATUS 1130 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev, 1131 uint8_t *bssid, struct wlan_ssid *ssid) 1132 { 1133 uint8_t pdev_id; 1134 struct wlan_scan_obj *scan_obj; 1135 1136 if (!pdev) { 1137 scm_warn("null vdev"); 1138 return QDF_STATUS_E_NULL_VALUE; 1139 } 1140 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1141 scan_obj = wlan_pdev_get_scan_obj(pdev); 1142 if (!scan_obj) 1143 return QDF_STATUS_E_FAILURE; 1144 1145 scm_debug("Configure bsssid:%pM ssid:%.*s", 1146 bssid, ssid->length, ssid->ssid); 1147 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid, 1148 bssid, QDF_MAC_ADDR_SIZE); 1149 scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length; 1150 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid, 1151 ssid->ssid, 1152 scan_obj->pdev_info[pdev_id].conf_ssid.length); 1153 1154 return QDF_STATUS_SUCCESS; 1155 } 1156 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 1157 1158 QDF_STATUS 1159 ucfg_scan_cancel(struct scan_cancel_request *req) 1160 { 1161 struct scheduler_msg msg = {0}; 1162 QDF_STATUS status; 1163 1164 if (!req || !req->vdev) { 1165 scm_err("req or vdev within req is NULL"); 1166 if (req) 1167 qdf_mem_free(req); 1168 return QDF_STATUS_E_NULL_VALUE; 1169 } 1170 scm_debug("reqid: %d, scanid: %d, vdevid: %d, type: %d", 1171 req->cancel_req.requester, req->cancel_req.scan_id, 1172 req->cancel_req.vdev_id, req->cancel_req.req_type); 1173 1174 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 1175 if (QDF_IS_STATUS_ERROR(status)) { 1176 scm_info("Failed to get vdev ref; status:%d", status); 1177 goto req_free; 1178 } 1179 1180 msg.bodyptr = req; 1181 msg.callback = scm_scan_cancel_req; 1182 msg.flush_callback = scm_scan_cancel_flush_callback; 1183 1184 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 1185 QDF_MODULE_ID_SCAN, 1186 QDF_MODULE_ID_OS_IF, &msg); 1187 if (QDF_IS_STATUS_ERROR(status)) 1188 goto vdev_put; 1189 1190 return QDF_STATUS_SUCCESS; 1191 1192 vdev_put: 1193 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1194 1195 req_free: 1196 qdf_mem_free(req); 1197 1198 return status; 1199 } 1200 1201 QDF_STATUS 1202 ucfg_scan_cancel_sync(struct scan_cancel_request *req) 1203 { 1204 QDF_STATUS status; 1205 bool cancel_vdev = false, cancel_pdev = false; 1206 struct wlan_objmgr_vdev *vdev; 1207 struct wlan_objmgr_pdev *pdev; 1208 uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION; 1209 qdf_event_t cancel_scan_event; 1210 1211 if (!req || !req->vdev) { 1212 scm_err("req or vdev within req is NULL"); 1213 if (req) 1214 qdf_mem_free(req); 1215 return QDF_STATUS_E_NULL_VALUE; 1216 } 1217 1218 if (req->cancel_req.req_type == 1219 WLAN_SCAN_CANCEL_PDEV_ALL) 1220 cancel_pdev = true; 1221 else if (req->cancel_req.req_type == 1222 WLAN_SCAN_CANCEL_VDEV_ALL) 1223 cancel_vdev = true; 1224 1225 vdev = req->vdev; 1226 status = ucfg_scan_cancel(req); 1227 if (QDF_IS_STATUS_ERROR(status)) 1228 return status; 1229 1230 memset(&cancel_scan_event, 0, sizeof(cancel_scan_event)); 1231 /* 1232 * If cancel req is to cancel all scan of pdev or vdev 1233 * wait until all scan of pdev or vdev get cancelled 1234 */ 1235 qdf_event_create(&cancel_scan_event); 1236 qdf_event_reset(&cancel_scan_event); 1237 1238 if (cancel_pdev) { 1239 pdev = wlan_vdev_get_pdev(vdev); 1240 while ((ucfg_scan_get_pdev_status(pdev) != 1241 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 1242 scm_debug("wait for all pdev scan to get complete"); 1243 qdf_wait_single_event(&cancel_scan_event, 1244 qdf_system_msecs_to_ticks( 1245 SCM_CANCEL_SCAN_WAIT_TIME)); 1246 max_wait_iterations--; 1247 } 1248 } else if (cancel_vdev) { 1249 while ((ucfg_scan_get_vdev_status(vdev) != 1250 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 1251 scm_debug("wait for all vdev scan to get complete"); 1252 qdf_wait_single_event(&cancel_scan_event, 1253 qdf_system_msecs_to_ticks( 1254 SCM_CANCEL_SCAN_WAIT_TIME)); 1255 max_wait_iterations--; 1256 } 1257 } 1258 1259 qdf_event_destroy(&cancel_scan_event); 1260 1261 if (!max_wait_iterations) { 1262 scm_err("Failed to wait for scans to get complete"); 1263 return QDF_STATUS_E_TIMEOUT; 1264 } 1265 1266 return status; 1267 } 1268 1269 wlan_scan_requester 1270 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc, 1271 uint8_t *name, scan_event_handler event_cb, void *arg) 1272 { 1273 int i, j; 1274 struct wlan_scan_obj *scan; 1275 struct scan_requester_info *requesters; 1276 wlan_scan_requester requester = {0}; 1277 1278 if (!psoc) { 1279 scm_err("null psoc"); 1280 return 0; 1281 } 1282 scan = wlan_psoc_get_scan_obj(psoc); 1283 if (!scan) 1284 return 0; 1285 1286 requesters = scan->requesters; 1287 qdf_spin_lock_bh(&scan->lock); 1288 for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) { 1289 if (requesters[i].requester == 0) { 1290 requesters[i].requester = 1291 WLAN_SCAN_REQUESTER_ID_PREFIX | i; 1292 j = 0; 1293 while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) { 1294 requesters[i].module[j] = name[j]; 1295 ++j; 1296 } 1297 requesters[i].module[j] = 0; 1298 requesters[i].ev_handler.func = event_cb; 1299 requesters[i].ev_handler.arg = arg; 1300 requester = requesters[i].requester; 1301 break; 1302 } 1303 } 1304 qdf_spin_unlock_bh(&scan->lock); 1305 scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d", 1306 name, event_cb, arg, requester); 1307 1308 return requester; 1309 } 1310 1311 void 1312 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc, 1313 wlan_scan_requester requester) 1314 { 1315 int idx; 1316 struct wlan_scan_obj *scan; 1317 struct scan_requester_info *requesters; 1318 1319 idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX; 1320 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) { 1321 scm_err("prefix didn't match for requester id %d", requester); 1322 return; 1323 } 1324 1325 idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 1326 if (idx >= WLAN_MAX_REQUESTORS) { 1327 scm_err("requester id %d greater than max value", requester); 1328 return; 1329 } 1330 1331 if (!psoc) { 1332 scm_err("null psoc"); 1333 return; 1334 } 1335 scan = wlan_psoc_get_scan_obj(psoc); 1336 if (!scan) 1337 return; 1338 requesters = scan->requesters; 1339 scm_debug("reqid: %d", requester); 1340 1341 qdf_spin_lock_bh(&scan->lock); 1342 requesters[idx].requester = 0; 1343 requesters[idx].module[0] = 0; 1344 requesters[idx].ev_handler.func = NULL; 1345 requesters[idx].ev_handler.arg = NULL; 1346 qdf_spin_unlock_bh(&scan->lock); 1347 } 1348 1349 uint8_t* 1350 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc, 1351 wlan_scan_requester requester) 1352 { 1353 int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 1354 struct wlan_scan_obj *scan; 1355 struct scan_requester_info *requesters; 1356 1357 if (!psoc) { 1358 scm_err("null psoc"); 1359 return "null"; 1360 } 1361 scan = wlan_psoc_get_scan_obj(psoc); 1362 if (!scan) 1363 return "null"; 1364 1365 requesters = scan->requesters; 1366 1367 if ((idx < WLAN_MAX_REQUESTORS) && 1368 (requesters[idx].requester == requester)) { 1369 return requesters[idx].module; 1370 } 1371 1372 return (uint8_t *)"unknown"; 1373 } 1374 1375 wlan_scan_id 1376 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc) 1377 { 1378 wlan_scan_id id; 1379 struct wlan_scan_obj *scan; 1380 1381 if (!psoc) { 1382 QDF_ASSERT(0); 1383 scm_err("null psoc"); 1384 return 0; 1385 } 1386 scan = wlan_psoc_get_scan_obj(psoc); 1387 1388 id = qdf_atomic_inc_return(&scan->scan_ids); 1389 id = id & WLAN_SCAN_ID_MASK; 1390 /* Mark this scan request as triggered by host 1391 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag. 1392 */ 1393 id = id | WLAN_HOST_SCAN_REQ_ID_PREFIX; 1394 scm_debug("scan_id: 0x%x", id); 1395 1396 return id; 1397 } 1398 1399 static QDF_STATUS 1400 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 1401 scan_event_handler event_cb, void *arg) 1402 { 1403 struct cb_handler *cb_handler; 1404 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 1405 1406 /* Assign next available slot to this registration request */ 1407 cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]); 1408 cb_handler->func = event_cb; 1409 cb_handler->arg = arg; 1410 pdev_ev_handler->handler_cnt++; 1411 1412 return QDF_STATUS_SUCCESS; 1413 } 1414 1415 QDF_STATUS 1416 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev, 1417 scan_event_handler event_cb, void *arg) 1418 { 1419 uint32_t idx; 1420 struct wlan_scan_obj *scan; 1421 struct pdev_scan_ev_handler *pdev_ev_handler; 1422 struct cb_handler *cb_handler; 1423 1424 /* scan event handler call back can't be NULL */ 1425 if (!pdev || !event_cb) { 1426 scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb); 1427 return QDF_STATUS_E_NULL_VALUE; 1428 } 1429 1430 scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg); 1431 1432 scan = wlan_pdev_get_scan_obj(pdev); 1433 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 1434 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 1435 1436 qdf_spin_lock_bh(&scan->lock); 1437 /* Ensure its not a duplicate registration request */ 1438 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 1439 idx++, cb_handler++) { 1440 if ((cb_handler->func == event_cb) && 1441 (cb_handler->arg == arg)) { 1442 qdf_spin_unlock_bh(&scan->lock); 1443 scm_debug("func: %pK, arg: %pK already exists", 1444 event_cb, arg); 1445 return QDF_STATUS_SUCCESS; 1446 } 1447 } 1448 1449 QDF_ASSERT(pdev_ev_handler->handler_cnt < 1450 MAX_SCAN_EVENT_HANDLERS_PER_PDEV); 1451 1452 if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) { 1453 qdf_spin_unlock_bh(&scan->lock); 1454 scm_warn("No more registrations possible"); 1455 return QDF_STATUS_E_NOMEM; 1456 } 1457 1458 scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg); 1459 qdf_spin_unlock_bh(&scan->lock); 1460 1461 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 1462 1463 return QDF_STATUS_SUCCESS; 1464 } 1465 1466 static QDF_STATUS 1467 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, 1468 struct wlan_scan_obj *scan_obj) 1469 { 1470 scan_obj->scan_disabled = 0; 1471 scan_obj->drop_bcn_on_chan_mismatch = 1472 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH); 1473 scan_obj->disable_timeout = false; 1474 scan_obj->scan_def.active_dwell = 1475 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME); 1476 /* the ini is disallow DFS channel scan if ini is 1, so negate that */ 1477 scan_obj->scan_def.allow_dfs_chan_in_first_scan = 1478 !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN); 1479 scan_obj->scan_def.allow_dfs_chan_in_scan = 1480 cfg_get(psoc, CFG_ENABLE_DFS_SCAN); 1481 scan_obj->scan_def.use_wake_lock_in_user_scan = 1482 cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN); 1483 scan_obj->scan_def.active_dwell_2g = 1484 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME); 1485 scan_obj->scan_def.passive_dwell = 1486 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME); 1487 scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME; 1488 scan_obj->scan_def.sta_miracast_mcc_rest_time = 1489 SCAN_STA_MIRACAST_MCC_REST_TIME; 1490 scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME; 1491 scan_obj->scan_def.conc_active_dwell = 1492 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC); 1493 scan_obj->scan_def.conc_passive_dwell = 1494 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC); 1495 scan_obj->scan_def.conc_max_rest_time = 1496 cfg_get(psoc, CFG_MAX_REST_TIME_CONC); 1497 scan_obj->scan_def.conc_min_rest_time = 1498 cfg_get(psoc, CFG_MIN_REST_TIME_CONC); 1499 scan_obj->scan_def.conc_idle_time = 1500 cfg_get(psoc, CFG_IDLE_TIME_CONC); 1501 scan_obj->scan_def.repeat_probe_time = 1502 cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME); 1503 scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME; 1504 scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY; 1505 scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION; 1506 scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME; 1507 scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES); 1508 scan_obj->scan_def.scan_cache_aging_time = SCAN_CACHE_AGING_TIME; 1509 scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV; 1510 scan_obj->scan_def.scan_priority = SCAN_PRIORITY; 1511 scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT; 1512 scan_obj->scan_def.adaptive_dwell_time_mode = 1513 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE); 1514 scan_obj->scan_def.adaptive_dwell_time_mode_nc = 1515 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC); 1516 scan_obj->scan_def.is_bssid_hint_priority = 1517 cfg_get(psoc, CFG_IS_BSSID_HINT_PRIORITY); 1518 /* scan contrl flags */ 1519 scan_obj->scan_def.scan_f_passive = true; 1520 scan_obj->scan_def.scan_f_ofdm_rates = true; 1521 scan_obj->scan_def.scan_f_2ghz = true; 1522 scan_obj->scan_def.scan_f_5ghz = true; 1523 scan_obj->scan_def.scan_f_chan_stat_evnt = SCAN_CHAN_STATS_EVENT_ENAB; 1524 /* scan event flags */ 1525 scan_obj->scan_def.scan_ev_started = true; 1526 scan_obj->scan_def.scan_ev_completed = true; 1527 scan_obj->scan_def.scan_ev_bss_chan = true; 1528 scan_obj->scan_def.scan_ev_foreign_chan = true; 1529 scan_obj->scan_def.scan_ev_foreign_chn_exit = true; 1530 scan_obj->scan_def.scan_ev_dequeued = true; 1531 scan_obj->scan_def.scan_ev_preempted = true; 1532 scan_obj->scan_def.scan_ev_start_failed = true; 1533 scan_obj->scan_def.scan_ev_restarted = true; 1534 /* init scan id seed */ 1535 qdf_atomic_init(&scan_obj->scan_ids); 1536 1537 /* init extscan */ 1538 wlan_extscan_global_init(psoc, scan_obj); 1539 1540 return wlan_pno_global_init(psoc, &scan_obj->pno_cfg); 1541 } 1542 1543 static void 1544 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc) 1545 { 1546 struct wlan_scan_obj *scan_obj; 1547 1548 scan_obj = wlan_psoc_get_scan_obj(psoc); 1549 wlan_pno_global_deinit(&scan_obj->pno_cfg); 1550 wlan_extscan_global_deinit(); 1551 } 1552 1553 static QDF_STATUS 1554 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 1555 struct cb_handler *entry) 1556 { 1557 struct cb_handler *last_entry; 1558 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 1559 1560 /* Replace event handler being deleted 1561 * with the last one in the list. 1562 */ 1563 last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]); 1564 entry->func = last_entry->func; 1565 entry->arg = last_entry->arg; 1566 1567 /* Clear our last entry */ 1568 last_entry->func = NULL; 1569 last_entry->arg = NULL; 1570 pdev_ev_handler->handler_cnt--; 1571 1572 return QDF_STATUS_SUCCESS; 1573 } 1574 1575 void 1576 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev, 1577 scan_event_handler event_cb, void *arg) 1578 { 1579 uint8_t found = false; 1580 uint32_t idx; 1581 uint32_t handler_cnt; 1582 struct wlan_scan_obj *scan; 1583 struct cb_handler *cb_handler; 1584 struct pdev_scan_ev_handler *pdev_ev_handler; 1585 1586 scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb, 1587 arg); 1588 if (!pdev) { 1589 scm_err("null pdev"); 1590 return; 1591 } 1592 scan = wlan_pdev_get_scan_obj(pdev); 1593 if (!scan) 1594 return; 1595 1596 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 1597 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 1598 1599 qdf_spin_lock_bh(&scan->lock); 1600 handler_cnt = pdev_ev_handler->handler_cnt; 1601 if (!handler_cnt) { 1602 qdf_spin_unlock_bh(&scan->lock); 1603 scm_info("No event handlers registered"); 1604 return; 1605 } 1606 1607 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 1608 idx++, cb_handler++) { 1609 if ((cb_handler->func == event_cb) && 1610 (cb_handler->arg == arg)) { 1611 /* Event handler found, remove it 1612 * from event handler list. 1613 */ 1614 found = true; 1615 scm_remove_scan_event_handler(pdev_ev_handler, 1616 cb_handler); 1617 handler_cnt--; 1618 break; 1619 } 1620 } 1621 qdf_spin_unlock_bh(&scan->lock); 1622 1623 scm_debug("event handler %s, remaining handlers: %d", 1624 (found ? "removed" : "not found"), handler_cnt); 1625 } 1626 1627 QDF_STATUS 1628 ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev, 1629 struct scan_start_request *req) 1630 { 1631 struct scan_default_params *def; 1632 1633 if (!vdev | !req) { 1634 scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req); 1635 return QDF_STATUS_E_INVAL; 1636 } 1637 def = wlan_vdev_get_def_scan_params(vdev); 1638 if (!def) { 1639 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 1640 return QDF_STATUS_E_NULL_VALUE; 1641 } 1642 1643 /* Zero out everything and explicitly set fields as required */ 1644 qdf_mem_zero(req, sizeof(*req)); 1645 1646 req->vdev = vdev; 1647 req->scan_req.vdev_id = wlan_vdev_get_id(vdev); 1648 req->scan_req.p2p_scan_type = SCAN_NON_P2P_DEFAULT; 1649 req->scan_req.scan_priority = def->scan_priority; 1650 req->scan_req.dwell_time_active = def->active_dwell; 1651 req->scan_req.dwell_time_active_2g = def->active_dwell_2g; 1652 req->scan_req.dwell_time_passive = def->passive_dwell; 1653 req->scan_req.min_rest_time = def->min_rest_time; 1654 req->scan_req.max_rest_time = def->max_rest_time; 1655 req->scan_req.repeat_probe_time = def->repeat_probe_time; 1656 req->scan_req.probe_spacing_time = def->probe_spacing_time; 1657 req->scan_req.idle_time = def->idle_time; 1658 req->scan_req.max_scan_time = def->max_scan_time; 1659 req->scan_req.probe_delay = def->probe_delay; 1660 req->scan_req.burst_duration = def->burst_duration; 1661 req->scan_req.n_probes = def->num_probes; 1662 req->scan_req.adaptive_dwell_time_mode = 1663 def->adaptive_dwell_time_mode; 1664 req->scan_req.scan_flags = def->scan_flags; 1665 req->scan_req.scan_events = def->scan_events; 1666 req->scan_req.scan_random.randomize = def->enable_mac_spoofing; 1667 1668 return QDF_STATUS_SUCCESS; 1669 } 1670 1671 QDF_STATUS 1672 ucfg_scan_init_ssid_params(struct scan_start_request *req, 1673 uint32_t num_ssid, struct wlan_ssid *ssid_list) 1674 { 1675 uint32_t max_ssid = sizeof(req->scan_req.ssid) / 1676 sizeof(req->scan_req.ssid[0]); 1677 1678 if (!req) { 1679 scm_err("null request"); 1680 return QDF_STATUS_E_NULL_VALUE; 1681 } 1682 if (!num_ssid) { 1683 /* empty channel list provided */ 1684 req->scan_req.num_ssids = 0; 1685 qdf_mem_zero(&req->scan_req.ssid[0], 1686 sizeof(req->scan_req.ssid)); 1687 return QDF_STATUS_SUCCESS; 1688 } 1689 if (!ssid_list) { 1690 scm_err("null ssid_list while num_ssid: %d", num_ssid); 1691 return QDF_STATUS_E_NULL_VALUE; 1692 } 1693 if (num_ssid > max_ssid) { 1694 /* got a big list. alert and continue */ 1695 scm_warn("overflow: received %d, max supported : %d", 1696 num_ssid, max_ssid); 1697 return QDF_STATUS_E_E2BIG; 1698 } 1699 1700 if (max_ssid > num_ssid) 1701 max_ssid = num_ssid; 1702 1703 req->scan_req.num_ssids = max_ssid; 1704 qdf_mem_copy(&req->scan_req.ssid[0], ssid_list, 1705 (req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0]))); 1706 1707 return QDF_STATUS_SUCCESS; 1708 } 1709 1710 QDF_STATUS 1711 ucfg_scan_init_bssid_params(struct scan_start_request *req, 1712 uint32_t num_bssid, struct qdf_mac_addr *bssid_list) 1713 { 1714 uint32_t max_bssid = sizeof(req->scan_req.bssid_list) / 1715 sizeof(req->scan_req.bssid_list[0]); 1716 1717 if (!req) { 1718 scm_err("null request"); 1719 return QDF_STATUS_E_NULL_VALUE; 1720 } 1721 if (!num_bssid) { 1722 /* empty channel list provided */ 1723 req->scan_req.num_bssid = 0; 1724 qdf_mem_zero(&req->scan_req.bssid_list[0], 1725 sizeof(req->scan_req.bssid_list)); 1726 return QDF_STATUS_SUCCESS; 1727 } 1728 if (!bssid_list) { 1729 scm_err("null bssid_list while num_bssid: %d", num_bssid); 1730 return QDF_STATUS_E_NULL_VALUE; 1731 } 1732 if (num_bssid > max_bssid) { 1733 /* got a big list. alert and continue */ 1734 scm_warn("overflow: received %d, max supported : %d", 1735 num_bssid, max_bssid); 1736 return QDF_STATUS_E_E2BIG; 1737 } 1738 1739 if (max_bssid > num_bssid) 1740 max_bssid = num_bssid; 1741 1742 req->scan_req.num_bssid = max_bssid; 1743 qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list, 1744 req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0])); 1745 1746 return QDF_STATUS_SUCCESS; 1747 } 1748 1749 /** 1750 * is_chan_enabled_for_scan() - helper API to check if a frequency 1751 * is allowed to scan. 1752 * @reg_chan: regulatory_channel object 1753 * @low_2g: lower 2.4 GHz frequency thresold 1754 * @high_2g: upper 2.4 GHz frequency thresold 1755 * @low_5g: lower 5 GHz frequency thresold 1756 * @high_5g: upper 5 GHz frequency thresold 1757 * 1758 * Return: true if scan is allowed. false otherwise. 1759 */ 1760 static bool 1761 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan, 1762 uint32_t low_2g, uint32_t high_2g, uint32_t low_5g, 1763 uint32_t high_5g) 1764 { 1765 if (reg_chan->state == CHANNEL_STATE_DISABLE) 1766 return false; 1767 if (reg_chan->nol_chan) 1768 return false; 1769 /* 2 GHz channel */ 1770 if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1771 WLAN_BAND_2_4_GHZ) && 1772 ((reg_chan->center_freq < low_2g) || 1773 (reg_chan->center_freq > high_2g))) 1774 return false; 1775 else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) == 1776 WLAN_BAND_5_GHZ) && 1777 ((reg_chan->center_freq < low_5g) || 1778 (reg_chan->center_freq > high_5g))) 1779 return false; 1780 1781 return true; 1782 } 1783 1784 QDF_STATUS 1785 ucfg_scan_init_chanlist_params(struct scan_start_request *req, 1786 uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode) 1787 { 1788 uint32_t idx; 1789 QDF_STATUS status; 1790 struct regulatory_channel *reg_chan_list = NULL; 1791 uint32_t low_2g, high_2g, low_5g, high_5g; 1792 struct wlan_objmgr_pdev *pdev = NULL; 1793 uint32_t *scan_freqs = NULL; 1794 uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / 1795 sizeof(req->scan_req.chan_list.chan[0]); 1796 if (!req) { 1797 scm_err("null request"); 1798 return QDF_STATUS_E_NULL_VALUE; 1799 } 1800 1801 if (req->vdev) 1802 pdev = wlan_vdev_get_pdev(req->vdev); 1803 /* 1804 * If 0 channels are provided for scan and 1805 * wide band scan is enabled, scan all 20 mhz 1806 * available channels. This is required as FW 1807 * scans all channel/phy mode combinations 1808 * provided in scan channel list if 0 chans are 1809 * provided in scan request causing scan to take 1810 * too much time to complete. 1811 */ 1812 if (pdev && !num_chans) { 1813 reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS * 1814 sizeof(struct regulatory_channel)); 1815 if (!reg_chan_list) { 1816 scm_err("Couldn't allocate reg_chan_list memory"); 1817 status = QDF_STATUS_E_NOMEM; 1818 goto end; 1819 } 1820 scan_freqs = 1821 qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans); 1822 if (!scan_freqs) { 1823 scm_err("Couldn't allocate scan_freqs memory"); 1824 status = QDF_STATUS_E_NOMEM; 1825 goto end; 1826 } 1827 status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list); 1828 if (QDF_IS_STATUS_ERROR(status)) { 1829 scm_err("Couldn't get current chan list"); 1830 goto end; 1831 } 1832 status = wlan_reg_get_freq_range(pdev, &low_2g, 1833 &high_2g, &low_5g, &high_5g); 1834 if (QDF_IS_STATUS_ERROR(status)) { 1835 scm_err("Couldn't get frequency range"); 1836 goto end; 1837 } 1838 1839 for (idx = 0, num_chans = 0; 1840 (idx < NUM_CHANNELS && num_chans < max_chans); idx++) 1841 if (is_chan_enabled_for_scan(®_chan_list[idx], 1842 low_2g, high_2g, low_5g, high_5g)) 1843 scan_freqs[num_chans++] = 1844 reg_chan_list[idx].center_freq; 1845 1846 chan_list = scan_freqs; 1847 } 1848 1849 if (!num_chans) { 1850 /* empty channel list provided */ 1851 qdf_mem_zero(&req->scan_req.chan_list, 1852 sizeof(req->scan_req.chan_list)); 1853 req->scan_req.chan_list.num_chan = 0; 1854 status = QDF_STATUS_SUCCESS; 1855 goto end; 1856 } 1857 if (!chan_list) { 1858 scm_err("null chan_list while num_chans: %d", num_chans); 1859 status = QDF_STATUS_E_NULL_VALUE; 1860 goto end; 1861 } 1862 1863 if (num_chans > max_chans) { 1864 /* got a big list. alert and fail */ 1865 scm_warn("overflow: received %d, max supported : %d", 1866 num_chans, max_chans); 1867 status = QDF_STATUS_E_E2BIG; 1868 goto end; 1869 } 1870 1871 req->scan_req.chan_list.num_chan = num_chans; 1872 for (idx = 0; idx < num_chans; idx++) { 1873 req->scan_req.chan_list.chan[idx].freq = 1874 (chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ? 1875 chan_list[idx] : 1876 wlan_reg_chan_to_freq(pdev, chan_list[idx]); 1877 if (phymode) 1878 req->scan_req.chan_list.chan[idx].phymode = 1879 phymode[idx]; 1880 else if (req->scan_req.chan_list.chan[idx].freq <= 1881 WLAN_CHAN_15_FREQ) 1882 req->scan_req.chan_list.chan[idx].phymode = 1883 SCAN_PHY_MODE_11G; 1884 else 1885 req->scan_req.chan_list.chan[idx].phymode = 1886 SCAN_PHY_MODE_11A; 1887 1888 scm_debug("chan[%d]: freq:%d, phymode:%d", idx, 1889 req->scan_req.chan_list.chan[idx].freq, 1890 req->scan_req.chan_list.chan[idx].phymode); 1891 } 1892 1893 end: 1894 if (scan_freqs) 1895 qdf_mem_free(scan_freqs); 1896 1897 if (reg_chan_list) 1898 qdf_mem_free(reg_chan_list); 1899 1900 return QDF_STATUS_SUCCESS; 1901 } 1902 1903 static inline enum scm_scan_status 1904 get_scan_status_from_serialization_status( 1905 enum wlan_serialization_cmd_status status) 1906 { 1907 enum scm_scan_status scan_status; 1908 1909 switch (status) { 1910 case WLAN_SER_CMD_IN_PENDING_LIST: 1911 scan_status = SCAN_IS_PENDING; 1912 break; 1913 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1914 scan_status = SCAN_IS_ACTIVE; 1915 break; 1916 case WLAN_SER_CMDS_IN_ALL_LISTS: 1917 scan_status = SCAN_IS_ACTIVE_AND_PENDING; 1918 break; 1919 case WLAN_SER_CMD_NOT_FOUND: 1920 scan_status = SCAN_NOT_IN_PROGRESS; 1921 break; 1922 default: 1923 scm_warn("invalid serialization status %d", status); 1924 QDF_ASSERT(0); 1925 scan_status = SCAN_NOT_IN_PROGRESS; 1926 break; 1927 } 1928 1929 return scan_status; 1930 } 1931 1932 enum scm_scan_status 1933 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev) 1934 { 1935 enum wlan_serialization_cmd_status status; 1936 1937 if (!vdev) { 1938 scm_err("null vdev"); 1939 return SCAN_NOT_IN_PROGRESS; 1940 } 1941 status = wlan_serialization_vdev_scan_status(vdev); 1942 1943 return get_scan_status_from_serialization_status(status); 1944 } 1945 1946 enum scm_scan_status 1947 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev) 1948 { 1949 enum wlan_serialization_cmd_status status; 1950 1951 if (!pdev) { 1952 scm_err("null pdev"); 1953 return SCAN_NOT_IN_PROGRESS; 1954 } 1955 status = wlan_serialization_pdev_scan_status(pdev); 1956 1957 return get_scan_status_from_serialization_status(status); 1958 } 1959 1960 static void 1961 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc, 1962 bool enable) 1963 { 1964 QDF_STATUS status; 1965 struct mgmt_txrx_mgmt_frame_cb_info cb_info[2]; 1966 1967 cb_info[0].frm_type = MGMT_PROBE_RESP; 1968 cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1969 cb_info[1].frm_type = MGMT_BEACON; 1970 cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1971 1972 if (enable) 1973 status = wlan_mgmt_txrx_register_rx_cb(psoc, 1974 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1975 else 1976 status = wlan_mgmt_txrx_deregister_rx_cb(psoc, 1977 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1978 if (status != QDF_STATUS_SUCCESS) 1979 scm_err("%s the Handle with MGMT TXRX layer has failed", 1980 enable ? "Registering" : "Deregistering"); 1981 } 1982 1983 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc, 1984 struct scan_user_cfg *scan_cfg) 1985 { 1986 struct wlan_scan_obj *scan_obj; 1987 struct scan_default_params *scan_def; 1988 1989 if (!psoc) { 1990 scm_err("null psoc"); 1991 return QDF_STATUS_E_FAILURE; 1992 } 1993 scan_obj = wlan_psoc_get_scan_obj(psoc); 1994 if (scan_obj == NULL) { 1995 scm_err("Failed to get scan object"); 1996 return QDF_STATUS_E_FAILURE; 1997 } 1998 1999 scan_def = &scan_obj->scan_def; 2000 scan_def->scan_cache_aging_time = scan_cfg->scan_cache_aging_time; 2001 scan_def->scan_f_chan_stat_evnt = scan_cfg->is_snr_monitoring_enabled; 2002 scan_obj->ie_whitelist = scan_cfg->ie_whitelist; 2003 scan_def->enable_mac_spoofing = scan_cfg->enable_mac_spoofing; 2004 scan_def->sta_miracast_mcc_rest_time = 2005 scan_cfg->sta_miracast_mcc_rest_time; 2006 2007 qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config, 2008 sizeof(struct scoring_config)); 2009 scm_validate_scoring_config(&scan_def->score_config); 2010 2011 return QDF_STATUS_SUCCESS; 2012 } 2013 2014 QDF_STATUS ucfg_scan_update_roam_params(struct wlan_objmgr_psoc *psoc, 2015 struct roam_filter_params *roam_params) 2016 { 2017 struct scan_default_params *scan_def; 2018 2019 if (!psoc) { 2020 scm_err("null psoc"); 2021 return QDF_STATUS_E_FAILURE; 2022 } 2023 scan_def = wlan_scan_psoc_get_def_params(psoc); 2024 if (!scan_def) { 2025 scm_err("Failed to get scan object"); 2026 return QDF_STATUS_E_FAILURE; 2027 } 2028 2029 qdf_mem_copy(&scan_def->roam_params, roam_params, 2030 sizeof(struct roam_filter_params)); 2031 2032 return QDF_STATUS_SUCCESS; 2033 } 2034 2035 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 2036 static QDF_STATUS 2037 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) 2038 { 2039 struct scan_cancel_request *req; 2040 QDF_STATUS status; 2041 struct wlan_objmgr_vdev *vdev; 2042 2043 req = qdf_mem_malloc_atomic(sizeof(*req)); 2044 if (!req) { 2045 scm_err("Failed to allocate memory"); 2046 return QDF_STATUS_E_NOMEM; 2047 } 2048 2049 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID); 2050 if (!vdev) { 2051 scm_err("Failed to get vdev"); 2052 qdf_mem_free(req); 2053 return QDF_STATUS_E_INVAL; 2054 } 2055 req->vdev = vdev; 2056 req->cancel_req.scan_id = INVAL_SCAN_ID; 2057 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 2058 req->cancel_req.vdev_id = INVAL_VDEV_ID; 2059 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 2060 status = ucfg_scan_cancel_sync(req); 2061 if (QDF_IS_STATUS_ERROR(status)) 2062 scm_err("Cancel scan request failed"); 2063 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 2064 2065 return status; 2066 } 2067 2068 static QDF_STATUS 2069 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) 2070 { 2071 struct wlan_objmgr_pdev *pdev = NULL; 2072 QDF_STATUS status = QDF_STATUS_SUCCESS; 2073 int i; 2074 2075 ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND); 2076 /* Check all pdev */ 2077 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 2078 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); 2079 if (!pdev) 2080 continue; 2081 if (ucfg_scan_get_pdev_status(pdev) != 2082 SCAN_NOT_IN_PROGRESS) 2083 status = ucfg_scan_cancel_pdev_scan(pdev); 2084 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 2085 if (QDF_IS_STATUS_ERROR(status)) { 2086 scm_err("failed to cancel scan for pdev_id %d", i); 2087 return status; 2088 } 2089 } 2090 2091 return QDF_STATUS_SUCCESS; 2092 } 2093 2094 static QDF_STATUS 2095 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) 2096 { 2097 ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND); 2098 return QDF_STATUS_SUCCESS; 2099 } 2100 2101 static inline void 2102 ucfg_scan_register_pmo_handler(void) 2103 { 2104 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN, 2105 ucfg_scan_suspend_handler, NULL); 2106 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN, 2107 ucfg_scan_resume_handler, NULL); 2108 } 2109 2110 static inline void 2111 ucfg_scan_unregister_pmo_handler(void) 2112 { 2113 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN, 2114 ucfg_scan_suspend_handler); 2115 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN, 2116 ucfg_scan_resume_handler); 2117 } 2118 2119 #else 2120 static inline void 2121 ucfg_scan_register_pmo_handler(void) 2122 { 2123 } 2124 2125 static inline void 2126 ucfg_scan_unregister_pmo_handler(void) 2127 { 2128 } 2129 #endif 2130 2131 QDF_STATUS 2132 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) 2133 { 2134 struct wlan_scan_obj *scan_obj; 2135 2136 scm_debug("psoc open: 0x%pK", psoc); 2137 if (!psoc) { 2138 scm_err("null psoc"); 2139 return QDF_STATUS_E_FAILURE; 2140 } 2141 scan_obj = wlan_psoc_get_scan_obj(psoc); 2142 if (scan_obj == NULL) { 2143 scm_err("Failed to get scan object"); 2144 return QDF_STATUS_E_FAILURE; 2145 } 2146 /* Initialize the scan Globals */ 2147 wlan_scan_global_init(psoc, scan_obj); 2148 qdf_spinlock_create(&scan_obj->lock); 2149 ucfg_scan_register_pmo_handler(); 2150 scm_db_init(psoc); 2151 2152 return QDF_STATUS_SUCCESS; 2153 } 2154 2155 QDF_STATUS 2156 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) 2157 { 2158 struct wlan_scan_obj *scan_obj; 2159 2160 scm_debug("psoc close: 0x%pK", psoc); 2161 if (!psoc) { 2162 scm_err("null psoc"); 2163 return QDF_STATUS_E_FAILURE; 2164 } 2165 scm_db_deinit(psoc); 2166 scan_obj = wlan_psoc_get_scan_obj(psoc); 2167 if (scan_obj == NULL) { 2168 scm_err("Failed to get scan object"); 2169 return QDF_STATUS_E_FAILURE; 2170 } 2171 ucfg_scan_unregister_pmo_handler(); 2172 qdf_spinlock_destroy(&scan_obj->lock); 2173 wlan_scan_global_deinit(psoc); 2174 2175 return QDF_STATUS_SUCCESS; 2176 } 2177 2178 static bool scm_serialization_scan_rules_cb( 2179 union wlan_serialization_rules_info *comp_info, 2180 uint8_t comp_id) 2181 { 2182 switch (comp_id) { 2183 case WLAN_UMAC_COMP_TDLS: 2184 if (comp_info->scan_info.is_tdls_in_progress) { 2185 scm_debug("Cancel scan. Tdls in progress"); 2186 return false; 2187 } 2188 break; 2189 case WLAN_UMAC_COMP_DFS: 2190 if (comp_info->scan_info.is_cac_in_progress) { 2191 scm_debug("Cancel scan. CAC in progress"); 2192 return false; 2193 } 2194 break; 2195 case WLAN_UMAC_COMP_MLME: 2196 if (comp_info->scan_info.is_mlme_op_in_progress) { 2197 scm_debug("Cancel scan. MLME operation in progress"); 2198 return false; 2199 } 2200 break; 2201 default: 2202 scm_debug("not handled comp_id %d", comp_id); 2203 break; 2204 } 2205 2206 return true; 2207 } 2208 2209 QDF_STATUS 2210 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) 2211 { 2212 QDF_STATUS status; 2213 2214 scm_debug("psoc enable: 0x%pK", psoc); 2215 if (!psoc) { 2216 scm_err("null psoc"); 2217 return QDF_STATUS_E_FAILURE; 2218 } 2219 /* Subscribe for scan events from lmac layesr */ 2220 status = tgt_scan_register_ev_handler(psoc); 2221 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 2222 if (!wlan_reg_is_11d_offloaded(psoc)) 2223 scm_11d_cc_db_init(psoc); 2224 ucfg_scan_register_unregister_bcn_cb(psoc, true); 2225 status = wlan_serialization_register_apply_rules_cb(psoc, 2226 WLAN_SER_CMD_SCAN, 2227 scm_serialization_scan_rules_cb); 2228 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 2229 return status; 2230 } 2231 2232 QDF_STATUS 2233 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) 2234 { 2235 QDF_STATUS status; 2236 2237 scm_debug("psoc disable: 0x%pK", psoc); 2238 if (!psoc) { 2239 scm_err("null psoc"); 2240 return QDF_STATUS_E_FAILURE; 2241 } 2242 /* Unsubscribe for scan events from lmac layesr */ 2243 status = tgt_scan_unregister_ev_handler(psoc); 2244 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 2245 ucfg_scan_register_unregister_bcn_cb(psoc, false); 2246 if (!wlan_reg_is_11d_offloaded(psoc)) 2247 scm_11d_cc_db_deinit(psoc); 2248 2249 return status; 2250 } 2251 2252 uint32_t 2253 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc) 2254 { 2255 struct scan_default_params *scan_params = NULL; 2256 2257 if (!psoc) { 2258 scm_err("null psoc"); 2259 return 0; 2260 } 2261 scan_params = wlan_scan_psoc_get_def_params(psoc); 2262 if (!scan_params) { 2263 scm_err("Failed to get scan object"); 2264 return 0; 2265 } 2266 2267 return scan_params->max_active_scans_allowed; 2268 } 2269 2270 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc, 2271 struct probe_req_whitelist_attr *ie_whitelist) 2272 { 2273 struct wlan_scan_obj *scan_obj = NULL; 2274 2275 scan_obj = wlan_psoc_get_scan_obj(psoc); 2276 if (!scan_obj) 2277 return false; 2278 2279 qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist, 2280 sizeof(*ie_whitelist)); 2281 2282 return true; 2283 } 2284 2285 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc, 2286 struct wlan_objmgr_vdev *vdev) 2287 { 2288 struct wlan_scan_obj *scan_obj = NULL; 2289 2290 scan_obj = wlan_psoc_get_scan_obj(psoc); 2291 if (!scan_obj) 2292 return false; 2293 2294 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || 2295 wlan_vdev_is_connected(vdev)) 2296 return false; 2297 2298 if (!scan_obj->ie_whitelist.white_list) 2299 return false; 2300 2301 return true; 2302 } 2303 2304 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, 2305 bool bt_a2dp_active) 2306 { 2307 struct wlan_scan_obj *scan_obj; 2308 2309 scan_obj = wlan_psoc_get_scan_obj(psoc); 2310 if (!scan_obj) { 2311 scm_err("Failed to get scan object"); 2312 return; 2313 } 2314 scan_obj->bt_a2dp_enabled = bt_a2dp_active; 2315 } 2316 2317 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) 2318 { 2319 struct wlan_scan_obj *scan_obj; 2320 2321 scan_obj = wlan_psoc_get_scan_obj(psoc); 2322 if (!scan_obj) { 2323 scm_err("Failed to get scan object"); 2324 return false; 2325 } 2326 2327 return scan_obj->bt_a2dp_enabled; 2328 } 2329 2330 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc) 2331 { 2332 struct wlan_scan_obj *scan_obj; 2333 2334 scan_obj = wlan_psoc_get_scan_obj(psoc); 2335 if (!scan_obj) 2336 return false; 2337 2338 return scan_obj->scan_def.use_wake_lock_in_user_scan; 2339 } 2340 2341 QDF_STATUS 2342 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, 2343 enum scan_config config, uint32_t val) 2344 { 2345 struct wlan_scan_obj *scan_obj; 2346 QDF_STATUS status = QDF_STATUS_SUCCESS; 2347 2348 scan_obj = wlan_psoc_get_scan_obj(psoc); 2349 if (!scan_obj) { 2350 scm_err("Failed to get scan object config:%d, val:%d", 2351 config, val); 2352 return QDF_STATUS_E_INVAL; 2353 } 2354 switch (config) { 2355 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 2356 scan_obj->disable_timeout = !!val; 2357 break; 2358 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 2359 scan_obj->drop_bcn_on_chan_mismatch = !!val; 2360 break; 2361 2362 default: 2363 status = QDF_STATUS_E_INVAL; 2364 break; 2365 } 2366 2367 return status; 2368 } 2369 2370 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev, 2371 struct bss_info *bss_info, struct mlme_info *mlme) 2372 { 2373 QDF_STATUS status; 2374 2375 status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme); 2376 2377 return status; 2378 } 2379 2380 QDF_STATUS 2381 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc, 2382 enum scan_config config, uint32_t *val) 2383 { 2384 struct wlan_scan_obj *scan_obj; 2385 QDF_STATUS status = QDF_STATUS_SUCCESS; 2386 2387 scan_obj = wlan_psoc_get_scan_obj(psoc); 2388 if (!scan_obj || !val) { 2389 scm_err("scan object:%pK config:%d, val:0x%pK", 2390 scan_obj, config, val); 2391 return QDF_STATUS_E_INVAL; 2392 } 2393 switch (config) { 2394 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 2395 *val = scan_obj->disable_timeout; 2396 break; 2397 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 2398 *val = scan_obj->drop_bcn_on_chan_mismatch; 2399 break; 2400 2401 default: 2402 status = QDF_STATUS_E_INVAL; 2403 break; 2404 } 2405 2406 return status; 2407 } 2408 2409 #ifdef FEATURE_WLAN_SCAN_PNO 2410 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc) 2411 { 2412 struct wlan_scan_obj *scan_obj; 2413 2414 scan_obj = wlan_psoc_get_scan_obj(psoc); 2415 if (!scan_obj) { 2416 scm_err("NULL scan obj"); 2417 return false; 2418 } 2419 2420 return scan_obj->pno_cfg.pno_offload_enabled; 2421 } 2422 2423 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value) 2424 { 2425 struct wlan_scan_obj *scan_obj; 2426 2427 scan_obj = wlan_psoc_get_scan_obj(psoc); 2428 if (!scan_obj) { 2429 scm_err("NULL scan obj"); 2430 return; 2431 } 2432 2433 scan_obj->pno_cfg.pno_offload_enabled = value; 2434 } 2435 2436 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc) 2437 { 2438 struct wlan_scan_obj *scan_obj; 2439 2440 scan_obj = wlan_psoc_get_scan_obj(psoc); 2441 if (!scan_obj) { 2442 scm_err("NULL scan obj"); 2443 return cfg_default(CFG_PNO_SCAN_SUPPORT); 2444 } 2445 2446 return scan_obj->pno_cfg.scan_support_enabled; 2447 } 2448 2449 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc) 2450 { 2451 struct wlan_scan_obj *scan_obj; 2452 2453 scan_obj = wlan_psoc_get_scan_obj(psoc); 2454 if (!scan_obj) { 2455 scm_err("NULL scan obj"); 2456 return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER); 2457 } 2458 return scan_obj->pno_cfg.scan_backoff_multiplier; 2459 } 2460 2461 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc) 2462 { 2463 struct wlan_scan_obj *scan_obj; 2464 2465 scan_obj = wlan_psoc_get_scan_obj(psoc); 2466 if (!scan_obj) { 2467 scm_err("NULL scan obj"); 2468 return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN); 2469 } 2470 return scan_obj->pno_cfg.dfs_chnl_scan_enabled; 2471 } 2472 2473 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc) 2474 { 2475 struct wlan_scan_obj *scan_obj; 2476 2477 scan_obj = wlan_psoc_get_scan_obj(psoc); 2478 if (!scan_obj) { 2479 scm_err("NULL scan obj"); 2480 return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 2481 } 2482 return scan_obj->pno_cfg.scan_timer_repeat_value; 2483 } 2484 2485 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc) 2486 { 2487 struct wlan_scan_obj *scan_obj; 2488 2489 scan_obj = wlan_psoc_get_scan_obj(psoc); 2490 if (!scan_obj) { 2491 scm_err("NULL scan obj"); 2492 return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER); 2493 } 2494 return scan_obj->pno_cfg.slow_scan_multiplier; 2495 } 2496 #endif 2497