net/mlx5: remove Tx implementation
authorViacheslav Ovsiienko <viacheslavo@mellanox.com>
Sun, 21 Jul 2019 14:24:53 +0000 (14:24 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 23 Jul 2019 12:31:36 +0000 (14:31 +0200)
This patch removes the existing Tx datapath code
as preparation step before introducing the new
implementation. The following entities are being
removed:

- deprecated devargs support
- tx_burst() routines
- related PRM definitions
- SQ configuration code
- Tx routine selection code
- incompatible Tx completion code

The following devargs are deprecated and ignored:
- "txq_inline" is going to be converted to "txq_inline_max"
  for compatibility issue
- "tx_vec_en"
- "txqs_max_vec"
- "txq_mpw_hdr_dseg_en"
- "txq_max_inline_len" is going to be converted
  to "txq_inline_mpw" for compatibility issue

The deprecated devarg keys are recognized by PMD
and ignored/converted to the new ones in order not
to block device probing.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
Acked-by: Yongseok Koh <yskoh@mellanox.com>
12 files changed:
doc/guides/nics/mlx5.rst
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_defs.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_prm.h
drivers/net/mlx5/mlx5_rxtx.c
drivers/net/mlx5/mlx5_rxtx.h
drivers/net/mlx5/mlx5_rxtx_vec.c
drivers/net/mlx5/mlx5_rxtx_vec_neon.h
drivers/net/mlx5/mlx5_rxtx_vec_sse.h
drivers/net/mlx5/mlx5_txq.c

index 16aa390..5cf1e76 100644 (file)
@@ -350,13 +350,8 @@ Run-time configuration
 
 - ``txq_inline`` parameter [int]
 
-  Amount of data to be inlined during TX operations. Improves latency.
-  Can improve PPS performance when PCI back pressure is detected and may be
-  useful for scenarios involving heavy traffic on many queues.
-
-  Because additional software logic is necessary to handle this mode, this
-  option should be used with care, as it can lower performance when back
-  pressure is not expected.
+  Amount of data to be inlined during TX operations. This parameter is
+  deprecated and ignored, kept for compatibility issue.
 
 - ``txqs_min_inline`` parameter [int]
 
@@ -378,16 +373,8 @@ Run-time configuration
 - ``txqs_max_vec`` parameter [int]
 
   Enable vectorized Tx only when the number of TX queues is less than or
-  equal to this value. Effective only when ``tx_vec_en`` is enabled.
-
-  On ConnectX-5:
-
-        - Set to 8 by default on ARMv8.
-        - Set to 4 by default otherwise.
-
-  On BlueField
-
-        - Set to 16 by default.
+  equal to this value. This parameter is deprecated and ignored, kept
+  for compatibility issue to not prevent driver from probing.
 
 - ``txq_mpw_en`` parameter [int]
 
@@ -418,7 +405,8 @@ Run-time configuration
 - ``txq_mpw_hdr_dseg_en`` parameter [int]
 
   A nonzero value enables including two pointers in the first block of TX
-  descriptor. This can be used to lessen CPU load for memory copy.
+  descriptor. The parameter is deprecated and ignored, kept for compatibility
+  issue.
 
   Effective only when Enhanced MPS is supported. Disabled by default.
 
@@ -427,14 +415,14 @@ Run-time configuration
   Maximum size of packet to be inlined. This limits the size of packet to
   be inlined. If the size of a packet is larger than configured value, the
   packet isn't inlined even though there's enough space remained in the
-  descriptor. Instead, the packet is included with pointer.
-
-  Effective only when Enhanced MPS is supported. The default value is 256.
+  descriptor. Instead, the packet is included with pointer. This parameter
+  is deprecated.
 
 - ``tx_vec_en`` parameter [int]
 
-  A nonzero value enables Tx vector on ConnectX-5, ConnectX-6 and BlueField NICs if the number of
-  global Tx queues on the port is less than ``txqs_max_vec``.
+  A nonzero value enables Tx vector on ConnectX-5, ConnectX-6 and BlueField
+  NICs if the number of global Tx queues on the port is less than
+  ``txqs_max_vec``. The parameter is deprecated and ignored.
 
   This option cannot be used with certain offloads such as ``DEV_TX_OFFLOAD_TCP_TSO,
   DEV_TX_OFFLOAD_VXLAN_TNL_TSO, DEV_TX_OFFLOAD_GRE_TNL_TSO, DEV_TX_OFFLOAD_VLAN_INSERT``.
index 7e0df51..5b11b20 100644 (file)
@@ -69,7 +69,7 @@
 /* Device parameter to set the minimum number of Rx queues to enable MPRQ. */
 #define MLX5_RXQS_MIN_MPRQ "rxqs_min_mprq"
 
-/* Device parameter to configure inline send. */
+/* Device parameter to configure inline send. Deprecated, ignored.*/
 #define MLX5_TXQ_INLINE "txq_inline"
 
 /*
 
 /*
  * Device parameter to configure the number of TX queues threshold for
- * enabling vectorized Tx.
+ * enabling vectorized Tx, deprecated, ignored (no vectorized Tx routines).
  */
 #define MLX5_TXQS_MAX_VEC "txqs_max_vec"
 
 /* Device parameter to enable multi-packet send WQEs. */
 #define MLX5_TXQ_MPW_EN "txq_mpw_en"
 
-/* Device parameter to include 2 dsegs in the title WQEBB. */
+/*
+ * Device parameter to include 2 dsegs in the title WQEBB.
+ * Deprecated, ignored.
+ */
 #define MLX5_TXQ_MPW_HDR_DSEG_EN "txq_mpw_hdr_dseg_en"
 
-/* Device parameter to limit the size of inlining packet. */
+/*
+ * Device parameter to limit the size of inlining packet.
+ * Deprecated, ignored.
+ */
 #define MLX5_TXQ_MAX_INLINE_LEN "txq_max_inline_len"
 
-/* Device parameter to enable hardware Tx vector. */
+/*
+ * Device parameter to enable hardware Tx vector.
+ * Deprecated, ignored (no vectorized Tx routines anymore).
+ */
 #define MLX5_TX_VEC_EN "tx_vec_en"
 
 /* Device parameter to enable hardware Rx vector. */
@@ -997,19 +1006,19 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
        } else if (strcmp(MLX5_RXQS_MIN_MPRQ, key) == 0) {
                config->mprq.min_rxqs_num = tmp;
        } else if (strcmp(MLX5_TXQ_INLINE, key) == 0) {
-               config->txq_inline = tmp;
+               DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
        } else if (strcmp(MLX5_TXQS_MIN_INLINE, key) == 0) {
                config->txqs_inline = tmp;
        } else if (strcmp(MLX5_TXQS_MAX_VEC, key) == 0) {
-               config->txqs_vec = tmp;
+               DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
        } else if (strcmp(MLX5_TXQ_MPW_EN, key) == 0) {
                config->mps = !!tmp;
        } else if (strcmp(MLX5_TXQ_MPW_HDR_DSEG_EN, key) == 0) {
-               config->mpw_hdr_dseg = !!tmp;
+               DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
        } else if (strcmp(MLX5_TXQ_MAX_INLINE_LEN, key) == 0) {
-               config->inline_max_packet_sz = tmp;
+               DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
        } else if (strcmp(MLX5_TX_VEC_EN, key) == 0) {
-               config->tx_vec_en = !!tmp;
+               DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
        } else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
                config->rx_vec_en = !!tmp;
        } else if (strcmp(MLX5_L3_VXLAN_EN, key) == 0) {
@@ -2016,12 +2025,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        dev_config = (struct mlx5_dev_config){
                .hw_padding = 0,
                .mps = MLX5_ARG_UNSET,
-               .tx_vec_en = 1,
                .rx_vec_en = 1,
-               .txq_inline = MLX5_ARG_UNSET,
                .txqs_inline = MLX5_ARG_UNSET,
-               .txqs_vec = MLX5_ARG_UNSET,
-               .inline_max_packet_sz = MLX5_ARG_UNSET,
                .vf_nl_en = 1,
                .mr_ext_memseg_en = 1,
                .mprq = {
@@ -2034,9 +2039,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        };
        /* Device specific configuration. */
        switch (pci_dev->id.device_id) {
-       case PCI_DEVICE_ID_MELLANOX_CONNECTX5BF:
-               dev_config.txqs_vec = MLX5_VPMD_MAX_TXQS_BLUEFIELD;
-               break;
        case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
        case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
        case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
@@ -2046,9 +2048,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        default:
                break;
        }
-       /* Set architecture-dependent default value if unset. */
-       if (dev_config.txqs_vec == MLX5_ARG_UNSET)
-               dev_config.txqs_vec = MLX5_VPMD_MAX_TXQS;
        for (i = 0; i != ns; ++i) {
                uint32_t restore;
 
index 6230371..354f6bc 100644 (file)
@@ -198,9 +198,7 @@ struct mlx5_dev_config {
        unsigned int cqe_comp:1; /* CQE compression is enabled. */
        unsigned int cqe_pad:1; /* CQE padding is enabled. */
        unsigned int tso:1; /* Whether TSO is supported. */
-       unsigned int tx_vec_en:1; /* Tx vector is enabled. */
        unsigned int rx_vec_en:1; /* Rx vector is enabled. */
-       unsigned int mpw_hdr_dseg:1; /* Enable DSEGs in the title WQEBB. */
        unsigned int mr_ext_memseg_en:1;
        /* Whether memseg should be extended for MR creation. */
        unsigned int l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
@@ -224,10 +222,7 @@ struct mlx5_dev_config {
        unsigned int tso_max_payload_sz; /* Maximum TCP payload for TSO. */
        unsigned int ind_table_max_size; /* Maximum indirection table size. */
        unsigned int max_dump_files_num; /* Maximum dump files per queue. */
-       int txq_inline; /* Maximum packet size for inlining. */
        int txqs_inline; /* Queue number threshold for inlining. */
-       int txqs_vec; /* Queue number threshold for vectorized Tx. */
-       int inline_max_packet_sz; /* Max packet size for inlining. */
        struct mlx5_hca_attr hca_attr; /* HCA attributes. */
 };
 
index 13801a5..6861304 100644 (file)
 /* Maximum Packet headers size (L2+L3+L4) for TSO. */
 #define MLX5_MAX_TSO_HEADER 192
 
-/* Default maximum number of Tx queues for vectorized Tx. */
-#if defined(RTE_ARCH_ARM64)
-#define MLX5_VPMD_MAX_TXQS 8
-#define MLX5_VPMD_MAX_TXQS_BLUEFIELD 16
-#else
-#define MLX5_VPMD_MAX_TXQS 4
-#define MLX5_VPMD_MAX_TXQS_BLUEFIELD MLX5_VPMD_MAX_TXQS
-#endif
-
 /* Threshold of buffer replenishment for vectorized Rx. */
 #define MLX5_VPMD_RXQ_RPLNSH_THRESH(n) \
        (RTE_MIN(MLX5_VPMD_RX_MAX_BURST, (unsigned int)(n) >> 2))
 /* Maximum size of burst for vectorized Rx. */
 #define MLX5_VPMD_RX_MAX_BURST 64U
 
-/*
- * Maximum size of burst for vectorized Tx. This is related to the maximum size
- * of Enhanced MPW (eMPW) WQE as vectorized Tx is supported with eMPW.
- * Careful when changing, large value can cause WQE DS to overlap.
- */
-#define MLX5_VPMD_TX_MAX_BURST        32U
-
 /* Number of packets vectorized Rx can simultaneously process in a loop. */
 #define MLX5_VPMD_DESCS_PER_LOOP      4
 
index f9826c9..738d540 100644 (file)
@@ -1652,64 +1652,6 @@ mlx5_set_link_up(struct rte_eth_dev *dev)
        return mlx5_set_flags(dev, ~IFF_UP, IFF_UP);
 }
 
-/**
- * Configure the TX function to use.
- *
- * @param dev
- *   Pointer to private data structure.
- *
- * @return
- *   Pointer to selected Tx burst function.
- */
-eth_tx_burst_t
-mlx5_select_tx_function(struct rte_eth_dev *dev)
-{
-       struct mlx5_priv *priv = dev->data->dev_private;
-       eth_tx_burst_t tx_pkt_burst = mlx5_tx_burst;
-       struct mlx5_dev_config *config = &priv->config;
-       uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-       int tso = !!(tx_offloads & (DEV_TX_OFFLOAD_TCP_TSO |
-                                   DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
-                                   DEV_TX_OFFLOAD_GRE_TNL_TSO |
-                                   DEV_TX_OFFLOAD_IP_TNL_TSO |
-                                   DEV_TX_OFFLOAD_UDP_TNL_TSO));
-       int swp = !!(tx_offloads & (DEV_TX_OFFLOAD_IP_TNL_TSO |
-                                   DEV_TX_OFFLOAD_UDP_TNL_TSO |
-                                   DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM));
-       int vlan_insert = !!(tx_offloads & DEV_TX_OFFLOAD_VLAN_INSERT);
-
-       assert(priv != NULL);
-       /* Select appropriate TX function. */
-       if (vlan_insert || tso || swp)
-               return tx_pkt_burst;
-       if (config->mps == MLX5_MPW_ENHANCED) {
-               if (mlx5_check_vec_tx_support(dev) > 0) {
-                       if (mlx5_check_raw_vec_tx_support(dev) > 0)
-                               tx_pkt_burst = mlx5_tx_burst_raw_vec;
-                       else
-                               tx_pkt_burst = mlx5_tx_burst_vec;
-                       DRV_LOG(DEBUG,
-                               "port %u selected enhanced MPW Tx vectorized"
-                               " function",
-                               dev->data->port_id);
-               } else {
-                       tx_pkt_burst = mlx5_tx_burst_empw;
-                       DRV_LOG(DEBUG,
-                               "port %u selected enhanced MPW Tx function",
-                               dev->data->port_id);
-               }
-       } else if (config->mps && (config->txq_inline > 0)) {
-               tx_pkt_burst = mlx5_tx_burst_mpw_inline;
-               DRV_LOG(DEBUG, "port %u selected MPW inline Tx function",
-                       dev->data->port_id);
-       } else if (config->mps) {
-               tx_pkt_burst = mlx5_tx_burst_mpw;
-               DRV_LOG(DEBUG, "port %u selected MPW Tx function",
-                       dev->data->port_id);
-       }
-       return tx_pkt_burst;
-}
-
 /**
  * Configure the RX function to use.
  *
index 95ff29a..dfd9317 100644 (file)
 /* Invalidate a CQE. */
 #define MLX5_CQE_INVALIDATE (MLX5_CQE_INVALID << 4)
 
-/* Maximum number of packets a multi-packet WQE can handle. */
-#define MLX5_MPW_DSEG_MAX 5
-
 /* WQE DWORD size */
 #define MLX5_WQE_DWORD_SIZE 16
 
 /* WQE size */
 #define MLX5_WQE_SIZE (4 * MLX5_WQE_DWORD_SIZE)
 
-/* Max size of a WQE session. */
-#define MLX5_WQE_SIZE_MAX 960U
-
-/* Compute the number of DS. */
-#define MLX5_WQE_DS(n) \
-       (((n) + MLX5_WQE_DWORD_SIZE - 1) / MLX5_WQE_DWORD_SIZE)
-
-/* Room for inline data in multi-packet WQE. */
-#define MLX5_MWQE64_INL_DATA 28
-
-/* Default minimum number of Tx queues for inlining packets. */
-#define MLX5_EMPW_MIN_TXQS 8
-
-/* Default max packet length to be inlined. */
-#define MLX5_EMPW_MAX_INLINE_LEN (4U * MLX5_WQE_SIZE)
-
-
 #define MLX5_OPC_MOD_ENHANCED_MPSW 0
 #define MLX5_OPCODE_ENHANCED_MPSW 0x29
 
@@ -164,47 +144,11 @@ enum mlx5_completion_mode {
        MLX5_COMP_CQE_AND_EQE = 0x3,
 };
 
-/* Subset of struct mlx5_wqe_eth_seg. */
-struct mlx5_wqe_eth_seg_small {
-       uint32_t rsvd0;
-       uint8_t cs_flags;
-       uint8_t rsvd1;
-       uint16_t mss;
-       uint32_t flow_table_metadata;
-       uint16_t inline_hdr_sz;
-       uint8_t inline_hdr[2];
-} __rte_aligned(MLX5_WQE_DWORD_SIZE);
-
-struct mlx5_wqe_inl_small {
-       uint32_t byte_cnt;
-       uint8_t raw;
-} __rte_aligned(MLX5_WQE_DWORD_SIZE);
-
-struct mlx5_wqe_ctrl {
-       uint32_t ctrl0;
-       uint32_t ctrl1;
-       uint32_t ctrl2;
-       uint32_t ctrl3;
-} __rte_aligned(MLX5_WQE_DWORD_SIZE);
-
 /* Small common part of the WQE. */
 struct mlx5_wqe {
        uint32_t ctrl[4];
-       struct mlx5_wqe_eth_seg_small eseg;
-};
-
-/* Vectorize WQE header. */
-struct mlx5_wqe_v {
-       rte_v128u32_t ctrl;
-       rte_v128u32_t eseg;
 };
 
-/* WQE. */
-struct mlx5_wqe64 {
-       struct mlx5_wqe hdr;
-       uint8_t raw[32];
-} __rte_aligned(MLX5_WQE_SIZE);
-
 /* MPW mode. */
 enum mlx5_mpw_mode {
        MLX5_MPW_DISABLED,
@@ -212,27 +156,6 @@ enum mlx5_mpw_mode {
        MLX5_MPW_ENHANCED, /* Enhanced Multi-Packet Send WQE, a.k.a MPWv2. */
 };
 
-/* MPW session status. */
-enum mlx5_mpw_state {
-       MLX5_MPW_STATE_OPENED,
-       MLX5_MPW_INL_STATE_OPENED,
-       MLX5_MPW_ENHANCED_STATE_OPENED,
-       MLX5_MPW_STATE_CLOSED,
-};
-
-/* MPW session descriptor. */
-struct mlx5_mpw {
-       enum mlx5_mpw_state state;
-       unsigned int pkts_n;
-       unsigned int len;
-       unsigned int total_len;
-       volatile struct mlx5_wqe *wqe;
-       union {
-               volatile struct mlx5_wqe_data_seg *dseg[MLX5_MPW_DSEG_MAX];
-               volatile uint8_t *raw;
-       } data;
-};
-
 /* WQE for Multi-Packet RQ. */
 struct mlx5_wqe_mprq {
        struct mlx5_wqe_srq_next_seg next_seg;
index c1dc8c4..f2d6918 100644 (file)
@@ -287,140 +287,6 @@ mlx5_set_swp_types_table(void)
        }
 }
 
-/**
- * Return the size of tailroom of WQ.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param addr
- *   Pointer to tail of WQ.
- *
- * @return
- *   Size of tailroom.
- */
-static inline size_t
-tx_mlx5_wq_tailroom(struct mlx5_txq_data *txq, void *addr)
-{
-       size_t tailroom;
-       tailroom = (uintptr_t)(txq->wqes) +
-                  (1 << txq->wqe_n) * MLX5_WQE_SIZE -
-                  (uintptr_t)addr;
-       return tailroom;
-}
-
-/**
- * Copy data to tailroom of circular queue.
- *
- * @param dst
- *   Pointer to destination.
- * @param src
- *   Pointer to source.
- * @param n
- *   Number of bytes to copy.
- * @param base
- *   Pointer to head of queue.
- * @param tailroom
- *   Size of tailroom from dst.
- *
- * @return
- *   Pointer after copied data.
- */
-static inline void *
-mlx5_copy_to_wq(void *dst, const void *src, size_t n,
-               void *base, size_t tailroom)
-{
-       void *ret;
-
-       if (n > tailroom) {
-               rte_memcpy(dst, src, tailroom);
-               rte_memcpy(base, (void *)((uintptr_t)src + tailroom),
-                          n - tailroom);
-               ret = (uint8_t *)base + n - tailroom;
-       } else {
-               rte_memcpy(dst, src, n);
-               ret = (n == tailroom) ? base : (uint8_t *)dst + n;
-       }
-       return ret;
-}
-
-/**
- * Inline TSO headers into WQE.
- *
- * @return
- *   0 on success, negative errno value on failure.
- */
-static int
-inline_tso(struct mlx5_txq_data *txq, struct rte_mbuf *buf,
-          uint32_t *length,
-          uintptr_t *addr,
-          uint16_t *pkt_inline_sz,
-          uint8_t **raw,
-          uint16_t *max_wqe,
-          uint16_t *tso_segsz,
-          uint16_t *tso_header_sz)
-{
-       uintptr_t end = (uintptr_t)(((uintptr_t)txq->wqes) +
-                                   (1 << txq->wqe_n) * MLX5_WQE_SIZE);
-       unsigned int copy_b;
-       uint8_t vlan_sz = (buf->ol_flags & PKT_TX_VLAN_PKT) ? 4 : 0;
-       const uint8_t tunneled = txq->tunnel_en && (buf->ol_flags &
-                                PKT_TX_TUNNEL_MASK);
-       uint16_t n_wqe;
-
-       *tso_segsz = buf->tso_segsz;
-       *tso_header_sz = buf->l2_len + vlan_sz + buf->l3_len + buf->l4_len;
-       if (unlikely(*tso_segsz == 0 || *tso_header_sz == 0)) {
-               txq->stats.oerrors++;
-               return -EINVAL;
-       }
-       if (tunneled)
-               *tso_header_sz += buf->outer_l2_len + buf->outer_l3_len;
-       /* First seg must contain all TSO headers. */
-       if (unlikely(*tso_header_sz > MLX5_MAX_TSO_HEADER) ||
-                    *tso_header_sz > DATA_LEN(buf)) {
-               txq->stats.oerrors++;
-               return -EINVAL;
-       }
-       copy_b = *tso_header_sz - *pkt_inline_sz;
-       if (!copy_b || ((end - (uintptr_t)*raw) < copy_b))
-               return -EAGAIN;
-       n_wqe = (MLX5_WQE_DS(copy_b) - 1 + 3) / 4;
-       if (unlikely(*max_wqe < n_wqe))
-               return -EINVAL;
-       *max_wqe -= n_wqe;
-       rte_memcpy((void *)*raw, (void *)*addr, copy_b);
-       *length -= copy_b;
-       *addr += copy_b;
-       copy_b = MLX5_WQE_DS(copy_b) * MLX5_WQE_DWORD_SIZE;
-       *pkt_inline_sz += copy_b;
-       *raw += copy_b;
-       return 0;
-}
-
-/**
- * DPDK callback to check the status of a tx descriptor.
- *
- * @param tx_queue
- *   The tx queue.
- * @param[in] offset
- *   The index of the descriptor in the ring.
- *
- * @return
- *   The status of the tx descriptor.
- */
-int
-mlx5_tx_descriptor_status(void *tx_queue, uint16_t offset)
-{
-       struct mlx5_txq_data *txq = tx_queue;
-       uint16_t used;
-
-       mlx5_tx_complete(txq);
-       used = txq->elts_head - txq->elts_tail;
-       if (offset < used)
-               return RTE_ETH_TX_DESC_FULL;
-       return RTE_ETH_TX_DESC_DONE;
-}
-
 /**
  * Internal function to compute the number of used descriptors in an RX queue
  *
@@ -655,7 +521,7 @@ mlx5_tx_error_cqe_handle(struct mlx5_txq_data *txq,
                                                    (1 << txq->cqe_n));
                        mlx5_dump_debug_information(name, "MLX5 Error SQ:",
                                                    (const void *)((uintptr_t)
-                                                   tx_mlx5_wqe(txq, 0)),
+                                                   txq->wqes),
                                                    MLX5_WQE_SIZE *
                                                    (1 << txq->wqe_n));
                        txq_ctrl->dump_file_n++;
@@ -682,1247 +548,6 @@ mlx5_tx_error_cqe_handle(struct mlx5_txq_data *txq,
        return txq->elts_tail;
 }
 
-/**
- * DPDK callback for TX.
- *
- * @param dpdk_txq
- *   Generic pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-uint16_t
-mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
-{
-       struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq;
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       unsigned int i = 0;
-       unsigned int j = 0;
-       unsigned int k = 0;
-       uint16_t max_elts;
-       uint16_t max_wqe;
-       unsigned int comp;
-       volatile struct mlx5_wqe_ctrl *last_wqe = NULL;
-       unsigned int segs_n = 0;
-       const unsigned int max_inline = txq->max_inline;
-       uint64_t addr_64;
-
-       if (unlikely(!pkts_n))
-               return 0;
-       /* Prefetch first packet cacheline. */
-       rte_prefetch0(*pkts);
-       /* Start processing. */
-       mlx5_tx_complete(txq);
-       max_elts = (elts_n - (elts_head - txq->elts_tail));
-       max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-       if (unlikely(!max_wqe))
-               return 0;
-       do {
-               struct rte_mbuf *buf = *pkts; /* First_seg. */
-               uint8_t *raw;
-               volatile struct mlx5_wqe_v *wqe = NULL;
-               volatile rte_v128u32_t *dseg = NULL;
-               uint32_t length;
-               unsigned int ds = 0;
-               unsigned int sg = 0; /* counter of additional segs attached. */
-               uintptr_t addr;
-               uint16_t pkt_inline_sz = MLX5_WQE_DWORD_SIZE + 2;
-               uint16_t tso_header_sz = 0;
-               uint16_t ehdr;
-               uint8_t cs_flags;
-               uint8_t tso = txq->tso_en && (buf->ol_flags & PKT_TX_TCP_SEG);
-               uint32_t swp_offsets = 0;
-               uint8_t swp_types = 0;
-               rte_be32_t metadata;
-               uint16_t tso_segsz = 0;
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               uint32_t total_length = 0;
-#endif
-               int ret;
-
-               segs_n = buf->nb_segs;
-               /*
-                * Make sure there is enough room to store this packet and
-                * that one ring entry remains unused.
-                */
-               assert(segs_n);
-               if (max_elts < segs_n)
-                       break;
-               max_elts -= segs_n;
-               sg = --segs_n;
-               if (unlikely(--max_wqe == 0))
-                       break;
-               wqe = (volatile struct mlx5_wqe_v *)
-                       tx_mlx5_wqe(txq, txq->wqe_ci);
-               rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci + 1));
-               if (pkts_n - i > 1)
-                       rte_prefetch0(*(pkts + 1));
-               addr = rte_pktmbuf_mtod(buf, uintptr_t);
-               length = DATA_LEN(buf);
-               ehdr = (((uint8_t *)addr)[1] << 8) |
-                      ((uint8_t *)addr)[0];
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               total_length = length;
-#endif
-               if (length < (MLX5_WQE_DWORD_SIZE + 2)) {
-                       txq->stats.oerrors++;
-                       break;
-               }
-               /* Update element. */
-               (*txq->elts)[elts_head & elts_m] = buf;
-               /* Prefetch next buffer data. */
-               if (pkts_n - i > 1)
-                       rte_prefetch0(
-                           rte_pktmbuf_mtod(*(pkts + 1), volatile void *));
-               cs_flags = txq_ol_cksum_to_cs(buf);
-               txq_mbuf_to_swp(txq, buf, (uint8_t *)&swp_offsets, &swp_types);
-               raw = ((uint8_t *)(uintptr_t)wqe) + 2 * MLX5_WQE_DWORD_SIZE;
-               /* Copy metadata from mbuf if valid */
-               metadata = buf->ol_flags & PKT_TX_METADATA ? buf->tx_metadata :
-                                                            0;
-               /* Replace the Ethernet type by the VLAN if necessary. */
-               if (buf->ol_flags & PKT_TX_VLAN_PKT) {
-                       uint32_t vlan = rte_cpu_to_be_32(0x81000000 |
-                                                        buf->vlan_tci);
-                       unsigned int len = 2 * RTE_ETHER_ADDR_LEN - 2;
-
-                       addr += 2;
-                       length -= 2;
-                       /* Copy Destination and source mac address. */
-                       memcpy((uint8_t *)raw, ((uint8_t *)addr), len);
-                       /* Copy VLAN. */
-                       memcpy((uint8_t *)raw + len, &vlan, sizeof(vlan));
-                       /* Copy missing two bytes to end the DSeg. */
-                       memcpy((uint8_t *)raw + len + sizeof(vlan),
-                              ((uint8_t *)addr) + len, 2);
-                       addr += len + 2;
-                       length -= (len + 2);
-               } else {
-                       memcpy((uint8_t *)raw, ((uint8_t *)addr) + 2,
-                              MLX5_WQE_DWORD_SIZE);
-                       length -= pkt_inline_sz;
-                       addr += pkt_inline_sz;
-               }
-               raw += MLX5_WQE_DWORD_SIZE;
-               if (tso) {
-                       ret = inline_tso(txq, buf, &length,
-                                        &addr, &pkt_inline_sz,
-                                        &raw, &max_wqe,
-                                        &tso_segsz, &tso_header_sz);
-                       if (ret == -EINVAL) {
-                               break;
-                       } else if (ret == -EAGAIN) {
-                               /* NOP WQE. */
-                               wqe->ctrl = (rte_v128u32_t){
-                                       rte_cpu_to_be_32(txq->wqe_ci << 8),
-                                       rte_cpu_to_be_32(txq->qp_num_8s | 1),
-                                       rte_cpu_to_be_32
-                                               (MLX5_COMP_ONLY_FIRST_ERR <<
-                                                MLX5_COMP_MODE_OFFSET),
-                                       0,
-                               };
-                               ds = 1;
-#ifdef MLX5_PMD_SOFT_COUNTERS
-                               total_length = 0;
-#endif
-                               k++;
-                               goto next_wqe;
-                       }
-               }
-               /* Inline if enough room. */
-               if (max_inline || tso) {
-                       uint32_t inl = 0;
-                       uintptr_t end = (uintptr_t)
-                               (((uintptr_t)txq->wqes) +
-                                (1 << txq->wqe_n) * MLX5_WQE_SIZE);
-                       unsigned int inline_room = max_inline *
-                                                  RTE_CACHE_LINE_SIZE -
-                                                  (pkt_inline_sz - 2) -
-                                                  !!tso * sizeof(inl);
-                       uintptr_t addr_end;
-                       unsigned int copy_b;
-
-pkt_inline:
-                       addr_end = RTE_ALIGN_FLOOR(addr + inline_room,
-                                                  RTE_CACHE_LINE_SIZE);
-                       copy_b = (addr_end > addr) ?
-                                RTE_MIN((addr_end - addr), length) : 0;
-                       if (copy_b && ((end - (uintptr_t)raw) >
-                                      (copy_b + sizeof(inl)))) {
-                               /*
-                                * One Dseg remains in the current WQE.  To
-                                * keep the computation positive, it is
-                                * removed after the bytes to Dseg conversion.
-                                */
-                               uint16_t n = (MLX5_WQE_DS(copy_b) - 1 + 3) / 4;
-
-                               if (unlikely(max_wqe < n))
-                                       break;
-                               max_wqe -= n;
-                               if (tso) {
-                                       assert(inl == 0);
-                                       inl = rte_cpu_to_be_32(copy_b |
-                                                              MLX5_INLINE_SEG);
-                                       rte_memcpy((void *)raw,
-                                                  (void *)&inl, sizeof(inl));
-                                       raw += sizeof(inl);
-                                       pkt_inline_sz += sizeof(inl);
-                               }
-                               rte_memcpy((void *)raw, (void *)addr, copy_b);
-                               addr += copy_b;
-                               length -= copy_b;
-                               pkt_inline_sz += copy_b;
-                       }
-                       /*
-                        * 2 DWORDs consumed by the WQE header + ETH segment +
-                        * the size of the inline part of the packet.
-                        */
-                       ds = 2 + MLX5_WQE_DS(pkt_inline_sz - 2);
-                       if (length > 0) {
-                               if (ds % (MLX5_WQE_SIZE /
-                                         MLX5_WQE_DWORD_SIZE) == 0) {
-                                       if (unlikely(--max_wqe == 0))
-                                               break;
-                                       dseg = (volatile rte_v128u32_t *)
-                                              tx_mlx5_wqe(txq, txq->wqe_ci +
-                                                          ds / 4);
-                               } else {
-                                       dseg = (volatile rte_v128u32_t *)
-                                               ((uintptr_t)wqe +
-                                                (ds * MLX5_WQE_DWORD_SIZE));
-                               }
-                               goto use_dseg;
-                       } else if (!segs_n) {
-                               goto next_pkt;
-                       } else {
-                               /*
-                                * Further inline the next segment only for
-                                * non-TSO packets.
-                                */
-                               if (!tso) {
-                                       raw += copy_b;
-                                       inline_room -= copy_b;
-                               } else {
-                                       inline_room = 0;
-                               }
-                               /* Move to the next segment. */
-                               --segs_n;
-                               buf = buf->next;
-                               assert(buf);
-                               addr = rte_pktmbuf_mtod(buf, uintptr_t);
-                               length = DATA_LEN(buf);
-#ifdef MLX5_PMD_SOFT_COUNTERS
-                               total_length += length;
-#endif
-                               (*txq->elts)[++elts_head & elts_m] = buf;
-                               goto pkt_inline;
-                       }
-               } else {
-                       /*
-                        * No inline has been done in the packet, only the
-                        * Ethernet Header as been stored.
-                        */
-                       dseg = (volatile rte_v128u32_t *)
-                               ((uintptr_t)wqe + (3 * MLX5_WQE_DWORD_SIZE));
-                       ds = 3;
-use_dseg:
-                       /* Add the remaining packet as a simple ds. */
-                       addr_64 = rte_cpu_to_be_64(addr);
-                       *dseg = (rte_v128u32_t){
-                               rte_cpu_to_be_32(length),
-                               mlx5_tx_mb2mr(txq, buf),
-                               addr_64,
-                               addr_64 >> 32,
-                       };
-                       ++ds;
-                       if (!segs_n)
-                               goto next_pkt;
-               }
-next_seg:
-               assert(buf);
-               assert(ds);
-               assert(wqe);
-               /*
-                * Spill on next WQE when the current one does not have
-                * enough room left. Size of WQE must a be a multiple
-                * of data segment size.
-                */
-               assert(!(MLX5_WQE_SIZE % MLX5_WQE_DWORD_SIZE));
-               if (!(ds % (MLX5_WQE_SIZE / MLX5_WQE_DWORD_SIZE))) {
-                       if (unlikely(--max_wqe == 0))
-                               break;
-                       dseg = (volatile rte_v128u32_t *)
-                              tx_mlx5_wqe(txq, txq->wqe_ci + ds / 4);
-                       rte_prefetch0(tx_mlx5_wqe(txq,
-                                                 txq->wqe_ci + ds / 4 + 1));
-               } else {
-                       ++dseg;
-               }
-               ++ds;
-               buf = buf->next;
-               assert(buf);
-               length = DATA_LEN(buf);
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               total_length += length;
-#endif
-               /* Store segment information. */
-               addr_64 = rte_cpu_to_be_64(rte_pktmbuf_mtod(buf, uintptr_t));
-               *dseg = (rte_v128u32_t){
-                       rte_cpu_to_be_32(length),
-                       mlx5_tx_mb2mr(txq, buf),
-                       addr_64,
-                       addr_64 >> 32,
-               };
-               (*txq->elts)[++elts_head & elts_m] = buf;
-               if (--segs_n)
-                       goto next_seg;
-next_pkt:
-               if (ds > MLX5_DSEG_MAX) {
-                       txq->stats.oerrors++;
-                       break;
-               }
-               ++elts_head;
-               ++pkts;
-               ++i;
-               j += sg;
-               /* Initialize known and common part of the WQE structure. */
-               if (tso) {
-                       wqe->ctrl = (rte_v128u32_t){
-                               rte_cpu_to_be_32((txq->wqe_ci << 8) |
-                                                MLX5_OPCODE_TSO),
-                               rte_cpu_to_be_32(txq->qp_num_8s | ds),
-                               rte_cpu_to_be_32(MLX5_COMP_ONLY_FIRST_ERR <<
-                                                MLX5_COMP_MODE_OFFSET),
-                               0,
-                       };
-                       wqe->eseg = (rte_v128u32_t){
-                               swp_offsets,
-                               cs_flags | (swp_types << 8) |
-                               (rte_cpu_to_be_16(tso_segsz) << 16),
-                               metadata,
-                               (ehdr << 16) | rte_cpu_to_be_16(tso_header_sz),
-                       };
-               } else {
-                       wqe->ctrl = (rte_v128u32_t){
-                               rte_cpu_to_be_32((txq->wqe_ci << 8) |
-                                                MLX5_OPCODE_SEND),
-                               rte_cpu_to_be_32(txq->qp_num_8s | ds),
-                               rte_cpu_to_be_32(MLX5_COMP_ONLY_FIRST_ERR <<
-                                                MLX5_COMP_MODE_OFFSET),
-                               0,
-                       };
-                       wqe->eseg = (rte_v128u32_t){
-                               swp_offsets,
-                               cs_flags | (swp_types << 8),
-                               metadata,
-                               (ehdr << 16) | rte_cpu_to_be_16(pkt_inline_sz),
-                       };
-               }
-next_wqe:
-               txq->wqe_ci += (ds + 3) / 4;
-               /* Save the last successful WQE for completion request */
-               last_wqe = (volatile struct mlx5_wqe_ctrl *)wqe;
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               /* Increment sent bytes counter. */
-               txq->stats.obytes += total_length;
-#endif
-       } while (i < pkts_n);
-       /* Take a shortcut if nothing must be sent. */
-       if (unlikely((i + k) == 0))
-               return 0;
-       txq->elts_head += (i + j);
-       /* Check whether completion threshold has been reached. */
-       comp = txq->elts_comp + i + j + k;
-       if (comp >= MLX5_TX_COMP_THRESH) {
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               /* Request completion on last WQE. */
-               last_wqe->ctrl2 = rte_cpu_to_be_32(MLX5_COMP_ALWAYS <<
-                                                  MLX5_COMP_MODE_OFFSET);
-               /* Save elts_head in unused "immediate" field of WQE. */
-               last_wqe->ctrl3 = txq->elts_head;
-               txq->elts_comp = 0;
-       } else {
-               txq->elts_comp = comp;
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       /* Increment sent packets counter. */
-       txq->stats.opackets += i;
-#endif
-       /* Ring QP doorbell. */
-       mlx5_tx_dbrec(txq, (volatile struct mlx5_wqe *)last_wqe);
-       return i;
-}
-
-/**
- * Open a MPW session.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param mpw
- *   Pointer to MPW session structure.
- * @param length
- *   Packet length.
- */
-static inline void
-mlx5_mpw_new(struct mlx5_txq_data *txq, struct mlx5_mpw *mpw, uint32_t length)
-{
-       uint16_t idx = txq->wqe_ci & ((1 << txq->wqe_n) - 1);
-       volatile struct mlx5_wqe_data_seg (*dseg)[MLX5_MPW_DSEG_MAX] =
-               (volatile struct mlx5_wqe_data_seg (*)[])
-               tx_mlx5_wqe(txq, idx + 1);
-
-       mpw->state = MLX5_MPW_STATE_OPENED;
-       mpw->pkts_n = 0;
-       mpw->len = length;
-       mpw->total_len = 0;
-       mpw->wqe = (volatile struct mlx5_wqe *)tx_mlx5_wqe(txq, idx);
-       mpw->wqe->eseg.mss = rte_cpu_to_be_16(length);
-       mpw->wqe->eseg.inline_hdr_sz = 0;
-       mpw->wqe->eseg.rsvd0 = 0;
-       mpw->wqe->eseg.rsvd1 = 0;
-       mpw->wqe->eseg.flow_table_metadata = 0;
-       mpw->wqe->ctrl[0] = rte_cpu_to_be_32((MLX5_OPC_MOD_MPW << 24) |
-                                            (txq->wqe_ci << 8) |
-                                            MLX5_OPCODE_TSO);
-       mpw->wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ONLY_FIRST_ERR <<
-                                            MLX5_COMP_MODE_OFFSET);
-       mpw->wqe->ctrl[3] = 0;
-       mpw->data.dseg[0] = (volatile struct mlx5_wqe_data_seg *)
-               (((uintptr_t)mpw->wqe) + (2 * MLX5_WQE_DWORD_SIZE));
-       mpw->data.dseg[1] = (volatile struct mlx5_wqe_data_seg *)
-               (((uintptr_t)mpw->wqe) + (3 * MLX5_WQE_DWORD_SIZE));
-       mpw->data.dseg[2] = &(*dseg)[0];
-       mpw->data.dseg[3] = &(*dseg)[1];
-       mpw->data.dseg[4] = &(*dseg)[2];
-}
-
-/**
- * Close a MPW session.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param mpw
- *   Pointer to MPW session structure.
- */
-static inline void
-mlx5_mpw_close(struct mlx5_txq_data *txq, struct mlx5_mpw *mpw)
-{
-       unsigned int num = mpw->pkts_n;
-
-       /*
-        * Store size in multiple of 16 bytes. Control and Ethernet segments
-        * count as 2.
-        */
-       mpw->wqe->ctrl[1] = rte_cpu_to_be_32(txq->qp_num_8s | (2 + num));
-       mpw->state = MLX5_MPW_STATE_CLOSED;
-       if (num < 3)
-               ++txq->wqe_ci;
-       else
-               txq->wqe_ci += 2;
-       rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci));
-       rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci + 1));
-}
-
-/**
- * DPDK callback for TX with MPW support.
- *
- * @param dpdk_txq
- *   Generic pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-uint16_t
-mlx5_tx_burst_mpw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
-{
-       struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq;
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       unsigned int i = 0;
-       unsigned int j = 0;
-       uint16_t max_elts;
-       uint16_t max_wqe;
-       unsigned int comp;
-       struct mlx5_mpw mpw = {
-               .state = MLX5_MPW_STATE_CLOSED,
-       };
-
-       if (unlikely(!pkts_n))
-               return 0;
-       /* Prefetch first packet cacheline. */
-       rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci));
-       rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci + 1));
-       /* Start processing. */
-       mlx5_tx_complete(txq);
-       max_elts = (elts_n - (elts_head - txq->elts_tail));
-       max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-       if (unlikely(!max_wqe))
-               return 0;
-       do {
-               struct rte_mbuf *buf = *(pkts++);
-               uint32_t length;
-               unsigned int segs_n = buf->nb_segs;
-               uint32_t cs_flags;
-               rte_be32_t metadata;
-
-               /*
-                * Make sure there is enough room to store this packet and
-                * that one ring entry remains unused.
-                */
-               assert(segs_n);
-               if (max_elts < segs_n)
-                       break;
-               /* Do not bother with large packets MPW cannot handle. */
-               if (segs_n > MLX5_MPW_DSEG_MAX) {
-                       txq->stats.oerrors++;
-                       break;
-               }
-               max_elts -= segs_n;
-               --pkts_n;
-               cs_flags = txq_ol_cksum_to_cs(buf);
-               /* Copy metadata from mbuf if valid */
-               metadata = buf->ol_flags & PKT_TX_METADATA ? buf->tx_metadata :
-                                                            0;
-               /* Retrieve packet information. */
-               length = PKT_LEN(buf);
-               assert(length);
-               /* Start new session if packet differs. */
-               if ((mpw.state == MLX5_MPW_STATE_OPENED) &&
-                   ((mpw.len != length) ||
-                    (segs_n != 1) ||
-                    (mpw.wqe->eseg.flow_table_metadata != metadata) ||
-                    (mpw.wqe->eseg.cs_flags != cs_flags)))
-                       mlx5_mpw_close(txq, &mpw);
-               if (mpw.state == MLX5_MPW_STATE_CLOSED) {
-                       /*
-                        * Multi-Packet WQE consumes at most two WQE.
-                        * mlx5_mpw_new() expects to be able to use such
-                        * resources.
-                        */
-                       if (unlikely(max_wqe < 2))
-                               break;
-                       max_wqe -= 2;
-                       mlx5_mpw_new(txq, &mpw, length);
-                       mpw.wqe->eseg.cs_flags = cs_flags;
-                       mpw.wqe->eseg.flow_table_metadata = metadata;
-               }
-               /* Multi-segment packets must be alone in their MPW. */
-               assert((segs_n == 1) || (mpw.pkts_n == 0));
-#if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
-               length = 0;
-#endif
-               do {
-                       volatile struct mlx5_wqe_data_seg *dseg;
-                       uintptr_t addr;
-
-                       assert(buf);
-                       (*txq->elts)[elts_head++ & elts_m] = buf;
-                       dseg = mpw.data.dseg[mpw.pkts_n];
-                       addr = rte_pktmbuf_mtod(buf, uintptr_t);
-                       *dseg = (struct mlx5_wqe_data_seg){
-                               .byte_count = rte_cpu_to_be_32(DATA_LEN(buf)),
-                               .lkey = mlx5_tx_mb2mr(txq, buf),
-                               .addr = rte_cpu_to_be_64(addr),
-                       };
-#if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
-                       length += DATA_LEN(buf);
-#endif
-                       buf = buf->next;
-                       ++mpw.pkts_n;
-                       ++j;
-               } while (--segs_n);
-               assert(length == mpw.len);
-               if (mpw.pkts_n == MLX5_MPW_DSEG_MAX)
-                       mlx5_mpw_close(txq, &mpw);
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               /* Increment sent bytes counter. */
-               txq->stats.obytes += length;
-#endif
-               ++i;
-       } while (pkts_n);
-       /* Take a shortcut if nothing must be sent. */
-       if (unlikely(i == 0))
-               return 0;
-       /* Check whether completion threshold has been reached. */
-       /* "j" includes both packets and segments. */
-       comp = txq->elts_comp + j;
-       if (comp >= MLX5_TX_COMP_THRESH) {
-               volatile struct mlx5_wqe *wqe = mpw.wqe;
-
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               /* Request completion on last WQE. */
-               wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ALWAYS <<
-                                               MLX5_COMP_MODE_OFFSET);
-               /* Save elts_head in unused "immediate" field of WQE. */
-               wqe->ctrl[3] = elts_head;
-               txq->elts_comp = 0;
-       } else {
-               txq->elts_comp = comp;
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       /* Increment sent packets counter. */
-       txq->stats.opackets += i;
-#endif
-       /* Ring QP doorbell. */
-       if (mpw.state == MLX5_MPW_STATE_OPENED)
-               mlx5_mpw_close(txq, &mpw);
-       mlx5_tx_dbrec(txq, mpw.wqe);
-       txq->elts_head = elts_head;
-       return i;
-}
-
-/**
- * Open a MPW inline session.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param mpw
- *   Pointer to MPW session structure.
- * @param length
- *   Packet length.
- */
-static inline void
-mlx5_mpw_inline_new(struct mlx5_txq_data *txq, struct mlx5_mpw *mpw,
-                   uint32_t length)
-{
-       uint16_t idx = txq->wqe_ci & ((1 << txq->wqe_n) - 1);
-       struct mlx5_wqe_inl_small *inl;
-
-       mpw->state = MLX5_MPW_INL_STATE_OPENED;
-       mpw->pkts_n = 0;
-       mpw->len = length;
-       mpw->total_len = 0;
-       mpw->wqe = (volatile struct mlx5_wqe *)tx_mlx5_wqe(txq, idx);
-       mpw->wqe->ctrl[0] = rte_cpu_to_be_32((MLX5_OPC_MOD_MPW << 24) |
-                                            (txq->wqe_ci << 8) |
-                                            MLX5_OPCODE_TSO);
-       mpw->wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ONLY_FIRST_ERR <<
-                                            MLX5_COMP_MODE_OFFSET);
-       mpw->wqe->ctrl[3] = 0;
-       mpw->wqe->eseg.mss = rte_cpu_to_be_16(length);
-       mpw->wqe->eseg.inline_hdr_sz = 0;
-       mpw->wqe->eseg.cs_flags = 0;
-       mpw->wqe->eseg.rsvd0 = 0;
-       mpw->wqe->eseg.rsvd1 = 0;
-       mpw->wqe->eseg.flow_table_metadata = 0;
-       inl = (struct mlx5_wqe_inl_small *)
-               (((uintptr_t)mpw->wqe) + 2 * MLX5_WQE_DWORD_SIZE);
-       mpw->data.raw = (uint8_t *)&inl->raw;
-}
-
-/**
- * Close a MPW inline session.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param mpw
- *   Pointer to MPW session structure.
- */
-static inline void
-mlx5_mpw_inline_close(struct mlx5_txq_data *txq, struct mlx5_mpw *mpw)
-{
-       unsigned int size;
-       struct mlx5_wqe_inl_small *inl = (struct mlx5_wqe_inl_small *)
-               (((uintptr_t)mpw->wqe) + (2 * MLX5_WQE_DWORD_SIZE));
-
-       size = MLX5_WQE_SIZE - MLX5_MWQE64_INL_DATA + mpw->total_len;
-       /*
-        * Store size in multiple of 16 bytes. Control and Ethernet segments
-        * count as 2.
-        */
-       mpw->wqe->ctrl[1] = rte_cpu_to_be_32(txq->qp_num_8s |
-                                            MLX5_WQE_DS(size));
-       mpw->state = MLX5_MPW_STATE_CLOSED;
-       inl->byte_cnt = rte_cpu_to_be_32(mpw->total_len | MLX5_INLINE_SEG);
-       txq->wqe_ci += (size + (MLX5_WQE_SIZE - 1)) / MLX5_WQE_SIZE;
-}
-
-/**
- * DPDK callback for TX with MPW inline support.
- *
- * @param dpdk_txq
- *   Generic pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-uint16_t
-mlx5_tx_burst_mpw_inline(void *dpdk_txq, struct rte_mbuf **pkts,
-                        uint16_t pkts_n)
-{
-       struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq;
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       unsigned int i = 0;
-       unsigned int j = 0;
-       uint16_t max_elts;
-       uint16_t max_wqe;
-       unsigned int comp;
-       unsigned int inline_room = txq->max_inline * RTE_CACHE_LINE_SIZE;
-       struct mlx5_mpw mpw = {
-               .state = MLX5_MPW_STATE_CLOSED,
-       };
-       /*
-        * Compute the maximum number of WQE which can be consumed by inline
-        * code.
-        * - 2 DSEG for:
-        *   - 1 control segment,
-        *   - 1 Ethernet segment,
-        * - N Dseg from the inline request.
-        */
-       const unsigned int wqe_inl_n =
-               ((2 * MLX5_WQE_DWORD_SIZE +
-                 txq->max_inline * RTE_CACHE_LINE_SIZE) +
-                RTE_CACHE_LINE_SIZE - 1) / RTE_CACHE_LINE_SIZE;
-
-       if (unlikely(!pkts_n))
-               return 0;
-       /* Prefetch first packet cacheline. */
-       rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci));
-       rte_prefetch0(tx_mlx5_wqe(txq, txq->wqe_ci + 1));
-       /* Start processing. */
-       mlx5_tx_complete(txq);
-       max_elts = (elts_n - (elts_head - txq->elts_tail));
-       do {
-               struct rte_mbuf *buf = *(pkts++);
-               uintptr_t addr;
-               uint32_t length;
-               unsigned int segs_n = buf->nb_segs;
-               uint8_t cs_flags;
-               rte_be32_t metadata;
-
-               /*
-                * Make sure there is enough room to store this packet and
-                * that one ring entry remains unused.
-                */
-               assert(segs_n);
-               if (max_elts < segs_n)
-                       break;
-               /* Do not bother with large packets MPW cannot handle. */
-               if (segs_n > MLX5_MPW_DSEG_MAX) {
-                       txq->stats.oerrors++;
-                       break;
-               }
-               max_elts -= segs_n;
-               --pkts_n;
-               /*
-                * Compute max_wqe in case less WQE were consumed in previous
-                * iteration.
-                */
-               max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-               cs_flags = txq_ol_cksum_to_cs(buf);
-               /* Copy metadata from mbuf if valid */
-               metadata = buf->ol_flags & PKT_TX_METADATA ? buf->tx_metadata :
-                                                            0;
-               /* Retrieve packet information. */
-               length = PKT_LEN(buf);
-               /* Start new session if packet differs. */
-               if (mpw.state == MLX5_MPW_STATE_OPENED) {
-                       if ((mpw.len != length) ||
-                           (segs_n != 1) ||
-                           (mpw.wqe->eseg.flow_table_metadata != metadata) ||
-                           (mpw.wqe->eseg.cs_flags != cs_flags))
-                               mlx5_mpw_close(txq, &mpw);
-               } else if (mpw.state == MLX5_MPW_INL_STATE_OPENED) {
-                       if ((mpw.len != length) ||
-                           (segs_n != 1) ||
-                           (length > inline_room) ||
-                           (mpw.wqe->eseg.flow_table_metadata != metadata) ||
-                           (mpw.wqe->eseg.cs_flags != cs_flags)) {
-                               mlx5_mpw_inline_close(txq, &mpw);
-                               inline_room =
-                                       txq->max_inline * RTE_CACHE_LINE_SIZE;
-                       }
-               }
-               if (mpw.state == MLX5_MPW_STATE_CLOSED) {
-                       if ((segs_n != 1) ||
-                           (length > inline_room)) {
-                               /*
-                                * Multi-Packet WQE consumes at most two WQE.
-                                * mlx5_mpw_new() expects to be able to use
-                                * such resources.
-                                */
-                               if (unlikely(max_wqe < 2))
-                                       break;
-                               max_wqe -= 2;
-                               mlx5_mpw_new(txq, &mpw, length);
-                               mpw.wqe->eseg.cs_flags = cs_flags;
-                               mpw.wqe->eseg.flow_table_metadata = metadata;
-                       } else {
-                               if (unlikely(max_wqe < wqe_inl_n))
-                                       break;
-                               max_wqe -= wqe_inl_n;
-                               mlx5_mpw_inline_new(txq, &mpw, length);
-                               mpw.wqe->eseg.cs_flags = cs_flags;
-                               mpw.wqe->eseg.flow_table_metadata = metadata;
-                       }
-               }
-               /* Multi-segment packets must be alone in their MPW. */
-               assert((segs_n == 1) || (mpw.pkts_n == 0));
-               if (mpw.state == MLX5_MPW_STATE_OPENED) {
-                       assert(inline_room ==
-                              txq->max_inline * RTE_CACHE_LINE_SIZE);
-#if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
-                       length = 0;
-#endif
-                       do {
-                               volatile struct mlx5_wqe_data_seg *dseg;
-
-                               assert(buf);
-                               (*txq->elts)[elts_head++ & elts_m] = buf;
-                               dseg = mpw.data.dseg[mpw.pkts_n];
-                               addr = rte_pktmbuf_mtod(buf, uintptr_t);
-                               *dseg = (struct mlx5_wqe_data_seg){
-                                       .byte_count =
-                                              rte_cpu_to_be_32(DATA_LEN(buf)),
-                                       .lkey = mlx5_tx_mb2mr(txq, buf),
-                                       .addr = rte_cpu_to_be_64(addr),
-                               };
-#if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
-                               length += DATA_LEN(buf);
-#endif
-                               buf = buf->next;
-                               ++mpw.pkts_n;
-                               ++j;
-                       } while (--segs_n);
-                       assert(length == mpw.len);
-                       if (mpw.pkts_n == MLX5_MPW_DSEG_MAX)
-                               mlx5_mpw_close(txq, &mpw);
-               } else {
-                       unsigned int max;
-
-                       assert(mpw.state == MLX5_MPW_INL_STATE_OPENED);
-                       assert(length <= inline_room);
-                       assert(length == DATA_LEN(buf));
-                       addr = rte_pktmbuf_mtod(buf, uintptr_t);
-                       (*txq->elts)[elts_head++ & elts_m] = buf;
-                       /* Maximum number of bytes before wrapping. */
-                       max = ((((uintptr_t)(txq->wqes)) +
-                               (1 << txq->wqe_n) *
-                               MLX5_WQE_SIZE) -
-                              (uintptr_t)mpw.data.raw);
-                       if (length > max) {
-                               rte_memcpy((void *)(uintptr_t)mpw.data.raw,
-                                          (void *)addr,
-                                          max);
-                               mpw.data.raw = (volatile void *)txq->wqes;
-                               rte_memcpy((void *)(uintptr_t)mpw.data.raw,
-                                          (void *)(addr + max),
-                                          length - max);
-                               mpw.data.raw += length - max;
-                       } else {
-                               rte_memcpy((void *)(uintptr_t)mpw.data.raw,
-                                          (void *)addr,
-                                          length);
-
-                               if (length == max)
-                                       mpw.data.raw =
-                                               (volatile void *)txq->wqes;
-                               else
-                                       mpw.data.raw += length;
-                       }
-                       ++mpw.pkts_n;
-                       mpw.total_len += length;
-                       ++j;
-                       if (mpw.pkts_n == MLX5_MPW_DSEG_MAX) {
-                               mlx5_mpw_inline_close(txq, &mpw);
-                               inline_room =
-                                       txq->max_inline * RTE_CACHE_LINE_SIZE;
-                       } else {
-                               inline_room -= length;
-                       }
-               }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               /* Increment sent bytes counter. */
-               txq->stats.obytes += length;
-#endif
-               ++i;
-       } while (pkts_n);
-       /* Take a shortcut if nothing must be sent. */
-       if (unlikely(i == 0))
-               return 0;
-       /* Check whether completion threshold has been reached. */
-       /* "j" includes both packets and segments. */
-       comp = txq->elts_comp + j;
-       if (comp >= MLX5_TX_COMP_THRESH) {
-               volatile struct mlx5_wqe *wqe = mpw.wqe;
-
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               /* Request completion on last WQE. */
-               wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ALWAYS <<
-                                               MLX5_COMP_MODE_OFFSET);
-               /* Save elts_head in unused "immediate" field of WQE. */
-               wqe->ctrl[3] = elts_head;
-               txq->elts_comp = 0;
-       } else {
-               txq->elts_comp = comp;
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       /* Increment sent packets counter. */
-       txq->stats.opackets += i;
-#endif
-       /* Ring QP doorbell. */
-       if (mpw.state == MLX5_MPW_INL_STATE_OPENED)
-               mlx5_mpw_inline_close(txq, &mpw);
-       else if (mpw.state == MLX5_MPW_STATE_OPENED)
-               mlx5_mpw_close(txq, &mpw);
-       mlx5_tx_dbrec(txq, mpw.wqe);
-       txq->elts_head = elts_head;
-       return i;
-}
-
-/**
- * Open an Enhanced MPW session.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param mpw
- *   Pointer to MPW session structure.
- * @param length
- *   Packet length.
- */
-static inline void
-mlx5_empw_new(struct mlx5_txq_data *txq, struct mlx5_mpw *mpw, int padding)
-{
-       uint16_t idx = txq->wqe_ci & ((1 << txq->wqe_n) - 1);
-
-       mpw->state = MLX5_MPW_ENHANCED_STATE_OPENED;
-       mpw->pkts_n = 0;
-       mpw->total_len = sizeof(struct mlx5_wqe);
-       mpw->wqe = (volatile struct mlx5_wqe *)tx_mlx5_wqe(txq, idx);
-       mpw->wqe->ctrl[0] =
-               rte_cpu_to_be_32((MLX5_OPC_MOD_ENHANCED_MPSW << 24) |
-                                (txq->wqe_ci << 8) |
-                                MLX5_OPCODE_ENHANCED_MPSW);
-       mpw->wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ONLY_FIRST_ERR <<
-                                            MLX5_COMP_MODE_OFFSET);
-       mpw->wqe->ctrl[3] = 0;
-       memset((void *)(uintptr_t)&mpw->wqe->eseg, 0, MLX5_WQE_DWORD_SIZE);
-       if (unlikely(padding)) {
-               uintptr_t addr = (uintptr_t)(mpw->wqe + 1);
-
-               /* Pad the first 2 DWORDs with zero-length inline header. */
-               *(volatile uint32_t *)addr = rte_cpu_to_be_32(MLX5_INLINE_SEG);
-               *(volatile uint32_t *)(addr + MLX5_WQE_DWORD_SIZE) =
-                       rte_cpu_to_be_32(MLX5_INLINE_SEG);
-               mpw->total_len += 2 * MLX5_WQE_DWORD_SIZE;
-               /* Start from the next WQEBB. */
-               mpw->data.raw = (volatile void *)(tx_mlx5_wqe(txq, idx + 1));
-       } else {
-               mpw->data.raw = (volatile void *)(mpw->wqe + 1);
-       }
-}
-
-/**
- * Close an Enhanced MPW session.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param mpw
- *   Pointer to MPW session structure.
- *
- * @return
- *   Number of consumed WQEs.
- */
-static inline uint16_t
-mlx5_empw_close(struct mlx5_txq_data *txq, struct mlx5_mpw *mpw)
-{
-       uint16_t ret;
-
-       /* Store size in multiple of 16 bytes. Control and Ethernet segments
-        * count as 2.
-        */
-       mpw->wqe->ctrl[1] = rte_cpu_to_be_32(txq->qp_num_8s |
-                                            MLX5_WQE_DS(mpw->total_len));
-       mpw->state = MLX5_MPW_STATE_CLOSED;
-       ret = (mpw->total_len + (MLX5_WQE_SIZE - 1)) / MLX5_WQE_SIZE;
-       txq->wqe_ci += ret;
-       return ret;
-}
-
-/**
- * TX with Enhanced MPW support.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-static inline uint16_t
-txq_burst_empw(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
-              uint16_t pkts_n)
-{
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       unsigned int i = 0;
-       unsigned int j = 0;
-       uint16_t max_elts;
-       uint16_t max_wqe;
-       unsigned int max_inline = txq->max_inline * RTE_CACHE_LINE_SIZE;
-       unsigned int mpw_room = 0;
-       unsigned int inl_pad = 0;
-       uint32_t inl_hdr;
-       uint64_t addr_64;
-       struct mlx5_mpw mpw = {
-               .state = MLX5_MPW_STATE_CLOSED,
-       };
-
-       if (unlikely(!pkts_n))
-               return 0;
-       /* Start processing. */
-       mlx5_tx_complete(txq);
-       max_elts = (elts_n - (elts_head - txq->elts_tail));
-       max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-       if (unlikely(!max_wqe))
-               return 0;
-       do {
-               struct rte_mbuf *buf = *(pkts++);
-               uintptr_t addr;
-               unsigned int do_inline = 0; /* Whether inline is possible. */
-               uint32_t length;
-               uint8_t cs_flags;
-               rte_be32_t metadata;
-
-               /* Multi-segmented packet is handled in slow-path outside. */
-               assert(NB_SEGS(buf) == 1);
-               /* Make sure there is enough room to store this packet. */
-               if (max_elts - j == 0)
-                       break;
-               cs_flags = txq_ol_cksum_to_cs(buf);
-               /* Copy metadata from mbuf if valid */
-               metadata = buf->ol_flags & PKT_TX_METADATA ? buf->tx_metadata :
-                                                            0;
-               /* Retrieve packet information. */
-               length = PKT_LEN(buf);
-               /* Start new session if:
-                * - multi-segment packet
-                * - no space left even for a dseg
-                * - next packet can be inlined with a new WQE
-                * - cs_flag differs
-                */
-               if (mpw.state == MLX5_MPW_ENHANCED_STATE_OPENED) {
-                       if ((inl_pad + sizeof(struct mlx5_wqe_data_seg) >
-                            mpw_room) ||
-                           (length <= txq->inline_max_packet_sz &&
-                            inl_pad + sizeof(inl_hdr) + length >
-                            mpw_room) ||
-                            (mpw.wqe->eseg.flow_table_metadata != metadata) ||
-                           (mpw.wqe->eseg.cs_flags != cs_flags))
-                               max_wqe -= mlx5_empw_close(txq, &mpw);
-               }
-               if (unlikely(mpw.state == MLX5_MPW_STATE_CLOSED)) {
-                       /* In Enhanced MPW, inline as much as the budget is
-                        * allowed. The remaining space is to be filled with
-                        * dsegs. If the title WQEBB isn't padded, it will have
-                        * 2 dsegs there.
-                        */
-                       mpw_room = RTE_MIN(MLX5_WQE_SIZE_MAX,
-                                          (max_inline ? max_inline :
-                                           pkts_n * MLX5_WQE_DWORD_SIZE) +
-                                          MLX5_WQE_SIZE);
-                       if (unlikely(max_wqe * MLX5_WQE_SIZE < mpw_room))
-                               break;
-                       /* Don't pad the title WQEBB to not waste WQ. */
-                       mlx5_empw_new(txq, &mpw, 0);
-                       mpw_room -= mpw.total_len;
-                       inl_pad = 0;
-                       do_inline = length <= txq->inline_max_packet_sz &&
-                                   sizeof(inl_hdr) + length <= mpw_room &&
-                                   !txq->mpw_hdr_dseg;
-                       mpw.wqe->eseg.cs_flags = cs_flags;
-                       mpw.wqe->eseg.flow_table_metadata = metadata;
-               } else {
-                       /* Evaluate whether the next packet can be inlined.
-                        * Inlininig is possible when:
-                        * - length is less than configured value
-                        * - length fits for remaining space
-                        * - not required to fill the title WQEBB with dsegs
-                        */
-                       do_inline =
-                               length <= txq->inline_max_packet_sz &&
-                               inl_pad + sizeof(inl_hdr) + length <=
-                                mpw_room &&
-                               (!txq->mpw_hdr_dseg ||
-                                mpw.total_len >= MLX5_WQE_SIZE);
-               }
-               if (max_inline && do_inline) {
-                       /* Inline packet into WQE. */
-                       unsigned int max;
-
-                       assert(mpw.state == MLX5_MPW_ENHANCED_STATE_OPENED);
-                       assert(length == DATA_LEN(buf));
-                       inl_hdr = rte_cpu_to_be_32(length | MLX5_INLINE_SEG);
-                       addr = rte_pktmbuf_mtod(buf, uintptr_t);
-                       mpw.data.raw = (volatile void *)
-                               ((uintptr_t)mpw.data.raw + inl_pad);
-                       max = tx_mlx5_wq_tailroom(txq,
-                                       (void *)(uintptr_t)mpw.data.raw);
-                       /* Copy inline header. */
-                       mpw.data.raw = (volatile void *)
-                               mlx5_copy_to_wq(
-                                         (void *)(uintptr_t)mpw.data.raw,
-                                         &inl_hdr,
-                                         sizeof(inl_hdr),
-                                         (void *)(uintptr_t)txq->wqes,
-                                         max);
-                       max = tx_mlx5_wq_tailroom(txq,
-                                       (void *)(uintptr_t)mpw.data.raw);
-                       /* Copy packet data. */
-                       mpw.data.raw = (volatile void *)
-                               mlx5_copy_to_wq(
-                                         (void *)(uintptr_t)mpw.data.raw,
-                                         (void *)addr,
-                                         length,
-                                         (void *)(uintptr_t)txq->wqes,
-                                         max);
-                       ++mpw.pkts_n;
-                       mpw.total_len += (inl_pad + sizeof(inl_hdr) + length);
-                       /* No need to get completion as the entire packet is
-                        * copied to WQ. Free the buf right away.
-                        */
-                       rte_pktmbuf_free_seg(buf);
-                       mpw_room -= (inl_pad + sizeof(inl_hdr) + length);
-                       /* Add pad in the next packet if any. */
-                       inl_pad = (((uintptr_t)mpw.data.raw +
-                                       (MLX5_WQE_DWORD_SIZE - 1)) &
-                                       ~(MLX5_WQE_DWORD_SIZE - 1)) -
-                                 (uintptr_t)mpw.data.raw;
-               } else {
-                       /* No inline. Load a dseg of packet pointer. */
-                       volatile rte_v128u32_t *dseg;
-
-                       assert(mpw.state == MLX5_MPW_ENHANCED_STATE_OPENED);
-                       assert((inl_pad + sizeof(*dseg)) <= mpw_room);
-                       assert(length == DATA_LEN(buf));
-                       if (!tx_mlx5_wq_tailroom(txq,
-                                       (void *)((uintptr_t)mpw.data.raw
-                                               + inl_pad)))
-                               dseg = (volatile void *)txq->wqes;
-                       else
-                               dseg = (volatile void *)
-                                       ((uintptr_t)mpw.data.raw +
-                                        inl_pad);
-                       (*txq->elts)[elts_head++ & elts_m] = buf;
-                       addr_64 = rte_cpu_to_be_64(rte_pktmbuf_mtod(buf,
-                                                                   uintptr_t));
-                       *dseg = (rte_v128u32_t) {
-                               rte_cpu_to_be_32(length),
-                               mlx5_tx_mb2mr(txq, buf),
-                               addr_64,
-                               addr_64 >> 32,
-                       };
-                       mpw.data.raw = (volatile void *)(dseg + 1);
-                       mpw.total_len += (inl_pad + sizeof(*dseg));
-                       ++j;
-                       ++mpw.pkts_n;
-                       mpw_room -= (inl_pad + sizeof(*dseg));
-                       inl_pad = 0;
-               }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               /* Increment sent bytes counter. */
-               txq->stats.obytes += length;
-#endif
-               ++i;
-       } while (i < pkts_n);
-       /* Take a shortcut if nothing must be sent. */
-       if (unlikely(i == 0))
-               return 0;
-       /* Check whether completion threshold has been reached. */
-       if (txq->elts_comp + j >= MLX5_TX_COMP_THRESH ||
-                       (uint16_t)(txq->wqe_ci - txq->mpw_comp) >=
-                        (1 << txq->wqe_n) / MLX5_TX_COMP_THRESH_INLINE_DIV) {
-               volatile struct mlx5_wqe *wqe = mpw.wqe;
-
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               /* Request completion on last WQE. */
-               wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ALWAYS <<
-                                               MLX5_COMP_MODE_OFFSET);
-               /* Save elts_head in unused "immediate" field of WQE. */
-               wqe->ctrl[3] = elts_head;
-               txq->elts_comp = 0;
-               txq->mpw_comp = txq->wqe_ci;
-       } else {
-               txq->elts_comp += j;
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       /* Increment sent packets counter. */
-       txq->stats.opackets += i;
-#endif
-       if (mpw.state == MLX5_MPW_ENHANCED_STATE_OPENED)
-               mlx5_empw_close(txq, &mpw);
-       /* Ring QP doorbell. */
-       mlx5_tx_dbrec(txq, mpw.wqe);
-       txq->elts_head = elts_head;
-       return i;
-}
-
-/**
- * DPDK callback for TX with Enhanced MPW support.
- *
- * @param dpdk_txq
- *   Generic pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-uint16_t
-mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
-{
-       struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq;
-       uint16_t nb_tx = 0;
-
-       while (pkts_n > nb_tx) {
-               uint16_t n;
-               uint16_t ret;
-
-               n = txq_count_contig_multi_seg(&pkts[nb_tx], pkts_n - nb_tx);
-               if (n) {
-                       ret = mlx5_tx_burst(dpdk_txq, &pkts[nb_tx], n);
-                       if (!ret)
-                               break;
-                       nb_tx += ret;
-               }
-               n = txq_count_contig_single_seg(&pkts[nb_tx], pkts_n - nb_tx);
-               if (n) {
-                       ret = txq_burst_empw(txq, &pkts[nb_tx], n);
-                       if (!ret)
-                               break;
-                       nb_tx += ret;
-               }
-       }
-       return nb_tx;
-}
-
 /**
  * Translate RX completion flags to packet type.
  *
@@ -2866,22 +1491,6 @@ removed_rx_burst(void *dpdk_txq __rte_unused,
  * (e.g.  mlx5_rxtx_vec_sse.c for x86).
  */
 
