diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 650a625aa4..05c8bca716 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -467,6 +467,7 @@ static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, uint32_t value) { qdf_iowrite32(addr, value); + hal_srng_reg_his_add(srng, value); } #elif defined(FEATURE_HAL_DELAYED_REG_WRITE) static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, @@ -483,6 +484,7 @@ static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, uint32_t value) { hal_write_address_32_mb(hal_soc, addr, value, false); + hal_srng_reg_his_add(srng, value); } #endif diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 0fc743a28e..acae0fd820 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -692,6 +692,32 @@ hal_get_tsf_enum(uint32_t tsf_id, uint32_t mac_id, } } +#ifdef HAL_SRNG_REG_HIS_DEBUG + +#define HAL_SRNG_REG_MAX_ENTRIES 64 + +/** + * struct hal_srng_reg_his_entry - history entry for single srng pointer + * register update + * @write_time: register write timestamp + * @write_value: register write value + */ +struct hal_srng_reg_his_entry { + qdf_time_t write_time; + uint32_t write_value; +}; + +/** + * struct hal_srng_reg_his_ctx - context for srng pointer writing history + * @current_idx: the index which has recorded srng pointer writing + * @reg_his_arr: array to record the history + */ +struct hal_srng_reg_his_ctx { + qdf_atomic_t current_idx; + struct hal_srng_reg_his_entry reg_his_arr[HAL_SRNG_REG_MAX_ENTRIES]; +}; +#endif + /* Common SRNG ring structure for source and destination rings */ struct hal_srng { /* Unique SRNG ring ID */ @@ -847,8 +873,60 @@ struct hal_srng { uint16_t pointer_timer_threshold; /* Number threshold of ring entries to issue pointer update */ uint8_t pointer_num_threshold; +#ifdef HAL_SRNG_REG_HIS_DEBUG + /* pointer register writing history for this srng */ + struct hal_srng_reg_his_ctx reg_his_ctx; +#endif }; +#ifdef HAL_SRNG_REG_HIS_DEBUG +/** + * hal_srng_reg_his_init() - SRNG register history context initialize + * + * @srng: SRNG handle pointer + * + * Return: None + */ +static inline +void hal_srng_reg_his_init(struct hal_srng *srng) +{ + qdf_atomic_set(&srng->reg_his_ctx.current_idx, -1); +} + +/** + * hal_srng_reg_his_add() - add pointer writing history to SRNG + * + * @srng: SRNG handle pointer + * @reg_val: pointer value to write + * + * Return: None + */ +static inline +void hal_srng_reg_his_add(struct hal_srng *srng, uint32_t reg_val) +{ + uint32_t write_idx; + struct hal_srng_reg_his_entry *reg_his_entry; + + write_idx = qdf_atomic_inc_return(&srng->reg_his_ctx.current_idx); + write_idx = write_idx & (HAL_SRNG_REG_MAX_ENTRIES - 1); + + reg_his_entry = &srng->reg_his_ctx.reg_his_arr[write_idx]; + + reg_his_entry->write_time = qdf_get_log_timestamp(); + reg_his_entry->write_value = reg_val; +} +#else +static inline +void hal_srng_reg_his_init(struct hal_srng *srng) +{ +} + +static inline +void hal_srng_reg_his_add(struct hal_srng *srng, uint32_t reg_val) +{ +} +#endif + /* HW SRNG configuration table */ struct hal_hw_srng_config { int start_ring_id; diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 09c2dd8c89..f5c15948db 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -686,6 +686,7 @@ hal_process_reg_write_q_elem(struct hal_soc *hal, srng->u.dst_ring.tp, false); write_val = srng->u.dst_ring.tp; } + hal_srng_reg_his_add(srng, write_val); q_elem->valid = 0; srng->last_dequeue_time = q_elem->dequeue_time; @@ -1056,6 +1057,7 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc, PLD_MHI_STATE_L0 == pld_get_mhi_state(hal_soc->qdf_dev->dev))) { hal_write_address_32_mb(hal_soc, addr, value, false); + hal_srng_reg_his_add(srng, value); qdf_atomic_inc(&hal_soc->stats.wstats.direct); srng->wstats.direct++; } else { @@ -1070,6 +1072,7 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc, PLD_MHI_STATE_L0 == pld_get_mhi_state(hal_soc->qdf_dev->dev)) { hal_write_address_32_mb(hal_soc, addr, value, false); + hal_srng_reg_his_add(srng, value); qdf_atomic_inc(&hal_soc->stats.wstats.direct); srng->wstats.direct++; } else { @@ -1090,6 +1093,7 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc, qdf_atomic_inc(&hal_soc->stats.wstats.direct); srng->wstats.direct++; hal_write_address_32_mb(hal_soc, addr, value, false); + hal_srng_reg_his_add(srng, value); } else { hal_reg_write_enqueue(hal_soc, srng, addr, value); } @@ -1556,6 +1560,7 @@ void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, int mac_id, return NULL; } + hal_srng_reg_his_init(srng); dev_base_addr = hal->dev_base_addr; srng->ring_id = ring_id; srng->ring_type = ring_type;