i40e: fix VLAN stripping from inner header
[dpdk.git] / drivers / net / i40e / i40e_rxtx.c
index 81cde6c..a69fde1 100644 (file)
@@ -76,6 +76,7 @@
 #define I40E_TX_CKSUM_OFFLOAD_MASK (            \
                PKT_TX_IP_CKSUM |                \
                PKT_TX_L4_MASK |                 \
+               PKT_TX_TCP_SEG |                 \
                PKT_TX_OUTER_IP_CKSUM)
 
 static uint16_t i40e_xmit_pkts_simple(void *tx_queue,
@@ -188,7 +189,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_supported_ptypes_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -1175,6 +1179,14 @@ i40e_recv_pkts_bulk_alloc(void *rx_queue,
 
        return nb_rx;
 }
+#else
+static uint16_t
+i40e_recv_pkts_bulk_alloc(void __rte_unused *rx_queue,
+                         struct rte_mbuf __rte_unused **rx_pkts,
+                         uint16_t __rte_unused nb_pkts)
+{
+       return 0;
+}
 #endif /* RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC */
 
 uint16_t
@@ -2087,6 +2099,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
        return 0;
 }
 
+const uint32_t *
+i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+       static const uint32_t ptypes[] = {
+               /* refers to i40e_rxd_pkt_type_mapping() */
+               RTE_PTYPE_L2_ETHER,
+               RTE_PTYPE_L2_ETHER_TIMESYNC,
+               RTE_PTYPE_L2_ETHER_LLDP,
+               RTE_PTYPE_L2_ETHER_ARP,
+               RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+               RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+               RTE_PTYPE_L4_FRAG,
+               RTE_PTYPE_L4_ICMP,
+               RTE_PTYPE_L4_NONFRAG,
+               RTE_PTYPE_L4_SCTP,
+               RTE_PTYPE_L4_TCP,
+               RTE_PTYPE_L4_UDP,
+               RTE_PTYPE_TUNNEL_GRENAT,
+               RTE_PTYPE_TUNNEL_IP,
+               RTE_PTYPE_INNER_L2_ETHER,
+               RTE_PTYPE_INNER_L2_ETHER_VLAN,
+               RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+               RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+               RTE_PTYPE_INNER_L4_FRAG,
+               RTE_PTYPE_INNER_L4_ICMP,
+               RTE_PTYPE_INNER_L4_NONFRAG,
+               RTE_PTYPE_INNER_L4_SCTP,
+               RTE_PTYPE_INNER_L4_TCP,
+               RTE_PTYPE_INNER_L4_UDP,
+               RTE_PTYPE_UNKNOWN
+       };
+
+       if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+           dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+           dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+               return ptypes;
+       return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
                        uint16_t queue_idx,
@@ -2851,7 +2904,12 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
        rx_ctx.lrxqthresh = 2;
        rx_ctx.crcstrip = (rxq->crc_len == 0) ? 1 : 0;
        rx_ctx.l2tsel = 1;
-       rx_ctx.showiv = 1;
+       /* showiv indicates if inner VLAN is stripped inside of tunnel
+        * packet. When set it to 1, vlan information is stripped from
+        * the inner header, but the hardware does not put it in the
+        * descriptor. So set it zero by default.
+        */
+       rx_ctx.showiv = 0;
        rx_ctx.prefena = 1;
 
        err = i40e_clear_lan_rx_queue_context(hw, pf_q);