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