net/enetc: enable Rx checksum offload validation
[dpdk.git] / drivers / net / enetc / enetc_rxtx.c
index 631e243..0ce7dbe 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018 NXP
+ * Copyright 2018-2019 NXP
  */
 
 #include <stdbool.h>
@@ -64,7 +64,7 @@ enetc_xmit_pkts(void *tx_queue,
                txbd->buf_len = txbd->frm_len;
                txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
                txbd->addr = (uint64_t)(uintptr_t)
-               rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_addr +
+               rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_iova +
                                 tx_swbd->buffer_addr->data_off);
                i++;
                start++;
@@ -88,10 +88,11 @@ enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
        rx_swbd = &rx_ring->q_swbd[i];
        rxbd = ENETC_RXBD(*rx_ring, i);
        for (j = 0; j < buff_cnt; j++) {
-               rx_swbd->buffer_addr =
-                       rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+               rx_swbd->buffer_addr = (void *)(uintptr_t)
+                       rte_cpu_to_le_64((uint64_t)(uintptr_t)
+                                       rte_pktmbuf_alloc(rx_ring->mb_pool));
                rxbd->w.addr = (uint64_t)(uintptr_t)
-                              rx_swbd->buffer_addr->buf_addr +
+                              rx_swbd->buffer_addr->buf_iova +
                               rx_swbd->buffer_addr->data_off;
                /* clear 'R" as well */
                rxbd->r.lstatus = 0;
@@ -114,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
@@ -207,8 +289,10 @@ enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
                if (!bd_status)
                        break;
 
-               rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
-               rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+               rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len -
+                                               rx_ring->crc_len;
+               rx_swbd->buffer_addr->data_len = rxbd->r.buf_len -
+                                                rx_ring->crc_len;
                rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
                rx_swbd->buffer_addr->ol_flags = 0;
                enetc_dev_rx_parse(rx_swbd->buffer_addr,