From 78b01a1e1b8386d64ce465c6bc9d6d0344f0592d Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Mon, 16 Sep 2019 14:22:55 +0530 Subject: [PATCH] qcacmn: Flush srng tp and hp only for flush event Currently after runtime resume all SW2TCL data and reo cmd srng rings hp and tp value are flushed. In case of IPA offload case SW2TCL3 righ hp value will be updated by IPA and not by host. In case of runtime pm enable host is setting the value to zero as part of runtime resume which results in incorrect hp value of SW2TCL3. As part of this change set flush event for rings which are accessed by host during link down state and after runtime resume flush the rings for which flush event is set. Change-Id: I5c9afa708277cf3a6e6d5ef99447bc21f88cfdcf CRs-Fixed: 2514621 --- dp/wifi3.0/dp_main.c | 5 ++- dp/wifi3.0/dp_tx.c | 4 +++ hal/wifi3.0/hal_api.h | 71 ++++++++++++++++++++++++++++++++++++++ hal/wifi3.0/hal_internal.h | 11 +++++- hal/wifi3.0/hal_reo.c | 4 +-- hal/wifi3.0/hal_srng.c | 2 ++ 6 files changed, 93 insertions(+), 4 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index ff2a4fbdaf..516ff02ca5 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9241,11 +9241,14 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_pdev *opaque_pdev) static void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) { - if (hal_srng) { + if (hal_srng && hal_srng_get_clear_event(hal_srng, + HAL_SRNG_FLUSH_EVENT)) { /* Acquire the lock */ hal_srng_access_start(soc->hal_soc, hal_srng); hal_srng_access_end(soc->hal_soc, hal_srng); + + hal_srng_set_flush_last_ts(hal_srng); } } diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 1a7eda2811..0a0a93f194 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -1581,6 +1581,8 @@ fail_return: hif_pm_runtime_put(soc->hif_handle); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } return nbuf; @@ -1749,6 +1751,8 @@ done: hif_pm_runtime_put(soc->hif_handle); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } return nbuf; diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 54b9aa2e9c..fa8ce51550 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -21,6 +21,7 @@ #include "qdf_types.h" #include "qdf_util.h" +#include "qdf_atomic.h" #include "hal_internal.h" #define MAX_UNWINDOWED_ADDRESS 0x80000 #ifdef QCA_WIFI_QCA6390 @@ -1582,4 +1583,74 @@ hal_ring_desc_t hal_rxdma_desc_to_hal_ring_desc(hal_rxdma_desc_t ring_desc) { return (hal_ring_desc_t)ring_desc; } + +/** + * hal_srng_set_event() - Set hal_srng event + * @hal_ring_hdl: Source ring pointer + * @event: SRNG ring event + * + * Return: None + */ +static inline void hal_srng_set_event(hal_ring_handle_t hal_ring_hdl, int event) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + + qdf_atomic_set_bit(event, &srng->srng_event); +} + +/** + * hal_srng_clear_event() - Clear hal_srng event + * @hal_ring_hdl: Source ring pointer + * @event: SRNG ring event + * + * Return: None + */ +static inline +void hal_srng_clear_event(hal_ring_handle_t hal_ring_hdl, int event) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + + qdf_atomic_clear_bit(event, &srng->srng_event); +} + +/** + * hal_srng_get_clear_event() - Clear srng event and return old value + * @hal_ring_hdl: Source ring pointer + * @event: SRNG ring event + * + * Return: Return old event value + */ +static inline +int hal_srng_get_clear_event(hal_ring_handle_t hal_ring_hdl, int event) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + + return qdf_atomic_test_and_clear_bit(event, &srng->srng_event); +} + +/** + * hal_srng_set_flush_last_ts() - Record last flush time stamp + * @hal_ring_hdl: Source ring pointer + * + * Return: None + */ +static inline void hal_srng_set_flush_last_ts(hal_ring_handle_t hal_ring_hdl) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + + srng->last_flush_ts = qdf_get_log_timestamp(); +} + +/** + * hal_srng_inc_flush_cnt() - Increment flush counter + * @hal_ring_hdl: Source ring pointer + * + * Return: None + */ +static inline void hal_srng_inc_flush_cnt(hal_ring_handle_t hal_ring_hdl) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + + srng->flush_count++; +} #endif /* _HAL_APIH_ */ diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 1ac457ffc5..f01d2e1856 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -181,6 +181,11 @@ typedef struct hal_ring_handle *hal_ring_handle_t; #define MAX_SRNG_REG_GROUPS 2 +/* Hal Srng bit mask + * HAL_SRNG_FLUSH_EVENT: SRNG HP TP flush in case of link down + */ +#define HAL_SRNG_FLUSH_EVENT BIT(0) + /* Common SRNG ring structure for source and destination rings */ struct hal_srng { /* Unique SRNG ring ID */ @@ -286,7 +291,11 @@ struct hal_srng { struct hal_soc *hal_soc; /* Number of times hp/tp updated in runtime resume */ - uint32_t needs_flush; + uint32_t flush_count; + /* hal srng event flag*/ + unsigned long srng_event; + /* last flushed time stamp */ + uint64_t last_flush_ts; }; /* HW SRNG configuration table */ diff --git a/hal/wifi3.0/hal_reo.c b/hal/wifi3.0/hal_reo.c index ad2cad2a4b..b0ae3695bf 100644 --- a/hal/wifi3.0/hal_reo.c +++ b/hal/wifi3.0/hal_reo.c @@ -686,7 +686,6 @@ inline int hal_reo_cmd_update_rx_queue(hal_ring_handle_t hal_ring_hdl, struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t *reo_desc, val; struct hal_reo_cmd_update_queue_params *p; - struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; p = &cmd->u.upd_queue_params; @@ -888,7 +887,8 @@ inline int hal_reo_cmd_update_rx_queue(hal_ring_handle_t hal_ring_hdl, hif_pm_runtime_put(hal_soc->hif_handle); } else { hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); - srng->needs_flush++; + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } val = reo_desc[CMD_HEADER_DW_OFFSET]; diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 9ed6c3523c..26bd16e2ef 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -726,6 +726,8 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, SRNG_LOCK_INIT(&srng->lock); + srng->srng_event = 0; + srng->initialized = true; return (void *)srng;