From ee4fb4380c5ff760f28fe2611ee159dce12f40ec Mon Sep 17 00:00:00 2001 From: Tallapragada Kalyan Date: Fri, 13 Jan 2023 18:33:52 +0530 Subject: [PATCH] qcacmn: replenish used nbuf for DS flows in case of DS pkts the same pkt which is received in RX path (REO2PPE) can be refilled back to wifi rxdma CRs-Fixed: 3381462 Change-Id: I3762c91110ffcc95162bf068b7a1ed3e41904824 --- dp/wifi3.0/dp_rings_main.c | 9 ++- dp/wifi3.0/dp_rx.c | 99 ++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_rx.h | 112 +++++++++++++++++++++++++++++++++++-- dp/wifi3.0/dp_rx_desc.c | 21 ++++++- 4 files changed, 234 insertions(+), 7 deletions(-) diff --git a/dp/wifi3.0/dp_rings_main.c b/dp/wifi3.0/dp_rings_main.c index b027d5d096..2172431ff0 100644 --- a/dp/wifi3.0/dp_rings_main.c +++ b/dp/wifi3.0/dp_rings_main.c @@ -1148,6 +1148,10 @@ static int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget) uint32_t work_done = 0; int budget = total_budget; int ring = 0; + bool rx_refill_lt_disable; + + rx_refill_lt_disable = + wlan_cfg_get_dp_soc_rxdma_refill_lt_disable(soc->wlan_cfg_ctx); /* Process LMAC interrupts */ for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) { @@ -1208,7 +1212,10 @@ static int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget) &soc->rx_refill_buf_ring[pdev->lmac_id]; intr_stats->num_host2rxdma_ring_masks++; - dp_rx_buffers_lt_replenish_simple(soc, mac_for_pdev, + + if (!rx_refill_lt_disable) + dp_rx_buffers_lt_replenish_simple(soc, + mac_for_pdev, rx_refill_buf_ring, rx_desc_pool, 0, diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 7fc9ea30e1..85be48a8e2 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -458,7 +458,9 @@ __dp_rx_buffers_no_map_lt_replenish(struct dp_soc *soc, uint32_t mac_id, qdf_assert_always(rxdma_ring_entry); desc_list->rx_desc.nbuf = nbuf; + dp_rx_set_reuse_nbuf(&desc_list->rx_desc, nbuf); desc_list->rx_desc.rx_buf_start = nbuf->data; + desc_list->rx_desc.paddr_buf_start = paddr; desc_list->rx_desc.unmapped = 0; /* rx_desc.in_use should be zero at this time*/ @@ -560,7 +562,9 @@ __dp_rx_buffers_no_map_replenish(struct dp_soc *soc, uint32_t mac_id, break; (*desc_list)->rx_desc.nbuf = nbuf; + dp_rx_set_reuse_nbuf(&(*desc_list)->rx_desc, nbuf); (*desc_list)->rx_desc.rx_buf_start = nbuf->data; + (*desc_list)->rx_desc.paddr_buf_start = QDF_NBUF_CB_PADDR(nbuf); (*desc_list)->rx_desc.unmapped = 0; /* rx_desc.in_use should be zero at this time*/ @@ -600,6 +604,99 @@ __dp_rx_buffers_no_map_replenish(struct dp_soc *soc, uint32_t mac_id, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_SUPPORT_PPEDS +QDF_STATUS +__dp_rx_comp2refill_replenish(struct dp_soc *soc, uint32_t mac_id, + struct dp_srng *dp_rxdma_srng, + struct rx_desc_pool *rx_desc_pool, + uint32_t num_req_buffers, + union dp_rx_desc_list_elem_t **desc_list, + union dp_rx_desc_list_elem_t **tail) +{ + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + uint32_t count; + void *rxdma_ring_entry; + union dp_rx_desc_list_elem_t *next; + union dp_rx_desc_list_elem_t *cur; + void *rxdma_srng; + qdf_nbuf_t nbuf; + + rxdma_srng = dp_rxdma_srng->hal_srng; + + if (qdf_unlikely(!dp_pdev)) { + dp_rx_err("%pK: pdev is null for mac_id = %d", + soc, mac_id); + return QDF_STATUS_E_FAILURE; + } + + if (qdf_unlikely(!rxdma_srng)) { + dp_rx_debug("%pK: rxdma srng not initialized", soc); + DP_STATS_INC(dp_pdev, replenish.rxdma_err, num_req_buffers); + return QDF_STATUS_E_FAILURE; + } + + hal_srng_access_start(soc->hal_soc, rxdma_srng); + + for (count = 0; count < num_req_buffers; count++) { + next = (*desc_list)->next; + qdf_prefetch(next); + + rxdma_ring_entry = (struct dp_buffer_addr_info *) + hal_srng_src_get_next(soc->hal_soc, rxdma_srng); + + if (!rxdma_ring_entry) + break; + + (*desc_list)->rx_desc.in_use = 1; + (*desc_list)->rx_desc.in_err_state = 0; + (*desc_list)->rx_desc.nbuf = (*desc_list)->rx_desc.reuse_nbuf; + + hal_rxdma_buff_addr_info_set(soc->hal_soc, rxdma_ring_entry, + (*desc_list)->rx_desc.paddr_buf_start, + (*desc_list)->rx_desc.cookie, + rx_desc_pool->owner); + + *desc_list = next; + } + hal_srng_access_end(soc->hal_soc, rxdma_srng); + + /* No need to count the number of bytes received during replenish. + * Therefore set replenish.pkts.bytes as 0. + */ + DP_STATS_INC_PKT(dp_pdev, replenish.pkts, count, 0); + DP_STATS_INC(dp_pdev, buf_freelist, (num_req_buffers - count)); + + /* + * add any available free desc back to the free list + */ + cur = *desc_list; + for ( ; count < num_req_buffers; count++) { + next = cur->next; + qdf_prefetch(next); + + nbuf = cur->rx_desc.reuse_nbuf; + + cur->rx_desc.nbuf = NULL; + cur->rx_desc.in_use = 0; + cur->rx_desc.has_reuse_nbuf = false; + cur->rx_desc.reuse_nbuf = NULL; + if (!nbuf->recycled_for_ds) + dp_rx_nbuf_unmap_pool(soc, rx_desc_pool, nbuf); + + nbuf->recycled_for_ds = 0; + nbuf->fast_recycled = 0; + qdf_nbuf_free(nbuf); + cur = next; + } + + if (*desc_list) + dp_rx_add_desc_list_to_free_list(soc, desc_list, tail, + mac_id, rx_desc_pool); + + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS __dp_pdev_rx_buffers_no_map_attach(struct dp_soc *soc, uint32_t mac_id, struct dp_srng *dp_rxdma_srng, @@ -665,7 +762,9 @@ QDF_STATUS __dp_pdev_rx_buffers_no_map_attach(struct dp_soc *soc, qdf_assert_always(rxdma_ring_entry); desc_list->rx_desc.nbuf = nbuf; + dp_rx_set_reuse_nbuf(&desc_list->rx_desc, nbuf); desc_list->rx_desc.rx_buf_start = nbuf->data; + desc_list->rx_desc.paddr_buf_start = paddr; desc_list->rx_desc.unmapped = 0; /* rx_desc.in_use should be zero at this time*/ diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 40df7e26ac..c38cea13d7 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -131,6 +131,7 @@ struct dp_rx_desc_dbg_info { * steering * @chip_id: chip_id indicating MLO chip_id * valid or used only in case of multi-chip MLO + * @reuse_nbuf: VA of the "skb" which is being reused * @magic: * @nbuf_data_addr: VA of nbuf data posted * @dbg_info: @@ -138,9 +139,14 @@ struct dp_rx_desc_dbg_info { * @unmapped: used to mark rx_desc an unmapped if the corresponding * nbuf is already unmapped * @in_err_state: Nbuf sanity failed for this descriptor. + * @has_reuse_nbuf: the nbuf associated with this desc is also saved in + * reuse_nbuf field */ struct dp_rx_desc { qdf_nbuf_t nbuf; +#ifdef WLAN_SUPPORT_PPEDS + qdf_nbuf_t reuse_nbuf; +#endif uint8_t *rx_buf_start; qdf_dma_addr_t paddr_buf_start; uint32_t cookie; @@ -153,7 +159,8 @@ struct dp_rx_desc { #endif uint8_t in_use:1, unmapped:1, - in_err_state:1; + in_err_state:1, + has_reuse_nbuf:1; }; #ifndef QCA_HOST_MODE_WIFI_DISABLED @@ -209,6 +216,9 @@ struct dp_rx_desc { #define dp_rx_add_to_free_desc_list(head, tail, new) \ __dp_rx_add_to_free_desc_list(head, tail, new, __func__) +#define dp_rx_add_to_free_desc_list_reuse(head, tail, new) \ + __dp_rx_add_to_free_desc_list_reuse(head, tail, new, __func__) + #define dp_rx_buffers_replenish(soc, mac_id, rxdma_srng, rx_desc_pool, \ num_buffers, desc_list, tail, req_only) \ __dp_rx_buffers_replenish(soc, mac_id, rxdma_srng, rx_desc_pool, \ @@ -1710,6 +1720,33 @@ __dp_rx_buffers_no_map_replenish(struct dp_soc *dp_soc, uint32_t mac_id, union dp_rx_desc_list_elem_t **desc_list, union dp_rx_desc_list_elem_t **tail); +/** + * __dp_rx_comp2refill_replenish() - replenish rxdma ring with rx nbufs + * use direct APIs to get invalidate + * and get the physical address of the + * nbuf instead of map api,called during + * dp rx initialization and at the end + * of dp_rx_process. + * + * @dp_soc: core txrx main context + * @mac_id: mac_id which is one of 3 mac_ids + * @dp_rxdma_srng: dp rxdma circular ring + * @rx_desc_pool: Pointer to free Rx descriptor pool + * @num_req_buffers: number of buffer to be replenished + * @desc_list: list of descs if called from dp_rx_process + * or NULL during dp rx initialization or out of buffer + * interrupt. + * @tail: tail of descs list + * Return: return success or failure + */ +QDF_STATUS +__dp_rx_comp2refill_replenish(struct dp_soc *dp_soc, uint32_t mac_id, + struct dp_srng *dp_rxdma_srng, + struct rx_desc_pool *rx_desc_pool, + uint32_t num_req_buffers, + union dp_rx_desc_list_elem_t **desc_list, + union dp_rx_desc_list_elem_t **tail); + /** * __dp_rx_buffers_no_map_lt_replenish() - replenish rxdma ring with rx nbufs * use direct APIs to get invalidate @@ -1825,6 +1862,58 @@ void dp_rx_compute_tid_delay(struct cdp_delay_tid_stats *stats, qdf_nbuf_t nbuf); #endif /* QCA_PEER_EXT_STATS */ +#ifdef WLAN_SUPPORT_PPEDS +static inline +void dp_rx_set_reuse_nbuf(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf) +{ + rx_desc->reuse_nbuf = nbuf; + rx_desc->has_reuse_nbuf = true; +} + +/** + * __dp_rx_add_to_free_desc_list_reuse() - Adds to a local free descriptor list + * this list will reused + * + * @head: pointer to the head of local free list + * @tail: pointer to the tail of local free list + * @new: new descriptor that is added to the free list + * @func_name: caller func name + * + * Return: void: + */ +static inline +void __dp_rx_add_to_free_desc_list_reuse(union dp_rx_desc_list_elem_t **head, + union dp_rx_desc_list_elem_t **tail, + struct dp_rx_desc *new, + const char *func_name) +{ + qdf_assert(head && new); + + dp_rx_desc_update_dbg_info(new, func_name, RX_DESC_IN_FREELIST); + + new->nbuf = NULL; + + ((union dp_rx_desc_list_elem_t *)new)->next = *head; + *head = (union dp_rx_desc_list_elem_t *)new; + /* reset tail if head->next is NULL */ + if (!*tail || !(*head)->next) + *tail = *head; +} +#else +static inline +void dp_rx_set_reuse_nbuf(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf) +{ +} + +static inline +void __dp_rx_add_to_free_desc_list_reuse(union dp_rx_desc_list_elem_t **head, + union dp_rx_desc_list_elem_t **tail, + struct dp_rx_desc *new, + const char *func_name) +{ +} +#endif + #ifdef RX_DESC_DEBUG_CHECK /** * dp_rx_desc_check_magic() - check the magic value in dp_rx_desc @@ -1858,6 +1947,8 @@ void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, rx_desc->nbuf = (nbuf_frag_info_t->virt_addr).nbuf; rx_desc->unmapped = 0; rx_desc->nbuf_data_addr = (uint8_t *)qdf_nbuf_data(rx_desc->nbuf); + dp_rx_set_reuse_nbuf(rx_desc, rx_desc->nbuf); + rx_desc->paddr_buf_start = nbuf_frag_info_t->paddr; } /** @@ -1913,6 +2004,8 @@ void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, struct dp_rx_nbuf_frag_info *nbuf_frag_info_t) { rx_desc->nbuf = (nbuf_frag_info_t->virt_addr).nbuf; + dp_rx_set_reuse_nbuf(rx_desc, rx_desc->nbuf); + rx_desc->paddr_buf_start = nbuf_frag_info_t->paddr; rx_desc->unmapped = 0; } @@ -2436,6 +2529,18 @@ void dp_rx_buffers_replenish_simple(struct dp_soc *soc, uint32_t mac_id, num_req_buffers, desc_list, tail); } +static inline +void dp_rx_comp2refill_replenish(struct dp_soc *soc, uint32_t mac_id, + struct dp_srng *rxdma_srng, + struct rx_desc_pool *rx_desc_pool, + uint32_t num_req_buffers, + union dp_rx_desc_list_elem_t **desc_list, + union dp_rx_desc_list_elem_t **tail) +{ + __dp_rx_comp2refill_replenish(soc, mac_id, rxdma_srng, rx_desc_pool, + num_req_buffers, desc_list, tail); +} + static inline void dp_rx_buffers_lt_replenish_simple(struct dp_soc *soc, uint32_t mac_id, struct dp_srng *rxdma_srng, @@ -2466,10 +2571,8 @@ qdf_dma_addr_t dp_rx_nbuf_sync_no_dsb(struct dp_soc *dp_soc, qdf_nbuf_t nbuf, uint32_t buf_size) { - if (nbuf->recycled_for_ds) { - nbuf->recycled_for_ds = 0; + if (nbuf->recycled_for_ds) return (qdf_dma_addr_t)qdf_mem_virt_to_phys(nbuf->data); - } if (unlikely(!nbuf->fast_recycled)) { qdf_nbuf_dma_inv_range_no_dsb((void *)nbuf->data, @@ -2491,6 +2594,7 @@ qdf_dma_addr_t dp_rx_nbuf_sync_no_dsb(struct dp_soc *dp_soc, } nbuf->fast_recycled = 0; + return (qdf_dma_addr_t)qdf_mem_virt_to_phys(nbuf->data); } #endif diff --git a/dp/wifi3.0/dp_rx_desc.c b/dp/wifi3.0/dp_rx_desc.c index 42289636a3..9673fac3dc 100644 --- a/dp/wifi3.0/dp_rx_desc.c +++ b/dp/wifi3.0/dp_rx_desc.c @@ -345,6 +345,23 @@ void dp_rx_desc_pool_init(struct dp_soc *soc, uint32_t pool_id, qdf_export_symbol(dp_rx_desc_pool_init); +#ifdef WLAN_SUPPORT_PPEDS +static inline +qdf_nbuf_t dp_rx_desc_get_nbuf(struct rx_desc_pool *rx_desc_pool, int i) +{ + if (rx_desc_pool->array[i].rx_desc.has_reuse_nbuf) + return rx_desc_pool->array[i].rx_desc.reuse_nbuf; + else + return rx_desc_pool->array[i].rx_desc.nbuf; +} +#else +static inline +qdf_nbuf_t dp_rx_desc_get_nbuf(struct rx_desc_pool *rx_desc_pool, int i) +{ + return rx_desc_pool->array[i].rx_desc.nbuf; +} +#endif + void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id, struct rx_desc_pool *rx_desc_pool) { @@ -354,7 +371,7 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id, qdf_spin_lock_bh(&rx_desc_pool->lock); for (i = 0; i < rx_desc_pool->pool_size; i++) { if (rx_desc_pool->array[i].rx_desc.in_use) { - nbuf = rx_desc_pool->array[i].rx_desc.nbuf; + nbuf = dp_rx_desc_get_nbuf(rx_desc_pool, i); if (!(rx_desc_pool->array[i].rx_desc.unmapped)) { dp_rx_nbuf_unmap_pool(soc, rx_desc_pool, nbuf); @@ -379,7 +396,7 @@ void dp_rx_desc_nbuf_free(struct dp_soc *soc, for (i = 0; i < rx_desc_pool->pool_size; i++) { dp_rx_desc_free_dbg_info(&rx_desc_pool->array[i].rx_desc); if (rx_desc_pool->array[i].rx_desc.in_use) { - nbuf = rx_desc_pool->array[i].rx_desc.nbuf; + nbuf = dp_rx_desc_get_nbuf(rx_desc_pool, i); if (!(rx_desc_pool->array[i].rx_desc.unmapped)) { dp_rx_nbuf_unmap_pool(soc, rx_desc_pool, nbuf);