diff --git a/dp/inc/cdp_txrx_misc.h b/dp/inc/cdp_txrx_misc.h index dd28f0feb756..77bcb6c85ae0 100644 --- a/dp/inc/cdp_txrx_misc.h +++ b/dp/inc/cdp_txrx_misc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. 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 @@ -336,13 +336,15 @@ cdp_get_vdev_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) /** * cdp_get_tx_ack_stats() - get tx ack count for vdev * @soc - data path soc handle + * @pdev - data path device instance * @vdev_id - vdev id * * return tx ack count * 0 invalid count */ static inline uint32_t -cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) +cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, + uint8_t vdev_id) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -351,7 +353,8 @@ cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) } if (soc->ops->misc_ops->get_tx_ack_stats) - return soc->ops->misc_ops->get_tx_ack_stats(vdev_id); + return soc->ops->misc_ops->get_tx_ack_stats(pdev, vdev_id); + return 0; } diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 9f59b40d2951..5ce82fba31c6 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -989,7 +989,7 @@ struct cdp_misc_ops { qdf_nbuf_t (*tx_non_std)(struct cdp_vdev *vdev, enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); uint16_t (*get_vdev_id)(struct cdp_vdev *vdev); - uint32_t (*get_tx_ack_stats)(uint8_t vdev_id); + uint32_t (*get_tx_ack_stats)(struct cdp_pdev *pdev, uint8_t vdev_id); QDF_STATUS (*set_wisa_mode)(struct cdp_vdev *vdev, bool enable); QDF_STATUS (*txrx_data_stall_cb_register)(data_stall_detect_cb cb); QDF_STATUS (*txrx_data_stall_cb_deregister)(data_stall_detect_cb cb); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index e9582b93bc97..fb0efed19a12 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -10081,6 +10081,46 @@ static QDF_STATUS dp_runtime_resume(struct cdp_pdev *opaque_pdev) } #endif /* FEATURE_RUNTIME_PM */ +/** + * dp_tx_get_success_ack_stats() - get tx success completion count + * @opaque_pdev: dp pdev context + * @vdevid: vdev identifier + * + * Return: tx success ack count + */ +static uint32_t dp_tx_get_success_ack_stats(struct cdp_pdev *pdev, + uint8_t vdev_id) +{ + struct dp_vdev *vdev = + (struct dp_vdev *)dp_get_vdev_from_vdev_id_wifi3(pdev, + vdev_id); + struct dp_soc *soc = ((struct dp_pdev *)pdev)->soc; + struct cdp_vdev_stats *vdev_stats = NULL; + uint32_t tx_success; + + if (!vdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid vdev id %d"), vdev_id); + return 0; + } + + vdev_stats = qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats)); + if (!vdev_stats) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "DP alloc failure - unable to get alloc vdev stats"); + return 0; + } + + qdf_spin_lock_bh(&soc->peer_ref_mutex); + dp_aggregate_vdev_stats(vdev, vdev_stats); + qdf_spin_unlock_bh(&soc->peer_ref_mutex); + + tx_success = vdev_stats->tx.tx_success.num; + qdf_mem_free(vdev_stats); + + return tx_success; +} + #ifndef CONFIG_WIN static struct cdp_misc_ops dp_ops_misc = { #ifdef FEATURE_WLAN_TDLS @@ -10094,6 +10134,7 @@ static struct cdp_misc_ops dp_ops_misc = { .pkt_log_init = dp_pkt_log_init, .pkt_log_con_service = dp_pkt_log_con_service, .get_num_rx_contexts = dp_get_num_rx_contexts, + .get_tx_ack_stats = dp_tx_get_success_ack_stats, }; static struct cdp_flowctl_ops dp_ops_flowctl = {