net/iavf: fix VLAN insertion
[dpdk.git] / drivers / net / i40e / i40e_rxtx_vec_common.h
index 3ffedcb..f9a7f46 100644 (file)
@@ -5,12 +5,16 @@
 #ifndef _I40E_RXTX_VEC_COMMON_H_
 #define _I40E_RXTX_VEC_COMMON_H_
 #include <stdint.h>
-#include <rte_ethdev_driver.h>
+#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "i40e_ethdev.h"
 #include "i40e_rxtx.h"
 
+#ifndef __INTEL_COMPILER
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+
 static inline uint16_t
 reassemble_packets(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_bufs,
                   uint16_t nb_bufs, uint8_t *split_flags)
@@ -33,6 +37,7 @@ reassemble_packets(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_bufs,
                        if (!split_flags[buf_idx]) {
                                /* it's the last packet of the set */
                                start->hash = end->hash;
+                               start->vlan_tci = end->vlan_tci;
                                start->ol_flags = end->ol_flags;
                                /* we need to strip crc for the whole packet */
                                start->pkt_len -= rxq->crc_len;
@@ -94,6 +99,16 @@ i40e_tx_free_bufs(struct i40e_tx_queue *txq)
          * tx_next_dd - (tx_rs_thresh-1)
          */
        txep = &txq->sw_ring[txq->tx_next_dd - (n - 1)];
+
+       if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
+               for (i = 0; i < n; i++) {
+                       free[i] = txep[i].mbuf;
+                       txep[i].mbuf = NULL;
+               }
+               rte_mempool_put_bulk(free[0]->pool, (void **)free, n);
+               goto done;
+       }
+
        m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
        if (likely(m != NULL)) {
                free[0] = m;
@@ -121,6 +136,7 @@ i40e_tx_free_bufs(struct i40e_tx_queue *txq)
                }
        }
 
+done:
        /* buffers were freed, update counters */
        txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh);
        txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh);
@@ -192,27 +208,64 @@ static inline int
 i40e_rx_vec_dev_conf_condition_check_default(struct rte_eth_dev *dev)
 {
 #ifndef RTE_LIBRTE_IEEE1588
+       struct i40e_adapter *ad =
+               I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
-       struct rte_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf;
+       struct rte_eth_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf;
+       struct i40e_rx_queue *rxq;
+       uint16_t desc, i;
+       bool first_queue;
 
        /* no fdir support */
        if (fconf->mode != RTE_FDIR_MODE_NONE)
                return -1;
 
-        /* - no csum error report support
-        * - no header split support
-        */
-       if (rxmode->header_split == 1)
+        /* no header split support */
+       if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_HEADER_SPLIT)
                return -1;
 
        /* no QinQ support */
-       if (rxmode->hw_vlan_extend == 1)
+       if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
                return -1;
 
+       /**
+        * Vector mode is allowed only when number of Rx queue
+        * descriptor is power of 2.
+        */
+       if (!dev->data->dev_started) {
+               first_queue = true;
+               for (i = 0; i < dev->data->nb_rx_queues; i++) {
+                       rxq = dev->data->rx_queues[i];
+                       if (!rxq)
+                               continue;
+                       desc = rxq->nb_rx_desc;
+                       if (first_queue)
+                               ad->rx_vec_allowed =
+                                       rte_is_power_of_2(desc);
+                       else
+                               ad->rx_vec_allowed =
+                                       ad->rx_vec_allowed ?
+                                       rte_is_power_of_2(desc) :
+                                       ad->rx_vec_allowed;
+                       first_queue = false;
+               }
+       } else {
+               /* Only check the first queue's descriptor number */
+               for (i = 0; i < dev->data->nb_rx_queues; i++) {
+                       rxq = dev->data->rx_queues[i];
+                       if (!rxq)
+                               continue;
+                       desc = rxq->nb_rx_desc;
+                       ad->rx_vec_allowed = rte_is_power_of_2(desc);
+                       break;
+               }
+       }
+
        return 0;
 #else
        RTE_SET_USED(dev);
        return -1;
 #endif
 }
+
 #endif