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