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