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