1 /* 2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wma_dev_if.c 22 * This file contains vdev & peer related operations. 23 */ 24 25 /* Header files */ 26 27 #include "wma.h" 28 #include "wma_api.h" 29 #include "cds_api.h" 30 #include "wmi_unified_api.h" 31 #include "wlan_qct_sys.h" 32 #include "wni_api.h" 33 #include "ani_global.h" 34 #include "wmi_unified.h" 35 #include "wni_cfg.h" 36 37 #include "qdf_nbuf.h" 38 #include "qdf_types.h" 39 #include "qdf_mem.h" 40 41 #include "wma_types.h" 42 #include "lim_api.h" 43 #include "lim_session_utils.h" 44 #include "wma_pasn_peer_api.h" 45 46 #include "cds_utils.h" 47 48 #if !defined(REMOVE_PKT_LOG) 49 #include "pktlog_ac.h" 50 #endif /* REMOVE_PKT_LOG */ 51 52 #include "dbglog_host.h" 53 #include "csr_api.h" 54 55 #include "wma_internal.h" 56 57 #include "wma_ocb.h" 58 #include "cdp_txrx_cfg.h" 59 #include "cdp_txrx_flow_ctrl_legacy.h" 60 #include <cdp_txrx_peer_ops.h> 61 #include <cdp_txrx_cfg.h> 62 #include <cdp_txrx_cmn.h> 63 #include <cdp_txrx_misc.h> 64 #include <cdp_txrx_ctrl.h> 65 66 #include "wlan_policy_mgr_api.h" 67 #include "wma_nan_datapath.h" 68 #include "wifi_pos_pasn_api.h" 69 #if defined(CONFIG_HL_SUPPORT) 70 #include "wlan_tgt_def_config_hl.h" 71 #else 72 #include "wlan_tgt_def_config.h" 73 #endif 74 #include <wlan_dfs_tgt_api.h> 75 #include <cdp_txrx_handle.h> 76 #include "wlan_pmo_ucfg_api.h" 77 #include "wlan_reg_services_api.h" 78 #include <include/wlan_vdev_mlme.h> 79 #include "wma_he.h" 80 #include "wma_eht.h" 81 #include "wlan_roam_debug.h" 82 #include "wlan_ocb_ucfg_api.h" 83 #include "init_deinit_lmac.h" 84 #include <target_if.h> 85 #include "wlan_policy_mgr_ucfg.h" 86 #include "wlan_mlme_public_struct.h" 87 #include "wlan_mlme_api.h" 88 #include "wlan_mlme_main.h" 89 #include "wlan_mlme_ucfg_api.h" 90 #include "wlan_mlme_twt_api.h" 91 #include <wlan_dfs_utils_api.h> 92 #include "../../core/src/vdev_mgr_ops.h" 93 #include "wlan_utility.h" 94 #include "wlan_coex_ucfg_api.h" 95 #include <wlan_cp_stats_mc_ucfg_api.h> 96 #include "wmi_unified_vdev_api.h" 97 #include <wlan_cm_api.h> 98 #include <../../core/src/wlan_cm_vdev_api.h> 99 #include "wlan_nan_api.h" 100 #include "wlan_mlo_mgr_peer.h" 101 #include "wifi_pos_api.h" 102 #include "wifi_pos_pasn_api.h" 103 #ifdef DCS_INTERFERENCE_DETECTION 104 #include <wlan_dcs_ucfg_api.h> 105 #endif 106 107 #ifdef FEATURE_STA_MODE_VOTE_LINK 108 #include "wlan_ipa_ucfg_api.h" 109 #endif 110 111 #include "son_api.h" 112 #include "wlan_vdev_mgr_tgt_if_tx_defs.h" 113 #include "wlan_mlo_mgr_roam.h" 114 #include "target_if_vdev_mgr_tx_ops.h" 115 #include "wlan_fwol_ucfg_api.h" 116 #include "wlan_vdev_mgr_utils_api.h" 117 #include "target_if.h" 118 119 /* 120 * FW only supports 8 clients in SAP/GO mode for D3 WoW feature 121 * and hence host needs to hold a wake lock after 9th client connects 122 * and release the wake lock when 9th client disconnects 123 */ 124 #define SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK (9) 125 #define SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK (8) 126 127 QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr, 128 uint8_t *vdev_id) 129 { 130 uint8_t i; 131 struct wlan_objmgr_vdev *vdev; 132 133 for (i = 0; i < wma->max_bssid; i++) { 134 vdev = wma->interfaces[i].vdev; 135 if (!vdev) 136 continue; 137 138 if (qdf_is_macaddr_equal( 139 (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev), 140 (struct qdf_mac_addr *)addr) == true) { 141 *vdev_id = i; 142 return QDF_STATUS_SUCCESS; 143 } 144 145 if (qdf_is_macaddr_equal((struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev), 146 (struct qdf_mac_addr *)addr) == true) { 147 *vdev_id = i; 148 return QDF_STATUS_SUCCESS; 149 } 150 } 151 152 return QDF_STATUS_E_FAILURE; 153 } 154 155 156 /** 157 * wma_is_vdev_in_ap_mode() - check that vdev is in ap mode or not 158 * @wma: wma handle 159 * @vdev_id: vdev id 160 * 161 * Helper function to know whether given vdev id 162 * is in AP mode or not. 163 * 164 * Return: True/False 165 */ 166 bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id) 167 { 168 struct wma_txrx_node *intf = wma->interfaces; 169 170 if (vdev_id >= wma->max_bssid) { 171 wma_err("Invalid vdev_id %hu", vdev_id); 172 QDF_ASSERT(0); 173 return false; 174 } 175 176 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) && 177 ((intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) || 178 (intf[vdev_id].sub_type == 0))) 179 return true; 180 181 return false; 182 } 183 184 uint8_t *wma_get_vdev_bssid(struct wlan_objmgr_vdev *vdev) 185 { 186 struct vdev_mlme_obj *mlme_obj; 187 188 if (!vdev) { 189 wma_err("vdev is NULL"); 190 return NULL; 191 } 192 193 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 194 if (!mlme_obj) { 195 wma_err("Failed to get mlme_obj"); 196 return NULL; 197 } 198 199 return mlme_obj->mgmt.generic.bssid; 200 } 201 202 QDF_STATUS wma_find_vdev_id_by_bssid(tp_wma_handle wma, uint8_t *bssid, 203 uint8_t *vdev_id) 204 { 205 int i; 206 uint8_t *bssid_addr; 207 208 for (i = 0; i < wma->max_bssid; i++) { 209 if (!wma->interfaces[i].vdev) 210 continue; 211 bssid_addr = wma_get_vdev_bssid(wma->interfaces[i].vdev); 212 if (!bssid_addr) 213 continue; 214 215 if (qdf_is_macaddr_equal( 216 (struct qdf_mac_addr *)bssid_addr, 217 (struct qdf_mac_addr *)bssid) == true) { 218 *vdev_id = i; 219 return QDF_STATUS_SUCCESS; 220 } 221 } 222 223 return QDF_STATUS_E_FAILURE; 224 } 225 226 /** 227 * wma_find_req_on_timer_expiry() - find request by address 228 * @wma: wma handle 229 * @req: pointer to the target request 230 * 231 * On timer expiry, the pointer to the req message is received from the 232 * timer callback. Lookup the wma_hold_req_queue for the request with the 233 * same address and return success if found. 234 * 235 * Return: QDF_STATUS 236 */ 237 static QDF_STATUS wma_find_req_on_timer_expiry(tp_wma_handle wma, 238 struct wma_target_req *req) 239 { 240 struct wma_target_req *req_msg = NULL; 241 bool found = false; 242 qdf_list_node_t *cur_node = NULL, *next_node = NULL; 243 QDF_STATUS status; 244 245 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock); 246 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue, 247 &next_node)) { 248 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 249 wma_err("unable to get msg node from request queue"); 250 return QDF_STATUS_E_FAILURE; 251 } 252 253 do { 254 cur_node = next_node; 255 req_msg = qdf_container_of(cur_node, 256 struct wma_target_req, node); 257 if (req_msg != req) 258 continue; 259 260 found = true; 261 status = qdf_list_remove_node(&wma->wma_hold_req_queue, 262 cur_node); 263 if (QDF_STATUS_SUCCESS != status) { 264 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 265 wma_debug("Failed to remove request for req %pK", req); 266 return QDF_STATUS_E_FAILURE; 267 } 268 break; 269 } while (QDF_STATUS_SUCCESS == 270 qdf_list_peek_next(&wma->wma_hold_req_queue, 271 cur_node, &next_node)); 272 273 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 274 if (!found) { 275 wma_err("target request not found for req %pK", req); 276 return QDF_STATUS_E_INVAL; 277 } 278 279 wma_debug("target request found for vdev id: %d type %d", 280 req_msg->vdev_id, req_msg->type); 281 282 return QDF_STATUS_SUCCESS; 283 } 284 285 /** 286 * wma_find_req() - find target request for vdev id 287 * @wma: wma handle 288 * @vdev_id: vdev id 289 * @type: request type 290 * @peer_addr: Peer mac address 291 * 292 * Find target request for given vdev id & type of request. 293 * Remove that request from active list. 294 * 295 * Return: return target request if found or NULL. 296 */ 297 static struct wma_target_req *wma_find_req(tp_wma_handle wma, 298 uint8_t vdev_id, uint8_t type, 299 struct qdf_mac_addr *peer_addr) 300 { 301 struct wma_target_req *req_msg = NULL; 302 bool found = false; 303 qdf_list_node_t *node1 = NULL, *node2 = NULL; 304 QDF_STATUS status; 305 306 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock); 307 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue, 308 &node2)) { 309 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 310 wma_err("unable to get msg node from request queue"); 311 return NULL; 312 } 313 314 do { 315 node1 = node2; 316 req_msg = qdf_container_of(node1, struct wma_target_req, node); 317 if (req_msg->vdev_id != vdev_id) 318 continue; 319 if (req_msg->type != type) 320 continue; 321 322 found = true; 323 if (type == WMA_PEER_CREATE_RESPONSE && 324 peer_addr && 325 !qdf_is_macaddr_equal(&req_msg->addr, peer_addr)) 326 found = false; 327 328 status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1); 329 if (QDF_STATUS_SUCCESS != status) { 330 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 331 wma_debug("Failed to remove request for vdev_id %d type %d", 332 vdev_id, type); 333 return NULL; 334 } 335 break; 336 } while (QDF_STATUS_SUCCESS == 337 qdf_list_peek_next(&wma->wma_hold_req_queue, node1, 338 &node2)); 339 340 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 341 if (!found) { 342 wma_err("target request not found for vdev_id %d type %d", 343 vdev_id, type); 344 return NULL; 345 } 346 347 wma_debug("target request found for vdev id: %d type %d", 348 vdev_id, type); 349 350 return req_msg; 351 } 352 353 struct wma_target_req *wma_find_remove_req_msgtype(tp_wma_handle wma, 354 uint8_t vdev_id, 355 uint32_t msg_type) 356 { 357 struct wma_target_req *req_msg = NULL; 358 bool found = false; 359 qdf_list_node_t *node1 = NULL, *node2 = NULL; 360 QDF_STATUS status; 361 362 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock); 363 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue, 364 &node2)) { 365 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 366 wma_debug("unable to get msg node from request queue for vdev_id %d type %d", 367 vdev_id, msg_type); 368 return NULL; 369 } 370 371 do { 372 node1 = node2; 373 req_msg = qdf_container_of(node1, struct wma_target_req, node); 374 if (req_msg->vdev_id != vdev_id) 375 continue; 376 if (req_msg->msg_type != msg_type) 377 continue; 378 379 found = true; 380 status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1); 381 if (QDF_STATUS_SUCCESS != status) { 382 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 383 wma_debug("Failed to remove request. vdev_id %d type %d", 384 vdev_id, msg_type); 385 return NULL; 386 } 387 break; 388 } while (QDF_STATUS_SUCCESS == 389 qdf_list_peek_next(&wma->wma_hold_req_queue, node1, 390 &node2)); 391 392 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 393 if (!found) { 394 wma_debug("target request not found for vdev_id %d type %d", 395 vdev_id, msg_type); 396 return NULL; 397 } 398 399 wma_debug("target request found for vdev id: %d type %d", 400 vdev_id, msg_type); 401 402 return req_msg; 403 } 404 405 QDF_STATUS wma_vdev_detach_callback(struct vdev_delete_response *rsp) 406 { 407 tp_wma_handle wma; 408 struct wma_txrx_node *iface = NULL; 409 410 wma = cds_get_context(QDF_MODULE_ID_WMA); 411 if (!wma) 412 return QDF_STATUS_E_FAILURE; 413 414 /* Sanitize the vdev id*/ 415 if (rsp->vdev_id > wma->max_bssid) { 416 wma_err("vdev delete response with invalid vdev_id :%d", 417 rsp->vdev_id); 418 QDF_BUG(0); 419 return QDF_STATUS_E_FAILURE; 420 } 421 422 iface = &wma->interfaces[rsp->vdev_id]; 423 424 wma_debug("vdev del response received for VDEV_%d", rsp->vdev_id); 425 iface->del_staself_req = NULL; 426 427 if (iface->roam_scan_stats_req) { 428 struct sir_roam_scan_stats *roam_scan_stats_req = 429 iface->roam_scan_stats_req; 430 431 iface->roam_scan_stats_req = NULL; 432 qdf_mem_free(roam_scan_stats_req); 433 } 434 435 wma_vdev_deinit(iface); 436 qdf_mem_zero(iface, sizeof(*iface)); 437 wma_vdev_init(iface); 438 439 mlme_vdev_del_resp(rsp->vdev_id); 440 441 return QDF_STATUS_SUCCESS; 442 } 443 444 static void 445 wma_cdp_vdev_detach(ol_txrx_soc_handle soc, tp_wma_handle wma_handle, 446 uint8_t vdev_id) 447 { 448 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; 449 struct wlan_objmgr_vdev *vdev = iface->vdev; 450 451 if (!vdev) { 452 wma_err("vdev is NULL"); 453 return; 454 } 455 456 if (soc && wlan_vdev_get_id(vdev) != WLAN_INVALID_VDEV_ID) 457 cdp_vdev_detach(soc, vdev_id, NULL, NULL); 458 } 459 460 /** 461 * wma_release_vdev_ref() - Release vdev object reference count 462 * @iface: wma interface txrx node 463 * 464 * Purpose of this function is to release vdev object reference count 465 * from wma interface txrx node. 466 * 467 * Return: None 468 */ 469 static void 470 wma_release_vdev_ref(struct wma_txrx_node *iface) 471 { 472 struct wlan_objmgr_vdev *vdev; 473 474 vdev = iface->vdev; 475 476 iface->vdev_active = false; 477 iface->vdev = NULL; 478 if (vdev) 479 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); 480 } 481 482 /** 483 * wma_handle_monitor_mode_vdev_detach() - Stop and down monitor mode vdev 484 * @wma_handle: wma handle 485 * @vdev_id: used to get wma interface txrx node 486 * 487 * Monitor mode is unconneted mode, so do explicit vdev stop and down 488 * 489 * Return: None 490 */ 491 static void wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma, 492 uint8_t vdev_id) 493 { 494 struct wma_txrx_node *iface; 495 496 iface = &wma->interfaces[vdev_id]; 497 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 498 WLAN_VDEV_SM_EV_DOWN, 499 0, NULL); 500 iface->vdev_active = false; 501 } 502 503 /** 504 * wma_handle_vdev_detach() - wma vdev detach handler 505 * @wma_handle: pointer to wma handle 506 * @del_vdev_req_param: pointer to del req param 507 * 508 * Return: none. 509 */ 510 static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, 511 struct del_vdev_params *del_vdev_req_param) 512 { 513 QDF_STATUS status = QDF_STATUS_SUCCESS; 514 uint8_t vdev_id = del_vdev_req_param->vdev_id; 515 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; 516 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 517 struct wmi_mgmt_params mgmt_params = {}; 518 519 if (!soc) { 520 status = QDF_STATUS_E_FAILURE; 521 goto rel_ref; 522 } 523 524 if ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) || 525 (policy_mgr_is_sta_mon_concurrency(wma_handle->psoc) && 526 wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_MONITOR_MODE)) 527 wma_handle_monitor_mode_vdev_detach(wma_handle, vdev_id); 528 529 rel_ref: 530 wma_cdp_vdev_detach(soc, wma_handle, vdev_id); 531 if (qdf_is_recovering()) 532 wlan_mgmt_txrx_vdev_drain(iface->vdev, 533 wma_mgmt_frame_fill_peer_cb, 534 &mgmt_params); 535 wma_debug("Releasing wma reference for vdev:%d", vdev_id); 536 wma_release_vdev_ref(iface); 537 return status; 538 } 539 540 /** 541 * wma_self_peer_remove() - Self peer remove handler 542 * @wma: wma handle 543 * @del_vdev_req_param: vdev id 544 * @generate_vdev_rsp: request type 545 * 546 * Return: success if peer delete command sent to firmware, else failure. 547 */ 548 static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle, 549 struct del_vdev_params *del_vdev_req) 550 { 551 QDF_STATUS qdf_status; 552 uint8_t vdev_id = del_vdev_req->vdev_id; 553 struct wma_target_req *msg = NULL; 554 struct del_sta_self_rsp_params *sta_self_wmi_rsp; 555 556 wma_debug("P2P Device: removing self peer "QDF_MAC_ADDR_FMT, 557 QDF_MAC_ADDR_REF(del_vdev_req->self_mac_addr)); 558 559 qdf_status = wma_remove_peer(wma_handle, del_vdev_req->self_mac_addr, 560 vdev_id, false); 561 if (QDF_IS_STATUS_ERROR(qdf_status)) { 562 wma_err("wma_remove_peer is failed"); 563 goto error; 564 } 565 566 if (wmi_service_enabled(wma_handle->wmi_handle, 567 wmi_service_sync_delete_cmds)) { 568 sta_self_wmi_rsp = 569 qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params)); 570 if (!sta_self_wmi_rsp) { 571 qdf_status = QDF_STATUS_E_NOMEM; 572 goto error; 573 } 574 575 sta_self_wmi_rsp->self_sta_param = del_vdev_req; 576 msg = wma_fill_hold_req(wma_handle, vdev_id, 577 WMA_DELETE_STA_REQ, 578 WMA_DEL_P2P_SELF_STA_RSP_START, 579 sta_self_wmi_rsp, 580 WMA_DELETE_STA_TIMEOUT); 581 if (!msg) { 582 wma_err("Failed to allocate request for vdev_id %d", 583 vdev_id); 584 wma_remove_req(wma_handle, vdev_id, 585 WMA_DEL_P2P_SELF_STA_RSP_START); 586 qdf_mem_free(sta_self_wmi_rsp); 587 qdf_status = QDF_STATUS_E_FAILURE; 588 goto error; 589 } 590 } 591 592 error: 593 return qdf_status; 594 } 595 596 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 597 QDF_STATUS wma_p2p_self_peer_remove(struct wlan_objmgr_vdev *vdev) 598 { 599 struct del_vdev_params *del_self_peer_req; 600 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 601 QDF_STATUS status; 602 603 if (!wma_handle) 604 return QDF_STATUS_E_INVAL; 605 606 del_self_peer_req = qdf_mem_malloc(sizeof(*del_self_peer_req)); 607 if (!del_self_peer_req) 608 return QDF_STATUS_E_NOMEM; 609 610 del_self_peer_req->vdev = vdev; 611 del_self_peer_req->vdev_id = wlan_vdev_get_id(vdev); 612 qdf_mem_copy(del_self_peer_req->self_mac_addr, 613 wlan_vdev_mlme_get_macaddr(vdev), 614 QDF_MAC_ADDR_SIZE); 615 616 status = wma_self_peer_remove(wma_handle, del_self_peer_req); 617 618 return status; 619 } 620 #endif 621 622 void wma_remove_objmgr_peer(tp_wma_handle wma, 623 struct wlan_objmgr_vdev *obj_vdev, 624 uint8_t *peer_addr) 625 { 626 struct wlan_objmgr_psoc *psoc; 627 struct wlan_objmgr_peer *obj_peer; 628 struct wlan_objmgr_pdev *obj_pdev; 629 uint8_t pdev_id = 0; 630 631 psoc = wma->psoc; 632 if (!psoc) { 633 wma_err("PSOC is NULL"); 634 return; 635 } 636 637 obj_pdev = wlan_vdev_get_pdev(obj_vdev); 638 pdev_id = wlan_objmgr_pdev_get_pdev_id(obj_pdev); 639 obj_peer = wlan_objmgr_get_peer(psoc, pdev_id, peer_addr, 640 WLAN_LEGACY_WMA_ID); 641 if (obj_peer) { 642 wlan_objmgr_peer_obj_delete(obj_peer); 643 /* Unref to decrement ref happened in find_peer */ 644 wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID); 645 } else { 646 wma_nofl_err("Peer "QDF_MAC_ADDR_FMT" not found", 647 QDF_MAC_ADDR_REF(peer_addr)); 648 } 649 650 } 651 652 static QDF_STATUS wma_check_for_deferred_peer_delete(tp_wma_handle wma_handle, 653 struct del_vdev_params 654 *pdel_vdev_req_param) 655 { 656 QDF_STATUS status = QDF_STATUS_SUCCESS; 657 uint8_t vdev_id = pdel_vdev_req_param->vdev_id; 658 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; 659 uint32_t vdev_stop_type; 660 661 if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) { 662 status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type); 663 if (QDF_IS_STATUS_ERROR(status)) { 664 wma_err("Failed to get wma req msg_type for vdev_id: %d", 665 vdev_id); 666 status = QDF_STATUS_E_INVAL; 667 return status; 668 } 669 670 if (vdev_stop_type != WMA_DELETE_BSS_REQ) { 671 status = QDF_STATUS_E_INVAL; 672 return status; 673 } 674 675 wma_debug("BSS is not yet stopped. Deferring vdev(vdev id %x) deletion", 676 vdev_id); 677 iface->del_staself_req = pdel_vdev_req_param; 678 iface->is_del_sta_deferred = true; 679 } 680 681 return status; 682 } 683 684 static QDF_STATUS 685 wma_vdev_self_peer_delete(tp_wma_handle wma_handle, 686 struct del_vdev_params *pdel_vdev_req_param) 687 { 688 QDF_STATUS status = QDF_STATUS_SUCCESS; 689 uint8_t vdev_id = pdel_vdev_req_param->vdev_id; 690 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; 691 692 if (mlme_vdev_uses_self_peer(iface->type, iface->sub_type)) { 693 status = wma_self_peer_remove(wma_handle, pdel_vdev_req_param); 694 if (QDF_IS_STATUS_ERROR(status)) { 695 wma_err("can't remove selfpeer, send rsp session: %d", 696 vdev_id); 697 wma_handle_vdev_detach(wma_handle, pdel_vdev_req_param); 698 mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param); 699 cds_trigger_recovery(QDF_SELF_PEER_DEL_FAILED); 700 return status; 701 } 702 } else if (iface->type == WMI_VDEV_TYPE_STA || 703 iface->type == WMI_VDEV_TYPE_NAN) { 704 wma_remove_objmgr_peer(wma_handle, iface->vdev, 705 pdel_vdev_req_param->self_mac_addr); 706 } 707 708 return status; 709 } 710 711 QDF_STATUS wma_vdev_detach(struct del_vdev_params *pdel_vdev_req_param) 712 { 713 QDF_STATUS status = QDF_STATUS_SUCCESS; 714 uint8_t vdev_id; 715 struct wma_txrx_node *iface = NULL; 716 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 717 718 if (!wma_handle) 719 return QDF_STATUS_E_INVAL; 720 721 vdev_id = wlan_vdev_get_id(pdel_vdev_req_param->vdev); 722 iface = &wma_handle->interfaces[vdev_id]; 723 if (!iface->vdev) { 724 wma_err("vdev %d is NULL", vdev_id); 725 mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param); 726 return status; 727 } 728 729 status = wma_check_for_deferred_peer_delete(wma_handle, 730 pdel_vdev_req_param); 731 if (QDF_IS_STATUS_ERROR(status)) 732 goto send_fail_rsp; 733 734 if (iface->is_del_sta_deferred) 735 return status; 736 737 iface->is_del_sta_deferred = false; 738 iface->del_staself_req = NULL; 739 740 status = wma_vdev_self_peer_delete(wma_handle, pdel_vdev_req_param); 741 if (QDF_IS_STATUS_ERROR(status)) { 742 wma_err("Failed to send self peer delete:%d", status); 743 status = QDF_STATUS_E_INVAL; 744 return status; 745 } 746 747 if (iface->type != WMI_VDEV_TYPE_MONITOR) 748 iface->vdev_active = false; 749 750 if (!mlme_vdev_uses_self_peer(iface->type, iface->sub_type) || 751 !wmi_service_enabled(wma_handle->wmi_handle, 752 wmi_service_sync_delete_cmds)) { 753 status = wma_handle_vdev_detach(wma_handle, 754 pdel_vdev_req_param); 755 pdel_vdev_req_param->status = status; 756 mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param); 757 } 758 759 return status; 760 761 send_fail_rsp: 762 wma_err("rcvd del_self_sta without del_bss; vdev_id:%d", vdev_id); 763 cds_trigger_recovery(QDF_DEL_SELF_STA_FAILED); 764 status = QDF_STATUS_E_FAILURE; 765 return status; 766 } 767 768 /** 769 * wma_send_start_resp() - send vdev start response to upper layer 770 * @wma: wma handle 771 * @add_bss: add bss params 772 * @resp_event: response params 773 * 774 * Return: none 775 */ 776 static void wma_send_start_resp(tp_wma_handle wma, 777 struct add_bss_rsp *add_bss_rsp, 778 struct vdev_start_response *rsp) 779 { 780 struct wma_txrx_node *iface = &wma->interfaces[rsp->vdev_id]; 781 QDF_STATUS status; 782 783 if (QDF_IS_STATUS_SUCCESS(rsp->status) && 784 QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { 785 status = 786 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 787 WLAN_VDEV_SM_EV_START_RESP, 788 sizeof(*add_bss_rsp), 789 add_bss_rsp); 790 if (QDF_IS_STATUS_SUCCESS(status)) 791 return; 792 793 add_bss_rsp->status = status; 794 } 795 796 /* Send vdev stop if vdev start was success */ 797 if (QDF_IS_STATUS_ERROR(add_bss_rsp->status) && 798 QDF_IS_STATUS_SUCCESS(rsp->status)) { 799 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 800 WLAN_VDEV_SM_EV_DOWN, 801 sizeof(*add_bss_rsp), 802 add_bss_rsp); 803 return; 804 } 805 806 wma_remove_bss_peer_on_failure(wma, rsp->vdev_id); 807 808 wma_debug("Sending add bss rsp to umac(vdev %d status %d)", 809 rsp->vdev_id, add_bss_rsp->status); 810 lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp); 811 } 812 813 /** 814 * wma_vdev_start_rsp() - send vdev start response to upper layer 815 * @wma: wma handle 816 * @vdev: vdev 817 * @resp_event: response params 818 * 819 * Return: none 820 */ 821 static void wma_vdev_start_rsp(tp_wma_handle wma, struct wlan_objmgr_vdev *vdev, 822 struct vdev_start_response *rsp) 823 { 824 struct beacon_info *bcn; 825 enum QDF_OPMODE opmode; 826 struct add_bss_rsp *add_bss_rsp; 827 828 opmode = wlan_vdev_mlme_get_opmode(vdev); 829 830 add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp)); 831 if (!add_bss_rsp) 832 return; 833 834 add_bss_rsp->vdev_id = rsp->vdev_id; 835 add_bss_rsp->status = rsp->status; 836 add_bss_rsp->chain_mask = rsp->chain_mask; 837 add_bss_rsp->smps_mode = host_map_smps_mode(rsp->smps_mode); 838 839 if (rsp->status) 840 goto send_fail_resp; 841 842 if (opmode == QDF_P2P_GO_MODE || opmode == QDF_SAP_MODE) { 843 wma->interfaces[rsp->vdev_id].beacon = 844 qdf_mem_malloc(sizeof(struct beacon_info)); 845 846 bcn = wma->interfaces[rsp->vdev_id].beacon; 847 if (!bcn) { 848 add_bss_rsp->status = QDF_STATUS_E_NOMEM; 849 goto send_fail_resp; 850 } 851 bcn->buf = qdf_nbuf_alloc(NULL, SIR_MAX_BEACON_SIZE, 0, 852 sizeof(uint32_t), 0); 853 if (!bcn->buf) { 854 qdf_mem_free(bcn); 855 add_bss_rsp->status = QDF_STATUS_E_FAILURE; 856 goto send_fail_resp; 857 } 858 bcn->seq_no = MIN_SW_SEQ; 859 qdf_spinlock_create(&bcn->lock); 860 qdf_atomic_set(&wma->interfaces[rsp->vdev_id].bss_status, 861 WMA_BSS_STATUS_STARTED); 862 wma_debug("AP mode (type %d subtype %d) BSS is started", 863 wma->interfaces[rsp->vdev_id].type, 864 wma->interfaces[rsp->vdev_id].sub_type); 865 } 866 867 send_fail_resp: 868 wma_send_start_resp(wma, add_bss_rsp, rsp); 869 } 870 871 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 872 /** 873 * wma_find_mcc_ap() - finds if device is operating AP in MCC mode or not 874 * @wma: wma handle. 875 * @vdev_id: vdev ID of device for which MCC has to be checked 876 * @add: flag indicating if current device is added or deleted 877 * 878 * This function parses through all the interfaces in wma and finds if 879 * any of those devces are in MCC mode with AP. If such a vdev is found 880 * involved AP vdevs are sent WDA_UPDATE_Q2Q_IE_IND msg to update their 881 * beacon template to include Q2Q IE. 882 * 883 * Return: none 884 */ 885 static void wma_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id, bool add) 886 { 887 uint8_t i; 888 uint16_t prev_ch_freq = 0; 889 bool is_ap = false; 890 bool result = false; 891 uint8_t *ap_vdev_ids = NULL; 892 uint8_t num_ch = 0; 893 894 ap_vdev_ids = qdf_mem_malloc(wma->max_bssid); 895 if (!ap_vdev_ids) 896 return; 897 898 for (i = 0; i < wma->max_bssid; i++) { 899 ap_vdev_ids[i] = -1; 900 if (add == false && i == vdev_id) 901 continue; 902 903 if (wma_is_vdev_up(vdev_id) || (i == vdev_id && add)) { 904 if (wma->interfaces[i].type == WMI_VDEV_TYPE_AP) { 905 is_ap = true; 906 ap_vdev_ids[i] = i; 907 } 908 909 if (wma->interfaces[i].ch_freq != prev_ch_freq) { 910 num_ch++; 911 prev_ch_freq = wma->interfaces[i].ch_freq; 912 } 913 } 914 } 915 916 if (is_ap && (num_ch > 1)) 917 result = true; 918 else 919 result = false; 920 921 wma_send_msg(wma, WMA_UPDATE_Q2Q_IE_IND, (void *)ap_vdev_ids, result); 922 } 923 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 924 925 /** 926 * wma_handle_hidden_ssid_restart() - handle hidden ssid restart 927 * @wma: wma handle 928 * @iface: interface pointer 929 * 930 * Return: none 931 */ 932 static void wma_handle_hidden_ssid_restart(tp_wma_handle wma, 933 struct wma_txrx_node *iface) 934 { 935 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 936 WLAN_VDEV_SM_EV_RESTART_RESP, 937 0, NULL); 938 } 939 940 #ifdef WLAN_FEATURE_11BE 941 /** 942 * wma_get_peer_phymode() - get phy mode and eht puncture 943 * @nw_type: wlan type 944 * @old_peer_phymode: old peer phy mode 945 * @vdev_chan: vdev channel 946 * @is_eht: is eht mode 947 * @puncture_bitmap: eht puncture bitmap 948 * 949 * Return: new wlan phy mode 950 */ 951 static enum wlan_phymode 952 wma_get_peer_phymode(tSirNwType nw_type, enum wlan_phymode old_peer_phymode, 953 struct wlan_channel *vdev_chan, bool *is_eht, 954 uint16_t *puncture_bitmap) 955 { 956 enum wlan_phymode new_phymode; 957 958 new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER, 959 IS_WLAN_PHYMODE_HT(old_peer_phymode), 960 vdev_chan->ch_width, 961 IS_WLAN_PHYMODE_VHT(old_peer_phymode), 962 IS_WLAN_PHYMODE_HE(old_peer_phymode), 963 IS_WLAN_PHYMODE_EHT(old_peer_phymode)); 964 *is_eht = IS_WLAN_PHYMODE_EHT(new_phymode); 965 if (*is_eht) 966 *puncture_bitmap = vdev_chan->puncture_bitmap; 967 968 return new_phymode; 969 } 970 #else 971 static enum wlan_phymode 972 wma_get_peer_phymode(tSirNwType nw_type, enum wlan_phymode old_peer_phymode, 973 struct wlan_channel *vdev_chan, bool *is_eht, 974 uint16_t *puncture_bitmap) 975 { 976 enum wlan_phymode new_phymode; 977 978 new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER, 979 IS_WLAN_PHYMODE_HT(old_peer_phymode), 980 vdev_chan->ch_width, 981 IS_WLAN_PHYMODE_VHT(old_peer_phymode), 982 IS_WLAN_PHYMODE_HE(old_peer_phymode), 983 0); 984 985 return new_phymode; 986 } 987 #endif 988 989 static void wma_peer_send_phymode(struct wlan_objmgr_vdev *vdev, 990 void *object, void *arg) 991 { 992 struct wlan_objmgr_peer *peer = object; 993 enum wlan_phymode old_peer_phymode; 994 struct wlan_channel *vdev_chan; 995 enum wlan_phymode new_phymode; 996 tSirNwType nw_type; 997 uint32_t fw_phymode; 998 uint32_t max_ch_width_supported; 999 tp_wma_handle wma; 1000 uint8_t *peer_mac_addr; 1001 uint8_t vdev_id; 1002 bool is_eht = false; 1003 uint16_t puncture_bitmap = 0; 1004 uint16_t new_puncture_bitmap = 0; 1005 uint32_t bw_puncture = 0; 1006 enum phy_ch_width new_bw; 1007 1008 if (wlan_peer_get_peer_type(peer) == WLAN_PEER_SELF) 1009 return; 1010 1011 wma = cds_get_context(QDF_MODULE_ID_WMA); 1012 if(!wma) 1013 return; 1014 1015 old_peer_phymode = wlan_peer_get_phymode(peer); 1016 vdev_chan = wlan_vdev_mlme_get_des_chan(vdev); 1017 1018 peer_mac_addr = wlan_peer_get_macaddr(peer); 1019 1020 if (WLAN_REG_IS_24GHZ_CH_FREQ(vdev_chan->ch_freq)) { 1021 if (vdev_chan->ch_phymode == WLAN_PHYMODE_11B || 1022 old_peer_phymode == WLAN_PHYMODE_11B) 1023 nw_type = eSIR_11B_NW_TYPE; 1024 else 1025 nw_type = eSIR_11G_NW_TYPE; 1026 } else { 1027 nw_type = eSIR_11A_NW_TYPE; 1028 } 1029 1030 new_phymode = wma_get_peer_phymode(nw_type, old_peer_phymode, 1031 vdev_chan, &is_eht, 1032 &puncture_bitmap); 1033 1034 if (!is_eht && new_phymode == old_peer_phymode) { 1035 wma_debug("Ignore update as old %d and new %d phymode are same for mac "QDF_MAC_ADDR_FMT, 1036 old_peer_phymode, new_phymode, 1037 QDF_MAC_ADDR_REF(peer_mac_addr)); 1038 return; 1039 } 1040 wlan_peer_set_phymode(peer, new_phymode); 1041 1042 fw_phymode = wmi_host_to_fw_phymode(new_phymode); 1043 vdev_id = wlan_vdev_get_id(vdev); 1044 1045 wma_set_peer_param(wma, peer_mac_addr, WMI_HOST_PEER_PHYMODE, 1046 fw_phymode, vdev_id); 1047 1048 max_ch_width_supported = 1049 wmi_get_ch_width_from_phy_mode(wma->wmi_handle, 1050 fw_phymode); 1051 new_bw = 1052 target_if_wmi_chan_width_to_phy_ch_width(max_ch_width_supported); 1053 1054 if (is_eht) { 1055 wlan_reg_extract_puncture_by_bw(vdev_chan->ch_width, 1056 puncture_bitmap, 1057 vdev_chan->ch_freq, 1058 vdev_chan->ch_freq_seg2, 1059 new_bw, 1060 &new_puncture_bitmap); 1061 QDF_SET_BITS(bw_puncture, 0, 8, new_bw); 1062 QDF_SET_BITS(bw_puncture, 8, 16, new_puncture_bitmap); 1063 wlan_util_vdev_peer_set_param_send(vdev, peer_mac_addr, 1064 WLAN_MLME_PEER_BW_PUNCTURE, 1065 bw_puncture); 1066 } else { 1067 wma_set_peer_param(wma, peer_mac_addr, WMI_HOST_PEER_CHWIDTH, 1068 max_ch_width_supported, vdev_id); 1069 } 1070 wma_debug("FW phymode %d old phymode %d new phymode %d bw %d punct: 0x%x macaddr " QDF_MAC_ADDR_FMT, 1071 fw_phymode, old_peer_phymode, new_phymode, 1072 max_ch_width_supported, new_puncture_bitmap, 1073 QDF_MAC_ADDR_REF(peer_mac_addr)); 1074 } 1075 1076 static 1077 void wma_update_rate_flags_after_vdev_restart(tp_wma_handle wma, 1078 struct wma_txrx_node *iface) 1079 { 1080 struct vdev_mlme_obj *vdev_mlme; 1081 uint32_t rate_flags = 0; 1082 enum wlan_phymode bss_phymode; 1083 struct wlan_channel *des_chan; 1084 1085 if (iface->type != WMI_VDEV_TYPE_STA) 1086 return; 1087 1088 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); 1089 if (!vdev_mlme) 1090 return; 1091 1092 des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev); 1093 bss_phymode = des_chan->ch_phymode; 1094 1095 if (wma_is_eht_phymode_supported(bss_phymode)) { 1096 rate_flags = wma_get_eht_rate_flags(des_chan->ch_width); 1097 } else if (IS_WLAN_PHYMODE_HE(bss_phymode)) { 1098 rate_flags = wma_get_he_rate_flags(des_chan->ch_width); 1099 } else if (IS_WLAN_PHYMODE_VHT(bss_phymode)) { 1100 rate_flags = wma_get_vht_rate_flags(des_chan->ch_width); 1101 } else if (IS_WLAN_PHYMODE_HT(bss_phymode)) { 1102 rate_flags = wma_get_ht_rate_flags(des_chan->ch_width); 1103 } else { 1104 rate_flags = TX_RATE_LEGACY; 1105 } 1106 1107 vdev_mlme->mgmt.rate_info.rate_flags = rate_flags; 1108 1109 wma_debug("bss phymode %d rate_flags %x, ch_width %d", 1110 bss_phymode, rate_flags, des_chan->ch_width); 1111 1112 ucfg_mc_cp_stats_set_rate_flags(iface->vdev, rate_flags); 1113 } 1114 1115 QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, 1116 struct vdev_start_response *rsp) 1117 { 1118 enum wlan_vdev_sm_evt event; 1119 struct wma_txrx_node *iface; 1120 1121 iface = &wma->interfaces[rsp->vdev_id]; 1122 wma_debug("Send channel switch resp vdev %d status %d", 1123 rsp->vdev_id, rsp->status); 1124 1125 /* Indicate channel switch failure to LIM */ 1126 if (QDF_IS_STATUS_ERROR(rsp->status) && 1127 (iface->type == WMI_VDEV_TYPE_MONITOR || 1128 wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) || 1129 mlme_is_chan_switch_in_progress(iface->vdev))) { 1130 mlme_set_chan_switch_in_progress(iface->vdev, false); 1131 lim_process_switch_channel_rsp(wma->mac_context, rsp); 1132 return QDF_STATUS_SUCCESS; 1133 } 1134 1135 if (QDF_IS_STATUS_SUCCESS(rsp->status) && 1136 rsp->resp_type == WMI_VDEV_RESTART_RESP_EVENT) { 1137 wlan_objmgr_iterate_peerobj_list(iface->vdev, 1138 wma_peer_send_phymode, NULL, 1139 WLAN_LEGACY_WMA_ID); 1140 wma_update_rate_flags_after_vdev_restart(wma, iface); 1141 } 1142 1143 if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) || 1144 mlme_is_chan_switch_in_progress(iface->vdev)) 1145 event = WLAN_VDEV_SM_EV_RESTART_RESP; 1146 else 1147 event = WLAN_VDEV_SM_EV_START_RESP; 1148 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, event, 1149 sizeof(rsp), rsp); 1150 1151 return QDF_STATUS_SUCCESS; 1152 } 1153 1154 #ifdef DCS_INTERFERENCE_DETECTION 1155 /** 1156 * wma_dcs_clear_vdev_starting() - clear vdev starting within dcs information 1157 * @mac_ctx: mac context 1158 * @vdev_id: vdev id 1159 * 1160 * This function is used to clear vdev starting within dcs information 1161 * 1162 * Return: None 1163 */ 1164 static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx, 1165 uint32_t vdev_id) 1166 { 1167 mac_ctx->sap.dcs_info.is_vdev_starting[vdev_id] = false; 1168 } 1169 1170 /** 1171 * wma_dcs_wlan_interference_mitigation_enable() - enable wlan 1172 * interference mitigation 1173 * @mac_ctx: mac context 1174 * @mac_id: mac id 1175 * @rsp: vdev start response 1176 * 1177 * This function is used to enable wlan interference mitigation through 1178 * send dcs command 1179 * 1180 * Return: None 1181 */ 1182 static void wma_dcs_wlan_interference_mitigation_enable( 1183 struct mac_context *mac_ctx, 1184 uint32_t mac_id, 1185 struct vdev_start_response *rsp) 1186 { 1187 int vdev_index; 1188 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 1189 uint32_t count; 1190 bool wlan_interference_mitigation_enable = 1191 mac_ctx->sap.dcs_info. 1192 wlan_interference_mitigation_enable[rsp->vdev_id]; 1193 1194 count = policy_mgr_get_sap_go_count_on_mac( 1195 mac_ctx->psoc, list, mac_id); 1196 1197 for (vdev_index = 0; vdev_index < count; vdev_index++) { 1198 if (mac_ctx->sap.dcs_info.is_vdev_starting[list[vdev_index]]) { 1199 wma_err("vdev %d: does not finish restart", 1200 list[vdev_index]); 1201 return; 1202 } 1203 wlan_interference_mitigation_enable = 1204 wlan_interference_mitigation_enable || 1205 mac_ctx->sap.dcs_info. 1206 wlan_interference_mitigation_enable[list[vdev_index]]; 1207 } 1208 1209 if (wlan_interference_mitigation_enable) 1210 ucfg_config_dcs_event_data(mac_ctx->psoc, mac_id, true); 1211 1212 if (rsp->resp_type == WMI_HOST_VDEV_START_RESP_EVENT) { 1213 ucfg_config_dcs_enable(mac_ctx->psoc, mac_id, 1214 WLAN_HOST_DCS_WLANIM); 1215 ucfg_wlan_dcs_cmd(mac_ctx->psoc, mac_id, true); 1216 } 1217 } 1218 #else 1219 static void wma_dcs_wlan_interference_mitigation_enable( 1220 struct mac_context *mac_ctx, 1221 uint32_t mac_id, 1222 struct vdev_start_response *rsp) 1223 { 1224 } 1225 1226 1227 static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx, 1228 uint32_t vdev_id) 1229 { 1230 } 1231 #endif 1232 1233 /* 1234 * wma_get_ratemask_type() - convert user input ratemask type to FW type 1235 * @type: User input ratemask type maintained in HDD 1236 * @fwtype: Value return arg for fw ratemask type value 1237 * 1238 * Return: FW configurable ratemask type 1239 */ 1240 static QDF_STATUS wma_get_ratemask_type(enum wlan_mlme_ratemask_type type, 1241 uint8_t *fwtype) 1242 { 1243 switch (type) { 1244 case WLAN_MLME_RATEMASK_TYPE_CCK: 1245 *fwtype = WMI_RATEMASK_TYPE_CCK; 1246 break; 1247 case WLAN_MLME_RATEMASK_TYPE_HT: 1248 *fwtype = WMI_RATEMASK_TYPE_HT; 1249 break; 1250 case WLAN_MLME_RATEMASK_TYPE_VHT: 1251 *fwtype = WMI_RATEMASK_TYPE_VHT; 1252 break; 1253 case WLAN_MLME_RATEMASK_TYPE_HE: 1254 *fwtype = WMI_RATEMASK_TYPE_HE; 1255 break; 1256 default: 1257 return QDF_STATUS_E_INVAL; 1258 } 1259 1260 return QDF_STATUS_SUCCESS; 1261 } 1262 1263 QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, 1264 struct vdev_start_response *rsp) 1265 { 1266 tp_wma_handle wma; 1267 struct wma_txrx_node *iface; 1268 target_resource_config *wlan_res_cfg; 1269 struct wlan_objmgr_psoc *psoc; 1270 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 1271 QDF_STATUS status; 1272 enum vdev_assoc_type assoc_type = VDEV_ASSOC; 1273 struct vdev_mlme_obj *mlme_obj; 1274 struct wlan_mlme_psoc_ext_obj *mlme_psoc_obj; 1275 const struct wlan_mlme_ratemask *ratemask_cfg; 1276 struct config_ratemask_params rparams = {0}; 1277 1278 wma = cds_get_context(QDF_MODULE_ID_WMA); 1279 if (!wma) 1280 return QDF_STATUS_E_FAILURE; 1281 1282 psoc = wma->psoc; 1283 if (!psoc) { 1284 wma_err("psoc is NULL"); 1285 return QDF_STATUS_E_FAILURE; 1286 } 1287 1288 mlme_psoc_obj = mlme_get_psoc_ext_obj(psoc); 1289 if (!mlme_psoc_obj) { 1290 wma_err("Failed to get mlme_psoc"); 1291 return QDF_STATUS_E_FAILURE; 1292 } 1293 1294 ratemask_cfg = &mlme_psoc_obj->cfg.ratemask_cfg; 1295 1296 if (!mac_ctx) { 1297 wma_err("Failed to get mac_ctx"); 1298 return QDF_STATUS_E_FAILURE; 1299 } 1300 1301 wlan_res_cfg = lmac_get_tgt_res_cfg(psoc); 1302 if (!wlan_res_cfg) { 1303 wma_err("Wlan resource config is NULL"); 1304 return QDF_STATUS_E_FAILURE; 1305 } 1306 1307 if (rsp->vdev_id >= wma->max_bssid) { 1308 wma_err("Invalid vdev id received from firmware"); 1309 return QDF_STATUS_E_FAILURE; 1310 } 1311 1312 if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) 1313 tgt_dfs_radar_enable(wma->pdev, 0, 0, true); 1314 1315 iface = &wma->interfaces[rsp->vdev_id]; 1316 if (!iface->vdev) { 1317 wma_err("Invalid vdev"); 1318 return QDF_STATUS_E_FAILURE; 1319 } 1320 1321 if (rsp->status == QDF_STATUS_SUCCESS) { 1322 wma->interfaces[rsp->vdev_id].tx_streams = 1323 rsp->cfgd_tx_streams; 1324 1325 if (wlan_res_cfg->use_pdev_id) { 1326 if (rsp->mac_id == OL_TXRX_PDEV_ID) { 1327 wma_err("soc level id received for mac id"); 1328 return -QDF_STATUS_E_INVAL; 1329 } 1330 wma->interfaces[rsp->vdev_id].mac_id = 1331 WMA_PDEV_TO_MAC_MAP(rsp->mac_id); 1332 } else { 1333 wma->interfaces[rsp->vdev_id].mac_id = 1334 rsp->mac_id; 1335 } 1336 1337 wma_debug("vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d", 1338 rsp->vdev_id, 1339 rsp->cfgd_tx_streams, 1340 rsp->cfgd_rx_streams, 1341 rsp->chain_mask, 1342 wma->interfaces[rsp->vdev_id].mac_id); 1343 1344 /* Fill bss_chan after vdev start */ 1345 qdf_mem_copy(iface->vdev->vdev_mlme.bss_chan, 1346 iface->vdev->vdev_mlme.des_chan, 1347 sizeof(struct wlan_channel)); 1348 } 1349 1350 if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) { 1351 wma_dcs_clear_vdev_starting(mac_ctx, rsp->vdev_id); 1352 wma_dcs_wlan_interference_mitigation_enable(mac_ctx, 1353 iface->mac_id, rsp); 1354 } 1355 1356 if (iface->type == WMI_VDEV_TYPE_STA && 1357 rsp->resp_type == WMI_VDEV_START_RESP_EVENT) { 1358 wma_debug("BA mode: %d", mac_ctx->ba_mode); 1359 if (wma_cli_set_command(rsp->vdev_id, 1360 wmi_vdev_param_set_ba_mode, 1361 mac_ctx->ba_mode, VDEV_CMD)) 1362 wma_err("Set BA opmode failed for vdev: %d", 1363 rsp->vdev_id); 1364 } 1365 1366 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 1367 if (rsp->status == QDF_STATUS_SUCCESS 1368 && mac_ctx->sap.sap_channel_avoidance) 1369 wma_find_mcc_ap(wma, rsp->vdev_id, true); 1370 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 1371 1372 if (wma_get_hidden_ssid_restart_in_progress(iface) && 1373 wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) { 1374 wma_handle_hidden_ssid_restart(wma, iface); 1375 return QDF_STATUS_SUCCESS; 1376 } 1377 1378 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); 1379 if (!mlme_obj) 1380 return QDF_STATUS_E_INVAL; 1381 1382 mlme_obj->mgmt.generic.tx_pwrlimit = rsp->max_allowed_tx_power; 1383 wma_debug("Max allowed tx power: %d", rsp->max_allowed_tx_power); 1384 1385 if (iface->type == WMI_VDEV_TYPE_STA) 1386 assoc_type = mlme_get_assoc_type(vdev_mlme->vdev); 1387 1388 if (mlme_is_chan_switch_in_progress(iface->vdev) || 1389 iface->type == WMI_VDEV_TYPE_MONITOR || 1390 (iface->type == WMI_VDEV_TYPE_STA && 1391 (assoc_type == VDEV_ASSOC || assoc_type == VDEV_REASSOC))) { 1392 status = wma_handle_channel_switch_resp(wma, 1393 rsp); 1394 if (QDF_IS_STATUS_ERROR(status)) 1395 return QDF_STATUS_E_FAILURE; 1396 } else if (iface->type == WMI_VDEV_TYPE_OCB) { 1397 mlme_obj->proto.sta.assoc_id = iface->aid; 1398 if (vdev_mgr_up_send(mlme_obj) != QDF_STATUS_SUCCESS) { 1399 wma_err("failed to send vdev up"); 1400 return QDF_STATUS_E_FAILURE; 1401 } 1402 ucfg_ocb_config_channel(wma->pdev); 1403 } else { 1404 struct qdf_mac_addr bss_peer; 1405 1406 status = 1407 wlan_vdev_get_bss_peer_mac(iface->vdev, &bss_peer); 1408 if (QDF_IS_STATUS_ERROR(status)) { 1409 wma_err("Failed to get bssid"); 1410 return QDF_STATUS_E_INVAL; 1411 } 1412 qdf_mem_copy(mlme_obj->mgmt.generic.bssid, bss_peer.bytes, 1413 QDF_MAC_ADDR_SIZE); 1414 wma_vdev_start_rsp(wma, vdev_mlme->vdev, rsp); 1415 } 1416 if (iface->type == WMI_VDEV_TYPE_AP && wma_is_vdev_up(rsp->vdev_id)) 1417 wma_set_sap_keepalive(wma, rsp->vdev_id); 1418 1419 /* Send ratemask to firmware */ 1420 if ((ratemask_cfg->type > WLAN_MLME_RATEMASK_TYPE_NO_MASK) && 1421 (ratemask_cfg->type < WLAN_MLME_RATEMASK_TYPE_MAX)) { 1422 struct wmi_unified *wmi_handle = wma->wmi_handle; 1423 1424 if (wmi_validate_handle(wmi_handle)) 1425 return QDF_STATUS_E_INVAL; 1426 1427 rparams.vdev_id = rsp->vdev_id; 1428 status = wma_get_ratemask_type(ratemask_cfg->type, 1429 &rparams.type); 1430 1431 if (QDF_IS_STATUS_ERROR(status)) { 1432 wma_err(FL("unable to map ratemask")); 1433 /* don't fail, default rates will still work */ 1434 return QDF_STATUS_SUCCESS; 1435 } 1436 1437 rparams.lower32 = ratemask_cfg->lower32; 1438 rparams.higher32 = ratemask_cfg->higher32; 1439 rparams.lower32_2 = ratemask_cfg->lower32_2; 1440 rparams.higher32_2 = ratemask_cfg->higher32_2; 1441 1442 status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle, 1443 &rparams); 1444 /* Only log failure. Do not abort */ 1445 if (QDF_IS_STATUS_ERROR(status)) 1446 wma_err(FL("failed to send ratemask")); 1447 } 1448 1449 return QDF_STATUS_SUCCESS; 1450 } 1451 1452 bool wma_is_vdev_valid(uint32_t vdev_id) 1453 { 1454 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 1455 1456 if (!wma_handle) 1457 return false; 1458 1459 /* No of interface are allocated based on max_bssid value */ 1460 if (vdev_id >= wma_handle->max_bssid) { 1461 wma_debug("vdev_id: %d is invalid, max_bssid: %d", 1462 vdev_id, wma_handle->max_bssid); 1463 return false; 1464 } 1465 1466 return wma_handle->interfaces[vdev_id].vdev_active; 1467 } 1468 1469 /** 1470 * wma_vdev_set_param() - set per vdev params in fw 1471 * @wmi_handle: wmi handle 1472 * @if_id: vdev id 1473 * @param_id: parameter id 1474 * @param_value: parameter value 1475 * 1476 * Return: QDF_STATUS_SUCCESS for success or error code 1477 */ 1478 QDF_STATUS 1479 wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id, 1480 uint32_t param_id, uint32_t param_value) 1481 { 1482 struct vdev_set_params param = {0}; 1483 1484 if (!wma_is_vdev_valid(if_id)) { 1485 wma_err("vdev_id: %d is not active reject the req: param id %d val %d", 1486 if_id, param_id, param_value); 1487 return QDF_STATUS_E_INVAL; 1488 } 1489 1490 param.vdev_id = if_id; 1491 param.param_id = param_id; 1492 param.param_value = param_value; 1493 1494 return wmi_unified_vdev_set_param_send(wmi_handle, ¶m); 1495 } 1496 1497 /** 1498 * wma_set_peer_param() - set peer parameter in fw 1499 * @wma_ctx: wma handle 1500 * @peer_addr: peer mac address 1501 * @param_id: parameter id 1502 * @param_value: parameter value 1503 * @vdev_id: vdev id 1504 * 1505 * Return: QDF_STATUS_SUCCESS for success or error code 1506 */ 1507 QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr, 1508 uint32_t param_id, uint32_t param_value, 1509 uint32_t vdev_id) 1510 { 1511 tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx; 1512 struct peer_set_params param = {0}; 1513 QDF_STATUS status; 1514 1515 param.vdev_id = vdev_id; 1516 param.param_value = param_value; 1517 param.param_id = param_id; 1518 1519 status = wmi_set_peer_param_send(wma_handle->wmi_handle, 1520 peer_addr, 1521 ¶m); 1522 if (QDF_IS_STATUS_ERROR(status)) 1523 wma_err("vdev_id: %d peer set failed, id %d, val %d", 1524 vdev_id, param_id, param_value); 1525 return status; 1526 } 1527 1528 /** 1529 * wma_peer_unmap_conf_send - send peer unmap conf cmnd to fw 1530 * @wma_ctx: wma handle 1531 * @msg: peer unmap conf params 1532 * 1533 * Return: QDF_STATUS 1534 */ 1535 QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma, 1536 struct send_peer_unmap_conf_params *msg) 1537 { 1538 QDF_STATUS qdf_status; 1539 1540 if (!msg) { 1541 wma_err("null input params"); 1542 return QDF_STATUS_E_INVAL; 1543 } 1544 1545 qdf_status = wmi_unified_peer_unmap_conf_send( 1546 wma->wmi_handle, 1547 msg->vdev_id, 1548 msg->peer_id_cnt, 1549 msg->peer_id_list); 1550 1551 if (qdf_status != QDF_STATUS_SUCCESS) 1552 wma_err("peer_unmap_conf_send failed %d", qdf_status); 1553 1554 qdf_mem_free(msg->peer_id_list); 1555 msg->peer_id_list = NULL; 1556 1557 return qdf_status; 1558 } 1559 1560 /** 1561 * wma_peer_unmap_conf_cb - send peer unmap conf cmnd to fw 1562 * @vdev_id: vdev id 1563 * @peer_id_cnt: no of peer id 1564 * @peer_id_list: list of peer ids 1565 * 1566 * Return: QDF_STATUS 1567 */ 1568 QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id, 1569 uint32_t peer_id_cnt, 1570 uint16_t *peer_id_list) 1571 { 1572 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 1573 QDF_STATUS qdf_status; 1574 1575 if (!wma) 1576 return QDF_STATUS_E_INVAL; 1577 1578 wma_debug("peer_id_cnt: %d", peer_id_cnt); 1579 qdf_status = wmi_unified_peer_unmap_conf_send( 1580 wma->wmi_handle, 1581 vdev_id, peer_id_cnt, 1582 peer_id_list); 1583 1584 if (qdf_status == QDF_STATUS_E_BUSY) { 1585 QDF_STATUS retcode; 1586 struct scheduler_msg msg = {0}; 1587 struct send_peer_unmap_conf_params *peer_unmap_conf_req; 1588 void *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 1589 1590 wma_debug("post unmap_conf cmd to MC thread"); 1591 1592 if (!mac_ctx) 1593 return QDF_STATUS_E_FAILURE; 1594 1595 peer_unmap_conf_req = qdf_mem_malloc(sizeof( 1596 struct send_peer_unmap_conf_params)); 1597 1598 if (!peer_unmap_conf_req) 1599 return QDF_STATUS_E_NOMEM; 1600 1601 peer_unmap_conf_req->vdev_id = vdev_id; 1602 peer_unmap_conf_req->peer_id_cnt = peer_id_cnt; 1603 peer_unmap_conf_req->peer_id_list = qdf_mem_malloc( 1604 sizeof(uint16_t) * peer_id_cnt); 1605 if (!peer_unmap_conf_req->peer_id_list) { 1606 qdf_mem_free(peer_unmap_conf_req); 1607 peer_unmap_conf_req = NULL; 1608 return QDF_STATUS_E_NOMEM; 1609 } 1610 qdf_mem_copy(peer_unmap_conf_req->peer_id_list, 1611 peer_id_list, sizeof(uint16_t) * peer_id_cnt); 1612 1613 msg.type = WMA_SEND_PEER_UNMAP_CONF; 1614 msg.reserved = 0; 1615 msg.bodyptr = peer_unmap_conf_req; 1616 msg.bodyval = 0; 1617 1618 retcode = wma_post_ctrl_msg(mac_ctx, &msg); 1619 if (retcode != QDF_STATUS_SUCCESS) { 1620 wma_err("wma_post_ctrl_msg failed"); 1621 qdf_mem_free(peer_unmap_conf_req->peer_id_list); 1622 qdf_mem_free(peer_unmap_conf_req); 1623 return QDF_STATUS_E_FAILURE; 1624 } 1625 } 1626 1627 return qdf_status; 1628 } 1629 1630 bool wma_objmgr_peer_exist(tp_wma_handle wma, 1631 uint8_t *peer_addr, uint8_t *peer_vdev_id) 1632 { 1633 struct wlan_objmgr_peer *peer; 1634 1635 if (!peer_addr || 1636 qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr)) 1637 return false; 1638 1639 peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_addr, 1640 WLAN_LEGACY_WMA_ID); 1641 if (!peer) 1642 return false; 1643 1644 if (peer_vdev_id) 1645 *peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); 1646 1647 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); 1648 1649 return true; 1650 } 1651 1652 /** 1653 * wma_remove_peer() - remove peer information from host driver and fw 1654 * @wma: wma handle 1655 * @mac_addr: peer mac address, to be removed 1656 * @vdev_id: vdev id 1657 * @no_fw_peer_delete: If true dont send peer delete to firmware 1658 * 1659 * Return: QDF_STATUS 1660 */ 1661 QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, 1662 uint8_t vdev_id, bool no_fw_peer_delete) 1663 { 1664 #define PEER_ALL_TID_BITMASK 0xffffffff 1665 uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK; 1666 uint8_t *peer_addr = mac_addr; 1667 uint8_t peer_mac[QDF_MAC_ADDR_SIZE] = {0}; 1668 struct peer_flush_params param = {0}; 1669 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 1670 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1671 uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL; 1672 bool peer_unmap_conf_support_enabled; 1673 uint8_t peer_vdev_id; 1674 struct peer_delete_cmd_params del_param = {0}; 1675 1676 if (!wma->interfaces[vdev_id].peer_count) { 1677 wma_err("Can't remove peer with peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d", 1678 QDF_MAC_ADDR_REF(peer_addr), vdev_id, 1679 wma->interfaces[vdev_id].peer_count); 1680 QDF_ASSERT(0); 1681 return QDF_STATUS_E_INVAL; 1682 } 1683 1684 if (!soc) { 1685 QDF_BUG(0); 1686 return QDF_STATUS_E_INVAL; 1687 } 1688 1689 if (!wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) { 1690 wma_err("peer doesn't exist peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d", 1691 QDF_MAC_ADDR_REF(peer_addr), vdev_id, 1692 wma->interfaces[vdev_id].peer_count); 1693 return QDF_STATUS_E_INVAL; 1694 } 1695 1696 if (peer_vdev_id != vdev_id) { 1697 wma_err("peer "QDF_MAC_ADDR_FMT" is on vdev id %d but delete req on vdevid %d peer_count %d", 1698 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id, 1699 wma->interfaces[vdev_id].peer_count); 1700 return QDF_STATUS_E_INVAL; 1701 } 1702 peer_unmap_conf_support_enabled = 1703 cdp_cfg_get_peer_unmap_conf_support(soc); 1704 1705 cdp_peer_teardown(soc, vdev_id, peer_addr); 1706 1707 if (no_fw_peer_delete) 1708 goto peer_detach; 1709 1710 /* Flush all TIDs except MGMT TID for this peer in Target */ 1711 peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID); 1712 param.peer_tid_bitmap = peer_tid_bitmap; 1713 param.vdev_id = vdev_id; 1714 if (!wmi_service_enabled(wma->wmi_handle, 1715 wmi_service_peer_delete_no_peer_flush_tids_cmd)) 1716 wmi_unified_peer_flush_tids_send(wma->wmi_handle, mac_addr, 1717 ¶m); 1718 1719 /* peer->ref_cnt is not visible in WMA */ 1720 wlan_roam_debug_log(vdev_id, DEBUG_PEER_DELETE_SEND, 1721 DEBUG_INVALID_PEER_ID, peer_addr, NULL, 1722 0, 0); 1723 1724 del_param.vdev_id = vdev_id; 1725 qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr, 1726 &del_param); 1727 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1728 wma_err("Peer delete could not be sent to firmware %d", 1729 qdf_status); 1730 /* Clear default bit and set to NOT_START_UNMAP */ 1731 bitmap = 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER; 1732 qdf_status = QDF_STATUS_E_FAILURE; 1733 } 1734 1735 peer_detach: 1736 wma_debug("vdevid %d is detaching with peer_addr "QDF_MAC_ADDR_FMT" peer_count %d", 1737 vdev_id, QDF_MAC_ADDR_REF(peer_addr), 1738 wma->interfaces[vdev_id].peer_count); 1739 /* Copy peer mac to find and delete objmgr peer */ 1740 qdf_mem_copy(peer_mac, peer_addr, QDF_MAC_ADDR_SIZE); 1741 if (no_fw_peer_delete && 1742 is_cdp_peer_detach_force_delete_supported(soc)) { 1743 if (!peer_unmap_conf_support_enabled) { 1744 wma_debug("LFR3: trigger force delete for peer "QDF_MAC_ADDR_FMT, 1745 QDF_MAC_ADDR_REF(peer_addr)); 1746 cdp_peer_detach_force_delete(soc, vdev_id, peer_addr); 1747 } else { 1748 cdp_peer_delete_sync(soc, vdev_id, peer_addr, 1749 wma_peer_unmap_conf_cb, 1750 bitmap); 1751 } 1752 } else { 1753 if (no_fw_peer_delete) 1754 wma_debug("LFR3: Delete the peer "QDF_MAC_ADDR_FMT, 1755 QDF_MAC_ADDR_REF(peer_addr)); 1756 1757 if (peer_unmap_conf_support_enabled) 1758 cdp_peer_delete_sync(soc, vdev_id, peer_addr, 1759 wma_peer_unmap_conf_cb, 1760 bitmap); 1761 else 1762 cdp_peer_delete(soc, vdev_id, peer_addr, bitmap); 1763 } 1764 1765 wlan_release_peer_key_wakelock(wma->pdev, peer_mac); 1766 wma_remove_objmgr_peer(wma, wma->interfaces[vdev_id].vdev, peer_mac); 1767 1768 wma->interfaces[vdev_id].peer_count--; 1769 #undef PEER_ALL_TID_BITMASK 1770 1771 return qdf_status; 1772 } 1773 1774 /** 1775 * wma_get_peer_type() - Determine the type of peer(eg. STA/AP) and return it 1776 * @wma: wma handle 1777 * @vdev_id: vdev id 1778 * @peer_addr: peer mac address 1779 * @wma_peer_type: wma peer type 1780 * 1781 * Return: Peer type 1782 */ 1783 static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id, 1784 uint8_t *peer_addr, uint32_t wma_peer_type) 1785 1786 { 1787 uint32_t obj_peer_type = 0; 1788 struct wlan_objmgr_vdev *vdev; 1789 uint8_t *addr; 1790 uint8_t *mld_addr; 1791 1792 vdev = wma->interfaces[vdev_id].vdev; 1793 if (!vdev) { 1794 wma_err("Couldn't find vdev for VDEV_%d", vdev_id); 1795 return obj_peer_type; 1796 } 1797 addr = wlan_vdev_mlme_get_macaddr(vdev); 1798 mld_addr = wlan_vdev_mlme_get_mldaddr(vdev); 1799 1800 if (wma_peer_type == WMI_PEER_TYPE_TDLS) 1801 return WLAN_PEER_TDLS; 1802 1803 if (wma_peer_type == WMI_PEER_TYPE_PASN) 1804 return WLAN_PEER_RTT_PASN; 1805 1806 if (!qdf_mem_cmp(addr, peer_addr, QDF_MAC_ADDR_SIZE) || 1807 !qdf_mem_cmp(mld_addr, peer_addr, QDF_MAC_ADDR_SIZE)) { 1808 obj_peer_type = WLAN_PEER_SELF; 1809 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) { 1810 if (wma->interfaces[vdev_id].sub_type == 1811 WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) 1812 obj_peer_type = WLAN_PEER_P2P_GO; 1813 else 1814 obj_peer_type = WLAN_PEER_AP; 1815 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_AP) { 1816 obj_peer_type = WLAN_PEER_STA; 1817 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_IBSS) { 1818 obj_peer_type = WLAN_PEER_IBSS; 1819 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_NDI) { 1820 obj_peer_type = WLAN_PEER_NDP; 1821 } else { 1822 wma_err("Couldn't find peertype for type %d and sub type %d", 1823 wma->interfaces[vdev_id].type, 1824 wma->interfaces[vdev_id].sub_type); 1825 } 1826 1827 return obj_peer_type; 1828 1829 } 1830 1831 #ifdef WLAN_FEATURE_11BE_MLO 1832 static QDF_STATUS 1833 wma_create_peer_validate_mld_address(tp_wma_handle wma, 1834 uint8_t *peer_mld_addr, 1835 struct wlan_objmgr_vdev *vdev) 1836 { 1837 uint8_t peer_vdev_id, vdev_id; 1838 struct wlan_objmgr_vdev *dup_vdev; 1839 QDF_STATUS status = QDF_STATUS_SUCCESS; 1840 struct wlan_objmgr_psoc *psoc = wma->psoc; 1841 1842 vdev_id = wlan_vdev_get_id(vdev); 1843 /* Check if the @peer_mld_addr matches any other 1844 * peer's link address. 1845 * We may find a match if one of the peers added 1846 * has same MLD and link, in such case check if 1847 * both are in same ML dev context. 1848 */ 1849 if (wma_objmgr_peer_exist(wma, peer_mld_addr, &peer_vdev_id)) { 1850 if (peer_vdev_id != vdev_id) { 1851 dup_vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 1852 psoc, peer_vdev_id, 1853 WLAN_LEGACY_WMA_ID); 1854 if (!dup_vdev) 1855 return QDF_STATUS_E_INVAL; 1856 1857 /* If ML dev context is NULL then the matching 1858 * peer exist on non ML VDEV, so reject the peer. 1859 */ 1860 if (!dup_vdev->mlo_dev_ctx) { 1861 wlan_objmgr_vdev_release_ref( 1862 dup_vdev, WLAN_LEGACY_WMA_ID); 1863 return QDF_STATUS_E_ALREADY; 1864 } else if (dup_vdev->mlo_dev_ctx != vdev->mlo_dev_ctx) { 1865 wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d", 1866 QDF_MAC_ADDR_REF(peer_mld_addr), 1867 peer_vdev_id, vdev_id); 1868 wlan_objmgr_vdev_release_ref( 1869 dup_vdev, WLAN_LEGACY_WMA_ID); 1870 status = QDF_STATUS_E_ALREADY; 1871 } else { 1872 wlan_objmgr_vdev_release_ref( 1873 dup_vdev, WLAN_LEGACY_WMA_ID); 1874 wma_debug("Allow ML peer on same ML dev context"); 1875 status = QDF_STATUS_SUCCESS; 1876 } 1877 } else { 1878 wma_debug("ML Peer exists on same VDEV %d", vdev_id); 1879 status = QDF_STATUS_E_ALREADY; 1880 } 1881 } else if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_mld_addr, 1882 &vdev_id)) { 1883 /* Reject if MLD exists on different ML dev context, 1884 */ 1885 wma_debug("ML Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context", 1886 QDF_MAC_ADDR_REF(peer_mld_addr)); 1887 status = QDF_STATUS_E_ALREADY; 1888 } 1889 1890 return status; 1891 } 1892 #else 1893 static QDF_STATUS 1894 wma_create_peer_validate_mld_address(tp_wma_handle wma, 1895 uint8_t *peer_mld_addr, 1896 struct wlan_objmgr_vdev *vdev) 1897 { 1898 return QDF_STATUS_SUCCESS; 1899 } 1900 #endif 1901 1902 struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma, 1903 uint8_t vdev_id, 1904 uint8_t *peer_addr, 1905 uint32_t wma_peer_type, 1906 uint8_t *peer_mld_addr) 1907 { 1908 QDF_STATUS status; 1909 uint8_t peer_vdev_id; 1910 uint32_t obj_peer_type; 1911 struct wlan_objmgr_vdev *obj_vdev; 1912 struct wlan_objmgr_peer *obj_peer = NULL; 1913 struct wlan_objmgr_psoc *psoc = wma->psoc; 1914 1915 obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1916 WLAN_LEGACY_WMA_ID); 1917 1918 if (!obj_vdev) { 1919 wma_err("Invalid obj vdev. Unable to create peer"); 1920 return NULL; 1921 } 1922 1923 /* 1924 * Check if peer with same MAC exist on any Vdev, If so avoid 1925 * adding this peer. 1926 */ 1927 if (wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) { 1928 wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d", 1929 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id); 1930 goto vdev_ref; 1931 } 1932 1933 /* Reject if same MAC exists on different ML dev context */ 1934 if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_addr, 1935 &vdev_id)) { 1936 wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context", 1937 QDF_MAC_ADDR_REF(peer_addr)); 1938 goto vdev_ref; 1939 } 1940 1941 status = wma_create_peer_validate_mld_address(wma, peer_mld_addr, 1942 obj_vdev); 1943 if (QDF_IS_STATUS_ERROR(status)) { 1944 wma_debug("MLD " QDF_MAC_ADDR_FMT " matches with peer on different MLD context", 1945 QDF_MAC_ADDR_REF(peer_mld_addr)); 1946 goto vdev_ref; 1947 } 1948 1949 obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr, 1950 wma_peer_type); 1951 if (!obj_peer_type) { 1952 wma_err("Invalid obj peer type. Unable to create peer %d", 1953 obj_peer_type); 1954 goto vdev_ref; 1955 } 1956 1957 /* Create obj_mgr peer */ 1958 obj_peer = wlan_objmgr_peer_obj_create(obj_vdev, obj_peer_type, 1959 peer_addr); 1960 1961 vdev_ref: 1962 wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID); 1963 1964 return obj_peer; 1965 1966 } 1967 1968 /** 1969 * wma_increment_peer_count() - Increment the vdev peer 1970 * count 1971 * @wma: wma handle 1972 * @vdev_id: vdev id 1973 * 1974 * Return: None 1975 */ 1976 static void 1977 wma_increment_peer_count(tp_wma_handle wma, uint8_t vdev_id) 1978 { 1979 wma->interfaces[vdev_id].peer_count++; 1980 } 1981 1982 /** 1983 * wma_update_mlo_peer_create() - update mlo parameter for peer creation 1984 * @param: peer create param 1985 * @mlo_enable: mlo enable or not 1986 * 1987 * Return: Void 1988 */ 1989 #ifdef WLAN_FEATURE_11BE_MLO 1990 static void wma_update_mlo_peer_create(struct peer_create_params *param, 1991 bool mlo_enable) 1992 { 1993 param->mlo_enabled = mlo_enable; 1994 } 1995 #else 1996 static void wma_update_mlo_peer_create(struct peer_create_params *param, 1997 bool mlo_enable) 1998 { 1999 } 2000 #endif 2001 2002 /** 2003 * wma_add_peer() - send peer create command to fw 2004 * @wma: wma handle 2005 * @peer_addr: peer mac addr 2006 * @peer_type: peer type 2007 * @vdev_id: vdev id 2008 * @peer_mld_addr: peer mld addr 2009 * @is_assoc_peer: is assoc peer or not 2010 * 2011 * Return: QDF status 2012 */ 2013 static 2014 QDF_STATUS wma_add_peer(tp_wma_handle wma, 2015 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 2016 uint32_t peer_type, uint8_t vdev_id, 2017 uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE], 2018 bool is_assoc_peer) 2019 { 2020 struct peer_create_params param = {0}; 2021 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); 2022 struct wlan_objmgr_psoc *psoc = wma->psoc; 2023 target_resource_config *wlan_res_cfg; 2024 struct wlan_objmgr_peer *obj_peer = NULL; 2025 QDF_STATUS status; 2026 2027 if (!psoc) { 2028 wma_err("psoc is NULL"); 2029 return QDF_STATUS_E_INVAL; 2030 } 2031 2032 wlan_res_cfg = lmac_get_tgt_res_cfg(psoc); 2033 if (!wlan_res_cfg) { 2034 wma_err("psoc target res cfg is null"); 2035 return QDF_STATUS_E_INVAL; 2036 } 2037 2038 if (wma->interfaces[vdev_id].peer_count >= 2039 wlan_res_cfg->num_peers) { 2040 wma_err("the peer count exceeds the limit %d", 2041 wma->interfaces[vdev_id].peer_count); 2042 return QDF_STATUS_E_FAILURE; 2043 } 2044 2045 if (!dp_soc) 2046 return QDF_STATUS_E_FAILURE; 2047 2048 if (qdf_is_macaddr_group((struct qdf_mac_addr *)peer_addr) || 2049 qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr)) { 2050 wma_err("Invalid peer address received reject it"); 2051 return QDF_STATUS_E_FAILURE; 2052 } 2053 2054 obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type, 2055 peer_mld_addr); 2056 if (!obj_peer) 2057 return QDF_STATUS_E_FAILURE; 2058 2059 /* The peer object should be created before sending the WMI peer 2060 * create command to firmware. This is to prevent a race condition 2061 * where the HTT peer map event is received before the peer object 2062 * is created in the data path 2063 */ 2064 if (peer_mld_addr && 2065 !qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_mld_addr)) { 2066 wlan_peer_mlme_flag_ext_set(obj_peer, WLAN_PEER_FEXT_MLO); 2067 wma_debug("peer " QDF_MAC_ADDR_FMT "is_assoc_peer%d mld mac " QDF_MAC_ADDR_FMT, 2068 QDF_MAC_ADDR_REF(peer_addr), is_assoc_peer, 2069 QDF_MAC_ADDR_REF(peer_mld_addr)); 2070 wlan_peer_mlme_set_mldaddr(obj_peer, peer_mld_addr); 2071 wlan_peer_mlme_set_assoc_peer(obj_peer, is_assoc_peer); 2072 wma_update_mlo_peer_create(¶m, true); 2073 } 2074 status = cdp_peer_create(dp_soc, vdev_id, peer_addr); 2075 if (QDF_IS_STATUS_ERROR(status)) { 2076 wma_err("Unable to attach peer "QDF_MAC_ADDR_FMT, 2077 QDF_MAC_ADDR_REF(peer_addr)); 2078 wlan_objmgr_peer_obj_delete(obj_peer); 2079 return QDF_STATUS_E_FAILURE; 2080 } 2081 2082 if (peer_type == WMI_PEER_TYPE_TDLS) 2083 cdp_peer_set_peer_as_tdls(dp_soc, vdev_id, peer_addr, true); 2084 2085 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) || 2086 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id)) { 2087 wma_debug("LFR3: Created peer "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count %d", 2088 QDF_MAC_ADDR_REF(peer_addr), vdev_id, 2089 wma->interfaces[vdev_id].peer_count + 1); 2090 return QDF_STATUS_SUCCESS; 2091 } 2092 param.peer_addr = peer_addr; 2093 param.peer_type = peer_type; 2094 param.vdev_id = vdev_id; 2095 if (wmi_unified_peer_create_send(wma->wmi_handle, 2096 ¶m) != QDF_STATUS_SUCCESS) { 2097 wma_err("Unable to create peer in Target"); 2098 if (cdp_cfg_get_peer_unmap_conf_support(dp_soc)) 2099 cdp_peer_delete_sync( 2100 dp_soc, vdev_id, peer_addr, 2101 wma_peer_unmap_conf_cb, 2102 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER); 2103 else 2104 cdp_peer_delete( 2105 dp_soc, vdev_id, peer_addr, 2106 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER); 2107 wlan_objmgr_peer_obj_delete(obj_peer); 2108 2109 return QDF_STATUS_E_FAILURE; 2110 } 2111 2112 wma_debug("Created peer peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count - %d", 2113 QDF_MAC_ADDR_REF(peer_addr), vdev_id, 2114 wma->interfaces[vdev_id].peer_count + 1); 2115 2116 wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND, 2117 DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0); 2118 2119 return QDF_STATUS_SUCCESS; 2120 } 2121 2122 #ifdef WLAN_FEATURE_11BE_MLO 2123 /** 2124 * wma_cdp_peer_setup() - provide mlo information to cdp_peer_setup 2125 * @wma: wma handle 2126 * @dp_soc: dp soc 2127 * @vdev_id: vdev id 2128 * @peer_addr: peer mac addr 2129 * 2130 * Return: VOID 2131 */ 2132 static void wma_cdp_peer_setup(tp_wma_handle wma, 2133 ol_txrx_soc_handle dp_soc, 2134 uint8_t vdev_id, 2135 uint8_t *peer_addr) 2136 { 2137 struct cdp_peer_setup_info peer_info; 2138 uint8_t *mld_mac; 2139 struct wlan_objmgr_peer *obj_peer = NULL; 2140 2141 obj_peer = wlan_objmgr_get_peer_by_mac(wma->psoc, 2142 peer_addr, 2143 WLAN_LEGACY_WMA_ID); 2144 if (!obj_peer) { 2145 wma_err("Invalid obj_peer"); 2146 return; 2147 } 2148 2149 mld_mac = wlan_peer_mlme_get_mldaddr(obj_peer); 2150 2151 if (!mld_mac || qdf_is_macaddr_zero((struct qdf_mac_addr *)mld_mac)) { 2152 cdp_peer_setup(dp_soc, vdev_id, peer_addr, NULL); 2153 wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID); 2154 return; 2155 } 2156 2157 qdf_mem_zero(&peer_info, sizeof(peer_info)); 2158 2159 peer_info.mld_peer_mac = mld_mac; 2160 if (MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) && 2161 wlan_vdev_mlme_get_is_mlo_link(wma->psoc, vdev_id)) { 2162 peer_info.is_first_link = 1; 2163 peer_info.is_primary_link = 0; 2164 } else if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) && 2165 wlan_vdev_mlme_get_is_mlo_vdev(wma->psoc, vdev_id)) { 2166 if (mlo_get_single_link_ml_roaming(wma->psoc, vdev_id)) { 2167 peer_info.is_first_link = 1; 2168 peer_info.is_primary_link = 1; 2169 } else { 2170 peer_info.is_first_link = 0; 2171 peer_info.is_primary_link = 1; 2172 } 2173 } else { 2174 peer_info.is_first_link = wlan_peer_mlme_is_assoc_peer(obj_peer); 2175 peer_info.is_primary_link = peer_info.is_first_link; 2176 } 2177 2178 cdp_peer_setup(dp_soc, vdev_id, peer_addr, &peer_info); 2179 wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID); 2180 } 2181 #else 2182 static void wma_cdp_peer_setup(tp_wma_handle wma, 2183 ol_txrx_soc_handle dp_soc, 2184 uint8_t vdev_id, 2185 uint8_t *peer_addr) 2186 { 2187 cdp_peer_setup(dp_soc, vdev_id, peer_addr, NULL); 2188 } 2189 #endif 2190 2191 QDF_STATUS wma_create_peer(tp_wma_handle wma, 2192 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 2193 uint32_t peer_type, uint8_t vdev_id, 2194 uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE], 2195 bool is_assoc_peer) 2196 { 2197 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); 2198 QDF_STATUS status; 2199 2200 if (!dp_soc) 2201 return QDF_STATUS_E_FAILURE; 2202 status = wma_add_peer(wma, peer_addr, peer_type, vdev_id, 2203 peer_mld_addr, is_assoc_peer); 2204 if (QDF_IS_STATUS_ERROR(status)) 2205 return status; 2206 2207 wma_increment_peer_count(wma, vdev_id); 2208 wma_cdp_peer_setup(wma, dp_soc, vdev_id, peer_addr); 2209 2210 return QDF_STATUS_SUCCESS; 2211 } 2212 2213 /** 2214 * wma_create_sta_mode_bss_peer() - send peer create command to fw 2215 * and start peer create response timer 2216 * @wma: wma handle 2217 * @peer_addr: peer mac address 2218 * @peer_type: peer type 2219 * @vdev_id: vdev id 2220 * @mld_addr: peer mld address 2221 * @is_assoc_peer: is assoc peer or not 2222 * 2223 * Return: QDF_STATUS 2224 */ 2225 static QDF_STATUS 2226 wma_create_sta_mode_bss_peer(tp_wma_handle wma, 2227 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 2228 uint32_t peer_type, uint8_t vdev_id, 2229 uint8_t mld_addr[QDF_MAC_ADDR_SIZE], 2230 bool is_assoc_peer) 2231 { 2232 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 2233 struct wma_target_req *msg = NULL; 2234 struct peer_create_rsp_params *peer_create_rsp = NULL; 2235 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2236 bool is_tgt_peer_conf_supported = false; 2237 2238 if (!mac) { 2239 wma_err("vdev%d: Mac context is null", vdev_id); 2240 return status; 2241 } 2242 2243 /* 2244 * If fw doesn't advertise peer create confirm event support, 2245 * use the legacy peer create API 2246 */ 2247 is_tgt_peer_conf_supported = 2248 wlan_psoc_nif_fw_ext_cap_get(wma->psoc, 2249 WLAN_SOC_F_PEER_CREATE_RESP); 2250 if (!is_tgt_peer_conf_supported) { 2251 status = wma_create_peer(wma, peer_addr, peer_type, vdev_id, 2252 mld_addr, is_assoc_peer); 2253 goto end; 2254 } 2255 2256 peer_create_rsp = qdf_mem_malloc(sizeof(*peer_create_rsp)); 2257 if (!peer_create_rsp) 2258 goto end; 2259 2260 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock, 2261 WMA_PEER_CREATE_RESPONSE_TIMEOUT); 2262 2263 status = wma_add_peer(wma, peer_addr, peer_type, vdev_id, 2264 mld_addr, is_assoc_peer); 2265 if (QDF_IS_STATUS_ERROR(status)) { 2266 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); 2267 goto end; 2268 } 2269 2270 wma_increment_peer_count(wma, vdev_id); 2271 qdf_mem_copy(peer_create_rsp->peer_mac.bytes, peer_addr, 2272 QDF_MAC_ADDR_SIZE); 2273 2274 msg = wma_fill_hold_req(wma, vdev_id, WMA_PEER_CREATE_REQ, 2275 WMA_PEER_CREATE_RESPONSE, 2276 (void *)peer_create_rsp, 2277 WMA_PEER_CREATE_RESPONSE_TIMEOUT); 2278 if (!msg) { 2279 wma_err("vdev:%d failed to fill peer create req", vdev_id); 2280 wma_remove_peer_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE, 2281 (struct qdf_mac_addr *)peer_addr); 2282 wma_remove_peer(wma, peer_addr, vdev_id, false); 2283 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); 2284 status = QDF_STATUS_E_FAILURE; 2285 goto end; 2286 } 2287 2288 return status; 2289 2290 end: 2291 qdf_mem_free(peer_create_rsp); 2292 lim_send_peer_create_resp(mac, vdev_id, status, peer_addr); 2293 2294 return status; 2295 } 2296 2297 /** 2298 * wma_remove_bss_peer() - remove BSS peer 2299 * @wma: pointer to WMA handle 2300 * @vdev_id: vdev id on which delete BSS request was received 2301 * @vdev_stop_resp: pointer to Delete BSS response 2302 * 2303 * This function is called on receiving vdev stop response from FW or 2304 * vdev stop response timeout. In case of NDI, use vdev's self MAC 2305 * for removing the peer. In case of STA/SAP use bssid passed as part of 2306 * delete STA parameter. 2307 * 2308 * Return: 0 on success, ERROR code on failure 2309 */ 2310 static int wma_remove_bss_peer(tp_wma_handle wma, uint32_t vdev_id, 2311 struct del_bss_resp *vdev_stop_resp, 2312 uint8_t type) 2313 { 2314 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 2315 uint8_t *mac_addr = NULL; 2316 struct wma_target_req *del_req; 2317 int ret_value = 0; 2318 QDF_STATUS qdf_status; 2319 struct qdf_mac_addr bssid; 2320 2321 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) { 2322 mac_addr = cdp_get_vdev_mac_addr(soc, vdev_id); 2323 if (!mac_addr) { 2324 wma_err("mac_addr is NULL for vdev_id = %d", vdev_id); 2325 return -EINVAL; 2326 } 2327 } else { 2328 qdf_status = wlan_vdev_get_bss_peer_mac( 2329 wma->interfaces[vdev_id].vdev, 2330 &bssid); 2331 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2332 wma_err("Failed to get bssid for vdev_id: %d", vdev_id); 2333 return -EINVAL; 2334 } 2335 mac_addr = bssid.bytes; 2336 } 2337 2338 qdf_status = wma_remove_peer(wma, mac_addr, vdev_id, false); 2339 2340 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2341 wma_err("wma_remove_peer failed vdev_id:%d", vdev_id); 2342 return -EINVAL; 2343 } 2344 2345 if (cds_is_driver_recovering()) 2346 return -EINVAL; 2347 2348 if (wmi_service_enabled(wma->wmi_handle, 2349 wmi_service_sync_delete_cmds)) { 2350 wma_debug("Wait for the peer delete. vdev_id %d", vdev_id); 2351 del_req = wma_fill_hold_req(wma, vdev_id, 2352 WMA_DELETE_STA_REQ, 2353 type, 2354 vdev_stop_resp, 2355 WMA_DELETE_STA_TIMEOUT); 2356 if (!del_req) { 2357 wma_err("Failed to allocate request. vdev_id %d", vdev_id); 2358 vdev_stop_resp->status = QDF_STATUS_E_NOMEM; 2359 ret_value = -EINVAL; 2360 } 2361 } 2362 2363 return ret_value; 2364 } 2365 2366 #ifdef FEATURE_WLAN_APF 2367 /* 2368 * get_fw_active_apf_mode() - convert HDD APF mode to FW configurable APF 2369 * mode 2370 * @mode: APF mode maintained in HDD 2371 * 2372 * Return: FW configurable BP mode 2373 */ 2374 static enum wmi_host_active_apf_mode 2375 get_fw_active_apf_mode(enum active_apf_mode mode) 2376 { 2377 switch (mode) { 2378 case ACTIVE_APF_DISABLED: 2379 return WMI_HOST_ACTIVE_APF_DISABLED; 2380 case ACTIVE_APF_ENABLED: 2381 return WMI_HOST_ACTIVE_APF_ENABLED; 2382 case ACTIVE_APF_ADAPTIVE: 2383 return WMI_HOST_ACTIVE_APF_ADAPTIVE; 2384 default: 2385 wma_err("Invalid Active APF Mode %d; Using 'disabled'", mode); 2386 return WMI_HOST_ACTIVE_APF_DISABLED; 2387 } 2388 } 2389 2390 /** 2391 * wma_config_active_apf_mode() - Config active APF mode in FW 2392 * @wma: the WMA handle 2393 * @vdev_id: the Id of the vdev for which the configuration should be applied 2394 * 2395 * Return: QDF status 2396 */ 2397 static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id) 2398 { 2399 enum wmi_host_active_apf_mode uc_mode, mcbc_mode; 2400 2401 uc_mode = get_fw_active_apf_mode(wma->active_uc_apf_mode); 2402 mcbc_mode = get_fw_active_apf_mode(wma->active_mc_bc_apf_mode); 2403 2404 wma_debug("Configuring Active APF Mode UC:%d MC/BC:%d for vdev %u", 2405 uc_mode, mcbc_mode, vdev_id); 2406 2407 return wmi_unified_set_active_apf_mode_cmd(wma->wmi_handle, vdev_id, 2408 uc_mode, mcbc_mode); 2409 } 2410 #else /* FEATURE_WLAN_APF */ 2411 static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id) 2412 { 2413 return QDF_STATUS_SUCCESS; 2414 } 2415 #endif /* FEATURE_WLAN_APF */ 2416 2417 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 2418 /** 2419 * wma_check_and_find_mcc_ap() - finds if device is operating AP 2420 * in MCC mode or not 2421 * @wma: wma handle. 2422 * @vdev_id: vdev ID of device for which MCC has to be checked 2423 * 2424 * This function internally calls wma_find_mcc_ap finds if 2425 * device is operating AP in MCC mode or not 2426 * 2427 * Return: none 2428 */ 2429 static void 2430 wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id) 2431 { 2432 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 2433 2434 if (!mac_ctx) 2435 return; 2436 2437 if (mac_ctx->sap.sap_channel_avoidance) 2438 wma_find_mcc_ap(wma, vdev_id, false); 2439 } 2440 #else 2441 static inline void 2442 wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id) 2443 {} 2444 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 2445 2446 void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp) 2447 { 2448 struct wma_txrx_node *iface; 2449 struct beacon_info *bcn; 2450 uint8_t vdev_id; 2451 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 2452 2453 if (!resp) { 2454 wma_err("req is NULL"); 2455 return; 2456 } 2457 2458 vdev_id = resp->vdev_id; 2459 iface = &wma->interfaces[vdev_id]; 2460 2461 if (!iface->vdev) { 2462 wma_err("vdev id %d iface->vdev is NULL", vdev_id); 2463 if (resp) 2464 qdf_mem_free(resp); 2465 return; 2466 } 2467 2468 cdp_fc_vdev_flush(soc, vdev_id); 2469 wma_debug("vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", 2470 vdev_id); 2471 cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); 2472 wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST); 2473 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); 2474 wma_debug("(type %d subtype %d) BSS is stopped", 2475 iface->type, iface->sub_type); 2476 2477 bcn = wma->interfaces[vdev_id].beacon; 2478 if (bcn) { 2479 wma_debug("Freeing beacon struct %pK, template memory %pK", 2480 bcn, bcn->buf); 2481 if (bcn->dma_mapped) 2482 qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf, 2483 QDF_DMA_TO_DEVICE); 2484 qdf_nbuf_free(bcn->buf); 2485 qdf_mem_free(bcn); 2486 wma->interfaces[vdev_id].beacon = NULL; 2487 } 2488 2489 /* Timeout status means its WMA generated DEL BSS REQ when ADD 2490 * BSS REQ was timed out to stop the VDEV in this case no need 2491 * to send response to UMAC 2492 */ 2493 if (resp->status == QDF_STATUS_FW_MSG_TIMEDOUT) { 2494 qdf_mem_free(resp); 2495 wma_err("DEL BSS from ADD BSS timeout do not send resp to UMAC (vdev id %x)", 2496 vdev_id); 2497 } else { 2498 resp->status = QDF_STATUS_SUCCESS; 2499 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, 2500 (void *)resp, 0); 2501 } 2502 2503 if (iface->del_staself_req && iface->is_del_sta_deferred) { 2504 iface->is_del_sta_deferred = false; 2505 wma_nofl_alert("scheduling deferred deletion (vdev id %x)", 2506 vdev_id); 2507 wma_vdev_detach(iface->del_staself_req); 2508 } 2509 } 2510 2511 QDF_STATUS 2512 wma_send_vdev_down(tp_wma_handle wma, struct del_bss_resp *resp) 2513 { 2514 uint8_t vdev_id; 2515 struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id]; 2516 uint32_t vdev_stop_type; 2517 QDF_STATUS status; 2518 2519 if (!resp) { 2520 wma_err("resp is NULL"); 2521 return QDF_STATUS_E_NULL_VALUE; 2522 } 2523 2524 vdev_id = resp->vdev_id; 2525 status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type); 2526 if (QDF_IS_STATUS_ERROR(status)) { 2527 wma_err("Failed to get vdev stop type"); 2528 qdf_mem_free(resp); 2529 return status; 2530 } 2531 2532 if (vdev_stop_type != WMA_DELETE_BSS_HO_FAIL_REQ) { 2533 status = wma_send_vdev_down_to_fw(wma, vdev_id); 2534 if (QDF_IS_STATUS_ERROR(status)) 2535 wma_err("Failed to send vdev down cmd: vdev %d", vdev_id); 2536 else 2537 wma_check_and_find_mcc_ap(wma, vdev_id); 2538 } 2539 2540 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 2541 WLAN_VDEV_SM_EV_DOWN_COMPLETE, 2542 sizeof(*resp), resp); 2543 return status; 2544 } 2545 2546 /** 2547 * wma_send_vdev_down_req() - handle vdev down req 2548 * @wma: wma handle 2549 * @resp: pointer to vde del bss response 2550 * 2551 * Return: none 2552 */ 2553 2554 static void wma_send_vdev_down_req(tp_wma_handle wma, 2555 struct del_bss_resp *resp) 2556 { 2557 struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id]; 2558 enum QDF_OPMODE mode; 2559 2560 mode = wlan_vdev_mlme_get_opmode(iface->vdev); 2561 if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) { 2562 /* initiate MLME Down req from CM for STA/CLI */ 2563 wlan_cm_bss_peer_delete_rsp(iface->vdev, resp->status); 2564 qdf_mem_free(resp); 2565 return; 2566 } 2567 2568 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 2569 WLAN_VDEV_SM_EV_MLME_DOWN_REQ, 2570 sizeof(*resp), resp); 2571 } 2572 2573 #ifdef WLAN_FEATURE_11BE_MLO 2574 void wma_delete_peer_mlo(struct wlan_objmgr_psoc *psoc, uint8_t *macaddr) 2575 { 2576 struct wlan_objmgr_peer *peer = NULL; 2577 2578 peer = wlan_objmgr_get_peer_by_mac(psoc, macaddr, WLAN_LEGACY_WMA_ID); 2579 if (peer) { 2580 wlan_mlo_link_peer_delete(peer); 2581 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); 2582 } 2583 } 2584 #endif /* WLAN_FEATURE_11BE_MLO */ 2585 2586 static QDF_STATUS 2587 wma_delete_peer_on_vdev_stop(tp_wma_handle wma, uint8_t vdev_id) 2588 { 2589 uint32_t vdev_stop_type; 2590 struct del_bss_resp *vdev_stop_resp; 2591 struct wma_txrx_node *iface; 2592 QDF_STATUS status; 2593 struct qdf_mac_addr bssid; 2594 2595 iface = &wma->interfaces[vdev_id]; 2596 status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid); 2597 if (QDF_IS_STATUS_ERROR(status)) { 2598 wma_err("Failed to get bssid"); 2599 return QDF_STATUS_E_INVAL; 2600 } 2601 2602 status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type); 2603 if (QDF_IS_STATUS_ERROR(status)) { 2604 wma_err("Failed to get wma req msg type for vdev id %d", 2605 vdev_id); 2606 return QDF_STATUS_E_INVAL; 2607 } 2608 2609 wma_delete_peer_mlo(wma->psoc, bssid.bytes); 2610 2611 vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp)); 2612 if (!vdev_stop_resp) 2613 return QDF_STATUS_E_NOMEM; 2614 2615 if (vdev_stop_type == WMA_DELETE_BSS_HO_FAIL_REQ) { 2616 status = wma_remove_peer(wma, bssid.bytes, 2617 vdev_id, true); 2618 if (QDF_IS_STATUS_ERROR(status)) 2619 goto free_params; 2620 2621 vdev_stop_resp->status = status; 2622 vdev_stop_resp->vdev_id = vdev_id; 2623 wma_send_vdev_down_req(wma, vdev_stop_resp); 2624 } else if (vdev_stop_type == WMA_DELETE_BSS_REQ || 2625 vdev_stop_type == WMA_SET_LINK_STATE) { 2626 uint8_t type; 2627 2628 /* CCA is required only for sta interface */ 2629 if (iface->type == WMI_VDEV_TYPE_STA) 2630 wma_get_cca_stats(wma, vdev_id); 2631 if (vdev_stop_type == WMA_DELETE_BSS_REQ) 2632 type = WMA_DELETE_PEER_RSP; 2633 else 2634 type = WMA_SET_LINK_PEER_RSP; 2635 2636 vdev_stop_resp->vdev_id = vdev_id; 2637 vdev_stop_resp->status = status; 2638 status = wma_remove_bss_peer(wma, vdev_id, 2639 vdev_stop_resp, type); 2640 if (status) { 2641 wma_err("Del bss failed vdev:%d", vdev_id); 2642 wma_send_vdev_down_req(wma, vdev_stop_resp); 2643 return status; 2644 } 2645 2646 if (wmi_service_enabled(wma->wmi_handle, 2647 wmi_service_sync_delete_cmds)) 2648 return status; 2649 2650 wma_send_vdev_down_req(wma, vdev_stop_resp); 2651 } 2652 2653 return status; 2654 2655 free_params: 2656 qdf_mem_free(vdev_stop_resp); 2657 return status; 2658 } 2659 2660 QDF_STATUS 2661 cm_send_bss_peer_delete_req(struct wlan_objmgr_vdev *vdev) 2662 { 2663 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 2664 uint8_t vdev_id = wlan_vdev_get_id(vdev); 2665 2666 if (!wma) 2667 return QDF_STATUS_E_INVAL; 2668 2669 if (wlan_vdev_mlme_is_init_state(vdev) == QDF_STATUS_SUCCESS) { 2670 wma_remove_bss_peer_on_failure(wma, vdev_id); 2671 return QDF_STATUS_SUCCESS; 2672 } 2673 2674 return wma_delete_peer_on_vdev_stop(wma, vdev_id); 2675 } 2676 2677 QDF_STATUS 2678 __wma_handle_vdev_stop_rsp(struct vdev_stop_response *resp_event) 2679 { 2680 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 2681 struct wma_txrx_node *iface; 2682 QDF_STATUS status; 2683 struct qdf_mac_addr bssid; 2684 enum QDF_OPMODE mode; 2685 2686 if (!wma) 2687 return QDF_STATUS_E_INVAL; 2688 2689 /* Ignore stop_response in Monitor mode */ 2690 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 2691 return QDF_STATUS_SUCCESS; 2692 2693 iface = &wma->interfaces[resp_event->vdev_id]; 2694 2695 /* vdev in stopped state, no more waiting for key */ 2696 iface->is_waiting_for_key = false; 2697 2698 /* 2699 * Reset the rmfEnabled as there might be MGMT action frames 2700 * sent on this vdev before the next session is established. 2701 */ 2702 if (iface->rmfEnabled) { 2703 iface->rmfEnabled = 0; 2704 wma_debug("Reset rmfEnabled for vdev %d", 2705 resp_event->vdev_id); 2706 } 2707 2708 mode = wlan_vdev_mlme_get_opmode(iface->vdev); 2709 if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) { 2710 status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid); 2711 if (QDF_IS_STATUS_ERROR(status)) { 2712 wma_debug("Failed to get bssid, peer might have got deleted already"); 2713 return wlan_cm_bss_peer_delete_rsp(iface->vdev, status); 2714 } 2715 /* initiate CM to delete bss peer */ 2716 return wlan_cm_bss_peer_delete_ind(iface->vdev, &bssid); 2717 } else if (mode == QDF_SAP_MODE) { 2718 wlan_son_deliver_vdev_stop(iface->vdev); 2719 } 2720 2721 return wma_delete_peer_on_vdev_stop(wma, resp_event->vdev_id); 2722 } 2723 2724 /** 2725 * wma_handle_vdev_stop_rsp() - handle vdev stop resp 2726 * @wma: wma handle 2727 * @resp_event: fw resp 2728 * 2729 * Return: QDF_STATUS 2730 */ 2731 static QDF_STATUS 2732 wma_handle_vdev_stop_rsp(tp_wma_handle wma, 2733 struct vdev_stop_response *resp_event) 2734 { 2735 struct wma_txrx_node *iface; 2736 2737 iface = &wma->interfaces[resp_event->vdev_id]; 2738 return wlan_vdev_mlme_sm_deliver_evt(iface->vdev, 2739 WLAN_VDEV_SM_EV_STOP_RESP, 2740 sizeof(*resp_event), resp_event); 2741 } 2742 2743 QDF_STATUS wma_vdev_stop_resp_handler(struct vdev_mlme_obj *vdev_mlme, 2744 struct vdev_stop_response *rsp) 2745 { 2746 tp_wma_handle wma; 2747 struct wma_txrx_node *iface = NULL; 2748 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2749 2750 wma = cds_get_context(QDF_MODULE_ID_WMA); 2751 if (!wma) 2752 return status; 2753 2754 iface = &wma->interfaces[vdev_mlme->vdev->vdev_objmgr.vdev_id]; 2755 2756 if (rsp->vdev_id >= wma->max_bssid) { 2757 wma_err("Invalid vdev_id %d from FW", rsp->vdev_id); 2758 return QDF_STATUS_E_INVAL; 2759 } 2760 2761 status = wma_handle_vdev_stop_rsp(wma, rsp); 2762 2763 return status; 2764 } 2765 2766 void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev) 2767 { 2768 tp_wma_handle wma_handle; 2769 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 2770 uint8_t vdev_id = wlan_vdev_get_id(vdev); 2771 struct vdev_mlme_obj *vdev_mlme; 2772 2773 if (!soc) 2774 return; 2775 2776 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 2777 if (!wma_handle) 2778 return; 2779 2780 if (!wma_handle->interfaces[vdev_id].vdev) { 2781 wma_err("vdev is NULL"); 2782 return; 2783 } 2784 2785 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 2786 if (!vdev_mlme) { 2787 wma_err("Failed to get vdev mlme obj for vdev id %d", vdev_id); 2788 return; 2789 } 2790 2791 wma_cdp_vdev_detach(soc, wma_handle, vdev_id); 2792 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); 2793 wma_handle->interfaces[vdev_id].vdev = NULL; 2794 wma_handle->interfaces[vdev_id].vdev_active = false; 2795 } 2796 2797 QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme) 2798 { 2799 struct wlan_objmgr_peer *obj_peer; 2800 QDF_STATUS status = QDF_STATUS_SUCCESS; 2801 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 2802 tp_wma_handle wma_handle; 2803 uint8_t peer_vdev_id, *self_peer_macaddr; 2804 2805 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 2806 if (!wma_handle) 2807 return QDF_STATUS_E_FAILURE; 2808 2809 if (mlme_vdev_uses_self_peer(vdev_mlme->mgmt.generic.type, 2810 vdev_mlme->mgmt.generic.subtype)) { 2811 status = wma_create_peer(wma_handle, 2812 vdev->vdev_mlme.macaddr, 2813 WMI_PEER_TYPE_DEFAULT, 2814 wlan_vdev_get_id(vdev), 2815 NULL, false); 2816 if (QDF_IS_STATUS_ERROR(status)) 2817 wma_err("Failed to create peer %d", status); 2818 } else if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA || 2819 vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_NAN) { 2820 if (!qdf_is_macaddr_zero( 2821 (struct qdf_mac_addr *)vdev->vdev_mlme.mldaddr)) 2822 self_peer_macaddr = vdev->vdev_mlme.mldaddr; 2823 else 2824 self_peer_macaddr = vdev->vdev_mlme.macaddr; 2825 2826 /** 2827 * Self peer is used for the frames exchanged before 2828 * association. For ML STA, Self peer create will be triggered 2829 * for both the VDEVs, but one self peer is enough. So in case 2830 * of ML, use MLD address for the self peer and ignore self peer 2831 * creation for the partner link vdev. 2832 */ 2833 if (wma_objmgr_peer_exist(wma_handle, self_peer_macaddr, 2834 &peer_vdev_id)) 2835 return QDF_STATUS_SUCCESS; 2836 2837 obj_peer = wma_create_objmgr_peer(wma_handle, 2838 wlan_vdev_get_id(vdev), 2839 self_peer_macaddr, 2840 WMI_PEER_TYPE_DEFAULT, 2841 vdev->vdev_mlme.macaddr); 2842 if (!obj_peer) { 2843 wma_err("Failed to create obj mgr peer for self"); 2844 status = QDF_STATUS_E_INVAL; 2845 } 2846 } 2847 2848 return status; 2849 } 2850 2851 #ifdef MULTI_CLIENT_LL_SUPPORT 2852 #define MAX_VDEV_LATENCY_PARAMS 10 2853 /* params being sent: 2854 * 1.wmi_vdev_param_set_multi_client_ll_feature_config 2855 * 2.wmi_vdev_param_set_normal_latency_flags_config 2856 * 3.wmi_vdev_param_set_xr_latency_flags_config 2857 * 4.wmi_vdev_param_set_low_latency_flags_config 2858 * 5.wmi_vdev_param_set_ultra_low_latency_flags_config 2859 * 6.wmi_vdev_param_set_normal_latency_ul_dl_config 2860 * 7.wmi_vdev_param_set_xr_latency_ul_dl_config 2861 * 8.wmi_vdev_param_set_low_latency_ul_dl_config 2862 * 9.wmi_vdev_param_set_ultra_low_latency_ul_dl_config 2863 * 10.wmi_vdev_param_set_default_ll_config 2864 */ 2865 2866 /** 2867 * wma_set_vdev_latency_level_param() - Set per vdev latency level params in FW 2868 * @wma_handle: wma handle 2869 * @mac: mac context 2870 * @vdev_id: vdev id 2871 * 2872 * Return: QDF_STATUS 2873 */ 2874 static QDF_STATUS wma_set_vdev_latency_level_param(tp_wma_handle wma_handle, 2875 struct mac_context *mac, 2876 uint8_t vdev_id) 2877 { 2878 QDF_STATUS status = QDF_STATUS_SUCCESS; 2879 bool multi_client_ll_ini_support, multi_client_ll_caps; 2880 uint32_t latency_flags; 2881 static uint32_t ll[4] = {100, 60, 40, 20}; 2882 uint32_t ul_latency, dl_latency, ul_dl_latency; 2883 uint8_t default_latency_level; 2884 struct dev_set_param setparam[MAX_VDEV_LATENCY_PARAMS]; 2885 uint8_t index = 0; 2886 2887 multi_client_ll_ini_support = 2888 mac->mlme_cfg->wlm_config.multi_client_ll_support; 2889 multi_client_ll_caps = 2890 wlan_mlme_get_wlm_multi_client_ll_caps(mac->psoc); 2891 wma_debug("INI support: %d, fw capability:%d", 2892 multi_client_ll_ini_support, multi_client_ll_caps); 2893 /* 2894 * Multi-Client arbiter functionality is enabled only if both INI is 2895 * set, and Service bit is configured. 2896 */ 2897 if (!(multi_client_ll_ini_support && multi_client_ll_caps)) 2898 return status; 2899 status = mlme_check_index_setparam( 2900 setparam, 2901 wmi_vdev_param_set_multi_client_ll_feature_config, 2902 multi_client_ll_ini_support, index++, 2903 MAX_VDEV_LATENCY_PARAMS); 2904 if (QDF_IS_STATUS_ERROR(status)) { 2905 wma_err("failed to configure low latency feature"); 2906 return status; 2907 } 2908 2909 /* wlm latency level index:0 - normal, 1 - xr, 2 - low, 3 - ultralow */ 2910 wma_debug("Setting vdev params for latency level flags"); 2911 2912 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[0]; 2913 status = mlme_check_index_setparam( 2914 setparam, 2915 wmi_vdev_param_set_normal_latency_flags_config, 2916 latency_flags, index++, 2917 MAX_VDEV_LATENCY_PARAMS); 2918 if (QDF_IS_STATUS_ERROR(status)) { 2919 wma_err("failed to configure normal latency feature"); 2920 return status; 2921 } 2922 2923 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[1]; 2924 status = mlme_check_index_setparam( 2925 setparam, 2926 wmi_vdev_param_set_xr_latency_flags_config, 2927 latency_flags, index++, 2928 MAX_VDEV_LATENCY_PARAMS); 2929 if (QDF_IS_STATUS_ERROR(status)) { 2930 wma_err("failed to configure xr latency feature"); 2931 return status; 2932 } 2933 2934 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[2]; 2935 status = mlme_check_index_setparam( 2936 setparam, 2937 wmi_vdev_param_set_low_latency_flags_config, 2938 latency_flags, index++, 2939 MAX_VDEV_LATENCY_PARAMS); 2940 if (QDF_IS_STATUS_ERROR(status)) { 2941 wma_err("failed to configure low latency feature"); 2942 return status; 2943 } 2944 2945 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[3]; 2946 status = mlme_check_index_setparam( 2947 setparam, 2948 wmi_vdev_param_set_ultra_low_latency_flags_config, 2949 latency_flags, index++, MAX_VDEV_LATENCY_PARAMS); 2950 if (QDF_IS_STATUS_ERROR(status)) { 2951 wma_err("failed to configure ultra low latency feature"); 2952 return status; 2953 } 2954 2955 wma_debug("Setting vdev params for Latency level UL/DL flags"); 2956 /* 2957 * Latency level UL/DL 2958 * 0-15 bits: UL and 16-31 bits: DL 2959 */ 2960 dl_latency = ll[0]; 2961 ul_latency = ll[0]; 2962 ul_dl_latency = dl_latency << 16 | ul_latency; 2963 status = mlme_check_index_setparam( 2964 setparam, 2965 wmi_vdev_param_set_normal_latency_ul_dl_config, 2966 ul_dl_latency, index++, 2967 MAX_VDEV_LATENCY_PARAMS); 2968 if (QDF_IS_STATUS_ERROR(status)) { 2969 wma_err("failed to configure normal latency ul dl flag"); 2970 return status; 2971 } 2972 2973 dl_latency = ll[1]; 2974 ul_latency = ll[1]; 2975 ul_dl_latency = dl_latency << 16 | ul_latency; 2976 status = mlme_check_index_setparam( 2977 setparam, 2978 wmi_vdev_param_set_xr_latency_ul_dl_config, 2979 ul_dl_latency, index++, 2980 MAX_VDEV_LATENCY_PARAMS); 2981 if (QDF_IS_STATUS_ERROR(status)) { 2982 wma_err("failed to configure normal latency ul dl flag"); 2983 return status; 2984 } 2985 2986 dl_latency = ll[2]; 2987 ul_latency = ll[2]; 2988 ul_dl_latency = dl_latency << 16 | ul_latency; 2989 status = mlme_check_index_setparam( 2990 setparam, 2991 wmi_vdev_param_set_low_latency_ul_dl_config, 2992 ul_dl_latency, index++, 2993 MAX_VDEV_LATENCY_PARAMS); 2994 if (QDF_IS_STATUS_ERROR(status)) { 2995 wma_err("failed to configure normal latency ul dl flag"); 2996 return status; 2997 } 2998 2999 dl_latency = ll[3]; 3000 ul_latency = ll[3]; 3001 ul_dl_latency = dl_latency << 16 | ul_latency; 3002 status = mlme_check_index_setparam( 3003 setparam, 3004 wmi_vdev_param_set_ultra_low_latency_ul_dl_config, 3005 ul_dl_latency, index++, 3006 MAX_VDEV_LATENCY_PARAMS); 3007 if (QDF_IS_STATUS_ERROR(status)) { 3008 wma_err("failed to configure normal latency ul dl flag"); 3009 return status; 3010 } 3011 3012 default_latency_level = mac->mlme_cfg->wlm_config.latency_level; 3013 status = mlme_check_index_setparam( 3014 setparam, 3015 wmi_vdev_param_set_default_ll_config, 3016 default_latency_level, index++, 3017 MAX_VDEV_LATENCY_PARAMS); 3018 if (QDF_IS_STATUS_ERROR(status)) { 3019 wma_err("failed to configure low latency feature"); 3020 return status; 3021 } 3022 3023 status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 3024 vdev_id, setparam, index); 3025 if (QDF_IS_STATUS_ERROR(status)) 3026 wma_err("Failed to configure vdev latency level params"); 3027 return status; 3028 } 3029 #else 3030 static QDF_STATUS wma_set_vdev_latency_level_param(tp_wma_handle wma_handle, 3031 struct mac_context *mac, 3032 uint8_t vdev_id) 3033 { 3034 return QDF_STATUS_E_FAILURE; 3035 } 3036 #endif 3037 3038 QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev) 3039 { 3040 QDF_STATUS status = QDF_STATUS_SUCCESS; 3041 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 3042 bool mcc_adapt_sch = false; 3043 QDF_STATUS ret; 3044 uint8_t vdev_id; 3045 struct wlan_mlme_qos *qos_aggr; 3046 struct vdev_mlme_obj *vdev_mlme; 3047 tp_wma_handle wma_handle; 3048 uint8_t enable_sifs_burst = 0; 3049 3050 if (!mac) 3051 return QDF_STATUS_E_FAILURE; 3052 3053 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 3054 if (!wma_handle) 3055 return QDF_STATUS_E_FAILURE; 3056 3057 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_WMA_ID) != 3058 QDF_STATUS_SUCCESS) 3059 return QDF_STATUS_E_FAILURE; 3060 3061 vdev_id = wlan_vdev_get_id(vdev); 3062 wma_handle->interfaces[vdev_id].vdev = vdev; 3063 wma_handle->interfaces[vdev_id].vdev_active = true; 3064 3065 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 3066 if (!vdev_mlme) { 3067 wma_err("Failed to get vdev mlme obj!"); 3068 goto end; 3069 } 3070 3071 wma_vdev_update_pause_bitmap(vdev_id, 0); 3072 3073 wma_handle->interfaces[vdev_id].type = 3074 vdev_mlme->mgmt.generic.type; 3075 wma_handle->interfaces[vdev_id].sub_type = 3076 vdev_mlme->mgmt.generic.subtype; 3077 3078 qos_aggr = &mac->mlme_cfg->qos_mlme_params; 3079 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA) { 3080 wma_set_sta_keep_alive( 3081 wma_handle, vdev_id, 3082 SIR_KEEP_ALIVE_NULL_PKT, 3083 mac->mlme_cfg->sta.sta_keep_alive_period, 3084 NULL, NULL, NULL); 3085 3086 /* offload STA SA query related params to fwr */ 3087 if (wmi_service_enabled(wma_handle->wmi_handle, 3088 wmi_service_sta_pmf_offload)) { 3089 wma_set_sta_sa_query_param(wma_handle, vdev_id); 3090 } 3091 3092 status = wma_set_sw_retry_threshold(qos_aggr); 3093 if (QDF_IS_STATUS_ERROR(status)) 3094 wma_err("failed to set sw retry threshold (status = %d)", 3095 status); 3096 3097 status = wma_set_sw_retry_threshold_per_ac(wma_handle, vdev_id, 3098 qos_aggr); 3099 if (QDF_IS_STATUS_ERROR(status)) 3100 wma_err("failed to set sw retry threshold per ac(status = %d)", 3101 status); 3102 } 3103 3104 status = wma_vdev_create_set_param(vdev); 3105 if (QDF_IS_STATUS_ERROR(status)) { 3106 wma_err("Failed to setup Vdev create set param for vdev: %d", 3107 vdev_id); 3108 return status; 3109 } 3110 3111 if (policy_mgr_get_dynamic_mcc_adaptive_sch(mac->psoc, 3112 &mcc_adapt_sch) == 3113 QDF_STATUS_SUCCESS) { 3114 wma_debug("setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d", 3115 mcc_adapt_sch); 3116 ret = 3117 wma_set_enable_disable_mcc_adaptive_scheduler(mcc_adapt_sch); 3118 if (QDF_IS_STATUS_ERROR(ret)) { 3119 wma_err("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED"); 3120 } 3121 } else { 3122 wma_err("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged"); 3123 } 3124 3125 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA && 3126 ucfg_pmo_is_apf_enabled(wma_handle->psoc)) { 3127 ret = wma_config_active_apf_mode(wma_handle, 3128 vdev_id); 3129 if (QDF_IS_STATUS_ERROR(ret)) 3130 wma_err("Failed to configure active APF mode"); 3131 } 3132 3133 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA && 3134 vdev_mlme->mgmt.generic.subtype == 0) 3135 wma_set_vdev_latency_level_param(wma_handle, mac, vdev_id); 3136 3137 switch (vdev_mlme->mgmt.generic.type) { 3138 case WMI_VDEV_TYPE_AP: 3139 if (vdev_mlme->mgmt.generic.subtype != 3140 WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE) 3141 break; 3142 3143 fallthrough; 3144 case WMI_VDEV_TYPE_STA: 3145 case WMI_VDEV_TYPE_NAN: 3146 case WMI_VDEV_TYPE_OCB: 3147 case WMI_VDEV_TYPE_MONITOR: 3148 status = ucfg_get_enable_sifs_burst(wma_handle->psoc, 3149 &enable_sifs_burst); 3150 if (QDF_IS_STATUS_ERROR(status)) 3151 wma_err("Failed to get sifs burst value, use default"); 3152 3153 status = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id, 3154 WMI_PDEV_PARAM_BURST_ENABLE, 3155 enable_sifs_burst); 3156 3157 if (QDF_IS_STATUS_ERROR(status)) 3158 wma_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", 3159 status); 3160 break; 3161 default: 3162 break; 3163 } 3164 3165 wma_vdev_set_data_tx_callback(vdev); 3166 3167 return QDF_STATUS_SUCCESS; 3168 3169 end: 3170 wma_cleanup_vdev(vdev); 3171 return QDF_STATUS_E_FAILURE; 3172 } 3173 3174 QDF_STATUS wma_vdev_set_data_tx_callback(struct wlan_objmgr_vdev *vdev) 3175 { 3176 u_int8_t vdev_id; 3177 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 3178 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 3179 3180 if (!vdev || !wma_handle || !soc) { 3181 wma_err("null vdev, wma_handle or soc"); 3182 return QDF_STATUS_E_FAILURE; 3183 } 3184 3185 vdev_id = wlan_vdev_get_id(vdev); 3186 cdp_data_tx_cb_set(soc, vdev_id, 3187 wma_data_tx_ack_comp_hdlr, 3188 wma_handle); 3189 3190 return QDF_STATUS_SUCCESS; 3191 } 3192 3193 enum mlme_bcn_tx_rate_code wma_get_bcn_rate_code(uint16_t rate) 3194 { 3195 /* rate in multiples of 100 Kbps */ 3196 switch (rate) { 3197 case WMA_BEACON_TX_RATE_1_M: 3198 return MLME_BCN_TX_RATE_CODE_1_M; 3199 case WMA_BEACON_TX_RATE_2_M: 3200 return MLME_BCN_TX_RATE_CODE_2_M; 3201 case WMA_BEACON_TX_RATE_5_5_M: 3202 return MLME_BCN_TX_RATE_CODE_5_5_M; 3203 case WMA_BEACON_TX_RATE_11_M: 3204 return MLME_BCN_TX_RATE_CODE_11M; 3205 case WMA_BEACON_TX_RATE_6_M: 3206 return MLME_BCN_TX_RATE_CODE_6_M; 3207 case WMA_BEACON_TX_RATE_9_M: 3208 return MLME_BCN_TX_RATE_CODE_9_M; 3209 case WMA_BEACON_TX_RATE_12_M: 3210 return MLME_BCN_TX_RATE_CODE_12_M; 3211 case WMA_BEACON_TX_RATE_18_M: 3212 return MLME_BCN_TX_RATE_CODE_18_M; 3213 case WMA_BEACON_TX_RATE_24_M: 3214 return MLME_BCN_TX_RATE_CODE_24_M; 3215 case WMA_BEACON_TX_RATE_36_M: 3216 return MLME_BCN_TX_RATE_CODE_36_M; 3217 case WMA_BEACON_TX_RATE_48_M: 3218 return MLME_BCN_TX_RATE_CODE_48_M; 3219 case WMA_BEACON_TX_RATE_54_M: 3220 return MLME_BCN_TX_RATE_CODE_54_M; 3221 default: 3222 return MLME_BCN_TX_RATE_CODE_1_M; 3223 } 3224 } 3225 3226 QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart) 3227 { 3228 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 3229 struct wma_txrx_node *intr; 3230 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 3231 struct wlan_mlme_nss_chains *ini_cfg; 3232 struct vdev_mlme_obj *mlme_obj; 3233 struct wlan_objmgr_vdev *vdev; 3234 struct wlan_channel *des_chan; 3235 QDF_STATUS status; 3236 enum coex_btc_chain_mode btc_chain_mode; 3237 struct wlan_mlme_qos *qos_aggr; 3238 uint8_t amsdu_val; 3239 3240 if (!wma || !mac_ctx) 3241 return QDF_STATUS_E_FAILURE; 3242 3243 intr = wma->interfaces; 3244 if (!intr) { 3245 wma_err("Invalid interface"); 3246 return QDF_STATUS_E_FAILURE; 3247 } 3248 if (vdev_id >= WLAN_MAX_VDEVS) { 3249 wma_err("Invalid vdev id"); 3250 return QDF_STATUS_E_INVAL; 3251 } 3252 vdev = intr[vdev_id].vdev; 3253 if (!vdev) { 3254 wma_err("Invalid vdev"); 3255 return QDF_STATUS_E_FAILURE; 3256 } 3257 3258 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 3259 if (!mlme_obj) { 3260 wma_err("vdev component object is NULL"); 3261 return QDF_STATUS_E_FAILURE; 3262 } 3263 des_chan = vdev->vdev_mlme.des_chan; 3264 3265 ini_cfg = mlme_get_ini_vdev_config(vdev); 3266 if (!ini_cfg) { 3267 wma_err("nss chain ini config NULL"); 3268 return QDF_STATUS_E_FAILURE; 3269 } 3270 3271 intr[vdev_id].config.gtx_info.gtxRTMask[0] = 3272 CFG_TGT_DEFAULT_GTX_HT_MASK; 3273 intr[vdev_id].config.gtx_info.gtxRTMask[1] = 3274 CFG_TGT_DEFAULT_GTX_VHT_MASK; 3275 3276 intr[vdev_id].config.gtx_info.gtxUsrcfg = 3277 mac_ctx->mlme_cfg->sta.tgt_gtx_usr_cfg; 3278 3279 intr[vdev_id].config.gtx_info.gtxPERThreshold = 3280 CFG_TGT_DEFAULT_GTX_PER_THRESHOLD; 3281 intr[vdev_id].config.gtx_info.gtxPERMargin = 3282 CFG_TGT_DEFAULT_GTX_PER_MARGIN; 3283 intr[vdev_id].config.gtx_info.gtxTPCstep = 3284 CFG_TGT_DEFAULT_GTX_TPC_STEP; 3285 intr[vdev_id].config.gtx_info.gtxTPCMin = 3286 CFG_TGT_DEFAULT_GTX_TPC_MIN; 3287 intr[vdev_id].config.gtx_info.gtxBWMask = 3288 CFG_TGT_DEFAULT_GTX_BW_MASK; 3289 intr[vdev_id].chan_width = des_chan->ch_width; 3290 intr[vdev_id].ch_freq = des_chan->ch_freq; 3291 intr[vdev_id].ch_flagext = des_chan->ch_flagext; 3292 3293 /* 3294 * If the channel has DFS set, flip on radar reporting. 3295 * 3296 * It may be that this should only be done for hostap operation 3297 * as this flag may be interpreted (at some point in the future) 3298 * by the firmware as "oh, and please do radar DETECTION." 3299 * 3300 * If that is ever the case we would insert the decision whether to 3301 * enable the firmware flag here. 3302 */ 3303 if (QDF_GLOBAL_MONITOR_MODE != cds_get_conparam() && 3304 utils_is_dfs_chan_for_freq(wma->pdev, des_chan->ch_freq)) 3305 mlme_obj->mgmt.generic.disable_hw_ack = true; 3306 3307 if (mlme_obj->mgmt.rate_info.bcn_tx_rate) { 3308 wma_debug("beacon tx rate [%u * 100 Kbps]", 3309 mlme_obj->mgmt.rate_info.bcn_tx_rate); 3310 /* 3311 * beacon_tx_rate is in multiples of 100 Kbps. 3312 * Convert the data rate to hw rate code. 3313 */ 3314 mlme_obj->mgmt.rate_info.bcn_tx_rate = 3315 wma_get_bcn_rate_code(mlme_obj->mgmt.rate_info.bcn_tx_rate); 3316 } 3317 3318 if (!restart) { 3319 wma_debug("vdev_id: %d, unpausing tx_ll_queue at VDEV_START", 3320 vdev_id); 3321 3322 cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), 3323 vdev_id, 0xffffffff, 0); 3324 wma_vdev_update_pause_bitmap(vdev_id, 0); 3325 } 3326 3327 /* Send the dynamic nss chain params before vdev start to fw */ 3328 if (wma->dynamic_nss_chains_support && !restart) 3329 wma_vdev_nss_chain_params_send(vdev_id, ini_cfg); 3330 3331 status = ucfg_coex_psoc_get_btc_chain_mode(wma->psoc, &btc_chain_mode); 3332 if (QDF_IS_STATUS_ERROR(status)) { 3333 wma_err("Failed to get btc chain mode"); 3334 return QDF_STATUS_E_FAILURE; 3335 } 3336 3337 if (btc_chain_mode != WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED) { 3338 status = ucfg_coex_send_btc_chain_mode(vdev, btc_chain_mode); 3339 if (QDF_IS_STATUS_ERROR(status)) { 3340 wma_err("Failed to send btc chain mode %d", 3341 btc_chain_mode); 3342 return QDF_STATUS_E_FAILURE; 3343 } 3344 } 3345 3346 qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params; 3347 status = wma_set_tx_rx_aggr_size(vdev_id, qos_aggr->tx_aggregation_size, 3348 qos_aggr->rx_aggregation_size, 3349 WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU); 3350 if (QDF_IS_STATUS_ERROR(status)) 3351 wma_err("failed to set aggregation sizes(status = %d)", status); 3352 3353 status = wlan_mlme_get_max_amsdu_num(wma->psoc, &amsdu_val); 3354 if (QDF_IS_STATUS_ERROR(status)) { 3355 wma_err("failed to get amsdu aggr.size(status = %d)", status); 3356 } else { 3357 status = wma_set_tx_rx_aggr_size(vdev_id, amsdu_val, amsdu_val, 3358 WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU); 3359 if (QDF_IS_STATUS_ERROR(status)) 3360 wma_err("failed to set amsdu aggr.size(status = %d)", 3361 status); 3362 } 3363 3364 if (mlme_obj->mgmt.generic.type == WMI_VDEV_TYPE_STA) { 3365 status = wma_set_tx_rx_aggr_size_per_ac(wma, vdev_id, qos_aggr, 3366 WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU); 3367 3368 if (QDF_IS_STATUS_ERROR(status)) 3369 wma_err("failed to set aggr size per ac(status = %d)", 3370 status); 3371 } 3372 3373 return QDF_STATUS_SUCCESS; 3374 } 3375 3376 /** 3377 * wma_peer_assoc_conf_handler() - peer assoc conf handler 3378 * @handle: wma handle 3379 * @cmd_param_info: event buffer 3380 * @len: buffer length 3381 * 3382 * Return: 0 for success or error code 3383 */ 3384 int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info, 3385 uint32_t len) 3386 { 3387 tp_wma_handle wma = (tp_wma_handle) handle; 3388 WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *param_buf; 3389 wmi_peer_assoc_conf_event_fixed_param *event; 3390 struct wma_target_req *req_msg; 3391 uint8_t macaddr[QDF_MAC_ADDR_SIZE]; 3392 int status = 0; 3393 3394 param_buf = (WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *) cmd_param_info; 3395 if (!param_buf) { 3396 wma_err("Invalid peer assoc conf event buffer"); 3397 return -EINVAL; 3398 } 3399 3400 event = param_buf->fixed_param; 3401 if (!event) { 3402 wma_err("Invalid peer assoc conf event buffer"); 3403 return -EINVAL; 3404 } 3405 3406 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr); 3407 wma_debug("peer assoc conf for vdev:%d mac="QDF_MAC_ADDR_FMT, 3408 event->vdev_id, QDF_MAC_ADDR_REF(macaddr)); 3409 3410 req_msg = wma_find_req(wma, event->vdev_id, 3411 WMA_PEER_ASSOC_CNF_START, NULL); 3412 3413 if (!req_msg) { 3414 wma_err("Failed to lookup request message for vdev %d", 3415 event->vdev_id); 3416 return -EINVAL; 3417 } 3418 3419 qdf_mc_timer_stop(&req_msg->event_timeout); 3420 3421 if (req_msg->msg_type == WMA_ADD_STA_REQ) { 3422 tpAddStaParams params = (tpAddStaParams)req_msg->user_data; 3423 3424 if (!params) { 3425 wma_err("add STA params is NULL for vdev %d", 3426 event->vdev_id); 3427 status = -EINVAL; 3428 goto free_req_msg; 3429 } 3430 3431 /* peer assoc conf event means the cmd succeeds */ 3432 params->status = event->status; 3433 wma_debug("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d", 3434 params->staType, params->smesessionId, 3435 params->assocId, QDF_MAC_ADDR_REF(params->bssId), 3436 params->status); 3437 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, 3438 (void *)params, 0); 3439 } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) { 3440 wma_send_add_bss_resp(wma, event->vdev_id, event->status); 3441 } else { 3442 wma_err("Unhandled request message type: %d", req_msg->msg_type); 3443 } 3444 3445 free_req_msg: 3446 qdf_mc_timer_destroy(&req_msg->event_timeout); 3447 qdf_mem_free(req_msg); 3448 3449 return status; 3450 } 3451 3452 int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info, 3453 uint32_t len) 3454 { 3455 tp_wma_handle wma = (tp_wma_handle)handle; 3456 wmi_peer_create_conf_event_fixed_param *peer_create_rsp; 3457 WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *param_buf; 3458 struct wma_target_req *req_msg = NULL; 3459 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 3460 struct peer_create_rsp_params *rsp_data; 3461 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); 3462 struct qdf_mac_addr peer_mac; 3463 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3464 int ret = -EINVAL; 3465 uint8_t req_msg_type; 3466 3467 param_buf = (WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *)evt_param_info; 3468 if (!param_buf) { 3469 wma_err("Invalid peer create conf evt buffer"); 3470 return -EINVAL; 3471 } 3472 3473 peer_create_rsp = param_buf->fixed_param; 3474 3475 WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_create_rsp->peer_macaddr, 3476 peer_mac.bytes); 3477 if (qdf_is_macaddr_zero(&peer_mac) || 3478 qdf_is_macaddr_broadcast(&peer_mac) || 3479 qdf_is_macaddr_group(&peer_mac)) { 3480 wma_err("Invalid bssid"); 3481 return -EINVAL; 3482 } 3483 3484 wma_debug("vdev:%d Peer create confirm for bssid: " QDF_MAC_ADDR_FMT, 3485 peer_create_rsp->vdev_id, QDF_MAC_ADDR_REF(peer_mac.bytes)); 3486 req_msg = wma_find_remove_req_msgtype(wma, peer_create_rsp->vdev_id, 3487 WMA_PEER_CREATE_REQ); 3488 if (!req_msg) { 3489 wma_debug("vdev:%d Failed to lookup peer create request msg", 3490 peer_create_rsp->vdev_id); 3491 return -EINVAL; 3492 } 3493 3494 rsp_data = (struct peer_create_rsp_params *)req_msg->user_data; 3495 req_msg_type = req_msg->type; 3496 3497 qdf_mc_timer_stop(&req_msg->event_timeout); 3498 qdf_mc_timer_destroy(&req_msg->event_timeout); 3499 qdf_mem_free(rsp_data); 3500 qdf_mem_free(req_msg); 3501 3502 if (req_msg_type == WMA_PASN_PEER_CREATE_RESPONSE) { 3503 wma_pasn_handle_peer_create_conf(wma, &peer_mac, 3504 peer_create_rsp->status, 3505 peer_create_rsp->vdev_id); 3506 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); 3507 return 0; 3508 } 3509 3510 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); 3511 if (!peer_create_rsp->status) { 3512 if (!dp_soc) { 3513 wma_err("DP SOC context is NULL"); 3514 goto fail; 3515 } 3516 3517 wma_cdp_peer_setup(wma, dp_soc, peer_create_rsp->vdev_id, 3518 peer_mac.bytes); 3519 3520 status = QDF_STATUS_SUCCESS; 3521 ret = 0; 3522 } 3523 3524 fail: 3525 if (QDF_IS_STATUS_ERROR(status)) 3526 wma_remove_peer(wma, peer_mac.bytes, peer_create_rsp->vdev_id, 3527 (peer_create_rsp->status > 0) ? true : false); 3528 3529 if (mac) 3530 lim_send_peer_create_resp(mac, peer_create_rsp->vdev_id, status, 3531 peer_mac.bytes); 3532 3533 return ret; 3534 } 3535 3536 #ifdef FEATURE_WDS 3537 /* 3538 * wma_cdp_cp_peer_del_response - handle peer delete response 3539 * @psoc: psoc object pointer 3540 * @mac_addr: Mac address of the peer 3541 * @vdev_id: id of virtual device object 3542 * 3543 * when peer map v2 is enabled, cdp_peer_teardown() does not remove the AST from 3544 * hash table. Call cdp_cp_peer_del_response() when peer delete response is 3545 * received from fw to delete the AST entry from the AST hash. 3546 * 3547 * Return: None 3548 */ 3549 static void 3550 wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc *psoc, 3551 uint8_t *peer_mac, uint8_t vdev_id) 3552 { 3553 ol_txrx_soc_handle soc_txrx_handle; 3554 3555 soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); 3556 cdp_cp_peer_del_response(soc_txrx_handle, vdev_id, peer_mac); 3557 } 3558 #else 3559 static void 3560 wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc *psoc, 3561 uint8_t *peer_mac, uint8_t vdev_id) 3562 { 3563 } 3564 #endif 3565 3566 /** 3567 * wma_peer_delete_handler() - peer delete response handler 3568 * @handle: wma handle 3569 * @cmd_param_info: event buffer 3570 * @len: buffer length 3571 * 3572 * Return: 0 for success or error code 3573 */ 3574 int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info, 3575 uint32_t len) 3576 { 3577 tp_wma_handle wma = (tp_wma_handle) handle; 3578 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 3579 wmi_peer_delete_cmd_fixed_param *event; 3580 struct wma_target_req *req_msg; 3581 tDeleteStaParams *del_sta; 3582 uint8_t macaddr[QDF_MAC_ADDR_SIZE]; 3583 int status = 0; 3584 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 3585 3586 if (!mac) { 3587 wma_err("mac context is null"); 3588 return -EINVAL; 3589 } 3590 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info; 3591 if (!param_buf) { 3592 wma_err("Invalid vdev delete event buffer"); 3593 return -EINVAL; 3594 } 3595 3596 event = (wmi_peer_delete_cmd_fixed_param *)param_buf->fixed_param; 3597 if (!event) { 3598 wma_err("Invalid vdev delete event buffer"); 3599 return -EINVAL; 3600 } 3601 3602 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr); 3603 wma_debug("Peer Delete Response, vdev %d Peer "QDF_MAC_ADDR_FMT, 3604 event->vdev_id, QDF_MAC_ADDR_REF(macaddr)); 3605 wlan_roam_debug_log(event->vdev_id, DEBUG_PEER_DELETE_RESP, 3606 DEBUG_INVALID_PEER_ID, macaddr, NULL, 0, 0); 3607 req_msg = wma_find_remove_req_msgtype(wma, event->vdev_id, 3608 WMA_DELETE_STA_REQ); 3609 if (!req_msg) { 3610 wma_debug("Peer Delete response is not handled"); 3611 return -EINVAL; 3612 } 3613 3614 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); 3615 3616 /* Cleanup timeout handler */ 3617 qdf_mc_timer_stop(&req_msg->event_timeout); 3618 qdf_mc_timer_destroy(&req_msg->event_timeout); 3619 3620 if (req_msg->type == WMA_DELETE_STA_RSP_START) { 3621 del_sta = req_msg->user_data; 3622 if (del_sta->respReqd) { 3623 wma_debug("Sending peer del rsp to umac"); 3624 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, 3625 (void *)del_sta, QDF_STATUS_SUCCESS); 3626 } else { 3627 qdf_mem_free(del_sta); 3628 } 3629 } else if (req_msg->type == WMA_DEL_P2P_SELF_STA_RSP_START) { 3630 struct del_sta_self_rsp_params *data; 3631 3632 data = (struct del_sta_self_rsp_params *)req_msg->user_data; 3633 wma_debug("Calling vdev detach handler"); 3634 wma_handle_vdev_detach(wma, data->self_sta_param); 3635 mlme_vdev_self_peer_delete_resp(data->self_sta_param); 3636 qdf_mem_free(data); 3637 } else if (req_msg->type == WMA_SET_LINK_PEER_RSP || 3638 req_msg->type == WMA_DELETE_PEER_RSP) { 3639 wma_send_vdev_down_req(wma, req_msg->user_data); 3640 } else if (req_msg->type == WMA_DELETE_STA_CONNECT_RSP) { 3641 wma_debug("wma delete peer completed vdev %d", 3642 req_msg->vdev_id); 3643 lim_cm_send_connect_rsp(mac, NULL, req_msg->user_data, 3644 CM_GENERIC_FAILURE, 3645 QDF_STATUS_E_FAILURE, 0, false); 3646 cm_free_join_req(req_msg->user_data); 3647 } 3648 3649 wma_cdp_cp_peer_del_response(wma->psoc, macaddr, event->vdev_id); 3650 qdf_mem_free(req_msg); 3651 3652 return status; 3653 } 3654 3655 static 3656 void wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg, 3657 enum qdf_hang_reason reason) 3658 { 3659 wma_err("%s timed out, triggering recovery", 3660 mac_trace_get_wma_msg_string(wma_msg)); 3661 qdf_trigger_self_recovery(NULL, reason); 3662 } 3663 3664 static inline bool wma_crash_on_fw_timeout(bool crash_enabled) 3665 { 3666 /* Discard FW timeouts and dont crash during SSR */ 3667 if (cds_is_driver_recovering()) 3668 return false; 3669 3670 /* Firmware is down send failure response */ 3671 if (cds_is_fw_down()) 3672 return false; 3673 3674 if (cds_is_driver_unloading()) 3675 return false; 3676 3677 return crash_enabled; 3678 } 3679 3680 /** 3681 * wma_hold_req_timer() - wma hold request timeout function 3682 * @data: target request params 3683 * 3684 * Return: none 3685 */ 3686 void wma_hold_req_timer(void *data) 3687 { 3688 tp_wma_handle wma; 3689 struct wma_target_req *tgt_req = (struct wma_target_req *)data; 3690 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 3691 QDF_STATUS status; 3692 3693 wma = cds_get_context(QDF_MODULE_ID_WMA); 3694 if (!wma) 3695 return; 3696 3697 status = wma_find_req_on_timer_expiry(wma, tgt_req); 3698 3699 if (QDF_IS_STATUS_ERROR(status)) { 3700 /* 3701 * if find request failed, then firmware rsp should have 3702 * consumed the buffer. Do not free. 3703 */ 3704 wma_debug("Failed to lookup request message - %pK", tgt_req); 3705 return; 3706 } 3707 wma_alert("request %d is timed out for vdev_id - %d", 3708 tgt_req->msg_type, tgt_req->vdev_id); 3709 3710 if (tgt_req->msg_type == WMA_ADD_STA_REQ) { 3711 tpAddStaParams params = (tpAddStaParams) tgt_req->user_data; 3712 3713 params->status = QDF_STATUS_E_TIMEOUT; 3714 wma_alert("WMA_ADD_STA_REQ timed out"); 3715 wma_debug("Sending add sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)", 3716 QDF_MAC_ADDR_REF(params->staMac), params->status); 3717 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3718 wma_trigger_recovery_assert_on_fw_timeout( 3719 WMA_ADD_STA_REQ, 3720 QDF_AP_STA_CONNECT_REQ_TIMEOUT); 3721 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, 3722 (void *)params, 0); 3723 } else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) { 3724 3725 wma_alert("WMA_ADD_BSS_REQ timed out"); 3726 wma_debug("Sending add bss rsp to umac (vdev %d, status:%d)", 3727 tgt_req->vdev_id, QDF_STATUS_E_TIMEOUT); 3728 3729 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3730 wma_trigger_recovery_assert_on_fw_timeout( 3731 WMA_ADD_BSS_REQ, 3732 QDF_STA_AP_CONNECT_REQ_TIMEOUT); 3733 3734 wma_send_add_bss_resp(wma, tgt_req->vdev_id, 3735 QDF_STATUS_E_TIMEOUT); 3736 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && 3737 (tgt_req->type == WMA_DELETE_STA_RSP_START)) { 3738 tpDeleteStaParams params = 3739 (tpDeleteStaParams) tgt_req->user_data; 3740 params->status = QDF_STATUS_E_TIMEOUT; 3741 wma_err("WMA_DEL_STA_REQ timed out"); 3742 wma_debug("Sending del sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)", 3743 QDF_MAC_ADDR_REF(params->staMac), params->status); 3744 3745 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3746 wma_trigger_recovery_assert_on_fw_timeout( 3747 WMA_DELETE_STA_REQ, 3748 QDF_PEER_DELETION_TIMEDOUT); 3749 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, 3750 (void *)params, 0); 3751 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && 3752 (tgt_req->type == WMA_DEL_P2P_SELF_STA_RSP_START)) { 3753 struct del_sta_self_rsp_params *del_sta; 3754 3755 del_sta = (struct del_sta_self_rsp_params *)tgt_req->user_data; 3756 3757 del_sta->self_sta_param->status = QDF_STATUS_E_TIMEOUT; 3758 wma_alert("wma delete sta p2p request timed out"); 3759 3760 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3761 wma_trigger_recovery_assert_on_fw_timeout( 3762 WMA_DELETE_STA_REQ, 3763 QDF_PEER_DELETION_TIMEDOUT); 3764 wma_handle_vdev_detach(wma, del_sta->self_sta_param); 3765 mlme_vdev_self_peer_delete_resp(del_sta->self_sta_param); 3766 qdf_mem_free(tgt_req->user_data); 3767 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && 3768 (tgt_req->type == WMA_SET_LINK_PEER_RSP || 3769 tgt_req->type == WMA_DELETE_PEER_RSP)) { 3770 struct del_bss_resp *params = 3771 (struct del_bss_resp *)tgt_req->user_data; 3772 3773 params->status = QDF_STATUS_E_TIMEOUT; 3774 wma_err("wma delete peer for del bss req timed out"); 3775 3776 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3777 wma_trigger_recovery_assert_on_fw_timeout( 3778 WMA_DELETE_STA_REQ, 3779 QDF_PEER_DELETION_TIMEDOUT); 3780 wma_send_vdev_down_req(wma, params); 3781 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && 3782 (tgt_req->type == WMA_DELETE_STA_CONNECT_RSP)) { 3783 wma_err("wma delete peer timed out vdev %d", 3784 tgt_req->vdev_id); 3785 3786 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3787 wma_trigger_recovery_assert_on_fw_timeout( 3788 WMA_DELETE_STA_REQ, 3789 QDF_PEER_DELETION_TIMEDOUT); 3790 if (!mac) { 3791 wma_err("mac: Null Pointer Error"); 3792 goto timer_destroy; 3793 } 3794 lim_cm_send_connect_rsp(mac, NULL, tgt_req->user_data, 3795 CM_GENERIC_FAILURE, 3796 QDF_STATUS_E_FAILURE, 0, false); 3797 cm_free_join_req(tgt_req->user_data); 3798 } else if ((tgt_req->msg_type == SIR_HAL_PDEV_SET_HW_MODE) && 3799 (tgt_req->type == WMA_PDEV_SET_HW_MODE_RESP)) { 3800 struct sir_set_hw_mode_resp *params = 3801 qdf_mem_malloc(sizeof(*params)); 3802 3803 wma_err("set hw mode req timed out"); 3804 3805 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3806 wma_trigger_recovery_assert_on_fw_timeout( 3807 SIR_HAL_PDEV_SET_HW_MODE, 3808 QDF_MAC_HW_MODE_CHANGE_TIMEOUT); 3809 if (!params) 3810 goto timer_destroy; 3811 3812 params->status = SET_HW_MODE_STATUS_ECANCELED; 3813 params->cfgd_hw_mode_index = 0; 3814 params->num_vdev_mac_entries = 0; 3815 wma_send_msg_high_priority(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP, 3816 params, 0); 3817 } else if ((tgt_req->msg_type == SIR_HAL_PDEV_DUAL_MAC_CFG_REQ) && 3818 (tgt_req->type == WMA_PDEV_MAC_CFG_RESP)) { 3819 struct sir_dual_mac_config_resp *resp = 3820 qdf_mem_malloc(sizeof(*resp)); 3821 3822 wma_err("set dual mac config timeout"); 3823 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3824 wma_trigger_recovery_assert_on_fw_timeout( 3825 SIR_HAL_PDEV_DUAL_MAC_CFG_REQ, 3826 QDF_MAC_HW_MODE_CONFIG_TIMEOUT); 3827 if (!resp) 3828 goto timer_destroy; 3829 3830 resp->status = SET_HW_MODE_STATUS_ECANCELED; 3831 wma_send_msg_high_priority(wma, SIR_HAL_PDEV_MAC_CFG_RESP, 3832 resp, 0); 3833 } else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) && 3834 (tgt_req->type == WMA_PEER_CREATE_RESPONSE)) { 3835 struct peer_create_rsp_params *peer_create_rsp; 3836 struct qdf_mac_addr *peer_mac; 3837 3838 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3839 wma_trigger_recovery_assert_on_fw_timeout( 3840 WMA_PEER_CREATE_RESPONSE, 3841 WMA_PEER_CREATE_RESPONSE_TIMEOUT); 3842 3843 peer_create_rsp = 3844 (struct peer_create_rsp_params *)tgt_req->user_data; 3845 peer_mac = &peer_create_rsp->peer_mac; 3846 wma_remove_peer(wma, peer_mac->bytes, 3847 tgt_req->vdev_id, false); 3848 if (!mac) { 3849 qdf_mem_free(tgt_req->user_data); 3850 goto timer_destroy; 3851 } 3852 3853 lim_send_peer_create_resp(mac, tgt_req->vdev_id, 3854 QDF_STATUS_E_TIMEOUT, 3855 (uint8_t *)tgt_req->user_data); 3856 qdf_mem_free(tgt_req->user_data); 3857 } else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) && 3858 (tgt_req->type == WMA_PASN_PEER_CREATE_RESPONSE)) { 3859 struct peer_create_rsp_params *peer_create_rsp; 3860 struct qdf_mac_addr *peer_mac; 3861 3862 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3863 wma_trigger_recovery_assert_on_fw_timeout( 3864 WMA_PEER_CREATE_RESPONSE, 3865 WMA_PEER_CREATE_RESPONSE_TIMEOUT); 3866 3867 peer_create_rsp = 3868 (struct peer_create_rsp_params *)tgt_req->user_data; 3869 peer_mac = &peer_create_rsp->peer_mac; 3870 3871 wma_pasn_handle_peer_create_conf( 3872 wma, peer_mac, QDF_STATUS_E_TIMEOUT, 3873 tgt_req->vdev_id); 3874 qdf_mem_free(tgt_req->user_data); 3875 } else if (tgt_req->msg_type == WMA_PASN_PEER_DELETE_REQUEST && 3876 tgt_req->type == WMA_PASN_PEER_DELETE_RESPONSE) { 3877 wma_err("PASN Peer delete all resp not received. vdev:%d", 3878 tgt_req->vdev_id); 3879 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) 3880 wma_trigger_recovery_assert_on_fw_timeout( 3881 WMA_PASN_PEER_DELETE_RESPONSE, 3882 WMA_PEER_DELETE_RESPONSE_TIMEOUT); 3883 3884 wma_resume_vdev_delete(wma, tgt_req->vdev_id); 3885 } else { 3886 wma_err("Unhandled timeout for msg_type:%d and type:%d", 3887 tgt_req->msg_type, tgt_req->type); 3888 QDF_BUG(0); 3889 } 3890 3891 timer_destroy: 3892 qdf_mc_timer_destroy(&tgt_req->event_timeout); 3893 qdf_mem_free(tgt_req); 3894 } 3895 3896 /** 3897 * wma_fill_hold_req() - fill wma request 3898 * @wma: wma handle 3899 * @vdev_id: vdev id 3900 * @msg_type: message type 3901 * @type: request type 3902 * @params: request params 3903 * @timeout: timeout value 3904 * 3905 * Return: wma_target_req ptr 3906 */ 3907 struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma, 3908 uint8_t vdev_id, 3909 uint32_t msg_type, uint8_t type, 3910 void *params, uint32_t timeout) 3911 { 3912 struct wma_target_req *req; 3913 QDF_STATUS status; 3914 3915 req = qdf_mem_malloc(sizeof(*req)); 3916 if (!req) 3917 return NULL; 3918 3919 wma_debug("vdev_id %d msg %d type %d", vdev_id, msg_type, type); 3920 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock); 3921 req->vdev_id = vdev_id; 3922 req->msg_type = msg_type; 3923 req->type = type; 3924 req->user_data = params; 3925 status = qdf_list_insert_back(&wma->wma_hold_req_queue, &req->node); 3926 if (QDF_STATUS_SUCCESS != status) { 3927 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 3928 wma_err("Failed add request in queue"); 3929 qdf_mem_free(req); 3930 return NULL; 3931 } 3932 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); 3933 qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW, 3934 wma_hold_req_timer, req); 3935 qdf_mc_timer_start(&req->event_timeout, timeout); 3936 return req; 3937 } 3938 3939 void wma_remove_peer_req(tp_wma_handle wma, uint8_t vdev_id, 3940 uint8_t type, struct qdf_mac_addr *peer_addr) 3941 { 3942 struct wma_target_req *req_msg; 3943 3944 wma_debug("Remove req for vdev: %d type: %d", vdev_id, type); 3945 req_msg = wma_find_req(wma, vdev_id, type, peer_addr); 3946 if (!req_msg) { 3947 wma_err("target req not found for vdev: %d type: %d", 3948 vdev_id, type); 3949 return; 3950 } 3951 3952 qdf_mc_timer_stop(&req_msg->event_timeout); 3953 qdf_mc_timer_destroy(&req_msg->event_timeout); 3954 qdf_mem_free(req_msg); 3955 } 3956 3957 /** 3958 * wma_remove_req() - remove request 3959 * @wma: wma handle 3960 * @vdev_id: vdev id 3961 * @type: type 3962 * 3963 * Return: none 3964 */ 3965 void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id, 3966 uint8_t type) 3967 { 3968 struct wma_target_req *req_msg; 3969 3970 wma_debug("Remove req for vdev: %d type: %d", vdev_id, type); 3971 req_msg = wma_find_req(wma, vdev_id, type, NULL); 3972 if (!req_msg) { 3973 wma_err("target req not found for vdev: %d type: %d", 3974 vdev_id, type); 3975 return; 3976 } 3977 3978 qdf_mc_timer_stop(&req_msg->event_timeout); 3979 qdf_mc_timer_destroy(&req_msg->event_timeout); 3980 qdf_mem_free(req_msg); 3981 } 3982 3983 #define MAX_VDEV_SET_BSS_PARAMS 5 3984 /* params being sent: 3985 * 1.wmi_vdev_param_beacon_interval 3986 * 2.wmi_vdev_param_dtim_period 3987 * 3.wmi_vdev_param_tx_pwrlimit 3988 * 4.wmi_vdev_param_slot_time 3989 * 5.wmi_vdev_param_protection_mode 3990 */ 3991 3992 /** 3993 * wma_vdev_set_bss_params() - BSS set params functions 3994 * @wma: wma handle 3995 * @vdev_id: vdev id 3996 * @beaconInterval: beacon interval 3997 * @dtimPeriod: DTIM period 3998 * @shortSlotTimeSupported: short slot time 3999 * @llbCoexist: llbCoexist 4000 * @maxTxPower: max tx power 4001 * @bss_max_idle_period: BSS max idle period 4002 * 4003 * Return: QDF_STATUS 4004 */ 4005 static QDF_STATUS 4006 wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id, 4007 tSirMacBeaconInterval beaconInterval, 4008 uint8_t dtimPeriod, uint8_t shortSlotTimeSupported, 4009 uint8_t llbCoexist, int8_t maxTxPower, 4010 uint16_t bss_max_idle_period) 4011 { 4012 uint32_t slot_time; 4013 struct wma_txrx_node *intr = wma->interfaces; 4014 struct dev_set_param setparam[MAX_VDEV_SET_BSS_PARAMS]; 4015 uint8_t index = 0; 4016 enum ieee80211_protmode prot_mode; 4017 QDF_STATUS ret; 4018 4019 ret = QDF_STATUS_E_FAILURE; 4020 /* Beacon Interval setting */ 4021 ret = mlme_check_index_setparam(setparam, 4022 wmi_vdev_param_beacon_interval, 4023 beaconInterval, index++, 4024 MAX_VDEV_SET_BSS_PARAMS); 4025 if (QDF_IS_STATUS_ERROR(ret)) { 4026 wma_debug("failed to send wmi_vdev_param_beacon_interval to fw"); 4027 goto error; 4028 } 4029 4030 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id, 4031 &intr[vdev_id].config.gtx_info); 4032 if (QDF_IS_STATUS_ERROR(ret)) { 4033 wma_err("failed to set vdev gtx cfg"); 4034 goto error; 4035 } 4036 ret = mlme_check_index_setparam(setparam, wmi_vdev_param_dtim_period, 4037 dtimPeriod, index++, 4038 MAX_VDEV_SET_BSS_PARAMS); 4039 if (QDF_IS_STATUS_ERROR(ret)) { 4040 wma_debug("failed to send wmi_vdev_param_dtim_period fw"); 4041 goto error; 4042 } 4043 intr[vdev_id].dtimPeriod = dtimPeriod; 4044 4045 if (!wlan_reg_is_ext_tpc_supported(wma->psoc)) { 4046 if (!maxTxPower) 4047 wma_warn("Setting Tx power limit to 0"); 4048 4049 wma_nofl_debug("TXP[W][set_bss_params]: %d", maxTxPower); 4050 4051 if (maxTxPower != INVALID_TXPOWER) { 4052 ret = mlme_check_index_setparam( 4053 setparam, 4054 wmi_vdev_param_tx_pwrlimit, 4055 maxTxPower, index++, 4056 MAX_VDEV_SET_BSS_PARAMS); 4057 if (QDF_IS_STATUS_ERROR(ret)) { 4058 wma_debug("failed to send wmi_vdev_param_tx_pwrlimit to fw"); 4059 goto error; 4060 } 4061 } else { 4062 wma_err("Invalid max Tx power"); 4063 } 4064 } 4065 /* Slot time */ 4066 if (shortSlotTimeSupported) 4067 slot_time = WMI_VDEV_SLOT_TIME_SHORT; 4068 else 4069 slot_time = WMI_VDEV_SLOT_TIME_LONG; 4070 ret = mlme_check_index_setparam(setparam, wmi_vdev_param_slot_time, 4071 slot_time, index++, 4072 MAX_VDEV_SET_BSS_PARAMS); 4073 if (QDF_IS_STATUS_ERROR(ret)) { 4074 wma_debug("failed to send wmi_vdev_param_slot_time to fw"); 4075 goto error; 4076 } 4077 /* Initialize protection mode in case of coexistence */ 4078 prot_mode = llbCoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE; 4079 ret = mlme_check_index_setparam(setparam, 4080 wmi_vdev_param_protection_mode, 4081 prot_mode, index++, 4082 MAX_VDEV_SET_BSS_PARAMS); 4083 if (QDF_IS_STATUS_ERROR(ret)) { 4084 wma_debug("failed to send wmi_vdev_param_protection_mode to fw"); 4085 goto error; 4086 } 4087 ret = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 4088 vdev_id, setparam, index); 4089 if (QDF_IS_STATUS_ERROR(ret)) { 4090 wma_err("Failed to set BEACON/DTIM_PERIOD/PWRLIMIT/SLOTTIME/PROTECTION params"); 4091 goto error; 4092 } 4093 mlme_set_max_reg_power(intr[vdev_id].vdev, maxTxPower); 4094 if (bss_max_idle_period) 4095 wma_set_sta_keep_alive( 4096 wma, vdev_id, 4097 SIR_KEEP_ALIVE_NULL_PKT, 4098 bss_max_idle_period, 4099 NULL, NULL, NULL); 4100 error: 4101 return ret; 4102 } 4103 4104 static void wma_set_mgmt_frame_protection(tp_wma_handle wma) 4105 { 4106 struct pdev_params param = {0}; 4107 QDF_STATUS ret; 4108 4109 /* 4110 * when 802.11w PMF is enabled for hw encr/decr 4111 * use hw MFP Qos bits 0x10 4112 */ 4113 param.param_id = wmi_pdev_param_pmf_qos; 4114 param.param_value = true; 4115 ret = wmi_unified_pdev_param_send(wma->wmi_handle, 4116 ¶m, WMA_WILDCARD_PDEV_ID); 4117 if (QDF_IS_STATUS_ERROR(ret)) { 4118 wma_err("Failed to set QOS MFP/PMF (%d)", ret); 4119 } else { 4120 wma_debug("QOS MFP/PMF set"); 4121 } 4122 } 4123 4124 /** 4125 * wma_set_peer_pmf_status() - Get the peer and update PMF capability of it 4126 * @wma: wma handle 4127 * @peer_mac: peer mac addr 4128 * @is_pmf_enabled: Carries the status whether PMF is enabled or not 4129 * 4130 * Return: QDF_STATUS 4131 */ 4132 static QDF_STATUS 4133 wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac, 4134 bool is_pmf_enabled) 4135 { 4136 struct wlan_objmgr_peer *peer; 4137 4138 peer = wlan_objmgr_get_peer(wma->psoc, 4139 wlan_objmgr_pdev_get_pdev_id(wma->pdev), 4140 peer_mac, WLAN_LEGACY_WMA_ID); 4141 if (!peer) { 4142 wma_err("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", 4143 QDF_MAC_ADDR_REF(peer_mac)); 4144 return QDF_STATUS_E_INVAL; 4145 } 4146 mlme_set_peer_pmf_status(peer, is_pmf_enabled); 4147 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); 4148 wma_debug("set is_pmf_enabled %d for "QDF_MAC_ADDR_FMT, 4149 is_pmf_enabled, QDF_MAC_ADDR_REF(peer_mac)); 4150 4151 return QDF_STATUS_SUCCESS; 4152 } 4153 4154 QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id, 4155 struct bss_params *add_bss) 4156 { 4157 QDF_STATUS status; 4158 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 4159 struct wma_txrx_node *iface; 4160 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 4161 struct vdev_mlme_obj *mlme_obj; 4162 uint8_t *mac_addr; 4163 4164 if (!soc || !wma) 4165 return QDF_STATUS_E_FAILURE; 4166 4167 iface = &wma->interfaces[vdev_id]; 4168 4169 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); 4170 if (!mlme_obj) { 4171 wma_err("vdev component object is NULL"); 4172 return QDF_STATUS_E_FAILURE; 4173 } 4174 4175 wma_set_bss_rate_flags(wma, vdev_id, add_bss); 4176 if (wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_NDI_MODE || 4177 wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_IBSS_MODE) 4178 mac_addr = mlme_obj->mgmt.generic.bssid; 4179 else 4180 mac_addr = wlan_vdev_mlme_get_macaddr(iface->vdev); 4181 4182 status = wma_create_peer(wma, mac_addr, 4183 WMI_PEER_TYPE_DEFAULT, vdev_id, 4184 NULL, false); 4185 if (status != QDF_STATUS_SUCCESS) { 4186 wma_err("Failed to create peer"); 4187 return status; 4188 } 4189 4190 if (!cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID, mac_addr)) { 4191 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, 4192 QDF_MAC_ADDR_REF(mac_addr)); 4193 return QDF_STATUS_E_FAILURE; 4194 } 4195 4196 iface->rmfEnabled = add_bss->rmfEnabled; 4197 if (add_bss->rmfEnabled) 4198 wma_set_mgmt_frame_protection(wma); 4199 4200 return status; 4201 } 4202 4203 QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id) 4204 { 4205 QDF_STATUS status = QDF_STATUS_SUCCESS; 4206 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 4207 struct wma_txrx_node *intr; 4208 struct vdev_mlme_obj *mlme_obj; 4209 struct wlan_objmgr_vdev *vdev; 4210 uint8_t bss_power = 0; 4211 4212 if (!wma) 4213 return QDF_STATUS_E_FAILURE; 4214 4215 intr = &wma->interfaces[vdev_id]; 4216 if (!intr) { 4217 wma_err("Invalid interface"); 4218 return QDF_STATUS_E_FAILURE; 4219 } 4220 vdev = intr->vdev; 4221 if (!vdev) { 4222 wma_err("vdev is NULL"); 4223 return QDF_STATUS_E_FAILURE; 4224 } 4225 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NDI_MODE || 4226 wlan_vdev_mlme_get_opmode(vdev) == QDF_IBSS_MODE) { 4227 /* Initialize protection mode to no protection */ 4228 wma_vdev_set_param(wma->wmi_handle, vdev_id, 4229 wmi_vdev_param_protection_mode, 4230 IEEE80211_PROT_NONE); 4231 return status; 4232 } 4233 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 4234 if (!mlme_obj) { 4235 wma_err("vdev component object is NULL"); 4236 return QDF_STATUS_E_FAILURE; 4237 } 4238 4239 /* Fill bss_chan after vdev start */ 4240 qdf_mem_copy(vdev->vdev_mlme.bss_chan, 4241 vdev->vdev_mlme.des_chan, 4242 sizeof(struct wlan_channel)); 4243 4244 if (!wlan_reg_is_ext_tpc_supported(wma->psoc)) 4245 bss_power = wlan_reg_get_channel_reg_power_for_freq( 4246 wma->pdev, vdev->vdev_mlme.bss_chan->ch_freq); 4247 4248 if (wma_vdev_set_bss_params(wma, vdev_id, 4249 mlme_obj->proto.generic.beacon_interval, 4250 mlme_obj->proto.generic.dtim_period, 4251 mlme_obj->proto.generic.slot_time, 4252 mlme_obj->proto.generic.protection_mode, 4253 bss_power, 0)) { 4254 wma_err("Failed to set wma_vdev_set_bss_params"); 4255 } 4256 4257 wma_vdev_set_he_bss_params(wma, vdev_id, 4258 &mlme_obj->proto.he_ops_info); 4259 #if defined(WLAN_FEATURE_11BE) 4260 wma_vdev_set_eht_bss_params(wma, vdev_id, 4261 &mlme_obj->proto.eht_ops_info); 4262 #endif 4263 4264 return status; 4265 } 4266 4267 static QDF_STATUS wma_update_iface_params(tp_wma_handle wma, 4268 struct bss_params *add_bss) 4269 { 4270 struct wma_txrx_node *iface; 4271 uint8_t vdev_id; 4272 4273 vdev_id = add_bss->staContext.smesessionId; 4274 iface = &wma->interfaces[vdev_id]; 4275 wma_set_bss_rate_flags(wma, vdev_id, add_bss); 4276 4277 if (iface->addBssStaContext) 4278 qdf_mem_free(iface->addBssStaContext); 4279 iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams)); 4280 if (!iface->addBssStaContext) 4281 return QDF_STATUS_E_RESOURCES; 4282 4283 *iface->addBssStaContext = add_bss->staContext; 4284 /* Save parameters later needed by WMA_ADD_STA_REQ */ 4285 iface->rmfEnabled = add_bss->rmfEnabled; 4286 if (add_bss->rmfEnabled) 4287 wma_set_peer_pmf_status(wma, add_bss->bssId, true); 4288 iface->beaconInterval = add_bss->beaconInterval; 4289 iface->llbCoexist = add_bss->llbCoexist; 4290 iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported; 4291 iface->nwType = add_bss->nwType; 4292 iface->bss_max_idle_period = add_bss->bss_max_idle_period; 4293 4294 return QDF_STATUS_SUCCESS; 4295 } 4296 4297 static inline 4298 bool wma_cdp_find_peer_by_addr(uint8_t *peer_addr) 4299 { 4300 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 4301 uint8_t pdev_id = OL_TXRX_PDEV_ID; 4302 4303 if (!soc || pdev_id == OL_TXRX_INVALID_PDEV_ID) { 4304 wma_err("Failed to get pdev/soc"); 4305 return NULL; 4306 } 4307 4308 return cdp_find_peer_exist(soc, pdev_id, peer_addr); 4309 } 4310 4311 static 4312 QDF_STATUS wma_save_bss_params(tp_wma_handle wma, struct bss_params *add_bss) 4313 { 4314 QDF_STATUS status; 4315 4316 wma_vdev_set_he_config(wma, add_bss->staContext.smesessionId, add_bss); 4317 if (!wma_cdp_find_peer_by_addr(add_bss->bssId)) 4318 status = QDF_STATUS_E_FAILURE; 4319 else 4320 status = QDF_STATUS_SUCCESS; 4321 qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId, 4322 sizeof(add_bss->staContext.staMac)); 4323 4324 wma_debug("update_bss %d nw_type %d bssid "QDF_MAC_ADDR_FMT" status %d", 4325 add_bss->updateBss, add_bss->nwType, 4326 QDF_MAC_ADDR_REF(add_bss->bssId), 4327 status); 4328 4329 return status; 4330 } 4331 4332 QDF_STATUS wma_pre_assoc_req(struct bss_params *add_bss) 4333 { 4334 QDF_STATUS status; 4335 tp_wma_handle wma; 4336 4337 wma = cds_get_context(QDF_MODULE_ID_WMA); 4338 if (!wma) 4339 return QDF_STATUS_E_INVAL; 4340 4341 status = wma_update_iface_params(wma, add_bss); 4342 if (QDF_IS_STATUS_ERROR(status)) 4343 return status; 4344 4345 status = wma_save_bss_params(wma, add_bss); 4346 4347 return status; 4348 } 4349 4350 void wma_add_bss_lfr3(tp_wma_handle wma, struct bss_params *add_bss) 4351 { 4352 QDF_STATUS status; 4353 4354 status = wma_update_iface_params(wma, add_bss); 4355 if (QDF_IS_STATUS_ERROR(status)) 4356 return; 4357 4358 if (!wma_cdp_find_peer_by_addr(add_bss->bssId)) { 4359 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, 4360 QDF_MAC_ADDR_REF(add_bss->bssId)); 4361 return; 4362 } 4363 wma_debug("LFR3: bssid "QDF_MAC_ADDR_FMT, 4364 QDF_MAC_ADDR_REF(add_bss->bssId)); 4365 } 4366 4367 4368 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) 4369 static 4370 QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id) 4371 { 4372 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 4373 4374 cdp_fc_vdev_pause(soc, vdev_id, 4375 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED, 0); 4376 4377 return QDF_STATUS_SUCCESS; 4378 } 4379 #else 4380 static inline 4381 QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id) 4382 { 4383 return QDF_STATUS_SUCCESS; 4384 } 4385 #endif 4386 4387 void wma_send_add_bss_resp(tp_wma_handle wma, uint8_t vdev_id, 4388 QDF_STATUS status) 4389 { 4390 struct add_bss_rsp *add_bss_rsp; 4391 4392 add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp)); 4393 if (!add_bss_rsp) 4394 return; 4395 4396 add_bss_rsp->vdev_id = vdev_id; 4397 add_bss_rsp->status = status; 4398 lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp); 4399 } 4400 4401 #ifdef WLAN_FEATURE_HOST_ROAM 4402 QDF_STATUS wma_add_bss_lfr2_vdev_start(struct wlan_objmgr_vdev *vdev, 4403 struct bss_params *add_bss) 4404 { 4405 tp_wma_handle wma; 4406 QDF_STATUS status; 4407 struct vdev_mlme_obj *mlme_obj; 4408 uint8_t vdev_id; 4409 bool peer_exist = false; 4410 4411 wma = cds_get_context(QDF_MODULE_ID_WMA); 4412 if (!wma || !vdev) { 4413 wma_err("Invalid wma or vdev"); 4414 return QDF_STATUS_E_INVAL; 4415 } 4416 4417 vdev_id = vdev->vdev_objmgr.vdev_id; 4418 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 4419 if (!mlme_obj) { 4420 wma_err("vdev component object is NULL"); 4421 return QDF_STATUS_E_FAILURE; 4422 } 4423 4424 status = wma_update_iface_params(wma, add_bss); 4425 if (QDF_IS_STATUS_ERROR(status)) 4426 goto send_fail_resp; 4427 4428 peer_exist = wma_cdp_find_peer_by_addr(mlme_obj->mgmt.generic.bssid); 4429 if (!peer_exist) { 4430 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, 4431 QDF_MAC_ADDR_REF(mlme_obj->mgmt.generic.bssid)); 4432 goto send_fail_resp; 4433 } 4434 4435 status = wma_vdev_pre_start(vdev_id, false); 4436 if (QDF_IS_STATUS_ERROR(status)) { 4437 wma_err("failed, status: %d", status); 4438 goto peer_cleanup; 4439 } 4440 status = vdev_mgr_start_send(mlme_obj, false); 4441 if (QDF_IS_STATUS_ERROR(status)) { 4442 wma_err("failed, status: %d", status); 4443 goto peer_cleanup; 4444 } 4445 status = wma_set_cdp_vdev_pause_reason(wma, vdev_id); 4446 if (QDF_IS_STATUS_ERROR(status)) 4447 goto peer_cleanup; 4448 4449 /* ADD_BSS_RESP will be deferred to completion of VDEV_START */ 4450 return QDF_STATUS_SUCCESS; 4451 4452 peer_cleanup: 4453 if (peer_exist) 4454 wma_remove_peer(wma, mlme_obj->mgmt.generic.bssid, vdev_id, 4455 false); 4456 4457 send_fail_resp: 4458 wma_send_add_bss_resp(wma, vdev_id, QDF_STATUS_E_FAILURE); 4459 4460 return QDF_STATUS_SUCCESS; 4461 } 4462 #endif 4463 4464 QDF_STATUS wma_send_peer_assoc_req(struct bss_params *add_bss) 4465 { 4466 struct wma_target_req *msg; 4467 tp_wma_handle wma; 4468 uint8_t vdev_id; 4469 bool peer_exist; 4470 QDF_STATUS status; 4471 struct wma_txrx_node *iface; 4472 int pps_val = 0; 4473 struct vdev_mlme_obj *mlme_obj; 4474 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 4475 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 4476 4477 wma = cds_get_context(QDF_MODULE_ID_WMA); 4478 if (!wma || !mac || !soc) 4479 return QDF_STATUS_E_INVAL; 4480 4481 vdev_id = add_bss->staContext.smesessionId; 4482 4483 iface = &wma->interfaces[vdev_id]; 4484 status = wma_update_iface_params(wma, add_bss); 4485 if (QDF_IS_STATUS_ERROR(status)) 4486 goto send_resp; 4487 4488 peer_exist = wma_cdp_find_peer_by_addr(add_bss->bssId); 4489 if (add_bss->nonRoamReassoc && peer_exist) 4490 goto send_resp; 4491 4492 if (!add_bss->updateBss) 4493 goto send_resp; 4494 4495 if (!peer_exist) { 4496 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, 4497 QDF_MAC_ADDR_REF(add_bss->bssId)); 4498 status = QDF_STATUS_E_FAILURE; 4499 goto send_resp; 4500 } 4501 4502 4503 if (add_bss->staContext.encryptType == eSIR_ED_NONE) { 4504 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into auth", 4505 QDF_MAC_ADDR_REF(add_bss->bssId)); 4506 cdp_peer_state_update(soc, add_bss->bssId, 4507 OL_TXRX_PEER_STATE_AUTH); 4508 } else { 4509 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into conn", 4510 QDF_MAC_ADDR_REF(add_bss->bssId)); 4511 cdp_peer_state_update(soc, add_bss->bssId, 4512 OL_TXRX_PEER_STATE_CONN); 4513 status = wma_set_cdp_vdev_pause_reason(wma, vdev_id); 4514 if (QDF_IS_STATUS_ERROR(status)) 4515 goto send_resp; 4516 } 4517 4518 wmi_unified_send_txbf(wma, &add_bss->staContext); 4519 4520 pps_val = ((mac->mlme_cfg->sta.enable_5g_ebt << 31) & 4521 0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff); 4522 status = wma_vdev_set_param(wma->wmi_handle, vdev_id, 4523 wmi_vdev_param_packet_powersave, 4524 pps_val); 4525 if (QDF_IS_STATUS_ERROR(status)) 4526 wma_err("Failed to send wmi packet power save cmd"); 4527 else 4528 wma_debug("Sent packet power save %x", pps_val); 4529 4530 add_bss->staContext.no_ptk_4_way = add_bss->no_ptk_4_way; 4531 4532 status = wma_send_peer_assoc(wma, add_bss->nwType, 4533 &add_bss->staContext); 4534 if (QDF_IS_STATUS_ERROR(status)) { 4535 wma_err("Failed to send peer assoc status:%d", status); 4536 goto send_resp; 4537 } 4538 4539 /* we just had peer assoc, so install key will be done later */ 4540 if (add_bss->staContext.encryptType != eSIR_ED_NONE) 4541 iface->is_waiting_for_key = true; 4542 4543 if (add_bss->rmfEnabled) 4544 wma_set_mgmt_frame_protection(wma); 4545 4546 if (wlan_reg_is_ext_tpc_supported(wma->psoc)) 4547 add_bss->maxTxPower = 0; 4548 4549 if (wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId, 4550 add_bss->beaconInterval, 4551 add_bss->dtimPeriod, 4552 add_bss->shortSlotTimeSupported, 4553 add_bss->llbCoexist, 4554 add_bss->maxTxPower, 4555 add_bss->bss_max_idle_period)) { 4556 wma_err("Failed to set bss params"); 4557 } 4558 4559 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); 4560 if (!mlme_obj) { 4561 wma_err("Failed to mlme obj"); 4562 status = QDF_STATUS_E_FAILURE; 4563 goto send_resp; 4564 } 4565 /* 4566 * Store the bssid in interface table, bssid will 4567 * be used during group key setting sta mode. 4568 */ 4569 qdf_mem_copy(mlme_obj->mgmt.generic.bssid, 4570 add_bss->bssId, QDF_MAC_ADDR_SIZE); 4571 4572 wma_save_bss_params(wma, add_bss); 4573 4574 if (!wmi_service_enabled(wma->wmi_handle, 4575 wmi_service_peer_assoc_conf)) { 4576 wma_debug("WMI_SERVICE_PEER_ASSOC_CONF not enabled"); 4577 goto send_resp; 4578 } 4579 4580 msg = wma_fill_hold_req(wma, vdev_id, WMA_ADD_BSS_REQ, 4581 WMA_PEER_ASSOC_CNF_START, NULL, 4582 WMA_PEER_ASSOC_TIMEOUT); 4583 if (!msg) { 4584 wma_err("Failed to allocate request for vdev_id %d", vdev_id); 4585 wma_remove_req(wma, vdev_id, WMA_PEER_ASSOC_CNF_START); 4586 status = QDF_STATUS_E_FAILURE; 4587 goto send_resp; 4588 } 4589 4590 return QDF_STATUS_SUCCESS; 4591 4592 send_resp: 4593 wma_send_add_bss_resp(wma, vdev_id, status); 4594 4595 return QDF_STATUS_SUCCESS; 4596 } 4597 4598 #ifdef WLAN_FEATURE_11BE_MLO 4599 /** 4600 * wma_get_mld_info_ap() - get mld mac addr and assoc peer flag for ap 4601 * @add_sta: tpAddStaParams 4602 * @peer_mld_addr: peer mld mac addr 4603 * @is_assoc_peer: is assoc peer or not 4604 * 4605 * Return: void 4606 */ 4607 static void wma_get_mld_info_ap(tpAddStaParams add_sta, 4608 uint8_t **peer_mld_addr, 4609 bool *is_assoc_peer) 4610 { 4611 if (add_sta) { 4612 *peer_mld_addr = add_sta->mld_mac_addr; 4613 *is_assoc_peer = add_sta->is_assoc_peer; 4614 } else { 4615 peer_mld_addr = NULL; 4616 *is_assoc_peer = false; 4617 } 4618 } 4619 #else 4620 static void wma_get_mld_info_ap(tpAddStaParams add_sta, 4621 uint8_t **peer_mld_addr, 4622 bool *is_assoc_peer) 4623 { 4624 *peer_mld_addr = NULL; 4625 *is_assoc_peer = false; 4626 } 4627 #endif 4628 4629 /** 4630 * wma_add_sta_req_ap_mode() - process add sta request in ap mode 4631 * @wma: wma handle 4632 * @add_sta: add sta params 4633 * 4634 * Return: none 4635 */ 4636 static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) 4637 { 4638 enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN; 4639 uint8_t pdev_id = OL_TXRX_PDEV_ID; 4640 QDF_STATUS status; 4641 int32_t ret; 4642 struct wma_txrx_node *iface = NULL; 4643 struct wma_target_req *msg; 4644 bool peer_assoc_cnf = false; 4645 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 4646 uint32_t i, j; 4647 uint16_t mcs_limit; 4648 uint8_t *rate_pos; 4649 struct mac_context *mac = wma->mac_context; 4650 uint8_t *peer_mld_addr = NULL; 4651 bool is_assoc_peer = false; 4652 4653 /* UMAC sends WMA_ADD_STA_REQ msg twice to WMA when the station 4654 * associates. First WMA_ADD_STA_REQ will have staType as 4655 * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF. 4656 * Peer creation is done in first WMA_ADD_STA_REQ and second 4657 * WMA_ADD_STA_REQ which has STA_ENTRY_SELF is ignored and 4658 * send fake response with success to UMAC. Otherwise UMAC 4659 * will get blocked. 4660 */ 4661 if (add_sta->staType != STA_ENTRY_PEER) { 4662 add_sta->status = QDF_STATUS_SUCCESS; 4663 goto send_rsp; 4664 } 4665 4666 iface = &wma->interfaces[add_sta->smesessionId]; 4667 4668 if (cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId, 4669 add_sta->staMac)) { 4670 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, 4671 false); 4672 wma_err("Peer already exists, Deleted peer with peer_addr "QDF_MAC_ADDR_FMT, 4673 QDF_MAC_ADDR_REF(add_sta->staMac)); 4674 } 4675 /* The code above only checks the peer existence on its own vdev. 4676 * Need to check whether the peer exists on other vDevs because firmware 4677 * can't create the peer if the peer with same MAC address already 4678 * exists on the pDev. As this peer belongs to other vDevs, just return 4679 * here. 4680 */ 4681 if (cdp_find_peer_exist(soc, pdev_id, add_sta->staMac)) { 4682 wma_err("My vdev id %d, but Peer exists on other vdev with peer_addr "QDF_MAC_ADDR_FMT, 4683 add_sta->smesessionId, 4684 QDF_MAC_ADDR_REF(add_sta->staMac)); 4685 add_sta->status = QDF_STATUS_E_FAILURE; 4686 goto send_rsp; 4687 } 4688 4689 wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac); 4690 4691 wma_get_mld_info_ap(add_sta, &peer_mld_addr, &is_assoc_peer); 4692 status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_DEFAULT, 4693 add_sta->smesessionId, peer_mld_addr, 4694 is_assoc_peer); 4695 if (status != QDF_STATUS_SUCCESS) { 4696 wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT, 4697 QDF_MAC_ADDR_REF(add_sta->staMac)); 4698 add_sta->status = status; 4699 goto send_rsp; 4700 } 4701 4702 if (!cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId, 4703 add_sta->staMac)) { 4704 wma_err("Failed to find peer handle using peer mac "QDF_MAC_ADDR_FMT, 4705 QDF_MAC_ADDR_REF(add_sta->staMac)); 4706 add_sta->status = QDF_STATUS_E_FAILURE; 4707 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, 4708 false); 4709 goto send_rsp; 4710 } 4711 4712 wmi_unified_send_txbf(wma, add_sta); 4713 4714 /* 4715 * Get MCS limit from ini configure, and map it to rate parameters 4716 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to 4717 * check whether ini config is enabled and CFG_DATA_MASK to get the 4718 * MCS value. 4719 */ 4720 #define CFG_CTRL_MASK 0xFF00 4721 #define CFG_DATA_MASK 0x00FF 4722 4723 mcs_limit = mac->mlme_cfg->rates.sap_max_mcs_txdata; 4724 4725 if (mcs_limit & CFG_CTRL_MASK) { 4726 wma_debug("set mcs_limit %x", mcs_limit); 4727 4728 mcs_limit &= CFG_DATA_MASK; 4729 rate_pos = (u_int8_t *)add_sta->supportedRates.supportedMCSSet; 4730 for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) { 4731 if (j < mcs_limit / 8) { 4732 rate_pos[j] = 0xff; 4733 j++; 4734 i += 8; 4735 } else if (j < mcs_limit / 8 + 1) { 4736 if (i <= mcs_limit) 4737 rate_pos[i / 8] |= 1 << (i % 8); 4738 else 4739 rate_pos[i / 8] &= ~(1 << (i % 8)); 4740 i++; 4741 4742 if (i >= (j + 1) * 8) 4743 j++; 4744 } else { 4745 rate_pos[j++] = 0; 4746 i += 8; 4747 } 4748 } 4749 } 4750 4751 if (wmi_service_enabled(wma->wmi_handle, 4752 wmi_service_peer_assoc_conf)) { 4753 peer_assoc_cnf = true; 4754 msg = wma_fill_hold_req(wma, add_sta->smesessionId, 4755 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START, 4756 add_sta, WMA_PEER_ASSOC_TIMEOUT); 4757 if (!msg) { 4758 wma_err("Failed to alloc request for vdev_id %d", 4759 add_sta->smesessionId); 4760 add_sta->status = QDF_STATUS_E_FAILURE; 4761 wma_remove_req(wma, add_sta->smesessionId, 4762 WMA_PEER_ASSOC_CNF_START); 4763 wma_remove_peer(wma, add_sta->staMac, 4764 add_sta->smesessionId, false); 4765 peer_assoc_cnf = false; 4766 goto send_rsp; 4767 } 4768 } else { 4769 wma_err("WMI_SERVICE_PEER_ASSOC_CONF not enabled"); 4770 } 4771 4772 ret = wma_send_peer_assoc(wma, add_sta->nwType, add_sta); 4773 if (ret) { 4774 add_sta->status = QDF_STATUS_E_FAILURE; 4775 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, 4776 false); 4777 goto send_rsp; 4778 } 4779 4780 if (add_sta->rmfEnabled) 4781 wma_set_peer_pmf_status(wma, add_sta->staMac, true); 4782 4783 if (add_sta->uAPSD) { 4784 status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId, 4785 add_sta->staMac, 4786 add_sta->uAPSD, add_sta->maxSPLen); 4787 if (QDF_IS_STATUS_ERROR(status)) { 4788 wma_err("Failed to set peer uapsd param for "QDF_MAC_ADDR_FMT, 4789 QDF_MAC_ADDR_REF(add_sta->staMac)); 4790 add_sta->status = QDF_STATUS_E_FAILURE; 4791 wma_remove_peer(wma, add_sta->staMac, 4792 add_sta->smesessionId, false); 4793 goto send_rsp; 4794 } 4795 } 4796 4797 wma_debug("Moving peer "QDF_MAC_ADDR_FMT" to state %d", 4798 QDF_MAC_ADDR_REF(add_sta->staMac), state); 4799 cdp_peer_state_update(soc, add_sta->staMac, state); 4800 4801 add_sta->nss = wma_objmgr_get_peer_mlme_nss(wma, add_sta->staMac); 4802 add_sta->status = QDF_STATUS_SUCCESS; 4803 send_rsp: 4804 /* Do not send add stat resp when peer assoc cnf is enabled */ 4805 if (peer_assoc_cnf) { 4806 wma_debug("WMI_SERVICE_PEER_ASSOC_CONF is enabled"); 4807 return; 4808 } 4809 4810 wma_debug("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d", 4811 add_sta->staType, add_sta->smesessionId, 4812 add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId), 4813 add_sta->status); 4814 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0); 4815 } 4816 4817 #ifdef FEATURE_WLAN_TDLS 4818 4819 /** 4820 * wma_add_tdls_sta() - process add sta request in TDLS mode 4821 * @wma: wma handle 4822 * @add_sta: add sta params 4823 * 4824 * Return: none 4825 */ 4826 static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) 4827 { 4828 QDF_STATUS status; 4829 int32_t ret; 4830 struct tdls_peer_update_state *peer_state; 4831 struct wma_target_req *msg; 4832 bool peer_assoc_cnf = false; 4833 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 4834 uint8_t pdev_id = OL_TXRX_PDEV_ID; 4835 struct wma_txrx_node *iface = &wma->interfaces[add_sta->smesessionId]; 4836 4837 wma_debug("staType: %d, updateSta: %d, bssId: "QDF_MAC_ADDR_FMT", staMac: "QDF_MAC_ADDR_FMT, 4838 add_sta->staType, 4839 add_sta->updateSta, QDF_MAC_ADDR_REF(add_sta->bssId), 4840 QDF_MAC_ADDR_REF(add_sta->staMac)); 4841 4842 if (iface->vdev && wlan_cm_is_vdev_roaming(iface->vdev)) { 4843 wma_err("Vdev %d roaming in progress, reject add sta!", 4844 add_sta->smesessionId); 4845 add_sta->status = QDF_STATUS_E_PERM; 4846 goto send_rsp; 4847 } 4848 4849 if (0 == add_sta->updateSta) { 4850 /* its a add sta request * */ 4851 4852 cdp_peer_copy_mac_addr_raw(soc, add_sta->smesessionId, 4853 add_sta->bssId); 4854 4855 wma_debug("addSta, calling wma_create_peer for "QDF_MAC_ADDR_FMT", vdev_id %hu", 4856 QDF_MAC_ADDR_REF(add_sta->staMac), 4857 add_sta->smesessionId); 4858 4859 status = wma_create_peer(wma, add_sta->staMac, 4860 WMI_PEER_TYPE_TDLS, 4861 add_sta->smesessionId, NULL, false); 4862 if (status != QDF_STATUS_SUCCESS) { 4863 wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT, 4864 QDF_MAC_ADDR_REF(add_sta->staMac)); 4865 add_sta->status = status; 4866 goto send_rsp; 4867 } 4868 4869 wma_debug("addSta, after calling cdp_local_peer_id, staMac: "QDF_MAC_ADDR_FMT, 4870 QDF_MAC_ADDR_REF(add_sta->staMac)); 4871 4872 peer_state = qdf_mem_malloc(sizeof(*peer_state)); 4873 if (!peer_state) { 4874 add_sta->status = QDF_STATUS_E_NOMEM; 4875 goto send_rsp; 4876 } 4877 4878 peer_state->peer_state = WMI_TDLS_PEER_STATE_PEERING; 4879 peer_state->vdev_id = add_sta->smesessionId; 4880 qdf_mem_copy(&peer_state->peer_macaddr, 4881 &add_sta->staMac, sizeof(tSirMacAddr)); 4882 wma_update_tdls_peer_state(wma, peer_state); 4883 } else { 4884 if (wmi_service_enabled(wma->wmi_handle, 4885 wmi_service_peer_assoc_conf)) { 4886 wma_err("WMI_SERVICE_PEER_ASSOC_CONF is enabled"); 4887 peer_assoc_cnf = true; 4888 msg = wma_fill_hold_req(wma, add_sta->smesessionId, 4889 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START, 4890 add_sta, WMA_PEER_ASSOC_TIMEOUT); 4891 if (!msg) { 4892 wma_err("Failed to alloc request for vdev_id %d", 4893 add_sta->smesessionId); 4894 add_sta->status = QDF_STATUS_E_FAILURE; 4895 wma_remove_req(wma, add_sta->smesessionId, 4896 WMA_PEER_ASSOC_CNF_START); 4897 wma_remove_peer(wma, add_sta->staMac, 4898 add_sta->smesessionId, false); 4899 peer_assoc_cnf = false; 4900 goto send_rsp; 4901 } 4902 } else { 4903 wma_err("WMI_SERVICE_PEER_ASSOC_CONF not enabled"); 4904 } 4905 4906 wma_debug("changeSta, calling wma_send_peer_assoc"); 4907 if (add_sta->rmfEnabled) 4908 wma_set_peer_pmf_status(wma, add_sta->staMac, true); 4909 4910 ret = 4911 wma_send_peer_assoc(wma, add_sta->nwType, add_sta); 4912 if (ret) { 4913 add_sta->status = QDF_STATUS_E_FAILURE; 4914 wma_remove_peer(wma, add_sta->staMac, 4915 add_sta->smesessionId, false); 4916 cdp_peer_add_last_real_peer(soc, pdev_id, 4917 add_sta->smesessionId); 4918 wma_remove_req(wma, add_sta->smesessionId, 4919 WMA_PEER_ASSOC_CNF_START); 4920 peer_assoc_cnf = false; 4921 4922 goto send_rsp; 4923 } 4924 } 4925 4926 send_rsp: 4927 /* Do not send add stat resp when peer assoc cnf is enabled */ 4928 if (peer_assoc_cnf) 4929 return; 4930 4931 wma_debug("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d", 4932 add_sta->staType, add_sta->smesessionId, 4933 add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId), 4934 add_sta->status); 4935 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0); 4936 } 4937 #endif 4938 4939 /** 4940 * wma_send_bss_color_change_enable() - send bss color change enable cmd. 4941 * @wma: wma handle 4942 * @params: add sta params 4943 * 4944 * Send bss color change command to firmware, to enable firmware to update 4945 * internally if any change in bss color in advertised by associated AP. 4946 * 4947 * Return: none 4948 */ 4949 #ifdef WLAN_FEATURE_11AX 4950 static void wma_send_bss_color_change_enable(tp_wma_handle wma, 4951 tpAddStaParams params) 4952 { 4953 QDF_STATUS status; 4954 uint32_t vdev_id = params->smesessionId; 4955 4956 if (!params->he_capable) { 4957 wma_debug("he_capable is not set for vdev_id:%d", vdev_id); 4958 return; 4959 } 4960 4961 status = wmi_unified_send_bss_color_change_enable_cmd(wma->wmi_handle, 4962 vdev_id, 4963 true); 4964 if (QDF_IS_STATUS_ERROR(status)) { 4965 wma_err("Failed to enable bss color change offload, vdev:%d", 4966 vdev_id); 4967 } 4968 4969 return; 4970 } 4971 #else 4972 static void wma_send_bss_color_change_enable(tp_wma_handle wma, 4973 tpAddStaParams params) 4974 { 4975 } 4976 #endif 4977 4978 #define MAX_VDEV_STA_REQ_PARAMS 5 4979 /* params being sent: 4980 * 1.wmi_vdev_param_max_li_of_moddtim 4981 * 2.wmi_vdev_param_max_li_of_moddtim_ms 4982 * 3.wmi_vdev_param_dyndtim_cnt 4983 * 4.wmi_vdev_param_moddtim_cnt 4984 * 5.wmi_vdev_param_moddtim_cnt 4985 */ 4986 4987 /** 4988 * wma_add_sta_req_sta_mode() - process add sta request in sta mode 4989 * @wma: wma handle 4990 * @params: add sta params 4991 * 4992 * Return: none 4993 */ 4994 static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) 4995 { 4996 QDF_STATUS status = QDF_STATUS_SUCCESS; 4997 struct wma_txrx_node *iface; 4998 int8_t maxTxPower = 0; 4999 int ret = 0; 5000 struct wma_target_req *msg; 5001 bool peer_assoc_cnf = false; 5002 int smps_param; 5003 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 5004 struct dev_set_param setparam[MAX_VDEV_STA_REQ_PARAMS]; 5005 uint8_t index = 0; 5006 5007 #ifdef FEATURE_WLAN_TDLS 5008 if (STA_ENTRY_TDLS_PEER == params->staType) { 5009 wma_add_tdls_sta(wma, params); 5010 return; 5011 } 5012 #endif 5013 5014 iface = &wma->interfaces[params->smesessionId]; 5015 if (params->staType != STA_ENTRY_SELF) { 5016 wma_err("unsupported station type %d", params->staType); 5017 goto out; 5018 } 5019 if (params->nonRoamReassoc) { 5020 cdp_peer_state_update(soc, params->bssId, 5021 OL_TXRX_PEER_STATE_AUTH); 5022 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); 5023 iface->aid = params->assocId; 5024 goto out; 5025 } 5026 5027 if (wma_is_vdev_up(params->smesessionId)) { 5028 wma_debug("vdev id %d is already UP for "QDF_MAC_ADDR_FMT, 5029 params->smesessionId, 5030 QDF_MAC_ADDR_REF(params->bssId)); 5031 status = QDF_STATUS_E_FAILURE; 5032 goto out; 5033 } 5034 5035 if (cdp_peer_state_get(soc, params->smesessionId, 5036 params->bssId) == OL_TXRX_PEER_STATE_DISC) { 5037 /* 5038 * This is the case for reassociation. 5039 * peer state update and peer_assoc is required since it 5040 * was not done by WMA_ADD_BSS_REQ. 5041 */ 5042 5043 /* Update peer state */ 5044 if (params->encryptType == eSIR_ED_NONE) { 5045 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into auth", 5046 QDF_MAC_ADDR_REF(params->bssId)); 5047 cdp_peer_state_update(soc, params->bssId, 5048 OL_TXRX_PEER_STATE_AUTH); 5049 } else { 5050 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into conn", 5051 QDF_MAC_ADDR_REF(params->bssId)); 5052 cdp_peer_state_update(soc, params->bssId, 5053 OL_TXRX_PEER_STATE_CONN); 5054 } 5055 5056 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, 5057 params->smesessionId) || 5058 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, 5059 params->smesessionId)) { 5060 /* iface->nss = params->nss; */ 5061 /*In LFR2.0, the following operations are performed as 5062 * part of wma_send_peer_assoc. As we are 5063 * skipping this operation, we are just executing the 5064 * following which are useful for LFR3.0 5065 */ 5066 cdp_peer_state_update(soc, params->bssId, 5067 OL_TXRX_PEER_STATE_AUTH); 5068 qdf_atomic_set(&iface->bss_status, 5069 WMA_BSS_STATUS_STARTED); 5070 iface->aid = params->assocId; 5071 wma_debug("LFR3:statype %d vdev %d aid %d bssid "QDF_MAC_ADDR_FMT, 5072 params->staType, params->smesessionId, 5073 params->assocId, 5074 QDF_MAC_ADDR_REF(params->bssId)); 5075 return; 5076 } 5077 wmi_unified_send_txbf(wma, params); 5078 5079 if (wmi_service_enabled(wma->wmi_handle, 5080 wmi_service_peer_assoc_conf)) { 5081 peer_assoc_cnf = true; 5082 msg = wma_fill_hold_req(wma, params->smesessionId, 5083 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START, 5084 params, WMA_PEER_ASSOC_TIMEOUT); 5085 if (!msg) { 5086 wma_debug("Failed to alloc request for vdev_id %d", 5087 params->smesessionId); 5088 params->status = QDF_STATUS_E_FAILURE; 5089 wma_remove_req(wma, params->smesessionId, 5090 WMA_PEER_ASSOC_CNF_START); 5091 wma_remove_peer(wma, params->bssId, 5092 params->smesessionId, false); 5093 peer_assoc_cnf = false; 5094 goto out; 5095 } 5096 } else { 5097 wma_debug("WMI_SERVICE_PEER_ASSOC_CONF not enabled"); 5098 } 5099 5100 ((tAddStaParams *)iface->addBssStaContext)->no_ptk_4_way = 5101 params->no_ptk_4_way; 5102 5103 qdf_mem_copy(((tAddStaParams *)iface->addBssStaContext)-> 5104 supportedRates.supportedMCSSet, 5105 params->supportedRates.supportedMCSSet, 5106 SIR_MAC_MAX_SUPPORTED_MCS_SET); 5107 5108 5109 ret = wma_send_peer_assoc(wma, 5110 iface->nwType, 5111 (tAddStaParams *) iface->addBssStaContext); 5112 if (ret) { 5113 status = QDF_STATUS_E_FAILURE; 5114 wma_remove_peer(wma, params->bssId, 5115 params->smesessionId, false); 5116 goto out; 5117 } 5118 5119 if (params->rmfEnabled) { 5120 wma_set_mgmt_frame_protection(wma); 5121 wma_set_peer_pmf_status(wma, params->bssId, true); 5122 } 5123 } 5124 5125 if (!wlan_reg_is_ext_tpc_supported(wma->psoc)) 5126 maxTxPower = params->maxTxPower; 5127 5128 if (wma_vdev_set_bss_params(wma, params->smesessionId, 5129 iface->beaconInterval, iface->dtimPeriod, 5130 iface->shortSlotTimeSupported, 5131 iface->llbCoexist, maxTxPower, 5132 iface->bss_max_idle_period)) { 5133 wma_err("Failed to bss params"); 5134 } 5135 5136 params->csaOffloadEnable = 0; 5137 if (wmi_service_enabled(wma->wmi_handle, 5138 wmi_service_csa_offload)) { 5139 params->csaOffloadEnable = 1; 5140 if (wma_unified_csa_offload_enable(wma, params->smesessionId) < 5141 0) { 5142 wma_err("Unable to enable CSA offload for vdev_id:%d", 5143 params->smesessionId); 5144 } 5145 } 5146 5147 if (wmi_service_enabled(wma->wmi_handle, 5148 wmi_service_filter_ipsec_natkeepalive)) { 5149 if (wmi_unified_nat_keepalive_en_cmd(wma->wmi_handle, 5150 params->smesessionId)) { 5151 wma_err("Unable to enable NAT keepalive for vdev_id:%d", 5152 params->smesessionId); 5153 } 5154 } 5155 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); 5156 /* Sta is now associated, configure various params */ 5157 5158 /* Send SMPS force command to FW to send the required 5159 * action frame only when SM power save is enabled in 5160 * from INI. In case dynamic antenna selection, the 5161 * action frames are sent by the chain mask manager 5162 * In addition to the action frames, The SM power save is 5163 * published in the assoc request HT SMPS IE for both cases. 5164 */ 5165 if ((params->enableHtSmps) && (params->send_smps_action)) { 5166 smps_param = wma_smps_mode_to_force_mode_param( 5167 params->htSmpsconfig); 5168 if (smps_param >= 0) { 5169 wma_debug("Send SMPS force mode: %d", 5170 params->htSmpsconfig); 5171 wma_set_mimops(wma, params->smesessionId, 5172 smps_param); 5173 } 5174 } 5175 5176 wma_send_bss_color_change_enable(wma, params); 5177 5178 /* Partial AID match power save, enable when SU bformee */ 5179 if (params->enableVhtpAid && params->vhtTxBFCapable) 5180 wma_set_ppsconfig(params->smesessionId, 5181 WMA_VHT_PPS_PAID_MATCH, 1); 5182 5183 /* Enable AMPDU power save, if htCapable/vhtCapable */ 5184 if (params->enableAmpduPs && (params->htCapable || params->vhtCapable)) 5185 wma_set_ppsconfig(params->smesessionId, 5186 WMA_VHT_PPS_DELIM_CRC_FAIL, 1); 5187 if (wmi_service_enabled(wma->wmi_handle, 5188 wmi_service_listen_interval_offload_support)) { 5189 struct wlan_objmgr_vdev *vdev; 5190 uint32_t moddtim; 5191 bool is_connection_roaming_cfg_set = 0; 5192 5193 wma_debug("listen interval offload enabled, setting params"); 5194 status = mlme_check_index_setparam( 5195 setparam, 5196 wmi_vdev_param_max_li_of_moddtim, 5197 wma->staMaxLIModDtim, index++, 5198 MAX_VDEV_STA_REQ_PARAMS); 5199 if (QDF_IS_STATUS_ERROR(status)) { 5200 wma_debug("failed to send wmi_vdev_param_max_li_of_moddtim"); 5201 goto out; 5202 } 5203 5204 ucfg_mlme_get_connection_roaming_ini_present( 5205 wma->psoc, 5206 &is_connection_roaming_cfg_set); 5207 if (is_connection_roaming_cfg_set) { 5208 status = mlme_check_index_setparam( 5209 setparam, 5210 wmi_vdev_param_max_li_of_moddtim_ms, 5211 wma->sta_max_li_mod_dtim_ms, index++, 5212 MAX_VDEV_STA_REQ_PARAMS); 5213 if (QDF_IS_STATUS_ERROR(status)) { 5214 wma_debug("failed to send wmi_vdev_param_max_li_of_moddtim_ms"); 5215 goto out; 5216 } 5217 } 5218 status = mlme_check_index_setparam( 5219 setparam, 5220 wmi_vdev_param_dyndtim_cnt, 5221 wma->staDynamicDtim, index++, 5222 MAX_VDEV_STA_REQ_PARAMS); 5223 if (QDF_IS_STATUS_ERROR(status)) { 5224 wma_debug("failed to send wmi_vdev_param_dyndtim_cnt"); 5225 goto out; 5226 } 5227 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, 5228 params->smesessionId, 5229 WLAN_LEGACY_WMA_ID); 5230 if (!vdev || !ucfg_pmo_get_moddtim_user_enable(vdev)) { 5231 moddtim = wma->staModDtim; 5232 status = mlme_check_index_setparam( 5233 setparam, 5234 wmi_vdev_param_moddtim_cnt, 5235 moddtim, index++, 5236 MAX_VDEV_STA_REQ_PARAMS); 5237 if (QDF_IS_STATUS_ERROR(status)) { 5238 wma_debug("failed to send wmi_vdev_param_moddtim_cnt"); 5239 if (vdev) 5240 wlan_objmgr_vdev_release_ref(vdev, 5241 WLAN_LEGACY_WMA_ID); 5242 goto out; 5243 } 5244 if (vdev) 5245 wlan_objmgr_vdev_release_ref(vdev, 5246 WLAN_LEGACY_WMA_ID); 5247 } else if (vdev && ucfg_pmo_get_moddtim_user_enable(vdev) && 5248 !ucfg_pmo_get_moddtim_user_active(vdev)) { 5249 moddtim = ucfg_pmo_get_moddtim_user(vdev); 5250 status = mlme_check_index_setparam( 5251 setparam, 5252 wmi_vdev_param_moddtim_cnt, 5253 moddtim, index++, 5254 MAX_VDEV_STA_REQ_PARAMS); 5255 if (QDF_IS_STATUS_ERROR(status)) { 5256 wma_debug("failed to send wmi_vdev_param_moddtim_cnt"); 5257 wlan_objmgr_vdev_release_ref(vdev, 5258 WLAN_LEGACY_WMA_ID); 5259 goto out; 5260 } 5261 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); 5262 } 5263 status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 5264 params->smesessionId, 5265 setparam, index); 5266 if (QDF_IS_STATUS_ERROR(status)) { 5267 wma_err("failed to send DTIM vdev setparams"); 5268 goto out; 5269 } 5270 5271 } else { 5272 wma_debug("listen interval offload is not set"); 5273 } 5274 params->nss = iface->nss; 5275 out: 5276 iface->aid = params->assocId; 5277 5278 /* Do not send add stat resp when peer assoc cnf is enabled */ 5279 if (peer_assoc_cnf) 5280 return; 5281 5282 params->status = status; 5283 wma_debug("vdev_id %d aid %d sta mac " QDF_MAC_ADDR_FMT " status %d", 5284 params->smesessionId, iface->aid, 5285 QDF_MAC_ADDR_REF(params->bssId), params->status); 5286 5287 /* Don't send a response during roam sync operation */ 5288 if (!wlan_cm_is_roam_sync_in_progress(wma->psoc, 5289 params->smesessionId) && 5290 !MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, 5291 params->smesessionId)) 5292 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, 5293 (void *)params, 0); 5294 } 5295 5296 /** 5297 * wma_delete_sta_req_ap_mode() - process delete sta request from UMAC in AP mode 5298 * @wma: wma handle 5299 * @del_sta: delete sta params 5300 * 5301 * Return: none 5302 */ 5303 static void wma_delete_sta_req_ap_mode(tp_wma_handle wma, 5304 tpDeleteStaParams del_sta) 5305 { 5306 struct wma_target_req *msg; 5307 QDF_STATUS qdf_status; 5308 5309 qdf_status = wma_remove_peer(wma, del_sta->staMac, 5310 del_sta->smesessionId, false); 5311 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5312 wma_err("wma_remove_peer failed"); 5313 del_sta->status = QDF_STATUS_E_FAILURE; 5314 goto send_del_rsp; 5315 } 5316 del_sta->status = QDF_STATUS_SUCCESS; 5317 5318 if (wmi_service_enabled(wma->wmi_handle, 5319 wmi_service_sync_delete_cmds)) { 5320 msg = wma_fill_hold_req(wma, del_sta->smesessionId, 5321 WMA_DELETE_STA_REQ, 5322 WMA_DELETE_STA_RSP_START, del_sta, 5323 WMA_DELETE_STA_TIMEOUT); 5324 if (!msg) { 5325 wma_err("Failed to allocate request. vdev_id %d", 5326 del_sta->smesessionId); 5327 wma_remove_req(wma, del_sta->smesessionId, 5328 WMA_DELETE_STA_RSP_START); 5329 del_sta->status = QDF_STATUS_E_NOMEM; 5330 goto send_del_rsp; 5331 } 5332 5333 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock, 5334 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION); 5335 5336 return; 5337 } 5338 5339 send_del_rsp: 5340 if (del_sta->respReqd) { 5341 wma_debug("Sending del rsp to umac (status: %d)", 5342 del_sta->status); 5343 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, 5344 (void *)del_sta, 0); 5345 } 5346 } 5347 5348 #ifdef FEATURE_WLAN_TDLS 5349 /** 5350 * wma_del_tdls_sta() - process delete sta request from UMAC in TDLS 5351 * @wma: wma handle 5352 * @del_sta: delete sta params 5353 * 5354 * Return: none 5355 */ 5356 static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) 5357 { 5358 struct tdls_peer_update_state *peer_state; 5359 struct wma_target_req *msg; 5360 int status; 5361 5362 peer_state = qdf_mem_malloc(sizeof(*peer_state)); 5363 if (!peer_state) { 5364 del_sta->status = QDF_STATUS_E_NOMEM; 5365 goto send_del_rsp; 5366 } 5367 5368 peer_state->peer_state = TDLS_PEER_STATE_TEARDOWN; 5369 peer_state->vdev_id = del_sta->smesessionId; 5370 peer_state->resp_reqd = del_sta->respReqd; 5371 qdf_mem_copy(&peer_state->peer_macaddr, 5372 &del_sta->staMac, sizeof(tSirMacAddr)); 5373 5374 wma_debug("sending tdls_peer_state for peer mac: "QDF_MAC_ADDR_FMT", peerState: %d", 5375 QDF_MAC_ADDR_REF(peer_state->peer_macaddr), 5376 peer_state->peer_state); 5377 5378 status = wma_update_tdls_peer_state(wma, peer_state); 5379 5380 if (status < 0) { 5381 wma_err("wma_update_tdls_peer_state returned failure"); 5382 del_sta->status = QDF_STATUS_E_FAILURE; 5383 goto send_del_rsp; 5384 } 5385 5386 if (del_sta->respReqd && 5387 wmi_service_enabled(wma->wmi_handle, 5388 wmi_service_sync_delete_cmds)) { 5389 del_sta->status = QDF_STATUS_SUCCESS; 5390 msg = wma_fill_hold_req(wma, 5391 del_sta->smesessionId, 5392 WMA_DELETE_STA_REQ, 5393 WMA_DELETE_STA_RSP_START, del_sta, 5394 WMA_DELETE_STA_TIMEOUT); 5395 if (!msg) { 5396 wma_err("Failed to allocate vdev_id %d", 5397 del_sta->smesessionId); 5398 wma_remove_req(wma, 5399 del_sta->smesessionId, 5400 WMA_DELETE_STA_RSP_START); 5401 del_sta->status = QDF_STATUS_E_NOMEM; 5402 goto send_del_rsp; 5403 } 5404 5405 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock, 5406 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION); 5407 } 5408 5409 return; 5410 5411 send_del_rsp: 5412 if (del_sta->respReqd) { 5413 wma_debug("Sending del rsp to umac (status: %d)", 5414 del_sta->status); 5415 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, 5416 (void *)del_sta, 0); 5417 } 5418 } 5419 #endif 5420 5421 /** 5422 * wma_delete_sta_req_sta_mode() - process delete sta request from UMAC 5423 * @wma: wma handle 5424 * @params: delete sta params 5425 * 5426 * Return: none 5427 */ 5428 static void wma_delete_sta_req_sta_mode(tp_wma_handle wma, 5429 tpDeleteStaParams params) 5430 { 5431 QDF_STATUS status = QDF_STATUS_SUCCESS; 5432 struct wma_txrx_node *iface; 5433 5434 if (wmi_service_enabled(wma->wmi_handle, 5435 wmi_service_listen_interval_offload_support)) { 5436 struct wlan_objmgr_vdev *vdev; 5437 5438 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, 5439 params->smesessionId, 5440 WLAN_LEGACY_WMA_ID); 5441 if (vdev) { 5442 if (ucfg_pmo_get_moddtim_user_enable(vdev)) 5443 ucfg_pmo_set_moddtim_user_enable(vdev, false); 5444 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); 5445 } 5446 } 5447 5448 iface = &wma->interfaces[params->smesessionId]; 5449 iface->uapsd_cached_val = 0; 5450 #ifdef FEATURE_WLAN_TDLS 5451 if (STA_ENTRY_TDLS_PEER == params->staType) { 5452 wma_del_tdls_sta(wma, params); 5453 return; 5454 } 5455 #endif 5456 params->status = status; 5457 if (params->respReqd) { 5458 wma_debug("vdev_id %d status %d", 5459 params->smesessionId, status); 5460 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, 5461 (void *)params, 0); 5462 } 5463 } 5464 5465 static void wma_sap_prevent_runtime_pm(tp_wma_handle wma) 5466 { 5467 qdf_runtime_pm_prevent_suspend(&wma->sap_prevent_runtime_pm_lock); 5468 } 5469 5470 static void wma_sap_allow_runtime_pm(tp_wma_handle wma) 5471 { 5472 qdf_runtime_pm_allow_suspend(&wma->sap_prevent_runtime_pm_lock); 5473 } 5474 5475 static void wma_ndp_prevent_runtime_pm(tp_wma_handle wma) 5476 { 5477 qdf_runtime_pm_prevent_suspend(&wma->ndp_prevent_runtime_pm_lock); 5478 } 5479 5480 static void wma_ndp_allow_runtime_pm(tp_wma_handle wma) 5481 { 5482 qdf_runtime_pm_allow_suspend(&wma->ndp_prevent_runtime_pm_lock); 5483 } 5484 #ifdef FEATURE_STA_MODE_VOTE_LINK 5485 static bool wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode) 5486 { 5487 if (oper_mode == BSS_OPERATIONAL_MODE_STA && ucfg_ipa_is_enabled()) 5488 return true; 5489 5490 return false; 5491 } 5492 #else /* !FEATURE_STA_MODE_VOTE_LINK */ 5493 static bool wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode) 5494 { 5495 return false; 5496 } 5497 #endif /* FEATURE_STA_MODE_VOTE_LINK */ 5498 5499 static bool wma_is_vdev_in_sap_mode(tp_wma_handle wma, uint8_t vdev_id) 5500 { 5501 struct wma_txrx_node *intf = wma->interfaces; 5502 5503 if (vdev_id >= wma->max_bssid) { 5504 wma_err("Invalid vdev_id %hu", vdev_id); 5505 QDF_ASSERT(0); 5506 return false; 5507 } 5508 5509 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) && 5510 (intf[vdev_id].sub_type == 0)) 5511 return true; 5512 5513 return false; 5514 } 5515 5516 static bool wma_is_vdev_in_go_mode(tp_wma_handle wma, uint8_t vdev_id) 5517 { 5518 struct wma_txrx_node *intf = wma->interfaces; 5519 5520 if (vdev_id >= wma->max_bssid) { 5521 wma_err("Invalid vdev_id %hu", vdev_id); 5522 QDF_ASSERT(0); 5523 return false; 5524 } 5525 5526 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) && 5527 (intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO)) 5528 return true; 5529 5530 return false; 5531 } 5532 5533 static void wma_sap_d3_wow_client_connect(tp_wma_handle wma) 5534 { 5535 uint32_t num_clients; 5536 5537 num_clients = qdf_atomic_inc_return(&wma->sap_num_clients_connected); 5538 wmi_debug("sap d3 wow %d client connected", num_clients); 5539 if (num_clients == SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK) { 5540 wmi_info("max clients connected acquire sap d3 wow wake lock"); 5541 qdf_wake_lock_acquire(&wma->sap_d3_wow_wake_lock, 5542 WIFI_POWER_EVENT_WAKELOCK_SAP_D3_WOW); 5543 } 5544 } 5545 5546 static void wma_sap_d3_wow_client_disconnect(tp_wma_handle wma) 5547 { 5548 uint32_t num_clients; 5549 5550 num_clients = qdf_atomic_dec_return(&wma->sap_num_clients_connected); 5551 wmi_debug("sap d3 wow %d client connected", num_clients); 5552 if (num_clients == SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK) { 5553 wmi_info("max clients disconnected release sap d3 wow wake lock"); 5554 qdf_wake_lock_release(&wma->sap_d3_wow_wake_lock, 5555 WIFI_POWER_EVENT_WAKELOCK_SAP_D3_WOW); 5556 } 5557 } 5558 5559 static void wma_go_d3_wow_client_connect(tp_wma_handle wma) 5560 { 5561 uint32_t num_clients; 5562 5563 num_clients = qdf_atomic_inc_return(&wma->go_num_clients_connected); 5564 wmi_debug("go d3 wow %d client connected", num_clients); 5565 if (num_clients == SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK) { 5566 wmi_info("max clients connected acquire go d3 wow wake lock"); 5567 qdf_wake_lock_acquire(&wma->go_d3_wow_wake_lock, 5568 WIFI_POWER_EVENT_WAKELOCK_GO_D3_WOW); 5569 } 5570 } 5571 5572 static void wma_go_d3_wow_client_disconnect(tp_wma_handle wma) 5573 { 5574 uint32_t num_clients; 5575 5576 num_clients = qdf_atomic_dec_return(&wma->go_num_clients_connected); 5577 wmi_debug("go d3 wow %d client connected", num_clients); 5578 if (num_clients == SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK) { 5579 wmi_info("max clients disconnected release go d3 wow wake lock"); 5580 qdf_wake_lock_release(&wma->go_d3_wow_wake_lock, 5581 WIFI_POWER_EVENT_WAKELOCK_GO_D3_WOW); 5582 } 5583 } 5584 5585 void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) 5586 { 5587 uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA; 5588 void *htc_handle; 5589 QDF_STATUS status = QDF_STATUS_SUCCESS; 5590 uint8_t vdev_id = add_sta->smesessionId; 5591 5592 htc_handle = lmac_get_htc_hdl(wma->psoc); 5593 if (!htc_handle) { 5594 wma_err("HTC handle is NULL"); 5595 return; 5596 } 5597 5598 wma_debug("Vdev %d BSSID "QDF_MAC_ADDR_FMT, vdev_id, 5599 QDF_MAC_ADDR_REF(add_sta->bssId)); 5600 5601 if (wma_is_vdev_in_ap_mode(wma, vdev_id)) 5602 oper_mode = BSS_OPERATIONAL_MODE_AP; 5603 5604 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) 5605 oper_mode = BSS_OPERATIONAL_MODE_NDI; 5606 switch (oper_mode) { 5607 case BSS_OPERATIONAL_MODE_STA: 5608 wma_add_sta_req_sta_mode(wma, add_sta); 5609 break; 5610 5611 case BSS_OPERATIONAL_MODE_AP: 5612 wma_add_sta_req_ap_mode(wma, add_sta); 5613 break; 5614 case BSS_OPERATIONAL_MODE_NDI: 5615 wma_add_sta_ndi_mode(wma, add_sta); 5616 break; 5617 } 5618 5619 /* 5620 * not use add_sta after this to avoid use after free 5621 * as it maybe freed. 5622 */ 5623 5624 /* handle wow for sap with 1 or more peer in same way */ 5625 if (wma_is_vdev_in_sap_mode(wma, vdev_id)) { 5626 bool is_bus_suspend_allowed_in_sap_mode = 5627 (wlan_pmo_get_sap_mode_bus_suspend(wma->psoc) && 5628 wmi_service_enabled(wma->wmi_handle, 5629 wmi_service_sap_connected_d3_wow)); 5630 if (!is_bus_suspend_allowed_in_sap_mode) { 5631 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_SAP_USER_ID); 5632 wmi_info("sap d0 wow"); 5633 } else { 5634 wmi_debug("sap d3 wow"); 5635 wma_sap_d3_wow_client_connect(wma); 5636 } 5637 wma_sap_prevent_runtime_pm(wma); 5638 5639 return; 5640 } 5641 5642 /* handle wow for p2pgo with 1 or more peer in same way */ 5643 if (wma_is_vdev_in_go_mode(wma, vdev_id)) { 5644 bool is_bus_suspend_allowed_in_go_mode = 5645 (wlan_pmo_get_go_mode_bus_suspend(wma->psoc) && 5646 wmi_service_enabled(wma->wmi_handle, 5647 wmi_service_go_connected_d3_wow)); 5648 if (!is_bus_suspend_allowed_in_go_mode) { 5649 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_GO_USER_ID); 5650 wmi_info("p2p go d0 wow"); 5651 } else { 5652 wmi_info("p2p go d3 wow"); 5653 wma_go_d3_wow_client_connect(wma); 5654 } 5655 wma_sap_prevent_runtime_pm(wma); 5656 5657 return; 5658 } 5659 5660 /* handle wow for nan with 1 or more peer in same way */ 5661 if (BSS_OPERATIONAL_MODE_NDI == oper_mode && 5662 QDF_IS_STATUS_SUCCESS(status)) { 5663 wma_debug("disable runtime pm and vote for link up"); 5664 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_NDP_USER_ID); 5665 wma_ndp_prevent_runtime_pm(wma); 5666 } else if (wma_add_sta_allow_sta_mode_vote_link(oper_mode)) { 5667 wma_debug("vote for link up"); 5668 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_STA_USER_ID); 5669 } 5670 } 5671 5672 void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) 5673 { 5674 uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA; 5675 uint8_t vdev_id = del_sta->smesessionId; 5676 bool rsp_requested = del_sta->respReqd; 5677 void *htc_handle; 5678 QDF_STATUS status = QDF_STATUS_SUCCESS; 5679 5680 htc_handle = lmac_get_htc_hdl(wma->psoc); 5681 if (!htc_handle) { 5682 wma_err("HTC handle is NULL"); 5683 return; 5684 } 5685 5686 if (wma_is_vdev_in_ap_mode(wma, vdev_id)) 5687 oper_mode = BSS_OPERATIONAL_MODE_AP; 5688 if (del_sta->staType == STA_ENTRY_NDI_PEER) 5689 oper_mode = BSS_OPERATIONAL_MODE_NDI; 5690 5691 wma_debug("vdev %d oper_mode %d", vdev_id, oper_mode); 5692 5693 switch (oper_mode) { 5694 case BSS_OPERATIONAL_MODE_STA: 5695 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) || 5696 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) || 5697 mlo_is_roaming_in_progress(wma->psoc, vdev_id)) { 5698 wma_debug("LFR3: Del STA on vdev_id %d", vdev_id); 5699 qdf_mem_free(del_sta); 5700 return; 5701 } 5702 wma_delete_sta_req_sta_mode(wma, del_sta); 5703 if (!rsp_requested) 5704 qdf_mem_free(del_sta); 5705 5706 break; 5707 5708 case BSS_OPERATIONAL_MODE_AP: 5709 wma_delete_sta_req_ap_mode(wma, del_sta); 5710 /* free the memory here only if sync feature is not enabled */ 5711 if (!rsp_requested && 5712 !wmi_service_enabled(wma->wmi_handle, 5713 wmi_service_sync_delete_cmds)) 5714 qdf_mem_free(del_sta); 5715 else if (!rsp_requested && 5716 (del_sta->status != QDF_STATUS_SUCCESS)) 5717 qdf_mem_free(del_sta); 5718 break; 5719 case BSS_OPERATIONAL_MODE_NDI: 5720 status = wma_delete_sta_req_ndi_mode(wma, del_sta); 5721 break; 5722 default: 5723 wma_err("Incorrect oper mode %d", oper_mode); 5724 qdf_mem_free(del_sta); 5725 } 5726 5727 if (wma_is_vdev_in_sap_mode(wma, vdev_id)) { 5728 bool is_bus_suspend_allowed_in_sap_mode = 5729 (wlan_pmo_get_sap_mode_bus_suspend(wma->psoc) && 5730 wmi_service_enabled(wma->wmi_handle, 5731 wmi_service_sap_connected_d3_wow)); 5732 if (!is_bus_suspend_allowed_in_sap_mode) { 5733 htc_vote_link_down(htc_handle, 5734 HTC_LINK_VOTE_SAP_USER_ID); 5735 wmi_info("sap d0 wow"); 5736 } else { 5737 wmi_debug("sap d3 wow"); 5738 wma_sap_d3_wow_client_disconnect(wma); 5739 } 5740 wma_sap_allow_runtime_pm(wma); 5741 5742 return; 5743 } 5744 5745 if (wma_is_vdev_in_go_mode(wma, vdev_id)) { 5746 bool is_bus_suspend_allowed_in_go_mode = 5747 (wlan_pmo_get_go_mode_bus_suspend(wma->psoc) && 5748 wmi_service_enabled(wma->wmi_handle, 5749 wmi_service_go_connected_d3_wow)); 5750 if (!is_bus_suspend_allowed_in_go_mode) { 5751 htc_vote_link_down(htc_handle, 5752 HTC_LINK_VOTE_GO_USER_ID); 5753 wmi_info("p2p go d0 wow"); 5754 } else { 5755 wmi_info("p2p go d3 wow"); 5756 wma_go_d3_wow_client_disconnect(wma); 5757 } 5758 wma_sap_allow_runtime_pm(wma); 5759 5760 return; 5761 } 5762 5763 if (BSS_OPERATIONAL_MODE_NDI == oper_mode && 5764 QDF_IS_STATUS_SUCCESS(status)) { 5765 wma_debug("allow runtime pm and vote for link down"); 5766 htc_vote_link_down(htc_handle, HTC_LINK_VOTE_NDP_USER_ID); 5767 wma_ndp_allow_runtime_pm(wma); 5768 } else if (wma_add_sta_allow_sta_mode_vote_link(oper_mode)) { 5769 wma_debug("vote for link down"); 5770 htc_vote_link_down(htc_handle, HTC_LINK_VOTE_STA_USER_ID); 5771 } 5772 } 5773 5774 void wma_delete_bss_ho_fail(tp_wma_handle wma, uint8_t vdev_id) 5775 { 5776 QDF_STATUS status = QDF_STATUS_SUCCESS; 5777 struct wma_txrx_node *iface; 5778 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 5779 struct vdev_stop_response resp_event; 5780 struct del_bss_resp *vdev_stop_resp; 5781 uint8_t *bssid; 5782 5783 iface = &wma->interfaces[vdev_id]; 5784 if (!iface) { 5785 wma_err("iface for vdev_id %d is already deleted", vdev_id); 5786 goto fail_del_bss_ho_fail; 5787 } 5788 bssid = wma_get_vdev_bssid(iface->vdev); 5789 if (!bssid) { 5790 wma_err("Invalid bssid"); 5791 status = QDF_STATUS_E_FAILURE; 5792 goto fail_del_bss_ho_fail; 5793 } 5794 qdf_mem_zero(bssid, QDF_MAC_ADDR_SIZE); 5795 5796 if (iface->psnr_req) { 5797 qdf_mem_free(iface->psnr_req); 5798 iface->psnr_req = NULL; 5799 } 5800 5801 if (iface->rcpi_req) { 5802 struct sme_rcpi_req *rcpi_req = iface->rcpi_req; 5803 5804 iface->rcpi_req = NULL; 5805 qdf_mem_free(rcpi_req); 5806 } 5807 5808 if (iface->roam_scan_stats_req) { 5809 struct sir_roam_scan_stats *roam_scan_stats_req = 5810 iface->roam_scan_stats_req; 5811 5812 iface->roam_scan_stats_req = NULL; 5813 qdf_mem_free(roam_scan_stats_req); 5814 } 5815 5816 wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)", 5817 vdev_id); 5818 cdp_fc_vdev_pause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); 5819 wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); 5820 cdp_fc_vdev_flush(soc, vdev_id); 5821 wma_debug("vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", 5822 vdev_id); 5823 cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); 5824 wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST); 5825 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); 5826 wma_debug("(type %d subtype %d) BSS is stopped", 5827 iface->type, iface->sub_type); 5828 5829 status = mlme_set_vdev_stop_type(iface->vdev, 5830 WMA_DELETE_BSS_HO_FAIL_REQ); 5831 if (QDF_IS_STATUS_ERROR(status)) { 5832 wma_err("Failed to set wma req msg_type for vdev_id: %d", 5833 vdev_id); 5834 goto fail_del_bss_ho_fail; 5835 } 5836 5837 /* Try to use the vdev stop response path */ 5838 resp_event.vdev_id = vdev_id; 5839 status = wma_handle_vdev_stop_rsp(wma, &resp_event); 5840 if (QDF_IS_STATUS_ERROR(status)) { 5841 wma_err("Failed to handle vdev stop rsp for vdev_id %d", 5842 vdev_id); 5843 goto fail_del_bss_ho_fail; 5844 } 5845 5846 return; 5847 5848 fail_del_bss_ho_fail: 5849 vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp)); 5850 if (!vdev_stop_resp) 5851 return; 5852 5853 vdev_stop_resp->vdev_id = vdev_id; 5854 vdev_stop_resp->status = status; 5855 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP, 5856 (void *)vdev_stop_resp, 0); 5857 } 5858 5859 /** 5860 * wma_wait_tx_complete() - Wait till tx packets are drained 5861 * @wma: wma handle 5862 * @session_id: vdev id 5863 * 5864 * Return: none 5865 */ 5866 static void wma_wait_tx_complete(tp_wma_handle wma, 5867 uint32_t session_id) 5868 { 5869 uint8_t max_wait_iterations = 0, delay = 0; 5870 cdp_config_param_type val; 5871 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 5872 QDF_STATUS status; 5873 5874 if (!wma_is_vdev_valid(session_id)) { 5875 wma_err("Vdev is not valid: %d", session_id); 5876 return; 5877 } 5878 5879 status = ucfg_mlme_get_delay_before_vdev_stop(wma->psoc, &delay); 5880 if (QDF_IS_STATUS_ERROR(status)) 5881 wma_err("Failed to get delay before vdev stop"); 5882 5883 max_wait_iterations = delay / WMA_TX_Q_RECHECK_TIMER_WAIT; 5884 if (cdp_txrx_get_pdev_param(soc, 5885 wlan_objmgr_pdev_get_pdev_id(wma->pdev), 5886 CDP_TX_PENDING, &val)) 5887 return; 5888 while (val.cdp_pdev_param_tx_pending && max_wait_iterations) { 5889 wma_warn("Waiting for outstanding packet to drain"); 5890 qdf_wait_for_event_completion(&wma->tx_queue_empty_event, 5891 WMA_TX_Q_RECHECK_TIMER_WAIT); 5892 if (cdp_txrx_get_pdev_param( 5893 soc, 5894 wlan_objmgr_pdev_get_pdev_id(wma->pdev), 5895 CDP_TX_PENDING, &val)) 5896 return; 5897 max_wait_iterations--; 5898 } 5899 } 5900 5901 void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id) 5902 { 5903 bool peer_exist = false; 5904 QDF_STATUS status = QDF_STATUS_SUCCESS; 5905 uint32_t tx_pending = 0; 5906 cdp_config_param_type val; 5907 bool roam_synch_in_progress = false; 5908 struct wma_txrx_node *iface; 5909 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 5910 struct qdf_mac_addr bssid; 5911 struct del_bss_resp *params; 5912 uint8_t *addr, *bssid_addr; 5913 5914 iface = &wma->interfaces[vdev_id]; 5915 if (!iface || !iface->vdev) { 5916 wma_err("vdev id %d is already deleted", vdev_id); 5917 goto out; 5918 } 5919 5920 status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid); 5921 if (QDF_IS_STATUS_ERROR(status)) { 5922 wma_err("vdev id %d : failed to get bssid", vdev_id); 5923 goto out; 5924 } 5925 5926 addr = wlan_vdev_mlme_get_macaddr(iface->vdev); 5927 if (!addr) { 5928 wma_err("vdev id %d : failed to get macaddr", vdev_id); 5929 goto out; 5930 } 5931 5932 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, 5933 vdev_id)) 5934 /* In ndi case, self mac is used to create the self peer */ 5935 peer_exist = wma_cdp_find_peer_by_addr(addr); 5936 else 5937 peer_exist = wma_cdp_find_peer_by_addr(bssid.bytes); 5938 if (!peer_exist) { 5939 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, 5940 QDF_MAC_ADDR_REF(bssid.bytes)); 5941 status = QDF_STATUS_E_FAILURE; 5942 goto out; 5943 } 5944 bssid_addr = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev); 5945 if (!bssid_addr) { 5946 wma_err("Failed to bssid for vdev_%d", vdev_id); 5947 status = QDF_STATUS_E_FAILURE; 5948 goto out; 5949 } 5950 qdf_mem_zero(bssid_addr, 5951 QDF_MAC_ADDR_SIZE); 5952 5953 wma_delete_invalid_peer_entries(vdev_id, NULL); 5954 5955 if (iface->psnr_req) { 5956 qdf_mem_free(iface->psnr_req); 5957 iface->psnr_req = NULL; 5958 } 5959 5960 if (iface->rcpi_req) { 5961 struct sme_rcpi_req *rcpi_req = iface->rcpi_req; 5962 5963 iface->rcpi_req = NULL; 5964 qdf_mem_free(rcpi_req); 5965 } 5966 5967 if (iface->roam_scan_stats_req) { 5968 struct sir_roam_scan_stats *roam_scan_stats_req = 5969 iface->roam_scan_stats_req; 5970 5971 iface->roam_scan_stats_req = NULL; 5972 qdf_mem_free(roam_scan_stats_req); 5973 } 5974 5975 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) || 5976 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) || 5977 mlo_is_roaming_in_progress(wma->psoc, vdev_id)) { 5978 roam_synch_in_progress = true; 5979 wma_debug("LFR3: Setting vdev_up to FALSE for vdev:%d", 5980 vdev_id); 5981 5982 goto detach_peer; 5983 } 5984 5985 status = mlme_set_vdev_stop_type(iface->vdev, 5986 WMA_DELETE_BSS_REQ); 5987 if (QDF_IS_STATUS_ERROR(status)) { 5988 wma_err("Failed to set wma req msg_type for vdev_id: %d", 5989 vdev_id); 5990 goto out; 5991 } 5992 5993 cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev), 5994 CDP_TX_PENDING, &val); 5995 tx_pending = val.cdp_pdev_param_tx_pending; 5996 wma_debug("Outstanding msdu packets: %u", tx_pending); 5997 wma_wait_tx_complete(wma, vdev_id); 5998 5999 cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev), 6000 CDP_TX_PENDING, &val); 6001 if (tx_pending) { 6002 wma_debug("Outstanding msdu packets before VDEV_STOP : %u", 6003 tx_pending); 6004 } 6005 6006 wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)", 6007 vdev_id); 6008 wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); 6009 cdp_fc_vdev_pause(soc, vdev_id, 6010 OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); 6011 6012 if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { 6013 struct vdev_stop_response vdev_stop_rsp = {0}; 6014 6015 wma_err("Failed to send vdev stop to FW, explicitly invoke vdev stop rsp"); 6016 vdev_stop_rsp.vdev_id = vdev_id; 6017 wma_handle_vdev_stop_rsp(wma, &vdev_stop_rsp); 6018 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); 6019 } 6020 wma_debug("bssid "QDF_MAC_ADDR_FMT" vdev_id %d", 6021 QDF_MAC_ADDR_REF(bssid.bytes), vdev_id); 6022 6023 return; 6024 6025 detach_peer: 6026 wma_remove_peer(wma, bssid.bytes, vdev_id, roam_synch_in_progress); 6027 if (roam_synch_in_progress) 6028 return; 6029 6030 out: 6031 /* skip when legacy to mlo roam sync ongoing */ 6032 if (MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id)) 6033 return; 6034 6035 params = qdf_mem_malloc(sizeof(*params)); 6036 if (!params) 6037 return; 6038 6039 params->vdev_id = vdev_id; 6040 params->status = status; 6041 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, params, 0); 6042 } 6043 6044 /** 6045 * wma_find_ibss_vdev() - This function finds vdev_id based on input type 6046 * @wma: wma handle 6047 * @type: vdev type 6048 * 6049 * Return: vdev id 6050 */ 6051 int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type) 6052 { 6053 int32_t vdev_id = 0; 6054 struct wma_txrx_node *intf = wma->interfaces; 6055 6056 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { 6057 if (intf) { 6058 if (intf[vdev_id].type == type) 6059 return vdev_id; 6060 } 6061 } 6062 6063 return -EFAULT; 6064 } 6065 6066 void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle, 6067 tpDisableIntraBssFwd pdis_intra_fwd) 6068 { 6069 struct wlan_objmgr_vdev *vdev; 6070 6071 wma_debug("intra_fwd:vdev(%d) intrabss_dis=%s", 6072 pdis_intra_fwd->sessionId, 6073 (pdis_intra_fwd->disableintrabssfwd ? "true" : "false")); 6074 6075 vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].vdev; 6076 cdp_cfg_vdev_rx_set_intrabss_fwd(cds_get_context(QDF_MODULE_ID_SOC), 6077 pdis_intra_fwd->sessionId, 6078 pdis_intra_fwd->disableintrabssfwd); 6079 } 6080 6081 /** 6082 * wma_get_pdev_from_scn_handle() - API to get pdev from scn handle 6083 * @scn_handle: opaque wma handle 6084 * 6085 * API to get pdev from scn handle 6086 * 6087 * Return: None 6088 */ 6089 static struct wlan_objmgr_pdev *wma_get_pdev_from_scn_handle(void *scn_handle) 6090 { 6091 tp_wma_handle wma_handle; 6092 6093 if (!scn_handle) { 6094 wma_err("invalid scn handle"); 6095 return NULL; 6096 } 6097 wma_handle = (tp_wma_handle)scn_handle; 6098 6099 return wma_handle->pdev; 6100 } 6101 6102 void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev) 6103 { 6104 tp_wma_handle wma = (tp_wma_handle)wma_ctx; 6105 QDF_STATUS status; 6106 6107 status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_WMA_ID); 6108 if (QDF_STATUS_SUCCESS != status) { 6109 wma->pdev = NULL; 6110 return; 6111 } 6112 6113 wma->pdev = pdev; 6114 6115 target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle); 6116 target_pdev_set_wmi_handle(wma->pdev->tgt_if_handle, 6117 wma->wmi_handle); 6118 } 6119 6120 /** 6121 * wma_vdev_reset_beacon_interval_timer() - reset beacon interval back 6122 * to its original value after the channel switch. 6123 * 6124 * @data: data 6125 * 6126 * Return: void 6127 */ 6128 static void wma_vdev_reset_beacon_interval_timer(void *data) 6129 { 6130 tp_wma_handle wma; 6131 struct wma_beacon_interval_reset_req *req = 6132 (struct wma_beacon_interval_reset_req *)data; 6133 uint16_t beacon_interval = req->interval; 6134 uint8_t vdev_id = req->vdev_id; 6135 6136 wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA); 6137 if (!wma) 6138 goto end; 6139 6140 /* Change the beacon interval back to its original value */ 6141 wma_debug("Change beacon interval back to %d", beacon_interval); 6142 wma_update_beacon_interval(wma, vdev_id, beacon_interval); 6143 6144 end: 6145 qdf_timer_stop(&req->event_timeout); 6146 qdf_timer_free(&req->event_timeout); 6147 qdf_mem_free(req); 6148 } 6149 6150 int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id, 6151 uint16_t beacon_interval, uint32_t timeout) 6152 { 6153 struct wma_beacon_interval_reset_req *req; 6154 6155 req = qdf_mem_malloc(sizeof(*req)); 6156 if (!req) 6157 return -ENOMEM; 6158 6159 wma_debug("vdev_id %d ", vdev_id); 6160 req->vdev_id = vdev_id; 6161 req->interval = beacon_interval; 6162 qdf_timer_init(NULL, &req->event_timeout, 6163 wma_vdev_reset_beacon_interval_timer, req, QDF_TIMER_TYPE_SW); 6164 qdf_timer_start(&req->event_timeout, timeout); 6165 6166 return 0; 6167 } 6168 6169 QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr, 6170 struct wlm_latency_level_param *latency_params) 6171 { 6172 QDF_STATUS ret; 6173 tp_wma_handle wma = (tp_wma_handle)wma_ptr; 6174 6175 wma_debug("set latency level %d, fw wlm_latency_flags 0x%x", 6176 latency_params->wlm_latency_level, 6177 latency_params->wlm_latency_flags); 6178 6179 ret = wmi_unified_wlm_latency_level_cmd(wma->wmi_handle, 6180 latency_params); 6181 if (QDF_IS_STATUS_ERROR(ret)) 6182 wma_warn("Failed to set latency level"); 6183 6184 return ret; 6185 } 6186 6187 QDF_STATUS wma_add_bss_peer_sta(uint8_t vdev_id, uint8_t *bssid, 6188 bool is_resp_required, 6189 uint8_t *mld_mac, bool is_assoc_peer) 6190 { 6191 tp_wma_handle wma; 6192 QDF_STATUS status = QDF_STATUS_E_FAILURE; 6193 6194 wma = cds_get_context(QDF_MODULE_ID_WMA); 6195 if (!wma) 6196 goto err; 6197 6198 if (is_resp_required) 6199 status = wma_create_sta_mode_bss_peer(wma, bssid, 6200 WMI_PEER_TYPE_DEFAULT, 6201 vdev_id, mld_mac, 6202 is_assoc_peer); 6203 else 6204 status = wma_create_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT, 6205 vdev_id, mld_mac, is_assoc_peer); 6206 err: 6207 return status; 6208 } 6209 6210 QDF_STATUS wma_send_vdev_stop(uint8_t vdev_id) 6211 { 6212 tp_wma_handle wma; 6213 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 6214 QDF_STATUS status; 6215 6216 wma = cds_get_context(QDF_MODULE_ID_WMA); 6217 if (!wma) 6218 return QDF_STATUS_E_FAILURE; 6219 6220 wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", vdev_id); 6221 cdp_fc_vdev_pause(soc, vdev_id, 6222 OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); 6223 6224 status = mlme_set_vdev_stop_type( 6225 wma->interfaces[vdev_id].vdev, 6226 WMA_SET_LINK_STATE); 6227 if (QDF_IS_STATUS_ERROR(status)) { 6228 wma_alert("Failed to set wma req msg_type for vdev_id %d", 6229 vdev_id); 6230 return QDF_STATUS_E_FAILURE; 6231 } 6232 6233 wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); 6234 6235 status = wma_send_vdev_stop_to_fw(wma, vdev_id); 6236 if (QDF_IS_STATUS_ERROR(status)) { 6237 struct vdev_stop_response resp_event; 6238 6239 wma_info("vdev %d Failed to send vdev stop", vdev_id); 6240 resp_event.vdev_id = vdev_id; 6241 mlme_set_connection_fail(wma->interfaces[vdev_id].vdev, false); 6242 wma_handle_vdev_stop_rsp(wma, &resp_event); 6243 } 6244 6245 /* 6246 * Remove peer, Vdev down and sending set link 6247 * response will be handled in vdev stop response 6248 * handler 6249 */ 6250 6251 return QDF_STATUS_SUCCESS; 6252 } 6253 6254 #define TX_MGMT_RATE_2G_ENABLE_OFFSET 30 6255 #define TX_MGMT_RATE_5G_ENABLE_OFFSET 31 6256 #define TX_MGMT_RATE_2G_OFFSET 0 6257 #define TX_MGMT_RATE_5G_OFFSET 12 6258 6259 /** 6260 * wma_verify_rate_code() - verify if rate code is valid. 6261 * @rate_code: rate code 6262 * @band: band information 6263 * 6264 * Return: verify result 6265 */ 6266 static bool wma_verify_rate_code(uint32_t rate_code, enum cds_band_type band) 6267 { 6268 uint8_t preamble, nss, rate; 6269 bool valid = true; 6270 6271 preamble = (rate_code & 0xc0) >> 6; 6272 nss = (rate_code & 0x30) >> 4; 6273 rate = rate_code & 0xf; 6274 6275 switch (preamble) { 6276 case WMI_RATE_PREAMBLE_CCK: 6277 if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ) 6278 valid = false; 6279 break; 6280 case WMI_RATE_PREAMBLE_OFDM: 6281 if (nss != 0 || rate > 7) 6282 valid = false; 6283 break; 6284 case WMI_RATE_PREAMBLE_HT: 6285 if (nss != 0 || rate > 7) 6286 valid = false; 6287 break; 6288 case WMI_RATE_PREAMBLE_VHT: 6289 if (nss != 0 || rate > 9) 6290 valid = false; 6291 break; 6292 default: 6293 break; 6294 } 6295 return valid; 6296 } 6297 6298 /** 6299 * wma_vdev_mgmt_tx_rate() - set vdev mgmt rate. 6300 * @info: pointer to vdev set param. 6301 * 6302 * Return: return status 6303 */ 6304 static QDF_STATUS wma_vdev_mgmt_tx_rate(struct dev_set_param *info) 6305 { 6306 uint32_t cfg_val; 6307 enum cds_band_type band = 0; 6308 QDF_STATUS status; 6309 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 6310 6311 if (!mac) { 6312 wma_err("Failed to get mac"); 6313 return QDF_STATUS_E_FAILURE; 6314 } 6315 6316 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt; 6317 band = CDS_BAND_ALL; 6318 if (cfg_val == MLME_CFG_TX_MGMT_RATE_DEF || 6319 !wma_verify_rate_code(cfg_val, band)) { 6320 wma_nofl_debug("default WNI_CFG_RATE_FOR_TX_MGMT, ignore"); 6321 status = QDF_STATUS_E_FAILURE; 6322 } else { 6323 info->param_id = wmi_vdev_param_mgmt_tx_rate; 6324 info->param_value = cfg_val; 6325 status = QDF_STATUS_SUCCESS; 6326 } 6327 return status; 6328 } 6329 6330 /** 6331 * wma_vdev_mgmt_perband_tx_rate() - set vdev mgmt perband tx rate. 6332 * @info: pointer to vdev set param 6333 * 6334 * Return: returns status 6335 */ 6336 static QDF_STATUS wma_vdev_mgmt_perband_tx_rate(struct dev_set_param *info) 6337 { 6338 uint32_t cfg_val; 6339 uint32_t per_band_mgmt_tx_rate = 0; 6340 enum cds_band_type band = 0; 6341 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 6342 6343 if (!mac) { 6344 wma_err("failed to get mac"); 6345 return QDF_STATUS_E_FAILURE; 6346 } 6347 6348 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g; 6349 band = CDS_BAND_2GHZ; 6350 if (cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF || 6351 !wma_verify_rate_code(cfg_val, band)) { 6352 wma_nofl_debug("use default 2G MGMT rate."); 6353 per_band_mgmt_tx_rate &= 6354 ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET); 6355 } else { 6356 per_band_mgmt_tx_rate |= 6357 (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET); 6358 per_band_mgmt_tx_rate |= 6359 ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET); 6360 } 6361 6362 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt; 6363 band = CDS_BAND_5GHZ; 6364 if (cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF || 6365 !wma_verify_rate_code(cfg_val, band)) { 6366 wma_nofl_debug("use default 5G MGMT rate."); 6367 per_band_mgmt_tx_rate &= 6368 ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET); 6369 } else { 6370 per_band_mgmt_tx_rate |= 6371 (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET); 6372 per_band_mgmt_tx_rate |= 6373 ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET); 6374 } 6375 6376 info->param_id = wmi_vdev_param_per_band_mgmt_tx_rate; 6377 info->param_value = per_band_mgmt_tx_rate; 6378 return QDF_STATUS_SUCCESS; 6379 } 6380 6381 #define MAX_VDEV_CREATE_PARAMS 21 6382 /* params being sent: 6383 * 1.wmi_vdev_param_wmm_txop_enable 6384 * 2.wmi_vdev_param_disconnect_th 6385 * 3.wmi_vdev_param_mcc_rtscts_protection_enable 6386 * 4.wmi_vdev_param_mcc_broadcast_probe_enable 6387 * 5.wmi_vdev_param_rts_threshold 6388 * 6.wmi_vdev_param_fragmentation_threshold 6389 * 7.wmi_vdev_param_tx_stbc 6390 * 8.wmi_vdev_param_mgmt_tx_rate 6391 * 9.wmi_vdev_param_per_band_mgmt_tx_rate 6392 * 10.wmi_vdev_param_set_eht_mu_mode 6393 * 11.wmi_vdev_param_set_hemu_mode 6394 * 12.wmi_vdev_param_txbf 6395 * 13.wmi_vdev_param_enable_bcast_probe_response 6396 * 14.wmi_vdev_param_fils_max_channel_guard_time 6397 * 15.wmi_vdev_param_probe_delay 6398 * 16.wmi_vdev_param_repeat_probe_time 6399 * 17.wmi_vdev_param_enable_disable_oce_features 6400 * 18.wmi_vdev_param_bmiss_first_bcnt 6401 * 19.wmi_vdev_param_bmiss_final_bcnt 6402 * 20.wmi_vdev_param_set_sap_ps_with_twt 6403 * 21.wmi_vdev_param_disable_2g_twt 6404 */ 6405 6406 QDF_STATUS wma_vdev_create_set_param(struct wlan_objmgr_vdev *vdev) 6407 { 6408 QDF_STATUS status; 6409 struct mlme_ht_capabilities_info *ht_cap_info; 6410 uint32_t cfg_val; 6411 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 6412 struct dev_set_param ext_val; 6413 wmi_vdev_txbf_en txbf_en = {0}; 6414 struct vdev_mlme_obj *vdev_mlme; 6415 uint8_t vdev_id; 6416 uint32_t hemu_mode; 6417 struct dev_set_param setparam[MAX_VDEV_CREATE_PARAMS]; 6418 uint8_t index = 0; 6419 bool is_24ghz_twt_enabled; 6420 enum QDF_OPMODE opmode; 6421 6422 if (!mac) 6423 return QDF_STATUS_E_FAILURE; 6424 6425 vdev_id = wlan_vdev_get_id(vdev); 6426 6427 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 6428 if (!vdev_mlme) { 6429 wma_err("Failed to get vdev mlme obj!"); 6430 return QDF_STATUS_E_FAILURE; 6431 } 6432 6433 status = mlme_check_index_setparam( 6434 setparam, wmi_vdev_param_wmm_txop_enable, 6435 mac->mlme_cfg->edca_params.enable_wmm_txop, 6436 index++, MAX_VDEV_CREATE_PARAMS); 6437 if (QDF_IS_STATUS_ERROR(status)) { 6438 wma_debug("failed to set wmi_vdev_param_wmm_txop_enable"); 6439 goto error; 6440 } 6441 wma_debug("Setting wmi_vdev_param_disconnect_th: %d", 6442 mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh); 6443 status = mlme_check_index_setparam( 6444 setparam, wmi_vdev_param_disconnect_th, 6445 mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh, 6446 index++, MAX_VDEV_CREATE_PARAMS); 6447 if (QDF_IS_STATUS_ERROR(status)) { 6448 wma_debug("failed to set wmi_vdev_param_disconnect_th"); 6449 goto error; 6450 } 6451 status = mlme_check_index_setparam( 6452 setparam, 6453 wmi_vdev_param_mcc_rtscts_protection_enable, 6454 mac->roam.configParam.mcc_rts_cts_prot_enable, 6455 index++, MAX_VDEV_CREATE_PARAMS); 6456 if (QDF_IS_STATUS_ERROR(status)) { 6457 wma_debug("failed to set wmi_vdev_param_mcc_rtscts_protection_enable"); 6458 goto error; 6459 } 6460 status = mlme_check_index_setparam( 6461 setparam, 6462 wmi_vdev_param_mcc_broadcast_probe_enable, 6463 mac->roam.configParam.mcc_bcast_prob_resp_enable, 6464 index++, MAX_VDEV_CREATE_PARAMS); 6465 if (QDF_IS_STATUS_ERROR(status)) { 6466 wma_debug("failed to set wmi_vdev_param_mcc_broadcast_probe_enable"); 6467 goto error; 6468 } 6469 if (wlan_mlme_get_rts_threshold(mac->psoc, &cfg_val) == 6470 QDF_STATUS_SUCCESS) { 6471 status = mlme_check_index_setparam( 6472 setparam, 6473 wmi_vdev_param_rts_threshold, 6474 cfg_val, index++, 6475 MAX_VDEV_CREATE_PARAMS); 6476 if (QDF_IS_STATUS_ERROR(status)) { 6477 wma_debug("failed to set wmi_vdev_param_rts_threshold"); 6478 goto error; 6479 } 6480 } else { 6481 wma_err("Fail to get val for rts threshold, leave unchanged"); 6482 } 6483 if (wlan_mlme_get_frag_threshold(mac->psoc, &cfg_val) == 6484 QDF_STATUS_SUCCESS) { 6485 status = mlme_check_index_setparam( 6486 setparam, 6487 wmi_vdev_param_fragmentation_threshold, 6488 cfg_val, index++, 6489 MAX_VDEV_CREATE_PARAMS); 6490 if (QDF_IS_STATUS_ERROR(status)) { 6491 wma_debug("failed to set wmi_vdev_param_fragmentation_threshold"); 6492 goto error; 6493 } 6494 } else { 6495 wma_err("Fail to get val for frag threshold, leave unchanged"); 6496 } 6497 6498 ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info; 6499 status = mlme_check_index_setparam(setparam, 6500 wmi_vdev_param_tx_stbc, 6501 ht_cap_info->tx_stbc, index++, 6502 MAX_VDEV_CREATE_PARAMS); 6503 if (QDF_IS_STATUS_ERROR(status)) { 6504 wma_debug("failed to set wmi_vdev_param_tx_stbc"); 6505 goto error; 6506 } 6507 if (!wma_vdev_mgmt_tx_rate(&ext_val)) { 6508 status = mlme_check_index_setparam(setparam, ext_val.param_id, 6509 ext_val.param_value, index++, 6510 MAX_VDEV_CREATE_PARAMS); 6511 if (QDF_IS_STATUS_ERROR(status)) { 6512 wma_debug("failed to set param for MGMT RATE"); 6513 goto error; 6514 } 6515 } 6516 if (!wma_vdev_mgmt_perband_tx_rate(&ext_val)) { 6517 status = mlme_check_index_setparam(setparam, ext_val.param_id, 6518 ext_val.param_value, index++, 6519 MAX_VDEV_CREATE_PARAMS); 6520 if (QDF_IS_STATUS_ERROR(status)) { 6521 wma_debug("failed to set PERBAND_MGMT RATE"); 6522 goto error; 6523 } 6524 } 6525 if (IS_FEATURE_11BE_SUPPORTED_BY_FW) { 6526 uint32_t mode; 6527 6528 status = wma_set_eht_txbf_vdev_params(mac, &mode); 6529 if (status == QDF_STATUS_SUCCESS) { 6530 wma_debug("set EHTMU_MODE (ehtmu_mode = 0x%x)", mode); 6531 status = mlme_check_index_setparam( 6532 setparam, 6533 wmi_vdev_param_set_eht_mu_mode, 6534 mode, index++, 6535 MAX_VDEV_CREATE_PARAMS); 6536 if (QDF_IS_STATUS_ERROR(status)) { 6537 wma_debug("failed to set wmi_vdev_param_set_eht_mu_mode"); 6538 goto error; 6539 } 6540 } 6541 } 6542 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) { 6543 if (!wma_get_hemu_mode(&hemu_mode, mac)) { 6544 wma_debug("set HEMU_MODE (hemu_mode = 0x%x)", 6545 hemu_mode); 6546 status = mlme_check_index_setparam( 6547 setparam, 6548 wmi_vdev_param_set_hemu_mode, 6549 hemu_mode, index++, 6550 MAX_VDEV_CREATE_PARAMS); 6551 if (QDF_IS_STATUS_ERROR(status)) { 6552 wma_debug("failed to set wmi_vdev_param_set_hemu_mode"); 6553 goto error; 6554 } 6555 } 6556 } 6557 if (wlan_nan_is_beamforming_supported(mac->psoc)) { 6558 txbf_en.sutxbfee = 6559 mac->mlme_cfg->vht_caps.vht_cap_info.su_bformee; 6560 txbf_en.mutxbfee = 6561 mac->mlme_cfg->vht_caps.vht_cap_info.enable_mu_bformee; 6562 txbf_en.sutxbfer = 6563 mac->mlme_cfg->vht_caps.vht_cap_info.su_bformer; 6564 status = mlme_check_index_setparam(setparam, 6565 wmi_vdev_param_txbf, 6566 *((A_UINT8 *)&txbf_en), index++, 6567 MAX_VDEV_CREATE_PARAMS); 6568 if (QDF_IS_STATUS_ERROR(status)) { 6569 wma_debug("failed to set wmi_vdev_param_txbf"); 6570 goto error; 6571 } 6572 } 6573 /* Initialize roaming offload state */ 6574 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA && 6575 vdev_mlme->mgmt.generic.subtype == 0) { 6576 /* Pass down enable/disable bcast probe rsp to FW */ 6577 status = mlme_check_index_setparam( 6578 setparam, 6579 wmi_vdev_param_enable_bcast_probe_response, 6580 mac->mlme_cfg->oce.enable_bcast_probe_rsp, 6581 index++, MAX_VDEV_CREATE_PARAMS); 6582 if (QDF_IS_STATUS_ERROR(status)) { 6583 wma_debug("failed to set wmi_vdev_param_enable_bcast_probe_response"); 6584 goto error; 6585 } 6586 /* Pass down the FILS max channel guard time to FW */ 6587 status = mlme_check_index_setparam( 6588 setparam, 6589 wmi_vdev_param_fils_max_channel_guard_time, 6590 mac->mlme_cfg->sta.fils_max_chan_guard_time, 6591 index++, MAX_VDEV_CREATE_PARAMS); 6592 if (QDF_IS_STATUS_ERROR(status)) { 6593 wma_debug("failed to set wmi_vdev_param_fils_max_channel_guard_time"); 6594 goto error; 6595 } 6596 /* Pass down the Probe Request tx delay(in ms) to FW */ 6597 status = mlme_check_index_setparam(setparam, 6598 wmi_vdev_param_probe_delay, 6599 PROBE_REQ_TX_DELAY, index++, 6600 MAX_VDEV_CREATE_PARAMS); 6601 if (QDF_IS_STATUS_ERROR(status)) { 6602 wma_debug("failed to set wmi_vdev_param_probe_delay"); 6603 goto error; 6604 } 6605 /* Pass down the probe request tx time gap_ms to FW */ 6606 status = mlme_check_index_setparam( 6607 setparam, 6608 wmi_vdev_param_repeat_probe_time, 6609 PROBE_REQ_TX_TIME_GAP, index++, 6610 MAX_VDEV_CREATE_PARAMS); 6611 if (QDF_IS_STATUS_ERROR(status)) { 6612 wma_debug("failed to set wmi_vdev_param_repeat_probe_time"); 6613 goto error; 6614 } 6615 status = mlme_check_index_setparam( 6616 setparam, 6617 wmi_vdev_param_enable_disable_oce_features, 6618 mac->mlme_cfg->oce.feature_bitmap, index++, 6619 MAX_VDEV_CREATE_PARAMS); 6620 if (QDF_IS_STATUS_ERROR(status)) { 6621 wma_debug("failed to set wmi_vdev_param_enable_disable_oce_features"); 6622 goto error; 6623 } 6624 /* Initialize BMISS parameters */ 6625 wma_debug("first_bcnt: %d, final_bcnt: %d", 6626 mac->mlme_cfg->lfr.roam_bmiss_first_bcnt, 6627 mac->mlme_cfg->lfr.roam_bmiss_final_bcnt); 6628 status = mlme_check_index_setparam( 6629 setparam, 6630 wmi_vdev_param_bmiss_first_bcnt, 6631 mac->mlme_cfg->lfr.roam_bmiss_first_bcnt, 6632 index++, MAX_VDEV_CREATE_PARAMS); 6633 if (QDF_IS_STATUS_ERROR(status)) { 6634 wma_debug("failed to set wmi_vdev_param_bmiss_first_bcnt"); 6635 goto error; 6636 } 6637 status = mlme_check_index_setparam(setparam, 6638 wmi_vdev_param_bmiss_final_bcnt, 6639 mac->mlme_cfg->lfr.roam_bmiss_final_bcnt, 6640 index++, MAX_VDEV_CREATE_PARAMS); 6641 if (QDF_IS_STATUS_ERROR(status)) { 6642 wma_debug("failed to set wmi_vdev_param_bmiss_final_bcnt"); 6643 goto error; 6644 } 6645 } 6646 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_AP && 6647 vdev_mlme->mgmt.generic.subtype == 0) { 6648 status = mlme_check_index_setparam(setparam, 6649 wmi_vdev_param_enable_disable_oce_features, 6650 mac->mlme_cfg->oce.feature_bitmap, index++, 6651 MAX_VDEV_CREATE_PARAMS); 6652 if (QDF_IS_STATUS_ERROR(status)) { 6653 wma_debug("failed to set wmi_vdev_param_enable_disable_oce_features"); 6654 goto error; 6655 } 6656 } 6657 6658 opmode = wlan_vdev_mlme_get_opmode(vdev); 6659 if (opmode == QDF_SAP_MODE) { 6660 status = mlme_check_index_setparam( 6661 setparam, 6662 wmi_vdev_param_set_sap_ps_with_twt, 6663 wlan_mlme_get_sap_ps_with_twt(mac->psoc), 6664 index++, MAX_VDEV_CREATE_PARAMS); 6665 if (QDF_IS_STATUS_ERROR(status)) { 6666 wma_debug("failed to set wmi_vdev_param_set_sap_ps_with_twt"); 6667 goto error; 6668 } 6669 } 6670 6671 is_24ghz_twt_enabled = mlme_is_24ghz_twt_enabled(mac->psoc); 6672 status = mlme_check_index_setparam(setparam, 6673 wmi_vdev_param_disable_2g_twt, 6674 !is_24ghz_twt_enabled, 6675 index++, MAX_VDEV_CREATE_PARAMS); 6676 if (QDF_IS_STATUS_ERROR(status)) { 6677 wma_debug("failed to set wmi_vdev_param_disable_2g_twt"); 6678 goto error; 6679 } 6680 6681 status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 6682 vdev_id, setparam, index); 6683 if (QDF_IS_STATUS_ERROR(status)) { 6684 wma_err("failed to update vdev set all params"); 6685 status = QDF_STATUS_E_FAILURE; 6686 goto error; 6687 } 6688 error: 6689 return status; 6690 } 6691 6692 static inline bool wma_tx_is_chainmask_valid(int value, 6693 struct target_psoc_info *tgt_hdl) 6694 { 6695 struct wlan_psoc_host_mac_phy_caps *mac_phy_cap; 6696 uint8_t total_mac_phy_cnt, i; 6697 6698 mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); 6699 if (!mac_phy_cap) { 6700 wma_err("Invalid MAC PHY capabilities handle"); 6701 return false; 6702 } 6703 total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); 6704 for (i = 0; i < total_mac_phy_cnt; i++) { 6705 if (((mac_phy_cap[i].tx_chain_mask_5G) & (value))) 6706 return true; 6707 } 6708 return false; 6709 } 6710 6711 QDF_STATUS 6712 wma_validate_txrx_chain_mask(uint32_t id, uint32_t value) 6713 { 6714 tp_wma_handle wma_handle = 6715 cds_get_context(QDF_MODULE_ID_WMA); 6716 struct target_psoc_info *tgt_hdl; 6717 6718 if (!wma_handle) 6719 return QDF_STATUS_E_FAILURE; 6720 6721 tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc); 6722 if (!tgt_hdl) 6723 return QDF_STATUS_E_FAILURE; 6724 6725 wma_debug("pdev pid %d pval %d", id, value); 6726 if (id == wmi_pdev_param_tx_chain_mask) { 6727 if (wma_check_txrx_chainmask(target_if_get_num_rf_chains( 6728 tgt_hdl), value) || !wma_tx_is_chainmask_valid(value, 6729 tgt_hdl)) { 6730 wma_err("failed in validating tx chainmask"); 6731 return QDF_STATUS_E_FAILURE; 6732 } 6733 } 6734 if (id == wmi_pdev_param_rx_chain_mask) { 6735 if (wma_check_txrx_chainmask(target_if_get_num_rf_chains( 6736 tgt_hdl), value)) { 6737 wma_err("failed in validating rtx chainmask"); 6738 return QDF_STATUS_SUCCESS; 6739 } 6740 } 6741 return QDF_STATUS_SUCCESS; 6742 } 6743 6744 QDF_STATUS wma_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type, 6745 uint8_t dev_id, 6746 struct dev_set_param *param, 6747 uint8_t n_params) 6748 { 6749 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); 6750 struct set_multiple_pdev_vdev_param params = {}; 6751 QDF_STATUS status; 6752 wmi_unified_t wmi_handle; 6753 6754 if (!mac) 6755 return QDF_STATUS_E_FAILURE; 6756 6757 wmi_handle = get_wmi_unified_hdl_from_psoc(mac->psoc); 6758 if (!wmi_handle) 6759 return QDF_STATUS_E_FAILURE; 6760 6761 params.param_type = param_type; 6762 params.dev_id = dev_id; 6763 params.is_host_pdev_id = false; 6764 params.params = param; 6765 params.n_params = n_params; 6766 6767 if (param_type == MLME_VDEV_SETPARAM) { 6768 status = wmi_unified_multiple_vdev_param_send(wmi_handle, 6769 ¶ms); 6770 if (QDF_IS_STATUS_ERROR(status)) 6771 wma_err("failed to send multi vdev set params"); 6772 } else if (param_type == MLME_PDEV_SETPARAM) { 6773 status = wmi_unified_multiple_pdev_param_send(wmi_handle, 6774 ¶ms); 6775 if (QDF_IS_STATUS_ERROR(status)) 6776 wma_err("failed to send multi pdev set params"); 6777 } else { 6778 status = QDF_STATUS_E_FAILURE; 6779 wma_err("Invalid param type"); 6780 } 6781 return status; 6782 } 6783