net/vmxnet3: add Tx preparation
authorKonstantin Ananyev <konstantin.ananyev@intel.com>
Fri, 23 Dec 2016 18:40:52 +0000 (19:40 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 4 Jan 2017 19:40:25 +0000 (20:40 +0100)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Yong Wang <yongwang@vmware.com>
drivers/net/vmxnet3/vmxnet3_ethdev.c
drivers/net/vmxnet3/vmxnet3_ethdev.h
drivers/net/vmxnet3/vmxnet3_rxtx.c

index 9c4d93c..54533ca 100644 (file)
@@ -69,6 +69,8 @@
 
 #define PROCESS_SYS_EVENTS 0
 
+#define        VMXNET3_TX_MAX_SEG      UINT8_MAX
+
 static int eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev);
 static int vmxnet3_dev_configure(struct rte_eth_dev *dev);
@@ -237,6 +239,7 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
        eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
        eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
        eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
+       eth_dev->tx_pkt_prepare = vmxnet3_prep_pkts;
        pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
 
        /*
@@ -326,6 +329,7 @@ eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev)
        eth_dev->dev_ops = NULL;
        eth_dev->rx_pkt_burst = NULL;
        eth_dev->tx_pkt_burst = NULL;
+       eth_dev->tx_pkt_prepare = NULL;
 
        rte_free(eth_dev->data->mac_addrs);
        eth_dev->data->mac_addrs = NULL;
@@ -730,6 +734,8 @@ vmxnet3_dev_info_get(struct rte_eth_dev *dev,
                .nb_max = VMXNET3_TX_RING_MAX_SIZE,
                .nb_min = VMXNET3_DEF_TX_RING_SIZE,
                .nb_align = 1,
+               .nb_seg_max = VMXNET3_TX_MAX_SEG,
+               .nb_mtu_seg_max = VMXNET3_MAX_TXD_PER_PKT,
        };
 
        dev_info->rx_offload_capa =
index 7d3b11e..469db71 100644 (file)
@@ -171,5 +171,7 @@ uint16_t vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
                           uint16_t nb_pkts);
 uint16_t vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
                           uint16_t nb_pkts);
+uint16_t vmxnet3_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+                       uint16_t nb_pkts);
 
 #endif /* _VMXNET3_ETHDEV_H_ */
index b109168..3651369 100644 (file)
@@ -69,6 +69,7 @@
 #include <rte_sctp.h>
 #include <rte_string_fns.h>
 #include <rte_errno.h>
+#include <rte_net.h>
 
 #include "base/vmxnet3_defs.h"
 #include "vmxnet3_ring.h"
 #include "vmxnet3_logs.h"
 #include "vmxnet3_ethdev.h"
 
+#define        VMXNET3_TX_OFFLOAD_MASK ( \
+               PKT_TX_VLAN_PKT | \
+               PKT_TX_L4_MASK |  \
+               PKT_TX_TCP_SEG)
+
+#define        VMXNET3_TX_OFFLOAD_NOTSUP_MASK  \
+       (PKT_TX_OFFLOAD_MASK ^ VMXNET3_TX_OFFLOAD_MASK)
+
 static const uint32_t rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
 
 static int vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t*, uint8_t);
@@ -349,6 +358,53 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
        PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
 }
 
+uint16_t
+vmxnet3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+       uint16_t nb_pkts)
+{
+       int32_t ret;
+       uint32_t i;
+       uint64_t ol_flags;
+       struct rte_mbuf *m;
+
+       for (i = 0; i != nb_pkts; i++) {
+               m = tx_pkts[i];
+               ol_flags = m->ol_flags;
+
+               /* Non-TSO packet cannot occupy more than
+                * VMXNET3_MAX_TXD_PER_PKT TX descriptors.
+                */
+               if ((ol_flags & PKT_TX_TCP_SEG) == 0 &&
+                               m->nb_segs > VMXNET3_MAX_TXD_PER_PKT) {
+                       rte_errno = -EINVAL;
+                       return i;
+               }
+
+               /* check that only supported TX offloads are requested. */
+               if ((ol_flags & VMXNET3_TX_OFFLOAD_NOTSUP_MASK) != 0 ||
+                               (ol_flags & PKT_TX_L4_MASK) ==
+                               PKT_TX_SCTP_CKSUM) {
+                       rte_errno = -ENOTSUP;
+                       return i;
+               }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+               ret = rte_validate_tx_offload(m);
+               if (ret != 0) {
+                       rte_errno = ret;
+                       return i;
+               }
+#endif
+               ret = rte_net_intel_cksum_prepare(m);
+               if (ret != 0) {
+                       rte_errno = ret;
+                       return i;
+               }
+       }
+
+       return i;
+}
+
 uint16_t
 vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
                  uint16_t nb_pkts)