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