-__rte_weak uint16_t
-mlx5_tx_burst_raw_vec(void *dpdk_txq __rte_unused,
-                     struct rte_mbuf **pkts __rte_unused,
-                     uint16_t pkts_n __rte_unused)
-{
-       return 0;
-}
-
-__rte_weak uint16_t
-mlx5_tx_burst_vec(void *dpdk_txq __rte_unused,
-                 struct rte_mbuf **pkts __rte_unused,
-                 uint16_t pkts_n __rte_unused)
-{
-       return 0;
-}
-
 __rte_weak uint16_t
 mlx5_rx_burst_vec(void *dpdk_txq __rte_unused,
                  struct rte_mbuf **pkts __rte_unused,
@@ -2891,25 +1500,50 @@ mlx5_rx_burst_vec(void *dpdk_txq __rte_unused,
 }
 
 __rte_weak int
-mlx5_check_raw_vec_tx_support(struct rte_eth_dev *dev __rte_unused)
+mlx5_rxq_check_vec_support(struct mlx5_rxq_data *rxq __rte_unused)
 {
        return -ENOTSUP;
 }
 
 __rte_weak int
-mlx5_check_vec_tx_support(struct rte_eth_dev *dev __rte_unused)
+mlx5_check_vec_rx_support(struct rte_eth_dev *dev __rte_unused)
 {
        return -ENOTSUP;
 }
 
-__rte_weak int
-mlx5_rxq_check_vec_support(struct mlx5_rxq_data *rxq __rte_unused)
+/**
+ * DPDK callback to check the status of a tx descriptor.
+ *
+ * @param tx_queue
+ *   The tx queue.
+ * @param[in] offset
+ *   The index of the descriptor in the ring.
+ *
+ * @return
+ *   The status of the tx descriptor.
+ */
+int
+mlx5_tx_descriptor_status(void *tx_queue, uint16_t offset)
 {
-       return -ENOTSUP;
+       (void)tx_queue;
+       (void)offset;
+       return RTE_ETH_TX_DESC_FULL;
 }
 
-__rte_weak int
-mlx5_check_vec_rx_support(struct rte_eth_dev *dev __rte_unused)
+/**
+ * Configure the TX function to use.
+ *
+ * @param dev
+ *   Pointer to private data structure.
+ *
+ * @return
+ *   Pointer to selected Tx burst function.
+ */
+eth_tx_burst_t
+mlx5_select_tx_function(struct rte_eth_dev *dev)
 {
-       return -ENOTSUP;
+       (void)dev;
+       return removed_tx_burst;
 }
+
+
index 3d79c18..acde09d 100644 (file)
@@ -329,14 +329,6 @@ extern uint8_t mlx5_swp_types_table[];
 void mlx5_set_ptype_table(void);
 void mlx5_set_cksum_table(void);
 void mlx5_set_swp_types_table(void);
-uint16_t mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts,
-                      uint16_t pkts_n);
-uint16_t mlx5_tx_burst_mpw(void *dpdk_txq, struct rte_mbuf **pkts,
-                          uint16_t pkts_n);
-uint16_t mlx5_tx_burst_mpw_inline(void *dpdk_txq, struct rte_mbuf **pkts,
-                                 uint16_t pkts_n);
-uint16_t mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts,
-                           uint16_t pkts_n);
 __rte_noinline uint16_t mlx5_tx_error_cqe_handle(struct mlx5_txq_data *txq,
                                        volatile struct mlx5_err_cqe *err_cqe);
 uint16_t mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n);
