net/enetc: enable Rx checksum offload validation
authorGagandeep Singh <g.singh@nxp.com>
Fri, 12 Apr 2019 12:29:10 +0000 (12:29 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 19 Apr 2019 12:51:54 +0000 (14:51 +0200)
Checksum Validation on Rx is supported.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
doc/guides/nics/features/enetc.ini
doc/guides/rel_notes/release_19_05.rst
drivers/net/enetc/base/enetc_hw.h
drivers/net/enetc/enetc_ethdev.c
drivers/net/enetc/enetc_rxtx.c

index 101dc0a..39a5201 100644 (file)
@@ -13,6 +13,8 @@ MTU update           = Y
 Jumbo frame          = Y
 Queue start/stop     = Y
 CRC offload          = Y
+L3 checksum offload  = P
+L4 checksum offload  = P
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
index 3312a87..25cd61c 100644 (file)
@@ -154,6 +154,7 @@ New Features
   * Added jumbo frame support
   * Added queue start/stop
   * Added CRC offload support
+  * Added Rx checksum offload validation support
 
 * **Updated the QuickAssist Technology PMD.**
 
index 261ad15..ff2bda5 100644 (file)
@@ -99,6 +99,10 @@ enum enetc_bdr_type {TX, RX};
 #define ENETC_PM0_RX_EN                        BIT(1)
 #define ENETC_PM0_CRC                  BIT(6)
 
+#define ENETC_PAR_PORT_CFG             0x03050
+#define L3_CKSUM                       BIT(0)
+#define L4_CKSUM                       BIT(1)
+
 #define ENETC_PM0_MAXFRM               0x08014
 #define ENETC_SET_TX_MTU(val)          ((val) << 16)
 #define ENETC_SET_MAXFRM(val)          ((val) & 0xffff)
@@ -182,6 +186,7 @@ enum enetc_bdr_type {TX, RX};
 #define ENETC_TXBD_FLAGS_F             BIT(15)
 
 /* ENETC Parsed values (Little Endian) */
+#define ENETC_PARSE_ERROR              0x8000
 #define ENETC_PKT_TYPE_ETHER            0x0060
 #define ENETC_PKT_TYPE_IPV4             0x0000
 #define ENETC_PKT_TYPE_IPV6             0x0020
index ffae8ae..362e074 100644 (file)
@@ -163,7 +163,10 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
        dev_info->max_tx_queues = MAX_TX_RINGS;
        dev_info->max_rx_pktlen = ENETC_MAC_MAXFRM_SIZE;
        dev_info->rx_offload_capa =
-               (DEV_RX_OFFLOAD_KEEP_CRC |
+               (DEV_RX_OFFLOAD_IPV4_CKSUM |
+                DEV_RX_OFFLOAD_UDP_CKSUM |
+                DEV_RX_OFFLOAD_TCP_CKSUM |
+                DEV_RX_OFFLOAD_KEEP_CRC |
                 DEV_RX_OFFLOAD_JUMBO_FRAME);
 }
 
@@ -636,6 +639,7 @@ enetc_dev_configure(struct rte_eth_dev *dev)
        struct enetc_hw *enetc_hw = &hw->hw;
        struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
        uint64_t rx_offloads = eth_conf->rxmode.offloads;
+       uint32_t checksum = L3_CKSUM | L4_CKSUM;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -661,6 +665,15 @@ enetc_dev_configure(struct rte_eth_dev *dev)
                enetc_port_wr(enetc_hw, ENETC_PM0_CMD_CFG, config);
        }
 
+       if (rx_offloads & DEV_RX_OFFLOAD_IPV4_CKSUM)
+               checksum &= ~L3_CKSUM;
+
+       if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM))
+               checksum &= ~L4_CKSUM;
+
+       enetc_port_wr(enetc_hw, ENETC_PAR_PORT_CFG, checksum);
+
+
        return 0;
 }
 
index 4a758d2..0ce7dbe 100644 (file)
@@ -115,69 +115,150 @@ enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
        return j;
 }
 
+static inline void enetc_slow_parsing(struct rte_mbuf *m,
+                                    uint64_t parse_results)
+{
+       m->ol_flags &= ~(PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD);
+
+       switch (parse_results) {
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV4;
+               m->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV6;
+               m->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_TCP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV4 |
+                                RTE_PTYPE_L4_TCP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_TCP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV6 |
+                                RTE_PTYPE_L4_TCP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_UDP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV4 |
+                                RTE_PTYPE_L4_UDP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_UDP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV6 |
+                                RTE_PTYPE_L4_UDP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_SCTP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV4 |
+                                RTE_PTYPE_L4_SCTP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_SCTP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV6 |
+                                RTE_PTYPE_L4_SCTP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_ICMP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV4 |
+                                RTE_PTYPE_L4_ICMP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_ICMP:
+               m->packet_type = RTE_PTYPE_L2_ETHER |
+                                RTE_PTYPE_L3_IPV6 |
+                                RTE_PTYPE_L4_ICMP;
+               m->ol_flags |= PKT_RX_IP_CKSUM_GOOD |
+                              PKT_RX_L4_CKSUM_BAD;
+               return;
+       /* More switch cases can be added */
+       default:
+               m->packet_type = RTE_PTYPE_UNKNOWN;
+               m->ol_flags |= PKT_RX_IP_CKSUM_UNKNOWN |
+                              PKT_RX_L4_CKSUM_UNKNOWN;
+       }
+}
+
 
 static inline void __attribute__((hot))
 enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
 {
        ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+       m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD;
 
-       m->packet_type = RTE_PTYPE_UNKNOWN;
        switch (parse_results) {
        case ENETC_PKT_TYPE_ETHER:
                m->packet_type = RTE_PTYPE_L2_ETHER;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV4:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV4;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV6:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV6;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV4_TCP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV4 |
                                 RTE_PTYPE_L4_TCP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV6_TCP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV6 |
                                 RTE_PTYPE_L4_TCP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV4_UDP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV4 |
                                 RTE_PTYPE_L4_UDP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV6_UDP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV6 |
                                 RTE_PTYPE_L4_UDP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV4_SCTP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV4 |
                                 RTE_PTYPE_L4_SCTP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV6_SCTP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV6 |
                                 RTE_PTYPE_L4_SCTP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV4_ICMP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV4 |
                                 RTE_PTYPE_L4_ICMP;
-               break;
+               return;
        case ENETC_PKT_TYPE_IPV6_ICMP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
                                 RTE_PTYPE_L3_IPV6 |
                                 RTE_PTYPE_L4_ICMP;
-               break;
+               return;
        /* More switch cases can be added */
        default:
-               m->packet_type = RTE_PTYPE_UNKNOWN;
+               enetc_slow_parsing(m, parse_results);
        }
+
 }
 
 static int