1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 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: contains scan manager functionality 22 */ 23 24 #include <wlan_serialization_api.h> 25 #include <wlan_scan_ucfg_api.h> 26 #include <wlan_scan_tgt_api.h> 27 #include "wlan_scan_main.h" 28 #include "wlan_scan_manager.h" 29 #include "wlan_utility.h" 30 #include <wlan_reg_services_api.h> 31 #ifdef FEATURE_WLAN_SCAN_PNO 32 #include <host_diag_core_event.h> 33 #endif 34 #ifdef WLAN_POLICY_MGR_ENABLE 35 #include <wlan_policy_mgr_api.h> 36 #endif 37 #include <wlan_dfs_utils_api.h> 38 #include <cfg_scan.h> 39 40 QDF_STATUS 41 scm_scan_free_scan_request_mem(struct scan_start_request *req) 42 { 43 void *ie; 44 45 if (!req) { 46 scm_err("null request"); 47 QDF_ASSERT(0); 48 return QDF_STATUS_E_FAILURE; 49 } 50 /* Free vendor(extra) ie */ 51 ie = req->scan_req.extraie.ptr; 52 if (ie) { 53 req->scan_req.extraie.ptr = NULL; 54 req->scan_req.extraie.len = 0; 55 qdf_mem_free(ie); 56 } 57 58 /* Free htcap ie */ 59 ie = req->scan_req.htcap.ptr; 60 if (ie) { 61 req->scan_req.htcap.len = 0; 62 req->scan_req.htcap.ptr = NULL; 63 qdf_mem_free(ie); 64 } 65 66 /* Free vhtcap ie */ 67 ie = req->scan_req.vhtcap.ptr; 68 if (ie) { 69 req->scan_req.vhtcap.len = 0; 70 req->scan_req.vhtcap.ptr = NULL; 71 qdf_mem_free(ie); 72 } 73 /* free scan_start_request memory */ 74 qdf_mem_free(req); 75 76 return QDF_STATUS_SUCCESS; 77 } 78 79 static QDF_STATUS 80 scm_scan_get_pdev_global_event_handlers(struct scan_event_listeners *listeners, 81 struct pdev_scan_ev_handler *pdev_ev_handler) 82 { 83 uint32_t i; 84 struct cb_handler *cb_handlers = &(pdev_ev_handler->cb_handlers[0]); 85 86 for (i = 0; i < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; i++, cb_handlers++) { 87 if ((cb_handlers->func) && 88 (listeners->count < MAX_SCAN_EVENT_LISTENERS)) { 89 listeners->cb[listeners->count].func = 90 cb_handlers->func; 91 listeners->cb[listeners->count].arg = 92 cb_handlers->arg; 93 listeners->count++; 94 } 95 } 96 97 return QDF_STATUS_SUCCESS; 98 } 99 100 static QDF_STATUS 101 scm_scan_get_requester_event_handler(struct scan_event_listeners *listeners, 102 struct scan_requester_info *requesters, 103 wlan_scan_requester requester_id) 104 { 105 uint32_t idx; 106 struct cb_handler *ev_handler; 107 108 idx = requester_id & WLAN_SCAN_REQUESTER_ID_PREFIX; 109 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) 110 return QDF_STATUS_SUCCESS; 111 112 idx = requester_id & WLAN_SCAN_REQUESTER_ID_MASK; 113 if (idx < WLAN_MAX_REQUESTORS) { 114 ev_handler = &(requesters[idx].ev_handler); 115 if (ev_handler->func) { 116 if (listeners->count < MAX_SCAN_EVENT_LISTENERS) { 117 listeners->cb[listeners->count].func = 118 ev_handler->func; 119 listeners->cb[listeners->count].arg = 120 ev_handler->arg; 121 listeners->count++; 122 } 123 } 124 return QDF_STATUS_SUCCESS; 125 } else { 126 scm_err("invalid requester id"); 127 return QDF_STATUS_E_INVAL; 128 } 129 130 } 131 132 static void scm_scan_post_event(struct wlan_objmgr_vdev *vdev, 133 struct scan_event *event) 134 { 135 uint32_t i = 0; 136 struct wlan_scan_obj *scan; 137 struct pdev_scan_ev_handler *pdev_ev_handler; 138 struct cb_handler *cb_handlers; 139 struct scan_requester_info *requesters; 140 struct scan_event_listeners *listeners; 141 142 if (!vdev || !event) { 143 scm_err("vdev: 0x%pK, event: 0x%pK", vdev, event); 144 return; 145 } 146 if (!event->requester) { 147 scm_err("invalid requester id"); 148 QDF_ASSERT(0); 149 } 150 scan = wlan_vdev_get_scan_obj(vdev); 151 pdev_ev_handler = wlan_vdev_get_pdev_scan_ev_handlers(vdev); 152 if (!pdev_ev_handler) 153 return; 154 cb_handlers = &(pdev_ev_handler->cb_handlers[0]); 155 requesters = scan->requesters; 156 157 listeners = qdf_mem_malloc_atomic(sizeof(*listeners)); 158 if (!listeners) { 159 scm_warn("couldn't allocate listeners list"); 160 return; 161 } 162 163 /* initialize number of listeners */ 164 listeners->count = 0; 165 166 /* 167 * Initiator of scan request decides which all scan events 168 * he is interested in and FW will send only those scan events 169 * to host driver. 170 * All the events received by scan module will be notified 171 * to all registered handlers. 172 */ 173 174 qdf_spin_lock_bh(&scan->lock); 175 /* find all global scan event handlers on this pdev */ 176 scm_scan_get_pdev_global_event_handlers(listeners, pdev_ev_handler); 177 /* find owner who triggered this scan request */ 178 scm_scan_get_requester_event_handler(listeners, requesters, 179 event->requester); 180 qdf_spin_unlock_bh(&scan->lock); 181 182 scm_listener_duration_init(scan); 183 184 /* notify all interested handlers */ 185 for (i = 0; i < listeners->count; i++) { 186 scm_listener_cb_exe_dur_start(scan, i); 187 listeners->cb[i].func(vdev, event, listeners->cb[i].arg); 188 scm_listener_cb_exe_dur_end(scan, i); 189 } 190 qdf_mem_free(listeners); 191 } 192 193 static QDF_STATUS 194 scm_release_serialization_command(struct wlan_objmgr_vdev *vdev, 195 uint32_t scan_id) 196 { 197 struct wlan_serialization_queued_cmd_info cmd = {0}; 198 199 cmd.requestor = WLAN_UMAC_COMP_SCAN; 200 cmd.cmd_type = WLAN_SER_CMD_SCAN; 201 cmd.cmd_id = scan_id; 202 cmd.req_type = WLAN_SER_CANCEL_SINGLE_SCAN; 203 cmd.vdev = vdev; 204 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE; 205 206 /* Inform serialization for command completion */ 207 wlan_serialization_remove_cmd(&cmd); 208 209 return QDF_STATUS_SUCCESS; 210 } 211 212 static QDF_STATUS 213 scm_post_internal_scan_complete_event(struct scan_start_request *req, 214 enum scan_completion_reason reason) 215 { 216 struct scan_event event = {0, }; 217 218 /* prepare internal scan complete event */ 219 event.type = SCAN_EVENT_TYPE_COMPLETED; 220 event.reason = reason; 221 event.chan_freq = 0; /* Invalid frequency */ 222 event.vdev_id = req->scan_req.vdev_id; 223 event.requester = req->scan_req.scan_req_id; 224 event.scan_id = req->scan_req.scan_id; 225 /* Fill scan_start_request used to trigger this scan */ 226 event.scan_start_req = req; 227 /* post scan event to registered handlers */ 228 scm_scan_post_event(req->vdev, &event); 229 230 return QDF_STATUS_SUCCESS; 231 } 232 233 static inline struct pdev_scan_info * 234 scm_scan_get_pdev_priv_info(uint8_t pdev_id, struct wlan_scan_obj *scan_obj) 235 { 236 return &scan_obj->pdev_info[pdev_id]; 237 } 238 239 static QDF_STATUS 240 scm_update_last_scan_time(struct scan_start_request *req) 241 { 242 uint8_t pdev_id; 243 struct wlan_scan_obj *scan_obj; 244 struct pdev_scan_info *pdev_scan_info; 245 246 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 247 pdev_id = wlan_scan_vdev_get_pdev_id(req->vdev); 248 pdev_scan_info = scm_scan_get_pdev_priv_info(pdev_id, scan_obj); 249 /* update last scan start time */ 250 pdev_scan_info->last_scan_time = qdf_system_ticks(); 251 252 return QDF_STATUS_SUCCESS; 253 } 254 255 static QDF_STATUS 256 scm_activate_scan_request(struct scan_start_request *req) 257 { 258 QDF_STATUS status; 259 260 status = tgt_scan_start(req); 261 if (status != QDF_STATUS_SUCCESS) { 262 scm_err("tgt_scan_start failed, status: %d", status); 263 /* scan could not be started and hence 264 * we will not receive any completions. 265 * post scan cancelled 266 */ 267 scm_post_internal_scan_complete_event(req, 268 SCAN_REASON_CANCELLED); 269 return status; 270 } 271 /* save last scan start time */ 272 status = scm_update_last_scan_time(req); 273 274 return status; 275 } 276 277 static QDF_STATUS 278 scm_cancel_scan_request(struct scan_start_request *req) 279 { 280 struct scan_cancel_request cancel_req = {0, }; 281 QDF_STATUS status; 282 283 cancel_req.vdev = req->vdev; 284 cancel_req.cancel_req.scan_id = req->scan_req.scan_id; 285 cancel_req.cancel_req.requester = req->scan_req.scan_req_id; 286 cancel_req.cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE; 287 cancel_req.cancel_req.vdev_id = req->scan_req.vdev_id; 288 /* send scan cancel to fw */ 289 status = tgt_scan_cancel(&cancel_req); 290 if (status != QDF_STATUS_SUCCESS) 291 scm_err("tgt_scan_cancel failed: status: %d, scanid: %d", 292 status, req->scan_req.scan_id); 293 /* notify event handler about scan cancellation */ 294 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 295 296 return status; 297 } 298 299 static QDF_STATUS 300 scm_scan_serialize_callback(struct wlan_serialization_command *cmd, 301 enum wlan_serialization_cb_reason reason) 302 { 303 struct scan_start_request *req; 304 QDF_STATUS status; 305 306 if (!cmd) { 307 scm_err("cmd is NULL, reason: %d", reason); 308 QDF_ASSERT(0); 309 return QDF_STATUS_E_NULL_VALUE; 310 } 311 312 if (!cmd->umac_cmd) { 313 scm_err("cmd->umac_cmd is NULL , reason: %d", reason); 314 QDF_ASSERT(0); 315 return QDF_STATUS_E_NULL_VALUE; 316 } 317 318 req = cmd->umac_cmd; 319 if (!req->vdev) { 320 scm_err("NULL vdev. req:0x%pK, reason:%d\n", req, reason); 321 QDF_ASSERT(0); 322 return QDF_STATUS_E_NULL_VALUE; 323 } 324 325 qdf_mtrace(QDF_MODULE_ID_SERIALIZATION, QDF_MODULE_ID_SCAN, reason, 326 req->scan_req.vdev_id, req->scan_req.scan_id); 327 328 switch (reason) { 329 case WLAN_SER_CB_ACTIVATE_CMD: 330 /* command moved to active list 331 * modify the params if required for concurrency case. 332 */ 333 status = scm_activate_scan_request(req); 334 break; 335 336 case WLAN_SER_CB_CANCEL_CMD: 337 /* command removed from pending list. 338 * notify registered scan event handlers with 339 * status completed and reason cancelled. 340 */ 341 status = scm_post_internal_scan_complete_event(req, 342 SCAN_REASON_CANCELLED); 343 break; 344 345 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 346 /* active command timed out. 347 * prepare internal scan cancel request 348 */ 349 status = scm_cancel_scan_request(req); 350 break; 351 352 case WLAN_SER_CB_RELEASE_MEM_CMD: 353 /* command successfully completed. 354 * Release vdev reference and free scan_start_request memory 355 */ 356 cmd->umac_cmd = NULL; 357 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 358 status = scm_scan_free_scan_request_mem(req); 359 break; 360 361 default: 362 /* Do nothing but logging */ 363 QDF_ASSERT(0); 364 status = QDF_STATUS_E_INVAL; 365 break; 366 } 367 368 return status; 369 } 370 371 bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev) 372 { 373 struct wlan_scan_obj *scan_psoc_obj; 374 struct scan_vdev_obj *scan_vdev_obj; 375 376 if (!vdev) { 377 scm_err("vdev is NULL"); 378 return false; 379 } 380 381 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 382 if (!scan_psoc_obj) { 383 scm_err("Couldn't find scan psoc object"); 384 return false; 385 } 386 387 if (scan_psoc_obj->scan_disabled) { 388 scm_err_rl("scan disabled %x, for psoc", 389 scan_psoc_obj->scan_disabled); 390 return false; 391 } 392 393 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 394 if (!scan_vdev_obj) { 395 scm_err("Couldn't find scan vdev object"); 396 return false; 397 } 398 399 if (scan_vdev_obj->scan_disabled) { 400 scm_err_rl("scan disabled %x on vdev_id:%d", 401 scan_vdev_obj->scan_disabled, 402 wlan_vdev_get_id(vdev)); 403 return false; 404 } 405 406 return true; 407 } 408 409 #ifdef WLAN_POLICY_MGR_ENABLE 410 /** 411 * scm_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags 412 * @req: pointer to scan request 413 * 414 * This function sets scan_ctrl_flags_ext value depending on the type of 415 * scan and the channel lists. 416 * 417 * Non-DBS scan is requested if any of the below case is met: 418 * 1. HW is DBS incapable 419 * 2. A high accuracy scan request is sent by kernel. 420 * 421 * DBS scan is enabled for these conditions: 422 * 1. A low power or low span scan request is sent by kernel. 423 * For remaining cases DBS is enabled by default. 424 * Return: void 425 */ 426 static void 427 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 428 { 429 struct wlan_objmgr_psoc *psoc; 430 uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; 431 bool ndi_present; 432 433 psoc = wlan_vdev_get_psoc(req->vdev); 434 435 if (!policy_mgr_is_dbs_scan_allowed(psoc)) { 436 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 437 goto end; 438 } 439 440 if (!wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 441 scm_debug_rl("nl scan policy flags not honoured, goto end"); 442 goto end; 443 } 444 445 ndi_present = policy_mgr_mode_specific_connection_count(psoc, 446 PM_NDI_MODE, 447 NULL); 448 449 if (ndi_present || policy_mgr_is_hw_dbs_2x2_capable(psoc)) { 450 scm_debug("NDP present or HW 2x2 capable, go for DBS scan"); 451 goto end; 452 } 453 454 if (req->scan_req.scan_policy_high_accuracy) { 455 scm_debug("high accuracy scan received, going for non-dbs scan"); 456 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 457 goto end; 458 } 459 460 if ((req->scan_req.scan_policy_low_power) || 461 (req->scan_req.scan_policy_low_span)) { 462 scm_debug("low power/span scan received, going for dbs scan"); 463 scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; 464 goto end; 465 } 466 467 end: 468 req->scan_req.scan_ctrl_flags_ext |= 469 ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) 470 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); 471 } 472 473 /** 474 * scm_update_passive_dwell_time() - update dwell passive time 475 * @vdev: vdev object 476 * @req: scan request 477 * 478 * Return: None 479 */ 480 static void 481 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 482 struct scan_start_request *req) 483 { 484 struct wlan_objmgr_psoc *psoc; 485 486 psoc = wlan_vdev_get_psoc(vdev); 487 if (!psoc) 488 return; 489 490 if (policy_mgr_is_sta_connected_2g(psoc) && 491 !policy_mgr_is_hw_dbs_capable(psoc) && 492 ucfg_scan_get_bt_activity(psoc)) 493 req->scan_req.dwell_time_passive = 494 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 495 } 496 497 static const struct probe_time_dwell_time 498 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 499 {28, 11}, /* 0 SSID */ 500 {28, 20}, /* 1 SSID */ 501 {28, 20}, /* 2 SSID */ 502 {28, 20}, /* 3 SSID */ 503 {28, 20}, /* 4 SSID */ 504 {28, 20}, /* 5 SSID */ 505 {28, 20}, /* 6 SSID */ 506 {28, 11}, /* 7 SSID */ 507 {28, 11}, /* 8 SSID */ 508 {28, 11}, /* 9 SSID */ 509 {28, 8} /* 10 SSID */ 510 }; 511 512 /** 513 * scm_scan_get_burst_duration() - get burst duration depending on max chan 514 * and miracast. 515 * @max_ch_time: max channel time 516 * @miracast_enabled: if miracast is enabled 517 * 518 * Return: burst_duration 519 */ 520 static inline 521 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) 522 { 523 int burst_duration = 0; 524 525 if (miracast_enabled) { 526 /* 527 * When miracast is running, burst 528 * duration needs to be minimum to avoid 529 * any stutter or glitch in miracast 530 * during station scan 531 */ 532 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 533 burst_duration = max_ch_time; 534 else 535 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 536 } else { 537 /* 538 * If miracast is not running, accommodate max 539 * stations to make the scans faster 540 */ 541 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 542 max_ch_time; 543 544 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 545 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 546 max_ch_time; 547 548 if (channels) 549 burst_duration = channels * max_ch_time; 550 else 551 burst_duration = 552 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 553 } 554 } 555 return burst_duration; 556 } 557 558 #define SCM_ACTIVE_DWELL_TIME_NAN 60 559 #define SCM_ACTIVE_DWELL_TIME_SAP 40 560 561 /** 562 * scm_req_update_concurrency_params() - update scan req params depending on 563 * concurrent mode present. 564 * @vdev: vdev object pointer 565 * @req: scan request 566 * @scan_obj: scan object 567 * 568 * Return: void 569 */ 570 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 571 struct scan_start_request *req, 572 struct wlan_scan_obj *scan_obj) 573 { 574 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 575 struct wlan_objmgr_psoc *psoc; 576 uint16_t sap_peer_count = 0; 577 uint16_t go_peer_count = 0; 578 struct wlan_objmgr_pdev *pdev; 579 580 psoc = wlan_vdev_get_psoc(vdev); 581 pdev = wlan_vdev_get_pdev(vdev); 582 583 if (!psoc || !pdev) 584 return; 585 586 ap_present = policy_mgr_mode_specific_connection_count( 587 psoc, PM_SAP_MODE, NULL); 588 go_present = policy_mgr_mode_specific_connection_count( 589 psoc, PM_P2P_GO_MODE, NULL); 590 p2p_cli_present = policy_mgr_mode_specific_connection_count( 591 psoc, PM_P2P_CLIENT_MODE, NULL); 592 sta_active = policy_mgr_mode_specific_connection_count( 593 psoc, PM_STA_MODE, NULL); 594 ndi_present = policy_mgr_mode_specific_connection_count( 595 psoc, PM_NDI_MODE, NULL); 596 if (ap_present) 597 sap_peer_count = 598 wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); 599 if (go_present) 600 go_peer_count = 601 wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); 602 603 if (!req->scan_req.scan_f_passive) 604 scm_update_passive_dwell_time(vdev, req); 605 606 if (policy_mgr_get_connection_count(psoc)) { 607 if (!req->scan_req.scan_f_passive) 608 req->scan_req.dwell_time_active = 609 scan_obj->scan_def.conc_active_dwell; 610 /* 611 * Irrespective of any concurrency, if a scan request is 612 * triggered to get channel utilization for the current 613 * connected channel, passive scan dwell time should be 614 * MLME_GET_CHAN_STATS_PASSIVE_SCAN_TIME 615 */ 616 if (!req->scan_req.scan_f_pause_home_channel) 617 req->scan_req.dwell_time_passive = 618 scan_obj->scan_def.conc_passive_dwell; 619 req->scan_req.max_rest_time = 620 scan_obj->scan_def.conc_max_rest_time; 621 req->scan_req.min_rest_time = 622 scan_obj->scan_def.conc_min_rest_time; 623 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 624 } 625 626 if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) 627 req->scan_req.adaptive_dwell_time_mode = 628 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 629 /* 630 * If AP/GO is active and has connected clients : 631 * 1.set min rest time same as max rest time, so that 632 * firmware spends more time on home channel which will 633 * increase the probability of sending beacon at TBTT 634 * 2.if DBS is supported and SAP is not on 2g, 635 * do not reset active dwell time for 2g. 636 */ 637 638 /* 639 * For SAP, the dwell time cannot exceed 32 ms as it can't go 640 * offchannel more than 32 ms. For Go, since we 641 * advertise NOA, GO can have regular dwell time which is 40 ms. 642 */ 643 if ((ap_present && sap_peer_count) || 644 (go_present && go_peer_count)) { 645 if ((policy_mgr_is_hw_dbs_capable(psoc) && 646 policy_mgr_is_sap_go_on_2g(psoc)) || 647 !policy_mgr_is_hw_dbs_capable(psoc)) { 648 if (ap_present) 649 req->scan_req.dwell_time_active_2g = 650 QDF_MIN(req->scan_req.dwell_time_active, 651 (SCAN_CTS_DURATION_MS_MAX - 652 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 653 else 654 req->scan_req.dwell_time_active_2g = 0; 655 } 656 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 657 } 658 659 if (policy_mgr_current_concurrency_is_mcc(psoc)) 660 req->scan_req.min_rest_time = 661 scan_obj->scan_def.conc_max_rest_time; 662 663 /* 664 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell 665 * time for 2g channels instead of dwell_time_active_2g 666 */ 667 if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) 668 req->scan_req.dwell_time_active_2g = SCM_ACTIVE_DWELL_TIME_SAP; 669 670 if (req->scan_req.scan_type == SCAN_TYPE_DEFAULT) { 671 /* 672 * Decide burst_duration and dwell_time_active based on 673 * what type of devices are active. 674 */ 675 do { 676 if (ap_present && go_present && sta_active) { 677 if (req->scan_req.dwell_time_active <= 678 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 679 req->scan_req.burst_duration = 680 req->scan_req.dwell_time_active; 681 else 682 req->scan_req.burst_duration = 683 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 684 685 break; 686 } 687 688 if (scan_obj->miracast_enabled && 689 policy_mgr_is_mcc_in_24G(psoc)) 690 req->scan_req.max_rest_time = 691 scan_obj->scan_def.sta_miracast_mcc_rest_time; 692 693 if (go_present) { 694 /* 695 * Background scan while GO is sending beacons. 696 * Every off-channel transition has overhead of 697 * 2 beacon intervals for NOA. Maximize number 698 * of channels in every transition by using 699 * burst scan. 700 */ 701 if (scan_obj->scan_def.go_scan_burst_duration) 702 req->scan_req.burst_duration = 703 scan_obj-> 704 scan_def.go_scan_burst_duration; 705 else 706 req->scan_req.burst_duration = 707 scm_scan_get_burst_duration( 708 req->scan_req. 709 dwell_time_active, 710 scan_obj-> 711 miracast_enabled); 712 break; 713 } 714 if ((sta_active || p2p_cli_present)) { 715 if (scan_obj->scan_def.sta_scan_burst_duration) 716 req->scan_req.burst_duration = 717 scan_obj->scan_def. 718 sta_scan_burst_duration; 719 break; 720 } 721 722 if (go_present && sta_active) { 723 req->scan_req.burst_duration = 724 req->scan_req.dwell_time_active; 725 break; 726 } 727 728 if (ndi_present || (p2p_cli_present && sta_active)) { 729 req->scan_req.burst_duration = 0; 730 break; 731 } 732 } while (0); 733 734 if (ap_present) { 735 uint8_t ssid_num; 736 737 ssid_num = req->scan_req.num_ssids * 738 req->scan_req.num_bssid; 739 req->scan_req.repeat_probe_time = 740 scan_probe_time_dwell_time_map[ 741 QDF_MIN(ssid_num, 742 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 743 - 1)].probe_time; 744 req->scan_req.n_probes = 745 (req->scan_req.repeat_probe_time > 0) ? 746 req->scan_req.dwell_time_active / 747 req->scan_req.repeat_probe_time : 0; 748 } 749 } 750 751 if (ap_present) { 752 uint16_t ap_chan_freq; 753 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 754 755 ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 756 /* 757 * P2P/STA scan while SoftAP is sending beacons. 758 * Max duration of CTS2self is 32 ms, which limits the 759 * dwell time. 760 * If DBS is supported and: 761 * 1.if SAP is on 2G channel then keep passive 762 * dwell time default. 763 * 2.if SAP is on 5G/6G channel then update dwell time active. 764 */ 765 if (sap_peer_count) { 766 if (policy_mgr_is_hw_dbs_capable(psoc) && 767 (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) || 768 WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) { 769 req->scan_req.dwell_time_active = 770 QDF_MIN(req->scan_req.dwell_time_active, 771 (SCAN_CTS_DURATION_MS_MAX - 772 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 773 } 774 if (!policy_mgr_is_hw_dbs_capable(psoc) || 775 (policy_mgr_is_hw_dbs_capable(psoc) && 776 WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) { 777 req->scan_req.dwell_time_passive = 778 req->scan_req.dwell_time_active; 779 } 780 } 781 782 if (scan_obj->scan_def.ap_scan_burst_duration) { 783 req->scan_req.burst_duration = 784 scan_obj->scan_def.ap_scan_burst_duration; 785 } else { 786 req->scan_req.burst_duration = 0; 787 if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq)) 788 req->scan_req.burst_duration = 789 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 790 req->scan_req.dwell_time_active; 791 } 792 } 793 794 if (ndi_present) { 795 req->scan_req.dwell_time_active = 796 SCM_ACTIVE_DWELL_TIME_NAN; 797 req->scan_req.dwell_time_active_2g = 798 QDF_MIN(req->scan_req.dwell_time_active_2g, 799 SCM_ACTIVE_DWELL_TIME_NAN); 800 scm_debug("NDP active modify dwell time 2ghz %d", 801 req->scan_req.dwell_time_active_2g); 802 } 803 804 if (sta_active) { 805 req->scan_req.dwell_time_active_6g = 806 scan_obj->scan_def.active_dwell_time_6g_conc; 807 /* 808 * Irrespective of any concurrency, if a scan request is 809 * triggered to get channel utilization for the current 810 * connected channel, 6g passive scan dwell time should be 811 * MLME_GET_CHAN_STATS_WIDE_BAND_PASSIVE_SCAN_TIME 812 */ 813 if (!req->scan_req.scan_f_pause_home_channel) 814 req->scan_req.dwell_time_passive_6g = 815 scan_obj->scan_def.passive_dwell_time_6g_conc; 816 } 817 } 818 819 static inline void scm_update_5ghz_6ghz_chlist(struct scan_start_request *req, 820 qdf_freq_t intf_freq) 821 { 822 struct wlan_objmgr_psoc *psoc; 823 struct wlan_objmgr_pdev *pdev; 824 uint32_t i; 825 uint32_t num_scan_channels; 826 827 pdev = wlan_vdev_get_pdev(req->vdev); 828 if (!pdev) 829 return; 830 831 psoc = wlan_pdev_get_psoc(pdev); 832 if (!psoc) 833 return; 834 835 num_scan_channels = 0; 836 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 837 if (!WLAN_REG_IS_24GHZ_CH_FREQ( 838 req->scan_req.chan_list.chan[i].freq)) { 839 /* 840 * If no intf_freq, skip all 5 + 6 GHz freq 841 * else, skip only freq on same mac as intf_freq 842 */ 843 if (!intf_freq || 844 policy_mgr_2_freq_always_on_same_mac( 845 psoc, intf_freq, 846 req->scan_req.chan_list.chan[i].freq)) 847 continue; 848 } 849 850 req->scan_req.chan_list.chan[num_scan_channels++] = 851 req->scan_req.chan_list.chan[i]; 852 } 853 if (num_scan_channels < req->scan_req.chan_list.num_chan) 854 scm_debug("5g chan skipped (%d, %d)", 855 req->scan_req.chan_list.num_chan, num_scan_channels); 856 req->scan_req.chan_list.num_chan = num_scan_channels; 857 } 858 859 static inline void scm_update_24g_chlist(struct scan_start_request *req) 860 { 861 uint32_t i; 862 uint32_t num_scan_channels; 863 864 num_scan_channels = 0; 865 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 866 if (WLAN_REG_IS_24GHZ_CH_FREQ( 867 req->scan_req.chan_list.chan[i].freq)) 868 continue; 869 870 req->scan_req.chan_list.chan[num_scan_channels++] = 871 req->scan_req.chan_list.chan[i]; 872 } 873 if (num_scan_channels < req->scan_req.chan_list.num_chan) 874 scm_debug("2g chan skipped (%d, %d)", 875 req->scan_req.chan_list.num_chan, num_scan_channels); 876 req->scan_req.chan_list.num_chan = num_scan_channels; 877 } 878 879 /** 880 * scm_filter_6g_and_indoor_freq() - Modify channel list to skip 6Ghz and 5Ghz 881 * indoor channel if hw mode is non dbs and SAP is present 882 * @pdev: pointer to pdev 883 * @req: scan request 884 * 885 * Return: None 886 */ 887 static void scm_filter_6g_and_indoor_freq(struct wlan_objmgr_pdev *pdev, 888 struct scan_start_request *req) 889 { 890 uint32_t i; 891 uint32_t num_scan_channels; 892 qdf_freq_t freq; 893 894 num_scan_channels = 0; 895 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 896 freq = req->scan_req.chan_list.chan[i].freq; 897 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) 898 continue; 899 900 if (wlan_reg_is_freq_indoor(pdev, freq)) 901 continue; 902 903 req->scan_req.chan_list.chan[num_scan_channels++] = 904 req->scan_req.chan_list.chan[i]; 905 } 906 if (num_scan_channels < req->scan_req.chan_list.num_chan) 907 scm_debug("6g and indoor channel chan skipped (%d, %d)", 908 req->scan_req.chan_list.num_chan, num_scan_channels); 909 req->scan_req.chan_list.num_chan = num_scan_channels; 910 } 911 912 /** 913 * scm_scan_chlist_concurrency_modify() - modify chan list to skip 5G if 914 * required 915 * @vdev: vdev object 916 * @req: scan request 917 * 918 * Check and skip 5G chan list based on DFS AP present and current hw mode. 919 * 920 * Return: void 921 */ 922 static inline void scm_scan_chlist_concurrency_modify( 923 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 924 { 925 struct wlan_objmgr_psoc *psoc; 926 struct wlan_objmgr_pdev *pdev; 927 struct wlan_scan_obj *scan_obj; 928 uint16_t trim; 929 qdf_freq_t dfs_ap_freq; 930 931 pdev = wlan_vdev_get_pdev(vdev); 932 if (!pdev) 933 return; 934 935 psoc = wlan_pdev_get_psoc(pdev); 936 if (!psoc) 937 return; 938 939 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 940 if (!scan_obj) 941 return; 942 943 /* do this only for STA and P2P-CLI mode */ 944 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 945 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 946 return; 947 948 if (policy_mgr_scan_trim_5g_chnls_for_dfs_ap(psoc, &dfs_ap_freq)) 949 scm_update_5ghz_6ghz_chlist(req, dfs_ap_freq); 950 951 if (scan_obj->scan_def.conc_chlist_trim) { 952 trim = policy_mgr_scan_trim_chnls_for_connected_ap(pdev); 953 if (trim & TRIM_CHANNEL_LIST_5G) 954 scm_update_5ghz_6ghz_chlist(req, 0); 955 if (trim & TRIM_CHANNEL_LIST_24G) 956 scm_update_24g_chlist(req); 957 } 958 959 /* 960 * Do not allow STA to scan on 6Ghz or indoor channel for non dbs 961 * hardware if SAP and skip_6g_and_indoor_freq_scan ini are present 962 */ 963 if (scan_obj->scan_def.skip_6g_and_indoor_freq && 964 !policy_mgr_is_hw_dbs_capable(psoc) && 965 (wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 966 policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL)) 967 scm_filter_6g_and_indoor_freq(pdev, req); 968 969 } 970 #else 971 static inline 972 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 973 struct scan_start_request *req, 974 struct wlan_scan_obj *scan_obj) 975 { 976 } 977 978 static inline void 979 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 980 { 981 } 982 983 static inline void scm_scan_chlist_concurrency_modify( 984 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 985 { 986 } 987 #endif 988 989 /** 990 * scm_update_channel_list() - update scan req params depending on dfs inis 991 * and initial scan request. 992 * @req: scan request 993 * @scan_obj: scan object 994 * 995 * Return: void 996 */ 997 static void 998 scm_update_channel_list(struct scan_start_request *req, 999 struct wlan_scan_obj *scan_obj) 1000 { 1001 uint8_t i; 1002 uint8_t num_scan_channels = 0; 1003 struct scan_vdev_obj *scan_vdev_obj; 1004 struct wlan_objmgr_pdev *pdev; 1005 bool first_scan_done = true; 1006 bool p2p_search = false; 1007 bool skip_dfs_ch = true; 1008 uint32_t first_freq; 1009 1010 pdev = wlan_vdev_get_pdev(req->vdev); 1011 1012 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 1013 if (!scan_vdev_obj) { 1014 scm_err("null scan_vdev_obj"); 1015 return; 1016 } 1017 1018 if (!scan_vdev_obj->first_scan_done) { 1019 first_scan_done = false; 1020 scan_vdev_obj->first_scan_done = true; 1021 } 1022 1023 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH) 1024 p2p_search = true; 1025 /* 1026 * No need to update channels if req is single channel* ie ROC, 1027 * Preauth or a single channel scan etc. 1028 * If the single chan in the scan channel list is an NOL channel,it is 1029 * removed and it would reduce the number of scan channels to 0. 1030 */ 1031 first_freq = req->scan_req.chan_list.chan[0].freq; 1032 if ((req->scan_req.chan_list.num_chan == 1) && 1033 (!utils_dfs_is_freq_in_nol(pdev, first_freq))) 1034 return; 1035 1036 /* do this only for STA and P2P-CLI mode */ 1037 if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 1038 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) && 1039 !p2p_search) 1040 skip_dfs_ch = false; 1041 1042 if ((scan_obj->scan_def.allow_dfs_chan_in_scan && 1043 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 1044 first_scan_done)) && 1045 !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search) && 1046 !scan_obj->miracast_enabled) 1047 skip_dfs_ch = false; 1048 1049 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 1050 uint32_t freq; 1051 1052 freq = req->scan_req.chan_list.chan[i].freq; 1053 if ((wlan_reg_is_6ghz_chan_freq(freq) && 1054 !wlan_reg_is_6ghz_band_set(pdev))) { 1055 scm_nofl_debug("Skip 6 GHz freq = %d", freq); 1056 continue; 1057 } 1058 if (skip_dfs_ch && 1059 wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) { 1060 scm_nofl_debug("Skip DFS freq %d", freq); 1061 continue; 1062 } 1063 if (utils_dfs_is_freq_in_nol(pdev, freq)) { 1064 scm_nofl_debug("Skip NOL freq %d", freq); 1065 continue; 1066 } 1067 1068 req->scan_req.chan_list.chan[num_scan_channels++] = 1069 req->scan_req.chan_list.chan[i]; 1070 } 1071 1072 req->scan_req.chan_list.num_chan = num_scan_channels; 1073 1074 scm_update_6ghz_channel_list(req, scan_obj); 1075 scm_scan_chlist_concurrency_modify(req->vdev, req); 1076 } 1077 1078 /** 1079 * scm_req_update_dwell_time_as_per_scan_mode() - update scan req params 1080 * dwell time as per scan mode. 1081 * @vdev: vdev to update 1082 * @req: scan request 1083 * 1084 * Return: void 1085 */ 1086 static void 1087 scm_req_update_dwell_time_as_per_scan_mode( 1088 struct wlan_objmgr_vdev *vdev, 1089 struct scan_start_request *req) 1090 { 1091 struct wlan_objmgr_psoc *psoc; 1092 1093 psoc = wlan_vdev_get_psoc(vdev); 1094 1095 if (req->scan_req.scan_policy_low_span && 1096 wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 1097 req->scan_req.adaptive_dwell_time_mode = 1098 SCAN_DWELL_MODE_STATIC; 1099 req->scan_req.dwell_time_active = 1100 QDF_MIN(req->scan_req.dwell_time_active, 1101 LOW_SPAN_ACTIVE_DWELL_TIME); 1102 req->scan_req.dwell_time_active_2g = 1103 QDF_MIN(req->scan_req.dwell_time_active_2g, 1104 LOW_SPAN_ACTIVE_DWELL_TIME); 1105 req->scan_req.dwell_time_passive = 1106 QDF_MIN(req->scan_req.dwell_time_passive, 1107 LOW_SPAN_PASSIVE_DWELL_TIME); 1108 } 1109 } 1110 1111 /** 1112 * scm_scan_req_update_params() - update scan req params depending on modes 1113 * and scan type. 1114 * @vdev: vdev object pointer 1115 * @req: scan request 1116 * @scan_obj: scan object 1117 * 1118 * Return: void 1119 */ 1120 static void 1121 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 1122 struct scan_start_request *req, 1123 struct wlan_scan_obj *scan_obj) 1124 { 1125 struct chan_list *custom_chan_list; 1126 struct wlan_objmgr_pdev *pdev; 1127 uint8_t pdev_id; 1128 1129 /* Ensure correct number of probes are sent on active channel */ 1130 if (!req->scan_req.repeat_probe_time) 1131 req->scan_req.repeat_probe_time = 1132 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 1133 1134 if (req->scan_req.scan_f_passive) 1135 req->scan_req.scan_ctrl_flags_ext |= 1136 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 1137 1138 if (!req->scan_req.n_probes) 1139 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 1140 req->scan_req.dwell_time_active / 1141 req->scan_req.repeat_probe_time : 0; 1142 1143 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH || 1144 req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1145 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 1146 req->scan_req.dwell_time_active_2g = 0; 1147 if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1148 req->scan_req.repeat_probe_time = 0; 1149 } else { 1150 req->scan_req.scan_f_filter_prb_req = true; 1151 if (!req->scan_req.num_ssids) 1152 req->scan_req.scan_f_bcast_probe = true; 1153 1154 req->scan_req.dwell_time_active += 1155 P2P_SEARCH_DWELL_TIME_INC; 1156 /* 1157 * 3 channels with default max dwell time 40 ms. 1158 * Cap limit will be set by 1159 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 1160 * should be such that no channel is scanned less 1161 * than the dwell time in normal scenarios. 1162 */ 1163 if (req->scan_req.chan_list.num_chan == 1164 WLAN_P2P_SOCIAL_CHANNELS && 1165 !scan_obj->miracast_enabled) 1166 req->scan_req.repeat_probe_time = 1167 req->scan_req.dwell_time_active / 5; 1168 else 1169 req->scan_req.repeat_probe_time = 1170 req->scan_req.dwell_time_active / 3; 1171 if (scan_obj->scan_def.p2p_scan_burst_duration) { 1172 req->scan_req.burst_duration = 1173 scan_obj->scan_def. 1174 p2p_scan_burst_duration; 1175 } else { 1176 req->scan_req.burst_duration = 1177 BURST_SCAN_MAX_NUM_OFFCHANNELS * 1178 req->scan_req.dwell_time_active; 1179 if (req->scan_req.burst_duration > 1180 P2P_SCAN_MAX_BURST_DURATION) { 1181 uint8_t channels = 1182 P2P_SCAN_MAX_BURST_DURATION / 1183 req->scan_req.dwell_time_active; 1184 if (channels) 1185 req->scan_req.burst_duration = 1186 channels * 1187 req->scan_req.dwell_time_active; 1188 else 1189 req->scan_req.burst_duration = 1190 P2P_SCAN_MAX_BURST_DURATION; 1191 } 1192 } 1193 req->scan_req.scan_ev_bss_chan = false; 1194 } 1195 } else { 1196 req->scan_req.scan_f_cck_rates = true; 1197 if (!req->scan_req.num_ssids) 1198 req->scan_req.scan_f_bcast_probe = true; 1199 req->scan_req.scan_f_add_ds_ie_in_probe = true; 1200 req->scan_req.scan_f_filter_prb_req = true; 1201 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 1202 } 1203 1204 scm_update_dbs_scan_ctrl_ext_flag(req); 1205 1206 /* 1207 * No need to update conncurrency parmas if req is passive scan on 1208 * single channel ie ROC, Preauth etc 1209 */ 1210 if (!(req->scan_req.scan_f_passive && 1211 req->scan_req.chan_list.num_chan == 1) && 1212 req->scan_req.scan_type != SCAN_TYPE_RRM) 1213 scm_req_update_concurrency_params(vdev, req, scan_obj); 1214 1215 if (req->scan_req.scan_type == SCAN_TYPE_RRM) 1216 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_RRM_SCAN_IND; 1217 1218 scm_req_update_dwell_time_as_per_scan_mode(vdev, req); 1219 1220 scm_debug("scan_ctrl_flags_ext %0x", req->scan_req.scan_ctrl_flags_ext); 1221 /* 1222 * Set wide band flag if enabled. This will cause 1223 * phymode TLV being sent to FW. 1224 */ 1225 pdev = wlan_vdev_get_pdev(vdev); 1226 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1227 /* 1228 * Trigger wide band scan also if 1229 * scan_f_report_cca_busy_for_each_20mhz flag is set 1230 */ 1231 if (ucfg_scan_get_wide_band_scan(pdev) || 1232 req->scan_req.scan_f_report_cca_busy_for_each_20mhz) 1233 req->scan_req.scan_f_wide_band = true; 1234 else 1235 req->scan_req.scan_f_wide_band = false; 1236 1237 /* 1238 * Overwrite scan channels with custom scan channel 1239 * list if configured. 1240 */ 1241 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 1242 if (custom_chan_list->num_chan) 1243 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 1244 sizeof(struct chan_list)); 1245 else if (!req->scan_req.chan_list.num_chan) 1246 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 1247 1248 scm_update_channel_list(req, scan_obj); 1249 1250 wlan_scan_update_low_latency_profile_chnlist(vdev, req); 1251 } 1252 1253 static inline void scm_print_scan_req_info(struct scan_req_params *req) 1254 { 1255 uint32_t buff_len; 1256 char *chan_buff; 1257 uint32_t len = 0; 1258 uint8_t buff_size, idx, count = 0; 1259 struct chan_list *chan_lst; 1260 #define MAX_SCAN_FREQ_TO_PRINT 25 1261 1262 scm_nofl_debug("Scan start: scan id %d vdev %d Dwell time: act %d pass %d act_2G %d act_6G %d pass_6G %d, probe time %d n_probes %d flags %x ext_flag %x events %x policy %d is_wb: %d pri %d", 1263 req->scan_id, req->vdev_id, req->dwell_time_active, 1264 req->dwell_time_passive, req->dwell_time_active_2g, 1265 req->dwell_time_active_6g, req->dwell_time_passive_6g, 1266 req->repeat_probe_time, req->n_probes, req->scan_flags, 1267 req->scan_ctrl_flags_ext, req->scan_events, 1268 req->scan_policy_type, req->scan_f_wide_band, 1269 req->scan_priority); 1270 scm_nofl_debug("Scan Type %d rest time: min %d max %d probe spacing %d idle %d probe delay %d scan offset %d burst duration %d adaptive dwell mode %d", 1271 req->scan_type, req->min_rest_time, req->max_rest_time, 1272 req->probe_spacing_time, req->idle_time, 1273 req->probe_delay, req->scan_offset_time, 1274 req->burst_duration, req->adaptive_dwell_time_mode); 1275 1276 for (idx = 0; idx < req->num_ssids; idx++) 1277 scm_nofl_debug("SSID[%d]: " QDF_SSID_FMT, idx, 1278 QDF_SSID_REF(req->ssid[idx].length, 1279 req->ssid[idx].ssid)); 1280 1281 chan_lst = &req->chan_list; 1282 1283 if (!chan_lst->num_chan) 1284 return; 1285 1286 /* 1287 * Buffer of (num channel * buff_size) + 1 to consider the 4 char freq, 1288 * 6 char flags and 1 space after it for each channel and 1 to end the 1289 * string with NULL. 1290 * In case of wide band scan extra 4 char for phymode. 1291 */ 1292 if (req->scan_f_wide_band) 1293 buff_size = 15; 1294 else 1295 buff_size = 11; 1296 1297 buff_len = (QDF_MIN(MAX_SCAN_FREQ_TO_PRINT, 1298 chan_lst->num_chan) * buff_size) + 1; 1299 1300 chan_buff = qdf_mem_malloc(buff_len); 1301 if (!chan_buff) 1302 return; 1303 1304 scm_nofl_debug("Total freq %d", chan_lst->num_chan); 1305 for (idx = 0; idx < chan_lst->num_chan; idx++) { 1306 if (req->scan_f_wide_band) 1307 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1308 "%d(0x%02x)[%d] ", 1309 chan_lst->chan[idx].freq, 1310 chan_lst->chan[idx].flags, 1311 chan_lst->chan[idx].phymode); 1312 else 1313 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1314 "%d(0x%02x) ", 1315 chan_lst->chan[idx].freq, 1316 chan_lst->chan[idx].flags); 1317 1318 count++; 1319 if (count >= MAX_SCAN_FREQ_TO_PRINT) { 1320 /* Print the MAX_SCAN_FREQ_TO_PRINT channels */ 1321 scm_nofl_debug("Freq list: %s", chan_buff); 1322 len = 0; 1323 count = 0; 1324 } 1325 } 1326 if (len) 1327 scm_nofl_debug("Freq list: %s", chan_buff); 1328 1329 qdf_mem_free(chan_buff); 1330 } 1331 QDF_STATUS 1332 scm_scan_start_req(struct scheduler_msg *msg) 1333 { 1334 struct wlan_serialization_command cmd = {0, }; 1335 enum wlan_serialization_status ser_cmd_status; 1336 struct scan_start_request *req = NULL; 1337 struct wlan_scan_obj *scan_obj; 1338 QDF_STATUS status = QDF_STATUS_SUCCESS; 1339 1340 1341 if (!msg) { 1342 scm_err("msg received is NULL"); 1343 QDF_ASSERT(0); 1344 return QDF_STATUS_E_NULL_VALUE; 1345 } 1346 if (!msg->bodyptr) { 1347 scm_err("bodyptr is NULL"); 1348 QDF_ASSERT(0); 1349 return QDF_STATUS_E_NULL_VALUE; 1350 } 1351 1352 req = msg->bodyptr; 1353 1354 if (!scm_is_scan_allowed(req->vdev)) { 1355 scm_err("scan disabled, rejecting the scan req"); 1356 status = QDF_STATUS_E_NULL_VALUE; 1357 goto err; 1358 } 1359 1360 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 1361 if (!scan_obj) { 1362 scm_debug("Couldn't find scan object"); 1363 status = QDF_STATUS_E_NULL_VALUE; 1364 goto err; 1365 } 1366 1367 scm_scan_req_update_params(req->vdev, req, scan_obj); 1368 scm_print_scan_req_info(&req->scan_req); 1369 1370 if (!req->scan_req.chan_list.num_chan) { 1371 scm_info("Reject 0 channel Scan"); 1372 status = QDF_STATUS_E_NULL_VALUE; 1373 goto err; 1374 } 1375 1376 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1377 cmd.cmd_id = req->scan_req.scan_id; 1378 cmd.cmd_cb = scm_scan_serialize_callback; 1379 cmd.umac_cmd = req; 1380 cmd.source = WLAN_UMAC_COMP_SCAN; 1381 cmd.is_high_priority = false; 1382 cmd.cmd_timeout_duration = req->scan_req.max_scan_time + 1383 SCAN_TIMEOUT_GRACE_PERIOD; 1384 cmd.vdev = req->vdev; 1385 1386 if (scan_obj->disable_timeout) 1387 cmd.cmd_timeout_duration = 0; 1388 1389 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION, 1390 WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id, 1391 req->scan_req.scan_id); 1392 1393 ser_cmd_status = wlan_serialization_request(&cmd); 1394 switch (ser_cmd_status) { 1395 case WLAN_SER_CMD_PENDING: 1396 /* command moved to pending list.Do nothing */ 1397 break; 1398 case WLAN_SER_CMD_ACTIVE: 1399 /* command moved to active list. Do nothing */ 1400 break; 1401 default: 1402 scm_debug("ser cmd status %d", ser_cmd_status); 1403 goto err; 1404 } 1405 1406 return status; 1407 err: 1408 /* 1409 * notify registered scan event handlers 1410 * about internal error 1411 */ 1412 scm_post_internal_scan_complete_event(req, 1413 SCAN_REASON_INTERNAL_FAILURE); 1414 /* 1415 * cmd can't be serviced. 1416 * release vdev reference and free scan_start_request memory 1417 */ 1418 if (req) { 1419 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1420 scm_scan_free_scan_request_mem(req); 1421 } 1422 1423 return status; 1424 } 1425 1426 static inline enum wlan_serialization_cancel_type 1427 get_serialization_cancel_type(enum scan_cancel_req_type type) 1428 { 1429 enum wlan_serialization_cancel_type serialization_type; 1430 1431 switch (type) { 1432 case WLAN_SCAN_CANCEL_SINGLE: 1433 serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN; 1434 break; 1435 case WLAN_SCAN_CANCEL_VDEV_ALL: 1436 serialization_type = WLAN_SER_CANCEL_VDEV_SCANS; 1437 break; 1438 case WLAN_SCAN_CANCEL_PDEV_ALL: 1439 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1440 break; 1441 case WLAN_SCAN_CANCEL_HOST_VDEV_ALL: 1442 serialization_type = WLAN_SER_CANCEL_VDEV_HOST_SCANS; 1443 break; 1444 default: 1445 QDF_ASSERT(0); 1446 scm_warn("invalid scan_cancel_req_type: %d", type); 1447 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1448 break; 1449 } 1450 1451 return serialization_type; 1452 } 1453 1454 QDF_STATUS 1455 scm_scan_cancel_req(struct scheduler_msg *msg) 1456 { 1457 struct wlan_serialization_queued_cmd_info cmd = {0,}; 1458 struct wlan_serialization_command ser_cmd = {0,}; 1459 enum wlan_serialization_cmd_status ser_cmd_status; 1460 struct scan_cancel_request *req; 1461 QDF_STATUS status = QDF_STATUS_SUCCESS; 1462 1463 if (!msg) { 1464 scm_err("msg received is NULL"); 1465 QDF_ASSERT(0); 1466 return QDF_STATUS_E_NULL_VALUE; 1467 } 1468 if (!msg->bodyptr) { 1469 scm_err("Bodyptr is NULL"); 1470 QDF_ASSERT(0); 1471 return QDF_STATUS_E_NULL_VALUE; 1472 } 1473 1474 req = msg->bodyptr; 1475 /* 1476 * If requester wants to wait for target scan cancel event 1477 * instead of internally generated cancel event, just check 1478 * which queue this scan request belongs to and send scan 1479 * cancel request to FW accordingly. 1480 * Else generate internal scan cancel event and notify 1481 * handlers and free scan request resources. 1482 */ 1483 if (req->wait_tgt_cancel && 1484 (req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) { 1485 ser_cmd.cmd_type = WLAN_SER_CMD_SCAN; 1486 ser_cmd.cmd_id = req->cancel_req.scan_id; 1487 ser_cmd.cmd_cb = NULL; 1488 ser_cmd.umac_cmd = NULL; 1489 ser_cmd.source = WLAN_UMAC_COMP_SCAN; 1490 ser_cmd.is_high_priority = false; 1491 ser_cmd.vdev = req->vdev; 1492 if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd)) 1493 ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST; 1494 else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd)) 1495 ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST; 1496 else 1497 ser_cmd_status = WLAN_SER_CMD_NOT_FOUND; 1498 } else { 1499 cmd.requestor = 0; 1500 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1501 cmd.cmd_id = req->cancel_req.scan_id; 1502 cmd.vdev = req->vdev; 1503 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE | 1504 WLAN_SERIALIZATION_PENDING_QUEUE; 1505 cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type); 1506 1507 ser_cmd_status = wlan_serialization_cancel_request(&cmd); 1508 } 1509 1510 scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d", 1511 ser_cmd_status, req->cancel_req.requester, 1512 req->cancel_req.scan_id, req->cancel_req.vdev_id, 1513 req->cancel_req.req_type); 1514 1515 switch (ser_cmd_status) { 1516 case WLAN_SER_CMD_IN_PENDING_LIST: 1517 /* do nothing */ 1518 break; 1519 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1520 case WLAN_SER_CMDS_IN_ALL_LISTS: 1521 /* send wmi scan cancel to fw */ 1522 status = tgt_scan_cancel(req); 1523 break; 1524 case WLAN_SER_CMD_NOT_FOUND: 1525 /* do nothing */ 1526 break; 1527 default: 1528 QDF_ASSERT(0); 1529 status = QDF_STATUS_E_INVAL; 1530 break; 1531 } 1532 1533 /* Release vdev reference and scan cancel request 1534 * processing is complete 1535 */ 1536 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1537 /* Free cancel request memory */ 1538 qdf_mem_free(req); 1539 1540 return status; 1541 } 1542 1543 #ifdef FEATURE_WLAN_SCAN_PNO 1544 static QDF_STATUS 1545 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1546 struct scan_event *event) 1547 { 1548 struct scan_vdev_obj *scan_vdev_obj; 1549 struct wlan_scan_obj *scan_psoc_obj; 1550 scan_event_handler pno_cb; 1551 void *cb_arg; 1552 1553 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1554 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 1555 if (!scan_vdev_obj || !scan_psoc_obj) { 1556 scm_err("null scan_vdev_obj %pK scan_obj %pK", 1557 scan_vdev_obj, scan_psoc_obj); 1558 return QDF_STATUS_E_INVAL; 1559 } 1560 1561 switch (event->type) { 1562 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1563 if (!scan_vdev_obj->pno_match_evt_received) 1564 return QDF_STATUS_SUCCESS; 1565 qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock, 1566 WIFI_POWER_EVENT_WAKELOCK_PNO); 1567 qdf_wake_lock_timeout_acquire( 1568 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1569 SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT); 1570 qdf_runtime_pm_allow_suspend( 1571 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1572 scan_vdev_obj->pno_match_evt_received = false; 1573 break; 1574 case SCAN_EVENT_TYPE_NLO_MATCH: 1575 scan_vdev_obj->pno_match_evt_received = true; 1576 qdf_wake_lock_timeout_acquire( 1577 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1578 SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT); 1579 qdf_runtime_pm_prevent_suspend( 1580 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1581 return QDF_STATUS_SUCCESS; 1582 default: 1583 return QDF_STATUS_E_INVAL; 1584 } 1585 qdf_spin_lock_bh(&scan_psoc_obj->lock); 1586 pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func; 1587 cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg; 1588 qdf_spin_unlock_bh(&scan_psoc_obj->lock); 1589 1590 if (pno_cb) 1591 pno_cb(vdev, event, cb_arg); 1592 1593 return QDF_STATUS_SUCCESS; 1594 } 1595 #else 1596 1597 static QDF_STATUS 1598 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1599 struct scan_event *event) 1600 { 1601 return QDF_STATUS_SUCCESS; 1602 } 1603 #endif 1604 1605 /** 1606 * scm_scan_update_scan_event() - update scan event 1607 * @scan: scan object 1608 * @event: scan event 1609 * @scan_start_req: scan_start_req used for triggering scan 1610 * 1611 * update scan params in scan event 1612 * 1613 * Return: QDF_STATUS 1614 */ 1615 static QDF_STATUS 1616 scm_scan_update_scan_event(struct wlan_scan_obj *scan, 1617 struct scan_event *event, 1618 struct scan_start_request *scan_start_req) 1619 { 1620 if (!event) 1621 return QDF_STATUS_E_NULL_VALUE; 1622 1623 if (!scan || !scan_start_req) { 1624 event->scan_start_req = NULL; 1625 return QDF_STATUS_E_NULL_VALUE; 1626 } 1627 /* copy scan start request to pass back buffer */ 1628 qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req, 1629 sizeof(struct scan_start_request)); 1630 /* reset all pointers */ 1631 scan->scan_start_request_buff.scan_req.extraie.ptr = NULL; 1632 scan->scan_start_request_buff.scan_req.extraie.len = 0; 1633 scan->scan_start_request_buff.scan_req.htcap.ptr = NULL; 1634 scan->scan_start_request_buff.scan_req.htcap.len = 0; 1635 scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL; 1636 scan->scan_start_request_buff.scan_req.vhtcap.len = 0; 1637 1638 event->scan_start_req = &scan->scan_start_request_buff; 1639 1640 return QDF_STATUS_SUCCESS; 1641 } 1642 1643 static 1644 void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev, 1645 uint32_t chan_freq, uint32_t time) 1646 { 1647 struct wlan_scan_obj *scan_obj; 1648 struct chan_list_scan_info *chan_info; 1649 bool chan_found = false; 1650 uint8_t pdev_id; 1651 int i; 1652 1653 scan_obj = wlan_vdev_get_scan_obj(vdev); 1654 if (!scan_obj) 1655 return; 1656 1657 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 1658 chan_info = &scan_obj->pdev_info[pdev_id].chan_scan_info; 1659 1660 for (i = 0; i < chan_info->num_chan ; i++) { 1661 if (chan_info->ch_scan_info[i].freq == chan_freq) { 1662 chan_info->ch_scan_info[i].last_scan_time = time; 1663 scm_debug("chan freq %d scan time %u\n", 1664 chan_freq, time); 1665 chan_found = true; 1666 break; 1667 } 1668 } 1669 1670 if (!chan_found) { 1671 chan_info->ch_scan_info[chan_info->num_chan].freq = chan_freq; 1672 chan_info->ch_scan_info[chan_info->num_chan].last_scan_time = 1673 time; 1674 chan_info->num_chan++; 1675 scm_debug("chan freq %d scan time %u\n", chan_freq, time); 1676 } 1677 } 1678 1679 QDF_STATUS 1680 scm_scan_event_handler(struct scheduler_msg *msg) 1681 { 1682 struct wlan_objmgr_vdev *vdev; 1683 struct scan_event *event; 1684 struct scan_event_info *event_info; 1685 struct wlan_serialization_command cmd = {0,}; 1686 struct wlan_serialization_command *queued_cmd; 1687 struct scan_start_request *scan_start_req; 1688 struct wlan_scan_obj *scan; 1689 1690 if (!msg) { 1691 scm_err("NULL msg received "); 1692 QDF_ASSERT(0); 1693 return QDF_STATUS_E_NULL_VALUE; 1694 } 1695 if (!msg->bodyptr) { 1696 scm_err("NULL scan event received"); 1697 QDF_ASSERT(0); 1698 return QDF_STATUS_E_NULL_VALUE; 1699 } 1700 1701 event_info = msg->bodyptr; 1702 vdev = event_info->vdev; 1703 event = &(event_info->event); 1704 1705 scan = wlan_vdev_get_scan_obj(vdev); 1706 1707 scm_duration_init(scan); 1708 1709 scm_event_duration_start(scan); 1710 1711 scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d," 1712 "scanid:%d (0x%x), timestamp:%u", event->vdev_id, 1713 event->type, event->reason, event->chan_freq, 1714 event->requester, event->scan_id, event->scan_id, 1715 event->timestamp); 1716 1717 if (event->type == SCAN_EVENT_TYPE_FOREIGN_CHANNEL) 1718 scm_update_last_scan_time_per_channel( 1719 vdev, event->chan_freq, qdf_get_time_of_the_day_ms()); 1720 1721 /* 1722 * NLO requests are never queued, so post NLO events 1723 * without checking for their presence in active queue. 1724 */ 1725 switch (event->type) { 1726 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1727 case SCAN_EVENT_TYPE_NLO_MATCH: 1728 scm_pno_event_handler(vdev, event); 1729 goto exit; 1730 default: 1731 break; 1732 } 1733 1734 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1735 cmd.cmd_id = event->scan_id; 1736 cmd.cmd_cb = NULL; 1737 cmd.umac_cmd = NULL; 1738 cmd.source = WLAN_UMAC_COMP_SCAN; 1739 cmd.is_high_priority = false; 1740 cmd.vdev = vdev; 1741 if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { 1742 /* 1743 * We received scan event for an already completed/cancelled 1744 * scan request. Drop this event. 1745 */ 1746 scm_debug("Received scan event while request not in active queue"); 1747 goto exit; 1748 } 1749 1750 /* Fill scan_start_request used to trigger this scan */ 1751 queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id( 1752 wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), 1753 event->scan_id, true); 1754 1755 if (!queued_cmd) { 1756 scm_err("NULL queued_cmd"); 1757 goto exit; 1758 } 1759 if (!queued_cmd->umac_cmd) { 1760 scm_err("NULL umac_cmd"); 1761 goto exit; 1762 } 1763 scan_start_req = queued_cmd->umac_cmd; 1764 1765 if (scan_start_req->scan_req.scan_req_id != event->requester) { 1766 scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d", 1767 scan_start_req->scan_req.scan_req_id, event->requester); 1768 goto exit; 1769 } 1770 1771 if (scan) 1772 scm_scan_update_scan_event(scan, event, scan_start_req); 1773 1774 switch (event->type) { 1775 case SCAN_EVENT_TYPE_COMPLETED: 1776 if (event->reason == SCAN_REASON_COMPLETED) 1777 scm_11d_decide_country_code(vdev); 1778 /* release the command */ 1779 fallthrough; 1780 case SCAN_EVENT_TYPE_START_FAILED: 1781 case SCAN_EVENT_TYPE_DEQUEUED: 1782 scm_release_serialization_command(vdev, event->scan_id); 1783 break; 1784 default: 1785 break; 1786 } 1787 1788 scm_to_post_scan_duration_set(scan); 1789 /* Notify all interested parties */ 1790 scm_scan_post_event(vdev, event); 1791 1792 exit: 1793 /* free event info memory */ 1794 qdf_mem_free(event_info); 1795 1796 scm_event_duration_end(scan); 1797 1798 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1799 1800 return QDF_STATUS_SUCCESS; 1801 } 1802 1803 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg) 1804 { 1805 struct wlan_objmgr_vdev *vdev; 1806 struct scan_event_info *event_info; 1807 struct scan_event *event; 1808 1809 if (!msg || !msg->bodyptr) { 1810 scm_err("msg or msg->bodyptr is NULL"); 1811 return QDF_STATUS_E_NULL_VALUE; 1812 } 1813 1814 event_info = msg->bodyptr; 1815 vdev = event_info->vdev; 1816 event = &event_info->event; 1817 1818 scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d", 1819 event->vdev_id, event->type, event->reason, event->chan_freq, 1820 event->requester, event->scan_id); 1821 1822 /* free event info memory */ 1823 qdf_mem_free(event_info); 1824 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1825 1826 return QDF_STATUS_SUCCESS; 1827 } 1828 1829 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg) 1830 { 1831 struct scan_bcn_probe_event *bcn; 1832 1833 bcn = msg->bodyptr; 1834 1835 if (!bcn) { 1836 scm_err("bcn is NULL"); 1837 return QDF_STATUS_E_NULL_VALUE; 1838 } 1839 if (bcn->psoc) 1840 wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); 1841 if (bcn->rx_data) 1842 qdf_mem_free(bcn->rx_data); 1843 if (bcn->buf) 1844 qdf_nbuf_free(bcn->buf); 1845 qdf_mem_free(bcn); 1846 1847 return QDF_STATUS_SUCCESS; 1848 } 1849 1850 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg) 1851 { 1852 struct scan_start_request *req; 1853 1854 if (!msg || !msg->bodyptr) { 1855 scm_err("msg or msg->bodyptr is NULL"); 1856 return QDF_STATUS_E_NULL_VALUE; 1857 } 1858 1859 req = msg->bodyptr; 1860 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 1861 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1862 scm_scan_free_scan_request_mem(req); 1863 1864 return QDF_STATUS_SUCCESS; 1865 } 1866 1867 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg) 1868 { 1869 struct scan_cancel_request *req; 1870 1871 if (!msg || !msg->bodyptr) { 1872 scm_err("msg or msg->bodyptr is NULL"); 1873 return QDF_STATUS_E_NULL_VALUE; 1874 } 1875 1876 req = msg->bodyptr; 1877 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1878 /* Free cancel request memory */ 1879 qdf_mem_free(req); 1880 1881 return QDF_STATUS_SUCCESS; 1882 } 1883 1884 void scm_disable_obss_pdev_scan(struct wlan_objmgr_psoc *psoc, 1885 struct wlan_objmgr_pdev *pdev) 1886 { 1887 struct wlan_objmgr_vdev *vdev; 1888 struct wlan_scan_obj *scan_obj; 1889 struct scan_vdev_obj *scan_vdev_obj; 1890 QDF_STATUS status; 1891 struct wlan_objmgr_pdev_objmgr *pdev_objmgr; 1892 qdf_list_t *vdev_list; 1893 uint16_t index = 0; 1894 1895 scan_obj = wlan_psoc_get_scan_obj(psoc); 1896 if (!scan_obj) { 1897 scm_err("scan object null"); 1898 return; 1899 } 1900 1901 if (scan_obj->obss_scan_offload) { 1902 pdev_objmgr = &pdev->pdev_objmgr; 1903 1904 wlan_pdev_obj_lock(pdev); 1905 vdev_list = &pdev_objmgr->wlan_vdev_list; 1906 /* Get first vdev */ 1907 vdev = wlan_pdev_vdev_list_peek_head(vdev_list); 1908 1909 while (vdev) { 1910 scm_debug("wlan_vdev_list[%d]: %pK", index, vdev); 1911 1912 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1913 if (!scan_vdev_obj) { 1914 scm_err("null scan_vdev_obj"); 1915 goto next; 1916 } 1917 1918 status = tgt_scan_obss_disable(vdev); 1919 if (QDF_IS_STATUS_ERROR(status)) 1920 scm_err("disable obss scan failed"); 1921 next: 1922 index++; 1923 /* get next vdev */ 1924 vdev = wlan_vdev_get_next_vdev_of_pdev(vdev_list, 1925 vdev); 1926 } 1927 wlan_pdev_obj_unlock(pdev); 1928 } 1929 } 1930