From 09526ac0d18212fd4559cb9d7dfe8918369adb36 Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 12 Apr 2019 17:42:40 +0800 Subject: [PATCH] qcacmn: Fix REO2IPA reo destination routing Observed that when IPA offload is enabled, RX packets are not routed correctly to IPA ring. Currently only IX0 of REO_DESTINATION_CTRL_IX registers are remapped, which only covers 3-bit reo_destination_indication of range 0 to 7. Fix is to remap REO_DESTINATION_CTRL_IX2|3 registers so that reo_destination_indication of range 16 to 31 can also be routed REO2IPA ring when IPA offload is enabled. Upon IPA offload is disabled, save values of IX2 and IX3 are reset back to HW. Change-Id: I3428b450ab10076d27c7628a3729e8cec088bd94 CRs-Fixed: 2434331 --- dp/wifi3.0/dp_ipa.c | 59 ++++++++++++++++++++++------------ dp/wifi3.0/dp_ipa.h | 3 ++ dp/wifi3.0/dp_main.c | 4 +-- hal/wifi3.0/hal_api.h | 12 +++++-- hal/wifi3.0/hal_srng.c | 73 ++++++++++++++++++++++++++++++++++++++---- 5 files changed, 119 insertions(+), 32 deletions(-) diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 4d0e4fab88..7da01a48b2 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/dp/wifi3.0/dp_ipa.c @@ -692,7 +692,8 @@ QDF_STATUS dp_ipa_enable_autonomy(struct cdp_pdev *ppdev) { struct dp_pdev *pdev = (struct dp_pdev *)ppdev; struct dp_soc *soc = pdev->soc; - uint32_t remap_val; + uint32_t ix0; + uint32_t ix2; if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -704,15 +705,25 @@ QDF_STATUS dp_ipa_enable_autonomy(struct cdp_pdev *ppdev) dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, true); /* Call HAL API to remap REO rings to REO2IPA ring */ - remap_val = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | - HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | - HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | - HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); - hal_reo_remap_IX0(soc->hal_soc, remap_val); + ix0 = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | + HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW4) | + HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW4) | + HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW4) | + HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW4) | + HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | + HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | + HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); + + if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { + ix2 = ((REO_REMAP_SW4 << 0) | (REO_REMAP_SW4 << 3) | + (REO_REMAP_SW4 << 6) | (REO_REMAP_SW4 << 9) | + (REO_REMAP_SW4 << 12) | (REO_REMAP_SW4 << 15) | + (REO_REMAP_SW4 << 18) | (REO_REMAP_SW4 << 21)) << 8; + + hal_reo_read_write_ctrl_ix(soc->hal_soc, false, &ix0, NULL, + &ix2, &ix2); + } + return QDF_STATUS_SUCCESS; } @@ -728,21 +739,29 @@ QDF_STATUS dp_ipa_disable_autonomy(struct cdp_pdev *ppdev) { struct dp_pdev *pdev = (struct dp_pdev *)ppdev; struct dp_soc *soc = pdev->soc; - uint32_t remap_val; + uint32_t ix0; + uint32_t ix2; + uint32_t ix3; if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; /* Call HAL API to remap REO rings to REO2IPA ring */ - remap_val = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | - HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW1) | - HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW2) | - HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW3) | - HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW2) | - HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | - HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | - HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); - hal_reo_remap_IX0(soc->hal_soc, remap_val); + ix0 = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | + HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW1) | + HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW2) | + HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW3) | + HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW2) | + HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | + HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | + HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); + + if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { + dp_reo_remap_config(soc, &ix2, &ix3); + + hal_reo_read_write_ctrl_ix(soc->hal_soc, false, &ix0, NULL, + &ix2, &ix3); + } qdf_spin_lock_bh(&soc->remap_lock); soc->reo_remapped = false; diff --git a/dp/wifi3.0/dp_ipa.h b/dp/wifi3.0/dp_ipa.h index 830ddd2b4b..67737c503a 100644 --- a/dp/wifi3.0/dp_ipa.h +++ b/dp/wifi3.0/dp_ipa.h @@ -108,6 +108,9 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc, qdf_nbuf_t nbuf, bool create); + +bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1, + uint32_t *remap2); #else static inline int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 1d80e7fe83..64762a3d8f 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -2558,9 +2558,7 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc) * @remap2: output parameter indicates reo remap 2 register value * Return: bool type, true if remap is configured else false. */ -static bool dp_reo_remap_config(struct dp_soc *soc, - uint32_t *remap1, - uint32_t *remap2) +bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1, uint32_t *remap2) { *remap1 = ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x1 << 9) | (0x2 << 12) | (0x3 << 15) | (0x1 << 18) | (0x2 << 21)) << 8; diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 936f5cf13d..a4cb6ccf5d 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -480,11 +480,17 @@ extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, _ORIGINAL_DEST ## _SHFT)) /** - * hal_reo_remap_IX0 - Remap REO ring destination + * hal_reo_read_write_ctrl_ix - Read or write REO_DESTINATION_RING_CTRL_IX * @hal: HAL SOC handle - * @remap_val: Remap value + * @read: boolean value to indicate if read or write + * @ix0: pointer to store IX0 reg value + * @ix1: pointer to store IX1 reg value + * @ix2: pointer to store IX2 reg value + * @ix3: pointer to store IX3 reg value */ -extern void hal_reo_remap_IX0(struct hal_soc *hal, uint32_t remap_val); +extern void hal_reo_read_write_ctrl_ix(struct hal_soc *hal, bool read, + uint32_t *ix0, uint32_t *ix1, + uint32_t *ix2, uint32_t *ix3); /** * hal_srng_set_hp_paddr() - Set physical address to dest SRNG head pointer diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 4d01770c3d..c432274278 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -428,15 +428,76 @@ static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng, } /** - * hal_reo_remap_IX0 - Remap REO ring destination + * hal_reo_read_write_ctrl_ix - Read or write REO_DESTINATION_RING_CTRL_IX * @hal: HAL SOC handle - * @remap_val: Remap value + * @read: boolean value to indicate if read or write + * @ix0: pointer to store IX0 reg value + * @ix1: pointer to store IX1 reg value + * @ix2: pointer to store IX2 reg value + * @ix3: pointer to store IX3 reg value */ -void hal_reo_remap_IX0(struct hal_soc *hal, uint32_t remap_val) +void hal_reo_read_write_ctrl_ix(struct hal_soc *hal, bool read, uint32_t *ix0, + uint32_t *ix1, uint32_t *ix2, uint32_t *ix3) { - uint32_t reg_offset = HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET); - HAL_REG_WRITE(hal, reg_offset, remap_val); + uint32_t reg_offset; + + if (read) { + if (ix0) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + *ix0 = HAL_REG_READ(hal, reg_offset); + } + + if (ix1) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + *ix1 = HAL_REG_READ(hal, reg_offset); + } + + if (ix2) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + *ix2 = HAL_REG_READ(hal, reg_offset); + } + + if (ix3) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + *ix3 = HAL_REG_READ(hal, reg_offset); + } + } else { + if (ix0) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + HAL_REG_WRITE(hal, reg_offset, *ix0); + } + + if (ix1) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + HAL_REG_WRITE(hal, reg_offset, *ix1); + } + + if (ix2) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + HAL_REG_WRITE(hal, reg_offset, *ix2); + } + + if (ix3) { + reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + HAL_REG_WRITE(hal, reg_offset, *ix3); + } + } } /**