diff mbox series

[RFC,13/29] net/qdma: add callback support for Rx queue count

Message ID 20220706075219.517046-14-aman.kumar@vvdntech.in (mailing list archive)
State New
Delegated to: Thomas Monjalon
Headers show
Series cover letter for net/qdma PMD | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Aman Kumar July 6, 2022, 7:52 a.m. UTC
this patch implements callback support to read
rx_desc and fetch rx_queue_count info.

Signed-off-by: Aman Kumar <aman.kumar@vvdntech.in>
---
 drivers/net/qdma/qdma_devops.c |   2 +
 drivers/net/qdma/qdma_devops.h |   6 +-
 drivers/net/qdma/qdma_rxtx.c   | 120 +++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/qdma/qdma_devops.c b/drivers/net/qdma/qdma_devops.c
index 017dcf39ff..fefbbda012 100644
--- a/drivers/net/qdma/qdma_devops.c
+++ b/drivers/net/qdma/qdma_devops.c
@@ -1399,4 +1399,6 @@  void qdma_dev_ops_init(struct rte_eth_dev *dev)
 	dev->dev_ops = &qdma_eth_dev_ops;
 	dev->rx_pkt_burst = &qdma_recv_pkts;
 	dev->tx_pkt_burst = &qdma_xmit_pkts;
+	dev->rx_queue_count = &qdma_dev_rx_queue_count;
+	dev->rx_descriptor_status = &qdma_dev_rx_descriptor_status;
 }
diff --git a/drivers/net/qdma/qdma_devops.h b/drivers/net/qdma/qdma_devops.h
index c0f903f1cf..0014f4b0c9 100644
--- a/drivers/net/qdma/qdma_devops.h
+++ b/drivers/net/qdma/qdma_devops.h
@@ -294,9 +294,7 @@  int qdma_dev_queue_stats_mapping(struct rte_eth_dev *dev,
 /**
  * DPDK callback to get the number of used descriptors of a rx queue
  *
- * @param dev
- *   Pointer to Ethernet device structure
- * @param rx_queue_id
+ * @param rxq
  *   The RX queue on the Ethernet device for which information will be
  *   retrieved
  *
@@ -305,7 +303,7 @@  int qdma_dev_queue_stats_mapping(struct rte_eth_dev *dev,
  * @ingroup dpdk_devops_func
  */
 uint32_t
-qdma_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id);
+qdma_dev_rx_queue_count(void *rxq);
 
 /**
  * DPDK callback to check the status of a Rx descriptor in the queue
diff --git a/drivers/net/qdma/qdma_rxtx.c b/drivers/net/qdma/qdma_rxtx.c
index 15f6661cbf..102671e16f 100644
--- a/drivers/net/qdma/qdma_rxtx.c
+++ b/drivers/net/qdma/qdma_rxtx.c
@@ -206,3 +206,123 @@  static void adapt_update_counter(struct qdma_rx_queue *rxq,
 	}
 }
 #endif /* QDMA_LATENCY_OPTIMIZED */
