From 9313b57907f1b280844b1e5f3090d385a7b6fe28 Mon Sep 17 00:00:00 2001 From: Amrit Sahai Date: Fri, 26 Aug 2022 12:11:59 +0530 Subject: [PATCH] qcacmn: Add support to get jitter stats on peer level Add support to get jitter stats on peer level Change-Id: I5e37a24e93cde5e34e561b26c0834d9cfe42bf9f CRs-Fixed: 3296380 --- dp/inc/cdp_txrx_stats_struct.h | 2 + dp/wifi3.0/dp_peer.c | 57 +++++++--- dp/wifi3.0/dp_stats.c | 42 ++++++-- dp/wifi3.0/dp_tx.c | 187 +++++++++++++++++++++++++++++++++ wlan_cfg/cfg_dp.h | 5 + wlan_cfg/wlan_cfg.c | 14 +++ wlan_cfg/wlan_cfg.h | 23 ++++ 7 files changed, 310 insertions(+), 20 deletions(-) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index f23c86908c..8947557848 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1929,6 +1929,7 @@ struct cdp_peer_stats { }; /* struct cdp_peer_tid_stats - Per peer and per TID stats + * @tx_prev_delay: tx previous delay * @tx_avg_jitter: tx average jitter * @tx_avg_delay: tx average delay * @tx_avg_err: tx average error @@ -1937,6 +1938,7 @@ struct cdp_peer_stats { */ struct cdp_peer_tid_stats { #ifdef WLAN_PEER_JITTER + uint32_t tx_prev_delay; uint32_t tx_avg_jitter; uint32_t tx_avg_delay; uint64_t tx_avg_err; diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index e58d88af52..772df64948 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -5224,15 +5224,25 @@ QDF_STATUS dp_peer_jitter_stats_ctx_alloc(struct dp_pdev *pdev, return QDF_STATUS_E_INVAL; } - /* - * Allocate memory for jitter stats only when - * operating in offload enabled mode. - */ - if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) + if (!wlan_cfg_is_peer_jitter_stats_enabled(pdev->soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; - txrx_peer->jitter_stats = - qdf_mem_malloc(sizeof(struct cdp_peer_tid_stats) * DP_MAX_TIDS); + if (wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) { + /* + * Allocate memory on per tid basis when nss is enabled + */ + txrx_peer->jitter_stats = + qdf_mem_malloc(sizeof(struct cdp_peer_tid_stats) + * DP_MAX_TIDS); + } else { + /* + * Allocate memory on per tid per ring basis + */ + txrx_peer->jitter_stats = + qdf_mem_malloc(sizeof(struct cdp_peer_tid_stats) + * DP_MAX_TIDS * CDP_MAX_TXRX_CTX); + } + if (!txrx_peer->jitter_stats) { dp_warn("Jitter stats obj alloc failed!!"); return QDF_STATUS_E_NOMEM; @@ -5257,8 +5267,7 @@ void dp_peer_jitter_stats_ctx_dealloc(struct dp_pdev *pdev, return; } - /* Check for offload mode */ - if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) + if (!wlan_cfg_is_peer_jitter_stats_enabled(pdev->soc->wlan_cfg_ctx)) return; if (txrx_peer->jitter_stats) { @@ -5276,9 +5285,33 @@ void dp_peer_jitter_stats_ctx_dealloc(struct dp_pdev *pdev, */ void dp_peer_jitter_stats_ctx_clr(struct dp_txrx_peer *txrx_peer) { - if (txrx_peer->jitter_stats) - qdf_mem_zero(txrx_peer->jitter_stats, - sizeof(struct cdp_peer_tid_stats) * DP_MAX_TIDS); + struct cdp_peer_tid_stats *jitter_stats = NULL; + + if (!txrx_peer) { + dp_warn("Null peer"); + return; + } + + if (!wlan_cfg_is_peer_jitter_stats_enabled(txrx_peer-> + vdev-> + pdev->soc->wlan_cfg_ctx)) + return; + + jitter_stats = txrx_peer->jitter_stats; + if (!jitter_stats) + return; + + if (wlan_cfg_get_dp_pdev_nss_enabled(txrx_peer-> + vdev->pdev->wlan_cfg_ctx)) + qdf_mem_zero(jitter_stats, + sizeof(struct cdp_peer_tid_stats) * + DP_MAX_TIDS); + + else + qdf_mem_zero(jitter_stats, + sizeof(struct cdp_peer_tid_stats) * + DP_MAX_TIDS * CDP_MAX_TXRX_CTX); + } #endif diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index f736f3959d..15f5ac4867 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -9035,11 +9035,13 @@ dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct dp_peer *peer = NULL; uint8_t tid; struct cdp_peer_info peer_info = { 0 }; + struct cdp_peer_tid_stats *jitter_stats; + uint8_t ring_id; if (!pdev) return QDF_STATUS_E_FAILURE; - if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) + if (!wlan_cfg_is_peer_jitter_stats_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_E_FAILURE; DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false, @@ -9054,16 +9056,40 @@ dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, return QDF_STATUS_E_FAILURE; } - for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) { - struct cdp_peer_tid_stats *rx_tid = + if (wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) { + for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) { + struct cdp_peer_tid_stats *rx_tid = &peer->txrx_peer->jitter_stats[tid]; - tid_stats[tid].tx_avg_jitter = rx_tid->tx_avg_jitter; - tid_stats[tid].tx_avg_delay = rx_tid->tx_avg_delay; - tid_stats[tid].tx_avg_err = rx_tid->tx_avg_err; - tid_stats[tid].tx_total_success = rx_tid->tx_total_success; - tid_stats[tid].tx_drop = rx_tid->tx_drop; + tid_stats[tid].tx_avg_jitter = rx_tid->tx_avg_jitter; + tid_stats[tid].tx_avg_delay = rx_tid->tx_avg_delay; + tid_stats[tid].tx_avg_err = rx_tid->tx_avg_err; + tid_stats[tid].tx_total_success = rx_tid->tx_total_success; + tid_stats[tid].tx_drop = rx_tid->tx_drop; + } + + } else { + jitter_stats = peer->txrx_peer->jitter_stats; + for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) { + for (ring_id = 0; ring_id < CDP_MAX_TXRX_CTX; ring_id++) { + struct cdp_peer_tid_stats *rx_tid = + &jitter_stats[tid * + CDP_MAX_TXRX_CTX + ring_id]; + tid_stats[tid].tx_avg_jitter = + (rx_tid->tx_avg_jitter + + tid_stats[tid].tx_avg_jitter) >> 1; + tid_stats[tid].tx_avg_delay = + (rx_tid->tx_avg_delay + + tid_stats[tid].tx_avg_delay) >> 1; + tid_stats[tid].tx_avg_err = (rx_tid->tx_avg_err + + tid_stats[tid].tx_avg_err) >> 1; + tid_stats[tid].tx_total_success += + rx_tid->tx_total_success; + tid_stats[tid].tx_drop += rx_tid->tx_drop; + } + } } + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); return QDF_STATUS_SUCCESS; diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index ad27a01d7b..263766e8bd 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -68,6 +68,10 @@ #define DP_INVALID_PEER 0XFFFE #define DP_RETRY_COUNT 7 +#ifdef WLAN_PEER_JITTER +#define DP_AVG_JITTER_WEIGHT_DENOM 4 +#define DP_AVG_DELAY_WEIGHT_DENOM 3 +#endif #ifdef QCA_DP_TX_FW_METADATA_V2 #define DP_TX_TCL_METADATA_PDEV_ID_SET(_var, _val)\ @@ -4121,6 +4125,188 @@ void dp_tx_update_peer_delay_stats(struct dp_txrx_peer *txrx_peer, } #endif +#ifdef WLAN_PEER_JITTER +/* + * dp_tx_jitter_get_avg_jitter() - compute the average jitter + * @curr_delay: Current delay + * @prev_Delay: Previous delay + * @avg_jitter: Average Jitter + * Return: Newly Computed Average Jitter + */ +static uint32_t dp_tx_jitter_get_avg_jitter(uint32_t curr_delay, + uint32_t prev_delay, + uint32_t avg_jitter) +{ + uint32_t curr_jitter; + int32_t jitter_diff; + + curr_jitter = qdf_abs(curr_delay - prev_delay); + if (!avg_jitter) + return curr_jitter; + + jitter_diff = curr_jitter - avg_jitter; + if (jitter_diff < 0) + avg_jitter = avg_jitter - + (qdf_abs(jitter_diff) >> DP_AVG_JITTER_WEIGHT_DENOM); + else + avg_jitter = avg_jitter + + (qdf_abs(jitter_diff) >> DP_AVG_JITTER_WEIGHT_DENOM); + + return avg_jitter; +} + +/* + * dp_tx_jitter_get_avg_delay() - compute the average delay + * @curr_delay: Current delay + * @avg_Delay: Average delay + * Return: Newly Computed Average Delay + */ +static uint32_t dp_tx_jitter_get_avg_delay(uint32_t curr_delay, + uint32_t avg_delay) +{ + int32_t delay_diff; + + if (!avg_delay) + return curr_delay; + + delay_diff = curr_delay - avg_delay; + if (delay_diff < 0) + avg_delay = avg_delay - (qdf_abs(delay_diff) >> + DP_AVG_DELAY_WEIGHT_DENOM); + else + avg_delay = avg_delay + (qdf_abs(delay_diff) >> + DP_AVG_DELAY_WEIGHT_DENOM); + + return avg_delay; +} + +#ifdef WLAN_CONFIG_TX_DELAY +/* + * dp_tx_compute_cur_delay() - get the current delay + * @soc: soc handle + * @vdev: vdev structure for data path state + * @ts: Tx completion status + * @curr_delay: current delay + * @tx_desc: tx descriptor + * Return: void + */ +static +QDF_STATUS dp_tx_compute_cur_delay(struct dp_soc *soc, + struct dp_vdev *vdev, + struct hal_tx_completion_status *ts, + uint32_t *curr_delay, + struct dp_tx_desc_s *tx_desc) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (soc->arch_ops.dp_tx_compute_hw_delay) + status = soc->arch_ops.dp_tx_compute_hw_delay(soc, vdev, ts, + curr_delay); + return status; +} +#else +static +QDF_STATUS dp_tx_compute_cur_delay(struct dp_soc *soc, + struct dp_vdev *vdev, + struct hal_tx_completion_status *ts, + uint32_t *curr_delay, + struct dp_tx_desc_s *tx_desc) +{ + int64_t current_timestamp, timestamp_hw_enqueue; + + current_timestamp = qdf_ktime_to_us(qdf_ktime_real_get()); + timestamp_hw_enqueue = qdf_ktime_to_us(tx_desc->timestamp); + *curr_delay = (uint32_t)(current_timestamp - timestamp_hw_enqueue); + + return QDF_STATUS_SUCCESS; +} +#endif + +/* dp_tx_compute_tid_jitter() - compute per tid per ring jitter + * @jiiter - per tid per ring jitter stats + * @ts: Tx completion status + * @vdev - vdev structure for data path state + * @tx_desc - tx descriptor + * Return: void + */ +static void dp_tx_compute_tid_jitter(struct cdp_peer_tid_stats *jitter, + struct hal_tx_completion_status *ts, + struct dp_vdev *vdev, + struct dp_tx_desc_s *tx_desc) +{ + uint32_t curr_delay, avg_delay, avg_jitter, prev_delay; + struct dp_soc *soc = vdev->pdev->soc; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (ts->status != HAL_TX_TQM_RR_FRAME_ACKED) { + jitter->tx_drop += 1; + return; + } + + status = dp_tx_compute_cur_delay(soc, vdev, ts, &curr_delay, + tx_desc); + + if (QDF_IS_STATUS_SUCCESS(status)) { + avg_delay = jitter->tx_avg_delay; + avg_jitter = jitter->tx_avg_jitter; + prev_delay = jitter->tx_prev_delay; + avg_jitter = dp_tx_jitter_get_avg_jitter(curr_delay, + prev_delay, + avg_jitter); + avg_delay = dp_tx_jitter_get_avg_delay(curr_delay, avg_delay); + jitter->tx_avg_delay = avg_delay; + jitter->tx_avg_jitter = avg_jitter; + jitter->tx_prev_delay = curr_delay; + jitter->tx_total_success += 1; + } else if (status == QDF_STATUS_E_FAILURE) { + jitter->tx_avg_err += 1; + } +} + +/* dp_tx_update_peer_jitter_stats() - Update the peer jitter stats + * @txrx_peer: DP peer context + * @tx_desc: Tx software descriptor + * @ts: Tx completion status + * @ring_id: Rx CPU context ID/CPU_ID + * Return: void + */ +static void dp_tx_update_peer_jitter_stats(struct dp_txrx_peer *txrx_peer, + struct dp_tx_desc_s *tx_desc, + struct hal_tx_completion_status *ts, + uint8_t ring_id) +{ + struct dp_pdev *pdev = txrx_peer->vdev->pdev; + struct dp_soc *soc = pdev->soc; + struct cdp_peer_tid_stats *jitter_stats = NULL; + uint8_t tid; + struct cdp_peer_tid_stats *rx_tid = NULL; + + if (qdf_likely(!wlan_cfg_is_peer_jitter_stats_enabled(soc->wlan_cfg_ctx))) + return; + + tid = ts->tid; + jitter_stats = txrx_peer->jitter_stats; + qdf_assert_always(jitter_stats); + qdf_assert(ring < CDP_MAX_TXRX_CTX); + /* + * For non-TID packets use the TID 9 + */ + if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS)) + tid = CDP_MAX_DATA_TIDS - 1; + + rx_tid = &jitter_stats[tid * CDP_MAX_TXRX_CTX + ring_id]; + dp_tx_compute_tid_jitter(rx_tid, + ts, txrx_peer->vdev, tx_desc); +} +#else +static void dp_tx_update_peer_jitter_stats(struct dp_txrx_peer *txrx_peer, + struct dp_tx_desc_s *tx_desc, + struct hal_tx_completion_status *ts, + uint8_t ring_id) +{ +} +#endif + #ifdef HW_TX_DELAY_STATS_ENABLE /** * dp_update_tx_delay_stats() - update the delay stats @@ -5022,6 +5208,7 @@ void dp_tx_comp_process_tx_status(struct dp_soc *soc, dp_tx_update_peer_stats(tx_desc, ts, txrx_peer, ring_id); dp_tx_update_peer_delay_stats(txrx_peer, tx_desc, ts, ring_id); + dp_tx_update_peer_jitter_stats(txrx_peer, tx_desc, ts, ring_id); dp_tx_update_peer_sawf_stats(soc, vdev, txrx_peer, tx_desc, ts, ts->tid); dp_tx_send_pktlog(soc, vdev->pdev, tx_desc, nbuf, dp_status); diff --git a/wlan_cfg/cfg_dp.h b/wlan_cfg/cfg_dp.h index 29b277ea87..9b8085fdd1 100644 --- a/wlan_cfg/cfg_dp.h +++ b/wlan_cfg/cfg_dp.h @@ -1355,6 +1355,10 @@ CFG_INI_BOOL("peer_ext_stats", \ false, "Peer extended stats") +#define CFG_DP_PEER_JITTER_STATS \ + CFG_INI_BOOL("peer_jitter_stats", \ + false, "Peer Jitter stats") + #define CFG_DP_NAPI_SCALE_FACTOR \ CFG_INI_UINT("dp_napi_scale_factor", \ WLAN_CFG_DP_NAPI_SCALE_FACTOR_MIN, \ @@ -1826,6 +1830,7 @@ CFG(CFG_DP_FULL_MON_MODE) \ CFG(CFG_DP_REO_RINGS_MAP) \ CFG(CFG_DP_PEER_EXT_STATS) \ + CFG(CFG_DP_PEER_JITTER_STATS) \ CFG(CFG_DP_RX_BUFF_POOL_ENABLE) \ CFG(CFG_DP_RX_REFILL_BUFF_POOL_ENABLE) \ CFG(CFG_DP_RX_PENDING_HL_THRESHOLD) \ diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index 387413a26d..20b3891dee 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -2847,6 +2847,8 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc) cfg_get(psoc, CFG_DP_RX_FISA_LRU_DEL_ENABLE); wlan_cfg_ctx->reo_rings_mapping = cfg_get(psoc, CFG_DP_REO_RINGS_MAP); wlan_cfg_ctx->pext_stats_enabled = cfg_get(psoc, CFG_DP_PEER_EXT_STATS); + wlan_cfg_ctx->jitter_stats_enabled = + cfg_get(psoc, CFG_DP_PEER_JITTER_STATS); wlan_cfg_ctx->is_rx_buff_pool_enabled = cfg_get(psoc, CFG_DP_RX_BUFF_POOL_ENABLE); wlan_cfg_ctx->is_rx_refill_buff_pool_enabled = @@ -3836,6 +3838,13 @@ wlan_cfg_set_peer_ext_stats(struct wlan_cfg_dp_soc_ctxt *cfg, cfg->pext_stats_enabled = val; } +void +wlan_cfg_set_peer_jitter_stats(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val) +{ + cfg->jitter_stats_enabled = val; +} + bool wlan_cfg_is_peer_ext_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) { @@ -3847,6 +3856,11 @@ bool wlan_cfg_is_fst_in_cmem_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->fst_in_cmem; } +bool wlan_cfg_is_peer_jitter_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->jitter_stats_enabled; +} + #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL bool wlan_cfg_is_rx_buffer_pool_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) { diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index b04e591fd8..318ceb8a1b 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -401,6 +401,7 @@ struct wlan_cfg_dp_soc_ctxt { uint8_t radio1_rx_default_reo; uint8_t radio2_rx_default_reo; bool wow_check_rx_pending_enable; + bool jitter_stats_enabled; #ifdef IPA_OFFLOAD uint32_t ipa_tx_ring_size; uint32_t ipa_tx_comp_ring_size; @@ -1791,6 +1792,18 @@ void wlan_cfg_set_peer_ext_stats(struct wlan_cfg_dp_soc_ctxt *cfg, bool val); +/** + * wlan_cfg_set_peer_jitter_stats() - set peer jitter stats + * + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * @val: Flag value read from INI + * + * Return: bool + */ +void +wlan_cfg_set_peer_jitter_stats(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val); + /** * wlan_cfg_is_peer_ext_stats_enabled() - Check if peer extended * stats are enabled @@ -1802,6 +1815,16 @@ wlan_cfg_set_peer_ext_stats(struct wlan_cfg_dp_soc_ctxt *cfg, bool wlan_cfg_is_peer_ext_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); +/** + * wlan_cfg_is_peer_jitter_stats_enabled() - check if jitter stats are enabled + * + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: bool + */ +bool +wlan_cfg_is_peer_jitter_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); + /** * wlan_cfg_is_poll_mode_enabled() - Check if poll mode is enabled *