qcacmn: Support HW Tx completion delay and Tx enqueue stats

- Add support to compute HW Tx completion delay on WKK
- Define arch op to calculate delay

Change-Id: I82567cc781e90fe01dc5a0edfffacd4cde73f652
CRs-Fixed: 3220911
This commit is contained in:
Ripan Deuri
2022-06-05 16:40:21 +05:30
committed by Madan Koyyalamudi
parent b8fadd7061
commit fc7daffbd0
7 changed files with 156 additions and 0 deletions

View File

@@ -1779,6 +1779,7 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
dp_peer_rx_reorder_queue_setup_be; dp_peer_rx_reorder_queue_setup_be;
arch_ops->txrx_print_peer_stats = dp_print_peer_txrx_stats_be; arch_ops->txrx_print_peer_stats = dp_print_peer_txrx_stats_be;
arch_ops->dp_find_peer_by_destmac = dp_find_peer_by_destmac_be; arch_ops->dp_find_peer_by_destmac = dp_find_peer_by_destmac_be;
arch_ops->dp_tx_compute_hw_delay = dp_tx_compute_tx_delay_be;
dp_init_near_full_arch_ops_be(arch_ops); dp_init_near_full_arch_ops_be(arch_ops);
arch_ops->get_rx_hash_key = dp_get_rx_hash_key_be; arch_ops->get_rx_hash_key = dp_get_rx_hash_key_be;
} }

View File

@@ -549,6 +549,20 @@ void dp_sawf_config_be(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
uint16_t *fw_metadata, qdf_nbuf_t nbuf) uint16_t *fw_metadata, qdf_nbuf_t nbuf)
{ {
} }
static inline
QDF_STATUS dp_sawf_tx_enqueue_peer_stats(struct dp_soc *soc,
struct dp_tx_desc_s *tx_desc)
{
return QDF_STATUS_SUCCESS;
}
static inline
QDF_STATUS dp_sawf_tx_enqueue_fail_peer_stats(struct dp_soc *soc,
struct dp_tx_desc_s *tx_desc)
{
return QDF_STATUS_SUCCESS;
}
#endif #endif
QDF_STATUS QDF_STATUS
@@ -594,6 +608,7 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
if (dp_sawf_tag_valid_get(tx_desc->nbuf)) { if (dp_sawf_tag_valid_get(tx_desc->nbuf)) {
dp_sawf_config_be(soc, hal_tx_desc_cached, dp_sawf_config_be(soc, hal_tx_desc_cached,
&fw_metadata, tx_desc->nbuf); &fw_metadata, tx_desc->nbuf);
dp_sawf_tx_enqueue_peer_stats(soc, tx_desc);
} }
hal_tx_desc_set_buf_addr_be(soc->hal_soc, hal_tx_desc_cached, hal_tx_desc_set_buf_addr_be(soc->hal_soc, hal_tx_desc_cached,
@@ -644,6 +659,7 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl); dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1); DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1); DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
dp_sawf_tx_enqueue_fail_peer_stats(soc, tx_desc);
return status; return status;
} }
@@ -652,6 +668,7 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
dp_verbose_debug("TCL ring full ring_id:%d", ring_id); dp_verbose_debug("TCL ring full ring_id:%d", ring_id);
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1); DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1); DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
dp_sawf_tx_enqueue_fail_peer_stats(soc, tx_desc);
goto ring_access_fail; goto ring_access_fail;
} }
@@ -942,3 +959,81 @@ uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
return work_done; return work_done;
} }
#endif #endif
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
defined(CONFIG_SAWF)
#define PPDUID_GET_HW_LINK_ID(PPDU_ID, LINK_ID_OFFSET, LINK_ID_BITS) \
(((PPDU_ID) >> (LINK_ID_OFFSET)) & ((1 << (LINK_ID_BITS)) - 1))
#define HW_TX_DELAY_MAX 0x1000000
#define TX_COMPL_SHIFT_BUFFER_TIMESTAMP_US 10
#define HW_TX_DELAY_MASK 0x1FFFFFFF
#define TX_COMPL_BUFFER_TSTAMP_US(TSTAMP) \
(((TSTAMP) << TX_COMPL_SHIFT_BUFFER_TIMESTAMP_US) & \
HW_TX_DELAY_MASK)
static inline
QDF_STATUS dp_mlo_compute_hw_delay_us(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us)
{
uint32_t ppdu_id;
uint8_t link_id_offset, link_id_bits;
uint8_t hw_link_id;
uint32_t msdu_tqm_enqueue_tstamp_us, final_msdu_tqm_enqueue_tstamp_us;
uint32_t msdu_compl_tsf_tstamp_us, final_msdu_compl_tsf_tstamp_us;
uint32_t delay;
int32_t delta_tsf2, delta_tqm;
if (!ts->valid)
return QDF_STATUS_E_INVAL;
link_id_offset = soc->link_id_offset;
link_id_bits = soc->link_id_bits;
ppdu_id = ts->ppdu_id;
hw_link_id = PPDUID_GET_HW_LINK_ID(ppdu_id, link_id_offset,
link_id_bits);
msdu_tqm_enqueue_tstamp_us =
TX_COMPL_BUFFER_TSTAMP_US(ts->buffer_timestamp);
msdu_compl_tsf_tstamp_us = ts->tsf;
delta_tsf2 = dp_mlo_get_delta_tsf2_wrt_mlo_offset(soc, hw_link_id);
delta_tqm = dp_mlo_get_delta_tqm_wrt_mlo_offset(soc);
final_msdu_tqm_enqueue_tstamp_us = (msdu_tqm_enqueue_tstamp_us +
delta_tqm) & HW_TX_DELAY_MASK;
final_msdu_compl_tsf_tstamp_us = (msdu_compl_tsf_tstamp_us +
delta_tsf2) & HW_TX_DELAY_MASK;
delay = (final_msdu_compl_tsf_tstamp_us -
final_msdu_tqm_enqueue_tstamp_us) & HW_TX_DELAY_MASK;
if (delay > HW_TX_DELAY_MAX)
return QDF_STATUS_E_FAILURE;
if (delay_us)
*delay_us = delay;
return QDF_STATUS_SUCCESS;
}
#else
static inline
QDF_STATUS dp_mlo_compute_hw_delay_us(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us)
{
return QDF_STATUS_SUCCESS;
}
#endif
QDF_STATUS dp_tx_compute_tx_delay_be(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us)
{
return dp_mlo_compute_hw_delay_us(soc, vdev, ts, delay_us);
}

