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 
7 /* Describe properties of a protocol header field */
8 struct ice_flow_field_info {
9 	enum ice_flow_seg_hdr hdr;
10 	s16 off;	/* Offset from start of a protocol header, in bits */
11 	u16 size;	/* Size of fields in bits */
12 	u16 mask;	/* 16-bit mask for field */
13 };
14 
15 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
16 	.hdr = _hdr, \
17 	.off = (_offset_bytes) * BITS_PER_BYTE, \
18 	.size = (_size_bytes) * BITS_PER_BYTE, \
19 	.mask = 0, \
20 }
21 
22 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
23 	.hdr = _hdr, \
24 	.off = (_offset_bytes) * BITS_PER_BYTE, \
25 	.size = (_size_bytes) * BITS_PER_BYTE, \
26 	.mask = _mask, \
27 }
28 
29 /* Table containing properties of supported protocol header fields */
30 static const
31 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
32 	/* Ether */
33 	/* ICE_FLOW_FIELD_IDX_ETH_DA */
34 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
35 	/* ICE_FLOW_FIELD_IDX_ETH_SA */
36 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
37 	/* ICE_FLOW_FIELD_IDX_S_VLAN */
38 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)),
39 	/* ICE_FLOW_FIELD_IDX_C_VLAN */
40 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)),
41 	/* ICE_FLOW_FIELD_IDX_ETH_TYPE */
42 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)),
43 	/* IPv4 / IPv6 */
44 	/* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
45 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc),
46 	/* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
47 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0),
48 	/* ICE_FLOW_FIELD_IDX_IPV4_TTL */
49 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00),
50 	/* ICE_FLOW_FIELD_IDX_IPV4_PROT */
51 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff),
52 	/* ICE_FLOW_FIELD_IDX_IPV6_TTL */
53 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff),
54 	/* ICE_FLOW_FIELD_IDX_IPV6_PROT */
55 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00),
56 	/* ICE_FLOW_FIELD_IDX_IPV4_SA */
57 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)),
58 	/* ICE_FLOW_FIELD_IDX_IPV4_DA */
59 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)),
60 	/* ICE_FLOW_FIELD_IDX_IPV6_SA */
61 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
62 	/* ICE_FLOW_FIELD_IDX_IPV6_DA */
63 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
64 	/* Transport */
65 	/* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
66 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
67 	/* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
68 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)),
69 	/* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
70 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)),
71 	/* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
72 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)),
73 	/* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
74 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)),
75 	/* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
76 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
77 	/* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
78 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
79 	/* ARP */
80 	/* ICE_FLOW_FIELD_IDX_ARP_SIP */
81 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
82 	/* ICE_FLOW_FIELD_IDX_ARP_DIP */
83 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)),
84 	/* ICE_FLOW_FIELD_IDX_ARP_SHA */
85 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
86 	/* ICE_FLOW_FIELD_IDX_ARP_DHA */
87 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
88 	/* ICE_FLOW_FIELD_IDX_ARP_OP */
89 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)),
90 	/* ICMP */
91 	/* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
92 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1),
93 	/* ICE_FLOW_FIELD_IDX_ICMP_CODE */
94 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1),
95 	/* GRE */
96 	/* ICE_FLOW_FIELD_IDX_GRE_KEYID */
97 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12,
98 			  sizeof_field(struct gre_full_hdr, key)),
99 	/* GTP */
100 	/* ICE_FLOW_FIELD_IDX_GTPC_TEID */
101 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)),
102 	/* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
103 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)),
104 	/* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
105 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)),
106 	/* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
107 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
108 			      0x3f00),
109 	/* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
110 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
111 	/* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
112 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
113 	/* PPPoE */
114 	/* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
115 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
116 	/* PFCP */
117 	/* ICE_FLOW_FIELD_IDX_PFCP_SEID */
118 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
119 	/* L2TPv3 */
120 	/* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
121 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
122 	/* ESP */
123 	/* ICE_FLOW_FIELD_IDX_ESP_SPI */
124 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
125 	/* AH */
126 	/* ICE_FLOW_FIELD_IDX_AH_SPI */
127 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
128 	/* NAT_T_ESP */
129 	/* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
130 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
131 };
132 
133 /* Bitmaps indicating relevant packet types for a particular protocol header
134  *
135  * Packet types for packets with an Outer/First/Single MAC header
136  */
137 static const u32 ice_ptypes_mac_ofos[] = {
138 	0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
139 	0x0000077E, 0x00000000, 0x00000000, 0x00000000,
140 	0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000,
141 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
142 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
143 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
144 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
145 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
146 };
147 
148 /* Packet types for packets with an Innermost/Last MAC VLAN header */
149 static const u32 ice_ptypes_macvlan_il[] = {
150 	0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
151 	0x0000077E, 0x00000000, 0x00000000, 0x00000000,
152 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
153 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
154 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
155 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
156 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
157 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
158 };
159 
160 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
161  * include IPv4 other PTYPEs
162  */
163 static const u32 ice_ptypes_ipv4_ofos[] = {
164 	0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
165 	0x00000000, 0x00000155, 0x00000000, 0x00000000,
166 	0x00000000, 0x000FC000, 0x00000000, 0x00000000,
167 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
168 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
169 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
170 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
171 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
172 };
173 
174 /* Packet types for packets with an Outer/First/Single IPv4 header, includes
175  * IPv4 other PTYPEs
176  */
177 static const u32 ice_ptypes_ipv4_ofos_all[] = {
178 	0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
179 	0x00000000, 0x00000155, 0x00000000, 0x00000000,
180 	0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
181 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
182 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
183 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
184 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
185 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
186 };
187 
188 /* Packet types for packets with an Innermost/Last IPv4 header */
189 static const u32 ice_ptypes_ipv4_il[] = {
190 	0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
191 	0x0000000E, 0x00000000, 0x00000000, 0x00000000,
192 	0x00000000, 0x00000000, 0x001FF800, 0x00000000,
193 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
194 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
195 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
196 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
197 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
198 };
199 
200 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
201  * include IPv6 other PTYPEs
202  */
203 static const u32 ice_ptypes_ipv6_ofos[] = {
204 	0x00000000, 0x00000000, 0x77000000, 0x10002000,
205 	0x00000000, 0x000002AA, 0x00000000, 0x00000000,
206 	0x00000000, 0x03F00000, 0x00000000, 0x00000000,
207 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
208 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
209 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
210 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
211 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
212 };
213 
214 /* Packet types for packets with an Outer/First/Single IPv6 header, includes
215  * IPv6 other PTYPEs
216  */
217 static const u32 ice_ptypes_ipv6_ofos_all[] = {
218 	0x00000000, 0x00000000, 0x77000000, 0x10002000,
219 	0x00000000, 0x000002AA, 0x00000000, 0x00000000,
220 	0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
221 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
222 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
223 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
224 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
225 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
226 };
227 
228 /* Packet types for packets with an Innermost/Last IPv6 header */
229 static const u32 ice_ptypes_ipv6_il[] = {
230 	0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
231 	0x00000770, 0x00000000, 0x00000000, 0x00000000,
232 	0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
233 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
234 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
235 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
236 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
237 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
238 };
239 
240 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
241 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
242 	0x10C00000, 0x04000800, 0x00000000, 0x00000000,
243 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
244 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
245 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
246 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
247 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
248 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
249 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
250 };
251 
252 /* Packet types for packets with an Outermost/First ARP header */
253 static const u32 ice_ptypes_arp_of[] = {
254 	0x00000800, 0x00000000, 0x00000000, 0x00000000,
255 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
256 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
257 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
258 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
259 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
260 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
261 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
262 };
263 
264 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
265 static const u32 ice_ptypes_ipv4_il_no_l4[] = {
266 	0x60000000, 0x18043008, 0x80000002, 0x6010c021,
267 	0x00000008, 0x00000000, 0x00000000, 0x00000000,
268 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
269 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
270 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
271 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
272 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
273 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
274 };
275 
276 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
277 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
278 	0x00000000, 0x00000000, 0x43000000, 0x10002000,
279 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
280 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
281 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
282 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
283 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
284 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
285 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
286 };
287 
288 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
289 static const u32 ice_ptypes_ipv6_il_no_l4[] = {
290 	0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
291 	0x00000430, 0x00000000, 0x00000000, 0x00000000,
292 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
293 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
294 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
295 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
296 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
297 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
298 };
299 
300 /* UDP Packet types for non-tunneled packets or tunneled
301  * packets with inner UDP.
302  */
303 static const u32 ice_ptypes_udp_il[] = {
304 	0x81000000, 0x20204040, 0x04000010, 0x80810102,
305 	0x00000040, 0x00000000, 0x00000000, 0x00000000,
306 	0x00000000, 0x00410000, 0x90842000, 0x00000007,
307 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
308 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
309 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
310 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
311 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
312 };
313 
314 /* Packet types for packets with an Innermost/Last TCP header */
315 static const u32 ice_ptypes_tcp_il[] = {
316 	0x04000000, 0x80810102, 0x10000040, 0x02040408,
317 	0x00000102, 0x00000000, 0x00000000, 0x00000000,
318 	0x00000000, 0x00820000, 0x21084000, 0x00000000,
319 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
320 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
321 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
322 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
323 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
324 };
325 
326 /* Packet types for packets with an Innermost/Last SCTP header */
327 static const u32 ice_ptypes_sctp_il[] = {
328 	0x08000000, 0x01020204, 0x20000081, 0x04080810,
329 	0x00000204, 0x00000000, 0x00000000, 0x00000000,
330 	0x00000000, 0x01040000, 0x00000000, 0x00000000,
331 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
332 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
333 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
334 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
335 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
336 };
337 
338 /* Packet types for packets with an Outermost/First ICMP header */
339 static const u32 ice_ptypes_icmp_of[] = {
340 	0x10000000, 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 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
347 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
348 };
349 
350 /* Packet types for packets with an Innermost/Last ICMP header */
351 static const u32 ice_ptypes_icmp_il[] = {
352 	0x00000000, 0x02040408, 0x40000102, 0x08101020,
353 	0x00000408, 0x00000000, 0x00000000, 0x00000000,
354 	0x00000000, 0x00000000, 0x42108000, 0x00000000,
355 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
356 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
357 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
358 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
359 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
360 };
361 
362 /* Packet types for packets with an Outermost/First GRE header */
363 static const u32 ice_ptypes_gre_of[] = {
364 	0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
365 	0x0000017E, 0x00000000, 0x00000000, 0x00000000,
366 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
367 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
368 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
369 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
370 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
371 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
372 };
373 
374 /* Packet types for packets with an Innermost/Last MAC header */
375 static const u32 ice_ptypes_mac_il[] = {
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 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
383 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
384 };
385 
386 /* Packet types for GTPC */
387 static const u32 ice_ptypes_gtpc[] = {
388 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
389 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
390 	0x00000000, 0x00000000, 0x00000180, 0x00000000,
391 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
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 GTPC with TEID */
399 static const u32 ice_ptypes_gtpc_tid[] = {
400 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
401 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
402 	0x00000000, 0x00000000, 0x00000060, 0x00000000,
403 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
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 GTPU */
411 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
412 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
413 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
414 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
415 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
416 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
417 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
418 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
419 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
420 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
421 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
422 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
423 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
424 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
425 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
426 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
427 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
428 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
429 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
430 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
431 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
432 };
433 
434 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
435 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
436 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
437 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
438 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
439 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
440 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
441 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
442 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
443 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
444 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
445 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
446 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
447 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
448 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
449 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
450 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
451 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
452 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
453 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
454 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
455 };
456 
457 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
458 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
459 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
460 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
461 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
462 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
463 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
464 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
465 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
466 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
467 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
468 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
469 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
470 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
471 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
472 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
473 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
474 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
475 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
476 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
477 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
478 };
479 
480 static const u32 ice_ptypes_gtpu[] = {
481 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
482 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
483 	0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
484 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
485 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
486 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
487 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
488 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
489 };
490 
491 /* Packet types for PPPoE */
492 static const u32 ice_ptypes_pppoe[] = {
493 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
494 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
495 	0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
496 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
497 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
498 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
499 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
500 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
501 };
502 
503 /* Packet types for packets with PFCP NODE header */
504 static const u32 ice_ptypes_pfcp_node[] = {
505 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
506 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
507 	0x00000000, 0x00000000, 0x80000000, 0x00000002,
508 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
509 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
510 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
511 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
512 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
513 };
514 
515 /* Packet types for packets with PFCP SESSION header */
516 static const u32 ice_ptypes_pfcp_session[] = {
517 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
518 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
519 	0x00000000, 0x00000000, 0x00000000, 0x00000005,
520 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
521 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
522 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
523 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
524 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
525 };
526 
527 /* Packet types for L2TPv3 */
528 static const u32 ice_ptypes_l2tpv3[] = {
529 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
530 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
531 	0x00000000, 0x00000000, 0x00000000, 0x00000300,
532 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
533 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
534 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
535 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
536 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
537 };
538 
539 /* Packet types for ESP */
540 static const u32 ice_ptypes_esp[] = {
541 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
542 	0x00000000, 0x00000003, 0x00000000, 0x00000000,
543 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
544 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
545 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
546 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
547 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
548 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
549 };
550 
551 /* Packet types for AH */
552 static const u32 ice_ptypes_ah[] = {
553 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
554 	0x00000000, 0x0000000C, 0x00000000, 0x00000000,
555 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
556 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
557 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
558 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
559 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
560 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
561 };
562 
563 /* Packet types for packets with NAT_T ESP header */
564 static const u32 ice_ptypes_nat_t_esp[] = {
565 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
566 	0x00000000, 0x00000030, 0x00000000, 0x00000000,
567 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
568 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
569 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
570 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
571 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
572 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
573 };
574 
575 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
576 	0x00000846, 0x00000000, 0x00000000, 0x00000000,
577 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
578 	0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
579 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
580 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
581 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
582 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
583 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
584 };
585 
586 /* Manage parameters and info. used during the creation of a flow profile */
587 struct ice_flow_prof_params {
588 	enum ice_block blk;
589 	u16 entry_length; /* # of bytes formatted entry will require */
590 	u8 es_cnt;
591 	struct ice_flow_prof *prof;
592 
593 	/* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
594 	 * This will give us the direction flags.
595 	 */
596 	struct ice_fv_word es[ICE_MAX_FV_WORDS];
597 	/* attributes can be used to add attributes to a particular PTYPE */
598 	const struct ice_ptype_attributes *attr;
599 	u16 attr_cnt;
600 
601 	u16 mask[ICE_MAX_FV_WORDS];
602 	DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
603 };
604 
605 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
606 	(ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
607 	ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
608 	ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
609 	ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
610 	ICE_FLOW_SEG_HDR_NAT_T_ESP)
611 
612 #define ICE_FLOW_SEG_HDRS_L2_MASK	\
613 	(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
614 #define ICE_FLOW_SEG_HDRS_L3_MASK	\
615 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
616 #define ICE_FLOW_SEG_HDRS_L4_MASK	\
617 	(ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
618 	 ICE_FLOW_SEG_HDR_SCTP)
619 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
620 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER	\
621 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
622 
623 /**
624  * ice_flow_val_hdrs - validates packet segments for valid protocol headers
625  * @segs: array of one or more packet segments that describe the flow
626  * @segs_cnt: number of packet segments provided
627  */
628 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
629 {
630 	u8 i;
631 
632 	for (i = 0; i < segs_cnt; i++) {
633 		/* Multiple L3 headers */
634 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
635 		    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
636 			return -EINVAL;
637 
638 		/* Multiple L4 headers */
639 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
640 		    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
641 			return -EINVAL;
642 	}
643 
644 	return 0;
645 }
646 
647 /* Sizes of fixed known protocol headers without header options */
648 #define ICE_FLOW_PROT_HDR_SZ_MAC	14
649 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN	(ICE_FLOW_PROT_HDR_SZ_MAC + 2)
650 #define ICE_FLOW_PROT_HDR_SZ_IPV4	20
651 #define ICE_FLOW_PROT_HDR_SZ_IPV6	40
652 #define ICE_FLOW_PROT_HDR_SZ_ARP	28
653 #define ICE_FLOW_PROT_HDR_SZ_ICMP	8
654 #define ICE_FLOW_PROT_HDR_SZ_TCP	20
655 #define ICE_FLOW_PROT_HDR_SZ_UDP	8
656 #define ICE_FLOW_PROT_HDR_SZ_SCTP	12
657 
658 /**
659  * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
660  * @params: information about the flow to be processed
661  * @seg: index of packet segment whose header size is to be determined
662  */
663 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
664 {
665 	u16 sz;
666 
667 	/* L2 headers */
668 	sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
669 		ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
670 
671 	/* L3 headers */
672 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
673 		sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
674 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
675 		sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
676 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
677 		sz += ICE_FLOW_PROT_HDR_SZ_ARP;
678 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
679 		/* An L3 header is required if L4 is specified */
680 		return 0;
681 
682 	/* L4 headers */
683 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
684 		sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
685 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
686 		sz += ICE_FLOW_PROT_HDR_SZ_TCP;
687 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
688 		sz += ICE_FLOW_PROT_HDR_SZ_UDP;
689 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
690 		sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
691 
692 	return sz;
693 }
694 
695 /**
696  * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
697  * @params: information about the flow to be processed
698  *
699  * This function identifies the packet types associated with the protocol
700  * headers being present in packet segments of the specified flow profile.
701  */
702 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
703 {
704 	struct ice_flow_prof *prof;
705 	u8 i;
706 
707 	memset(params->ptypes, 0xff, sizeof(params->ptypes));
708 
709 	prof = params->prof;
710 
711 	for (i = 0; i < params->prof->segs_cnt; i++) {
712 		const unsigned long *src;
713 		u32 hdrs;
714 
715 		hdrs = prof->segs[i].hdrs;
716 
717 		if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
718 			src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
719 				(const unsigned long *)ice_ptypes_mac_il;
720 			bitmap_and(params->ptypes, params->ptypes, src,
721 				   ICE_FLOW_PTYPE_MAX);
722 		}
723 
724 		if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
725 			src = (const unsigned long *)ice_ptypes_macvlan_il;
726 			bitmap_and(params->ptypes, params->ptypes, src,
727 				   ICE_FLOW_PTYPE_MAX);
728 		}
729 
730 		if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
731 			bitmap_and(params->ptypes, params->ptypes,
732 				   (const unsigned long *)ice_ptypes_arp_of,
733 				   ICE_FLOW_PTYPE_MAX);
734 		}
735 
736 		if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
737 		    (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
738 			src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
739 				(const unsigned long *)ice_ptypes_ipv4_ofos_all;
740 			bitmap_and(params->ptypes, params->ptypes, src,
741 				   ICE_FLOW_PTYPE_MAX);
742 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
743 			   (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
744 			src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
745 				(const unsigned long *)ice_ptypes_ipv6_ofos_all;
746 			bitmap_and(params->ptypes, params->ptypes, src,
747 				   ICE_FLOW_PTYPE_MAX);
748 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
749 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
750 			src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
751 				(const unsigned long *)ice_ptypes_ipv4_il_no_l4;
752 			bitmap_and(params->ptypes, params->ptypes, src,
753 				   ICE_FLOW_PTYPE_MAX);
754 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
755 			src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
756 				(const unsigned long *)ice_ptypes_ipv4_il;
757 			bitmap_and(params->ptypes, params->ptypes, src,
758 				   ICE_FLOW_PTYPE_MAX);
759 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
760 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
761 			src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
762 				(const unsigned long *)ice_ptypes_ipv6_il_no_l4;
763 			bitmap_and(params->ptypes, params->ptypes, src,
764 				   ICE_FLOW_PTYPE_MAX);
765 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
766 			src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
767 				(const unsigned long *)ice_ptypes_ipv6_il;
768 			bitmap_and(params->ptypes, params->ptypes, src,
769 				   ICE_FLOW_PTYPE_MAX);
770 		}
771 
772 		if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
773 			src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
774 			bitmap_and(params->ptypes, params->ptypes, src,
775 				   ICE_FLOW_PTYPE_MAX);
776 		} else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
777 			src = (const unsigned long *)ice_ptypes_pppoe;
778 			bitmap_and(params->ptypes, params->ptypes, src,
779 				   ICE_FLOW_PTYPE_MAX);
780 		} else {
781 			src = (const unsigned long *)ice_ptypes_pppoe;
782 			bitmap_andnot(params->ptypes, params->ptypes, src,
783 				      ICE_FLOW_PTYPE_MAX);
784 		}
785 
786 		if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
787 			src = (const unsigned long *)ice_ptypes_udp_il;
788 			bitmap_and(params->ptypes, params->ptypes, src,
789 				   ICE_FLOW_PTYPE_MAX);
790 		} else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
791 			bitmap_and(params->ptypes, params->ptypes,
792 				   (const unsigned long *)ice_ptypes_tcp_il,
793 				   ICE_FLOW_PTYPE_MAX);
794 		} else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
795 			src = (const unsigned long *)ice_ptypes_sctp_il;
796 			bitmap_and(params->ptypes, params->ptypes, src,
797 				   ICE_FLOW_PTYPE_MAX);
798 		}
799 
800 		if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
801 			src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
802 				(const unsigned long *)ice_ptypes_icmp_il;
803 			bitmap_and(params->ptypes, params->ptypes, src,
804 				   ICE_FLOW_PTYPE_MAX);
805 		} else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
806 			if (!i) {
807 				src = (const unsigned long *)ice_ptypes_gre_of;
808 				bitmap_and(params->ptypes, params->ptypes,
809 					   src, ICE_FLOW_PTYPE_MAX);
810 			}
811 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
812 			src = (const unsigned long *)ice_ptypes_gtpc;
813 			bitmap_and(params->ptypes, params->ptypes, src,
814 				   ICE_FLOW_PTYPE_MAX);
815 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
816 			src = (const unsigned long *)ice_ptypes_gtpc_tid;
817 			bitmap_and(params->ptypes, params->ptypes, src,
818 				   ICE_FLOW_PTYPE_MAX);
819 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
820 			src = (const unsigned long *)ice_ptypes_gtpu;
821 			bitmap_and(params->ptypes, params->ptypes, src,
822 				   ICE_FLOW_PTYPE_MAX);
823 
824 			/* Attributes for GTP packet with downlink */
825 			params->attr = ice_attr_gtpu_down;
826 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
827 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
828 			src = (const unsigned long *)ice_ptypes_gtpu;
829 			bitmap_and(params->ptypes, params->ptypes, src,
830 				   ICE_FLOW_PTYPE_MAX);
831 
832 			/* Attributes for GTP packet with uplink */
833 			params->attr = ice_attr_gtpu_up;
834 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
835 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
836 			src = (const unsigned long *)ice_ptypes_gtpu;
837 			bitmap_and(params->ptypes, params->ptypes, src,
838 				   ICE_FLOW_PTYPE_MAX);
839 
840 			/* Attributes for GTP packet with Extension Header */
841 			params->attr = ice_attr_gtpu_eh;
842 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
843 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
844 			src = (const unsigned long *)ice_ptypes_gtpu;
845 			bitmap_and(params->ptypes, params->ptypes, src,
846 				   ICE_FLOW_PTYPE_MAX);
847 		} else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
848 			src = (const unsigned long *)ice_ptypes_l2tpv3;
849 			bitmap_and(params->ptypes, params->ptypes, src,
850 				   ICE_FLOW_PTYPE_MAX);
851 		} else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
852 			src = (const unsigned long *)ice_ptypes_esp;
853 			bitmap_and(params->ptypes, params->ptypes, src,
854 				   ICE_FLOW_PTYPE_MAX);
855 		} else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
856 			src = (const unsigned long *)ice_ptypes_ah;
857 			bitmap_and(params->ptypes, params->ptypes, src,
858 				   ICE_FLOW_PTYPE_MAX);
859 		} else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
860 			src = (const unsigned long *)ice_ptypes_nat_t_esp;
861 			bitmap_and(params->ptypes, params->ptypes, src,
862 				   ICE_FLOW_PTYPE_MAX);
863 		}
864 
865 		if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
866 			if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
867 				src = (const unsigned long *)ice_ptypes_pfcp_node;
868 			else
869 				src = (const unsigned long *)ice_ptypes_pfcp_session;
870 
871 			bitmap_and(params->ptypes, params->ptypes, src,
872 				   ICE_FLOW_PTYPE_MAX);
873 		} else {
874 			src = (const unsigned long *)ice_ptypes_pfcp_node;
875 			bitmap_andnot(params->ptypes, params->ptypes, src,
876 				      ICE_FLOW_PTYPE_MAX);
877 
878 			src = (const unsigned long *)ice_ptypes_pfcp_session;
879 			bitmap_andnot(params->ptypes, params->ptypes, src,
880 				      ICE_FLOW_PTYPE_MAX);
881 		}
882 	}
883 
884 	return 0;
885 }
886 
887 /**
888  * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
889  * @hw: pointer to the HW struct
890  * @params: information about the flow to be processed
891  * @seg: packet segment index of the field to be extracted
892  * @fld: ID of field to be extracted
893  * @match: bit field of all fields
894  *
895  * This function determines the protocol ID, offset, and size of the given
896  * field. It then allocates one or more extraction sequence entries for the
897  * given field, and fill the entries with protocol ID and offset information.
898  */
899 static int
900 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
901 		    u8 seg, enum ice_flow_field fld, u64 match)
902 {
903 	enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
904 	enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
905 	u8 fv_words = hw->blk[params->blk].es.fvw;
906 	struct ice_flow_fld_info *flds;
907 	u16 cnt, ese_bits, i;
908 	u16 sib_mask = 0;
909 	u16 mask;
910 	u16 off;
911 
912 	flds = params->prof->segs[seg].fields;
913 
914 	switch (fld) {
915 	case ICE_FLOW_FIELD_IDX_ETH_DA:
916 	case ICE_FLOW_FIELD_IDX_ETH_SA:
917 	case ICE_FLOW_FIELD_IDX_S_VLAN:
918 	case ICE_FLOW_FIELD_IDX_C_VLAN:
919 		prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
920 		break;
921 	case ICE_FLOW_FIELD_IDX_ETH_TYPE:
922 		prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
923 		break;
924 	case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
925 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
926 		break;
927 	case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
928 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
929 		break;
930 	case ICE_FLOW_FIELD_IDX_IPV4_TTL:
931 	case ICE_FLOW_FIELD_IDX_IPV4_PROT:
932 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
933 
934 		/* TTL and PROT share the same extraction seq. entry.
935 		 * Each is considered a sibling to the other in terms of sharing
936 		 * the same extraction sequence entry.
937 		 */
938 		if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
939 			sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
940 		else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
941 			sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
942 
943 		/* If the sibling field is also included, that field's
944 		 * mask needs to be included.
945 		 */
946 		if (match & BIT(sib))
947 			sib_mask = ice_flds_info[sib].mask;
948 		break;
949 	case ICE_FLOW_FIELD_IDX_IPV6_TTL:
950 	case ICE_FLOW_FIELD_IDX_IPV6_PROT:
951 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
952 
953 		/* TTL and PROT share the same extraction seq. entry.
954 		 * Each is considered a sibling to the other in terms of sharing
955 		 * the same extraction sequence entry.
956 		 */
957 		if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
958 			sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
959 		else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
960 			sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
961 
962 		/* If the sibling field is also included, that field's
963 		 * mask needs to be included.
964 		 */
965 		if (match & BIT(sib))
966 			sib_mask = ice_flds_info[sib].mask;
967 		break;
968 	case ICE_FLOW_FIELD_IDX_IPV4_SA:
969 	case ICE_FLOW_FIELD_IDX_IPV4_DA:
970 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
971 		break;
972 	case ICE_FLOW_FIELD_IDX_IPV6_SA:
973 	case ICE_FLOW_FIELD_IDX_IPV6_DA:
974 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
975 		break;
976 	case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
977 	case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
978 	case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
979 		prot_id = ICE_PROT_TCP_IL;
980 		break;
981 	case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
982 	case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
983 		prot_id = ICE_PROT_UDP_IL_OR_S;
984 		break;
985 	case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
986 	case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
987 		prot_id = ICE_PROT_SCTP_IL;
988 		break;
989 	case ICE_FLOW_FIELD_IDX_GTPC_TEID:
990 	case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
991 	case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
992 	case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
993 	case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
994 	case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
995 		/* GTP is accessed through UDP OF protocol */
996 		prot_id = ICE_PROT_UDP_OF;
997 		break;
998 	case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
999 		prot_id = ICE_PROT_PPPOE;
1000 		break;
1001 	case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1002 		prot_id = ICE_PROT_UDP_IL_OR_S;
1003 		break;
1004 	case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1005 		prot_id = ICE_PROT_L2TPV3;
1006 		break;
1007 	case ICE_FLOW_FIELD_IDX_ESP_SPI:
1008 		prot_id = ICE_PROT_ESP_F;
1009 		break;
1010 	case ICE_FLOW_FIELD_IDX_AH_SPI:
1011 		prot_id = ICE_PROT_ESP_2;
1012 		break;
1013 	case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1014 		prot_id = ICE_PROT_UDP_IL_OR_S;
1015 		break;
1016 	case ICE_FLOW_FIELD_IDX_ARP_SIP:
1017 	case ICE_FLOW_FIELD_IDX_ARP_DIP:
1018 	case ICE_FLOW_FIELD_IDX_ARP_SHA:
1019 	case ICE_FLOW_FIELD_IDX_ARP_DHA:
1020 	case ICE_FLOW_FIELD_IDX_ARP_OP:
1021 		prot_id = ICE_PROT_ARP_OF;
1022 		break;
1023 	case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1024 	case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1025 		/* ICMP type and code share the same extraction seq. entry */
1026 		prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1027 				ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1028 		sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1029 			ICE_FLOW_FIELD_IDX_ICMP_CODE :
1030 			ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1031 		break;
1032 	case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1033 		prot_id = ICE_PROT_GRE_OF;
1034 		break;
1035 	default:
1036 		return -EOPNOTSUPP;
1037 	}
1038 
1039 	/* Each extraction sequence entry is a word in size, and extracts a
1040 	 * word-aligned offset from a protocol header.
1041 	 */
1042 	ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1043 
1044 	flds[fld].xtrct.prot_id = prot_id;
1045 	flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1046 		ICE_FLOW_FV_EXTRACT_SZ;
1047 	flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1048 	flds[fld].xtrct.idx = params->es_cnt;
1049 	flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1050 
1051 	/* Adjust the next field-entry index after accommodating the number of
1052 	 * entries this field consumes
1053 	 */
1054 	cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1055 			   ese_bits);
1056 
1057 	/* Fill in the extraction sequence entries needed for this field */
1058 	off = flds[fld].xtrct.off;
1059 	mask = flds[fld].xtrct.mask;
1060 	for (i = 0; i < cnt; i++) {
1061 		/* Only consume an extraction sequence entry if there is no
1062 		 * sibling field associated with this field or the sibling entry
1063 		 * already extracts the word shared with this field.
1064 		 */
1065 		if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1066 		    flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1067 		    flds[sib].xtrct.off != off) {
1068 			u8 idx;
1069 
1070 			/* Make sure the number of extraction sequence required
1071 			 * does not exceed the block's capability
1072 			 */
1073 			if (params->es_cnt >= fv_words)
1074 				return -ENOSPC;
1075 
1076 			/* some blocks require a reversed field vector layout */
1077 			if (hw->blk[params->blk].es.reverse)
1078 				idx = fv_words - params->es_cnt - 1;
1079 			else
1080 				idx = params->es_cnt;
1081 
1082 			params->es[idx].prot_id = prot_id;
1083 			params->es[idx].off = off;
1084 			params->mask[idx] = mask | sib_mask;
1085 			params->es_cnt++;
1086 		}
1087 
1088 		off += ICE_FLOW_FV_EXTRACT_SZ;
1089 	}
1090 
1091 	return 0;
1092 }
1093 
1094 /**
1095  * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1096  * @hw: pointer to the HW struct
1097  * @params: information about the flow to be processed
1098  * @seg: index of packet segment whose raw fields are to be extracted
1099  */
1100 static int
1101 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1102 		     u8 seg)
1103 {
1104 	u16 fv_words;
1105 	u16 hdrs_sz;
1106 	u8 i;
1107 
1108 	if (!params->prof->segs[seg].raws_cnt)
1109 		return 0;
1110 
1111 	if (params->prof->segs[seg].raws_cnt >
1112 	    ARRAY_SIZE(params->prof->segs[seg].raws))
1113 		return -ENOSPC;
1114 
1115 	/* Offsets within the segment headers are not supported */
1116 	hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1117 	if (!hdrs_sz)
1118 		return -EINVAL;
1119 
1120 	fv_words = hw->blk[params->blk].es.fvw;
1121 
1122 	for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1123 		struct ice_flow_seg_fld_raw *raw;
1124 		u16 off, cnt, j;
1125 
1126 		raw = &params->prof->segs[seg].raws[i];
1127 
1128 		/* Storing extraction information */
1129 		raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1130 		raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1131 			ICE_FLOW_FV_EXTRACT_SZ;
1132 		raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1133 			BITS_PER_BYTE;
1134 		raw->info.xtrct.idx = params->es_cnt;
1135 
1136 		/* Determine the number of field vector entries this raw field
1137 		 * consumes.
1138 		 */
1139 		cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1140 				   (raw->info.src.last * BITS_PER_BYTE),
1141 				   (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1142 		off = raw->info.xtrct.off;
1143 		for (j = 0; j < cnt; j++) {
1144 			u16 idx;
1145 
1146 			/* Make sure the number of extraction sequence required
1147 			 * does not exceed the block's capability
1148 			 */
1149 			if (params->es_cnt >= hw->blk[params->blk].es.count ||
1150 			    params->es_cnt >= ICE_MAX_FV_WORDS)
1151 				return -ENOSPC;
1152 
1153 			/* some blocks require a reversed field vector layout */
1154 			if (hw->blk[params->blk].es.reverse)
1155 				idx = fv_words - params->es_cnt - 1;
1156 			else
1157 				idx = params->es_cnt;
1158 
1159 			params->es[idx].prot_id = raw->info.xtrct.prot_id;
1160 			params->es[idx].off = off;
1161 			params->es_cnt++;
1162 			off += ICE_FLOW_FV_EXTRACT_SZ;
1163 		}
1164 	}
1165 
1166 	return 0;
1167 }
1168 
1169 /**
1170  * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1171  * @hw: pointer to the HW struct
1172  * @params: information about the flow to be processed
1173  *
1174  * This function iterates through all matched fields in the given segments, and
1175  * creates an extraction sequence for the fields.
1176  */
1177 static int
1178 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1179 			  struct ice_flow_prof_params *params)
1180 {
1181 	struct ice_flow_prof *prof = params->prof;
1182 	int status = 0;
1183 	u8 i;
1184 
1185 	for (i = 0; i < prof->segs_cnt; i++) {
1186 		u64 match = params->prof->segs[i].match;
1187 		enum ice_flow_field j;
1188 
1189 		for_each_set_bit(j, (unsigned long *)&match,
1190 				 ICE_FLOW_FIELD_IDX_MAX) {
1191 			status = ice_flow_xtract_fld(hw, params, i, j, match);
1192 			if (status)
1193 				return status;
1194 			clear_bit(j, (unsigned long *)&match);
1195 		}
1196 
1197 		/* Process raw matching bytes */
1198 		status = ice_flow_xtract_raws(hw, params, i);
1199 		if (status)
1200 			return status;
1201 	}
1202 
1203 	return status;
1204 }
1205 
1206 /**
1207  * ice_flow_proc_segs - process all packet segments associated with a profile
1208  * @hw: pointer to the HW struct
1209  * @params: information about the flow to be processed
1210  */
1211 static int
1212 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1213 {
1214 	int status;
1215 
1216 	status = ice_flow_proc_seg_hdrs(params);
1217 	if (status)
1218 		return status;
1219 
1220 	status = ice_flow_create_xtrct_seq(hw, params);
1221 	if (status)
1222 		return status;
1223 
1224 	switch (params->blk) {
1225 	case ICE_BLK_FD:
1226 	case ICE_BLK_RSS:
1227 		status = 0;
1228 		break;
1229 	default:
1230 		return -EOPNOTSUPP;
1231 	}
1232 
1233 	return status;
1234 }
1235 
1236 #define ICE_FLOW_FIND_PROF_CHK_FLDS	0x00000001
1237 #define ICE_FLOW_FIND_PROF_CHK_VSI	0x00000002
1238 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR	0x00000004
1239 
1240 /**
1241  * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1242  * @hw: pointer to the HW struct
1243  * @blk: classification stage
1244  * @dir: flow direction
1245  * @segs: array of one or more packet segments that describe the flow
1246  * @segs_cnt: number of packet segments provided
1247  * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1248  * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1249  */
1250 static struct ice_flow_prof *
1251 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1252 			 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1253 			 u8 segs_cnt, u16 vsi_handle, u32 conds)
1254 {
1255 	struct ice_flow_prof *p, *prof = NULL;
1256 
1257 	mutex_lock(&hw->fl_profs_locks[blk]);
1258 	list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1259 		if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1260 		    segs_cnt && segs_cnt == p->segs_cnt) {
1261 			u8 i;
1262 
1263 			/* Check for profile-VSI association if specified */
1264 			if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1265 			    ice_is_vsi_valid(hw, vsi_handle) &&
1266 			    !test_bit(vsi_handle, p->vsis))
1267 				continue;
1268 
1269 			/* Protocol headers must be checked. Matched fields are
1270 			 * checked if specified.
1271 			 */
1272 			for (i = 0; i < segs_cnt; i++)
1273 				if (segs[i].hdrs != p->segs[i].hdrs ||
1274 				    ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1275 				     segs[i].match != p->segs[i].match))
1276 					break;
1277 
1278 			/* A match is found if all segments are matched */
1279 			if (i == segs_cnt) {
1280 				prof = p;
1281 				break;
1282 			}
1283 		}
1284 	mutex_unlock(&hw->fl_profs_locks[blk]);
1285 
1286 	return prof;
1287 }
1288 
1289 /**
1290  * ice_flow_find_prof_id - Look up a profile with given profile ID
1291  * @hw: pointer to the HW struct
1292  * @blk: classification stage
1293  * @prof_id: unique ID to identify this flow profile
1294  */
1295 static struct ice_flow_prof *
1296 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1297 {
1298 	struct ice_flow_prof *p;
1299 
1300 	list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1301 		if (p->id == prof_id)
1302 			return p;
1303 
1304 	return NULL;
1305 }
1306 
1307 /**
1308  * ice_dealloc_flow_entry - Deallocate flow entry memory
1309  * @hw: pointer to the HW struct
1310  * @entry: flow entry to be removed
1311  */
1312 static void
1313 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1314 {
1315 	if (!entry)
1316 		return;
1317 
1318 	if (entry->entry)
1319 		devm_kfree(ice_hw_to_dev(hw), entry->entry);
1320 
1321 	devm_kfree(ice_hw_to_dev(hw), entry);
1322 }
1323 
1324 /**
1325  * ice_flow_rem_entry_sync - Remove a flow entry
1326  * @hw: pointer to the HW struct
1327  * @blk: classification stage
1328  * @entry: flow entry to be removed
1329  */
1330 static int
1331 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1332 			struct ice_flow_entry *entry)
1333 {
1334 	if (!entry)
1335 		return -EINVAL;
1336 
1337 	list_del(&entry->l_entry);
1338 
1339 	ice_dealloc_flow_entry(hw, entry);
1340 
1341 	return 0;
1342 }
1343 
1344 /**
1345  * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1346  * @hw: pointer to the HW struct
1347  * @blk: classification stage
1348  * @dir: flow direction
1349  * @prof_id: unique ID to identify this flow profile
1350  * @segs: array of one or more packet segments that describe the flow
1351  * @segs_cnt: number of packet segments provided
1352  * @prof: stores the returned flow profile added
1353  *
1354  * Assumption: the caller has acquired the lock to the profile list
1355  */
1356 static int
1357 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1358 		       enum ice_flow_dir dir, u64 prof_id,
1359 		       struct ice_flow_seg_info *segs, u8 segs_cnt,
1360 		       struct ice_flow_prof **prof)
1361 {
1362 	struct ice_flow_prof_params *params;
1363 	int status;
1364 	u8 i;
1365 
1366 	if (!prof)
1367 		return -EINVAL;
1368 
1369 	params = kzalloc(sizeof(*params), GFP_KERNEL);
1370 	if (!params)
1371 		return -ENOMEM;
1372 
1373 	params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1374 				    GFP_KERNEL);
1375 	if (!params->prof) {
1376 		status = -ENOMEM;
1377 		goto free_params;
1378 	}
1379 
1380 	/* initialize extraction sequence to all invalid (0xff) */
1381 	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1382 		params->es[i].prot_id = ICE_PROT_INVALID;
1383 		params->es[i].off = ICE_FV_OFFSET_INVAL;
1384 	}
1385 
1386 	params->blk = blk;
1387 	params->prof->id = prof_id;
1388 	params->prof->dir = dir;
1389 	params->prof->segs_cnt = segs_cnt;
1390 
1391 	/* Make a copy of the segments that need to be persistent in the flow
1392 	 * profile instance
1393 	 */
1394 	for (i = 0; i < segs_cnt; i++)
1395 		memcpy(&params->prof->segs[i], &segs[i], sizeof(*segs));
1396 
1397 	status = ice_flow_proc_segs(hw, params);
1398 	if (status) {
1399 		ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1400 		goto out;
1401 	}
1402 
1403 	/* Add a HW profile for this flow profile */
1404 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1405 			      params->attr, params->attr_cnt, params->es,
1406 			      params->mask);
1407 	if (status) {
1408 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1409 		goto out;
1410 	}
1411 
1412 	INIT_LIST_HEAD(&params->prof->entries);
1413 	mutex_init(&params->prof->entries_lock);
1414 	*prof = params->prof;
1415 
1416 out:
1417 	if (status)
1418 		devm_kfree(ice_hw_to_dev(hw), params->prof);
1419 free_params:
1420 	kfree(params);
1421 
1422 	return status;
1423 }
1424 
1425 /**
1426  * ice_flow_rem_prof_sync - remove a flow profile
1427  * @hw: pointer to the hardware structure
1428  * @blk: classification stage
1429  * @prof: pointer to flow profile to remove
1430  *
1431  * Assumption: the caller has acquired the lock to the profile list
1432  */
1433 static int
1434 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1435 		       struct ice_flow_prof *prof)
1436 {
1437 	int status;
1438 
1439 	/* Remove all remaining flow entries before removing the flow profile */
1440 	if (!list_empty(&prof->entries)) {
1441 		struct ice_flow_entry *e, *t;
1442 
1443 		mutex_lock(&prof->entries_lock);
1444 
1445 		list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1446 			status = ice_flow_rem_entry_sync(hw, blk, e);
1447 			if (status)
1448 				break;
1449 		}
1450 
1451 		mutex_unlock(&prof->entries_lock);
1452 	}
1453 
1454 	/* Remove all hardware profiles associated with this flow profile */
1455 	status = ice_rem_prof(hw, blk, prof->id);
1456 	if (!status) {
1457 		list_del(&prof->l_entry);
1458 		mutex_destroy(&prof->entries_lock);
1459 		devm_kfree(ice_hw_to_dev(hw), prof);
1460 	}
1461 
1462 	return status;
1463 }
1464 
1465 /**
1466  * ice_flow_assoc_prof - associate a VSI with a flow profile
1467  * @hw: pointer to the hardware structure
1468  * @blk: classification stage
1469  * @prof: pointer to flow profile
1470  * @vsi_handle: software VSI handle
1471  *
1472  * Assumption: the caller has acquired the lock to the profile list
1473  * and the software VSI handle has been validated
1474  */
1475 static int
1476 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1477 		    struct ice_flow_prof *prof, u16 vsi_handle)
1478 {
1479 	int status = 0;
1480 
1481 	if (!test_bit(vsi_handle, prof->vsis)) {
1482 		status = ice_add_prof_id_flow(hw, blk,
1483 					      ice_get_hw_vsi_num(hw,
1484 								 vsi_handle),
1485 					      prof->id);
1486 		if (!status)
1487 			set_bit(vsi_handle, prof->vsis);
1488 		else
1489 			ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1490 				  status);
1491 	}
1492 
1493 	return status;
1494 }
1495 
1496 /**
1497  * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1498  * @hw: pointer to the hardware structure
1499  * @blk: classification stage
1500  * @prof: pointer to flow profile
1501  * @vsi_handle: software VSI handle
1502  *
1503  * Assumption: the caller has acquired the lock to the profile list
1504  * and the software VSI handle has been validated
1505  */
1506 static int
1507 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1508 		       struct ice_flow_prof *prof, u16 vsi_handle)
1509 {
1510 	int status = 0;
1511 
1512 	if (test_bit(vsi_handle, prof->vsis)) {
1513 		status = ice_rem_prof_id_flow(hw, blk,
1514 					      ice_get_hw_vsi_num(hw,
1515 								 vsi_handle),
1516 					      prof->id);
1517 		if (!status)
1518 			clear_bit(vsi_handle, prof->vsis);
1519 		else
1520 			ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1521 				  status);
1522 	}
1523 
1524 	return status;
1525 }
1526 
1527 /**
1528  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1529  * @hw: pointer to the HW struct
1530  * @blk: classification stage
1531  * @dir: flow direction
1532  * @prof_id: unique ID to identify this flow profile
1533  * @segs: array of one or more packet segments that describe the flow
1534  * @segs_cnt: number of packet segments provided
1535  * @prof: stores the returned flow profile added
1536  */
1537 int
1538 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1539 		  u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1540 		  struct ice_flow_prof **prof)
1541 {
1542 	int status;
1543 
1544 	if (segs_cnt > ICE_FLOW_SEG_MAX)
1545 		return -ENOSPC;
1546 
1547 	if (!segs_cnt)
1548 		return -EINVAL;
1549 
1550 	if (!segs)
1551 		return -EINVAL;
1552 
1553 	status = ice_flow_val_hdrs(segs, segs_cnt);
1554 	if (status)
1555 		return status;
1556 
1557 	mutex_lock(&hw->fl_profs_locks[blk]);
1558 
1559 	status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1560 					prof);
1561 	if (!status)
1562 		list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1563 
1564 	mutex_unlock(&hw->fl_profs_locks[blk]);
1565 
1566 	return status;
1567 }
1568 
1569 /**
1570  * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1571  * @hw: pointer to the HW struct
1572  * @blk: the block for which the flow profile is to be removed
1573  * @prof_id: unique ID of the flow profile to be removed
1574  */
1575 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1576 {
1577 	struct ice_flow_prof *prof;
1578 	int status;
1579 
1580 	mutex_lock(&hw->fl_profs_locks[blk]);
1581 
1582 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
1583 	if (!prof) {
1584 		status = -ENOENT;
1585 		goto out;
1586 	}
1587 
1588 	/* prof becomes invalid after the call */
1589 	status = ice_flow_rem_prof_sync(hw, blk, prof);
1590 
1591 out:
1592 	mutex_unlock(&hw->fl_profs_locks[blk]);
1593 
1594 	return status;
1595 }
1596 
1597 /**
1598  * ice_flow_add_entry - Add a flow entry
1599  * @hw: pointer to the HW struct
1600  * @blk: classification stage
1601  * @prof_id: ID of the profile to add a new flow entry to
1602  * @entry_id: unique ID to identify this flow entry
1603  * @vsi_handle: software VSI handle for the flow entry
1604  * @prio: priority of the flow entry
1605  * @data: pointer to a data buffer containing flow entry's match values/masks
1606  * @entry_h: pointer to buffer that receives the new flow entry's handle
1607  */
1608 int
1609 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1610 		   u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1611 		   void *data, u64 *entry_h)
1612 {
1613 	struct ice_flow_entry *e = NULL;
1614 	struct ice_flow_prof *prof;
1615 	int status;
1616 
1617 	/* No flow entry data is expected for RSS */
1618 	if (!entry_h || (!data && blk != ICE_BLK_RSS))
1619 		return -EINVAL;
1620 
1621 	if (!ice_is_vsi_valid(hw, vsi_handle))
1622 		return -EINVAL;
1623 
1624 	mutex_lock(&hw->fl_profs_locks[blk]);
1625 
1626 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
1627 	if (!prof) {
1628 		status = -ENOENT;
1629 	} else {
1630 		/* Allocate memory for the entry being added and associate
1631 		 * the VSI to the found flow profile
1632 		 */
1633 		e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1634 		if (!e)
1635 			status = -ENOMEM;
1636 		else
1637 			status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1638 	}
1639 
1640 	mutex_unlock(&hw->fl_profs_locks[blk]);
1641 	if (status)
1642 		goto out;
1643 
1644 	e->id = entry_id;
1645 	e->vsi_handle = vsi_handle;
1646 	e->prof = prof;
1647 	e->priority = prio;
1648 
1649 	switch (blk) {
1650 	case ICE_BLK_FD:
1651 	case ICE_BLK_RSS:
1652 		break;
1653 	default:
1654 		status = -EOPNOTSUPP;
1655 		goto out;
1656 	}
1657 
1658 	mutex_lock(&prof->entries_lock);
1659 	list_add(&e->l_entry, &prof->entries);
1660 	mutex_unlock(&prof->entries_lock);
1661 
1662 	*entry_h = ICE_FLOW_ENTRY_HNDL(e);
1663 
1664 out:
1665 	if (status && e) {
1666 		if (e->entry)
1667 			devm_kfree(ice_hw_to_dev(hw), e->entry);
1668 		devm_kfree(ice_hw_to_dev(hw), e);
1669 	}
1670 
1671 	return status;
1672 }
1673 
1674 /**
1675  * ice_flow_rem_entry - Remove a flow entry
1676  * @hw: pointer to the HW struct
1677  * @blk: classification stage
1678  * @entry_h: handle to the flow entry to be removed
1679  */
1680 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1681 {
1682 	struct ice_flow_entry *entry;
1683 	struct ice_flow_prof *prof;
1684 	int status = 0;
1685 
1686 	if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1687 		return -EINVAL;
1688 
1689 	entry = ICE_FLOW_ENTRY_PTR(entry_h);
1690 
1691 	/* Retain the pointer to the flow profile as the entry will be freed */
1692 	prof = entry->prof;
1693 
1694 	if (prof) {
1695 		mutex_lock(&prof->entries_lock);
1696 		status = ice_flow_rem_entry_sync(hw, blk, entry);
1697 		mutex_unlock(&prof->entries_lock);
1698 	}
1699 
1700 	return status;
1701 }
1702 
1703 /**
1704  * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1705  * @seg: packet segment the field being set belongs to
1706  * @fld: field to be set
1707  * @field_type: type of the field
1708  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1709  *           entry's input buffer
1710  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1711  *            input buffer
1712  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1713  *            entry's input buffer
1714  *
1715  * This helper function stores information of a field being matched, including
1716  * the type of the field and the locations of the value to match, the mask, and
1717  * the upper-bound value in the start of the input buffer for a flow entry.
1718  * This function should only be used for fixed-size data structures.
1719  *
1720  * This function also opportunistically determines the protocol headers to be
1721  * present based on the fields being set. Some fields cannot be used alone to
1722  * determine the protocol headers present. Sometimes, fields for particular
1723  * protocol headers are not matched. In those cases, the protocol headers
1724  * must be explicitly set.
1725  */
1726 static void
1727 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1728 		     enum ice_flow_fld_match_type field_type, u16 val_loc,
1729 		     u16 mask_loc, u16 last_loc)
1730 {
1731 	u64 bit = BIT_ULL(fld);
1732 
1733 	seg->match |= bit;
1734 	if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1735 		seg->range |= bit;
1736 
1737 	seg->fields[fld].type = field_type;
1738 	seg->fields[fld].src.val = val_loc;
1739 	seg->fields[fld].src.mask = mask_loc;
1740 	seg->fields[fld].src.last = last_loc;
1741 
1742 	ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1743 }
1744 
1745 /**
1746  * ice_flow_set_fld - specifies locations of field from entry's input buffer
1747  * @seg: packet segment the field being set belongs to
1748  * @fld: field to be set
1749  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1750  *           entry's input buffer
1751  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1752  *            input buffer
1753  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1754  *            entry's input buffer
1755  * @range: indicate if field being matched is to be in a range
1756  *
1757  * This function specifies the locations, in the form of byte offsets from the
1758  * start of the input buffer for a flow entry, from where the value to match,
1759  * the mask value, and upper value can be extracted. These locations are then
1760  * stored in the flow profile. When adding a flow entry associated with the
1761  * flow profile, these locations will be used to quickly extract the values and
1762  * create the content of a match entry. This function should only be used for
1763  * fixed-size data structures.
1764  */
1765 void
1766 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1767 		 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1768 {
1769 	enum ice_flow_fld_match_type t = range ?
1770 		ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1771 
1772 	ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1773 }
1774 
1775 /**
1776  * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1777  * @seg: packet segment the field being set belongs to
1778  * @off: offset of the raw field from the beginning of the segment in bytes
1779  * @len: length of the raw pattern to be matched
1780  * @val_loc: location of the value to match from entry's input buffer
1781  * @mask_loc: location of mask value from entry's input buffer
1782  *
1783  * This function specifies the offset of the raw field to be match from the
1784  * beginning of the specified packet segment, and the locations, in the form of
1785  * byte offsets from the start of the input buffer for a flow entry, from where
1786  * the value to match and the mask value to be extracted. These locations are
1787  * then stored in the flow profile. When adding flow entries to the associated
1788  * flow profile, these locations can be used to quickly extract the values to
1789  * create the content of a match entry. This function should only be used for
1790  * fixed-size data structures.
1791  */
1792 void
1793 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1794 		     u16 val_loc, u16 mask_loc)
1795 {
1796 	if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1797 		seg->raws[seg->raws_cnt].off = off;
1798 		seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1799 		seg->raws[seg->raws_cnt].info.src.val = val_loc;
1800 		seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1801 		/* The "last" field is used to store the length of the field */
1802 		seg->raws[seg->raws_cnt].info.src.last = len;
1803 	}
1804 
1805 	/* Overflows of "raws" will be handled as an error condition later in
1806 	 * the flow when this information is processed.
1807 	 */
1808 	seg->raws_cnt++;
1809 }
1810 
1811 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1812 	(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1813 
1814 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1815 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1816 
1817 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1818 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1819 
1820 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1821 	(ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1822 	 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1823 	 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1824 
1825 /**
1826  * ice_flow_set_rss_seg_info - setup packet segments for RSS
1827  * @segs: pointer to the flow field segment(s)
1828  * @hash_fields: fields to be hashed on for the segment(s)
1829  * @flow_hdr: protocol header fields within a packet segment
1830  *
1831  * Helper function to extract fields from hash bitmap and use flow
1832  * header value to set flow field segment for further use in flow
1833  * profile entry or removal.
1834  */
1835 static int
1836 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1837 			  u32 flow_hdr)
1838 {
1839 	u64 val;
1840 	u8 i;
1841 
1842 	for_each_set_bit(i, (unsigned long *)&hash_fields,
1843 			 ICE_FLOW_FIELD_IDX_MAX)
1844 		ice_flow_set_fld(segs, (enum ice_flow_field)i,
1845 				 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1846 				 ICE_FLOW_FLD_OFF_INVAL, false);
1847 
1848 	ICE_FLOW_SET_HDRS(segs, flow_hdr);
1849 
1850 	if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1851 	    ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1852 		return -EINVAL;
1853 
1854 	val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1855 	if (val && !is_power_of_2(val))
1856 		return -EIO;
1857 
1858 	val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1859 	if (val && !is_power_of_2(val))
1860 		return -EIO;
1861 
1862 	return 0;
1863 }
1864 
1865 /**
1866  * ice_rem_vsi_rss_list - remove VSI from RSS list
1867  * @hw: pointer to the hardware structure
1868  * @vsi_handle: software VSI handle
1869  *
1870  * Remove the VSI from all RSS configurations in the list.
1871  */
1872 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1873 {
1874 	struct ice_rss_cfg *r, *tmp;
1875 
1876 	if (list_empty(&hw->rss_list_head))
1877 		return;
1878 
1879 	mutex_lock(&hw->rss_locks);
1880 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1881 		if (test_and_clear_bit(vsi_handle, r->vsis))
1882 			if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1883 				list_del(&r->l_entry);
1884 				devm_kfree(ice_hw_to_dev(hw), r);
1885 			}
1886 	mutex_unlock(&hw->rss_locks);
1887 }
1888 
1889 /**
1890  * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1891  * @hw: pointer to the hardware structure
1892  * @vsi_handle: software VSI handle
1893  *
1894  * This function will iterate through all flow profiles and disassociate
1895  * the VSI from that profile. If the flow profile has no VSIs it will
1896  * be removed.
1897  */
1898 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1899 {
1900 	const enum ice_block blk = ICE_BLK_RSS;
1901 	struct ice_flow_prof *p, *t;
1902 	int status = 0;
1903 
1904 	if (!ice_is_vsi_valid(hw, vsi_handle))
1905 		return -EINVAL;
1906 
1907 	if (list_empty(&hw->fl_profs[blk]))
1908 		return 0;
1909 
1910 	mutex_lock(&hw->rss_locks);
1911 	list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1912 		if (test_bit(vsi_handle, p->vsis)) {
1913 			status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1914 			if (status)
1915 				break;
1916 
1917 			if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1918 				status = ice_flow_rem_prof(hw, blk, p->id);
1919 				if (status)
1920 					break;
1921 			}
1922 		}
1923 	mutex_unlock(&hw->rss_locks);
1924 
1925 	return status;
1926 }
1927 
1928 /**
1929  * ice_rem_rss_list - remove RSS configuration from list
1930  * @hw: pointer to the hardware structure
1931  * @vsi_handle: software VSI handle
1932  * @prof: pointer to flow profile
1933  *
1934  * Assumption: lock has already been acquired for RSS list
1935  */
1936 static void
1937 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1938 {
1939 	struct ice_rss_cfg *r, *tmp;
1940 
1941 	/* Search for RSS hash fields associated to the VSI that match the
1942 	 * hash configurations associated to the flow profile. If found
1943 	 * remove from the RSS entry list of the VSI context and delete entry.
1944 	 */
1945 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1946 		if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1947 		    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1948 			clear_bit(vsi_handle, r->vsis);
1949 			if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1950 				list_del(&r->l_entry);
1951 				devm_kfree(ice_hw_to_dev(hw), r);
1952 			}
1953 			return;
1954 		}
1955 }
1956 
1957 /**
1958  * ice_add_rss_list - add RSS configuration to list
1959  * @hw: pointer to the hardware structure
1960  * @vsi_handle: software VSI handle
1961  * @prof: pointer to flow profile
1962  *
1963  * Assumption: lock has already been acquired for RSS list
1964  */
1965 static int
1966 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1967 {
1968 	struct ice_rss_cfg *r, *rss_cfg;
1969 
1970 	list_for_each_entry(r, &hw->rss_list_head, l_entry)
1971 		if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1972 		    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1973 			set_bit(vsi_handle, r->vsis);
1974 			return 0;
1975 		}
1976 
1977 	rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
1978 			       GFP_KERNEL);
1979 	if (!rss_cfg)
1980 		return -ENOMEM;
1981 
1982 	rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
1983 	rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
1984 	set_bit(vsi_handle, rss_cfg->vsis);
1985 
1986 	list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
1987 
1988 	return 0;
1989 }
1990 
1991 #define ICE_FLOW_PROF_HASH_S	0
1992 #define ICE_FLOW_PROF_HASH_M	(0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
1993 #define ICE_FLOW_PROF_HDR_S	32
1994 #define ICE_FLOW_PROF_HDR_M	(0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
1995 #define ICE_FLOW_PROF_ENCAP_S	63
1996 #define ICE_FLOW_PROF_ENCAP_M	(BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
1997 
1998 #define ICE_RSS_OUTER_HEADERS	1
1999 #define ICE_RSS_INNER_HEADERS	2
2000 
2001 /* Flow profile ID format:
2002  * [0:31] - Packet match fields
2003  * [32:62] - Protocol header
2004  * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
2005  */
2006 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2007 	((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2008 	       (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2009 	       ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2010 
2011 /**
2012  * ice_add_rss_cfg_sync - add an RSS configuration
2013  * @hw: pointer to the hardware structure
2014  * @vsi_handle: software VSI handle
2015  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2016  * @addl_hdrs: protocol header fields
2017  * @segs_cnt: packet segment count
2018  *
2019  * Assumption: lock has already been acquired for RSS list
2020  */
2021 static int
2022 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2023 		     u32 addl_hdrs, u8 segs_cnt)
2024 {
2025 	const enum ice_block blk = ICE_BLK_RSS;
2026 	struct ice_flow_prof *prof = NULL;
2027 	struct ice_flow_seg_info *segs;
2028 	int status;
2029 
2030 	if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2031 		return -EINVAL;
2032 
2033 	segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2034 	if (!segs)
2035 		return -ENOMEM;
2036 
2037 	/* Construct the packet segment info from the hashed fields */
2038 	status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2039 					   addl_hdrs);
2040 	if (status)
2041 		goto exit;
2042 
2043 	/* Search for a flow profile that has matching headers, hash fields
2044 	 * and has the input VSI associated to it. If found, no further
2045 	 * operations required and exit.
2046 	 */
2047 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2048 					vsi_handle,
2049 					ICE_FLOW_FIND_PROF_CHK_FLDS |
2050 					ICE_FLOW_FIND_PROF_CHK_VSI);
2051 	if (prof)
2052 		goto exit;
2053 
2054 	/* Check if a flow profile exists with the same protocol headers and
2055 	 * associated with the input VSI. If so disassociate the VSI from
2056 	 * this profile. The VSI will be added to a new profile created with
2057 	 * the protocol header and new hash field configuration.
2058 	 */
2059 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2060 					vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2061 	if (prof) {
2062 		status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2063 		if (!status)
2064 			ice_rem_rss_list(hw, vsi_handle, prof);
2065 		else
2066 			goto exit;
2067 
2068 		/* Remove profile if it has no VSIs associated */
2069 		if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2070 			status = ice_flow_rem_prof(hw, blk, prof->id);
2071 			if (status)
2072 				goto exit;
2073 		}
2074 	}
2075 
2076 	/* Search for a profile that has same match fields only. If this
2077 	 * exists then associate the VSI to this profile.
2078 	 */
2079 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2080 					vsi_handle,
2081 					ICE_FLOW_FIND_PROF_CHK_FLDS);
2082 	if (prof) {
2083 		status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2084 		if (!status)
2085 			status = ice_add_rss_list(hw, vsi_handle, prof);
2086 		goto exit;
2087 	}
2088 
2089 	/* Create a new flow profile with generated profile and packet
2090 	 * segment information.
2091 	 */
2092 	status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2093 				   ICE_FLOW_GEN_PROFID(hashed_flds,
2094 						       segs[segs_cnt - 1].hdrs,
2095 						       segs_cnt),
2096 				   segs, segs_cnt, &prof);
2097 	if (status)
2098 		goto exit;
2099 
2100 	status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2101 	/* If association to a new flow profile failed then this profile can
2102 	 * be removed.
2103 	 */
2104 	if (status) {
2105 		ice_flow_rem_prof(hw, blk, prof->id);
2106 		goto exit;
2107 	}
2108 
2109 	status = ice_add_rss_list(hw, vsi_handle, prof);
2110 
2111 exit:
2112 	kfree(segs);
2113 	return status;
2114 }
2115 
2116 /**
2117  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2118  * @hw: pointer to the hardware structure
2119  * @vsi_handle: software VSI handle
2120  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2121  * @addl_hdrs: protocol header fields
2122  *
2123  * This function will generate a flow profile based on fields associated with
2124  * the input fields to hash on, the flow type and use the VSI number to add
2125  * a flow entry to the profile.
2126  */
2127 int
2128 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2129 		u32 addl_hdrs)
2130 {
2131 	int status;
2132 
2133 	if (hashed_flds == ICE_HASH_INVALID ||
2134 	    !ice_is_vsi_valid(hw, vsi_handle))
2135 		return -EINVAL;
2136 
2137 	mutex_lock(&hw->rss_locks);
2138 	status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2139 				      ICE_RSS_OUTER_HEADERS);
2140 	if (!status)
2141 		status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2142 					      addl_hdrs, ICE_RSS_INNER_HEADERS);
2143 	mutex_unlock(&hw->rss_locks);
2144 
2145 	return status;
2146 }
2147 
2148 /**
2149  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2150  * @hw: pointer to the hardware structure
2151  * @vsi_handle: software VSI handle
2152  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2153  * @addl_hdrs: Protocol header fields within a packet segment
2154  * @segs_cnt: packet segment count
2155  *
2156  * Assumption: lock has already been acquired for RSS list
2157  */
2158 static int
2159 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2160 		     u32 addl_hdrs, u8 segs_cnt)
2161 {
2162 	const enum ice_block blk = ICE_BLK_RSS;
2163 	struct ice_flow_seg_info *segs;
2164 	struct ice_flow_prof *prof;
2165 	int status;
2166 
2167 	segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2168 	if (!segs)
2169 		return -ENOMEM;
2170 
2171 	/* Construct the packet segment info from the hashed fields */
2172 	status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2173 					   addl_hdrs);
2174 	if (status)
2175 		goto out;
2176 
2177 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2178 					vsi_handle,
2179 					ICE_FLOW_FIND_PROF_CHK_FLDS);
2180 	if (!prof) {
2181 		status = -ENOENT;
2182 		goto out;
2183 	}
2184 
2185 	status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2186 	if (status)
2187 		goto out;
2188 
2189 	/* Remove RSS configuration from VSI context before deleting
2190 	 * the flow profile.
2191 	 */
2192 	ice_rem_rss_list(hw, vsi_handle, prof);
2193 
2194 	if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2195 		status = ice_flow_rem_prof(hw, blk, prof->id);
2196 
2197 out:
2198 	kfree(segs);
2199 	return status;
2200 }
2201 
2202 /**
2203  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2204  * @hw: pointer to the hardware structure
2205  * @vsi_handle: software VSI handle
2206  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2207  * @addl_hdrs: Protocol header fields within a packet segment
2208  *
2209  * This function will lookup the flow profile based on the input
2210  * hash field bitmap, iterate through the profile entry list of
2211  * that profile and find entry associated with input VSI to be
2212  * removed. Calls are made to underlying flow s which will APIs
2213  * turn build or update buffers for RSS XLT1 section.
2214  */
2215 int __maybe_unused
2216 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2217 		u32 addl_hdrs)
2218 {
2219 	int status;
2220 
2221 	if (hashed_flds == ICE_HASH_INVALID ||
2222 	    !ice_is_vsi_valid(hw, vsi_handle))
2223 		return -EINVAL;
2224 
2225 	mutex_lock(&hw->rss_locks);
2226 	status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2227 				      ICE_RSS_OUTER_HEADERS);
2228 	if (!status)
2229 		status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2230 					      addl_hdrs, ICE_RSS_INNER_HEADERS);
2231 	mutex_unlock(&hw->rss_locks);
2232 
2233 	return status;
2234 }
2235 
2236 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2237  * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2238  * convert its values to their appropriate flow L3, L4 values.
2239  */
2240 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2241 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2242 	 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2243 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2244 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2245 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2246 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2247 	(BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2248 	 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2249 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2250 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2251 	(ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2252 	 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2253 
2254 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2255 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2256 	 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2257 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2258 	(BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2259 	 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2260 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2261 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2262 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2263 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2264 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2265 	(ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2266 	 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2267 
2268 /**
2269  * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2270  * @hw: pointer to the hardware structure
2271  * @vsi_handle: software VSI handle
2272  * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2273  *
2274  * This function will take the hash bitmap provided by the AVF driver via a
2275  * message, convert it to ICE-compatible values, and configure RSS flow
2276  * profiles.
2277  */
2278 int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2279 {
2280 	int status = 0;
2281 	u64 hash_flds;
2282 
2283 	if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2284 	    !ice_is_vsi_valid(hw, vsi_handle))
2285 		return -EINVAL;
2286 
2287 	/* Make sure no unsupported bits are specified */
2288 	if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2289 			 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2290 		return -EIO;
2291 
2292 	hash_flds = avf_hash;
2293 
2294 	/* Always create an L3 RSS configuration for any L4 RSS configuration */
2295 	if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2296 		hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2297 
2298 	if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2299 		hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2300 
2301 	/* Create the corresponding RSS configuration for each valid hash bit */
2302 	while (hash_flds) {
2303 		u64 rss_hash = ICE_HASH_INVALID;
2304 
2305 		if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2306 			if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2307 				rss_hash = ICE_FLOW_HASH_IPV4;
2308 				hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2309 			} else if (hash_flds &
2310 				   ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2311 				rss_hash = ICE_FLOW_HASH_IPV4 |
2312 					ICE_FLOW_HASH_TCP_PORT;
2313 				hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2314 			} else if (hash_flds &
2315 				   ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2316 				rss_hash = ICE_FLOW_HASH_IPV4 |
2317 					ICE_FLOW_HASH_UDP_PORT;
2318 				hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2319 			} else if (hash_flds &
2320 				   BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2321 				rss_hash = ICE_FLOW_HASH_IPV4 |
2322 					ICE_FLOW_HASH_SCTP_PORT;
2323 				hash_flds &=
2324 					~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2325 			}
2326 		} else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2327 			if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2328 				rss_hash = ICE_FLOW_HASH_IPV6;
2329 				hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2330 			} else if (hash_flds &
2331 				   ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2332 				rss_hash = ICE_FLOW_HASH_IPV6 |
2333 					ICE_FLOW_HASH_TCP_PORT;
2334 				hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2335 			} else if (hash_flds &
2336 				   ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2337 				rss_hash = ICE_FLOW_HASH_IPV6 |
2338 					ICE_FLOW_HASH_UDP_PORT;
2339 				hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2340 			} else if (hash_flds &
2341 				   BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2342 				rss_hash = ICE_FLOW_HASH_IPV6 |
2343 					ICE_FLOW_HASH_SCTP_PORT;
2344 				hash_flds &=
2345 					~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2346 			}
2347 		}
2348 
2349 		if (rss_hash == ICE_HASH_INVALID)
2350 			return -EIO;
2351 
2352 		status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2353 					 ICE_FLOW_SEG_HDR_NONE);
2354 		if (status)
2355 			break;
2356 	}
2357 
2358 	return status;
2359 }
2360 
2361 /**
2362  * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2363  * @hw: pointer to the hardware structure
2364  * @vsi_handle: software VSI handle
2365  */
2366 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2367 {
2368 	struct ice_rss_cfg *r;
2369 	int status = 0;
2370 
2371 	if (!ice_is_vsi_valid(hw, vsi_handle))
2372 		return -EINVAL;
2373 
2374 	mutex_lock(&hw->rss_locks);
2375 	list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2376 		if (test_bit(vsi_handle, r->vsis)) {
2377 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
2378 						      r->hashed_flds,
2379 						      r->packet_hdr,
2380 						      ICE_RSS_OUTER_HEADERS);
2381 			if (status)
2382 				break;
2383 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
2384 						      r->hashed_flds,
2385 						      r->packet_hdr,
2386 						      ICE_RSS_INNER_HEADERS);
2387 			if (status)
2388 				break;
2389 		}
2390 	}
2391 	mutex_unlock(&hw->rss_locks);
2392 
2393 	return status;
2394 }
2395 
2396 /**
2397  * ice_get_rss_cfg - returns hashed fields for the given header types
2398  * @hw: pointer to the hardware structure
2399  * @vsi_handle: software VSI handle
2400  * @hdrs: protocol header type
2401  *
2402  * This function will return the match fields of the first instance of flow
2403  * profile having the given header types and containing input VSI
2404  */
2405 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2406 {
2407 	u64 rss_hash = ICE_HASH_INVALID;
2408 	struct ice_rss_cfg *r;
2409 
2410 	/* verify if the protocol header is non zero and VSI is valid */
2411 	if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2412 		return ICE_HASH_INVALID;
2413 
2414 	mutex_lock(&hw->rss_locks);
2415 	list_for_each_entry(r, &hw->rss_list_head, l_entry)
2416 		if (test_bit(vsi_handle, r->vsis) &&
2417 		    r->packet_hdr == hdrs) {
2418 			rss_hash = r->hashed_flds;
2419 			break;
2420 		}
2421 	mutex_unlock(&hw->rss_locks);
2422 
2423 	return rss_hash;
2424 }
2425