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