qcacmn: Fix tx completion and rx stats per wbm/reo ring
Tx completion stats should be counted per wbm ring on tx completion and not globally. Similarly, rx stats should be counter per reo ring. Change-Id: I1e4af0d38b23e60de78ca03316861db08ff0811a
This commit is contained in:
@@ -71,7 +71,8 @@
|
|||||||
#define WME_AC_VO 3 /* voice */
|
#define WME_AC_VO 3 /* voice */
|
||||||
#define WME_AC_MAX 4 /* MAX AC Value */
|
#define WME_AC_MAX 4 /* MAX AC Value */
|
||||||
|
|
||||||
#define CDP_MAX_RX_RINGS 4
|
#define CDP_MAX_RX_RINGS 4 /* max rx rings */
|
||||||
|
#define CDP_MAX_TX_COMP_RINGS 3 /* max tx completion rings */
|
||||||
|
|
||||||
/* TID level VoW stats macros
|
/* TID level VoW stats macros
|
||||||
* to add and get stats
|
* to add and get stats
|
||||||
@@ -291,8 +292,7 @@ struct cdp_delay_stats {
|
|||||||
* @hwtx_delay: delay between wifi driver exit (enqueue to HW) and tx completion
|
* @hwtx_delay: delay between wifi driver exit (enqueue to HW) and tx completion
|
||||||
* @intfrm_delay: interframe delay
|
* @intfrm_delay: interframe delay
|
||||||
* @success_cnt: total successful transmit count
|
* @success_cnt: total successful transmit count
|
||||||
* @complete_cnt: total transmit count
|
* @comp_fail_cnt: firmware drop found in tx completion path
|
||||||
* @fwdrop_cnt: firmware drop found in tx completion path
|
|
||||||
* @swdrop_cnt: software drop in tx path
|
* @swdrop_cnt: software drop in tx path
|
||||||
*/
|
*/
|
||||||
struct cdp_tid_tx_stats {
|
struct cdp_tid_tx_stats {
|
||||||
@@ -300,7 +300,6 @@ struct cdp_tid_tx_stats {
|
|||||||
struct cdp_delay_stats hwtx_delay;
|
struct cdp_delay_stats hwtx_delay;
|
||||||
struct cdp_delay_stats intfrm_delay;
|
struct cdp_delay_stats intfrm_delay;
|
||||||
uint64_t success_cnt;
|
uint64_t success_cnt;
|
||||||
uint64_t complete_cnt;
|
|
||||||
uint64_t comp_fail_cnt;
|
uint64_t comp_fail_cnt;
|
||||||
uint64_t swdrop_cnt[TX_MAX_DROP];
|
uint64_t swdrop_cnt[TX_MAX_DROP];
|
||||||
};
|
};
|
||||||
@@ -330,14 +329,17 @@ struct cdp_tid_rx_stats {
|
|||||||
/*
|
/*
|
||||||
* struct cdp_tid_stats
|
* struct cdp_tid_stats
|
||||||
* @ingress_stack: Total packets received from linux stack
|
* @ingress_stack: Total packets received from linux stack
|
||||||
|
* @osif_drop: drops in osif layer
|
||||||
* @tid_tx_stats: transmit counters per tid
|
* @tid_tx_stats: transmit counters per tid
|
||||||
* @tid_rx_stats: receive counters per tid
|
* @tid_rx_stats: receive counters per tid
|
||||||
*/
|
*/
|
||||||
struct cdp_tid_stats {
|
struct cdp_tid_stats {
|
||||||
uint64_t ingress_stack;
|
uint64_t ingress_stack;
|
||||||
uint64_t osif_drop;
|
uint64_t osif_drop;
|
||||||
struct cdp_tid_tx_stats tid_tx_stats[CDP_MAX_DATA_TIDS];
|
struct cdp_tid_tx_stats tid_tx_stats[CDP_MAX_TX_COMP_RINGS]
|
||||||
struct cdp_tid_rx_stats tid_rx_stats[CDP_MAX_DATA_TIDS];
|
[CDP_MAX_DATA_TIDS];
|
||||||
|
struct cdp_tid_rx_stats tid_rx_stats[CDP_MAX_RX_RINGS]
|
||||||
|
[CDP_MAX_DATA_TIDS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct cdp_pkt_info - packet info
|
/* struct cdp_pkt_info - packet info
|
||||||
|
@@ -858,8 +858,19 @@ uint32_t dp_pdev_tid_stats_display(void *pdev_handle,
|
|||||||
enum _ol_ath_param_t param, uint32_t value, void *buff);
|
enum _ol_ath_param_t param, uint32_t value, void *buff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_update_delay_stats() - Update delay statistics in structure
|
||||||
|
* and fill min, max and avg delay
|
||||||
|
* @pdev: pdev handle
|
||||||
|
* @delay: delay in ms
|
||||||
|
* @tid: tid value
|
||||||
|
* @mode: type of tx delay mode
|
||||||
|
* @ring id: ring number
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay,
|
void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay,
|
||||||
uint8_t tid, uint8_t mode);
|
uint8_t tid, uint8_t mode, uint8_t ring_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_print_ring_stats(): Print tail and head pointer
|
* dp_print_ring_stats(): Print tail and head pointer
|
||||||
|
@@ -1619,29 +1619,22 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
|
|||||||
struct dp_vdev *vdev,
|
struct dp_vdev *vdev,
|
||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
struct cdp_tid_rx_stats *tid_stats;
|
|
||||||
struct dp_peer *vdev_peer;
|
struct dp_peer *vdev_peer;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t tid;
|
|
||||||
|
|
||||||
vdev_peer = vdev->vap_bss_peer;
|
vdev_peer = vdev->vap_bss_peer;
|
||||||
if (qdf_unlikely(!vdev_peer))
|
if (qdf_unlikely(!vdev_peer))
|
||||||
return nbuf;
|
return nbuf;
|
||||||
|
|
||||||
tid = qdf_nbuf_get_priority(nbuf);
|
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_rx_stats[tid];
|
|
||||||
|
|
||||||
qdf_mem_zero(nbuf->cb, sizeof(nbuf->cb));
|
qdf_mem_zero(nbuf->cb, sizeof(nbuf->cb));
|
||||||
len = qdf_nbuf_len(nbuf);
|
len = qdf_nbuf_len(nbuf);
|
||||||
|
|
||||||
if (dp_tx_send(vdev, nbuf)) {
|
if (dp_tx_send(vdev, nbuf)) {
|
||||||
DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len);
|
DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len);
|
||||||
tid_stats->fail_cnt[INTRABSS_DROP]++;
|
|
||||||
return nbuf;
|
return nbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.pkts, 1, len);
|
DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.pkts, 1, len);
|
||||||
tid_stats->intrabss_cnt++;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1394,7 +1394,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||||||
work_done = dp_tx_comp_handler(int_ctx,
|
work_done = dp_tx_comp_handler(int_ctx,
|
||||||
soc,
|
soc,
|
||||||
soc->tx_comp_ring[ring].hal_srng,
|
soc->tx_comp_ring[ring].hal_srng,
|
||||||
remaining_quota);
|
ring, remaining_quota);
|
||||||
|
|
||||||
if (work_done) {
|
if (work_done) {
|
||||||
intr_stats->num_tx_ring_masks[ring]++;
|
intr_stats->num_tx_ring_masks[ring]++;
|
||||||
@@ -9635,19 +9635,20 @@ static uint8_t dp_bucket_index(uint32_t delay, uint16_t *array)
|
|||||||
*
|
*
|
||||||
* @pdev: pdev handle
|
* @pdev: pdev handle
|
||||||
* @delay: delay in ms
|
* @delay: delay in ms
|
||||||
* @t: tid value
|
* @tid: tid value
|
||||||
* @mode: type of tx delay mode
|
* @mode: type of tx delay mode
|
||||||
|
* @ring_id: ring number
|
||||||
* Return: pointer to cdp_delay_stats structure
|
* Return: pointer to cdp_delay_stats structure
|
||||||
*/
|
*/
|
||||||
static struct cdp_delay_stats *
|
static struct cdp_delay_stats *
|
||||||
dp_fill_delay_buckets(struct dp_pdev *pdev, uint32_t delay,
|
dp_fill_delay_buckets(struct dp_pdev *pdev, uint32_t delay,
|
||||||
uint8_t tid, uint8_t mode)
|
uint8_t tid, uint8_t mode, uint8_t ring_id)
|
||||||
{
|
{
|
||||||
uint8_t delay_index = 0;
|
uint8_t delay_index = 0;
|
||||||
struct cdp_tid_tx_stats *tstats =
|
struct cdp_tid_tx_stats *tstats =
|
||||||
&pdev->stats.tid_stats.tid_tx_stats[tid];
|
&pdev->stats.tid_stats.tid_tx_stats[ring_id][tid];
|
||||||
struct cdp_tid_rx_stats *rstats =
|
struct cdp_tid_rx_stats *rstats =
|
||||||
&pdev->stats.tid_stats.tid_rx_stats[tid];
|
&pdev->stats.tid_stats.tid_rx_stats[ring_id][tid];
|
||||||
/*
|
/*
|
||||||
* cdp_fw_to_hw_delay_range
|
* cdp_fw_to_hw_delay_range
|
||||||
* Fw to hw delay ranges in milliseconds
|
* Fw to hw delay ranges in milliseconds
|
||||||
@@ -9723,10 +9724,11 @@ dp_fill_delay_buckets(struct dp_pdev *pdev, uint32_t delay,
|
|||||||
* @delay: delay in ms
|
* @delay: delay in ms
|
||||||
* @tid: tid value
|
* @tid: tid value
|
||||||
* @mode: type of tx delay mode
|
* @mode: type of tx delay mode
|
||||||
|
* @ring id: ring number
|
||||||
* Return: none
|
* Return: none
|
||||||
*/
|
*/
|
||||||
void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay,
|
void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay,
|
||||||
uint8_t tid, uint8_t mode)
|
uint8_t tid, uint8_t mode, uint8_t ring_id)
|
||||||
{
|
{
|
||||||
struct cdp_delay_stats *dstats = NULL;
|
struct cdp_delay_stats *dstats = NULL;
|
||||||
|
|
||||||
@@ -9734,7 +9736,7 @@ void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay,
|
|||||||
* Delay ranges are different for different delay modes
|
* Delay ranges are different for different delay modes
|
||||||
* Get the correct index to update delay bucket
|
* Get the correct index to update delay bucket
|
||||||
*/
|
*/
|
||||||
dstats = dp_fill_delay_buckets(pdev, delay, tid, mode);
|
dstats = dp_fill_delay_buckets(pdev, delay, tid, mode, ring_id);
|
||||||
if (qdf_unlikely(!dstats))
|
if (qdf_unlikely(!dstats))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -393,8 +393,9 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
|
|||||||
struct dp_ast_entry *ast_entry;
|
struct dp_ast_entry *ast_entry;
|
||||||
qdf_nbuf_t nbuf_copy;
|
qdf_nbuf_t nbuf_copy;
|
||||||
uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
|
uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
|
||||||
struct cdp_tid_rx_stats *tid_stats =
|
uint8_t ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
|
||||||
&ta_peer->vdev->pdev->stats.tid_stats.tid_rx_stats[tid];
|
struct cdp_tid_rx_stats *tid_stats = &ta_peer->vdev->pdev->stats.
|
||||||
|
tid_stats.tid_rx_stats[ring_id][tid];
|
||||||
|
|
||||||
/* check if the destination peer is available in peer table
|
/* check if the destination peer is available in peer table
|
||||||
* and also check if the source peer and destination peer
|
* and also check if the source peer and destination peer
|
||||||
@@ -1078,6 +1079,7 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
|
|||||||
*/
|
*/
|
||||||
void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
|
void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
|
uint8_t ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
|
||||||
int64_t current_ts = qdf_ktime_to_ms(qdf_ktime_get());
|
int64_t current_ts = qdf_ktime_to_ms(qdf_ktime_get());
|
||||||
uint32_t to_stack = qdf_nbuf_get_timedelta_ms(nbuf);
|
uint32_t to_stack = qdf_nbuf_get_timedelta_ms(nbuf);
|
||||||
uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
|
uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
|
||||||
@@ -1085,7 +1087,7 @@ void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
|
|||||||
(uint32_t)(current_ts - vdev->prev_rx_deliver_tstamp);
|
(uint32_t)(current_ts - vdev->prev_rx_deliver_tstamp);
|
||||||
|
|
||||||
dp_update_delay_stats(vdev->pdev, to_stack, tid,
|
dp_update_delay_stats(vdev->pdev, to_stack, tid,
|
||||||
CDP_DELAY_STATS_REAP_STACK);
|
CDP_DELAY_STATS_REAP_STACK, ring_id);
|
||||||
/*
|
/*
|
||||||
* Update interframe delay stats calculated at deliver_data_ol point.
|
* Update interframe delay stats calculated at deliver_data_ol point.
|
||||||
* Value of vdev->prev_rx_deliver_tstamp will be 0 for 1st frame, so
|
* Value of vdev->prev_rx_deliver_tstamp will be 0 for 1st frame, so
|
||||||
@@ -1094,7 +1096,7 @@ void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
|
|||||||
* of vdev->prev_rx_deliver_tstamp.
|
* of vdev->prev_rx_deliver_tstamp.
|
||||||
*/
|
*/
|
||||||
dp_update_delay_stats(vdev->pdev, interframe_delay, tid,
|
dp_update_delay_stats(vdev->pdev, interframe_delay, tid,
|
||||||
CDP_DELAY_STATS_RX_INTERFRAME);
|
CDP_DELAY_STATS_RX_INTERFRAME, ring_id);
|
||||||
vdev->prev_rx_deliver_tstamp = current_ts;
|
vdev->prev_rx_deliver_tstamp = current_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,15 +1111,16 @@ static inline int dp_rx_drop_nbuf_list(struct dp_pdev *pdev,
|
|||||||
qdf_nbuf_t buf_list)
|
qdf_nbuf_t buf_list)
|
||||||
{
|
{
|
||||||
struct cdp_tid_rx_stats *stats = NULL;
|
struct cdp_tid_rx_stats *stats = NULL;
|
||||||
uint8_t tid = 0;
|
uint8_t tid = 0, ring_id = 0;
|
||||||
int num_dropped = 0;
|
int num_dropped = 0;
|
||||||
qdf_nbuf_t buf, next_buf;
|
qdf_nbuf_t buf, next_buf;
|
||||||
|
|
||||||
buf = buf_list;
|
buf = buf_list;
|
||||||
while (buf) {
|
while (buf) {
|
||||||
|
ring_id = QDF_NBUF_CB_RX_CTX_ID(buf);
|
||||||
next_buf = qdf_nbuf_queue_next(buf);
|
next_buf = qdf_nbuf_queue_next(buf);
|
||||||
tid = qdf_nbuf_get_tid_val(buf);
|
tid = qdf_nbuf_get_tid_val(buf);
|
||||||
stats = &pdev->stats.tid_stats.tid_rx_stats[tid];
|
stats = &pdev->stats.tid_stats.tid_rx_stats[ring_id][tid];
|
||||||
stats->fail_cnt[INVALID_PEER_VDEV]++;
|
stats->fail_cnt[INVALID_PEER_VDEV]++;
|
||||||
stats->delivered_to_stack--;
|
stats->delivered_to_stack--;
|
||||||
qdf_nbuf_free(buf);
|
qdf_nbuf_free(buf);
|
||||||
@@ -1816,7 +1819,8 @@ done:
|
|||||||
if (qdf_unlikely(rx_pdev->delay_stats_flag))
|
if (qdf_unlikely(rx_pdev->delay_stats_flag))
|
||||||
qdf_nbuf_set_timestamp(nbuf);
|
qdf_nbuf_set_timestamp(nbuf);
|
||||||
|
|
||||||
tid_stats = &rx_pdev->stats.tid_stats.tid_rx_stats[tid];
|
tid_stats = &rx_pdev->stats.tid_stats.
|
||||||
|
tid_rx_stats[ring_id][tid];
|
||||||
if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) {
|
if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) {
|
||||||
dp_err("MSDU DONE failure");
|
dp_err("MSDU DONE failure");
|
||||||
DP_STATS_INC(soc, rx.err.msdu_done_fail, 1);
|
DP_STATS_INC(soc, rx.err.msdu_done_fail, 1);
|
||||||
|
@@ -186,6 +186,9 @@ const char *intfrm_delay_bucket[CDP_DELAY_BUCKET_MAX + 1] = {
|
|||||||
#include "dp_tx_capture.h"
|
#include "dp_tx_capture.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TID_COUNTER_STATS 1 /* Success/drop stats type */
|
||||||
|
#define TID_DELAY_STATS 2 /* Delay stats type */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_print_stats_string_tlv: display htt_stats_string_tlv
|
* dp_print_stats_string_tlv: display htt_stats_string_tlv
|
||||||
* @tag_buf: buffer containing the tlv htt_stats_string_tlv
|
* @tag_buf: buffer containing the tlv htt_stats_string_tlv
|
||||||
@@ -4030,79 +4033,174 @@ static inline const char *dp_vow_str_intfrm_delay(uint8_t index)
|
|||||||
return intfrm_delay_bucket[index];
|
return intfrm_delay_bucket[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_accumulate_delay_stats() - Update delay stats members
|
||||||
|
* @total: Update stats total structure
|
||||||
|
* @per_ring: per ring structures from where stats need to be accumulated
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dp_accumulate_delay_stats(struct cdp_delay_stats *total,
|
||||||
|
struct cdp_delay_stats *per_ring)
|
||||||
|
{
|
||||||
|
uint8_t index;
|
||||||
|
|
||||||
|
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++)
|
||||||
|
total->delay_bucket[index] += per_ring->delay_bucket[index];
|
||||||
|
total->min_delay = QDF_MIN(total->min_delay, per_ring->min_delay);
|
||||||
|
total->max_delay = QDF_MAX(total->max_delay, per_ring->max_delay);
|
||||||
|
total->avg_delay = (total->avg_delay + per_ring->avg_delay) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_accumulate_tid_stats() - Accumulate TID stats from each ring
|
||||||
|
* @pdev: pdev handle
|
||||||
|
* @tid: traffic ID
|
||||||
|
* @total_tx: fill this tx structure to get stats from all wbm rings
|
||||||
|
* @total_rx: fill this rx structure to get stats from all reo rings
|
||||||
|
* @type: delay stats or regular frame counters
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dp_accumulate_tid_stats(struct dp_pdev *pdev, uint8_t tid,
|
||||||
|
struct cdp_tid_tx_stats *total_tx,
|
||||||
|
struct cdp_tid_rx_stats *total_rx, uint8_t type)
|
||||||
|
{
|
||||||
|
uint8_t ring_id = 0, drop = 0;
|
||||||
|
struct cdp_tid_stats *tid_stats = &pdev->stats.tid_stats;
|
||||||
|
struct cdp_tid_tx_stats *per_ring_tx = NULL;
|
||||||
|
struct cdp_tid_rx_stats *per_ring_rx = NULL;
|
||||||
|
|
||||||
|
if (wlan_cfg_get_dp_soc_nss_cfg(pdev->soc->wlan_cfg_ctx)) {
|
||||||
|
qdf_mem_copy(total_tx, &tid_stats->tid_tx_stats[0][tid],
|
||||||
|
sizeof(struct cdp_tid_tx_stats));
|
||||||
|
qdf_mem_copy(total_rx, &tid_stats->tid_rx_stats[0][tid],
|
||||||
|
sizeof(struct cdp_tid_rx_stats));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qdf_mem_zero(total_tx, sizeof(struct cdp_tid_tx_stats));
|
||||||
|
qdf_mem_zero(total_rx, sizeof(struct cdp_tid_rx_stats));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case TID_COUNTER_STATS:
|
||||||
|
{
|
||||||
|
for (ring_id = 0; ring_id < CDP_MAX_TX_COMP_RINGS; ring_id++) {
|
||||||
|
per_ring_tx = &tid_stats->tid_tx_stats[ring_id][tid];
|
||||||
|
total_tx->success_cnt += per_ring_tx->success_cnt;
|
||||||
|
total_tx->comp_fail_cnt += per_ring_tx->comp_fail_cnt;
|
||||||
|
for (drop = 0; drop < TX_MAX_DROP; drop++)
|
||||||
|
total_tx->swdrop_cnt[drop] +=
|
||||||
|
per_ring_tx->swdrop_cnt[drop];
|
||||||
|
}
|
||||||
|
for (ring_id = 0; ring_id < CDP_MAX_RX_RINGS; ring_id++) {
|
||||||
|
per_ring_rx = &tid_stats->tid_rx_stats[ring_id][tid];
|
||||||
|
total_rx->delivered_to_stack +=
|
||||||
|
per_ring_rx->delivered_to_stack;
|
||||||
|
total_rx->intrabss_cnt += per_ring_rx->intrabss_cnt;
|
||||||
|
total_rx->msdu_cnt += per_ring_rx->msdu_cnt;
|
||||||
|
total_rx->mcast_msdu_cnt += per_ring_rx->mcast_msdu_cnt;
|
||||||
|
total_rx->bcast_msdu_cnt += per_ring_rx->bcast_msdu_cnt;
|
||||||
|
for (drop = 0; drop < RX_MAX_DROP; drop++)
|
||||||
|
total_rx->fail_cnt[drop] +=
|
||||||
|
per_ring_rx->fail_cnt[drop];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TID_DELAY_STATS:
|
||||||
|
{
|
||||||
|
for (ring_id = 0; ring_id < CDP_MAX_TX_COMP_RINGS; ring_id++) {
|
||||||
|
per_ring_tx = &tid_stats->tid_tx_stats[ring_id][tid];
|
||||||
|
dp_accumulate_delay_stats(&total_tx->swq_delay,
|
||||||
|
&per_ring_tx->swq_delay);
|
||||||
|
dp_accumulate_delay_stats(&total_tx->hwtx_delay,
|
||||||
|
&per_ring_tx->hwtx_delay);
|
||||||
|
dp_accumulate_delay_stats(&total_tx->intfrm_delay,
|
||||||
|
&per_ring_tx->intfrm_delay);
|
||||||
|
}
|
||||||
|
for (ring_id = 0; ring_id < CDP_MAX_RX_RINGS; ring_id++) {
|
||||||
|
per_ring_rx = &tid_stats->tid_rx_stats[ring_id][tid];
|
||||||
|
dp_accumulate_delay_stats(&total_rx->intfrm_delay,
|
||||||
|
&per_ring_rx->intfrm_delay);
|
||||||
|
dp_accumulate_delay_stats(&total_rx->to_stack_delay,
|
||||||
|
&per_ring_rx->to_stack_delay);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
qdf_err("Invalid stats type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dp_pdev_print_tid_stats(struct dp_pdev *pdev)
|
void dp_pdev_print_tid_stats(struct dp_pdev *pdev)
|
||||||
{
|
{
|
||||||
struct cdp_tid_stats *tid_stats;
|
struct cdp_tid_tx_stats total_tx;
|
||||||
struct cdp_tid_tx_stats *txstats;
|
struct cdp_tid_rx_stats total_rx;
|
||||||
struct cdp_tid_rx_stats *rxstats;
|
|
||||||
struct dp_soc *soc = pdev->soc;
|
|
||||||
uint8_t tid;
|
uint8_t tid;
|
||||||
|
|
||||||
if (!soc)
|
|
||||||
return;
|
|
||||||
tid = 0;
|
|
||||||
rxstats = NULL;
|
|
||||||
txstats = NULL;
|
|
||||||
tid_stats = &pdev->stats.tid_stats;
|
|
||||||
|
|
||||||
DP_PRINT_STATS("Packets received in hardstart: %llu ",
|
DP_PRINT_STATS("Packets received in hardstart: %llu ",
|
||||||
tid_stats->ingress_stack);
|
pdev->stats.tid_stats.ingress_stack);
|
||||||
DP_PRINT_STATS("Packets dropped in osif layer: %llu ",
|
DP_PRINT_STATS("Packets dropped in osif layer: %llu ",
|
||||||
tid_stats->osif_drop);
|
pdev->stats.tid_stats.osif_drop);
|
||||||
DP_PRINT_STATS("Per TID Video Stats:\n");
|
DP_PRINT_STATS("Per TID Video Stats:\n");
|
||||||
|
|
||||||
for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) {
|
for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) {
|
||||||
txstats = &tid_stats->tid_tx_stats[tid];
|
dp_accumulate_tid_stats(pdev, tid, &total_tx, &total_rx,
|
||||||
rxstats = &tid_stats->tid_rx_stats[tid];
|
TID_COUNTER_STATS);
|
||||||
DP_PRINT_STATS("----TID: %d----", tid);
|
DP_PRINT_STATS("----TID: %d----", tid);
|
||||||
DP_PRINT_STATS("Tx Success Count: %llu", txstats->success_cnt);
|
DP_PRINT_STATS("Tx Success Count: %llu", total_tx.success_cnt);
|
||||||
DP_PRINT_STATS("Tx Complete Count: %llu",
|
|
||||||
txstats->complete_cnt);
|
|
||||||
DP_PRINT_STATS("Tx Firmware Drop Count: %llu",
|
DP_PRINT_STATS("Tx Firmware Drop Count: %llu",
|
||||||
txstats->comp_fail_cnt);
|
total_tx.comp_fail_cnt);
|
||||||
DP_PRINT_STATS("Tx Hardware Drop Count: %llu",
|
DP_PRINT_STATS("Tx Hardware Drop Count: %llu",
|
||||||
txstats->swdrop_cnt[TX_HW_ENQUEUE]);
|
total_tx.swdrop_cnt[TX_HW_ENQUEUE]);
|
||||||
DP_PRINT_STATS("Tx Software Drop Count: %llu",
|
DP_PRINT_STATS("Tx Software Drop Count: %llu",
|
||||||
txstats->swdrop_cnt[TX_SW_ENQUEUE]);
|
total_tx.swdrop_cnt[TX_SW_ENQUEUE]);
|
||||||
DP_PRINT_STATS("Tx Descriptor Error Count: %llu",
|
DP_PRINT_STATS("Tx Descriptor Error Count: %llu",
|
||||||
txstats->swdrop_cnt[TX_DESC_ERR]);
|
total_tx.swdrop_cnt[TX_DESC_ERR]);
|
||||||
DP_PRINT_STATS("Tx HAL Ring Error Count: %llu",
|
DP_PRINT_STATS("Tx HAL Ring Error Count: %llu",
|
||||||
txstats->swdrop_cnt[TX_HAL_RING_ACCESS_ERR]);
|
total_tx.swdrop_cnt[TX_HAL_RING_ACCESS_ERR]);
|
||||||
DP_PRINT_STATS("Tx Dma Map Error Count: %llu",
|
DP_PRINT_STATS("Tx Dma Map Error Count: %llu",
|
||||||
txstats->swdrop_cnt[TX_DMA_MAP_ERR]);
|
total_tx.swdrop_cnt[TX_DMA_MAP_ERR]);
|
||||||
DP_PRINT_STATS("Rx Delievered Count: %llu",
|
DP_PRINT_STATS("Rx Delievered Count: %llu",
|
||||||
rxstats->delivered_to_stack);
|
total_rx.delivered_to_stack);
|
||||||
DP_PRINT_STATS("Rx Software Enqueue Drop Count: %llu",
|
DP_PRINT_STATS("Rx Software Enqueue Drop Count: %llu",
|
||||||
rxstats->fail_cnt[ENQUEUE_DROP]);
|
total_rx.fail_cnt[ENQUEUE_DROP]);
|
||||||
DP_PRINT_STATS("Rx Intrabss Drop Count: %llu",
|
DP_PRINT_STATS("Rx Intrabss Drop Count: %llu",
|
||||||
rxstats->fail_cnt[INTRABSS_DROP]);
|
total_rx.fail_cnt[INTRABSS_DROP]);
|
||||||
DP_PRINT_STATS("Rx Msdu Done Failure Count: %llu",
|
DP_PRINT_STATS("Rx Msdu Done Failure Count: %llu",
|
||||||
rxstats->fail_cnt[MSDU_DONE_FAILURE]);
|
total_rx.fail_cnt[MSDU_DONE_FAILURE]);
|
||||||
DP_PRINT_STATS("Rx Invalid Peer Count: %llu",
|
DP_PRINT_STATS("Rx Invalid Peer Count: %llu",
|
||||||
rxstats->fail_cnt[INVALID_PEER_VDEV]);
|
total_rx.fail_cnt[INVALID_PEER_VDEV]);
|
||||||
DP_PRINT_STATS("Rx Policy Check Drop Count: %llu",
|
DP_PRINT_STATS("Rx Policy Check Drop Count: %llu",
|
||||||
rxstats->fail_cnt[POLICY_CHECK_DROP]);
|
total_rx.fail_cnt[POLICY_CHECK_DROP]);
|
||||||
DP_PRINT_STATS("Rx Mec Drop Count: %llu",
|
DP_PRINT_STATS("Rx Mec Drop Count: %llu",
|
||||||
rxstats->fail_cnt[MEC_DROP]);
|
total_rx.fail_cnt[MEC_DROP]);
|
||||||
DP_PRINT_STATS("Rx Nawds Mcast Drop Count: %llu",
|
DP_PRINT_STATS("Rx Nawds Mcast Drop Count: %llu",
|
||||||
rxstats->fail_cnt[NAWDS_MCAST_DROP]);
|
total_rx.fail_cnt[NAWDS_MCAST_DROP]);
|
||||||
DP_PRINT_STATS("Rx Mesh Filter Drop Count: %llu",
|
DP_PRINT_STATS("Rx Mesh Filter Drop Count: %llu",
|
||||||
rxstats->fail_cnt[MESH_FILTER_DROP]);
|
total_rx.fail_cnt[MESH_FILTER_DROP]);
|
||||||
DP_PRINT_STATS("Rx Intra Bss Deliver Count: %llu",
|
DP_PRINT_STATS("Rx Intra Bss Deliver Count: %llu",
|
||||||
rxstats->intrabss_cnt);
|
total_rx.intrabss_cnt);
|
||||||
DP_PRINT_STATS("Rx MSDU Count: %llu", rxstats->msdu_cnt);
|
DP_PRINT_STATS("Rx MSDU Count: %llu", total_rx.msdu_cnt);
|
||||||
DP_PRINT_STATS("Rx Multicast MSDU Count: %llu",
|
DP_PRINT_STATS("Rx Multicast MSDU Count: %llu",
|
||||||
rxstats->mcast_msdu_cnt);
|
total_rx.mcast_msdu_cnt);
|
||||||
DP_PRINT_STATS("Rx Broadcast MSDU Count: %llu\n",
|
DP_PRINT_STATS("Rx Broadcast MSDU Count: %llu\n",
|
||||||
rxstats->bcast_msdu_cnt);
|
total_rx.bcast_msdu_cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dp_pdev_print_delay_stats(struct dp_pdev *pdev)
|
void dp_pdev_print_delay_stats(struct dp_pdev *pdev)
|
||||||
{
|
{
|
||||||
struct dp_soc *soc = pdev->soc;
|
struct dp_soc *soc = pdev->soc;
|
||||||
struct cdp_tid_tx_stats *txstats = NULL;
|
struct cdp_tid_tx_stats total_tx;
|
||||||
struct cdp_tid_rx_stats *rxstats;
|
struct cdp_tid_rx_stats total_rx;
|
||||||
|
struct cdp_tid_stats *tid_stats;
|
||||||
|
|
||||||
uint8_t tid, index;
|
uint8_t tid, index;
|
||||||
uint64_t count = 0;
|
uint64_t count = 0;
|
||||||
|
|
||||||
@@ -4111,17 +4209,17 @@ void dp_pdev_print_delay_stats(struct dp_pdev *pdev)
|
|||||||
|
|
||||||
tid = 0;
|
tid = 0;
|
||||||
index = 0;
|
index = 0;
|
||||||
rxstats = NULL;
|
tid_stats = &pdev->stats.tid_stats;
|
||||||
|
|
||||||
DP_PRINT_STATS("Per TID Delay Non-Zero Stats:\n");
|
DP_PRINT_STATS("Per TID Delay Non-Zero Stats:\n");
|
||||||
for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) {
|
for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) {
|
||||||
|
dp_accumulate_tid_stats(pdev, tid, &total_tx, &total_rx,
|
||||||
|
TID_DELAY_STATS);
|
||||||
DP_PRINT_STATS("----TID: %d----", tid);
|
DP_PRINT_STATS("----TID: %d----", tid);
|
||||||
txstats = &pdev->stats.tid_stats.tid_tx_stats[tid];
|
|
||||||
rxstats = &pdev->stats.tid_stats.tid_rx_stats[tid];
|
|
||||||
|
|
||||||
DP_PRINT_STATS("Software Enqueue Delay:");
|
DP_PRINT_STATS("Software Enqueue Delay:");
|
||||||
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
||||||
count = txstats->swq_delay.delay_bucket[index];
|
count = total_tx.swq_delay.delay_bucket[index];
|
||||||
if (count) {
|
if (count) {
|
||||||
DP_PRINT_STATS("%s: Packets = %llu",
|
DP_PRINT_STATS("%s: Packets = %llu",
|
||||||
dp_vow_str_sw_enq_delay(index),
|
dp_vow_str_sw_enq_delay(index),
|
||||||
@@ -4129,52 +4227,52 @@ void dp_pdev_print_delay_stats(struct dp_pdev *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DP_PRINT_STATS("Min = %u", txstats->swq_delay.min_delay);
|
DP_PRINT_STATS("Min = %u", total_tx.swq_delay.min_delay);
|
||||||
DP_PRINT_STATS("Max = %u", txstats->swq_delay.max_delay);
|
DP_PRINT_STATS("Max = %u", total_tx.swq_delay.max_delay);
|
||||||
DP_PRINT_STATS("Avg = %u\n", txstats->swq_delay.avg_delay);
|
DP_PRINT_STATS("Avg = %u\n", total_tx.swq_delay.avg_delay);
|
||||||
|
|
||||||
DP_PRINT_STATS("Hardware Transmission Delay:");
|
DP_PRINT_STATS("Hardware Transmission Delay:");
|
||||||
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
||||||
count = txstats->hwtx_delay.delay_bucket[index];
|
count = total_tx.hwtx_delay.delay_bucket[index];
|
||||||
if (count) {
|
if (count) {
|
||||||
DP_PRINT_STATS("%s: Packets = %llu",
|
DP_PRINT_STATS("%s: Packets = %llu",
|
||||||
dp_vow_str_fw_to_hw_delay(index),
|
dp_vow_str_fw_to_hw_delay(index),
|
||||||
count);
|
count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DP_PRINT_STATS("Min = %u", txstats->hwtx_delay.min_delay);
|
DP_PRINT_STATS("Min = %u", total_tx.hwtx_delay.min_delay);
|
||||||
DP_PRINT_STATS("Max = %u", txstats->hwtx_delay.max_delay);
|
DP_PRINT_STATS("Max = %u", total_tx.hwtx_delay.max_delay);
|
||||||
DP_PRINT_STATS("Avg = %u\n", txstats->hwtx_delay.avg_delay);
|
DP_PRINT_STATS("Avg = %u\n", total_tx.hwtx_delay.avg_delay);
|
||||||
|
|
||||||
DP_PRINT_STATS("Tx Interframe Delay:");
|
DP_PRINT_STATS("Tx Interframe Delay:");
|
||||||
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
||||||
count = txstats->intfrm_delay.delay_bucket[index];
|
count = total_tx.intfrm_delay.delay_bucket[index];
|
||||||
if (count) {
|
if (count) {
|
||||||
DP_PRINT_STATS("%s: Packets = %llu",
|
DP_PRINT_STATS("%s: Packets = %llu",
|
||||||
dp_vow_str_intfrm_delay(index),
|
dp_vow_str_intfrm_delay(index),
|
||||||
count);
|
count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DP_PRINT_STATS("Min = %u", txstats->intfrm_delay.min_delay);
|
DP_PRINT_STATS("Min = %u", total_tx.intfrm_delay.min_delay);
|
||||||
DP_PRINT_STATS("Max = %u", txstats->intfrm_delay.max_delay);
|
DP_PRINT_STATS("Max = %u", total_tx.intfrm_delay.max_delay);
|
||||||
DP_PRINT_STATS("Avg = %u\n", txstats->intfrm_delay.avg_delay);
|
DP_PRINT_STATS("Avg = %u\n", total_tx.intfrm_delay.avg_delay);
|
||||||
|
|
||||||
DP_PRINT_STATS("Rx Interframe Delay:");
|
DP_PRINT_STATS("Rx Interframe Delay:");
|
||||||
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
||||||
count = rxstats->intfrm_delay.delay_bucket[index];
|
count = total_rx.intfrm_delay.delay_bucket[index];
|
||||||
if (count) {
|
if (count) {
|
||||||
DP_PRINT_STATS("%s: Packets = %llu",
|
DP_PRINT_STATS("%s: Packets = %llu",
|
||||||
dp_vow_str_intfrm_delay(index),
|
dp_vow_str_intfrm_delay(index),
|
||||||
count);
|
count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DP_PRINT_STATS("Min = %u", rxstats->intfrm_delay.min_delay);
|
DP_PRINT_STATS("Min = %u", total_rx.intfrm_delay.min_delay);
|
||||||
DP_PRINT_STATS("Max = %u", rxstats->intfrm_delay.max_delay);
|
DP_PRINT_STATS("Max = %u", total_rx.intfrm_delay.max_delay);
|
||||||
DP_PRINT_STATS("Avg = %u\n", rxstats->intfrm_delay.avg_delay);
|
DP_PRINT_STATS("Avg = %u\n", total_rx.intfrm_delay.avg_delay);
|
||||||
|
|
||||||
DP_PRINT_STATS("Rx Reap to Stack Delay:");
|
DP_PRINT_STATS("Rx Reap to Stack Delay:");
|
||||||
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
for (index = 0; index < CDP_DELAY_BUCKET_MAX; index++) {
|
||||||
count = rxstats->to_stack_delay.delay_bucket[index];
|
count = total_rx.to_stack_delay.delay_bucket[index];
|
||||||
if (count) {
|
if (count) {
|
||||||
DP_PRINT_STATS("%s: Packets = %llu",
|
DP_PRINT_STATS("%s: Packets = %llu",
|
||||||
dp_vow_str_intfrm_delay(index),
|
dp_vow_str_intfrm_delay(index),
|
||||||
@@ -4182,9 +4280,9 @@ void dp_pdev_print_delay_stats(struct dp_pdev *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DP_PRINT_STATS("Min = %u", rxstats->to_stack_delay.min_delay);
|
DP_PRINT_STATS("Min = %u", total_rx.to_stack_delay.min_delay);
|
||||||
DP_PRINT_STATS("Max = %u", rxstats->to_stack_delay.max_delay);
|
DP_PRINT_STATS("Max = %u", total_rx.to_stack_delay.max_delay);
|
||||||
DP_PRINT_STATS("Avg = %u\n", rxstats->to_stack_delay.avg_delay);
|
DP_PRINT_STATS("Avg = %u\n", total_rx.to_stack_delay.avg_delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1455,7 +1455,8 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
dp_err_rl("Tx_desc prepare Fail vdev %pK queue %d",
|
dp_err_rl("Tx_desc prepare Fail vdev %pK queue %d",
|
||||||
vdev, tx_q->desc_pool_id);
|
vdev, tx_q->desc_pool_id);
|
||||||
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[msdu_info->tid];
|
tid_stats = &pdev->stats.tid_stats.
|
||||||
|
tid_tx_stats[tx_q->ring_id][msdu_info->tid];
|
||||||
tid_stats->swdrop_cnt[TX_DESC_ERR]++;
|
tid_stats->swdrop_cnt[TX_DESC_ERR]++;
|
||||||
return nbuf;
|
return nbuf;
|
||||||
}
|
}
|
||||||
@@ -1475,7 +1476,8 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
"%s %d : HAL RING Access Failed -- %pK",
|
"%s %d : HAL RING Access Failed -- %pK",
|
||||||
__func__, __LINE__, hal_srng);
|
__func__, __LINE__, hal_srng);
|
||||||
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[msdu_info->tid];
|
tid_stats = &pdev->stats.tid_stats.
|
||||||
|
tid_tx_stats[tx_q->ring_id][tid];
|
||||||
tid_stats->swdrop_cnt[TX_HAL_RING_ACCESS_ERR]++;
|
tid_stats->swdrop_cnt[TX_HAL_RING_ACCESS_ERR]++;
|
||||||
DP_STATS_INC(vdev, tx_i.dropped.ring_full, 1);
|
DP_STATS_INC(vdev, tx_i.dropped.ring_full, 1);
|
||||||
dp_tx_desc_release(tx_desc, tx_q->desc_pool_id);
|
dp_tx_desc_release(tx_desc, tx_q->desc_pool_id);
|
||||||
@@ -1508,7 +1510,8 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
"%s Tx_hw_enqueue Fail tx_desc %pK queue %d",
|
"%s Tx_hw_enqueue Fail tx_desc %pK queue %d",
|
||||||
__func__, tx_desc, tx_q->ring_id);
|
__func__, tx_desc, tx_q->ring_id);
|
||||||
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[msdu_info->tid];
|
tid_stats = &pdev->stats.tid_stats.
|
||||||
|
tid_tx_stats[tx_q->ring_id][tid];
|
||||||
tid_stats->swdrop_cnt[TX_HW_ENQUEUE]++;
|
tid_stats->swdrop_cnt[TX_HW_ENQUEUE]++;
|
||||||
dp_tx_desc_release(tx_desc, tx_q->desc_pool_id);
|
dp_tx_desc_release(tx_desc, tx_q->desc_pool_id);
|
||||||
qdf_nbuf_unmap(vdev->osdev, nbuf, QDF_DMA_TO_DEVICE);
|
qdf_nbuf_unmap(vdev->osdev, nbuf, QDF_DMA_TO_DEVICE);
|
||||||
@@ -1564,7 +1567,8 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
"%s %d : HAL RING Access Failed -- %pK",
|
"%s %d : HAL RING Access Failed -- %pK",
|
||||||
__func__, __LINE__, hal_srng);
|
__func__, __LINE__, hal_srng);
|
||||||
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[msdu_info->tid];
|
tid_stats = &pdev->stats.tid_stats.
|
||||||
|
tid_tx_stats[tx_q->ring_id][msdu_info->tid];
|
||||||
tid_stats->swdrop_cnt[TX_HAL_RING_ACCESS_ERR]++;
|
tid_stats->swdrop_cnt[TX_HAL_RING_ACCESS_ERR]++;
|
||||||
DP_STATS_INC(vdev, tx_i.dropped.ring_full, 1);
|
DP_STATS_INC(vdev, tx_i.dropped.ring_full, 1);
|
||||||
return nbuf;
|
return nbuf;
|
||||||
@@ -1631,7 +1635,7 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
dp_tx_get_tid(vdev, nbuf, msdu_info);
|
||||||
tid_stats = &pdev->stats.tid_stats.
|
tid_stats = &pdev->stats.tid_stats.
|
||||||
tid_tx_stats[msdu_info->tid];
|
tid_tx_stats[tx_q->ring_id][msdu_info->tid];
|
||||||
tid_stats->swdrop_cnt[TX_HW_ENQUEUE]++;
|
tid_stats->swdrop_cnt[TX_HW_ENQUEUE]++;
|
||||||
if (tx_desc->flags & DP_TX_DESC_FLAG_ME)
|
if (tx_desc->flags & DP_TX_DESC_FLAG_ME)
|
||||||
dp_tx_me_free_buf(pdev, tx_desc->me_buffer);
|
dp_tx_me_free_buf(pdev, tx_desc->me_buffer);
|
||||||
@@ -2665,10 +2669,12 @@ void dp_tx_comp_fill_tx_completion_stats(struct dp_tx_desc_s *tx_desc,
|
|||||||
* @vdev: pdev handle
|
* @vdev: pdev handle
|
||||||
* @tx_desc: tx descriptor
|
* @tx_desc: tx descriptor
|
||||||
* @tid: tid value
|
* @tid: tid value
|
||||||
|
* @ring_id: TCL or WBM ring number for transmit path
|
||||||
* Return: none
|
* Return: none
|
||||||
*/
|
*/
|
||||||
static void dp_tx_compute_delay(struct dp_vdev *vdev,
|
static void dp_tx_compute_delay(struct dp_vdev *vdev,
|
||||||
struct dp_tx_desc_s *tx_desc, uint8_t tid)
|
struct dp_tx_desc_s *tx_desc,
|
||||||
|
uint8_t tid, uint8_t ring_id)
|
||||||
{
|
{
|
||||||
int64_t current_timestamp, timestamp_ingress, timestamp_hw_enqueue;
|
int64_t current_timestamp, timestamp_ingress, timestamp_hw_enqueue;
|
||||||
uint32_t sw_enqueue_delay, fwhw_transmit_delay, interframe_delay;
|
uint32_t sw_enqueue_delay, fwhw_transmit_delay, interframe_delay;
|
||||||
@@ -2689,12 +2695,12 @@ static void dp_tx_compute_delay(struct dp_vdev *vdev,
|
|||||||
* Delay in software enqueue
|
* Delay in software enqueue
|
||||||
*/
|
*/
|
||||||
dp_update_delay_stats(vdev->pdev, sw_enqueue_delay, tid,
|
dp_update_delay_stats(vdev->pdev, sw_enqueue_delay, tid,
|
||||||
CDP_DELAY_STATS_SW_ENQ);
|
CDP_DELAY_STATS_SW_ENQ, ring_id);
|
||||||
/*
|
/*
|
||||||
* Delay between packet enqueued to HW and Tx completion
|
* Delay between packet enqueued to HW and Tx completion
|
||||||
*/
|
*/
|
||||||
dp_update_delay_stats(vdev->pdev, fwhw_transmit_delay, tid,
|
dp_update_delay_stats(vdev->pdev, fwhw_transmit_delay, tid,
|
||||||
CDP_DELAY_STATS_FW_HW_TRANSMIT);
|
CDP_DELAY_STATS_FW_HW_TRANSMIT, ring_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update interframe delay stats calculated at hardstart receive point.
|
* Update interframe delay stats calculated at hardstart receive point.
|
||||||
@@ -2704,22 +2710,25 @@ static void dp_tx_compute_delay(struct dp_vdev *vdev,
|
|||||||
* of !vdev->prev_tx_enq_tstamp.
|
* of !vdev->prev_tx_enq_tstamp.
|
||||||
*/
|
*/
|
||||||
dp_update_delay_stats(vdev->pdev, interframe_delay, tid,
|
dp_update_delay_stats(vdev->pdev, interframe_delay, tid,
|
||||||
CDP_DELAY_STATS_TX_INTERFRAME);
|
CDP_DELAY_STATS_TX_INTERFRAME, ring_id);
|
||||||
vdev->prev_tx_enq_tstamp = timestamp_ingress;
|
vdev->prev_tx_enq_tstamp = timestamp_ingress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_tx_update_peer_stats() - Update peer stats from Tx completion indications
|
* dp_tx_update_peer_stats() - Update peer stats from Tx completion indications
|
||||||
|
* per wbm ring
|
||||||
|
*
|
||||||
* @tx_desc: software descriptor head pointer
|
* @tx_desc: software descriptor head pointer
|
||||||
* @ts: Tx completion status
|
* @ts: Tx completion status
|
||||||
* @peer: peer handle
|
* @peer: peer handle
|
||||||
|
* @ring_id: ring number
|
||||||
*
|
*
|
||||||
* Return: None
|
* Return: None
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
|
dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
|
||||||
struct hal_tx_completion_status *ts,
|
struct hal_tx_completion_status *ts,
|
||||||
struct dp_peer *peer)
|
struct dp_peer *peer, uint8_t ring_id)
|
||||||
{
|
{
|
||||||
struct dp_pdev *pdev = peer->vdev->pdev;
|
struct dp_pdev *pdev = peer->vdev->pdev;
|
||||||
struct dp_soc *soc = NULL;
|
struct dp_soc *soc = NULL;
|
||||||
@@ -2734,7 +2743,7 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
|
|||||||
if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS))
|
if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS))
|
||||||
tid = CDP_MAX_DATA_TIDS - 1;
|
tid = CDP_MAX_DATA_TIDS - 1;
|
||||||
|
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[tid];
|
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[ring_id][tid];
|
||||||
soc = pdev->soc;
|
soc = pdev->soc;
|
||||||
|
|
||||||
mcs = ts->mcs;
|
mcs = ts->mcs;
|
||||||
@@ -2749,8 +2758,7 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
|
|||||||
DP_STATS_INC_PKT(peer, tx.comp_pkt, 1, length);
|
DP_STATS_INC_PKT(peer, tx.comp_pkt, 1, length);
|
||||||
|
|
||||||
if (qdf_unlikely(pdev->delay_stats_flag))
|
if (qdf_unlikely(pdev->delay_stats_flag))
|
||||||
dp_tx_compute_delay(peer->vdev, tx_desc, tid);
|
dp_tx_compute_delay(peer->vdev, tx_desc, tid, ring_id);
|
||||||
tid_stats->complete_cnt++;
|
|
||||||
DP_STATS_INCC(peer, tx.dropped.age_out, 1,
|
DP_STATS_INCC(peer, tx.dropped.age_out, 1,
|
||||||
(ts->status == HAL_TX_TQM_RR_REM_CMD_AGED));
|
(ts->status == HAL_TX_TQM_RR_REM_CMD_AGED));
|
||||||
|
|
||||||
@@ -3023,13 +3031,14 @@ dp_tx_comp_process_desc(struct dp_soc *soc,
|
|||||||
* @tx_desc: software descriptor head pointer
|
* @tx_desc: software descriptor head pointer
|
||||||
* @ts: Tx completion status
|
* @ts: Tx completion status
|
||||||
* @peer: peer handle
|
* @peer: peer handle
|
||||||
|
* @ring_id: ring number
|
||||||
*
|
*
|
||||||
* Return: none
|
* Return: none
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline
|
||||||
void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc,
|
void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc,
|
||||||
struct hal_tx_completion_status *ts,
|
struct hal_tx_completion_status *ts,
|
||||||
struct dp_peer *peer)
|
struct dp_peer *peer, uint8_t ring_id)
|
||||||
{
|
{
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
qdf_ether_header_t *eh;
|
qdf_ether_header_t *eh;
|
||||||
@@ -3119,7 +3128,7 @@ void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dp_tx_update_peer_stats(tx_desc, ts, peer);
|
dp_tx_update_peer_stats(tx_desc, ts, peer, ring_id);
|
||||||
|
|
||||||
#ifdef QCA_SUPPORT_RDK_STATS
|
#ifdef QCA_SUPPORT_RDK_STATS
|
||||||
if (soc->wlanstats_enabled)
|
if (soc->wlanstats_enabled)
|
||||||
@@ -3135,6 +3144,7 @@ out:
|
|||||||
* dp_tx_comp_process_desc_list() - Tx complete software descriptor handler
|
* dp_tx_comp_process_desc_list() - Tx complete software descriptor handler
|
||||||
* @soc: core txrx main context
|
* @soc: core txrx main context
|
||||||
* @comp_head: software descriptor head pointer
|
* @comp_head: software descriptor head pointer
|
||||||
|
* @ring_id: ring number
|
||||||
*
|
*
|
||||||
* This function will process batch of descriptors reaped by dp_tx_comp_handler
|
* This function will process batch of descriptors reaped by dp_tx_comp_handler
|
||||||
* and release the software descriptors after processing is complete
|
* and release the software descriptors after processing is complete
|
||||||
@@ -3143,7 +3153,7 @@ out:
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dp_tx_comp_process_desc_list(struct dp_soc *soc,
|
dp_tx_comp_process_desc_list(struct dp_soc *soc,
|
||||||
struct dp_tx_desc_s *comp_head)
|
struct dp_tx_desc_s *comp_head, uint8_t ring_id)
|
||||||
{
|
{
|
||||||
struct dp_tx_desc_s *desc;
|
struct dp_tx_desc_s *desc;
|
||||||
struct dp_tx_desc_s *next;
|
struct dp_tx_desc_s *next;
|
||||||
@@ -3156,7 +3166,7 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
|
|||||||
while (desc) {
|
while (desc) {
|
||||||
hal_tx_comp_get_status(&desc->comp, &ts, soc->hal_soc);
|
hal_tx_comp_get_status(&desc->comp, &ts, soc->hal_soc);
|
||||||
peer = dp_peer_find_by_id(soc, ts.peer_id);
|
peer = dp_peer_find_by_id(soc, ts.peer_id);
|
||||||
dp_tx_comp_process_tx_status(desc, &ts, peer);
|
dp_tx_comp_process_tx_status(desc, &ts, peer, ring_id);
|
||||||
|
|
||||||
netbuf = desc->nbuf;
|
netbuf = desc->nbuf;
|
||||||
/* check tx complete notification */
|
/* check tx complete notification */
|
||||||
@@ -3180,13 +3190,15 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
|
|||||||
* dp_tx_process_htt_completion() - Tx HTT Completion Indication Handler
|
* dp_tx_process_htt_completion() - Tx HTT Completion Indication Handler
|
||||||
* @tx_desc: software descriptor head pointer
|
* @tx_desc: software descriptor head pointer
|
||||||
* @status : Tx completion status from HTT descriptor
|
* @status : Tx completion status from HTT descriptor
|
||||||
|
* @ring_id: ring number
|
||||||
*
|
*
|
||||||
* This function will process HTT Tx indication messages from Target
|
* This function will process HTT Tx indication messages from Target
|
||||||
*
|
*
|
||||||
* Return: none
|
* Return: none
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status,
|
||||||
|
uint8_t ring_id)
|
||||||
{
|
{
|
||||||
uint8_t tx_status;
|
uint8_t tx_status;
|
||||||
struct dp_pdev *pdev;
|
struct dp_pdev *pdev;
|
||||||
@@ -3238,11 +3250,10 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
|||||||
if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS))
|
if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS))
|
||||||
tid = CDP_MAX_DATA_TIDS - 1;
|
tid = CDP_MAX_DATA_TIDS - 1;
|
||||||
|
|
||||||
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[tid];
|
tid_stats = &pdev->stats.tid_stats.tid_tx_stats[ring_id][tid];
|
||||||
|
|
||||||
if (qdf_unlikely(pdev->delay_stats_flag))
|
if (qdf_unlikely(pdev->delay_stats_flag))
|
||||||
dp_tx_compute_delay(vdev, tx_desc, tid);
|
dp_tx_compute_delay(vdev, tx_desc, tid, ring_id);
|
||||||
tid_stats->complete_cnt++;
|
|
||||||
if (qdf_unlikely(tx_status != HTT_TX_FW2WBM_TX_STATUS_OK)) {
|
if (qdf_unlikely(tx_status != HTT_TX_FW2WBM_TX_STATUS_OK)) {
|
||||||
ts.status = HAL_TX_TQM_RR_REM_CMD_REM;
|
ts.status = HAL_TX_TQM_RR_REM_CMD_REM;
|
||||||
tid_stats->comp_fail_cnt++;
|
tid_stats->comp_fail_cnt++;
|
||||||
@@ -3255,7 +3266,7 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
|||||||
if (qdf_likely(peer))
|
if (qdf_likely(peer))
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
|
|
||||||
dp_tx_comp_process_tx_status(tx_desc, &ts, peer);
|
dp_tx_comp_process_tx_status(tx_desc, &ts, peer, ring_id);
|
||||||
dp_tx_comp_process_desc(soc, tx_desc, &ts, peer);
|
dp_tx_comp_process_desc(soc, tx_desc, &ts, peer);
|
||||||
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
||||||
|
|
||||||
@@ -3318,7 +3329,7 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||||
void *hal_srng, uint32_t quota)
|
void *hal_srng, uint8_t ring_id, uint32_t quota)
|
||||||
{
|
{
|
||||||
void *tx_comp_hal_desc;
|
void *tx_comp_hal_desc;
|
||||||
uint8_t buffer_src;
|
uint8_t buffer_src;
|
||||||
@@ -3400,7 +3411,7 @@ more_data:
|
|||||||
hal_tx_comp_get_htt_desc(tx_comp_hal_desc,
|
hal_tx_comp_get_htt_desc(tx_comp_hal_desc,
|
||||||
htt_tx_status);
|
htt_tx_status);
|
||||||
dp_tx_process_htt_completion(tx_desc,
|
dp_tx_process_htt_completion(tx_desc,
|
||||||
htt_tx_status);
|
htt_tx_status, ring_id);
|
||||||
} else {
|
} else {
|
||||||
/* Pool id is not matching. Error */
|
/* Pool id is not matching. Error */
|
||||||
if (tx_desc->pool_id != pool_id) {
|
if (tx_desc->pool_id != pool_id) {
|
||||||
@@ -3460,7 +3471,7 @@ more_data:
|
|||||||
|
|
||||||
/* Process the reaped descriptors */
|
/* Process the reaped descriptors */
|
||||||
if (head_desc)
|
if (head_desc)
|
||||||
dp_tx_comp_process_desc_list(soc, head_desc);
|
dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
|
||||||
|
|
||||||
if (dp_tx_comp_enable_eol_data_check(soc)) {
|
if (dp_tx_comp_enable_eol_data_check(soc)) {
|
||||||
if (!force_break &&
|
if (!force_break &&
|
||||||
|
@@ -185,6 +185,7 @@ qdf_nbuf_t dp_tx_non_std(struct cdp_vdev *vdev_handle,
|
|||||||
* dp_tx_comp_handler() - Tx completion handler
|
* dp_tx_comp_handler() - Tx completion handler
|
||||||
* @int_ctx: pointer to DP interrupt context
|
* @int_ctx: pointer to DP interrupt context
|
||||||
* @soc: core txrx main context
|
* @soc: core txrx main context
|
||||||
|
* @hal_srng: Opaque HAL SRNG pointer
|
||||||
* @ring_id: completion ring id
|
* @ring_id: completion ring id
|
||||||
* @quota: No. of packets/descriptors that can be serviced in one loop
|
* @quota: No. of packets/descriptors that can be serviced in one loop
|
||||||
*
|
*
|
||||||
@@ -195,7 +196,7 @@ qdf_nbuf_t dp_tx_non_std(struct cdp_vdev *vdev_handle,
|
|||||||
* Return: Number of TX completions processed
|
* Return: Number of TX completions processed
|
||||||
*/
|
*/
|
||||||
uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||||
void *hal_srng, uint32_t quota);
|
void *hal_srng, uint8_t ring_id, uint32_t quota);
|
||||||
|
|
||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
|
dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
|
||||||
|
Reference in New Issue
Block a user