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: wlan_vdev_mgr_tgt_if_tx_api.c 21 * 22 * This file provides definitions for mlme tgt_if APIs, which will 23 * further call target_if/mlme component using LMAC MLME txops 24 */ 25 #include <wlan_vdev_mgr_tgt_if_tx_api.h> 26 #include <target_if_vdev_mgr_tx_ops.h> 27 #include "include/wlan_vdev_mlme.h" 28 #include <wlan_mlme_dbg.h> 29 #include <cdp_txrx_cmn_struct.h> 30 #include <cdp_txrx_cmn.h> 31 #include <wlan_lmac_if_api.h> 32 #include <wlan_utility.h> 33 #include <cdp_txrx_ctrl.h> 34 #include <wlan_vdev_mlme_api.h> 35 #include <wlan_dfs_utils_api.h> 36 #include <wlan_vdev_mgr_utils_api.h> 37 #include <wlan_vdev_mgr_ucfg_api.h> 38 #include <wlan_vdev_mlme_main.h> 39 40 static inline struct wlan_lmac_if_mlme_tx_ops 41 *wlan_vdev_mlme_get_lmac_txops(struct wlan_objmgr_vdev *vdev) 42 { 43 struct wlan_objmgr_psoc *psoc; 44 45 psoc = wlan_vdev_get_psoc(vdev); 46 47 return target_if_vdev_mgr_get_tx_ops(psoc); 48 } 49 50 QDF_STATUS tgt_vdev_mgr_create_send( 51 struct vdev_mlme_obj *mlme_obj, 52 struct vdev_create_params *param) 53 { 54 QDF_STATUS status = QDF_STATUS_E_FAILURE; 55 struct wlan_lmac_if_mlme_tx_ops *txops; 56 struct wlan_objmgr_psoc *psoc; 57 struct wlan_objmgr_pdev *pdev; 58 struct wlan_objmgr_vdev *vdev; 59 ol_txrx_soc_handle soc_txrx_handle; 60 struct cdp_pdev *pdev_txrx_handle; 61 struct cdp_vdev *vdev_txrx_handle; 62 enum wlan_op_mode cdp_txrx_opmode; 63 uint32_t vdev_id; 64 uint8_t *vdev_addr; 65 struct vdev_response_timer *vdev_rsp; 66 67 if (!param) { 68 mlme_err("Invalid input"); 69 return QDF_STATUS_E_INVAL; 70 } 71 72 vdev = mlme_obj->vdev; 73 vdev_id = wlan_vdev_get_id(vdev); 74 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 75 if (!txops || !txops->vdev_create_send || 76 !txops->vdev_mgr_rsp_timer_init) { 77 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 78 return QDF_STATUS_E_INVAL; 79 } 80 81 status = txops->vdev_create_send(vdev, param); 82 if (QDF_IS_STATUS_SUCCESS(status)) { 83 vdev_rsp = &mlme_obj->vdev_rt; 84 txops->vdev_mgr_rsp_timer_init(vdev, &vdev_rsp->rsp_timer); 85 } else { 86 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 87 return status; 88 } 89 90 cdp_txrx_opmode = wlan_util_vdev_get_cdp_txrx_opmode(vdev); 91 vdev_addr = wlan_vdev_mlme_get_macaddr(vdev); 92 psoc = wlan_vdev_get_psoc(vdev); 93 pdev = wlan_vdev_get_pdev(vdev); 94 soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); 95 pdev_txrx_handle = wlan_pdev_get_dp_handle(pdev); 96 if (!soc_txrx_handle || !pdev_txrx_handle) 97 return QDF_STATUS_E_FAILURE; 98 99 vdev_txrx_handle = cdp_vdev_attach(soc_txrx_handle, 100 pdev_txrx_handle, 101 vdev_addr, vdev_id, 102 cdp_txrx_opmode); 103 if (!vdev_txrx_handle) 104 return QDF_STATUS_E_FAILURE; 105 106 wlan_vdev_set_dp_handle(vdev, vdev_txrx_handle); 107 108 return status; 109 } 110 111 QDF_STATUS tgt_vdev_mgr_create_complete(struct vdev_mlme_obj *vdev_mlme) 112 { 113 struct wlan_objmgr_vdev *vdev; 114 struct vdev_set_params param = {0}; 115 struct wlan_lmac_if_mlme_tx_ops *txops; 116 struct vdev_mlme_inactivity_params *inactivity; 117 uint8_t vdev_id; 118 QDF_STATUS status = QDF_STATUS_SUCCESS; 119 120 vdev = vdev_mlme->vdev; 121 vdev_id = wlan_vdev_get_id(vdev); 122 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 123 if (!txops || !txops->vdev_set_param_send) { 124 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 125 return QDF_STATUS_E_INVAL; 126 } 127 128 inactivity = &vdev_mlme->mgmt.inactivity_params; 129 130 param.vdev_id = vdev_id; 131 132 param.param_value = 133 inactivity->keepalive_min_idle_inactive_time_secs; 134 param.param_id = WLAN_MLME_CFG_MIN_IDLE_INACTIVE_TIME; 135 status = txops->vdev_set_param_send(vdev, ¶m); 136 if (QDF_IS_STATUS_ERROR(status)) 137 mlme_err("VDEV_%d: Failed to set min idle inactive time!", 138 vdev_id); 139 140 param.param_value = 141 inactivity->keepalive_max_idle_inactive_time_secs; 142 param.param_id = WLAN_MLME_CFG_MAX_IDLE_INACTIVE_TIME; 143 status = txops->vdev_set_param_send(vdev, ¶m); 144 if (QDF_IS_STATUS_ERROR(status)) 145 mlme_err("VDEV_%d: Failed to set max idle inactive time!", 146 vdev_id); 147 148 param.param_value = 149 inactivity->keepalive_max_unresponsive_time_secs; 150 param.param_id = WLAN_MLME_CFG_MAX_UNRESPONSIVE_INACTIVE_TIME; 151 status = txops->vdev_set_param_send(vdev, ¶m); 152 if (QDF_IS_STATUS_ERROR(status)) 153 mlme_err("VDEV_%d: Failed to set max unresponse inactive time!", 154 vdev_id); 155 156 return status; 157 } 158 159 QDF_STATUS tgt_vdev_mgr_start_send( 160 struct vdev_mlme_obj *mlme_obj, 161 struct vdev_start_params *param) 162 { 163 QDF_STATUS status; 164 struct wlan_lmac_if_mlme_tx_ops *txops; 165 struct wlan_objmgr_vdev *vdev; 166 uint8_t vdev_id; 167 168 if (!param) { 169 mlme_err("Invalid input"); 170 return QDF_STATUS_E_INVAL; 171 } 172 173 vdev = mlme_obj->vdev; 174 vdev_id = wlan_vdev_get_id(vdev); 175 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 176 if (!txops || !txops->vdev_start_send) { 177 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 178 return QDF_STATUS_E_INVAL; 179 } 180 181 status = txops->vdev_start_send(vdev, param); 182 if (QDF_IS_STATUS_ERROR(status)) 183 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 184 185 return status; 186 } 187 188 QDF_STATUS tgt_vdev_mgr_delete_send( 189 struct vdev_mlme_obj *mlme_obj, 190 struct vdev_delete_params *param) 191 { 192 QDF_STATUS status; 193 struct wlan_lmac_if_mlme_tx_ops *txops; 194 struct wlan_objmgr_vdev *vdev; 195 uint8_t vdev_id; 196 197 if (!param) { 198 mlme_err("Invalid input"); 199 return QDF_STATUS_E_INVAL; 200 } 201 202 vdev = mlme_obj->vdev; 203 vdev_id = wlan_vdev_get_id(vdev); 204 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 205 if (!txops || !txops->vdev_delete_send) { 206 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 207 return QDF_STATUS_E_INVAL; 208 } 209 210 status = txops->vdev_delete_send(vdev, param); 211 if (QDF_IS_STATUS_ERROR(status)) 212 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 213 214 return status; 215 } 216 217 QDF_STATUS tgt_vdev_mgr_peer_flush_tids_send( 218 struct vdev_mlme_obj *mlme_obj, 219 struct peer_flush_params *param) 220 { 221 QDF_STATUS status; 222 struct wlan_lmac_if_mlme_tx_ops *txops; 223 struct wlan_objmgr_vdev *vdev; 224 uint8_t vdev_id; 225 226 if (!param) { 227 mlme_err("Invalid input"); 228 return QDF_STATUS_E_INVAL; 229 } 230 231 vdev = mlme_obj->vdev; 232 vdev_id = wlan_vdev_get_id(vdev); 233 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 234 if (!txops || !txops->peer_flush_tids_send) { 235 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 236 return QDF_STATUS_E_INVAL; 237 } 238 239 status = txops->peer_flush_tids_send(vdev, param); 240 if (QDF_IS_STATUS_ERROR(status)) 241 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 242 243 return QDF_STATUS_SUCCESS; 244 } 245 246 QDF_STATUS tgt_vdev_mgr_stop_send( 247 struct vdev_mlme_obj *mlme_obj, 248 struct vdev_stop_params *param) 249 { 250 QDF_STATUS status; 251 struct wlan_lmac_if_mlme_tx_ops *txops; 252 struct wlan_objmgr_vdev *vdev; 253 uint8_t vdev_id; 254 255 if (!param) { 256 mlme_err("Invalid input"); 257 return QDF_STATUS_E_INVAL; 258 } 259 260 vdev = mlme_obj->vdev; 261 vdev_id = wlan_vdev_get_id(vdev); 262 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 263 if (!txops || !txops->vdev_stop_send) { 264 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 265 return QDF_STATUS_E_INVAL; 266 } 267 268 status = txops->vdev_stop_send(vdev, param); 269 if (QDF_IS_STATUS_ERROR(status)) 270 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 271 272 return status; 273 } 274 275 QDF_STATUS tgt_vdev_mgr_beacon_stop(struct vdev_mlme_obj *mlme_obj) 276 { 277 return QDF_STATUS_SUCCESS; 278 } 279 280 QDF_STATUS tgt_vdev_mgr_beacon_free(struct vdev_mlme_obj *mlme_obj) 281 { 282 return QDF_STATUS_SUCCESS; 283 } 284 285 QDF_STATUS tgt_vdev_mgr_up_send( 286 struct vdev_mlme_obj *mlme_obj, 287 struct vdev_up_params *param) 288 { 289 QDF_STATUS status; 290 struct wlan_lmac_if_mlme_tx_ops *txops; 291 ol_txrx_soc_handle soc_txrx_handle; 292 struct cdp_vdev *vdev_txrx_handle; 293 struct wlan_objmgr_psoc *psoc; 294 struct wlan_objmgr_vdev *vdev; 295 uint8_t vdev_id; 296 297 if (!param) { 298 mlme_err("Invalid input"); 299 return QDF_STATUS_E_INVAL; 300 } 301 302 vdev = mlme_obj->vdev; 303 vdev_id = wlan_vdev_get_id(vdev); 304 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 305 if (!txops || !txops->vdev_up_send) { 306 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 307 return QDF_STATUS_E_INVAL; 308 } 309 310 /* cdp set rx and tx decap type */ 311 psoc = wlan_vdev_get_psoc(vdev); 312 soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); 313 vdev_txrx_handle = wlan_vdev_get_dp_handle(vdev); 314 if (!soc_txrx_handle || !vdev_txrx_handle) 315 return QDF_STATUS_E_INVAL; 316 317 cdp_set_vdev_rx_decap_type(soc_txrx_handle, 318 (struct cdp_vdev *)vdev_txrx_handle, 319 mlme_obj->mgmt.generic.rx_decap_type); 320 cdp_set_tx_encap_type(soc_txrx_handle, 321 (struct cdp_vdev *)vdev_txrx_handle, 322 mlme_obj->mgmt.generic.tx_decap_type); 323 324 status = txops->vdev_up_send(vdev, param); 325 if (QDF_IS_STATUS_ERROR(status)) 326 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 327 328 return status; 329 } 330 331 QDF_STATUS tgt_vdev_mgr_down_send( 332 struct vdev_mlme_obj *mlme_obj, 333 struct vdev_down_params *param) 334 { 335 QDF_STATUS status; 336 struct wlan_lmac_if_mlme_tx_ops *txops; 337 struct wlan_objmgr_pdev *pdev; 338 struct wlan_objmgr_vdev *vdev; 339 enum QDF_OPMODE opmode; 340 uint8_t vdev_id; 341 342 if (!param) { 343 mlme_err("Invalid input"); 344 return QDF_STATUS_E_INVAL; 345 } 346 347 vdev = mlme_obj->vdev; 348 vdev_id = wlan_vdev_get_id(vdev); 349 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 350 if (!txops || !txops->vdev_down_send) { 351 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 352 return QDF_STATUS_E_INVAL; 353 } 354 355 pdev = wlan_vdev_get_pdev(vdev); 356 if (!pdev) { 357 mlme_err("PDEV is NULL"); 358 return QDF_STATUS_E_INVAL; 359 } 360 361 opmode = wlan_vdev_mlme_get_opmode(vdev); 362 if (wlan_util_is_vdev_active(pdev, WLAN_VDEV_TARGET_IF_ID) == 363 QDF_STATUS_SUCCESS) { 364 365 if (opmode == QDF_SAP_MODE) 366 utils_dfs_cancel_precac_timer(pdev); 367 } 368 369 status = txops->vdev_down_send(vdev, param); 370 if (QDF_IS_STATUS_ERROR(status)) 371 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 372 373 return status; 374 } 375 376 QDF_STATUS tgt_vdev_mgr_set_neighbour_rx_cmd_send( 377 struct vdev_mlme_obj *mlme_obj, 378 struct set_neighbour_rx_params *param) 379 { 380 return QDF_STATUS_SUCCESS; 381 } 382 383 QDF_STATUS tgt_vdev_mgr_nac_rssi_send( 384 struct vdev_mlme_obj *mlme_obj, 385 struct vdev_scan_nac_rssi_params *param) 386 { 387 return QDF_STATUS_SUCCESS; 388 } 389 390 QDF_STATUS tgt_vdev_mgr_sifs_trigger_send( 391 struct vdev_mlme_obj *mlme_obj, 392 struct sifs_trigger_param *param) 393 { 394 QDF_STATUS status = QDF_STATUS_E_FAILURE; 395 struct wlan_lmac_if_mlme_tx_ops *txops; 396 struct wlan_objmgr_vdev *vdev; 397 uint8_t vdev_id; 398 399 if (!param) { 400 mlme_err("Invalid input"); 401 return QDF_STATUS_E_INVAL; 402 } 403 404 vdev = mlme_obj->vdev; 405 vdev_id = wlan_vdev_get_id(vdev); 406 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 407 if (!txops || !txops->vdev_sifs_trigger_send) { 408 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 409 return QDF_STATUS_E_INVAL; 410 } 411 412 status = txops->vdev_sifs_trigger_send(vdev, param); 413 if (QDF_IS_STATUS_ERROR(status)) 414 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 415 416 return status; 417 } 418 419 QDF_STATUS tgt_vdev_mgr_set_custom_aggr_size_send( 420 struct vdev_mlme_obj *mlme_obj, 421 struct set_custom_aggr_size_params *param) 422 { 423 QDF_STATUS status; 424 struct wlan_lmac_if_mlme_tx_ops *txops; 425 struct wlan_objmgr_vdev *vdev; 426 uint8_t vdev_id; 427 428 if (!param) { 429 mlme_err("Invalid input"); 430 return QDF_STATUS_E_INVAL; 431 } 432 433 vdev = mlme_obj->vdev; 434 vdev_id = wlan_vdev_get_id(vdev); 435 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 436 if (!txops || !txops->vdev_set_custom_aggr_size_cmd_send) { 437 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 438 return QDF_STATUS_E_INVAL; 439 } 440 441 status = txops->vdev_set_custom_aggr_size_cmd_send(vdev, param); 442 if (QDF_IS_STATUS_ERROR(status)) 443 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 444 445 return status; 446 } 447 448 QDF_STATUS tgt_vdev_mgr_config_ratemask_cmd_send( 449 struct vdev_mlme_obj *mlme_obj, 450 struct config_ratemask_params *param) 451 { 452 QDF_STATUS status; 453 struct wlan_lmac_if_mlme_tx_ops *txops; 454 struct wlan_objmgr_vdev *vdev; 455 uint8_t vdev_id; 456 457 vdev = mlme_obj->vdev; 458 vdev_id = wlan_vdev_get_id(vdev); 459 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 460 if (!txops || !txops->vdev_config_ratemask_cmd_send) { 461 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 462 return QDF_STATUS_E_INVAL; 463 } 464 465 status = txops->vdev_config_ratemask_cmd_send(vdev, param); 466 if (QDF_IS_STATUS_ERROR(status)) 467 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 468 469 return status; 470 } 471 472 QDF_STATUS tgt_vdev_mgr_beacon_cmd_send( 473 struct vdev_mlme_obj *mlme_obj, 474 struct beacon_params *param) 475 { 476 return QDF_STATUS_SUCCESS; 477 } 478 479 QDF_STATUS tgt_vdev_mgr_beacon_tmpl_send( 480 struct vdev_mlme_obj *mlme_obj, 481 struct beacon_tmpl_params *param) 482 { 483 return QDF_STATUS_SUCCESS; 484 } 485 486 QDF_STATUS tgt_vdev_mgr_multiple_vdev_restart_send( 487 struct wlan_objmgr_pdev *pdev, 488 struct multiple_vdev_restart_params *param) 489 { 490 QDF_STATUS status = QDF_STATUS_SUCCESS; 491 struct wlan_lmac_if_mlme_tx_ops *txops; 492 struct wlan_objmgr_vdev *vdev; 493 494 if (!param) { 495 mlme_err("Invalid input"); 496 return QDF_STATUS_E_INVAL; 497 } 498 499 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, 500 param->vdev_ids[0], 501 WLAN_VDEV_TARGET_IF_ID); 502 if (vdev) { 503 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 504 if (!txops || !txops->multiple_vdev_restart_req_cmd) { 505 mlme_err("VDEV_%d: No Tx Ops", wlan_vdev_get_id(vdev)); 506 wlan_objmgr_vdev_release_ref(vdev, 507 WLAN_VDEV_TARGET_IF_ID); 508 return QDF_STATUS_E_INVAL; 509 } 510 511 status = txops->multiple_vdev_restart_req_cmd(pdev, param); 512 if (QDF_IS_STATUS_ERROR(status)) 513 mlme_err("Tx Ops Error: %d", status); 514 515 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 516 } 517 518 return status; 519 } 520 521 QDF_STATUS tgt_vdev_mgr_set_param_send( 522 struct vdev_mlme_obj *mlme_obj, 523 struct vdev_set_params *param) 524 { 525 QDF_STATUS status; 526 struct wlan_lmac_if_mlme_tx_ops *txops; 527 struct wlan_objmgr_vdev *vdev; 528 uint8_t vdev_id; 529 530 if (!param) { 531 mlme_err("Invalid input"); 532 return QDF_STATUS_E_INVAL; 533 } 534 535 vdev = mlme_obj->vdev; 536 vdev_id = wlan_vdev_get_id(vdev); 537 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 538 if (!txops || !txops->vdev_set_param_send) { 539 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 540 return QDF_STATUS_E_INVAL; 541 } 542 543 status = txops->vdev_set_param_send(vdev, param); 544 if (QDF_IS_STATUS_ERROR(status)) 545 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 546 547 return status; 548 } 549 550 QDF_STATUS tgt_vdev_mgr_sta_ps_param_send( 551 struct vdev_mlme_obj *mlme_obj, 552 struct sta_ps_params *param) 553 { 554 QDF_STATUS status; 555 struct wlan_lmac_if_mlme_tx_ops *txops; 556 struct wlan_objmgr_vdev *vdev; 557 uint8_t vdev_id; 558 559 if (!param) { 560 mlme_err("Invalid input"); 561 return QDF_STATUS_E_INVAL; 562 } 563 564 vdev = mlme_obj->vdev; 565 vdev_id = wlan_vdev_get_id(vdev); 566 txops = wlan_vdev_mlme_get_lmac_txops(vdev); 567 if (!txops || !txops->vdev_sta_ps_param_send) { 568 mlme_err("VDEV_%d: No Tx Ops", vdev_id); 569 return QDF_STATUS_E_INVAL; 570 } 571 572 status = txops->vdev_sta_ps_param_send(vdev, param); 573 if (QDF_IS_STATUS_ERROR(status)) 574 mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); 575 576 return status; 577 } 578