this patch implements callback support to read
rx_desc and fetch rx_queue_count info.

Signed-off-by: Aman Kumar <aman.ku...@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 --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;
+}
-- 
2.36.1

Reply via email to