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_L3_MASK	\
613 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
614 #define ICE_FLOW_SEG_HDRS_L4_MASK	\
615 	(ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
616 	 ICE_FLOW_SEG_HDR_SCTP)
617 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
618 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER	\
619 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
620 
621 /**
622  * ice_flow_val_hdrs - validates packet segments for valid protocol headers
623  * @segs: array of one or more packet segments that describe the flow
624  * @segs_cnt: number of packet segments provided
625  */
626 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
627 {
628 	u8 i;
629 
630 	for (i = 0; i < segs_cnt; i++) {
631 		/* Multiple L3 headers */
632 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
633 		    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
634 			return -EINVAL;
635 
636 		/* Multiple L4 headers */
637 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
638 		    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
639 			return -EINVAL;
640 	}
641 
642 	return 0;
643 }
644 
645 /* Sizes of fixed known protocol headers without header options */
646 #define ICE_FLOW_PROT_HDR_SZ_MAC	14
647 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN	(ICE_FLOW_PROT_HDR_SZ_MAC + 2)
648 #define ICE_FLOW_PROT_HDR_SZ_IPV4	20
649 #define ICE_FLOW_PROT_HDR_SZ_IPV6	40
650 #define ICE_FLOW_PROT_HDR_SZ_ARP	28
651 #define ICE_FLOW_PROT_HDR_SZ_ICMP	8
652 #define ICE_FLOW_PROT_HDR_SZ_TCP	20
653 #define ICE_FLOW_PROT_HDR_SZ_UDP	8
654 #define ICE_FLOW_PROT_HDR_SZ_SCTP	12
655 
656 /**
657  * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
658  * @params: information about the flow to be processed
659  * @seg: index of packet segment whose header size is to be determined
660  */
661 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
662 {
663 	u16 sz;
664 
665 	/* L2 headers */
666 	sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
667 		ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
668 
669 	/* L3 headers */
670 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
671 		sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
672 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
673 		sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
674 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
675 		sz += ICE_FLOW_PROT_HDR_SZ_ARP;
676 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
677 		/* An L3 header is required if L4 is specified */
678 		return 0;
679 
680 	/* L4 headers */
681 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
682 		sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
683 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
684 		sz += ICE_FLOW_PROT_HDR_SZ_TCP;
685 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
686 		sz += ICE_FLOW_PROT_HDR_SZ_UDP;
687 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
688 		sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
689 
690 	return sz;
691 }
692 
693 /**
694  * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
695  * @params: information about the flow to be processed
696  *
697  * This function identifies the packet types associated with the protocol
698  * headers being present in packet segments of the specified flow profile.
699  */
700 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
701 {
702 	struct ice_flow_prof *prof;
703 	u8 i;
704 
705 	memset(params->ptypes, 0xff, sizeof(params->ptypes));
706 
707 	prof = params->prof;
708 
709 	for (i = 0; i < params->prof->segs_cnt; i++) {
710 		const unsigned long *src;
711 		u32 hdrs;
712 
713 		hdrs = prof->segs[i].hdrs;
714 
715 		if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
716 			src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
717 				(const unsigned long *)ice_ptypes_mac_il;
718 			bitmap_and(params->ptypes, params->ptypes, src,
719 				   ICE_FLOW_PTYPE_MAX);
720 		}
721 
722 		if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
723 			src = (const unsigned long *)ice_ptypes_macvlan_il;
724 			bitmap_and(params->ptypes, params->ptypes, src,
725 				   ICE_FLOW_PTYPE_MAX);
726 		}
727 
728 		if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
729 			bitmap_and(params->ptypes, params->ptypes,
730 				   (const unsigned long *)ice_ptypes_arp_of,
731 				   ICE_FLOW_PTYPE_MAX);
732 		}
733 
734 		if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
735 		    (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
736 			src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
737 				(const unsigned long *)ice_ptypes_ipv4_ofos_all;
738 			bitmap_and(params->ptypes, params->ptypes, src,
739 				   ICE_FLOW_PTYPE_MAX);
740 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
741 			   (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
742 			src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
743 				(const unsigned long *)ice_ptypes_ipv6_ofos_all;
744 			bitmap_and(params->ptypes, params->ptypes, src,
745 				   ICE_FLOW_PTYPE_MAX);
746 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
747 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
748 			src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
749 				(const unsigned long *)ice_ptypes_ipv4_il_no_l4;
750 			bitmap_and(params->ptypes, params->ptypes, src,
751 				   ICE_FLOW_PTYPE_MAX);
752 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
753 			src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
754 				(const unsigned long *)ice_ptypes_ipv4_il;
755 			bitmap_and(params->ptypes, params->ptypes, src,
756 				   ICE_FLOW_PTYPE_MAX);
757 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
758 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
759 			src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
760 				(const unsigned long *)ice_ptypes_ipv6_il_no_l4;
761 			bitmap_and(params->ptypes, params->ptypes, src,
762 				   ICE_FLOW_PTYPE_MAX);
763 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
764 			src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
765 				(const unsigned long *)ice_ptypes_ipv6_il;
766 			bitmap_and(params->ptypes, params->ptypes, src,
767 				   ICE_FLOW_PTYPE_MAX);
768 		}
769 
770 		if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
771 			src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
772 			bitmap_and(params->ptypes, params->ptypes, src,
773 				   ICE_FLOW_PTYPE_MAX);
774 		} else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
775 			src = (const unsigned long *)ice_ptypes_pppoe;
776 			bitmap_and(params->ptypes, params->ptypes, src,
777 				   ICE_FLOW_PTYPE_MAX);
778 		} else {
779 			src = (const unsigned long *)ice_ptypes_pppoe;
780 			bitmap_andnot(params->ptypes, params->ptypes, src,
781 				      ICE_FLOW_PTYPE_MAX);
782 		}
783 
784 		if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
785 			src = (const unsigned long *)ice_ptypes_udp_il;
786 			bitmap_and(params->ptypes, params->ptypes, src,
787 				   ICE_FLOW_PTYPE_MAX);
788 		} else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
789 			bitmap_and(params->ptypes, params->ptypes,
790 				   (const unsigned long *)ice_ptypes_tcp_il,
791 				   ICE_FLOW_PTYPE_MAX);
792 		} else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
793 			src = (const unsigned long *)ice_ptypes_sctp_il;
794 			bitmap_and(params->ptypes, params->ptypes, src,
795 				   ICE_FLOW_PTYPE_MAX);
796 		}
797 
798 		if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
799 			src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
800 				(const unsigned long *)ice_ptypes_icmp_il;
801 			bitmap_and(params->ptypes, params->ptypes, src,
802 				   ICE_FLOW_PTYPE_MAX);
803 		} else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
804 			if (!i) {
805 				src = (const unsigned long *)ice_ptypes_gre_of;
806 				bitmap_and(params->ptypes, params->ptypes,
807 					   src, ICE_FLOW_PTYPE_MAX);
808 			}
809 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
810 			src = (const unsigned long *)ice_ptypes_gtpc;
811 			bitmap_and(params->ptypes, params->ptypes, src,
812 				   ICE_FLOW_PTYPE_MAX);
813 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
814 			src = (const unsigned long *)ice_ptypes_gtpc_tid;
815 			bitmap_and(params->ptypes, params->ptypes, src,
816 				   ICE_FLOW_PTYPE_MAX);
817 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
818 			src = (const unsigned long *)ice_ptypes_gtpu;
819 			bitmap_and(params->ptypes, params->ptypes, src,
820 				   ICE_FLOW_PTYPE_MAX);
821 
822 			/* Attributes for GTP packet with downlink */
823 			params->attr = ice_attr_gtpu_down;
824 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
825 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
826 			src = (const unsigned long *)ice_ptypes_gtpu;
827 			bitmap_and(params->ptypes, params->ptypes, src,
828 				   ICE_FLOW_PTYPE_MAX);
829 
830 			/* Attributes for GTP packet with uplink */
831 			params->attr = ice_attr_gtpu_up;
832 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
833 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
834 			src = (const unsigned long *)ice_ptypes_gtpu;
835 			bitmap_and(params->ptypes, params->ptypes, src,
836 				   ICE_FLOW_PTYPE_MAX);
837 
838 			/* Attributes for GTP packet with Extension Header */
839 			params->attr = ice_attr_gtpu_eh;
840 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
841 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
842 			src = (const unsigned long *)ice_ptypes_gtpu;
843 			bitmap_and(params->ptypes, params->ptypes, src,
844 				   ICE_FLOW_PTYPE_MAX);
845 		} else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
846 			src = (const unsigned long *)ice_ptypes_l2tpv3;
847 			bitmap_and(params->ptypes, params->ptypes, src,
848 				   ICE_FLOW_PTYPE_MAX);
849 		} else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
850 			src = (const unsigned long *)ice_ptypes_esp;
851 			bitmap_and(params->ptypes, params->ptypes, src,
852 				   ICE_FLOW_PTYPE_MAX);
853 		} else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
854 			src = (const unsigned long *)ice_ptypes_ah;
855 			bitmap_and(params->ptypes, params->ptypes, src,
856 				   ICE_FLOW_PTYPE_MAX);
857 		} else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
858 			src = (const unsigned long *)ice_ptypes_nat_t_esp;
859 			bitmap_and(params->ptypes, params->ptypes, src,
860 				   ICE_FLOW_PTYPE_MAX);
861 		}
862 
863 		if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
864 			if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
865 				src = (const unsigned long *)ice_ptypes_pfcp_node;
866 			else
867 				src = (const unsigned long *)ice_ptypes_pfcp_session;
868 
869 			bitmap_and(params->ptypes, params->ptypes, src,
870 				   ICE_FLOW_PTYPE_MAX);
871 		} else {
872 			src = (const unsigned long *)ice_ptypes_pfcp_node;
873 			bitmap_andnot(params->ptypes, params->ptypes, src,
874 				      ICE_FLOW_PTYPE_MAX);
875 
876 			src = (const unsigned long *)ice_ptypes_pfcp_session;
877 			bitmap_andnot(params->ptypes, params->ptypes, src,
878 				      ICE_FLOW_PTYPE_MAX);
879 		}
880 	}
881 
882 	return 0;
883 }
884 
885 /**
886  * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
887  * @hw: pointer to the HW struct
888  * @params: information about the flow to be processed
889  * @seg: packet segment index of the field to be extracted
890  * @fld: ID of field to be extracted
891  * @match: bit field of all fields
892  *
893  * This function determines the protocol ID, offset, and size of the given
894  * field. It then allocates one or more extraction sequence entries for the
895  * given field, and fill the entries with protocol ID and offset information.
896  */
897 static int
898 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
899 		    u8 seg, enum ice_flow_field fld, u64 match)
900 {
901 	enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
902 	enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
903 	u8 fv_words = hw->blk[params->blk].es.fvw;
904 	struct ice_flow_fld_info *flds;
905 	u16 cnt, ese_bits, i;
906 	u16 sib_mask = 0;
907 	u16 mask;
908 	u16 off;
909 
910 	flds = params->prof->segs[seg].fields;
911 
912 	switch (fld) {
913 	case ICE_FLOW_FIELD_IDX_ETH_DA:
914 	case ICE_FLOW_FIELD_IDX_ETH_SA:
915 	case ICE_FLOW_FIELD_IDX_S_VLAN:
916 	case ICE_FLOW_FIELD_IDX_C_VLAN:
917 		prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
918 		break;
919 	case ICE_FLOW_FIELD_IDX_ETH_TYPE:
920 		prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
921 		break;
922 	case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
923 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
924 		break;
925 	case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
926 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
927 		break;
928 	case ICE_FLOW_FIELD_IDX_IPV4_TTL:
929 	case ICE_FLOW_FIELD_IDX_IPV4_PROT:
930 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
931 
932 		/* TTL and PROT share the same extraction seq. entry.
933 		 * Each is considered a sibling to the other in terms of sharing
934 		 * the same extraction sequence entry.
935 		 */
936 		if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
937 			sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
938 		else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
939 			sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
940 
941 		/* If the sibling field is also included, that field's
942 		 * mask needs to be included.
943 		 */
944 		if (match & BIT(sib))
945 			sib_mask = ice_flds_info[sib].mask;
946 		break;
947 	case ICE_FLOW_FIELD_IDX_IPV6_TTL:
948 	case ICE_FLOW_FIELD_IDX_IPV6_PROT:
949 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
950 
951 		/* TTL and PROT share the same extraction seq. entry.
952 		 * Each is considered a sibling to the other in terms of sharing
953 		 * the same extraction sequence entry.
954 		 */
955 		if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
956 			sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
957 		else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
958 			sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
959 
960 		/* If the sibling field is also included, that field's
961 		 * mask needs to be included.
962 		 */
963 		if (match & BIT(sib))
964 			sib_mask = ice_flds_info[sib].mask;
965 		break;
966 	case ICE_FLOW_FIELD_IDX_IPV4_SA:
967 	case ICE_FLOW_FIELD_IDX_IPV4_DA:
968 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
969 		break;
970 	case ICE_FLOW_FIELD_IDX_IPV6_SA:
971 	case ICE_FLOW_FIELD_IDX_IPV6_DA:
972 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
973 		break;
974 	case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
975 	case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
976 	case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
977 		prot_id = ICE_PROT_TCP_IL;
978 		break;
979 	case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
980 	case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
981 		prot_id = ICE_PROT_UDP_IL_OR_S;
982 		break;
983 	case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
984 	case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
985 		prot_id = ICE_PROT_SCTP_IL;
986 		break;
987 	case ICE_FLOW_FIELD_IDX_GTPC_TEID:
988 	case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
989 	case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
990 	case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
991 	case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
992 	case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
993 		/* GTP is accessed through UDP OF protocol */
994 		prot_id = ICE_PROT_UDP_OF;
995 		break;
996 	case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
997 		prot_id = ICE_PROT_PPPOE;
998 		break;
999 	case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1000 		prot_id = ICE_PROT_UDP_IL_OR_S;
1001 		break;
1002 	case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1003 		prot_id = ICE_PROT_L2TPV3;
1004 		break;
1005 	case ICE_FLOW_FIELD_IDX_ESP_SPI:
1006 		prot_id = ICE_PROT_ESP_F;
1007 		break;
1008 	case ICE_FLOW_FIELD_IDX_AH_SPI:
1009 		prot_id = ICE_PROT_ESP_2;
1010 		break;
1011 	case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1012 		prot_id = ICE_PROT_UDP_IL_OR_S;
1013 		break;
1014 	case ICE_FLOW_FIELD_IDX_ARP_SIP:
1015 	case ICE_FLOW_FIELD_IDX_ARP_DIP:
1016 	case ICE_FLOW_FIELD_IDX_ARP_SHA:
1017 	case ICE_FLOW_FIELD_IDX_ARP_DHA:
1018 	case ICE_FLOW_FIELD_IDX_ARP_OP:
1019 		prot_id = ICE_PROT_ARP_OF;
1020 		break;
1021 	case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1022 	case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1023 		/* ICMP type and code share the same extraction seq. entry */
1024 		prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1025 				ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1026 		sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1027 			ICE_FLOW_FIELD_IDX_ICMP_CODE :
1028 			ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1029 		break;
1030 	case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1031 		prot_id = ICE_PROT_GRE_OF;
1032 		break;
1033 	default:
1034 		return -EOPNOTSUPP;
1035 	}
1036 
1037 	/* Each extraction sequence entry is a word in size, and extracts a
1038 	 * word-aligned offset from a protocol header.
1039 	 */
1040 	ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1041 
1042 	flds[fld].xtrct.prot_id = prot_id;
1043 	flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1044 		ICE_FLOW_FV_EXTRACT_SZ;
1045 	flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1046 	flds[fld].xtrct.idx = params->es_cnt;
1047 	flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1048 
1049 	/* Adjust the next field-entry index after accommodating the number of
1050 	 * entries this field consumes
1051 	 */
1052 	cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1053 			   ese_bits);
1054 
1055 	/* Fill in the extraction sequence entries needed for this field */
1056 	off = flds[fld].xtrct.off;
1057 	mask = flds[fld].xtrct.mask;
1058 	for (i = 0; i < cnt; i++) {
1059 		/* Only consume an extraction sequence entry if there is no
1060 		 * sibling field associated with this field or the sibling entry
1061 		 * already extracts the word shared with this field.
1062 		 */
1063 		if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1064 		    flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1065 		    flds[sib].xtrct.off != off) {
1066 			u8 idx;
1067 
1068 			/* Make sure the number of extraction sequence required
1069 			 * does not exceed the block's capability
1070 			 */
1071 			if (params->es_cnt >= fv_words)
1072 				return -ENOSPC;
1073 
1074 			/* some blocks require a reversed field vector layout */
1075 			if (hw->blk[params->blk].es.reverse)
1076 				idx = fv_words - params->es_cnt - 1;
1077 			else
1078 				idx = params->es_cnt;
1079 
1080 			params->es[idx].prot_id = prot_id;
1081 			params->es[idx].off = off;
1082 			params->mask[idx] = mask | sib_mask;
1083 			params->es_cnt++;
1084 		}
1085 
1086 		off += ICE_FLOW_FV_EXTRACT_SZ;
1087 	}
1088 
1089 	return 0;
1090 }
1091 
1092 /**
1093  * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1094  * @hw: pointer to the HW struct
1095  * @params: information about the flow to be processed
1096  * @seg: index of packet segment whose raw fields are to be extracted
1097  */
1098 static int
1099 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1100 		     u8 seg)
1101 {
1102 	u16 fv_words;
1103 	u16 hdrs_sz;
1104 	u8 i;
1105 
1106 	if (!params->prof->segs[seg].raws_cnt)
1107 		return 0;
1108 
1109 	if (params->prof->segs[seg].raws_cnt >
1110 	    ARRAY_SIZE(params->prof->segs[seg].raws))
1111 		return -ENOSPC;
1112 
1113 	/* Offsets within the segment headers are not supported */
1114 	hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1115 	if (!hdrs_sz)
1116 		return -EINVAL;
1117 
1118 	fv_words = hw->blk[params->blk].es.fvw;
1119 
1120 	for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1121 		struct ice_flow_seg_fld_raw *raw;
1122 		u16 off, cnt, j;
1123 
1124 		raw = &params->prof->segs[seg].raws[i];
1125 
1126 		/* Storing extraction information */
1127 		raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1128 		raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1129 			ICE_FLOW_FV_EXTRACT_SZ;
1130 		raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1131 			BITS_PER_BYTE;
1132 		raw->info.xtrct.idx = params->es_cnt;
1133 
1134 		/* Determine the number of field vector entries this raw field
1135 		 * consumes.
1136 		 */
1137 		cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1138 				   (raw->info.src.last * BITS_PER_BYTE),
1139 				   (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1140 		off = raw->info.xtrct.off;
1141 		for (j = 0; j < cnt; j++) {
1142 			u16 idx;
1143 
1144 			/* Make sure the number of extraction sequence required
1145 			 * does not exceed the block's capability
1146 			 */
1147 			if (params->es_cnt >= hw->blk[params->blk].es.count ||
1148 			    params->es_cnt >= ICE_MAX_FV_WORDS)
1149 				return -ENOSPC;
1150 
1151 			/* some blocks require a reversed field vector layout */
1152 			if (hw->blk[params->blk].es.reverse)
1153 				idx = fv_words - params->es_cnt - 1;
1154 			else
1155 				idx = params->es_cnt;
1156 
1157 			params->es[idx].prot_id = raw->info.xtrct.prot_id;
1158 			params->es[idx].off = off;
1159 			params->es_cnt++;
1160 			off += ICE_FLOW_FV_EXTRACT_SZ;
1161 		}
1162 	}
1163 
1164 	return 0;
1165 }
1166 
1167 /**
1168  * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1169  * @hw: pointer to the HW struct
1170  * @params: information about the flow to be processed
1171  *
1172  * This function iterates through all matched fields in the given segments, and
1173  * creates an extraction sequence for the fields.
1174  */
1175 static int
1176 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1177 			  struct ice_flow_prof_params *params)
1178 {
1179 	struct ice_flow_prof *prof = params->prof;
1180 	int status = 0;
1181 	u8 i;
1182 
1183 	for (i = 0; i < prof->segs_cnt; i++) {
1184 		u64 match = params->prof->segs[i].match;
1185 		enum ice_flow_field j;
1186 
1187 		for_each_set_bit(j, (unsigned long *)&match,
1188 				 ICE_FLOW_FIELD_IDX_MAX) {
1189 			status = ice_flow_xtract_fld(hw, params, i, j, match);
1190 			if (status)
1191 				return status;
1192 			clear_bit(j, (unsigned long *)&match);
1193 		}
1194 
1195 		/* Process raw matching bytes */
1196 		status = ice_flow_xtract_raws(hw, params, i);
1197 		if (status)
1198 			return status;
1199 	}
1200 
1201 	return status;
1202 }
1203 
1204 /**
1205  * ice_flow_proc_segs - process all packet segments associated with a profile
1206  * @hw: pointer to the HW struct
1207  * @params: information about the flow to be processed
1208  */
1209 static int
1210 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1211 {
1212 	int status;
1213 
1214 	status = ice_flow_proc_seg_hdrs(params);
1215 	if (status)
1216 		return status;
1217 
1218 	status = ice_flow_create_xtrct_seq(hw, params);
1219 	if (status)
1220 		return status;
1221 
1222 	switch (params->blk) {
1223 	case ICE_BLK_FD:
1224 	case ICE_BLK_RSS:
1225 		status = 0;
1226 		break;
1227 	default:
1228 		return -EOPNOTSUPP;
1229 	}
1230 
1231 	return status;
1232 }
1233 
1234 #define ICE_FLOW_FIND_PROF_CHK_FLDS	0x00000001
1235 #define ICE_FLOW_FIND_PROF_CHK_VSI	0x00000002
1236 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR	0x00000004
1237 
1238 /**
1239  * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1240  * @hw: pointer to the HW struct
1241  * @blk: classification stage
1242  * @dir: flow direction
1243  * @segs: array of one or more packet segments that describe the flow
1244  * @segs_cnt: number of packet segments provided
1245  * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1246  * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1247  */
1248 static struct ice_flow_prof *
1249 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1250 			 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1251 			 u8 segs_cnt, u16 vsi_handle, u32 conds)
1252 {
1253 	struct ice_flow_prof *p, *prof = NULL;
1254 
1255 	mutex_lock(&hw->fl_profs_locks[blk]);
1256 	list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1257 		if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1258 		    segs_cnt && segs_cnt == p->segs_cnt) {
1259 			u8 i;
1260 
1261 			/* Check for profile-VSI association if specified */
1262 			if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1263 			    ice_is_vsi_valid(hw, vsi_handle) &&
1264 			    !test_bit(vsi_handle, p->vsis))
1265 				continue;
1266 
1267 			/* Protocol headers must be checked. Matched fields are
1268 			 * checked if specified.
1269 			 */
1270 			for (i = 0; i < segs_cnt; i++)
1271 				if (segs[i].hdrs != p->segs[i].hdrs ||
1272 				    ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1273 				     segs[i].match != p->segs[i].match))
1274 					break;
1275 
1276 			/* A match is found if all segments are matched */
1277 			if (i == segs_cnt) {
1278 				prof = p;
1279 				break;
1280 			}
1281 		}
1282 	mutex_unlock(&hw->fl_profs_locks[blk]);
1283 
1284 	return prof;
1285 }
1286 
1287 /**
1288  * ice_flow_find_prof_id - Look up a profile with given profile ID
1289  * @hw: pointer to the HW struct
1290  * @blk: classification stage
1291  * @prof_id: unique ID to identify this flow profile
1292  */
1293 static struct ice_flow_prof *
1294 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1295 {
1296 	struct ice_flow_prof *p;
1297 
1298 	list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1299 		if (p->id == prof_id)
1300 			return p;
1301 
1302 	return NULL;
1303 }
1304 
1305 /**
1306  * ice_dealloc_flow_entry - Deallocate flow entry memory
1307  * @hw: pointer to the HW struct
1308  * @entry: flow entry to be removed
1309  */
1310 static void
1311 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1312 {
1313 	if (!entry)
1314 		return;
1315 
1316 	if (entry->entry)
1317 		devm_kfree(ice_hw_to_dev(hw), entry->entry);
1318 
1319 	devm_kfree(ice_hw_to_dev(hw), entry);
1320 }
1321 
1322 /**
1323  * ice_flow_rem_entry_sync - Remove a flow entry
1324  * @hw: pointer to the HW struct
1325  * @blk: classification stage
1326  * @entry: flow entry to be removed
1327  */
1328 static int
1329 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1330 			struct ice_flow_entry *entry)
1331 {
1332 	if (!entry)
1333 		return -EINVAL;
1334 
1335 	list_del(&entry->l_entry);
1336 
1337 	ice_dealloc_flow_entry(hw, entry);
1338 
1339 	return 0;
1340 }
1341 
1342 /**
1343  * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1344  * @hw: pointer to the HW struct
1345  * @blk: classification stage
1346  * @dir: flow direction
1347  * @prof_id: unique ID to identify this flow profile
1348  * @segs: array of one or more packet segments that describe the flow
1349  * @segs_cnt: number of packet segments provided
1350  * @prof: stores the returned flow profile added
1351  *
1352  * Assumption: the caller has acquired the lock to the profile list
1353  */
1354 static int
1355 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1356 		       enum ice_flow_dir dir, u64 prof_id,
1357 		       struct ice_flow_seg_info *segs, u8 segs_cnt,
1358 		       struct ice_flow_prof **prof)
1359 {
1360 	struct ice_flow_prof_params *params;
1361 	int status;
1362 	u8 i;
1363 
1364 	if (!prof)
1365 		return -EINVAL;
1366 
1367 	params = kzalloc(sizeof(*params), GFP_KERNEL);
1368 	if (!params)
1369 		return -ENOMEM;
1370 
1371 	params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1372 				    GFP_KERNEL);
1373 	if (!params->prof) {
1374 		status = -ENOMEM;
1375 		goto free_params;
1376 	}
1377 
1378 	/* initialize extraction sequence to all invalid (0xff) */
1379 	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1380 		params->es[i].prot_id = ICE_PROT_INVALID;
1381 		params->es[i].off = ICE_FV_OFFSET_INVAL;
1382 	}
1383 
1384 	params->blk = blk;
1385 	params->prof->id = prof_id;
1386 	params->prof->dir = dir;
1387 	params->prof->segs_cnt = segs_cnt;
1388 
1389 	/* Make a copy of the segments that need to be persistent in the flow
1390 	 * profile instance
1391 	 */
1392 	for (i = 0; i < segs_cnt; i++)
1393 		memcpy(&params->prof->segs[i], &segs[i], sizeof(*segs));
1394 
1395 	status = ice_flow_proc_segs(hw, params);
1396 	if (status) {
1397 		ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1398 		goto out;
1399 	}
1400 
1401 	/* Add a HW profile for this flow profile */
1402 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1403 			      params->attr, params->attr_cnt, params->es,
1404 			      params->mask);
1405 	if (status) {
1406 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1407 		goto out;
1408 	}
1409 
1410 	INIT_LIST_HEAD(&params->prof->entries);
1411 	mutex_init(&params->prof->entries_lock);
1412 	*prof = params->prof;
1413 
1414 out:
1415 	if (status)
1416 		devm_kfree(ice_hw_to_dev(hw), params->prof);
1417 free_params:
1418 	kfree(params);
1419 
1420 	return status;
1421 }
1422 
1423 /**
1424  * ice_flow_rem_prof_sync - remove a flow profile
1425  * @hw: pointer to the hardware structure
1426  * @blk: classification stage
1427  * @prof: pointer to flow profile to remove
1428  *
1429  * Assumption: the caller has acquired the lock to the profile list
1430  */
1431 static int
1432 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1433 		       struct ice_flow_prof *prof)
1434 {
1435 	int status;
1436 
1437 	/* Remove all remaining flow entries before removing the flow profile */
1438 	if (!list_empty(&prof->entries)) {
1439 		struct ice_flow_entry *e, *t;
1440 
1441 		mutex_lock(&prof->entries_lock);
1442 
1443 		list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1444 			status = ice_flow_rem_entry_sync(hw, blk, e);
1445 			if (status)
1446 				break;
1447 		}
1448 
1449 		mutex_unlock(&prof->entries_lock);
1450 	}
1451 
1452 	/* Remove all hardware profiles associated with this flow profile */
1453 	status = ice_rem_prof(hw, blk, prof->id);
1454 	if (!status) {
1455 		list_del(&prof->l_entry);
1456 		mutex_destroy(&prof->entries_lock);
1457 		devm_kfree(ice_hw_to_dev(hw), prof);
1458 	}
1459 
1460 	return status;
1461 }
1462 
1463 /**
1464  * ice_flow_assoc_prof - associate a VSI with a flow profile
1465  * @hw: pointer to the hardware structure
1466  * @blk: classification stage
1467  * @prof: pointer to flow profile
1468  * @vsi_handle: software VSI handle
1469  *
1470  * Assumption: the caller has acquired the lock to the profile list
1471  * and the software VSI handle has been validated
1472  */
1473 static int
1474 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1475 		    struct ice_flow_prof *prof, u16 vsi_handle)
1476 {
1477 	int status = 0;
1478 
1479 	if (!test_bit(vsi_handle, prof->vsis)) {
1480 		status = ice_add_prof_id_flow(hw, blk,
1481 					      ice_get_hw_vsi_num(hw,
1482 								 vsi_handle),
1483 					      prof->id);
1484 		if (!status)
1485 			set_bit(vsi_handle, prof->vsis);
1486 		else
1487 			ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1488 				  status);
1489 	}
1490 
1491 	return status;
1492 }
1493 
1494 /**
1495  * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1496  * @hw: pointer to the hardware structure
1497  * @blk: classification stage
1498  * @prof: pointer to flow profile
1499  * @vsi_handle: software VSI handle
1500  *
1501  * Assumption: the caller has acquired the lock to the profile list
1502  * and the software VSI handle has been validated
1503  */
1504 static int
1505 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1506 		       struct ice_flow_prof *prof, u16 vsi_handle)
1507 {
1508 	int status = 0;
1509 
1510 	if (test_bit(vsi_handle, prof->vsis)) {
1511 		status = ice_rem_prof_id_flow(hw, blk,
1512 					      ice_get_hw_vsi_num(hw,
1513 								 vsi_handle),
1514 					      prof->id);
1515 		if (!status)
1516 			clear_bit(vsi_handle, prof->vsis);
1517 		else
1518 			ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1519 				  status);
1520 	}
1521 
1522 	return status;
1523 }
1524 
1525 /**
1526  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1527  * @hw: pointer to the HW struct
1528  * @blk: classification stage
1529  * @dir: flow direction
1530  * @prof_id: unique ID to identify this flow profile
1531  * @segs: array of one or more packet segments that describe the flow
1532  * @segs_cnt: number of packet segments provided
1533  * @prof: stores the returned flow profile added
1534  */
1535 int
1536 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1537 		  u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1538 		  struct ice_flow_prof **prof)
1539 {
1540 	int status;
1541 
1542 	if (segs_cnt > ICE_FLOW_SEG_MAX)
1543 		return -ENOSPC;
1544 
1545 	if (!segs_cnt)
1546 		return -EINVAL;
1547 
1548 	if (!segs)
1549 		return -EINVAL;
1550 
1551 	status = ice_flow_val_hdrs(segs, segs_cnt);
1552 	if (status)
1553 		return status;
1554 
1555 	mutex_lock(&hw->fl_profs_locks[blk]);
1556 
1557 	status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1558 					prof);
1559 	if (!status)
1560 		list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1561 
1562 	mutex_unlock(&hw->fl_profs_locks[blk]);
1563 
1564 	return status;
1565 }
1566 
1567 /**
1568  * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1569  * @hw: pointer to the HW struct
1570  * @blk: the block for which the flow profile is to be removed
1571  * @prof_id: unique ID of the flow profile to be removed
1572  */
1573 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1574 {
1575 	struct ice_flow_prof *prof;
1576 	int status;
1577 
1578 	mutex_lock(&hw->fl_profs_locks[blk]);
1579 
1580 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
1581 	if (!prof) {
1582 		status = -ENOENT;
1583 		goto out;
1584 	}
1585 
1586 	/* prof becomes invalid after the call */
1587 	status = ice_flow_rem_prof_sync(hw, blk, prof);
1588 
1589 out:
1590 	mutex_unlock(&hw->fl_profs_locks[blk]);
1591 
1592 	return status;
1593 }
1594 
1595 /**
1596  * ice_flow_add_entry - Add a flow entry
1597  * @hw: pointer to the HW struct
1598  * @blk: classification stage
1599  * @prof_id: ID of the profile to add a new flow entry to
1600  * @entry_id: unique ID to identify this flow entry
1601  * @vsi_handle: software VSI handle for the flow entry
1602  * @prio: priority of the flow entry
1603  * @data: pointer to a data buffer containing flow entry's match values/masks
1604  * @entry_h: pointer to buffer that receives the new flow entry's handle
1605  */
1606 int
1607 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1608 		   u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1609 		   void *data, u64 *entry_h)
1610 {
1611 	struct ice_flow_entry *e = NULL;
1612 	struct ice_flow_prof *prof;
1613 	int status;
1614 
1615 	/* No flow entry data is expected for RSS */
1616 	if (!entry_h || (!data && blk != ICE_BLK_RSS))
1617 		return -EINVAL;
1618 
1619 	if (!ice_is_vsi_valid(hw, vsi_handle))
1620 		return -EINVAL;
1621 
1622 	mutex_lock(&hw->fl_profs_locks[blk]);
1623 
1624 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
1625 	if (!prof) {
1626 		status = -ENOENT;
1627 	} else {
1628 		/* Allocate memory for the entry being added and associate
1629 		 * the VSI to the found flow profile
1630 		 */
1631 		e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1632 		if (!e)
1633 			status = -ENOMEM;
1634 		else
1635 			status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1636 	}
1637 
1638 	mutex_unlock(&hw->fl_profs_locks[blk]);
1639 	if (status)
1640 		goto out;
1641 
1642 	e->id = entry_id;
1643 	e->vsi_handle = vsi_handle;
1644 	e->prof = prof;
1645 	e->priority = prio;
1646 
1647 	switch (blk) {
1648 	case ICE_BLK_FD:
1649 	case ICE_BLK_RSS:
1650 		break;
1651 	default:
1652 		status = -EOPNOTSUPP;
1653 		goto out;
1654 	}
1655 
1656 	mutex_lock(&prof->entries_lock);
1657 	list_add(&e->l_entry, &prof->entries);
1658 	mutex_unlock(&prof->entries_lock);
1659 
1660 	*entry_h = ICE_FLOW_ENTRY_HNDL(e);
1661 
1662 out:
1663 	if (status && e) {
1664 		if (e->entry)
1665 			devm_kfree(ice_hw_to_dev(hw), e->entry);
1666 		devm_kfree(ice_hw_to_dev(hw), e);
1667 	}
1668 
1669 	return status;
1670 }
1671 
1672 /**
1673  * ice_flow_rem_entry - Remove a flow entry
1674  * @hw: pointer to the HW struct
1675  * @blk: classification stage
1676  * @entry_h: handle to the flow entry to be removed
1677  */
1678 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1679 {
1680 	struct ice_flow_entry *entry;
1681 	struct ice_flow_prof *prof;
1682 	int status = 0;
1683 
1684 	if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1685 		return -EINVAL;
1686 
1687 	entry = ICE_FLOW_ENTRY_PTR(entry_h);
1688 
1689 	/* Retain the pointer to the flow profile as the entry will be freed */
1690 	prof = entry->prof;
1691 
1692 	if (prof) {
1693 		mutex_lock(&prof->entries_lock);
1694 		status = ice_flow_rem_entry_sync(hw, blk, entry);
1695 		mutex_unlock(&prof->entries_lock);
1696 	}
1697 
1698 	return status;
1699 }
1700 
1701 /**
1702  * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1703  * @seg: packet segment the field being set belongs to
1704  * @fld: field to be set
1705  * @field_type: type of the field
1706  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1707  *           entry's input buffer
1708  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1709  *            input buffer
1710  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1711  *            entry's input buffer
1712  *
1713  * This helper function stores information of a field being matched, including
1714  * the type of the field and the locations of the value to match, the mask, and
1715  * the upper-bound value in the start of the input buffer for a flow entry.
1716  * This function should only be used for fixed-size data structures.
1717  *
1718  * This function also opportunistically determines the protocol headers to be
1719  * present based on the fields being set. Some fields cannot be used alone to
1720  * determine the protocol headers present. Sometimes, fields for particular
1721  * protocol headers are not matched. In those cases, the protocol headers
1722  * must be explicitly set.
1723  */
1724 static void
1725 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1726 		     enum ice_flow_fld_match_type field_type, u16 val_loc,
1727 		     u16 mask_loc, u16 last_loc)
1728 {
1729 	u64 bit = BIT_ULL(fld);
1730 
1731 	seg->match |= bit;
1732 	if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1733 		seg->range |= bit;
1734 
1735 	seg->fields[fld].type = field_type;
1736 	seg->fields[fld].src.val = val_loc;
1737 	seg->fields[fld].src.mask = mask_loc;
1738 	seg->fields[fld].src.last = last_loc;
1739 
1740 	ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1741 }
1742 
1743 /**
1744  * ice_flow_set_fld - specifies locations of field from entry's input buffer
1745  * @seg: packet segment the field being set belongs to
1746  * @fld: field to be set
1747  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1748  *           entry's input buffer
1749  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1750  *            input buffer
1751  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1752  *            entry's input buffer
1753  * @range: indicate if field being matched is to be in a range
1754  *
1755  * This function specifies the locations, in the form of byte offsets from the
1756  * start of the input buffer for a flow entry, from where the value to match,
1757  * the mask value, and upper value can be extracted. These locations are then
1758  * stored in the flow profile. When adding a flow entry associated with the
1759  * flow profile, these locations will be used to quickly extract the values and
1760  * create the content of a match entry. This function should only be used for
1761  * fixed-size data structures.
1762  */
1763 void
1764 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1765 		 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1766 {
1767 	enum ice_flow_fld_match_type t = range ?
1768 		ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1769 
1770 	ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1771 }
1772 
1773 /**
1774  * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1775  * @seg: packet segment the field being set belongs to
1776  * @off: offset of the raw field from the beginning of the segment in bytes
1777  * @len: length of the raw pattern to be matched
1778  * @val_loc: location of the value to match from entry's input buffer
1779  * @mask_loc: location of mask value from entry's input buffer
1780  *
1781  * This function specifies the offset of the raw field to be match from the
1782  * beginning of the specified packet segment, and the locations, in the form of
1783  * byte offsets from the start of the input buffer for a flow entry, from where
1784  * the value to match and the mask value to be extracted. These locations are
1785  * then stored in the flow profile. When adding flow entries to the associated
1786  * flow profile, these locations can be used to quickly extract the values to
1787  * create the content of a match entry. This function should only be used for
1788  * fixed-size data structures.
1789  */
1790 void
1791 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1792 		     u16 val_loc, u16 mask_loc)
1793 {
1794 	if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1795 		seg->raws[seg->raws_cnt].off = off;
1796 		seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1797 		seg->raws[seg->raws_cnt].info.src.val = val_loc;
1798 		seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1799 		/* The "last" field is used to store the length of the field */
1800 		seg->raws[seg->raws_cnt].info.src.last = len;
1801 	}
1802 
1803 	/* Overflows of "raws" will be handled as an error condition later in
1804 	 * the flow when this information is processed.
1805 	 */
1806 	seg->raws_cnt++;
1807 }
1808 
1809 /**
1810  * ice_flow_rem_vsi_prof - remove VSI from flow profile
1811  * @hw: pointer to the hardware structure
1812  * @vsi_handle: software VSI handle
1813  * @prof_id: unique ID to identify this flow profile
1814  *
1815  * This function removes the flow entries associated to the input
1816  * VSI handle and disassociate the VSI from the flow profile.
1817  */
1818 int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1819 {
1820 	struct ice_flow_prof *prof;
1821 	int status = 0;
1822 
1823 	if (!ice_is_vsi_valid(hw, vsi_handle))
1824 		return -EINVAL;
1825 
1826 	/* find flow profile pointer with input package block and profile ID */
1827 	prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1828 	if (!prof) {
1829 		ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1830 			  prof_id);
1831 		return -ENOENT;
1832 	}
1833 
1834 	/* Remove all remaining flow entries before removing the flow profile */
1835 	if (!list_empty(&prof->entries)) {
1836 		struct ice_flow_entry *e, *t;
1837 
1838 		mutex_lock(&prof->entries_lock);
1839 		list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1840 			if (e->vsi_handle != vsi_handle)
1841 				continue;
1842 
1843 			status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1844 			if (status)
1845 				break;
1846 		}
1847 		mutex_unlock(&prof->entries_lock);
1848 	}
1849 	if (status)
1850 		return status;
1851 
1852 	/* disassociate the flow profile from sw VSI handle */
1853 	status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1854 	if (status)
1855 		ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1856 			  status);
1857 	return status;
1858 }
1859 
1860 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1861 	(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1862 
1863 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1864 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1865 
1866 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1867 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1868 
1869 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1870 	(ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1871 	 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1872 	 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1873 
1874 /**
1875  * ice_flow_set_rss_seg_info - setup packet segments for RSS
1876  * @segs: pointer to the flow field segment(s)
1877  * @hash_fields: fields to be hashed on for the segment(s)
1878  * @flow_hdr: protocol header fields within a packet segment
1879  *
1880  * Helper function to extract fields from hash bitmap and use flow
1881  * header value to set flow field segment for further use in flow
1882  * profile entry or removal.
1883  */
1884 static int
1885 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1886 			  u32 flow_hdr)
1887 {
1888 	u64 val;
1889 	u8 i;
1890 
1891 	for_each_set_bit(i, (unsigned long *)&hash_fields,
1892 			 ICE_FLOW_FIELD_IDX_MAX)
1893 		ice_flow_set_fld(segs, (enum ice_flow_field)i,
1894 				 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1895 				 ICE_FLOW_FLD_OFF_INVAL, false);
1896 
1897 	ICE_FLOW_SET_HDRS(segs, flow_hdr);
1898 
1899 	if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1900 	    ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1901 		return -EINVAL;
1902 
1903 	val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1904 	if (val && !is_power_of_2(val))
1905 		return -EIO;
1906 
1907 	val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1908 	if (val && !is_power_of_2(val))
1909 		return -EIO;
1910 
1911 	return 0;
1912 }
1913 
1914 /**
1915  * ice_rem_vsi_rss_list - remove VSI from RSS list
1916  * @hw: pointer to the hardware structure
1917  * @vsi_handle: software VSI handle
1918  *
1919  * Remove the VSI from all RSS configurations in the list.
1920  */
1921 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1922 {
1923 	struct ice_rss_cfg *r, *tmp;
1924 
1925 	if (list_empty(&hw->rss_list_head))
1926 		return;
1927 
1928 	mutex_lock(&hw->rss_locks);
1929 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1930 		if (test_and_clear_bit(vsi_handle, r->vsis))
1931 			if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1932 				list_del(&r->l_entry);
1933 				devm_kfree(ice_hw_to_dev(hw), r);
1934 			}
1935 	mutex_unlock(&hw->rss_locks);
1936 }
1937 
1938 /**
1939  * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1940  * @hw: pointer to the hardware structure
1941  * @vsi_handle: software VSI handle
1942  *
1943  * This function will iterate through all flow profiles and disassociate
1944  * the VSI from that profile. If the flow profile has no VSIs it will
1945  * be removed.
1946  */
1947 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1948 {
1949 	const enum ice_block blk = ICE_BLK_RSS;
1950 	struct ice_flow_prof *p, *t;
1951 	int status = 0;
1952 
1953 	if (!ice_is_vsi_valid(hw, vsi_handle))
1954 		return -EINVAL;
1955 
1956 	if (list_empty(&hw->fl_profs[blk]))
1957 		return 0;
1958 
1959 	mutex_lock(&hw->rss_locks);
1960 	list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1961 		if (test_bit(vsi_handle, p->vsis)) {
1962 			status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1963 			if (status)
1964 				break;
1965 
1966 			if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1967 				status = ice_flow_rem_prof(hw, blk, p->id);
1968 				if (status)
1969 					break;
1970 			}
1971 		}
1972 	mutex_unlock(&hw->rss_locks);
1973 
1974 	return status;
1975 }
1976 
1977 /**
1978  * ice_rem_rss_list - remove RSS configuration from list
1979  * @hw: pointer to the hardware structure
1980  * @vsi_handle: software VSI handle
1981  * @prof: pointer to flow profile
1982  *
1983  * Assumption: lock has already been acquired for RSS list
1984  */
1985 static void
1986 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1987 {
1988 	struct ice_rss_cfg *r, *tmp;
1989 
1990 	/* Search for RSS hash fields associated to the VSI that match the
1991 	 * hash configurations associated to the flow profile. If found
1992 	 * remove from the RSS entry list of the VSI context and delete entry.
1993 	 */
1994 	list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1995 		if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1996 		    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1997 			clear_bit(vsi_handle, r->vsis);
1998 			if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1999 				list_del(&r->l_entry);
2000 				devm_kfree(ice_hw_to_dev(hw), r);
2001 			}
2002 			return;
2003 		}
2004 }
2005 
2006 /**
2007  * ice_add_rss_list - add RSS configuration to list
2008  * @hw: pointer to the hardware structure
2009  * @vsi_handle: software VSI handle
2010  * @prof: pointer to flow profile
2011  *
2012  * Assumption: lock has already been acquired for RSS list
2013  */
2014 static int
2015 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2016 {
2017 	struct ice_rss_cfg *r, *rss_cfg;
2018 
2019 	list_for_each_entry(r, &hw->rss_list_head, l_entry)
2020 		if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
2021 		    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
2022 			set_bit(vsi_handle, r->vsis);
2023 			return 0;
2024 		}
2025 
2026 	rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2027 			       GFP_KERNEL);
2028 	if (!rss_cfg)
2029 		return -ENOMEM;
2030 
2031 	rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
2032 	rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
2033 	set_bit(vsi_handle, rss_cfg->vsis);
2034 
2035 	list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2036 
2037 	return 0;
2038 }
2039 
2040 #define ICE_FLOW_PROF_HASH_S	0
2041 #define ICE_FLOW_PROF_HASH_M	(0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
2042 #define ICE_FLOW_PROF_HDR_S	32
2043 #define ICE_FLOW_PROF_HDR_M	(0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
2044 #define ICE_FLOW_PROF_ENCAP_S	63
2045 #define ICE_FLOW_PROF_ENCAP_M	(BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2046 
2047 #define ICE_RSS_OUTER_HEADERS	1
2048 #define ICE_RSS_INNER_HEADERS	2
2049 
2050 /* Flow profile ID format:
2051  * [0:31] - Packet match fields
2052  * [32:62] - Protocol header
2053  * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
2054  */
2055 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2056 	((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2057 	       (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2058 	       ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2059 
2060 /**
2061  * ice_add_rss_cfg_sync - add an RSS configuration
2062  * @hw: pointer to the hardware structure
2063  * @vsi_handle: software VSI handle
2064  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2065  * @addl_hdrs: protocol header fields
2066  * @segs_cnt: packet segment count
2067  *
2068  * Assumption: lock has already been acquired for RSS list
2069  */
2070 static int
2071 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2072 		     u32 addl_hdrs, u8 segs_cnt)
2073 {
2074 	const enum ice_block blk = ICE_BLK_RSS;
2075 	struct ice_flow_prof *prof = NULL;
2076 	struct ice_flow_seg_info *segs;
2077 	int status;
2078 
2079 	if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2080 		return -EINVAL;
2081 
2082 	segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2083 	if (!segs)
2084 		return -ENOMEM;
2085 
2086 	/* Construct the packet segment info from the hashed fields */
2087 	status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2088 					   addl_hdrs);
2089 	if (status)
2090 		goto exit;
2091 
2092 	/* Search for a flow profile that has matching headers, hash fields
2093 	 * and has the input VSI associated to it. If found, no further
2094 	 * operations required and exit.
2095 	 */
2096 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2097 					vsi_handle,
2098 					ICE_FLOW_FIND_PROF_CHK_FLDS |
2099 					ICE_FLOW_FIND_PROF_CHK_VSI);
2100 	if (prof)
2101 		goto exit;
2102 
2103 	/* Check if a flow profile exists with the same protocol headers and
2104 	 * associated with the input VSI. If so disassociate the VSI from
2105 	 * this profile. The VSI will be added to a new profile created with
2106 	 * the protocol header and new hash field configuration.
2107 	 */
2108 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2109 					vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2110 	if (prof) {
2111 		status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2112 		if (!status)
2113 			ice_rem_rss_list(hw, vsi_handle, prof);
2114 		else
2115 			goto exit;
2116 
2117 		/* Remove profile if it has no VSIs associated */
2118 		if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2119 			status = ice_flow_rem_prof(hw, blk, prof->id);
2120 			if (status)
2121 				goto exit;
2122 		}
2123 	}
2124 
2125 	/* Search for a profile that has same match fields only. If this
2126 	 * exists then associate the VSI to this profile.
2127 	 */
2128 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2129 					vsi_handle,
2130 					ICE_FLOW_FIND_PROF_CHK_FLDS);
2131 	if (prof) {
2132 		status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2133 		if (!status)
2134 			status = ice_add_rss_list(hw, vsi_handle, prof);
2135 		goto exit;
2136 	}
2137 
2138 	/* Create a new flow profile with generated profile and packet
2139 	 * segment information.
2140 	 */
2141 	status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2142 				   ICE_FLOW_GEN_PROFID(hashed_flds,
2143 						       segs[segs_cnt - 1].hdrs,
2144 						       segs_cnt),
2145 				   segs, segs_cnt, &prof);
2146 	if (status)
2147 		goto exit;
2148 
2149 	status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2150 	/* If association to a new flow profile failed then this profile can
2151 	 * be removed.
2152 	 */
2153 	if (status) {
2154 		ice_flow_rem_prof(hw, blk, prof->id);
2155 		goto exit;
2156 	}
2157 
2158 	status = ice_add_rss_list(hw, vsi_handle, prof);
2159 
2160 exit:
2161 	kfree(segs);
2162 	return status;
2163 }
2164 
2165 /**
2166  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2167  * @hw: pointer to the hardware structure
2168  * @vsi_handle: software VSI handle
2169  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2170  * @addl_hdrs: protocol header fields
2171  *
2172  * This function will generate a flow profile based on fields associated with
2173  * the input fields to hash on, the flow type and use the VSI number to add
2174  * a flow entry to the profile.
2175  */
2176 int
2177 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2178 		u32 addl_hdrs)
2179 {
2180 	int status;
2181 
2182 	if (hashed_flds == ICE_HASH_INVALID ||
2183 	    !ice_is_vsi_valid(hw, vsi_handle))
2184 		return -EINVAL;
2185 
2186 	mutex_lock(&hw->rss_locks);
2187 	status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2188 				      ICE_RSS_OUTER_HEADERS);
2189 	if (!status)
2190 		status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2191 					      addl_hdrs, ICE_RSS_INNER_HEADERS);
2192 	mutex_unlock(&hw->rss_locks);
2193 
2194 	return status;
2195 }
2196 
2197 /**
2198  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2199  * @hw: pointer to the hardware structure
2200  * @vsi_handle: software VSI handle
2201  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2202  * @addl_hdrs: Protocol header fields within a packet segment
2203  * @segs_cnt: packet segment count
2204  *
2205  * Assumption: lock has already been acquired for RSS list
2206  */
2207 static int
2208 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2209 		     u32 addl_hdrs, u8 segs_cnt)
2210 {
2211 	const enum ice_block blk = ICE_BLK_RSS;
2212 	struct ice_flow_seg_info *segs;
2213 	struct ice_flow_prof *prof;
2214 	int status;
2215 
2216 	segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2217 	if (!segs)
2218 		return -ENOMEM;
2219 
2220 	/* Construct the packet segment info from the hashed fields */
2221 	status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2222 					   addl_hdrs);
2223 	if (status)
2224 		goto out;
2225 
2226 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2227 					vsi_handle,
2228 					ICE_FLOW_FIND_PROF_CHK_FLDS);
2229 	if (!prof) {
2230 		status = -ENOENT;
2231 		goto out;
2232 	}
2233 
2234 	status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2235 	if (status)
2236 		goto out;
2237 
2238 	/* Remove RSS configuration from VSI context before deleting
2239 	 * the flow profile.
2240 	 */
2241 	ice_rem_rss_list(hw, vsi_handle, prof);
2242 
2243 	if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2244 		status = ice_flow_rem_prof(hw, blk, prof->id);
2245 
2246 out:
2247 	kfree(segs);
2248 	return status;
2249 }
2250 
2251 /**
2252  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2253  * @hw: pointer to the hardware structure
2254  * @vsi_handle: software VSI handle
2255  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2256  * @addl_hdrs: Protocol header fields within a packet segment
2257  *
2258  * This function will lookup the flow profile based on the input
2259  * hash field bitmap, iterate through the profile entry list of
2260  * that profile and find entry associated with input VSI to be
2261  * removed. Calls are made to underlying flow s which will APIs
2262  * turn build or update buffers for RSS XLT1 section.
2263  */
2264 int __maybe_unused
2265 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2266 		u32 addl_hdrs)
2267 {
2268 	int status;
2269 
2270 	if (hashed_flds == ICE_HASH_INVALID ||
2271 	    !ice_is_vsi_valid(hw, vsi_handle))
2272 		return -EINVAL;
2273 
2274 	mutex_lock(&hw->rss_locks);
2275 	status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2276 				      ICE_RSS_OUTER_HEADERS);
2277 	if (!status)
2278 		status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2279 					      addl_hdrs, ICE_RSS_INNER_HEADERS);
2280 	mutex_unlock(&hw->rss_locks);
2281 
2282 	return status;
2283 }
2284 
2285 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2286  * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2287  * convert its values to their appropriate flow L3, L4 values.
2288  */
2289 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2290 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2291 	 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2292 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2293 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2294 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2295 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2296 	(BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2297 	 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2298 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2299 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2300 	(ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2301 	 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2302 
2303 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2304 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2305 	 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2306 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2307 	(BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2308 	 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2309 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2310 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2311 	(BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2312 	 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2313 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2314 	(ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2315 	 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2316 
2317 /**
2318  * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2319  * @hw: pointer to the hardware structure
2320  * @vsi_handle: software VSI handle
2321  * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2322  *
2323  * This function will take the hash bitmap provided by the AVF driver via a
2324  * message, convert it to ICE-compatible values, and configure RSS flow
2325  * profiles.
2326  */
2327 int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2328 {
2329 	int status = 0;
2330 	u64 hash_flds;
2331 
2332 	if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2333 	    !ice_is_vsi_valid(hw, vsi_handle))
2334 		return -EINVAL;
2335 
2336 	/* Make sure no unsupported bits are specified */
2337 	if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2338 			 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2339 		return -EIO;
2340 
2341 	hash_flds = avf_hash;
2342 
2343 	/* Always create an L3 RSS configuration for any L4 RSS configuration */
2344 	if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2345 		hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2346 
2347 	if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2348 		hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2349 
2350 	/* Create the corresponding RSS configuration for each valid hash bit */
2351 	while (hash_flds) {
2352 		u64 rss_hash = ICE_HASH_INVALID;
2353 
2354 		if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2355 			if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2356 				rss_hash = ICE_FLOW_HASH_IPV4;
2357 				hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2358 			} else if (hash_flds &
2359 				   ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2360 				rss_hash = ICE_FLOW_HASH_IPV4 |
2361 					ICE_FLOW_HASH_TCP_PORT;
2362 				hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2363 			} else if (hash_flds &
2364 				   ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2365 				rss_hash = ICE_FLOW_HASH_IPV4 |
2366 					ICE_FLOW_HASH_UDP_PORT;
2367 				hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2368 			} else if (hash_flds &
2369 				   BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2370 				rss_hash = ICE_FLOW_HASH_IPV4 |
2371 					ICE_FLOW_HASH_SCTP_PORT;
2372 				hash_flds &=
2373 					~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2374 			}
2375 		} else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2376 			if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2377 				rss_hash = ICE_FLOW_HASH_IPV6;
2378 				hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2379 			} else if (hash_flds &
2380 				   ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2381 				rss_hash = ICE_FLOW_HASH_IPV6 |
2382 					ICE_FLOW_HASH_TCP_PORT;
2383 				hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2384 			} else if (hash_flds &
2385 				   ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2386 				rss_hash = ICE_FLOW_HASH_IPV6 |
2387 					ICE_FLOW_HASH_UDP_PORT;
2388 				hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2389 			} else if (hash_flds &
2390 				   BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2391 				rss_hash = ICE_FLOW_HASH_IPV6 |
2392 					ICE_FLOW_HASH_SCTP_PORT;
2393 				hash_flds &=
2394 					~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2395 			}
2396 		}
2397 
2398 		if (rss_hash == ICE_HASH_INVALID)
2399 			return -EIO;
2400 
2401 		status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2402 					 ICE_FLOW_SEG_HDR_NONE);
2403 		if (status)
2404 			break;
2405 	}
2406 
2407 	return status;
2408 }
2409 
2410 /**
2411  * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2412  * @hw: pointer to the hardware structure
2413  * @vsi_handle: software VSI handle
2414  */
2415 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2416 {
2417 	struct ice_rss_cfg *r;
2418 	int status = 0;
2419 
2420 	if (!ice_is_vsi_valid(hw, vsi_handle))
2421 		return -EINVAL;
2422 
2423 	mutex_lock(&hw->rss_locks);
2424 	list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2425 		if (test_bit(vsi_handle, r->vsis)) {
2426 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
2427 						      r->hashed_flds,
2428 						      r->packet_hdr,
2429 						      ICE_RSS_OUTER_HEADERS);
2430 			if (status)
2431 				break;
2432 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
2433 						      r->hashed_flds,
2434 						      r->packet_hdr,
2435 						      ICE_RSS_INNER_HEADERS);
2436 			if (status)
2437 				break;
2438 		}
2439 	}
2440 	mutex_unlock(&hw->rss_locks);
2441 
2442 	return status;
2443 }
2444 
2445 /**
2446  * ice_get_rss_cfg - returns hashed fields for the given header types
2447  * @hw: pointer to the hardware structure
2448  * @vsi_handle: software VSI handle
2449  * @hdrs: protocol header type
2450  *
2451  * This function will return the match fields of the first instance of flow
2452  * profile having the given header types and containing input VSI
2453  */
2454 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2455 {
2456 	u64 rss_hash = ICE_HASH_INVALID;
2457 	struct ice_rss_cfg *r;
2458 
2459 	/* verify if the protocol header is non zero and VSI is valid */
2460 	if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2461 		return ICE_HASH_INVALID;
2462 
2463 	mutex_lock(&hw->rss_locks);
2464 	list_for_each_entry(r, &hw->rss_list_head, l_entry)
2465 		if (test_bit(vsi_handle, r->vsis) &&
2466 		    r->packet_hdr == hdrs) {
2467 			rss_hash = r->hashed_flds;
2468 			break;
2469 		}
2470 	mutex_unlock(&hw->rss_locks);
2471 
2472 	return rss_hash;
2473 }
2474