View File

@@ -226,4 +226,18 @@ uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
return 0; return 0;
} }
#endif /* WLAN_FEATURE_NEAR_FULL_IRQ */ #endif /* WLAN_FEATURE_NEAR_FULL_IRQ */
/**
* dp_tx_compute_tx_delay_be() - Compute HW Tx completion delay
* @soc: Handle to DP Soc structure
* @vdev: vdev
* @ts: Tx completion status
* @delay_us: Delay to be calculated in microseconds
*
* Return: QDF_STATUS
*/
QDF_STATUS dp_tx_compute_tx_delay_be(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us);
#endif #endif

View File

@@ -1863,6 +1863,11 @@ struct dp_arch_ops {
struct dp_peer *(*dp_find_peer_by_destmac)(struct dp_soc *soc, struct dp_peer *(*dp_find_peer_by_destmac)(struct dp_soc *soc,
uint8_t *dest_mac_addr, uint8_t *dest_mac_addr,
uint8_t vdev_id); uint8_t vdev_id);
QDF_STATUS
(*dp_tx_compute_hw_delay)(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us);
}; };
/** /**

View File

@@ -607,6 +607,7 @@ void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops)
arch_ops->dp_peer_rx_reorder_queue_setup = arch_ops->dp_peer_rx_reorder_queue_setup =
dp_peer_rx_reorder_queue_setup_li; dp_peer_rx_reorder_queue_setup_li;
arch_ops->dp_find_peer_by_destmac = dp_find_peer_by_destmac_li; arch_ops->dp_find_peer_by_destmac = dp_find_peer_by_destmac_li;
arch_ops->dp_tx_compute_hw_delay = dp_tx_compute_tx_delay_li;
} }
#ifdef QCA_DP_TX_HW_SW_NBUF_DESC_PREFETCH #ifdef QCA_DP_TX_HW_SW_NBUF_DESC_PREFETCH

View File

@@ -368,6 +368,15 @@ void dp_sawf_config_li(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
hal_tx_desc_set_search_index_li(soc->hal_soc, hal_tx_desc_cached, hal_tx_desc_set_search_index_li(soc->hal_soc, hal_tx_desc_cached,
search_index); search_index);
} }
static inline
QDF_STATUS dp_tx_compute_hw_delay_li(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us)
{
return dp_tx_compute_hw_delay_us(ts, vdev->delta_tsf, delay_us);
}
#else #else
static inline static inline
void dp_sawf_config_li(struct dp_soc *soc, uint32_t *hal_tx_desc_cached, void dp_sawf_config_li(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
@@ -376,6 +385,15 @@ void dp_sawf_config_li(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
{ {
} }
static inline
QDF_STATUS dp_tx_compute_hw_delay_li(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us)
{
return QDF_STATUS_SUCCESS;
}
#define dp_sawf_tx_enqueue_peer_stats(soc, tx_desc) #define dp_sawf_tx_enqueue_peer_stats(soc, tx_desc)
#define dp_sawf_tx_enqueue_fail_peer_stats(soc, tx_desc) #define dp_sawf_tx_enqueue_fail_peer_stats(soc, tx_desc)
#endif #endif
@@ -554,3 +572,11 @@ void dp_tx_desc_pool_deinit_li(struct dp_soc *soc,
uint8_t pool_id) uint8_t pool_id)
{ {
} }
QDF_STATUS dp_tx_compute_tx_delay_li(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us)
{
return dp_tx_compute_hw_delay_li(soc, vdev, ts, delay_us);
}

View File

@@ -93,4 +93,18 @@ QDF_STATUS dp_tx_desc_pool_init_li(struct dp_soc *soc,
void dp_tx_desc_pool_deinit_li(struct dp_soc *soc, void dp_tx_desc_pool_deinit_li(struct dp_soc *soc,
struct dp_tx_desc_pool_s *tx_desc_pool, struct dp_tx_desc_pool_s *tx_desc_pool,
uint8_t pool_id); uint8_t pool_id);
/**
* dp_tx_compute_tx_delay_li() - Compute HW Tx completion delay
* @soc: Handle to DP Soc structure
* @vdev: vdev
* @ts: Tx completion status
* @delay_us: Delay to be calculated in microseconds
*
* Return: QDF_STATUS
*/
QDF_STATUS dp_tx_compute_tx_delay_li(struct dp_soc *soc,
struct dp_vdev *vdev,
struct hal_tx_completion_status *ts,
uint32_t *delay_us);
#endif #endif