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 /** 475 * scm_update_passive_dwell_time() - update dwell passive time 476 * @vdev: vdev object 477 * @req: scan request 478 * 479 * Return: None 480 */ 481 static void 482 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 483 struct scan_start_request *req) 484 { 485 struct wlan_objmgr_psoc *psoc; 486 487 psoc = wlan_vdev_get_psoc(vdev); 488 if (!psoc) 489 return; 490 491 if (policy_mgr_is_sta_connected_2g(psoc) && 492 !policy_mgr_is_hw_dbs_capable(psoc) && 493 ucfg_scan_get_bt_activity(psoc)) 494 req->scan_req.dwell_time_passive = 495 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 496 } 497 498 static const struct probe_time_dwell_time 499 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 500 {28, 11}, /* 0 SSID */ 501 {28, 20}, /* 1 SSID */ 502 {28, 20}, /* 2 SSID */ 503 {28, 20}, /* 3 SSID */ 504 {28, 20}, /* 4 SSID */ 505 {28, 20}, /* 5 SSID */ 506 {28, 20}, /* 6 SSID */ 507 {28, 11}, /* 7 SSID */ 508 {28, 11}, /* 8 SSID */ 509 {28, 11}, /* 9 SSID */ 510 {28, 8} /* 10 SSID */ 511 }; 512 513 /** 514 * scm_scan_get_burst_duration() - get burst duration depending on max chan 515 * and miracast. 516 * @max_ch_time: max channel time 517 * @miracast_enabled: if miracast is enabled 518 * 519 * Return: burst_duration 520 */ 521 static inline 522 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) 523 { 524 int burst_duration = 0; 525 526 if (miracast_enabled) { 527 /* 528 * When miracast is running, burst 529 * duration needs to be minimum to avoid 530 * any stutter or glitch in miracast 531 * during station scan 532 */ 533 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 534 burst_duration = max_ch_time; 535 else 536 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 537 } else { 538 /* 539 * If miracast is not running, accommodate max 540 * stations to make the scans faster 541 */ 542 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 543 max_ch_time; 544 545 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 546 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 547 max_ch_time; 548 549 if (channels) 550 burst_duration = channels * max_ch_time; 551 else 552 burst_duration = 553 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 554 } 555 } 556 return burst_duration; 557 } 558 559 #define SCM_ACTIVE_DWELL_TIME_NAN 60 560 #define SCM_ACTIVE_DWELL_TIME_SAP 40 561 562 /** 563 * scm_req_update_concurrency_params() - update scan req params depending on 564 * concurrent mode present. 565 * @vdev: vdev object pointer 566 * @req: scan request 567 * @scan_obj: scan object 568 * 569 * Return: void 570 */ 571 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 572 struct scan_start_request *req, 573 struct wlan_scan_obj *scan_obj) 574 { 575 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 576 struct wlan_objmgr_psoc *psoc; 577 uint16_t sap_peer_count = 0; 578 uint16_t go_peer_count = 0; 579 struct wlan_objmgr_pdev *pdev; 580 581 psoc = wlan_vdev_get_psoc(vdev); 582 pdev = wlan_vdev_get_pdev(vdev); 583 584 if (!psoc || !pdev) 585 return; 586 587 ap_present = policy_mgr_mode_specific_connection_count( 588 psoc, PM_SAP_MODE, NULL); 589 go_present = policy_mgr_mode_specific_connection_count( 590 psoc, PM_P2P_GO_MODE, NULL); 591 p2p_cli_present = policy_mgr_mode_specific_connection_count( 592 psoc, PM_P2P_CLIENT_MODE, NULL); 593 sta_active = policy_mgr_mode_specific_connection_count( 594 psoc, PM_STA_MODE, NULL); 595 ndi_present = policy_mgr_mode_specific_connection_count( 596 psoc, PM_NDI_MODE, NULL); 597 if (ap_present) 598 sap_peer_count = 599 wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); 600 if (go_present) 601 go_peer_count = 602 wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); 603 604 if (!req->scan_req.scan_f_passive) 605 scm_update_passive_dwell_time(vdev, req); 606 607 if (policy_mgr_get_connection_count(psoc)) { 608 if (!req->scan_req.scan_f_passive) 609 req->scan_req.dwell_time_active = 610 scan_obj->scan_def.conc_active_dwell; 611 /* 612 * Irrespective of any concurrency, if a scan request is 613 * triggered to get channel utilization for the current 614 * connected channel, passive scan dwell time should be 615 * MLME_GET_CHAN_STATS_PASSIVE_SCAN_TIME 616 */ 617 if (!req->scan_req.scan_f_pause_home_channel) 618 req->scan_req.dwell_time_passive = 619 scan_obj->scan_def.conc_passive_dwell; 620 req->scan_req.max_rest_time = 621 scan_obj->scan_def.conc_max_rest_time; 622 req->scan_req.min_rest_time = 623 scan_obj->scan_def.conc_min_rest_time; 624 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 625 } 626 627 if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) 628 req->scan_req.adaptive_dwell_time_mode = 629 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 630 /* 631 * If AP/GO is active and has connected clients : 632 * 1.set min rest time same as max rest time, so that 633 * firmware spends more time on home channel which will 634 * increase the probability of sending beacon at TBTT 635 * 2.if DBS is supported and SAP is not on 2g, 636 * do not reset active dwell time for 2g. 637 */ 638 639 /* 640 * For SAP, the dwell time cannot exceed 32 ms as it can't go 641 * offchannel more than 32 ms. For Go, since we 642 * advertise NOA, GO can have regular dwell time which is 40 ms. 643 */ 644 if ((ap_present && sap_peer_count) || 645 (go_present && go_peer_count)) { 646 if ((policy_mgr_is_hw_dbs_capable(psoc) && 647 policy_mgr_is_sap_go_on_2g(psoc)) || 648 !policy_mgr_is_hw_dbs_capable(psoc)) { 649 if (ap_present) 650 req->scan_req.dwell_time_active_2g = 651 QDF_MIN(req->scan_req.dwell_time_active, 652 (SCAN_CTS_DURATION_MS_MAX - 653 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 654 else 655 req->scan_req.dwell_time_active_2g = 0; 656 } 657 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 658 } 659 660 if (policy_mgr_current_concurrency_is_mcc(psoc)) 661 req->scan_req.min_rest_time = 662 scan_obj->scan_def.conc_max_rest_time; 663 664 /* 665 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell 666 * time for 2g channels instead of dwell_time_active_2g 667 */ 668 if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) 669 req->scan_req.dwell_time_active_2g = SCM_ACTIVE_DWELL_TIME_SAP; 670 671 if (req->scan_req.scan_type == SCAN_TYPE_DEFAULT) { 672 /* 673 * Decide burst_duration and dwell_time_active based on 674 * what type of devices are active. 675 */ 676 do { 677 if (ap_present && go_present && sta_active) { 678 if (req->scan_req.dwell_time_active <= 679 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 680 req->scan_req.burst_duration = 681 req->scan_req.dwell_time_active; 682 else 683 req->scan_req.burst_duration = 684 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 685 686 break; 687 } 688 689 if (scan_obj->miracast_enabled && 690 policy_mgr_is_mcc_in_24G(psoc)) 691 req->scan_req.max_rest_time = 692 scan_obj->scan_def.sta_miracast_mcc_rest_time; 693 694 if (go_present) { 695 /* 696 * Background scan while GO is sending beacons. 697 * Every off-channel transition has overhead of 698 * 2 beacon intervals for NOA. Maximize number 699 * of channels in every transition by using 700 * burst scan. 701 */ 702 if (scan_obj->scan_def.go_scan_burst_duration) 703 req->scan_req.burst_duration = 704 scan_obj-> 705 scan_def.go_scan_burst_duration; 706 else 707 req->scan_req.burst_duration = 708 scm_scan_get_burst_duration( 709 req->scan_req. 710 dwell_time_active, 711 scan_obj-> 712 miracast_enabled); 713 break; 714 } 715 if ((sta_active || p2p_cli_present)) { 716 if (scan_obj->scan_def.sta_scan_burst_duration) 717 req->scan_req.burst_duration = 718 scan_obj->scan_def. 719 sta_scan_burst_duration; 720 break; 721 } 722 723 if (go_present && sta_active) { 724 req->scan_req.burst_duration = 725 req->scan_req.dwell_time_active; 726 break; 727 } 728 729 if (ndi_present || (p2p_cli_present && sta_active)) { 730 req->scan_req.burst_duration = 0; 731 break; 732 } 733 } while (0); 734 735 if (ap_present) { 736 uint8_t ssid_num; 737 738 ssid_num = req->scan_req.num_ssids * 739 req->scan_req.num_bssid; 740 req->scan_req.repeat_probe_time = 741 scan_probe_time_dwell_time_map[ 742 QDF_MIN(ssid_num, 743 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 744 - 1)].probe_time; 745 req->scan_req.n_probes = 746 (req->scan_req.repeat_probe_time > 0) ? 747 req->scan_req.dwell_time_active / 748 req->scan_req.repeat_probe_time : 0; 749 } 750 } 751 752 if (ap_present) { 753 uint16_t ap_chan_freq; 754 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 755 756 ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 757 /* 758 * P2P/STA scan while SoftAP is sending beacons. 759 * Max duration of CTS2self is 32 ms, which limits the 760 * dwell time. 761 * If DBS is supported and: 762 * 1.if SAP is on 2G channel then keep passive 763 * dwell time default. 764 * 2.if SAP is on 5G/6G channel then update dwell time active. 765 */ 766 if (sap_peer_count) { 767 if (policy_mgr_is_hw_dbs_capable(psoc) && 768 (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) || 769 WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) { 770 req->scan_req.dwell_time_active = 771 QDF_MIN(req->scan_req.dwell_time_active, 772 (SCAN_CTS_DURATION_MS_MAX - 773 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 774 } 775 if (!policy_mgr_is_hw_dbs_capable(psoc) || 776 (policy_mgr_is_hw_dbs_capable(psoc) && 777 WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) { 778 req->scan_req.dwell_time_passive = 779 req->scan_req.dwell_time_active; 780 } 781 } 782 783 if (scan_obj->scan_def.ap_scan_burst_duration) { 784 req->scan_req.burst_duration = 785 scan_obj->scan_def.ap_scan_burst_duration; 786 } else { 787 req->scan_req.burst_duration = 0; 788 if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq)) 789 req->scan_req.burst_duration = 790 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 791 req->scan_req.dwell_time_active; 792 } 793 } 794 795 if (ndi_present) { 796 req->scan_req.dwell_time_active = 797 SCM_ACTIVE_DWELL_TIME_NAN; 798 req->scan_req.dwell_time_active_2g = 799 QDF_MIN(req->scan_req.dwell_time_active_2g, 800 SCM_ACTIVE_DWELL_TIME_NAN); 801 scm_debug("NDP active modify dwell time 2ghz %d", 802 req->scan_req.dwell_time_active_2g); 803 } 804 805 if (sta_active) { 806 req->scan_req.dwell_time_active_6g = 807 scan_obj->scan_def.active_dwell_time_6g_conc; 808 /* 809 * Irrespective of any concurrency, if a scan request is 810 * triggered to get channel utilization for the current 811 * connected channel, 6g passive scan dwell time should be 812 * MLME_GET_CHAN_STATS_WIDE_BAND_PASSIVE_SCAN_TIME 813 */ 814 if (!req->scan_req.scan_f_pause_home_channel) 815 req->scan_req.dwell_time_passive_6g = 816 scan_obj->scan_def.passive_dwell_time_6g_conc; 817 } 818 } 819 820 static inline void scm_update_5ghz_6ghz_chlist(struct scan_start_request *req, 821 qdf_freq_t intf_freq) 822 { 823 struct wlan_objmgr_psoc *psoc; 824 struct wlan_objmgr_pdev *pdev; 825 uint32_t i; 826 uint32_t num_scan_channels; 827 828 pdev = wlan_vdev_get_pdev(req->vdev); 829 if (!pdev) 830 return; 831 832 psoc = wlan_pdev_get_psoc(pdev); 833 if (!psoc) 834 return; 835 836 num_scan_channels = 0; 837 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 838 if (!WLAN_REG_IS_24GHZ_CH_FREQ( 839 req->scan_req.chan_list.chan[i].freq)) { 840 /* 841 * If no intf_freq, skip all 5 + 6 GHz freq 842 * else, skip only freq on same mac as intf_freq 843 */ 844 if (!intf_freq || 845 policy_mgr_2_freq_always_on_same_mac( 846 psoc, intf_freq, 847 req->scan_req.chan_list.chan[i].freq)) 848 continue; 849 } 850 851 req->scan_req.chan_list.chan[num_scan_channels++] = 852 req->scan_req.chan_list.chan[i]; 853 } 854 if (num_scan_channels < req->scan_req.chan_list.num_chan) 855 scm_debug("5g chan skipped (%d, %d)", 856 req->scan_req.chan_list.num_chan, num_scan_channels); 857 req->scan_req.chan_list.num_chan = num_scan_channels; 858 } 859 860 static inline void scm_update_24g_chlist(struct scan_start_request *req) 861 { 862 uint32_t i; 863 uint32_t num_scan_channels; 864 865 num_scan_channels = 0; 866 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 867 if (WLAN_REG_IS_24GHZ_CH_FREQ( 868 req->scan_req.chan_list.chan[i].freq)) 869 continue; 870 871 req->scan_req.chan_list.chan[num_scan_channels++] = 872 req->scan_req.chan_list.chan[i]; 873 } 874 if (num_scan_channels < req->scan_req.chan_list.num_chan) 875 scm_debug("2g chan skipped (%d, %d)", 876 req->scan_req.chan_list.num_chan, num_scan_channels); 877 req->scan_req.chan_list.num_chan = num_scan_channels; 878 } 879 880 /** 881 * scm_filter_6g_and_indoor_freq() - Modify channel list to skip 6Ghz and 5Ghz 882 * indoor channel if hw mode is non dbs and SAP is present 883 * @pdev: pointer to pdev 884 * @req: scan request 885 * 886 * Return: None 887 */ 888 static void scm_filter_6g_and_indoor_freq(struct wlan_objmgr_pdev *pdev, 889 struct scan_start_request *req) 890 { 891 uint32_t i; 892 uint32_t num_scan_channels; 893 qdf_freq_t freq; 894 895 num_scan_channels = 0; 896 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 897 freq = req->scan_req.chan_list.chan[i].freq; 898 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) 899 continue; 900 901 if (wlan_reg_is_freq_indoor(pdev, freq)) 902 continue; 903 904 req->scan_req.chan_list.chan[num_scan_channels++] = 905 req->scan_req.chan_list.chan[i]; 906 } 907 if (num_scan_channels < req->scan_req.chan_list.num_chan) 908 scm_debug("6g and indoor channel chan skipped (%d, %d)", 909 req->scan_req.chan_list.num_chan, num_scan_channels); 910 req->scan_req.chan_list.num_chan = num_scan_channels; 911 } 912 913 /** 914 * scm_scan_chlist_concurrency_modify() - modify chan list to skip 5G if 915 * required 916 * @vdev: vdev object 917 * @req: scan request 918 * 919 * Check and skip 5G chan list based on DFS AP present and current hw mode. 920 * 921 * Return: void 922 */ 923 static inline void scm_scan_chlist_concurrency_modify( 924 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 925 { 926 struct wlan_objmgr_psoc *psoc; 927 struct wlan_objmgr_pdev *pdev; 928 struct wlan_scan_obj *scan_obj; 929 uint16_t trim; 930 qdf_freq_t dfs_ap_freq; 931 932 pdev = wlan_vdev_get_pdev(vdev); 933 if (!pdev) 934 return; 935 936 psoc = wlan_pdev_get_psoc(pdev); 937 if (!psoc) 938 return; 939 940 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 941 if (!scan_obj) 942 return; 943 944 /* do this only for STA and P2P-CLI mode */ 945 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 946 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 947 return; 948 949 if (policy_mgr_scan_trim_5g_chnls_for_dfs_ap(psoc, &dfs_ap_freq)) 950 scm_update_5ghz_6ghz_chlist(req, dfs_ap_freq); 951 952 if (scan_obj->scan_def.conc_chlist_trim) { 953 trim = policy_mgr_scan_trim_chnls_for_connected_ap(pdev); 954 if (trim & TRIM_CHANNEL_LIST_5G) 955 scm_update_5ghz_6ghz_chlist(req, 0); 956 if (trim & TRIM_CHANNEL_LIST_24G) 957 scm_update_24g_chlist(req); 958 } 959 960 /* 961 * Do not allow STA to scan on 6Ghz or indoor channel for non dbs 962 * hardware if SAP and skip_6g_and_indoor_freq_scan ini are present 963 */ 964 if (scan_obj->scan_def.skip_6g_and_indoor_freq && 965 !policy_mgr_is_hw_dbs_capable(psoc) && 966 (wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 967 policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL)) 968 scm_filter_6g_and_indoor_freq(pdev, req); 969 970 } 971 #else 972 static inline 973 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 974 struct scan_start_request *req, 975 struct wlan_scan_obj *scan_obj) 976 { 977 } 978 979 static inline void 980 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 981 { 982 } 983 984 static inline void scm_scan_chlist_concurrency_modify( 985 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 986 { 987 } 988 #endif 989 990 /** 991 * scm_update_channel_list() - update scan req params depending on dfs inis 992 * and initial scan request. 993 * @req: scan request 994 * @scan_obj: scan object 995 * 996 * Return: void 997 */ 998 static void 999 scm_update_channel_list(struct scan_start_request *req, 1000 struct wlan_scan_obj *scan_obj) 1001 { 1002 uint8_t i; 1003 uint8_t num_scan_channels = 0; 1004 struct scan_vdev_obj *scan_vdev_obj; 1005 struct wlan_objmgr_pdev *pdev; 1006 bool first_scan_done = true; 1007 bool p2p_search = false; 1008 bool skip_dfs_ch = true; 1009 uint32_t first_freq; 1010 1011 pdev = wlan_vdev_get_pdev(req->vdev); 1012 1013 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 1014 if (!scan_vdev_obj) { 1015 scm_err("null scan_vdev_obj"); 1016 return; 1017 } 1018 1019 if (!scan_vdev_obj->first_scan_done) { 1020 first_scan_done = false; 1021 scan_vdev_obj->first_scan_done = true; 1022 } 1023 1024 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH) 1025 p2p_search = true; 1026 /* 1027 * No need to update channels if req is single channel* ie ROC, 1028 * Preauth or a single channel scan etc. 1029 * If the single chan in the scan channel list is an NOL channel,it is 1030 * removed and it would reduce the number of scan channels to 0. 1031 */ 1032 first_freq = req->scan_req.chan_list.chan[0].freq; 1033 if ((req->scan_req.chan_list.num_chan == 1) && 1034 (!utils_dfs_is_freq_in_nol(pdev, first_freq))) 1035 return; 1036 1037 /* do this only for STA and P2P-CLI mode */ 1038 if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 1039 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) && 1040 !p2p_search) 1041 skip_dfs_ch = false; 1042 1043 if ((scan_obj->scan_def.allow_dfs_chan_in_scan && 1044 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 1045 first_scan_done)) && 1046 !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search) && 1047 !scan_obj->miracast_enabled) 1048 skip_dfs_ch = false; 1049 1050 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 1051 uint32_t freq; 1052 1053 freq = req->scan_req.chan_list.chan[i].freq; 1054 if ((wlan_reg_is_6ghz_chan_freq(freq) && 1055 !wlan_reg_is_6ghz_band_set(pdev))) { 1056 scm_nofl_debug("Skip 6 GHz freq = %d", freq); 1057 continue; 1058 } 1059 if (skip_dfs_ch && 1060 wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) { 1061 scm_nofl_debug("Skip DFS freq %d", freq); 1062 continue; 1063 } 1064 if (utils_dfs_is_freq_in_nol(pdev, freq)) { 1065 scm_nofl_debug("Skip NOL freq %d", freq); 1066 continue; 1067 } 1068 1069 req->scan_req.chan_list.chan[num_scan_channels++] = 1070 req->scan_req.chan_list.chan[i]; 1071 } 1072 1073 req->scan_req.chan_list.num_chan = num_scan_channels; 1074 1075 scm_update_6ghz_channel_list(req, scan_obj); 1076 scm_scan_chlist_concurrency_modify(req->vdev, req); 1077 } 1078 1079 /** 1080 * scm_req_update_dwell_time_as_per_scan_mode() - update scan req params 1081 * dwell time as per scan mode. 1082 * @vdev: vdev to update 1083 * @req: scan request 1084 * 1085 * Return: void 1086 */ 1087 static void 1088 scm_req_update_dwell_time_as_per_scan_mode( 1089 struct wlan_objmgr_vdev *vdev, 1090 struct scan_start_request *req) 1091 { 1092 struct wlan_objmgr_psoc *psoc; 1093 1094 psoc = wlan_vdev_get_psoc(vdev); 1095 1096 if (req->scan_req.scan_policy_low_span && 1097 wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 1098 req->scan_req.adaptive_dwell_time_mode = 1099 SCAN_DWELL_MODE_STATIC; 1100 req->scan_req.dwell_time_active = 1101 QDF_MIN(req->scan_req.dwell_time_active, 1102 LOW_SPAN_ACTIVE_DWELL_TIME); 1103 req->scan_req.dwell_time_active_2g = 1104 QDF_MIN(req->scan_req.dwell_time_active_2g, 1105 LOW_SPAN_ACTIVE_DWELL_TIME); 1106 req->scan_req.dwell_time_passive = 1107 QDF_MIN(req->scan_req.dwell_time_passive, 1108 LOW_SPAN_PASSIVE_DWELL_TIME); 1109 } 1110 } 1111 1112 /** 1113 * scm_update_aux_scan_ctrl_ext_flag() - update aux scan policy 1114 * @req: pointer to scan request 1115 * 1116 * Set aux scan bits in scan_ctrl_ext_flag value depending on scan type. 1117 * 1118 * Return: None 1119 */ 1120 1121 static void 1122 scm_update_aux_scan_ctrl_ext_flag(struct scan_start_request *req) 1123 { 1124 if (req->scan_req.scan_policy_low_span) 1125 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_AUX_FAST_SCAN; 1126 else if (req->scan_req.scan_policy_low_power) 1127 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_AUX_FAST_SCAN; 1128 else if (req->scan_req.scan_policy_high_accuracy) 1129 req->scan_req.scan_ctrl_flags_ext |= 1130 SCAN_FLAG_EXT_AUX_RELIABLE_SCAN; 1131 } 1132 1133 /** 1134 * scm_scan_req_update_params() - update scan req params depending on modes 1135 * and scan type. 1136 * @vdev: vdev object pointer 1137 * @req: scan request 1138 * @scan_obj: scan object 1139 * 1140 * Return: void 1141 */ 1142 static void 1143 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 1144 struct scan_start_request *req, 1145 struct wlan_scan_obj *scan_obj) 1146 { 1147 struct chan_list *custom_chan_list; 1148 struct wlan_objmgr_pdev *pdev; 1149 uint8_t pdev_id; 1150 struct wlan_objmgr_psoc *psoc; 1151 1152 /* Ensure correct number of probes are sent on active channel */ 1153 if (!req->scan_req.repeat_probe_time) 1154 req->scan_req.repeat_probe_time = 1155 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 1156 1157 if (req->scan_req.scan_f_passive) 1158 req->scan_req.scan_ctrl_flags_ext |= 1159 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 1160 1161 if (!req->scan_req.n_probes) 1162 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 1163 req->scan_req.dwell_time_active / 1164 req->scan_req.repeat_probe_time : 0; 1165 1166 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH || 1167 req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1168 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 1169 req->scan_req.dwell_time_active_2g = 0; 1170 if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1171 req->scan_req.repeat_probe_time = 0; 1172 } else { 1173 req->scan_req.scan_f_filter_prb_req = true; 1174 if (!req->scan_req.num_ssids) 1175 req->scan_req.scan_f_bcast_probe = true; 1176 1177 req->scan_req.dwell_time_active += 1178 P2P_SEARCH_DWELL_TIME_INC; 1179 /* 1180 * 3 channels with default max dwell time 40 ms. 1181 * Cap limit will be set by 1182 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 1183 * should be such that no channel is scanned less 1184 * than the dwell time in normal scenarios. 1185 */ 1186 if (req->scan_req.chan_list.num_chan == 1187 WLAN_P2P_SOCIAL_CHANNELS && 1188 !scan_obj->miracast_enabled) 1189 req->scan_req.repeat_probe_time = 1190 req->scan_req.dwell_time_active / 5; 1191 else 1192 req->scan_req.repeat_probe_time = 1193 req->scan_req.dwell_time_active / 3; 1194 if (scan_obj->scan_def.p2p_scan_burst_duration) { 1195 req->scan_req.burst_duration = 1196 scan_obj->scan_def. 1197 p2p_scan_burst_duration; 1198 } else { 1199 req->scan_req.burst_duration = 1200 BURST_SCAN_MAX_NUM_OFFCHANNELS * 1201 req->scan_req.dwell_time_active; 1202 if (req->scan_req.burst_duration > 1203 P2P_SCAN_MAX_BURST_DURATION) { 1204 uint8_t channels = 1205 P2P_SCAN_MAX_BURST_DURATION / 1206 req->scan_req.dwell_time_active; 1207 if (channels) 1208 req->scan_req.burst_duration = 1209 channels * 1210 req->scan_req.dwell_time_active; 1211 else 1212 req->scan_req.burst_duration = 1213 P2P_SCAN_MAX_BURST_DURATION; 1214 } 1215 } 1216 req->scan_req.scan_ev_bss_chan = false; 1217 } 1218 } else { 1219 req->scan_req.scan_f_cck_rates = true; 1220 if (!req->scan_req.num_ssids) 1221 req->scan_req.scan_f_bcast_probe = true; 1222 req->scan_req.scan_f_add_ds_ie_in_probe = true; 1223 req->scan_req.scan_f_filter_prb_req = true; 1224 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 1225 } 1226 1227 scm_update_dbs_scan_ctrl_ext_flag(req); 1228 1229 psoc = wlan_vdev_get_psoc(vdev); 1230 if (wlan_scan_get_aux_support(psoc)) 1231 scm_update_aux_scan_ctrl_ext_flag(req); 1232 1233 /* 1234 * No need to update conncurrency parmas if req is passive scan on 1235 * single channel ie ROC, Preauth etc 1236 */ 1237 if (!(req->scan_req.scan_f_passive && 1238 req->scan_req.chan_list.num_chan == 1) && 1239 req->scan_req.scan_type != SCAN_TYPE_RRM) 1240 scm_req_update_concurrency_params(vdev, req, scan_obj); 1241 1242 if (req->scan_req.scan_type == SCAN_TYPE_RRM) 1243 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_RRM_SCAN_IND; 1244 1245 scm_req_update_dwell_time_as_per_scan_mode(vdev, req); 1246 1247 scm_debug("scan_ctrl_flags_ext %0x", req->scan_req.scan_ctrl_flags_ext); 1248 /* 1249 * Set wide band flag if enabled. This will cause 1250 * phymode TLV being sent to FW. 1251 */ 1252 pdev = wlan_vdev_get_pdev(vdev); 1253 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1254 /* 1255 * Trigger wide band scan also if 1256 * scan_f_report_cca_busy_for_each_20mhz flag is set 1257 */ 1258 if (ucfg_scan_get_wide_band_scan(pdev) || 1259 req->scan_req.scan_f_report_cca_busy_for_each_20mhz) 1260 req->scan_req.scan_f_wide_band = true; 1261 else 1262 req->scan_req.scan_f_wide_band = false; 1263 1264 /* 1265 * Overwrite scan channels with custom scan channel 1266 * list if configured. 1267 */ 1268 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 1269 if (custom_chan_list->num_chan) 1270 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 1271 sizeof(struct chan_list)); 1272 else if (!req->scan_req.chan_list.num_chan) 1273 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 1274 1275 scm_update_channel_list(req, scan_obj); 1276 1277 wlan_scan_update_low_latency_profile_chnlist(vdev, req); 1278 } 1279 1280 static inline void scm_print_scan_req_info(struct scan_req_params *req) 1281 { 1282 uint32_t buff_len; 1283 char *chan_buff; 1284 uint32_t len = 0; 1285 uint8_t buff_size, idx, count = 0; 1286 struct chan_list *chan_lst; 1287 #define MAX_SCAN_FREQ_TO_PRINT 25 1288 1289 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", 1290 req->scan_id, req->vdev_id, req->dwell_time_active, 1291 req->dwell_time_passive, req->dwell_time_active_2g, 1292 req->dwell_time_active_6g, req->dwell_time_passive_6g, 1293 req->repeat_probe_time, req->n_probes, req->scan_flags, 1294 req->scan_ctrl_flags_ext, req->scan_events, 1295 req->scan_policy_type, req->scan_f_wide_band, 1296 req->scan_priority); 1297 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", 1298 req->scan_type, req->min_rest_time, req->max_rest_time, 1299 req->probe_spacing_time, req->idle_time, 1300 req->probe_delay, req->scan_offset_time, 1301 req->burst_duration, req->adaptive_dwell_time_mode); 1302 1303 for (idx = 0; idx < req->num_ssids; idx++) 1304 scm_nofl_debug("SSID[%d]: " QDF_SSID_FMT, idx, 1305 QDF_SSID_REF(req->ssid[idx].length, 1306 req->ssid[idx].ssid)); 1307 1308 chan_lst = &req->chan_list; 1309 1310 if (!chan_lst->num_chan) 1311 return; 1312 1313 /* 1314 * Buffer of (num channel * buff_size) + 1 to consider the 4 char freq, 1315 * 6 char flags and 1 space after it for each channel and 1 to end the 1316 * string with NULL. 1317 * In case of wide band scan extra 4 char for phymode. 1318 */ 1319 if (req->scan_f_wide_band) 1320 buff_size = 15; 1321 else 1322 buff_size = 11; 1323 1324 buff_len = (QDF_MIN(MAX_SCAN_FREQ_TO_PRINT, 1325 chan_lst->num_chan) * buff_size) + 1; 1326 1327 chan_buff = qdf_mem_malloc(buff_len); 1328 if (!chan_buff) 1329 return; 1330 1331 scm_nofl_debug("Total freq %d", chan_lst->num_chan); 1332 for (idx = 0; idx < chan_lst->num_chan; idx++) { 1333 if (req->scan_f_wide_band) 1334 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1335 "%d(0x%02x)[%d] ", 1336 chan_lst->chan[idx].freq, 1337 chan_lst->chan[idx].flags, 1338 chan_lst->chan[idx].phymode); 1339 else 1340 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1341 "%d(0x%02x) ", 1342 chan_lst->chan[idx].freq, 1343 chan_lst->chan[idx].flags); 1344 1345 count++; 1346 if (count >= MAX_SCAN_FREQ_TO_PRINT) { 1347 /* Print the MAX_SCAN_FREQ_TO_PRINT channels */ 1348 scm_nofl_debug("Freq list: %s", chan_buff); 1349 len = 0; 1350 count = 0; 1351 } 1352 } 1353 if (len) 1354 scm_nofl_debug("Freq list: %s", chan_buff); 1355 1356 qdf_mem_free(chan_buff); 1357 } 1358 QDF_STATUS 1359 scm_scan_start_req(struct scheduler_msg *msg) 1360 { 1361 struct wlan_serialization_command cmd = {0, }; 1362 enum wlan_serialization_status ser_cmd_status; 1363 struct scan_start_request *req = NULL; 1364 struct wlan_scan_obj *scan_obj; 1365 QDF_STATUS status = QDF_STATUS_SUCCESS; 1366 1367 1368 if (!msg) { 1369 scm_err("msg received is NULL"); 1370 QDF_ASSERT(0); 1371 return QDF_STATUS_E_NULL_VALUE; 1372 } 1373 if (!msg->bodyptr) { 1374 scm_err("bodyptr is NULL"); 1375 QDF_ASSERT(0); 1376 return QDF_STATUS_E_NULL_VALUE; 1377 } 1378 1379 req = msg->bodyptr; 1380 1381 if (!scm_is_scan_allowed(req->vdev)) { 1382 scm_err("scan disabled, rejecting the scan req"); 1383 status = QDF_STATUS_E_NULL_VALUE; 1384 goto err; 1385 } 1386 1387 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 1388 if (!scan_obj) { 1389 scm_debug("Couldn't find scan object"); 1390 status = QDF_STATUS_E_NULL_VALUE; 1391 goto err; 1392 } 1393 1394 scm_scan_req_update_params(req->vdev, req, scan_obj); 1395 scm_print_scan_req_info(&req->scan_req); 1396 1397 if (!req->scan_req.chan_list.num_chan) { 1398 scm_info("Reject 0 channel Scan"); 1399 status = QDF_STATUS_E_NULL_VALUE; 1400 goto err; 1401 } 1402 1403 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1404 cmd.cmd_id = req->scan_req.scan_id; 1405 cmd.cmd_cb = scm_scan_serialize_callback; 1406 cmd.umac_cmd = req; 1407 cmd.source = WLAN_UMAC_COMP_SCAN; 1408 cmd.is_high_priority = false; 1409 cmd.cmd_timeout_duration = req->scan_req.max_scan_time + 1410 SCAN_TIMEOUT_GRACE_PERIOD; 1411 cmd.vdev = req->vdev; 1412 1413 if (scan_obj->disable_timeout) 1414 cmd.cmd_timeout_duration = 0; 1415 1416 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION, 1417 WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id, 1418 req->scan_req.scan_id); 1419 1420 ser_cmd_status = wlan_serialization_request(&cmd); 1421 switch (ser_cmd_status) { 1422 case WLAN_SER_CMD_PENDING: 1423 /* command moved to pending list.Do nothing */ 1424 break; 1425 case WLAN_SER_CMD_ACTIVE: 1426 /* command moved to active list. Do nothing */ 1427 break; 1428 default: 1429 scm_debug("ser cmd status %d", ser_cmd_status); 1430 goto err; 1431 } 1432 1433 return status; 1434 err: 1435 /* 1436 * notify registered scan event handlers 1437 * about internal error 1438 */ 1439 scm_post_internal_scan_complete_event(req, 1440 SCAN_REASON_INTERNAL_FAILURE); 1441 /* 1442 * cmd can't be serviced. 1443 * release vdev reference and free scan_start_request memory 1444 */ 1445 if (req) { 1446 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1447 scm_scan_free_scan_request_mem(req); 1448 } 1449 1450 return status; 1451 } 1452 1453 static inline enum wlan_serialization_cancel_type 1454 get_serialization_cancel_type(enum scan_cancel_req_type type) 1455 { 1456 enum wlan_serialization_cancel_type serialization_type; 1457 1458 switch (type) { 1459 case WLAN_SCAN_CANCEL_SINGLE: 1460 serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN; 1461 break; 1462 case WLAN_SCAN_CANCEL_VDEV_ALL: 1463 serialization_type = WLAN_SER_CANCEL_VDEV_SCANS; 1464 break; 1465 case WLAN_SCAN_CANCEL_PDEV_ALL: 1466 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1467 break; 1468 case WLAN_SCAN_CANCEL_HOST_VDEV_ALL: 1469 serialization_type = WLAN_SER_CANCEL_VDEV_HOST_SCANS; 1470 break; 1471 default: 1472 QDF_ASSERT(0); 1473 scm_warn("invalid scan_cancel_req_type: %d", type); 1474 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1475 break; 1476 } 1477 1478 return serialization_type; 1479 } 1480 1481 QDF_STATUS 1482 scm_scan_cancel_req(struct scheduler_msg *msg) 1483 { 1484 struct wlan_serialization_queued_cmd_info cmd = {0,}; 1485 struct wlan_serialization_command ser_cmd = {0,}; 1486 enum wlan_serialization_cmd_status ser_cmd_status; 1487 struct scan_cancel_request *req; 1488 QDF_STATUS status = QDF_STATUS_SUCCESS; 1489 1490 if (!msg) { 1491 scm_err("msg received is NULL"); 1492 QDF_ASSERT(0); 1493 return QDF_STATUS_E_NULL_VALUE; 1494 } 1495 if (!msg->bodyptr) { 1496 scm_err("Bodyptr is NULL"); 1497 QDF_ASSERT(0); 1498 return QDF_STATUS_E_NULL_VALUE; 1499 } 1500 1501 req = msg->bodyptr; 1502 /* 1503 * If requester wants to wait for target scan cancel event 1504 * instead of internally generated cancel event, just check 1505 * which queue this scan request belongs to and send scan 1506 * cancel request to FW accordingly. 1507 * Else generate internal scan cancel event and notify 1508 * handlers and free scan request resources. 1509 */ 1510 if (req->wait_tgt_cancel && 1511 (req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) { 1512 ser_cmd.cmd_type = WLAN_SER_CMD_SCAN; 1513 ser_cmd.cmd_id = req->cancel_req.scan_id; 1514 ser_cmd.cmd_cb = NULL; 1515 ser_cmd.umac_cmd = NULL; 1516 ser_cmd.source = WLAN_UMAC_COMP_SCAN; 1517 ser_cmd.is_high_priority = false; 1518 ser_cmd.vdev = req->vdev; 1519 if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd)) 1520 ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST; 1521 else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd)) 1522 ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST; 1523 else 1524 ser_cmd_status = WLAN_SER_CMD_NOT_FOUND; 1525 } else { 1526 cmd.requestor = 0; 1527 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1528 cmd.cmd_id = req->cancel_req.scan_id; 1529 cmd.vdev = req->vdev; 1530 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE | 1531 WLAN_SERIALIZATION_PENDING_QUEUE; 1532 cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type); 1533 1534 ser_cmd_status = wlan_serialization_cancel_request(&cmd); 1535 } 1536 1537 scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d", 1538 ser_cmd_status, req->cancel_req.requester, 1539 req->cancel_req.scan_id, req->cancel_req.vdev_id, 1540 req->cancel_req.req_type); 1541 1542 switch (ser_cmd_status) { 1543 case WLAN_SER_CMD_IN_PENDING_LIST: 1544 /* do nothing */ 1545 break; 1546 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1547 case WLAN_SER_CMDS_IN_ALL_LISTS: 1548 /* send wmi scan cancel to fw */ 1549 status = tgt_scan_cancel(req); 1550 break; 1551 case WLAN_SER_CMD_NOT_FOUND: 1552 /* do nothing */ 1553 break; 1554 default: 1555 QDF_ASSERT(0); 1556 status = QDF_STATUS_E_INVAL; 1557 break; 1558 } 1559 1560 /* Release vdev reference and scan cancel request 1561 * processing is complete 1562 */ 1563 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1564 /* Free cancel request memory */ 1565 qdf_mem_free(req); 1566 1567 return status; 1568 } 1569 1570 #ifdef FEATURE_WLAN_SCAN_PNO 1571 static QDF_STATUS 1572 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1573 struct scan_event *event) 1574 { 1575 struct scan_vdev_obj *scan_vdev_obj; 1576 struct wlan_scan_obj *scan_psoc_obj; 1577 scan_event_handler pno_cb; 1578 void *cb_arg; 1579 1580 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1581 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 1582 if (!scan_vdev_obj || !scan_psoc_obj) { 1583 scm_err("null scan_vdev_obj %pK scan_obj %pK", 1584 scan_vdev_obj, scan_psoc_obj); 1585 return QDF_STATUS_E_INVAL; 1586 } 1587 1588 switch (event->type) { 1589 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1590 if (!scan_vdev_obj->pno_match_evt_received) 1591 return QDF_STATUS_SUCCESS; 1592 qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock, 1593 WIFI_POWER_EVENT_WAKELOCK_PNO); 1594 qdf_wake_lock_timeout_acquire( 1595 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1596 SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT); 1597 qdf_runtime_pm_allow_suspend( 1598 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1599 scan_vdev_obj->pno_match_evt_received = false; 1600 break; 1601 case SCAN_EVENT_TYPE_NLO_MATCH: 1602 scan_vdev_obj->pno_match_evt_received = true; 1603 qdf_wake_lock_timeout_acquire( 1604 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1605 SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT); 1606 qdf_runtime_pm_prevent_suspend( 1607 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1608 return QDF_STATUS_SUCCESS; 1609 default: 1610 return QDF_STATUS_E_INVAL; 1611 } 1612 qdf_spin_lock_bh(&scan_psoc_obj->lock); 1613 pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func; 1614 cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg; 1615 qdf_spin_unlock_bh(&scan_psoc_obj->lock); 1616 1617 if (pno_cb) 1618 pno_cb(vdev, event, cb_arg); 1619 1620 return QDF_STATUS_SUCCESS; 1621 } 1622 #else 1623 1624 static QDF_STATUS 1625 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1626 struct scan_event *event) 1627 { 1628 return QDF_STATUS_SUCCESS; 1629 } 1630 #endif 1631 1632 /** 1633 * scm_scan_update_scan_event() - update scan event 1634 * @scan: scan object 1635 * @event: scan event 1636 * @scan_start_req: scan_start_req used for triggering scan 1637 * 1638 * update scan params in scan event 1639 * 1640 * Return: QDF_STATUS 1641 */ 1642 static QDF_STATUS 1643 scm_scan_update_scan_event(struct wlan_scan_obj *scan, 1644 struct scan_event *event, 1645 struct scan_start_request *scan_start_req) 1646 { 1647 if (!event) 1648 return QDF_STATUS_E_NULL_VALUE; 1649 1650 if (!scan || !scan_start_req) { 1651 event->scan_start_req = NULL; 1652 return QDF_STATUS_E_NULL_VALUE; 1653 } 1654 /* copy scan start request to pass back buffer */ 1655 qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req, 1656 sizeof(struct scan_start_request)); 1657 /* reset all pointers */ 1658 scan->scan_start_request_buff.scan_req.extraie.ptr = NULL; 1659 scan->scan_start_request_buff.scan_req.extraie.len = 0; 1660 scan->scan_start_request_buff.scan_req.htcap.ptr = NULL; 1661 scan->scan_start_request_buff.scan_req.htcap.len = 0; 1662 scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL; 1663 scan->scan_start_request_buff.scan_req.vhtcap.len = 0; 1664 1665 event->scan_start_req = &scan->scan_start_request_buff; 1666 1667 return QDF_STATUS_SUCCESS; 1668 } 1669 1670 static 1671 void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev, 1672 uint32_t chan_freq, uint32_t time) 1673 { 1674 struct wlan_scan_obj *scan_obj; 1675 struct chan_list_scan_info *chan_info; 1676 bool chan_found = false; 1677 uint8_t pdev_id; 1678 int i; 1679 1680 scan_obj = wlan_vdev_get_scan_obj(vdev); 1681 if (!scan_obj) 1682 return; 1683 1684 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 1685 chan_info = &scan_obj->pdev_info[pdev_id].chan_scan_info; 1686 1687 for (i = 0; i < chan_info->num_chan ; i++) { 1688 if (chan_info->ch_scan_info[i].freq == chan_freq) { 1689 chan_info->ch_scan_info[i].last_scan_time = time; 1690 scm_debug("chan freq %d scan time %u\n", 1691 chan_freq, time); 1692 chan_found = true; 1693 break; 1694 } 1695 } 1696 1697 if (!chan_found) { 1698 chan_info->ch_scan_info[chan_info->num_chan].freq = chan_freq; 1699 chan_info->ch_scan_info[chan_info->num_chan].last_scan_time = 1700 time; 1701 chan_info->num_chan++; 1702 scm_debug("chan freq %d scan time %u\n", chan_freq, time); 1703 } 1704 } 1705 1706 QDF_STATUS 1707 scm_scan_event_handler(struct scheduler_msg *msg) 1708 { 1709 struct wlan_objmgr_vdev *vdev; 1710 struct scan_event *event; 1711 struct scan_event_info *event_info; 1712 struct wlan_serialization_command cmd = {0,}; 1713 struct wlan_serialization_command *queued_cmd; 1714 struct scan_start_request *scan_start_req; 1715 struct wlan_scan_obj *scan; 1716 1717 if (!msg) { 1718 scm_err("NULL msg received "); 1719 QDF_ASSERT(0); 1720 return QDF_STATUS_E_NULL_VALUE; 1721 } 1722 if (!msg->bodyptr) { 1723 scm_err("NULL scan event received"); 1724 QDF_ASSERT(0); 1725 return QDF_STATUS_E_NULL_VALUE; 1726 } 1727 1728 event_info = msg->bodyptr; 1729 vdev = event_info->vdev; 1730 event = &(event_info->event); 1731 1732 scan = wlan_vdev_get_scan_obj(vdev); 1733 1734 scm_duration_init(scan); 1735 1736 scm_event_duration_start(scan); 1737 1738 scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d," 1739 "scanid:%d (0x%x), timestamp:%u", event->vdev_id, 1740 event->type, event->reason, event->chan_freq, 1741 event->requester, event->scan_id, event->scan_id, 1742 event->timestamp); 1743 1744 if (event->type == SCAN_EVENT_TYPE_FOREIGN_CHANNEL) 1745 scm_update_last_scan_time_per_channel( 1746 vdev, event->chan_freq, qdf_get_time_of_the_day_ms()); 1747 1748 /* 1749 * NLO requests are never queued, so post NLO events 1750 * without checking for their presence in active queue. 1751 */ 1752 switch (event->type) { 1753 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1754 case SCAN_EVENT_TYPE_NLO_MATCH: 1755 scm_pno_event_handler(vdev, event); 1756 goto exit; 1757 default: 1758 break; 1759 } 1760 1761 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1762 cmd.cmd_id = event->scan_id; 1763 cmd.cmd_cb = NULL; 1764 cmd.umac_cmd = NULL; 1765 cmd.source = WLAN_UMAC_COMP_SCAN; 1766 cmd.is_high_priority = false; 1767 cmd.vdev = vdev; 1768 if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { 1769 /* 1770 * We received scan event for an already completed/cancelled 1771 * scan request. Drop this event. 1772 */ 1773 scm_debug("Received scan event while request not in active queue"); 1774 goto exit; 1775 } 1776 1777 /* Fill scan_start_request used to trigger this scan */ 1778 queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id( 1779 wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), 1780 event->scan_id, true); 1781 1782 if (!queued_cmd) { 1783 scm_err("NULL queued_cmd"); 1784 goto exit; 1785 } 1786 if (!queued_cmd->umac_cmd) { 1787 scm_err("NULL umac_cmd"); 1788 goto exit; 1789 } 1790 scan_start_req = queued_cmd->umac_cmd; 1791 1792 if (scan_start_req->scan_req.scan_req_id != event->requester) { 1793 scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d", 1794 scan_start_req->scan_req.scan_req_id, event->requester); 1795 goto exit; 1796 } 1797 1798 if (scan) 1799 scm_scan_update_scan_event(scan, event, scan_start_req); 1800 1801 switch (event->type) { 1802 case SCAN_EVENT_TYPE_COMPLETED: 1803 if (event->reason == SCAN_REASON_COMPLETED) 1804 scm_11d_decide_country_code(vdev); 1805 /* release the command */ 1806 fallthrough; 1807 case SCAN_EVENT_TYPE_START_FAILED: 1808 case SCAN_EVENT_TYPE_DEQUEUED: 1809 scm_release_serialization_command(vdev, event->scan_id); 1810 break; 1811 default: 1812 break; 1813 } 1814 1815 scm_to_post_scan_duration_set(scan); 1816 /* Notify all interested parties */ 1817 scm_scan_post_event(vdev, event); 1818 1819 exit: 1820 /* free event info memory */ 1821 qdf_mem_free(event_info); 1822 1823 scm_event_duration_end(scan); 1824 1825 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1826 1827 return QDF_STATUS_SUCCESS; 1828 } 1829 1830 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg) 1831 { 1832 struct wlan_objmgr_vdev *vdev; 1833 struct scan_event_info *event_info; 1834 struct scan_event *event; 1835 1836 if (!msg || !msg->bodyptr) { 1837 scm_err("msg or msg->bodyptr is NULL"); 1838 return QDF_STATUS_E_NULL_VALUE; 1839 } 1840 1841 event_info = msg->bodyptr; 1842 vdev = event_info->vdev; 1843 event = &event_info->event; 1844 1845 scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d", 1846 event->vdev_id, event->type, event->reason, event->chan_freq, 1847 event->requester, event->scan_id); 1848 1849 /* free event info memory */ 1850 qdf_mem_free(event_info); 1851 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1852 1853 return QDF_STATUS_SUCCESS; 1854 } 1855 1856 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg) 1857 { 1858 struct scan_bcn_probe_event *bcn; 1859 1860 bcn = msg->bodyptr; 1861 1862 if (!bcn) { 1863 scm_err("bcn is NULL"); 1864 return QDF_STATUS_E_NULL_VALUE; 1865 } 1866 if (bcn->psoc) 1867 wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); 1868 if (bcn->rx_data) 1869 qdf_mem_free(bcn->rx_data); 1870 if (bcn->buf) 1871 qdf_nbuf_free(bcn->buf); 1872 qdf_mem_free(bcn); 1873 1874 return QDF_STATUS_SUCCESS; 1875 } 1876 1877 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg) 1878 { 1879 struct scan_start_request *req; 1880 1881 if (!msg || !msg->bodyptr) { 1882 scm_err("msg or msg->bodyptr is NULL"); 1883 return QDF_STATUS_E_NULL_VALUE; 1884 } 1885 1886 req = msg->bodyptr; 1887 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 1888 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1889 scm_scan_free_scan_request_mem(req); 1890 1891 return QDF_STATUS_SUCCESS; 1892 } 1893 1894 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg) 1895 { 1896 struct scan_cancel_request *req; 1897 1898 if (!msg || !msg->bodyptr) { 1899 scm_err("msg or msg->bodyptr is NULL"); 1900 return QDF_STATUS_E_NULL_VALUE; 1901 } 1902 1903 req = msg->bodyptr; 1904 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1905 /* Free cancel request memory */ 1906 qdf_mem_free(req); 1907 1908 return QDF_STATUS_SUCCESS; 1909 } 1910 1911 void scm_disable_obss_pdev_scan(struct wlan_objmgr_psoc *psoc, 1912 struct wlan_objmgr_pdev *pdev) 1913 { 1914 struct wlan_objmgr_vdev *vdev; 1915 struct wlan_scan_obj *scan_obj; 1916 struct scan_vdev_obj *scan_vdev_obj; 1917 QDF_STATUS status; 1918 struct wlan_objmgr_pdev_objmgr *pdev_objmgr; 1919 qdf_list_t *vdev_list; 1920 uint16_t index = 0; 1921 1922 scan_obj = wlan_psoc_get_scan_obj(psoc); 1923 if (!scan_obj) { 1924 scm_err("scan object null"); 1925 return; 1926 } 1927 1928 if (scan_obj->obss_scan_offload) { 1929 pdev_objmgr = &pdev->pdev_objmgr; 1930 1931 wlan_pdev_obj_lock(pdev); 1932 vdev_list = &pdev_objmgr->wlan_vdev_list; 1933 /* Get first vdev */ 1934 vdev = wlan_pdev_vdev_list_peek_head(vdev_list); 1935 1936 while (vdev) { 1937 scm_debug("wlan_vdev_list[%d]: %pK", index, vdev); 1938 1939 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1940 if (!scan_vdev_obj) { 1941 scm_err("null scan_vdev_obj"); 1942 goto next; 1943 } 1944 1945 status = tgt_scan_obss_disable(vdev); 1946 if (QDF_IS_STATUS_ERROR(status)) 1947 scm_err("disable obss scan failed"); 1948 next: 1949 index++; 1950 /* get next vdev */ 1951 vdev = wlan_vdev_get_next_vdev_of_pdev(vdev_list, 1952 vdev); 1953 } 1954 wlan_pdev_obj_unlock(pdev); 1955 } 1956 } 1957