xref: /dpdk/drivers/net/sfc/sfc_ef10_rx_ev.h (revision 7be78d027918dbc846e502780faf94d5acdf5f75)
1c121f008SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
2c121f008SAndrew Rybchenko  *
398d26ef7SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
4a0147be5SAndrew Rybchenko  * Copyright(c) 2018-2019 Solarflare Communications Inc.
5c121f008SAndrew Rybchenko  *
6c121f008SAndrew Rybchenko  * This software was jointly developed between OKTET Labs (under contract
7c121f008SAndrew Rybchenko  * for Solarflare) and Solarflare Communications, Inc.
8c121f008SAndrew Rybchenko  */
9c121f008SAndrew Rybchenko 
10c121f008SAndrew Rybchenko #ifndef _SFC_EF10_RX_EV_H
11c121f008SAndrew Rybchenko #define _SFC_EF10_RX_EV_H
12c121f008SAndrew Rybchenko 
13c121f008SAndrew Rybchenko #include <rte_mbuf.h>
14c121f008SAndrew Rybchenko 
15c121f008SAndrew Rybchenko #include "efx_types.h"
16c121f008SAndrew Rybchenko #include "efx_regs.h"
17c121f008SAndrew Rybchenko #include "efx_regs_ef10.h"
18c121f008SAndrew Rybchenko 
191b0236e2SAndrew Rybchenko #include "sfc_debug.h"
201b0236e2SAndrew Rybchenko 
21c121f008SAndrew Rybchenko #ifdef __cplusplus
22c121f008SAndrew Rybchenko extern "C" {
23c121f008SAndrew Rybchenko #endif
24c121f008SAndrew Rybchenko 
25c121f008SAndrew Rybchenko static inline void
sfc_ef10_rx_ev_to_offloads(const efx_qword_t rx_ev,struct rte_mbuf * m,uint64_t ol_mask)26c121f008SAndrew Rybchenko sfc_ef10_rx_ev_to_offloads(const efx_qword_t rx_ev, struct rte_mbuf *m,
27c121f008SAndrew Rybchenko 			   uint64_t ol_mask)
28c121f008SAndrew Rybchenko {
29c121f008SAndrew Rybchenko 	uint32_t tun_ptype = 0;
30daa02b5cSOlivier Matz 	/* Which event bit is mapped to RTE_MBUF_F_RX_IP_CKSUM_* */
31c121f008SAndrew Rybchenko 	int8_t ip_csum_err_bit;
32daa02b5cSOlivier Matz 	/* Which event bit is mapped to RTE_MBUF_F_RX_L4_CKSUM_* */
33c121f008SAndrew Rybchenko 	int8_t l4_csum_err_bit;
34c121f008SAndrew Rybchenko 	uint32_t l2_ptype = 0;
35c121f008SAndrew Rybchenko 	uint32_t l3_ptype = 0;
36c121f008SAndrew Rybchenko 	uint32_t l4_ptype = 0;
37c121f008SAndrew Rybchenko 	uint64_t ol_flags = 0;
38c121f008SAndrew Rybchenko 
39390f9b8dSAndrew Rybchenko 	if (unlikely(rx_ev.eq_u64[0] &
40390f9b8dSAndrew Rybchenko 		rte_cpu_to_le_64((1ull << ESF_DZ_RX_ECC_ERR_LBN) |
41390f9b8dSAndrew Rybchenko 				 (1ull << ESF_DZ_RX_ECRC_ERR_LBN) |
42aeeb5571SAndrew Rybchenko 				 (1ull << ESF_DZ_RX_PARSE_INCOMPLETE_LBN)))) {
43*7be78d02SJosh Soref 		/* Zero packet type is used as a marker to discard bad packets */
44c121f008SAndrew Rybchenko 		goto done;
45aeeb5571SAndrew Rybchenko 	}
46c121f008SAndrew Rybchenko 
477ee7e57cSAndrew Rybchenko #if SFC_EF10_RX_EV_ENCAP_SUPPORT
48c121f008SAndrew Rybchenko 	switch (EFX_QWORD_FIELD(rx_ev, ESF_EZ_RX_ENCAP_HDR)) {
49c121f008SAndrew Rybchenko 	default:
50c121f008SAndrew Rybchenko 		/* Unexpected encapsulation tag class */
51c121f008SAndrew Rybchenko 		SFC_ASSERT(false);
52c121f008SAndrew Rybchenko 		/* FALLTHROUGH */
53c121f008SAndrew Rybchenko 	case ESE_EZ_ENCAP_HDR_NONE:
54c121f008SAndrew Rybchenko 		break;
55c121f008SAndrew Rybchenko 	case ESE_EZ_ENCAP_HDR_VXLAN:
56c121f008SAndrew Rybchenko 		/*
57c121f008SAndrew Rybchenko 		 * It is definitely UDP, but we have no information
58c121f008SAndrew Rybchenko 		 * about IPv4 vs IPv6 and VLAN tagging.
59c121f008SAndrew Rybchenko 		 */
60c121f008SAndrew Rybchenko 		tun_ptype = RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP;
61c121f008SAndrew Rybchenko 		break;
62c121f008SAndrew Rybchenko 	case ESE_EZ_ENCAP_HDR_GRE:
63c121f008SAndrew Rybchenko 		/*
64c121f008SAndrew Rybchenko 		 * We have no information about IPv4 vs IPv6 and VLAN tagging.
65c121f008SAndrew Rybchenko 		 */
66c121f008SAndrew Rybchenko 		tun_ptype = RTE_PTYPE_TUNNEL_NVGRE;
67c121f008SAndrew Rybchenko 		break;
68c121f008SAndrew Rybchenko 	}
697ee7e57cSAndrew Rybchenko #endif
70c121f008SAndrew Rybchenko 
71c121f008SAndrew Rybchenko 	if (tun_ptype == 0) {
72c121f008SAndrew Rybchenko 		ip_csum_err_bit = ESF_DZ_RX_IPCKSUM_ERR_LBN;
73c121f008SAndrew Rybchenko 		l4_csum_err_bit = ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN;
74c121f008SAndrew Rybchenko 	} else {
75c121f008SAndrew Rybchenko 		ip_csum_err_bit = ESF_EZ_RX_IP_INNER_CHKSUM_ERR_LBN;
76c121f008SAndrew Rybchenko 		l4_csum_err_bit = ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR_LBN;
77c121f008SAndrew Rybchenko 		if (unlikely(EFX_TEST_QWORD_BIT(rx_ev,
78c121f008SAndrew Rybchenko 						ESF_DZ_RX_IPCKSUM_ERR_LBN)))
79daa02b5cSOlivier Matz 			ol_flags |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
80c121f008SAndrew Rybchenko 	}
81c121f008SAndrew Rybchenko 
82c121f008SAndrew Rybchenko 	switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_ETH_TAG_CLASS)) {
83c121f008SAndrew Rybchenko 	case ESE_DZ_ETH_TAG_CLASS_NONE:
84c121f008SAndrew Rybchenko 		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER :
85c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L2_ETHER;
86c121f008SAndrew Rybchenko 		break;
87c121f008SAndrew Rybchenko 	case ESE_DZ_ETH_TAG_CLASS_VLAN1:
88c121f008SAndrew Rybchenko 		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER_VLAN :
89c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L2_ETHER_VLAN;
90c121f008SAndrew Rybchenko 		break;
91c121f008SAndrew Rybchenko 	case ESE_DZ_ETH_TAG_CLASS_VLAN2:
92c121f008SAndrew Rybchenko 		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER_QINQ :
93c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L2_ETHER_QINQ;
94c121f008SAndrew Rybchenko 		break;
95c121f008SAndrew Rybchenko 	default:
96c121f008SAndrew Rybchenko 		/* Unexpected Eth tag class */
97c121f008SAndrew Rybchenko 		SFC_ASSERT(false);
98c121f008SAndrew Rybchenko 	}
99c121f008SAndrew Rybchenko 
100c121f008SAndrew Rybchenko 	switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_L3_CLASS)) {
101c121f008SAndrew Rybchenko 	case ESE_DZ_L3_CLASS_IP4_FRAG:
102c121f008SAndrew Rybchenko 		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_FRAG :
103c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L4_FRAG;
104c121f008SAndrew Rybchenko 		/* FALLTHROUGH */
105c121f008SAndrew Rybchenko 	case ESE_DZ_L3_CLASS_IP4:
106c121f008SAndrew Rybchenko 		l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV4_EXT_UNKNOWN :
107c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
108daa02b5cSOlivier Matz 		ol_flags |= RTE_MBUF_F_RX_RSS_HASH |
109c121f008SAndrew Rybchenko 			((EFX_TEST_QWORD_BIT(rx_ev, ip_csum_err_bit)) ?
110daa02b5cSOlivier Matz 			 RTE_MBUF_F_RX_IP_CKSUM_BAD : RTE_MBUF_F_RX_IP_CKSUM_GOOD);
111c121f008SAndrew Rybchenko 		break;
112c121f008SAndrew Rybchenko 	case ESE_DZ_L3_CLASS_IP6_FRAG:
113c121f008SAndrew Rybchenko 		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_FRAG :
114c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L4_FRAG;
115c121f008SAndrew Rybchenko 		/* FALLTHROUGH */
116c121f008SAndrew Rybchenko 	case ESE_DZ_L3_CLASS_IP6:
117c121f008SAndrew Rybchenko 		l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV6_EXT_UNKNOWN :
118c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
119daa02b5cSOlivier Matz 		ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
120c121f008SAndrew Rybchenko 		break;
121c121f008SAndrew Rybchenko 	case ESE_DZ_L3_CLASS_ARP:
122c121f008SAndrew Rybchenko 		/* Override Layer 2 packet type */
123c121f008SAndrew Rybchenko 		/* There is no ARP classification for inner packets */
124c121f008SAndrew Rybchenko 		if (tun_ptype == 0)
125c121f008SAndrew Rybchenko 			l2_ptype = RTE_PTYPE_L2_ETHER_ARP;
126c121f008SAndrew Rybchenko 		break;
127812bb208SAndrew Rybchenko 	case ESE_DZ_L3_CLASS_UNKNOWN:
128812bb208SAndrew Rybchenko 		break;
129c121f008SAndrew Rybchenko 	default:
130c121f008SAndrew Rybchenko 		/* Unexpected Layer 3 class */
131c121f008SAndrew Rybchenko 		SFC_ASSERT(false);
132c121f008SAndrew Rybchenko 	}
133c121f008SAndrew Rybchenko 
134c121f008SAndrew Rybchenko 	/*
135c121f008SAndrew Rybchenko 	 * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is only
136c121f008SAndrew Rybchenko 	 * 2 bits wide on Medford2. Check it is safe to use the Medford2 field
137c121f008SAndrew Rybchenko 	 * and values for all EF10 controllers.
138c121f008SAndrew Rybchenko 	 */
139c121f008SAndrew Rybchenko 	RTE_BUILD_BUG_ON(ESF_FZ_RX_L4_CLASS_LBN != ESF_DE_RX_L4_CLASS_LBN);
140c121f008SAndrew Rybchenko 	switch (EFX_QWORD_FIELD(rx_ev, ESF_FZ_RX_L4_CLASS)) {
141c121f008SAndrew Rybchenko 	case ESE_FZ_L4_CLASS_TCP:
142c121f008SAndrew Rybchenko 		 RTE_BUILD_BUG_ON(ESE_FZ_L4_CLASS_TCP != ESE_DE_L4_CLASS_TCP);
143c121f008SAndrew Rybchenko 		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_TCP :
144c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L4_TCP;
145c121f008SAndrew Rybchenko 		ol_flags |=
146c121f008SAndrew Rybchenko 			(EFX_TEST_QWORD_BIT(rx_ev, l4_csum_err_bit)) ?
147daa02b5cSOlivier Matz 			RTE_MBUF_F_RX_L4_CKSUM_BAD : RTE_MBUF_F_RX_L4_CKSUM_GOOD;
148c121f008SAndrew Rybchenko 		break;
149c121f008SAndrew Rybchenko 	case ESE_FZ_L4_CLASS_UDP:
150c121f008SAndrew Rybchenko 		 RTE_BUILD_BUG_ON(ESE_FZ_L4_CLASS_UDP != ESE_DE_L4_CLASS_UDP);
151c121f008SAndrew Rybchenko 		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_UDP :
152c121f008SAndrew Rybchenko 			RTE_PTYPE_INNER_L4_UDP;
153c121f008SAndrew Rybchenko 		ol_flags |=
154c121f008SAndrew Rybchenko 			(EFX_TEST_QWORD_BIT(rx_ev, l4_csum_err_bit)) ?
155daa02b5cSOlivier Matz 			RTE_MBUF_F_RX_L4_CKSUM_BAD : RTE_MBUF_F_RX_L4_CKSUM_GOOD;
156c121f008SAndrew Rybchenko 		break;
157c121f008SAndrew Rybchenko 	case ESE_FZ_L4_CLASS_UNKNOWN:
158c121f008SAndrew Rybchenko 		 RTE_BUILD_BUG_ON(ESE_FZ_L4_CLASS_UNKNOWN !=
159c121f008SAndrew Rybchenko 				  ESE_DE_L4_CLASS_UNKNOWN);
160c121f008SAndrew Rybchenko 		break;
161c121f008SAndrew Rybchenko 	default:
162c121f008SAndrew Rybchenko 		/* Unexpected Layer 4 class */
163c121f008SAndrew Rybchenko 		SFC_ASSERT(false);
164c121f008SAndrew Rybchenko 	}
165c121f008SAndrew Rybchenko 
166aeeb5571SAndrew Rybchenko 	SFC_ASSERT(l2_ptype != 0);
167aeeb5571SAndrew Rybchenko 
168c121f008SAndrew Rybchenko done:
169c121f008SAndrew Rybchenko 	m->ol_flags = ol_flags & ol_mask;
170c121f008SAndrew Rybchenko 	m->packet_type = tun_ptype | l2_ptype | l3_ptype | l4_ptype;
171c121f008SAndrew Rybchenko }
172c121f008SAndrew Rybchenko 
173c121f008SAndrew Rybchenko 
174c121f008SAndrew Rybchenko #ifdef __cplusplus
175c121f008SAndrew Rybchenko }
176c121f008SAndrew Rybchenko #endif
177c121f008SAndrew Rybchenko #endif /* _SFC_EF10_RX_EV_H */
178