qcacmn: Add near-full irq handler for TX completion ring
Add the handler to process the near-full condition on the tx completion ring. Change-Id: I547cd27d2a8a347fca1cebc6b27072f2d1d8a99d CRs-Fixed: 2965081
This commit is contained in:

committad av
Madan Koyyalamudi

förälder
5605d45923
incheckning
813b3bb474
@@ -570,11 +570,41 @@ budget_done:
|
|||||||
return dp_budget - budget;
|
return dp_budget - budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_srng_test_and_update_nf_params_be() - Check if the srng is in near full
|
||||||
|
* state and set the reap_limit appropriately
|
||||||
|
* as per the near full state
|
||||||
|
* @soc: Datapath soc handle
|
||||||
|
* @dp_srng: Datapath handle for SRNG
|
||||||
|
* @max_reap_limit: [Output Buffer] Buffer to set the max reap limit as per
|
||||||
|
* the srng near-full state
|
||||||
|
*
|
||||||
|
* Return: 1, if the srng is in near-full state
|
||||||
|
* 0, if the srng is not in near-full state
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
dp_srng_test_and_update_nf_params_be(struct dp_soc *soc,
|
||||||
|
struct dp_srng *dp_srng,
|
||||||
|
int *max_reap_limit)
|
||||||
|
{
|
||||||
|
return _dp_srng_test_and_update_nf_params(soc, dp_srng, max_reap_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_init_near_full_arch_ops_be() - Initialize the arch ops handler for the
|
||||||
|
* near full IRQ handling operations.
|
||||||
|
* @arch_ops: arch ops handle
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
|
dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
|
||||||
{
|
{
|
||||||
arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be;
|
arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be;
|
||||||
|
arch_ops->dp_srng_test_and_update_nf_params =
|
||||||
|
dp_srng_test_and_update_nf_params_be;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
|
dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
|
||||||
|
@@ -441,9 +441,9 @@ dp_srng_get_near_full_level(struct dp_soc *soc, struct dp_srng *dp_srng)
|
|||||||
* 0, if the srng is not near full
|
* 0, if the srng is not near full
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
dp_srng_test_and_update_nf_params(struct dp_soc *soc,
|
_dp_srng_test_and_update_nf_params(struct dp_soc *soc,
|
||||||
struct dp_srng *srng,
|
struct dp_srng *srng,
|
||||||
int *max_reap_limit)
|
int *max_reap_limit)
|
||||||
{
|
{
|
||||||
int ring_near_full = 0, near_full_level;
|
int ring_near_full = 0, near_full_level;
|
||||||
|
|
||||||
@@ -471,9 +471,9 @@ dp_srng_test_and_update_nf_params(struct dp_soc *soc,
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline int
|
static inline int
|
||||||
dp_srng_test_and_update_nf_params(struct dp_soc *soc,
|
_dp_srng_test_and_update_nf_params(struct dp_soc *soc,
|
||||||
struct dp_srng *srng,
|
struct dp_srng *srng,
|
||||||
int *max_reap_limit)
|
int *max_reap_limit)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -134,8 +134,8 @@ more_data:
|
|||||||
qdf_mem_zero(head, sizeof(head));
|
qdf_mem_zero(head, sizeof(head));
|
||||||
qdf_mem_zero(tail, sizeof(tail));
|
qdf_mem_zero(tail, sizeof(tail));
|
||||||
|
|
||||||
ring_near_full = dp_srng_test_and_update_nf_params(soc, rx_ring,
|
ring_near_full = _dp_srng_test_and_update_nf_params(soc, rx_ring,
|
||||||
&max_reap_limit);
|
&max_reap_limit);
|
||||||
|
|
||||||
if (qdf_unlikely(dp_rx_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
|
if (qdf_unlikely(dp_rx_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
|
||||||
/*
|
/*
|
||||||
|
@@ -435,6 +435,16 @@ uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
|
hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
|
||||||
uint32_t quota)
|
uint32_t quota)
|
||||||
{
|
{
|
||||||
return 0;
|
struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id];
|
||||||
|
uint32_t work_done = 0;
|
||||||
|
|
||||||
|
if (dp_srng_get_near_full_level(soc, tx_comp_ring) <
|
||||||
|
DP_SRNG_THRESH_NEAR_FULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
qdf_atomic_set(&tx_comp_ring->near_full, 1);
|
||||||
|
work_done++;
|
||||||
|
|
||||||
|
return work_done;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4355,13 +4355,13 @@ void dp_tx_process_htt_completion(struct dp_soc *soc,
|
|||||||
|
|
||||||
#ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
|
#ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
|
||||||
static inline
|
static inline
|
||||||
bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped)
|
bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped,
|
||||||
|
int max_reap_limit)
|
||||||
{
|
{
|
||||||
bool limit_hit = false;
|
bool limit_hit = false;
|
||||||
struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
|
|
||||||
|
|
||||||
limit_hit =
|
limit_hit =
|
||||||
(num_reaped >= cfg->tx_comp_loop_pkt_limit) ? true : false;
|
(num_reaped >= max_reap_limit) ? true : false;
|
||||||
|
|
||||||
if (limit_hit)
|
if (limit_hit)
|
||||||
DP_STATS_INC(soc, tx.tx_comp_loop_pkt_limit_hit, 1);
|
DP_STATS_INC(soc, tx.tx_comp_loop_pkt_limit_hit, 1);
|
||||||
@@ -4373,9 +4373,17 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc)
|
|||||||
{
|
{
|
||||||
return soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check;
|
return soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int dp_tx_comp_get_loop_pkt_limit(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
|
||||||
|
|
||||||
|
return cfg->tx_comp_loop_pkt_limit;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static inline
|
static inline
|
||||||
bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped)
|
bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped,
|
||||||
|
int max_reap_limit)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4384,6 +4392,28 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int dp_tx_comp_get_loop_pkt_limit(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
|
||||||
|
static inline int
|
||||||
|
dp_srng_test_and_update_nf_params(struct dp_soc *soc, struct dp_srng *dp_srng,
|
||||||
|
int *max_reap_limit)
|
||||||
|
{
|
||||||
|
return soc->arch_ops.dp_srng_test_and_update_nf_params(soc, dp_srng,
|
||||||
|
max_reap_limit);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline int
|
||||||
|
dp_srng_test_and_update_nf_params(struct dp_soc *soc, struct dp_srng *dp_srng,
|
||||||
|
int *max_reap_limit)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#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,
|
||||||
@@ -4399,6 +4429,8 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t num_avail_for_reap = 0;
|
uint32_t num_avail_for_reap = 0;
|
||||||
bool force_break = false;
|
bool force_break = false;
|
||||||
|
struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id];
|
||||||
|
int max_reap_limit, ring_near_full;
|
||||||
|
|
||||||
DP_HIST_INIT();
|
DP_HIST_INIT();
|
||||||
|
|
||||||
@@ -4407,6 +4439,10 @@ more_data:
|
|||||||
head_desc = NULL;
|
head_desc = NULL;
|
||||||
tail_desc = NULL;
|
tail_desc = NULL;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
max_reap_limit = dp_tx_comp_get_loop_pkt_limit(soc);
|
||||||
|
|
||||||
|
ring_near_full = dp_srng_test_and_update_nf_params(soc, tx_comp_ring,
|
||||||
|
&max_reap_limit);
|
||||||
|
|
||||||
if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
|
if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
|
||||||
dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
|
dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
|
||||||
@@ -4561,7 +4597,7 @@ next_desc:
|
|||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (dp_tx_comp_loop_pkt_limit_hit(soc, count))
|
if (dp_tx_comp_loop_pkt_limit_hit(soc, count, max_reap_limit))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4571,6 +4607,17 @@ next_desc:
|
|||||||
if (head_desc)
|
if (head_desc)
|
||||||
dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
|
dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are processing in near-full condition, there are 3 scenario
|
||||||
|
* 1) Ring entries has reached critical state
|
||||||
|
* 2) Ring entries are still near high threshold
|
||||||
|
* 3) Ring entries are below the safe level
|
||||||
|
*
|
||||||
|
* One more loop will move te state to normal processing and yield
|
||||||
|
*/
|
||||||
|
if (ring_near_full)
|
||||||
|
goto more_data;
|
||||||
|
|
||||||
if (dp_tx_comp_enable_eol_data_check(soc)) {
|
if (dp_tx_comp_enable_eol_data_check(soc)) {
|
||||||
|
|
||||||
if (num_processed >= quota)
|
if (num_processed >= quota)
|
||||||
|
@@ -1557,6 +1557,8 @@ enum dp_context_type {
|
|||||||
* source from HAL desc for wbm release ring
|
* source from HAL desc for wbm release ring
|
||||||
* @dp_service_near_full_srngs: Handler for servicing the near full IRQ
|
* @dp_service_near_full_srngs: Handler for servicing the near full IRQ
|
||||||
* @txrx_set_vdev_param: target specific ops while setting vdev params
|
* @txrx_set_vdev_param: target specific ops while setting vdev params
|
||||||
|
* @dp_srng_test_and_update_nf_params: Check if the srng is in near full state
|
||||||
|
* and set the near-full params.
|
||||||
*/
|
*/
|
||||||
struct dp_arch_ops {
|
struct dp_arch_ops {
|
||||||
/* INIT/DEINIT Arch Ops */
|
/* INIT/DEINIT Arch Ops */
|
||||||
@@ -1620,6 +1622,9 @@ struct dp_arch_ops {
|
|||||||
|
|
||||||
/* Misc Arch Ops */
|
/* Misc Arch Ops */
|
||||||
qdf_size_t (*txrx_get_context_size)(enum dp_context_type);
|
qdf_size_t (*txrx_get_context_size)(enum dp_context_type);
|
||||||
|
int (*dp_srng_test_and_update_nf_params)(struct dp_soc *soc,
|
||||||
|
struct dp_srng *dp_srng,
|
||||||
|
int *max_reap_limit);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SOC level structure for data path */
|
/* SOC level structure for data path */
|
||||||
|
Referens i nytt ärende
Block a user