1 /* 2 * Copyright (c) 2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: target_if_vdev_mgr_tx_ops.c 21 * 22 * This file provide definition for APIs registered through lmac Tx Ops 23 */ 24 #include <wlan_objmgr_pdev_obj.h> 25 #include <wlan_objmgr_vdev_obj.h> 26 #include <wmi_unified_api.h> 27 #include <wmi_unified_param.h> 28 #include <init_deinit_lmac.h> 29 #include <target_if_vdev_mgr_tx_ops.h> 30 #include <target_if_vdev_mgr_rx_ops.h> 31 #include <target_if_vdev_mgr_wake_lock.h> 32 #include <target_if.h> 33 #include <target_type.h> 34 #include <wlan_mlme_dbg.h> 35 #include <wlan_vdev_mgr_tgt_if_tx_defs.h> 36 #include <wlan_vdev_mgr_utils_api.h> 37 #include <wlan_cmn.h> 38 #include <wmi_unified_vdev_api.h> 39 #include <cdp_txrx_ctrl.h> 40 41 static QDF_STATUS target_if_vdev_mgr_register_event_handler( 42 struct wlan_objmgr_psoc *psoc) 43 { 44 return target_if_vdev_mgr_wmi_event_register(psoc); 45 } 46 47 static QDF_STATUS target_if_vdev_mgr_unregister_event_handler( 48 struct wlan_objmgr_psoc *psoc) 49 { 50 return target_if_vdev_mgr_wmi_event_unregister(psoc); 51 } 52 53 static QDF_STATUS target_if_vdev_mgr_rsp_timer_mod( 54 struct wlan_objmgr_vdev *vdev, 55 struct vdev_response_timer *vdev_rsp, 56 int mseconds) 57 { 58 if (!vdev || !vdev_rsp) { 59 mlme_err("Invalid input"); 60 return QDF_STATUS_E_FAILURE; 61 } 62 63 qdf_timer_mod(&vdev_rsp->rsp_timer, mseconds); 64 return QDF_STATUS_SUCCESS; 65 } 66 67 QDF_STATUS target_if_vdev_mgr_rsp_timer_stop( 68 struct wlan_objmgr_vdev *vdev, 69 struct vdev_response_timer *vdev_rsp, 70 uint8_t clear_bit) 71 { 72 if (qdf_atomic_test_and_clear_bit(clear_bit, &vdev_rsp->rsp_status)) { 73 /* 74 * This is triggered from timer expiry case only for 75 * which timer stop is not required 76 */ 77 if (vdev_rsp->timer_status != QDF_STATUS_E_TIMEOUT) 78 qdf_timer_stop(&vdev_rsp->rsp_timer); 79 80 vdev_rsp->timer_status = QDF_STATUS_SUCCESS; 81 /* 82 * Releasing reference taken at the time of 83 * starting response timer 84 */ 85 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 86 return QDF_STATUS_SUCCESS; 87 } 88 89 return QDF_STATUS_E_FAILURE; 90 } 91 92 static QDF_STATUS target_if_vdev_mgr_rsp_timer_start( 93 struct wlan_objmgr_vdev *vdev, 94 struct vdev_response_timer *vdev_rsp, 95 uint8_t set_bit) 96 { 97 uint8_t vdev_id; 98 uint8_t rsp_pos; 99 struct wlan_objmgr_psoc *psoc; 100 101 psoc = wlan_vdev_get_psoc(vdev); 102 if (!psoc) { 103 mlme_err("PSOC is NULL"); 104 return QDF_STATUS_E_INVAL; 105 } 106 107 vdev_id = wlan_vdev_get_id(vdev); 108 /* it is expected to be only one command with FW at a time */ 109 for (rsp_pos = START_RESPONSE_BIT; rsp_pos <= RESPONSE_BIT_MAX; 110 rsp_pos++) { 111 if (rsp_pos != set_bit) { 112 if (qdf_atomic_test_bit(rsp_pos, 113 &vdev_rsp->rsp_status)) { 114 mlme_err("PSOC_%d VDEV_%d: %s requested, waiting for %s response", 115 wlan_psoc_get_id(psoc), 116 vdev_id, string_from_rsp_bit(set_bit), 117 string_from_rsp_bit(rsp_pos)); 118 target_if_vdev_mgr_assert_mgmt(vdev, vdev_rsp, 119 rsp_pos); 120 target_if_vdev_mgr_rsp_timer_stop(vdev, 121 vdev_rsp, 122 rsp_pos); 123 } 124 } 125 } 126 127 if (qdf_atomic_test_and_set_bit(set_bit, &vdev_rsp->rsp_status)) { 128 mlme_err("PSOC_%d VDEV_%d: %s requested, waiting for %s response", 129 wlan_psoc_get_id(psoc), 130 vdev_id, string_from_rsp_bit(set_bit), 131 string_from_rsp_bit(set_bit)); 132 target_if_vdev_mgr_assert_mgmt(vdev, vdev_rsp, 133 set_bit); 134 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, set_bit); 135 136 qdf_atomic_set_bit(set_bit, &vdev_rsp->rsp_status); 137 } 138 139 /* reference taken for timer start, will be released with stop */ 140 wlan_objmgr_vdev_get_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 141 qdf_timer_start(&vdev_rsp->rsp_timer, vdev_rsp->expire_time); 142 143 return QDF_STATUS_SUCCESS; 144 } 145 146 static QDF_STATUS target_if_vdev_mgr_rsp_timer_init( 147 struct wlan_objmgr_vdev *vdev, 148 qdf_timer_t *rsp_timer) 149 { 150 if (!vdev || !rsp_timer) { 151 mlme_err("Invalid input"); 152 return QDF_STATUS_E_INVAL; 153 } 154 155 qdf_timer_init(NULL, rsp_timer, 156 target_if_vdev_mgr_rsp_timer_mgmt_cb, 157 (void *)vdev, QDF_TIMER_TYPE_WAKE_APPS); 158 mlme_debug("VDEV_%d: Response timer initialized", 159 wlan_vdev_get_id(vdev)); 160 161 return QDF_STATUS_SUCCESS; 162 } 163 164 struct wmi_unified 165 *target_if_vdev_mgr_wmi_handle_get(struct wlan_objmgr_vdev *vdev) 166 { 167 struct wlan_objmgr_pdev *pdev; 168 struct wmi_unified *wmi_handle; 169 170 pdev = wlan_vdev_get_pdev(vdev); 171 if (!pdev) { 172 mlme_err("PDEV is NULL"); 173 return NULL; 174 } 175 176 wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); 177 if (!wmi_handle) { 178 mlme_err("wmi_handle is null"); 179 return NULL; 180 } 181 182 return wmi_handle; 183 } 184 185 static inline uint32_t 186 target_if_vdev_mlme_build_txbf_caps(struct wlan_objmgr_vdev *vdev) 187 { 188 uint32_t txbf_cap; 189 uint32_t subfer; 190 uint32_t mubfer; 191 uint32_t subfee; 192 uint32_t mubfee; 193 uint32_t implicit_bf; 194 uint32_t sounding_dimension; 195 uint32_t bfee_sts_cap; 196 197 txbf_cap = 0; 198 /* 199 * ensure to set these after mlme component is attached to objmgr 200 */ 201 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SUBFEE, &subfee); 202 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_MUBFEE, &mubfee); 203 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SUBFER, &subfer); 204 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_MUBFER, &mubfer); 205 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_BFEE_STS_CAP, 206 &bfee_sts_cap); 207 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_IMLICIT_BF, 208 &implicit_bf); 209 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SOUNDING_DIM, 210 &sounding_dimension); 211 212 WMI_HOST_TXBF_CONF_SU_TX_BFEE_SET(txbf_cap, subfee); 213 WMI_HOST_TXBF_CONF_MU_TX_BFEE_SET(txbf_cap, mubfee); 214 WMI_HOST_TXBF_CONF_SU_TX_BFER_SET(txbf_cap, subfer); 215 WMI_HOST_TXBF_CONF_MU_TX_BFER_SET(txbf_cap, mubfer); 216 WMI_HOST_TXBF_CONF_STS_CAP_SET(txbf_cap, bfee_sts_cap); 217 WMI_HOST_TXBF_CONF_IMPLICIT_BF_SET(txbf_cap, implicit_bf); 218 WMI_HOST_TXBF_CONF_BF_SND_DIM_SET(txbf_cap, sounding_dimension); 219 220 mlme_debug("VHT su bfee:%d mu bfee:%d su bfer:%d " 221 "mu bfer:%d impl bf:%d sounding dim:%d", 222 WMI_HOST_TXBF_CONF_SU_TX_BFEE_GET(txbf_cap), 223 WMI_HOST_TXBF_CONF_MU_TX_BFEE_GET(txbf_cap), 224 WMI_HOST_TXBF_CONF_SU_TX_BFER_GET(txbf_cap), 225 WMI_HOST_TXBF_CONF_MU_TX_BFER_GET(txbf_cap), 226 WMI_HOST_TXBF_CONF_IMPLICIT_BF_GET(txbf_cap), 227 WMI_HOST_TXBF_CONF_BF_SND_DIM_GET(txbf_cap)); 228 229 return txbf_cap; 230 } 231 232 static inline uint32_t 233 target_if_vdev_mlme_id_2_wmi(uint32_t cfg_id) 234 { 235 int wmi_id; 236 237 switch (cfg_id) { 238 case WLAN_MLME_CFG_DTIM_PERIOD: 239 wmi_id = wmi_vdev_param_dtim_period; 240 break; 241 case WLAN_MLME_CFG_SLOT_TIME: 242 wmi_id = wmi_vdev_param_slot_time; 243 break; 244 case WLAN_MLME_CFG_PROTECTION_MODE: 245 wmi_id = wmi_vdev_param_protection_mode; 246 break; 247 case WLAN_MLME_CFG_BEACON_INTERVAL: 248 wmi_id = wmi_vdev_param_beacon_interval; 249 break; 250 case WLAN_MLME_CFG_LDPC: 251 wmi_id = wmi_vdev_param_ldpc; 252 break; 253 case WLAN_MLME_CFG_NSS: 254 wmi_id = wmi_vdev_param_nss; 255 break; 256 case WLAN_MLME_CFG_SUBFER: 257 case WLAN_MLME_CFG_MUBFER: 258 case WLAN_MLME_CFG_SUBFEE: 259 case WLAN_MLME_CFG_MUBFEE: 260 case WLAN_MLME_CFG_IMLICIT_BF: 261 case WLAN_MLME_CFG_SOUNDING_DIM: 262 case WLAN_MLME_CFG_TXBF_CAPS: 263 wmi_id = wmi_vdev_param_txbf; 264 break; 265 case WLAN_MLME_CFG_HE_OPS: 266 wmi_id = wmi_vdev_param_set_heop; 267 break; 268 case WLAN_MLME_CFG_RTS_THRESHOLD: 269 wmi_id = wmi_vdev_param_rts_threshold; 270 break; 271 case WLAN_MLME_CFG_FRAG_THRESHOLD: 272 wmi_id = wmi_vdev_param_fragmentation_threshold; 273 break; 274 case WLAN_MLME_CFG_DROP_UNENCRY: 275 wmi_id = wmi_vdev_param_drop_unencry; 276 break; 277 case WLAN_MLME_CFG_TX_POWER: 278 wmi_id = wmi_vdev_param_tx_power; 279 break; 280 case WLAN_MLME_CFG_AMPDU: 281 wmi_id = wmi_vdev_param_ampdu_subframe_size_per_ac; 282 break; 283 case WLAN_MLME_CFG_AMSDU: 284 wmi_id = wmi_vdev_param_amsdu_subframe_size_per_ac; 285 break; 286 case WLAN_MLME_CFG_MIN_IDLE_INACTIVE_TIME: 287 wmi_id = 288 wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs; 289 break; 290 case WLAN_MLME_CFG_MAX_IDLE_INACTIVE_TIME: 291 wmi_id = 292 wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs; 293 break; 294 case WLAN_MLME_CFG_MAX_UNRESPONSIVE_INACTIVE_TIME: 295 wmi_id = 296 wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs; 297 break; 298 case WLAN_MLME_CFG_UAPSD: 299 wmi_id = WMI_HOST_STA_PS_PARAM_UAPSD; 300 break; 301 case WLAN_MLME_CFG_BCN_TX_RATE_CODE: 302 wmi_id = wmi_vdev_param_beacon_rate; 303 break; 304 case WLAN_MLME_CFG_TX_MGMT_RATE_CODE: 305 wmi_id = wmi_vdev_param_mgmt_rate; 306 break; 307 case WLAN_MLME_CFG_LISTEN_INTERVAL: 308 wmi_id = wmi_vdev_param_listen_interval; 309 break; 310 case WLAN_MLME_CFG_ENABLE_MULTI_GROUP_KEY: 311 wmi_id = wmi_vdev_param_enable_multi_group_key; 312 break; 313 case WLAN_MLME_CFG_MAX_GROUP_KEYS: 314 wmi_id = wmi_vdev_param_max_group_keys; 315 break; 316 case WLAN_MLME_CFG_TX_ENCAP_TYPE: 317 wmi_id = wmi_vdev_param_tx_encap_type; 318 break; 319 case WLAN_MLME_CFG_RX_DECAP_TYPE: 320 wmi_id = wmi_vdev_param_rx_decap_type; 321 break; 322 default: 323 wmi_id = cfg_id; 324 break; 325 } 326 327 return wmi_id; 328 } 329 330 static 331 QDF_STATUS target_if_vdev_set_tx_rx_decap_type(struct wlan_objmgr_vdev *vdev, 332 enum wlan_mlme_cfg_id param_id, 333 uint32_t value) 334 { 335 ol_txrx_soc_handle soc_txrx_handle; 336 struct cdp_vdev *vdev_txrx_handle; 337 struct wlan_objmgr_psoc *psoc; 338 339 psoc = wlan_vdev_get_psoc(vdev); 340 soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); 341 vdev_txrx_handle = wlan_vdev_get_dp_handle(vdev); 342 343 if (!soc_txrx_handle || !vdev_txrx_handle) 344 return QDF_STATUS_E_INVAL; 345 346 if (param_id == WLAN_MLME_CFG_TX_ENCAP_TYPE) 347 cdp_set_tx_encap_type(soc_txrx_handle, 348 (struct cdp_vdev *)vdev_txrx_handle, 349 value); 350 else if (param_id == WLAN_MLME_CFG_RX_DECAP_TYPE) 351 cdp_set_vdev_rx_decap_type(soc_txrx_handle, 352 (struct cdp_vdev *)vdev_txrx_handle, 353 value); 354 355 return QDF_STATUS_SUCCESS; 356 } 357 358 static QDF_STATUS target_if_vdev_mgr_set_param_send( 359 struct wlan_objmgr_vdev *vdev, 360 struct vdev_set_params *param) 361 { 362 QDF_STATUS status; 363 struct wmi_unified *wmi_handle; 364 int param_id; 365 366 if (!vdev || !param) { 367 mlme_err("Invalid input"); 368 return QDF_STATUS_E_INVAL; 369 } 370 371 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 372 if (!wmi_handle) { 373 mlme_err("Failed to get WMI handle!"); 374 return QDF_STATUS_E_INVAL; 375 } 376 param_id = target_if_vdev_mlme_id_2_wmi(param->param_id); 377 param->param_id = param_id; 378 if (param->param_id == wmi_vdev_param_txbf) 379 param->param_value = target_if_vdev_mlme_build_txbf_caps(vdev); 380 381 status = wmi_unified_vdev_set_param_send(wmi_handle, param); 382 383 return status; 384 } 385 386 static QDF_STATUS target_if_vdev_mgr_create_send( 387 struct wlan_objmgr_vdev *vdev, 388 struct vdev_create_params *param) 389 { 390 QDF_STATUS status; 391 struct wmi_unified *wmi_handle; 392 uint8_t vap_addr[QDF_MAC_ADDR_SIZE] = {0}; 393 394 if (!vdev || !param) { 395 mlme_err("Invalid input"); 396 return QDF_STATUS_E_INVAL; 397 } 398 399 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 400 if (!wmi_handle) { 401 mlme_err("Failed to get WMI handle!"); 402 return QDF_STATUS_E_INVAL; 403 } 404 405 WLAN_ADDR_COPY(vap_addr, wlan_vdev_mlme_get_macaddr(vdev)); 406 status = wmi_unified_vdev_create_send(wmi_handle, vap_addr, 407 param); 408 409 return status; 410 } 411 412 static QDF_STATUS target_if_vdev_mgr_start_send( 413 struct wlan_objmgr_vdev *vdev, 414 struct vdev_start_params *param) 415 { 416 QDF_STATUS status; 417 struct wmi_unified *wmi_handle; 418 struct wlan_objmgr_psoc *psoc; 419 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 420 struct vdev_response_timer *vdev_rsp; 421 uint8_t vdev_id; 422 423 if (!vdev || !param) { 424 mlme_err("Invalid input"); 425 return QDF_STATUS_E_INVAL; 426 } 427 428 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 429 if (!wmi_handle) { 430 mlme_err("Failed to get WMI handle!"); 431 return QDF_STATUS_E_INVAL; 432 } 433 434 vdev_id = wlan_vdev_get_id(vdev); 435 psoc = wlan_vdev_get_psoc(vdev); 436 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 437 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 438 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 439 return QDF_STATUS_E_INVAL; 440 } 441 442 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 443 if (!vdev_rsp) { 444 mlme_err("VDEV_%d: Invalid response structure", vdev_id); 445 return QDF_STATUS_E_FAILURE; 446 } 447 target_if_wake_lock_timeout_acquire(vdev, START_WAKELOCK); 448 449 vdev_rsp->expire_time = START_RESPONSE_TIMER; 450 if (param->is_restart) 451 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, 452 RESTART_RESPONSE_BIT); 453 else 454 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, 455 START_RESPONSE_BIT); 456 457 status = wmi_unified_vdev_start_send(wmi_handle, param); 458 if (QDF_IS_STATUS_ERROR(status)) { 459 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 460 vdev_rsp->expire_time = 0; 461 target_if_wake_lock_timeout_release(vdev, START_WAKELOCK); 462 if (param->is_restart) 463 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 464 RESTART_RESPONSE_BIT); 465 else 466 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 467 START_RESPONSE_BIT); 468 } 469 470 return status; 471 } 472 473 static QDF_STATUS target_if_vdev_mgr_delete_response_send( 474 struct wlan_objmgr_vdev *vdev, 475 struct wlan_lmac_if_mlme_rx_ops *rx_ops) 476 { 477 QDF_STATUS status = QDF_STATUS_SUCCESS; 478 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 479 struct vdev_delete_response rsp = {0}; 480 481 rsp.vdev_id = wlan_vdev_get_id(vdev); 482 status = rx_ops->vdev_mgr_delete_response(psoc, &rsp); 483 target_if_wake_lock_timeout_release(vdev, DELETE_WAKELOCK); 484 485 return status; 486 } 487 488 static QDF_STATUS target_if_vdev_mgr_delete_send( 489 struct wlan_objmgr_vdev *vdev, 490 struct vdev_delete_params *param) 491 { 492 QDF_STATUS status; 493 struct wlan_objmgr_psoc *psoc; 494 struct wmi_unified *wmi_handle; 495 struct vdev_response_timer *vdev_rsp; 496 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 497 uint8_t vdev_id; 498 499 if (!vdev || !param) { 500 mlme_err("Invalid input"); 501 return QDF_STATUS_E_INVAL; 502 } 503 504 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 505 if (!wmi_handle) { 506 mlme_err("Failed to get WMI handle!"); 507 return QDF_STATUS_E_INVAL; 508 } 509 510 vdev_id = wlan_vdev_get_id(vdev); 511 psoc = wlan_vdev_get_psoc(vdev); 512 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 513 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 514 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 515 return QDF_STATUS_E_INVAL; 516 } 517 518 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 519 if (!vdev_rsp) { 520 mlme_err("VDEV_%d: Invalid response structure", vdev_id); 521 return QDF_STATUS_E_FAILURE; 522 } 523 target_if_wake_lock_timeout_acquire(vdev, DELETE_WAKELOCK); 524 vdev_rsp->expire_time = DELETE_RESPONSE_TIMER; 525 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, 526 DELETE_RESPONSE_BIT); 527 528 status = wmi_unified_vdev_delete_send(wmi_handle, param->vdev_id); 529 if (QDF_IS_STATUS_SUCCESS(status)) { 530 /* 531 * Simulate delete response if target doesn't support 532 */ 533 if (!wmi_service_enabled(wmi_handle, 534 wmi_service_sync_delete_cmds) || 535 wlan_psoc_nif_feat_cap_get(psoc, 536 WLAN_SOC_F_TESTMODE_ENABLE)) { 537 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 538 DELETE_RESPONSE_BIT); 539 target_if_vdev_mgr_delete_response_send(vdev, rx_ops); 540 } 541 } else { 542 target_if_wake_lock_timeout_release(vdev, DELETE_WAKELOCK); 543 vdev_rsp->expire_time = 0; 544 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 545 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 546 DELETE_RESPONSE_BIT); 547 } 548 549 return status; 550 } 551 552 static QDF_STATUS target_if_vdev_mgr_stop_send( 553 struct wlan_objmgr_vdev *vdev, 554 struct vdev_stop_params *param) 555 { 556 QDF_STATUS status; 557 struct wmi_unified *wmi_handle; 558 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 559 struct wlan_objmgr_psoc *psoc; 560 struct vdev_response_timer *vdev_rsp; 561 uint8_t vdev_id; 562 563 if (!vdev || !param) { 564 mlme_err("Invalid input"); 565 return QDF_STATUS_E_INVAL; 566 } 567 568 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 569 if (!wmi_handle) { 570 mlme_err("Failed to get WMI handle!"); 571 return QDF_STATUS_E_INVAL; 572 } 573 574 vdev_id = wlan_vdev_get_id(vdev); 575 psoc = wlan_vdev_get_psoc(vdev); 576 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 577 578 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 579 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 580 return QDF_STATUS_E_INVAL; 581 } 582 583 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 584 if (!vdev_rsp) { 585 mlme_err("VDEV_%d: Invalid response structure", vdev_id); 586 return QDF_STATUS_E_FAILURE; 587 } 588 589 target_if_wake_lock_timeout_acquire(vdev, STOP_WAKELOCK); 590 vdev_rsp->expire_time = STOP_RESPONSE_TIMER; 591 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, STOP_RESPONSE_BIT); 592 593 status = wmi_unified_vdev_stop_send(wmi_handle, param->vdev_id); 594 if (QDF_IS_STATUS_ERROR(status)) { 595 vdev_rsp->expire_time = 0; 596 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 597 target_if_wake_lock_timeout_release(vdev, STOP_WAKELOCK); 598 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 599 STOP_RESPONSE_BIT); 600 } 601 602 return status; 603 } 604 605 static QDF_STATUS target_if_vdev_mgr_down_send( 606 struct wlan_objmgr_vdev *vdev, 607 struct vdev_down_params *param) 608 { 609 QDF_STATUS status; 610 struct wmi_unified *wmi_handle; 611 612 if (!vdev || !param) { 613 mlme_err("Invalid input"); 614 return QDF_STATUS_E_INVAL; 615 } 616 617 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 618 if (!wmi_handle) { 619 mlme_err("Failed to get WMI handle!"); 620 return QDF_STATUS_E_INVAL; 621 } 622 623 status = wmi_unified_vdev_down_send(wmi_handle, param->vdev_id); 624 target_if_wake_lock_timeout_release(vdev, START_WAKELOCK); 625 626 return status; 627 } 628 629 static QDF_STATUS target_if_vdev_mgr_up_send( 630 struct wlan_objmgr_vdev *vdev, 631 struct vdev_up_params *param) 632 { 633 QDF_STATUS status; 634 struct wmi_unified *wmi_handle; 635 struct vdev_set_params sparam = {0}; 636 uint8_t bssid[QDF_MAC_ADDR_SIZE]; 637 uint8_t vdev_id; 638 639 if (!vdev || !param) { 640 mlme_err("Invalid input"); 641 return QDF_STATUS_E_INVAL; 642 } 643 644 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 645 if (!wmi_handle) { 646 mlme_err("Failed to get WMI handle!"); 647 return QDF_STATUS_E_INVAL; 648 } 649 650 vdev_id = wlan_vdev_get_id(vdev); 651 sparam.vdev_id = vdev_id; 652 653 sparam.param_id = WLAN_MLME_CFG_BEACON_INTERVAL; 654 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_BEACON_INTERVAL, 655 &sparam.param_value); 656 status = target_if_vdev_mgr_set_param_send(vdev, &sparam); 657 if (QDF_IS_STATUS_ERROR(status)) 658 mlme_err("VDEV_%d: Failed to set beacon interval!", vdev_id); 659 660 ucfg_wlan_vdev_mgr_get_param_bssid(vdev, bssid); 661 662 status = wmi_unified_vdev_up_send(wmi_handle, bssid, param); 663 target_if_wake_lock_timeout_release(vdev, START_WAKELOCK); 664 665 return status; 666 } 667 668 static QDF_STATUS target_if_vdev_mgr_beacon_tmpl_send( 669 struct wlan_objmgr_vdev *vdev, 670 struct beacon_tmpl_params *param) 671 { 672 QDF_STATUS status; 673 struct wmi_unified *wmi_handle; 674 675 if (!vdev || !param) { 676 mlme_err("Invalid input"); 677 return QDF_STATUS_E_INVAL; 678 } 679 680 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 681 if (!wmi_handle) { 682 mlme_err("Failed to get WMI handle!"); 683 return QDF_STATUS_E_INVAL; 684 } 685 686 status = wmi_unified_beacon_tmpl_send_cmd(wmi_handle, param); 687 return status; 688 } 689 690 static QDF_STATUS target_if_vdev_mgr_set_nac_rssi_send( 691 struct wlan_objmgr_vdev *vdev, 692 struct vdev_scan_nac_rssi_params *param) 693 { 694 QDF_STATUS status; 695 struct wmi_unified *wmi_handle; 696 697 if (!vdev || !param) { 698 mlme_err("Invalid input"); 699 return QDF_STATUS_E_INVAL; 700 } 701 702 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 703 if (!wmi_handle) { 704 mlme_err("Failed to get WMI handle!"); 705 return QDF_STATUS_E_INVAL; 706 } 707 708 status = wmi_unified_vdev_set_nac_rssi_send(wmi_handle, param); 709 710 return status; 711 } 712 713 static QDF_STATUS target_if_vdev_mgr_set_neighbour_rx_cmd_send( 714 struct wlan_objmgr_vdev *vdev, 715 struct set_neighbour_rx_params *param, 716 uint8_t *mac) 717 { 718 QDF_STATUS status; 719 struct wmi_unified *wmi_handle; 720 721 if (!vdev || !param) { 722 mlme_err("Invalid input"); 723 return QDF_STATUS_E_INVAL; 724 } 725 726 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 727 if (!wmi_handle) { 728 mlme_err("Failed to get WMI handle!"); 729 return QDF_STATUS_E_INVAL; 730 } 731 732 status = wmi_unified_vdev_set_neighbour_rx_cmd_send(wmi_handle, 733 mac, param); 734 735 return status; 736 } 737 738 static QDF_STATUS target_if_vdev_mgr_sifs_trigger_send( 739 struct wlan_objmgr_vdev *vdev, 740 struct sifs_trigger_param *param) 741 { 742 QDF_STATUS status; 743 struct wmi_unified *wmi_handle; 744 745 if (!vdev || !param) { 746 mlme_err("Invalid input"); 747 return QDF_STATUS_E_INVAL; 748 } 749 750 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 751 if (!wmi_handle) { 752 mlme_err("Failed to get WMI handle!"); 753 return QDF_STATUS_E_INVAL; 754 } 755 756 status = wmi_unified_sifs_trigger_send(wmi_handle, param); 757 758 return status; 759 } 760 761 static QDF_STATUS target_if_vdev_mgr_set_custom_aggr_size_cmd_send( 762 struct wlan_objmgr_vdev *vdev, 763 struct set_custom_aggr_size_params *param) 764 { 765 QDF_STATUS status; 766 struct wmi_unified *wmi_handle; 767 768 if (!vdev || !param) { 769 mlme_err("Invalid input"); 770 return QDF_STATUS_E_INVAL; 771 } 772 773 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 774 if (!wmi_handle) { 775 mlme_err("Failed to get WMI handle!"); 776 return QDF_STATUS_E_INVAL; 777 } 778 779 status = wmi_unified_vdev_set_custom_aggr_size_cmd_send(wmi_handle, 780 param); 781 782 return status; 783 } 784 785 static QDF_STATUS target_if_vdev_mgr_config_ratemask_cmd_send( 786 struct wlan_objmgr_vdev *vdev, 787 struct config_ratemask_params *param) 788 { 789 QDF_STATUS status; 790 struct wmi_unified *wmi_handle; 791 792 if (!vdev || !param) { 793 mlme_err("Invalid input"); 794 return QDF_STATUS_E_INVAL; 795 } 796 797 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 798 if (!wmi_handle) { 799 mlme_err("Failed to get WMI handle!"); 800 return QDF_STATUS_E_INVAL; 801 } 802 803 status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle, 804 param); 805 return status; 806 } 807 808 static QDF_STATUS target_if_vdev_mgr_peer_flush_tids_send( 809 struct wlan_objmgr_vdev *vdev, 810 struct peer_flush_params *param) 811 { 812 QDF_STATUS status; 813 struct wmi_unified *wmi_handle; 814 815 if (!vdev || !param) { 816 mlme_err("Invalid input"); 817 return QDF_STATUS_E_INVAL; 818 } 819 820 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 821 if (!wmi_handle) { 822 mlme_err("Failed to get WMI handle!"); 823 return QDF_STATUS_E_INVAL; 824 } 825 826 status = wmi_unified_peer_flush_tids_send(wmi_handle, param->peer_mac, 827 param); 828 829 return status; 830 } 831 832 static int32_t target_if_vdev_mgr_multi_vdev_restart_get_ref( 833 struct wlan_objmgr_pdev *pdev, 834 struct multiple_vdev_restart_params *param, 835 struct wlan_objmgr_vdev **vdev_list, 836 bool *vdev_timer_started) 837 { 838 struct wlan_objmgr_psoc *psoc; 839 struct wlan_objmgr_vdev *tvdev; 840 struct vdev_response_timer *vdev_rsp = NULL; 841 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 842 uint32_t vdev_idx; 843 int32_t last_vdev_idx = -1; 844 845 psoc = wlan_pdev_get_psoc(pdev); 846 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 847 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 848 mlme_err("VDEV_%d: No Rx Ops", vdev_idx); 849 return last_vdev_idx; 850 } 851 852 for (vdev_idx = 0; vdev_idx < param->num_vdevs ; vdev_idx++) { 853 vdev_list[vdev_idx] = wlan_objmgr_get_vdev_by_id_from_pdev( 854 pdev, 855 param->vdev_ids[vdev_idx], 856 WLAN_VDEV_TARGET_IF_ID); 857 tvdev = vdev_list[vdev_idx]; 858 if (!tvdev) { 859 mlme_err("VDEV_%d is NULL", vdev_idx); 860 return last_vdev_idx; 861 } 862 863 last_vdev_idx = vdev_idx; 864 vdev_rsp = 865 rx_ops->vdev_mgr_get_response_timer_info(tvdev); 866 if (!vdev_rsp) { 867 mlme_err("VDEV_%d: No Rx Ops", vdev_idx); 868 return last_vdev_idx; 869 } 870 871 target_if_vdev_mgr_rsp_timer_start(tvdev, vdev_rsp, 872 RESTART_RESPONSE_BIT); 873 vdev_timer_started[vdev_idx] = true; 874 } 875 876 return last_vdev_idx; 877 } 878 879 static void target_if_vdev_mgr_multi_vdev_restart_rel_ref( 880 struct wlan_objmgr_pdev *pdev, 881 struct wlan_objmgr_vdev **vdev_list, 882 bool *vdev_timer_started, 883 int32_t last_vdev_idx, 884 QDF_STATUS status) 885 { 886 struct wlan_objmgr_psoc *psoc; 887 struct wlan_objmgr_vdev *tvdev; 888 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 889 struct vdev_response_timer *vdev_rsp = NULL; 890 uint32_t vdev_idx; 891 892 psoc = wlan_pdev_get_psoc(pdev); 893 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 894 for (vdev_idx = 0; vdev_idx <= last_vdev_idx; vdev_idx++) { 895 tvdev = vdev_list[vdev_idx]; 896 if (QDF_IS_STATUS_ERROR(status)) { 897 vdev_rsp = 898 rx_ops->vdev_mgr_get_response_timer_info(tvdev); 899 if (vdev_rsp && vdev_timer_started[vdev_idx]) { 900 target_if_vdev_mgr_rsp_timer_stop( 901 tvdev, vdev_rsp, 902 RESTART_RESPONSE_BIT); 903 vdev_timer_started[vdev_idx] = false; 904 } 905 } 906 wlan_objmgr_vdev_release_ref(tvdev, 907 WLAN_VDEV_TARGET_IF_ID); 908 } 909 } 910 911 static QDF_STATUS target_if_vdev_mgr_multiple_vdev_restart_req_cmd( 912 struct wlan_objmgr_pdev *pdev, 913 struct multiple_vdev_restart_params *param) 914 { 915 QDF_STATUS status = QDF_STATUS_E_FAILURE; 916 struct wmi_unified *wmi_handle; 917 struct wlan_objmgr_psoc *psoc; 918 struct wlan_objmgr_vdev *vdev_list[WLAN_UMAC_PDEV_MAX_VDEVS] = {NULL}; 919 bool vdev_timer_started[WLAN_UMAC_PDEV_MAX_VDEVS] = {false}; 920 int32_t last_vdev_idx = -1; 921 922 if (!pdev || !param) { 923 mlme_err("Invalid input"); 924 return QDF_STATUS_E_INVAL; 925 } 926 927 psoc = wlan_pdev_get_psoc(pdev); 928 if (!psoc) { 929 mlme_err("PSOC is NULL"); 930 return QDF_STATUS_E_INVAL; 931 } 932 933 wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); 934 if (!wmi_handle) { 935 mlme_err("PDEV WMI Handle is NULL!"); 936 return QDF_STATUS_E_INVAL; 937 } 938 939 last_vdev_idx = target_if_vdev_mgr_multi_vdev_restart_get_ref( 940 pdev, param, 941 vdev_list, 942 vdev_timer_started); 943 if (last_vdev_idx < 0 || (last_vdev_idx != (param->num_vdevs - 1))) { 944 target_if_vdev_mgr_multi_vdev_restart_rel_ref( 945 pdev, vdev_list, 946 vdev_timer_started, 947 last_vdev_idx, 948 QDF_STATUS_E_FAILURE); 949 return QDF_STATUS_E_INVAL; 950 } 951 952 status = wmi_unified_send_multiple_vdev_restart_req_cmd(wmi_handle, 953 param); 954 955 target_if_vdev_mgr_multi_vdev_restart_rel_ref( 956 pdev, vdev_list, 957 vdev_timer_started, 958 last_vdev_idx, status); 959 960 return status; 961 } 962 963 static QDF_STATUS target_if_vdev_mgr_beacon_send( 964 struct wlan_objmgr_vdev *vdev, 965 struct beacon_params *param) 966 { 967 QDF_STATUS status; 968 struct wmi_unified *wmi_handle; 969 970 if (!vdev || !param) { 971 mlme_err("Invalid input"); 972 return QDF_STATUS_E_INVAL; 973 } 974 975 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 976 if (!wmi_handle) { 977 mlme_err("Failed to get WMI handle!"); 978 return QDF_STATUS_E_INVAL; 979 } 980 981 status = wmi_unified_beacon_send_cmd(wmi_handle, param); 982 983 return status; 984 } 985 986 static QDF_STATUS target_if_vdev_mgr_sta_ps_param_send( 987 struct wlan_objmgr_vdev *vdev, 988 struct sta_ps_params *param) 989 { 990 QDF_STATUS status; 991 struct wmi_unified *wmi_handle; 992 int param_id; 993 994 if (!vdev || !param) { 995 mlme_err("Invalid input"); 996 return QDF_STATUS_E_INVAL; 997 } 998 999 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 1000 if (!wmi_handle) { 1001 mlme_err("Failed to get WMI handle!"); 1002 return QDF_STATUS_E_INVAL; 1003 } 1004 1005 param_id = target_if_vdev_mlme_id_2_wmi(param->param_id); 1006 param->param_id = param_id; 1007 1008 status = wmi_unified_sta_ps_cmd_send(wmi_handle, param); 1009 1010 return status; 1011 } 1012 1013 static QDF_STATUS target_if_vdev_mgr_peer_delete_all_send( 1014 struct wlan_objmgr_vdev *vdev, 1015 struct peer_delete_all_params *param) 1016 { 1017 QDF_STATUS status; 1018 struct wmi_unified *wmi_handle; 1019 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 1020 struct wlan_objmgr_psoc *psoc; 1021 struct vdev_response_timer *vdev_rsp; 1022 uint8_t vdev_id; 1023 1024 if (!vdev || !param) { 1025 mlme_err("Invalid input"); 1026 return QDF_STATUS_E_INVAL; 1027 } 1028 1029 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 1030 if (!wmi_handle) { 1031 mlme_err("Failed to get WMI handle!"); 1032 return QDF_STATUS_E_INVAL; 1033 } 1034 1035 vdev_id = wlan_vdev_get_id(vdev); 1036 psoc = wlan_vdev_get_psoc(vdev); 1037 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 1038 1039 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 1040 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 1041 return QDF_STATUS_E_INVAL; 1042 } 1043 1044 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 1045 if (!vdev_rsp) { 1046 mlme_err("VDEV_%d: Invalid response structure", vdev_id); 1047 return QDF_STATUS_E_FAILURE; 1048 } 1049 1050 vdev_rsp->expire_time = PEER_DELETE_ALL_RESPONSE_TIMER; 1051 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, 1052 PEER_DELETE_ALL_RESPONSE_BIT); 1053 1054 status = wmi_unified_peer_delete_all_send(wmi_handle, param); 1055 if (QDF_IS_STATUS_ERROR(status)) { 1056 vdev_rsp->expire_time = 0; 1057 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 1058 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 1059 PEER_DELETE_ALL_RESPONSE_BIT); 1060 } 1061 1062 return status; 1063 } 1064 1065 QDF_STATUS 1066 target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 1067 { 1068 struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops; 1069 1070 if (!tx_ops) { 1071 mlme_err("Invalid input"); 1072 return QDF_STATUS_E_INVAL; 1073 } 1074 1075 mlme_tx_ops = &tx_ops->mops; 1076 if (!mlme_tx_ops) { 1077 mlme_err("No Tx Ops"); 1078 return QDF_STATUS_E_FAILURE; 1079 } 1080 1081 mlme_tx_ops->vdev_mlme_attach = 1082 target_if_vdev_mgr_register_event_handler; 1083 mlme_tx_ops->vdev_mlme_detach = 1084 target_if_vdev_mgr_unregister_event_handler; 1085 mlme_tx_ops->vdev_create_send = target_if_vdev_mgr_create_send; 1086 mlme_tx_ops->vdev_start_send = target_if_vdev_mgr_start_send; 1087 mlme_tx_ops->vdev_up_send = target_if_vdev_mgr_up_send; 1088 mlme_tx_ops->vdev_delete_send = target_if_vdev_mgr_delete_send; 1089 mlme_tx_ops->vdev_stop_send = target_if_vdev_mgr_stop_send; 1090 mlme_tx_ops->vdev_down_send = target_if_vdev_mgr_down_send; 1091 mlme_tx_ops->vdev_set_nac_rssi_send = 1092 target_if_vdev_mgr_set_nac_rssi_send; 1093 mlme_tx_ops->vdev_set_neighbour_rx_cmd_send = 1094 target_if_vdev_mgr_set_neighbour_rx_cmd_send; 1095 mlme_tx_ops->vdev_sifs_trigger_send = 1096 target_if_vdev_mgr_sifs_trigger_send; 1097 mlme_tx_ops->vdev_set_custom_aggr_size_cmd_send = 1098 target_if_vdev_mgr_set_custom_aggr_size_cmd_send; 1099 mlme_tx_ops->vdev_config_ratemask_cmd_send = 1100 target_if_vdev_mgr_config_ratemask_cmd_send; 1101 mlme_tx_ops->peer_flush_tids_send = 1102 target_if_vdev_mgr_peer_flush_tids_send; 1103 mlme_tx_ops->multiple_vdev_restart_req_cmd = 1104 target_if_vdev_mgr_multiple_vdev_restart_req_cmd; 1105 mlme_tx_ops->beacon_cmd_send = target_if_vdev_mgr_beacon_send; 1106 mlme_tx_ops->beacon_tmpl_send = target_if_vdev_mgr_beacon_tmpl_send; 1107 mlme_tx_ops->vdev_set_param_send = 1108 target_if_vdev_mgr_set_param_send; 1109 mlme_tx_ops->vdev_set_tx_rx_decap_type = 1110 target_if_vdev_set_tx_rx_decap_type; 1111 mlme_tx_ops->vdev_sta_ps_param_send = 1112 target_if_vdev_mgr_sta_ps_param_send; 1113 mlme_tx_ops->vdev_mgr_rsp_timer_init = 1114 target_if_vdev_mgr_rsp_timer_init; 1115 mlme_tx_ops->vdev_mgr_rsp_timer_mod = 1116 target_if_vdev_mgr_rsp_timer_mod; 1117 mlme_tx_ops->peer_delete_all_send = 1118 target_if_vdev_mgr_peer_delete_all_send; 1119 1120 return QDF_STATUS_SUCCESS; 1121 } 1122