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 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * DOC: contains scan north bound interface definitions 21 */ 22 23 #include <scheduler_api.h> 24 #include <wlan_scan_ucfg_api.h> 25 #include <wlan_objmgr_global_obj.h> 26 #include <wlan_objmgr_cmn.h> 27 #include <wlan_serialization_api.h> 28 #include <wlan_scan_tgt_api.h> 29 #include <wlan_scan_utils_api.h> 30 #include <wlan_reg_ucfg_api.h> 31 #include <wlan_reg_services_api.h> 32 #include <wlan_utility.h> 33 #include "../../core/src/wlan_scan_main.h" 34 #include "../../core/src/wlan_scan_manager.h" 35 #include "../../core/src/wlan_scan_cache_db.h" 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include <wlan_pmo_obj_mgmt_api.h> 38 #endif 39 #ifdef WLAN_POLICY_MGR_ENABLE 40 #include <wlan_dfs_utils_api.h> 41 #include <wlan_policy_mgr_api.h> 42 #endif 43 #include "cfg_ucfg_api.h" 44 #include "wlan_extscan_api.h" 45 46 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc, 47 update_beacon_cb cb, enum scan_cb_type type) 48 { 49 return scm_scan_register_bcn_cb(psoc, cb, type); 50 } 51 52 qdf_list_t *ucfg_scan_get_result(struct wlan_objmgr_pdev *pdev, 53 struct scan_filter *filter) 54 { 55 return scm_get_scan_result(pdev, filter); 56 } 57 58 QDF_STATUS ucfg_scan_db_iterate(struct wlan_objmgr_pdev *pdev, 59 scan_iterator_func func, void *arg) 60 { 61 return scm_iterate_scan_db(pdev, func, arg); 62 } 63 64 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list) 65 { 66 return scm_purge_scan_results(scan_list); 67 } 68 69 QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev, 70 struct scan_filter *filter) 71 { 72 return scm_flush_results(pdev, filter); 73 } 74 75 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev, 76 uint8_t *chan_list, uint32_t num_chan) 77 { 78 scm_filter_valid_channel(pdev, chan_list, num_chan); 79 } 80 81 QDF_STATUS ucfg_scan_init(void) 82 { 83 QDF_STATUS status; 84 85 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 86 wlan_scan_psoc_created_notification, NULL); 87 if (QDF_IS_STATUS_ERROR(status)) { 88 scm_err("Failed to register psoc create handler"); 89 goto fail_create_psoc; 90 } 91 92 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN, 93 wlan_scan_psoc_destroyed_notification, NULL); 94 if (QDF_IS_STATUS_ERROR(status)) { 95 scm_err("Failed to create psoc delete handler"); 96 goto fail_psoc_destroy; 97 } 98 scm_debug("scan psoc create and delete handler registered with objmgr"); 99 100 status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 101 wlan_scan_vdev_created_notification, NULL); 102 if (QDF_IS_STATUS_ERROR(status)) { 103 scm_err("Failed to register vdev create handler"); 104 goto fail_pdev_create; 105 } 106 107 status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN, 108 wlan_scan_vdev_destroyed_notification, NULL); 109 if (QDF_IS_STATUS_SUCCESS(status)) { 110 scm_debug("scan vdev create and delete handler registered with objmgr"); 111 return QDF_STATUS_SUCCESS; 112 } 113 114 scm_err("Failed to destroy vdev delete handler"); 115 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 116 wlan_scan_vdev_created_notification, NULL); 117 fail_pdev_create: 118 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN, 119 wlan_scan_psoc_destroyed_notification, NULL); 120 fail_psoc_destroy: 121 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 122 wlan_scan_psoc_created_notification, NULL); 123 fail_create_psoc: 124 return status; 125 } 126 127 QDF_STATUS ucfg_scan_deinit(void) 128 { 129 QDF_STATUS status; 130 131 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 132 wlan_scan_psoc_created_notification, NULL); 133 if (status != QDF_STATUS_SUCCESS) 134 scm_err("Failed to unregister psoc create handler"); 135 136 status = wlan_objmgr_unregister_psoc_destroy_handler( 137 WLAN_UMAC_COMP_SCAN, 138 wlan_scan_psoc_destroyed_notification, NULL); 139 if (status != QDF_STATUS_SUCCESS) 140 scm_err("Failed to unregister psoc delete handler"); 141 142 status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 143 wlan_scan_vdev_created_notification, NULL); 144 if (status != QDF_STATUS_SUCCESS) 145 scm_err("Failed to unregister vdev create handler"); 146 147 status = wlan_objmgr_unregister_vdev_destroy_handler( 148 WLAN_UMAC_COMP_SCAN, 149 wlan_scan_vdev_destroyed_notification, NULL); 150 if (status != QDF_STATUS_SUCCESS) 151 scm_err("Failed to unregister vdev delete handler"); 152 153 return status; 154 } 155 156 #ifdef FEATURE_WLAN_SCAN_PNO 157 158 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev, 159 struct pno_scan_req_params *req) 160 { 161 struct scan_vdev_obj *scan_vdev_obj; 162 QDF_STATUS status; 163 164 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 165 if (!scan_vdev_obj) { 166 scm_err("null scan_vdev_obj"); 167 return QDF_STATUS_E_INVAL; 168 } 169 if (scan_vdev_obj->pno_in_progress) { 170 scm_err("pno already in progress"); 171 return QDF_STATUS_E_ALREADY; 172 } 173 174 status = tgt_scan_pno_start(vdev, req); 175 if (QDF_IS_STATUS_ERROR(status)) 176 scm_err("pno start failed"); 177 else 178 scan_vdev_obj->pno_in_progress = true; 179 180 return status; 181 } 182 183 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev) 184 { 185 struct scan_vdev_obj *scan_vdev_obj; 186 QDF_STATUS status; 187 188 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 189 if (!scan_vdev_obj) { 190 scm_err("null scan_vdev_obj"); 191 return QDF_STATUS_E_INVAL; 192 } 193 if (!scan_vdev_obj->pno_in_progress) { 194 scm_debug("pno already stopped"); 195 return QDF_STATUS_E_ALREADY; 196 } 197 198 status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev)); 199 if (QDF_IS_STATUS_ERROR(status)) 200 scm_err("pno start failed"); 201 else 202 scan_vdev_obj->pno_in_progress = false; 203 204 return status; 205 } 206 207 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev) 208 { 209 struct scan_vdev_obj *scan_vdev_obj; 210 211 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 212 if (!scan_vdev_obj) { 213 scm_err("null scan_vdev_obj"); 214 return false; 215 } 216 217 return scan_vdev_obj->pno_in_progress; 218 } 219 220 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev) 221 { 222 struct scan_vdev_obj *scan_vdev_obj; 223 224 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 225 if (!scan_vdev_obj) { 226 scm_err("null scan_vdev_obj"); 227 return false; 228 } 229 230 return scan_vdev_obj->pno_match_evt_received; 231 } 232 233 static QDF_STATUS 234 wlan_pno_global_init(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 = SCAN_PNO_CHANNEL_PREDICTION; 241 pno_def->top_k_num_of_channels = SCAN_TOP_K_NUM_OF_CHANNELS; 242 pno_def->stationary_thresh = SCAN_STATIONARY_THRESHOLD; 243 pno_def->channel_prediction_full_scan = 244 SCAN_CHANNEL_PREDICTION_FULL_SCAN_MS; 245 pno_def->adaptive_dwell_mode = SCAN_ADAPTIVE_PNOSCAN_DWELL_MODE; 246 mawc_cfg->enable = SCAN_MAWC_NLO_ENABLED; 247 mawc_cfg->exp_backoff_ratio = SCAN_MAWC_NLO_EXP_BACKOFF_RATIO; 248 mawc_cfg->init_scan_interval = SCAN_MAWC_NLO_INIT_SCAN_INTERVAL; 249 mawc_cfg->max_scan_interval = SCAN_MAWC_NLO_MAX_SCAN_INTERVAL; 250 251 return QDF_STATUS_SUCCESS; 252 } 253 254 static QDF_STATUS 255 wlan_pno_global_deinit(struct pno_def_config *pno_def) 256 { 257 qdf_wake_lock_destroy(&pno_def->pno_wake_lock); 258 259 return QDF_STATUS_SUCCESS; 260 } 261 262 #ifdef WLAN_POLICY_MGR_ENABLE 263 /* 264 * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time 265 * depending on active concurrency modes 266 * @vdev: vdev object pointer 267 * @req: scan request 268 * 269 * Return: void 270 */ 271 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 272 struct pno_scan_req_params *req, struct scan_default_params *scan_def) 273 { 274 bool sap_or_p2p_present; 275 struct wlan_objmgr_psoc *psoc; 276 277 psoc = wlan_vdev_get_psoc(vdev); 278 279 if (!psoc) 280 return; 281 282 sap_or_p2p_present = policy_mgr_mode_specific_connection_count( 283 psoc, PM_SAP_MODE, NULL) || 284 policy_mgr_mode_specific_connection_count( 285 psoc, PM_P2P_GO_MODE, NULL) || 286 policy_mgr_mode_specific_connection_count( 287 psoc, PM_P2P_CLIENT_MODE, NULL); 288 289 if (sap_or_p2p_present) { 290 req->active_dwell_time = scan_def->conc_active_dwell; 291 req->passive_dwell_time = scan_def->conc_passive_dwell; 292 } 293 294 } 295 #else 296 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 297 struct pno_scan_req_params *req, struct scan_default_params *scan_def){} 298 #endif 299 300 QDF_STATUS 301 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev, 302 struct pno_scan_req_params *req) 303 { 304 struct scan_default_params *scan_def; 305 struct wlan_scan_obj *scan; 306 struct pno_def_config *pno_def; 307 308 if (!vdev || !req) { 309 scm_err("vdev: 0x%pK, req: 0x%pK", 310 vdev, req); 311 return QDF_STATUS_E_INVAL; 312 } 313 314 scan = wlan_vdev_get_scan_obj(vdev); 315 if (!scan) { 316 scm_err("scan is NULL"); 317 return QDF_STATUS_E_INVAL; 318 } 319 scan_def = wlan_vdev_get_def_scan_params(vdev); 320 if (!scan_def) { 321 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 322 return QDF_STATUS_E_NULL_VALUE; 323 } 324 325 pno_def = &scan->pno_cfg; 326 req->active_dwell_time = scan_def->active_dwell; 327 req->passive_dwell_time = scan_def->passive_dwell; 328 req->scan_random.randomize = scan_def->enable_mac_spoofing; 329 330 /* 331 * Update active and passive dwell time depending 332 * upon the present active concurrency mode 333 */ 334 ucfg_scan_update_pno_dwell_time(vdev, req, scan_def); 335 req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode; 336 req->pno_channel_prediction = pno_def->channel_prediction; 337 req->top_k_num_of_channels = pno_def->top_k_num_of_channels; 338 req->stationary_thresh = pno_def->stationary_thresh; 339 req->channel_prediction_full_scan = 340 pno_def->channel_prediction_full_scan; 341 req->mawc_params.vdev_id = wlan_vdev_get_id(vdev); 342 qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params, 343 sizeof(req->mawc_params)); 344 345 return QDF_STATUS_SUCCESS; 346 } 347 348 static QDF_STATUS ucfg_scan_update_pno_config(struct pno_def_config *pno, 349 struct pno_user_cfg *pno_cfg) 350 { 351 pno->channel_prediction = pno_cfg->channel_prediction; 352 pno->top_k_num_of_channels = pno_cfg->top_k_num_of_channels; 353 pno->stationary_thresh = pno_cfg->stationary_thresh; 354 pno->adaptive_dwell_mode = pno_cfg->adaptive_dwell_mode; 355 pno->channel_prediction_full_scan = 356 pno_cfg->channel_prediction_full_scan; 357 qdf_mem_copy(&pno->mawc_params, &pno_cfg->mawc_params, 358 sizeof(pno->mawc_params)); 359 360 return QDF_STATUS_SUCCESS; 361 } 362 363 QDF_STATUS 364 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc, 365 scan_event_handler event_cb, void *arg) 366 { 367 struct wlan_scan_obj *scan; 368 369 if (!psoc) { 370 scm_err("null psoc"); 371 return QDF_STATUS_E_INVAL; 372 } 373 scan = wlan_psoc_get_scan_obj(psoc); 374 qdf_spin_lock_bh(&scan->lock); 375 scan->pno_cfg.pno_cb.func = event_cb; 376 scan->pno_cfg.pno_cb.arg = arg; 377 qdf_spin_unlock_bh(&scan->lock); 378 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 379 380 return QDF_STATUS_SUCCESS; 381 } 382 383 #else 384 385 static inline QDF_STATUS 386 wlan_pno_global_init(struct pno_def_config *pno_def) 387 { 388 return QDF_STATUS_SUCCESS; 389 } 390 static inline QDF_STATUS 391 wlan_pno_global_deinit(struct pno_def_config *pno_def) 392 { 393 return QDF_STATUS_SUCCESS; 394 } 395 396 static inline QDF_STATUS 397 ucfg_scan_update_pno_config(struct pno_def_config *pno, 398 struct pno_user_cfg *pno_cfg) 399 { 400 return QDF_STATUS_SUCCESS; 401 } 402 403 #endif 404 405 #ifdef WLAN_POLICY_MGR_ENABLE 406 /** 407 * ucfg_scan_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags 408 * @req: pointer to scan request 409 * 410 * This function sets scan_ctrl_flags_ext value depending on the type of 411 * scan and the channel lists. 412 * 413 * Non-DBS scan is requested if any of the below case is met: 414 * 1. HW is DBS incapable 415 * 2. A high accuracy scan request is sent by kernel. 416 * 417 * DBS scan is enabled for these conditions: 418 * 1. A low power or low span scan request is sent by kernel. 419 * For remaining cases DBS is enabled by default. 420 * Return: void 421 */ 422 static void 423 ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 424 { 425 struct wlan_objmgr_psoc *psoc; 426 uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; 427 428 psoc = wlan_vdev_get_psoc(req->vdev); 429 430 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 431 scm_debug("dbs disabled, going for non-dbs scan"); 432 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 433 goto end; 434 } 435 436 if (req->scan_req.scan_policy_high_accuracy) { 437 scm_debug("high accuracy scan received, going for non-dbs scan"); 438 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 439 goto end; 440 } 441 if ((req->scan_req.scan_policy_low_power) || 442 (req->scan_req.scan_policy_low_span)) { 443 scm_debug("low power/span scan received, going for dbs scan"); 444 scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; 445 goto end; 446 } 447 448 end: 449 req->scan_req.scan_ctrl_flags_ext |= 450 ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) 451 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); 452 scm_debug("scan_ctrl_flags_ext: 0x%x", 453 req->scan_req.scan_ctrl_flags_ext); 454 } 455 456 /** 457 * ucfg_update_passive_dwell_time() - update dwell passive time 458 * @vdev: vdev object 459 * @req: scan request 460 * 461 * Return: None 462 */ 463 static void 464 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 465 struct scan_start_request *req) 466 { 467 struct wlan_objmgr_psoc *psoc; 468 469 psoc = wlan_vdev_get_psoc(vdev); 470 if (!psoc) 471 return; 472 473 if (policy_mgr_is_sta_connected_2g(psoc) && 474 !policy_mgr_is_hw_dbs_capable(psoc) && 475 ucfg_scan_get_bt_activity(psoc)) 476 req->scan_req.dwell_time_passive = 477 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 478 } 479 480 static const struct probe_time_dwell_time 481 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 482 {28, 11}, /* 0 SSID */ 483 {28, 20}, /* 1 SSID */ 484 {28, 20}, /* 2 SSID */ 485 {28, 20}, /* 3 SSID */ 486 {28, 20}, /* 4 SSID */ 487 {28, 20}, /* 5 SSID */ 488 {28, 20}, /* 6 SSID */ 489 {28, 11}, /* 7 SSID */ 490 {28, 11}, /* 8 SSID */ 491 {28, 11}, /* 9 SSID */ 492 {28, 8} /* 10 SSID */ 493 }; 494 495 /** 496 * ucfg_scan_get_burst_duration() - get burst duration depending on max chan 497 * and miracast. 498 * @max_ch_time: max channel time 499 * @miracast_enabled: if miracast is enabled 500 * 501 * Return: burst_duration 502 */ 503 static inline 504 int ucfg_scan_get_burst_duration(int max_ch_time, 505 bool miracast_enabled) 506 { 507 int burst_duration = 0; 508 509 if (miracast_enabled) { 510 /* 511 * When miracast is running, burst 512 * duration needs to be minimum to avoid 513 * any stutter or glitch in miracast 514 * during station scan 515 */ 516 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 517 burst_duration = max_ch_time; 518 else 519 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 520 } else { 521 /* 522 * If miracast is not running, accommodate max 523 * stations to make the scans faster 524 */ 525 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 526 max_ch_time; 527 528 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 529 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 530 max_ch_time; 531 532 if (channels) 533 burst_duration = channels * max_ch_time; 534 else 535 burst_duration = 536 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 537 } 538 } 539 return burst_duration; 540 } 541 542 /** 543 * ucfg_scan_req_update_params() - update scan req params depending on 544 * concurrent mode present. 545 * @vdev: vdev object pointer 546 * @req: scan request 547 * @scan_obj: scan object 548 * 549 * Return: void 550 */ 551 static void ucfg_scan_req_update_concurrency_params( 552 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req, 553 struct wlan_scan_obj *scan_obj) 554 { 555 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 556 struct wlan_objmgr_psoc *psoc; 557 558 psoc = wlan_vdev_get_psoc(vdev); 559 560 if (!psoc) 561 return; 562 563 ap_present = policy_mgr_mode_specific_connection_count( 564 psoc, PM_SAP_MODE, NULL); 565 go_present = policy_mgr_mode_specific_connection_count( 566 psoc, PM_P2P_GO_MODE, NULL); 567 p2p_cli_present = policy_mgr_mode_specific_connection_count( 568 psoc, PM_P2P_CLIENT_MODE, NULL); 569 sta_active = policy_mgr_mode_specific_connection_count( 570 psoc, PM_STA_MODE, NULL); 571 ndi_present = policy_mgr_mode_specific_connection_count( 572 psoc, PM_NDI_MODE, NULL); 573 574 if (policy_mgr_get_connection_count(psoc)) { 575 if (req->scan_req.scan_f_passive) 576 req->scan_req.dwell_time_passive = 577 scan_obj->scan_def.conc_passive_dwell; 578 else 579 req->scan_req.dwell_time_active = 580 scan_obj->scan_def.conc_active_dwell; 581 req->scan_req.max_rest_time = 582 scan_obj->scan_def.conc_max_rest_time; 583 req->scan_req.min_rest_time = 584 scan_obj->scan_def.conc_min_rest_time; 585 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 586 } 587 588 if (!wlan_vdev_is_up(req->vdev)) 589 req->scan_req.adaptive_dwell_time_mode = 590 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 591 /* 592 * If AP is active set min rest time same as max rest time, so that 593 * firmware spends more time on home channel which will increase the 594 * probability of sending beacon at TBTT 595 */ 596 if (ap_present || go_present) { 597 req->scan_req.dwell_time_active_2g = 0; 598 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 599 } 600 601 if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { 602 /* 603 * Decide burst_duration and dwell_time_active based on 604 * what type of devices are active. 605 */ 606 do { 607 if (ap_present && go_present && sta_active) { 608 if (req->scan_req.dwell_time_active <= 609 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 610 req->scan_req.burst_duration = 611 req->scan_req.dwell_time_active; 612 else 613 req->scan_req.burst_duration = 614 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 615 616 break; 617 } 618 619 if (scan_obj->miracast_enabled && 620 policy_mgr_is_mcc_in_24G(psoc)) 621 req->scan_req.max_rest_time = 622 scan_obj->scan_def.sta_miracast_mcc_rest_time; 623 624 if (go_present) { 625 /* 626 * Background scan while GO is sending beacons. 627 * Every off-channel transition has overhead of 628 * 2 beacon intervals for NOA. Maximize number 629 * of channels in every transition by using 630 * burst scan. 631 */ 632 req->scan_req.burst_duration = 633 ucfg_scan_get_burst_duration( 634 req->scan_req.dwell_time_active, 635 scan_obj->miracast_enabled); 636 break; 637 } 638 if ((sta_active || p2p_cli_present) && 639 !req->scan_req.burst_duration) { 640 /* Typical background scan. 641 * Disable burst scan for now. 642 */ 643 req->scan_req.burst_duration = 0; 644 break; 645 } 646 647 if (ndi_present) { 648 req->scan_req.burst_duration = 649 ucfg_scan_get_burst_duration( 650 req->scan_req.dwell_time_active, 651 scan_obj->miracast_enabled); 652 break; 653 } 654 } while (0); 655 656 if (ap_present) { 657 uint8_t ssid_num; 658 ssid_num = req->scan_req.num_ssids * 659 req->scan_req.num_bssid; 660 req->scan_req.repeat_probe_time = 661 scan_probe_time_dwell_time_map[ 662 QDF_MIN(ssid_num, 663 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 664 - 1)].probe_time; 665 req->scan_req.n_probes = 666 (req->scan_req.repeat_probe_time > 0) ? 667 req->scan_req.dwell_time_active / 668 req->scan_req.repeat_probe_time : 0; 669 } 670 } 671 672 if (ap_present) { 673 uint8_t ap_chan; 674 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 675 676 ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 677 /* 678 * P2P/STA scan while SoftAP is sending beacons. 679 * Max duration of CTS2self is 32 ms, which limits the 680 * dwell time. If DBS is supported and if SAP is on 2G channel 681 * then keep passive dwell time default. 682 */ 683 req->scan_req.dwell_time_active = 684 QDF_MIN(req->scan_req.dwell_time_active, 685 (SCAN_CTS_DURATION_MS_MAX - 686 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 687 if (!policy_mgr_is_hw_dbs_capable(psoc) || 688 (policy_mgr_is_hw_dbs_capable(psoc) && 689 WLAN_CHAN_IS_5GHZ(ap_chan))) { 690 req->scan_req.dwell_time_passive = 691 req->scan_req.dwell_time_active; 692 } 693 req->scan_req.burst_duration = 0; 694 if (utils_is_dfs_ch(pdev, ap_chan)) 695 req->scan_req.burst_duration = 696 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 697 req->scan_req.dwell_time_active; 698 } 699 } 700 701 #else 702 static inline void ucfg_scan_req_update_concurrency_params( 703 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req, 704 struct wlan_scan_obj *scan_obj) 705 { 706 } 707 static inline void 708 ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 709 struct scan_start_request *req) {} 710 static inline void 711 ucfg_scan_update_dbs_scan_ctrl_ext_flag( 712 struct scan_start_request *req) {} 713 #endif 714 715 QDF_STATUS 716 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev, 717 struct chan_list *chan_list) 718 { 719 uint8_t pdev_id; 720 struct wlan_scan_obj *scan_obj; 721 722 if (!pdev || !chan_list) { 723 scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list); 724 return QDF_STATUS_E_NULL_VALUE; 725 } 726 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 727 scan_obj = wlan_pdev_get_scan_obj(pdev); 728 729 qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list, 730 chan_list, sizeof(*chan_list)); 731 732 return QDF_STATUS_SUCCESS; 733 } 734 735 /** 736 * ucfg_update_channel_list() - update scan req params depending on dfs inis 737 * and initial scan request. 738 * @req: scan request 739 * @scan_obj: scan object 740 * 741 * Return: void 742 */ 743 static void 744 ucfg_update_channel_list(struct scan_start_request *req, 745 struct wlan_scan_obj *scan_obj) 746 { 747 uint8_t i; 748 uint8_t num_scan_channels = 0; 749 struct scan_vdev_obj *scan_vdev_obj; 750 struct wlan_objmgr_pdev *pdev; 751 bool first_scan_done = true; 752 753 pdev = wlan_vdev_get_pdev(req->vdev); 754 755 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 756 if (!scan_vdev_obj) { 757 scm_err("null scan_vdev_obj"); 758 return; 759 } 760 761 if (!scan_vdev_obj->first_scan_done) { 762 first_scan_done = false; 763 scan_vdev_obj->first_scan_done = true; 764 } 765 766 /* 767 * No need to update channels if req is passive scan and single channel 768 * ie ROC, Preauth etc 769 */ 770 if (req->scan_req.scan_f_passive && 771 req->scan_req.chan_list.num_chan == 1) 772 return; 773 774 /* do this only for STA and P2P-CLI mode */ 775 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 776 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 777 return; 778 779 if (scan_obj->scan_def.allow_dfs_chan_in_scan && 780 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 781 first_scan_done)) 782 return; 783 784 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 785 if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev, 786 req->scan_req.chan_list. 787 chan[i].freq))) 788 continue; 789 req->scan_req.chan_list.chan[num_scan_channels++] = 790 req->scan_req.chan_list.chan[i]; 791 } 792 req->scan_req.chan_list.num_chan = num_scan_channels; 793 } 794 795 /** 796 * ucfg_scan_req_update_params() - update scan req params depending on modes 797 * and scan type. 798 * @vdev: vdev object pointer 799 * @req: scan request 800 * @scan_obj: scan object 801 * 802 * Return: void 803 */ 804 static void 805 ucfg_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 806 struct scan_start_request *req, struct wlan_scan_obj *scan_obj) 807 { 808 struct chan_list *custom_chan_list; 809 struct wlan_objmgr_pdev *pdev; 810 uint8_t pdev_id; 811 812 /* Ensure correct number of probes are sent on active channel */ 813 if (!req->scan_req.repeat_probe_time) 814 req->scan_req.repeat_probe_time = 815 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 816 817 if (req->scan_req.scan_f_passive) 818 req->scan_req.scan_ctrl_flags_ext |= 819 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 820 821 if (!req->scan_req.n_probes) 822 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 823 req->scan_req.dwell_time_active / 824 req->scan_req.repeat_probe_time : 0; 825 826 if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { 827 req->scan_req.scan_f_cck_rates = true; 828 if (!req->scan_req.num_ssids) 829 req->scan_req.scan_f_bcast_probe = true; 830 req->scan_req.scan_f_add_ds_ie_in_probe = true; 831 req->scan_req.scan_f_filter_prb_req = true; 832 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 833 } else { 834 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 835 req->scan_req.dwell_time_active_2g = 0; 836 if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) { 837 req->scan_req.repeat_probe_time = 0; 838 } else { 839 req->scan_req.scan_f_filter_prb_req = true; 840 if (!req->scan_req.num_ssids) 841 req->scan_req.scan_f_bcast_probe = true; 842 843 req->scan_req.dwell_time_active += 844 P2P_SEARCH_DWELL_TIME_INC; 845 /* 846 * 3 channels with default max dwell time 40 ms. 847 * Cap limit will be set by 848 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 849 * should be such that no channel is scanned less 850 * than the dwell time in normal scenarios. 851 */ 852 if (req->scan_req.chan_list.num_chan == 853 WLAN_P2P_SOCIAL_CHANNELS && 854 !scan_obj->miracast_enabled) 855 req->scan_req.repeat_probe_time = 856 req->scan_req.dwell_time_active / 5; 857 else 858 req->scan_req.repeat_probe_time = 859 req->scan_req.dwell_time_active / 3; 860 861 req->scan_req.burst_duration = 862 BURST_SCAN_MAX_NUM_OFFCHANNELS * 863 req->scan_req.dwell_time_active; 864 if (req->scan_req.burst_duration > 865 P2P_SCAN_MAX_BURST_DURATION) { 866 uint8_t channels = 867 P2P_SCAN_MAX_BURST_DURATION / 868 req->scan_req.dwell_time_active; 869 if (channels) 870 req->scan_req.burst_duration = 871 channels * 872 req->scan_req.dwell_time_active; 873 else 874 req->scan_req.burst_duration = 875 P2P_SCAN_MAX_BURST_DURATION; 876 } 877 req->scan_req.scan_ev_bss_chan = false; 878 } 879 } 880 881 if (!req->scan_req.scan_f_passive) 882 ucfg_update_passive_dwell_time(vdev, req); 883 ucfg_scan_update_dbs_scan_ctrl_ext_flag(req); 884 885 /* 886 * No need to update conncurrency parmas if req is passive scan on 887 * single channel ie ROC, Preauth etc 888 */ 889 if (!(req->scan_req.scan_f_passive && 890 req->scan_req.chan_list.num_chan == 1)) 891 ucfg_scan_req_update_concurrency_params(vdev, req, scan_obj); 892 893 /* Set wide band flag if enabled. This will cause 894 * phymode TLV being sent to FW. 895 */ 896 pdev = wlan_vdev_get_pdev(vdev); 897 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 898 if (ucfg_scan_get_wide_band_scan(pdev)) 899 req->scan_req.scan_f_wide_band = true; 900 else 901 req->scan_req.scan_f_wide_band = false; 902 903 /* Overwrite scan channles with custom scan channel 904 * list if configured. 905 */ 906 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 907 if (custom_chan_list->num_chan) 908 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 909 sizeof(struct chan_list)); 910 else if (!req->scan_req.chan_list.num_chan) 911 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 912 913 ucfg_update_channel_list(req, scan_obj); 914 scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d " 915 "n_probes %d flags_ext %x, wide_bw_scan: %d", 916 req->scan_req.dwell_time_active, 917 req->scan_req.dwell_time_passive, 918 req->scan_req.repeat_probe_time, req->scan_req.n_probes, 919 req->scan_req.scan_ctrl_flags_ext, 920 req->scan_req.scan_f_wide_band); 921 } 922 923 QDF_STATUS 924 ucfg_scan_start(struct scan_start_request *req) 925 { 926 struct scheduler_msg msg = {0}; 927 QDF_STATUS status; 928 struct wlan_scan_obj *scan_obj; 929 struct wlan_objmgr_pdev *pdev; 930 uint8_t idx; 931 932 if (!req || !req->vdev) { 933 scm_err("req or vdev within req is NULL"); 934 if (req) 935 scm_scan_free_scan_request_mem(req); 936 return QDF_STATUS_E_NULL_VALUE; 937 } 938 939 pdev = wlan_vdev_get_pdev(req->vdev); 940 if (!pdev) { 941 scm_err("Failed to get pdev object"); 942 scm_scan_free_scan_request_mem(req); 943 return QDF_STATUS_E_NULL_VALUE; 944 } 945 946 if (!scm_is_scan_allowed(req->vdev)) { 947 scm_err("scan disabled, rejecting the scan req"); 948 scm_scan_free_scan_request_mem(req); 949 return QDF_STATUS_E_AGAIN; 950 } 951 952 scan_obj = wlan_pdev_get_scan_obj(pdev); 953 if (!scan_obj) { 954 scm_err("Failed to get scan object"); 955 scm_scan_free_scan_request_mem(req); 956 return QDF_STATUS_E_NULL_VALUE; 957 } 958 959 scm_debug("reqid: %d, scanid: %d, vdevid: %d", 960 req->scan_req.scan_req_id, req->scan_req.scan_id, 961 req->scan_req.vdev_id); 962 963 ucfg_scan_req_update_params(req->vdev, req, scan_obj); 964 965 /* Try to get vdev reference. Return if reference could 966 * not be taken. Reference will be released once scan 967 * request handling completes along with free of @req. 968 */ 969 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 970 if (QDF_IS_STATUS_ERROR(status)) { 971 scm_info("unable to get reference"); 972 scm_scan_free_scan_request_mem(req); 973 return status; 974 } 975 976 scm_info("request to scan %d channels", 977 req->scan_req.chan_list.num_chan); 978 for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++) 979 scm_debug("chan[%d]: freq:%d, phymode:%d", idx, 980 req->scan_req.chan_list.chan[idx].freq, 981 req->scan_req.chan_list.chan[idx].phymode); 982 983 msg.bodyptr = req; 984 msg.callback = scm_scan_start_req; 985 msg.flush_callback = scm_scan_start_flush_callback; 986 987 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 988 QDF_MODULE_ID_SCAN, 989 QDF_MODULE_ID_OS_IF, &msg); 990 if (QDF_IS_STATUS_ERROR(status)) { 991 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 992 scm_err("failed to post to QDF_MODULE_ID_OS_IF"); 993 scm_scan_free_scan_request_mem(req); 994 } 995 996 return status; 997 } 998 999 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, 1000 enum scan_disable_reason reason) 1001 { 1002 struct wlan_scan_obj *scan_obj; 1003 1004 scan_obj = wlan_psoc_get_scan_obj(psoc); 1005 if (!scan_obj) { 1006 scm_err("Failed to get scan object"); 1007 return QDF_STATUS_E_NULL_VALUE; 1008 } 1009 1010 scan_obj->scan_disabled &= ~reason; 1011 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 1012 1013 return QDF_STATUS_SUCCESS; 1014 } 1015 1016 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, 1017 enum scan_disable_reason reason) 1018 { 1019 struct wlan_scan_obj *scan_obj; 1020 1021 scan_obj = wlan_psoc_get_scan_obj(psoc); 1022 if (!scan_obj) { 1023 scm_err("Failed to get scan object"); 1024 return QDF_STATUS_E_NULL_VALUE; 1025 } 1026 1027 scan_obj->scan_disabled |= reason; 1028 1029 scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); 1030 1031 return QDF_STATUS_SUCCESS; 1032 } 1033 1034 1035 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, 1036 enum scan_disable_reason reason) 1037 { 1038 struct scan_vdev_obj *scan_vdev_obj; 1039 1040 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1041 if (!scan_vdev_obj) { 1042 scm_err("null scan_vdev_obj"); 1043 return QDF_STATUS_E_NULL_VALUE; 1044 } 1045 1046 scan_vdev_obj->scan_disabled &= ~reason; 1047 1048 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 1049 1050 return QDF_STATUS_SUCCESS; 1051 } 1052 1053 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, 1054 enum scan_disable_reason reason) 1055 { 1056 struct scan_vdev_obj *scan_vdev_obj; 1057 1058 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1059 if (!scan_vdev_obj) { 1060 scm_err("null scan_vdev_obj"); 1061 return QDF_STATUS_E_NULL_VALUE; 1062 } 1063 1064 scan_vdev_obj->scan_disabled |= reason; 1065 1066 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 1067 1068 return QDF_STATUS_SUCCESS; 1069 } 1070 1071 1072 QDF_STATUS ucfg_scan_set_miracast( 1073 struct wlan_objmgr_psoc *psoc, bool enable) 1074 { 1075 struct wlan_scan_obj *scan_obj; 1076 1077 scan_obj = wlan_psoc_get_scan_obj(psoc); 1078 if (!scan_obj) { 1079 scm_err("Failed to get scan object"); 1080 return QDF_STATUS_E_NULL_VALUE; 1081 } 1082 scan_obj->miracast_enabled = enable; 1083 scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled); 1084 1085 return QDF_STATUS_SUCCESS; 1086 } 1087 1088 QDF_STATUS 1089 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable) 1090 { 1091 uint8_t pdev_id; 1092 struct wlan_scan_obj *scan_obj; 1093 1094 if (!pdev) { 1095 scm_warn("null vdev"); 1096 return QDF_STATUS_E_NULL_VALUE; 1097 } 1098 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1099 scan_obj = wlan_pdev_get_scan_obj(pdev); 1100 if (!scan_obj) 1101 return QDF_STATUS_E_FAILURE; 1102 1103 scm_debug("set wide_band_scan to %d", enable); 1104 scan_obj->pdev_info[pdev_id].wide_band_scan = enable; 1105 1106 return QDF_STATUS_SUCCESS; 1107 } 1108 1109 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev) 1110 { 1111 uint8_t pdev_id; 1112 struct wlan_scan_obj *scan_obj; 1113 1114 if (!pdev) { 1115 scm_warn("null vdev"); 1116 return QDF_STATUS_E_NULL_VALUE; 1117 } 1118 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1119 scan_obj = wlan_pdev_get_scan_obj(pdev); 1120 if (!scan_obj) 1121 return QDF_STATUS_E_FAILURE; 1122 1123 return scan_obj->pdev_info[pdev_id].wide_band_scan; 1124 } 1125 1126 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 1127 QDF_STATUS 1128 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev, 1129 uint8_t *bssid, struct wlan_ssid *ssid) 1130 { 1131 uint8_t pdev_id; 1132 struct wlan_scan_obj *scan_obj; 1133 1134 if (!pdev) { 1135 scm_warn("null vdev"); 1136 return QDF_STATUS_E_NULL_VALUE; 1137 } 1138 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1139 scan_obj = wlan_pdev_get_scan_obj(pdev); 1140 if (!scan_obj) 1141 return QDF_STATUS_E_FAILURE; 1142 1143 scm_debug("Configure bsssid:%pM ssid:%.*s", 1144 bssid, ssid->length, ssid->ssid); 1145 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid, 1146 bssid, QDF_MAC_ADDR_SIZE); 1147 scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length; 1148 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid, 1149 ssid->ssid, 1150 scan_obj->pdev_info[pdev_id].conf_ssid.length); 1151 1152 return QDF_STATUS_SUCCESS; 1153 } 1154 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 1155 1156 QDF_STATUS 1157 ucfg_scan_cancel(struct scan_cancel_request *req) 1158 { 1159 struct scheduler_msg msg = {0}; 1160 QDF_STATUS status; 1161 1162 if (!req || !req->vdev) { 1163 scm_err("req or vdev within req is NULL"); 1164 if (req) 1165 qdf_mem_free(req); 1166 return QDF_STATUS_E_NULL_VALUE; 1167 } 1168 scm_debug("reqid: %d, scanid: %d, vdevid: %d, type: %d", 1169 req->cancel_req.requester, req->cancel_req.scan_id, 1170 req->cancel_req.vdev_id, req->cancel_req.req_type); 1171 1172 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 1173 if (QDF_IS_STATUS_ERROR(status)) { 1174 scm_info("Failed to get vdev ref; status:%d", status); 1175 goto req_free; 1176 } 1177 1178 msg.bodyptr = req; 1179 msg.callback = scm_scan_cancel_req; 1180 msg.flush_callback = scm_scan_cancel_flush_callback; 1181 1182 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 1183 QDF_MODULE_ID_SCAN, 1184 QDF_MODULE_ID_OS_IF, &msg); 1185 if (QDF_IS_STATUS_ERROR(status)) { 1186 scm_err("failed to post to QDF_MODULE_ID_OS_IF"); 1187 goto vdev_put; 1188 } 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 scm_err("failed to post to QDF_MODULE_ID_OS_IF"); 1229 return status; 1230 } 1231 1232 memset(&cancel_scan_event, 0, sizeof(cancel_scan_event)); 1233 /* 1234 * If cancel req is to cancel all scan of pdev or vdev 1235 * wait until all scan of pdev or vdev get cancelled 1236 */ 1237 qdf_event_create(&cancel_scan_event); 1238 qdf_event_reset(&cancel_scan_event); 1239 1240 if (cancel_pdev) { 1241 pdev = wlan_vdev_get_pdev(vdev); 1242 while ((ucfg_scan_get_pdev_status(pdev) != 1243 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 1244 scm_debug("wait for all pdev scan to get complete"); 1245 qdf_wait_single_event(&cancel_scan_event, 1246 qdf_system_msecs_to_ticks( 1247 SCM_CANCEL_SCAN_WAIT_TIME)); 1248 max_wait_iterations--; 1249 } 1250 } else if (cancel_vdev) { 1251 while ((ucfg_scan_get_vdev_status(vdev) != 1252 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 1253 scm_debug("wait for all vdev scan to get complete"); 1254 qdf_wait_single_event(&cancel_scan_event, 1255 qdf_system_msecs_to_ticks( 1256 SCM_CANCEL_SCAN_WAIT_TIME)); 1257 max_wait_iterations--; 1258 } 1259 } 1260 1261 qdf_event_destroy(&cancel_scan_event); 1262 1263 if (!max_wait_iterations) { 1264 scm_err("Failed to wait for scans to get complete"); 1265 return QDF_STATUS_E_TIMEOUT; 1266 } 1267 1268 return status; 1269 } 1270 1271 wlan_scan_requester 1272 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc, 1273 uint8_t *name, scan_event_handler event_cb, void *arg) 1274 { 1275 int i, j; 1276 struct wlan_scan_obj *scan; 1277 struct scan_requester_info *requesters; 1278 wlan_scan_requester requester = {0}; 1279 1280 if (!psoc) { 1281 scm_err("null psoc"); 1282 return 0; 1283 } 1284 scan = wlan_psoc_get_scan_obj(psoc); 1285 if (!scan) 1286 return 0; 1287 1288 requesters = scan->requesters; 1289 qdf_spin_lock_bh(&scan->lock); 1290 for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) { 1291 if (requesters[i].requester == 0) { 1292 requesters[i].requester = 1293 WLAN_SCAN_REQUESTER_ID_PREFIX | i; 1294 j = 0; 1295 while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) { 1296 requesters[i].module[j] = name[j]; 1297 ++j; 1298 } 1299 requesters[i].module[j] = 0; 1300 requesters[i].ev_handler.func = event_cb; 1301 requesters[i].ev_handler.arg = arg; 1302 requester = requesters[i].requester; 1303 break; 1304 } 1305 } 1306 qdf_spin_unlock_bh(&scan->lock); 1307 scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d", 1308 name, event_cb, arg, requester); 1309 1310 return requester; 1311 } 1312 1313 void 1314 ucfg_scan_unregister_requester(struct wlan_objmgr_psoc *psoc, 1315 wlan_scan_requester requester) 1316 { 1317 int idx; 1318 struct wlan_scan_obj *scan; 1319 struct scan_requester_info *requesters; 1320 1321 idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX; 1322 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) { 1323 scm_err("prefix didn't match for requester id %d", requester); 1324 return; 1325 } 1326 1327 idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 1328 if (idx >= WLAN_MAX_REQUESTORS) { 1329 scm_err("requester id %d greater than max value", requester); 1330 return; 1331 } 1332 1333 if (!psoc) { 1334 scm_err("null psoc"); 1335 return; 1336 } 1337 scan = wlan_psoc_get_scan_obj(psoc); 1338 if (!scan) 1339 return; 1340 requesters = scan->requesters; 1341 scm_debug("reqid: %d", requester); 1342 1343 qdf_spin_lock_bh(&scan->lock); 1344 requesters[idx].requester = 0; 1345 requesters[idx].module[0] = 0; 1346 requesters[idx].ev_handler.func = NULL; 1347 requesters[idx].ev_handler.arg = NULL; 1348 qdf_spin_unlock_bh(&scan->lock); 1349 } 1350 1351 uint8_t* 1352 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc, 1353 wlan_scan_requester requester) 1354 { 1355 int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 1356 struct wlan_scan_obj *scan; 1357 struct scan_requester_info *requesters; 1358 1359 if (!psoc) { 1360 scm_err("null psoc"); 1361 return "null"; 1362 } 1363 scan = wlan_psoc_get_scan_obj(psoc); 1364 if (!scan) 1365 return "null"; 1366 1367 requesters = scan->requesters; 1368 1369 if ((idx < WLAN_MAX_REQUESTORS) && 1370 (requesters[idx].requester == requester)) { 1371 return requesters[idx].module; 1372 } 1373 1374 return (uint8_t *)"unknown"; 1375 } 1376 1377 wlan_scan_id 1378 ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc) 1379 { 1380 wlan_scan_id id; 1381 struct wlan_scan_obj *scan; 1382 1383 if (!psoc) { 1384 QDF_ASSERT(0); 1385 scm_err("null psoc"); 1386 return 0; 1387 } 1388 scan = wlan_psoc_get_scan_obj(psoc); 1389 1390 id = qdf_atomic_inc_return(&scan->scan_ids); 1391 id = id & WLAN_SCAN_ID_MASK; 1392 /* Mark this scan request as triggered by host 1393 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag. 1394 */ 1395 id = id | WLAN_HOST_SCAN_REQ_ID_PREFIX; 1396 scm_debug("scan_id: 0x%x", id); 1397 1398 return id; 1399 } 1400 1401 static QDF_STATUS 1402 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 1403 scan_event_handler event_cb, void *arg) 1404 { 1405 struct cb_handler *cb_handler; 1406 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 1407 1408 /* Assign next available slot to this registration request */ 1409 cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]); 1410 cb_handler->func = event_cb; 1411 cb_handler->arg = arg; 1412 pdev_ev_handler->handler_cnt++; 1413 1414 return QDF_STATUS_SUCCESS; 1415 } 1416 1417 QDF_STATUS 1418 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev, 1419 scan_event_handler event_cb, void *arg) 1420 { 1421 uint32_t idx; 1422 struct wlan_scan_obj *scan; 1423 struct pdev_scan_ev_handler *pdev_ev_handler; 1424 struct cb_handler *cb_handler; 1425 1426 /* scan event handler call back can't be NULL */ 1427 if (!pdev || !event_cb) { 1428 scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb); 1429 return QDF_STATUS_E_NULL_VALUE; 1430 } 1431 1432 scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg); 1433 1434 scan = wlan_pdev_get_scan_obj(pdev); 1435 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 1436 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 1437 1438 qdf_spin_lock_bh(&scan->lock); 1439 /* Ensure its not a duplicate registration request */ 1440 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 1441 idx++, cb_handler++) { 1442 if ((cb_handler->func == event_cb) && 1443 (cb_handler->arg == arg)) { 1444 qdf_spin_unlock_bh(&scan->lock); 1445 scm_debug("func: %pK, arg: %pK already exists", 1446 event_cb, arg); 1447 return QDF_STATUS_SUCCESS; 1448 } 1449 } 1450 1451 QDF_ASSERT(pdev_ev_handler->handler_cnt < 1452 MAX_SCAN_EVENT_HANDLERS_PER_PDEV); 1453 1454 if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) { 1455 qdf_spin_unlock_bh(&scan->lock); 1456 scm_warn("No more registrations possible"); 1457 return QDF_STATUS_E_NOMEM; 1458 } 1459 1460 scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg); 1461 qdf_spin_unlock_bh(&scan->lock); 1462 1463 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 1464 1465 return QDF_STATUS_SUCCESS; 1466 } 1467 1468 static QDF_STATUS 1469 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, 1470 struct wlan_scan_obj *scan_obj) 1471 { 1472 scan_obj->scan_disabled = 0; 1473 scan_obj->drop_bcn_on_chan_mismatch = 1474 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH); 1475 scan_obj->disable_timeout = false; 1476 scan_obj->scan_def.active_dwell = 1477 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME); 1478 /* the ini is disallow DFS channel scan if ini is 1, so negate that */ 1479 scan_obj->scan_def.allow_dfs_chan_in_first_scan = 1480 !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN); 1481 scan_obj->scan_def.allow_dfs_chan_in_scan = 1482 cfg_get(psoc, CFG_ENABLE_DFS_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(&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 ucfg_scan_update_pno_config(&scan_obj->pno_cfg, 2008 &scan_cfg->pno_cfg); 2009 2010 qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config, 2011 sizeof(struct scoring_config)); 2012 scm_validate_scoring_config(&scan_def->score_config); 2013 2014 return QDF_STATUS_SUCCESS; 2015 } 2016 2017 QDF_STATUS ucfg_scan_update_roam_params(struct wlan_objmgr_psoc *psoc, 2018 struct roam_filter_params *roam_params) 2019 { 2020 struct scan_default_params *scan_def; 2021 2022 if (!psoc) { 2023 scm_err("null psoc"); 2024 return QDF_STATUS_E_FAILURE; 2025 } 2026 scan_def = wlan_scan_psoc_get_def_params(psoc); 2027 if (!scan_def) { 2028 scm_err("Failed to get scan object"); 2029 return QDF_STATUS_E_FAILURE; 2030 } 2031 2032 qdf_mem_copy(&scan_def->roam_params, roam_params, 2033 sizeof(struct roam_filter_params)); 2034 2035 return QDF_STATUS_SUCCESS; 2036 } 2037 2038 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 2039 static QDF_STATUS 2040 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) 2041 { 2042 struct scan_cancel_request *req; 2043 QDF_STATUS status; 2044 struct wlan_objmgr_vdev *vdev; 2045 2046 req = qdf_mem_malloc_atomic(sizeof(*req)); 2047 if (!req) { 2048 scm_err("Failed to allocate memory"); 2049 return QDF_STATUS_E_NOMEM; 2050 } 2051 2052 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID); 2053 if (!vdev) { 2054 scm_err("Failed to get vdev"); 2055 qdf_mem_free(req); 2056 return QDF_STATUS_E_INVAL; 2057 } 2058 req->vdev = vdev; 2059 req->cancel_req.scan_id = INVAL_SCAN_ID; 2060 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 2061 req->cancel_req.vdev_id = INVAL_VDEV_ID; 2062 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 2063 status = ucfg_scan_cancel_sync(req); 2064 if (QDF_IS_STATUS_ERROR(status)) 2065 scm_err("Cancel scan request failed"); 2066 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 2067 2068 return status; 2069 } 2070 2071 static QDF_STATUS 2072 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) 2073 { 2074 struct wlan_objmgr_pdev *pdev = NULL; 2075 QDF_STATUS status = QDF_STATUS_SUCCESS; 2076 int i; 2077 2078 ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND); 2079 /* Check all pdev */ 2080 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 2081 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); 2082 if (!pdev) 2083 continue; 2084 if (ucfg_scan_get_pdev_status(pdev) != 2085 SCAN_NOT_IN_PROGRESS) 2086 status = ucfg_scan_cancel_pdev_scan(pdev); 2087 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 2088 if (QDF_IS_STATUS_ERROR(status)) { 2089 scm_err("failed to cancel scan for pdev_id %d", i); 2090 return status; 2091 } 2092 } 2093 2094 return QDF_STATUS_SUCCESS; 2095 } 2096 2097 static QDF_STATUS 2098 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) 2099 { 2100 ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND); 2101 return QDF_STATUS_SUCCESS; 2102 } 2103 2104 static inline void 2105 ucfg_scan_register_pmo_handler(void) 2106 { 2107 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN, 2108 ucfg_scan_suspend_handler, NULL); 2109 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN, 2110 ucfg_scan_resume_handler, NULL); 2111 } 2112 2113 static inline void 2114 ucfg_scan_unregister_pmo_handler(void) 2115 { 2116 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN, 2117 ucfg_scan_suspend_handler); 2118 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN, 2119 ucfg_scan_resume_handler); 2120 } 2121 2122 #else 2123 static inline void 2124 ucfg_scan_register_pmo_handler(void) 2125 { 2126 } 2127 2128 static inline void 2129 ucfg_scan_unregister_pmo_handler(void) 2130 { 2131 } 2132 #endif 2133 2134 QDF_STATUS 2135 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) 2136 { 2137 struct wlan_scan_obj *scan_obj; 2138 2139 scm_debug("psoc open: 0x%pK", psoc); 2140 if (!psoc) { 2141 scm_err("null psoc"); 2142 return QDF_STATUS_E_FAILURE; 2143 } 2144 scan_obj = wlan_psoc_get_scan_obj(psoc); 2145 if (scan_obj == NULL) { 2146 scm_err("Failed to get scan object"); 2147 return QDF_STATUS_E_FAILURE; 2148 } 2149 /* Initialize the scan Globals */ 2150 wlan_scan_global_init(psoc, scan_obj); 2151 qdf_spinlock_create(&scan_obj->lock); 2152 ucfg_scan_register_pmo_handler(); 2153 scm_db_init(psoc); 2154 2155 return QDF_STATUS_SUCCESS; 2156 } 2157 2158 QDF_STATUS 2159 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) 2160 { 2161 struct wlan_scan_obj *scan_obj; 2162 2163 scm_debug("psoc close: 0x%pK", psoc); 2164 if (!psoc) { 2165 scm_err("null psoc"); 2166 return QDF_STATUS_E_FAILURE; 2167 } 2168 scm_db_deinit(psoc); 2169 scan_obj = wlan_psoc_get_scan_obj(psoc); 2170 if (scan_obj == NULL) { 2171 scm_err("Failed to get scan object"); 2172 return QDF_STATUS_E_FAILURE; 2173 } 2174 ucfg_scan_unregister_pmo_handler(); 2175 qdf_spinlock_destroy(&scan_obj->lock); 2176 wlan_scan_global_deinit(psoc); 2177 2178 return QDF_STATUS_SUCCESS; 2179 } 2180 2181 static bool scm_serialization_scan_rules_cb( 2182 union wlan_serialization_rules_info *comp_info, 2183 uint8_t comp_id) 2184 { 2185 switch (comp_id) { 2186 case WLAN_UMAC_COMP_TDLS: 2187 if (comp_info->scan_info.is_tdls_in_progress) { 2188 scm_debug("Cancel scan. Tdls in progress"); 2189 return false; 2190 } 2191 break; 2192 case WLAN_UMAC_COMP_DFS: 2193 if (comp_info->scan_info.is_cac_in_progress) { 2194 scm_debug("Cancel scan. CAC in progress"); 2195 return false; 2196 } 2197 break; 2198 default: 2199 scm_debug("not handled comp_id %d", comp_id); 2200 break; 2201 } 2202 2203 return true; 2204 } 2205 2206 QDF_STATUS 2207 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) 2208 { 2209 QDF_STATUS status; 2210 2211 scm_debug("psoc enable: 0x%pK", psoc); 2212 if (!psoc) { 2213 scm_err("null psoc"); 2214 return QDF_STATUS_E_FAILURE; 2215 } 2216 /* Subscribe for scan events from lmac layesr */ 2217 status = tgt_scan_register_ev_handler(psoc); 2218 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 2219 if (!wlan_reg_is_11d_offloaded(psoc)) 2220 scm_11d_cc_db_init(psoc); 2221 ucfg_scan_register_unregister_bcn_cb(psoc, true); 2222 status = wlan_serialization_register_apply_rules_cb(psoc, 2223 WLAN_SER_CMD_SCAN, 2224 scm_serialization_scan_rules_cb); 2225 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 2226 return status; 2227 } 2228 2229 QDF_STATUS 2230 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) 2231 { 2232 QDF_STATUS status; 2233 2234 scm_debug("psoc disable: 0x%pK", psoc); 2235 if (!psoc) { 2236 scm_err("null psoc"); 2237 return QDF_STATUS_E_FAILURE; 2238 } 2239 /* Unsubscribe for scan events from lmac layesr */ 2240 status = tgt_scan_unregister_ev_handler(psoc); 2241 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 2242 ucfg_scan_register_unregister_bcn_cb(psoc, false); 2243 if (!wlan_reg_is_11d_offloaded(psoc)) 2244 scm_11d_cc_db_deinit(psoc); 2245 2246 return status; 2247 } 2248 2249 uint32_t 2250 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc) 2251 { 2252 struct scan_default_params *scan_params = NULL; 2253 2254 if (!psoc) { 2255 scm_err("null psoc"); 2256 return 0; 2257 } 2258 scan_params = wlan_scan_psoc_get_def_params(psoc); 2259 if (!scan_params) { 2260 scm_err("Failed to get scan object"); 2261 return 0; 2262 } 2263 2264 return scan_params->max_active_scans_allowed; 2265 } 2266 2267 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc, 2268 struct probe_req_whitelist_attr *ie_whitelist) 2269 { 2270 struct wlan_scan_obj *scan_obj = NULL; 2271 2272 scan_obj = wlan_psoc_get_scan_obj(psoc); 2273 if (!scan_obj) 2274 return false; 2275 2276 qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist, 2277 sizeof(*ie_whitelist)); 2278 2279 return true; 2280 } 2281 2282 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc, 2283 struct wlan_objmgr_vdev *vdev) 2284 { 2285 struct wlan_scan_obj *scan_obj = NULL; 2286 2287 scan_obj = wlan_psoc_get_scan_obj(psoc); 2288 if (!scan_obj) 2289 return false; 2290 2291 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || 2292 wlan_vdev_is_connected(vdev)) 2293 return false; 2294 2295 if (!scan_obj->ie_whitelist.white_list) 2296 return false; 2297 2298 return true; 2299 } 2300 2301 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, 2302 bool bt_a2dp_active) 2303 { 2304 struct wlan_scan_obj *scan_obj; 2305 2306 scan_obj = wlan_psoc_get_scan_obj(psoc); 2307 if (!scan_obj) { 2308 scm_err("Failed to get scan object"); 2309 return; 2310 } 2311 scan_obj->bt_a2dp_enabled = bt_a2dp_active; 2312 } 2313 2314 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) 2315 { 2316 struct wlan_scan_obj *scan_obj; 2317 2318 scan_obj = wlan_psoc_get_scan_obj(psoc); 2319 if (!scan_obj) { 2320 scm_err("Failed to get scan object"); 2321 return false; 2322 } 2323 2324 return scan_obj->bt_a2dp_enabled; 2325 } 2326 2327 QDF_STATUS 2328 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, 2329 enum scan_config config, uint32_t val) 2330 { 2331 struct wlan_scan_obj *scan_obj; 2332 QDF_STATUS status = QDF_STATUS_SUCCESS; 2333 2334 scan_obj = wlan_psoc_get_scan_obj(psoc); 2335 if (!scan_obj) { 2336 scm_err("Failed to get scan object config:%d, val:%d", 2337 config, val); 2338 return QDF_STATUS_E_INVAL; 2339 } 2340 switch (config) { 2341 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 2342 scan_obj->disable_timeout = !!val; 2343 break; 2344 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 2345 scan_obj->drop_bcn_on_chan_mismatch = !!val; 2346 break; 2347 2348 default: 2349 status = QDF_STATUS_E_INVAL; 2350 break; 2351 } 2352 2353 return status; 2354 } 2355 2356 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev, 2357 struct bss_info *bss_info, struct mlme_info *mlme) 2358 { 2359 QDF_STATUS status; 2360 2361 status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme); 2362 2363 return status; 2364 } 2365 2366 QDF_STATUS 2367 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc, 2368 enum scan_config config, uint32_t *val) 2369 { 2370 struct wlan_scan_obj *scan_obj; 2371 QDF_STATUS status = QDF_STATUS_SUCCESS; 2372 2373 scan_obj = wlan_psoc_get_scan_obj(psoc); 2374 if (!scan_obj || !val) { 2375 scm_err("scan object:%pK config:%d, val:0x%pK", 2376 scan_obj, config, val); 2377 return QDF_STATUS_E_INVAL; 2378 } 2379 switch (config) { 2380 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 2381 *val = scan_obj->disable_timeout; 2382 break; 2383 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 2384 *val = scan_obj->drop_bcn_on_chan_mismatch; 2385 break; 2386 2387 default: 2388 status = QDF_STATUS_E_INVAL; 2389 break; 2390 } 2391 2392 return status; 2393 } 2394