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;