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