rx/tx queue setup and intr enable implementations. Signed-off-by: Junlong Wang --- 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 #include +#include #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