rx/tx queue setup and intr enable implementations.

Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn>
---
 drivers/net/zxdh/zxdh_ethdev.c |   4 +
 drivers/net/zxdh/zxdh_queue.c  | 149 +++++++++++++++++++++++++++++++++
 drivers/net/zxdh/zxdh_queue.h  |  33 ++++++++
 3 files changed, 186 insertions(+)

diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 717a1d2b0b..521d7ed433 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -933,6 +933,10 @@ static const struct eth_dev_ops zxdh_eth_dev_ops = {
 	.dev_configure			 = zxdh_dev_configure,
 	.dev_close				 = zxdh_dev_close,
 	.dev_infos_get			 = zxdh_dev_infos_get,
+	.rx_queue_setup			 = zxdh_dev_rx_queue_setup,
+	.tx_queue_setup			 = zxdh_dev_tx_queue_setup,
+	.rx_queue_intr_enable	 = zxdh_dev_rx_queue_intr_enable,
+	.rx_queue_intr_disable	 = zxdh_dev_rx_queue_intr_disable,
 };
 
 static int32_t
diff --git a/drivers/net/zxdh/zxdh_queue.c b/drivers/net/zxdh/zxdh_queue.c
index b4ef90ea36..af21f046ad 100644
--- a/drivers/net/zxdh/zxdh_queue.c
+++ b/drivers/net/zxdh/zxdh_queue.c
@@ -12,6 +12,11 @@
 #include "zxdh_common.h"
 #include "zxdh_msg.h"
 
+#define ZXDH_MBUF_MIN_SIZE       sizeof(struct zxdh_net_hdr_dl)
+#define ZXDH_MBUF_SIZE_4K             4096
+#define ZXDH_RX_FREE_THRESH           32
+#define ZXDH_TX_FREE_THRESH           32
+
 struct rte_mbuf *
 zxdh_queue_detach_unused(struct zxdh_virtqueue *vq)
 {
@@ -125,3 +130,147 @@ zxdh_free_queues(struct rte_eth_dev *dev)
 
 	return 0;
 }
+
+static int
+zxdh_check_mempool(struct rte_mempool *mp, uint16_t offset, uint16_t min_length)
+{
+	uint16_t data_room_size;
+
+	if (mp == NULL)
+		return -EINVAL;
+	data_room_size = rte_pktmbuf_data_room_size(mp);
+	if (data_room_size < offset + min_length) {
+		PMD_RX_LOG(ERR,
+				   "%s mbuf_data_room_size %u < %u (%u + %u)",
+				   mp->name, data_room_size,
+				   offset + min_length, offset, min_length);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int32_t
+zxdh_dev_rx_queue_setup(struct rte_eth_dev *dev,
+			uint16_t queue_idx,
+			uint16_t nb_desc,
+			uint32_t socket_id __rte_unused,
+			const struct rte_eth_rxconf *rx_conf,
+			struct rte_mempool *mp)
+{
+	struct zxdh_hw *hw = dev->data->dev_private;
+	uint16_t vtpci_logic_qidx = 2 * queue_idx + ZXDH_RQ_QUEUE_IDX;
+	struct zxdh_virtqueue *vq = hw->vqs[vtpci_logic_qidx];
+	int32_t ret = 0;
+
+	if (rx_conf->rx_deferred_start) {
+		PMD_RX_LOG(ERR, "Rx deferred start is not supported");
+		return -EINVAL;
+	}
+	uint16_t rx_free_thresh = rx_conf->rx_free_thresh;
+
+	if (rx_free_thresh == 0)
+		rx_free_thresh = RTE_MIN(vq->vq_nentries / 4, ZXDH_RX_FREE_THRESH);
+
+	/* rx_free_thresh must be multiples of four. */
+	if (rx_free_thresh & 0x3) {
+		PMD_RX_LOG(ERR, "(rx_free_thresh=%u port=%u queue=%u)",
+			rx_free_thresh, dev->data->port_id, queue_idx);
+		return -EINVAL;
+	}
+	/* rx_free_thresh must be less than the number of RX entries */
+	if (rx_free_thresh >= vq->vq_nentries) {
+		PMD_RX_LOG(ERR, "RX entries (%u). (rx_free_thresh=%u port=%u queue=%u)",
+			vq->vq_nentries, rx_free_thresh, dev->data->port_id, queue_idx);
+		return -EINVAL;
+	}
+	vq->vq_free_thresh = rx_free_thresh;
+	nb_desc = ZXDH_QUEUE_DEPTH;
+
+	vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);
+	struct zxdh_virtnet_rx *rxvq = &vq->rxq;
+
+	rxvq->queue_id = vtpci_logic_qidx;
+
+	int mbuf_min_size  = ZXDH_MBUF_MIN_SIZE;
+
+	if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
+		mbuf_min_size = ZXDH_MBUF_SIZE_4K;
+
+	ret = zxdh_check_mempool(mp, RTE_PKTMBUF_HEADROOM, mbuf_min_size);
+	if (ret != 0) {
+		PMD_RX_LOG(ERR,
+			"rxq setup but mpool size too small(<%d) failed", mbuf_min_size);
+		return -EINVAL;
+	}
+	rxvq->mpool = mp;
+	if (queue_idx < dev->data->nb_rx_queues)
+		dev->data->rx_queues[queue_idx] = rxvq;
+
+	return 0;
+}
+
+int32_t
+zxdh_dev_tx_queue_setup(struct rte_eth_dev *dev,
+			uint16_t queue_idx,
+			uint16_t nb_desc,
+			uint32_t socket_id __rte_unused,
+			const struct rte_eth_txconf *tx_conf)
+{
+	uint16_t vtpci_logic_qidx = 2 * queue_idx + ZXDH_TQ_QUEUE_IDX;
+	struct zxdh_hw *hw = dev->data->dev_private;
+	struct zxdh_virtqueue *vq = hw->vqs[vtpci_logic_qidx];
+	struct zxdh_virtnet_tx *txvq = NULL;
+	uint16_t tx_free_thresh = 0;
+
+	if (tx_conf->tx_deferred_start) {
+		PMD_TX_LOG(ERR, "Tx deferred start is not supported");
+		return -EINVAL;
+	}
+
+	nb_desc = ZXDH_QUEUE_DEPTH;
+
+	vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);
+
+	txvq = &vq->txq;
+	txvq->queue_id = vtpci_logic_qidx;
+
+	tx_free_thresh = tx_conf->tx_free_thresh;
+	if (tx_free_thresh == 0)
+		tx_free_thresh = RTE_MIN(vq->vq_nentries / 4, ZXDH_TX_FREE_THRESH);
+
+	/* tx_free_thresh must be less than the number of TX entries minus 3 */
+	if (tx_free_thresh >= (vq->vq_nentries - 3)) {
+		PMD_TX_LOG(ERR, "TX entries - 3 (%u). (tx_free_thresh=%u port=%u queue=%u)",
+				vq->vq_nentries - 3, tx_free_thresh, dev->data->port_id, queue_idx);
+		return -EINVAL;
+	}
+
+	vq->vq_free_thresh = tx_free_thresh;
+
+	if (queue_idx < dev->data->nb_tx_queues)
+		dev->data->tx_queues[queue_idx] = txvq;
+
+	return 0;
+}
+
+int32_t
+zxdh_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct zxdh_hw *hw = dev->data->dev_private;
+	struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct zxdh_virtqueue *vq = rxvq->vq;
+
+	zxdh_queue_enable_intr(vq);
+	zxdh_mb(hw->weak_barriers);
+	return 0;
+}
+
+int32_t
+zxdh_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct zxdh_virtqueue  *vq	= rxvq->vq;
+
+	zxdh_queue_disable_intr(vq);
+	return 0;
+}
diff --git a/drivers/net/zxdh/zxdh_queue.h b/drivers/net/zxdh/zxdh_queue.h
index 1304d5e4ea..2f602d894f 100644
--- a/drivers/net/zxdh/zxdh_queue.h
+++ b/drivers/net/zxdh/zxdh_queue.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <rte_common.h>
+#include <rte_atomic.h>
 
 #include "zxdh_ethdev.h"
 #include "zxdh_rxtx.h"
