diff --git a/dp/inc/cdp_txrx_host_stats.h b/dp/inc/cdp_txrx_host_stats.h index 2ebf2ad6eb..b604237c65 100644 --- a/dp/inc/cdp_txrx_host_stats.h +++ b/dp/inc/cdp_txrx_host_stats.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -755,4 +756,50 @@ cdp_get_scan_spcl_vap_stats(ol_txrx_soc_handle soc, stats); } #endif + +static inline QDF_STATUS +cdp_get_peer_delay_stats(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->host_stats_ops || + !soc->ops->host_stats_ops->txrx_get_peer_delay_stats) + return QDF_STATUS_E_FAILURE; + + return soc->ops->host_stats_ops->txrx_get_peer_delay_stats(soc, + vdev_id, + peer_mac, + delay_stats); +} + +static inline QDF_STATUS +cdp_get_peer_jitter_stats(ol_txrx_soc_handle soc, + uint8_t pdev_id, + uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->host_stats_ops || + !soc->ops->host_stats_ops->txrx_get_peer_jitter_stats) + return QDF_STATUS_E_FAILURE; + + return soc->ops->host_stats_ops->txrx_get_peer_jitter_stats(soc, + pdev_id, + vdev_id, + peer_mac, + tid_stats); +} #endif /* _CDP_TXRX_HOST_STATS_H_ */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index ee3e58bd73..5e20522313 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1012,6 +1012,16 @@ struct cdp_host_stats_ops { (*txrx_get_scan_spcl_vap_stats)(struct cdp_soc_t *soc, uint8_t vdev_id, struct cdp_scan_spcl_vap_stats *stats); #endif + + QDF_STATUS + (*txrx_get_peer_delay_stats)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats); + + QDF_STATUS + (*txrx_get_peer_jitter_stats)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t vdev_id, uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats); }; struct cdp_wds_ops { diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 942dc33a22..1b6139f016 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -120,6 +120,8 @@ #define CDP_MAX_DATA_TIDS 9 #define CDP_MAX_VOW_TID 4 +#define CDP_MAX_TIDS 17 + #define CDP_WDI_NUM_EVENTS WDI_NUM_EVENTS #define CDP_FCTL_RETRY 0x0800 diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index babe4517f7..d46d23d988 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -3117,4 +3118,22 @@ void dp_peer_flush_frags(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, * Return: */ void dp_soc_reset_mon_intr_mask(struct dp_soc *soc); + +#ifdef QCA_PEER_EXT_STATS +/* + * dp_accumulate_delay_tid_stats(): Accumulate the tid stats to the + * hist stats. + * @soc: DP SoC handle + * @stats: cdp_delay_tid stats + * @dst_hstats: Destination histogram to copy tid stats + * @tid: TID value + * + * Return: void + */ +void dp_accumulate_delay_tid_stats(struct dp_soc *soc, + struct cdp_delay_tid_stats stats[] + [CDP_MAX_TXRX_CTX], + struct cdp_hist_stats *dst_hstats, + uint8_t tid, uint32_t mode); +#endif /* QCA_PEER_EXT_STATS */ #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index e3ac6734ea..a1f41eecef 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9401,6 +9401,121 @@ dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl, return QDF_STATUS_SUCCESS; } +#ifdef QCA_PEER_EXT_STATS +/* dp_txrx_get_peer_delay_stats - to get peer delay stats per TIDs + * @soc: soc handle + * @vdev_id: id of vdev handle + * @peer_mac: mac of DP_PEER handle + * @delay_stats: pointer to delay stats array + * return: status success/failure + */ +static QDF_STATUS +dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, + DP_MOD_ID_CDP); + struct cdp_peer_ext_stats *pext_stats; + struct cdp_delay_rx_stats *rx_delay; + struct cdp_delay_tx_stats *tx_delay; + uint8_t tid; + + if (!peer) + return QDF_STATUS_E_FAILURE; + + if (!wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx)) { + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return QDF_STATUS_E_FAILURE; + } + + pext_stats = peer->pext_stats; + if (!pext_stats) { + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return QDF_STATUS_E_FAILURE; + } + + for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) { + rx_delay = &delay_stats[tid].rx_delay; + dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, + &rx_delay->to_stack_delay, tid, + CDP_HIST_TYPE_REAP_STACK); + tx_delay = &delay_stats[tid].tx_delay; + dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, + &tx_delay->tx_swq_delay, tid, + CDP_HIST_TYPE_SW_ENQEUE_DELAY); + dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, + &tx_delay->hwtx_delay, tid, + CDP_HIST_TYPE_HW_COMP_DELAY); + } + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS +dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats) +{ + return QDF_STATUS_E_FAILURE; +} +#endif /* QCA_PEER_EXT_STATS */ + +#ifdef WLAN_PEER_JITTER +/* dp_txrx_get_peer_jitter_stats - to get peer jitter stats per TIDs + * @soc: soc handle + * @pdev_id: id of pdev handle + * @vdev_id: id of vdev handle + * @peer_mac: mac of DP_PEER handle + * @tid_stats: pointer to jitter stats array + * return: status success/failure + */ +static QDF_STATUS +dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id, uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_peer *peer; + uint8_t tid; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) + return QDF_STATUS_E_FAILURE; + + peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, DP_MOD_ID_CDP); + if (!peer) + return QDF_STATUS_E_FAILURE; + + for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) { + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + + tid_stats[tid].tx_avg_jitter = rx_tid->stats.tx_avg_jitter; + tid_stats[tid].tx_avg_delay = rx_tid->stats.tx_avg_delay; + tid_stats[tid].tx_avg_err = rx_tid->stats.tx_avg_err; + tid_stats[tid].tx_total_success = + rx_tid->stats.tx_total_success; + tid_stats[tid].tx_drop = rx_tid->stats.tx_drop; + } + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS +dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id, uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats) +{ + return QDF_STATUS_E_FAILURE; +} +#endif /* WLAN_PEER_JITTER */ + /* dp_txrx_get_peer_stats - will return cdp_peer_stats * @soc: soc handle * @vdev_id: id of vdev handle @@ -11389,6 +11504,8 @@ static struct cdp_host_stats_ops dp_ops_host_stats = { .txrx_get_pdev_stats = dp_txrx_get_pdev_stats, .txrx_get_ratekbps = dp_txrx_get_ratekbps, .txrx_update_vdev_stats = dp_txrx_update_vdev_host_stats, + .txrx_get_peer_delay_stats = dp_txrx_get_peer_delay_stats, + .txrx_get_peer_jitter_stats = dp_txrx_get_peer_jitter_stats, /* TODO */ }; diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index 8e3d33ff0c..48e3806101 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -5495,22 +5495,11 @@ static void dp_print_hist_stats(struct cdp_hist_stats *hstats, DP_PRINT_STATS("Avg = %u\n", hstats->avg); } -/* - * dp_accumulate_delay_tid_stats(): Accumulate the tid stats to the - * hist stats. - * @soc: DP SoC handle - * @stats: cdp_delay_tid stats - * @dst_hstats: Destination histogram to copy tid stats - * @tid: TID value - * - * Return: void - */ -static void -dp_accumulate_delay_tid_stats(struct dp_soc *soc, - struct cdp_delay_tid_stats stats[] - [CDP_MAX_TXRX_CTX], - struct cdp_hist_stats *dst_hstats, - uint8_t tid, uint32_t mode) +void dp_accumulate_delay_tid_stats(struct dp_soc *soc, + struct cdp_delay_tid_stats stats[] + [CDP_MAX_TXRX_CTX], + struct cdp_hist_stats *dst_hstats, + uint8_t tid, uint32_t mode) { uint8_t ring_id;