net/vmxnet3: complete Rx offloads support
authorDidier Pallard <didier.pallard@6wind.com>
Wed, 28 Mar 2018 15:43:46 +0000 (17:43 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 27 Apr 2018 16:34:41 +0000 (17:34 +0100)
Add support for IPv6, LRO and properly set packet type in all
supported cases.

Signed-off-by: Didier Pallard <didier.pallard@6wind.com>
Acked-by: Yong Wang <yongwang@vmware.com>
drivers/net/vmxnet3/base/vmxnet3_defs.h
drivers/net/vmxnet3/vmxnet3_rxtx.c

index a30b8f2..bbec708 100644 (file)
@@ -324,7 +324,32 @@ struct Vmxnet3_RxCompDescExt {
    uint8  segCnt;       /* Number of aggregated packets */
    uint8  dupAckCnt;    /* Number of duplicate Acks */
    __le16 tsDelta;      /* TCP timestamp difference */
-   __le32 dword2[2];
+       __le32 dword2;
+#ifdef __BIG_ENDIAN_BITFIELD
+       uint32 gen : 1;     /* generation bit */
+       uint32 type : 7;    /* completion type */
+       uint32 fcs : 1;     /* Frame CRC correct */
+       uint32 frg : 1;     /* IP Fragment */
+       uint32 v4 : 1;      /* IPv4 */
+       uint32 v6 : 1;      /* IPv6 */
+       uint32 ipc : 1;     /* IP Checksum Correct */
+       uint32 tcp : 1;     /* TCP packet */
+       uint32 udp : 1;     /* UDP packet */
+       uint32 tuc : 1;     /* TCP/UDP Checksum Correct */
+       uint32 mss : 16;
+#else
+       uint32 mss : 16;
+       uint32 tuc : 1;     /* TCP/UDP Checksum Correct */
+       uint32 udp : 1;     /* UDP packet */
+       uint32 tcp : 1;     /* TCP packet */
+       uint32 ipc : 1;     /* IP Checksum Correct */
+       uint32 v6 : 1;      /* IPv6 */
+       uint32 v4 : 1;      /* IPv4 */
+       uint32 frg : 1;     /* IP Fragment */
+       uint32 fcs : 1;     /* Frame CRC correct */
+       uint32 type : 7;    /* completion type */
+       uint32 gen : 1;     /* generation bit */
+#endif  /* __BIG_ENDIAN_BITFIELD */
 }
 #include "vmware_pack_end.h"
 Vmxnet3_RxCompDescExt;
index c0dad2d..5693c51 100644 (file)
@@ -652,38 +652,89 @@ static inline void
 vmxnet3_rx_offload(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
                struct rte_mbuf *rxm, const uint8_t sop)
 {
-       (void)hw;
+       uint64_t ol_flags = rxm->ol_flags;
+       uint32_t packet_type = rxm->packet_type;
 
        /* Offloads set in sop */
        if (sop) {
+               /* Set packet type */
+               packet_type |= RTE_PTYPE_L2_ETHER;
+
+               /* Check large packet receive */
+               if (VMXNET3_VERSION_GE_2(hw) &&
+                   rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
+                       const Vmxnet3_RxCompDescExt *rcde =
+                                       (const Vmxnet3_RxCompDescExt *)rcd;
+
+                       rxm->tso_segsz = rcde->mss;
+                       ol_flags |= PKT_RX_LRO;
+               }
        } else { /* Offloads set in eop */
                /* Check for RSS */
                if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE) {
-                       rxm->ol_flags |= PKT_RX_RSS_HASH;
+                       ol_flags |= PKT_RX_RSS_HASH;
                        rxm->hash.rss = rcd->rssHash;
                }
 
                /* Check for hardware stripped VLAN tag */
                if (rcd->ts) {
-                       rxm->ol_flags |= (PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED);
+                       ol_flags |= (PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED);
                        rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
                }
 
-               /* Check packet type, checksum errors. Only IPv4 for now. */
-               if (rcd->v4) {
-                       rxm->packet_type = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
-
-                       if (!rcd->cnc) {
-                               if (!rcd->ipc)
-                                       rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
-
-                               if ((rcd->tcp || rcd->udp) && !rcd->tuc)
-                                       rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
-                       }
+               /* Check packet type, checksum errors, etc. */
+               if (rcd->cnc) {
+                       ol_flags |= PKT_RX_L4_CKSUM_UNKNOWN;
                } else {
-                       rxm->packet_type = RTE_PTYPE_UNKNOWN;
+                       if (rcd->v4) {
+                               packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+
+                               if (rcd->ipc)
+                                       ol_flags |= PKT_RX_IP_CKSUM_GOOD;
+                               else
+                                       ol_flags |= PKT_RX_IP_CKSUM_BAD;
+
+                               if (rcd->tuc) {
+                                       ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+                                       if (rcd->tcp)
+                                               packet_type |= RTE_PTYPE_L4_TCP;
+                                       else
+                                               packet_type |= RTE_PTYPE_L4_UDP;
+                               } else {
+                                       if (rcd->tcp) {
+                                               packet_type |= RTE_PTYPE_L4_TCP;
+                                               ol_flags |= PKT_RX_L4_CKSUM_BAD;
+                                       } else if (rcd->udp) {
+                                               packet_type |= RTE_PTYPE_L4_UDP;
+                                               ol_flags |= PKT_RX_L4_CKSUM_BAD;
+                                       }
+                               }
+                       } else if (rcd->v6) {
+                               packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+                               if (rcd->tuc) {
+                                       ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+                                       if (rcd->tcp)
+                                               packet_type |= RTE_PTYPE_L4_TCP;
+                                       else
+                                               packet_type |= RTE_PTYPE_L4_UDP;
+                               } else {
+                                       if (rcd->tcp) {
+                                               packet_type |= RTE_PTYPE_L4_TCP;
+                                               ol_flags |= PKT_RX_L4_CKSUM_BAD;
+                                       } else if (rcd->udp) {
+                                               packet_type |= RTE_PTYPE_L4_UDP;
+                                               ol_flags |= PKT_RX_L4_CKSUM_BAD;
+                                       }
+                               }
+                       } else {
+                               packet_type |= RTE_PTYPE_UNKNOWN;
+                       }
                }
        }
+
+       rxm->ol_flags = ol_flags;
+       rxm->packet_type = packet_type;
 }
 
 /*
@@ -783,6 +834,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                rxm->data_off = RTE_PKTMBUF_HEADROOM;
                rxm->ol_flags = 0;
                rxm->vlan_tci = 0;
+               rxm->packet_type = 0;
 
                /*
                 * If this is the first buffer of the received packet,