@@ -30,6 +31,7 @@ enum { ZXDH_VTNET_RQ = 0, ZXDH_VTNET_TQ = 1 };
 #define ZXDH_RING_EVENT_FLAGS_DESC        0x2
 
 #define ZXDH_VQ_RING_DESC_CHAIN_END       32768
+#define ZXDH_QUEUE_DEPTH                  1024
 
 /*
  * ring descriptors: 16 bytes.
@@ -270,8 +272,39 @@ zxdh_queue_disable_intr(struct zxdh_virtqueue *vq)
 	}
 }
 
+static inline void
+zxdh_queue_enable_intr(struct zxdh_virtqueue *vq)
+{
+	if (vq->vq_packed.event_flags_shadow == ZXDH_RING_EVENT_FLAGS_DISABLE) {
+		vq->vq_packed.event_flags_shadow = ZXDH_RING_EVENT_FLAGS_DISABLE;
+		vq->vq_packed.ring.driver->desc_event_flags = vq->vq_packed.event_flags_shadow;
+	}
+}
+
+static inline void
+zxdh_mb(uint8_t weak_barriers)
+{
+	if (weak_barriers)
+		rte_atomic_thread_fence(rte_memory_order_seq_cst);
+	else
+		rte_mb();
+}
+
 struct rte_mbuf *zxdh_queue_detach_unused(struct zxdh_virtqueue *vq);
 int32_t zxdh_free_queues(struct rte_eth_dev *dev);
 int32_t zxdh_get_queue_type(uint16_t vtpci_queue_idx);
+int32_t zxdh_dev_tx_queue_setup(struct rte_eth_dev *dev,
+			uint16_t queue_idx,
+			uint16_t nb_desc,
+			uint32_t socket_id __rte_unused,
+			const struct rte_eth_txconf *tx_conf);
+int32_t zxdh_dev_rx_queue_setup(struct rte_eth_dev *dev,
+			uint16_t queue_idx,
+			uint16_t nb_desc,
+			uint32_t socket_id __rte_unused,
+			const struct rte_eth_rxconf *rx_conf,
+			struct rte_mempool *mp);
+int32_t zxdh_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
+int32_t zxdh_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
 
 #endif /* ZXDH_QUEUE_H */
-- 
2.27.0