Forráskód Böngészése

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
Tallapragada Kalyan 2 éve
szülő
commit
ee4fb4380c
4 módosított fájl, 234 hozzáadás és 7 törlés
  1. 8 1
      dp/wifi3.0/dp_rings_main.c
  2. 99 0
      dp/wifi3.0/dp_rx.c
  3. 108 4
      dp/wifi3.0/dp_rx.h
  4. 19 2
      dp/wifi3.0/dp_rx_desc.c

+ 8 - 1
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,

+ 99 - 0
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*/

+ 108 - 4
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

+ 19 - 2
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);