diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index efaf5cf2c8..d39f40de15 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4481,6 +4481,41 @@ static QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev) return QDF_STATUS_SUCCESS; } +#ifdef DP_TX_HW_DESC_HISTORY +/** + * dp_soc_tx_hw_desc_history_attach - Attach TX HW descriptor history + * + * @soc: DP soc handle + * + * Return: None + */ +static void dp_soc_tx_hw_desc_history_attach(struct dp_soc *soc) +{ + soc->tx_hw_desc_history = dp_context_alloc_mem( + soc, DP_TX_HW_DESC_HIST_TYPE, + sizeof(struct dp_tx_hw_desc_evt)); + if (soc->tx_hw_desc_history) + soc->tx_hw_desc_history->index = 0; +} + +static void dp_soc_tx_hw_desc_history_detach(struct dp_soc *soc) +{ + dp_context_free_mem(soc, DP_TX_HW_DESC_HIST_TYPE, + soc->tx_hw_desc_history); +} + +#else /* DP_TX_HW_DESC_HISTORY */ +static inline void +dp_soc_tx_hw_desc_history_attach(struct dp_soc *soc) +{ +} + +static inline void +dp_soc_tx_hw_desc_history_detach(struct dp_soc *soc) +{ +} +#endif /* DP_TX_HW_DESC_HISTORY */ + #ifdef WLAN_FEATURE_DP_RX_RING_HISTORY #ifndef RX_DEFRAG_DO_NOT_REINJECT /** @@ -5157,6 +5192,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc) dp_hw_link_desc_ring_free(soc); dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID); wlan_cfg_soc_detach(soc->wlan_cfg_ctx); + dp_soc_tx_hw_desc_history_detach(soc); dp_soc_rx_history_detach(soc); if (soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) { qdf_timer_free(&soc->mon_vdev_timer); @@ -12687,6 +12723,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, /* Reset wbm sg list and flags */ dp_rx_wbm_sg_list_reset(soc); + dp_soc_tx_hw_desc_history_attach(soc); dp_soc_rx_history_attach(soc); wlan_set_srng_cfg(&soc->wlan_srng_cfg); soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index fde4ba8f08..7ecb659e9e 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -1392,6 +1392,34 @@ dp_tx_ring_access_end_wrapper(struct dp_soc *soc, } #endif +#ifdef DP_TX_HW_DESC_HISTORY +static inline void +dp_tx_hw_desc_update_evt(uint8_t *hal_tx_desc_cached, + hal_ring_handle_t hal_ring_hdl, + struct dp_soc *soc) +{ + struct dp_tx_hw_desc_evt *evt; + uint64_t idx = 0; + + idx = ++soc->tx_hw_desc_history->index; + if (idx == DP_TX_HW_DESC_HIST_MAX) + soc->tx_hw_desc_history->index = 0; + idx = (idx % DP_TX_HW_DESC_HIST_MAX); + + evt = &soc->tx_hw_desc_history->entry[idx]; + qdf_mem_copy(evt->tcl_desc, hal_tx_desc_cached, HAL_TX_DESC_LEN_BYTES); + evt->posted = qdf_get_log_timestamp(); + hal_get_sw_hptp(soc->hal_soc, hal_ring_hdl, &evt->tp, &evt->hp); +} +#else +static inline void +dp_tx_hw_desc_update_evt(uint8_t *hal_tx_desc_cached, + hal_ring_handle_t hal_ring_hdl, + struct dp_soc *soc) +{ +} +#endif + /** * dp_tx_hw_enqueue() - Enqueue to TCL HW for transmit * @soc: DP Soc Handle @@ -1526,6 +1554,9 @@ dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, dp_tx_update_stats(soc, tx_desc->nbuf); status = QDF_STATUS_SUCCESS; + dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached, + hal_ring_hdl, soc); + ring_access_fail: dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl, coalesce); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 552032f37f..c8f88c6747 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -380,6 +380,7 @@ struct dp_rx_nbuf_frag_info { * @DP_RX_ERR_RING_HIST_TYPE: Datapath rx error ring history * @DP_RX_REINJECT_RING_HIST_TYPE: Datapath reinject ring history * @DP_RX_REFILL_RING_HIST_TYPE: Datapath rx refill ring history + * @DP_TX_HW_DESC_HIST_TYPE: Datapath TX HW descriptor history */ enum dp_ctxt_type { DP_PDEV_TYPE, @@ -388,6 +389,7 @@ enum dp_ctxt_type { DP_RX_REINJECT_RING_HIST_TYPE, DP_FISA_RX_FT_TYPE, DP_RX_REFILL_RING_HIST_TYPE, + DP_TX_HW_DESC_HIST_TYPE, }; /** @@ -1165,6 +1167,26 @@ struct rx_refill_buff_pool { bool is_initialized; }; +#ifdef DP_TX_HW_DESC_HISTORY +#define DP_TX_HW_DESC_HIST_MAX 6144 + +struct dp_tx_hw_desc_evt { + uint8_t tcl_desc[HAL_TX_DESC_LEN_BYTES]; + uint64_t posted; + uint32_t hp; + uint32_t tp; +}; + +/* struct dp_tx_hw_desc_history - TX HW desc hisotry + * @index: Index where the last entry is written + * @entry: history entries + */ +struct dp_tx_hw_desc_history { + uint64_t index; + struct dp_tx_hw_desc_evt entry[DP_TX_HW_DESC_HIST_MAX]; +}; +#endif + #ifdef WLAN_FEATURE_DP_RX_RING_HISTORY /* * The logic for get current index of these history is dependent on this @@ -1653,6 +1675,10 @@ struct dp_soc { TAILQ_HEAD(, dp_ast_entry) * bins; } ast_hash; +#ifdef DP_TX_HW_DESC_HISTORY + struct dp_tx_hw_desc_history *tx_hw_desc_history; +#endif + #ifdef WLAN_FEATURE_DP_RX_RING_HISTORY struct dp_rx_history *rx_ring_history[MAX_REO_DEST_RINGS]; struct dp_rx_refill_history *rx_refill_ring_history[MAX_PDEV_CNT];