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