[RFC,13/29] net/qdma: add callback support for Rx queue count
Checks
Commit Message
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(-)
@@ -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;
}
@@ -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
@@ -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;
+}