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