net/sfc: handle received packet type info from HW
[dpdk.git] / drivers / net / sfc / sfc_rx.c
index 5587620..be8fa23 100644 (file)
@@ -130,6 +130,57 @@ 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;
+}
+
+static uint32_t
+sfc_rx_desc_flags_to_packet_type(const unsigned int desc_flags)
+{
+       return RTE_PTYPE_L2_ETHER |
+               ((desc_flags & EFX_PKT_IPV4) ?
+                       RTE_PTYPE_L3_IPV4_EXT_UNKNOWN : 0) |
+               ((desc_flags & EFX_PKT_IPV6) ?
+                       RTE_PTYPE_L3_IPV6_EXT_UNKNOWN : 0) |
+               ((desc_flags & EFX_PKT_TCP) ? RTE_PTYPE_L4_TCP : 0) |
+               ((desc_flags & EFX_PKT_UDP) ? RTE_PTYPE_L4_UDP : 0);
+}
+
 uint16_t
 sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -137,6 +188,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
        unsigned int completed;
        unsigned int prefix_size = rxq->prefix_size;
        unsigned int done_pkts = 0;
+       boolean_t discard_next = B_FALSE;
 
        if (unlikely((rxq->state & SFC_RXQ_RUNNING) == 0))
                return 0;
@@ -156,9 +208,15 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                m = rxd->mbuf;
                desc_flags = rxd->flags;
 
+               if (discard_next)
+                       goto discard;
+
                if (desc_flags & (EFX_ADDR_MISMATCH | EFX_DISCARD))
                        goto discard;
 
+               if (desc_flags & EFX_PKT_CONT)
+                       goto discard;
+
                if (desc_flags & EFX_PKT_PREFIX_LEN) {
                        uint16_t tmp_size;
                        int rc __rte_unused;
@@ -175,13 +233,15 @@ 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->packet_type = RTE_PTYPE_L2_ETHER;
+               m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
+               m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
 
                *rx_pkts++ = m;
                done_pkts++;
                continue;
 
 discard:
+               discard_next = ((desc_flags & EFX_PKT_CONT) != 0);
                rte_mempool_put(rxq->refill_mb_pool, m);
                rxd->mbuf = NULL;
        }