@@ -360,14 +352,8 @@ int mlx5_queue_state_modify_primary(struct rte_eth_dev *dev,
                        const struct mlx5_mp_arg_queue_state_modify *sm);
 
 /* Vectorized version of mlx5_rxtx.c */
-int mlx5_check_raw_vec_tx_support(struct rte_eth_dev *dev);
-int mlx5_check_vec_tx_support(struct rte_eth_dev *dev);
 int mlx5_rxq_check_vec_support(struct mlx5_rxq_data *rxq_data);
 int mlx5_check_vec_rx_support(struct rte_eth_dev *dev);
-uint16_t mlx5_tx_burst_raw_vec(void *dpdk_txq, struct rte_mbuf **pkts,
-                              uint16_t pkts_n);
-uint16_t mlx5_tx_burst_vec(void *dpdk_txq, struct rte_mbuf **pkts,
-                          uint16_t pkts_n);
 uint16_t mlx5_rx_burst_vec(void *dpdk_txq, struct rte_mbuf **pkts,
                           uint16_t pkts_n);
 
@@ -477,122 +463,6 @@ check_cqe(volatile struct mlx5_cqe *cqe, const uint16_t cqes_n,
        return MLX5_CQE_STATUS_SW_OWN;
 }
 
-/**
- * Return the address of the WQE.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param  wqe_ci
- *   WQE consumer index.
- *
- * @return
- *   WQE address.
- */
-static inline uintptr_t *
-tx_mlx5_wqe(struct mlx5_txq_data *txq, uint16_t ci)
-{
-       ci &= ((1 << txq->wqe_n) - 1);
-       return (uintptr_t *)((uintptr_t)txq->wqes + ci * MLX5_WQE_SIZE);
-}
-
-/**
- * Handle the next CQE.
- *
- * @param txq
- *   Pointer to TX queue structure.
- *
- * @return
- *   The last Tx buffer element to free.
- */
-static __rte_always_inline uint16_t
-mlx5_tx_cqe_handle(struct mlx5_txq_data *txq)
-{
-       const unsigned int cqe_n = 1 << txq->cqe_n;
-       const unsigned int cqe_cnt = cqe_n - 1;
-       uint16_t last_elts;
-       union {
-               volatile struct mlx5_cqe *cqe;
-               volatile struct mlx5_err_cqe *err_cqe;
-       } u = {
-               .cqe =  &(*txq->cqes)[txq->cq_ci & cqe_cnt],
-       };
-       int ret = check_cqe(u.cqe, cqe_n, txq->cq_ci);
-
-       if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) {
-               if (unlikely(ret == MLX5_CQE_STATUS_ERR))
-                       last_elts = mlx5_tx_error_cqe_handle(txq, u.err_cqe);
-               else
-                       /* Do not release buffers. */
-                       return txq->elts_tail;
-       } else {
-               uint16_t new_wqe_pi = rte_be_to_cpu_16(u.cqe->wqe_counter);
-               volatile struct mlx5_wqe_ctrl *ctrl =
-                               (volatile struct mlx5_wqe_ctrl *)
-                                       tx_mlx5_wqe(txq, new_wqe_pi);
-
-               /* Release completion burst buffers. */
-               last_elts = ctrl->ctrl3;
-               txq->wqe_pi = new_wqe_pi;
-               txq->cq_ci++;
-       }
-       rte_compiler_barrier();
-       *txq->cq_db = rte_cpu_to_be_32(txq->cq_ci);
-       return last_elts;
-}
-
-/**
- * Manage TX completions.
- *
- * When sending a burst, mlx5_tx_burst() posts several WRs.
- *
- * @param txq
- *   Pointer to TX queue structure.
- */
-static __rte_always_inline void
-mlx5_tx_complete(struct mlx5_txq_data *txq)
-{
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       uint16_t elts_free = txq->elts_tail;
-       uint16_t elts_tail;
-       struct rte_mbuf *m, *free[elts_n];
-       struct rte_mempool *pool = NULL;
-       unsigned int blk_n = 0;
-
-       elts_tail = mlx5_tx_cqe_handle(txq);
-       assert((elts_tail & elts_m) < (1 << txq->wqe_n));
-       /* Free buffers. */
-       while (elts_free != elts_tail) {
-               m = rte_pktmbuf_prefree_seg((*txq->elts)[elts_free++ & elts_m]);
-               if (likely(m != NULL)) {
-                       if (likely(m->pool == pool)) {
-                               free[blk_n++] = m;
-                       } else {
-                               if (likely(pool != NULL))
-                                       rte_mempool_put_bulk(pool,
-                                                            (void *)free,
-                                                            blk_n);
-                               free[0] = m;
-                               pool = m->pool;
-                               blk_n = 1;
-                       }
-               }
-       }
-       if (blk_n)
-               rte_mempool_put_bulk(pool, (void *)free, blk_n);
-#ifndef NDEBUG
-       elts_free = txq->elts_tail;
-       /* Poisoning. */
-       while (elts_free != elts_tail) {
-               memset(&(*txq->elts)[elts_free & elts_m],
-                      0x66,
-                      sizeof((*txq->elts)[elts_free & elts_m]));
-               ++elts_free;
-       }
-#endif
-       txq->elts_tail = elts_tail;
-}
-
 /**
  * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which the
  * cloned mbuf is allocated is returned instead.
@@ -710,147 +580,4 @@ mlx5_tx_dbrec(struct mlx5_txq_data *txq, volatile struct mlx5_wqe *wqe)
        mlx5_tx_dbrec_cond_wmb(txq, wqe, 1);
 }
 
-/**
- * Convert mbuf to Verb SWP.
- *
- * @param txq_data
- *   Pointer to the Tx queue.
- * @param buf
- *   Pointer to the mbuf.
- * @param offsets
- *   Pointer to the SWP header offsets.
- * @param swp_types
- *   Pointer to the SWP header types.
- */
-static __rte_always_inline void
-txq_mbuf_to_swp(struct mlx5_txq_data *txq, struct rte_mbuf *buf,
-               uint8_t *offsets, uint8_t *swp_types)
-{
-       const uint64_t vlan = buf->ol_flags & PKT_TX_VLAN_PKT;
-       const uint64_t tunnel = buf->ol_flags & PKT_TX_TUNNEL_MASK;
-       const uint64_t tso = buf->ol_flags & PKT_TX_TCP_SEG;
-       const uint64_t csum_flags = buf->ol_flags & PKT_TX_L4_MASK;
-       const uint64_t inner_ip =
-               buf->ol_flags & (PKT_TX_IPV4 | PKT_TX_IPV6);
-       const uint64_t ol_flags_mask = PKT_TX_L4_MASK | PKT_TX_IPV6 |
-                                      PKT_TX_OUTER_IPV6;
-       uint16_t idx;
-       uint16_t off;
-
-       if (likely(!txq->swp_en || (tunnel != PKT_TX_TUNNEL_UDP &&
-                                   tunnel != PKT_TX_TUNNEL_IP)))
-               return;
-       /*
-        * The index should have:
-        * bit[0:1] = PKT_TX_L4_MASK
-        * bit[4] = PKT_TX_IPV6
-        * bit[8] = PKT_TX_OUTER_IPV6
-        * bit[9] = PKT_TX_OUTER_UDP
-        */
-       idx = (buf->ol_flags & ol_flags_mask) >> 52;
-       if (tunnel == PKT_TX_TUNNEL_UDP)
-               idx |= 1 << 9;
-       *swp_types = mlx5_swp_types_table[idx];
-       /*
-        * Set offsets for SW parser. Since ConnectX-5, SW parser just
-        * complements HW parser. SW parser starts to engage only if HW parser
-        * can't reach a header. For the older devices, HW parser will not kick
-        * in if any of SWP offsets is set. Therefore, all of the L3 offsets
-        * should be set regardless of HW offload.
-        */
-       off = buf->outer_l2_len + (vlan ? sizeof(struct rte_vlan_hdr) : 0);
-       offsets[1] = off >> 1; /* Outer L3 offset. */
-       off += buf->outer_l3_len;
-       if (tunnel == PKT_TX_TUNNEL_UDP)
-               offsets[0] = off >> 1; /* Outer L4 offset. */
-       if (inner_ip) {
-               off += buf->l2_len;
-               offsets[3] = off >> 1; /* Inner L3 offset. */
-               if (csum_flags == PKT_TX_TCP_CKSUM || tso ||
-                   csum_flags == PKT_TX_UDP_CKSUM) {
-                       off += buf->l3_len;
-                       offsets[2] = off >> 1; /* Inner L4 offset. */
-               }
-       }
-}
-
-/**
- * Convert the Checksum offloads to Verbs.
- *
- * @param buf
- *   Pointer to the mbuf.
- *
- * @return
- *   Converted checksum flags.
- */
-static __rte_always_inline uint8_t
-txq_ol_cksum_to_cs(struct rte_mbuf *buf)
-{
-       uint32_t idx;
-       uint8_t is_tunnel = !!(buf->ol_flags & PKT_TX_TUNNEL_MASK);
-       const uint64_t ol_flags_mask = PKT_TX_TCP_SEG | PKT_TX_L4_MASK |
-                                      PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM;
-
-       /*
-        * The index should have:
-        * bit[0] = PKT_TX_TCP_SEG
-        * bit[2:3] = PKT_TX_UDP_CKSUM, PKT_TX_TCP_CKSUM
-        * bit[4] = PKT_TX_IP_CKSUM
-        * bit[8] = PKT_TX_OUTER_IP_CKSUM
-        * bit[9] = tunnel
-        */
-       idx = ((buf->ol_flags & ol_flags_mask) >> 50) | (!!is_tunnel << 9);
-       return mlx5_cksum_table[idx];
-}
-
-/**
- * Count the number of contiguous single segment packets.
- *
- * @param pkts
- *   Pointer to array of packets.
- * @param pkts_n
- *   Number of packets.
- *
- * @return
- *   Number of contiguous single segment packets.
- */
-static __rte_always_inline unsigned int
-txq_count_contig_single_seg(struct rte_mbuf **pkts, uint16_t pkts_n)
-{
-       unsigned int pos;
-
-       if (!pkts_n)
-               return 0;
-       /* Count the number of contiguous single segment packets. */
-       for (pos = 0; pos < pkts_n; ++pos)
-               if (NB_SEGS(pkts[pos]) > 1)
-                       break;
-       return pos;
-}
-
-/**
- * Count the number of contiguous multi-segment packets.
- *
- * @param pkts
- *   Pointer to array of packets.
- * @param pkts_n
- *   Number of packets.
- *
- * @return
- *   Number of contiguous multi-segment packets.
- */
-static __rte_always_inline unsigned int
-txq_count_contig_multi_seg(struct rte_mbuf **pkts, uint16_t pkts_n)
-{
-       unsigned int pos;
-
-       if (!pkts_n)
-               return 0;
-       /* Count the number of contiguous multi-segment packets. */
-       for (pos = 0; pos < pkts_n; ++pos)
-               if (NB_SEGS(pkts[pos]) == 1)
-                       break;
-       return pos;
-}
-
 #endif /* RTE_PMD_MLX5_RXTX_H_ */
