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