1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* 19 * DOC: contains scan north bound interface definitions 20 */ 21 22 #include <scheduler_api.h> 23 #include <wlan_scan_ucfg_api.h> 24 #include <wlan_objmgr_global_obj.h> 25 #include <wlan_objmgr_cmn.h> 26 #include <wlan_serialization_api.h> 27 #include <wlan_scan_tgt_api.h> 28 #include <wlan_scan_utils_api.h> 29 #include <wlan_reg_ucfg_api.h> 30 #include <wlan_reg_services_api.h> 31 #include <wlan_utility.h> 32 #include "../../core/src/wlan_scan_main.h" 33 #include "../../core/src/wlan_scan_manager.h" 34 #include "../../core/src/wlan_scan_cache_db.h" 35 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 36 #include <wlan_pmo_obj_mgmt_api.h> 37 #endif 38 #ifdef WLAN_POLICY_MGR_ENABLE 39 #include <wlan_dfs_utils_api.h> 40 #include <wlan_policy_mgr_api.h> 41 #endif 42 #include "cfg_ucfg_api.h" 43 #include "wlan_extscan_api.h" 44 ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc * psoc,update_beacon_cb cb,enum scan_cb_type type)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 ucfg_scan_get_result(struct wlan_objmgr_pdev * pdev,struct scan_filter * filter)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 ucfg_scan_db_iterate(struct wlan_objmgr_pdev * pdev,scan_iterator_func func,void * arg)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 ucfg_scan_purge_results(qdf_list_t * scan_list)63 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list) 64 { 65 return scm_purge_scan_results(scan_list); 66 } 67 ucfg_scan_flush_results(struct wlan_objmgr_pdev * pdev,struct scan_filter * filter)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 ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev * pdev,uint32_t * chan_freq_list,uint32_t num_chan)74 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev, 75 uint32_t *chan_freq_list, uint32_t num_chan) 76 { 77 scm_filter_valid_channel(pdev, chan_freq_list, num_chan); 78 } 79 ucfg_scan_get_entry_frame_len(struct scan_cache_entry * scan_entry)80 uint32_t ucfg_scan_get_entry_frame_len(struct scan_cache_entry *scan_entry) 81 { 82 return util_scan_entry_frame_len(scan_entry); 83 } 84 ucfg_scan_init(void)85 QDF_STATUS ucfg_scan_init(void) 86 { 87 QDF_STATUS status; 88 89 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 90 wlan_scan_psoc_created_notification, NULL); 91 if (QDF_IS_STATUS_ERROR(status)) { 92 scm_err("Failed to register psoc create handler"); 93 goto fail_create_psoc; 94 } 95 96 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN, 97 wlan_scan_psoc_destroyed_notification, NULL); 98 if (QDF_IS_STATUS_ERROR(status)) { 99 scm_err("Failed to create psoc delete handler"); 100 goto fail_psoc_destroy; 101 } 102 scm_debug("scan psoc create and delete handler registered with objmgr"); 103 104 status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 105 wlan_scan_vdev_created_notification, NULL); 106 if (QDF_IS_STATUS_ERROR(status)) { 107 scm_err("Failed to register vdev create handler"); 108 goto fail_pdev_create; 109 } 110 111 status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN, 112 wlan_scan_vdev_destroyed_notification, NULL); 113 if (QDF_IS_STATUS_SUCCESS(status)) { 114 scm_debug("scan vdev create and delete handler registered with objmgr"); 115 return QDF_STATUS_SUCCESS; 116 } 117 118 scm_err("Failed to destroy vdev delete handler"); 119 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 120 wlan_scan_vdev_created_notification, NULL); 121 fail_pdev_create: 122 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN, 123 wlan_scan_psoc_destroyed_notification, NULL); 124 fail_psoc_destroy: 125 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 126 wlan_scan_psoc_created_notification, NULL); 127 fail_create_psoc: 128 return status; 129 } 130 ucfg_scan_deinit(void)131 QDF_STATUS ucfg_scan_deinit(void) 132 { 133 QDF_STATUS status; 134 135 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN, 136 wlan_scan_psoc_created_notification, NULL); 137 if (status != QDF_STATUS_SUCCESS) 138 scm_err("Failed to unregister psoc create handler"); 139 140 status = wlan_objmgr_unregister_psoc_destroy_handler( 141 WLAN_UMAC_COMP_SCAN, 142 wlan_scan_psoc_destroyed_notification, NULL); 143 if (status != QDF_STATUS_SUCCESS) 144 scm_err("Failed to unregister psoc delete handler"); 145 146 status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN, 147 wlan_scan_vdev_created_notification, NULL); 148 if (status != QDF_STATUS_SUCCESS) 149 scm_err("Failed to unregister vdev create handler"); 150 151 status = wlan_objmgr_unregister_vdev_destroy_handler( 152 WLAN_UMAC_COMP_SCAN, 153 wlan_scan_vdev_destroyed_notification, NULL); 154 if (status != QDF_STATUS_SUCCESS) 155 scm_err("Failed to unregister vdev delete handler"); 156 157 return status; 158 } 159 160 #ifdef FEATURE_WLAN_SCAN_PNO 161 bool ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc * psoc)162 ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc *psoc) 163 { 164 return wlan_psoc_nif_fw_ext_cap_get(psoc, 165 WLAN_SOC_PNO_SCAN_CONFIG_PER_CHANNEL); 166 } 167 ucfg_scan_pno_start(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req)168 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev, 169 struct pno_scan_req_params *req) 170 { 171 struct scan_vdev_obj *scan_vdev_obj; 172 QDF_STATUS status; 173 174 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 175 if (!scan_vdev_obj) { 176 scm_err("null scan_vdev_obj"); 177 return QDF_STATUS_E_INVAL; 178 } 179 if (scan_vdev_obj->pno_in_progress) { 180 scm_err("pno already in progress"); 181 return QDF_STATUS_E_ALREADY; 182 } 183 184 status = tgt_scan_pno_start(vdev, req); 185 if (QDF_IS_STATUS_ERROR(status)) 186 scm_err("pno start failed"); 187 else 188 scan_vdev_obj->pno_in_progress = true; 189 190 return status; 191 } 192 ucfg_scan_add_flags_to_pno_chan_list(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req,uint8_t * num_chan,uint32_t short_ssid,int list_idx)193 void ucfg_scan_add_flags_to_pno_chan_list(struct wlan_objmgr_vdev *vdev, 194 struct pno_scan_req_params *req, 195 uint8_t *num_chan, 196 uint32_t short_ssid, 197 int list_idx) 198 { 199 struct chan_list *pno_chan_list = 200 &req->networks_list[list_idx].pno_chan_list; 201 202 /* Add RNR flags to channels based on scan_mode_6g ini */ 203 scm_add_channel_flags(vdev, pno_chan_list, num_chan, 204 req->scan_policy_colocated_6ghz, true); 205 /* Filter RNR flags in pno channel list based on short ssid entry in 206 * RNR db cache. 207 */ 208 scm_filter_rnr_flag_pno(vdev, short_ssid, 209 &req->networks_list[0].pno_chan_list); 210 } 211 ucfg_scan_pno_stop(struct wlan_objmgr_vdev * vdev)212 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev) 213 { 214 struct scan_vdev_obj *scan_vdev_obj; 215 QDF_STATUS status; 216 217 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 218 if (!scan_vdev_obj) { 219 scm_err("null scan_vdev_obj"); 220 return QDF_STATUS_E_INVAL; 221 } 222 if (!scan_vdev_obj->pno_in_progress) { 223 scm_debug("pno already stopped"); 224 return QDF_STATUS_SUCCESS; 225 } 226 227 status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev)); 228 if (QDF_IS_STATUS_ERROR(status)) 229 scm_err("pno stop failed"); 230 else 231 scan_vdev_obj->pno_in_progress = false; 232 233 return status; 234 } 235 ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev * vdev)236 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev) 237 { 238 struct scan_vdev_obj *scan_vdev_obj; 239 240 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 241 if (!scan_vdev_obj) { 242 scm_err("null scan_vdev_obj"); 243 return false; 244 } 245 246 return scan_vdev_obj->pno_in_progress; 247 } 248 ucfg_scan_get_pno_match(struct wlan_objmgr_vdev * vdev)249 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev) 250 { 251 struct scan_vdev_obj *scan_vdev_obj; 252 253 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 254 if (!scan_vdev_obj) { 255 scm_err("null scan_vdev_obj"); 256 return false; 257 } 258 259 return scan_vdev_obj->pno_match_evt_received; 260 } 261 262 static QDF_STATUS wlan_pno_global_init(struct wlan_objmgr_psoc * psoc,struct wlan_scan_obj * scan_obj)263 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc, 264 struct wlan_scan_obj *scan_obj) 265 { 266 struct nlo_mawc_params *mawc_cfg; 267 struct pno_def_config *pno_def; 268 269 pno_def = &scan_obj->pno_cfg; 270 qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl"); 271 qdf_runtime_lock_init(&pno_def->pno_runtime_pm_lock); 272 mawc_cfg = &pno_def->mawc_params; 273 pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION); 274 pno_def->top_k_num_of_channels = 275 cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS); 276 pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD); 277 pno_def->channel_prediction_full_scan = 278 cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER); 279 pno_def->adaptive_dwell_mode = 280 cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE); 281 pno_def->dfs_chnl_scan_enabled = 282 cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN); 283 pno_def->scan_support_enabled = 284 cfg_get(psoc, CFG_PNO_SCAN_SUPPORT); 285 pno_def->scan_timer_repeat_value = 286 cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 287 pno_def->slow_scan_multiplier = 288 cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER); 289 pno_def->scan_backoff_multiplier = 290 cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER); 291 pno_def->max_sched_scan_plan_interval = 292 cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); 293 pno_def->max_sched_scan_plan_iterations = 294 cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 295 pno_def->user_config_sched_scan_plan = 296 cfg_get(psoc, CFG_USER_CONFIG_SCHED_SCAN_PLAN); 297 298 mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED); 299 mawc_cfg->exp_backoff_ratio = 300 cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO); 301 mawc_cfg->init_scan_interval = 302 cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL); 303 mawc_cfg->max_scan_interval = 304 cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL); 305 306 return QDF_STATUS_SUCCESS; 307 } 308 309 static QDF_STATUS wlan_pno_global_deinit(struct wlan_scan_obj * scan_obj)310 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj) 311 { 312 qdf_runtime_lock_deinit(&scan_obj->pno_cfg.pno_runtime_pm_lock); 313 qdf_wake_lock_destroy(&scan_obj->pno_cfg.pno_wake_lock); 314 315 return QDF_STATUS_SUCCESS; 316 } 317 318 QDF_STATUS ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req)319 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev, 320 struct pno_scan_req_params *req) 321 { 322 struct scan_default_params *scan_def; 323 struct wlan_scan_obj *scan; 324 struct pno_def_config *pno_def; 325 326 if (!vdev || !req) { 327 scm_err("vdev: 0x%pK, req: 0x%pK", 328 vdev, req); 329 return QDF_STATUS_E_INVAL; 330 } 331 332 scan = wlan_vdev_get_scan_obj(vdev); 333 if (!scan) { 334 scm_err("scan is NULL"); 335 return QDF_STATUS_E_INVAL; 336 } 337 scan_def = wlan_vdev_get_def_scan_params(vdev); 338 if (!scan_def) { 339 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 340 return QDF_STATUS_E_NULL_VALUE; 341 } 342 343 pno_def = &scan->pno_cfg; 344 req->active_dwell_time = scan_def->active_dwell; 345 req->passive_dwell_time = scan_def->passive_dwell; 346 req->scan_random.randomize = scan_def->enable_mac_spoofing; 347 348 /* 349 * Update active and passive dwell time depending 350 * upon the present active concurrency mode 351 */ 352 wlan_scan_update_pno_dwell_time(vdev, req, scan_def); 353 req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode; 354 req->pno_channel_prediction = pno_def->channel_prediction; 355 req->top_k_num_of_channels = pno_def->top_k_num_of_channels; 356 req->stationary_thresh = pno_def->stationary_thresh; 357 req->channel_prediction_full_scan = 358 pno_def->channel_prediction_full_scan; 359 req->mawc_params.vdev_id = wlan_vdev_get_id(vdev); 360 qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params, 361 sizeof(req->mawc_params)); 362 363 return QDF_STATUS_SUCCESS; 364 } 365 366 QDF_STATUS ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc * psoc,scan_event_handler event_cb,void * arg)367 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc, 368 scan_event_handler event_cb, void *arg) 369 { 370 struct wlan_scan_obj *scan; 371 372 if (!psoc) { 373 scm_err("null psoc"); 374 return QDF_STATUS_E_INVAL; 375 } 376 377 scan = wlan_psoc_get_scan_obj(psoc); 378 if (!scan) { 379 scm_err("scan object null"); 380 return QDF_STATUS_E_INVAL; 381 } 382 383 qdf_spin_lock_bh(&scan->lock); 384 scan->pno_cfg.pno_cb.func = event_cb; 385 scan->pno_cfg.pno_cb.arg = arg; 386 qdf_spin_unlock_bh(&scan->lock); 387 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 388 389 return QDF_STATUS_SUCCESS; 390 } 391 392 #else 393 394 static inline QDF_STATUS wlan_pno_global_init(struct wlan_objmgr_psoc * psoc,struct wlan_scan_obj * scan_obj)395 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc, 396 struct wlan_scan_obj *scan_obj) 397 { 398 return QDF_STATUS_SUCCESS; 399 } 400 401 static inline QDF_STATUS wlan_pno_global_deinit(struct wlan_scan_obj * scan_obj)402 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj) 403 { 404 return QDF_STATUS_SUCCESS; 405 } 406 407 #endif 408 409 QDF_STATUS ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev * pdev,struct chan_list * chan_list)410 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev, 411 struct chan_list *chan_list) 412 { 413 uint8_t pdev_id; 414 struct wlan_scan_obj *scan_obj; 415 416 if (!pdev || !chan_list) { 417 scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list); 418 return QDF_STATUS_E_NULL_VALUE; 419 } 420 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 421 scan_obj = wlan_pdev_get_scan_obj(pdev); 422 423 qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list, 424 chan_list, sizeof(*chan_list)); 425 426 return QDF_STATUS_SUCCESS; 427 } 428 429 QDF_STATUS ucfg_scm_scan_free_scan_request_mem(struct scan_start_request * req)430 ucfg_scm_scan_free_scan_request_mem(struct scan_start_request *req) 431 { 432 return scm_scan_free_scan_request_mem(req); 433 } 434 ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc * psoc,enum scan_disable_reason reason)435 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, 436 enum scan_disable_reason reason) 437 { 438 return wlan_scan_psoc_set_enable(psoc, reason); 439 } 440 ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc * psoc,enum scan_disable_reason reason)441 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, 442 enum scan_disable_reason reason) 443 { 444 return wlan_scan_psoc_set_disable(psoc, reason); 445 } 446 447 ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev * vdev,enum scan_disable_reason reason)448 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, 449 enum scan_disable_reason reason) 450 { 451 struct scan_vdev_obj *scan_vdev_obj; 452 453 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 454 if (!scan_vdev_obj) { 455 scm_err("null scan_vdev_obj"); 456 return QDF_STATUS_E_NULL_VALUE; 457 } 458 459 scan_vdev_obj->scan_disabled &= ~reason; 460 461 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 462 463 return QDF_STATUS_SUCCESS; 464 } 465 ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev * vdev,enum scan_disable_reason reason)466 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, 467 enum scan_disable_reason reason) 468 { 469 struct scan_vdev_obj *scan_vdev_obj; 470 471 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 472 if (!scan_vdev_obj) { 473 scm_err("null scan_vdev_obj"); 474 return QDF_STATUS_E_NULL_VALUE; 475 } 476 477 scan_vdev_obj->scan_disabled |= reason; 478 479 scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); 480 481 return QDF_STATUS_SUCCESS; 482 } 483 484 ucfg_scan_set_miracast(struct wlan_objmgr_psoc * psoc,bool enable)485 QDF_STATUS ucfg_scan_set_miracast( 486 struct wlan_objmgr_psoc *psoc, bool enable) 487 { 488 struct wlan_scan_obj *scan_obj; 489 490 scan_obj = wlan_psoc_get_scan_obj(psoc); 491 if (!scan_obj) { 492 scm_err("Failed to get scan object"); 493 return QDF_STATUS_E_NULL_VALUE; 494 } 495 scan_obj->miracast_enabled = enable; 496 scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled); 497 498 return QDF_STATUS_SUCCESS; 499 } 500 501 QDF_STATUS ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev * pdev,bool enable)502 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable) 503 { 504 uint8_t pdev_id; 505 struct wlan_scan_obj *scan_obj; 506 507 if (!pdev) { 508 scm_warn("null vdev"); 509 return QDF_STATUS_E_NULL_VALUE; 510 } 511 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 512 scan_obj = wlan_pdev_get_scan_obj(pdev); 513 if (!scan_obj) 514 return QDF_STATUS_E_FAILURE; 515 516 scm_debug("set wide_band_scan to %d", enable); 517 scan_obj->pdev_info[pdev_id].wide_band_scan = enable; 518 519 return QDF_STATUS_SUCCESS; 520 } 521 ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev * pdev)522 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev) 523 { 524 uint8_t pdev_id; 525 struct wlan_scan_obj *scan_obj; 526 527 if (!pdev) { 528 scm_warn("null vdev"); 529 return QDF_STATUS_E_NULL_VALUE; 530 } 531 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 532 scan_obj = wlan_pdev_get_scan_obj(pdev); 533 if (!scan_obj) 534 return QDF_STATUS_E_FAILURE; 535 536 return scan_obj->pdev_info[pdev_id].wide_band_scan; 537 } 538 539 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 540 QDF_STATUS ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev * pdev,uint8_t * bssid,struct wlan_ssid * ssid)541 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev, 542 uint8_t *bssid, struct wlan_ssid *ssid) 543 { 544 uint8_t pdev_id; 545 struct wlan_scan_obj *scan_obj; 546 547 if (!pdev) { 548 scm_warn("null vdev"); 549 return QDF_STATUS_E_NULL_VALUE; 550 } 551 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 552 scan_obj = wlan_pdev_get_scan_obj(pdev); 553 if (!scan_obj) 554 return QDF_STATUS_E_FAILURE; 555 556 scm_debug("Configure bsssid:" QDF_MAC_ADDR_FMT " ssid:" QDF_SSID_FMT, 557 QDF_MAC_ADDR_REF(bssid), 558 QDF_SSID_REF(ssid->length, ssid->ssid)); 559 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid, 560 bssid, QDF_MAC_ADDR_SIZE); 561 scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length; 562 qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid, 563 ssid->ssid, 564 scan_obj->pdev_info[pdev_id].conf_ssid.length); 565 566 return QDF_STATUS_SUCCESS; 567 } 568 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 569 570 QDF_STATUS ucfg_scan_cancel_sync(struct scan_cancel_request * req)571 ucfg_scan_cancel_sync(struct scan_cancel_request *req) 572 { 573 QDF_STATUS status; 574 bool cancel_vdev = false, cancel_pdev = false; 575 struct wlan_objmgr_vdev *vdev; 576 struct wlan_objmgr_pdev *pdev; 577 uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION; 578 579 if (!req || !req->vdev) { 580 scm_err("req or vdev within req is NULL"); 581 if (req) 582 qdf_mem_free(req); 583 return QDF_STATUS_E_NULL_VALUE; 584 } 585 586 if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL) 587 cancel_pdev = true; 588 else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL || 589 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) 590 cancel_vdev = true; 591 592 vdev = req->vdev; 593 status = wlan_scan_cancel(req); 594 if (QDF_IS_STATUS_ERROR(status)) 595 return status; 596 597 if (cancel_pdev) { 598 pdev = wlan_vdev_get_pdev(vdev); 599 while ((wlan_get_pdev_status(pdev) != 600 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 601 scm_debug("wait for all pdev scan to get complete"); 602 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME); 603 max_wait_iterations--; 604 } 605 } else if (cancel_vdev) { 606 while ((wlan_get_vdev_status(vdev) != 607 SCAN_NOT_IN_PROGRESS) && max_wait_iterations) { 608 scm_debug("wait for all vdev scan to get complete"); 609 qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME); 610 max_wait_iterations--; 611 } 612 } 613 614 if (!max_wait_iterations) { 615 scm_err("Failed to wait for scans to get complete"); 616 return QDF_STATUS_E_TIMEOUT; 617 } 618 619 return status; 620 } 621 622 uint8_t* ucfg_get_scan_requester_name(struct wlan_objmgr_psoc * psoc,wlan_scan_requester requester)623 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc, 624 wlan_scan_requester requester) 625 { 626 int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 627 struct wlan_scan_obj *scan; 628 struct scan_requester_info *requesters; 629 630 if (!psoc) { 631 scm_err("null psoc"); 632 return "null"; 633 } 634 scan = wlan_psoc_get_scan_obj(psoc); 635 if (!scan) 636 return "null"; 637 638 requesters = scan->requesters; 639 640 if ((idx < WLAN_MAX_REQUESTORS) && 641 (requesters[idx].requester == requester)) { 642 return requesters[idx].module; 643 } 644 645 return (uint8_t *)"unknown"; 646 } 647 648 static QDF_STATUS scm_add_scan_event_handler(struct pdev_scan_ev_handler * pdev_ev_handler,scan_event_handler event_cb,void * arg)649 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 650 scan_event_handler event_cb, void *arg) 651 { 652 struct cb_handler *cb_handler; 653 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 654 655 /* Assign next available slot to this registration request */ 656 cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]); 657 cb_handler->func = event_cb; 658 cb_handler->arg = arg; 659 pdev_ev_handler->handler_cnt++; 660 661 return QDF_STATUS_SUCCESS; 662 } 663 664 QDF_STATUS ucfg_scan_register_event_handler(struct wlan_objmgr_pdev * pdev,scan_event_handler event_cb,void * arg)665 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev, 666 scan_event_handler event_cb, void *arg) 667 { 668 uint32_t idx; 669 struct wlan_scan_obj *scan; 670 struct pdev_scan_ev_handler *pdev_ev_handler; 671 struct cb_handler *cb_handler; 672 673 /* scan event handler call back can't be NULL */ 674 if (!pdev || !event_cb) { 675 scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb); 676 return QDF_STATUS_E_NULL_VALUE; 677 } 678 679 scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg); 680 681 scan = wlan_pdev_get_scan_obj(pdev); 682 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 683 if (!pdev_ev_handler) { 684 scm_err("null pdev_ev_handler"); 685 return QDF_STATUS_E_NULL_VALUE; 686 } 687 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 688 689 qdf_spin_lock_bh(&scan->lock); 690 /* Ensure its not a duplicate registration request */ 691 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 692 idx++, cb_handler++) { 693 if ((cb_handler->func == event_cb) && 694 (cb_handler->arg == arg)) { 695 qdf_spin_unlock_bh(&scan->lock); 696 scm_debug("func: %pK, arg: %pK already exists", 697 event_cb, arg); 698 return QDF_STATUS_SUCCESS; 699 } 700 } 701 702 QDF_ASSERT(pdev_ev_handler->handler_cnt < 703 MAX_SCAN_EVENT_HANDLERS_PER_PDEV); 704 705 if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) { 706 qdf_spin_unlock_bh(&scan->lock); 707 scm_warn("No more registrations possible"); 708 return QDF_STATUS_E_NOMEM; 709 } 710 711 scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg); 712 qdf_spin_unlock_bh(&scan->lock); 713 714 scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg); 715 716 return QDF_STATUS_SUCCESS; 717 } 718 719 static QDF_STATUS wlan_scan_global_init(struct wlan_objmgr_psoc * psoc,struct wlan_scan_obj * scan_obj)720 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, 721 struct wlan_scan_obj *scan_obj) 722 { 723 scan_obj->scan_disabled = 0; 724 scan_obj->drop_bcn_on_chan_mismatch = 725 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH); 726 scan_obj->drop_bcn_on_invalid_freq = 727 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ); 728 scan_obj->disable_timeout = false; 729 scan_obj->obss_scan_offload = false; 730 scan_obj->scan_def.active_dwell = 731 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME); 732 /* the ini is disallow DFS channel scan if ini is 1, so negate that */ 733 scan_obj->scan_def.allow_dfs_chan_in_first_scan = 734 !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN); 735 scan_obj->scan_def.allow_dfs_chan_in_scan = 736 cfg_get(psoc, CFG_ENABLE_DFS_SCAN); 737 scan_obj->scan_def.skip_dfs_chan_in_p2p_search = 738 cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH); 739 scan_obj->scan_def.use_wake_lock_in_user_scan = 740 cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN); 741 scan_obj->scan_def.active_dwell_2g = 742 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME); 743 scan_obj->scan_def.min_dwell_time_6g = 744 cfg_get(psoc, CFG_MIN_6G_CHANNEL_TIME); 745 scan_obj->scan_def.active_dwell_6g = 746 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME); 747 scan_obj->scan_def.passive_dwell_6g = 748 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME); 749 scan_obj->scan_def.active_dwell_time_6g_conc = 750 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME_CONC); 751 scan_obj->scan_def.passive_dwell_time_6g_conc = 752 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME_CONC); 753 scan_obj->scan_def.passive_dwell = 754 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME); 755 scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME; 756 scan_obj->scan_def.sta_miracast_mcc_rest_time = 757 SCAN_STA_MIRACAST_MCC_REST_TIME; 758 scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME; 759 scan_obj->scan_def.conc_active_dwell = 760 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC); 761 scan_obj->scan_def.conc_passive_dwell = 762 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC); 763 scan_obj->scan_def.conc_max_rest_time = 764 cfg_get(psoc, CFG_MAX_REST_TIME_CONC); 765 scan_obj->scan_def.conc_min_rest_time = 766 cfg_get(psoc, CFG_MIN_REST_TIME_CONC); 767 scan_obj->scan_def.conc_idle_time = 768 cfg_get(psoc, CFG_IDLE_TIME_CONC); 769 scan_obj->scan_def.conc_chlist_trim = 770 cfg_get(psoc, CFG_CHAN_LIST_TRIM_CONC); 771 scan_obj->scan_def.repeat_probe_time = 772 cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME); 773 scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME; 774 scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY; 775 scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION; 776 scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME; 777 scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES); 778 scan_obj->scan_def.scan_cache_aging_time = 779 (cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000); 780 scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV; 781 scan_obj->scan_def.scan_priority = SCAN_PRIORITY; 782 scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT; 783 scan_obj->scan_def.adaptive_dwell_time_mode = 784 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE); 785 scan_obj->scan_def.adaptive_dwell_time_mode_nc = 786 cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC); 787 scan_obj->scan_def.honour_nl_scan_policy_flags = 788 cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS); 789 scan_obj->scan_def.enable_mac_spoofing = 790 cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING); 791 scan_obj->scan_def.extscan_adaptive_dwell_mode = 792 cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 793 794 /* init burst durations */ 795 scan_obj->scan_def.sta_scan_burst_duration = 796 cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION); 797 scan_obj->scan_def.p2p_scan_burst_duration = 798 cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION); 799 scan_obj->scan_def.go_scan_burst_duration = 800 cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION); 801 scan_obj->scan_def.ap_scan_burst_duration = 802 cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION); 803 /* scan control flags */ 804 scan_obj->scan_def.scan_f_passive = true; 805 scan_obj->scan_def.scan_f_ofdm_rates = true; 806 scan_obj->scan_def.scan_f_2ghz = true; 807 scan_obj->scan_def.scan_f_5ghz = true; 808 scan_obj->scan_def.scan_f_chan_stat_evnt = 809 cfg_get(psoc, CFG_ENABLE_SNR_MONITORING); 810 /* scan event flags */ 811 scan_obj->scan_def.scan_ev_started = true; 812 scan_obj->scan_def.scan_ev_completed = true; 813 scan_obj->scan_def.scan_ev_bss_chan = true; 814 scan_obj->scan_def.scan_ev_foreign_chan = true; 815 scan_obj->scan_def.scan_ev_foreign_chn_exit = true; 816 scan_obj->scan_def.scan_ev_dequeued = true; 817 scan_obj->scan_def.scan_ev_preempted = true; 818 scan_obj->scan_def.scan_ev_start_failed = true; 819 scan_obj->scan_def.scan_ev_restarted = true; 820 scan_obj->scan_def.enable_connected_scan = 821 cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN); 822 scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE); 823 scan_obj->scan_def.duty_cycle_6ghz = 824 cfg_get(psoc, CFG_6GHZ_SCAN_MODE_DUTY_CYCLE); 825 scan_obj->allow_bss_with_incomplete_ie = 826 cfg_get(psoc, CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE); 827 828 scan_obj->scan_def.skip_6g_and_indoor_freq = 829 cfg_get(psoc, CFG_SKIP_6GHZ_AND_INDOOR_FREQ_SCAN); 830 scan_obj->scan_def.last_scan_ageout_time = 831 cfg_get(psoc, CFG_LAST_SCAN_AGEOUT_TIME); 832 scan_obj->aux_mac_support = false; 833 834 /* init scan id seed */ 835 qdf_atomic_init(&scan_obj->scan_ids); 836 837 /* init extscan */ 838 wlan_extscan_global_init(psoc, scan_obj); 839 840 return wlan_pno_global_init(psoc, scan_obj); 841 } 842 843 static void wlan_scan_global_deinit(struct wlan_objmgr_psoc * psoc)844 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc) 845 { 846 struct wlan_scan_obj *scan_obj; 847 848 scan_obj = wlan_psoc_get_scan_obj(psoc); 849 wlan_pno_global_deinit(scan_obj); 850 wlan_extscan_global_deinit(); 851 } 852 853 static QDF_STATUS scm_remove_scan_event_handler(struct pdev_scan_ev_handler * pdev_ev_handler,struct cb_handler * entry)854 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler, 855 struct cb_handler *entry) 856 { 857 struct cb_handler *last_entry; 858 uint32_t handler_cnt = pdev_ev_handler->handler_cnt; 859 860 /* Replace event handler being deleted 861 * with the last one in the list. 862 */ 863 last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]); 864 entry->func = last_entry->func; 865 entry->arg = last_entry->arg; 866 867 /* Clear our last entry */ 868 last_entry->func = NULL; 869 last_entry->arg = NULL; 870 pdev_ev_handler->handler_cnt--; 871 872 return QDF_STATUS_SUCCESS; 873 } 874 875 void ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev * pdev,scan_event_handler event_cb,void * arg)876 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev, 877 scan_event_handler event_cb, void *arg) 878 { 879 uint8_t found = false; 880 uint32_t idx; 881 uint32_t handler_cnt; 882 struct wlan_scan_obj *scan; 883 struct cb_handler *cb_handler; 884 struct pdev_scan_ev_handler *pdev_ev_handler; 885 886 scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb, 887 arg); 888 if (!pdev) { 889 scm_err("null pdev"); 890 return; 891 } 892 scan = wlan_pdev_get_scan_obj(pdev); 893 if (!scan) 894 return; 895 896 pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev); 897 if (!pdev_ev_handler) 898 return; 899 900 cb_handler = &(pdev_ev_handler->cb_handlers[0]); 901 902 qdf_spin_lock_bh(&scan->lock); 903 handler_cnt = pdev_ev_handler->handler_cnt; 904 if (!handler_cnt) { 905 qdf_spin_unlock_bh(&scan->lock); 906 scm_info("No event handlers registered"); 907 return; 908 } 909 910 for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; 911 idx++, cb_handler++) { 912 if ((cb_handler->func == event_cb) && 913 (cb_handler->arg == arg)) { 914 /* Event handler found, remove it 915 * from event handler list. 916 */ 917 found = true; 918 scm_remove_scan_event_handler(pdev_ev_handler, 919 cb_handler); 920 handler_cnt--; 921 break; 922 } 923 } 924 qdf_spin_unlock_bh(&scan->lock); 925 926 scm_debug("event handler %s, remaining handlers: %d", 927 (found ? "removed" : "not found"), handler_cnt); 928 } 929 930 QDF_STATUS ucfg_scan_init_ssid_params(struct scan_start_request * req,uint32_t num_ssid,struct wlan_ssid * ssid_list)931 ucfg_scan_init_ssid_params(struct scan_start_request *req, 932 uint32_t num_ssid, struct wlan_ssid *ssid_list) 933 { 934 uint32_t max_ssid = sizeof(req->scan_req.ssid) / 935 sizeof(req->scan_req.ssid[0]); 936 937 if (!req) { 938 scm_err("null request"); 939 return QDF_STATUS_E_NULL_VALUE; 940 } 941 if (!num_ssid) { 942 /* empty channel list provided */ 943 req->scan_req.num_ssids = 0; 944 qdf_mem_zero(&req->scan_req.ssid[0], 945 sizeof(req->scan_req.ssid)); 946 return QDF_STATUS_SUCCESS; 947 } 948 if (!ssid_list) { 949 scm_err("null ssid_list while num_ssid: %d", num_ssid); 950 return QDF_STATUS_E_NULL_VALUE; 951 } 952 if (num_ssid > max_ssid) { 953 /* got a big list. alert and continue */ 954 scm_warn("overflow: received %d, max supported : %d", 955 num_ssid, max_ssid); 956 return QDF_STATUS_E_E2BIG; 957 } 958 959 if (max_ssid > num_ssid) 960 max_ssid = num_ssid; 961 962 req->scan_req.num_ssids = max_ssid; 963 qdf_mem_copy(&req->scan_req.ssid[0], ssid_list, 964 (req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0]))); 965 966 return QDF_STATUS_SUCCESS; 967 } 968 969 QDF_STATUS ucfg_scan_init_bssid_params(struct scan_start_request * req,uint32_t num_bssid,struct qdf_mac_addr * bssid_list)970 ucfg_scan_init_bssid_params(struct scan_start_request *req, 971 uint32_t num_bssid, struct qdf_mac_addr *bssid_list) 972 { 973 uint32_t max_bssid = sizeof(req->scan_req.bssid_list) / 974 sizeof(req->scan_req.bssid_list[0]); 975 976 if (!req) { 977 scm_err("null request"); 978 return QDF_STATUS_E_NULL_VALUE; 979 } 980 if (!num_bssid) { 981 /* empty channel list provided */ 982 req->scan_req.num_bssid = 0; 983 qdf_mem_zero(&req->scan_req.bssid_list[0], 984 sizeof(req->scan_req.bssid_list)); 985 return QDF_STATUS_SUCCESS; 986 } 987 if (!bssid_list) { 988 scm_err("null bssid_list while num_bssid: %d", num_bssid); 989 return QDF_STATUS_E_NULL_VALUE; 990 } 991 if (num_bssid > max_bssid) { 992 /* got a big list. alert and continue */ 993 scm_warn("overflow: received %d, max supported : %d", 994 num_bssid, max_bssid); 995 return QDF_STATUS_E_E2BIG; 996 } 997 998 if (max_bssid > num_bssid) 999 max_bssid = num_bssid; 1000 1001 req->scan_req.num_bssid = max_bssid; 1002 qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list, 1003 req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0])); 1004 1005 return QDF_STATUS_SUCCESS; 1006 } 1007 1008 /** 1009 * is_chan_enabled_for_scan() - helper API to check if a frequency 1010 * is allowed to scan. 1011 * @pdev: pointer to pdev 1012 * @reg_chan: regulatory_channel object 1013 * @low_2g: lower 2.4 GHz frequency threshold 1014 * @high_2g: upper 2.4 GHz frequency threshold 1015 * @low_5g: lower 5 GHz frequency threshold 1016 * @high_5g: upper 5 GHz frequency threshold 1017 * 1018 * Return: true if scan is allowed. false otherwise. 1019 */ 1020 static bool is_chan_enabled_for_scan(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * reg_chan,qdf_freq_t low_2g,qdf_freq_t high_2g,qdf_freq_t low_5g,qdf_freq_t high_5g)1021 is_chan_enabled_for_scan(struct wlan_objmgr_pdev *pdev, 1022 struct regulatory_channel *reg_chan, 1023 qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g, 1024 qdf_freq_t high_5g) 1025 { 1026 if (wlan_reg_is_disable_for_pwrmode(pdev, 1027 reg_chan->center_freq, 1028 REG_BEST_PWR_MODE)) 1029 return false; 1030 1031 if (reg_chan->nol_chan) 1032 return false; 1033 1034 /* 2 GHz channel */ 1035 if ((util_scan_scm_freq_to_band(reg_chan->center_freq) == 1036 WLAN_BAND_2_4_GHZ) && 1037 ((reg_chan->center_freq < low_2g) || 1038 (reg_chan->center_freq > high_2g))) 1039 return false; 1040 else if ((util_scan_scm_freq_to_band(reg_chan->center_freq) == 1041 WLAN_BAND_5_GHZ) && 1042 ((reg_chan->center_freq < low_5g) || 1043 (reg_chan->center_freq > high_5g))) 1044 return false; 1045 1046 return true; 1047 } 1048 1049 QDF_STATUS ucfg_scan_init_chanlist_params(struct scan_start_request * req,uint32_t num_chans,uint32_t * chan_list,uint32_t * phymode)1050 ucfg_scan_init_chanlist_params(struct scan_start_request *req, 1051 uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode) 1052 { 1053 uint32_t idx; 1054 QDF_STATUS status; 1055 struct regulatory_channel *reg_chan_list = NULL; 1056 qdf_freq_t low_2g, high_2g, low_5g, high_5g; 1057 struct wlan_objmgr_pdev *pdev = NULL; 1058 uint32_t *scan_freqs = NULL; 1059 uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / 1060 sizeof(req->scan_req.chan_list.chan[0]); 1061 if (!req) { 1062 scm_err("null request"); 1063 return QDF_STATUS_E_NULL_VALUE; 1064 } 1065 1066 if (req->vdev) 1067 pdev = wlan_vdev_get_pdev(req->vdev); 1068 /* 1069 * If 0 channels are provided for scan and 1070 * wide band scan is enabled, scan all 20 mhz 1071 * available channels. This is required as FW 1072 * scans all channel/phy mode combinations 1073 * provided in scan channel list if 0 chans are 1074 * provided in scan request causing scan to take 1075 * too much time to complete. 1076 */ 1077 if (pdev && !num_chans) { 1078 reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS * 1079 sizeof(struct regulatory_channel)); 1080 if (!reg_chan_list) { 1081 status = QDF_STATUS_E_NOMEM; 1082 goto end; 1083 } 1084 scan_freqs = 1085 qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans); 1086 if (!scan_freqs) { 1087 status = QDF_STATUS_E_NOMEM; 1088 goto end; 1089 } 1090 status = wlan_reg_get_current_chan_list(pdev, reg_chan_list); 1091 if (QDF_IS_STATUS_ERROR(status)) 1092 goto end; 1093 1094 status = wlan_reg_get_freq_range(pdev, &low_2g, 1095 &high_2g, &low_5g, &high_5g); 1096 if (QDF_IS_STATUS_ERROR(status)) 1097 goto end; 1098 1099 for (idx = 0, num_chans = 0; 1100 (idx < NUM_CHANNELS && num_chans < max_chans); idx++) 1101 if ((is_chan_enabled_for_scan(pdev, 1102 ®_chan_list[idx], 1103 low_2g, high_2g, 1104 low_5g, high_5g)) && 1105 ((req->scan_req.scan_f_2ghz && 1106 WLAN_REG_IS_24GHZ_CH_FREQ( 1107 reg_chan_list[idx].center_freq)) || 1108 (req->scan_req.scan_f_5ghz && 1109 (WLAN_REG_IS_5GHZ_CH_FREQ( 1110 reg_chan_list[idx].center_freq) || 1111 WLAN_REG_IS_49GHZ_FREQ( 1112 reg_chan_list[idx].center_freq) || 1113 WLAN_REG_IS_6GHZ_CHAN_FREQ( 1114 reg_chan_list[idx].center_freq))))) 1115 scan_freqs[num_chans++] = 1116 reg_chan_list[idx].center_freq; 1117 1118 chan_list = scan_freqs; 1119 } 1120 1121 if (!num_chans) { 1122 /* empty channel list provided */ 1123 qdf_mem_zero(&req->scan_req.chan_list, 1124 sizeof(req->scan_req.chan_list)); 1125 req->scan_req.chan_list.num_chan = 0; 1126 status = QDF_STATUS_SUCCESS; 1127 goto end; 1128 } 1129 if (!chan_list) { 1130 scm_info("null chan_list while num_chans: %d", num_chans); 1131 status = QDF_STATUS_E_NULL_VALUE; 1132 goto end; 1133 } 1134 1135 if (num_chans > max_chans) { 1136 /* got a big list. alert and fail */ 1137 scm_warn("overflow: received %d, max supported : %d", 1138 num_chans, max_chans); 1139 status = QDF_STATUS_E_E2BIG; 1140 goto end; 1141 } 1142 1143 req->scan_req.chan_list.num_chan = num_chans; 1144 for (idx = 0; idx < num_chans; idx++) { 1145 req->scan_req.chan_list.chan[idx].freq = 1146 (chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ? 1147 chan_list[idx] : 1148 wlan_reg_legacy_chan_to_freq(pdev, chan_list[idx]); 1149 if (phymode) 1150 req->scan_req.chan_list.chan[idx].phymode = 1151 phymode[idx]; 1152 else if (req->scan_req.chan_list.chan[idx].freq <= 1153 WLAN_CHAN_15_FREQ) 1154 req->scan_req.chan_list.chan[idx].phymode = 1155 SCAN_PHY_MODE_11G; 1156 else if (req->scan_req.chan_list.chan[idx].freq <= 1157 WLAN_REG_MAX_5GHZ_CHAN_FREQ) 1158 req->scan_req.chan_list.chan[idx].phymode = 1159 SCAN_PHY_MODE_11A; 1160 else 1161 req->scan_req.chan_list.chan[idx].phymode = 1162 SCAN_PHY_MODE_11AX_HE20; 1163 } 1164 1165 end: 1166 if (scan_freqs) 1167 qdf_mem_free(scan_freqs); 1168 1169 if (reg_chan_list) 1170 qdf_mem_free(reg_chan_list); 1171 1172 return QDF_STATUS_SUCCESS; 1173 } 1174 1175 enum scm_scan_status ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev * vdev)1176 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev) 1177 { 1178 return wlan_get_vdev_status(vdev); 1179 } 1180 1181 enum scm_scan_status ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev * pdev)1182 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev) 1183 { 1184 return wlan_get_pdev_status(pdev); 1185 } 1186 1187 static void scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc * psoc,bool enable)1188 scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc, 1189 bool enable) 1190 { 1191 QDF_STATUS status; 1192 struct mgmt_txrx_mgmt_frame_cb_info cb_info[2]; 1193 1194 cb_info[0].frm_type = MGMT_PROBE_RESP; 1195 cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1196 cb_info[1].frm_type = MGMT_BEACON; 1197 cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback; 1198 1199 if (enable) 1200 status = wlan_mgmt_txrx_register_rx_cb(psoc, 1201 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1202 else 1203 status = wlan_mgmt_txrx_deregister_rx_cb(psoc, 1204 WLAN_UMAC_COMP_SCAN, cb_info, 2); 1205 if (status != QDF_STATUS_SUCCESS) 1206 scm_err("%s the Handle with MGMT TXRX layer has failed", 1207 enable ? "Registering" : "Deregistering"); 1208 } 1209 ucfg_scan_update_user_config(struct wlan_objmgr_psoc * psoc,struct scan_user_cfg * scan_cfg)1210 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc, 1211 struct scan_user_cfg *scan_cfg) 1212 { 1213 struct wlan_scan_obj *scan_obj; 1214 struct scan_default_params *scan_def; 1215 1216 if (!psoc) { 1217 scm_err("null psoc"); 1218 return QDF_STATUS_E_FAILURE; 1219 } 1220 scan_obj = wlan_psoc_get_scan_obj(psoc); 1221 if (!scan_obj) { 1222 scm_err("Failed to get scan object"); 1223 return QDF_STATUS_E_FAILURE; 1224 } 1225 1226 scan_def = &scan_obj->scan_def; 1227 scan_obj->ie_allowlist = scan_cfg->ie_allowlist; 1228 scan_def->sta_miracast_mcc_rest_time = 1229 scan_cfg->sta_miracast_mcc_rest_time; 1230 1231 return QDF_STATUS_SUCCESS; 1232 } 1233 1234 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 1235 static QDF_STATUS scan_cancel_pdev_scan(struct wlan_objmgr_pdev * pdev)1236 scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) 1237 { 1238 struct scan_cancel_request *req; 1239 QDF_STATUS status; 1240 struct wlan_objmgr_vdev *vdev; 1241 1242 req = qdf_mem_malloc_atomic(sizeof(*req)); 1243 if (!req) { 1244 scm_err("Failed to allocate memory"); 1245 return QDF_STATUS_E_NOMEM; 1246 } 1247 1248 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID); 1249 if (!vdev) { 1250 scm_err("Failed to get vdev"); 1251 qdf_mem_free(req); 1252 return QDF_STATUS_E_INVAL; 1253 } 1254 req->vdev = vdev; 1255 req->cancel_req.scan_id = INVAL_SCAN_ID; 1256 req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1257 req->cancel_req.vdev_id = INVAL_VDEV_ID; 1258 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 1259 status = ucfg_scan_cancel_sync(req); 1260 if (QDF_IS_STATUS_ERROR(status)) 1261 scm_err("Cancel scan request failed"); 1262 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1263 1264 return status; 1265 } 1266 1267 static QDF_STATUS ucfg_scan_suspend_handler(struct wlan_objmgr_psoc * psoc,void * arg)1268 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1269 { 1270 struct wlan_objmgr_pdev *pdev = NULL; 1271 QDF_STATUS status = QDF_STATUS_SUCCESS; 1272 int i; 1273 wlan_scan_psoc_set_disable(psoc, REASON_SUSPEND); 1274 1275 /* Check all pdev */ 1276 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 1277 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); 1278 if (!pdev) 1279 continue; 1280 if (wlan_get_pdev_status(pdev) != SCAN_NOT_IN_PROGRESS) 1281 status = scan_cancel_pdev_scan(pdev); 1282 scm_disable_obss_pdev_scan(psoc, pdev); 1283 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 1284 if (QDF_IS_STATUS_ERROR(status)) { 1285 scm_err("failed to cancel scan for pdev_id %d", i); 1286 return status; 1287 } 1288 } 1289 1290 return QDF_STATUS_SUCCESS; 1291 } 1292 1293 static QDF_STATUS ucfg_scan_resume_handler(struct wlan_objmgr_psoc * psoc,void * arg)1294 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) 1295 { 1296 wlan_scan_psoc_set_enable(psoc, REASON_SUSPEND); 1297 return QDF_STATUS_SUCCESS; 1298 } 1299 1300 static inline void scan_register_pmo_handler(void)1301 scan_register_pmo_handler(void) 1302 { 1303 pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN, 1304 ucfg_scan_suspend_handler, NULL); 1305 pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN, 1306 ucfg_scan_resume_handler, NULL); 1307 } 1308 1309 static inline void scan_unregister_pmo_handler(void)1310 scan_unregister_pmo_handler(void) 1311 { 1312 pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN, 1313 ucfg_scan_suspend_handler); 1314 pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN, 1315 ucfg_scan_resume_handler); 1316 } 1317 1318 #else 1319 static inline void scan_register_pmo_handler(void)1320 scan_register_pmo_handler(void) 1321 { 1322 } 1323 1324 static inline void scan_unregister_pmo_handler(void)1325 scan_unregister_pmo_handler(void) 1326 { 1327 } 1328 #endif 1329 1330 QDF_STATUS ucfg_scan_psoc_open(struct wlan_objmgr_psoc * psoc)1331 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) 1332 { 1333 struct wlan_scan_obj *scan_obj; 1334 1335 scm_debug("psoc open: 0x%pK", psoc); 1336 if (!psoc) { 1337 scm_err("null psoc"); 1338 return QDF_STATUS_E_FAILURE; 1339 } 1340 scan_obj = wlan_psoc_get_scan_obj(psoc); 1341 if (!scan_obj) { 1342 scm_err("Failed to get scan object"); 1343 return QDF_STATUS_E_FAILURE; 1344 } 1345 /* Initialize the scan Globals */ 1346 wlan_scan_global_init(psoc, scan_obj); 1347 qdf_spinlock_create(&scan_obj->lock); 1348 scan_register_pmo_handler(); 1349 scm_db_init(psoc); 1350 scm_channel_list_db_init(psoc); 1351 1352 return QDF_STATUS_SUCCESS; 1353 } 1354 1355 QDF_STATUS ucfg_scan_psoc_close(struct wlan_objmgr_psoc * psoc)1356 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) 1357 { 1358 struct wlan_scan_obj *scan_obj; 1359 1360 scm_debug("psoc close: 0x%pK", psoc); 1361 if (!psoc) { 1362 scm_err("null psoc"); 1363 return QDF_STATUS_E_FAILURE; 1364 } 1365 scm_db_deinit(psoc); 1366 scan_obj = wlan_psoc_get_scan_obj(psoc); 1367 if (!scan_obj) { 1368 scm_err("Failed to get scan object"); 1369 return QDF_STATUS_E_FAILURE; 1370 } 1371 scan_unregister_pmo_handler(); 1372 qdf_spinlock_destroy(&scan_obj->lock); 1373 wlan_scan_global_deinit(psoc); 1374 scm_channel_list_db_deinit(psoc); 1375 1376 return QDF_STATUS_SUCCESS; 1377 } 1378 scm_serialization_scan_rules_cb(union wlan_serialization_rules_info * comp_info,uint8_t comp_id)1379 static bool scm_serialization_scan_rules_cb( 1380 union wlan_serialization_rules_info *comp_info, 1381 uint8_t comp_id) 1382 { 1383 switch (comp_id) { 1384 case WLAN_UMAC_COMP_TDLS: 1385 if (comp_info->scan_info.is_tdls_in_progress) { 1386 scm_debug("Cancel scan. Tdls in progress"); 1387 return false; 1388 } 1389 break; 1390 case WLAN_UMAC_COMP_DFS: 1391 if (comp_info->scan_info.is_cac_in_progress) { 1392 scm_debug("Cancel scan. CAC in progress"); 1393 return false; 1394 } 1395 break; 1396 case WLAN_UMAC_COMP_MLME: 1397 if (comp_info->scan_info.is_scan_for_connect) { 1398 scm_debug("Allow scan request from connect"); 1399 return true; 1400 } 1401 1402 if (comp_info->scan_info.is_mlme_op_in_progress) { 1403 scm_debug("Cancel scan. MLME operation in progress"); 1404 return false; 1405 } 1406 break; 1407 default: 1408 scm_debug("not handled comp_id %d", comp_id); 1409 break; 1410 } 1411 1412 return true; 1413 } 1414 1415 QDF_STATUS ucfg_scan_psoc_enable(struct wlan_objmgr_psoc * psoc)1416 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) 1417 { 1418 QDF_STATUS status; 1419 1420 scm_debug("psoc enable: 0x%pK", psoc); 1421 if (!psoc) { 1422 scm_err("null psoc"); 1423 return QDF_STATUS_E_FAILURE; 1424 } 1425 /* Subscribe for scan events from lmac layesr */ 1426 status = tgt_scan_register_ev_handler(psoc); 1427 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1428 if (!wlan_reg_is_11d_offloaded(psoc)) 1429 scm_11d_cc_db_init(psoc); 1430 scan_register_unregister_bcn_cb(psoc, true); 1431 status = wlan_serialization_register_apply_rules_cb(psoc, 1432 WLAN_SER_CMD_SCAN, 1433 scm_serialization_scan_rules_cb); 1434 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1435 return status; 1436 } 1437 1438 QDF_STATUS ucfg_scan_psoc_disable(struct wlan_objmgr_psoc * psoc)1439 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) 1440 { 1441 QDF_STATUS status; 1442 1443 scm_debug("psoc disable: 0x%pK", psoc); 1444 if (!psoc) { 1445 scm_err("null psoc"); 1446 return QDF_STATUS_E_FAILURE; 1447 } 1448 /* Unsubscribe for scan events from lmac layesr */ 1449 status = tgt_scan_unregister_ev_handler(psoc); 1450 QDF_ASSERT(status == QDF_STATUS_SUCCESS); 1451 scan_register_unregister_bcn_cb(psoc, false); 1452 if (!wlan_reg_is_11d_offloaded(psoc)) 1453 scm_11d_cc_db_deinit(psoc); 1454 1455 return status; 1456 } 1457 1458 uint32_t ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc * psoc)1459 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc) 1460 { 1461 struct scan_default_params *scan_params = NULL; 1462 1463 if (!psoc) { 1464 scm_err("null psoc"); 1465 return 0; 1466 } 1467 scan_params = wlan_scan_psoc_get_def_params(psoc); 1468 if (!scan_params) { 1469 scm_err("Failed to get scan object"); 1470 return 0; 1471 } 1472 1473 return scan_params->max_active_scans_allowed; 1474 } 1475 ucfg_copy_ie_allowlist_attrs(struct wlan_objmgr_psoc * psoc,struct probe_req_allowlist_attr * ie_allowlist)1476 bool ucfg_copy_ie_allowlist_attrs(struct wlan_objmgr_psoc *psoc, 1477 struct probe_req_allowlist_attr *ie_allowlist) 1478 { 1479 struct wlan_scan_obj *scan_obj = NULL; 1480 1481 scan_obj = wlan_psoc_get_scan_obj(psoc); 1482 if (!scan_obj) 1483 return false; 1484 1485 qdf_mem_copy(ie_allowlist, &scan_obj->ie_allowlist, 1486 sizeof(*ie_allowlist)); 1487 1488 return true; 1489 } 1490 ucfg_ie_allowlist_enabled(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)1491 bool ucfg_ie_allowlist_enabled(struct wlan_objmgr_psoc *psoc, 1492 struct wlan_objmgr_vdev *vdev) 1493 { 1494 struct wlan_scan_obj *scan_obj = NULL; 1495 1496 scan_obj = wlan_psoc_get_scan_obj(psoc); 1497 if (!scan_obj) 1498 return false; 1499 1500 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || 1501 wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS) 1502 return false; 1503 1504 if (!scan_obj->ie_allowlist.allow_list) 1505 return false; 1506 1507 return true; 1508 } 1509 ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc * psoc,bool bt_a2dp_active)1510 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, 1511 bool bt_a2dp_active) 1512 { 1513 struct wlan_scan_obj *scan_obj; 1514 1515 scan_obj = wlan_psoc_get_scan_obj(psoc); 1516 if (!scan_obj) { 1517 scm_err("Failed to get scan object"); 1518 return; 1519 } 1520 scan_obj->bt_a2dp_enabled = bt_a2dp_active; 1521 } 1522 ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc * psoc)1523 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) 1524 { 1525 struct wlan_scan_obj *scan_obj; 1526 1527 scan_obj = wlan_psoc_get_scan_obj(psoc); 1528 if (!scan_obj) { 1529 scm_err("Failed to get scan object"); 1530 return false; 1531 } 1532 1533 return scan_obj->bt_a2dp_enabled; 1534 } 1535 ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc * psoc)1536 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc) 1537 { 1538 struct wlan_scan_obj *scan_obj; 1539 1540 scan_obj = wlan_psoc_get_scan_obj(psoc); 1541 if (!scan_obj) 1542 return false; 1543 1544 return scan_obj->scan_def.use_wake_lock_in_user_scan; 1545 } 1546 ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc * psoc)1547 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc) 1548 { 1549 struct wlan_scan_obj *scan_obj; 1550 1551 scan_obj = wlan_psoc_get_scan_obj(psoc); 1552 if (!scan_obj) { 1553 scm_err("Failed to get scan object"); 1554 return cfg_default(CFG_ENABLE_CONNECTED_SCAN); 1555 } 1556 1557 return scan_obj->scan_def.enable_connected_scan; 1558 } 1559 ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc * psoc)1560 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc) 1561 { 1562 struct wlan_scan_obj *scan_obj; 1563 1564 scan_obj = wlan_psoc_get_scan_obj(psoc); 1565 if (!scan_obj) { 1566 scm_err("Failed to get scan object"); 1567 return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING); 1568 } 1569 1570 return scan_obj->scan_def.enable_mac_spoofing; 1571 } 1572 1573 enum scan_dwelltime_adaptive_mode ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc * psoc)1574 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc) 1575 { 1576 struct wlan_scan_obj *scan_obj; 1577 1578 scan_obj = wlan_psoc_get_scan_obj(psoc); 1579 if (!scan_obj) { 1580 scm_err("Failed to get scan object"); 1581 return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE); 1582 } 1583 1584 return scan_obj->scan_def.extscan_adaptive_dwell_mode; 1585 } 1586 1587 QDF_STATUS ucfg_scan_set_global_config(struct wlan_objmgr_psoc * psoc,enum scan_config config,uint32_t val)1588 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, 1589 enum scan_config config, uint32_t val) 1590 { 1591 struct wlan_scan_obj *scan_obj; 1592 QDF_STATUS status = QDF_STATUS_SUCCESS; 1593 1594 scan_obj = wlan_psoc_get_scan_obj(psoc); 1595 if (!scan_obj) { 1596 scm_err("Failed to get scan object config:%d, val:%d", 1597 config, val); 1598 return QDF_STATUS_E_INVAL; 1599 } 1600 switch (config) { 1601 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1602 scan_obj->disable_timeout = !!val; 1603 break; 1604 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1605 scan_obj->drop_bcn_on_chan_mismatch = !!val; 1606 break; 1607 1608 default: 1609 status = QDF_STATUS_E_INVAL; 1610 break; 1611 } 1612 1613 return status; 1614 } 1615 1616 QDF_STATUS ucfg_scan_get_global_config(struct wlan_objmgr_psoc * psoc,enum scan_config config,uint32_t * val)1617 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc, 1618 enum scan_config config, uint32_t *val) 1619 { 1620 struct wlan_scan_obj *scan_obj; 1621 QDF_STATUS status = QDF_STATUS_SUCCESS; 1622 1623 scan_obj = wlan_psoc_get_scan_obj(psoc); 1624 if (!scan_obj || !val) { 1625 scm_err("scan object:%pK config:%d, val:0x%pK", 1626 scan_obj, config, val); 1627 return QDF_STATUS_E_INVAL; 1628 } 1629 switch (config) { 1630 case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT: 1631 *val = scan_obj->disable_timeout; 1632 break; 1633 case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH: 1634 *val = scan_obj->drop_bcn_on_chan_mismatch; 1635 break; 1636 1637 default: 1638 status = QDF_STATUS_E_INVAL; 1639 break; 1640 } 1641 1642 return status; 1643 } 1644 ucfg_scan_set_obss_scan_offload(struct wlan_objmgr_psoc * psoc,bool value)1645 void ucfg_scan_set_obss_scan_offload(struct wlan_objmgr_psoc *psoc, bool value) 1646 { 1647 struct wlan_scan_obj *scan_obj; 1648 1649 scan_obj = wlan_psoc_get_scan_obj(psoc); 1650 if (!scan_obj) { 1651 scm_err("NULL scan obj"); 1652 return; 1653 } 1654 1655 scan_obj->obss_scan_offload = value; 1656 } 1657 1658 #ifdef FEATURE_WLAN_SCAN_PNO ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc * psoc)1659 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc) 1660 { 1661 struct wlan_scan_obj *scan_obj; 1662 1663 scan_obj = wlan_psoc_get_scan_obj(psoc); 1664 if (!scan_obj) { 1665 scm_err("NULL scan obj"); 1666 return false; 1667 } 1668 1669 return scan_obj->pno_cfg.pno_offload_enabled; 1670 } 1671 ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc * psoc,bool value)1672 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value) 1673 { 1674 struct wlan_scan_obj *scan_obj; 1675 1676 scan_obj = wlan_psoc_get_scan_obj(psoc); 1677 if (!scan_obj) { 1678 scm_err("NULL scan obj"); 1679 return; 1680 } 1681 1682 scan_obj->pno_cfg.pno_offload_enabled = value; 1683 } 1684 ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc * psoc)1685 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc) 1686 { 1687 struct wlan_scan_obj *scan_obj; 1688 1689 scan_obj = wlan_psoc_get_scan_obj(psoc); 1690 if (!scan_obj) { 1691 scm_err("NULL scan obj"); 1692 return cfg_default(CFG_PNO_SCAN_SUPPORT); 1693 } 1694 1695 return scan_obj->pno_cfg.scan_support_enabled; 1696 } 1697 ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc * psoc)1698 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc) 1699 { 1700 struct wlan_scan_obj *scan_obj; 1701 1702 scan_obj = wlan_psoc_get_scan_obj(psoc); 1703 if (!scan_obj) { 1704 scm_err("NULL scan obj"); 1705 return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER); 1706 } 1707 return scan_obj->pno_cfg.scan_backoff_multiplier; 1708 } 1709 ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc * psoc)1710 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc) 1711 { 1712 struct wlan_scan_obj *scan_obj; 1713 1714 scan_obj = wlan_psoc_get_scan_obj(psoc); 1715 if (!scan_obj) { 1716 scm_err("NULL scan obj"); 1717 return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN); 1718 } 1719 return scan_obj->pno_cfg.dfs_chnl_scan_enabled; 1720 } 1721 ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc * psoc)1722 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc) 1723 { 1724 struct wlan_scan_obj *scan_obj; 1725 1726 scan_obj = wlan_psoc_get_scan_obj(psoc); 1727 if (!scan_obj) { 1728 scm_err("NULL scan obj"); 1729 return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE); 1730 } 1731 return scan_obj->pno_cfg.scan_timer_repeat_value; 1732 } 1733 ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc * psoc)1734 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc) 1735 { 1736 struct wlan_scan_obj *scan_obj; 1737 1738 scan_obj = wlan_psoc_get_scan_obj(psoc); 1739 if (!scan_obj) { 1740 scm_err("NULL scan obj"); 1741 return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER); 1742 } 1743 return scan_obj->pno_cfg.slow_scan_multiplier; 1744 } 1745 1746 uint32_t ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc * psoc)1747 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc) 1748 { 1749 struct wlan_scan_obj *scan_obj; 1750 1751 scan_obj = wlan_psoc_get_scan_obj(psoc); 1752 if (!scan_obj) { 1753 scm_err("Failed to get scan object"); 1754 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); 1755 } 1756 1757 return scan_obj->pno_cfg.max_sched_scan_plan_interval; 1758 } 1759 1760 uint32_t ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc * psoc)1761 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc) 1762 { 1763 struct wlan_scan_obj *scan_obj; 1764 1765 scan_obj = wlan_psoc_get_scan_obj(psoc); 1766 if (!scan_obj) { 1767 scm_err("Failed to get scan object"); 1768 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 1769 } 1770 1771 return scan_obj->pno_cfg.max_sched_scan_plan_iterations; 1772 } 1773 1774 bool ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc * psoc)1775 ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc) 1776 { 1777 struct wlan_scan_obj *scan_obj; 1778 1779 scan_obj = wlan_psoc_get_scan_obj(psoc); 1780 if (!scan_obj) { 1781 scm_err("Failed to get scan object"); 1782 return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); 1783 } 1784 1785 return scan_obj->pno_cfg.user_config_sched_scan_plan; 1786 } 1787 #endif 1788