index 073044f..f6ec828 100644 (file)
 #error "This should not be compiled if SIMD instructions are not supported."
 #endif
 
-/**
- * Count the number of packets having same ol_flags and same metadata (if
- * PKT_TX_METADATA is set in ol_flags), and calculate cs_flags.
- *
- * @param pkts
- *   Pointer to array of packets.
- * @param pkts_n
- *   Number of packets.
- * @param cs_flags
- *   Pointer of flags to be returned.
- * @param metadata
- *   Pointer of metadata to be returned.
- * @param txq_offloads
- *   Offloads enabled on Tx queue
- *
- * @return
- *   Number of packets having same ol_flags and metadata, if relevant.
- */
-static inline unsigned int
-txq_calc_offload(struct rte_mbuf **pkts, uint16_t pkts_n, uint8_t *cs_flags,
-                rte_be32_t *metadata, const uint64_t txq_offloads)
-{
-       unsigned int pos;
-       const uint64_t cksum_ol_mask =
-               PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM |
-               PKT_TX_UDP_CKSUM | PKT_TX_TUNNEL_GRE |
-               PKT_TX_TUNNEL_VXLAN | PKT_TX_OUTER_IP_CKSUM;
-       rte_be32_t p0_metadata, pn_metadata;
-
-       if (!pkts_n)
-               return 0;
-       p0_metadata = pkts[0]->ol_flags & PKT_TX_METADATA ?
-                       pkts[0]->tx_metadata : 0;
-       /* Count the number of packets having same offload parameters. */
-       for (pos = 1; pos < pkts_n; ++pos) {
-               /* Check if packet has same checksum flags. */
-               if ((txq_offloads & MLX5_VEC_TX_CKSUM_OFFLOAD_CAP) &&
-                   ((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & cksum_ol_mask))
-                       break;
-               /* Check if packet has same metadata. */
-               if (txq_offloads & DEV_TX_OFFLOAD_MATCH_METADATA) {
-                       pn_metadata = pkts[pos]->ol_flags & PKT_TX_METADATA ?
-                                       pkts[pos]->tx_metadata : 0;
-                       if (pn_metadata != p0_metadata)
-                               break;
-               }
-       }
-       *cs_flags = txq_ol_cksum_to_cs(pkts[0]);
-       *metadata = p0_metadata;
-       return pos;
-}
-
-/**
- * DPDK callback for vectorized TX.
- *
- * @param dpdk_txq
- *   Generic pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-uint16_t
-mlx5_tx_burst_raw_vec(void *dpdk_txq, struct rte_mbuf **pkts,
-                     uint16_t pkts_n)
-{
-       struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq;
-       uint16_t nb_tx = 0;
-
-       while (pkts_n > nb_tx) {
-               uint16_t n;
-               uint16_t ret;
-
-               n = RTE_MIN((uint16_t)(pkts_n - nb_tx), MLX5_VPMD_TX_MAX_BURST);
-               ret = txq_burst_v(txq, &pkts[nb_tx], n, 0, 0);
-               nb_tx += ret;
-               if (!ret)
-                       break;
-       }
-       return nb_tx;
-}
-
-/**
- * DPDK callback for vectorized TX with multi-seg packets and offload.
- *
- * @param dpdk_txq
- *   Generic pointer to TX queue structure.
- * @param[in] pkts
- *   Packets to transmit.
- * @param pkts_n
- *   Number of packets in array.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-uint16_t
-mlx5_tx_burst_vec(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
-{
-       struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq;
-       uint16_t nb_tx = 0;
-
-       while (pkts_n > nb_tx) {
-               uint8_t cs_flags = 0;
-               uint16_t n;
-               uint16_t ret;
-               rte_be32_t metadata = 0;
-
-               /* Transmit multi-seg packets in the head of pkts list. */
-               if ((txq->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-                   NB_SEGS(pkts[nb_tx]) > 1)
-                       nb_tx += txq_scatter_v(txq,
-                                              &pkts[nb_tx],
-                                              pkts_n - nb_tx);
-               n = RTE_MIN((uint16_t)(pkts_n - nb_tx), MLX5_VPMD_TX_MAX_BURST);
-               if (txq->offloads & DEV_TX_OFFLOAD_MULTI_SEGS)
-                       n = txq_count_contig_single_seg(&pkts[nb_tx], n);
-               if (txq->offloads & (MLX5_VEC_TX_CKSUM_OFFLOAD_CAP |
-                                    DEV_TX_OFFLOAD_MATCH_METADATA))
-                       n = txq_calc_offload(&pkts[nb_tx], n,
-                                            &cs_flags, &metadata,
-                                            txq->offloads);
-               ret = txq_burst_v(txq, &pkts[nb_tx], n, cs_flags, metadata);
-               nb_tx += ret;
-               if (!ret)
-                       break;
-       }
-       return nb_tx;
-}
-
 /**
  * Skip error packets.
  *
@@ -242,49 +110,6 @@ mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
        return nb_rx;
 }
 
-/**
- * Check Tx queue flags are set for raw vectorized Tx.
- *
- * @param dev
- *   Pointer to Ethernet device.
- *
- * @return
- *   1 if supported, negative errno value if not.
- */
-int __attribute__((cold))
-mlx5_check_raw_vec_tx_support(struct rte_eth_dev *dev)
-{
-       uint64_t offloads = dev->data->dev_conf.txmode.offloads;
-
-       /* Doesn't support any offload. */
-       if (offloads)
-               return -ENOTSUP;
-       return 1;
-}
-
-/**
- * Check a device can support vectorized TX.
- *
- * @param dev
- *   Pointer to Ethernet device.
- *
- * @return
- *   1 if supported, negative errno value if not.
- */
-int __attribute__((cold))
-mlx5_check_vec_tx_support(struct rte_eth_dev *dev)
-{
-       struct mlx5_priv *priv = dev->data->dev_private;
-       uint64_t offloads = dev->data->dev_conf.txmode.offloads;
-
-       if (!priv->config.tx_vec_en ||
-           priv->txqs_n > (unsigned int)priv->config.txqs_vec ||
-           priv->config.mps != MLX5_MPW_ENHANCED ||
-           offloads & ~MLX5_VEC_TX_OFFLOAD_CAP)
-               return -ENOTSUP;
-       return 1;
-}
-
 /**
  * Check a RX queue can support vectorized RX.
  *
index 1c7e3b4..9930286 100644 (file)
 
 #pragma GCC diagnostic ignored "-Wcast-qual"
 
-/**
- * Fill in buffer descriptors in a multi-packet send descriptor.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param dseg
- *   Pointer to buffer descriptor to be written.
- * @param pkts
- *   Pointer to array of packets to be sent.
- * @param n
- *   Number of packets to be filled.
- */
-static inline void
-txq_wr_dseg_v(struct mlx5_txq_data *txq, uint8_t *dseg,
-             struct rte_mbuf **pkts, unsigned int n)
-{
-       unsigned int pos;
-       uintptr_t addr;
-       const uint8x16_t dseg_shuf_m = {
-                3,  2,  1,  0, /* length, bswap32 */
-                4,  5,  6,  7, /* lkey */
-               15, 14, 13, 12, /* addr, bswap64 */
-               11, 10,  9,  8
-       };
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       uint32_t tx_byte = 0;
-#endif
-
-       for (pos = 0; pos < n; ++pos, dseg += MLX5_WQE_DWORD_SIZE) {
-               uint8x16_t desc;
-               struct rte_mbuf *pkt = pkts[pos];
-
-               addr = rte_pktmbuf_mtod(pkt, uintptr_t);
-               desc = vreinterpretq_u8_u32((uint32x4_t) {
-                               DATA_LEN(pkt),
-                               mlx5_tx_mb2mr(txq, pkt),
-                               addr,
-                               addr >> 32 });
-               desc = vqtbl1q_u8(desc, dseg_shuf_m);
-               vst1q_u8(dseg, desc);
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               tx_byte += DATA_LEN(pkt);
-#endif
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       txq->stats.obytes += tx_byte;
-#endif
-}
-
-/**
- * Send multi-segmented packets until it encounters a single segment packet in
- * the pkts list.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param pkts
- *   Pointer to array of packets to be sent.
- * @param pkts_n
- *   Number of packets to be sent.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-static uint16_t
-txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
-             uint16_t pkts_n)
-{
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       const uint16_t wq_n = 1 << txq->wqe_n;
-       const uint16_t wq_mask = wq_n - 1;
-       const unsigned int nb_dword_per_wqebb =
-               MLX5_WQE_SIZE / MLX5_WQE_DWORD_SIZE;
-       const unsigned int nb_dword_in_hdr =
-               sizeof(struct mlx5_wqe) / MLX5_WQE_DWORD_SIZE;
-       unsigned int n;
-       volatile struct mlx5_wqe *wqe = NULL;
-       bool metadata_ol =
-               txq->offloads & DEV_TX_OFFLOAD_MATCH_METADATA ? true : false;
-
-       assert(elts_n > pkts_n);
-       mlx5_tx_complete(txq);
-       if (unlikely(!pkts_n))
-               return 0;
-       for (n = 0; n < pkts_n; ++n) {
-               struct rte_mbuf *buf = pkts[n];
-               unsigned int segs_n = buf->nb_segs;
-               unsigned int ds = nb_dword_in_hdr;
-               unsigned int len = PKT_LEN(buf);
-               uint16_t wqe_ci = txq->wqe_ci;
-               const uint8x16_t ctrl_shuf_m = {
-                       3,  2,  1,  0, /* bswap32 */
-                       7,  6,  5,  4, /* bswap32 */
-                       11, 10,  9,  8, /* bswap32 */
-                       12, 13, 14, 15
-               };
-               uint8_t cs_flags;
-               uint16_t max_elts;
-               uint16_t max_wqe;
-               uint8x16_t *t_wqe;
-               uint8_t *dseg;
-               uint8x16_t ctrl;
-               rte_be32_t metadata =
-                       metadata_ol && (buf->ol_flags & PKT_TX_METADATA) ?
-                       buf->tx_metadata : 0;
-
-               assert(segs_n);
-               max_elts = elts_n - (elts_head - txq->elts_tail);
-               max_wqe = wq_n - (txq->wqe_ci - txq->wqe_pi);
-               /*
-                * A MPW session consumes 2 WQEs at most to
-                * include MLX5_MPW_DSEG_MAX pointers.
-                */
-               if (segs_n == 1 ||
-                   max_elts < segs_n || max_wqe < 2)
-                       break;
-               wqe = &((volatile struct mlx5_wqe64 *)
-                        txq->wqes)[wqe_ci & wq_mask].hdr;
-               cs_flags = txq_ol_cksum_to_cs(buf);
-               /* Title WQEBB pointer. */
-               t_wqe = (uint8x16_t *)wqe;
-               dseg = (uint8_t *)(wqe + 1);
-               do {
-                       if (!(ds++ % nb_dword_per_wqebb)) {
-                               dseg = (uint8_t *)
-                                       &((volatile struct mlx5_wqe64 *)
-                                          txq->wqes)[++wqe_ci & wq_mask];
-                       }
-                       txq_wr_dseg_v(txq, dseg, &buf, 1);
-                       dseg += MLX5_WQE_DWORD_SIZE;
-                       (*txq->elts)[elts_head++ & elts_m] = buf;
-                       buf = buf->next;
-               } while (--segs_n);
-               ++wqe_ci;
-               /* Fill CTRL in the header. */
-               ctrl = vreinterpretq_u8_u32((uint32x4_t) {
-                               MLX5_OPC_MOD_MPW << 24 |
-                               txq->wqe_ci << 8 | MLX5_OPCODE_TSO,
-                               txq->qp_num_8s | ds, 4, 0});
-               ctrl = vqtbl1q_u8(ctrl, ctrl_shuf_m);
-               vst1q_u8((void *)t_wqe, ctrl);
-               /* Fill ESEG in the header. */
-               vst1q_u32((void *)(t_wqe + 1),
-                         ((uint32x4_t){ 0,
-                                        rte_cpu_to_be_16(len) << 16 | cs_flags,
-                                        metadata, 0 }));
-               txq->wqe_ci = wqe_ci;
-       }
-       if (!n)
-               return 0;
-       txq->elts_comp += (uint16_t)(elts_head - txq->elts_head);
-       txq->elts_head = elts_head;
-       if (txq->elts_comp >= MLX5_TX_COMP_THRESH) {
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ALWAYS <<
-                                               MLX5_COMP_MODE_OFFSET);
-               wqe->ctrl[3] = txq->elts_head;
-               txq->elts_comp = 0;
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       txq->stats.opackets += n;
-#endif
-       mlx5_tx_dbrec(txq, wqe);
-       return n;
-}
-
-/**
- * Send burst of packets with Enhanced MPW. If it encounters a multi-seg packet,
- * it returns to make it processed by txq_scatter_v(). All the packets in
- * the pkts list should be single segment packets having same offload flags.
- * This must be checked by txq_count_contig_single_seg() and txq_calc_offload().
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param pkts
- *   Pointer to array of packets to be sent.
- * @param pkts_n
- *   Number of packets to be sent (<= MLX5_VPMD_TX_MAX_BURST).
- * @param cs_flags
- *   Checksum offload flags to be written in the descriptor.
- * @param metadata
- *   Metadata value to be written in the descriptor.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-static inline uint16_t
-txq_burst_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts, uint16_t pkts_n,
-           uint8_t cs_flags, rte_be32_t metadata)
-{
-       struct rte_mbuf **elts;
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       const unsigned int nb_dword_per_wqebb =
-               MLX5_WQE_SIZE / MLX5_WQE_DWORD_SIZE;
-       const unsigned int nb_dword_in_hdr =
-               sizeof(struct mlx5_wqe) / MLX5_WQE_DWORD_SIZE;
-       unsigned int n = 0;
-       unsigned int pos;
-       uint16_t max_elts;
-       uint16_t max_wqe;
-       uint32_t comp_req;
-       const uint16_t wq_n = 1 << txq->wqe_n;
-       const uint16_t wq_mask = wq_n - 1;
-       uint16_t wq_idx = txq->wqe_ci & wq_mask;
-       volatile struct mlx5_wqe64 *wq =
-               &((volatile struct mlx5_wqe64 *)txq->wqes)[wq_idx];
-       volatile struct mlx5_wqe *wqe = (volatile struct mlx5_wqe *)wq;
-       const uint8x16_t ctrl_shuf_m = {
-                3,  2,  1,  0, /* bswap32 */
-                7,  6,  5,  4, /* bswap32 */
-               11, 10,  9,  8, /* bswap32 */
-               12, 13, 14, 15
-       };
-       uint8x16_t *t_wqe;
-       uint8_t *dseg;
-       uint8x16_t ctrl;
-
-       /* Make sure all packets can fit into a single WQE. */
-       assert(elts_n > pkts_n);
-       mlx5_tx_complete(txq);
-       max_elts = (elts_n - (elts_head - txq->elts_tail));
-       max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-       pkts_n = RTE_MIN((unsigned int)RTE_MIN(pkts_n, max_wqe), max_elts);
-       if (unlikely(!pkts_n))
-               return 0;
-       elts = &(*txq->elts)[elts_head & elts_m];
-       /* Loop for available tailroom first. */
-       n = RTE_MIN(elts_n - (elts_head & elts_m), pkts_n);
-       for (pos = 0; pos < (n & -2); pos += 2)
-               vst1q_u64((void *)&elts[pos], vld1q_u64((void *)&pkts[pos]));
-       if (n & 1)
-               elts[pos] = pkts[pos];
-       /* Check if it crosses the end of the queue. */
-       if (unlikely(n < pkts_n)) {
-               elts = &(*txq->elts)[0];
-               for (pos = 0; pos < pkts_n - n; ++pos)
-                       elts[pos] = pkts[n + pos];
-       }
-       txq->elts_head += pkts_n;
-       /* Save title WQEBB pointer. */
-       t_wqe = (uint8x16_t *)wqe;
-       dseg = (uint8_t *)(wqe + 1);
-       /* Calculate the number of entries to the end. */
-       n = RTE_MIN(
-               (wq_n - wq_idx) * nb_dword_per_wqebb - nb_dword_in_hdr,
-               pkts_n);
-       /* Fill DSEGs. */
-       txq_wr_dseg_v(txq, dseg, pkts, n);
-       /* Check if it crosses the end of the queue. */
-       if (n < pkts_n) {
-               dseg = (uint8_t *)txq->wqes;
-               txq_wr_dseg_v(txq, dseg, &pkts[n], pkts_n - n);
-       }
-       if (txq->elts_comp + pkts_n < MLX5_TX_COMP_THRESH) {
-               txq->elts_comp += pkts_n;
-               comp_req = MLX5_COMP_ONLY_FIRST_ERR << MLX5_COMP_MODE_OFFSET;
-       } else {
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               /* Request a completion. */
-               txq->elts_comp = 0;
-               comp_req = MLX5_COMP_ALWAYS << MLX5_COMP_MODE_OFFSET;
-       }
-       /* Fill CTRL in the header. */
-       ctrl = vreinterpretq_u8_u32((uint32x4_t) {
-                       MLX5_OPC_MOD_ENHANCED_MPSW << 24 |
-                       txq->wqe_ci << 8 | MLX5_OPCODE_ENHANCED_MPSW,
-                       txq->qp_num_8s | (pkts_n + 2),
-                       comp_req,
-                       txq->elts_head });
-       ctrl = vqtbl1q_u8(ctrl, ctrl_shuf_m);
-       vst1q_u8((void *)t_wqe, ctrl);
-       /* Fill ESEG in the header. */
-       vst1q_u32((void *)(t_wqe + 1),
-                ((uint32x4_t) { 0, cs_flags, metadata, 0 }));
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       txq->stats.opackets += pkts_n;
-#endif
-       txq->wqe_ci += (nb_dword_in_hdr + pkts_n + (nb_dword_per_wqebb - 1)) /
-                      nb_dword_per_wqebb;
-       /* Ring QP doorbell. */
-       mlx5_tx_dbrec_cond_wmb(txq, wqe, pkts_n < MLX5_VPMD_TX_MAX_BURST);
-       return pkts_n;
-}
-
 /**
  * Store free buffers to RX SW ring.
  *
index 503ca0f..7bd254f 100644 (file)
 #pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
 
-/**
- * Fill in buffer descriptors in a multi-packet send descriptor.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param dseg
- *   Pointer to buffer descriptor to be written.
- * @param pkts
- *   Pointer to array of packets to be sent.
- * @param n
- *   Number of packets to be filled.
- */
-static inline void
-txq_wr_dseg_v(struct mlx5_txq_data *txq, __m128i *dseg,
-             struct rte_mbuf **pkts, unsigned int n)
-{
-       unsigned int pos;
-       uintptr_t addr;
-       const __m128i shuf_mask_dseg =
-               _mm_set_epi8(8,  9, 10, 11, /* addr, bswap64 */
-                           12, 13, 14, 15,
-                            7,  6,  5,  4, /* lkey */
-                            0,  1,  2,  3  /* length, bswap32 */);
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       uint32_t tx_byte = 0;
-#endif
-
-       for (pos = 0; pos < n; ++pos, ++dseg) {
-               __m128i desc;
-               struct rte_mbuf *pkt = pkts[pos];
-
-               addr = rte_pktmbuf_mtod(pkt, uintptr_t);
-               desc = _mm_set_epi32(addr >> 32,
-                                    addr,
-                                    mlx5_tx_mb2mr(txq, pkt),
-                                    DATA_LEN(pkt));
-               desc = _mm_shuffle_epi8(desc, shuf_mask_dseg);
-               _mm_store_si128(dseg, desc);
-#ifdef MLX5_PMD_SOFT_COUNTERS
-               tx_byte += DATA_LEN(pkt);
-#endif
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       txq->stats.obytes += tx_byte;
-#endif
-}
-
-/**
- * Send multi-segmented packets until it encounters a single segment packet in
- * the pkts list.
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param pkts
- *   Pointer to array of packets to be sent.
- * @param pkts_n
- *   Number of packets to be sent.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-static uint16_t
-txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
-             uint16_t pkts_n)
-{
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       const uint16_t wq_n = 1 << txq->wqe_n;
-       const uint16_t wq_mask = wq_n - 1;
-       const unsigned int nb_dword_per_wqebb =
-               MLX5_WQE_SIZE / MLX5_WQE_DWORD_SIZE;
-       const unsigned int nb_dword_in_hdr =
-               sizeof(struct mlx5_wqe) / MLX5_WQE_DWORD_SIZE;
-       unsigned int n;
-       volatile struct mlx5_wqe *wqe = NULL;
-       bool metadata_ol =
-               txq->offloads & DEV_TX_OFFLOAD_MATCH_METADATA ? true : false;
-
-       assert(elts_n > pkts_n);
-       mlx5_tx_complete(txq);
-       if (unlikely(!pkts_n))
-               return 0;
-       for (n = 0; n < pkts_n; ++n) {
-               struct rte_mbuf *buf = pkts[n];
-               unsigned int segs_n = buf->nb_segs;
-               unsigned int ds = nb_dword_in_hdr;
-               unsigned int len = PKT_LEN(buf);
-               uint16_t wqe_ci = txq->wqe_ci;
-               const __m128i shuf_mask_ctrl =
-                       _mm_set_epi8(15, 14, 13, 12,
-                                     8,  9, 10, 11, /* bswap32 */
-                                     4,  5,  6,  7, /* bswap32 */
-                                     0,  1,  2,  3  /* bswap32 */);
-               uint8_t cs_flags;
-               uint16_t max_elts;
-               uint16_t max_wqe;
-               __m128i *t_wqe, *dseg;
-               __m128i ctrl;
-               rte_be32_t metadata =
-                       metadata_ol && (buf->ol_flags & PKT_TX_METADATA) ?
-                       buf->tx_metadata : 0;
-
-               assert(segs_n);
-               max_elts = elts_n - (elts_head - txq->elts_tail);
-               max_wqe = wq_n - (txq->wqe_ci - txq->wqe_pi);
-               /*
-                * A MPW session consumes 2 WQEs at most to
-                * include MLX5_MPW_DSEG_MAX pointers.
-                */
-               if (segs_n == 1 ||
-                   max_elts < segs_n || max_wqe < 2)
-                       break;
-               if (segs_n > MLX5_MPW_DSEG_MAX) {
-                       txq->stats.oerrors++;
-                       break;
-               }
-               wqe = &((volatile struct mlx5_wqe64 *)
-                        txq->wqes)[wqe_ci & wq_mask].hdr;
-               cs_flags = txq_ol_cksum_to_cs(buf);
-               /* Title WQEBB pointer. */
-               t_wqe = (__m128i *)wqe;
-               dseg = (__m128i *)(wqe + 1);
-               do {
-                       if (!(ds++ % nb_dword_per_wqebb)) {
-                               dseg = (__m128i *)
-                                       &((volatile struct mlx5_wqe64 *)
-                                          txq->wqes)[++wqe_ci & wq_mask];
-                       }
-                       txq_wr_dseg_v(txq, dseg++, &buf, 1);
-                       (*txq->elts)[elts_head++ & elts_m] = buf;
-                       buf = buf->next;
-               } while (--segs_n);
-               ++wqe_ci;
-               /* Fill CTRL in the header. */
-               ctrl = _mm_set_epi32(0, 4, txq->qp_num_8s | ds,
-                                    MLX5_OPC_MOD_MPW << 24 |
-                                    txq->wqe_ci << 8 | MLX5_OPCODE_TSO);
-               ctrl = _mm_shuffle_epi8(ctrl, shuf_mask_ctrl);
-               _mm_store_si128(t_wqe, ctrl);
-               /* Fill ESEG in the header. */
-               _mm_store_si128(t_wqe + 1,
-                               _mm_set_epi32(0, metadata,
-                                             (rte_cpu_to_be_16(len) << 16) |
-                                             cs_flags, 0));
-               txq->wqe_ci = wqe_ci;
-       }
-       if (!n)
-               return 0;
-       txq->elts_comp += (uint16_t)(elts_head - txq->elts_head);
-       txq->elts_head = elts_head;
-       if (txq->elts_comp >= MLX5_TX_COMP_THRESH) {
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               wqe->ctrl[2] = rte_cpu_to_be_32(MLX5_COMP_ALWAYS <<
-                                               MLX5_COMP_MODE_OFFSET);
-               wqe->ctrl[3] = txq->elts_head;
-               txq->elts_comp = 0;
-       }
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       txq->stats.opackets += n;
-#endif
-       mlx5_tx_dbrec(txq, wqe);
-       return n;
-}
-
-/**
- * Send burst of packets with Enhanced MPW. If it encounters a multi-seg packet,
- * it returns to make it processed by txq_scatter_v(). All the packets in
- * the pkts list should be single segment packets having same offload flags.
- * This must be checked by txq_count_contig_single_seg() and txq_calc_offload().
- *
- * @param txq
- *   Pointer to TX queue structure.
- * @param pkts
- *   Pointer to array of packets to be sent.
- * @param pkts_n
- *   Number of packets to be sent (<= MLX5_VPMD_TX_MAX_BURST).
- * @param cs_flags
- *   Checksum offload flags to be written in the descriptor.
- * @param metadata
- *   Metadata value to be written in the descriptor.
- *
- * @return
- *   Number of packets successfully transmitted (<= pkts_n).
- */
-static inline uint16_t
-txq_burst_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts, uint16_t pkts_n,
-           uint8_t cs_flags, rte_be32_t metadata)
-{
-       struct rte_mbuf **elts;
-       uint16_t elts_head = txq->elts_head;
-       const uint16_t elts_n = 1 << txq->elts_n;
-       const uint16_t elts_m = elts_n - 1;
-       const unsigned int nb_dword_per_wqebb =
-               MLX5_WQE_SIZE / MLX5_WQE_DWORD_SIZE;
-       const unsigned int nb_dword_in_hdr =
-               sizeof(struct mlx5_wqe) / MLX5_WQE_DWORD_SIZE;
-       unsigned int n = 0;
-       unsigned int pos;
-       uint16_t max_elts;
-       uint16_t max_wqe;
-       uint32_t comp_req;
-       const uint16_t wq_n = 1 << txq->wqe_n;
-       const uint16_t wq_mask = wq_n - 1;
-       uint16_t wq_idx = txq->wqe_ci & wq_mask;
-       volatile struct mlx5_wqe64 *wq =
-               &((volatile struct mlx5_wqe64 *)txq->wqes)[wq_idx];
-       volatile struct mlx5_wqe *wqe = (volatile struct mlx5_wqe *)wq;
-       const __m128i shuf_mask_ctrl =
-               _mm_set_epi8(15, 14, 13, 12,
-                             8,  9, 10, 11, /* bswap32 */
-                             4,  5,  6,  7, /* bswap32 */
-                             0,  1,  2,  3  /* bswap32 */);
-       __m128i *t_wqe, *dseg;
-       __m128i ctrl;
-
-       /* Make sure all packets can fit into a single WQE. */
-       assert(elts_n > pkts_n);
-       mlx5_tx_complete(txq);
-       max_elts = (elts_n - (elts_head - txq->elts_tail));
-       max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-       pkts_n = RTE_MIN((unsigned int)RTE_MIN(pkts_n, max_wqe), max_elts);
-       assert(pkts_n <= MLX5_DSEG_MAX - nb_dword_in_hdr);
-       if (unlikely(!pkts_n))
-               return 0;
-       elts = &(*txq->elts)[elts_head & elts_m];
-       /* Loop for available tailroom first. */
-       n = RTE_MIN(elts_n - (elts_head & elts_m), pkts_n);
-       for (pos = 0; pos < (n & -2); pos += 2)
-               _mm_storeu_si128((__m128i *)&elts[pos],
-                                _mm_loadu_si128((__m128i *)&pkts[pos]));
-       if (n & 1)
-               elts[pos] = pkts[pos];
-       /* Check if it crosses the end of the queue. */
-       if (unlikely(n < pkts_n)) {
-               elts = &(*txq->elts)[0];
-               for (pos = 0; pos < pkts_n - n; ++pos)
-                       elts[pos] = pkts[n + pos];
-       }
-       txq->elts_head += pkts_n;
-       /* Save title WQEBB pointer. */
-       t_wqe = (__m128i *)wqe;
-       dseg = (__m128i *)(wqe + 1);
-       /* Calculate the number of entries to the end. */
-       n = RTE_MIN(
-               (wq_n - wq_idx) * nb_dword_per_wqebb - nb_dword_in_hdr,
-               pkts_n);
-       /* Fill DSEGs. */
-       txq_wr_dseg_v(txq, dseg, pkts, n);
-       /* Check if it crosses the end of the queue. */
-       if (n < pkts_n) {
-               dseg = (__m128i *)txq->wqes;
-               txq_wr_dseg_v(txq, dseg, &pkts[n], pkts_n - n);
-       }
-       if (txq->elts_comp + pkts_n < MLX5_TX_COMP_THRESH) {
-               txq->elts_comp += pkts_n;
-               comp_req = MLX5_COMP_ONLY_FIRST_ERR << MLX5_COMP_MODE_OFFSET;
-       } else {
-               /* A CQE slot must always be available. */
-               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
-               /* Request a completion. */
-               txq->elts_comp = 0;
-               comp_req = MLX5_COMP_ALWAYS << MLX5_COMP_MODE_OFFSET;
-       }
-       /* Fill CTRL in the header. */
-       ctrl = _mm_set_epi32(txq->elts_head, comp_req,
-                            txq->qp_num_8s | (pkts_n + 2),
-                            MLX5_OPC_MOD_ENHANCED_MPSW << 24 |
-                               txq->wqe_ci << 8 | MLX5_OPCODE_ENHANCED_MPSW);
-       ctrl = _mm_shuffle_epi8(ctrl, shuf_mask_ctrl);
-       _mm_store_si128(t_wqe, ctrl);
-       /* Fill ESEG in the header. */
-       _mm_store_si128(t_wqe + 1, _mm_set_epi32(0, metadata, cs_flags, 0));
-#ifdef MLX5_PMD_SOFT_COUNTERS
-       txq->stats.opackets += pkts_n;
-#endif
-       txq->wqe_ci += (nb_dword_in_hdr + pkts_n + (nb_dword_per_wqebb - 1)) /
-                      nb_dword_per_wqebb;
-       /* Ring QP doorbell. */
-       mlx5_tx_dbrec_cond_wmb(txq, wqe, pkts_n < MLX5_VPMD_TX_MAX_BURST);
-       return pkts_n;
-}
-
 /**
  * Store free buffers to RX SW ring.
  *
index 82493d7..55892e2 100644 (file)
@@ -364,25 +364,6 @@ error:
        return -rte_errno;
 }
 
-/**
- * Check if the burst function is using eMPW.
- *
- * @param tx_pkt_burst
- *   Tx burst function pointer.
- *
- * @return
- *   1 if the burst function is using eMPW, 0 otherwise.
- */
-static int
-is_empw_burst_func(eth_tx_burst_t tx_pkt_burst)
-{
-       if (tx_pkt_burst == mlx5_tx_burst_raw_vec ||
-           tx_pkt_burst == mlx5_tx_burst_vec ||
-           tx_pkt_burst == mlx5_tx_burst_empw)
-               return 1;
-       return 0;
-}
-
 /**
  * Create the Tx queue Verbs object.
  *
@@ -414,7 +395,6 @@ mlx5_txq_ibv_new(struct rte_eth_dev *dev, uint16_t idx)
        struct mlx5dv_cq cq_info;
        struct mlx5dv_obj obj;
        const int desc = 1 << txq_data->elts_n;
-       eth_tx_burst_t tx_pkt_burst = mlx5_select_tx_function(dev);
        int ret = 0;
 
        assert(txq_data);
@@ -432,8 +412,6 @@ mlx5_txq_ibv_new(struct rte_eth_dev *dev, uint16_t idx)
                .comp_mask = 0,
        };
        cqe_n = desc / MLX5_TX_COMP_THRESH + 1;
-       if (is_empw_burst_func(tx_pkt_burst))
-               cqe_n += MLX5_TX_COMP_THRESH_INLINE_DIV;
        tmpl.cq = mlx5_glue->create_cq(priv->sh->ctx, cqe_n, NULL, NULL, 0);
        if (tmpl.cq == NULL) {
                DRV_LOG(ERR, "port %u Tx queue %u CQ creation failure",
@@ -698,93 +676,7 @@ txq_calc_wqebb_cnt(struct mlx5_txq_ctrl *txq_ctrl)
 static void
 txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
-       struct mlx5_priv *priv = txq_ctrl->priv;
-       struct mlx5_dev_config *config = &priv->config;
-       const unsigned int max_tso_inline =
-               ((MLX5_MAX_TSO_HEADER + (RTE_CACHE_LINE_SIZE - 1)) /
-                RTE_CACHE_LINE_SIZE);
-       unsigned int txq_inline;
-       unsigned int txqs_inline;
-       unsigned int inline_max_packet_sz;
-       eth_tx_burst_t tx_pkt_burst =
-               mlx5_select_tx_function(ETH_DEV(priv));
-       int is_empw_func = is_empw_burst_func(tx_pkt_burst);
-       int tso = !!(txq_ctrl->txq.offloads & (DEV_TX_OFFLOAD_TCP_TSO |
-                                              DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
-                                              DEV_TX_OFFLOAD_GRE_TNL_TSO |
-                                              DEV_TX_OFFLOAD_IP_TNL_TSO |
-                                              DEV_TX_OFFLOAD_UDP_TNL_TSO));
-
-       txq_inline = (config->txq_inline == MLX5_ARG_UNSET) ?
-               0 : config->txq_inline;
-       txqs_inline = (config->txqs_inline == MLX5_ARG_UNSET) ?
-               0 : config->txqs_inline;
-       inline_max_packet_sz =
-               (config->inline_max_packet_sz == MLX5_ARG_UNSET) ?
-               0 : config->inline_max_packet_sz;
-       if (is_empw_func) {
-               if (config->txq_inline == MLX5_ARG_UNSET)
-                       txq_inline = MLX5_WQE_SIZE_MAX - MLX5_WQE_SIZE;
-               if (config->txqs_inline == MLX5_ARG_UNSET)
-                       txqs_inline = MLX5_EMPW_MIN_TXQS;
-               if (config->inline_max_packet_sz == MLX5_ARG_UNSET)
-                       inline_max_packet_sz = MLX5_EMPW_MAX_INLINE_LEN;
-               txq_ctrl->txq.mpw_hdr_dseg = config->mpw_hdr_dseg;
-               txq_ctrl->txq.inline_max_packet_sz = inline_max_packet_sz;
-       }
-       if (txq_inline && priv->txqs_n >= txqs_inline) {
-               unsigned int ds_cnt;
-
-               txq_ctrl->txq.max_inline =
-                       ((txq_inline + (RTE_CACHE_LINE_SIZE - 1)) /
-                        RTE_CACHE_LINE_SIZE);
-               if (is_empw_func) {
-                       /* To minimize the size of data set, avoid requesting
-                        * too large WQ.
-                        */
-                       txq_ctrl->max_inline_data =
-                               ((RTE_MIN(txq_inline,
-                                         inline_max_packet_sz) +
-                                 (RTE_CACHE_LINE_SIZE - 1)) /
-                                RTE_CACHE_LINE_SIZE) * RTE_CACHE_LINE_SIZE;
-               } else {
-                       txq_ctrl->max_inline_data =
-                               txq_ctrl->txq.max_inline * RTE_CACHE_LINE_SIZE;
-               }
-               /*
-                * Check if the inline size is too large in a way which
-                * can make the WQE DS to overflow.
-                * Considering in calculation:
-                *      WQE CTRL (1 DS)
-                *      WQE ETH  (1 DS)
-                *      Inline part (N DS)
-                */
-               ds_cnt = 2 + (txq_ctrl->txq.max_inline / MLX5_WQE_DWORD_SIZE);
-               if (ds_cnt > MLX5_DSEG_MAX) {
-                       unsigned int max_inline = (MLX5_DSEG_MAX - 2) *
-                                                 MLX5_WQE_DWORD_SIZE;
-
-                       max_inline = max_inline - (max_inline %
-                                                  RTE_CACHE_LINE_SIZE);
-                       DRV_LOG(WARNING,
-                               "port %u txq inline is too large (%d) setting"
-                               " it to the maximum possible: %d\n",
-                               PORT_ID(priv), txq_inline, max_inline);
-                       txq_ctrl->txq.max_inline = max_inline /
-                                                  RTE_CACHE_LINE_SIZE;
-               }
-       }
-       if (tso) {
-               txq_ctrl->max_tso_header = max_tso_inline * RTE_CACHE_LINE_SIZE;
-               txq_ctrl->txq.max_inline = RTE_MAX(txq_ctrl->txq.max_inline,
-                                                  max_tso_inline);
-               txq_ctrl->txq.tso_en = 1;
-       }
-       txq_ctrl->txq.tunnel_en = config->tunnel_en | config->swp;
-       txq_ctrl->txq.swp_en = ((DEV_TX_OFFLOAD_IP_TNL_TSO |
-                                DEV_TX_OFFLOAD_UDP_TNL_TSO |
-                                DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) &
-                               txq_ctrl->txq.offloads) && config->swp;
+       (void)txq_ctrl;
 }
 
 /**