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