+
+static uint32_t rx_queue_count(void *rx_queue)
+{
+	struct qdma_rx_queue *rxq = rx_queue;
+	struct wb_status *wb_status;
+	uint16_t pkt_length;
+	uint16_t nb_pkts_avail = 0;
+	uint16_t rx_cmpt_tail = 0;
+	uint16_t cmpt_pidx;
+	uint32_t nb_desc_used = 0, count = 0;
+	union qdma_ul_st_cmpt_ring *user_cmpt_entry;
+	union qdma_ul_st_cmpt_ring cmpt_data;
+
+	wb_status = rxq->wb_status;
+	rx_cmpt_tail = rxq->cmpt_cidx_info.wrb_cidx;
+	cmpt_pidx = wb_status->pidx;
+
+	if (rx_cmpt_tail < cmpt_pidx)
+		nb_pkts_avail = cmpt_pidx - rx_cmpt_tail;
+	else if (rx_cmpt_tail > cmpt_pidx)
+		nb_pkts_avail = rxq->nb_rx_cmpt_desc - 1 - rx_cmpt_tail +
+				cmpt_pidx;
+
+	if (nb_pkts_avail == 0)
+		return 0;
+
+	while (count < nb_pkts_avail) {
+		user_cmpt_entry =
+		(union qdma_ul_st_cmpt_ring *)((uint64_t)rxq->cmpt_ring +
+		((uint64_t)rx_cmpt_tail * rxq->cmpt_desc_len));
+
+		if (qdma_ul_extract_st_cmpt_info(user_cmpt_entry,
+				&cmpt_data)) {
+			break;
+		}
+
+		pkt_length = qdma_ul_get_cmpt_pkt_len(&cmpt_data);
+		if (unlikely(!pkt_length)) {
+			count++;
+			continue;
+		}
+
+		nb_desc_used += ((pkt_length / rxq->rx_buff_size) + 1);
+		rx_cmpt_tail++;
+		if (unlikely(rx_cmpt_tail >= (rxq->nb_rx_cmpt_desc - 1)))
+			rx_cmpt_tail -= (rxq->nb_rx_cmpt_desc - 1);
+		count++;
+	}
+	PMD_DRV_LOG(DEBUG, "%s: nb_desc_used = %d",
+			__func__, nb_desc_used);
+	return nb_desc_used;
+}
+
+/**
+ * DPDK callback to get the number of used descriptors of a rx queue.
+ *
+ * @param dev
+ *   Pointer to Ethernet device structure.
+ * @param rx_queue_id
+ *   The RX queue on the Ethernet device for which information will be
+ *   retrieved
+ *
+ * @return
+ *   The number of used descriptors in the specific queue.
+ */
+uint32_t
+qdma_dev_rx_queue_count(void *rxq)
+{
+	return rx_queue_count(rxq);
+}
+/**
+ * DPDK callback to check the status of a Rx descriptor in the queue.
+ *
+ * @param rx_queue
+ *   Pointer to Rx queue specific data structure.
+ * @param offset
+ *   The offset of the descriptor starting from tail (0 is the next
+ *   packet to be received by the driver).
+ *
+ * @return
+ *  - (RTE_ETH_RX_DESC_AVAIL): Descriptor is available for the hardware to
+ *    receive a packet.
+ *  - (RTE_ETH_RX_DESC_DONE): Descriptor is done, it is filled by hw, but
+ *    not yet processed by the driver (i.e. in the receive queue).
+ *  - (RTE_ETH_RX_DESC_UNAVAIL): Descriptor is unavailable, either hold by
+ *    the driver and not yet returned to hw, or reserved by the hw.
+ *  - (-EINVAL) bad descriptor offset.
+ */
+int
+qdma_dev_rx_descriptor_status(void *rx_queue, uint16_t offset)
+{
+	struct qdma_rx_queue *rxq = rx_queue;
+	uint32_t desc_used_count;
+	uint16_t rx_tail, c2h_pidx, pending_desc;
+
+	if (unlikely(offset >= (rxq->nb_rx_desc - 1)))
+		return -EINVAL;
+
+	/* One descriptor is reserved so that pidx is not same as tail */
+	if (offset == (rxq->nb_rx_desc - 2))
+		return RTE_ETH_RX_DESC_UNAVAIL;
+
+	desc_used_count = rx_queue_count(rxq);
+	if (offset < desc_used_count)
+		return RTE_ETH_RX_DESC_DONE;
+
+	/* If Tail is not same as PIDX, descriptors are held by the driver */
+	rx_tail = rxq->rx_tail;
+	c2h_pidx = rxq->q_pidx_info.pidx;
+
+	pending_desc = rx_tail - c2h_pidx - 1;
+	if (rx_tail < (c2h_pidx + 1))
+		pending_desc = rxq->nb_rx_desc - 2 + rx_tail -
+				c2h_pidx;
+
+	if (offset < (desc_used_count + pending_desc))
+		return RTE_ETH_RX_DESC_UNAVAIL;
+
+	return RTE_ETH_RX_DESC_AVAIL;
+}