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:
Rakesh Pillai
2021-04-08 04:15:49 -07:00
committad av Madan Koyyalamudi
förälder 5605d45923
incheckning 813b3bb474
6 ändrade filer med 106 tillägg och 14 borttagningar

Visa fil

@@ -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)

Visa fil

@@ -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;
} }

Visa fil

@@ -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))) {
/* /*

Visa fil

@@ -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

Visa fil

@@ -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)

Visa fil

@@ -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 */