1 /* 2 * Copyright (c) 2017-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: API for interacting with target interface. 21 * 22 */ 23 24 #include "target_if.h" 25 #include "target_type.h" 26 #ifdef WLAN_ATF_ENABLE 27 #include "target_if_atf.h" 28 #endif 29 #ifdef WLAN_SA_API_ENABLE 30 #include "target_if_sa_api.h" 31 #endif 32 #ifdef WLAN_CFR_ENABLE 33 #include "target_if_cfr.h" 34 #endif 35 #ifdef WLAN_CONV_SPECTRAL_ENABLE 36 #include "target_if_spectral.h" 37 #endif 38 #include <target_if_reg.h> 39 #include <target_if_scan.h> 40 #include <target_if_ftm.h> 41 #ifdef DFS_COMPONENT_ENABLE 42 #include <target_if_dfs.h> 43 #endif 44 45 #ifdef CONVERGED_P2P_ENABLE 46 #include "target_if_p2p.h" 47 #endif 48 49 #ifdef WIFI_POS_CONVERGED 50 #include "target_if_wifi_pos.h" 51 #endif 52 53 #ifdef FEATURE_WLAN_TDLS 54 #include "target_if_tdls.h" 55 #endif 56 #ifdef QCA_SUPPORT_SON 57 #include <target_if_son.h> 58 #endif 59 #ifdef WLAN_OFFCHAN_TXRX_ENABLE 60 #include <target_if_offchan_txrx_api.h> 61 #endif 62 #ifdef WLAN_SUPPORT_GREEN_AP 63 #include <target_if_green_ap.h> 64 #endif 65 #include <init_deinit_lmac.h> 66 #include <service_ready_util.h> 67 68 #ifdef DIRECT_BUF_RX_ENABLE 69 #include <target_if_direct_buf_rx_api.h> 70 #endif 71 72 #ifdef WLAN_SUPPORT_FILS 73 #include <target_if_fd.h> 74 #endif 75 #include "qdf_module.h" 76 77 #include <target_if_cp_stats.h> 78 #ifdef CRYPTO_SET_KEY_CONVERGED 79 #include <target_if_crypto.h> 80 #endif 81 82 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 83 #include <target_if_vdev_mgr_tx_ops.h> 84 #endif 85 86 static struct target_if_ctx *g_target_if_ctx; 87 88 struct target_if_ctx *target_if_get_ctx() 89 { 90 return g_target_if_ctx; 91 } 92 93 struct wlan_objmgr_psoc *target_if_get_psoc_from_scn_hdl(void *scn_handle) 94 { 95 struct wlan_objmgr_psoc *psoc; 96 97 qdf_spin_lock_bh(&g_target_if_ctx->lock); 98 if (scn_handle && g_target_if_ctx->get_psoc_hdl_cb) 99 psoc = g_target_if_ctx->get_psoc_hdl_cb(scn_handle); 100 else 101 psoc = NULL; 102 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 103 104 return psoc; 105 } 106 107 struct wlan_objmgr_pdev *target_if_get_pdev_from_scn_hdl(void *scn_handle) 108 { 109 struct wlan_objmgr_pdev *pdev; 110 111 qdf_spin_lock_bh(&g_target_if_ctx->lock); 112 if (scn_handle && g_target_if_ctx->get_pdev_hdl_cb) 113 pdev = g_target_if_ctx->get_pdev_hdl_cb(scn_handle); 114 else 115 pdev = NULL; 116 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 117 118 return pdev; 119 } 120 121 #ifdef DIRECT_BUF_RX_ENABLE 122 static QDF_STATUS target_if_direct_buf_rx_init(void) 123 { 124 return direct_buf_rx_init(); 125 } 126 127 static QDF_STATUS target_if_direct_buf_rx_deinit(void) 128 { 129 return direct_buf_rx_deinit(); 130 } 131 #else 132 static QDF_STATUS target_if_direct_buf_rx_init(void) 133 { 134 return QDF_STATUS_SUCCESS; 135 } 136 137 static QDF_STATUS target_if_direct_buf_rx_deinit(void) 138 { 139 return QDF_STATUS_SUCCESS; 140 } 141 #endif /* DIRECT_BUF_RX_ENABLE */ 142 143 QDF_STATUS target_if_init(get_psoc_handle_callback psoc_hdl_cb) 144 { 145 g_target_if_ctx = qdf_mem_malloc(sizeof(*g_target_if_ctx)); 146 if (!g_target_if_ctx) { 147 QDF_ASSERT(0); 148 return QDF_STATUS_E_NOMEM; 149 } 150 151 qdf_spinlock_create(&g_target_if_ctx->lock); 152 153 qdf_spin_lock_bh(&g_target_if_ctx->lock); 154 g_target_if_ctx->magic = TGT_MAGIC; 155 g_target_if_ctx->get_psoc_hdl_cb = psoc_hdl_cb; 156 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 157 158 target_if_direct_buf_rx_init(); 159 160 return QDF_STATUS_SUCCESS; 161 } 162 163 QDF_STATUS target_if_deinit(void) 164 { 165 if (!g_target_if_ctx) { 166 QDF_ASSERT(0); 167 target_if_err("target if ctx is null"); 168 return QDF_STATUS_E_INVAL; 169 } 170 171 qdf_spin_lock_bh(&g_target_if_ctx->lock); 172 g_target_if_ctx->magic = 0; 173 g_target_if_ctx->get_psoc_hdl_cb = NULL; 174 g_target_if_ctx->get_pdev_hdl_cb = NULL; 175 g_target_if_ctx->service_ready_cb = NULL; 176 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 177 178 qdf_spinlock_destroy(&g_target_if_ctx->lock); 179 qdf_mem_free(g_target_if_ctx); 180 g_target_if_ctx = NULL; 181 182 target_if_direct_buf_rx_deinit(); 183 184 return QDF_STATUS_SUCCESS; 185 } 186 187 qdf_export_symbol(target_if_deinit); 188 189 QDF_STATUS target_if_store_pdev_target_if_ctx( 190 get_pdev_handle_callback pdev_hdl_cb) 191 { 192 if (!g_target_if_ctx) { 193 QDF_ASSERT(0); 194 target_if_err("target if ctx is null"); 195 return QDF_STATUS_E_INVAL; 196 } 197 198 qdf_spin_lock_bh(&g_target_if_ctx->lock); 199 g_target_if_ctx->get_pdev_hdl_cb = pdev_hdl_cb; 200 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 201 202 return QDF_STATUS_SUCCESS; 203 } 204 205 #ifndef WLAN_OFFCHAN_TXRX_ENABLE 206 static void target_if_offchan_txrx_ops_register( 207 struct wlan_lmac_if_tx_ops *tx_ops) 208 { 209 } 210 #endif /* WLAN_OFFCHAN_TXRX_ENABLE */ 211 212 #ifndef WLAN_ATF_ENABLE 213 static void target_if_atf_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 214 { 215 } 216 #endif /* WLAN_ATF_ENABLE */ 217 218 #ifndef WLAN_SA_API_ENABLE 219 static void target_if_sa_api_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 220 { 221 } 222 #endif /* WLAN_SA_API_ENABLE */ 223 224 #ifndef WLAN_CFR_ENABLE 225 static void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 226 { 227 } 228 #endif 229 230 #ifdef WLAN_SUPPORT_FILS 231 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 232 { 233 target_if_fd_register_tx_ops(tx_ops); 234 } 235 #else 236 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 237 { 238 } 239 #endif 240 241 #ifdef WIFI_POS_CONVERGED 242 static void target_if_wifi_pos_tx_ops_register( 243 struct wlan_lmac_if_tx_ops *tx_ops) 244 { 245 target_if_wifi_pos_register_tx_ops(tx_ops); 246 } 247 #else 248 static void target_if_wifi_pos_tx_ops_register( 249 struct wlan_lmac_if_tx_ops *tx_ops) 250 { 251 } 252 #endif 253 #ifdef QCA_SUPPORT_SON 254 static void target_if_son_tx_ops_register( 255 struct wlan_lmac_if_tx_ops *tx_ops) 256 { 257 target_if_son_register_tx_ops(tx_ops); 258 return; 259 } 260 #else 261 static void target_if_son_tx_ops_register( 262 struct wlan_lmac_if_tx_ops *tx_ops) 263 { 264 return; 265 } 266 #endif 267 268 #ifdef FEATURE_WLAN_TDLS 269 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 270 { 271 target_if_tdls_register_tx_ops(tx_ops); 272 } 273 #else 274 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 275 { 276 } 277 #endif /* FEATURE_WLAN_TDLS */ 278 279 #ifdef DFS_COMPONENT_ENABLE 280 static void target_if_dfs_tx_ops_register( 281 struct wlan_lmac_if_tx_ops *tx_ops) 282 { 283 target_if_register_dfs_tx_ops(tx_ops); 284 } 285 #else 286 static void target_if_dfs_tx_ops_register( 287 struct wlan_lmac_if_tx_ops *tx_ops) 288 { 289 } 290 #endif /* DFS_COMPONENT_ENABLE */ 291 292 #ifdef WLAN_CONV_SPECTRAL_ENABLE 293 static void target_if_sptrl_tx_ops_register( 294 struct wlan_lmac_if_tx_ops *tx_ops) 295 { 296 target_if_sptrl_register_tx_ops(tx_ops); 297 } 298 #else 299 static void target_if_sptrl_tx_ops_register( 300 struct wlan_lmac_if_tx_ops *tx_ops) 301 { 302 } 303 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 304 305 #ifdef DIRECT_BUF_RX_ENABLE 306 static void target_if_direct_buf_rx_tx_ops_register( 307 struct wlan_lmac_if_tx_ops *tx_ops) 308 { 309 target_if_direct_buf_rx_register_tx_ops(tx_ops); 310 } 311 #else 312 static void target_if_direct_buf_rx_tx_ops_register( 313 struct wlan_lmac_if_tx_ops *tx_ops) 314 { 315 } 316 #endif /* DIRECT_BUF_RX_ENABLE */ 317 318 #ifdef WLAN_SUPPORT_GREEN_AP 319 static QDF_STATUS target_if_green_ap_tx_ops_register( 320 struct wlan_lmac_if_tx_ops *tx_ops) 321 { 322 return target_if_register_green_ap_tx_ops(tx_ops); 323 } 324 #else 325 static QDF_STATUS target_if_green_ap_tx_ops_register( 326 struct wlan_lmac_if_tx_ops *tx_ops) 327 { 328 return QDF_STATUS_SUCCESS; 329 } 330 #endif /* WLAN_SUPPORT_GREEN_AP */ 331 #if defined(WLAN_CONV_CRYPTO_SUPPORTED) && defined(CRYPTO_SET_KEY_CONVERGED) 332 static void target_if_crypto_tx_ops_register( 333 struct wlan_lmac_if_tx_ops *tx_ops) 334 { 335 target_if_crypto_register_tx_ops(tx_ops); 336 } 337 #else 338 static inline void target_if_crypto_tx_ops_register( 339 struct wlan_lmac_if_tx_ops *tx_ops) 340 { 341 } 342 #endif 343 344 static void target_if_target_tx_ops_register( 345 struct wlan_lmac_if_tx_ops *tx_ops) 346 { 347 struct wlan_lmac_if_target_tx_ops *target_tx_ops; 348 349 if (!tx_ops) { 350 target_if_err("invalid tx_ops"); 351 return; 352 } 353 354 target_tx_ops = &tx_ops->target_tx_ops; 355 356 target_tx_ops->tgt_is_tgt_type_ar900b = 357 target_is_tgt_type_ar900b; 358 359 target_tx_ops->tgt_is_tgt_type_ipq4019 = 360 target_is_tgt_type_ipq4019; 361 362 target_tx_ops->tgt_is_tgt_type_qca9984 = 363 target_is_tgt_type_qca9984; 364 365 target_tx_ops->tgt_is_tgt_type_qca9888 = 366 target_is_tgt_type_qca9888; 367 368 target_tx_ops->tgt_get_tgt_type = 369 lmac_get_tgt_type; 370 371 target_tx_ops->tgt_get_tgt_version = 372 lmac_get_tgt_version; 373 374 target_tx_ops->tgt_get_tgt_revision = 375 lmac_get_tgt_revision; 376 } 377 378 static QDF_STATUS 379 target_if_cp_stats_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 380 { 381 return target_if_cp_stats_register_tx_ops(tx_ops); 382 } 383 384 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 385 static QDF_STATUS 386 target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 387 { 388 return target_if_vdev_mgr_register_tx_ops(tx_ops); 389 } 390 #else 391 static QDF_STATUS 392 target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 393 { 394 return QDF_STATUS_SUCCESS; 395 } 396 #endif 397 398 #ifdef QCA_WIFI_FTM 399 static 400 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 401 { 402 target_if_ftm_register_tx_ops(tx_ops); 403 } 404 #else 405 static 406 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 407 { 408 } 409 #endif 410 static 411 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 412 { 413 /* call regulatory callback to register tx ops */ 414 target_if_register_regulatory_tx_ops(tx_ops); 415 416 /* call umac callback to register legacy tx ops */ 417 wlan_lmac_if_umac_tx_ops_register(tx_ops); 418 419 /* Register scan tx ops */ 420 target_if_scan_tx_ops_register(tx_ops); 421 422 target_if_atf_tx_ops_register(tx_ops); 423 424 target_if_sa_api_tx_ops_register(tx_ops); 425 426 target_if_cfr_tx_ops_register(tx_ops); 427 428 target_if_wifi_pos_tx_ops_register(tx_ops); 429 430 target_if_dfs_tx_ops_register(tx_ops); 431 432 target_if_son_tx_ops_register(tx_ops); 433 434 target_if_tdls_tx_ops_register(tx_ops); 435 436 target_if_fd_tx_ops_register(tx_ops); 437 438 target_if_target_tx_ops_register(tx_ops); 439 440 target_if_offchan_txrx_ops_register(tx_ops); 441 442 target_if_green_ap_tx_ops_register(tx_ops); 443 444 target_if_ftm_tx_ops_register(tx_ops); 445 446 target_if_cp_stats_tx_ops_register(tx_ops); 447 448 target_if_crypto_tx_ops_register(tx_ops); 449 450 target_if_vdev_mgr_tx_ops_register(tx_ops); 451 452 /* Converged UMAC components to register their TX-ops here */ 453 return QDF_STATUS_SUCCESS; 454 } 455 456 QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 457 { 458 /* Converged UMAC components to register their TX-ops */ 459 target_if_register_umac_tx_ops(tx_ops); 460 461 /* Components parallel to UMAC to register their TX-ops here */ 462 target_if_sptrl_tx_ops_register(tx_ops); 463 464 /* Register direct buffer rx component tx ops here */ 465 target_if_direct_buf_rx_tx_ops_register(tx_ops); 466 467 #ifdef CONVERGED_P2P_ENABLE 468 /* Converged UMAC components to register P2P TX-ops */ 469 target_if_p2p_register_tx_ops(tx_ops); 470 #endif 471 472 return QDF_STATUS_SUCCESS; 473 } 474 qdf_export_symbol(target_if_register_tx_ops); 475 476 wmi_legacy_service_ready_callback 477 target_if_get_psoc_legacy_service_ready_cb(void) 478 { 479 wmi_legacy_service_ready_callback service_ready_cb; 480 481 qdf_spin_lock_bh(&g_target_if_ctx->lock); 482 if (g_target_if_ctx->service_ready_cb) 483 service_ready_cb = g_target_if_ctx->service_ready_cb; 484 else 485 service_ready_cb = NULL; 486 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 487 488 return service_ready_cb; 489 } 490 qdf_export_symbol(target_if_get_psoc_legacy_service_ready_cb); 491 492 QDF_STATUS target_if_register_legacy_service_ready_cb( 493 wmi_legacy_service_ready_callback service_ready_cb) 494 { 495 qdf_spin_lock_bh(&g_target_if_ctx->lock); 496 g_target_if_ctx->service_ready_cb = service_ready_cb; 497 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 498 499 return QDF_STATUS_SUCCESS; 500 } 501 qdf_export_symbol(target_if_register_legacy_service_ready_cb); 502 503 QDF_STATUS target_if_alloc_pdev_tgt_info(struct wlan_objmgr_pdev *pdev) 504 { 505 struct target_pdev_info *tgt_pdev_info; 506 507 if (!pdev) { 508 target_if_err("pdev is null"); 509 return QDF_STATUS_E_INVAL; 510 } 511 512 tgt_pdev_info = qdf_mem_malloc(sizeof(*tgt_pdev_info)); 513 514 if (!tgt_pdev_info) 515 return QDF_STATUS_E_NOMEM; 516 517 wlan_pdev_set_tgt_if_handle(pdev, tgt_pdev_info); 518 519 return QDF_STATUS_SUCCESS; 520 } 521 522 QDF_STATUS target_if_free_pdev_tgt_info(struct wlan_objmgr_pdev *pdev) 523 { 524 struct target_pdev_info *tgt_pdev_info; 525 526 if (!pdev) { 527 target_if_err("pdev is null"); 528 return QDF_STATUS_E_INVAL; 529 } 530 531 tgt_pdev_info = wlan_pdev_get_tgt_if_handle(pdev); 532 533 wlan_pdev_set_tgt_if_handle(pdev, NULL); 534 535 qdf_mem_free(tgt_pdev_info); 536 537 return QDF_STATUS_SUCCESS; 538 } 539 540 QDF_STATUS target_if_alloc_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) 541 { 542 struct target_psoc_info *tgt_psoc_info; 543 544 if (!psoc) { 545 target_if_err("psoc is null"); 546 return QDF_STATUS_E_INVAL; 547 } 548 549 tgt_psoc_info = qdf_mem_malloc(sizeof(*tgt_psoc_info)); 550 551 if (!tgt_psoc_info) 552 return QDF_STATUS_E_NOMEM; 553 554 wlan_psoc_set_tgt_if_handle(psoc, tgt_psoc_info); 555 target_psoc_set_preferred_hw_mode(tgt_psoc_info, WMI_HOST_HW_MODE_MAX); 556 557 qdf_event_create(&tgt_psoc_info->info.event); 558 559 return QDF_STATUS_SUCCESS; 560 } 561 562 QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) 563 { 564 struct target_psoc_info *tgt_psoc_info; 565 struct wlan_psoc_host_service_ext_param *ext_param; 566 567 if (!psoc) { 568 target_if_err("psoc is null"); 569 return QDF_STATUS_E_INVAL; 570 } 571 572 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 573 574 ext_param = target_psoc_get_service_ext_param(tgt_psoc_info); 575 if (!ext_param) { 576 target_if_err("tgt_psoc_info is NULL"); 577 return QDF_STATUS_E_INVAL; 578 } 579 init_deinit_chainmask_table_free(ext_param); 580 init_deinit_dbr_ring_cap_free(tgt_psoc_info); 581 init_deinit_spectral_scaling_params_free(tgt_psoc_info); 582 583 qdf_event_destroy(&tgt_psoc_info->info.event); 584 585 wlan_psoc_set_tgt_if_handle(psoc, NULL); 586 587 qdf_mem_free(tgt_psoc_info); 588 589 return QDF_STATUS_SUCCESS; 590 } 591 592 bool target_is_tgt_type_ar900b(uint32_t target_type) 593 { 594 return target_type == TARGET_TYPE_AR900B; 595 } 596 597 bool target_is_tgt_type_ipq4019(uint32_t target_type) 598 { 599 return target_type == TARGET_TYPE_IPQ4019; 600 } 601 602 bool target_is_tgt_type_qca9984(uint32_t target_type) 603 { 604 return target_type == TARGET_TYPE_QCA9984; 605 } 606 607 bool target_is_tgt_type_qca9888(uint32_t target_type) 608 { 609 return target_type == TARGET_TYPE_QCA9888; 610 } 611