+ struct otx_ep_device *otx_epvf = OTX_EP_DEV(eth_dev);
+ struct rte_pktmbuf_pool_private *mbp_priv;
+ uint16_t buf_size;
+
+ if (q_no >= otx_epvf->max_rx_queues) {
+ otx_ep_err("Invalid rx queue number %u\n", q_no);
+ return -EINVAL;
+ }
+
+ if (num_rx_descs & (num_rx_descs - 1)) {
+ otx_ep_err("Invalid rx desc number should be pow 2 %u\n",
+ num_rx_descs);
+ return -EINVAL;
+ }
+ if (num_rx_descs < (SDP_GBL_WMARK * 8)) {
+ otx_ep_err("Invalid rx desc number should at least be greater than 8xwmark %u\n",
+ num_rx_descs);
+ return -EINVAL;
+ }
+
+ otx_ep_dbg("setting up rx queue %u\n", q_no);
+
+ mbp_priv = rte_mempool_get_priv(mp);
+ buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+
+ if (otx_ep_setup_oqs(otx_epvf, q_no, num_rx_descs, buf_size, mp,
+ socket_id)) {
+ otx_ep_err("droq allocation failed\n");
+ return -1;
+ }
+
+ eth_dev->data->rx_queues[q_no] = otx_epvf->droq[q_no];
+
+ return 0;
+}
+
+/**
+ * Release the receive queue/ringbuffer. Called by
+ * the upper layers.
+ *
+ * @param rxq
+ * Opaque pointer to the receive queue to release
+ *
+ * @return
+ * - nothing
+ */
+static void
+otx_ep_rx_queue_release(void *rxq)
+{
+ struct otx_ep_droq *rq = (struct otx_ep_droq *)rxq;
+ struct otx_ep_device *otx_epvf = rq->otx_ep_dev;
+ int q_id = rq->q_no;
+
+ if (otx_ep_delete_oqs(otx_epvf, q_id))
+ otx_ep_err("Failed to delete OQ:%d\n", q_id);
+}
+
+/**
+ * Allocate and initialize SW ring. Initialize associated HW registers.
+ *
+ * @param eth_dev
+ * Pointer to structure rte_eth_dev
+ *
+ * @param q_no
+ * Queue number
+ *
+ * @param num_tx_descs
+ * Number of ringbuffer descriptors
+ *
+ * @param socket_id
+ * NUMA socket id, used for memory allocations
+ *
+ * @param tx_conf
+ * Pointer to the structure rte_eth_txconf
+ *
+ * @return
+ * - On success, return 0
+ * - On failure, return -errno value
+ */
+static int
+otx_ep_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t q_no,
+ uint16_t num_tx_descs, unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+ struct otx_ep_device *otx_epvf = OTX_EP_DEV(eth_dev);
+ int retval;
+
+ if (q_no >= otx_epvf->max_tx_queues) {
+ otx_ep_err("Invalid tx queue number %u\n", q_no);
+ return -EINVAL;
+ }
+ if (num_tx_descs & (num_tx_descs - 1)) {
+ otx_ep_err("Invalid tx desc number should be pow 2 %u\n",
+ num_tx_descs);
+ return -EINVAL;
+ }
+
+ retval = otx_ep_setup_iqs(otx_epvf, q_no, num_tx_descs, socket_id);
+
+ if (retval) {
+ otx_ep_err("IQ(TxQ) creation failed.\n");
+ return retval;
+ }
+
+ eth_dev->data->tx_queues[q_no] = otx_epvf->instr_queue[q_no];
+ otx_ep_dbg("tx queue[%d] setup\n", q_no);
+ return 0;
+}
+
+/**
+ * Release the transmit queue/ringbuffer. Called by
+ * the upper layers.
+ *
+ * @param txq
+ * Opaque pointer to the transmit queue to release
+ *
+ * @return
+ * - nothing
+ */
+static void
+otx_ep_tx_queue_release(void *txq)
+{
+ struct otx_ep_instr_queue *tq = (struct otx_ep_instr_queue *)txq;
+
+ otx_ep_delete_iqs(tq->otx_ep_dev, tq->q_no);
+}
+
+/* Define our ethernet definitions */
+static const struct eth_dev_ops otx_ep_eth_dev_ops = {
+ .dev_configure = otx_ep_dev_configure,
+ .dev_start = otx_ep_dev_start,
+ .dev_stop = otx_ep_dev_stop,
+ .rx_queue_setup = otx_ep_rx_queue_setup,
+ .rx_queue_release = otx_ep_rx_queue_release,
+ .tx_queue_setup = otx_ep_tx_queue_setup,
+ .tx_queue_release = otx_ep_tx_queue_release,
+ .dev_infos_get = otx_ep_dev_info_get,
+};
+
+static int
+otx_epdev_exit(struct rte_eth_dev *eth_dev)
+{
+ struct otx_ep_device *otx_epvf;
+ uint32_t num_queues, q;
+
+ otx_ep_info("%s:\n", __func__);
+
+ otx_epvf = OTX_EP_DEV(eth_dev);
+
+ otx_epvf->fn_list.disable_io_queues(otx_epvf);
+
+ num_queues = otx_epvf->nb_rx_queues;
+ for (q = 0; q < num_queues; q++) {
+ if (otx_ep_delete_oqs(otx_epvf, q)) {
+ otx_ep_err("Failed to delete OQ:%d\n", q);
+ return -EINVAL;
+ }
+ }
+ otx_ep_info("Num OQs:%d freed\n", otx_epvf->nb_rx_queues);
+
+ num_queues = otx_epvf->nb_tx_queues;
+ for (q = 0; q < num_queues; q++) {
+ if (otx_ep_delete_iqs(otx_epvf, q)) {
+ otx_ep_err("Failed to delete IQ:%d\n", q);
+ return -EINVAL;
+ }
+ }
+ otx_ep_dbg("Num IQs:%d freed\n", otx_epvf->nb_tx_queues);
+
+ return 0;
+}
+
+static int
+otx_ep_eth_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+ otx_epdev_exit(eth_dev);
+
+ eth_dev->dev_ops = NULL;
+ eth_dev->rx_pkt_burst = NULL;
+ eth_dev->tx_pkt_burst = NULL;
+