1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 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 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 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 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 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 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 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 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 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 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 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 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 #endif 167 168 #ifdef WLAN_POLICY_MGR_ENABLE 169 void wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev, 170 struct pno_scan_req_params *req, 171 struct scan_default_params *scan_def) 172 { 173 bool sap_or_p2p_present; 174 struct wlan_objmgr_psoc *psoc; 175 176 psoc = wlan_vdev_get_psoc(vdev); 177 178 if (!psoc) 179 return; 180 181 sap_or_p2p_present = policy_mgr_mode_specific_connection_count 182 (psoc, 183 PM_SAP_MODE, NULL) || 184 policy_mgr_mode_specific_connection_count 185 (psoc, 186 PM_P2P_GO_MODE, NULL) || 187 policy_mgr_mode_specific_connection_count 188 (psoc, 189 PM_P2P_CLIENT_MODE, NULL); 190 191 if (sap_or_p2p_present) { 192 req->active_dwell_time = scan_def->conc_active_dwell; 193 req->passive_dwell_time = scan_def->conc_passive_dwell; 194 } 195 } 196 #endif 197 198 void wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc, 199 uint32_t *dwell_time) 200 { 201 struct wlan_scan_obj *scan_obj; 202 203 scan_obj = wlan_psoc_get_scan_obj(psoc); 204 if (!scan_obj) 205 return; 206 207 *dwell_time = scan_obj->scan_def.conc_active_dwell; 208 } 209 210 void wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc, 211 uint32_t dwell_time) 212 { 213 struct wlan_scan_obj *scan_obj; 214 215 scan_obj = wlan_psoc_get_scan_obj(psoc); 216 if (!scan_obj) 217 return; 218 219 scan_obj->scan_def.conc_active_dwell = dwell_time; 220 } 221 222 void wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc, 223 uint32_t *dwell_time) 224 { 225 struct wlan_scan_obj *scan_obj; 226 227 scan_obj = wlan_psoc_get_scan_obj(psoc); 228 if (!scan_obj) 229 return; 230 231 *dwell_time = scan_obj->scan_def.conc_passive_dwell; 232 } 233 234 void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc, 235 uint32_t dwell_time) 236 { 237 struct wlan_scan_obj *scan_obj; 238 239 scan_obj = wlan_psoc_get_scan_obj(psoc); 240 if (!scan_obj) 241 return; 242 243 scan_obj->scan_def.conc_passive_dwell = dwell_time; 244 } 245 246 void 247 wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc, 248 bool *enable_dfs_scan) 249 { 250 struct wlan_scan_obj *scan_obj; 251 252 scan_obj = wlan_psoc_get_scan_obj(psoc); 253 if (!scan_obj) 254 return; 255 256 *enable_dfs_scan = scan_obj->scan_def.allow_dfs_chan_in_scan; 257 } 258 259 void 260 wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc, 261 bool enable_dfs_scan) 262 { 263 struct wlan_scan_obj *scan_obj; 264 265 scan_obj = wlan_psoc_get_scan_obj(psoc); 266 if (!scan_obj) 267 return; 268 269 scan_obj->scan_def.allow_dfs_chan_in_scan = enable_dfs_scan; 270 } 271 272 bool wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc *psoc) 273 { 274 struct wlan_scan_obj *scan_obj; 275 276 scan_obj = wlan_psoc_get_scan_obj(psoc); 277 if (!scan_obj) 278 return false; 279 280 return scan_obj->scan_def.honour_nl_scan_policy_flags; 281 } 282 283 void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc, 284 uint32_t *rest_time) 285 { 286 struct wlan_scan_obj *scan_obj; 287 288 scan_obj = wlan_psoc_get_scan_obj(psoc); 289 if (!scan_obj) 290 return; 291 292 *rest_time = scan_obj->scan_def.conc_max_rest_time; 293 } 294 295 void wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc *psoc, 296 uint32_t *rest_time) 297 { 298 struct wlan_scan_obj *scan_obj; 299 300 scan_obj = wlan_psoc_get_scan_obj(psoc); 301 if (!scan_obj) 302 return; 303 304 *rest_time = scan_obj->scan_def.conc_min_rest_time; 305 } 306 307 bool wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc *psoc) 308 { 309 struct wlan_scan_obj *scan_obj; 310 311 scan_obj = wlan_psoc_get_scan_obj(psoc); 312 if (!scan_obj) 313 return cfg_default(CFG_ENABLE_SNR_MONITORING); 314 315 return scan_obj->scan_def.scan_f_chan_stat_evnt; 316 } 317 318 QDF_STATUS 319 wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc, 320 qdf_nbuf_t buf, 321 struct mgmt_rx_event_params *rx_param, 322 enum mgmt_frame_type frm_type) 323 { 324 struct scan_bcn_probe_event *bcn = NULL; 325 QDF_STATUS status; 326 327 if ((frm_type != MGMT_PROBE_RESP) && 328 (frm_type != MGMT_BEACON)) { 329 scm_err("frame is not beacon or probe resp"); 330 status = QDF_STATUS_E_INVAL; 331 goto free; 332 } 333 334 bcn = qdf_mem_malloc_atomic(sizeof(*bcn)); 335 if (!bcn) { 336 status = QDF_STATUS_E_NOMEM; 337 goto free; 338 } 339 bcn->rx_data = 340 qdf_mem_malloc_atomic(sizeof(*rx_param)); 341 if (!bcn->rx_data) { 342 status = QDF_STATUS_E_NOMEM; 343 goto free; 344 } 345 346 if (frm_type == MGMT_PROBE_RESP) 347 bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP; 348 else 349 bcn->frm_type = MGMT_SUBTYPE_BEACON; 350 351 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID); 352 if (QDF_IS_STATUS_ERROR(status)) { 353 scm_info("unable to get reference"); 354 goto free; 355 } 356 357 bcn->psoc = psoc; 358 bcn->buf = buf; 359 qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param)); 360 361 return __scm_handle_bcn_probe(bcn); 362 free: 363 if (bcn && bcn->rx_data) 364 qdf_mem_free(bcn->rx_data); 365 if (bcn) 366 qdf_mem_free(bcn); 367 if (buf) 368 qdf_nbuf_free(buf); 369 370 return status; 371 } 372 373 qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc) 374 { 375 struct wlan_scan_obj *scan_obj; 376 377 scan_obj = wlan_psoc_get_scan_obj(psoc); 378 if (!scan_obj) 379 return cfg_default(CFG_SCAN_AGING_TIME) * 1000; 380 381 return scan_obj->scan_def.scan_cache_aging_time; 382 } 383 384 QDF_STATUS wlan_scan_set_aging_time(struct wlan_objmgr_psoc *psoc, 385 qdf_time_t time) 386 { 387 struct wlan_scan_obj *scan_obj; 388 QDF_STATUS status = QDF_STATUS_E_FAILURE; 389 390 scan_obj = wlan_psoc_get_scan_obj(psoc); 391 if (!scan_obj) 392 return status; 393 394 if (!cfg_in_range(CFG_SCAN_AGING_TIME, time / 1000)) { 395 status = QDF_STATUS_E_RANGE; 396 return status; 397 } 398 399 scan_obj->scan_def.scan_cache_aging_time = time; 400 status = QDF_STATUS_SUCCESS; 401 return status; 402 } 403 404 QDF_STATUS wlan_scan_start(struct scan_start_request *req) 405 { 406 struct scheduler_msg msg = {0}; 407 QDF_STATUS status; 408 409 if (!req || !req->vdev) { 410 scm_err("req or vdev within req is NULL"); 411 if (req) 412 scm_scan_free_scan_request_mem(req); 413 return QDF_STATUS_E_NULL_VALUE; 414 } 415 416 if (!scm_is_scan_allowed(req->vdev)) { 417 scm_err_rl("scan disabled, rejecting the scan req"); 418 scm_scan_free_scan_request_mem(req); 419 return QDF_STATUS_E_AGAIN; 420 } 421 422 /* 423 * Try to get vdev reference. Return if reference could 424 * not be taken. Reference will be released once scan 425 * request handling completes along with free of @req. 426 */ 427 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 428 if (QDF_IS_STATUS_ERROR(status)) { 429 scm_info("unable to get reference"); 430 scm_scan_free_scan_request_mem(req); 431 return status; 432 } 433 434 msg.bodyptr = req; 435 msg.callback = scm_scan_start_req; 436 msg.flush_callback = scm_scan_start_flush_callback; 437 438 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 439 QDF_MODULE_ID_SCAN, 440 QDF_MODULE_ID_OS_IF, &msg); 441 if (QDF_IS_STATUS_ERROR(status)) { 442 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 443 scm_scan_free_scan_request_mem(req); 444 } 445 446 return status; 447 } 448 449 QDF_STATUS wlan_scan_cancel(struct scan_cancel_request *req) 450 { 451 struct scheduler_msg msg = {0}; 452 QDF_STATUS status; 453 454 if (!req || !req->vdev) { 455 scm_err("req or vdev within req is NULL"); 456 if (req) 457 qdf_mem_free(req); 458 return QDF_STATUS_E_NULL_VALUE; 459 } 460 461 status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); 462 if (QDF_IS_STATUS_ERROR(status)) { 463 scm_info("Failed to get vdev ref; status:%d", status); 464 goto req_free; 465 } 466 467 msg.bodyptr = req; 468 msg.callback = scm_scan_cancel_req; 469 msg.flush_callback = scm_scan_cancel_flush_callback; 470 471 status = scheduler_post_message(QDF_MODULE_ID_OS_IF, 472 QDF_MODULE_ID_SCAN, 473 QDF_MODULE_ID_OS_IF, &msg); 474 if (QDF_IS_STATUS_ERROR(status)) 475 goto vdev_put; 476 477 return QDF_STATUS_SUCCESS; 478 479 vdev_put: 480 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 481 482 req_free: 483 qdf_mem_free(req); 484 485 return status; 486 } 487 488 wlan_scan_id 489 wlan_scan_get_scan_id(struct wlan_objmgr_psoc *psoc) 490 { 491 wlan_scan_id id; 492 struct wlan_scan_obj *scan; 493 494 if (!psoc) { 495 QDF_ASSERT(0); 496 scm_err("null psoc"); 497 return 0; 498 } 499 500 scan = wlan_psoc_get_scan_obj(psoc); 501 if (!scan) { 502 scm_err("scan object null"); 503 return 0; 504 } 505 506 id = qdf_atomic_inc_return(&scan->scan_ids); 507 id = id & WLAN_SCAN_ID_MASK; 508 /* Mark this scan request as triggered by host 509 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag. 510 */ 511 id = id | WLAN_HOST_SCAN_REQ_ID_PREFIX; 512 scm_debug("scan_id: 0x%x", id); 513 514 return id; 515 } 516 517 QDF_STATUS 518 wlan_scan_init_default_params(struct wlan_objmgr_vdev *vdev, 519 struct scan_start_request *req) 520 { 521 struct scan_default_params *def; 522 523 if (!vdev | !req) { 524 scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req); 525 return QDF_STATUS_E_INVAL; 526 } 527 def = wlan_vdev_get_def_scan_params(vdev); 528 if (!def) { 529 scm_err("wlan_vdev_get_def_scan_params returned NULL"); 530 return QDF_STATUS_E_NULL_VALUE; 531 } 532 533 /* Zero out everything and explicitly set fields as required */ 534 qdf_mem_zero(req, sizeof(*req)); 535 536 req->vdev = vdev; 537 req->scan_req.vdev_id = wlan_vdev_get_id(vdev); 538 req->scan_req.scan_type = SCAN_TYPE_DEFAULT; 539 req->scan_req.scan_priority = def->scan_priority; 540 req->scan_req.dwell_time_active = def->active_dwell; 541 req->scan_req.dwell_time_active_2g = def->active_dwell_2g; 542 req->scan_req.min_dwell_time_6g = def->min_dwell_time_6g; 543 req->scan_req.dwell_time_active_6g = def->active_dwell_6g; 544 req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g; 545 req->scan_req.dwell_time_passive = def->passive_dwell; 546 req->scan_req.min_rest_time = def->min_rest_time; 547 req->scan_req.max_rest_time = def->max_rest_time; 548 req->scan_req.repeat_probe_time = def->repeat_probe_time; 549 req->scan_req.probe_spacing_time = def->probe_spacing_time; 550 req->scan_req.idle_time = def->idle_time; 551 req->scan_req.max_scan_time = def->max_scan_time; 552 req->scan_req.probe_delay = def->probe_delay; 553 req->scan_req.burst_duration = def->burst_duration; 554 req->scan_req.n_probes = def->num_probes; 555 req->scan_req.adaptive_dwell_time_mode = 556 def->adaptive_dwell_time_mode; 557 req->scan_req.scan_flags = def->scan_flags; 558 req->scan_req.scan_events = def->scan_events; 559 req->scan_req.scan_random.randomize = def->enable_mac_spoofing; 560 561 return QDF_STATUS_SUCCESS; 562 } 563 564 wlan_scan_requester 565 wlan_scan_register_requester(struct wlan_objmgr_psoc *psoc, 566 uint8_t *name, 567 scan_event_handler event_cb, 568 void *arg) 569 { 570 int i, j; 571 struct wlan_scan_obj *scan; 572 struct scan_requester_info *requesters; 573 wlan_scan_requester requester = {0}; 574 575 if (!psoc) { 576 scm_err("null psoc"); 577 return 0; 578 } 579 scan = wlan_psoc_get_scan_obj(psoc); 580 if (!scan) 581 return 0; 582 583 requesters = scan->requesters; 584 qdf_spin_lock_bh(&scan->lock); 585 for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) { 586 if (requesters[i].requester == 0) { 587 requesters[i].requester = 588 WLAN_SCAN_REQUESTER_ID_PREFIX | i; 589 j = 0; 590 while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) { 591 requesters[i].module[j] = name[j]; 592 ++j; 593 } 594 requesters[i].module[j] = 0; 595 requesters[i].ev_handler.func = event_cb; 596 requesters[i].ev_handler.arg = arg; 597 requester = requesters[i].requester; 598 break; 599 } 600 } 601 qdf_spin_unlock_bh(&scan->lock); 602 scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d", 603 name, event_cb, arg, requester); 604 605 return requester; 606 } 607 608 void 609 wlan_scan_unregister_requester(struct wlan_objmgr_psoc *psoc, 610 wlan_scan_requester requester) 611 { 612 int idx; 613 struct wlan_scan_obj *scan; 614 struct scan_requester_info *requesters; 615 616 idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX; 617 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) { 618 scm_err("prefix didn't match for requester id %d", requester); 619 return; 620 } 621 622 idx = requester & WLAN_SCAN_REQUESTER_ID_MASK; 623 if (idx >= WLAN_MAX_REQUESTORS) { 624 scm_err("requester id %d greater than max value", requester); 625 return; 626 } 627 628 if (!psoc) { 629 scm_err("null psoc"); 630 return; 631 } 632 scan = wlan_psoc_get_scan_obj(psoc); 633 if (!scan) 634 return; 635 requesters = scan->requesters; 636 scm_debug("reqid: %d", requester); 637 638 qdf_spin_lock_bh(&scan->lock); 639 requesters[idx].requester = 0; 640 requesters[idx].module[0] = 0; 641 requesters[idx].ev_handler.func = NULL; 642 requesters[idx].ev_handler.arg = NULL; 643 qdf_spin_unlock_bh(&scan->lock); 644 } 645 646 bool wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc *psoc) 647 { 648 struct wlan_scan_obj *scan_obj; 649 650 scan_obj = wlan_psoc_get_scan_obj(psoc); 651 if (!scan_obj) 652 return false; 653 654 return scan_obj->scan_def.skip_6g_and_indoor_freq; 655 } 656 657 #ifdef FEATURE_SET 658 /** 659 * wlan_scan_get_pno_scan_support() - Check if pno scan support is enabled 660 * @psoc: pointer to psoc object 661 * 662 * Return: pno scan_support_enabled flag 663 */ 664 static bool wlan_scan_get_pno_scan_support(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 scm_err("NULL scan obj"); 671 return cfg_default(CFG_PNO_SCAN_SUPPORT); 672 } 673 674 return scan_obj->pno_cfg.scan_support_enabled; 675 } 676 677 /** 678 * wlan_scan_is_connected_scan_enabled() - API to get scan enabled after connect 679 * @psoc: pointer to psoc object 680 * 681 * Return: value. 682 */ 683 static bool wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc) 684 { 685 struct wlan_scan_obj *scan_obj; 686 687 scan_obj = wlan_psoc_get_scan_obj(psoc); 688 if (!scan_obj) { 689 scm_err("Failed to get scan object"); 690 return cfg_default(CFG_ENABLE_CONNECTED_SCAN); 691 } 692 693 return scan_obj->scan_def.enable_connected_scan; 694 } 695 696 void wlan_scan_get_feature_info(struct wlan_objmgr_psoc *psoc, 697 struct wlan_scan_features *scan_feature_set) 698 { 699 scan_feature_set->pno_in_unassoc_state = 700 wlan_scan_get_pno_scan_support(psoc); 701 if (scan_feature_set->pno_in_unassoc_state) 702 scan_feature_set->pno_in_assoc_state = 703 wlan_scan_is_connected_scan_enabled(psoc); 704 } 705 #endif 706 707 #ifdef WLAN_POLICY_MGR_ENABLE 708 void wlan_scan_update_low_latency_profile_chnlist( 709 struct wlan_objmgr_vdev *vdev, 710 struct scan_start_request *req) 711 { 712 uint32_t num_scan_channels = 0, i; 713 struct wlan_objmgr_psoc *psoc; 714 qdf_freq_t freq, ll_sap_freq; 715 716 psoc = wlan_vdev_get_psoc(vdev); 717 if (!psoc) { 718 scm_err("psoc is null"); 719 return; 720 } 721 722 ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc); 723 if (!ll_sap_freq) 724 return; 725 726 /* 727 * Scenario: LL SAP is present and scan is requested. 728 * Allow scan on freq on mutually exclusive mac. 729 */ 730 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 731 freq = req->scan_req.chan_list.chan[i].freq; 732 if (policy_mgr_2_freq_always_on_same_mac(psoc, 733 ll_sap_freq, 734 freq)) 735 continue; 736 737 req->scan_req.chan_list.chan[num_scan_channels++] = 738 req->scan_req.chan_list.chan[i]; 739 } 740 if (num_scan_channels < req->scan_req.chan_list.num_chan) 741 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", 742 req->scan_req.chan_list.num_chan, 743 num_scan_channels, 744 ll_sap_freq); 745 req->scan_req.chan_list.num_chan = num_scan_channels; 746 } 747 #endif 748