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