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