diff --git a/sys/dev/ena/ena_datapath.c b/sys/dev/ena/ena_datapath.c index 0e6a6fe8203..3026671b6a1 100644 --- a/sys/dev/ena/ena_datapath.c +++ b/sys/dev/ena/ena_datapath.c @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include #endif /* RSS */ +#include + /********************************************************************* * Static functions prototypes *********************************************************************/ @@ -712,6 +714,7 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct mbuf *mbuf, uint16_t etype; int ehdrlen; struct ip *ip; + int ipproto; int iphlen; struct tcphdr *th; int offset; @@ -729,6 +732,9 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct mbuf *mbuf, if ((mbuf->m_pkthdr.csum_flags & CSUM_OFFLOAD) != 0) offload = true; + if ((mbuf->m_pkthdr.csum_flags & CSUM6_OFFLOAD) != 0) + offload = true; + if (!offload) { if (disable_meta_caching) { memset(ena_meta, 0, sizeof(*ena_meta)); @@ -750,8 +756,27 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct mbuf *mbuf, } mbuf_next = m_getptr(mbuf, ehdrlen, &offset); - ip = (struct ip *)(mtodo(mbuf_next, offset)); - iphlen = ip->ip_hl << 2; + + switch (etype) { + case ETHERTYPE_IP: + ip = (struct ip *)(mtodo(mbuf_next, offset)); + iphlen = ip->ip_hl << 2; + ipproto = ip->ip_p; + ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV4; + if ((ip->ip_off & htons(IP_DF)) != 0) + ena_tx_ctx->df = 1; + break; + case ETHERTYPE_IPV6: + ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV6; + iphlen = ip6_lasthdr(mbuf, ehdrlen, IPPROTO_IPV6, &ipproto); + iphlen -= ehdrlen; + ena_tx_ctx->df = 1; + break; + default: + iphlen = 0; + ipproto = 0; + break; + } mbuf_next = m_getptr(mbuf, iphlen + ehdrlen, &offset); th = (struct tcphdr *)(mtodo(mbuf_next, offset)); @@ -764,27 +789,14 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct mbuf *mbuf, ena_meta->l4_hdr_len = (th->th_off); } - switch (etype) { - case ETHERTYPE_IP: - ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV4; - if ((ip->ip_off & htons(IP_DF)) != 0) - ena_tx_ctx->df = 1; - break; - case ETHERTYPE_IPV6: - ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV6; - - default: - break; - } - - if (ip->ip_p == IPPROTO_TCP) { + if (ipproto == IPPROTO_TCP) { ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_TCP; if ((mbuf->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP)) != 0) ena_tx_ctx->l4_csum_enable = 1; else ena_tx_ctx->l4_csum_enable = 0; - } else if (ip->ip_p == IPPROTO_UDP) { + } else if (ipproto == IPPROTO_UDP) { ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_UDP; if ((mbuf->m_pkthdr.csum_flags & (CSUM_IP_UDP | CSUM_IP6_UDP)) != 0) diff --git a/sys/dev/ena/ena_datapath.h b/sys/dev/ena/ena_datapath.h index 8da6a2a0edc..f3b721359c7 100644 --- a/sys/dev/ena/ena_datapath.h +++ b/sys/dev/ena/ena_datapath.h @@ -40,5 +40,6 @@ int ena_mq_start(if_t ifp, struct mbuf *m); void ena_deferred_mq_start(void *arg, int pending); #define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP) +#define CSUM6_OFFLOAD (CSUM_IP6_UDP|CSUM_IP6_TCP) #endif /* ENA_TXRX_H */