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