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.h> 32 #include <target_type.h> 33 #include <wlan_mlme_dbg.h> 34 #include <wlan_vdev_mgr_tgt_if_tx_defs.h> 35 #include <wlan_vdev_mgr_utils_api.h> 36 #include <wlan_cmn.h> 37 38 static QDF_STATUS target_if_vdev_mgr_register_event_handler( 39 struct wlan_objmgr_psoc *psoc) 40 { 41 return target_if_vdev_mgr_wmi_event_register(psoc); 42 } 43 44 static QDF_STATUS target_if_vdev_mgr_unregister_event_handler( 45 struct wlan_objmgr_psoc *psoc) 46 { 47 return target_if_vdev_mgr_wmi_event_unregister(psoc); 48 } 49 50 static QDF_STATUS target_if_vdev_mgr_rsp_timer_mod( 51 struct wlan_objmgr_vdev *vdev, 52 struct vdev_response_timer *vdev_rsp, 53 int mseconds) 54 { 55 if (!vdev || !vdev_rsp) { 56 mlme_err("Invalid input"); 57 return QDF_STATUS_E_FAILURE; 58 } 59 60 qdf_timer_mod(&vdev_rsp->rsp_timer, mseconds); 61 return QDF_STATUS_SUCCESS; 62 } 63 64 static QDF_STATUS target_if_vdev_mgr_rsp_timer_stop( 65 struct wlan_objmgr_vdev *vdev, 66 struct vdev_response_timer *vdev_rsp, 67 uint8_t clear_bit) 68 { 69 if (qdf_atomic_test_and_clear_bit(clear_bit, &vdev_rsp->rsp_status)) { 70 /* 71 * This is triggered from timer expiry case only for 72 * which timer stop is not required 73 */ 74 if (vdev_rsp->timer_status != QDF_STATUS_E_TIMEOUT) 75 qdf_timer_stop(&vdev_rsp->rsp_timer); 76 77 /* 78 * Releasing reference taken at the time of 79 * starting response timer 80 */ 81 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 82 return QDF_STATUS_SUCCESS; 83 } 84 85 return QDF_STATUS_E_FAILURE; 86 } 87 88 static QDF_STATUS target_if_vdev_mgr_rsp_timer_start( 89 struct wlan_objmgr_vdev *vdev, 90 struct vdev_response_timer *vdev_rsp, 91 uint8_t set_bit) 92 { 93 uint8_t vdev_id; 94 uint8_t rsp_pos; 95 96 vdev_id = wlan_vdev_get_id(vdev); 97 /* it is expected to be only one command with FW at a time */ 98 for (rsp_pos = START_RESPONSE_BIT; rsp_pos <= RESPONSE_BIT_MAX; 99 rsp_pos++) { 100 if (rsp_pos != set_bit) { 101 if (qdf_atomic_test_bit(rsp_pos, 102 &vdev_rsp->rsp_status)) { 103 mlme_err("VDEV_%d: Response bit is set %d", 104 vdev_id, vdev_rsp->rsp_status); 105 QDF_ASSERT(0); 106 } 107 } 108 } 109 110 if (qdf_atomic_test_and_set_bit(set_bit, &vdev_rsp->rsp_status)) { 111 mlme_err("VDEV_%d: Response bit is set %d", 112 vdev_id, vdev_rsp->rsp_status); 113 QDF_ASSERT(0); 114 } 115 116 /* reference taken for timer start, will be released with stop */ 117 wlan_objmgr_vdev_get_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 118 qdf_timer_start(&vdev_rsp->rsp_timer, vdev_rsp->expire_time); 119 120 return QDF_STATUS_SUCCESS; 121 } 122 123 static QDF_STATUS target_if_vdev_mgr_rsp_timer_init( 124 struct wlan_objmgr_vdev *vdev, 125 qdf_timer_t *rsp_timer) 126 { 127 if (!vdev || !rsp_timer) { 128 mlme_err("Invalid input"); 129 return QDF_STATUS_E_INVAL; 130 } 131 132 qdf_timer_init(NULL, rsp_timer, 133 target_if_vdev_mgr_rsp_timer_mgmt_cb, 134 (void *)vdev, QDF_TIMER_TYPE_WAKE_APPS); 135 mlme_debug("VDEV_%d: Response timer initialized", 136 wlan_vdev_get_id(vdev)); 137 138 return QDF_STATUS_SUCCESS; 139 } 140 141 static QDF_STATUS target_if_vdev_mgr_rsp_timer_deinit( 142 struct wlan_objmgr_vdev *vdev, 143 qdf_timer_t *rsp_timer) 144 { 145 if (!vdev || !rsp_timer) { 146 mlme_err("Invalid input"); 147 return QDF_STATUS_E_INVAL; 148 } 149 150 qdf_timer_free(rsp_timer); 151 mlme_debug("VDEV_%d: Response timer free", wlan_vdev_get_id(vdev)); 152 153 return QDF_STATUS_SUCCESS; 154 } 155 156 struct wmi_unified 157 *target_if_vdev_mgr_wmi_handle_get(struct wlan_objmgr_vdev *vdev) 158 { 159 struct wlan_objmgr_pdev *pdev; 160 struct wmi_unified *wmi_handle; 161 162 pdev = wlan_vdev_get_pdev(vdev); 163 if (!pdev) { 164 mlme_err("PDEV is NULL"); 165 return NULL; 166 } 167 168 wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); 169 if (!wmi_handle) { 170 mlme_err("wmi_handle is null"); 171 return NULL; 172 } 173 174 return wmi_handle; 175 } 176 177 static bool target_if_check_is_pre_lithium( 178 struct wlan_objmgr_psoc *psoc) 179 { 180 if (lmac_get_tgt_type(psoc) < TARGET_TYPE_QCA8074) 181 return true; 182 else 183 return false; 184 } 185 186 static inline uint32_t 187 target_if_vdev_mlme_id_2_wmi(uint32_t cfg_id) 188 { 189 int wmi_id; 190 191 switch (cfg_id) { 192 case WLAN_MLME_CFG_DTIM_PERIOD: 193 wmi_id = wmi_vdev_param_dtim_period; 194 break; 195 case WLAN_MLME_CFG_SLOT_TIME: 196 wmi_id = wmi_vdev_param_slot_time; 197 break; 198 case WLAN_MLME_CFG_PROTECTION_MODE: 199 wmi_id = wmi_vdev_param_protection_mode; 200 break; 201 case WLAN_MLME_CFG_BEACON_INTERVAL: 202 wmi_id = wmi_vdev_param_beacon_interval; 203 break; 204 case WLAN_MLME_CFG_LDPC: 205 wmi_id = wmi_vdev_param_ldpc; 206 break; 207 case WLAN_MLME_CFG_NSS: 208 wmi_id = wmi_vdev_param_nss; 209 break; 210 case WLAN_MLME_CFG_SUBFER: 211 case WLAN_MLME_CFG_MUBFER: 212 case WLAN_MLME_CFG_SUBFEE: 213 case WLAN_MLME_CFG_MUBFEE: 214 case WLAN_MLME_CFG_IMLICIT_BF: 215 case WLAN_MLME_CFG_SOUNDING_DIM: 216 case WLAN_MLME_CFG_TXBF_CAPS: 217 wmi_id = wmi_vdev_param_txbf; 218 break; 219 case WLAN_MLME_CFG_HE_OPS: 220 wmi_id = wmi_vdev_param_set_heop; 221 break; 222 case WLAN_MLME_CFG_RTS_THRESHOLD: 223 wmi_id = wmi_vdev_param_rts_threshold; 224 break; 225 case WLAN_MLME_CFG_FRAG_THRESHOLD: 226 wmi_id = wmi_vdev_param_fragmentation_threshold; 227 break; 228 case WLAN_MLME_CFG_DROP_UNENCRY: 229 wmi_id = wmi_vdev_param_drop_unencry; 230 break; 231 case WLAN_MLME_CFG_TX_POWER: 232 wmi_id = wmi_vdev_param_tx_power; 233 break; 234 case WLAN_MLME_CFG_AMPDU: 235 wmi_id = wmi_vdev_param_amsdu_subframe_size_per_ac; 236 break; 237 case WLAN_MLME_CFG_AMSDU: 238 wmi_id = wmi_vdev_param_amsdu_subframe_size_per_ac; 239 break; 240 case WLAN_MLME_CFG_MIN_IDLE_INACTIVE_TIME: 241 wmi_id = 242 wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs; 243 break; 244 case WLAN_MLME_CFG_MAX_IDLE_INACTIVE_TIME: 245 wmi_id = 246 wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs; 247 break; 248 case WLAN_MLME_CFG_MAX_UNRESPONSIVE_INACTIVE_TIME: 249 wmi_id = 250 wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs; 251 break; 252 case WLAN_MLME_CFG_UAPSD: 253 wmi_id = WMI_HOST_STA_PS_PARAM_UAPSD; 254 break; 255 case WLAN_MLME_CFG_BCN_TX_RATE: 256 wmi_id = wmi_vdev_param_beacon_rate; 257 break; 258 default: 259 wmi_id = cfg_id; 260 break; 261 } 262 263 return wmi_id; 264 } 265 266 static QDF_STATUS target_if_vdev_mgr_set_param_send( 267 struct wlan_objmgr_vdev *vdev, 268 struct vdev_set_params *param) 269 { 270 QDF_STATUS status; 271 struct wmi_unified *wmi_handle; 272 int param_id; 273 274 if (!vdev || !param) { 275 mlme_err("Invalid input"); 276 return QDF_STATUS_E_INVAL; 277 } 278 279 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 280 if (!wmi_handle) { 281 mlme_err("Failed to get WMI handle!"); 282 return QDF_STATUS_E_INVAL; 283 } 284 param_id = target_if_vdev_mlme_id_2_wmi(param->param_id); 285 param->param_id = param_id; 286 287 status = wmi_unified_vdev_set_param_send(wmi_handle, param); 288 289 return status; 290 } 291 292 static QDF_STATUS target_if_vdev_mgr_create_send( 293 struct wlan_objmgr_vdev *vdev, 294 struct vdev_create_params *param) 295 { 296 QDF_STATUS status; 297 struct wmi_unified *wmi_handle; 298 uint8_t vap_addr[QDF_MAC_ADDR_SIZE] = {0}; 299 300 if (!vdev || !param) { 301 mlme_err("Invalid input"); 302 return QDF_STATUS_E_INVAL; 303 } 304 305 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 306 if (!wmi_handle) { 307 mlme_err("Failed to get WMI handle!"); 308 return QDF_STATUS_E_INVAL; 309 } 310 311 WLAN_ADDR_COPY(vap_addr, wlan_vdev_mlme_get_macaddr(vdev)); 312 status = wmi_unified_vdev_create_send(wmi_handle, vap_addr, 313 param); 314 315 return status; 316 } 317 318 static QDF_STATUS target_if_vdev_mgr_start_send( 319 struct wlan_objmgr_vdev *vdev, 320 struct vdev_start_params *param) 321 { 322 QDF_STATUS status; 323 struct wmi_unified *wmi_handle; 324 struct wlan_objmgr_psoc *psoc; 325 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 326 struct vdev_response_timer *vdev_rsp; 327 uint8_t vdev_id; 328 329 if (!vdev || !param) { 330 mlme_err("Invalid input"); 331 return QDF_STATUS_E_INVAL; 332 } 333 334 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 335 if (!wmi_handle) { 336 mlme_err("Failed to get WMI handle!"); 337 return QDF_STATUS_E_INVAL; 338 } 339 340 vdev_id = wlan_vdev_get_id(vdev); 341 psoc = wlan_vdev_get_psoc(vdev); 342 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 343 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 344 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 345 return QDF_STATUS_E_INVAL; 346 } 347 348 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 349 if (vdev_rsp) { 350 vdev_rsp->expire_time = START_RESPONSE_TIMER; 351 if (param->is_restart) 352 target_if_vdev_mgr_rsp_timer_start( 353 vdev, vdev_rsp, 354 RESTART_RESPONSE_BIT); 355 else 356 target_if_vdev_mgr_rsp_timer_start( 357 vdev, vdev_rsp, 358 START_RESPONSE_BIT); 359 } 360 361 status = wmi_unified_vdev_start_send(wmi_handle, param); 362 if (QDF_IS_STATUS_ERROR(status) && vdev_rsp) { 363 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 364 vdev_rsp->expire_time = 0; 365 if (param->is_restart) 366 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 367 RESTART_RESPONSE_BIT); 368 else 369 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 370 START_RESPONSE_BIT); 371 } 372 373 return status; 374 } 375 376 static QDF_STATUS target_if_vdev_mgr_delete_response_send( 377 struct wlan_objmgr_vdev *vdev, 378 struct wlan_lmac_if_mlme_rx_ops *rx_ops) 379 { 380 QDF_STATUS status = QDF_STATUS_SUCCESS; 381 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 382 struct vdev_delete_response rsp = {0}; 383 384 rsp.vdev_id = wlan_vdev_get_id(vdev); 385 status = rx_ops->vdev_mgr_delete_response(psoc, &rsp); 386 387 return status; 388 } 389 390 static QDF_STATUS target_if_vdev_mgr_delete_send( 391 struct wlan_objmgr_vdev *vdev, 392 struct vdev_delete_params *param) 393 { 394 QDF_STATUS status; 395 struct wlan_objmgr_psoc *psoc; 396 struct wmi_unified *wmi_handle; 397 struct vdev_response_timer *vdev_rsp; 398 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 399 uint8_t vdev_id; 400 401 if (!vdev || !param) { 402 mlme_err("Invalid input"); 403 return QDF_STATUS_E_INVAL; 404 } 405 406 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 407 if (!wmi_handle) { 408 mlme_err("Failed to get WMI handle!"); 409 return QDF_STATUS_E_INVAL; 410 } 411 412 vdev_id = wlan_vdev_get_id(vdev); 413 psoc = wlan_vdev_get_psoc(vdev); 414 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 415 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 416 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 417 return QDF_STATUS_E_INVAL; 418 } 419 420 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 421 if (vdev_rsp) { 422 vdev_rsp->expire_time = DELETE_RESPONSE_TIMER; 423 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, 424 DELETE_RESPONSE_BIT); 425 } 426 427 status = wmi_unified_vdev_delete_send(wmi_handle, param->vdev_id); 428 if (QDF_IS_STATUS_SUCCESS(status)) { 429 /* 430 * pre lithium chipsets doesn't have a delete response 431 * hence fake response is sent 432 */ 433 if (target_if_check_is_pre_lithium(psoc) || 434 wlan_psoc_nif_feat_cap_get(psoc, 435 WLAN_SOC_F_TESTMODE_ENABLE)) 436 target_if_vdev_mgr_delete_response_send(vdev, rx_ops); 437 } else { 438 if (vdev_rsp) { 439 vdev_rsp->expire_time = 0; 440 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 441 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 442 DELETE_RESPONSE_BIT); 443 } 444 } 445 446 return status; 447 } 448 449 static QDF_STATUS target_if_vdev_mgr_stop_send( 450 struct wlan_objmgr_vdev *vdev, 451 struct vdev_stop_params *param) 452 { 453 QDF_STATUS status; 454 struct wmi_unified *wmi_handle; 455 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 456 struct wlan_objmgr_psoc *psoc; 457 struct vdev_response_timer *vdev_rsp; 458 uint8_t vdev_id; 459 460 if (!vdev || !param) { 461 mlme_err("Invalid input"); 462 return QDF_STATUS_E_INVAL; 463 } 464 465 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 466 if (!wmi_handle) { 467 mlme_err("Failed to get WMI handle!"); 468 return QDF_STATUS_E_INVAL; 469 } 470 471 vdev_id = wlan_vdev_get_id(vdev); 472 psoc = wlan_vdev_get_psoc(vdev); 473 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 474 475 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 476 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 477 return QDF_STATUS_E_INVAL; 478 } 479 480 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 481 if (vdev_rsp) { 482 vdev_rsp->expire_time = STOP_RESPONSE_TIMER; 483 target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, 484 STOP_RESPONSE_BIT); 485 } 486 487 status = wmi_unified_vdev_stop_send(wmi_handle, param->vdev_id); 488 if (QDF_IS_STATUS_ERROR(status) && vdev_rsp) { 489 vdev_rsp->expire_time = 0; 490 vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; 491 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 492 STOP_RESPONSE_BIT); 493 } 494 495 return status; 496 } 497 498 static QDF_STATUS target_if_vdev_mgr_down_send( 499 struct wlan_objmgr_vdev *vdev, 500 struct vdev_down_params *param) 501 { 502 QDF_STATUS status; 503 struct wmi_unified *wmi_handle; 504 505 if (!vdev || !param) { 506 mlme_err("Invalid input"); 507 return QDF_STATUS_E_INVAL; 508 } 509 510 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 511 if (!wmi_handle) { 512 mlme_err("Failed to get WMI handle!"); 513 return QDF_STATUS_E_INVAL; 514 } 515 516 status = wmi_unified_vdev_down_send(wmi_handle, param->vdev_id); 517 518 return status; 519 } 520 521 static QDF_STATUS target_if_vdev_mgr_up_send( 522 struct wlan_objmgr_vdev *vdev, 523 struct vdev_up_params *param) 524 { 525 QDF_STATUS status; 526 struct wmi_unified *wmi_handle; 527 struct vdev_set_params sparam = {0}; 528 uint8_t bssid[QDF_MAC_ADDR_SIZE]; 529 uint8_t vdev_id; 530 531 if (!vdev || !param) { 532 mlme_err("Invalid input"); 533 return QDF_STATUS_E_INVAL; 534 } 535 536 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 537 if (!wmi_handle) { 538 mlme_err("Failed to get WMI handle!"); 539 return QDF_STATUS_E_INVAL; 540 } 541 542 vdev_id = wlan_vdev_get_id(vdev); 543 sparam.vdev_id = vdev_id; 544 545 sparam.param_id = WLAN_MLME_CFG_BEACON_INTERVAL; 546 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_BEACON_INTERVAL, 547 &sparam.param_value); 548 status = target_if_vdev_mgr_set_param_send(vdev, &sparam); 549 if (QDF_IS_STATUS_ERROR(status)) 550 mlme_err("VDEV_%d: Failed to set beacon interval!", vdev_id); 551 552 sparam.param_id = WLAN_MLME_CFG_SUBFEE; 553 wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SUBFEE, 554 &sparam.param_value); 555 status = target_if_vdev_mgr_set_param_send(vdev, &sparam); 556 if (QDF_IS_STATUS_ERROR(status)) 557 mlme_err("VDEV_%d: Failed to set SU beam formee!", vdev_id); 558 559 ucfg_wlan_vdev_mgr_get_param_bssid(vdev, bssid); 560 561 status = wmi_unified_vdev_up_send(wmi_handle, bssid, param); 562 563 return status; 564 } 565 566 static QDF_STATUS target_if_vdev_mgr_beacon_tmpl_send( 567 struct wlan_objmgr_vdev *vdev, 568 struct beacon_tmpl_params *param) 569 { 570 QDF_STATUS status; 571 struct wmi_unified *wmi_handle; 572 573 if (!vdev || !param) { 574 mlme_err("Invalid input"); 575 return QDF_STATUS_E_INVAL; 576 } 577 578 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 579 if (!wmi_handle) { 580 mlme_err("Failed to get WMI handle!"); 581 return QDF_STATUS_E_INVAL; 582 } 583 584 status = wmi_unified_beacon_tmpl_send_cmd(wmi_handle, param); 585 return status; 586 } 587 588 static QDF_STATUS target_if_vdev_mgr_set_nac_rssi_send( 589 struct wlan_objmgr_vdev *vdev, 590 struct vdev_scan_nac_rssi_params *param) 591 { 592 QDF_STATUS status; 593 struct wmi_unified *wmi_handle; 594 595 if (!vdev || !param) { 596 mlme_err("Invalid input"); 597 return QDF_STATUS_E_INVAL; 598 } 599 600 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 601 if (!wmi_handle) { 602 mlme_err("Failed to get WMI handle!"); 603 return QDF_STATUS_E_INVAL; 604 } 605 606 status = wmi_unified_vdev_set_nac_rssi_send(wmi_handle, param); 607 608 return status; 609 } 610 611 static QDF_STATUS target_if_vdev_mgr_set_neighbour_rx_cmd_send( 612 struct wlan_objmgr_vdev *vdev, 613 struct set_neighbour_rx_params *param, 614 uint8_t *mac) 615 { 616 QDF_STATUS status; 617 struct wmi_unified *wmi_handle; 618 619 if (!vdev || !param) { 620 mlme_err("Invalid input"); 621 return QDF_STATUS_E_INVAL; 622 } 623 624 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 625 if (!wmi_handle) { 626 mlme_err("Failed to get WMI handle!"); 627 return QDF_STATUS_E_INVAL; 628 } 629 630 status = wmi_unified_vdev_set_neighbour_rx_cmd_send(wmi_handle, 631 mac, param); 632 633 return status; 634 } 635 636 static QDF_STATUS target_if_vdev_mgr_sifs_trigger_send( 637 struct wlan_objmgr_vdev *vdev, 638 struct sifs_trigger_param *param) 639 { 640 QDF_STATUS status; 641 struct wmi_unified *wmi_handle; 642 643 if (!vdev || !param) { 644 mlme_err("Invalid input"); 645 return QDF_STATUS_E_INVAL; 646 } 647 648 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 649 if (!wmi_handle) { 650 mlme_err("Failed to get WMI handle!"); 651 return QDF_STATUS_E_INVAL; 652 } 653 654 status = wmi_unified_sifs_trigger_send(wmi_handle, param); 655 656 return status; 657 } 658 659 static QDF_STATUS target_if_vdev_mgr_set_custom_aggr_size_cmd_send( 660 struct wlan_objmgr_vdev *vdev, 661 struct set_custom_aggr_size_params *param) 662 { 663 QDF_STATUS status; 664 struct wmi_unified *wmi_handle; 665 666 if (!vdev || !param) { 667 mlme_err("Invalid input"); 668 return QDF_STATUS_E_INVAL; 669 } 670 671 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 672 if (!wmi_handle) { 673 mlme_err("Failed to get WMI handle!"); 674 return QDF_STATUS_E_INVAL; 675 } 676 677 status = wmi_unified_vdev_set_custom_aggr_size_cmd_send(wmi_handle, 678 param); 679 680 return status; 681 } 682 683 static QDF_STATUS target_if_vdev_mgr_config_ratemask_cmd_send( 684 struct wlan_objmgr_vdev *vdev, 685 struct config_ratemask_params *param) 686 { 687 QDF_STATUS status; 688 struct wmi_unified *wmi_handle; 689 690 if (!vdev || !param) { 691 mlme_err("Invalid input"); 692 return QDF_STATUS_E_INVAL; 693 } 694 695 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 696 if (!wmi_handle) { 697 mlme_err("Failed to get WMI handle!"); 698 return QDF_STATUS_E_INVAL; 699 } 700 701 status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle, 702 param); 703 704 return status; 705 } 706 707 static QDF_STATUS target_if_vdev_mgr_peer_flush_tids_send( 708 struct wlan_objmgr_vdev *vdev, 709 struct peer_flush_params *param) 710 { 711 QDF_STATUS status; 712 struct wmi_unified *wmi_handle; 713 714 if (!vdev || !param) { 715 mlme_err("Invalid input"); 716 return QDF_STATUS_E_INVAL; 717 } 718 719 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 720 if (!wmi_handle) { 721 mlme_err("Failed to get WMI handle!"); 722 return QDF_STATUS_E_INVAL; 723 } 724 725 status = wmi_unified_peer_flush_tids_send(wmi_handle, param->peer_mac, 726 param); 727 728 return status; 729 } 730 731 static QDF_STATUS target_if_vdev_mgr_multiple_vdev_restart_req_cmd( 732 struct wlan_objmgr_pdev *pdev, 733 struct multiple_vdev_restart_params *param) 734 { 735 QDF_STATUS status; 736 struct wmi_unified *wmi_handle; 737 struct wlan_objmgr_psoc *psoc; 738 struct vdev_response_timer *vdev_rsp = NULL; 739 struct wlan_objmgr_vdev *vdev; 740 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 741 uint32_t vdev_id; 742 743 if (!pdev || !param) { 744 mlme_err("Invalid input"); 745 return QDF_STATUS_E_INVAL; 746 } 747 748 psoc = wlan_pdev_get_psoc(pdev); 749 if (!psoc) { 750 mlme_err("PSOC is NULL"); 751 return QDF_STATUS_E_INVAL; 752 } 753 754 wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); 755 if (!wmi_handle) { 756 mlme_err("PDEV WMI Handle is NULL!"); 757 return QDF_STATUS_E_INVAL; 758 } 759 760 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 761 if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { 762 mlme_err("VDEV_%d: No Rx Ops", vdev_id); 763 return QDF_STATUS_E_INVAL; 764 } 765 766 for (vdev_id = 0; vdev_id < param->num_vdevs ; vdev_id++) { 767 vdev = wlan_objmgr_get_vdev_by_id_from_pdev( 768 pdev, 769 param->vdev_ids[vdev_id], 770 WLAN_VDEV_TARGET_IF_ID); 771 if (vdev) { 772 vdev_rsp = 773 rx_ops->vdev_mgr_get_response_timer_info(vdev); 774 if (vdev_rsp) 775 target_if_vdev_mgr_rsp_timer_start( 776 vdev, vdev_rsp, 777 RESTART_RESPONSE_BIT); 778 wlan_objmgr_vdev_release_ref(vdev, 779 WLAN_VDEV_TARGET_IF_ID); 780 } 781 } 782 783 status = wmi_unified_send_multiple_vdev_restart_req_cmd(wmi_handle, 784 param); 785 if (QDF_IS_STATUS_ERROR(status)) { 786 for (vdev_id = 0; vdev_id < param->num_vdevs ; vdev_id++) { 787 vdev = wlan_objmgr_get_vdev_by_id_from_pdev( 788 pdev, 789 param->vdev_ids[vdev_id], 790 WLAN_VDEV_TARGET_IF_ID); 791 if (vdev) { 792 vdev_rsp = 793 rx_ops->vdev_mgr_get_response_timer_info(vdev); 794 if (vdev_rsp) 795 target_if_vdev_mgr_rsp_timer_stop( 796 vdev, vdev_rsp, 797 RESTART_RESPONSE_BIT); 798 wlan_objmgr_vdev_release_ref( 799 vdev, 800 WLAN_VDEV_TARGET_IF_ID); 801 } 802 } 803 } 804 805 return status; 806 } 807 808 static QDF_STATUS target_if_vdev_mgr_beacon_send( 809 struct wlan_objmgr_vdev *vdev, 810 struct beacon_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_beacon_send_cmd(wmi_handle, param); 827 828 return status; 829 } 830 831 static QDF_STATUS target_if_vdev_mgr_sta_ps_param_send( 832 struct wlan_objmgr_vdev *vdev, 833 struct sta_ps_params *param) 834 { 835 QDF_STATUS status; 836 struct wmi_unified *wmi_handle; 837 int param_id; 838 839 if (!vdev || !param) { 840 mlme_err("Invalid input"); 841 return QDF_STATUS_E_INVAL; 842 } 843 844 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 845 if (!wmi_handle) { 846 mlme_err("Failed to get WMI handle!"); 847 return QDF_STATUS_E_INVAL; 848 } 849 850 param_id = target_if_vdev_mlme_id_2_wmi(param->param_id); 851 param->param_id = param_id; 852 853 status = wmi_unified_sta_ps_cmd_send(wmi_handle, param); 854 855 return status; 856 } 857 858 QDF_STATUS 859 target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 860 { 861 struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops; 862 863 if (!tx_ops) { 864 mlme_err("Invalid input"); 865 return QDF_STATUS_E_INVAL; 866 } 867 868 mlme_tx_ops = &tx_ops->mops; 869 if (!mlme_tx_ops) { 870 mlme_err("No Tx Ops"); 871 return QDF_STATUS_E_FAILURE; 872 } 873 874 mlme_tx_ops->vdev_mlme_attach = 875 target_if_vdev_mgr_register_event_handler; 876 mlme_tx_ops->vdev_mlme_detach = 877 target_if_vdev_mgr_unregister_event_handler; 878 mlme_tx_ops->vdev_create_send = target_if_vdev_mgr_create_send; 879 mlme_tx_ops->vdev_start_send = target_if_vdev_mgr_start_send; 880 mlme_tx_ops->vdev_up_send = target_if_vdev_mgr_up_send; 881 mlme_tx_ops->vdev_delete_send = target_if_vdev_mgr_delete_send; 882 mlme_tx_ops->vdev_stop_send = target_if_vdev_mgr_stop_send; 883 mlme_tx_ops->vdev_down_send = target_if_vdev_mgr_down_send; 884 mlme_tx_ops->vdev_set_nac_rssi_send = 885 target_if_vdev_mgr_set_nac_rssi_send; 886 mlme_tx_ops->vdev_set_neighbour_rx_cmd_send = 887 target_if_vdev_mgr_set_neighbour_rx_cmd_send; 888 mlme_tx_ops->vdev_sifs_trigger_send = 889 target_if_vdev_mgr_sifs_trigger_send; 890 mlme_tx_ops->vdev_set_custom_aggr_size_cmd_send = 891 target_if_vdev_mgr_set_custom_aggr_size_cmd_send; 892 mlme_tx_ops->vdev_config_ratemask_cmd_send = 893 target_if_vdev_mgr_config_ratemask_cmd_send; 894 mlme_tx_ops->peer_flush_tids_send = 895 target_if_vdev_mgr_peer_flush_tids_send; 896 mlme_tx_ops->multiple_vdev_restart_req_cmd = 897 target_if_vdev_mgr_multiple_vdev_restart_req_cmd; 898 mlme_tx_ops->beacon_cmd_send = target_if_vdev_mgr_beacon_send; 899 mlme_tx_ops->beacon_tmpl_send = target_if_vdev_mgr_beacon_tmpl_send; 900 mlme_tx_ops->vdev_set_param_send = 901 target_if_vdev_mgr_set_param_send; 902 mlme_tx_ops->vdev_sta_ps_param_send = 903 target_if_vdev_mgr_sta_ps_param_send; 904 mlme_tx_ops->target_is_pre_lithium = 905 target_if_check_is_pre_lithium; 906 mlme_tx_ops->vdev_mgr_rsp_timer_init = 907 target_if_vdev_mgr_rsp_timer_init; 908 mlme_tx_ops->vdev_mgr_rsp_timer_deinit = 909 target_if_vdev_mgr_rsp_timer_deinit; 910 mlme_tx_ops->vdev_mgr_rsp_timer_mod = 911 target_if_vdev_mgr_rsp_timer_mod; 912 mlme_tx_ops->vdev_mgr_rsp_timer_stop = 913 target_if_vdev_mgr_rsp_timer_stop; 914 915 return QDF_STATUS_SUCCESS; 916 } 917