diff --git a/dp/inc/cdp_txrx_flow_ctrl_v2.h b/dp/inc/cdp_txrx_flow_ctrl_v2.h index e3a9e0d3ba..9ef5cb5685 100644 --- a/dp/inc/cdp_txrx_flow_ctrl_v2.h +++ b/dp/inc/cdp_txrx_flow_ctrl_v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018 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 @@ -107,4 +107,28 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc) soc->ops->flowctl_ops->dump_flow_pool_info(dp_soc); } + +/** + * cdp_tx_desc_thresh_reached() - Check if avail tx desc meet threshold + * @soc - data path soc handle + * @vdev - dp vdev handle + * + * Return: true if threshold is met, false if not + */ +static inline bool +cdp_tx_desc_thresh_reached(struct cdp_soc_t *soc, struct cdp_vdev *vdev) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s invalid instance", __func__); + QDF_BUG(0); + return false; + } + + if (!soc->ops->flowctl_ops || + !soc->ops->flowctl_ops->tx_desc_thresh_reached) + return false; + + return soc->ops->flowctl_ops->tx_desc_thresh_reached(vdev); +} #endif /* _CDP_TXRX_FC_V2_H_ */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 7efd6821f3..1610f93125 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1078,6 +1078,8 @@ struct cdp_flowctl_ops { void (*set_desc_global_pool_size)(uint32_t num_msdu_desc); void (*dump_flow_pool_info)(void *); + + bool (*tx_desc_thresh_reached)(struct cdp_vdev *vdev); }; /** diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index a42cd2e656..9c06974643 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9166,6 +9166,7 @@ static struct cdp_flowctl_ops dp_ops_flowctl = { .flow_pool_unmap_handler = dp_tx_flow_pool_unmap, .register_pause_cb = dp_txrx_register_pause_cb, .dump_flow_pool_info = dp_tx_dump_flow_pool_info, + .tx_desc_thresh_reached = dp_tx_desc_thresh_reached, #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ }; diff --git a/dp/wifi3.0/dp_tx_desc.h b/dp/wifi3.0/dp_tx_desc.h index a903d99b3e..8afe00e84c 100644 --- a/dp/wifi3.0/dp_tx_desc.h +++ b/dp/wifi3.0/dp_tx_desc.h @@ -374,6 +374,16 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, qdf_spin_unlock_bh(&pool->flow_pool_lock); } #else /* QCA_AC_BASED_FLOW_CONTROL */ + +static inline bool +dp_tx_is_threshold_reached(struct dp_tx_desc_pool_s *pool, uint16_t avail_desc) +{ + if (qdf_unlikely(avail_desc < pool->stop_th)) + return true; + else + return false; +} + /** * dp_tx_desc_alloc() - Allocate a Software Tx Descriptor from given pool * @@ -482,6 +492,21 @@ out: } #endif /* QCA_AC_BASED_FLOW_CONTROL */ + +static inline bool +dp_tx_desc_thresh_reached(struct cdp_vdev *vdev) +{ + struct dp_vdev *dp_vdev = (struct dp_vdev *)vdev; + struct dp_tx_desc_pool_s *pool; + + if (!vdev) + return false; + + pool = dp_vdev->pool; + + return dp_tx_is_threshold_reached(pool, pool->avail_desc); +} + #else /* QCA_LL_TX_FLOW_CONTROL_V2 */ static inline void dp_tx_flow_control_init(struct dp_soc *handle)