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