1 /* 2 * Copyright (c) 2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <wlan_utility.h> 21 #include <dp_internal.h> 22 #include <dp_htt.h> 23 #include "dp_be.h" 24 #include "dp_be_tx.h" 25 #include "dp_be_rx.h" 26 #if !defined(DISABLE_MON_CONFIG) && defined(QCA_MONITOR_2_0_SUPPORT) 27 #include "dp_mon_2.0.h" 28 #endif 29 #include <hal_be_api.h> 30 31 /* Generic AST entry aging timer value */ 32 #define DP_AST_AGING_TIMER_DEFAULT_MS 5000 33 34 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) 35 #define DP_TX_VDEV_ID_CHECK_ENABLE 0 36 37 static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = { 38 {.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_BE_WBM_SW0_BM_ID, .for_ipa = 0}, 39 {1, 4, HAL_BE_WBM_SW4_BM_ID, 0}, 40 {2, 2, HAL_BE_WBM_SW2_BM_ID, 0}, 41 #ifdef QCA_WIFI_KIWI_V2 42 {3, 5, HAL_BE_WBM_SW5_BM_ID, 0}, 43 {4, 6, HAL_BE_WBM_SW6_BM_ID, 0} 44 #else 45 {3, 6, HAL_BE_WBM_SW5_BM_ID, 0}, 46 {4, 7, HAL_BE_WBM_SW6_BM_ID, 0} 47 #endif 48 }; 49 #else 50 #define DP_TX_VDEV_ID_CHECK_ENABLE 1 51 52 static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = { 53 {.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_BE_WBM_SW0_BM_ID, .for_ipa = 0}, 54 {1, 1, HAL_BE_WBM_SW1_BM_ID, 0}, 55 {2, 2, HAL_BE_WBM_SW2_BM_ID, 0}, 56 {3, 3, HAL_BE_WBM_SW3_BM_ID, 0}, 57 {4, 4, HAL_BE_WBM_SW4_BM_ID, 0} 58 }; 59 #endif 60 61 static void dp_soc_cfg_attach_be(struct dp_soc *soc) 62 { 63 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 64 65 wlan_cfg_set_rx_rel_ring_id(soc_cfg_ctx, WBM2SW_REL_ERR_RING_NUM); 66 67 soc->wlan_cfg_ctx->tcl_wbm_map_array = g_tcl_wbm_map_array; 68 69 /* this is used only when dmac mode is enabled */ 70 soc->num_rx_refill_buf_rings = 1; 71 72 soc->wlan_cfg_ctx->notify_frame_support = 73 DP_MARK_NOTIFY_FRAME_SUPPORT; 74 } 75 76 qdf_size_t dp_get_context_size_be(enum dp_context_type context_type) 77 { 78 switch (context_type) { 79 case DP_CONTEXT_TYPE_SOC: 80 return sizeof(struct dp_soc_be); 81 case DP_CONTEXT_TYPE_PDEV: 82 return sizeof(struct dp_pdev_be); 83 case DP_CONTEXT_TYPE_VDEV: 84 return sizeof(struct dp_vdev_be); 85 case DP_CONTEXT_TYPE_PEER: 86 return sizeof(struct dp_peer_be); 87 default: 88 return 0; 89 } 90 } 91 92 #if !defined(DISABLE_MON_CONFIG) && defined(QCA_MONITOR_2_0_SUPPORT) 93 qdf_size_t dp_mon_get_context_size_be(enum dp_context_type context_type) 94 { 95 switch (context_type) { 96 case DP_CONTEXT_TYPE_MON_SOC: 97 return sizeof(struct dp_mon_soc_be); 98 case DP_CONTEXT_TYPE_MON_PDEV: 99 return sizeof(struct dp_mon_pdev_be); 100 default: 101 return 0; 102 } 103 } 104 #else 105 qdf_size_t dp_mon_get_context_size_be(enum dp_context_type context_type) 106 { 107 switch (context_type) { 108 case DP_CONTEXT_TYPE_MON_SOC: 109 return sizeof(struct dp_mon_soc); 110 case DP_CONTEXT_TYPE_MON_PDEV: 111 return sizeof(struct dp_mon_pdev); 112 default: 113 return 0; 114 } 115 } 116 #endif 117 118 #ifdef DP_FEATURE_HW_COOKIE_CONVERSION 119 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) 120 /** 121 * dp_cc_wbm_sw_en_cfg() - configure HW cookie conversion enablement 122 per wbm2sw ring 123 * @cc_cfg: HAL HW cookie conversion configuration structure pointer 124 * 125 * Return: None 126 */ 127 static inline 128 void dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config *cc_cfg) 129 { 130 cc_cfg->wbm2sw6_cc_en = 1; 131 cc_cfg->wbm2sw5_cc_en = 1; 132 cc_cfg->wbm2sw4_cc_en = 1; 133 cc_cfg->wbm2sw3_cc_en = 1; 134 cc_cfg->wbm2sw2_cc_en = 1; 135 /* disable wbm2sw1 hw cc as it's for FW */ 136 cc_cfg->wbm2sw1_cc_en = 0; 137 cc_cfg->wbm2sw0_cc_en = 1; 138 cc_cfg->wbm2fw_cc_en = 0; 139 } 140 #else 141 static inline 142 void dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config *cc_cfg) 143 { 144 cc_cfg->wbm2sw6_cc_en = 1; 145 cc_cfg->wbm2sw5_cc_en = 1; 146 cc_cfg->wbm2sw4_cc_en = 1; 147 cc_cfg->wbm2sw3_cc_en = 1; 148 cc_cfg->wbm2sw2_cc_en = 1; 149 cc_cfg->wbm2sw1_cc_en = 1; 150 cc_cfg->wbm2sw0_cc_en = 1; 151 cc_cfg->wbm2fw_cc_en = 0; 152 } 153 #endif 154 155 #if defined(WLAN_SUPPORT_RX_FISA) 156 static QDF_STATUS dp_fisa_fst_cmem_addr_init(struct dp_soc *soc) 157 { 158 dp_info("cmem base 0x%llx, total size 0x%llx avail_size 0x%llx", 159 soc->cmem_base, soc->cmem_total_size, soc->cmem_avail_size); 160 /* get CMEM for cookie conversion */ 161 if (soc->cmem_avail_size < DP_CMEM_FST_SIZE) { 162 dp_err("cmem_size 0x%llx bytes < 16K", soc->cmem_avail_size); 163 return QDF_STATUS_E_NOMEM; 164 } 165 166 soc->fst_cmem_size = DP_CMEM_FST_SIZE; 167 168 soc->fst_cmem_base = soc->cmem_base + 169 (soc->cmem_total_size - soc->cmem_avail_size); 170 soc->cmem_avail_size -= soc->fst_cmem_size; 171 172 dp_info("fst_cmem_base 0x%llx, fst_cmem_size 0x%llx", 173 soc->fst_cmem_base, soc->fst_cmem_size); 174 175 return QDF_STATUS_SUCCESS; 176 } 177 #else /* !WLAN_SUPPORT_RX_FISA */ 178 static QDF_STATUS dp_fisa_fst_cmem_addr_init(struct dp_soc *soc) 179 { 180 return QDF_STATUS_SUCCESS; 181 } 182 #endif 183 184 /** 185 * dp_cc_reg_cfg_init() - initialize and configure HW cookie 186 conversion register 187 * @soc: SOC handle 188 * @is_4k_align: page address 4k alignd 189 * 190 * Return: None 191 */ 192 static void dp_cc_reg_cfg_init(struct dp_soc *soc, 193 bool is_4k_align) 194 { 195 struct hal_hw_cc_config cc_cfg = { 0 }; 196 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 197 198 if (soc->cdp_soc.ol_ops->get_con_mode && 199 soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_FTM_MODE) 200 return; 201 202 if (!soc->wlan_cfg_ctx->hw_cc_enabled) { 203 dp_info("INI skip HW CC register setting"); 204 return; 205 } 206 207 cc_cfg.lut_base_addr_31_0 = be_soc->cc_cmem_base; 208 cc_cfg.cc_global_en = true; 209 cc_cfg.page_4k_align = is_4k_align; 210 cc_cfg.cookie_offset_msb = DP_CC_DESC_ID_SPT_VA_OS_MSB; 211 cc_cfg.cookie_page_msb = DP_CC_DESC_ID_PPT_PAGE_OS_MSB; 212 /* 36th bit should be 1 then HW know this is CMEM address */ 213 cc_cfg.lut_base_addr_39_32 = 0x10; 214 215 cc_cfg.error_path_cookie_conv_en = true; 216 cc_cfg.release_path_cookie_conv_en = true; 217 dp_cc_wbm_sw_en_cfg(&cc_cfg); 218 219 hal_cookie_conversion_reg_cfg_be(soc->hal_soc, &cc_cfg); 220 } 221 222 /** 223 * dp_hw_cc_cmem_write() - DP wrapper function for CMEM buffer writing 224 * @hal_soc_hdl: HAL SOC handle 225 * @offset: CMEM address 226 * @value: value to write 227 * 228 * Return: None. 229 */ 230 static inline void dp_hw_cc_cmem_write(hal_soc_handle_t hal_soc_hdl, 231 uint32_t offset, 232 uint32_t value) 233 { 234 hal_cmem_write(hal_soc_hdl, offset, value); 235 } 236 237 /** 238 * dp_hw_cc_cmem_addr_init() - Check and initialize CMEM base address for 239 HW cookie conversion 240 * @soc: SOC handle 241 * @cc_ctx: cookie conversion context pointer 242 * 243 * Return: 0 in case of success, else error value 244 */ 245 static inline QDF_STATUS dp_hw_cc_cmem_addr_init(struct dp_soc *soc) 246 { 247 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 248 249 dp_info("cmem base 0x%llx, total size 0x%llx avail_size 0x%llx", 250 soc->cmem_base, soc->cmem_total_size, soc->cmem_avail_size); 251 /* get CMEM for cookie conversion */ 252 if (soc->cmem_avail_size < DP_CC_PPT_MEM_SIZE) { 253 dp_err("cmem_size 0x%llx bytes < 4K", soc->cmem_avail_size); 254 return QDF_STATUS_E_RESOURCES; 255 } 256 be_soc->cc_cmem_base = (uint32_t)(soc->cmem_base + 257 DP_CC_MEM_OFFSET_IN_CMEM); 258 259 soc->cmem_avail_size -= DP_CC_PPT_MEM_SIZE; 260 261 dp_info("cc_cmem_base 0x%x, cmem_avail_size 0x%llx", 262 be_soc->cc_cmem_base, soc->cmem_avail_size); 263 return QDF_STATUS_SUCCESS; 264 } 265 266 static QDF_STATUS dp_get_cmem_allocation(struct dp_soc *soc, 267 uint8_t for_feature) 268 { 269 QDF_STATUS status = QDF_STATUS_E_NOMEM; 270 271 switch (for_feature) { 272 case COOKIE_CONVERSION: 273 status = dp_hw_cc_cmem_addr_init(soc); 274 break; 275 case FISA_FST: 276 status = dp_fisa_fst_cmem_addr_init(soc); 277 break; 278 default: 279 dp_err("Invalid CMEM request"); 280 } 281 282 return status; 283 } 284 285 #else 286 287 static inline void dp_cc_reg_cfg_init(struct dp_soc *soc, 288 bool is_4k_align) {} 289 290 static inline void dp_hw_cc_cmem_write(hal_soc_handle_t hal_soc_hdl, 291 uint32_t offset, 292 uint32_t value) 293 { } 294 295 static inline QDF_STATUS dp_hw_cc_cmem_addr_init(struct dp_soc *soc) 296 { 297 return QDF_STATUS_SUCCESS; 298 } 299 300 static QDF_STATUS dp_get_cmem_allocation(struct dp_soc *soc, 301 uint8_t for_feature) 302 { 303 return QDF_STATUS_SUCCESS; 304 } 305 306 #endif 307 308 QDF_STATUS 309 dp_hw_cookie_conversion_attach(struct dp_soc_be *be_soc, 310 struct dp_hw_cookie_conversion_t *cc_ctx, 311 uint32_t num_descs, 312 enum dp_desc_type desc_type, 313 uint8_t desc_pool_id) 314 { 315 struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc); 316 uint32_t num_spt_pages, i = 0; 317 struct dp_spt_page_desc *spt_desc; 318 struct qdf_mem_dma_page_t *dma_page; 319 uint8_t chip_id; 320 321 /* estimate how many SPT DDR pages needed */ 322 num_spt_pages = num_descs / DP_CC_SPT_PAGE_MAX_ENTRIES; 323 num_spt_pages = num_spt_pages <= DP_CC_PPT_MAX_ENTRIES ? 324 num_spt_pages : DP_CC_PPT_MAX_ENTRIES; 325 dp_info("num_spt_pages needed %d", num_spt_pages); 326 327 dp_desc_multi_pages_mem_alloc(soc, DP_HW_CC_SPT_PAGE_TYPE, 328 &cc_ctx->page_pool, qdf_page_size, 329 num_spt_pages, 0, false); 330 if (!cc_ctx->page_pool.dma_pages) { 331 dp_err("spt ddr pages allocation failed"); 332 return QDF_STATUS_E_RESOURCES; 333 } 334 cc_ctx->page_desc_base = qdf_mem_malloc( 335 num_spt_pages * sizeof(struct dp_spt_page_desc)); 336 if (!cc_ctx->page_desc_base) { 337 dp_err("spt page descs allocation failed"); 338 goto fail_0; 339 } 340 341 chip_id = dp_mlo_get_chip_id(soc); 342 cc_ctx->cmem_offset = dp_desc_pool_get_cmem_base(chip_id, desc_pool_id, 343 desc_type); 344 345 /* initial page desc */ 346 spt_desc = cc_ctx->page_desc_base; 347 dma_page = cc_ctx->page_pool.dma_pages; 348 while (i < num_spt_pages) { 349 /* check if page address 4K aligned */ 350 if (qdf_unlikely(dma_page[i].page_p_addr & 0xFFF)) { 351 dp_err("non-4k aligned pages addr %pK", 352 (void *)dma_page[i].page_p_addr); 353 goto fail_1; 354 } 355 356 spt_desc[i].page_v_addr = 357 dma_page[i].page_v_addr_start; 358 spt_desc[i].page_p_addr = 359 dma_page[i].page_p_addr; 360 i++; 361 } 362 363 cc_ctx->total_page_num = num_spt_pages; 364 qdf_spinlock_create(&cc_ctx->cc_lock); 365 366 return QDF_STATUS_SUCCESS; 367 fail_1: 368 qdf_mem_free(cc_ctx->page_desc_base); 369 fail_0: 370 dp_desc_multi_pages_mem_free(soc, DP_HW_CC_SPT_PAGE_TYPE, 371 &cc_ctx->page_pool, 0, false); 372 373 return QDF_STATUS_E_FAILURE; 374 } 375 376 QDF_STATUS 377 dp_hw_cookie_conversion_detach(struct dp_soc_be *be_soc, 378 struct dp_hw_cookie_conversion_t *cc_ctx) 379 { 380 struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc); 381 382 qdf_mem_free(cc_ctx->page_desc_base); 383 dp_desc_multi_pages_mem_free(soc, DP_HW_CC_SPT_PAGE_TYPE, 384 &cc_ctx->page_pool, 0, false); 385 qdf_spinlock_destroy(&cc_ctx->cc_lock); 386 387 return QDF_STATUS_SUCCESS; 388 } 389 390 QDF_STATUS 391 dp_hw_cookie_conversion_init(struct dp_soc_be *be_soc, 392 struct dp_hw_cookie_conversion_t *cc_ctx) 393 { 394 struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc); 395 uint32_t i = 0; 396 struct dp_spt_page_desc *spt_desc; 397 uint32_t ppt_index; 398 uint32_t ppt_id_start; 399 400 if (!cc_ctx->total_page_num) { 401 dp_err("total page num is 0"); 402 return QDF_STATUS_E_INVAL; 403 } 404 405 ppt_id_start = DP_CMEM_OFFSET_TO_PPT_ID(cc_ctx->cmem_offset); 406 spt_desc = cc_ctx->page_desc_base; 407 while (i < cc_ctx->total_page_num) { 408 /* write page PA to CMEM */ 409 dp_hw_cc_cmem_write(soc->hal_soc, 410 (cc_ctx->cmem_offset + be_soc->cc_cmem_base 411 + (i * DP_CC_PPT_ENTRY_SIZE_4K_ALIGNED)), 412 (spt_desc[i].page_p_addr >> 413 DP_CC_PPT_ENTRY_HW_APEND_BITS_4K_ALIGNED)); 414 415 ppt_index = ppt_id_start + i; 416 417 if (ppt_index >= DP_CC_PPT_MAX_ENTRIES) 418 qdf_assert_always(0); 419 420 spt_desc[i].ppt_index = ppt_index; 421 422 be_soc->page_desc_base[ppt_index].page_v_addr = 423 spt_desc[i].page_v_addr; 424 i++; 425 } 426 return QDF_STATUS_SUCCESS; 427 } 428 429 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) 430 QDF_STATUS 431 dp_hw_cookie_conversion_deinit(struct dp_soc_be *be_soc, 432 struct dp_hw_cookie_conversion_t *cc_ctx) 433 { 434 uint32_t ppt_index; 435 struct dp_spt_page_desc *spt_desc; 436 int i = 0; 437 438 spt_desc = cc_ctx->page_desc_base; 439 while (i < cc_ctx->total_page_num) { 440 ppt_index = spt_desc[i].ppt_index; 441 be_soc->page_desc_base[ppt_index].page_v_addr = NULL; 442 i++; 443 } 444 return QDF_STATUS_SUCCESS; 445 } 446 #else 447 QDF_STATUS 448 dp_hw_cookie_conversion_deinit(struct dp_soc_be *be_soc, 449 struct dp_hw_cookie_conversion_t *cc_ctx) 450 { 451 struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc); 452 uint32_t ppt_index; 453 struct dp_spt_page_desc *spt_desc; 454 int i = 0; 455 456 spt_desc = cc_ctx->page_desc_base; 457 while (i < cc_ctx->total_page_num) { 458 /* reset PA in CMEM to NULL */ 459 dp_hw_cc_cmem_write(soc->hal_soc, 460 (cc_ctx->cmem_offset + be_soc->cc_cmem_base 461 + (i * DP_CC_PPT_ENTRY_SIZE_4K_ALIGNED)), 462 0); 463 464 ppt_index = spt_desc[i].ppt_index; 465 be_soc->page_desc_base[ppt_index].page_v_addr = NULL; 466 i++; 467 } 468 return QDF_STATUS_SUCCESS; 469 } 470 #endif 471 472 static QDF_STATUS dp_soc_detach_be(struct dp_soc *soc) 473 { 474 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 475 int i = 0; 476 477 478 for (i = 0; i < MAX_TXDESC_POOLS; i++) 479 dp_hw_cookie_conversion_detach(be_soc, 480 &be_soc->tx_cc_ctx[i]); 481 482 for (i = 0; i < MAX_RXDESC_POOLS; i++) 483 dp_hw_cookie_conversion_detach(be_soc, 484 &be_soc->rx_cc_ctx[i]); 485 486 qdf_mem_free(be_soc->page_desc_base); 487 be_soc->page_desc_base = NULL; 488 489 return QDF_STATUS_SUCCESS; 490 } 491 492 #ifdef WLAN_MLO_MULTI_CHIP 493 #ifdef WLAN_MCAST_MLO 494 static inline void 495 dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev) 496 { 497 struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); 498 499 be_vdev->mcast_primary = false; 500 be_vdev->seq_num = 0; 501 dp_tx_mcast_mlo_reinject_routing_set(soc, 502 (void *)&be_vdev->mcast_primary); 503 if (vdev->opmode == wlan_op_mode_ap) { 504 if (vdev->mlo_vdev) 505 hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, 506 vdev->vdev_id, 507 HAL_TX_MCAST_CTRL_DROP); 508 else 509 hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, 510 vdev->vdev_id, 511 HAL_TX_MCAST_CTRL_FW_EXCEPTION); 512 } 513 } 514 515 static inline void 516 dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev) 517 { 518 struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); 519 520 be_vdev->seq_num = 0; 521 be_vdev->mcast_primary = false; 522 vdev->mlo_vdev = false; 523 } 524 #else 525 static inline void 526 dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev) 527 { 528 } 529 530 static inline void 531 dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev) 532 { 533 } 534 #endif 535 static void dp_mlo_init_ptnr_list(struct dp_vdev *vdev) 536 { 537 struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); 538 539 qdf_mem_set(be_vdev->partner_vdev_list, 540 WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC, 541 CDP_INVALID_VDEV_ID); 542 } 543 544 static void dp_get_rx_hash_key_be(struct dp_soc *soc, 545 struct cdp_lro_hash_config *lro_hash) 546 { 547 dp_mlo_get_rx_hash_key(soc, lro_hash); 548 } 549 #else 550 static inline void 551 dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev) 552 { 553 } 554 555 static inline void 556 dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev) 557 { 558 } 559 560 static void dp_mlo_init_ptnr_list(struct dp_vdev *vdev) 561 { 562 } 563 564 static void dp_get_rx_hash_key_be(struct dp_soc *soc, 565 struct cdp_lro_hash_config *lro_hash) 566 { 567 dp_get_rx_hash_key_bytes(lro_hash); 568 } 569 #endif 570 571 static QDF_STATUS dp_soc_attach_be(struct dp_soc *soc, 572 struct cdp_soc_attach_params *params) 573 { 574 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 575 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 576 uint32_t max_tx_rx_desc_num, num_spt_pages; 577 uint32_t num_entries; 578 int i = 0; 579 580 max_tx_rx_desc_num = WLAN_CFG_NUM_TX_DESC_MAX * MAX_TXDESC_POOLS + 581 WLAN_CFG_RX_SW_DESC_NUM_SIZE_MAX * MAX_RXDESC_POOLS; 582 /* estimate how many SPT DDR pages needed */ 583 num_spt_pages = max_tx_rx_desc_num / DP_CC_SPT_PAGE_MAX_ENTRIES; 584 num_spt_pages = num_spt_pages <= DP_CC_PPT_MAX_ENTRIES ? 585 num_spt_pages : DP_CC_PPT_MAX_ENTRIES; 586 587 be_soc->page_desc_base = qdf_mem_malloc( 588 DP_CC_PPT_MAX_ENTRIES * sizeof(struct dp_spt_page_desc)); 589 if (!be_soc->page_desc_base) { 590 dp_err("spt page descs allocation failed"); 591 return QDF_STATUS_E_NOMEM; 592 } 593 594 soc->wbm_sw0_bm_id = hal_tx_get_wbm_sw0_bm_id(); 595 596 qdf_status = dp_get_cmem_allocation(soc, COOKIE_CONVERSION); 597 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 598 goto fail; 599 600 dp_soc_mlo_fill_params(soc, params); 601 602 for (i = 0; i < MAX_TXDESC_POOLS; i++) { 603 num_entries = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx); 604 qdf_status = 605 dp_hw_cookie_conversion_attach(be_soc, 606 &be_soc->tx_cc_ctx[i], 607 num_entries, 608 DP_TX_DESC_TYPE, i); 609 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 610 goto fail; 611 } 612 613 qdf_status = dp_get_cmem_allocation(soc, FISA_FST); 614 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 615 goto fail; 616 617 for (i = 0; i < MAX_RXDESC_POOLS; i++) { 618 num_entries = 619 wlan_cfg_get_dp_soc_rx_sw_desc_num(soc->wlan_cfg_ctx); 620 qdf_status = 621 dp_hw_cookie_conversion_attach(be_soc, 622 &be_soc->rx_cc_ctx[i], 623 num_entries, 624 DP_RX_DESC_BUF_TYPE, i); 625 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 626 goto fail; 627 } 628 629 return qdf_status; 630 fail: 631 dp_soc_detach_be(soc); 632 return qdf_status; 633 } 634 635 static QDF_STATUS dp_soc_deinit_be(struct dp_soc *soc) 636 { 637 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 638 int i = 0; 639 640 dp_tx_deinit_bank_profiles(be_soc); 641 for (i = 0; i < MAX_TXDESC_POOLS; i++) 642 dp_hw_cookie_conversion_deinit(be_soc, 643 &be_soc->tx_cc_ctx[i]); 644 645 for (i = 0; i < MAX_RXDESC_POOLS; i++) 646 dp_hw_cookie_conversion_deinit(be_soc, 647 &be_soc->rx_cc_ctx[i]); 648 649 return QDF_STATUS_SUCCESS; 650 } 651 652 static QDF_STATUS dp_soc_init_be(struct dp_soc *soc) 653 { 654 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 655 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 656 int i = 0; 657 658 for (i = 0; i < MAX_TXDESC_POOLS; i++) { 659 qdf_status = 660 dp_hw_cookie_conversion_init(be_soc, 661 &be_soc->tx_cc_ctx[i]); 662 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 663 goto fail; 664 } 665 666 for (i = 0; i < MAX_RXDESC_POOLS; i++) { 667 qdf_status = 668 dp_hw_cookie_conversion_init(be_soc, 669 &be_soc->rx_cc_ctx[i]); 670 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 671 goto fail; 672 } 673 674 /* route vdev_id mismatch notification via FW completion */ 675 hal_tx_vdev_mismatch_routing_set(soc->hal_soc, 676 HAL_TX_VDEV_MISMATCH_FW_NOTIFY); 677 678 qdf_status = dp_tx_init_bank_profiles(be_soc); 679 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 680 goto fail; 681 682 /* write WBM/REO cookie conversion CFG register */ 683 dp_cc_reg_cfg_init(soc, true); 684 685 return qdf_status; 686 fail: 687 dp_soc_deinit_be(soc); 688 return qdf_status; 689 } 690 691 static QDF_STATUS dp_pdev_attach_be(struct dp_pdev *pdev, 692 struct cdp_pdev_attach_params *params) 693 { 694 dp_pdev_mlo_fill_params(pdev, params); 695 dp_mlo_update_link_to_pdev_map(pdev->soc, pdev); 696 697 return QDF_STATUS_SUCCESS; 698 } 699 700 static QDF_STATUS dp_pdev_detach_be(struct dp_pdev *pdev) 701 { 702 dp_mlo_update_link_to_pdev_unmap(pdev->soc, pdev); 703 704 return QDF_STATUS_SUCCESS; 705 } 706 707 static QDF_STATUS dp_vdev_attach_be(struct dp_soc *soc, struct dp_vdev *vdev) 708 { 709 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 710 struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); 711 struct dp_pdev *pdev = vdev->pdev; 712 713 if (vdev->opmode == wlan_op_mode_monitor) 714 return QDF_STATUS_SUCCESS; 715 716 be_vdev->vdev_id_check_en = DP_TX_VDEV_ID_CHECK_ENABLE; 717 718 be_vdev->bank_id = dp_tx_get_bank_profile(be_soc, be_vdev); 719 720 if (be_vdev->bank_id == DP_BE_INVALID_BANK_ID) { 721 QDF_BUG(0); 722 return QDF_STATUS_E_FAULT; 723 } 724 725 if (vdev->opmode == wlan_op_mode_sta) { 726 if (soc->cdp_soc.ol_ops->set_mec_timer) 727 soc->cdp_soc.ol_ops->set_mec_timer( 728 soc->ctrl_psoc, 729 vdev->vdev_id, 730 DP_AST_AGING_TIMER_DEFAULT_MS); 731 732 if (pdev->isolation) 733 hal_tx_vdev_mcast_ctrl_set(soc->hal_soc, vdev->vdev_id, 734 HAL_TX_MCAST_CTRL_FW_EXCEPTION); 735 else 736 hal_tx_vdev_mcast_ctrl_set(soc->hal_soc, vdev->vdev_id, 737 HAL_TX_MCAST_CTRL_MEC_NOTIFY); 738 } 739 740 dp_mlo_mcast_init(soc, vdev); 741 dp_mlo_init_ptnr_list(vdev); 742 743 return QDF_STATUS_SUCCESS; 744 } 745 746 static QDF_STATUS dp_vdev_detach_be(struct dp_soc *soc, struct dp_vdev *vdev) 747 { 748 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 749 struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); 750 751 if (vdev->opmode == wlan_op_mode_monitor) 752 return QDF_STATUS_SUCCESS; 753 754 if (vdev->opmode == wlan_op_mode_ap) 755 dp_mlo_mcast_deinit(soc, vdev); 756 757 dp_tx_put_bank_profile(be_soc, be_vdev); 758 dp_clr_mlo_ptnr_list(soc, vdev); 759 760 return QDF_STATUS_SUCCESS; 761 } 762 763 qdf_size_t dp_get_soc_context_size_be(void) 764 { 765 return sizeof(struct dp_soc_be); 766 } 767 768 #ifdef NO_RX_PKT_HDR_TLV 769 /** 770 * dp_rxdma_ring_sel_cfg_be() - Setup RXDMA ring config 771 * @soc: Common DP soc handle 772 * 773 * Return: QDF_STATUS 774 */ 775 static QDF_STATUS 776 dp_rxdma_ring_sel_cfg_be(struct dp_soc *soc) 777 { 778 int i; 779 int mac_id; 780 struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; 781 struct dp_srng *rx_mac_srng; 782 QDF_STATUS status = QDF_STATUS_SUCCESS; 783 784 /* 785 * In Beryllium chipset msdu_start, mpdu_end 786 * and rx_attn are part of msdu_end/mpdu_start 787 */ 788 htt_tlv_filter.msdu_start = 0; 789 htt_tlv_filter.mpdu_end = 0; 790 htt_tlv_filter.attention = 0; 791 htt_tlv_filter.mpdu_start = 1; 792 htt_tlv_filter.msdu_end = 1; 793 htt_tlv_filter.packet = 1; 794 htt_tlv_filter.packet_header = 0; 795 796 htt_tlv_filter.ppdu_start = 0; 797 htt_tlv_filter.ppdu_end = 0; 798 htt_tlv_filter.ppdu_end_user_stats = 0; 799 htt_tlv_filter.ppdu_end_user_stats_ext = 0; 800 htt_tlv_filter.ppdu_end_status_done = 0; 801 htt_tlv_filter.enable_fp = 1; 802 htt_tlv_filter.enable_md = 0; 803 htt_tlv_filter.enable_md = 0; 804 htt_tlv_filter.enable_mo = 0; 805 806 htt_tlv_filter.fp_mgmt_filter = 0; 807 htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_BA_REQ; 808 htt_tlv_filter.fp_data_filter = (FILTER_DATA_UCAST | 809 FILTER_DATA_MCAST | 810 FILTER_DATA_DATA); 811 htt_tlv_filter.mo_mgmt_filter = 0; 812 htt_tlv_filter.mo_ctrl_filter = 0; 813 htt_tlv_filter.mo_data_filter = 0; 814 htt_tlv_filter.md_data_filter = 0; 815 816 htt_tlv_filter.offset_valid = true; 817 818 /* Not subscribing to mpdu_end, msdu_start and rx_attn */ 819 htt_tlv_filter.rx_mpdu_end_offset = 0; 820 htt_tlv_filter.rx_msdu_start_offset = 0; 821 htt_tlv_filter.rx_attn_offset = 0; 822 823 htt_tlv_filter.rx_packet_offset = soc->rx_pkt_tlv_size; 824 /*Not subscribing rx_pkt_header*/ 825 htt_tlv_filter.rx_header_offset = 0; 826 htt_tlv_filter.rx_mpdu_start_offset = 827 hal_rx_mpdu_start_offset_get(soc->hal_soc); 828 htt_tlv_filter.rx_msdu_end_offset = 829 hal_rx_msdu_end_offset_get(soc->hal_soc); 830 831 for (i = 0; i < MAX_PDEV_CNT; i++) { 832 struct dp_pdev *pdev = soc->pdev_list[i]; 833 834 if (!pdev) 835 continue; 836 837 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { 838 int mac_for_pdev = 839 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 840 /* 841 * Obtain lmac id from pdev to access the LMAC ring 842 * in soc context 843 */ 844 int lmac_id = 845 dp_get_lmac_id_for_pdev_id(soc, mac_id, 846 pdev->pdev_id); 847 848 rx_mac_srng = dp_get_rxdma_ring(pdev, lmac_id); 849 850 if (!rx_mac_srng->hal_srng) 851 continue; 852 853 htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 854 rx_mac_srng->hal_srng, 855 RXDMA_BUF, RX_DATA_BUFFER_SIZE, 856 &htt_tlv_filter); 857 } 858 } 859 return status; 860 } 861 #else 862 /** 863 * dp_rxdma_ring_sel_cfg_be() - Setup RXDMA ring config 864 * @soc: Common DP soc handle 865 * 866 * Return: QDF_STATUS 867 */ 868 static QDF_STATUS 869 dp_rxdma_ring_sel_cfg_be(struct dp_soc *soc) 870 { 871 int i; 872 int mac_id; 873 struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; 874 struct dp_srng *rx_mac_srng; 875 QDF_STATUS status = QDF_STATUS_SUCCESS; 876 877 /* 878 * In Beryllium chipset msdu_start, mpdu_end 879 * and rx_attn are part of msdu_end/mpdu_start 880 */ 881 htt_tlv_filter.msdu_start = 0; 882 htt_tlv_filter.mpdu_end = 0; 883 htt_tlv_filter.attention = 0; 884 htt_tlv_filter.mpdu_start = 1; 885 htt_tlv_filter.msdu_end = 1; 886 htt_tlv_filter.packet = 1; 887 htt_tlv_filter.packet_header = 1; 888 889 htt_tlv_filter.ppdu_start = 0; 890 htt_tlv_filter.ppdu_end = 0; 891 htt_tlv_filter.ppdu_end_user_stats = 0; 892 htt_tlv_filter.ppdu_end_user_stats_ext = 0; 893 htt_tlv_filter.ppdu_end_status_done = 0; 894 htt_tlv_filter.enable_fp = 1; 895 htt_tlv_filter.enable_md = 0; 896 htt_tlv_filter.enable_md = 0; 897 htt_tlv_filter.enable_mo = 0; 898 899 htt_tlv_filter.fp_mgmt_filter = 0; 900 htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_BA_REQ; 901 htt_tlv_filter.fp_data_filter = (FILTER_DATA_UCAST | 902 FILTER_DATA_MCAST | 903 FILTER_DATA_DATA); 904 htt_tlv_filter.mo_mgmt_filter = 0; 905 htt_tlv_filter.mo_ctrl_filter = 0; 906 htt_tlv_filter.mo_data_filter = 0; 907 htt_tlv_filter.md_data_filter = 0; 908 909 htt_tlv_filter.offset_valid = true; 910 911 /* Not subscribing to mpdu_end, msdu_start and rx_attn */ 912 htt_tlv_filter.rx_mpdu_end_offset = 0; 913 htt_tlv_filter.rx_msdu_start_offset = 0; 914 htt_tlv_filter.rx_attn_offset = 0; 915 916 htt_tlv_filter.rx_packet_offset = soc->rx_pkt_tlv_size; 917 htt_tlv_filter.rx_header_offset = 918 hal_rx_pkt_tlv_offset_get(soc->hal_soc); 919 htt_tlv_filter.rx_mpdu_start_offset = 920 hal_rx_mpdu_start_offset_get(soc->hal_soc); 921 htt_tlv_filter.rx_msdu_end_offset = 922 hal_rx_msdu_end_offset_get(soc->hal_soc); 923 924 dp_info("TLV subscription\n" 925 "msdu_start %d, mpdu_end %d, attention %d" 926 "mpdu_start %d, msdu_end %d, pkt_hdr %d, pkt %d\n" 927 "TLV offsets\n" 928 "msdu_start %d, mpdu_end %d, attention %d" 929 "mpdu_start %d, msdu_end %d, pkt_hdr %d, pkt %d\n", 930 htt_tlv_filter.msdu_start, 931 htt_tlv_filter.mpdu_end, 932 htt_tlv_filter.attention, 933 htt_tlv_filter.mpdu_start, 934 htt_tlv_filter.msdu_end, 935 htt_tlv_filter.packet_header, 936 htt_tlv_filter.packet, 937 htt_tlv_filter.rx_msdu_start_offset, 938 htt_tlv_filter.rx_mpdu_end_offset, 939 htt_tlv_filter.rx_attn_offset, 940 htt_tlv_filter.rx_mpdu_start_offset, 941 htt_tlv_filter.rx_msdu_end_offset, 942 htt_tlv_filter.rx_header_offset, 943 htt_tlv_filter.rx_packet_offset); 944 945 for (i = 0; i < MAX_PDEV_CNT; i++) { 946 struct dp_pdev *pdev = soc->pdev_list[i]; 947 948 if (!pdev) 949 continue; 950 951 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { 952 int mac_for_pdev = 953 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 954 /* 955 * Obtain lmac id from pdev to access the LMAC ring 956 * in soc context 957 */ 958 int lmac_id = 959 dp_get_lmac_id_for_pdev_id(soc, mac_id, 960 pdev->pdev_id); 961 962 rx_mac_srng = dp_get_rxdma_ring(pdev, lmac_id); 963 964 if (!rx_mac_srng->hal_srng) 965 continue; 966 967 htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 968 rx_mac_srng->hal_srng, 969 RXDMA_BUF, RX_DATA_BUFFER_SIZE, 970 &htt_tlv_filter); 971 } 972 } 973 return status; 974 975 } 976 #endif 977 978 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ 979 /** 980 * dp_service_near_full_srngs_be() - Main bottom half callback for the 981 * near-full IRQs. 982 * @soc: Datapath SoC handle 983 * @int_ctx: Interrupt context 984 * @dp_budget: Budget of the work that can be done in the bottom half 985 * 986 * Return: work done in the handler 987 */ 988 static uint32_t 989 dp_service_near_full_srngs_be(struct dp_soc *soc, struct dp_intr *int_ctx, 990 uint32_t dp_budget) 991 { 992 int ring = 0; 993 int budget = dp_budget; 994 uint32_t work_done = 0; 995 uint32_t remaining_quota = dp_budget; 996 struct dp_intr_stats *intr_stats = &int_ctx->intr_stats; 997 int tx_ring_near_full_mask = int_ctx->tx_ring_near_full_mask; 998 int rx_near_full_grp_1_mask = int_ctx->rx_near_full_grp_1_mask; 999 int rx_near_full_grp_2_mask = int_ctx->rx_near_full_grp_2_mask; 1000 int rx_near_full_mask = rx_near_full_grp_1_mask | 1001 rx_near_full_grp_2_mask; 1002 1003 dp_verbose_debug("rx_ring_near_full 0x%x tx_ring_near_full 0x%x", 1004 rx_near_full_mask, 1005 tx_ring_near_full_mask); 1006 1007 if (rx_near_full_mask) { 1008 for (ring = 0; ring < soc->num_reo_dest_rings; ring++) { 1009 if (!(rx_near_full_mask & (1 << ring))) 1010 continue; 1011 1012 work_done = dp_rx_nf_process(int_ctx, 1013 soc->reo_dest_ring[ring].hal_srng, 1014 ring, remaining_quota); 1015 if (work_done) { 1016 intr_stats->num_rx_ring_near_full_masks[ring]++; 1017 dp_verbose_debug("rx NF mask 0x%x ring %d, work_done %d budget %d", 1018 rx_near_full_mask, ring, 1019 work_done, 1020 budget); 1021 budget -= work_done; 1022 if (budget <= 0) 1023 goto budget_done; 1024 remaining_quota = budget; 1025 } 1026 } 1027 } 1028 1029 if (tx_ring_near_full_mask) { 1030 for (ring = 0; ring < soc->num_tcl_data_rings; ring++) { 1031 if (!(tx_ring_near_full_mask & (1 << ring))) 1032 continue; 1033 1034 work_done = dp_tx_comp_nf_handler(int_ctx, soc, 1035 soc->tx_comp_ring[ring].hal_srng, 1036 ring, remaining_quota); 1037 if (work_done) { 1038 intr_stats->num_tx_comp_ring_near_full_masks[ring]++; 1039 dp_verbose_debug("tx NF mask 0x%x ring %d, work_done %d budget %d", 1040 tx_ring_near_full_mask, ring, 1041 work_done, budget); 1042 budget -= work_done; 1043 if (budget <= 0) 1044 break; 1045 remaining_quota = budget; 1046 } 1047 } 1048 } 1049 1050 intr_stats->num_near_full_masks++; 1051 1052 budget_done: 1053 return dp_budget - budget; 1054 } 1055 1056 /** 1057 * dp_srng_test_and_update_nf_params_be() - Check if the srng is in near full 1058 * state and set the reap_limit appropriately 1059 * as per the near full state 1060 * @soc: Datapath soc handle 1061 * @dp_srng: Datapath handle for SRNG 1062 * @max_reap_limit: [Output Buffer] Buffer to set the max reap limit as per 1063 * the srng near-full state 1064 * 1065 * Return: 1, if the srng is in near-full state 1066 * 0, if the srng is not in near-full state 1067 */ 1068 static int 1069 dp_srng_test_and_update_nf_params_be(struct dp_soc *soc, 1070 struct dp_srng *dp_srng, 1071 int *max_reap_limit) 1072 { 1073 return _dp_srng_test_and_update_nf_params(soc, dp_srng, max_reap_limit); 1074 } 1075 1076 /** 1077 * dp_init_near_full_arch_ops_be() - Initialize the arch ops handler for the 1078 * near full IRQ handling operations. 1079 * @arch_ops: arch ops handle 1080 * 1081 * Return: none 1082 */ 1083 static inline void 1084 dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops) 1085 { 1086 arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be; 1087 arch_ops->dp_srng_test_and_update_nf_params = 1088 dp_srng_test_and_update_nf_params_be; 1089 } 1090 1091 #else 1092 static inline void 1093 dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops) 1094 { 1095 } 1096 #endif 1097 1098 #ifdef WLAN_SUPPORT_PPEDS 1099 static void dp_soc_ppe_srng_deinit(struct dp_soc *soc) 1100 { 1101 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 1102 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1103 1104 soc_cfg_ctx = soc->wlan_cfg_ctx; 1105 1106 if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc_cfg_ctx)) 1107 return; 1108 1109 dp_srng_deinit(soc, &be_soc->ppe_release_ring, PPE_RELEASE, 0); 1110 wlan_minidump_remove(be_soc->ppe_release_ring.base_vaddr_unaligned, 1111 be_soc->ppe_release_ring.alloc_size, 1112 soc->ctrl_psoc, 1113 WLAN_MD_DP_SRNG_PPE_RELEASE, 1114 "ppe_release_ring"); 1115 1116 dp_srng_deinit(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 0); 1117 wlan_minidump_remove(be_soc->ppe2tcl_ring.base_vaddr_unaligned, 1118 be_soc->ppe2tcl_ring.alloc_size, 1119 soc->ctrl_psoc, 1120 WLAN_MD_DP_SRNG_PPE2TCL, 1121 "ppe2tcl_ring"); 1122 1123 dp_srng_deinit(soc, &be_soc->reo2ppe_ring, REO2PPE, 0); 1124 wlan_minidump_remove(be_soc->reo2ppe_ring.base_vaddr_unaligned, 1125 be_soc->reo2ppe_ring.alloc_size, 1126 soc->ctrl_psoc, 1127 WLAN_MD_DP_SRNG_REO2PPE, 1128 "reo2ppe_ring"); 1129 } 1130 1131 static void dp_soc_ppe_srng_free(struct dp_soc *soc) 1132 { 1133 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 1134 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1135 1136 soc_cfg_ctx = soc->wlan_cfg_ctx; 1137 1138 if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc_cfg_ctx)) 1139 return; 1140 1141 dp_srng_free(soc, &be_soc->ppe_release_ring); 1142 1143 dp_srng_free(soc, &be_soc->ppe2tcl_ring); 1144 1145 dp_srng_free(soc, &be_soc->reo2ppe_ring); 1146 } 1147 1148 static QDF_STATUS dp_soc_ppe_srng_alloc(struct dp_soc *soc) 1149 { 1150 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 1151 uint32_t entries; 1152 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1153 1154 soc_cfg_ctx = soc->wlan_cfg_ctx; 1155 1156 if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc_cfg_ctx)) 1157 return QDF_STATUS_SUCCESS; 1158 1159 entries = wlan_cfg_get_dp_soc_reo2ppe_ring_size(soc_cfg_ctx); 1160 1161 if (dp_srng_alloc(soc, &be_soc->reo2ppe_ring, REO2PPE, 1162 entries, 0)) { 1163 dp_err("%pK: dp_srng_alloc failed for reo2ppe", soc); 1164 goto fail; 1165 } 1166 1167 entries = wlan_cfg_get_dp_soc_ppe2tcl_ring_size(soc_cfg_ctx); 1168 if (dp_srng_alloc(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 1169 entries, 0)) { 1170 dp_err("%pK: dp_srng_alloc failed for ppe2tcl_ring", soc); 1171 goto fail; 1172 } 1173 1174 entries = wlan_cfg_get_dp_soc_ppe_release_ring_size(soc_cfg_ctx); 1175 if (dp_srng_alloc(soc, &be_soc->ppe_release_ring, PPE_RELEASE, 1176 entries, 0)) { 1177 dp_err("%pK: dp_srng_alloc failed for ppe_release_ring", soc); 1178 goto fail; 1179 } 1180 1181 return QDF_STATUS_SUCCESS; 1182 fail: 1183 dp_soc_ppe_srng_free(soc); 1184 return QDF_STATUS_E_NOMEM; 1185 } 1186 1187 static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc) 1188 { 1189 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 1190 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1191 1192 soc_cfg_ctx = soc->wlan_cfg_ctx; 1193 1194 if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc_cfg_ctx)) 1195 return QDF_STATUS_SUCCESS; 1196 1197 if (dp_srng_init(soc, &be_soc->reo2ppe_ring, REO2PPE, 0, 0)) { 1198 dp_err("%pK: dp_srng_init failed for reo2ppe", soc); 1199 goto fail; 1200 } 1201 1202 wlan_minidump_log(be_soc->reo2ppe_ring.base_vaddr_unaligned, 1203 be_soc->reo2ppe_ring.alloc_size, 1204 soc->ctrl_psoc, 1205 WLAN_MD_DP_SRNG_REO2PPE, 1206 "reo2ppe_ring"); 1207 1208 if (dp_srng_init(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 0, 0)) { 1209 dp_err("%pK: dp_srng_init failed for ppe2tcl_ring", soc); 1210 goto fail; 1211 } 1212 1213 wlan_minidump_log(be_soc->ppe2tcl_ring.base_vaddr_unaligned, 1214 be_soc->ppe2tcl_ring.alloc_size, 1215 soc->ctrl_psoc, 1216 WLAN_MD_DP_SRNG_PPE2TCL, 1217 "ppe2tcl_ring"); 1218 1219 if (dp_srng_init(soc, &be_soc->ppe_release_ring, PPE_RELEASE, 0, 0)) { 1220 dp_err("%pK: dp_srng_init failed for ppe_release_ring", soc); 1221 goto fail; 1222 } 1223 1224 wlan_minidump_log(be_soc->ppe_release_ring.base_vaddr_unaligned, 1225 be_soc->ppe_release_ring.alloc_size, 1226 soc->ctrl_psoc, 1227 WLAN_MD_DP_SRNG_PPE_RELEASE, 1228 "ppe_release_ring"); 1229 1230 return QDF_STATUS_SUCCESS; 1231 fail: 1232 dp_soc_ppe_srng_deinit(soc); 1233 return QDF_STATUS_E_NOMEM; 1234 } 1235 #else 1236 static void dp_soc_ppe_srng_deinit(struct dp_soc *soc) 1237 { 1238 } 1239 1240 static void dp_soc_ppe_srng_free(struct dp_soc *soc) 1241 { 1242 } 1243 1244 static QDF_STATUS dp_soc_ppe_srng_alloc(struct dp_soc *soc) 1245 { 1246 return QDF_STATUS_SUCCESS; 1247 } 1248 1249 static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc) 1250 { 1251 return QDF_STATUS_SUCCESS; 1252 } 1253 #endif 1254 1255 static void dp_soc_srng_deinit_be(struct dp_soc *soc) 1256 { 1257 uint32_t i; 1258 1259 dp_soc_ppe_srng_deinit(soc); 1260 1261 if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { 1262 for (i = 0; i < soc->num_rx_refill_buf_rings; i++) { 1263 dp_srng_deinit(soc, &soc->rx_refill_buf_ring[i], 1264 RXDMA_BUF, 0); 1265 } 1266 } 1267 } 1268 1269 static void dp_soc_srng_free_be(struct dp_soc *soc) 1270 { 1271 uint32_t i; 1272 1273 dp_soc_ppe_srng_free(soc); 1274 1275 if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { 1276 for (i = 0; i < soc->num_rx_refill_buf_rings; i++) 1277 dp_srng_free(soc, &soc->rx_refill_buf_ring[i]); 1278 } 1279 } 1280 1281 static QDF_STATUS dp_soc_srng_alloc_be(struct dp_soc *soc) 1282 { 1283 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1284 uint32_t ring_size; 1285 uint32_t i; 1286 1287 soc_cfg_ctx = soc->wlan_cfg_ctx; 1288 1289 ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); 1290 if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { 1291 for (i = 0; i < soc->num_rx_refill_buf_rings; i++) { 1292 if (dp_srng_alloc(soc, &soc->rx_refill_buf_ring[i], 1293 RXDMA_BUF, ring_size, 0)) { 1294 dp_err("%pK: dp_srng_alloc failed refill ring", 1295 soc); 1296 goto fail; 1297 } 1298 } 1299 } 1300 1301 if (dp_soc_ppe_srng_alloc(soc)) { 1302 dp_err("%pK: ppe rings alloc failed", 1303 soc); 1304 goto fail; 1305 } 1306 1307 return QDF_STATUS_SUCCESS; 1308 fail: 1309 dp_soc_srng_free_be(soc); 1310 return QDF_STATUS_E_NOMEM; 1311 } 1312 1313 static QDF_STATUS dp_soc_srng_init_be(struct dp_soc *soc) 1314 { 1315 int i = 0; 1316 1317 if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { 1318 for (i = 0; i < soc->num_rx_refill_buf_rings; i++) { 1319 if (dp_srng_init(soc, &soc->rx_refill_buf_ring[i], 1320 RXDMA_BUF, 0, 0)) { 1321 dp_err("%pK: dp_srng_init failed refill ring", 1322 soc); 1323 goto fail; 1324 } 1325 } 1326 } 1327 1328 if (dp_soc_ppe_srng_init(soc)) { 1329 dp_err("%pK: ppe rings init failed", 1330 soc); 1331 goto fail; 1332 } 1333 1334 return QDF_STATUS_SUCCESS; 1335 fail: 1336 dp_soc_srng_deinit_be(soc); 1337 return QDF_STATUS_E_NOMEM; 1338 } 1339 1340 #ifdef WLAN_FEATURE_11BE_MLO 1341 static inline unsigned 1342 dp_mlo_peer_find_hash_index(dp_mld_peer_hash_obj_t mld_hash_obj, 1343 union dp_align_mac_addr *mac_addr) 1344 { 1345 uint32_t index; 1346 1347 index = 1348 mac_addr->align2.bytes_ab ^ 1349 mac_addr->align2.bytes_cd ^ 1350 mac_addr->align2.bytes_ef; 1351 1352 index ^= index >> mld_hash_obj->mld_peer_hash.idx_bits; 1353 index &= mld_hash_obj->mld_peer_hash.mask; 1354 1355 return index; 1356 } 1357 1358 QDF_STATUS 1359 dp_mlo_peer_find_hash_attach_be(dp_mld_peer_hash_obj_t mld_hash_obj, 1360 int hash_elems) 1361 { 1362 int i, log2; 1363 1364 if (!mld_hash_obj) 1365 return QDF_STATUS_E_FAILURE; 1366 1367 hash_elems *= DP_PEER_HASH_LOAD_MULT; 1368 hash_elems >>= DP_PEER_HASH_LOAD_SHIFT; 1369 log2 = dp_log2_ceil(hash_elems); 1370 hash_elems = 1 << log2; 1371 1372 mld_hash_obj->mld_peer_hash.mask = hash_elems - 1; 1373 mld_hash_obj->mld_peer_hash.idx_bits = log2; 1374 /* allocate an array of TAILQ peer object lists */ 1375 mld_hash_obj->mld_peer_hash.bins = qdf_mem_malloc( 1376 hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q, dp_peer))); 1377 if (!mld_hash_obj->mld_peer_hash.bins) 1378 return QDF_STATUS_E_NOMEM; 1379 1380 for (i = 0; i < hash_elems; i++) 1381 TAILQ_INIT(&mld_hash_obj->mld_peer_hash.bins[i]); 1382 1383 qdf_spinlock_create(&mld_hash_obj->mld_peer_hash_lock); 1384 1385 return QDF_STATUS_SUCCESS; 1386 } 1387 1388 void 1389 dp_mlo_peer_find_hash_detach_be(dp_mld_peer_hash_obj_t mld_hash_obj) 1390 { 1391 if (!mld_hash_obj) 1392 return; 1393 1394 if (mld_hash_obj->mld_peer_hash.bins) { 1395 qdf_mem_free(mld_hash_obj->mld_peer_hash.bins); 1396 mld_hash_obj->mld_peer_hash.bins = NULL; 1397 qdf_spinlock_destroy(&mld_hash_obj->mld_peer_hash_lock); 1398 } 1399 } 1400 1401 #ifdef WLAN_MLO_MULTI_CHIP 1402 static QDF_STATUS dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc *soc) 1403 { 1404 /* In case of MULTI chip MLO peer hash table when MLO global object 1405 * is created, avoid from SOC attach path 1406 */ 1407 return QDF_STATUS_SUCCESS; 1408 } 1409 1410 static void dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc *soc) 1411 { 1412 } 1413 #else 1414 static QDF_STATUS dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc *soc) 1415 { 1416 dp_mld_peer_hash_obj_t mld_hash_obj; 1417 1418 mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); 1419 1420 if (!mld_hash_obj) 1421 return QDF_STATUS_E_FAILURE; 1422 1423 return dp_mlo_peer_find_hash_attach_be(mld_hash_obj, soc->max_peers); 1424 } 1425 1426 static void dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc *soc) 1427 { 1428 dp_mld_peer_hash_obj_t mld_hash_obj; 1429 1430 mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); 1431 1432 if (!mld_hash_obj) 1433 return; 1434 1435 return dp_mlo_peer_find_hash_detach_be(mld_hash_obj); 1436 } 1437 #endif 1438 1439 static struct dp_peer * 1440 dp_mlo_peer_find_hash_find_be(struct dp_soc *soc, 1441 uint8_t *peer_mac_addr, 1442 int mac_addr_is_aligned, 1443 enum dp_mod_id mod_id, 1444 uint8_t vdev_id) 1445 { 1446 union dp_align_mac_addr local_mac_addr_aligned, *mac_addr; 1447 uint32_t index; 1448 struct dp_peer *peer; 1449 struct dp_vdev *vdev; 1450 dp_mld_peer_hash_obj_t mld_hash_obj; 1451 1452 mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); 1453 if (!mld_hash_obj) 1454 return NULL; 1455 1456 if (!mld_hash_obj->mld_peer_hash.bins) 1457 return NULL; 1458 1459 if (mac_addr_is_aligned) { 1460 mac_addr = (union dp_align_mac_addr *)peer_mac_addr; 1461 } else { 1462 qdf_mem_copy( 1463 &local_mac_addr_aligned.raw[0], 1464 peer_mac_addr, QDF_MAC_ADDR_SIZE); 1465 mac_addr = &local_mac_addr_aligned; 1466 } 1467 1468 if (vdev_id != DP_VDEV_ALL) { 1469 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, mod_id); 1470 if (!vdev) { 1471 dp_err("vdev is null\n"); 1472 return NULL; 1473 } 1474 } else { 1475 vdev = NULL; 1476 } 1477 /* search mld peer table if no link peer for given mac address */ 1478 index = dp_mlo_peer_find_hash_index(mld_hash_obj, mac_addr); 1479 qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock); 1480 TAILQ_FOREACH(peer, &mld_hash_obj->mld_peer_hash.bins[index], 1481 hash_list_elem) { 1482 if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0) { 1483 if ((vdev_id == DP_VDEV_ALL) || ( 1484 dp_peer_find_mac_addr_cmp( 1485 &peer->vdev->mld_mac_addr, 1486 &vdev->mld_mac_addr) == 0)) { 1487 /* take peer reference before returning */ 1488 if (dp_peer_get_ref(NULL, peer, mod_id) != 1489 QDF_STATUS_SUCCESS) 1490 peer = NULL; 1491 1492 if (vdev) 1493 dp_vdev_unref_delete(soc, vdev, mod_id); 1494 1495 qdf_spin_unlock_bh( 1496 &mld_hash_obj->mld_peer_hash_lock); 1497 return peer; 1498 } 1499 } 1500 } 1501 1502 if (vdev) 1503 dp_vdev_unref_delete(soc, vdev, mod_id); 1504 1505 qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); 1506 1507 return NULL; /* failure */ 1508 } 1509 1510 static void 1511 dp_mlo_peer_find_hash_remove_be(struct dp_soc *soc, struct dp_peer *peer) 1512 { 1513 uint32_t index; 1514 struct dp_peer *tmppeer = NULL; 1515 int found = 0; 1516 dp_mld_peer_hash_obj_t mld_hash_obj; 1517 1518 mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); 1519 1520 if (!mld_hash_obj) 1521 return; 1522 1523 index = dp_mlo_peer_find_hash_index(mld_hash_obj, &peer->mac_addr); 1524 QDF_ASSERT(!TAILQ_EMPTY(&mld_hash_obj->mld_peer_hash.bins[index])); 1525 1526 qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock); 1527 TAILQ_FOREACH(tmppeer, &mld_hash_obj->mld_peer_hash.bins[index], 1528 hash_list_elem) { 1529 if (tmppeer == peer) { 1530 found = 1; 1531 break; 1532 } 1533 } 1534 QDF_ASSERT(found); 1535 TAILQ_REMOVE(&mld_hash_obj->mld_peer_hash.bins[index], peer, 1536 hash_list_elem); 1537 1538 dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG); 1539 qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); 1540 } 1541 1542 static void 1543 dp_mlo_peer_find_hash_add_be(struct dp_soc *soc, struct dp_peer *peer) 1544 { 1545 uint32_t index; 1546 dp_mld_peer_hash_obj_t mld_hash_obj; 1547 1548 mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); 1549 1550 if (!mld_hash_obj) 1551 return; 1552 1553 index = dp_mlo_peer_find_hash_index(mld_hash_obj, &peer->mac_addr); 1554 1555 qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock); 1556 1557 if (QDF_IS_STATUS_ERROR(dp_peer_get_ref(NULL, peer, 1558 DP_MOD_ID_CONFIG))) { 1559 dp_err("fail to get peer ref:" QDF_MAC_ADDR_FMT, 1560 QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 1561 qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); 1562 return; 1563 } 1564 TAILQ_INSERT_TAIL(&mld_hash_obj->mld_peer_hash.bins[index], peer, 1565 hash_list_elem); 1566 qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); 1567 } 1568 1569 void dp_print_mlo_ast_stats_be(struct dp_soc *soc) 1570 { 1571 uint32_t index; 1572 struct dp_peer *peer; 1573 dp_mld_peer_hash_obj_t mld_hash_obj; 1574 1575 mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); 1576 1577 if (!mld_hash_obj) 1578 return; 1579 1580 qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock); 1581 for (index = 0; index < mld_hash_obj->mld_peer_hash.mask; index++) { 1582 TAILQ_FOREACH(peer, &mld_hash_obj->mld_peer_hash.bins[index], 1583 hash_list_elem) { 1584 dp_print_peer_ast_entries(soc, peer, NULL); 1585 } 1586 } 1587 qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); 1588 } 1589 1590 #endif 1591 1592 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \ 1593 defined(WLAN_MCAST_MLO) 1594 static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( 1595 struct dp_vdev_be *be_vdev, 1596 cdp_config_param_type val) 1597 { 1598 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc( 1599 be_vdev->vdev.pdev->soc); 1600 hal_soc_handle_t hal_soc = be_vdev->vdev.pdev->soc->hal_soc; 1601 uint8_t vdev_id = be_vdev->vdev.vdev_id; 1602 1603 be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev; 1604 1605 if (be_vdev->mcast_primary) { 1606 hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, 1607 HAL_TX_MCAST_CTRL_NO_SPECIAL); 1608 hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id + 128, 1609 HAL_TX_MCAST_CTRL_FW_EXCEPTION); 1610 dp_mcast_mlo_iter_ptnr_soc(be_soc, 1611 dp_tx_mcast_mlo_reinject_routing_set, 1612 (void *)&be_vdev->mcast_primary); 1613 } else { 1614 hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, 1615 HAL_TX_MCAST_CTRL_DROP); 1616 } 1617 } 1618 #else 1619 static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( 1620 struct dp_vdev_be *be_vdev, 1621 cdp_config_param_type val) 1622 { 1623 } 1624 #endif 1625 1626 #ifdef DP_TX_IMPLICIT_RBM_MAPPING 1627 static void dp_tx_implicit_rbm_set_be(struct dp_soc *soc, 1628 uint8_t tx_ring_id, 1629 uint8_t bm_id) 1630 { 1631 hal_tx_config_rbm_mapping_be(soc->hal_soc, 1632 soc->tcl_data_ring[tx_ring_id].hal_srng, 1633 bm_id); 1634 } 1635 #else 1636 static void dp_tx_implicit_rbm_set_be(struct dp_soc *soc, 1637 uint8_t tx_ring_id, 1638 uint8_t bm_id) 1639 { 1640 } 1641 #endif 1642 1643 QDF_STATUS dp_txrx_set_vdev_param_be(struct dp_soc *soc, 1644 struct dp_vdev *vdev, 1645 enum cdp_vdev_param_type param, 1646 cdp_config_param_type val) 1647 { 1648 struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); 1649 struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); 1650 1651 switch (param) { 1652 case CDP_TX_ENCAP_TYPE: 1653 case CDP_UPDATE_DSCP_TO_TID_MAP: 1654 case CDP_UPDATE_TDLS_FLAGS: 1655 dp_tx_update_bank_profile(be_soc, be_vdev); 1656 break; 1657 case CDP_ENABLE_CIPHER: 1658 if (vdev->tx_encap_type == htt_cmn_pkt_type_raw) 1659 dp_tx_update_bank_profile(be_soc, be_vdev); 1660 break; 1661 case CDP_SET_MCAST_VDEV: 1662 dp_txrx_set_mlo_mcast_primary_vdev_param_be(be_vdev, val); 1663 break; 1664 default: 1665 dp_warn("invalid param %d", param); 1666 break; 1667 } 1668 1669 return QDF_STATUS_SUCCESS; 1670 } 1671 1672 #ifdef WLAN_FEATURE_11BE_MLO 1673 #ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH 1674 static inline void 1675 dp_soc_max_peer_id_set(struct dp_soc *soc) 1676 { 1677 soc->peer_id_shift = dp_log2_ceil(soc->max_peers); 1678 soc->peer_id_mask = (1 << soc->peer_id_shift) - 1; 1679 /* 1680 * Double the peers since we use ML indication bit 1681 * alongwith peer_id to find peers. 1682 */ 1683 soc->max_peer_id = 1 << (soc->peer_id_shift + 1); 1684 } 1685 #else 1686 static inline void 1687 dp_soc_max_peer_id_set(struct dp_soc *soc) 1688 { 1689 soc->max_peer_id = 1690 (1 << (HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S + 1)) - 1; 1691 } 1692 #endif /* DP_USE_REDUCED_PEER_ID_FIELD_WIDTH */ 1693 #else 1694 static inline void 1695 dp_soc_max_peer_id_set(struct dp_soc *soc) 1696 { 1697 soc->max_peer_id = soc->max_peers; 1698 } 1699 #endif /* WLAN_FEATURE_11BE_MLO */ 1700 1701 static void dp_peer_map_detach_be(struct dp_soc *soc) 1702 { 1703 if (soc->host_ast_db_enable) 1704 dp_peer_ast_hash_detach(soc); 1705 } 1706 1707 static QDF_STATUS dp_peer_map_attach_be(struct dp_soc *soc) 1708 { 1709 QDF_STATUS status; 1710 1711 if (soc->host_ast_db_enable) { 1712 status = dp_peer_ast_hash_attach(soc); 1713 if (QDF_IS_STATUS_ERROR(status)) 1714 return status; 1715 } 1716 1717 dp_soc_max_peer_id_set(soc); 1718 1719 return QDF_STATUS_SUCCESS; 1720 } 1721 1722 static struct dp_peer *dp_find_peer_by_destmac_be(struct dp_soc *soc, 1723 uint8_t *dest_mac, 1724 uint8_t vdev_id) 1725 { 1726 struct dp_peer *peer = NULL; 1727 struct dp_peer *tgt_peer = NULL; 1728 struct dp_ast_entry *ast_entry = NULL; 1729 uint16_t peer_id; 1730 1731 qdf_spin_lock_bh(&soc->ast_lock); 1732 ast_entry = dp_peer_ast_hash_find_soc(soc, dest_mac); 1733 if (!ast_entry) { 1734 qdf_spin_unlock_bh(&soc->ast_lock); 1735 dp_err("NULL ast entry"); 1736 return NULL; 1737 } 1738 1739 peer_id = ast_entry->peer_id; 1740 qdf_spin_unlock_bh(&soc->ast_lock); 1741 1742 if (peer_id == HTT_INVALID_PEER) 1743 return NULL; 1744 1745 peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_SAWF); 1746 if (!peer) { 1747 dp_err("NULL peer for peer_id:%d", peer_id); 1748 return NULL; 1749 } 1750 1751 tgt_peer = dp_get_tgt_peer_from_peer(peer); 1752 1753 /* 1754 * Once tgt_peer is obtained, 1755 * release the ref taken for original peer. 1756 */ 1757 dp_peer_get_ref(NULL, tgt_peer, DP_MOD_ID_SAWF); 1758 dp_peer_unref_delete(peer, DP_MOD_ID_SAWF); 1759 1760 return tgt_peer; 1761 } 1762 1763 #ifdef WLAN_FEATURE_11BE_MLO 1764 #ifdef WLAN_MCAST_MLO 1765 static inline void 1766 dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops *arch_ops) 1767 { 1768 arch_ops->dp_tx_mcast_handler = dp_tx_mlo_mcast_handler_be; 1769 arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler; 1770 } 1771 #else /* WLAN_MCAST_MLO */ 1772 static inline void 1773 dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops *arch_ops) 1774 { 1775 } 1776 #endif /* WLAN_MCAST_MLO */ 1777 1778 static inline void 1779 dp_initialize_arch_ops_be_mlo(struct dp_arch_ops *arch_ops) 1780 { 1781 dp_initialize_arch_ops_be_mcast_mlo(arch_ops); 1782 arch_ops->mlo_peer_find_hash_detach = 1783 dp_mlo_peer_find_hash_detach_wrapper; 1784 arch_ops->mlo_peer_find_hash_attach = 1785 dp_mlo_peer_find_hash_attach_wrapper; 1786 arch_ops->mlo_peer_find_hash_add = dp_mlo_peer_find_hash_add_be; 1787 arch_ops->mlo_peer_find_hash_remove = dp_mlo_peer_find_hash_remove_be; 1788 arch_ops->mlo_peer_find_hash_find = dp_mlo_peer_find_hash_find_be; 1789 } 1790 #else /* WLAN_FEATURE_11BE_MLO */ 1791 static inline void 1792 dp_initialize_arch_ops_be_mlo(struct dp_arch_ops *arch_ops) 1793 { 1794 } 1795 #endif /* WLAN_FEATURE_11BE_MLO */ 1796 1797 void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops) 1798 { 1799 #ifndef QCA_HOST_MODE_WIFI_DISABLED 1800 arch_ops->tx_hw_enqueue = dp_tx_hw_enqueue_be; 1801 arch_ops->dp_rx_process = dp_rx_process_be; 1802 arch_ops->tx_comp_get_params_from_hal_desc = 1803 dp_tx_comp_get_params_from_hal_desc_be; 1804 arch_ops->dp_tx_process_htt_completion = 1805 dp_tx_process_htt_completion_be; 1806 arch_ops->dp_tx_desc_pool_init = dp_tx_desc_pool_init_be; 1807 arch_ops->dp_tx_desc_pool_deinit = dp_tx_desc_pool_deinit_be; 1808 arch_ops->dp_rx_desc_pool_init = dp_rx_desc_pool_init_be; 1809 arch_ops->dp_rx_desc_pool_deinit = dp_rx_desc_pool_deinit_be; 1810 arch_ops->dp_wbm_get_rx_desc_from_hal_desc = 1811 dp_wbm_get_rx_desc_from_hal_desc_be; 1812 arch_ops->dp_tx_compute_hw_delay = dp_tx_compute_tx_delay_be; 1813 #endif 1814 arch_ops->txrx_get_context_size = dp_get_context_size_be; 1815 arch_ops->txrx_get_mon_context_size = dp_mon_get_context_size_be; 1816 arch_ops->dp_rx_desc_cookie_2_va = 1817 dp_rx_desc_cookie_2_va_be; 1818 arch_ops->dp_rx_intrabss_handle_nawds = dp_rx_intrabss_handle_nawds_be; 1819 1820 arch_ops->txrx_soc_attach = dp_soc_attach_be; 1821 arch_ops->txrx_soc_detach = dp_soc_detach_be; 1822 arch_ops->txrx_soc_init = dp_soc_init_be; 1823 arch_ops->txrx_soc_deinit = dp_soc_deinit_be; 1824 arch_ops->txrx_soc_srng_alloc = dp_soc_srng_alloc_be; 1825 arch_ops->txrx_soc_srng_init = dp_soc_srng_init_be; 1826 arch_ops->txrx_soc_srng_deinit = dp_soc_srng_deinit_be; 1827 arch_ops->txrx_soc_srng_free = dp_soc_srng_free_be; 1828 arch_ops->txrx_pdev_attach = dp_pdev_attach_be; 1829 arch_ops->txrx_pdev_detach = dp_pdev_detach_be; 1830 arch_ops->txrx_vdev_attach = dp_vdev_attach_be; 1831 arch_ops->txrx_vdev_detach = dp_vdev_detach_be; 1832 arch_ops->txrx_peer_map_attach = dp_peer_map_attach_be; 1833 arch_ops->txrx_peer_map_detach = dp_peer_map_detach_be; 1834 arch_ops->dp_rxdma_ring_sel_cfg = dp_rxdma_ring_sel_cfg_be; 1835 arch_ops->dp_rx_peer_metadata_peer_id_get = 1836 dp_rx_peer_metadata_peer_id_get_be; 1837 arch_ops->soc_cfg_attach = dp_soc_cfg_attach_be; 1838 arch_ops->tx_implicit_rbm_set = dp_tx_implicit_rbm_set_be; 1839 arch_ops->txrx_set_vdev_param = dp_txrx_set_vdev_param_be; 1840 dp_initialize_arch_ops_be_mlo(arch_ops); 1841 arch_ops->dp_peer_rx_reorder_queue_setup = 1842 dp_peer_rx_reorder_queue_setup_be; 1843 arch_ops->txrx_print_peer_stats = dp_print_peer_txrx_stats_be; 1844 arch_ops->dp_find_peer_by_destmac = dp_find_peer_by_destmac_be; 1845 dp_init_near_full_arch_ops_be(arch_ops); 1846 arch_ops->get_rx_hash_key = dp_get_rx_hash_key_be; 1847 arch_ops->print_mlo_ast_stats = dp_print_mlo_ast_stats_be; 1848 } 1849