net/mlx5: fix match on ethertype and CVLAN tag
[dpdk.git] / drivers / net / ixgbe / ixgbe_rxtx.c
index 18938fc..f839bca 100644 (file)
 #define rte_ixgbe_prefetch(p)   do {} while (0)
 #endif
 
-#ifdef RTE_IXGBE_INC_VECTOR
-uint16_t ixgbe_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
-                                   uint16_t nb_pkts);
-#endif
-
 /*********************************************************************
  *
  *  TX functions
@@ -344,7 +339,6 @@ ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
        return nb_tx;
 }
 
-#ifdef RTE_IXGBE_INC_VECTOR
 static uint16_t
 ixgbe_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
                    uint16_t nb_pkts)
@@ -366,7 +360,6 @@ ixgbe_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
 
        return nb_tx;
 }
-#endif
 
 static inline void
 ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,
@@ -422,21 +415,24 @@ ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,
                case PKT_TX_UDP_CKSUM:
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP |
                                IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;
-                       mss_l4len_idx |= sizeof(struct udp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;
+                       mss_l4len_idx |= sizeof(struct rte_udp_hdr)
+                               << IXGBE_ADVTXD_L4LEN_SHIFT;
                        tx_offload_mask.l2_len |= ~0;
                        tx_offload_mask.l3_len |= ~0;
                        break;
                case PKT_TX_TCP_CKSUM:
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP |
                                IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;
-                       mss_l4len_idx |= sizeof(struct tcp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;
+                       mss_l4len_idx |= sizeof(struct rte_tcp_hdr)
+                               << IXGBE_ADVTXD_L4LEN_SHIFT;
                        tx_offload_mask.l2_len |= ~0;
                        tx_offload_mask.l3_len |= ~0;
                        break;
                case PKT_TX_SCTP_CKSUM:
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP |
                                IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;
-                       mss_l4len_idx |= sizeof(struct sctp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;
+                       mss_l4len_idx |= sizeof(struct rte_sctp_hdr)
+                               << IXGBE_ADVTXD_L4LEN_SHIFT;
                        tx_offload_mask.l2_len |= ~0;
                        tx_offload_mask.l3_len |= ~0;
                        break;
@@ -981,25 +977,31 @@ ixgbe_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                 */
 
                if (m->nb_segs > IXGBE_TX_MAX_SEG - txq->wthresh) {
-                       rte_errno = -EINVAL;
+                       rte_errno = EINVAL;
                        return i;
                }
 
                if (ol_flags & IXGBE_TX_OFFLOAD_NOTSUP_MASK) {
-                       rte_errno = -ENOTSUP;
+                       rte_errno = ENOTSUP;
+                       return i;
+               }
+
+               /* check the size of packet */
+               if (m->pkt_len < IXGBE_TX_MIN_PKT_LEN) {
+                       rte_errno = EINVAL;
                        return i;
                }
 
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
                ret = rte_validate_tx_offload(m);
                if (ret != 0) {
-                       rte_errno = ret;
+                       rte_errno = -ret;
                        return i;
                }
 #endif
                ret = rte_net_intel_cksum_prepare(m);
                if (ret != 0) {
-                       rte_errno = ret;
+                       rte_errno = -ret;
                        return i;
                }
        }
@@ -2025,7 +2027,7 @@ ixgbe_recv_pkts_lro(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts,
                bool eop;
                struct ixgbe_rx_entry *rxe;
                struct ixgbe_scattered_rx_entry *sc_entry;
-               struct ixgbe_scattered_rx_entry *next_sc_entry;
+               struct ixgbe_scattered_rx_entry *next_sc_entry = NULL;
                struct ixgbe_rx_entry *next_rxe = NULL;
                struct rte_mbuf *first_seg;
                struct rte_mbuf *rxm;
@@ -2303,6 +2305,116 @@ ixgbe_tx_queue_release_mbufs(struct ixgbe_tx_queue *txq)
        }
 }
 
