qcacmn: Support IPA WDI 3.0 with two tx pipes

Currently a set of IPA2TCL and WBM2IPA rings is used for
IPA TX data path. Issue is when wlan is configured as
SAP-SAP DBS mode, slow 2G traffic will consume much more
TX resources and thus 5G traffic will have starvation,
which leads to severe degradation of DBS KPI.

Therefore separate IPA2TCL (SW2TCL2) and WBM2IPA (WBM2SW4)
rings are added to support alternative IPA TX pipe for 2G
traffic.

Change-Id: I4b648d0bcacbcde0b9b0a824516c1f06e3b0c7ad
CRs-Fixed: 2750079
This commit is contained in:
Tiger Yu
2021-02-23 17:51:27 +08:00
committed by Madan Koyyalamudi
parent 63e6497955
commit 2cd64402c6
4 changed files with 1025 additions and 149 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies. * copyright notice and this permission notice appear in all copies.
* *
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@@ -28,6 +28,16 @@
#define TX_COMP_DRAIN_WAIT_MS 50 #define TX_COMP_DRAIN_WAIT_MS 50
#define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 100 #define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 100
#ifdef IPA_WDI3_TX_TWO_PIPES
#define IPA_TX_ALT_RING_IDX 1
/*
* must be same as IPA_TX_ALT_RING_IDX as tcl and wbm ring
* are initialized with same index as a pair.
*/
#define IPA_TX_ALT_COMP_RING_IDX 1
#define IPA_SESSION_ID_SHIFT 1
#endif
/** /**
* struct dp_ipa_uc_tx_hdr - full tx header registered to IPA hardware * struct dp_ipa_uc_tx_hdr - full tx header registered to IPA hardware
* @eth: ether II header * @eth: ether II header

View File

@@ -258,6 +258,12 @@ static inline void
dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
bool enable); bool enable);
#endif #endif
static QDF_STATUS dp_init_tx_ring_pair_by_index(struct dp_soc *soc,
uint8_t index);
static void dp_deinit_tx_pair_by_index(struct dp_soc *soc, int index);
static void dp_free_tx_ring_pair_by_index(struct dp_soc *soc, uint8_t index);
static QDF_STATUS dp_alloc_tx_ring_pair_by_index(struct dp_soc *soc,
uint8_t index);
static inline bool static inline bool
dp_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev); dp_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev);
static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc, static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc,
@@ -3248,6 +3254,93 @@ void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id)
#define REO_DST_RING_SIZE_QCN9000 8 #define REO_DST_RING_SIZE_QCN9000 8
#endif /* CONFIG_WIFI_EMULATION_WIFI_3_0 */ #endif /* CONFIG_WIFI_EMULATION_WIFI_3_0 */
#ifdef IPA_WDI3_TX_TWO_PIPES
static int dp_ipa_get_tx_alt_comp_ring_num(int ring_num)
{
/* IPA alternate TX comp ring for 2G is WBM2SW4 */
if (ring_num == IPA_TX_ALT_COMP_RING_IDX)
ring_num = 4;
return ring_num;
}
#ifdef DP_MEMORY_OPT
static int dp_ipa_init_alt_tx_ring(struct dp_soc *soc)
{
return dp_init_tx_ring_pair_by_index(soc, IPA_TX_ALT_RING_IDX);
}
static void dp_ipa_deinit_alt_tx_ring(struct dp_soc *soc)
{
dp_deinit_tx_pair_by_index(soc, IPA_TX_ALT_RING_IDX);
}
static int dp_ipa_alloc_alt_tx_ring(struct dp_soc *soc)
{
return dp_alloc_tx_ring_pair_by_index(soc, IPA_TX_ALT_RING_IDX);
}
static void dp_ipa_free_alt_tx_ring(struct dp_soc *soc)
{
dp_free_tx_ring_pair_by_index(soc, IPA_TX_ALT_RING_IDX);
}
#else /* !DP_MEMORY_OPT */
static int dp_ipa_init_alt_tx_ring(struct dp_soc *soc)
{
return 0;
}
static void dp_ipa_deinit_alt_tx_ring(struct dp_soc *soc)
{
}
static int dp_ipa_alloc_alt_tx_ring(struct dp_soc *soc)
{
return 0
}
static void dp_ipa_free_alt_tx_ring(struct dp_soc *soc)
{
}
#endif /* DP_MEMORY_OPT */
static void dp_ipa_hal_tx_init_alt_data_ring(struct dp_soc *soc)
{
hal_tx_init_data_ring(soc->hal_soc,
soc->tcl_data_ring[IPA_TX_ALT_RING_IDX].hal_srng);
}
#else /* !IPA_WDI3_TX_TWO_PIPES */
static int dp_ipa_get_tx_alt_comp_ring_num(int ring_num)
{
return ring_num;
}
static int dp_ipa_init_alt_tx_ring(struct dp_soc *soc)
{
return 0;
}
static void dp_ipa_deinit_alt_tx_ring(struct dp_soc *soc)
{
}
static int dp_ipa_alloc_alt_tx_ring(struct dp_soc *soc)
{
return 0;
}
static void dp_ipa_free_alt_tx_ring(struct dp_soc *soc)
{
}
static void dp_ipa_hal_tx_init_alt_data_ring(struct dp_soc *soc)
{
}
#endif /* IPA_WDI3_TX_TWO_PIPES */
#else #else
#define REO_DST_RING_SIZE_QCA6290 1024 #define REO_DST_RING_SIZE_QCA6290 1024
@@ -3258,6 +3351,34 @@ void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id)
#define REO_DST_RING_SIZE_QCA8074 8 #define REO_DST_RING_SIZE_QCA8074 8
#define REO_DST_RING_SIZE_QCN9000 8 #define REO_DST_RING_SIZE_QCN9000 8
#endif /* CONFIG_WIFI_EMULATION_WIFI_3_0 */ #endif /* CONFIG_WIFI_EMULATION_WIFI_3_0 */
static int dp_ipa_init_alt_tx_ring(struct dp_soc *soc)
{
return 0;
}
static void dp_ipa_deinit_alt_tx_ring(struct dp_soc *soc)
{
}
static int dp_ipa_alloc_alt_tx_ring(struct dp_soc *soc)
{
return 0;
}
static void dp_ipa_free_alt_tx_ring(struct dp_soc *soc)
{
}
static int dp_ipa_get_tx_alt_comp_ring_num(int ring_num)
{
return ring_num;
}
static void dp_ipa_hal_tx_init_alt_data_ring(struct dp_soc *soc)
{
}
#endif /* IPA_OFFLOAD */ #endif /* IPA_OFFLOAD */
/* /*
@@ -3539,6 +3660,28 @@ bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1, uint32_t *remap2)
return true; return true;
} }
#ifdef IPA_WDI3_TX_TWO_PIPES
static bool dp_ipa_is_alt_tx_ring(int index)
{
return index == IPA_TX_ALT_RING_IDX;
}
static bool dp_ipa_is_alt_tx_comp_ring(int index)
{
return index == IPA_TX_ALT_COMP_RING_IDX;
}
#else /* !IPA_WDI3_TX_TWO_PIPES */
static bool dp_ipa_is_alt_tx_ring(int index)
{
return false;
}
static bool dp_ipa_is_alt_tx_comp_ring(int index)
{
return false;
}
#endif /* IPA_WDI3_TX_TWO_PIPES */
/** /**
* dp_ipa_get_tx_ring_size() - Get Tx ring size for IPA * dp_ipa_get_tx_ring_size() - Get Tx ring size for IPA
* *
@@ -3549,7 +3692,8 @@ bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1, uint32_t *remap2)
*/ */
static void dp_ipa_get_tx_ring_size(int tx_ring_num, int *tx_ipa_ring_sz) static void dp_ipa_get_tx_ring_size(int tx_ring_num, int *tx_ipa_ring_sz)
{ {
if (tx_ring_num == IPA_TCL_DATA_RING_IDX) if (tx_ring_num == IPA_TCL_DATA_RING_IDX ||
dp_ipa_is_alt_tx_ring(tx_ring_num))
*tx_ipa_ring_sz = WLAN_CFG_IPA_TX_RING_SIZE; *tx_ipa_ring_sz = WLAN_CFG_IPA_TX_RING_SIZE;
} }
@@ -3564,7 +3708,8 @@ static void dp_ipa_get_tx_ring_size(int tx_ring_num, int *tx_ipa_ring_sz)
static void dp_ipa_get_tx_comp_ring_size(int tx_comp_ring_num, static void dp_ipa_get_tx_comp_ring_size(int tx_comp_ring_num,
int *tx_comp_ipa_ring_sz) int *tx_comp_ipa_ring_sz)
{ {
if (tx_comp_ring_num == IPA_TCL_DATA_RING_IDX) if (tx_comp_ring_num == IPA_TCL_DATA_RING_IDX ||
dp_ipa_is_alt_tx_comp_ring(tx_comp_ring_num))
*tx_comp_ipa_ring_sz = WLAN_CFG_IPA_TX_COMP_RING_SIZE; *tx_comp_ipa_ring_sz = WLAN_CFG_IPA_TX_COMP_RING_SIZE;
} }
#else #else
@@ -3784,6 +3929,8 @@ static inline void dp_create_ext_stats_event(struct dp_soc *soc)
static void dp_deinit_tx_pair_by_index(struct dp_soc *soc, int index) static void dp_deinit_tx_pair_by_index(struct dp_soc *soc, int index)
{ {
int ring_num;
wlan_minidump_remove(soc->tcl_data_ring[index].base_vaddr_unaligned, wlan_minidump_remove(soc->tcl_data_ring[index].base_vaddr_unaligned,
soc->tcl_data_ring[index].alloc_size, soc->tcl_data_ring[index].alloc_size,
soc->ctrl_psoc, soc->ctrl_psoc,
@@ -3796,12 +3943,16 @@ static void dp_deinit_tx_pair_by_index(struct dp_soc *soc, int index)
soc->ctrl_psoc, soc->ctrl_psoc,
WLAN_MD_DP_SRNG_TX_COMP, WLAN_MD_DP_SRNG_TX_COMP,
"tcl_comp_ring"); "tcl_comp_ring");
dp_srng_deinit(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE, index); ring_num = dp_ipa_get_tx_alt_comp_ring_num(index);
dp_srng_deinit(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE,
ring_num);
} }
static QDF_STATUS dp_init_tx_ring_pair_by_index(struct dp_soc *soc, static QDF_STATUS dp_init_tx_ring_pair_by_index(struct dp_soc *soc,
uint8_t index) uint8_t index)
{ {
int ring_num;
if (dp_srng_init(soc, &soc->tcl_data_ring[index], TCL_DATA, index, 0)) { if (dp_srng_init(soc, &soc->tcl_data_ring[index], TCL_DATA, index, 0)) {
dp_err("dp_srng_init failed for tcl_data_ring"); dp_err("dp_srng_init failed for tcl_data_ring");
goto fail1; goto fail1;
@@ -3812,8 +3963,9 @@ static QDF_STATUS dp_init_tx_ring_pair_by_index(struct dp_soc *soc,
WLAN_MD_DP_SRNG_TCL_DATA, WLAN_MD_DP_SRNG_TCL_DATA,
"tcl_data_ring"); "tcl_data_ring");
ring_num = dp_ipa_get_tx_alt_comp_ring_num(index);
if (dp_srng_init(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE, if (dp_srng_init(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE,
index, 0)) { ring_num, 0)) {
dp_err("dp_srng_init failed for tx_comp_ring"); dp_err("dp_srng_init failed for tx_comp_ring");
goto fail1; goto fail1;
} }
@@ -13521,8 +13673,10 @@ static void dp_pdev_srng_deinit(struct dp_pdev *pdev)
dp_srng_deinit(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], RXDMA_BUF, dp_srng_deinit(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], RXDMA_BUF,
pdev->lmac_id); pdev->lmac_id);
if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
dp_deinit_tx_pair_by_index(soc, IPA_TCL_DATA_RING_IDX); dp_deinit_tx_pair_by_index(soc, IPA_TCL_DATA_RING_IDX);
dp_ipa_deinit_alt_tx_ring(soc);
}
for (i = 0; i < NUM_RXDMA_RINGS_PER_PDEV; i++) { for (i = 0; i < NUM_RXDMA_RINGS_PER_PDEV; i++) {
int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, pdev->pdev_id); int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, pdev->pdev_id);
@@ -13564,6 +13718,9 @@ static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev)
if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) { if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
if (dp_init_tx_ring_pair_by_index(soc, IPA_TCL_DATA_RING_IDX)) if (dp_init_tx_ring_pair_by_index(soc, IPA_TCL_DATA_RING_IDX))
goto fail1; goto fail1;
if (dp_ipa_init_alt_tx_ring(soc))
goto fail1;
} }
if (dp_mon_rings_init(soc, pdev)) { if (dp_mon_rings_init(soc, pdev)) {
@@ -13613,8 +13770,10 @@ static void dp_pdev_srng_free(struct dp_pdev *pdev)
dp_srng_free(soc, &soc->rx_refill_buf_ring[pdev->lmac_id]); dp_srng_free(soc, &soc->rx_refill_buf_ring[pdev->lmac_id]);
dp_mon_rings_free(pdev); dp_mon_rings_free(pdev);
if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
dp_free_tx_ring_pair_by_index(soc, IPA_TCL_DATA_RING_IDX); dp_free_tx_ring_pair_by_index(soc, IPA_TCL_DATA_RING_IDX);
dp_ipa_free_alt_tx_ring(soc);
}
for (i = 0; i < NUM_RXDMA_RINGS_PER_PDEV; i++) { for (i = 0; i < NUM_RXDMA_RINGS_PER_PDEV; i++) {
int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, pdev->pdev_id); int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, pdev->pdev_id);
@@ -13655,6 +13814,9 @@ static QDF_STATUS dp_pdev_srng_alloc(struct dp_pdev *pdev)
if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) { if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
if (dp_alloc_tx_ring_pair_by_index(soc, IPA_TCL_DATA_RING_IDX)) if (dp_alloc_tx_ring_pair_by_index(soc, IPA_TCL_DATA_RING_IDX))
goto fail1; goto fail1;
if (dp_ipa_alloc_alt_tx_ring(soc))
goto fail1;
} }
ring_size = wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(soc_cfg_ctx); ring_size = wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(soc_cfg_ctx);
@@ -14297,9 +14459,11 @@ static QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc,
} }
/* Initialize descriptors in TCL Rings used by IPA */ /* Initialize descriptors in TCL Rings used by IPA */
if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
hal_tx_init_data_ring(soc->hal_soc, hal_tx_init_data_ring(soc->hal_soc,
soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng); soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng);
dp_ipa_hal_tx_init_alt_data_ring(soc);
}
/* /*
* Initialize command/credit ring descriptor * Initialize command/credit ring descriptor

View File

@@ -1338,6 +1338,29 @@ struct dp_swlm {
}; };
#endif #endif
#ifdef IPA_OFFLOAD
/* IPA uC datapath offload Wlan Tx resources */
struct ipa_dp_tx_rsc {
/* Resource info to be passed to IPA */
qdf_dma_addr_t ipa_tcl_ring_base_paddr;
void *ipa_tcl_ring_base_vaddr;
uint32_t ipa_tcl_ring_size;
qdf_dma_addr_t ipa_tcl_hp_paddr;
uint32_t alloc_tx_buf_cnt;
qdf_dma_addr_t ipa_wbm_ring_base_paddr;
void *ipa_wbm_ring_base_vaddr;
uint32_t ipa_wbm_ring_size;
qdf_dma_addr_t ipa_wbm_tp_paddr;
/* WBM2SW HP shadow paddr */
qdf_dma_addr_t ipa_wbm_hp_shadow_paddr;
/* TX buffers populated into the WBM ring */
void **tx_buf_pool_vaddr_unaligned;
qdf_dma_addr_t *tx_buf_pool_paddr_unaligned;
};
#endif
/* SOC level structure for data path */ /* SOC level structure for data path */
struct dp_soc { struct dp_soc {
/** /**
@@ -1614,26 +1637,11 @@ struct dp_soc {
void *external_txrx_handle; /* External data path handle */ void *external_txrx_handle; /* External data path handle */
#ifdef IPA_OFFLOAD #ifdef IPA_OFFLOAD
/* IPA uC datapath offload Wlan Tx resources */ struct ipa_dp_tx_rsc ipa_uc_tx_rsc;
struct { #ifdef IPA_WDI3_TX_TWO_PIPES
/* Resource info to be passed to IPA */ /* Resources for the alternative IPA TX pipe */
qdf_dma_addr_t ipa_tcl_ring_base_paddr; struct ipa_dp_tx_rsc ipa_uc_tx_rsc_alt;
void *ipa_tcl_ring_base_vaddr; #endif
uint32_t ipa_tcl_ring_size;
qdf_dma_addr_t ipa_tcl_hp_paddr;
uint32_t alloc_tx_buf_cnt;
qdf_dma_addr_t ipa_wbm_ring_base_paddr;
void *ipa_wbm_ring_base_vaddr;
uint32_t ipa_wbm_ring_size;
qdf_dma_addr_t ipa_wbm_tp_paddr;
/* WBM2SW HP shadow paddr */
qdf_dma_addr_t ipa_wbm_hp_shadow_paddr;
/* TX buffers populated into the WBM ring */
void **tx_buf_pool_vaddr_unaligned;
qdf_dma_addr_t *tx_buf_pool_paddr_unaligned;
} ipa_uc_tx_rsc;
/* IPA uC datapath offload Wlan Rx resources */ /* IPA uC datapath offload Wlan Rx resources */
struct { struct {
@@ -1799,6 +1807,16 @@ struct dp_ipa_resources {
qdf_dma_addr_t rx_ready_doorbell_paddr; qdf_dma_addr_t rx_ready_doorbell_paddr;
bool is_db_ddr_mapped; bool is_db_ddr_mapped;
#ifdef IPA_WDI3_TX_TWO_PIPES
qdf_shared_mem_t tx_alt_ring;
uint32_t tx_alt_ring_num_alloc_buffer;
qdf_shared_mem_t tx_alt_comp_ring;
/* IPA UC doorbell registers paddr */
qdf_dma_addr_t tx_alt_comp_doorbell_paddr;
uint32_t *tx_alt_comp_doorbell_vaddr;
#endif
}; };
#endif #endif