1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * DOC: This file contains all SCAN component's APIs 22 */ 23 24 #include "cfg_ucfg_api.h" 25 #include "wlan_scan_api.h" 26 #include "../../core/src/wlan_scan_manager.h" 27 #ifdef WLAN_POLICY_MGR_ENABLE 28 #include <wlan_policy_mgr_api.h> 29 #include "wlan_policy_mgr_public_struct.h" 30 #endif 31 wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)32 void wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc *psoc, 33 uint32_t *dwell_time) 34 { 35 struct wlan_scan_obj *scan_obj; 36 37 scan_obj = wlan_psoc_get_scan_obj(psoc); 38 if (!scan_obj) 39 return; 40 *dwell_time = scan_obj->scan_def.passive_dwell; 41 } 42 wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)43 void wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc *psoc, 44 uint32_t dwell_time) 45 { 46 struct wlan_scan_obj *scan_obj; 47 48 scan_obj = wlan_psoc_get_scan_obj(psoc); 49 if (!scan_obj) 50 return; 51 scan_obj->scan_def.passive_dwell = dwell_time; 52 } 53 wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)54 void wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc *psoc, 55 uint32_t *dwell_time) 56 { 57 struct wlan_scan_obj *scan_obj; 58 59 scan_obj = wlan_psoc_get_scan_obj(psoc); 60 if (!scan_obj) 61 return; 62 *dwell_time = scan_obj->scan_def.active_dwell; 63 } 64 wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)65 void wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc *psoc, 66 uint32_t dwell_time) 67 { 68 struct wlan_scan_obj *scan_obj; 69 70 scan_obj = wlan_psoc_get_scan_obj(psoc); 71 if (!scan_obj) 72 return; 73 scan_obj->scan_def.active_dwell = dwell_time; 74 } 75 wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)76 void wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc, 77 uint32_t *dwell_time) 78 { 79 struct wlan_scan_obj *scan_obj; 80 81 scan_obj = wlan_psoc_get_scan_obj(psoc); 82 if (!scan_obj) 83 return; 84 85 *dwell_time = scan_obj->scan_def.active_dwell_2g; 86 } 87 wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)88 void wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc, 89 uint32_t dwell_time) 90 { 91 struct wlan_scan_obj *scan_obj; 92 93 scan_obj = wlan_psoc_get_scan_obj(psoc); 94 if (!scan_obj) 95 return; 96 scan_obj->scan_def.active_dwell_2g = dwell_time; 97 } 98 99 #ifdef CONFIG_BAND_6GHZ wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)100 QDF_STATUS wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc, 101 uint32_t *dwell_time) 102 { 103 struct wlan_scan_obj *scan_obj; 104 105 scan_obj = wlan_psoc_get_scan_obj(psoc); 106 if (!scan_obj) 107 return QDF_STATUS_E_INVAL; 108 109 *dwell_time = scan_obj->scan_def.active_dwell_6g; 110 111 return QDF_STATUS_SUCCESS; 112 } 113 wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)114 QDF_STATUS wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc, 115 uint32_t dwell_time) 116 { 117 struct wlan_scan_obj *scan_obj; 118 119 scan_obj = wlan_psoc_get_scan_obj(psoc); 120 if (!scan_obj) 121 return QDF_STATUS_E_INVAL; 122 123 scan_obj->scan_def.active_dwell_6g = dwell_time; 124 125 return QDF_STATUS_SUCCESS; 126 } 127 wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)128 QDF_STATUS wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc, 129 uint32_t *dwell_time) 130 { 131 struct wlan_scan_obj *scan_obj; 132 133 scan_obj = wlan_psoc_get_scan_obj(psoc); 134 if (!scan_obj) 135 return QDF_STATUS_E_INVAL; 136 137 *dwell_time = scan_obj->scan_def.passive_dwell_6g; 138 139 return QDF_STATUS_SUCCESS; 140 } 141 wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)142 QDF_STATUS wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc, 143 uint32_t dwell_time) 144 { 145 struct wlan_scan_obj *scan_obj; 146 147 scan_obj = wlan_psoc_get_scan_obj(psoc); 148 if (!scan_obj) 149 return QDF_STATUS_E_INVAL; 150 151 scan_obj->scan_def.passive_dwell_6g = dwell_time; 152 153 return QDF_STATUS_SUCCESS; 154 } 155 wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc * psoc,uint32_t * min_dwell_time_6ghz)156 void wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc *psoc, 157 uint32_t *min_dwell_time_6ghz) 158 { 159 struct wlan_scan_obj *scan_obj; 160 161 scan_obj = wlan_psoc_get_scan_obj(psoc); 162 if (!scan_obj) 163 return; 164 *min_dwell_time_6ghz = scan_obj->scan_def.min_dwell_time_6g; 165 } 166 wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc * psoc,enum scan_mode_6ghz scan_mode_6g)167 QDF_STATUS wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc *psoc, 168 enum scan_mode_6ghz scan_mode_6g) 169 { 170 struct wlan_scan_obj *scan_obj; 171 172 scan_obj = wlan_psoc_get_scan_obj(psoc); 173 if (!scan_obj) 174 return QDF_STATUS_E_INVAL; 175 176 scan_obj->scan_def.scan_mode_6g = scan_mode_6g; 177 178 return QDF_STATUS_SUCCESS; 179 } 180 #endif 181 182 #ifdef WLAN_POLICY_MGR_ENABLE wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req,struct scan_default_params * scan_def)183 void wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 184 struct pno_scan_req_params *req, 185 struct scan_default_params *scan_def) 186 { 187 bool sap_or_p2p_present; 188 struct wlan_objmgr_psoc *psoc; 189 190 psoc = wlan_vdev_get_psoc(vdev); 191 192 if (!psoc) 193 return; 194 195 sap_or_p2p_present = policy_mgr_get_beaconing_mode_count(psoc, NULL) || 196 policy_mgr_mode_specific_connection_count 197 (psoc, 198 PM_P2P_CLIENT_MODE, NULL); 199 200 if (sap_or_p2p_present) { 201 req->active_dwell_time = scan_def->conc_active_dwell; 202 req->passive_dwell_time = scan_def->conc_passive_dwell; 203 } 204 } 205 #endif 206 wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)207 void wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc, 208 uint32_t *dwell_time) 209 { 210 struct wlan_scan_obj *scan_obj; 211 212 scan_obj = wlan_psoc_get_scan_obj(psoc); 213 if (!scan_obj) 214 return; 215 216 *dwell_time = scan_obj->scan_def.conc_active_dwell; 217 } 218 wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)219 void wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc, 220 uint32_t dwell_time) 221 { 222 struct wlan_scan_obj *scan_obj; 223 224 scan_obj = wlan_psoc_get_scan_obj(psoc); 225 if (!scan_obj) 226 return; 227 228 scan_obj->scan_def.conc_active_dwell = dwell_time; 229 } 230 wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)231 void wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc, 232 uint32_t *dwell_time) 233 { 234 struct wlan_scan_obj *scan_obj; 235 236 scan_obj = wlan_psoc_get_scan_obj(psoc); 237 if (!scan_obj) 238 return; 239 240 *dwell_time = scan_obj->scan_def.conc_passive_dwell; 241 } 242 wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)243 void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc, 244 uint32_t dwell_time) 245 { 246 struct wlan_scan_obj *scan_obj; 247 248 scan_obj = wlan_psoc_get_scan_obj(psoc); 249 if (!scan_obj) 250 return; 251 252 scan_obj->scan_def.conc_passive_dwell = dwell_time; 253 } 254 255 void wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc * psoc,bool * enable_dfs_scan)256 wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc, 257 bool *enable_dfs_scan) 258 { 259 struct wlan_scan_obj *scan_obj; 260 261 scan_obj = wlan_psoc_get_scan_obj(psoc); 262 if (!scan_obj) 263 return; 264 265 *enable_dfs_scan = scan_obj->scan_def.allow_dfs_chan_in_scan; 266 } 267 268 void wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc * psoc,bool enable_dfs_scan)269 wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc, 270 bool enable_dfs_scan) 271 { 272 struct wlan_scan_obj *scan_obj; 273 274 scan_obj = wlan_psoc_get_scan_obj(psoc); 275 if (!scan_obj) 276 return; 277 278 scan_obj->scan_def.allow_dfs_chan_in_scan = enable_dfs_scan; 279 } 280 wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc * psoc)281 bool wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc *psoc) 282 { 283 struct wlan_scan_obj *scan_obj; 284 285 scan_obj = wlan_psoc_get_scan_obj(psoc); 286 if (!scan_obj) 287 return false; 288 289 return scan_obj->scan_def.honour_nl_scan_policy_flags; 290 } 291 wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc * psoc,uint32_t * rest_time)292 void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc, 293 uint32_t *rest_time) 294 { 295 struct wlan_scan_obj *scan_obj; 296 297 scan_obj = wlan_psoc_get_scan_obj(psoc); 298 if (!scan_obj) 299 return; 300 301 *rest_time = scan_obj->scan_def.conc_max_rest_time; 302 } 303 wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc * psoc,uint32_t * rest_time)304 void wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc *psoc, 305 uint32_t *rest_time) 306 { 307 struct wlan_scan_obj *scan_obj; 308 309 scan_obj = wlan_psoc_get_scan_obj(psoc); 310 if (!scan_obj) 311 return; 312 313 *rest_time = scan_obj->scan_def.conc_min_rest_time; 314 } 315 wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc * psoc)316 bool wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc *psoc) 317 { 318 struct wlan_scan_obj *scan_obj; 319 320 scan_obj = wlan_psoc_get_scan_obj(psoc); 321 if (!scan_obj) 322 return cfg_default(CFG_ENABLE_SNR_MONITORING); 323 324 return scan_obj->scan_def.scan_f_chan_stat_evnt; 325 } 326 327 QDF_STATUS wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc * psoc,qdf_nbuf_t buf,struct mgmt_rx_event_params * rx_param,enum mgmt_frame_type frm_type)328 wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc, 329 qdf_nbuf_t buf, 330 struct mgmt_rx_event_params *rx_param, 331 enum mgmt_frame_type frm_type) 332 { 333 struct scan_bcn_probe_event *bcn = NULL; 334 QDF_STATUS status; 335 336 if ((frm_type != MGMT_PROBE_RESP) && 337 (frm_type != MGMT_BEACON)) { 338 scm_err("frame is not beacon or probe resp"); 339 status = QDF_STATUS_E_INVAL; 340 goto free; 341 } 342 343 bcn = qdf_mem_malloc_atomic(sizeof(*bcn)); 344 if (!bcn) { 345 status = QDF_STATUS_E_NOMEM; 346 goto free; 347 } 348 bcn->rx_data = 349 qdf_mem_malloc_atomic(sizeof(*rx_param)); 350 if (!bcn->rx_data) { 351 status = QDF_STATUS_E_NOMEM; 352 goto free; 353 } 354 355 if (frm_type == MGMT_PROBE_RESP) 356 bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP; 357 else 358 bcn->frm_type = MGMT_SUBTYPE_BEACON; 359 360 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID); 361 if (QDF_IS_STATUS_ERROR(status)) { 362 scm_info("unable to get reference"); 363 goto free; 364 } 365 366 bcn->psoc = psoc; 367 bcn->buf = buf; 368 369 /* 370 * Save the rnr entries from the frame into rnr db. 371 * The RNR entry would have the partner links as well. 372 * If the partner link is a non-tx profile, and if there 373 * is no MBSSID info for that partner link, then look up 374 * into the rnr db will help to identify if that partner 375 * is a non-tx profile. 376 */ 377 bcn->save_rnr_info = true; 378 qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param)); 379 380 return __scm_handle_bcn_probe(bcn); 381 free: 382 if (bcn && bcn->rx_data) 383 qdf_mem_free(bcn->rx_data); 384 if (bcn) 385 qdf_mem_free(bcn); 386 if (buf) 387 qdf_nbuf_free(buf); 388 389 return status; 390 } 391 wlan_scan_get_aging_time(struct wlan_objmgr_psoc * psoc)392 qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc) 393 { 394 struct wlan_scan_obj *scan_obj; 395 396 scan_obj = wlan_psoc_get_scan_obj(psoc); 397 if (!scan_obj) 398 return cfg_default(CFG_SCAN_AGING_TIME) * 1000; 399 400 return scan_obj->scan_def.scan_cache_aging_time; 401 } 402 wlan_scan_set_aging_time(struct wlan_objmgr_psoc * psoc,qdf_time_t time)403 QDF_STATUS wlan_scan_set_aging_time(struct wlan_objmgr_psoc *psoc, 404 qdf_time_t time) 405 { 406 struct wlan_scan_obj *scan_obj; 407 QDF_STATUS status = QDF_STATUS_E_FAILURE; 408 409 scan_obj = wlan_psoc_get_scan_obj(psoc); 410 if (!scan_obj) 411 return status; 412 413 if (!cfg_in_range(CFG_SCAN_AGING_TIME, time / 1000)) { 414 status = QDF_STATUS_E_RANGE; 415 return status; 416 } 417 418 scan_obj->scan_def.scan_cache_aging_time = time; 419 status = QDF_STATUS_SUCCESS; 420 return status; 421 } 422 wlan_scan_start(struct scan_start_request * req)423 QDF_STATUS wlan_scan_start(struct scan_start_request *req) 424 { 425 struct scheduler_msg msg = {0}; 426 QDF_STATUS status; 427 428 if (!req || !req->vdev) { 429 scm_err("req or vdev within req is NULL"); 430 scm_scan_free_scan_request_mem(req); 431 return QDF_STATUS_E_NULL_VALUE; 432 } 433 434 if (!scm_is_scan_allowed(req->vdev)) { 435 scm_err_rl("scan disabled, rejecting the scan req"); 436 scm_scan_free_scan_request_mem(req); 437 return QDF_STATUS_E_AGAIN; 438 } 439 440 /* 441 * Try to get vdev reference. Return if reference could 442 * not be taken. Reference will be released once scan 443 * request handling completes along with free of @req. 444 */ 445 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 446 if (QDF_IS_STATUS_ERROR(status)) { 447 scm_info("unable to get reference"); 448 scm_scan_free_scan_request_mem(req); 449 return status; 450 } 451 452 msg.bodyptr = req; 453 msg.callback = scm_scan_start_req; 454 msg.flush_callback = scm_scan_start_flush_callback; 455 456 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 457 QDF_MODULE_ID_SCAN, 458 QDF_MODULE_ID_OS_IF, &msg); 459 if (QDF_IS_STATUS_ERROR(status)) { 460 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 461 scm_scan_free_scan_request_mem(req); 462 } 463 464 return status; 465 } 466 wlan_scan_cancel(struct scan_cancel_request * req)467 QDF_STATUS wlan_scan_cancel(struct scan_cancel_request *req) 468 { 469 struct scheduler_msg msg = {0}; 470 QDF_STATUS status; 471 472 if (!req || !req->vdev) { 473 scm_err("req or vdev within req is NULL"); 474 if (req) 475 qdf_mem_free(req); 476 return QDF_STATUS_E_NULL_VALUE; 477 } 478 479 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 480 if (QDF_IS_STATUS_ERROR(status)) { 481 scm_info("Failed to get vdev ref; status:%d", status); 482 goto req_free; 483 } 484 485 msg.bodyptr = req; 486 msg.callback = scm_scan_cancel_req; 487 msg.flush_callback = scm_scan_cancel_flush_callback; 488 489 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 490 QDF_MODULE_ID_SCAN, 491 QDF_MODULE_ID_OS_IF, &msg); 492 if (QDF_IS_STATUS_ERROR(status)) 493 goto vdev_put; 494 495 return QDF_STATUS_SUCCESS; 496 497 vdev_put: 498 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 499 500 req_free: 501 qdf_mem_free(req); 502 503 return status; 504 } 505 506 wlan_scan_id wlan_scan_get_scan_id(struct wlan_objmgr_psoc * psoc)507 wlan_scan_get_scan_id(struct wlan_objmgr_psoc *psoc) 508 { 509 wlan_scan_id id; 510 struct wlan_scan_obj *scan; 511 512 if (!psoc) { 513 QDF_ASSERT(0); 514 scm_err("null psoc"); 515 return 0; 516 } 517 518 scan = wlan_psoc_get_scan_obj(psoc); 519 if (!scan) { 520 scm_err("scan object null"); 521 return 0; 522 } 523 524 id = qdf_atomic_inc_return(&scan->scan_ids); 525 id = id & WLAN_SCAN_ID_MASK; 526 /* Mark this scan request as triggered by host 527 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag. 528 */ 529 id = id | WLAN_HOST_SCAN_REQ_ID_PREFIX; 530 scm_debug("scan_id: 0x%x", id); 531 532 return id; 533 } 534 535 QDF_STATUS wlan_scan_init_default_params(struct wlan_objmgr_vdev * vdev,struct scan_start_request * req)536 wlan_scan_init_default_params(struct wlan_objmgr_vdev *vdev, 537 struct scan_start_request *req) 538 { 539 struct scan_default_params *def; 540 541 if (!vdev | !req) { 542 scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req); 543 return QDF_STATUS_E_INVAL; 544 } 545 def = wlan_vdev_get_def_scan_params(vdev); 546 if (!def) { 547 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 548 return QDF_STATUS_E_NULL_VALUE; 549 } 550 551 /* Zero out everything and explicitly set fields as required */ 552 qdf_mem_zero(req, sizeof(*req)); 553 554 req->vdev = vdev; 555 req->scan_req.vdev_id = wlan_vdev_get_id(vdev); 556 req->scan_req.scan_type = SCAN_TYPE_DEFAULT; 557 req->scan_req.scan_priority = def->scan_priority; 558 req->scan_req.dwell_time_active = def->active_dwell; 559 req->scan_req.dwell_time_active_2g = def->active_dwell_2g; 560 req->scan_req.min_dwell_time_6g = def->min_dwell_time_6g; 561 req->scan_req.dwell_time_active_6g = def->active_dwell_6g; 562 req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g; 563 req->scan_req.dwell_time_passive = def->passive_dwell; 564 req->scan_req.min_rest_time = def->min_rest_time; 565 req->scan_req.max_rest_time = def->max_rest_time; 566 req->scan_req.repeat_probe_time = def->repeat_probe_time; 567 req->scan_req.probe_spacing_time = def->probe_spacing_time; 568 req->scan_req.idle_time = def->idle_time; 569 req->scan_req.max_scan_time = def->max_scan_time; 570 req->scan_req.probe_delay = def->probe_delay; 571 req->scan_req.burst_duration = def->burst_duration; 572 req->scan_req.n_probes = def->num_probes; 573 req->scan_req.adaptive_dwell_time_mode = 574 def->adaptive_dwell_time_mode; 575 req->scan_req.scan_flags = def->scan_flags; 576 req->scan_req.scan_events = def->scan_events; 577 req->scan_req.scan_random.randomize = def->enable_mac_spoofing; 578 579 return QDF_STATUS_SUCCESS; 580 } 581 582 wlan_scan_requester wlan_scan_register_requester(struct wlan_objmgr_psoc * psoc,uint8_t * name,scan_event_handler event_cb,void * arg)583 wlan_scan_register_requester(struct wlan_objmgr_psoc *psoc, 584 uint8_t *name, 585 scan_event_handler event_cb, 586 void *arg) 587 { 588 int i, j; 589 struct wlan_scan_obj *scan; 590 struct scan_requester_info *requesters; 591 wlan_scan_requester requester = {0}; 592 593 if (!psoc) { 594 scm_err("null psoc"); 595 return 0; 596 } 597 scan = wlan_psoc_get_scan_obj(psoc); 598 if (!scan) 599 return 0; 600 601 requesters = scan->requesters; 602 qdf_spin_lock_bh(&scan->lock); 603 for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) { 604 if (requesters[i].requester == 0) { 605 requesters[i].requester = 606 WLAN_SCAN_REQUESTER_ID_PREFIX | i; 607 j = 0; 608 while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) { 609 requesters[i].module[j] = name[j]; 610 ++j; 611 } 612 requesters[i].module[j] = 0; 613 requesters[i].ev_handler.func = event_cb; 614 requesters[i].ev_handler.arg = arg; 615 requester = requesters[i].requester; 616 break; 617 } 618 } 619 qdf_spin_unlock_bh(&scan->lock); 620 scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d", 621 name, event_cb, arg, requester); 622 623 return requester; 624 } 625 626 void wlan_scan_unregister_requester(struct wlan_objmgr_psoc * psoc,wlan_scan_requester requester)627 wlan_scan_unregister_requester(struct wlan_objmgr_psoc *psoc, 628 wlan_scan_requester requester) 629 { 630 int idx; 631 struct wlan_scan_obj *scan; 632 struct scan_requester_info *requesters; 633 634 idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX; 635 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) { 636 scm_err("prefix didn't match for requester id %d", requester); 637 return; 638 } 639 640 idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 641 if (idx >= WLAN_MAX_REQUESTORS) { 642 scm_err("requester id %d greater than max value", requester); 643 return; 644 } 645 646 if (!psoc) { 647 scm_err("null psoc"); 648 return; 649 } 650 scan = wlan_psoc_get_scan_obj(psoc); 651 if (!scan) 652 return; 653 requesters = scan->requesters; 654 scm_debug("reqid: %d", requester); 655 656 qdf_spin_lock_bh(&scan->lock); 657 requesters[idx].requester = 0; 658 requesters[idx].module[0] = 0; 659 requesters[idx].ev_handler.func = NULL; 660 requesters[idx].ev_handler.arg = NULL; 661 qdf_spin_unlock_bh(&scan->lock); 662 } 663 wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc * psoc)664 bool wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc *psoc) 665 { 666 struct wlan_scan_obj *scan_obj; 667 668 scan_obj = wlan_psoc_get_scan_obj(psoc); 669 if (!scan_obj) 670 return false; 671 672 return scan_obj->scan_def.skip_6g_and_indoor_freq; 673 } 674 wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc * psoc,uint32_t * last_scan_ageout_time)675 void wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc *psoc, 676 uint32_t *last_scan_ageout_time) 677 { 678 struct wlan_scan_obj *scan_obj; 679 680 scan_obj = wlan_psoc_get_scan_obj(psoc); 681 if (!scan_obj) { 682 *last_scan_ageout_time = 0; 683 return; 684 } 685 *last_scan_ageout_time = 686 scan_obj->scan_def.last_scan_ageout_time; 687 } 688 689 #ifdef FEATURE_SET 690 /** 691 * wlan_scan_get_pno_scan_support() - Check if pno scan support is enabled 692 * @psoc: pointer to psoc object 693 * 694 * Return: pno scan_support_enabled flag 695 */ wlan_scan_get_pno_scan_support(struct wlan_objmgr_psoc * psoc)696 static bool wlan_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc) 697 { 698 struct wlan_scan_obj *scan_obj; 699 700 scan_obj = wlan_psoc_get_scan_obj(psoc); 701 if (!scan_obj) { 702 scm_err("NULL scan obj"); 703 return cfg_default(CFG_PNO_SCAN_SUPPORT); 704 } 705 706 return scan_obj->pno_cfg.scan_support_enabled; 707 } 708 709 /** 710 * wlan_scan_is_connected_scan_enabled() - API to get scan enabled after connect 711 * @psoc: pointer to psoc object 712 * 713 * Return: value. 714 */ wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc * psoc)715 static bool wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc) 716 { 717 struct wlan_scan_obj *scan_obj; 718 719 scan_obj = wlan_psoc_get_scan_obj(psoc); 720 if (!scan_obj) { 721 scm_err("Failed to get scan object"); 722 return cfg_default(CFG_ENABLE_CONNECTED_SCAN); 723 } 724 725 return scan_obj->scan_def.enable_connected_scan; 726 } 727 wlan_scan_get_feature_info(struct wlan_objmgr_psoc * psoc,struct wlan_scan_features * scan_feature_set)728 void wlan_scan_get_feature_info(struct wlan_objmgr_psoc *psoc, 729 struct wlan_scan_features *scan_feature_set) 730 { 731 scan_feature_set->pno_in_unassoc_state = 732 wlan_scan_get_pno_scan_support(psoc); 733 if (scan_feature_set->pno_in_unassoc_state) 734 scan_feature_set->pno_in_assoc_state = 735 wlan_scan_is_connected_scan_enabled(psoc); 736 } 737 #endif 738 739 #ifdef WLAN_POLICY_MGR_ENABLE 740 /** 741 * wlan_scan_update_hint_bssid() - Update rnr hint bssid info 742 * @psoc: objmgr psoc 743 * @req: Scan request 744 * @ll_sap_freq: ll sap freq 745 * 746 * Use to update hint_bssid if low latency Sap is UP 747 * 748 * Return: void 749 */ 750 static void wlan_scan_update_hint_bssid(struct wlan_objmgr_psoc * psoc,struct scan_start_request * req,qdf_freq_t ll_sap_freq)751 wlan_scan_update_hint_bssid(struct wlan_objmgr_psoc *psoc, 752 struct scan_start_request *req, 753 qdf_freq_t ll_sap_freq) 754 { 755 struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID] = {0}; 756 uint32_t i; 757 uint32_t count = 0; 758 qdf_freq_t freq; 759 760 if (!req->scan_req.num_hint_bssid) 761 return; 762 763 for (i = 0; i < req->scan_req.num_hint_bssid; i++) { 764 freq = req->scan_req.hint_bssid[i].freq_flags >> 16; 765 if (!freq) 766 continue; 767 if (!policy_mgr_2_freq_always_on_same_mac(psoc, 768 ll_sap_freq, 769 freq)) { 770 qdf_mem_copy( 771 &hint_bssid[count].bssid, 772 &req->scan_req.hint_bssid[i].bssid, 773 sizeof(hint_bssid[i].bssid)); 774 hint_bssid[count].freq_flags = 775 req->scan_req.hint_bssid[i].freq_flags; 776 count++; 777 } 778 } 779 qdf_mem_zero(req->scan_req.hint_bssid, 780 sizeof(req->scan_req.hint_bssid)); 781 if (count) 782 qdf_mem_copy(req->scan_req.hint_bssid, hint_bssid, 783 sizeof(hint_bssid)); 784 req->scan_req.num_hint_bssid = count; 785 } 786 787 /** 788 * wlan_scan_update_hint_s_ssid() - Update rnr hint short ssid info 789 * @psoc: objmgr psoc 790 * @req: Scan request 791 * @ll_sap_freq: ll sap freq 792 * 793 * Use to update hint_s_ssid if low latency Sap is UP 794 * 795 * Return: void 796 */ 797 static wlan_scan_update_hint_s_ssid(struct wlan_objmgr_psoc * psoc,struct scan_start_request * req,qdf_freq_t ll_sap_freq)798 void wlan_scan_update_hint_s_ssid(struct wlan_objmgr_psoc *psoc, 799 struct scan_start_request *req, 800 qdf_freq_t ll_sap_freq) 801 { 802 struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_BSSID] = {0}; 803 uint32_t i; 804 uint32_t count = 0; 805 qdf_freq_t freq; 806 807 if (!req->scan_req.num_hint_s_ssid) 808 return; 809 810 for (i = 0; i < req->scan_req.num_hint_s_ssid; i++) { 811 freq = req->scan_req.hint_s_ssid[i].freq_flags >> 16; 812 if (!freq) 813 continue; 814 if (!policy_mgr_2_freq_always_on_same_mac(psoc, 815 ll_sap_freq, 816 freq)) { 817 qdf_mem_copy( 818 &hint_s_ssid[count].short_ssid, 819 &req->scan_req.hint_s_ssid[i].short_ssid, 820 sizeof(hint_s_ssid[i].short_ssid)); 821 hint_s_ssid[count].freq_flags = 822 req->scan_req.hint_s_ssid[i].freq_flags; 823 count++; 824 } 825 } 826 qdf_mem_zero(req->scan_req.hint_s_ssid, 827 sizeof(req->scan_req.hint_s_ssid)); 828 if (count) 829 qdf_mem_copy(req->scan_req.hint_s_ssid, hint_s_ssid, 830 sizeof(hint_s_ssid)); 831 req->scan_req.num_hint_s_ssid = count; 832 } 833 wlan_scan_update_low_latency_profile_chnlist(struct wlan_objmgr_vdev * vdev,struct scan_start_request * req)834 void wlan_scan_update_low_latency_profile_chnlist( 835 struct wlan_objmgr_vdev *vdev, 836 struct scan_start_request *req) 837 { 838 uint32_t num_scan_channels = 0, i; 839 struct wlan_objmgr_psoc *psoc; 840 qdf_freq_t freq, ll_sap_freq; 841 842 psoc = wlan_vdev_get_psoc(vdev); 843 if (!psoc) { 844 scm_err("psoc is null"); 845 return; 846 } 847 848 /* 849 * Get ll_sap freq api will be cleaned up once macro is enabled 850 */ 851 #ifndef WLAN_FEATURE_LL_LT_SAP 852 ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc); 853 #else 854 ll_sap_freq = policy_mgr_get_ll_ht_sap_freq(psoc); 855 #endif 856 857 if (!ll_sap_freq) 858 return; 859 860 wlan_scan_update_hint_bssid(psoc, req, ll_sap_freq); 861 wlan_scan_update_hint_s_ssid(psoc, req, ll_sap_freq); 862 /* 863 * Scenario: LL SAP is present and scan is requested. 864 * Allow scan on freq on mutually exclusive mac. 865 */ 866 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 867 freq = req->scan_req.chan_list.chan[i].freq; 868 if (policy_mgr_2_freq_always_on_same_mac(psoc, 869 ll_sap_freq, 870 freq)) 871 continue; 872 873 req->scan_req.chan_list.chan[num_scan_channels++] = 874 req->scan_req.chan_list.chan[i]; 875 } 876 if (num_scan_channels < req->scan_req.chan_list.num_chan) 877 scm_debug("For DBS: only 2.4Ghz chan and for SBS: mutually exclusive ll-sap 5GHz chan allowed, total-chan %d, remaining-chan %d, ll-sap chan %d", 878 req->scan_req.chan_list.num_chan, 879 num_scan_channels, 880 ll_sap_freq); 881 req->scan_req.chan_list.num_chan = num_scan_channels; 882 } 883 #endif 884 885 QDF_STATUS wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,struct element_info * frame)886 wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev *pdev, 887 struct qdf_mac_addr *bssid, 888 struct element_info *frame) 889 { 890 return scm_scan_get_entry_by_mac_addr(pdev, bssid, frame); 891 } 892 wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc * psoc,update_mbssid_bcn_prb_rsp cb)893 QDF_STATUS wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc *psoc, 894 update_mbssid_bcn_prb_rsp cb) 895 { 896 return scm_scan_register_mbssid_cb(psoc, cb); 897 } 898 899 struct scan_cache_entry * wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid)900 wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev *pdev, 901 struct qdf_mac_addr *bssid) 902 { 903 return scm_scan_get_entry_by_bssid(pdev, bssid); 904 } 905 906 QDF_STATUS wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * link_addr,struct qdf_mac_addr * mld_mac_addr)907 wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev *pdev, 908 struct qdf_mac_addr *link_addr, 909 struct qdf_mac_addr *mld_mac_addr) 910 { 911 return scm_get_mld_addr_by_link_addr(pdev, link_addr, mld_mac_addr); 912 } 913 914 struct scan_cache_entry * wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,uint16_t freq)915 wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev *pdev, 916 struct qdf_mac_addr *bssid, 917 uint16_t freq) 918 { 919 return scm_scan_get_scan_entry_by_mac_freq(pdev, bssid, freq); 920 } 921 wlan_scan_get_aux_support(struct wlan_objmgr_psoc * psoc)922 bool wlan_scan_get_aux_support(struct wlan_objmgr_psoc *psoc) 923 924 { 925 struct wlan_scan_obj *scan_obj; 926 927 scan_obj = wlan_psoc_get_scan_obj(psoc); 928 if (!scan_obj) 929 return false; 930 931 if (scan_obj->aux_mac_support) 932 scm_debug("aux mac support: %d", scan_obj->aux_mac_support); 933 else 934 scm_debug("aux mac not supported"); 935 936 return scan_obj->aux_mac_support; 937 } 938 939