xref: /linux/drivers/net/ethernet/intel/ice/ice_flow.c (revision 8f7aa3d3c7323f4ca2768a9e74ebbe359c4f8f88)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019, Intel Corporation. */
3 
4 #include "ice_common.h"
5 #include "ice_flow.h"
6 #include <net/gre.h>
7 
8 /* Size of known protocol header fields */
9 #define ICE_FLOW_FLD_SZ_ETH_TYPE	2
10 #define ICE_FLOW_FLD_SZ_VLAN		2
11 #define ICE_FLOW_FLD_SZ_IPV4_ADDR	4
12 #define ICE_FLOW_FLD_SZ_IPV6_ADDR	16
13 #define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR	4
14 #define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR	6
15 #define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR	8
16 #define ICE_FLOW_FLD_SZ_IPV4_ID		2
17 #define ICE_FLOW_FLD_SZ_IPV6_ID		4
18 #define ICE_FLOW_FLD_SZ_IP_CHKSUM	2
19 #define ICE_FLOW_FLD_SZ_TCP_CHKSUM	2
20 #define ICE_FLOW_FLD_SZ_UDP_CHKSUM	2
21 #define ICE_FLOW_FLD_SZ_SCTP_CHKSUM	4
22 #define ICE_FLOW_FLD_SZ_IP_DSCP		1
23 #define ICE_FLOW_FLD_SZ_IP_TTL		1
24 #define ICE_FLOW_FLD_SZ_IP_PROT		1
25 #define ICE_FLOW_FLD_SZ_PORT		2
26 #define ICE_FLOW_FLD_SZ_TCP_FLAGS	1
27 #define ICE_FLOW_FLD_SZ_ICMP_TYPE	1
28 #define ICE_FLOW_FLD_SZ_ICMP_CODE	1
29 #define ICE_FLOW_FLD_SZ_ARP_OPER	2
30 #define ICE_FLOW_FLD_SZ_GRE_KEYID	4
31 #define ICE_FLOW_FLD_SZ_GTP_TEID	4
32 #define ICE_FLOW_FLD_SZ_GTP_QFI		2
33 #define ICE_FLOW_FLD_SZ_PFCP_SEID 8
34 #define ICE_FLOW_FLD_SZ_ESP_SPI	4
35 #define ICE_FLOW_FLD_SZ_AH_SPI	4
36 #define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI	4
37 #define ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID	2
38 #define ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID	2
39 
40 /* Describe properties of a protocol header field */
41 struct ice_flow_field_info {
42 	enum ice_flow_seg_hdr hdr;
43 	s16 off;	/* Offset from start of a protocol header, in bits */
44 	u16 size;	/* Size of fields in bits */
45 	u16 mask;	/* 16-bit mask for field */
46 };
47 
48 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
49 	.hdr = _hdr, \
50 	.off = (_offset_bytes) * BITS_PER_BYTE, \
51 	.size = (_size_bytes) * BITS_PER_BYTE, \
52 	.mask = 0, \
53 }
54 
55 /* QFI: 6-bit field in GTP-U PDU Session Container (3GPP TS 38.415) */
56 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
57 	.hdr = _hdr, \
58 	.off = (_offset_bytes) * BITS_PER_BYTE, \
59 	.size = (_size_bytes) * BITS_PER_BYTE, \
60 	.mask = _mask, \
61 }
62 
63 /* Table containing properties of supported protocol header fields */
64 static const
65 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
66 	/* Ether */
67 	/* ICE_FLOW_FIELD_IDX_ETH_DA */
68 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
69 	/* ICE_FLOW_FIELD_IDX_ETH_SA */
70 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
71 	/* ICE_FLOW_FIELD_IDX_S_VLAN */
72 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)),
73 	/* ICE_FLOW_FIELD_IDX_C_VLAN */
74 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)),
75 	/* ICE_FLOW_FIELD_IDX_ETH_TYPE */
76 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)),
77 	/* IPv4 / IPv6 */
78 	/* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
79 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc),
80 	/* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
81 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0),
82 	/* ICE_FLOW_FIELD_IDX_IPV4_TTL */
83 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00),
84 	/* ICE_FLOW_FIELD_IDX_IPV4_PROT */
85 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff),
86 	/* ICE_FLOW_FIELD_IDX_IPV6_TTL */
87 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff),
88 	/* ICE_FLOW_FIELD_IDX_IPV6_PROT */
89 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00),
90 	/* ICE_FLOW_FIELD_IDX_IPV4_SA */
91 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)),
92 	/* ICE_FLOW_FIELD_IDX_IPV4_DA */
93 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)),
94 	/* ICE_FLOW_FIELD_IDX_IPV6_SA */
95 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
96 	/* ICE_FLOW_FIELD_IDX_IPV6_DA */
97 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
98 	/* ICE_FLOW_FIELD_IDX_IPV4_CHKSUM */
99 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 10, ICE_FLOW_FLD_SZ_IP_CHKSUM),
100 	/* ICE_FLOW_FIELD_IDX_IPV4_FRAG */
101 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
102 			  ICE_FLOW_FLD_SZ_IPV4_ID),
103 	/* ICE_FLOW_FIELD_IDX_IPV6_FRAG */
104 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
105 			  ICE_FLOW_FLD_SZ_IPV6_ID),
106 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
107 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
108 			  ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
109 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */
110 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
111 			  ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
112 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */
113 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
114 			  ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
115 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */
116 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
117 			  ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
118 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */
119 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
120 			  ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
121 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */
122 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
123 			  ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
124 	/* Transport */
125 	/* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
126 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
127 	/* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
128 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)),
129 	/* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
130 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)),
131 	/* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
132 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)),
133 	/* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
134 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)),
135 	/* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
136 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
137 	/* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
138 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS),
139 	/* ICE_FLOW_FIELD_IDX_TCP_CHKSUM */
140 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 16, ICE_FLOW_FLD_SZ_TCP_CHKSUM),
141 	/* ICE_FLOW_FIELD_IDX_UDP_CHKSUM */
142 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 6, ICE_FLOW_FLD_SZ_UDP_CHKSUM),
143 	/* ICE_FLOW_FIELD_IDX_SCTP_CHKSUM */
144 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 8,
145 			  ICE_FLOW_FLD_SZ_SCTP_CHKSUM),
146 	/* ARP */
147 	/* ICE_FLOW_FIELD_IDX_ARP_SIP */
148 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
149 	/* ICE_FLOW_FIELD_IDX_ARP_DIP */
150 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)),
151 	/* ICE_FLOW_FIELD_IDX_ARP_SHA */
152 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
153 	/* ICE_FLOW_FIELD_IDX_ARP_DHA */
154 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
155 	/* ICE_FLOW_FIELD_IDX_ARP_OP */
156 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)),
157 	/* ICMP */
158 	/* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
159 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1),
160 	/* ICE_FLOW_FIELD_IDX_ICMP_CODE */
161 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1),
162 	/* GRE */
163 	/* ICE_FLOW_FIELD_IDX_GRE_KEYID */
164 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12,
165 			  sizeof_field(struct gre_full_hdr, key)),
166 	/* GTP */
167 	/* ICE_FLOW_FIELD_IDX_GTPC_TEID */
168 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)),
169 	/* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
170 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)),
171 	/* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
172 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)),
173 	/* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
174 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
175 			      0x3f00),
176 	/* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
177 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12,
178 			  ICE_FLOW_FLD_SZ_GTP_TEID),
179 	/* ICE_FLOW_FIELD_IDX_GTPU_UP_QFI */
180 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_UP, 22,
181 			      ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
182 	/* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
183 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12,
184 			  ICE_FLOW_FLD_SZ_GTP_TEID),
185 	/* ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI */
186 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_DWN, 22,
187 			      ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
188 	/* PPPoE */
189 	/* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
190 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
191 	/* PFCP */
192 	/* ICE_FLOW_FIELD_IDX_PFCP_SEID */
193 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
194 	/* L2TPv3 */
195 	/* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
196 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
197 	/* ESP */
198 	/* ICE_FLOW_FIELD_IDX_ESP_SPI */
199 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
200 	/* AH */
201 	/* ICE_FLOW_FIELD_IDX_AH_SPI */
202 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
203 	/* NAT_T_ESP */
204 	/* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
205 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8,
206 			  ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI),
207 	/* L2TPV2 */
208 	/* ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID */
209 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 12,
210 			  ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID),
211 	/* L2TPV2_LEN */
212 	/* ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID */
213 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 14,
214 			  ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID),
215 };
216 
217 /* Bitmaps indicating relevant packet types for a particular protocol header
218  *
219  * Packet types for packets with an Outer/First/Single MAC header
220  */
221 static const u32 ice_ptypes_mac_ofos[] = {
222 	0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
223 	0x0000077E, 0x000003FF, 0x00000000, 0x00000000,
224 	0x00400000, 0x03FFF000, 0xFFFFFFE0, 0x00000707,
225 	0xFFFFF000, 0x000003FF, 0x00000000, 0x00000000,
226 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
227 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
228 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
229 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
230 };
231 
232 /* Packet types for packets with an Innermost/Last MAC VLAN header */
233 static const u32 ice_ptypes_macvlan_il[] = {
234 	0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
235 	0x0000077E, 0x00000000, 0x00000000, 0x00000000,
236 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
237 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
238 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
239 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
240 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
241 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
242 };
243 
244 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
245  * include IPv4 other PTYPEs
246  */
247 static const u32 ice_ptypes_ipv4_ofos[] = {
248 	0x1D800000, 0xBFBF7800, 0x000001DF, 0x00000000,
249 	0x00000000, 0x00000155, 0x00000000, 0x00000000,
250 	0x00000000, 0x000FC000, 0x000002A0, 0x00000000,
251 	0x00015000, 0x00000000, 0x00000000, 0x00000000,
252 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
253 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
254 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
255 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
256 };
257 
258 /* Packet types for packets with an Outer/First/Single IPv4 header, includes
259  * IPv4 other PTYPEs
260  */
261 static const u32 ice_ptypes_ipv4_ofos_all[] = {
262 	0x1D800000, 0x27BF7800, 0x00000000, 0x00000000,
263 	0x00000000, 0x00000155, 0x00000000, 0x00000000,
264 	0x00000000, 0x000FC000, 0x83E0FAA0, 0x00000101,
265 	0x3FFD5000, 0x00000000, 0x02FBEFBC, 0x00000000,
266 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
267 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
268 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
269 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
270 };
271 
272 /* Packet types for packets with an Innermost/Last IPv4 header */
273 static const u32 ice_ptypes_ipv4_il[] = {
274 	0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
275 	0x0000000E, 0x00000000, 0x00000000, 0x00000000,
276 	0x00000000, 0x00000000, 0x001FF800, 0x00000000,
277 	0xC0FC0000, 0x0000000F, 0xBC0BC0BC, 0x00000BC0,
278 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
279 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
280 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
281 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
282 };
283 
284 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
285  * include IPv6 other PTYPEs
286  */
287 static const u32 ice_ptypes_ipv6_ofos[] = {
288 	0x00000000, 0x00000000, 0x76000000, 0x10002000,
289 	0x00000000, 0x000002AA, 0x00000000, 0x00000000,
290 	0x00000000, 0x03F00000, 0x00000540, 0x00000000,
291 	0x0002A000, 0x00000000, 0x00000000, 0x00000000,
292 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
293 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
294 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
295 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
296 };
297 
298 /* Packet types for packets with an Outer/First/Single IPv6 header, includes
299  * IPv6 other PTYPEs
300  */
301 static const u32 ice_ptypes_ipv6_ofos_all[] = {
302 	0x00000000, 0x00000000, 0x76000000, 0xFEFDE000,
303 	0x0000077E, 0x000002AA, 0x00000000, 0x00000000,
304 	0x00000000, 0x03F00000, 0x7C1F0540, 0x00000206,
305 	0xC002A000, 0x000003FF, 0xBC000000, 0x0002FBEF,
306 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
307 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
308 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
309 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
310 };
311 
312 /* Packet types for packets with an Innermost/Last IPv6 header */
313 static const u32 ice_ptypes_ipv6_il[] = {
314 	0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
315 	0x00000770, 0x00000000, 0x00000000, 0x00000000,
316 	0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
317 	0x3F000000, 0x000003F0, 0x02F02F00, 0x0002F02F,
318 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
319 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
320 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
321 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
322 };
323 
324 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
325 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
326 	0x10C00000, 0x04000800, 0x00000000, 0x00000000,
327 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
328 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
329 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
330 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
331 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
332 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
333 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
334 };
335 
336 /* Packet types for packets with an Outermost/First ARP header */
337 static const u32 ice_ptypes_arp_of[] = {
338 	0x00000800, 0x00000000, 0x00000000, 0x00000000,
339 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
340 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
341 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
342 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
343 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
344 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
345 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
346 };
347 
348 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
349 static const u32 ice_ptypes_ipv4_il_no_l4[] = {
350 	0x60000000, 0x18043008, 0x80000002, 0x6010c021,
351 	0x00000008, 0x00000000, 0x00000000, 0x00000000,
352 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
353 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
354 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
355 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
356 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
357 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
358 };
359 
360 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
361 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
362 	0x00000000, 0x00000000, 0x43000000, 0x10002000,
363 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
364 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
365 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
366 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
367 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
368 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
369 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
370 };
371 
372 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
373 static const u32 ice_ptypes_ipv6_il_no_l4[] = {
374 	0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
375 	0x00000430, 0x00000000, 0x00000000, 0x00000000,
376 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
377 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
378 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
379 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
380 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
381 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
382 };
383 
384 /* UDP Packet types for non-tunneled packets or tunneled
385  * packets with inner UDP.
386  */
387 static const u32 ice_ptypes_udp_il[] = {
388 	0x81000000, 0x20204040, 0x04000010, 0x80810102,
389 	0x00000040, 0x00000000, 0x00000000, 0x00000000,
390 	0x00000000, 0x00410000, 0x908427E0, 0x00000007,
391 	0x0413F000, 0x00000041, 0x10410410, 0x00004104,
392 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
393 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
394 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
395 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
396 };
397 
398 /* Packet types for packets with an Innermost/Last TCP header */
399 static const u32 ice_ptypes_tcp_il[] = {
400 	0x04000000, 0x80810102, 0x10000040, 0x02040408,
401 	0x00000102, 0x00000000, 0x00000000, 0x00000000,
402 	0x00000000, 0x00820000, 0x21084000, 0x00000000,
403 	0x08200000, 0x00000082, 0x20820820, 0x00008208,
404 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
405 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
406 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
407 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
408 };
409 
410 /* Packet types for packets with an Innermost/Last SCTP header */
411 static const u32 ice_ptypes_sctp_il[] = {
412 	0x08000000, 0x01020204, 0x20000081, 0x04080810,
413 	0x00000204, 0x00000000, 0x00000000, 0x00000000,
414 	0x00000000, 0x01040000, 0x00000000, 0x00000000,
415 	0x10400000, 0x00000104, 0x00000000, 0x00000000,
416 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
417 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
418 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
419 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
420 };
421 
422 /* Packet types for packets with an Outermost/First ICMP header */
423 static const u32 ice_ptypes_icmp_of[] = {
424 	0x10000000, 0x00000000, 0x00000000, 0x00000000,
425 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
426 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
427 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
428 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
429 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
430 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
431 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
432 };
433 
434 /* Packet types for packets with an Innermost/Last ICMP header */
435 static const u32 ice_ptypes_icmp_il[] = {
436 	0x00000000, 0x02040408, 0x40000102, 0x08101020,
437 	0x00000408, 0x00000000, 0x00000000, 0x00000000,
438 	0x00000000, 0x00000000, 0x42108000, 0x00000000,
439 	0x20800000, 0x00000208, 0x00000000, 0x00000000,
440 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
441 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
442 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
443 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
444 };
445 
446 /* Packet types for packets with an Outermost/First GRE header */
447 static const u32 ice_ptypes_gre_of[] = {
448 	0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
449 	0x0000017E, 0x00000000, 0x00000000, 0x00000000,
450 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
451 	0x00000000, 0x00000000, 0xBEFBEFBC, 0x0002FBEF,
452 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
453 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
454 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
455 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
456 };
457 
458 /* Packet types for packets with an Innermost/Last MAC header */
459 static const u32 ice_ptypes_mac_il[] = {
460 	0x00000000, 0x20000000, 0x00000000, 0x00000000,
461 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
462 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
463 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
464 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
465 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
466 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
467 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
468 };
469 
470 /* Packet types for GTPC */
471 static const u32 ice_ptypes_gtpc[] = {
472 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
473 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
474 	0x00000000, 0x00000000, 0x000001E0, 0x00000000,
475 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
476 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
477 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
478 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
479 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
480 };
481 
482 /* Packet types for GTPC with TEID */
483 static const u32 ice_ptypes_gtpc_tid[] = {
484 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
485 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
486 	0x00000000, 0x00000000, 0x00000060, 0x00000000,
487 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
488 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
489 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
490 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
491 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
492 };
493 
494 /* Packet types for GTPU */
495 static const struct ice_ptype_attributes ice_attr_gtpu_session[] = {
496 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
497 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
498 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
499 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
500 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_SESSION },
501 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
502 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
503 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
504 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
505 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_SESSION },
506 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
507 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
508 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
509 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
510 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_SESSION },
511 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
512 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
513 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
514 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
515 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_SESSION },
516 };
517 
518 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
519 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
520 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
521 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
522 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
523 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
524 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
525 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
526 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
527 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
528 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
529 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
530 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
531 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
532 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
533 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
534 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
535 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
536 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
537 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
538 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
539 };
540 
541 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
542 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
543 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
544 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
545 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
546 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
547 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
548 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
549 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
550 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
551 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
552 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
553 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
554 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
555 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
556 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
557 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
558 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
559 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
560 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
561 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
562 };
563 
564 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
565 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
566 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
567 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
568 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
569 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
570 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
571 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
572 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
573 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
574 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
575 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
576 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
577 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
578 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
579 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
580 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
581 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
582 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
583 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
584 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
585 };
586 
587 static const u32 ice_ptypes_gtpu[] = {
588 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
589 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
590 	0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
591 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
592 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
593 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
594 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
595 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
596 };
597 
598 /* Packet types for PPPoE */
599 static const u32 ice_ptypes_pppoe[] = {
600 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
601 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
602 	0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
603 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
604 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
605 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
606 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
607 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
608 };
609 
610 /* Packet types for packets with PFCP NODE header */
611 static const u32 ice_ptypes_pfcp_node[] = {
612 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
613 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
614 	0x00000000, 0x00000000, 0x80000000, 0x00000002,
615 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
616 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
617 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
618 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
619 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
620 };
621 
622 /* Packet types for packets with PFCP SESSION header */
623 static const u32 ice_ptypes_pfcp_session[] = {
624 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
625 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
626 	0x00000000, 0x00000000, 0x00000000, 0x00000005,
627 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
628 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
629 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
630 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
631 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
632 };
633 
634 /* Packet types for L2TPv3 */
635 static const u32 ice_ptypes_l2tpv3[] = {
636 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
637 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
638 	0x00000000, 0x00000000, 0x00000000, 0x00000300,
639 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
640 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
641 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
642 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
643 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
644 };
645 
646 /* Packet types for ESP */
647 static const u32 ice_ptypes_esp[] = {
648 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
649 	0x00000000, 0x00000003, 0x00000000, 0x00000000,
650 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
651 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
652 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
653 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
654 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
655 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
656 };
657 
658 /* Packet types for AH */
659 static const u32 ice_ptypes_ah[] = {
660 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
661 	0x00000000, 0x0000000C, 0x00000000, 0x00000000,
662 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
663 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
664 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
665 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
666 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
667 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
668 };
669 
670 /* Packet types for packets with NAT_T ESP header */
671 static const u32 ice_ptypes_nat_t_esp[] = {
672 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
673 	0x00000000, 0x00000030, 0x00000000, 0x00000000,
674 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
675 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
676 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
677 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
678 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
679 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
680 };
681 
682 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
683 	0x00000846, 0x00000000, 0x00000000, 0x00000000,
684 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
685 	0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
686 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
687 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
688 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
689 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
690 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
691 };
692 
693 /* Manage parameters and info. used during the creation of a flow profile */
694 struct ice_flow_prof_params {
695 	enum ice_block blk;
696 	u16 entry_length; /* # of bytes formatted entry will require */
697 	u8 es_cnt;
698 	struct ice_flow_prof *prof;
699 
700 	/* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
701 	 * This will give us the direction flags.
702 	 */
703 	struct ice_fv_word es[ICE_MAX_FV_WORDS];
704 	/* attributes can be used to add attributes to a particular PTYPE */
705 	const struct ice_ptype_attributes *attr;
706 	u16 attr_cnt;
707 
708 	u16 mask[ICE_MAX_FV_WORDS];
709 	DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
710 };
711 
712 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
713 	(ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
714 	ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
715 	ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
716 	ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
717 	ICE_FLOW_SEG_HDR_NAT_T_ESP)
718 
719 #define ICE_FLOW_SEG_HDRS_L3_MASK	\
720 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
721 #define ICE_FLOW_SEG_HDRS_L4_MASK	\
722 	(ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
723 	 ICE_FLOW_SEG_HDR_SCTP)
724 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
725 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER	\
726 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
727 
728 /**
729  * ice_flow_val_hdrs - validates packet segments for valid protocol headers
730  * @segs: array of one or more packet segments that describe the flow
731  * @segs_cnt: number of packet segments provided
732  */
733 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
734 {
735 	u8 i;
736 
737 	for (i = 0; i < segs_cnt; i++) {
738 		/* Multiple L3 headers */
739 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
740 		    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
741 			return -EINVAL;
742 
743 		/* Multiple L4 headers */
744 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
745 		    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
746 			return -EINVAL;
747 	}
748 
749 	return 0;
750 }
751 
752 /* Sizes of fixed known protocol headers without header options */
753 #define ICE_FLOW_PROT_HDR_SZ_MAC	14
754 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN	(ICE_FLOW_PROT_HDR_SZ_MAC + 2)
755 #define ICE_FLOW_PROT_HDR_SZ_IPV4	20
756 #define ICE_FLOW_PROT_HDR_SZ_IPV6	40
757 #define ICE_FLOW_PROT_HDR_SZ_ARP	28
758 #define ICE_FLOW_PROT_HDR_SZ_ICMP	8
759 #define ICE_FLOW_PROT_HDR_SZ_TCP	20
760 #define ICE_FLOW_PROT_HDR_SZ_UDP	8
761 #define ICE_FLOW_PROT_HDR_SZ_SCTP	12
762 
763 /**
764  * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
765  * @params: information about the flow to be processed
766  * @seg: index of packet segment whose header size is to be determined
767  */
768 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
769 {
770 	u16 sz;
771 
772 	/* L2 headers */
773 	sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
774 		ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
775 
776 	/* L3 headers */
777 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
778 		sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
779 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
780 		sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
781 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
782 		sz += ICE_FLOW_PROT_HDR_SZ_ARP;
783 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
784 		/* An L3 header is required if L4 is specified */
785 		return 0;
786 
787 	/* L4 headers */
788 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
789 		sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
790 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
791 		sz += ICE_FLOW_PROT_HDR_SZ_TCP;
792 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
793 		sz += ICE_FLOW_PROT_HDR_SZ_UDP;
794 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
795 		sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
796 
797 	return sz;
798 }
799 
800 /**
801  * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
802  * @params: information about the flow to be processed
803  *
804  * This function identifies the packet types associated with the protocol
805  * headers being present in packet segments of the specified flow profile.
806  */
807 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
808 {
809 	struct ice_flow_prof *prof;
810 	u8 i;
811 
812 	memset(params->ptypes, 0xff, sizeof(params->ptypes));
813 
814 	prof = params->prof;
815 
816 	for (i = 0; i < params->prof->segs_cnt; i++) {
817 		const unsigned long *src;
818 		u32 hdrs;
819 
820 		hdrs = prof->segs[i].hdrs;
821 
822 		if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
823 			src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
824 				(const unsigned long *)ice_ptypes_mac_il;
825 			bitmap_and(params->ptypes, params->ptypes, src,
826 				   ICE_FLOW_PTYPE_MAX);
827 		}
828 
829 		if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
830 			src = (const unsigned long *)ice_ptypes_macvlan_il;
831 			bitmap_and(params->ptypes, params->ptypes, src,
832 				   ICE_FLOW_PTYPE_MAX);
833 		}
834 
835 		if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
836 			bitmap_and(params->ptypes, params->ptypes,
837 				   (const unsigned long *)ice_ptypes_arp_of,
838 				   ICE_FLOW_PTYPE_MAX);
839 		}
840 
841 		if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
842 		    (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
843 			src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
844 				(const unsigned long *)ice_ptypes_ipv4_ofos_all;
845 			bitmap_and(params->ptypes, params->ptypes, src,
846 				   ICE_FLOW_PTYPE_MAX);
847 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
848 			   (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
849 			src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
850 				(const unsigned long *)ice_ptypes_ipv6_ofos_all;
851 			bitmap_and(params->ptypes, params->ptypes, src,
852 				   ICE_FLOW_PTYPE_MAX);
853 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
854 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
855 			src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
856 				(const unsigned long *)ice_ptypes_ipv4_il_no_l4;
857 			bitmap_and(params->ptypes, params->ptypes, src,
858 				   ICE_FLOW_PTYPE_MAX);
859 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
860 			src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
861 				(const unsigned long *)ice_ptypes_ipv4_il;
862 			bitmap_and(params->ptypes, params->ptypes, src,
863 				   ICE_FLOW_PTYPE_MAX);
864 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
865 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
866 			src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
867 				(const unsigned long *)ice_ptypes_ipv6_il_no_l4;
868 			bitmap_and(params->ptypes, params->ptypes, src,
869 				   ICE_FLOW_PTYPE_MAX);
870 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
871 			src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
872 				(const unsigned long *)ice_ptypes_ipv6_il;
873 			bitmap_and(params->ptypes, params->ptypes, src,
874 				   ICE_FLOW_PTYPE_MAX);
875 		}
876 
877 		if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
878 			src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
879 			bitmap_and(params->ptypes, params->ptypes, src,
880 				   ICE_FLOW_PTYPE_MAX);
881 		} else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
882 			src = (const unsigned long *)ice_ptypes_pppoe;
883 			bitmap_and(params->ptypes, params->ptypes, src,
884 				   ICE_FLOW_PTYPE_MAX);
885 		} else {
886 			src = (const unsigned long *)ice_ptypes_pppoe;
887 			bitmap_andnot(params->ptypes, params->ptypes, src,
888 				      ICE_FLOW_PTYPE_MAX);
889 		}
890 
891 		if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
892 			src = (const unsigned long *)ice_ptypes_udp_il;
893 			bitmap_and(params->ptypes, params->ptypes, src,
894 				   ICE_FLOW_PTYPE_MAX);
895 		} else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
896 			bitmap_and(params->ptypes, params->ptypes,
897 				   (const unsigned long *)ice_ptypes_tcp_il,
898 				   ICE_FLOW_PTYPE_MAX);
899 		} else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
900 			src = (const unsigned long *)ice_ptypes_sctp_il;
901 			bitmap_and(params->ptypes, params->ptypes, src,
902 				   ICE_FLOW_PTYPE_MAX);
903 		}
904 
905 		if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
906 			src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
907 				(const unsigned long *)ice_ptypes_icmp_il;
908 			bitmap_and(params->ptypes, params->ptypes, src,
909 				   ICE_FLOW_PTYPE_MAX);
910 		} else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
911 			if (!i) {
912 				src = (const unsigned long *)ice_ptypes_gre_of;
913 				bitmap_and(params->ptypes, params->ptypes,
914 					   src, ICE_FLOW_PTYPE_MAX);
915 			}
916 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
917 			src = (const unsigned long *)ice_ptypes_gtpc;
918 			bitmap_and(params->ptypes, params->ptypes, src,
919 				   ICE_FLOW_PTYPE_MAX);
920 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
921 			src = (const unsigned long *)ice_ptypes_gtpc_tid;
922 			bitmap_and(params->ptypes, params->ptypes, src,
923 				   ICE_FLOW_PTYPE_MAX);
924 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
925 			src = (const unsigned long *)ice_ptypes_gtpu;
926 			bitmap_and(params->ptypes, params->ptypes, src,
927 				   ICE_FLOW_PTYPE_MAX);
928 
929 			/* Attributes for GTP packet with downlink */
930 			params->attr = ice_attr_gtpu_down;
931 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
932 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
933 			src = (const unsigned long *)ice_ptypes_gtpu;
934 			bitmap_and(params->ptypes, params->ptypes, src,
935 				   ICE_FLOW_PTYPE_MAX);
936 
937 			/* Attributes for GTP packet with uplink */
938 			params->attr = ice_attr_gtpu_up;
939 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
940 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
941 			src = (const unsigned long *)ice_ptypes_gtpu;
942 			bitmap_and(params->ptypes, params->ptypes, src,
943 				   ICE_FLOW_PTYPE_MAX);
944 
945 			/* Attributes for GTP packet with Extension Header */
946 			params->attr = ice_attr_gtpu_eh;
947 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
948 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
949 			src = (const unsigned long *)ice_ptypes_gtpu;
950 			bitmap_and(params->ptypes, params->ptypes, src,
951 				   ICE_FLOW_PTYPE_MAX);
952 		} else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
953 			src = (const unsigned long *)ice_ptypes_l2tpv3;
954 			bitmap_and(params->ptypes, params->ptypes, src,
955 				   ICE_FLOW_PTYPE_MAX);
956 		} else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
957 			src = (const unsigned long *)ice_ptypes_esp;
958 			bitmap_and(params->ptypes, params->ptypes, src,
959 				   ICE_FLOW_PTYPE_MAX);
960 		} else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
961 			src = (const unsigned long *)ice_ptypes_ah;
962 			bitmap_and(params->ptypes, params->ptypes, src,
963 				   ICE_FLOW_PTYPE_MAX);
964 		} else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
965 			src = (const unsigned long *)ice_ptypes_nat_t_esp;
966 			bitmap_and(params->ptypes, params->ptypes, src,
967 				   ICE_FLOW_PTYPE_MAX);
968 		}
969 
970 		if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
971 			if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
972 				src = (const unsigned long *)ice_ptypes_pfcp_node;
973 			else
974 				src = (const unsigned long *)ice_ptypes_pfcp_session;
975 
976 			bitmap_and(params->ptypes, params->ptypes, src,
977 				   ICE_FLOW_PTYPE_MAX);
978 		} else {
979 			src = (const unsigned long *)ice_ptypes_pfcp_node;
980 			bitmap_andnot(params->ptypes, params->ptypes, src,
981 				      ICE_FLOW_PTYPE_MAX);
982 
983 			src = (const unsigned long *)ice_ptypes_pfcp_session;
984 			bitmap_andnot(params->ptypes, params->ptypes, src,
985 				      ICE_FLOW_PTYPE_MAX);
986 		}
987 	}
988 
989 	return 0;
990 }
991 
992 /**
993  * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
994  * @hw: pointer to the HW struct
995  * @params: information about the flow to be processed
996  * @seg: packet segment index of the field to be extracted
997  * @fld: ID of field to be extracted
998  * @match: bit field of all fields
999  *
1000  * This function determines the protocol ID, offset, and size of the given
1001  * field. It then allocates one or more extraction sequence entries for the
1002  * given field, and fill the entries with protocol ID and offset information.
1003  */
1004 static int
1005 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
1006 		    u8 seg, enum ice_flow_field fld, u64 match)
1007 {
1008 	enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
1009 	enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
1010 	u8 fv_words = hw->blk[params->blk].es.fvw;
1011 	struct ice_flow_fld_info *flds;
1012 	u16 cnt, ese_bits, i;
1013 	u16 sib_mask = 0;
1014 	u16 mask;
1015 	u16 off;
1016 
1017 	flds = params->prof->segs[seg].fields;
1018 
1019 	switch (fld) {
1020 	case ICE_FLOW_FIELD_IDX_ETH_DA:
1021 	case ICE_FLOW_FIELD_IDX_ETH_SA:
1022 	case ICE_FLOW_FIELD_IDX_S_VLAN:
1023 	case ICE_FLOW_FIELD_IDX_C_VLAN:
1024 		prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
1025 		break;
1026 	case ICE_FLOW_FIELD_IDX_ETH_TYPE:
1027 		prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
1028 		break;
1029 	case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
1030 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
1031 		break;
1032 	case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
1033 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
1034 		break;
1035 	case ICE_FLOW_FIELD_IDX_IPV4_TTL:
1036 	case ICE_FLOW_FIELD_IDX_IPV4_PROT:
1037 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
1038 
1039 		/* TTL and PROT share the same extraction seq. entry.
1040 		 * Each is considered a sibling to the other in terms of sharing
1041 		 * the same extraction sequence entry.
1042 		 */
1043 		if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
1044 			sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
1045 		else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
1046 			sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
1047 
1048 		/* If the sibling field is also included, that field's
1049 		 * mask needs to be included.
1050 		 */
1051 		if (match & BIT(sib))
1052 			sib_mask = ice_flds_info[sib].mask;
1053 		break;
1054 	case ICE_FLOW_FIELD_IDX_IPV6_TTL:
1055 	case ICE_FLOW_FIELD_IDX_IPV6_PROT:
1056 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
1057 
1058 		/* TTL and PROT share the same extraction seq. entry.
1059 		 * Each is considered a sibling to the other in terms of sharing
1060 		 * the same extraction sequence entry.
1061 		 */
1062 		if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
1063 			sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
1064 		else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
1065 			sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
1066 
1067 		/* If the sibling field is also included, that field's
1068 		 * mask needs to be included.
1069 		 */
1070 		if (match & BIT(sib))
1071 			sib_mask = ice_flds_info[sib].mask;
1072 		break;
1073 	case ICE_FLOW_FIELD_IDX_IPV4_SA:
1074 	case ICE_FLOW_FIELD_IDX_IPV4_DA:
1075 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
1076 		break;
1077 	case ICE_FLOW_FIELD_IDX_IPV6_SA:
1078 	case ICE_FLOW_FIELD_IDX_IPV6_DA:
1079 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
1080 		break;
1081 	case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
1082 	case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
1083 	case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
1084 		prot_id = ICE_PROT_TCP_IL;
1085 		break;
1086 	case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
1087 	case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
1088 		prot_id = ICE_PROT_UDP_IL_OR_S;
1089 		break;
1090 	case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
1091 	case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
1092 		prot_id = ICE_PROT_SCTP_IL;
1093 		break;
1094 	case ICE_FLOW_FIELD_IDX_GTPC_TEID:
1095 	case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
1096 	case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
1097 	case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
1098 	case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
1099 	case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
1100 		/* GTP is accessed through UDP OF protocol */
1101 		prot_id = ICE_PROT_UDP_OF;
1102 		break;
1103 	case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
1104 		prot_id = ICE_PROT_PPPOE;
1105 		break;
1106 	case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1107 		prot_id = ICE_PROT_UDP_IL_OR_S;
1108 		break;
1109 	case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1110 		prot_id = ICE_PROT_L2TPV3;
1111 		break;
1112 	case ICE_FLOW_FIELD_IDX_ESP_SPI:
1113 		prot_id = ICE_PROT_ESP_F;
1114 		break;
1115 	case ICE_FLOW_FIELD_IDX_AH_SPI:
1116 		prot_id = ICE_PROT_ESP_2;
1117 		break;
1118 	case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1119 		prot_id = ICE_PROT_UDP_IL_OR_S;
1120 		break;
1121 	case ICE_FLOW_FIELD_IDX_ARP_SIP:
1122 	case ICE_FLOW_FIELD_IDX_ARP_DIP:
1123 	case ICE_FLOW_FIELD_IDX_ARP_SHA:
1124 	case ICE_FLOW_FIELD_IDX_ARP_DHA:
1125 	case ICE_FLOW_FIELD_IDX_ARP_OP:
1126 		prot_id = ICE_PROT_ARP_OF;
1127 		break;
1128 	case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1129 	case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1130 		/* ICMP type and code share the same extraction seq. entry */
1131 		prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1132 				ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1133 		sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1134 			ICE_FLOW_FIELD_IDX_ICMP_CODE :
1135 			ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1136 		break;
1137 	case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1138 		prot_id = ICE_PROT_GRE_OF;
1139 		break;
1140 	default:
1141 		return -EOPNOTSUPP;
1142 	}
1143 
1144 	/* Each extraction sequence entry is a word in size, and extracts a
1145 	 * word-aligned offset from a protocol header.
1146 	 */
1147 	ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1148 
1149 	flds[fld].xtrct.prot_id = prot_id;
1150 	flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1151 		ICE_FLOW_FV_EXTRACT_SZ;
1152 	flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1153 	flds[fld].xtrct.idx = params->es_cnt;
1154 	flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1155 
1156 	/* Adjust the next field-entry index after accommodating the number of
1157 	 * entries this field consumes
1158 	 */
1159 	cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1160 			   ese_bits);
1161 
1162 	/* Fill in the extraction sequence entries needed for this field */
1163 	off = flds[fld].xtrct.off;
1164 	mask = flds[fld].xtrct.mask;
1165 	for (i = 0; i < cnt; i++) {
1166 		/* Only consume an extraction sequence entry if there is no
1167 		 * sibling field associated with this field or the sibling entry
1168 		 * already extracts the word shared with this field.
1169 		 */
1170 		if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1171 		    flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1172 		    flds[sib].xtrct.off != off) {
1173 			u8 idx;
1174 
1175 			/* Make sure the number of extraction sequence required
1176 			 * does not exceed the block's capability
1177 			 */
1178 			if (params->es_cnt >= fv_words)
1179 				return -ENOSPC;
1180 
1181 			/* some blocks require a reversed field vector layout */
1182 			if (hw->blk[params->blk].es.reverse)
1183 				idx = fv_words - params->es_cnt - 1;
1184 			else
1185 				idx = params->es_cnt;
1186 
1187 			params->es[idx].prot_id = prot_id;
1188 			params->es[idx].off = off;
1189 			params->mask[idx] = mask | sib_mask;
1190 			params->es_cnt++;
1191 		}
1192 
1193 		off += ICE_FLOW_FV_EXTRACT_SZ;
1194 	}
1195 
1196 	return 0;
1197 }
1198 
1199 /**
1200  * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1201  * @hw: pointer to the HW struct
1202  * @params: information about the flow to be processed
1203  * @seg: index of packet segment whose raw fields are to be extracted
1204  */
1205 static int
1206 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1207 		     u8 seg)
1208 {
1209 	u16 fv_words;
1210 	u16 hdrs_sz;
1211 	u8 i;
1212 
1213 	if (!params->prof->segs[seg].raws_cnt)
1214 		return 0;
1215 
1216 	if (params->prof->segs[seg].raws_cnt >
1217 	    ARRAY_SIZE(params->prof->segs[seg].raws))
1218 		return -ENOSPC;
1219 
1220 	/* Offsets within the segment headers are not supported */
1221 	hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1222 	if (!hdrs_sz)
1223 		return -EINVAL;
1224 
1225 	fv_words = hw->blk[params->blk].es.fvw;
1226 
1227 	for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1228 		struct ice_flow_seg_fld_raw *raw;
1229 		u16 off, cnt, j;
1230 
1231 		raw = &params->prof->segs[seg].raws[i];
1232 
1233 		/* Storing extraction information */
1234 		raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1235 		raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1236 			ICE_FLOW_FV_EXTRACT_SZ;
1237 		raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1238 			BITS_PER_BYTE;
1239 		raw->info.xtrct.idx = params->es_cnt;
1240 
1241 		/* Determine the number of field vector entries this raw field
1242 		 * consumes.
1243 		 */
1244 		cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1245 				   (raw->info.src.last * BITS_PER_BYTE),
1246 				   (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1247 		off = raw->info.xtrct.off;
1248 		for (j = 0; j < cnt; j++) {
1249 			u16 idx;
1250 
1251 			/* Make sure the number of extraction sequence required
1252 			 * does not exceed the block's capability
1253 			 */
1254 			if (params->es_cnt >= hw->blk[params->blk].es.count ||
1255 			    params->es_cnt >= ICE_MAX_FV_WORDS)
1256 				return -ENOSPC;
1257 
1258 			/* some blocks require a reversed field vector layout */
1259 			if (hw->blk[params->blk].es.reverse)
1260 				idx = fv_words - params->es_cnt - 1;
1261 			else
1262 				idx = params->es_cnt;
1263 
1264 			params->es[idx].prot_id = raw->info.xtrct.prot_id;
1265 			params->es[idx].off = off;
1266 			params->es_cnt++;
1267 			off += ICE_FLOW_FV_EXTRACT_SZ;
1268 		}
1269 	}
1270 
1271 	return 0;
1272 }
1273 
1274 /**
1275  * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1276  * @hw: pointer to the HW struct
1277  * @params: information about the flow to be processed
1278  *
1279  * This function iterates through all matched fields in the given segments, and
1280  * creates an extraction sequence for the fields.
1281  */
1282 static int
1283 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1284 			  struct ice_flow_prof_params *params)
1285 {
1286 	struct ice_flow_prof *prof = params->prof;
1287 	int status = 0;
1288 	u8 i;
1289 
1290 	for (i = 0; i < prof->segs_cnt; i++) {
1291 		u64 match = params->prof->segs[i].match;
1292 		enum ice_flow_field j;
1293 
1294 		for_each_set_bit(j, (unsigned long *)&match,
1295 				 ICE_FLOW_FIELD_IDX_MAX) {
1296 			status = ice_flow_xtract_fld(hw, params, i, j, match);
1297 			if (status)
1298 				return status;
1299 			clear_bit(j, (unsigned long *)&match);
1300 		}
1301 
1302 		/* Process raw matching bytes */
1303 		status = ice_flow_xtract_raws(hw, params, i);
1304 		if (status)
1305 			return status;
1306 	}
1307 
1308 	return status;
1309 }
1310 
1311 /**
1312  * ice_flow_proc_segs - process all packet segments associated with a profile
1313  * @hw: pointer to the HW struct
1314  * @params: information about the flow to be processed
1315  */
1316 static int
1317 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1318 {
1319 	int status;
1320 
1321 	status = ice_flow_proc_seg_hdrs(params);
1322 	if (status)
1323 		return status;
1324 
1325 	status = ice_flow_create_xtrct_seq(hw, params);
1326 	if (status)
1327 		return status;
1328 
1329 	switch (params->blk) {
1330 	case ICE_BLK_FD:
1331 	case ICE_BLK_RSS:
1332 		status = 0;
1333 		break;
1334 	default:
1335 		return -EOPNOTSUPP;
1336 	}
1337 
1338 	return status;
1339 }
1340 
1341 #define ICE_FLOW_FIND_PROF_CHK_FLDS	0x00000001
1342 #define ICE_FLOW_FIND_PROF_CHK_VSI	0x00000002
1343 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR	0x00000004
1344 #define ICE_FLOW_FIND_PROF_CHK_SYMM	0x00000008
1345 
1346 /**
1347  * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1348  * @hw: pointer to the HW struct
1349  * @blk: classification stage
1350  * @dir: flow direction
1351  * @segs: array of one or more packet segments that describe the flow
1352  * @segs_cnt: number of packet segments provided
1353  * @symm: symmetric setting for RSS profiles
1354  * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1355  * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1356  */
1357 static struct ice_flow_prof *
1358 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1359 			 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1360 			 u8 segs_cnt, bool symm, u16 vsi_handle, u32 conds)
1361 {
1362 	struct ice_flow_prof *p, *prof = NULL;
1363 
1364 	mutex_lock(&hw->fl_profs_locks[blk]);
1365 	list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1366 		if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1367 		    segs_cnt && segs_cnt == p->segs_cnt) {
1368 			u8 i;
1369 
1370 			/* Check for profile-VSI association if specified */
1371 			if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1372 			    ice_is_vsi_valid(hw, vsi_handle) &&
1373 			    !test_bit(vsi_handle, p->vsis))
1374 				continue;
1375 
1376 			/* Check for symmetric settings */
1377 			if ((conds & ICE_FLOW_FIND_PROF_CHK_SYMM) &&
1378 			    p->symm != symm)
1379 				continue;
1380 
1381 			/* Protocol headers must be checked. Matched fields are
1382 			 * checked if specified.
1383 			 */
1384 			for (i = 0; i < segs_cnt; i++)
1385 				if (segs[i].hdrs != p->segs[i].hdrs ||
1386 				    ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1387 				     segs[i].match != p->segs[i].match))
1388 					break;
1389 
1390 			/* A match is found if all segments are matched */
1391 			if (i == segs_cnt) {
1392 				prof = p;
1393 				break;
1394 			}
1395 		}
1396 	mutex_unlock(&hw->fl_profs_locks[blk]);
1397 
1398 	return prof;
1399 }
1400 
1401 /**
1402  * ice_flow_find_prof_id - Look up a profile with given profile ID
1403  * @hw: pointer to the HW struct
1404  * @blk: classification stage
1405  * @prof_id: unique ID to identify this flow profile
1406  */
1407 static struct ice_flow_prof *
1408 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1409 {
1410 	struct ice_flow_prof *p;
1411 
1412 	list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1413 		if (p->id == prof_id)
1414 			return p;
1415 
1416 	return NULL;
1417 }
1418 
1419 /**
1420  * ice_flow_rem_entry_sync - Remove a flow entry
1421  * @hw: pointer to the HW struct
1422  * @blk: classification stage
1423  * @entry: flow entry to be removed
1424  */
1425 static int
1426 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1427 			struct ice_flow_entry *entry)
1428 {
1429 	if (!entry)
1430 		return -EINVAL;
1431 
1432 	list_del(&entry->l_entry);
1433 
1434 	devm_kfree(ice_hw_to_dev(hw), entry);
1435 
1436 	return 0;
1437 }
1438 
1439 /**
1440  * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1441  * @hw: pointer to the HW struct
1442  * @blk: classification stage
1443  * @dir: flow direction
1444  * @segs: array of one or more packet segments that describe the flow
1445  * @segs_cnt: number of packet segments provided
1446  * @symm: symmetric setting for RSS profiles
1447  * @prof: stores the returned flow profile added
1448  *
1449  * Assumption: the caller has acquired the lock to the profile list
1450  */
1451 static int
1452 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1453 		       enum ice_flow_dir dir,
1454 		       struct ice_flow_seg_info *segs, u8 segs_cnt,
1455 		       bool symm, struct ice_flow_prof **prof)
1456 {
1457 	struct ice_flow_prof_params *params;
1458 	struct ice_prof_id *ids;
1459 	int status;
1460 	u64 prof_id;
1461 	u8 i;
1462 
1463 	if (!prof)
1464 		return -EINVAL;
1465 
1466 	ids = &hw->blk[blk].prof_id;
1467 	prof_id = find_first_zero_bit(ids->id, ids->count);
1468 	if (prof_id >= ids->count)
1469 		return -ENOSPC;
1470 
1471 	params = kzalloc(sizeof(*params), GFP_KERNEL);
1472 	if (!params)
1473 		return -ENOMEM;
1474 
1475 	params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1476 				    GFP_KERNEL);
1477 	if (!params->prof) {
1478 		status = -ENOMEM;
1479 		goto free_params;
1480 	}
1481 
1482 	/* initialize extraction sequence to all invalid (0xff) */
1483 	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1484 		params->es[i].prot_id = ICE_PROT_INVALID;
1485 		params->es[i].off = ICE_FV_OFFSET_INVAL;
1486 	}
1487 
1488 	params->blk = blk;
1489 	params->prof->id = prof_id;
1490 	params->prof->dir = dir;
1491 	params->prof->segs_cnt = segs_cnt;
1492 	params->prof->symm = symm;
1493 
1494 	/* Make a copy of the segments that need to be persistent in the flow
1495 	 * profile instance
1496 	 */
1497 	for (i = 0; i < segs_cnt; i++)
1498 		memcpy(&params->prof->segs[i], &segs[i], sizeof(*segs));
1499 
1500 	status = ice_flow_proc_segs(hw, params);
1501 	if (status) {
1502 		ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1503 		goto out;
1504 	}
1505 
1506 	/* Add a HW profile for this flow profile */
1507 	status = ice_add_prof(hw, blk, prof_id, params->ptypes,
1508 			      params->attr, params->attr_cnt, params->es,
1509 			      params->mask, symm, true);
1510 	if (status) {
1511 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1512 		goto out;
1513 	}
1514 
1515 	INIT_LIST_HEAD(&params->prof->entries);
1516 	mutex_init(&params->prof->entries_lock);
1517 	set_bit(prof_id, ids->id);
1518 	*prof = params->prof;
1519 
1520 out:
1521 	if (status)
1522 		devm_kfree(ice_hw_to_dev(hw), params->prof);
1523 free_params:
1524 	kfree(params);
1525 
1526 	return status;
1527 }
1528 
1529 /**
1530  * ice_flow_rem_prof_sync - remove a flow profile
1531  * @hw: pointer to the hardware structure
1532  * @blk: classification stage
1533  * @prof: pointer to flow profile to remove
1534  *
1535  * Assumption: the caller has acquired the lock to the profile list
1536  */
1537 static int
1538 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1539 		       struct ice_flow_prof *prof)
1540 {
1541 	int status;
1542 
1543 	/* Remove all remaining flow entries before removing the flow profile */
1544 	if (!list_empty(&prof->entries)) {
1545 		struct ice_flow_entry *e, *t;
1546 
1547 		mutex_lock(&prof->entries_lock);
1548 
1549 		list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1550 			status = ice_flow_rem_entry_sync(hw, blk, e);
1551 			if (status)
1552 				break;
1553 		}
1554 
1555 		mutex_unlock(&prof->entries_lock);
1556 	}
1557 
1558 	/* Remove all hardware profiles associated with this flow profile */
1559 	status = ice_rem_prof(hw, blk, prof->id);
1560 	if (!status) {
1561 		clear_bit(prof->id, hw->blk[blk].prof_id.id);
1562 		list_del(&prof->l_entry);
1563 		mutex_destroy(&prof->entries_lock);
1564 		devm_kfree(ice_hw_to_dev(hw), prof);
1565 	}
1566 
1567 	return status;
1568 }
1569 
1570 /**
1571  * ice_flow_assoc_prof - associate a VSI with a flow profile
1572  * @hw: pointer to the hardware structure
1573  * @blk: classification stage
1574  * @prof: pointer to flow profile
1575  * @vsi_handle: software VSI handle
1576  *
1577  * Assumption: the caller has acquired the lock to the profile list
1578  * and the software VSI handle has been validated
1579  */
1580 static int
1581 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1582 		    struct ice_flow_prof *prof, u16 vsi_handle)
1583 {
1584 	int status = 0;
1585 
1586 	if (!test_bit(vsi_handle, prof->vsis)) {
1587 		status = ice_add_prof_id_flow(hw, blk,
1588 					      ice_get_hw_vsi_num(hw,
1589 								 vsi_handle),
1590 					      prof->id);
1591 		if (!status)
1592 			set_bit(vsi_handle, prof->vsis);
1593 		else
1594 			ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1595 				  status);
1596 	}
1597 
1598 	return status;
1599 }
1600 
1601 /**
1602  * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1603  * @hw: pointer to the hardware structure
1604  * @blk: classification stage
1605  * @prof: pointer to flow profile
1606  * @vsi_handle: software VSI handle
1607  *
1608  * Assumption: the caller has acquired the lock to the profile list
1609  * and the software VSI handle has been validated
1610  */
1611 static int
1612 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1613 		       struct ice_flow_prof *prof, u16 vsi_handle)
1614 {
1615 	int status = 0;
1616 
1617 	if (test_bit(vsi_handle, prof->vsis)) {
1618 		status = ice_rem_prof_id_flow(hw, blk,
1619 					      ice_get_hw_vsi_num(hw,
1620 								 vsi_handle),
1621 					      prof->id);
1622 		if (!status)
1623 			clear_bit(vsi_handle, prof->vsis);
1624 		else
1625 			ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1626 				  status);
1627 	}
1628 
1629 	return status;
1630 }
1631 
1632 #define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
1633 #define FLAG_GTP_EH_PDU		BIT_ULL(14)
1634 
1635 #define HI_BYTE_IN_WORD		GENMASK(15, 8)
1636 #define LO_BYTE_IN_WORD		GENMASK(7, 0)
1637 
1638 #define FLAG_GTPU_MSK	\
1639 	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
1640 #define FLAG_GTPU_UP	\
1641 	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
1642 #define FLAG_GTPU_DW	FLAG_GTP_EH_PDU
1643 
1644 /**
1645  * ice_flow_set_parser_prof - Set flow profile based on the parsed profile info
1646  * @hw: pointer to the HW struct
1647  * @dest_vsi: dest VSI
1648  * @fdir_vsi: fdir programming VSI
1649  * @prof: stores parsed profile info from raw flow
1650  * @blk: classification blk
1651  *
1652  * Return: 0 on success or negative errno on failure.
1653  */
1654 int
1655 ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi,
1656 			 struct ice_parser_profile *prof, enum ice_block blk)
1657 {
1658 	u64 id = find_first_bit(prof->ptypes, ICE_FLOW_PTYPE_MAX);
1659 	struct ice_flow_prof_params *params __free(kfree);
1660 	u8 fv_words = hw->blk[blk].es.fvw;
1661 	int status;
1662 	int i, idx;
1663 
1664 	params = kzalloc(sizeof(*params), GFP_KERNEL);
1665 	if (!params)
1666 		return -ENOMEM;
1667 
1668 	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1669 		params->es[i].prot_id = ICE_PROT_INVALID;
1670 		params->es[i].off = ICE_FV_OFFSET_INVAL;
1671 	}
1672 
1673 	for (i = 0; i < prof->fv_num; i++) {
1674 		if (hw->blk[blk].es.reverse)
1675 			idx = fv_words - i - 1;
1676 		else
1677 			idx = i;
1678 		params->es[idx].prot_id = prof->fv[i].proto_id;
1679 		params->es[idx].off = prof->fv[i].offset;
1680 		params->mask[idx] = (((prof->fv[i].msk) << BITS_PER_BYTE) &
1681 				      HI_BYTE_IN_WORD) |
1682 				    (((prof->fv[i].msk) >> BITS_PER_BYTE) &
1683 				      LO_BYTE_IN_WORD);
1684 	}
1685 
1686 	switch (prof->flags) {
1687 	case FLAG_GTPU_DW:
1688 		params->attr = ice_attr_gtpu_down;
1689 		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
1690 		break;
1691 	case FLAG_GTPU_UP:
1692 		params->attr = ice_attr_gtpu_up;
1693 		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
1694 		break;
1695 	default:
1696 		if (prof->flags_msk & FLAG_GTPU_MSK) {
1697 			params->attr = ice_attr_gtpu_session;
1698 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
1699 		}
1700 		break;
1701 	}
1702 
1703 	status = ice_add_prof(hw, blk, id, prof->ptypes,
1704 			      params->attr, params->attr_cnt,
1705 			      params->es, params->mask, false, false);
1706 	if (status)
1707 		return status;
1708 
1709 	status = ice_flow_assoc_fdir_prof(hw, blk, dest_vsi, fdir_vsi, id);
1710 	if (status)
1711 		ice_rem_prof(hw, blk, id);
1712 
1713 	return status;
1714 }
1715 
1716 /**
1717  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1718  * @hw: pointer to the HW struct
1719  * @blk: classification stage
1720  * @dir: flow direction
1721  * @segs: array of one or more packet segments that describe the flow
1722  * @segs_cnt: number of packet segments provided
1723  * @symm: symmetric setting for RSS profiles
1724  * @prof: stores the returned flow profile added
1725  */
1726 int
1727 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1728 		  struct ice_flow_seg_info *segs, u8 segs_cnt,
1729 		  bool symm, struct ice_flow_prof **prof)
1730 {
1731 	int status;
1732 
1733 	if (segs_cnt > ICE_FLOW_SEG_MAX)
1734 		return -ENOSPC;
1735 
1736 	if (!segs_cnt)
1737 		return -EINVAL;
1738 
1739 	if (!segs)
1740 		return -EINVAL;
1741 
1742 	status = ice_flow_val_hdrs(segs, segs_cnt);
1743 	if (status)
1744 		return status;
1745 
1746 	mutex_lock(&hw->fl_profs_locks[blk]);
1747 
1748 	status = ice_flow_add_prof_sync(hw, blk, dir, segs, segs_cnt,
1749 					symm, prof);
1750 	if (!status)
1751 		list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1752 
1753 	mutex_unlock(&hw->fl_profs_locks[blk]);
1754 
1755 	return status;
1756 }
1757 
1758 /**
1759  * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1760  * @hw: pointer to the HW struct
1761  * @blk: the block for which the flow profile is to be removed
1762  * @prof_id: unique ID of the flow profile to be removed
1763  */
1764 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1765 {
1766 	struct ice_flow_prof *prof;
1767 	int status;
1768 
1769 	mutex_lock(&hw->fl_profs_locks[blk]);
1770 
1771 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
1772 	if (!prof) {
1773 		status = -ENOENT;
1774 		goto out;
1775 	}
1776 
1777 	/* prof becomes invalid after the call */
1778 	status = ice_flow_rem_prof_sync(hw, blk, prof);
1779 
1780 out:
1781 	mutex_unlock(&hw->fl_profs_locks[blk]);
1782 
1783 	return status;
1784 }
1785 
1786 /**
1787  * ice_flow_add_entry - Add a flow entry
1788  * @hw: pointer to the HW struct
1789  * @blk: classification stage
1790  * @prof_id: ID of the profile to add a new flow entry to
1791  * @entry_id: unique ID to identify this flow entry
1792  * @vsi_handle: software VSI handle for the flow entry
1793  * @prio: priority of the flow entry
1794  * @data: pointer to a data buffer containing flow entry's match values/masks
1795  * @entry_h: pointer to buffer that receives the new flow entry's handle
1796  */
1797 int
1798 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1799 		   u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1800 		   void *data, u64 *entry_h)
1801 {
1802 	struct ice_flow_entry *e = NULL;
1803 	struct ice_flow_prof *prof;
1804 	int status;
1805 
1806 	/* No flow entry data is expected for RSS */
1807 	if (!entry_h || (!data && blk != ICE_BLK_RSS))
1808 		return -EINVAL;
1809 
1810 	if (!ice_is_vsi_valid(hw, vsi_handle))
1811 		return -EINVAL;
1812 
1813 	mutex_lock(&hw->fl_profs_locks[blk]);
1814 
1815 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
1816 	if (!prof) {
1817 		status = -ENOENT;
1818 	} else {
1819 		/* Allocate memory for the entry being added and associate
1820 		 * the VSI to the found flow profile
1821 		 */
1822 		e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1823 		if (!e)
1824 			status = -ENOMEM;
1825 		else
1826 			status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1827 	}
1828 
1829 	mutex_unlock(&hw->fl_profs_locks[blk]);
1830 	if (status)
1831 		goto out;
1832 
1833 	e->id = entry_id;
1834 	e->vsi_handle = vsi_handle;
1835 	e->prof = prof;
1836 	e->priority = prio;
1837 
1838 	switch (blk) {
1839 	case ICE_BLK_FD:
1840 	case ICE_BLK_RSS:
1841 		break;
1842 	default:
1843 		status = -EOPNOTSUPP;
1844 		goto out;
1845 	}
1846 
1847 	mutex_lock(&prof->entries_lock);
1848 	list_add(&e->l_entry, &prof->entries);
1849 	mutex_unlock(&prof->entries_lock);
1850 
1851 	*entry_h = ICE_FLOW_ENTRY_HNDL(e);
1852 
1853 out:
1854 	if (status)
1855 		devm_kfree(ice_hw_to_dev(hw), e);
1856 
1857 	return status;
1858 }
1859 
1860 /**
1861  * ice_flow_rem_entry - Remove a flow entry
1862  * @hw: pointer to the HW struct
1863  * @blk: classification stage
1864  * @entry_h: handle to the flow entry to be removed
1865  */
1866 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1867 {
1868 	struct ice_flow_entry *entry;
1869 	struct ice_flow_prof *prof;
1870 	int status = 0;
1871 
1872 	if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1873 		return -EINVAL;
1874 
1875 	entry = ICE_FLOW_ENTRY_PTR(entry_h);
1876 
1877 	/* Retain the pointer to the flow profile as the entry will be freed */
1878 	prof = entry->prof;
1879 
1880 	if (prof) {
1881 		mutex_lock(&prof->entries_lock);
1882 		status = ice_flow_rem_entry_sync(hw, blk, entry);
1883 		mutex_unlock(&prof->entries_lock);
1884 	}
1885 
1886 	return status;
1887 }
1888 
1889 /**
1890  * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1891  * @seg: packet segment the field being set belongs to
1892  * @fld: field to be set
1893  * @field_type: type of the field
1894  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1895  *           entry's input buffer
1896  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1897  *            input buffer
1898  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1899  *            entry's input buffer
1900  *
1901  * This helper function stores information of a field being matched, including
1902  * the type of the field and the locations of the value to match, the mask, and
1903  * the upper-bound value in the start of the input buffer for a flow entry.
1904  * This function should only be used for fixed-size data structures.
1905  *
1906  * This function also opportunistically determines the protocol headers to be
1907  * present based on the fields being set. Some fields cannot be used alone to
1908  * determine the protocol headers present. Sometimes, fields for particular
1909  * protocol headers are not matched. In those cases, the protocol headers
1910  * must be explicitly set.
1911  */
1912 static void
1913 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1914 		     enum ice_flow_fld_match_type field_type, u16 val_loc,
1915 		     u16 mask_loc, u16 last_loc)
1916 {
1917 	u64 bit = BIT_ULL(fld);
1918 
1919 	seg->match |= bit;
1920 	if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1921 		seg->range |= bit;
1922 
1923 	seg->fields[fld].type = field_type;
1924 	seg->fields[fld].src.val = val_loc;
1925 	seg->fields[fld].src.mask = mask_loc;
1926 	seg->fields[fld].src.last = last_loc;
1927 
1928 	ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1929 }
1930 
1931 /**
1932  * ice_flow_set_fld - specifies locations of field from entry's input buffer
1933  * @seg: packet segment the field being set belongs to
1934  * @fld: field to be set
1935  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1936  *           entry's input buffer
1937  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1938  *            input buffer
1939  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1940  *            entry's input buffer
1941  * @range: indicate if field being matched is to be in a range
1942  *
1943  * This function specifies the locations, in the form of byte offsets from the
1944  * start of the input buffer for a flow entry, from where the value to match,
1945  * the mask value, and upper value can be extracted. These locations are then
1946  * stored in the flow profile. When adding a flow entry associated with the
1947  * flow profile, these locations will be used to quickly extract the values and
1948  * create the content of a match entry. This function should only be used for
1949  * fixed-size data structures.
1950  */
1951 void
1952 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1953 		 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1954 {
1955 	enum ice_flow_fld_match_type t = range ?
1956 		ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1957 
1958 	ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1959 }
1960 
1961 /**
1962  * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1963  * @seg: packet segment the field being set belongs to
1964  * @off: offset of the raw field from the beginning of the segment in bytes
1965  * @len: length of the raw pattern to be matched
1966  * @val_loc: location of the value to match from entry's input buffer
1967  * @mask_loc: location of mask value from entry's input buffer
1968  *
1969  * This function specifies the offset of the raw field to be match from the
1970  * beginning of the specified packet segment, and the locations, in the form of
1971  * byte offsets from the start of the input buffer for a flow entry, from where
1972  * the value to match and the mask value to be extracted. These locations are
1973  * then stored in the flow profile. When adding flow entries to the associated
1974  * flow profile, these locations can be used to quickly extract the values to
1975  * create the content of a match entry. This function should only be used for
1976  * fixed-size data structures.
1977  */
1978 void
1979 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1980 		     u16 val_loc, u16 mask_loc)
1981 {
1982 	if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1983 		seg->raws[seg->raws_cnt].off = off;
1984 		seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1985 		seg->raws[seg->raws_cnt].info.src.val = val_loc;
1986 		seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1987 		/* The "last" field is used to store the length of the field */
1988 		seg->raws[seg->raws_cnt].info.src.last = len;
1989 	}
1990 
1991 	/* Overflows of "raws" will be handled as an error condition later in
1992 	 * the flow when this information is processed.
1993 	 */
1994 	seg->raws_cnt++;
1995 }
1996 
1997 /**
1998  * ice_flow_rem_vsi_prof - remove VSI from flow profile
1999  * @hw: pointer to the hardware structure
2000  * @vsi_handle: software VSI handle
2001  * @prof_id: unique ID to identify this flow profile
2002  *
2003  * This function removes the flow entries associated to the input
2004  * VSI handle and disassociate the VSI from the flow profile.
2005  */
2006 int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
2007 {
2008 	struct ice_flow_prof *prof;
2009 	int status = 0;
2010 
2011 	if (!ice_is_vsi_valid(hw, vsi_handle))
2012 		return -EINVAL;
2013 
2014 	/* find flow profile pointer with input package block and profile ID */
2015 	prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
2016 	if (!prof) {
2017 		ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
2018 			  prof_id);
2019 		return -ENOENT;
2020 	}
2021 
2022 	/* Remove all remaining flow entries before removing the flow profile */
2023 	if (!list_empty(&prof->entries)) {
2024 		struct ice_flow_entry *e, *t;
2025 
2026 		mutex_lock(&prof->entries_lock);
2027 		list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
2028 			if (e->vsi_handle != vsi_handle)
2029 				continue;
2030 
2031 			status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
2032 			if (status)
2033 				break;
2034 		}
2035 		mutex_unlock(&prof->entries_lock);
2036 	}
2037 	if (status)
2038 		return status;
2039 
2040 	/* disassociate the flow profile from sw VSI handle */
2041 	status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
2042 	if (status)
2043 		ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
2044 			  status);
2045 	return status;
2046 }
2047 
2048 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
2049 	(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
2050 
2051 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
2052 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
2053 
2054 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
2055 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
2056 
2057 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
2058 	(ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
2059 	 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
2060 	 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
2061 
2062 /**
2063  * ice_flow_set_rss_seg_info - setup packet segments for RSS
2064  * @segs: pointer to the flow field segment(s)
2065  * @seg_cnt: segment count
2066  * @cfg: configure parameters
2067  *
2068  * Helper function to extract fields from hash bitmap and use flow
2069  * header value to set flow field segment for further use in flow
2070  * profile entry or removal.
2071  */
2072 static int
2073 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
2074 			  const struct ice_rss_hash_cfg *cfg)
2075 {
2076 	struct ice_flow_seg_info *seg;
2077 	u64 val;
2078 	u16 i;
2079 
2080 	/* set inner most segment */
2081 	seg = &segs[seg_cnt - 1];
2082 
2083 	for_each_set_bit(i, (const unsigned long *)&cfg->hash_flds,
2084 			 (u16)ICE_FLOW_FIELD_IDX_MAX)
2085 		ice_flow_set_fld(seg, (enum ice_flow_field)i,
2086 				 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
2087 				 ICE_FLOW_FLD_OFF_INVAL, false);
2088 
2089 	ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs);
2090 
2091 	/* set outer most header */
2092 	if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
2093 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
2094 						    ICE_FLOW_SEG_HDR_IPV_OTHER;
2095 	else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
2096 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
2097 						    ICE_FLOW_SEG_HDR_IPV_OTHER;
2098 
2099 	if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
2100 	    ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
2101 		return -EINVAL;
2102 
2103 	val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
2104 	if (val && !is_power_of_2(val))
2105 		return -EIO;
2106 
2107 	val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
2108 	if (val && !is_power_of_2(val))
2109 		return -EIO;
2110 
2111 	return 0;
2112 }
2113 
2114 /**
2115  * ice_rem_vsi_rss_list - remove VSI from RSS list
2116  * @hw: pointer to the hardware structure
2117  * @vsi_handle: software VSI handle
2118  *
2119  * Remove the VSI from all RSS configurations in the list.
2120  */
2121 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
2122 {
2123 	struct ice_rss_cfg *r, *tmp;
2124 
2125 	if (list_empty(&hw->rss_list_head))
2126 		return;
2127 
2128 	mutex_lock(&hw->rss_locks);
2129 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
2130 		if (test_and_clear_bit(vsi_handle, r->vsis))
2131 			if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2132 				list_del(&r->l_entry);
2133 				devm_kfree(ice_hw_to_dev(hw), r);
2134 			}
2135 	mutex_unlock(&hw->rss_locks);
2136 }
2137 
2138 /**
2139  * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
2140  * @hw: pointer to the hardware structure
2141  * @vsi_handle: software VSI handle
2142  *
2143  * This function will iterate through all flow profiles and disassociate
2144  * the VSI from that profile. If the flow profile has no VSIs it will
2145  * be removed.
2146  */
2147 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2148 {
2149 	const enum ice_block blk = ICE_BLK_RSS;
2150 	struct ice_flow_prof *p, *t;
2151 	int status = 0;
2152 
2153 	if (!ice_is_vsi_valid(hw, vsi_handle))
2154 		return -EINVAL;
2155 
2156 	if (list_empty(&hw->fl_profs[blk]))
2157 		return 0;
2158 
2159 	mutex_lock(&hw->rss_locks);
2160 	list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
2161 		if (test_bit(vsi_handle, p->vsis)) {
2162 			status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
2163 			if (status)
2164 				break;
2165 
2166 			if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
2167 				status = ice_flow_rem_prof(hw, blk, p->id);
2168 				if (status)
2169 					break;
2170 			}
2171 		}
2172 	mutex_unlock(&hw->rss_locks);
2173 
2174 	return status;
2175 }
2176 
2177 /**
2178  * ice_get_rss_hdr_type - get a RSS profile's header type
2179  * @prof: RSS flow profile
2180  */
2181 static enum ice_rss_cfg_hdr_type
2182 ice_get_rss_hdr_type(struct ice_flow_prof *prof)
2183 {
2184 	if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) {
2185 		return ICE_RSS_OUTER_HEADERS;
2186 	} else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) {
2187 		const struct ice_flow_seg_info *s;
2188 
2189 		s = &prof->segs[ICE_RSS_OUTER_HEADERS];
2190 		if (s->hdrs == ICE_FLOW_SEG_HDR_NONE)
2191 			return ICE_RSS_INNER_HEADERS;
2192 		if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4)
2193 			return ICE_RSS_INNER_HEADERS_W_OUTER_IPV4;
2194 		if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6)
2195 			return ICE_RSS_INNER_HEADERS_W_OUTER_IPV6;
2196 	}
2197 
2198 	return ICE_RSS_ANY_HEADERS;
2199 }
2200 
2201 static bool
2202 ice_rss_match_prof(struct ice_rss_cfg *r, struct ice_flow_prof *prof,
2203 		   enum ice_rss_cfg_hdr_type hdr_type)
2204 {
2205 	return (r->hash.hdr_type == hdr_type &&
2206 		r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match &&
2207 		r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs);
2208 }
2209 
2210 /**
2211  * ice_rem_rss_list - remove RSS configuration from list
2212  * @hw: pointer to the hardware structure
2213  * @vsi_handle: software VSI handle
2214  * @prof: pointer to flow profile
2215  *
2216  * Assumption: lock has already been acquired for RSS list
2217  */
2218 static void
2219 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2220 {
2221 	enum ice_rss_cfg_hdr_type hdr_type;
2222 	struct ice_rss_cfg *r, *tmp;
2223 
2224 	/* Search for RSS hash fields associated to the VSI that match the
2225 	 * hash configurations associated to the flow profile. If found
2226 	 * remove from the RSS entry list of the VSI context and delete entry.
2227 	 */
2228 	hdr_type = ice_get_rss_hdr_type(prof);
2229 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
2230 		if (ice_rss_match_prof(r, prof, hdr_type)) {
2231 			clear_bit(vsi_handle, r->vsis);
2232 			if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2233 				list_del(&r->l_entry);
2234 				devm_kfree(ice_hw_to_dev(hw), r);
2235 			}
2236 			return;
2237 		}
2238 }
2239 
2240 /**
2241  * ice_add_rss_list - add RSS configuration to list
2242  * @hw: pointer to the hardware structure
2243  * @vsi_handle: software VSI handle
2244  * @prof: pointer to flow profile
2245  *
2246  * Assumption: lock has already been acquired for RSS list
2247  */
2248 static int
2249 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2250 {
2251 	enum ice_rss_cfg_hdr_type hdr_type;
2252 	struct ice_rss_cfg *r, *rss_cfg;
2253 
2254 	hdr_type = ice_get_rss_hdr_type(prof);
2255 	list_for_each_entry(r, &hw->rss_list_head, l_entry)
2256 		if (ice_rss_match_prof(r, prof, hdr_type)) {
2257 			set_bit(vsi_handle, r->vsis);
2258 			return 0;
2259 		}
2260 
2261 	rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2262 			       GFP_KERNEL);
2263 	if (!rss_cfg)
2264 		return -ENOMEM;
2265 
2266 	rss_cfg->hash.hash_flds = prof->segs[prof->segs_cnt - 1].match;
2267 	rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs;
2268 	rss_cfg->hash.hdr_type = hdr_type;
2269 	rss_cfg->hash.symm = prof->symm;
2270 	set_bit(vsi_handle, rss_cfg->vsis);
2271 
2272 	list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2273 
2274 	return 0;
2275 }
2276 
2277 /**
2278  * ice_rss_config_xor_word - set the HSYMM registers for one input set word
2279  * @hw: pointer to the hardware structure
2280  * @prof_id: RSS hardware profile id
2281  * @src: the FV index used by the protocol's source field
2282  * @dst: the FV index used by the protocol's destination field
2283  *
2284  * Write to the HSYMM register with the index of @src FV the value of the @dst
2285  * FV index. This will tell the hardware to XOR HSYMM[src] with INSET[dst]
2286  * while calculating the RSS input set.
2287  */
2288 static void
2289 ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst)
2290 {
2291 	u32 val, reg, bits_shift;
2292 	u8 reg_idx;
2293 
2294 	reg_idx = src / GLQF_HSYMM_REG_SIZE;
2295 	bits_shift = ((src % GLQF_HSYMM_REG_SIZE) << 3);
2296 	val = dst | GLQF_HSYMM_ENABLE_BIT;
2297 
2298 	reg = rd32(hw, GLQF_HSYMM(prof_id, reg_idx));
2299 	reg = (reg & ~(0xff << bits_shift)) | (val << bits_shift);
2300 	wr32(hw, GLQF_HSYMM(prof_id, reg_idx), reg);
2301 }
2302 
2303 /**
2304  * ice_rss_config_xor - set the symmetric registers for a profile's protocol
2305  * @hw: pointer to the hardware structure
2306  * @prof_id: RSS hardware profile id
2307  * @src: the FV index used by the protocol's source field
2308  * @dst: the FV index used by the protocol's destination field
2309  * @len: length of the source/destination fields in words
2310  */
2311 static void
2312 ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len)
2313 {
2314 	int fv_last_word =
2315 		ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1;
2316 	int i;
2317 
2318 	for (i = 0; i < len; i++) {
2319 		ice_rss_config_xor_word(hw, prof_id,
2320 					/* Yes, field vector in GLQF_HSYMM and
2321 					 * GLQF_HINSET is inversed!
2322 					 */
2323 					fv_last_word - (src + i),
2324 					fv_last_word - (dst + i));
2325 		ice_rss_config_xor_word(hw, prof_id,
2326 					fv_last_word - (dst + i),
2327 					fv_last_word - (src + i));
2328 	}
2329 }
2330 
2331 /**
2332  * ice_rss_set_symm - set the symmetric settings for an RSS profile
2333  * @hw: pointer to the hardware structure
2334  * @prof: pointer to flow profile
2335  *
2336  * The symmetric hash will result from XORing the protocol's fields with
2337  * indexes in GLQF_HSYMM and GLQF_HINSET. This function configures the profile's
2338  * GLQF_HSYMM registers.
2339  */
2340 static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof)
2341 {
2342 	struct ice_prof_map *map;
2343 	u8 prof_id, m;
2344 
2345 	mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2346 	map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id);
2347 	if (map)
2348 		prof_id = map->prof_id;
2349 	mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2350 
2351 	if (!map)
2352 		return;
2353 
2354 	/* clear to default */
2355 	for (m = 0; m < GLQF_HSYMM_REG_PER_PROF; m++)
2356 		wr32(hw, GLQF_HSYMM(prof_id, m), 0);
2357 
2358 	if (prof->symm) {
2359 		struct ice_flow_seg_xtrct *ipv4_src, *ipv4_dst;
2360 		struct ice_flow_seg_xtrct *ipv6_src, *ipv6_dst;
2361 		struct ice_flow_seg_xtrct *sctp_src, *sctp_dst;
2362 		struct ice_flow_seg_xtrct *tcp_src, *tcp_dst;
2363 		struct ice_flow_seg_xtrct *udp_src, *udp_dst;
2364 		struct ice_flow_seg_info *seg;
2365 
2366 		seg = &prof->segs[prof->segs_cnt - 1];
2367 
2368 		ipv4_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct;
2369 		ipv4_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct;
2370 
2371 		ipv6_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct;
2372 		ipv6_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct;
2373 
2374 		tcp_src = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct;
2375 		tcp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct;
2376 
2377 		udp_src = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct;
2378 		udp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct;
2379 
2380 		sctp_src = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct;
2381 		sctp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct;
2382 
2383 		/* xor IPv4 */
2384 		if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0)
2385 			ice_rss_config_xor(hw, prof_id,
2386 					   ipv4_src->idx, ipv4_dst->idx, 2);
2387 
2388 		/* xor IPv6 */
2389 		if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0)
2390 			ice_rss_config_xor(hw, prof_id,
2391 					   ipv6_src->idx, ipv6_dst->idx, 8);
2392 
2393 		/* xor TCP */
2394 		if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0)
2395 			ice_rss_config_xor(hw, prof_id,
2396 					   tcp_src->idx, tcp_dst->idx, 1);
2397 
2398 		/* xor UDP */
2399 		if (udp_src->prot_id != 0 && udp_dst->prot_id != 0)
2400 			ice_rss_config_xor(hw, prof_id,
2401 					   udp_src->idx, udp_dst->idx, 1);
2402 
2403 		/* xor SCTP */
2404 		if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0)
2405 			ice_rss_config_xor(hw, prof_id,
2406 					   sctp_src->idx, sctp_dst->idx, 1);
2407 	}
2408 }
2409 
2410 /**
2411  * ice_rss_cfg_raw_symm - Configure symmetric RSS for a raw parser profile
2412  * @hw:      device HW
2413  * @prof:    parser profile describing extracted FV (field vector) entries
2414  * @prof_id: RSS profile identifier used to program symmetry registers
2415  *
2416  * The routine scans the parser profile's FV entries and looks for
2417  * direction-sensitive pairs (L3 src/dst, L4 src/dst). When a pair is found,
2418  * it programs XOR-based symmetry so that flows hash identically regardless
2419  * of packet direction. This preserves CPU affinity for the same 5-tuple.
2420  *
2421  * Notes:
2422  * - The size of each logical field (IPv4/IPv6 address, L4 port) is expressed
2423  *   in units of ICE_FLOW_FV_EXTRACT_SZ so we can step across fv[] correctly.
2424  * - We guard against out-of-bounds access before looking at fv[i + len].
2425  */
2426 static void ice_rss_cfg_raw_symm(struct ice_hw *hw,
2427 				 const struct ice_parser_profile *prof,
2428 				 u64 prof_id)
2429 {
2430 	for (size_t i = 0; i < prof->fv_num; i++) {
2431 		u8 proto_id = prof->fv[i].proto_id;
2432 		u16 src_off = 0, dst_off = 0;
2433 		size_t src_idx, dst_idx;
2434 		bool is_matched = false;
2435 		unsigned int len = 0;
2436 
2437 		switch (proto_id) {
2438 		/* IPv4 address pairs (outer/inner variants) */
2439 		case ICE_PROT_IPV4_OF_OR_S:
2440 		case ICE_PROT_IPV4_IL:
2441 		case ICE_PROT_IPV4_IL_IL:
2442 			len = ICE_FLOW_FLD_SZ_IPV4_ADDR /
2443 			      ICE_FLOW_FV_EXTRACT_SZ;
2444 			src_off = ICE_FLOW_FIELD_IPV4_SRC_OFFSET;
2445 			dst_off = ICE_FLOW_FIELD_IPV4_DST_OFFSET;
2446 			break;
2447 
2448 		/* IPv6 address pairs (outer/inner variants) */
2449 		case ICE_PROT_IPV6_OF_OR_S:
2450 		case ICE_PROT_IPV6_IL:
2451 		case ICE_PROT_IPV6_IL_IL:
2452 			len = ICE_FLOW_FLD_SZ_IPV6_ADDR /
2453 			      ICE_FLOW_FV_EXTRACT_SZ;
2454 			src_off = ICE_FLOW_FIELD_IPV6_SRC_OFFSET;
2455 			dst_off = ICE_FLOW_FIELD_IPV6_DST_OFFSET;
2456 			break;
2457 
2458 		/* L4 port pairs (TCP/UDP/SCTP) */
2459 		case ICE_PROT_TCP_IL:
2460 		case ICE_PROT_UDP_IL_OR_S:
2461 		case ICE_PROT_SCTP_IL:
2462 			len = ICE_FLOW_FLD_SZ_PORT / ICE_FLOW_FV_EXTRACT_SZ;
2463 			src_off = ICE_FLOW_FIELD_SRC_PORT_OFFSET;
2464 			dst_off = ICE_FLOW_FIELD_DST_PORT_OFFSET;
2465 			break;
2466 
2467 		default:
2468 			continue;
2469 		}
2470 
2471 		/* Bounds check before accessing fv[i + len]. */
2472 		if (i + len >= prof->fv_num)
2473 			continue;
2474 
2475 		/* Verify src/dst pairing for this protocol id. */
2476 		is_matched = prof->fv[i].offset == src_off &&
2477 			     prof->fv[i + len].proto_id == proto_id &&
2478 			     prof->fv[i + len].offset == dst_off;
2479 		if (!is_matched)
2480 			continue;
2481 
2482 		/* Program XOR symmetry for this field pair. */
2483 		src_idx = i;
2484 		dst_idx = i + len;
2485 
2486 		ice_rss_config_xor(hw, prof_id, src_idx, dst_idx, len);
2487 
2488 		/* Skip over the pair we just handled; the loop's ++i advances
2489 		 * one more element, hence the --i after the jump.
2490 		 */
2491 		i += (2 * len);
2492 		/* not strictly needed; keeps static analyzers happy */
2493 		if (i == 0)
2494 			break;
2495 		--i;
2496 	}
2497 }
2498 
2499 /* Max registers index per packet profile */
2500 #define ICE_SYMM_REG_INDEX_MAX 6
2501 
2502 /**
2503  * ice_rss_update_raw_symm - update symmetric hash configuration
2504  * for raw pattern
2505  * @hw: pointer to the hardware structure
2506  * @cfg: configure parameters for raw pattern
2507  * @id: profile tracking ID
2508  *
2509  * Update symmetric hash configuration for raw pattern if required.
2510  * Otherwise only clear to default.
2511  */
2512 void
2513 ice_rss_update_raw_symm(struct ice_hw *hw,
2514 			struct ice_rss_raw_cfg *cfg, u64 id)
2515 {
2516 	struct ice_prof_map *map;
2517 	u8 prof_id, m;
2518 
2519 	mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2520 	map = ice_search_prof_id(hw, ICE_BLK_RSS, id);
2521 	if (map)
2522 		prof_id = map->prof_id;
2523 	mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2524 	if (!map)
2525 		return;
2526 	/* clear to default */
2527 	for (m = 0; m < ICE_SYMM_REG_INDEX_MAX; m++)
2528 		wr32(hw, GLQF_HSYMM(prof_id, m), 0);
2529 
2530 	if (cfg->symm)
2531 		ice_rss_cfg_raw_symm(hw, &cfg->prof, prof_id);
2532 }
2533 
2534 /**
2535  * ice_add_rss_cfg_sync - add an RSS configuration
2536  * @hw: pointer to the hardware structure
2537  * @vsi_handle: software VSI handle
2538  * @cfg: configure parameters
2539  *
2540  * Assumption: lock has already been acquired for RSS list
2541  */
2542 static int
2543 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
2544 		     const struct ice_rss_hash_cfg *cfg)
2545 {
2546 	const enum ice_block blk = ICE_BLK_RSS;
2547 	struct ice_flow_prof *prof = NULL;
2548 	struct ice_flow_seg_info *segs;
2549 	u8 segs_cnt;
2550 	int status;
2551 
2552 	segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
2553 			ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
2554 
2555 	segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2556 	if (!segs)
2557 		return -ENOMEM;
2558 
2559 	/* Construct the packet segment info from the hashed fields */
2560 	status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
2561 	if (status)
2562 		goto exit;
2563 
2564 	/* Search for a flow profile that has matching headers, hash fields,
2565 	 * symm and has the input VSI associated to it. If found, no further
2566 	 * operations required and exit.
2567 	 */
2568 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2569 					cfg->symm, vsi_handle,
2570 					ICE_FLOW_FIND_PROF_CHK_FLDS |
2571 					ICE_FLOW_FIND_PROF_CHK_SYMM |
2572 					ICE_FLOW_FIND_PROF_CHK_VSI);
2573 	if (prof)
2574 		goto exit;
2575 
2576 	/* Check if a flow profile exists with the same protocol headers and
2577 	 * associated with the input VSI. If so disassociate the VSI from
2578 	 * this profile. The VSI will be added to a new profile created with
2579 	 * the protocol header and new hash field configuration.
2580 	 */
2581 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2582 					cfg->symm, vsi_handle,
2583 					ICE_FLOW_FIND_PROF_CHK_VSI);
2584 	if (prof) {
2585 		status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2586 		if (!status)
2587 			ice_rem_rss_list(hw, vsi_handle, prof);
2588 		else
2589 			goto exit;
2590 
2591 		/* Remove profile if it has no VSIs associated */
2592 		if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2593 			status = ice_flow_rem_prof(hw, blk, prof->id);
2594 			if (status)
2595 				goto exit;
2596 		}
2597 	}
2598 
2599 	/* Search for a profile that has the same match fields and symmetric
2600 	 * setting. If this exists then associate the VSI to this profile.
2601 	 */
2602 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2603 					cfg->symm, vsi_handle,
2604 					ICE_FLOW_FIND_PROF_CHK_SYMM |
2605 					ICE_FLOW_FIND_PROF_CHK_FLDS);
2606 	if (prof) {
2607 		status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2608 		if (!status)
2609 			status = ice_add_rss_list(hw, vsi_handle, prof);
2610 		goto exit;
2611 	}
2612 
2613 	/* Create a new flow profile with packet segment information. */
2614 	status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2615 				   segs, segs_cnt, cfg->symm, &prof);
2616 	if (status)
2617 		goto exit;
2618 
2619 	prof->symm = cfg->symm;
2620 	ice_rss_set_symm(hw, prof);
2621 	status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2622 	/* If association to a new flow profile failed then this profile can
2623 	 * be removed.
2624 	 */
2625 	if (status) {
2626 		ice_flow_rem_prof(hw, blk, prof->id);
2627 		goto exit;
2628 	}
2629 
2630 	status = ice_add_rss_list(hw, vsi_handle, prof);
2631 
2632 exit:
2633 	kfree(segs);
2634 	return status;
2635 }
2636 
2637 /**
2638  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2639  * @hw: pointer to the hardware structure
2640  * @vsi: VSI to add the RSS configuration to
2641  * @cfg: configure parameters
2642  *
2643  * This function will generate a flow profile based on fields associated with
2644  * the input fields to hash on, the flow type and use the VSI number to add
2645  * a flow entry to the profile.
2646  */
2647 int
2648 ice_add_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi,
2649 		const struct ice_rss_hash_cfg *cfg)
2650 {
2651 	struct ice_rss_hash_cfg local_cfg;
2652 	u16 vsi_handle;
2653 	int status;
2654 
2655 	if (!vsi)
2656 		return -EINVAL;
2657 
2658 	vsi_handle = vsi->idx;
2659 	if (!ice_is_vsi_valid(hw, vsi_handle) ||
2660 	    !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
2661 	    cfg->hash_flds == ICE_HASH_INVALID)
2662 		return -EINVAL;
2663 
2664 	mutex_lock(&hw->rss_locks);
2665 	local_cfg = *cfg;
2666 	if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
2667 		status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2668 	} else {
2669 		local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
2670 		status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2671 		if (!status) {
2672 			local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
2673 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
2674 						      &local_cfg);
2675 		}
2676 	}
2677 	mutex_unlock(&hw->rss_locks);
2678 
2679 	return status;
2680 }
2681 
2682 /**
2683  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2684  * @hw: pointer to the hardware structure
2685  * @vsi_handle: software VSI handle
2686  * @cfg: configure parameters
2687  *
2688  * Assumption: lock has already been acquired for RSS list
2689  */
2690 static int
2691 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
2692 		     const struct ice_rss_hash_cfg *cfg)
2693 {
2694 	const enum ice_block blk = ICE_BLK_RSS;
2695 	struct ice_flow_seg_info *segs;
2696 	struct ice_flow_prof *prof;
2697 	u8 segs_cnt;
2698 	int status;
2699 
2700 	segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
2701 			ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
2702 	segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2703 	if (!segs)
2704 		return -ENOMEM;
2705 
2706 	/* Construct the packet segment info from the hashed fields */
2707 	status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
2708 	if (status)
2709 		goto out;
2710 
2711 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2712 					cfg->symm, vsi_handle,
2713 					ICE_FLOW_FIND_PROF_CHK_FLDS);
2714 	if (!prof) {
2715 		status = -ENOENT;
2716 		goto out;
2717 	}
2718 
2719 	status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2720 	if (status)
2721 		goto out;
2722 
2723 	/* Remove RSS configuration from VSI context before deleting
2724 	 * the flow profile.
2725 	 */
2726 	ice_rem_rss_list(hw, vsi_handle, prof);
2727 
2728 	if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2729 		status = ice_flow_rem_prof(hw, blk, prof->id);
2730 
2731 out:
2732 	kfree(segs);
2733 	return status;
2734 }
2735 
2736 /**
2737  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2738  * @hw: pointer to the hardware structure
2739  * @vsi_handle: software VSI handle
2740  * @cfg: configure parameters
2741  *
2742  * This function will lookup the flow profile based on the input
2743  * hash field bitmap, iterate through the profile entry list of
2744  * that profile and find entry associated with input VSI to be
2745  * removed. Calls are made to underlying flow apis which will in
2746  * turn build or update buffers for RSS XLT1 section.
2747  */
2748 int
2749 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
2750 		const struct ice_rss_hash_cfg *cfg)
2751 {
2752 	struct ice_rss_hash_cfg local_cfg;
2753 	int status;
2754 
2755 	if (!ice_is_vsi_valid(hw, vsi_handle) ||
2756 	    !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
2757 	    cfg->hash_flds == ICE_HASH_INVALID)
2758 		return -EINVAL;
2759 
2760 	mutex_lock(&hw->rss_locks);
2761 	local_cfg = *cfg;
2762 	if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
2763 		status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2764 	} else {
2765 		local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
2766 		status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2767 		if (!status) {
2768 			local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
2769 			status = ice_rem_rss_cfg_sync(hw, vsi_handle,
2770 						      &local_cfg);
2771 		}
2772 	}
2773 	mutex_unlock(&hw->rss_locks);
2774 
2775 	return status;
2776 }
2777 
2778 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2779  * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2780  * convert its values to their appropriate flow L3, L4 values.
2781  */
2782 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2783 	(BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_OTHER) | \
2784 	 BIT_ULL(LIBIE_FILTER_PCTYPE_FRAG_IPV4))
2785 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2786 	(BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK) | \
2787 	 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_TCP))
2788 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2789 	(BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | \
2790 	 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | \
2791 	 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_UDP))
2792 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2793 	(ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2794 	 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_SCTP))
2795 
2796 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2797 	(BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_OTHER) | \
2798 	 BIT_ULL(LIBIE_FILTER_PCTYPE_FRAG_IPV6))
2799 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2800 	(BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | \
2801 	 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) | \
2802 	 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_UDP))
2803 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2804 	(BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK) | \
2805 	 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_TCP))
2806 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2807 	(ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2808 	 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_SCTP))
2809 
2810 /**
2811  * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2812  * @hw: pointer to the hardware structure
2813  * @vsi: VF's VSI
2814  * @avf_hash: hash bit fields (LIBIE_FILTER_PCTYPE_*) to configure
2815  *
2816  * This function will take the hash bitmap provided by the AVF driver via a
2817  * message, convert it to ICE-compatible values, and configure RSS flow
2818  * profiles.
2819  */
2820 int ice_add_avf_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi, u64 avf_hash)
2821 {
2822 	struct ice_rss_hash_cfg hcfg;
2823 	u16 vsi_handle;
2824 	int status = 0;
2825 	u64 hash_flds;
2826 
2827 	if (!vsi)
2828 		return -EINVAL;
2829 
2830 	vsi_handle = vsi->idx;
2831 	if (!avf_hash || !ice_is_vsi_valid(hw, vsi_handle))
2832 		return -EINVAL;
2833 
2834 	/* Make sure no unsupported bits are specified */
2835 	if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2836 			 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2837 		return -EIO;
2838 
2839 	hash_flds = avf_hash;
2840 
2841 	/* Always create an L3 RSS configuration for any L4 RSS configuration */
2842 	if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2843 		hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2844 
2845 	if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2846 		hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2847 
2848 	/* Create the corresponding RSS configuration for each valid hash bit */
2849 	while (hash_flds) {
2850 		u64 rss_hash = ICE_HASH_INVALID;
2851 
2852 		if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2853 			if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2854 				rss_hash = ICE_FLOW_HASH_IPV4;
2855 				hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2856 			} else if (hash_flds &
2857 				   ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2858 				rss_hash = ICE_FLOW_HASH_IPV4 |
2859 					ICE_FLOW_HASH_TCP_PORT;
2860 				hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2861 			} else if (hash_flds &
2862 				   ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2863 				rss_hash = ICE_FLOW_HASH_IPV4 |
2864 					ICE_FLOW_HASH_UDP_PORT;
2865 				hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2866 			} else if (hash_flds &
2867 				   BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_SCTP)) {
2868 				rss_hash = ICE_FLOW_HASH_IPV4 |
2869 					ICE_FLOW_HASH_SCTP_PORT;
2870 				hash_flds &=
2871 					~BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_SCTP);
2872 			}
2873 		} else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2874 			if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2875 				rss_hash = ICE_FLOW_HASH_IPV6;
2876 				hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2877 			} else if (hash_flds &
2878 				   ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2879 				rss_hash = ICE_FLOW_HASH_IPV6 |
2880 					ICE_FLOW_HASH_TCP_PORT;
2881 				hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2882 			} else if (hash_flds &
2883 				   ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2884 				rss_hash = ICE_FLOW_HASH_IPV6 |
2885 					ICE_FLOW_HASH_UDP_PORT;
2886 				hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2887 			} else if (hash_flds &
2888 				   BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_SCTP)) {
2889 				rss_hash = ICE_FLOW_HASH_IPV6 |
2890 					ICE_FLOW_HASH_SCTP_PORT;
2891 				hash_flds &=
2892 					~BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_SCTP);
2893 			}
2894 		}
2895 
2896 		if (rss_hash == ICE_HASH_INVALID)
2897 			return -EIO;
2898 
2899 		hcfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
2900 		hcfg.hash_flds = rss_hash;
2901 		hcfg.hdr_type = ICE_RSS_ANY_HEADERS;
2902 		hcfg.symm = false;
2903 		status = ice_add_rss_cfg(hw, vsi, &hcfg);
2904 		if (status)
2905 			break;
2906 	}
2907 
2908 	return status;
2909 }
2910 
2911 static bool rss_cfg_symm_valid(u64 hfld)
2912 {
2913 	return !((!!(hfld & ICE_FLOW_HASH_FLD_IPV4_SA) ^
2914 		  !!(hfld & ICE_FLOW_HASH_FLD_IPV4_DA)) ||
2915 		 (!!(hfld & ICE_FLOW_HASH_FLD_IPV6_SA) ^
2916 		  !!(hfld & ICE_FLOW_HASH_FLD_IPV6_DA)) ||
2917 		 (!!(hfld & ICE_FLOW_HASH_FLD_TCP_SRC_PORT) ^
2918 		  !!(hfld & ICE_FLOW_HASH_FLD_TCP_DST_PORT)) ||
2919 		 (!!(hfld & ICE_FLOW_HASH_FLD_UDP_SRC_PORT) ^
2920 		  !!(hfld & ICE_FLOW_HASH_FLD_UDP_DST_PORT)) ||
2921 		 (!!(hfld & ICE_FLOW_HASH_FLD_SCTP_SRC_PORT) ^
2922 		  !!(hfld & ICE_FLOW_HASH_FLD_SCTP_DST_PORT)));
2923 }
2924 
2925 /**
2926  * ice_set_rss_cfg_symm - set symmtery for all VSI's RSS configurations
2927  * @hw: pointer to the hardware structure
2928  * @vsi: VSI to set/unset Symmetric RSS
2929  * @symm: TRUE to set Symmetric RSS hashing
2930  */
2931 int ice_set_rss_cfg_symm(struct ice_hw *hw, struct ice_vsi *vsi, bool symm)
2932 {
2933 	struct ice_rss_hash_cfg	local;
2934 	struct ice_rss_cfg *r, *tmp;
2935 	u16 vsi_handle = vsi->idx;
2936 	int status = 0;
2937 
2938 	if (!ice_is_vsi_valid(hw, vsi_handle))
2939 		return -EINVAL;
2940 
2941 	mutex_lock(&hw->rss_locks);
2942 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) {
2943 		if (test_bit(vsi_handle, r->vsis) && r->hash.symm != symm) {
2944 			local = r->hash;
2945 			local.symm = symm;
2946 			if (symm && !rss_cfg_symm_valid(r->hash.hash_flds))
2947 				continue;
2948 
2949 			status = ice_add_rss_cfg_sync(hw, vsi_handle, &local);
2950 			if (status)
2951 				break;
2952 		}
2953 	}
2954 	mutex_unlock(&hw->rss_locks);
2955 
2956 	return status;
2957 }
2958 
2959 /**
2960  * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2961  * @hw: pointer to the hardware structure
2962  * @vsi_handle: software VSI handle
2963  */
2964 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2965 {
2966 	struct ice_rss_cfg *r;
2967 	int status = 0;
2968 
2969 	if (!ice_is_vsi_valid(hw, vsi_handle))
2970 		return -EINVAL;
2971 
2972 	mutex_lock(&hw->rss_locks);
2973 	list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2974 		if (test_bit(vsi_handle, r->vsis)) {
2975 			status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash);
2976 			if (status)
2977 				break;
2978 		}
2979 	}
2980 	mutex_unlock(&hw->rss_locks);
2981 
2982 	return status;
2983 }
2984 
2985 /**
2986  * ice_get_rss_cfg - returns hashed fields for the given header types
2987  * @hw: pointer to the hardware structure
2988  * @vsi_handle: software VSI handle
2989  * @hdrs: protocol header type
2990  * @symm: whether the RSS is symmetric (bool, output)
2991  *
2992  * This function will return the match fields of the first instance of flow
2993  * profile having the given header types and containing input VSI
2994  */
2995 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs, bool *symm)
2996 {
2997 	u64 rss_hash = ICE_HASH_INVALID;
2998 	struct ice_rss_cfg *r;
2999 
3000 	/* verify if the protocol header is non zero and VSI is valid */
3001 	if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
3002 		return ICE_HASH_INVALID;
3003 
3004 	mutex_lock(&hw->rss_locks);
3005 	list_for_each_entry(r, &hw->rss_list_head, l_entry)
3006 		if (test_bit(vsi_handle, r->vsis) &&
3007 		    r->hash.addl_hdrs == hdrs) {
3008 			rss_hash = r->hash.hash_flds;
3009 			*symm = r->hash.symm;
3010 			break;
3011 		}
3012 	mutex_unlock(&hw->rss_locks);
3013 
3014 	return rss_hash;
3015 }
3016