From 1df15533437e0454625bcdb581fd047b132e2638 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 12 Nov 2020 21:59:24 +0530 Subject: [PATCH] qcacmn: Use only shadow writes for REO remap and WBM HP reg REO remap register direct writes as part of SAP stop could result in a NOC error if the UMAC is in low power state. Fix is to use shadow register writes for REO remap and WBM HP registers. Change-Id: Ie515c3d28f4ccdd99a3757808f1ab6c5cf373e3d CRs-Fixed: 2813105 --- dp/wifi3.0/dp_ipa.c | 14 ++++++++++++ dp/wifi3.0/dp_ipa.h | 2 +- hal/wifi3.0/hal_api.h | 51 +++++++++++++++++++------------------------ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 19c12c73d0..da83669020 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/dp/wifi3.0/dp_ipa.c @@ -1778,6 +1778,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } +#ifdef DEVICE_FORCE_WAKE_ENABLED /* * dp_ipa_get_tx_comp_pending_check() - Check if tx completions are pending. * @soc: DP pdev Context @@ -1805,6 +1806,7 @@ static bool dp_ipa_get_tx_comp_pending_check(struct dp_soc *soc) return (soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt != buf_cnt); } +#endif QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { @@ -1819,6 +1821,15 @@ QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_E_FAILURE; } + /* + * The tx completions pending check will trigger register read + * for HP and TP of wbm2sw2 ring. There is a possibility for + * these reg read to cause a NOC error if UMAC is in low power + * state. The WAR is to sleep for the drain timeout without checking + * for the pending tx completions. This WAR can be replaced with + * poll logic for HP/TP difference once force wake is in place. + */ +#ifdef DEVICE_FORCE_WAKE_ENABLED while (dp_ipa_get_tx_comp_pending_check(soc)) { qdf_sleep(TX_COMP_DRAIN_WAIT_MS); timeout -= TX_COMP_DRAIN_WAIT_MS; @@ -1827,6 +1838,9 @@ QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) break; } } +#else + qdf_sleep(timeout); +#endif result = qdf_ipa_wdi_disable_pipes(); if (result) { diff --git a/dp/wifi3.0/dp_ipa.h b/dp/wifi3.0/dp_ipa.h index 353414c168..7df2b28734 100644 --- a/dp/wifi3.0/dp_ipa.h +++ b/dp/wifi3.0/dp_ipa.h @@ -26,7 +26,7 @@ /* Adding delay before disabling ipa pipes if any Tx Completions are pending */ #define TX_COMP_DRAIN_WAIT_MS 50 -#define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 200 +#define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 100 /** * struct dp_ipa_uc_tx_hdr - full tx header registered to IPA hardware diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index dc220cd77a..c0ac1b7db3 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -600,6 +600,11 @@ uint32_t hal_read32_mb_cmem(struct hal_soc *hal_soc, uint32_t offset) } #endif +/* Max times allowed for register writing retry */ +#define HAL_REG_WRITE_RETRY_MAX 5 +/* Delay milliseconds for each time retry */ +#define HAL_REG_WRITE_RETRY_DELAY 1 + #ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE /* To check shadow config index range between 0..31 */ #define HAL_SHADOW_REG_INDEX_LOW 32 @@ -682,7 +687,6 @@ static inline QDF_STATUS hal_write32_mb_shadow_confirm( int i; QDF_STATUS ret; uint32_t shadow_reg_offset; - uint32_t read_value; int shadow_config_index; bool is_reg_offset_present = false; @@ -705,9 +709,8 @@ static inline QDF_STATUS hal_write32_mb_shadow_confirm( } if (is_reg_offset_present) { ret = hal_poll_dirty_bit_reg(hal, shadow_config_index); - read_value = hal_read32_mb(hal, reg_offset); - hal_info("Shadow retry:reg 0x%x val 0x%x readval 0x%x ret %d", - reg_offset, value, read_value, ret); + hal_info("Shadow write:reg 0x%x val 0x%x ret %d", + reg_offset, value, ret); if (QDF_IS_STATUS_ERROR(ret)) { HAL_STATS_INC(hal, shadow_reg_write_fail, 1); return ret; @@ -717,23 +720,6 @@ static inline QDF_STATUS hal_write32_mb_shadow_confirm( return ret; } -#else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ - -static inline QDF_STATUS hal_write32_mb_shadow_confirm( - struct hal_soc *hal_soc, - uint32_t offset, - uint32_t value) -{ - return QDF_STATUS_SUCCESS; -} - -#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ - -/* Max times allowed for register writing retry */ -#define HAL_REG_WRITE_RETRY_MAX 5 -/* Delay milliseconds for each time retry */ -#define HAL_REG_WRITE_RETRY_DELAY 1 - /** * hal_write32_mb_confirm_retry() - write register with confirming and do retry/recovery if writing failed @@ -749,6 +735,19 @@ static inline QDF_STATUS hal_write32_mb_shadow_confirm( * * Return: None */ +static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, + uint32_t offset, + uint32_t value, + bool recovery) +{ + QDF_STATUS ret; + + ret = hal_write32_mb_shadow_confirm(hal_soc, offset, value); + if (QDF_IS_STATUS_ERROR(ret) && recovery) + qdf_trigger_self_recovery(NULL, QDF_HAL_REG_WRITE_FAILURE); +} +#else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ + static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, uint32_t offset, uint32_t value, @@ -756,7 +755,6 @@ static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, { uint8_t retry_cnt = 0; uint32_t read_value; - QDF_STATUS ret; while (retry_cnt <= HAL_REG_WRITE_RETRY_MAX) { hal_write32_mb_confirm(hal_soc, offset, value); @@ -771,13 +769,10 @@ static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, retry_cnt++; } - if (retry_cnt > HAL_REG_WRITE_RETRY_MAX) { - ret = hal_write32_mb_shadow_confirm(hal_soc, offset, value); - if (QDF_IS_STATUS_ERROR(ret) && recovery) - qdf_trigger_self_recovery( - NULL, QDF_HAL_REG_WRITE_FAILURE); - } + if (retry_cnt > HAL_REG_WRITE_RETRY_MAX && recovery) + qdf_trigger_self_recovery(NULL, QDF_HAL_REG_WRITE_FAILURE); } +#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ #ifdef FEATURE_HAL_DELAYED_REG_WRITE /**