diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 53bc61cf0e..1fdec4a8f5 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -733,60 +733,70 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget) struct dp_soc *soc = int_ctx->soc; int ring = 0; uint32_t work_done = 0; - uint32_t budget = dp_budget; + int budget = dp_budget; uint8_t tx_mask = int_ctx->tx_ring_mask; uint8_t rx_mask = int_ctx->rx_ring_mask; uint8_t rx_err_mask = int_ctx->rx_err_ring_mask; uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask; uint8_t reo_status_mask = int_ctx->reo_status_ring_mask; + uint32_t remaining_quota = dp_budget; /* Process Tx completion interrupts first to return back buffers */ - if (tx_mask) { - for (ring = 0; ring < soc->num_tcl_data_rings; ring++) { - if (tx_mask & (1 << ring)) { - work_done = - dp_tx_comp_handler(soc, ring, budget); - budget -= work_done; - if (work_done) - QDF_TRACE(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_INFO, - "tx mask 0x%x ring %d," - "budget %d", - tx_mask, ring, budget); - if (budget <= 0) - goto budget_done; - } + while (tx_mask) { + if (tx_mask & 0x1) { + work_done = + dp_tx_comp_handler(soc, + soc->tx_comp_ring[ring].hal_srng, + remaining_quota); + + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_INFO, + "tx mask 0x%x ring %d," + "budget %d, work_done %d", + tx_mask, ring, budget, work_done); + + budget -= work_done; + if (budget <= 0) + goto budget_done; + + remaining_quota = budget; } + tx_mask = tx_mask >> 1; + ring++; } + /* Process REO Exception ring interrupt */ if (rx_err_mask) { work_done = dp_rx_err_process(soc, - soc->reo_exception_ring.hal_srng, budget); - budget -= work_done; + soc->reo_exception_ring.hal_srng, + remaining_quota); - if (work_done) - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "REO Exception Ring: work_done %d budget %d", work_done, budget); + + budget -= work_done; if (budget <= 0) { goto budget_done; } + remaining_quota = budget; } /* Process Rx WBM release ring interrupt */ if (rx_wbm_rel_mask) { work_done = dp_rx_wbm_err_process(soc, - soc->rx_rel_ring.hal_srng, budget); - budget -= work_done; + soc->rx_rel_ring.hal_srng, remaining_quota); - if (work_done) - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "WBM Release Ring: work_done %d budget %d", work_done, budget); + + budget -= work_done; if (budget <= 0) { goto budget_done; } + remaining_quota = budget; } /* Process Rx interrupts */ @@ -796,16 +806,19 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget) work_done = dp_rx_process(int_ctx, soc->reo_dest_ring[ring].hal_srng, - budget); - budget -= work_done; - if (work_done) - QDF_TRACE(QDF_MODULE_ID_DP, + remaining_quota); + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "rx mask 0x%x ring %d," - "budget %d", - tx_mask, ring, budget); + "work_done %d budget %d", + rx_mask, ring, work_done, + budget); + + budget -= work_done; if (budget <= 0) goto budget_done; + remaining_quota = budget; } } } @@ -819,16 +832,17 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget) continue; if (int_ctx->rx_mon_ring_mask & (1 << ring)) { work_done = - dp_mon_process(soc, ring, budget); - budget -= work_done; + dp_mon_process(soc, ring, remaining_quota); + budget -= work_done; + remaining_quota = budget; } if (int_ctx->rxdma2host_ring_mask & (1 << ring)) { work_done = - dp_rxdma_err_process(soc, ring, budget); + dp_rxdma_err_process(soc, ring, + remaining_quota); budget -= work_done; } - } qdf_lro_flush(int_ctx->lro_ctx); diff --git a/dp/wifi3.0/dp_rx_mon.h b/dp/wifi3.0/dp_rx_mon.h index d3fc6fff96..a4154e886b 100644 --- a/dp/wifi3.0/dp_rx_mon.h +++ b/dp/wifi3.0/dp_rx_mon.h @@ -38,7 +38,6 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota); - QDF_STATUS dp_rx_pdev_mon_attach(struct dp_pdev *pdev); QDF_STATUS dp_rx_pdev_mon_detach(struct dp_pdev *pdev); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 78e291c67a..06da27076e 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -2063,7 +2063,7 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc, * dp_tx_comp_handler() - Tx completion handler * @soc: core txrx main context * @ring_id: completion ring id - * @budget: No. of packets/descriptors that can be serviced in one loop + * @quota: No. of packets/descriptors that can be serviced in one loop * * This function will collect hardware release ring element contents and * handle descriptor contents. Based on contents, free packet or handle error @@ -2071,8 +2071,7 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc, * * Return: none */ -uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, - uint32_t budget) +uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota) { void *tx_comp_hal_desc; uint8_t buffer_src; @@ -2082,7 +2081,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, struct dp_tx_desc_s *head_desc = NULL; struct dp_tx_desc_s *tail_desc = NULL; uint32_t num_processed; - void *hal_srng = soc->tx_comp_ring[ring_id].hal_srng; + uint32_t count; if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -2092,6 +2091,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, } num_processed = 0; + count = 0; /* Find head descriptor from completion ring */ while (qdf_likely(tx_comp_hal_desc = @@ -2100,16 +2100,15 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc); /* If this buffer was not released by TQM or FW, then it is not - * Tx completion indication, skip to next descriptor */ + * Tx completion indication, assert */ if ((buffer_src != HAL_TX_COMP_RELEASE_SOURCE_TQM) && (buffer_src != HAL_TX_COMP_RELEASE_SOURCE_FW)) { QDF_TRACE(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_ERROR, + QDF_TRACE_LEVEL_FATAL, "Tx comp release_src != TQM | FW"); - /* TODO Handle Freeing of the buffer in descriptor */ - continue; + qdf_assert_always(0); } /* Get descriptor id */ @@ -2122,12 +2121,10 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, soc->wlan_cfg_ctx)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "TX COMP pool id %d not valid", + "Tx Comp pool id %d not valid", pool_id); - /* Check if assert aborts execution, if not handle - * return here */ - QDF_ASSERT(0); + qdf_assert_always(0); } /* Find Tx descriptor */ @@ -2144,9 +2141,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, "Tx Comp pool id %d not matched %d", pool_id, tx_desc->pool_id); - /* Check if assert aborts execution, if not handle - * return here */ - QDF_ASSERT(0); + qdf_assert_always(0); } if (!(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED) || @@ -2160,8 +2155,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, } /* - * If the release source is FW, process the HTT - * status + * If the release source is FW, process the HTT status */ if (qdf_unlikely(buffer_src == HAL_TX_COMP_RELEASE_SOURCE_FW)) { @@ -2171,15 +2165,15 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, dp_tx_process_htt_completion(tx_desc, htt_tx_status); } else { - tx_desc->next = NULL; /* First ring descriptor on the cycle */ if (!head_desc) { head_desc = tx_desc; - } else { - tail_desc->next = tx_desc; + tail_desc = tx_desc; } + tail_desc->next = tx_desc; + tx_desc->next = NULL; tail_desc = tx_desc; /* Collect hw completion contents */ @@ -2188,15 +2182,16 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, } - num_processed++; + num_processed += !(count & DP_TX_NAPI_BUDGET_DIV_MASK); /* * Processed packet count is more than given quota * stop to processing */ - if (num_processed >= budget) + if ((num_processed >= quota)) break; + count++; } hal_srng_access_end(soc->hal_soc, hal_srng); diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h index e07bb03fca..fae65be80a 100644 --- a/dp/wifi3.0/dp_tx.h +++ b/dp/wifi3.0/dp_tx.h @@ -143,8 +143,7 @@ QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev); qdf_nbuf_t dp_tx_send(void *data_vdev, qdf_nbuf_t nbuf); -uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, - uint32_t budget); +uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota); int32_t dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf); diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 8c4613fb71..6a439c41ea 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -26,9 +26,19 @@ #if defined(CONFIG_MCL) #define MAX_PDEV_CNT 1 #define WLAN_CFG_INT_NUM_CONTEXTS 7 +/* + * This mask defines how many transmit frames account for 1 NAPI work unit + * 0 means each tx completion is 1 unit + */ +#define DP_TX_NAPI_BUDGET_DIV_MASK 0 #else #define MAX_PDEV_CNT 3 #define WLAN_CFG_INT_NUM_CONTEXTS 4 +/* + * This mask defines how many transmit frames account for 1 NAPI work unit + * 0xFFFF means each 64K tx frame completions account for 1 unit of NAPI budget + */ +#define DP_TX_NAPI_BUDGET_DIV_MASK 0xFFFF #endif /* Tx configuration */