net/sfc: support checksum offloads on receive
authorAndrew Rybchenko <arybchenko@solarflare.com>
Thu, 15 Dec 2016 12:51:04 +0000 (12:51 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:40:50 +0000 (19:40 +0100)
IPv4 header and TCP/UDP checksums for both IPv4 and IPv6 are supported.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
doc/guides/nics/features/sfc_efx.ini
doc/guides/nics/sfc_efx.rst
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_rx.c

index 35633cb..ec1d1db 100644 (file)
@@ -13,8 +13,8 @@ Promiscuous mode     = Y
 Allmulticast mode    = Y
 Multicast MAC filter = Y
 Flow control         = Y
-L3 checksum offload  = P
-L4 checksum offload  = P
+L3 checksum offload  = Y
+L4 checksum offload  = Y
 Basic stats          = Y
 Extended stats       = Y
 BSD nic_uio          = Y
index 43dd4cf..8724eae 100644 (file)
@@ -65,6 +65,8 @@ SFC EFX PMD has support for:
 
 - Multicast MAC filter
 
+- IPv4/IPv6 TCP/UDP receive checksum offload
+
 
 Non-supported Features
 ----------------------
index 4766ae9..4e49180 100644 (file)
@@ -67,6 +67,11 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        /* By default packets are dropped if no descriptors are available */
        dev_info->default_rxconf.rx_drop_en = 1;
 
+       dev_info->rx_offload_capa =
+               DEV_RX_OFFLOAD_IPV4_CKSUM |
+               DEV_RX_OFFLOAD_UDP_CKSUM |
+               DEV_RX_OFFLOAD_TCP_CKSUM;
+
        dev_info->tx_offload_capa =
                DEV_TX_OFFLOAD_IPV4_CKSUM |
                DEV_TX_OFFLOAD_UDP_CKSUM |
index bd41131..4df4132 100644 (file)
@@ -130,6 +130,45 @@ sfc_rx_qrefill(struct sfc_rxq *rxq)
        }
 }
 
+static uint64_t
+sfc_rx_desc_flags_to_offload_flags(const unsigned int desc_flags)
+{
+       uint64_t mbuf_flags = 0;
+
+       switch (desc_flags & (EFX_PKT_IPV4 | EFX_CKSUM_IPV4)) {
+       case (EFX_PKT_IPV4 | EFX_CKSUM_IPV4):
+               mbuf_flags |= PKT_RX_IP_CKSUM_GOOD;
+               break;
+       case EFX_PKT_IPV4:
+               mbuf_flags |= PKT_RX_IP_CKSUM_BAD;
+               break;
+       default:
+               RTE_BUILD_BUG_ON(PKT_RX_IP_CKSUM_UNKNOWN != 0);
+               SFC_ASSERT((mbuf_flags & PKT_RX_IP_CKSUM_MASK) ==
+                          PKT_RX_IP_CKSUM_UNKNOWN);
+               break;
+       }
+
+       switch ((desc_flags &
+                (EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP))) {
+       case (EFX_PKT_TCP | EFX_CKSUM_TCPUDP):
+       case (EFX_PKT_UDP | EFX_CKSUM_TCPUDP):
+               mbuf_flags |= PKT_RX_L4_CKSUM_GOOD;
+               break;
+       case EFX_PKT_TCP:
+       case EFX_PKT_UDP:
+               mbuf_flags |= PKT_RX_L4_CKSUM_BAD;
+               break;
+       default:
+               RTE_BUILD_BUG_ON(PKT_RX_L4_CKSUM_UNKNOWN != 0);
+               SFC_ASSERT((mbuf_flags & PKT_RX_L4_CKSUM_MASK) ==
+                          PKT_RX_L4_CKSUM_UNKNOWN);
+               break;
+       }
+
+       return mbuf_flags;
+}
+
 uint16_t
 sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -182,6 +221,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                rte_pktmbuf_data_len(m) = seg_len;
                rte_pktmbuf_pkt_len(m) = seg_len;
 
+               m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
                m->packet_type = RTE_PTYPE_L2_ETHER;
 
                *rx_pkts++ = m;