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