+static int
+ixgbe_tx_done_cleanup_full(struct ixgbe_tx_queue *txq, uint32_t free_cnt)
+{
+       struct ixgbe_tx_entry *swr_ring = txq->sw_ring;
+       uint16_t i, tx_last, tx_id;
+       uint16_t nb_tx_free_last;
+       uint16_t nb_tx_to_clean;
+       uint32_t pkt_cnt;
+
+       /* Start free mbuf from the next of tx_tail */
+       tx_last = txq->tx_tail;
+       tx_id  = swr_ring[tx_last].next_id;
+
+       if (txq->nb_tx_free == 0 && ixgbe_xmit_cleanup(txq))
+               return 0;
+
+       nb_tx_to_clean = txq->nb_tx_free;
+       nb_tx_free_last = txq->nb_tx_free;
+       if (!free_cnt)
+               free_cnt = txq->nb_tx_desc;
+
+       /* Loop through swr_ring to count the amount of
+        * freeable mubfs and packets.
+        */
+       for (pkt_cnt = 0; pkt_cnt < free_cnt; ) {
+               for (i = 0; i < nb_tx_to_clean &&
+                       pkt_cnt < free_cnt &&
+                       tx_id != tx_last; i++) {
+                       if (swr_ring[tx_id].mbuf != NULL) {
+                               rte_pktmbuf_free_seg(swr_ring[tx_id].mbuf);
+                               swr_ring[tx_id].mbuf = NULL;
+
+                               /*
+                                * last segment in the packet,
+                                * increment packet count
+                                */
+                               pkt_cnt += (swr_ring[tx_id].last_id == tx_id);
+                       }
+
+                       tx_id = swr_ring[tx_id].next_id;
+               }
+
+               if (txq->tx_rs_thresh > txq->nb_tx_desc -
+                       txq->nb_tx_free || tx_id == tx_last)
+                       break;
+
+               if (pkt_cnt < free_cnt) {
+                       if (ixgbe_xmit_cleanup(txq))
+                               break;
+
+                       nb_tx_to_clean = txq->nb_tx_free - nb_tx_free_last;
+                       nb_tx_free_last = txq->nb_tx_free;
+               }
+       }
+
+       return (int)pkt_cnt;
+}
+
+static int
+ixgbe_tx_done_cleanup_simple(struct ixgbe_tx_queue *txq,
+                       uint32_t free_cnt)
+{
+       int i, n, cnt;
+
+       if (free_cnt == 0 || free_cnt > txq->nb_tx_desc)
+               free_cnt = txq->nb_tx_desc;
+
+       cnt = free_cnt - free_cnt % txq->tx_rs_thresh;
+
+       for (i = 0; i < cnt; i += n) {
+               if (txq->nb_tx_desc - txq->nb_tx_free < txq->tx_rs_thresh)
+                       break;
+
+               n = ixgbe_tx_free_bufs(txq);
+
+               if (n == 0)
+                       break;
+       }
+
+       return i;
+}
+
+static int
+ixgbe_tx_done_cleanup_vec(struct ixgbe_tx_queue *txq __rte_unused,
+                       uint32_t free_cnt __rte_unused)
+{
+       return -ENOTSUP;
+}
+
+int
+ixgbe_dev_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
+{
+       struct ixgbe_tx_queue *txq = (struct ixgbe_tx_queue *)tx_queue;
+       if (txq->offloads == 0 &&
+#ifdef RTE_LIBRTE_SECURITY
+                       !(txq->using_ipsec) &&
+#endif
+                       txq->tx_rs_thresh >= RTE_PMD_IXGBE_TX_MAX_BURST) {
+               if (txq->tx_rs_thresh <= RTE_IXGBE_TX_MAX_FREE_BUF_SZ &&
+                               (rte_eal_process_type() != RTE_PROC_PRIMARY ||
+                                       txq->sw_ring_v != NULL)) {
+                       return ixgbe_tx_done_cleanup_vec(txq, free_cnt);
+               } else {
+                       return ixgbe_tx_done_cleanup_simple(txq, free_cnt);
+               }
+       }
+
+       return ixgbe_tx_done_cleanup_full(txq, free_cnt);
+}
+
 static void __attribute__((cold))
 ixgbe_tx_free_swring(struct ixgbe_tx_queue *txq)
 {
@@ -2389,14 +2501,12 @@ ixgbe_set_tx_function(struct rte_eth_dev *dev, struct ixgbe_tx_queue *txq)
                        (txq->tx_rs_thresh >= RTE_PMD_IXGBE_TX_MAX_BURST)) {
                PMD_INIT_LOG(DEBUG, "Using simple tx code path");
                dev->tx_pkt_prepare = NULL;
-#ifdef RTE_IXGBE_INC_VECTOR
                if (txq->tx_rs_thresh <= RTE_IXGBE_TX_MAX_FREE_BUF_SZ &&
                                (rte_eal_process_type() != RTE_PROC_PRIMARY ||
                                        ixgbe_txq_vec_setup(txq) == 0)) {
                        PMD_INIT_LOG(DEBUG, "Vector tx enabled.");
                        dev->tx_pkt_burst = ixgbe_xmit_pkts_vec;
                } else
-#endif
                dev->tx_pkt_burst = ixgbe_xmit_pkts_simple;
        } else {
                PMD_INIT_LOG(DEBUG, "Using full-featured tx code path");
@@ -2684,13 +2794,11 @@ ixgbe_rx_queue_release_mbufs(struct ixgbe_rx_queue *rxq)
 {
        unsigned i;
 
-#ifdef RTE_IXGBE_INC_VECTOR
        /* SSE Vector driver has a different way of releasing mbufs. */
        if (rxq->rx_using_sse) {
                ixgbe_rx_queue_release_mbufs_vec(rxq);
                return;
        }
-#endif
 
        if (rxq->sw_ring != NULL) {
                for (i = 0; i < rxq->nb_rx_desc; i++) {
@@ -2822,7 +2930,7 @@ ixgbe_reset_rx_queue(struct ixgbe_adapter *adapter, struct ixgbe_rx_queue *rxq)
        rxq->pkt_first_seg = NULL;
        rxq->pkt_last_seg = NULL;
 
-#ifdef RTE_IXGBE_INC_VECTOR
+#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
        rxq->rxrearm_start = 0;
        rxq->rxrearm_nb = 0;
 #endif
@@ -2869,7 +2977,8 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
                   DEV_RX_OFFLOAD_KEEP_CRC    |
                   DEV_RX_OFFLOAD_JUMBO_FRAME |
                   DEV_RX_OFFLOAD_VLAN_FILTER |
-                  DEV_RX_OFFLOAD_SCATTER;
+                  DEV_RX_OFFLOAD_SCATTER |
+                  DEV_RX_OFFLOAD_RSS_HASH;
 
        if (hw->mac.type == ixgbe_mac_82598EB)
                offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
@@ -2916,8 +3025,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
        struct ixgbe_rx_queue *rxq;
        struct ixgbe_hw     *hw;
        uint16_t len;
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        uint64_t offloads;
 
        PMD_INIT_FUNC_TRACE();
@@ -3136,7 +3244,7 @@ ixgbe_dev_rx_descriptor_status(void *rx_queue, uint16_t offset)
        if (unlikely(offset >= rxq->nb_rx_desc))
                return -EINVAL;
 
-#ifdef RTE_IXGBE_INC_VECTOR
+#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
        if (rxq->rx_using_sse)
                nb_hold = rxq->rxrearm_nb;
        else
@@ -3218,8 +3326,7 @@ void __attribute__((cold))
 ixgbe_dev_clear_queues(struct rte_eth_dev *dev)
 {
        unsigned i;
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        PMD_INIT_FUNC_TRACE();
@@ -3482,7 +3589,7 @@ ixgbe_rss_configure(struct rte_eth_dev *dev)
        uint32_t reta_reg;
 
        PMD_INIT_FUNC_TRACE();
-       adapter = (struct ixgbe_adapter *)dev->data->dev_private;
+       adapter = dev->data->dev_private;
        hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        sp_reta_size = ixgbe_reta_size_get(hw->mac.type);
@@ -4627,8 +4734,7 @@ void __attribute__((cold))
 ixgbe_set_rx_function(struct rte_eth_dev *dev)
 {
        uint16_t i, rx_using_sse;
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
 
        /*
         * In order to allow Vector Rx there are a few configuration
@@ -4637,8 +4743,7 @@ ixgbe_set_rx_function(struct rte_eth_dev *dev)
        if (ixgbe_rx_vec_dev_conf_condition_check(dev) ||
            !adapter->rx_bulk_alloc_allowed) {
                PMD_INIT_LOG(DEBUG, "Port[%d] doesn't meet Vector Rx "
-                                   "preconditions or RTE_IXGBE_INC_VECTOR is "
-                                   "not enabled",
+                                   "preconditions",
                             dev->data->port_id);
 
                adapter->rx_vec_allowed = false;
@@ -5306,8 +5411,7 @@ int __attribute__((cold))
 ixgbe_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
 {
        struct ixgbe_hw     *hw;
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        struct ixgbe_rx_queue *rxq;
        uint32_t rxdctl;
        int poll_ms;
@@ -5809,14 +5913,15 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
        return 0;
 }
 
-/* Stubs needed for linkage when CONFIG_RTE_IXGBE_INC_VECTOR is set to 'n' */
-__rte_weak int
+/* Stubs needed for linkage when CONFIG_RTE_ARCH_PPC_64 is set */
+#if defined(RTE_ARCH_PPC_64)
+int
 ixgbe_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
 {
        return -1;
 }
 
-__rte_weak uint16_t
+uint16_t
 ixgbe_recv_pkts_vec(
        void __rte_unused *rx_queue,
        struct rte_mbuf __rte_unused **rx_pkts,
@@ -5825,7 +5930,7 @@ ixgbe_recv_pkts_vec(
        return 0;
 }
 
-__rte_weak uint16_t
+uint16_t
 ixgbe_recv_scattered_pkts_vec(
        void __rte_unused *rx_queue,
        struct rte_mbuf __rte_unused **rx_pkts,
@@ -5834,8 +5939,29 @@ ixgbe_recv_scattered_pkts_vec(
        return 0;
 }
 
-__rte_weak int
+int
 ixgbe_rxq_vec_setup(struct ixgbe_rx_queue __rte_unused *rxq)
 {
        return -1;
 }
+
+uint16_t
+ixgbe_xmit_fixed_burst_vec(void __rte_unused *tx_queue,
+               struct rte_mbuf __rte_unused **tx_pkts,
+               uint16_t __rte_unused nb_pkts)
+{
+       return 0;
+}
+
+int
+ixgbe_txq_vec_setup(struct ixgbe_tx_queue __rte_unused *txq)
+{
+       return -1;
+}
+
+void
+ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue __rte_unused *rxq)
+{
+       return;
+}
+#endif