From 813e5ff2ec164a30d00d7dd127684d83e009e68f Mon Sep 17 00:00:00 2001 From: Jia Ding Date: Mon, 16 Oct 2023 11:15:19 +0800 Subject: [PATCH] qcacmn: Ring IPA TX doorbell with HW HP value Ring IPA TX doorbell with HW HP value to avoid out-of-sync scenarios between WLAN and IPA after IPA pipes are disabled and then re-enabled. CRs-Fixed: 3479426 Change-Id: Ia88c0228759e241722fe31fd1a252e70484684e9 --- dp/wifi3.0/dp_ipa.c | 30 ++++++++++++++++++++++++++++++ hal/wifi3.0/hal_api.h | 10 ++++++++++ hal/wifi3.0/hal_srng.c | 21 +++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 8cdbf00d10..6c1359c610 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/dp/wifi3.0/dp_ipa.c @@ -1059,6 +1059,23 @@ static void dp_ipa_tx_comp_ring_init_hp(struct dp_soc *soc, res->tx_alt_comp_doorbell_vaddr); } +static void +dp_ipa_tx_comp_ring_update_hp_addr(struct dp_soc *soc, + struct dp_ipa_resources *res) +{ + hal_ring_handle_t wbm_srng; + + /* Ring doorbell to WBM2IPA ring with current HW HP value */ + wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; + hal_srng_dst_update_hp_addr(soc->hal_soc, wbm_srng); + + if (!res->tx_alt_comp_doorbell_paddr) + return; + + wbm_srng = soc->tx_comp_ring[IPA_TX_ALT_COMP_RING_IDX].hal_srng; + hal_srng_dst_update_hp_addr(soc->hal_soc, wbm_srng); +} + static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc, struct dp_ipa_resources *ipa_res) { @@ -1255,6 +1272,17 @@ static inline void dp_ipa_tx_comp_ring_init_hp(struct dp_soc *soc, res->tx_comp_doorbell_vaddr); } +static void +dp_ipa_tx_comp_ring_update_hp_addr(struct dp_soc *soc, + struct dp_ipa_resources *res) +{ + hal_ring_handle_t wbm_srng; + + /* Ring doorbell to WBM2IPA ring with current HW HP value */ + wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; + hal_srng_dst_update_hp_addr(soc->hal_soc, wbm_srng); +} + static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc, struct dp_ipa_resources *ipa_res) { @@ -3500,6 +3528,8 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, if (soc->ipa_first_tx_db_access) { dp_ipa_tx_comp_ring_init_hp(soc, ipa_res); soc->ipa_first_tx_db_access = false; + } else { + dp_ipa_tx_comp_ring_update_hp_addr(soc, ipa_res); } return QDF_STATUS_SUCCESS; diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 5b5f157e6a..9a558831af 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -1302,6 +1302,16 @@ void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc, struct hal_srng *srng, uint32_t *vaddr); +/** + * hal_srng_dst_update_hp_addr() - Update hp_addr with current HW HP value + * @hal_soc: hal_soc handle + * @hal_ring_hdl: Opaque HAL SRNG pointer + * + * Return: None + */ +void hal_srng_dst_update_hp_addr(struct hal_soc_handle *hal_soc, + hal_ring_handle_t hal_ring_hdl); + /** * hal_srng_cleanup() - Deinitialize HW SRNG ring. * @hal_soc: Opaque HAL SOC handle diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index b066e4fb16..b1494dbd8b 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -1465,6 +1465,27 @@ void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc, qdf_export_symbol(hal_srng_dst_init_hp); +void hal_srng_dst_update_hp_addr(struct hal_soc_handle *hal_soc, + hal_ring_handle_t hal_ring_hdl) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + int32_t hw_hp; + int32_t hw_tp; + + if (!srng) + return; + + if (srng->u.dst_ring.hp_addr) { + hal_get_hw_hptp(hal_soc, hal_ring_hdl, &hw_hp, &hw_tp, + WBM2SW_RELEASE); + *srng->u.dst_ring.hp_addr = hw_hp; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "hw_hp=%d", hw_hp); + } +} + +qdf_export_symbol(hal_srng_dst_update_hp_addr); + /** * hal_srng_hw_init - Private function to initialize SRNG HW * @hal: HAL SOC handle