xref: /dpdk/drivers/net/ice/base/ice_flow.c (revision ca39d3a8)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2020 Intel Corporation
3  */
4 
5 #include "ice_common.h"
6 #include "ice_flow.h"
7 
8 /* Size of known protocol header fields */
9 #define ICE_FLOW_FLD_SZ_ETH_TYPE	2
10 #define ICE_FLOW_FLD_SZ_VLAN		2
11 #define ICE_FLOW_FLD_SZ_IPV4_ADDR	4
12 #define ICE_FLOW_FLD_SZ_IPV6_ADDR	16
13 #define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR	4
14 #define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR	6
15 #define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR	8
16 #define ICE_FLOW_FLD_SZ_IP_DSCP		1
17 #define ICE_FLOW_FLD_SZ_IP_TTL		1
18 #define ICE_FLOW_FLD_SZ_IP_PROT		1
19 #define ICE_FLOW_FLD_SZ_PORT		2
20 #define ICE_FLOW_FLD_SZ_TCP_FLAGS	1
21 #define ICE_FLOW_FLD_SZ_ICMP_TYPE	1
22 #define ICE_FLOW_FLD_SZ_ICMP_CODE	1
23 #define ICE_FLOW_FLD_SZ_ARP_OPER	2
24 #define ICE_FLOW_FLD_SZ_GRE_KEYID	4
25 #define ICE_FLOW_FLD_SZ_GTP_TEID	4
26 #define ICE_FLOW_FLD_SZ_GTP_QFI		2
27 #define ICE_FLOW_FLD_SZ_PPPOE_SESS_ID   2
28 #define ICE_FLOW_FLD_SZ_PFCP_SEID 8
29 #define ICE_FLOW_FLD_SZ_L2TPV3_SESS_ID	4
30 #define ICE_FLOW_FLD_SZ_ESP_SPI	4
31 #define ICE_FLOW_FLD_SZ_AH_SPI	4
32 #define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI	4
33 
34 /* Describe properties of a protocol header field */
35 struct ice_flow_field_info {
36 	enum ice_flow_seg_hdr hdr;
37 	s16 off;	/* Offset from start of a protocol header, in bits */
38 	u16 size;	/* Size of fields in bits */
39 	u16 mask;	/* 16-bit mask for field */
40 };
41 
42 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
43 	.hdr = _hdr, \
44 	.off = (_offset_bytes) * BITS_PER_BYTE, \
45 	.size = (_size_bytes) * BITS_PER_BYTE, \
46 	.mask = 0, \
47 }
48 
49 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
50 	.hdr = _hdr, \
51 	.off = (_offset_bytes) * BITS_PER_BYTE, \
52 	.size = (_size_bytes) * BITS_PER_BYTE, \
53 	.mask = _mask, \
54 }
55 
56 /* Table containing properties of supported protocol header fields */
57 static const
58 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
59 	/* Ether */
60 	/* ICE_FLOW_FIELD_IDX_ETH_DA */
61 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
62 	/* ICE_FLOW_FIELD_IDX_ETH_SA */
63 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
64 	/* ICE_FLOW_FIELD_IDX_S_VLAN */
65 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, ICE_FLOW_FLD_SZ_VLAN),
66 	/* ICE_FLOW_FIELD_IDX_C_VLAN */
67 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, ICE_FLOW_FLD_SZ_VLAN),
68 	/* ICE_FLOW_FIELD_IDX_ETH_TYPE */
69 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ICE_FLOW_FLD_SZ_ETH_TYPE),
70 	/* IPv4 / IPv6 */
71 	/* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
72 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, ICE_FLOW_FLD_SZ_IP_DSCP,
73 			      0x00fc),
74 	/* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
75 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, ICE_FLOW_FLD_SZ_IP_DSCP,
76 			      0x0ff0),
77 	/* ICE_FLOW_FIELD_IDX_IPV4_TTL */
78 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8,
79 			      ICE_FLOW_FLD_SZ_IP_TTL, 0xff00),
80 	/* ICE_FLOW_FIELD_IDX_IPV4_PROT */
81 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8,
82 			      ICE_FLOW_FLD_SZ_IP_PROT, 0x00ff),
83 	/* ICE_FLOW_FIELD_IDX_IPV6_TTL */
84 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6,
85 			      ICE_FLOW_FLD_SZ_IP_TTL, 0x00ff),
86 	/* ICE_FLOW_FIELD_IDX_IPV6_PROT */
87 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6,
88 			      ICE_FLOW_FLD_SZ_IP_PROT, 0xff00),
89 	/* ICE_FLOW_FIELD_IDX_IPV4_SA */
90 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, ICE_FLOW_FLD_SZ_IPV4_ADDR),
91 	/* ICE_FLOW_FIELD_IDX_IPV4_DA */
92 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, ICE_FLOW_FLD_SZ_IPV4_ADDR),
93 	/* ICE_FLOW_FIELD_IDX_IPV6_SA */
94 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, ICE_FLOW_FLD_SZ_IPV6_ADDR),
95 	/* ICE_FLOW_FIELD_IDX_IPV6_DA */
96 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
97 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
98 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
99 			  ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
100 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */
101 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
102 			  ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
103 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */
104 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
105 			  ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
106 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */
107 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
108 			  ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
109 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */
110 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
111 			  ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
112 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */
113 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
114 			  ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
115 	/* Transport */
116 	/* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
117 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, ICE_FLOW_FLD_SZ_PORT),
118 	/* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
119 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, ICE_FLOW_FLD_SZ_PORT),
120 	/* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
121 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, ICE_FLOW_FLD_SZ_PORT),
122 	/* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
123 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, ICE_FLOW_FLD_SZ_PORT),
124 	/* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
125 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, ICE_FLOW_FLD_SZ_PORT),
126 	/* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
127 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, ICE_FLOW_FLD_SZ_PORT),
128 	/* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
129 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS),
130 	/* ARP */
131 	/* ICE_FLOW_FIELD_IDX_ARP_SIP */
132 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, ICE_FLOW_FLD_SZ_IPV4_ADDR),
133 	/* ICE_FLOW_FIELD_IDX_ARP_DIP */
134 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, ICE_FLOW_FLD_SZ_IPV4_ADDR),
135 	/* ICE_FLOW_FIELD_IDX_ARP_SHA */
136 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
137 	/* ICE_FLOW_FIELD_IDX_ARP_DHA */
138 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
139 	/* ICE_FLOW_FIELD_IDX_ARP_OP */
140 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, ICE_FLOW_FLD_SZ_ARP_OPER),
141 	/* ICMP */
142 	/* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
143 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, ICE_FLOW_FLD_SZ_ICMP_TYPE),
144 	/* ICE_FLOW_FIELD_IDX_ICMP_CODE */
145 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, ICE_FLOW_FLD_SZ_ICMP_CODE),
146 	/* GRE */
147 	/* ICE_FLOW_FIELD_IDX_GRE_KEYID */
148 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, ICE_FLOW_FLD_SZ_GRE_KEYID),
149 	/* GTP */
150 	/* ICE_FLOW_FIELD_IDX_GTPC_TEID */
151 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12,
152 			  ICE_FLOW_FLD_SZ_GTP_TEID),
153 	/* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
154 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12,
155 			  ICE_FLOW_FLD_SZ_GTP_TEID),
156 	/* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
157 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12,
158 			  ICE_FLOW_FLD_SZ_GTP_TEID),
159 	/* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
160 	ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22,
161 			      ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
162 	/* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
163 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12,
164 			  ICE_FLOW_FLD_SZ_GTP_TEID),
165 	/* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
166 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12,
167 			  ICE_FLOW_FLD_SZ_GTP_TEID),
168 	/* PPPOE */
169 	/* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
170 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2,
171 			  ICE_FLOW_FLD_SZ_PPPOE_SESS_ID),
172 	/* PFCP */
173 	/* ICE_FLOW_FIELD_IDX_PFCP_SEID */
174 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12,
175 			  ICE_FLOW_FLD_SZ_PFCP_SEID),
176 	/* L2TPV3 */
177 	/* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
178 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0,
179 			  ICE_FLOW_FLD_SZ_L2TPV3_SESS_ID),
180 	/* ESP */
181 	/* ICE_FLOW_FIELD_IDX_ESP_SPI */
182 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0,
183 			  ICE_FLOW_FLD_SZ_ESP_SPI),
184 	/* AH */
185 	/* ICE_FLOW_FIELD_IDX_AH_SPI */
186 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4,
187 			  ICE_FLOW_FLD_SZ_AH_SPI),
188 	/* NAT_T_ESP */
189 	/* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
190 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8,
191 			  ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI),
192 };
193 
194 /* Bitmaps indicating relevant packet types for a particular protocol header
195  *
196  * Packet types for packets with an Outer/First/Single MAC header
197  */
198 static const u32 ice_ptypes_mac_ofos[] = {
199 	0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
200 	0x0000077E, 0x00000000, 0x00000000, 0x00000000,
201 	0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000,
202 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
203 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
204 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
205 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
206 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
207 };
208 
209 /* Packet types for packets with an Innermost/Last MAC VLAN header */
210 static const u32 ice_ptypes_macvlan_il[] = {
211 	0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
212 	0x0000077E, 0x00000000, 0x00000000, 0x00000000,
213 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
214 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
215 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
216 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
217 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
218 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
219 };
220 
221 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
222  * include IPV4 other PTYPEs
223  */
224 static const u32 ice_ptypes_ipv4_ofos[] = {
225 	0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
226 	0x00000000, 0x00000155, 0x00000000, 0x00000000,
227 	0x00000000, 0x000FC000, 0x00000000, 0x00000000,
228 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
229 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
230 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
231 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
232 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
233 };
234 
235 /* Packet types for packets with an Outer/First/Single IPv4 header, includes
236  * IPV4 other PTYPEs
237  */
238 static const u32 ice_ptypes_ipv4_ofos_all[] = {
239 	0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
240 	0x00000000, 0x00000155, 0x00000000, 0x00000000,
241 	0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
242 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
243 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
244 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
245 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
246 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
247 };
248 
249 /* Packet types for packets with an Innermost/Last IPv4 header */
250 static const u32 ice_ptypes_ipv4_il[] = {
251 	0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
252 	0x0000000E, 0x00000000, 0x00000000, 0x00000000,
253 	0x00000000, 0x00000000, 0x001FF800, 0x00000000,
254 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
255 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
256 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
257 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
258 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
259 };
260 
261 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
262  * include IVP6 other PTYPEs
263  */
264 static const u32 ice_ptypes_ipv6_ofos[] = {
265 	0x00000000, 0x00000000, 0x77000000, 0x10002000,
266 	0x00000000, 0x000002AA, 0x00000000, 0x00000000,
267 	0x00000000, 0x03F00000, 0x00000000, 0x00000000,
268 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
269 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
270 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
271 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
272 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
273 };
274 
275 /* Packet types for packets with an Outer/First/Single IPv6 header, includes
276  * IPV6 other PTYPEs
277  */
278 static const u32 ice_ptypes_ipv6_ofos_all[] = {
279 	0x00000000, 0x00000000, 0x77000000, 0x10002000,
280 	0x00000000, 0x000002AA, 0x00000000, 0x00000000,
281 	0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
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 */
290 static const u32 ice_ptypes_ipv6_il[] = {
291 	0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
292 	0x00000770, 0x00000000, 0x00000000, 0x00000000,
293 	0x00000000, 0x00000000, 0x7FE00000, 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 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
302 static const u32 ice_ipv4_ofos_no_l4[] = {
303 	0x10C00000, 0x04000800, 0x00000000, 0x00000000,
304 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
305 	0x00000000, 0x000cc000, 0x00000000, 0x00000000,
306 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
307 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
308 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
309 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
310 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
311 };
312 
313 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
314 static const u32 ice_ipv4_il_no_l4[] = {
315 	0x60000000, 0x18043008, 0x80000002, 0x6010c021,
316 	0x00000008, 0x00000000, 0x00000000, 0x00000000,
317 	0x00000000, 0x00000000, 0x00139800, 0x00000000,
318 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
319 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
320 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
321 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
322 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
323 };
324 
325 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
326 static const u32 ice_ipv6_ofos_no_l4[] = {
327 	0x00000000, 0x00000000, 0x43000000, 0x10002000,
328 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
329 	0x00000000, 0x02300000, 0x00000000, 0x00000000,
330 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
331 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
332 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
333 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
334 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
335 };
336 
337 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
338 static const u32 ice_ipv6_il_no_l4[] = {
339 	0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
340 	0x00000430, 0x00000000, 0x00000000, 0x00000000,
341 	0x00000000, 0x00000000, 0x4e600000, 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 };
348 
349 /* Packet types for packets with an Outermost/First ARP header */
350 static const u32 ice_ptypes_arp_of[] = {
351 	0x00000800, 0x00000000, 0x00000000, 0x00000000,
352 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
353 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
354 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
355 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
356 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
357 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
358 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
359 };
360 
361 /* UDP Packet types for non-tunneled packets or tunneled
362  * packets with inner UDP.
363  */
364 static const u32 ice_ptypes_udp_il[] = {
365 	0x81000000, 0x20204040, 0x04000010, 0x80810102,
366 	0x00000040, 0x00000000, 0x00000000, 0x00000000,
367 	0x00000000, 0x00410000, 0x90842000, 0x00000007,
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 TCP header */
376 static const u32 ice_ptypes_tcp_il[] = {
377 	0x04000000, 0x80810102, 0x10000040, 0x02040408,
378 	0x00000102, 0x00000000, 0x00000000, 0x00000000,
379 	0x00000000, 0x00820000, 0x21084000, 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 packets with an Innermost/Last SCTP header */
388 static const u32 ice_ptypes_sctp_il[] = {
389 	0x08000000, 0x01020204, 0x20000081, 0x04080810,
390 	0x00000204, 0x00000000, 0x00000000, 0x00000000,
391 	0x00000000, 0x01040000, 0x00000000, 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 packets with an Outermost/First ICMP header */
400 static const u32 ice_ptypes_icmp_of[] = {
401 	0x10000000, 0x00000000, 0x00000000, 0x00000000,
402 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
403 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
404 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
405 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
406 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
407 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
408 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
409 };
410 
411 /* Packet types for packets with an Innermost/Last ICMP header */
412 static const u32 ice_ptypes_icmp_il[] = {
413 	0x00000000, 0x02040408, 0x40000102, 0x08101020,
414 	0x00000408, 0x00000000, 0x00000000, 0x00000000,
415 	0x00000000, 0x00000000, 0x42108000, 0x00000000,
416 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
417 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
418 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
419 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
420 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
421 };
422 
423 /* Packet types for packets with an Outermost/First GRE header */
424 static const u32 ice_ptypes_gre_of[] = {
425 	0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
426 	0x0000017E, 0x00000000, 0x00000000, 0x00000000,
427 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
428 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
429 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
430 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
431 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
432 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
433 };
434 
435 /* Packet types for packets with an Innermost/Last MAC header */
436 static const u32 ice_ptypes_mac_il[] = {
437 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
438 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
439 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
440 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
441 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
442 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
443 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
444 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
445 };
446 
447 /* Packet types for GTPC */
448 static const u32 ice_ptypes_gtpc[] = {
449 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
450 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
451 	0x00000000, 0x00000000, 0x00000180, 0x00000000,
452 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
453 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
454 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
455 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
456 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
457 };
458 
459 /* Packet types for GTPC with TEID */
460 static const u32 ice_ptypes_gtpc_tid[] = {
461 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
462 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
463 	0x00000000, 0x00000000, 0x00000060, 0x00000000,
464 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
465 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
466 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
467 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
468 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
469 };
470 
471 /* Packet types for GTPU */
472 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
473 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
474 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
475 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
476 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
477 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
478 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
479 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
480 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
481 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
482 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
483 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
484 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
485 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
486 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
487 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
488 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
489 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
490 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
491 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
492 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
493 };
494 
495 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
496 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
497 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
498 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
499 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
500 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
501 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
502 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
503 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
504 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
505 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
506 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
507 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
508 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
509 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
510 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
511 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
512 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
513 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
514 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_DOWNLINK },
515 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
516 };
517 
518 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
519 	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
520 	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
521 	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
522 	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
523 	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
524 	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
525 	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
526 	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
527 	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
528 	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
529 	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
530 	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
531 	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
532 	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
533 	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
534 	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_UPLINK },
535 	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_UPLINK },
536 	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
537 	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_UPLINK },
538 	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
539 };
540 
541 static const u32 ice_ptypes_gtpu[] = {
542 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
543 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
544 	0x00000000, 0x00000000, 0x7FFFFE00, 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 pppoe */
553 static const u32 ice_ptypes_pppoe[] = {
554 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
555 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
556 	0x00000000, 0x03ffe000, 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 PFCP NODE header */
565 static const u32 ice_ptypes_pfcp_node[] = {
566 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
567 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
568 	0x00000000, 0x00000000, 0x80000000, 0x00000002,
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 /* Packet types for packets with PFCP SESSION header */
577 static const u32 ice_ptypes_pfcp_session[] = {
578 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
579 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
580 	0x00000000, 0x00000000, 0x00000000, 0x00000005,
581 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
582 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
583 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
584 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
585 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
586 };
587 
588 /* Packet types for l2tpv3 */
589 static const u32 ice_ptypes_l2tpv3[] = {
590 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
591 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
592 	0x00000000, 0x00000000, 0x00000000, 0x00000300,
593 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
594 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
595 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
596 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
597 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
598 };
599 
600 /* Packet types for esp */
601 static const u32 ice_ptypes_esp[] = {
602 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
603 	0x00000000, 0x00000003, 0x00000000, 0x00000000,
604 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
605 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
606 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
607 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
608 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
609 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
610 };
611 
612 /* Packet types for ah */
613 static const u32 ice_ptypes_ah[] = {
614 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
615 	0x00000000, 0x0000000C, 0x00000000, 0x00000000,
616 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
617 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
618 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
619 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
620 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
621 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
622 };
623 
624 /* Packet types for packets with NAT_T ESP header */
625 static const u32 ice_ptypes_nat_t_esp[] = {
626 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
627 	0x00000000, 0x00000030, 0x00000000, 0x00000000,
628 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
629 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
630 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
631 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
632 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
633 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
634 };
635 
636 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
637 	0x00000846, 0x00000000, 0x00000000, 0x00000000,
638 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
639 	0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
640 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
641 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
642 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
643 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
644 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
645 };
646 
647 /* Manage parameters and info. used during the creation of a flow profile */
648 struct ice_flow_prof_params {
649 	enum ice_block blk;
650 	u16 entry_length; /* # of bytes formatted entry will require */
651 	u8 es_cnt;
652 	struct ice_flow_prof *prof;
653 
654 	/* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
655 	 * This will give us the direction flags.
656 	 */
657 	struct ice_fv_word es[ICE_MAX_FV_WORDS];
658 	/* attributes can be used to add attributes to a particular PTYPE */
659 	const struct ice_ptype_attributes *attr;
660 	u16 attr_cnt;
661 
662 	u16 mask[ICE_MAX_FV_WORDS];
663 	ice_declare_bitmap(ptypes, ICE_FLOW_PTYPE_MAX);
664 };
665 
666 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
667 	(ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
668 	ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
669 	ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
670 	ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
671 	ICE_FLOW_SEG_HDR_NAT_T_ESP)
672 
673 #define ICE_FLOW_SEG_HDRS_L2_MASK	\
674 	(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
675 #define ICE_FLOW_SEG_HDRS_L3_MASK	\
676 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | \
677 	 ICE_FLOW_SEG_HDR_ARP)
678 #define ICE_FLOW_SEG_HDRS_L4_MASK	\
679 	(ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
680 	 ICE_FLOW_SEG_HDR_SCTP)
681 /* mask for L4 protocols that are NOT part of IPV4/6 OTHER PTYPE groups */
682 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER	\
683 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
684 
685 /**
686  * ice_flow_val_hdrs - validates packet segments for valid protocol headers
687  * @segs: array of one or more packet segments that describe the flow
688  * @segs_cnt: number of packet segments provided
689  */
690 static enum ice_status
691 ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
692 {
693 	u8 i;
694 
695 	for (i = 0; i < segs_cnt; i++) {
696 		/* Multiple L3 headers */
697 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
698 		    !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
699 			return ICE_ERR_PARAM;
700 
701 		/* Multiple L4 headers */
702 		if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
703 		    !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
704 			return ICE_ERR_PARAM;
705 	}
706 
707 	return ICE_SUCCESS;
708 }
709 
710 /* Sizes of fixed known protocol headers without header options */
711 #define ICE_FLOW_PROT_HDR_SZ_MAC	14
712 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN	(ICE_FLOW_PROT_HDR_SZ_MAC + 2)
713 #define ICE_FLOW_PROT_HDR_SZ_IPV4	20
714 #define ICE_FLOW_PROT_HDR_SZ_IPV6	40
715 #define ICE_FLOW_PROT_HDR_SZ_ARP	28
716 #define ICE_FLOW_PROT_HDR_SZ_ICMP	8
717 #define ICE_FLOW_PROT_HDR_SZ_TCP	20
718 #define ICE_FLOW_PROT_HDR_SZ_UDP	8
719 #define ICE_FLOW_PROT_HDR_SZ_SCTP	12
720 
721 /**
722  * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
723  * @params: information about the flow to be processed
724  * @seg: index of packet segment whose header size is to be determined
725  */
726 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
727 {
728 	u16 sz;
729 
730 	/* L2 headers */
731 	sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
732 		ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
733 
734 	/* L3 headers */
735 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
736 		sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
737 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
738 		sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
739 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
740 		sz += ICE_FLOW_PROT_HDR_SZ_ARP;
741 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
742 		/* A L3 header is required if L4 is specified */
743 		return 0;
744 
745 	/* L4 headers */
746 	if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
747 		sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
748 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
749 		sz += ICE_FLOW_PROT_HDR_SZ_TCP;
750 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
751 		sz += ICE_FLOW_PROT_HDR_SZ_UDP;
752 	else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
753 		sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
754 
755 	return sz;
756 }
757 
758 /**
759  * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
760  * @params: information about the flow to be processed
761  *
762  * This function identifies the packet types associated with the protocol
763  * headers being present in packet segments of the specified flow profile.
764  */
765 static enum ice_status
766 ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
767 {
768 	struct ice_flow_prof *prof;
769 	u8 i;
770 
771 	ice_memset(params->ptypes, 0xff, sizeof(params->ptypes),
772 		   ICE_NONDMA_MEM);
773 
774 	prof = params->prof;
775 
776 	for (i = 0; i < params->prof->segs_cnt; i++) {
777 		const ice_bitmap_t *src;
778 		u32 hdrs;
779 
780 		hdrs = prof->segs[i].hdrs;
781 
782 		if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
783 			src = !i ? (const ice_bitmap_t *)ice_ptypes_mac_ofos :
784 				(const ice_bitmap_t *)ice_ptypes_mac_il;
785 			ice_and_bitmap(params->ptypes, params->ptypes, src,
786 				       ICE_FLOW_PTYPE_MAX);
787 		}
788 
789 		if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
790 			src = (const ice_bitmap_t *)ice_ptypes_macvlan_il;
791 			ice_and_bitmap(params->ptypes, params->ptypes, src,
792 				       ICE_FLOW_PTYPE_MAX);
793 		}
794 
795 		if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
796 			ice_and_bitmap(params->ptypes, params->ptypes,
797 				       (const ice_bitmap_t *)ice_ptypes_arp_of,
798 				       ICE_FLOW_PTYPE_MAX);
799 		}
800 
801 		if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
802 			src = (const ice_bitmap_t *)ice_ptypes_pppoe;
803 			ice_and_bitmap(params->ptypes, params->ptypes, src,
804 				       ICE_FLOW_PTYPE_MAX);
805 		}
806 		if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
807 		    (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
808 			src = !i ?
809 				(const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all :
810 				(const ice_bitmap_t *)ice_ptypes_ipv4_il;
811 			ice_and_bitmap(params->ptypes, params->ptypes, src,
812 				       ICE_FLOW_PTYPE_MAX);
813 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
814 			   (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
815 			src = !i ?
816 				(const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all :
817 				(const ice_bitmap_t *)ice_ptypes_ipv6_il;
818 			ice_and_bitmap(params->ptypes, params->ptypes, src,
819 				       ICE_FLOW_PTYPE_MAX);
820 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
821 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
822 			src = !i ? (const ice_bitmap_t *)ice_ipv4_ofos_no_l4 :
823 				(const ice_bitmap_t *)ice_ipv4_il_no_l4;
824 			ice_and_bitmap(params->ptypes, params->ptypes, src,
825 				       ICE_FLOW_PTYPE_MAX);
826 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
827 			src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos :
828 				(const ice_bitmap_t *)ice_ptypes_ipv4_il;
829 			ice_and_bitmap(params->ptypes, params->ptypes, src,
830 				       ICE_FLOW_PTYPE_MAX);
831 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
832 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
833 			src = !i ? (const ice_bitmap_t *)ice_ipv6_ofos_no_l4 :
834 				(const ice_bitmap_t *)ice_ipv6_il_no_l4;
835 			ice_and_bitmap(params->ptypes, params->ptypes, src,
836 				       ICE_FLOW_PTYPE_MAX);
837 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
838 			src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos :
839 				(const ice_bitmap_t *)ice_ptypes_ipv6_il;
840 			ice_and_bitmap(params->ptypes, params->ptypes, src,
841 				       ICE_FLOW_PTYPE_MAX);
842 		}
843 
844 		if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
845 			src = (const ice_bitmap_t *)ice_ptypes_mac_non_ip_ofos;
846 			ice_and_bitmap(params->ptypes, params->ptypes,
847 				       src, ICE_FLOW_PTYPE_MAX);
848 		} else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
849 			src = (const ice_bitmap_t *)ice_ptypes_pppoe;
850 			ice_and_bitmap(params->ptypes, params->ptypes, src,
851 				       ICE_FLOW_PTYPE_MAX);
852 		} else {
853 			src = (const ice_bitmap_t *)ice_ptypes_pppoe;
854 			ice_andnot_bitmap(params->ptypes, params->ptypes, src,
855 					  ICE_FLOW_PTYPE_MAX);
856 		}
857 
858 		if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
859 			src = (const ice_bitmap_t *)ice_ptypes_udp_il;
860 			ice_and_bitmap(params->ptypes, params->ptypes, src,
861 				       ICE_FLOW_PTYPE_MAX);
862 		} else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
863 			ice_and_bitmap(params->ptypes, params->ptypes,
864 				       (const ice_bitmap_t *)ice_ptypes_tcp_il,
865 				       ICE_FLOW_PTYPE_MAX);
866 		} else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
867 			src = (const ice_bitmap_t *)ice_ptypes_sctp_il;
868 			ice_and_bitmap(params->ptypes, params->ptypes, src,
869 				       ICE_FLOW_PTYPE_MAX);
870 		}
871 
872 		if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
873 			src = !i ? (const ice_bitmap_t *)ice_ptypes_icmp_of :
874 				(const ice_bitmap_t *)ice_ptypes_icmp_il;
875 			ice_and_bitmap(params->ptypes, params->ptypes, src,
876 				       ICE_FLOW_PTYPE_MAX);
877 		} else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
878 			if (!i) {
879 				src = (const ice_bitmap_t *)ice_ptypes_gre_of;
880 				ice_and_bitmap(params->ptypes, params->ptypes,
881 					       src, ICE_FLOW_PTYPE_MAX);
882 			}
883 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
884 			src = (const ice_bitmap_t *)ice_ptypes_gtpc;
885 			ice_and_bitmap(params->ptypes, params->ptypes,
886 				       src, ICE_FLOW_PTYPE_MAX);
887 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
888 			src = (const ice_bitmap_t *)ice_ptypes_gtpc_tid;
889 			ice_and_bitmap(params->ptypes, params->ptypes,
890 				       src, ICE_FLOW_PTYPE_MAX);
891 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
892 			src = (const ice_bitmap_t *)ice_ptypes_gtpu;
893 			ice_and_bitmap(params->ptypes, params->ptypes,
894 				       src, ICE_FLOW_PTYPE_MAX);
895 
896 			/* Attributes for GTP packet with downlink */
897 			params->attr = ice_attr_gtpu_down;
898 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
899 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
900 			src = (const ice_bitmap_t *)ice_ptypes_gtpu;
901 			ice_and_bitmap(params->ptypes, params->ptypes,
902 				       src, ICE_FLOW_PTYPE_MAX);
903 
904 			/* Attributes for GTP packet with uplink */
905 			params->attr = ice_attr_gtpu_up;
906 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
907 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
908 			src = (const ice_bitmap_t *)ice_ptypes_gtpu;
909 			ice_and_bitmap(params->ptypes, params->ptypes,
910 				       src, ICE_FLOW_PTYPE_MAX);
911 
912 			/* Attributes for GTP packet with Extension Header */
913 			params->attr = ice_attr_gtpu_eh;
914 			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
915 		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
916 			src = (const ice_bitmap_t *)ice_ptypes_gtpu;
917 			ice_and_bitmap(params->ptypes, params->ptypes,
918 				       src, ICE_FLOW_PTYPE_MAX);
919 		} else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
920 			src = (const ice_bitmap_t *)ice_ptypes_l2tpv3;
921 			ice_and_bitmap(params->ptypes, params->ptypes,
922 				       src, ICE_FLOW_PTYPE_MAX);
923 		} else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
924 			src = (const ice_bitmap_t *)ice_ptypes_esp;
925 			ice_and_bitmap(params->ptypes, params->ptypes,
926 				       src, ICE_FLOW_PTYPE_MAX);
927 		} else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
928 			src = (const ice_bitmap_t *)ice_ptypes_ah;
929 			ice_and_bitmap(params->ptypes, params->ptypes,
930 				       src, ICE_FLOW_PTYPE_MAX);
931 		} else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
932 			src = (const ice_bitmap_t *)ice_ptypes_nat_t_esp;
933 			ice_and_bitmap(params->ptypes, params->ptypes,
934 				       src, ICE_FLOW_PTYPE_MAX);
935 		}
936 
937 		if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
938 			if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
939 				src =
940 				(const ice_bitmap_t *)ice_ptypes_pfcp_node;
941 			else
942 				src =
943 				(const ice_bitmap_t *)ice_ptypes_pfcp_session;
944 
945 			ice_and_bitmap(params->ptypes, params->ptypes,
946 				       src, ICE_FLOW_PTYPE_MAX);
947 		} else {
948 			src = (const ice_bitmap_t *)ice_ptypes_pfcp_node;
949 			ice_andnot_bitmap(params->ptypes, params->ptypes,
950 					  src, ICE_FLOW_PTYPE_MAX);
951 
952 			src = (const ice_bitmap_t *)ice_ptypes_pfcp_session;
953 			ice_andnot_bitmap(params->ptypes, params->ptypes,
954 					  src, ICE_FLOW_PTYPE_MAX);
955 		}
956 	}
957 
958 	return ICE_SUCCESS;
959 }
960 
961 /**
962  * ice_flow_xtract_pkt_flags - Create an extr sequence entry for packet flags
963  * @hw: pointer to the HW struct
964  * @params: information about the flow to be processed
965  * @flags: The value of pkt_flags[x:x] in Rx/Tx MDID metadata.
966  *
967  * This function will allocate an extraction sequence entries for a DWORD size
968  * chunk of the packet flags.
969  */
970 static enum ice_status
971 ice_flow_xtract_pkt_flags(struct ice_hw *hw,
972 			  struct ice_flow_prof_params *params,
973 			  enum ice_flex_mdid_pkt_flags flags)
974 {
975 	u8 fv_words = hw->blk[params->blk].es.fvw;
976 	u8 idx;
977 
978 	/* Make sure the number of extraction sequence entries required does not
979 	 * exceed the block's capacity.
980 	 */
981 	if (params->es_cnt >= fv_words)
982 		return ICE_ERR_MAX_LIMIT;
983 
984 	/* some blocks require a reversed field vector layout */
985 	if (hw->blk[params->blk].es.reverse)
986 		idx = fv_words - params->es_cnt - 1;
987 	else
988 		idx = params->es_cnt;
989 
990 	params->es[idx].prot_id = ICE_PROT_META_ID;
991 	params->es[idx].off = flags;
992 	params->es_cnt++;
993 
994 	return ICE_SUCCESS;
995 }
996 
997 /**
998  * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
999  * @hw: pointer to the HW struct
1000  * @params: information about the flow to be processed
1001  * @seg: packet segment index of the field to be extracted
1002  * @fld: ID of field to be extracted
1003  * @match: bitfield of all fields
1004  *
1005  * This function determines the protocol ID, offset, and size of the given
1006  * field. It then allocates one or more extraction sequence entries for the
1007  * given field, and fill the entries with protocol ID and offset information.
1008  */
1009 static enum ice_status
1010 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
1011 		    u8 seg, enum ice_flow_field fld, u64 match)
1012 {
1013 	enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
1014 	enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
1015 	u8 fv_words = hw->blk[params->blk].es.fvw;
1016 	struct ice_flow_fld_info *flds;
1017 	u16 cnt, ese_bits, i;
1018 	u16 sib_mask = 0;
1019 	u16 mask;
1020 	u16 off;
1021 
1022 	flds = params->prof->segs[seg].fields;
1023 
1024 	switch (fld) {
1025 	case ICE_FLOW_FIELD_IDX_ETH_DA:
1026 	case ICE_FLOW_FIELD_IDX_ETH_SA:
1027 	case ICE_FLOW_FIELD_IDX_S_VLAN:
1028 	case ICE_FLOW_FIELD_IDX_C_VLAN:
1029 		prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
1030 		break;
1031 	case ICE_FLOW_FIELD_IDX_ETH_TYPE:
1032 		prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
1033 		break;
1034 	case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
1035 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
1036 		break;
1037 	case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
1038 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
1039 		break;
1040 	case ICE_FLOW_FIELD_IDX_IPV4_TTL:
1041 	case ICE_FLOW_FIELD_IDX_IPV4_PROT:
1042 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
1043 
1044 		/* TTL and PROT share the same extraction seq. entry.
1045 		 * Each is considered a sibling to the other in terms of sharing
1046 		 * the same extraction sequence entry.
1047 		 */
1048 		if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
1049 			sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
1050 		else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
1051 			sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
1052 
1053 		/* If the sibling field is also included, that field's
1054 		 * mask needs to be included.
1055 		 */
1056 		if (match & BIT(sib))
1057 			sib_mask = ice_flds_info[sib].mask;
1058 		break;
1059 	case ICE_FLOW_FIELD_IDX_IPV6_TTL:
1060 	case ICE_FLOW_FIELD_IDX_IPV6_PROT:
1061 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
1062 
1063 		/* TTL and PROT share the same extraction seq. entry.
1064 		 * Each is considered a sibling to the other in terms of sharing
1065 		 * the same extraction sequence entry.
1066 		 */
1067 		if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
1068 			sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
1069 		else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
1070 			sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
1071 
1072 		/* If the sibling field is also included, that field's
1073 		 * mask needs to be included.
1074 		 */
1075 		if (match & BIT(sib))
1076 			sib_mask = ice_flds_info[sib].mask;
1077 		break;
1078 	case ICE_FLOW_FIELD_IDX_IPV4_SA:
1079 	case ICE_FLOW_FIELD_IDX_IPV4_DA:
1080 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
1081 		break;
1082 	case ICE_FLOW_FIELD_IDX_IPV6_SA:
1083 	case ICE_FLOW_FIELD_IDX_IPV6_DA:
1084 	case ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA:
1085 	case ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA:
1086 	case ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA:
1087 	case ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA:
1088 	case ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA:
1089 	case ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA:
1090 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
1091 		break;
1092 	case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
1093 	case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
1094 	case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
1095 		prot_id = ICE_PROT_TCP_IL;
1096 		break;
1097 	case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
1098 	case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
1099 		prot_id = ICE_PROT_UDP_IL_OR_S;
1100 		break;
1101 	case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
1102 	case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
1103 		prot_id = ICE_PROT_SCTP_IL;
1104 		break;
1105 	case ICE_FLOW_FIELD_IDX_GTPC_TEID:
1106 	case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
1107 	case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
1108 	case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
1109 	case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
1110 	case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
1111 		/* GTP is accessed through UDP OF protocol */
1112 		prot_id = ICE_PROT_UDP_OF;
1113 		break;
1114 	case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
1115 		prot_id = ICE_PROT_PPPOE;
1116 		break;
1117 	case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1118 		prot_id = ICE_PROT_UDP_IL_OR_S;
1119 		break;
1120 	case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1121 		prot_id = ICE_PROT_L2TPV3;
1122 		break;
1123 	case ICE_FLOW_FIELD_IDX_ESP_SPI:
1124 		prot_id = ICE_PROT_ESP_F;
1125 		break;
1126 	case ICE_FLOW_FIELD_IDX_AH_SPI:
1127 		prot_id = ICE_PROT_ESP_2;
1128 		break;
1129 	case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1130 		prot_id = ICE_PROT_UDP_IL_OR_S;
1131 		break;
1132 	case ICE_FLOW_FIELD_IDX_ARP_SIP:
1133 	case ICE_FLOW_FIELD_IDX_ARP_DIP:
1134 	case ICE_FLOW_FIELD_IDX_ARP_SHA:
1135 	case ICE_FLOW_FIELD_IDX_ARP_DHA:
1136 	case ICE_FLOW_FIELD_IDX_ARP_OP:
1137 		prot_id = ICE_PROT_ARP_OF;
1138 		break;
1139 	case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1140 	case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1141 		/* ICMP type and code share the same extraction seq. entry */
1142 		prot_id = (params->prof->segs[seg].hdrs &
1143 			   ICE_FLOW_SEG_HDR_IPV4) ?
1144 			ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1145 		sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1146 			ICE_FLOW_FIELD_IDX_ICMP_CODE :
1147 			ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1148 		break;
1149 	case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1150 		prot_id = ICE_PROT_GRE_OF;
1151 		break;
1152 	default:
1153 		return ICE_ERR_NOT_IMPL;
1154 	}
1155 
1156 	/* Each extraction sequence entry is a word in size, and extracts a
1157 	 * word-aligned offset from a protocol header.
1158 	 */
1159 	ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1160 
1161 	flds[fld].xtrct.prot_id = prot_id;
1162 	flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1163 		ICE_FLOW_FV_EXTRACT_SZ;
1164 	flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1165 	flds[fld].xtrct.idx = params->es_cnt;
1166 	flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1167 
1168 	/* Adjust the next field-entry index after accommodating the number of
1169 	 * entries this field consumes
1170 	 */
1171 	cnt = DIVIDE_AND_ROUND_UP(flds[fld].xtrct.disp +
1172 				  ice_flds_info[fld].size, ese_bits);
1173 
1174 	/* Fill in the extraction sequence entries needed for this field */
1175 	off = flds[fld].xtrct.off;
1176 	mask = flds[fld].xtrct.mask;
1177 	for (i = 0; i < cnt; i++) {
1178 		/* Only consume an extraction sequence entry if there is no
1179 		 * sibling field associated with this field or the sibling entry
1180 		 * already extracts the word shared with this field.
1181 		 */
1182 		if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1183 		    flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1184 		    flds[sib].xtrct.off != off) {
1185 			u8 idx;
1186 
1187 			/* Make sure the number of extraction sequence required
1188 			 * does not exceed the block's capability
1189 			 */
1190 			if (params->es_cnt >= fv_words)
1191 				return ICE_ERR_MAX_LIMIT;
1192 
1193 			/* some blocks require a reversed field vector layout */
1194 			if (hw->blk[params->blk].es.reverse)
1195 				idx = fv_words - params->es_cnt - 1;
1196 			else
1197 				idx = params->es_cnt;
1198 
1199 			params->es[idx].prot_id = prot_id;
1200 			params->es[idx].off = off;
1201 			params->mask[idx] = mask | sib_mask;
1202 			params->es_cnt++;
1203 		}
1204 
1205 		off += ICE_FLOW_FV_EXTRACT_SZ;
1206 	}
1207 
1208 	return ICE_SUCCESS;
1209 }
1210 
1211 /**
1212  * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1213  * @hw: pointer to the HW struct
1214  * @params: information about the flow to be processed
1215  * @seg: index of packet segment whose raw fields are to be be extracted
1216  */
1217 static enum ice_status
1218 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1219 		     u8 seg)
1220 {
1221 	u16 fv_words;
1222 	u16 hdrs_sz;
1223 	u8 i;
1224 
1225 	if (!params->prof->segs[seg].raws_cnt)
1226 		return ICE_SUCCESS;
1227 
1228 	if (params->prof->segs[seg].raws_cnt >
1229 	    ARRAY_SIZE(params->prof->segs[seg].raws))
1230 		return ICE_ERR_MAX_LIMIT;
1231 
1232 	/* Offsets within the segment headers are not supported */
1233 	hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1234 	if (!hdrs_sz)
1235 		return ICE_ERR_PARAM;
1236 
1237 	fv_words = hw->blk[params->blk].es.fvw;
1238 
1239 	for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1240 		struct ice_flow_seg_fld_raw *raw;
1241 		u16 off, cnt, j;
1242 
1243 		raw = &params->prof->segs[seg].raws[i];
1244 
1245 		/* Storing extraction information */
1246 		raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1247 		raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1248 			ICE_FLOW_FV_EXTRACT_SZ;
1249 		raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1250 			BITS_PER_BYTE;
1251 		raw->info.xtrct.idx = params->es_cnt;
1252 
1253 		/* Determine the number of field vector entries this raw field
1254 		 * consumes.
1255 		 */
1256 		cnt = DIVIDE_AND_ROUND_UP(raw->info.xtrct.disp +
1257 					  (raw->info.src.last * BITS_PER_BYTE),
1258 					  (ICE_FLOW_FV_EXTRACT_SZ *
1259 					   BITS_PER_BYTE));
1260 		off = raw->info.xtrct.off;
1261 		for (j = 0; j < cnt; j++) {
1262 			u16 idx;
1263 
1264 			/* Make sure the number of extraction sequence required
1265 			 * does not exceed the block's capability
1266 			 */
1267 			if (params->es_cnt >= hw->blk[params->blk].es.count ||
1268 			    params->es_cnt >= ICE_MAX_FV_WORDS)
1269 				return ICE_ERR_MAX_LIMIT;
1270 
1271 			/* some blocks require a reversed field vector layout */
1272 			if (hw->blk[params->blk].es.reverse)
1273 				idx = fv_words - params->es_cnt - 1;
1274 			else
1275 				idx = params->es_cnt;
1276 
1277 			params->es[idx].prot_id = raw->info.xtrct.prot_id;
1278 			params->es[idx].off = off;
1279 			params->es_cnt++;
1280 			off += ICE_FLOW_FV_EXTRACT_SZ;
1281 		}
1282 	}
1283 
1284 	return ICE_SUCCESS;
1285 }
1286 
1287 /**
1288  * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1289  * @hw: pointer to the HW struct
1290  * @params: information about the flow to be processed
1291  *
1292  * This function iterates through all matched fields in the given segments, and
1293  * creates an extraction sequence for the fields.
1294  */
1295 static enum ice_status
1296 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1297 			  struct ice_flow_prof_params *params)
1298 {
1299 	enum ice_status status = ICE_SUCCESS;
1300 	u8 i;
1301 
1302 	/* For ACL, we also need to extract the direction bit (Rx,Tx) data from
1303 	 * packet flags
1304 	 */
1305 	if (params->blk == ICE_BLK_ACL) {
1306 		status = ice_flow_xtract_pkt_flags(hw, params,
1307 						   ICE_RX_MDID_PKT_FLAGS_15_0);
1308 		if (status)
1309 			return status;
1310 	}
1311 
1312 	for (i = 0; i < params->prof->segs_cnt; i++) {
1313 		u64 match = params->prof->segs[i].match;
1314 		enum ice_flow_field j;
1315 
1316 		for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) {
1317 			const u64 bit = BIT_ULL(j);
1318 
1319 			if (match & bit) {
1320 				status = ice_flow_xtract_fld(hw, params, i, j,
1321 							     match);
1322 				if (status)
1323 					return status;
1324 				match &= ~bit;
1325 			}
1326 		}
1327 
1328 		/* Process raw matching bytes */
1329 		status = ice_flow_xtract_raws(hw, params, i);
1330 		if (status)
1331 			return status;
1332 	}
1333 
1334 	return status;
1335 }
1336 
1337 /**
1338  * ice_flow_sel_acl_scen - returns the specific scenario
1339  * @hw: pointer to the hardware structure
1340  * @params: information about the flow to be processed
1341  *
1342  * This function will return the specific scenario based on the
1343  * params passed to it
1344  */
1345 static enum ice_status
1346 ice_flow_sel_acl_scen(struct ice_hw *hw, struct ice_flow_prof_params *params)
1347 {
1348 	/* Find the best-fit scenario for the provided match width */
1349 	struct ice_acl_scen *cand_scen = NULL, *scen;
1350 
1351 	if (!hw->acl_tbl)
1352 		return ICE_ERR_DOES_NOT_EXIST;
1353 
1354 	/* Loop through each scenario and match against the scenario width
1355 	 * to select the specific scenario
1356 	 */
1357 	LIST_FOR_EACH_ENTRY(scen, &hw->acl_tbl->scens, ice_acl_scen, list_entry)
1358 		if (scen->eff_width >= params->entry_length &&
1359 		    (!cand_scen || cand_scen->eff_width > scen->eff_width))
1360 			cand_scen = scen;
1361 	if (!cand_scen)
1362 		return ICE_ERR_DOES_NOT_EXIST;
1363 
1364 	params->prof->cfg.scen = cand_scen;
1365 
1366 	return ICE_SUCCESS;
1367 }
1368 
1369 /**
1370  * ice_flow_acl_def_entry_frmt - Determine the layout of flow entries
1371  * @params: information about the flow to be processed
1372  */
1373 static enum ice_status
1374 ice_flow_acl_def_entry_frmt(struct ice_flow_prof_params *params)
1375 {
1376 	u16 index, i, range_idx = 0;
1377 
1378 	index = ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
1379 
1380 	for (i = 0; i < params->prof->segs_cnt; i++) {
1381 		struct ice_flow_seg_info *seg = &params->prof->segs[i];
1382 		u64 match = seg->match;
1383 		u8 j;
1384 
1385 		for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) {
1386 			struct ice_flow_fld_info *fld;
1387 			const u64 bit = BIT_ULL(j);
1388 
1389 			if (!(match & bit))
1390 				continue;
1391 
1392 			fld = &seg->fields[j];
1393 			fld->entry.mask = ICE_FLOW_FLD_OFF_INVAL;
1394 
1395 			if (fld->type == ICE_FLOW_FLD_TYPE_RANGE) {
1396 				fld->entry.last = ICE_FLOW_FLD_OFF_INVAL;
1397 
1398 				/* Range checking only supported for single
1399 				 * words
1400 				 */
1401 				if (DIVIDE_AND_ROUND_UP(ice_flds_info[j].size +
1402 							fld->xtrct.disp,
1403 							BITS_PER_BYTE * 2) > 1)
1404 					return ICE_ERR_PARAM;
1405 
1406 				/* Ranges must define low and high values */
1407 				if (fld->src.val == ICE_FLOW_FLD_OFF_INVAL ||
1408 				    fld->src.last == ICE_FLOW_FLD_OFF_INVAL)
1409 					return ICE_ERR_PARAM;
1410 
1411 				fld->entry.val = range_idx++;
1412 			} else {
1413 				/* Store adjusted byte-length of field for later
1414 				 * use, taking into account potential
1415 				 * non-byte-aligned displacement
1416 				 */
1417 				fld->entry.last = DIVIDE_AND_ROUND_UP
1418 					(ice_flds_info[j].size +
1419 					 (fld->xtrct.disp % BITS_PER_BYTE),
1420 					 BITS_PER_BYTE);
1421 				fld->entry.val = index;
1422 				index += fld->entry.last;
1423 			}
1424 
1425 			match &= ~bit;
1426 		}
1427 
1428 		for (j = 0; j < seg->raws_cnt; j++) {
1429 			struct ice_flow_seg_fld_raw *raw = &seg->raws[j];
1430 
1431 			raw->info.entry.mask = ICE_FLOW_FLD_OFF_INVAL;
1432 			raw->info.entry.val = index;
1433 			raw->info.entry.last = raw->info.src.last;
1434 			index += raw->info.entry.last;
1435 		}
1436 	}
1437 
1438 	/* Currently only support using the byte selection base, which only
1439 	 * allows for an effective entry size of 30 bytes. Reject anything
1440 	 * larger.
1441 	 */
1442 	if (index > ICE_AQC_ACL_PROF_BYTE_SEL_ELEMS)
1443 		return ICE_ERR_PARAM;
1444 
1445 	/* Only 8 range checkers per profile, reject anything trying to use
1446 	 * more
1447 	 */
1448 	if (range_idx > ICE_AQC_ACL_PROF_RANGES_NUM_CFG)
1449 		return ICE_ERR_PARAM;
1450 
1451 	/* Store # bytes required for entry for later use */
1452 	params->entry_length = index - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
1453 
1454 	return ICE_SUCCESS;
1455 }
1456 
1457 /**
1458  * ice_flow_proc_segs - process all packet segments associated with a profile
1459  * @hw: pointer to the HW struct
1460  * @params: information about the flow to be processed
1461  */
1462 static enum ice_status
1463 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1464 {
1465 	enum ice_status status;
1466 
1467 	status = ice_flow_proc_seg_hdrs(params);
1468 	if (status)
1469 		return status;
1470 
1471 	status = ice_flow_create_xtrct_seq(hw, params);
1472 	if (status)
1473 		return status;
1474 
1475 	switch (params->blk) {
1476 	case ICE_BLK_FD:
1477 	case ICE_BLK_RSS:
1478 		status = ICE_SUCCESS;
1479 		break;
1480 	case ICE_BLK_ACL:
1481 		status = ice_flow_acl_def_entry_frmt(params);
1482 		if (status)
1483 			return status;
1484 		status = ice_flow_sel_acl_scen(hw, params);
1485 		if (status)
1486 			return status;
1487 		break;
1488 	default:
1489 		return ICE_ERR_NOT_IMPL;
1490 	}
1491 
1492 	return status;
1493 }
1494 
1495 #define ICE_FLOW_FIND_PROF_CHK_FLDS	0x00000001
1496 #define ICE_FLOW_FIND_PROF_CHK_VSI	0x00000002
1497 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR	0x00000004
1498 
1499 /**
1500  * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1501  * @hw: pointer to the HW struct
1502  * @blk: classification stage
1503  * @dir: flow direction
1504  * @segs: array of one or more packet segments that describe the flow
1505  * @segs_cnt: number of packet segments provided
1506  * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1507  * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1508  */
1509 static struct ice_flow_prof *
1510 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1511 			 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1512 			 u8 segs_cnt, u16 vsi_handle, u32 conds)
1513 {
1514 	struct ice_flow_prof *p, *prof = NULL;
1515 
1516 	ice_acquire_lock(&hw->fl_profs_locks[blk]);
1517 	LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry)
1518 		if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1519 		    segs_cnt && segs_cnt == p->segs_cnt) {
1520 			u8 i;
1521 
1522 			/* Check for profile-VSI association if specified */
1523 			if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1524 			    ice_is_vsi_valid(hw, vsi_handle) &&
1525 			    !ice_is_bit_set(p->vsis, vsi_handle))
1526 				continue;
1527 
1528 			/* Protocol headers must be checked. Matched fields are
1529 			 * checked if specified.
1530 			 */
1531 			for (i = 0; i < segs_cnt; i++)
1532 				if (segs[i].hdrs != p->segs[i].hdrs ||
1533 				    ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1534 				     segs[i].match != p->segs[i].match))
1535 					break;
1536 
1537 			/* A match is found if all segments are matched */
1538 			if (i == segs_cnt) {
1539 				prof = p;
1540 				break;
1541 			}
1542 		}
1543 	ice_release_lock(&hw->fl_profs_locks[blk]);
1544 
1545 	return prof;
1546 }
1547 
1548 /**
1549  * ice_flow_find_prof - Look up a profile matching headers and matched fields
1550  * @hw: pointer to the HW struct
1551  * @blk: classification stage
1552  * @dir: flow direction
1553  * @segs: array of one or more packet segments that describe the flow
1554  * @segs_cnt: number of packet segments provided
1555  */
1556 u64
1557 ice_flow_find_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1558 		   struct ice_flow_seg_info *segs, u8 segs_cnt)
1559 {
1560 	struct ice_flow_prof *p;
1561 
1562 	p = ice_flow_find_prof_conds(hw, blk, dir, segs, segs_cnt,
1563 				     ICE_MAX_VSI, ICE_FLOW_FIND_PROF_CHK_FLDS);
1564 
1565 	return p ? p->id : ICE_FLOW_PROF_ID_INVAL;
1566 }
1567 
1568 /**
1569  * ice_flow_find_prof_id - Look up a profile with given profile ID
1570  * @hw: pointer to the HW struct
1571  * @blk: classification stage
1572  * @prof_id: unique ID to identify this flow profile
1573  */
1574 static struct ice_flow_prof *
1575 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1576 {
1577 	struct ice_flow_prof *p;
1578 
1579 	LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry)
1580 		if (p->id == prof_id)
1581 			return p;
1582 
1583 	return NULL;
1584 }
1585 
1586 /**
1587  * ice_dealloc_flow_entry - Deallocate flow entry memory
1588  * @hw: pointer to the HW struct
1589  * @entry: flow entry to be removed
1590  */
1591 static void
1592 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1593 {
1594 	if (!entry)
1595 		return;
1596 
1597 	if (entry->entry)
1598 		ice_free(hw, entry->entry);
1599 
1600 	if (entry->range_buf) {
1601 		ice_free(hw, entry->range_buf);
1602 		entry->range_buf = NULL;
1603 	}
1604 
1605 	if (entry->acts) {
1606 		ice_free(hw, entry->acts);
1607 		entry->acts = NULL;
1608 		entry->acts_cnt = 0;
1609 	}
1610 
1611 	ice_free(hw, entry);
1612 }
1613 
1614 #define ICE_ACL_INVALID_SCEN	0x3f
1615 
1616 /**
1617  * ice_flow_acl_is_prof_in_use - Verify if the profile is associated to any PF
1618  * @hw: pointer to the hardware structure
1619  * @prof: pointer to flow profile
1620  * @buf: destination buffer function writes partial extraction sequence to
1621  *
1622  * returns ICE_SUCCESS if no PF is associated to the given profile
1623  * returns ICE_ERR_IN_USE if at least one PF is associated to the given profile
1624  * returns other error code for real error
1625  */
1626 static enum ice_status
1627 ice_flow_acl_is_prof_in_use(struct ice_hw *hw, struct ice_flow_prof *prof,
1628 			    struct ice_aqc_acl_prof_generic_frmt *buf)
1629 {
1630 	enum ice_status status;
1631 	u8 prof_id = 0;
1632 
1633 	status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
1634 	if (status)
1635 		return status;
1636 
1637 	status = ice_query_acl_prof(hw, prof_id, buf, NULL);
1638 	if (status)
1639 		return status;
1640 
1641 	/* If all PF's associated scenarios are all 0 or all
1642 	 * ICE_ACL_INVALID_SCEN (63) for the given profile then the latter has
1643 	 * not been configured yet.
1644 	 */
1645 	if (buf->pf_scenario_num[0] == 0 && buf->pf_scenario_num[1] == 0 &&
1646 	    buf->pf_scenario_num[2] == 0 && buf->pf_scenario_num[3] == 0 &&
1647 	    buf->pf_scenario_num[4] == 0 && buf->pf_scenario_num[5] == 0 &&
1648 	    buf->pf_scenario_num[6] == 0 && buf->pf_scenario_num[7] == 0)
1649 		return ICE_SUCCESS;
1650 
1651 	if (buf->pf_scenario_num[0] == ICE_ACL_INVALID_SCEN &&
1652 	    buf->pf_scenario_num[1] == ICE_ACL_INVALID_SCEN &&
1653 	    buf->pf_scenario_num[2] == ICE_ACL_INVALID_SCEN &&
1654 	    buf->pf_scenario_num[3] == ICE_ACL_INVALID_SCEN &&
1655 	    buf->pf_scenario_num[4] == ICE_ACL_INVALID_SCEN &&
1656 	    buf->pf_scenario_num[5] == ICE_ACL_INVALID_SCEN &&
1657 	    buf->pf_scenario_num[6] == ICE_ACL_INVALID_SCEN &&
1658 	    buf->pf_scenario_num[7] == ICE_ACL_INVALID_SCEN)
1659 		return ICE_SUCCESS;
1660 	else
1661 		return ICE_ERR_IN_USE;
1662 }
1663 
1664 /**
1665  * ice_flow_acl_free_act_cntr - Free the ACL rule's actions
1666  * @hw: pointer to the hardware structure
1667  * @acts: array of actions to be performed on a match
1668  * @acts_cnt: number of actions
1669  */
1670 static enum ice_status
1671 ice_flow_acl_free_act_cntr(struct ice_hw *hw, struct ice_flow_action *acts,
1672 			   u8 acts_cnt)
1673 {
1674 	int i;
1675 
1676 	for (i = 0; i < acts_cnt; i++) {
1677 		if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT ||
1678 		    acts[i].type == ICE_FLOW_ACT_CNTR_BYTES ||
1679 		    acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES) {
1680 			struct ice_acl_cntrs cntrs;
1681 			enum ice_status status;
1682 
1683 			cntrs.bank = 0; /* Only bank0 for the moment */
1684 			cntrs.first_cntr =
1685 					LE16_TO_CPU(acts[i].data.acl_act.value);
1686 			cntrs.last_cntr =
1687 					LE16_TO_CPU(acts[i].data.acl_act.value);
1688 
1689 			if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES)
1690 				cntrs.type = ICE_AQC_ACL_CNT_TYPE_DUAL;
1691 			else
1692 				cntrs.type = ICE_AQC_ACL_CNT_TYPE_SINGLE;
1693 
1694 			status = ice_aq_dealloc_acl_cntrs(hw, &cntrs, NULL);
1695 			if (status)
1696 				return status;
1697 		}
1698 	}
1699 	return ICE_SUCCESS;
1700 }
1701 
1702 /**
1703  * ice_flow_acl_disassoc_scen - Disassociate the scenario from the profile
1704  * @hw: pointer to the hardware structure
1705  * @prof: pointer to flow profile
1706  *
1707  * Disassociate the scenario from the profile for the PF of the VSI.
1708  */
1709 static enum ice_status
1710 ice_flow_acl_disassoc_scen(struct ice_hw *hw, struct ice_flow_prof *prof)
1711 {
1712 	struct ice_aqc_acl_prof_generic_frmt buf;
1713 	enum ice_status status = ICE_SUCCESS;
1714 	u8 prof_id = 0;
1715 
1716 	ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
1717 
1718 	status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
1719 	if (status)
1720 		return status;
1721 
1722 	status = ice_query_acl_prof(hw, prof_id, &buf, NULL);
1723 	if (status)
1724 		return status;
1725 
1726 	/* Clear scenario for this PF */
1727 	buf.pf_scenario_num[hw->pf_id] = ICE_ACL_INVALID_SCEN;
1728 	status = ice_prgm_acl_prof_extrt(hw, prof_id, &buf, NULL);
1729 
1730 	return status;
1731 }
1732 
1733 /**
1734  * ice_flow_rem_entry_sync - Remove a flow entry
1735  * @hw: pointer to the HW struct
1736  * @blk: classification stage
1737  * @entry: flow entry to be removed
1738  */
1739 static enum ice_status
1740 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block blk,
1741 			struct ice_flow_entry *entry)
1742 {
1743 	if (!entry)
1744 		return ICE_ERR_BAD_PTR;
1745 
1746 	if (blk == ICE_BLK_ACL) {
1747 		enum ice_status status;
1748 
1749 		if (!entry->prof)
1750 			return ICE_ERR_BAD_PTR;
1751 
1752 		status = ice_acl_rem_entry(hw, entry->prof->cfg.scen,
1753 					   entry->scen_entry_idx);
1754 		if (status)
1755 			return status;
1756 
1757 		/* Checks if we need to release an ACL counter. */
1758 		if (entry->acts_cnt && entry->acts)
1759 			ice_flow_acl_free_act_cntr(hw, entry->acts,
1760 						   entry->acts_cnt);
1761 	}
1762 
1763 	LIST_DEL(&entry->l_entry);
1764 
1765 	ice_dealloc_flow_entry(hw, entry);
1766 
1767 	return ICE_SUCCESS;
1768 }
1769 
1770 /**
1771  * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1772  * @hw: pointer to the HW struct
1773  * @blk: classification stage
1774  * @dir: flow direction
1775  * @prof_id: unique ID to identify this flow profile
1776  * @segs: array of one or more packet segments that describe the flow
1777  * @segs_cnt: number of packet segments provided
1778  * @acts: array of default actions
1779  * @acts_cnt: number of default actions
1780  * @prof: stores the returned flow profile added
1781  *
1782  * Assumption: the caller has acquired the lock to the profile list
1783  */
1784 static enum ice_status
1785 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1786 		       enum ice_flow_dir dir, u64 prof_id,
1787 		       struct ice_flow_seg_info *segs, u8 segs_cnt,
1788 		       struct ice_flow_action *acts, u8 acts_cnt,
1789 		       struct ice_flow_prof **prof)
1790 {
1791 	struct ice_flow_prof_params params;
1792 	enum ice_status status;
1793 	u8 i;
1794 
1795 	if (!prof || (acts_cnt && !acts))
1796 		return ICE_ERR_BAD_PTR;
1797 
1798 	ice_memset(&params, 0, sizeof(params), ICE_NONDMA_MEM);
1799 	params.prof = (struct ice_flow_prof *)
1800 		ice_malloc(hw, sizeof(*params.prof));
1801 	if (!params.prof)
1802 		return ICE_ERR_NO_MEMORY;
1803 
1804 	/* initialize extraction sequence to all invalid (0xff) */
1805 	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1806 		params.es[i].prot_id = ICE_PROT_INVALID;
1807 		params.es[i].off = ICE_FV_OFFSET_INVAL;
1808 	}
1809 
1810 	params.blk = blk;
1811 	params.prof->id = prof_id;
1812 	params.prof->dir = dir;
1813 	params.prof->segs_cnt = segs_cnt;
1814 
1815 	/* Make a copy of the segments that need to be persistent in the flow
1816 	 * profile instance
1817 	 */
1818 	for (i = 0; i < segs_cnt; i++)
1819 		ice_memcpy(&params.prof->segs[i], &segs[i], sizeof(*segs),
1820 			   ICE_NONDMA_TO_NONDMA);
1821 
1822 	/* Make a copy of the actions that need to be persistent in the flow
1823 	 * profile instance.
1824 	 */
1825 	if (acts_cnt) {
1826 		params.prof->acts = (struct ice_flow_action *)
1827 			ice_memdup(hw, acts, acts_cnt * sizeof(*acts),
1828 				   ICE_NONDMA_TO_NONDMA);
1829 
1830 		if (!params.prof->acts) {
1831 			status = ICE_ERR_NO_MEMORY;
1832 			goto out;
1833 		}
1834 	}
1835 
1836 	status = ice_flow_proc_segs(hw, &params);
1837 	if (status) {
1838 		ice_debug(hw, ICE_DBG_FLOW,
1839 			  "Error processing a flow's packet segments\n");
1840 		goto out;
1841 	}
1842 
1843 	/* Add a HW profile for this flow profile */
1844 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params.ptypes,
1845 			      params.attr, params.attr_cnt, params.es,
1846 			      params.mask);
1847 	if (status) {
1848 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1849 		goto out;
1850 	}
1851 
1852 	INIT_LIST_HEAD(&params.prof->entries);
1853 	ice_init_lock(&params.prof->entries_lock);
1854 	*prof = params.prof;
1855 
1856 out:
1857 	if (status) {
1858 		if (params.prof->acts)
1859 			ice_free(hw, params.prof->acts);
1860 		ice_free(hw, params.prof);
1861 	}
1862 
1863 	return status;
1864 }
1865 
1866 /**
1867  * ice_flow_rem_prof_sync - remove a flow profile
1868  * @hw: pointer to the hardware structure
1869  * @blk: classification stage
1870  * @prof: pointer to flow profile to remove
1871  *
1872  * Assumption: the caller has acquired the lock to the profile list
1873  */
1874 static enum ice_status
1875 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1876 		       struct ice_flow_prof *prof)
1877 {
1878 	enum ice_status status;
1879 
1880 	/* Remove all remaining flow entries before removing the flow profile */
1881 	if (!LIST_EMPTY(&prof->entries)) {
1882 		struct ice_flow_entry *e, *t;
1883 
1884 		ice_acquire_lock(&prof->entries_lock);
1885 
1886 		LIST_FOR_EACH_ENTRY_SAFE(e, t, &prof->entries, ice_flow_entry,
1887 					 l_entry) {
1888 			status = ice_flow_rem_entry_sync(hw, blk, e);
1889 			if (status)
1890 				break;
1891 		}
1892 
1893 		ice_release_lock(&prof->entries_lock);
1894 	}
1895 
1896 	if (blk == ICE_BLK_ACL) {
1897 		struct ice_aqc_acl_profile_ranges query_rng_buf;
1898 		struct ice_aqc_acl_prof_generic_frmt buf;
1899 		u8 prof_id = 0;
1900 
1901 		/* Disassociate the scenario from the profile for the PF */
1902 		status = ice_flow_acl_disassoc_scen(hw, prof);
1903 		if (status)
1904 			return status;
1905 
1906 		/* Clear the range-checker if the profile ID is no longer
1907 		 * used by any PF
1908 		 */
1909 		status = ice_flow_acl_is_prof_in_use(hw, prof, &buf);
1910 		if (status && status != ICE_ERR_IN_USE) {
1911 			return status;
1912 		} else if (!status) {
1913 			/* Clear the range-checker value for profile ID */
1914 			ice_memset(&query_rng_buf, 0,
1915 				   sizeof(struct ice_aqc_acl_profile_ranges),
1916 				   ICE_NONDMA_MEM);
1917 
1918 			status = ice_flow_get_hw_prof(hw, blk, prof->id,
1919 						      &prof_id);
1920 			if (status)
1921 				return status;
1922 
1923 			status = ice_prog_acl_prof_ranges(hw, prof_id,
1924 							  &query_rng_buf, NULL);
1925 			if (status)
1926 				return status;
1927 		}
1928 	}
1929 
1930 	/* Remove all hardware profiles associated with this flow profile */
1931 	status = ice_rem_prof(hw, blk, prof->id);
1932 	if (!status) {
1933 		LIST_DEL(&prof->l_entry);
1934 		ice_destroy_lock(&prof->entries_lock);
1935 		if (prof->acts)
1936 			ice_free(hw, prof->acts);
1937 		ice_free(hw, prof);
1938 	}
1939 
1940 	return status;
1941 }
1942 
1943 /**
1944  * ice_flow_acl_set_xtrct_seq_fld - Populate xtrct seq for single field
1945  * @buf: Destination buffer function writes partial xtrct sequence to
1946  * @info: Info about field
1947  */
1948 static void
1949 ice_flow_acl_set_xtrct_seq_fld(struct ice_aqc_acl_prof_generic_frmt *buf,
1950 			       struct ice_flow_fld_info *info)
1951 {
1952 	u16 dst, i;
1953 	u8 src;
1954 
1955 	src = info->xtrct.idx * ICE_FLOW_FV_EXTRACT_SZ +
1956 		info->xtrct.disp / BITS_PER_BYTE;
1957 	dst = info->entry.val;
1958 	for (i = 0; i < info->entry.last; i++)
1959 		/* HW stores field vector words in LE, convert words back to BE
1960 		 * so constructed entries will end up in network order
1961 		 */
1962 		buf->byte_selection[dst++] = src++ ^ 1;
1963 }
1964 
1965 /**
1966  * ice_flow_acl_set_xtrct_seq - Program ACL extraction sequence
1967  * @hw: pointer to the hardware structure
1968  * @prof: pointer to flow profile
1969  */
1970 static enum ice_status
1971 ice_flow_acl_set_xtrct_seq(struct ice_hw *hw, struct ice_flow_prof *prof)
1972 {
1973 	struct ice_aqc_acl_prof_generic_frmt buf;
1974 	struct ice_flow_fld_info *info;
1975 	enum ice_status status;
1976 	u8 prof_id = 0;
1977 	u16 i;
1978 
1979 	ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
1980 
1981 	status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
1982 	if (status)
1983 		return status;
1984 
1985 	status = ice_flow_acl_is_prof_in_use(hw, prof, &buf);
1986 	if (status && status != ICE_ERR_IN_USE)
1987 		return status;
1988 
1989 	if (!status) {
1990 		/* Program the profile dependent configuration. This is done
1991 		 * only once regardless of the number of PFs using that profile
1992 		 */
1993 		ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
1994 
1995 		for (i = 0; i < prof->segs_cnt; i++) {
1996 			struct ice_flow_seg_info *seg = &prof->segs[i];
1997 			u64 match = seg->match;
1998 			u16 j;
1999 
2000 			for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) {
2001 				const u64 bit = BIT_ULL(j);
2002 
2003 				if (!(match & bit))
2004 					continue;
2005 
2006 				info = &seg->fields[j];
2007 
2008 				if (info->type == ICE_FLOW_FLD_TYPE_RANGE)
2009 					buf.word_selection[info->entry.val] =
2010 								info->xtrct.idx;
2011 				else
2012 					ice_flow_acl_set_xtrct_seq_fld(&buf,
2013 								       info);
2014 
2015 				match &= ~bit;
2016 			}
2017 
2018 			for (j = 0; j < seg->raws_cnt; j++) {
2019 				info = &seg->raws[j].info;
2020 				ice_flow_acl_set_xtrct_seq_fld(&buf, info);
2021 			}
2022 		}
2023 
2024 		ice_memset(&buf.pf_scenario_num[0], ICE_ACL_INVALID_SCEN,
2025 			   ICE_AQC_ACL_PROF_PF_SCEN_NUM_ELEMS,
2026 			   ICE_NONDMA_MEM);
2027 	}
2028 
2029 	/* Update the current PF */
2030 	buf.pf_scenario_num[hw->pf_id] = (u8)prof->cfg.scen->id;
2031 	status = ice_prgm_acl_prof_extrt(hw, prof_id, &buf, NULL);
2032 
2033 	return status;
2034 }
2035 
2036 /**
2037  * ice_flow_assoc_vsig_vsi - associate a VSI with VSIG
2038  * @hw: pointer to the hardware structure
2039  * @blk: classification stage
2040  * @vsi_handle: software VSI handle
2041  * @vsig: target VSI group
2042  *
2043  * Assumption: the caller has already verified that the VSI to
2044  * be added has the same characteristics as the VSIG and will
2045  * thereby have access to all resources added to that VSIG.
2046  */
2047 enum ice_status
2048 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
2049 			u16 vsig)
2050 {
2051 	enum ice_status status;
2052 
2053 	if (!ice_is_vsi_valid(hw, vsi_handle) || blk >= ICE_BLK_COUNT)
2054 		return ICE_ERR_PARAM;
2055 
2056 	ice_acquire_lock(&hw->fl_profs_locks[blk]);
2057 	status = ice_add_vsi_flow(hw, blk, ice_get_hw_vsi_num(hw, vsi_handle),
2058 				  vsig);
2059 	ice_release_lock(&hw->fl_profs_locks[blk]);
2060 
2061 	return status;
2062 }
2063 
2064 /**
2065  * ice_flow_assoc_prof - associate a VSI with a flow profile
2066  * @hw: pointer to the hardware structure
2067  * @blk: classification stage
2068  * @prof: pointer to flow profile
2069  * @vsi_handle: software VSI handle
2070  *
2071  * Assumption: the caller has acquired the lock to the profile list
2072  * and the software VSI handle has been validated
2073  */
2074 static enum ice_status
2075 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
2076 		    struct ice_flow_prof *prof, u16 vsi_handle)
2077 {
2078 	enum ice_status status = ICE_SUCCESS;
2079 
2080 	if (!ice_is_bit_set(prof->vsis, vsi_handle)) {
2081 		if (blk == ICE_BLK_ACL) {
2082 			status = ice_flow_acl_set_xtrct_seq(hw, prof);
2083 			if (status)
2084 				return status;
2085 		}
2086 		status = ice_add_prof_id_flow(hw, blk,
2087 					      ice_get_hw_vsi_num(hw,
2088 								 vsi_handle),
2089 					      prof->id);
2090 		if (!status)
2091 			ice_set_bit(vsi_handle, prof->vsis);
2092 		else
2093 			ice_debug(hw, ICE_DBG_FLOW,
2094 				  "HW profile add failed, %d\n",
2095 				  status);
2096 	}
2097 
2098 	return status;
2099 }
2100 
2101 /**
2102  * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
2103  * @hw: pointer to the hardware structure
2104  * @blk: classification stage
2105  * @prof: pointer to flow profile
2106  * @vsi_handle: software VSI handle
2107  *
2108  * Assumption: the caller has acquired the lock to the profile list
2109  * and the software VSI handle has been validated
2110  */
2111 static enum ice_status
2112 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
2113 		       struct ice_flow_prof *prof, u16 vsi_handle)
2114 {
2115 	enum ice_status status = ICE_SUCCESS;
2116 
2117 	if (ice_is_bit_set(prof->vsis, vsi_handle)) {
2118 		status = ice_rem_prof_id_flow(hw, blk,
2119 					      ice_get_hw_vsi_num(hw,
2120 								 vsi_handle),
2121 					      prof->id);
2122 		if (!status)
2123 			ice_clear_bit(vsi_handle, prof->vsis);
2124 		else
2125 			ice_debug(hw, ICE_DBG_FLOW,
2126 				  "HW profile remove failed, %d\n",
2127 				  status);
2128 	}
2129 
2130 	return status;
2131 }
2132 
2133 /**
2134  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
2135  * @hw: pointer to the HW struct
2136  * @blk: classification stage
2137  * @dir: flow direction
2138  * @prof_id: unique ID to identify this flow profile
2139  * @segs: array of one or more packet segments that describe the flow
2140  * @segs_cnt: number of packet segments provided
2141  * @acts: array of default actions
2142  * @acts_cnt: number of default actions
2143  * @prof: stores the returned flow profile added
2144  */
2145 enum ice_status
2146 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
2147 		  u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
2148 		  struct ice_flow_action *acts, u8 acts_cnt,
2149 		  struct ice_flow_prof **prof)
2150 {
2151 	enum ice_status status;
2152 
2153 	if (segs_cnt > ICE_FLOW_SEG_MAX)
2154 		return ICE_ERR_MAX_LIMIT;
2155 
2156 	if (!segs_cnt)
2157 		return ICE_ERR_PARAM;
2158 
2159 	if (!segs)
2160 		return ICE_ERR_BAD_PTR;
2161 
2162 	status = ice_flow_val_hdrs(segs, segs_cnt);
2163 	if (status)
2164 		return status;
2165 
2166 	ice_acquire_lock(&hw->fl_profs_locks[blk]);
2167 
2168 	status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
2169 					acts, acts_cnt, prof);
2170 	if (!status)
2171 		LIST_ADD(&(*prof)->l_entry, &hw->fl_profs[blk]);
2172 
2173 	ice_release_lock(&hw->fl_profs_locks[blk]);
2174 
2175 	return status;
2176 }
2177 
2178 /**
2179  * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
2180  * @hw: pointer to the HW struct
2181  * @blk: the block for which the flow profile is to be removed
2182  * @prof_id: unique ID of the flow profile to be removed
2183  */
2184 enum ice_status
2185 ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
2186 {
2187 	struct ice_flow_prof *prof;
2188 	enum ice_status status;
2189 
2190 	ice_acquire_lock(&hw->fl_profs_locks[blk]);
2191 
2192 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
2193 	if (!prof) {
2194 		status = ICE_ERR_DOES_NOT_EXIST;
2195 		goto out;
2196 	}
2197 
2198 	/* prof becomes invalid after the call */
2199 	status = ice_flow_rem_prof_sync(hw, blk, prof);
2200 
2201 out:
2202 	ice_release_lock(&hw->fl_profs_locks[blk]);
2203 
2204 	return status;
2205 }
2206 
2207 /**
2208  * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle
2209  * @hw: pointer to the HW struct
2210  * @blk: classification stage
2211  * @prof_id: the profile ID handle
2212  * @hw_prof_id: pointer to variable to receive the HW profile ID
2213  */
2214 enum ice_status
2215 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
2216 		     u8 *hw_prof_id)
2217 {
2218 	enum ice_status status = ICE_ERR_DOES_NOT_EXIST;
2219 	struct ice_prof_map *map;
2220 
2221 	ice_acquire_lock(&hw->blk[blk].es.prof_map_lock);
2222 	map = ice_search_prof_id(hw, blk, prof_id);
2223 	if (map) {
2224 		*hw_prof_id = map->prof_id;
2225 		status = ICE_SUCCESS;
2226 	}
2227 	ice_release_lock(&hw->blk[blk].es.prof_map_lock);
2228 	return status;
2229 }
2230 
2231 /**
2232  * ice_flow_find_entry - look for a flow entry using its unique ID
2233  * @hw: pointer to the HW struct
2234  * @blk: classification stage
2235  * @entry_id: unique ID to identify this flow entry
2236  *
2237  * This function looks for the flow entry with the specified unique ID in all
2238  * flow profiles of the specified classification stage. If the entry is found,
2239  * and it returns the handle to the flow entry. Otherwise, it returns
2240  * ICE_FLOW_ENTRY_ID_INVAL.
2241  */
2242 u64 ice_flow_find_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_id)
2243 {
2244 	struct ice_flow_entry *found = NULL;
2245 	struct ice_flow_prof *p;
2246 
2247 	ice_acquire_lock(&hw->fl_profs_locks[blk]);
2248 
2249 	LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) {
2250 		struct ice_flow_entry *e;
2251 
2252 		ice_acquire_lock(&p->entries_lock);
2253 		LIST_FOR_EACH_ENTRY(e, &p->entries, ice_flow_entry, l_entry)
2254 			if (e->id == entry_id) {
2255 				found = e;
2256 				break;
2257 			}
2258 		ice_release_lock(&p->entries_lock);
2259 
2260 		if (found)
2261 			break;
2262 	}
2263 
2264 	ice_release_lock(&hw->fl_profs_locks[blk]);
2265 
2266 	return found ? ICE_FLOW_ENTRY_HNDL(found) : ICE_FLOW_ENTRY_HANDLE_INVAL;
2267 }
2268 
2269 /**
2270  * ice_flow_acl_check_actions - Checks the ACL rule's actions
2271  * @hw: pointer to the hardware structure
2272  * @acts: array of actions to be performed on a match
2273  * @acts_cnt: number of actions
2274  * @cnt_alloc: indicates if an ACL counter has been allocated.
2275  */
2276 static enum ice_status
2277 ice_flow_acl_check_actions(struct ice_hw *hw, struct ice_flow_action *acts,
2278 			   u8 acts_cnt, bool *cnt_alloc)
2279 {
2280 	ice_declare_bitmap(dup_check, ICE_AQC_TBL_MAX_ACTION_PAIRS * 2);
2281 	int i;
2282 
2283 	ice_zero_bitmap(dup_check, ICE_AQC_TBL_MAX_ACTION_PAIRS * 2);
2284 	*cnt_alloc = false;
2285 
2286 	if (acts_cnt > ICE_FLOW_ACL_MAX_NUM_ACT)
2287 		return ICE_ERR_OUT_OF_RANGE;
2288 
2289 	for (i = 0; i < acts_cnt; i++) {
2290 		if (acts[i].type != ICE_FLOW_ACT_NOP &&
2291 		    acts[i].type != ICE_FLOW_ACT_DROP &&
2292 		    acts[i].type != ICE_FLOW_ACT_CNTR_PKT &&
2293 		    acts[i].type != ICE_FLOW_ACT_FWD_QUEUE)
2294 			return ICE_ERR_CFG;
2295 
2296 		/* If the caller want to add two actions of the same type, then
2297 		 * it is considered invalid configuration.
2298 		 */
2299 		if (ice_test_and_set_bit(acts[i].type, dup_check))
2300 			return ICE_ERR_PARAM;
2301 	}
2302 
2303 	/* Checks if ACL counters are needed. */
2304 	for (i = 0; i < acts_cnt; i++) {
2305 		if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT ||
2306 		    acts[i].type == ICE_FLOW_ACT_CNTR_BYTES ||
2307 		    acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES) {
2308 			struct ice_acl_cntrs cntrs;
2309 			enum ice_status status;
2310 
2311 			cntrs.amount = 1;
2312 			cntrs.bank = 0; /* Only bank0 for the moment */
2313 
2314 			if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES)
2315 				cntrs.type = ICE_AQC_ACL_CNT_TYPE_DUAL;
2316 			else
2317 				cntrs.type = ICE_AQC_ACL_CNT_TYPE_SINGLE;
2318 
2319 			status = ice_aq_alloc_acl_cntrs(hw, &cntrs, NULL);
2320 			if (status)
2321 				return status;
2322 			/* Counter index within the bank */
2323 			acts[i].data.acl_act.value =
2324 						CPU_TO_LE16(cntrs.first_cntr);
2325 			*cnt_alloc = true;
2326 		}
2327 	}
2328 
2329 	return ICE_SUCCESS;
2330 }
2331 
2332 /**
2333  * ice_flow_acl_frmt_entry_range - Format an ACL range checker for a given field
2334  * @fld: number of the given field
2335  * @info: info about field
2336  * @range_buf: range checker configuration buffer
2337  * @data: pointer to a data buffer containing flow entry's match values/masks
2338  * @range: Input/output param indicating which range checkers are being used
2339  */
2340 static void
2341 ice_flow_acl_frmt_entry_range(u16 fld, struct ice_flow_fld_info *info,
2342 			      struct ice_aqc_acl_profile_ranges *range_buf,
2343 			      u8 *data, u8 *range)
2344 {
2345 	u16 new_mask;
2346 
2347 	/* If not specified, default mask is all bits in field */
2348 	new_mask = (info->src.mask == ICE_FLOW_FLD_OFF_INVAL ?
2349 		    BIT(ice_flds_info[fld].size) - 1 :
2350 		    (*(u16 *)(data + info->src.mask))) << info->xtrct.disp;
2351 
2352 	/* If the mask is 0, then we don't need to worry about this input
2353 	 * range checker value.
2354 	 */
2355 	if (new_mask) {
2356 		u16 new_high =
2357 			(*(u16 *)(data + info->src.last)) << info->xtrct.disp;
2358 		u16 new_low =
2359 			(*(u16 *)(data + info->src.val)) << info->xtrct.disp;
2360 		u8 range_idx = info->entry.val;
2361 
2362 		range_buf->checker_cfg[range_idx].low_boundary =
2363 			CPU_TO_BE16(new_low);
2364 		range_buf->checker_cfg[range_idx].high_boundary =
2365 			CPU_TO_BE16(new_high);
2366 		range_buf->checker_cfg[range_idx].mask = CPU_TO_BE16(new_mask);
2367 
2368 		/* Indicate which range checker is being used */
2369 		*range |= BIT(range_idx);
2370 	}
2371 }
2372 
2373 /**
2374  * ice_flow_acl_frmt_entry_fld - Partially format ACL entry for a given field
2375  * @fld: number of the given field
2376  * @info: info about the field
2377  * @buf: buffer containing the entry
2378  * @dontcare: buffer containing don't care mask for entry
2379  * @data: pointer to a data buffer containing flow entry's match values/masks
2380  */
2381 static void
2382 ice_flow_acl_frmt_entry_fld(u16 fld, struct ice_flow_fld_info *info, u8 *buf,
2383 			    u8 *dontcare, u8 *data)
2384 {
2385 	u16 dst, src, mask, k, end_disp, tmp_s = 0, tmp_m = 0;
2386 	bool use_mask = false;
2387 	u8 disp;
2388 
2389 	src = info->src.val;
2390 	mask = info->src.mask;
2391 	dst = info->entry.val - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
2392 	disp = info->xtrct.disp % BITS_PER_BYTE;
2393 
2394 	if (mask != ICE_FLOW_FLD_OFF_INVAL)
2395 		use_mask = true;
2396 
2397 	for (k = 0; k < info->entry.last; k++, dst++) {
2398 		/* Add overflow bits from previous byte */
2399 		buf[dst] = (tmp_s & 0xff00) >> 8;
2400 
2401 		/* If mask is not valid, tmp_m is always zero, so just setting
2402 		 * dontcare to 0 (no masked bits). If mask is valid, pulls in
2403 		 * overflow bits of mask from prev byte
2404 		 */
2405 		dontcare[dst] = (tmp_m & 0xff00) >> 8;
2406 
2407 		/* If there is displacement, last byte will only contain
2408 		 * displaced data, but there is no more data to read from user
2409 		 * buffer, so skip so as not to potentially read beyond end of
2410 		 * user buffer
2411 		 */
2412 		if (!disp || k < info->entry.last - 1) {
2413 			/* Store shifted data to use in next byte */
2414 			tmp_s = data[src++] << disp;
2415 
2416 			/* Add current (shifted) byte */
2417 			buf[dst] |= tmp_s & 0xff;
2418 
2419 			/* Handle mask if valid */
2420 			if (use_mask) {
2421 				tmp_m = (~data[mask++] & 0xff) << disp;
2422 				dontcare[dst] |= tmp_m & 0xff;
2423 			}
2424 		}
2425 	}
2426 
2427 	/* Fill in don't care bits at beginning of field */
2428 	if (disp) {
2429 		dst = info->entry.val - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
2430 		for (k = 0; k < disp; k++)
2431 			dontcare[dst] |= BIT(k);
2432 	}
2433 
2434 	end_disp = (disp + ice_flds_info[fld].size) % BITS_PER_BYTE;
2435 
2436 	/* Fill in don't care bits at end of field */
2437 	if (end_disp) {
2438 		dst = info->entry.val - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX +
2439 		      info->entry.last - 1;
2440 		for (k = end_disp; k < BITS_PER_BYTE; k++)
2441 			dontcare[dst] |= BIT(k);
2442 	}
2443 }
2444 
2445 /**
2446  * ice_flow_acl_frmt_entry - Format ACL entry
2447  * @hw: pointer to the hardware structure
2448  * @prof: pointer to flow profile
2449  * @e: pointer to the flow entry
2450  * @data: pointer to a data buffer containing flow entry's match values/masks
2451  * @acts: array of actions to be performed on a match
2452  * @acts_cnt: number of actions
2453  *
2454  * Formats the key (and key_inverse) to be matched from the data passed in,
2455  * along with data from the flow profile. This key/key_inverse pair makes up
2456  * the 'entry' for an ACL flow entry.
2457  */
2458 static enum ice_status
2459 ice_flow_acl_frmt_entry(struct ice_hw *hw, struct ice_flow_prof *prof,
2460 			struct ice_flow_entry *e, u8 *data,
2461 			struct ice_flow_action *acts, u8 acts_cnt)
2462 {
2463 	u8 *buf = NULL, *dontcare = NULL, *key = NULL, range = 0, dir_flag_msk;
2464 	struct ice_aqc_acl_profile_ranges *range_buf = NULL;
2465 	enum ice_status status;
2466 	bool cnt_alloc;
2467 	u8 prof_id = 0;
2468 	u16 i, buf_sz;
2469 
2470 	status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
2471 	if (status)
2472 		return status;
2473 
2474 	/* Format the result action */
2475 
2476 	status = ice_flow_acl_check_actions(hw, acts, acts_cnt, &cnt_alloc);
2477 	if (status)
2478 		return status;
2479 
2480 	status = ICE_ERR_NO_MEMORY;
2481 
2482 	e->acts = (struct ice_flow_action *)
2483 		ice_memdup(hw, acts, acts_cnt * sizeof(*acts),
2484 			   ICE_NONDMA_TO_NONDMA);
2485 
2486 	if (!e->acts)
2487 		goto out;
2488 
2489 	e->acts_cnt = acts_cnt;
2490 
2491 	/* Format the matching data */
2492 	buf_sz = prof->cfg.scen->width;
2493 	buf = (u8 *)ice_malloc(hw, buf_sz);
2494 	if (!buf)
2495 		goto out;
2496 
2497 	dontcare = (u8 *)ice_malloc(hw, buf_sz);
2498 	if (!dontcare)
2499 		goto out;
2500 
2501 	/* 'key' buffer will store both key and key_inverse, so must be twice
2502 	 * size of buf
2503 	 */
2504 	key = (u8 *)ice_malloc(hw, buf_sz * 2);
2505 	if (!key)
2506 		goto out;
2507 
2508 	range_buf = (struct ice_aqc_acl_profile_ranges *)
2509 		ice_malloc(hw, sizeof(struct ice_aqc_acl_profile_ranges));
2510 	if (!range_buf)
2511 		goto out;
2512 
2513 	/* Set don't care mask to all 1's to start, will zero out used bytes */
2514 	ice_memset(dontcare, 0xff, buf_sz, ICE_NONDMA_MEM);
2515 
2516 	for (i = 0; i < prof->segs_cnt; i++) {
2517 		struct ice_flow_seg_info *seg = &prof->segs[i];
2518 		u64 match = seg->match;
2519 		u16 j;
2520 
2521 		for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) {
2522 			struct ice_flow_fld_info *info;
2523 			const u64 bit = BIT_ULL(j);
2524 
2525 			if (!(match & bit))
2526 				continue;
2527 
2528 			info = &seg->fields[j];
2529 
2530 			if (info->type == ICE_FLOW_FLD_TYPE_RANGE)
2531 				ice_flow_acl_frmt_entry_range(j, info,
2532 							      range_buf, data,
2533 							      &range);
2534 			else
2535 				ice_flow_acl_frmt_entry_fld(j, info, buf,
2536 							    dontcare, data);
2537 
2538 			match &= ~bit;
2539 		}
2540 
2541 		for (j = 0; j < seg->raws_cnt; j++) {
2542 			struct ice_flow_fld_info *info = &seg->raws[j].info;
2543 			u16 dst, src, mask, k;
2544 			bool use_mask = false;
2545 
2546 			src = info->src.val;
2547 			dst = info->entry.val -
2548 					ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
2549 			mask = info->src.mask;
2550 
2551 			if (mask != ICE_FLOW_FLD_OFF_INVAL)
2552 				use_mask = true;
2553 
2554 			for (k = 0; k < info->entry.last; k++, dst++) {
2555 				buf[dst] = data[src++];
2556 				if (use_mask)
2557 					dontcare[dst] = ~data[mask++];
2558 				else
2559 					dontcare[dst] = 0;
2560 			}
2561 		}
2562 	}
2563 
2564 	buf[prof->cfg.scen->pid_idx] = (u8)prof_id;
2565 	dontcare[prof->cfg.scen->pid_idx] = 0;
2566 
2567 	/* Format the buffer for direction flags */
2568 	dir_flag_msk = BIT(ICE_FLG_PKT_DIR);
2569 
2570 	if (prof->dir == ICE_FLOW_RX)
2571 		buf[prof->cfg.scen->pkt_dir_idx] = dir_flag_msk;
2572 
2573 	if (range) {
2574 		buf[prof->cfg.scen->rng_chk_idx] = range;
2575 		/* Mark any unused range checkers as don't care */
2576 		dontcare[prof->cfg.scen->rng_chk_idx] = ~range;
2577 		e->range_buf = range_buf;
2578 	} else {
2579 		ice_free(hw, range_buf);
2580 	}
2581 
2582 	status = ice_set_key(key, buf_sz * 2, buf, NULL, dontcare, NULL, 0,
2583 			     buf_sz);
2584 	if (status)
2585 		goto out;
2586 
2587 	e->entry = key;
2588 	e->entry_sz = buf_sz * 2;
2589 
2590 out:
2591 	if (buf)
2592 		ice_free(hw, buf);
2593 
2594 	if (dontcare)
2595 		ice_free(hw, dontcare);
2596 
2597 	if (status && key)
2598 		ice_free(hw, key);
2599 
2600 	if (status && range_buf) {
2601 		ice_free(hw, range_buf);
2602 		e->range_buf = NULL;
2603 	}
2604 
2605 	if (status && e->acts) {
2606 		ice_free(hw, e->acts);
2607 		e->acts = NULL;
2608 		e->acts_cnt = 0;
2609 	}
2610 
2611 	if (status && cnt_alloc)
2612 		ice_flow_acl_free_act_cntr(hw, acts, acts_cnt);
2613 
2614 	return status;
2615 }
2616 
2617 /**
2618  * ice_flow_acl_find_scen_entry_cond - Find an ACL scenario entry that matches
2619  *				       the compared data.
2620  * @prof: pointer to flow profile
2621  * @e: pointer to the comparing flow entry
2622  * @do_chg_action: decide if we want to change the ACL action
2623  * @do_add_entry: decide if we want to add the new ACL entry
2624  * @do_rem_entry: decide if we want to remove the current ACL entry
2625  *
2626  * Find an ACL scenario entry that matches the compared data. In the same time,
2627  * this function also figure out:
2628  * a/ If we want to change the ACL action
2629  * b/ If we want to add the new ACL entry
2630  * c/ If we want to remove the current ACL entry
2631  */
2632 static struct ice_flow_entry *
2633 ice_flow_acl_find_scen_entry_cond(struct ice_flow_prof *prof,
2634 				  struct ice_flow_entry *e, bool *do_chg_action,
2635 				  bool *do_add_entry, bool *do_rem_entry)
2636 {
2637 	struct ice_flow_entry *p, *return_entry = NULL;
2638 	u8 i, j;
2639 
2640 	/* Check if:
2641 	 * a/ There exists an entry with same matching data, but different
2642 	 *    priority, then we remove this existing ACL entry. Then, we
2643 	 *    will add the new entry to the ACL scenario.
2644 	 * b/ There exists an entry with same matching data, priority, and
2645 	 *    result action, then we do nothing
2646 	 * c/ There exists an entry with same matching data, priority, but
2647 	 *    different, action, then do only change the action's entry.
2648 	 * d/ Else, we add this new entry to the ACL scenario.
2649 	 */
2650 	*do_chg_action = false;
2651 	*do_add_entry = true;
2652 	*do_rem_entry = false;
2653 	LIST_FOR_EACH_ENTRY(p, &prof->entries, ice_flow_entry, l_entry) {
2654 		if (memcmp(p->entry, e->entry, p->entry_sz))
2655 			continue;
2656 
2657 		/* From this point, we have the same matching_data. */
2658 		*do_add_entry = false;
2659 		return_entry = p;
2660 
2661 		if (p->priority != e->priority) {
2662 			/* matching data && !priority */
2663 			*do_add_entry = true;
2664 			*do_rem_entry = true;
2665 			break;
2666 		}
2667 
2668 		/* From this point, we will have matching_data && priority */
2669 		if (p->acts_cnt != e->acts_cnt)
2670 			*do_chg_action = true;
2671 		for (i = 0; i < p->acts_cnt; i++) {
2672 			bool found_not_match = false;
2673 
2674 			for (j = 0; j < e->acts_cnt; j++)
2675 				if (memcmp(&p->acts[i], &e->acts[j],
2676 					   sizeof(struct ice_flow_action))) {
2677 					found_not_match = true;
2678 					break;
2679 				}
2680 
2681 			if (found_not_match) {
2682 				*do_chg_action = true;
2683 				break;
2684 			}
2685 		}
2686 
2687 		/* (do_chg_action = true) means :
2688 		 *    matching_data && priority && !result_action
2689 		 * (do_chg_action = false) means :
2690 		 *    matching_data && priority && result_action
2691 		 */
2692 		break;
2693 	}
2694 
2695 	return return_entry;
2696 }
2697 
2698 /**
2699  * ice_flow_acl_convert_to_acl_prior - Convert to ACL priority
2700  * @p: flow priority
2701  */
2702 static enum ice_acl_entry_prior
2703 ice_flow_acl_convert_to_acl_prior(enum ice_flow_priority p)
2704 {
2705 	enum ice_acl_entry_prior acl_prior;
2706 
2707 	switch (p) {
2708 	case ICE_FLOW_PRIO_LOW:
2709 		acl_prior = ICE_LOW;
2710 		break;
2711 	case ICE_FLOW_PRIO_NORMAL:
2712 		acl_prior = ICE_NORMAL;
2713 		break;
2714 	case ICE_FLOW_PRIO_HIGH:
2715 		acl_prior = ICE_HIGH;
2716 		break;
2717 	default:
2718 		acl_prior = ICE_NORMAL;
2719 		break;
2720 	}
2721 
2722 	return acl_prior;
2723 }
2724 
2725 /**
2726  * ice_flow_acl_union_rng_chk - Perform union operation between two
2727  *                              range-range checker buffers
2728  * @dst_buf: pointer to destination range checker buffer
2729  * @src_buf: pointer to source range checker buffer
2730  *
2731  * For this function, we do the union between dst_buf and src_buf
2732  * range checker buffer, and we will save the result back to dst_buf
2733  */
2734 static enum ice_status
2735 ice_flow_acl_union_rng_chk(struct ice_aqc_acl_profile_ranges *dst_buf,
2736 			   struct ice_aqc_acl_profile_ranges *src_buf)
2737 {
2738 	u8 i, j;
2739 
2740 	if (!dst_buf || !src_buf)
2741 		return ICE_ERR_BAD_PTR;
2742 
2743 	for (i = 0; i < ICE_AQC_ACL_PROF_RANGES_NUM_CFG; i++) {
2744 		struct ice_acl_rng_data *cfg_data = NULL, *in_data;
2745 		bool will_populate = false;
2746 
2747 		in_data = &src_buf->checker_cfg[i];
2748 
2749 		if (!in_data->mask)
2750 			break;
2751 
2752 		for (j = 0; j < ICE_AQC_ACL_PROF_RANGES_NUM_CFG; j++) {
2753 			cfg_data = &dst_buf->checker_cfg[j];
2754 
2755 			if (!cfg_data->mask ||
2756 			    !memcmp(cfg_data, in_data,
2757 				    sizeof(struct ice_acl_rng_data))) {
2758 				will_populate = true;
2759 				break;
2760 			}
2761 		}
2762 
2763 		if (will_populate) {
2764 			ice_memcpy(cfg_data, in_data,
2765 				   sizeof(struct ice_acl_rng_data),
2766 				   ICE_NONDMA_TO_NONDMA);
2767 		} else {
2768 			/* No available slot left to program range checker */
2769 			return ICE_ERR_MAX_LIMIT;
2770 		}
2771 	}
2772 
2773 	return ICE_SUCCESS;
2774 }
2775 
2776 /**
2777  * ice_flow_acl_add_scen_entry_sync - Add entry to ACL scenario sync
2778  * @hw: pointer to the hardware structure
2779  * @prof: pointer to flow profile
2780  * @entry: double pointer to the flow entry
2781  *
2782  * For this function, we will look at the current added entries in the
2783  * corresponding ACL scenario. Then, we will perform matching logic to
2784  * see if we want to add/modify/do nothing with this new entry.
2785  */
2786 static enum ice_status
2787 ice_flow_acl_add_scen_entry_sync(struct ice_hw *hw, struct ice_flow_prof *prof,
2788 				 struct ice_flow_entry **entry)
2789 {
2790 	bool do_add_entry, do_rem_entry, do_chg_action, do_chg_rng_chk;
2791 	struct ice_aqc_acl_profile_ranges query_rng_buf, cfg_rng_buf;
2792 	struct ice_acl_act_entry *acts = NULL;
2793 	struct ice_flow_entry *exist;
2794 	enum ice_status status = ICE_SUCCESS;
2795 	struct ice_flow_entry *e;
2796 	u8 i;
2797 
2798 	if (!entry || !(*entry) || !prof)
2799 		return ICE_ERR_BAD_PTR;
2800 
2801 	e = *(entry);
2802 
2803 	do_chg_rng_chk = false;
2804 	if (e->range_buf) {
2805 		u8 prof_id = 0;
2806 
2807 		status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id,
2808 					      &prof_id);
2809 		if (status)
2810 			return status;
2811 
2812 		/* Query the current range-checker value in FW */
2813 		status = ice_query_acl_prof_ranges(hw, prof_id, &query_rng_buf,
2814 						   NULL);
2815 		if (status)
2816 			return status;
2817 		ice_memcpy(&cfg_rng_buf, &query_rng_buf,
2818 			   sizeof(struct ice_aqc_acl_profile_ranges),
2819 			   ICE_NONDMA_TO_NONDMA);
2820 
2821 		/* Generate the new range-checker value */
2822 		status = ice_flow_acl_union_rng_chk(&cfg_rng_buf, e->range_buf);
2823 		if (status)
2824 			return status;
2825 
2826 		/* Reconfigure the range check if the buffer is changed. */
2827 		do_chg_rng_chk = false;
2828 		if (memcmp(&query_rng_buf, &cfg_rng_buf,
2829 			   sizeof(struct ice_aqc_acl_profile_ranges))) {
2830 			status = ice_prog_acl_prof_ranges(hw, prof_id,
2831 							  &cfg_rng_buf, NULL);
2832 			if (status)
2833 				return status;
2834 
2835 			do_chg_rng_chk = true;
2836 		}
2837 	}
2838 
2839 	/* Figure out if we want to (change the ACL action) and/or
2840 	 * (Add the new ACL entry) and/or (Remove the current ACL entry)
2841 	 */
2842 	exist = ice_flow_acl_find_scen_entry_cond(prof, e, &do_chg_action,
2843 						  &do_add_entry, &do_rem_entry);
2844 
2845 	if (do_rem_entry) {
2846 		status = ice_flow_rem_entry_sync(hw, ICE_BLK_ACL, exist);
2847 		if (status)
2848 			return status;
2849 	}
2850 
2851 	/* Prepare the result action buffer */
2852 	acts = (struct ice_acl_act_entry *)ice_calloc
2853 		(hw, e->entry_sz, sizeof(struct ice_acl_act_entry));
2854 	for (i = 0; i < e->acts_cnt; i++)
2855 		ice_memcpy(&acts[i], &e->acts[i].data.acl_act,
2856 			   sizeof(struct ice_acl_act_entry),
2857 			   ICE_NONDMA_TO_NONDMA);
2858 
2859 	if (do_add_entry) {
2860 		enum ice_acl_entry_prior prior;
2861 		u8 *keys, *inverts;
2862 		u16 entry_idx;
2863 
2864 		keys = (u8 *)e->entry;
2865 		inverts = keys + (e->entry_sz / 2);
2866 		prior = ice_flow_acl_convert_to_acl_prior(e->priority);
2867 
2868 		status = ice_acl_add_entry(hw, prof->cfg.scen, prior, keys,
2869 					   inverts, acts, e->acts_cnt,
2870 					   &entry_idx);
2871 		if (status)
2872 			goto out;
2873 
2874 		e->scen_entry_idx = entry_idx;
2875 		LIST_ADD(&e->l_entry, &prof->entries);
2876 	} else {
2877 		if (do_chg_action) {
2878 			/* For the action memory info, update the SW's copy of
2879 			 * exist entry with e's action memory info
2880 			 */
2881 			ice_free(hw, exist->acts);
2882 			exist->acts_cnt = e->acts_cnt;
2883 			exist->acts = (struct ice_flow_action *)
2884 				ice_calloc(hw, exist->acts_cnt,
2885 					   sizeof(struct ice_flow_action));
2886 
2887 			if (!exist->acts) {
2888 				status = ICE_ERR_NO_MEMORY;
2889 				goto out;
2890 			}
2891 
2892 			ice_memcpy(exist->acts, e->acts,
2893 				   sizeof(struct ice_flow_action) * e->acts_cnt,
2894 				   ICE_NONDMA_TO_NONDMA);
2895 
2896 			status = ice_acl_prog_act(hw, prof->cfg.scen, acts,
2897 						  e->acts_cnt,
2898 						  exist->scen_entry_idx);
2899 			if (status)
2900 				goto out;
2901 		}
2902 
2903 		if (do_chg_rng_chk) {
2904 			/* In this case, we want to update the range checker
2905 			 * information of the exist entry
2906 			 */
2907 			status = ice_flow_acl_union_rng_chk(exist->range_buf,
2908 							    e->range_buf);
2909 			if (status)
2910 				goto out;
2911 		}
2912 
2913 		/* As we don't add the new entry to our SW DB, deallocate its
2914 		 * memories, and return the exist entry to the caller
2915 		 */
2916 		ice_dealloc_flow_entry(hw, e);
2917 		*(entry) = exist;
2918 	}
2919 out:
2920 	if (acts)
2921 		ice_free(hw, acts);
2922 
2923 	return status;
2924 }
2925 
2926 /**
2927  * ice_flow_acl_add_scen_entry - Add entry to ACL scenario
2928  * @hw: pointer to the hardware structure
2929  * @prof: pointer to flow profile
2930  * @e: double pointer to the flow entry
2931  */
2932 static enum ice_status
2933 ice_flow_acl_add_scen_entry(struct ice_hw *hw, struct ice_flow_prof *prof,
2934 			    struct ice_flow_entry **e)
2935 {
2936 	enum ice_status status;
2937 
2938 	ice_acquire_lock(&prof->entries_lock);
2939 	status = ice_flow_acl_add_scen_entry_sync(hw, prof, e);
2940 	ice_release_lock(&prof->entries_lock);
2941 
2942 	return status;
2943 }
2944 
2945 /**
2946  * ice_flow_add_entry - Add a flow entry
2947  * @hw: pointer to the HW struct
2948  * @blk: classification stage
2949  * @prof_id: ID of the profile to add a new flow entry to
2950  * @entry_id: unique ID to identify this flow entry
2951  * @vsi_handle: software VSI handle for the flow entry
2952  * @prio: priority of the flow entry
2953  * @data: pointer to a data buffer containing flow entry's match values/masks
2954  * @acts: arrays of actions to be performed on a match
2955  * @acts_cnt: number of actions
2956  * @entry_h: pointer to buffer that receives the new flow entry's handle
2957  */
2958 enum ice_status
2959 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
2960 		   u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
2961 		   void *data, struct ice_flow_action *acts, u8 acts_cnt,
2962 		   u64 *entry_h)
2963 {
2964 	struct ice_flow_entry *e = NULL;
2965 	struct ice_flow_prof *prof;
2966 	enum ice_status status = ICE_SUCCESS;
2967 
2968 	/* ACL entries must indicate an action */
2969 	if (blk == ICE_BLK_ACL && (!acts || !acts_cnt))
2970 		return ICE_ERR_PARAM;
2971 
2972 	/* No flow entry data is expected for RSS */
2973 	if (!entry_h || (!data && blk != ICE_BLK_RSS))
2974 		return ICE_ERR_BAD_PTR;
2975 
2976 	if (!ice_is_vsi_valid(hw, vsi_handle))
2977 		return ICE_ERR_PARAM;
2978 
2979 	ice_acquire_lock(&hw->fl_profs_locks[blk]);
2980 
2981 	prof = ice_flow_find_prof_id(hw, blk, prof_id);
2982 	if (!prof) {
2983 		status = ICE_ERR_DOES_NOT_EXIST;
2984 	} else {
2985 		/* Allocate memory for the entry being added and associate
2986 		 * the VSI to the found flow profile
2987 		 */
2988 		e = (struct ice_flow_entry *)ice_malloc(hw, sizeof(*e));
2989 		if (!e)
2990 			status = ICE_ERR_NO_MEMORY;
2991 		else
2992 			status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2993 	}
2994 
2995 	ice_release_lock(&hw->fl_profs_locks[blk]);
2996 	if (status)
2997 		goto out;
2998 
2999 	e->id = entry_id;
3000 	e->vsi_handle = vsi_handle;
3001 	e->prof = prof;
3002 	e->priority = prio;
3003 
3004 	switch (blk) {
3005 	case ICE_BLK_FD:
3006 	case ICE_BLK_RSS:
3007 		break;
3008 	case ICE_BLK_ACL:
3009 		/* ACL will handle the entry management */
3010 		status = ice_flow_acl_frmt_entry(hw, prof, e, (u8 *)data, acts,
3011 						 acts_cnt);
3012 		if (status)
3013 			goto out;
3014 
3015 		status = ice_flow_acl_add_scen_entry(hw, prof, &e);
3016 		if (status)
3017 			goto out;
3018 
3019 		break;
3020 	default:
3021 		status = ICE_ERR_NOT_IMPL;
3022 		goto out;
3023 	}
3024 
3025 	if (blk != ICE_BLK_ACL) {
3026 		/* ACL will handle the entry management */
3027 		ice_acquire_lock(&prof->entries_lock);
3028 		LIST_ADD(&e->l_entry, &prof->entries);
3029 		ice_release_lock(&prof->entries_lock);
3030 	}
3031 
3032 	*entry_h = ICE_FLOW_ENTRY_HNDL(e);
3033 
3034 out:
3035 	if (status && e) {
3036 		if (e->entry)
3037 			ice_free(hw, e->entry);
3038 		ice_free(hw, e);
3039 	}
3040 
3041 	return status;
3042 }
3043 
3044 /**
3045  * ice_flow_rem_entry - Remove a flow entry
3046  * @hw: pointer to the HW struct
3047  * @blk: classification stage
3048  * @entry_h: handle to the flow entry to be removed
3049  */
3050 enum ice_status ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk,
3051 				   u64 entry_h)
3052 {
3053 	struct ice_flow_entry *entry;
3054 	struct ice_flow_prof *prof;
3055 	enum ice_status status = ICE_SUCCESS;
3056 
3057 	if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
3058 		return ICE_ERR_PARAM;
3059 
3060 	entry = ICE_FLOW_ENTRY_PTR((unsigned long)entry_h);
3061 
3062 	/* Retain the pointer to the flow profile as the entry will be freed */
3063 	prof = entry->prof;
3064 
3065 	if (prof) {
3066 		ice_acquire_lock(&prof->entries_lock);
3067 		status = ice_flow_rem_entry_sync(hw, blk, entry);
3068 		ice_release_lock(&prof->entries_lock);
3069 	}
3070 
3071 	return status;
3072 }
3073 
3074 /**
3075  * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
3076  * @seg: packet segment the field being set belongs to
3077  * @fld: field to be set
3078  * @field_type: type of the field
3079  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
3080  *           entry's input buffer
3081  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
3082  *            input buffer
3083  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
3084  *            entry's input buffer
3085  *
3086  * This helper function stores information of a field being matched, including
3087  * the type of the field and the locations of the value to match, the mask, and
3088  * and the upper-bound value in the start of the input buffer for a flow entry.
3089  * This function should only be used for fixed-size data structures.
3090  *
3091  * This function also opportunistically determines the protocol headers to be
3092  * present based on the fields being set. Some fields cannot be used alone to
3093  * determine the protocol headers present. Sometimes, fields for particular
3094  * protocol headers are not matched. In those cases, the protocol headers
3095  * must be explicitly set.
3096  */
3097 static void
3098 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
3099 		     enum ice_flow_fld_match_type field_type, u16 val_loc,
3100 		     u16 mask_loc, u16 last_loc)
3101 {
3102 	u64 bit = BIT_ULL(fld);
3103 
3104 	seg->match |= bit;
3105 	if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
3106 		seg->range |= bit;
3107 
3108 	seg->fields[fld].type = field_type;
3109 	seg->fields[fld].src.val = val_loc;
3110 	seg->fields[fld].src.mask = mask_loc;
3111 	seg->fields[fld].src.last = last_loc;
3112 
3113 	ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
3114 }
3115 
3116 /**
3117  * ice_flow_set_fld - specifies locations of field from entry's input buffer
3118  * @seg: packet segment the field being set belongs to
3119  * @fld: field to be set
3120  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
3121  *           entry's input buffer
3122  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
3123  *            input buffer
3124  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
3125  *            entry's input buffer
3126  * @range: indicate if field being matched is to be in a range
3127  *
3128  * This function specifies the locations, in the form of byte offsets from the
3129  * start of the input buffer for a flow entry, from where the value to match,
3130  * the mask value, and upper value can be extracted. These locations are then
3131  * stored in the flow profile. When adding a flow entry associated with the
3132  * flow profile, these locations will be used to quickly extract the values and
3133  * create the content of a match entry. This function should only be used for
3134  * fixed-size data structures.
3135  */
3136 void
3137 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
3138 		 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
3139 {
3140 	enum ice_flow_fld_match_type t = range ?
3141 		ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
3142 
3143 	ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
3144 }
3145 
3146 /**
3147  * ice_flow_set_fld_prefix - sets locations of prefix field from entry's buf
3148  * @seg: packet segment the field being set belongs to
3149  * @fld: field to be set
3150  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
3151  *           entry's input buffer
3152  * @pref_loc: location of prefix value from entry's input buffer
3153  * @pref_sz: size of the location holding the prefix value
3154  *
3155  * This function specifies the locations, in the form of byte offsets from the
3156  * start of the input buffer for a flow entry, from where the value to match
3157  * and the IPv4 prefix value can be extracted. These locations are then stored
3158  * in the flow profile. When adding flow entries to the associated flow profile,
3159  * these locations can be used to quickly extract the values to create the
3160  * content of a match entry. This function should only be used for fixed-size
3161  * data structures.
3162  */
3163 void
3164 ice_flow_set_fld_prefix(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
3165 			u16 val_loc, u16 pref_loc, u8 pref_sz)
3166 {
3167 	/* For this type of field, the "mask" location is for the prefix value's
3168 	 * location and the "last" location is for the size of the location of
3169 	 * the prefix value.
3170 	 */
3171 	ice_flow_set_fld_ext(seg, fld, ICE_FLOW_FLD_TYPE_PREFIX, val_loc,
3172 			     pref_loc, (u16)pref_sz);
3173 }
3174 
3175 /**
3176  * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
3177  * @seg: packet segment the field being set belongs to
3178  * @off: offset of the raw field from the beginning of the segment in bytes
3179  * @len: length of the raw pattern to be matched
3180  * @val_loc: location of the value to match from entry's input buffer
3181  * @mask_loc: location of mask value from entry's input buffer
3182  *
3183  * This function specifies the offset of the raw field to be match from the
3184  * beginning of the specified packet segment, and the locations, in the form of
3185  * byte offsets from the start of the input buffer for a flow entry, from where
3186  * the value to match and the mask value to be extracted. These locations are
3187  * then stored in the flow profile. When adding flow entries to the associated
3188  * flow profile, these locations can be used to quickly extract the values to
3189  * create the content of a match entry. This function should only be used for
3190  * fixed-size data structures.
3191  */
3192 void
3193 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
3194 		     u16 val_loc, u16 mask_loc)
3195 {
3196 	if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
3197 		seg->raws[seg->raws_cnt].off = off;
3198 		seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
3199 		seg->raws[seg->raws_cnt].info.src.val = val_loc;
3200 		seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
3201 		/* The "last" field is used to store the length of the field */
3202 		seg->raws[seg->raws_cnt].info.src.last = len;
3203 	}
3204 
3205 	/* Overflows of "raws" will be handled as an error condition later in
3206 	 * the flow when this information is processed.
3207 	 */
3208 	seg->raws_cnt++;
3209 }
3210 
3211 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
3212 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
3213 
3214 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
3215 	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
3216 
3217 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
3218 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
3219 	 ICE_FLOW_SEG_HDR_SCTP)
3220 
3221 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
3222 	(ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
3223 	 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
3224 	 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
3225 
3226 /**
3227  * ice_flow_set_rss_seg_info - setup packet segments for RSS
3228  * @segs: pointer to the flow field segment(s)
3229  * @hash_fields: fields to be hashed on for the segment(s)
3230  * @flow_hdr: protocol header fields within a packet segment
3231  *
3232  * Helper function to extract fields from hash bitmap and use flow
3233  * header value to set flow field segment for further use in flow
3234  * profile entry or removal.
3235  */
3236 static enum ice_status
3237 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
3238 			  u32 flow_hdr)
3239 {
3240 	u64 val = hash_fields;
3241 	u8 i;
3242 
3243 	for (i = 0; val && i < ICE_FLOW_FIELD_IDX_MAX; i++) {
3244 		u64 bit = BIT_ULL(i);
3245 
3246 		if (val & bit) {
3247 			ice_flow_set_fld(segs, (enum ice_flow_field)i,
3248 					 ICE_FLOW_FLD_OFF_INVAL,
3249 					 ICE_FLOW_FLD_OFF_INVAL,
3250 					 ICE_FLOW_FLD_OFF_INVAL, false);
3251 			val &= ~bit;
3252 		}
3253 	}
3254 	ICE_FLOW_SET_HDRS(segs, flow_hdr);
3255 
3256 	if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
3257 	    ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
3258 		return ICE_ERR_PARAM;
3259 
3260 	val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
3261 	if (val && !ice_is_pow2(val))
3262 		return ICE_ERR_CFG;
3263 
3264 	val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
3265 	if (val && !ice_is_pow2(val))
3266 		return ICE_ERR_CFG;
3267 
3268 	return ICE_SUCCESS;
3269 }
3270 
3271 /**
3272  * ice_rem_vsi_rss_list - remove VSI from RSS list
3273  * @hw: pointer to the hardware structure
3274  * @vsi_handle: software VSI handle
3275  *
3276  * Remove the VSI from all RSS configurations in the list.
3277  */
3278 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
3279 {
3280 	struct ice_rss_cfg *r, *tmp;
3281 
3282 	if (LIST_EMPTY(&hw->rss_list_head))
3283 		return;
3284 
3285 	ice_acquire_lock(&hw->rss_locks);
3286 	LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
3287 				 ice_rss_cfg, l_entry)
3288 		if (ice_test_and_clear_bit(vsi_handle, r->vsis))
3289 			if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
3290 				LIST_DEL(&r->l_entry);
3291 				ice_free(hw, r);
3292 			}
3293 	ice_release_lock(&hw->rss_locks);
3294 }
3295 
3296 /**
3297  * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
3298  * @hw: pointer to the hardware structure
3299  * @vsi_handle: software VSI handle
3300  *
3301  * This function will iterate through all flow profiles and disassociate
3302  * the VSI from that profile. If the flow profile has no VSIs it will
3303  * be removed.
3304  */
3305 enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
3306 {
3307 	const enum ice_block blk = ICE_BLK_RSS;
3308 	struct ice_flow_prof *p, *t;
3309 	enum ice_status status = ICE_SUCCESS;
3310 
3311 	if (!ice_is_vsi_valid(hw, vsi_handle))
3312 		return ICE_ERR_PARAM;
3313 
3314 	if (LIST_EMPTY(&hw->fl_profs[blk]))
3315 		return ICE_SUCCESS;
3316 
3317 	ice_acquire_lock(&hw->rss_locks);
3318 	LIST_FOR_EACH_ENTRY_SAFE(p, t, &hw->fl_profs[blk], ice_flow_prof,
3319 				 l_entry)
3320 		if (ice_is_bit_set(p->vsis, vsi_handle)) {
3321 			status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
3322 			if (status)
3323 				break;
3324 
3325 			if (!ice_is_any_bit_set(p->vsis, ICE_MAX_VSI)) {
3326 				status = ice_flow_rem_prof(hw, blk, p->id);
3327 				if (status)
3328 					break;
3329 			}
3330 		}
3331 	ice_release_lock(&hw->rss_locks);
3332 
3333 	return status;
3334 }
3335 
3336 /**
3337  * ice_rem_rss_list - remove RSS configuration from list
3338  * @hw: pointer to the hardware structure
3339  * @vsi_handle: software VSI handle
3340  * @prof: pointer to flow profile
3341  *
3342  * Assumption: lock has already been acquired for RSS list
3343  */
3344 static void
3345 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
3346 {
3347 	struct ice_rss_cfg *r, *tmp;
3348 
3349 	/* Search for RSS hash fields associated to the VSI that match the
3350 	 * hash configurations associated to the flow profile. If found
3351 	 * remove from the RSS entry list of the VSI context and delete entry.
3352 	 */
3353 	LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
3354 				 ice_rss_cfg, l_entry)
3355 		if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
3356 		    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
3357 			ice_clear_bit(vsi_handle, r->vsis);
3358 			if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
3359 				LIST_DEL(&r->l_entry);
3360 				ice_free(hw, r);
3361 			}
3362 			return;
3363 		}
3364 }
3365 
3366 /**
3367  * ice_add_rss_list - add RSS configuration to list
3368  * @hw: pointer to the hardware structure
3369  * @vsi_handle: software VSI handle
3370  * @prof: pointer to flow profile
3371  *
3372  * Assumption: lock has already been acquired for RSS list
3373  */
3374 static enum ice_status
3375 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
3376 {
3377 	struct ice_rss_cfg *r, *rss_cfg;
3378 
3379 	LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
3380 			    ice_rss_cfg, l_entry)
3381 		if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
3382 		    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
3383 			ice_set_bit(vsi_handle, r->vsis);
3384 			return ICE_SUCCESS;
3385 		}
3386 
3387 	rss_cfg = (struct ice_rss_cfg *)ice_malloc(hw, sizeof(*rss_cfg));
3388 	if (!rss_cfg)
3389 		return ICE_ERR_NO_MEMORY;
3390 
3391 	rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
3392 	rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
3393 	rss_cfg->symm = prof->cfg.symm;
3394 	ice_set_bit(vsi_handle, rss_cfg->vsis);
3395 
3396 	LIST_ADD_TAIL(&rss_cfg->l_entry, &hw->rss_list_head);
3397 
3398 	return ICE_SUCCESS;
3399 }
3400 
3401 #define ICE_FLOW_PROF_HASH_S	0
3402 #define ICE_FLOW_PROF_HASH_M	(0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
3403 #define ICE_FLOW_PROF_HDR_S	32
3404 #define ICE_FLOW_PROF_HDR_M	(0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
3405 #define ICE_FLOW_PROF_ENCAP_S	63
3406 #define ICE_FLOW_PROF_ENCAP_M	(BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
3407 
3408 #define ICE_RSS_OUTER_HEADERS	1
3409 #define ICE_RSS_INNER_HEADERS	2
3410 
3411 /* Flow profile ID format:
3412  * [0:31] - Packet match fields
3413  * [32:62] - Protocol header
3414  * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
3415  */
3416 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
3417 	(u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
3418 	      (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
3419 	      ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0))
3420 
3421 static void
3422 ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst)
3423 {
3424 	u32 s = ((src % 4) << 3); /* byte shift */
3425 	u32 v = dst | 0x80; /* value to program */
3426 	u8 i = src / 4; /* register index */
3427 	u32 reg;
3428 
3429 	reg = rd32(hw, GLQF_HSYMM(prof_id, i));
3430 	reg = (reg & ~(0xff << s)) | (v << s);
3431 	wr32(hw, GLQF_HSYMM(prof_id, i), reg);
3432 }
3433 
3434 static void
3435 ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len)
3436 {
3437 	int fv_last_word =
3438 		ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1;
3439 	int i;
3440 
3441 	for (i = 0; i < len; i++) {
3442 		ice_rss_config_xor_word(hw, prof_id,
3443 					/* Yes, field vector in GLQF_HSYMM and
3444 					 * GLQF_HINSET is inversed!
3445 					 */
3446 					fv_last_word - (src + i),
3447 					fv_last_word - (dst + i));
3448 		ice_rss_config_xor_word(hw, prof_id,
3449 					fv_last_word - (dst + i),
3450 					fv_last_word - (src + i));
3451 	}
3452 }
3453 
3454 static void
3455 ice_rss_update_symm(struct ice_hw *hw,
3456 		    struct ice_flow_prof *prof)
3457 {
3458 	struct ice_prof_map *map;
3459 	u8 prof_id, m;
3460 
3461 	ice_acquire_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
3462 	map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id);
3463 	if (map)
3464 		prof_id = map->prof_id;
3465 	ice_release_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
3466 	if (!map)
3467 		return;
3468 	/* clear to default */
3469 	for (m = 0; m < 6; m++)
3470 		wr32(hw, GLQF_HSYMM(prof_id, m), 0);
3471 	if (prof->cfg.symm) {
3472 		struct ice_flow_seg_info *seg =
3473 			&prof->segs[prof->segs_cnt - 1];
3474 
3475 		struct ice_flow_seg_xtrct *ipv4_src =
3476 			&seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct;
3477 		struct ice_flow_seg_xtrct *ipv4_dst =
3478 			&seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct;
3479 		struct ice_flow_seg_xtrct *ipv6_src =
3480 			&seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct;
3481 		struct ice_flow_seg_xtrct *ipv6_dst =
3482 			&seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct;
3483 
3484 		struct ice_flow_seg_xtrct *tcp_src =
3485 			&seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct;
3486 		struct ice_flow_seg_xtrct *tcp_dst =
3487 			&seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct;
3488 
3489 		struct ice_flow_seg_xtrct *udp_src =
3490 			&seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct;
3491 		struct ice_flow_seg_xtrct *udp_dst =
3492 			&seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct;
3493 
3494 		struct ice_flow_seg_xtrct *sctp_src =
3495 			&seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct;
3496 		struct ice_flow_seg_xtrct *sctp_dst =
3497 			&seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct;
3498 
3499 		/* xor IPv4 */
3500 		if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0)
3501 			ice_rss_config_xor(hw, prof_id,
3502 					   ipv4_src->idx, ipv4_dst->idx, 2);
3503 
3504 		/* xor IPv6 */
3505 		if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0)
3506 			ice_rss_config_xor(hw, prof_id,
3507 					   ipv6_src->idx, ipv6_dst->idx, 8);
3508 
3509 		/* xor TCP */
3510 		if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0)
3511 			ice_rss_config_xor(hw, prof_id,
3512 					   tcp_src->idx, tcp_dst->idx, 1);
3513 
3514 		/* xor UDP */
3515 		if (udp_src->prot_id != 0 && udp_dst->prot_id != 0)
3516 			ice_rss_config_xor(hw, prof_id,
3517 					   udp_src->idx, udp_dst->idx, 1);
3518 
3519 		/* xor SCTP */
3520 		if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0)
3521 			ice_rss_config_xor(hw, prof_id,
3522 					   sctp_src->idx, sctp_dst->idx, 1);
3523 	}
3524 }
3525 
3526 /**
3527  * ice_add_rss_cfg_sync - add an RSS configuration
3528  * @hw: pointer to the hardware structure
3529  * @vsi_handle: software VSI handle
3530  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
3531  * @addl_hdrs: protocol header fields
3532  * @segs_cnt: packet segment count
3533  * @symm: symmetric hash enable/disable
3534  *
3535  * Assumption: lock has already been acquired for RSS list
3536  */
3537 static enum ice_status
3538 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
3539 		     u32 addl_hdrs, u8 segs_cnt, bool symm)
3540 {
3541 	const enum ice_block blk = ICE_BLK_RSS;
3542 	struct ice_flow_prof *prof = NULL;
3543 	struct ice_flow_seg_info *segs;
3544 	enum ice_status status;
3545 
3546 	if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
3547 		return ICE_ERR_PARAM;
3548 
3549 	segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
3550 						      sizeof(*segs));
3551 	if (!segs)
3552 		return ICE_ERR_NO_MEMORY;
3553 
3554 	/* Construct the packet segment info from the hashed fields */
3555 	status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
3556 					   addl_hdrs);
3557 	if (status)
3558 		goto exit;
3559 
3560 	/* Search for a flow profile that has matching headers, hash fields
3561 	 * and has the input VSI associated to it. If found, no further
3562 	 * operations required and exit.
3563 	 */
3564 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
3565 					vsi_handle,
3566 					ICE_FLOW_FIND_PROF_CHK_FLDS |
3567 					ICE_FLOW_FIND_PROF_CHK_VSI);
3568 	if (prof) {
3569 		if (prof->cfg.symm == symm)
3570 			goto exit;
3571 		prof->cfg.symm = symm;
3572 		goto update_symm;
3573 	}
3574 
3575 	/* Check if a flow profile exists with the same protocol headers and
3576 	 * associated with the input VSI. If so disassociate the VSI from
3577 	 * this profile. The VSI will be added to a new profile created with
3578 	 * the protocol header and new hash field configuration.
3579 	 */
3580 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
3581 					vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
3582 	if (prof) {
3583 		status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
3584 		if (!status)
3585 			ice_rem_rss_list(hw, vsi_handle, prof);
3586 		else
3587 			goto exit;
3588 
3589 		/* Remove profile if it has no VSIs associated */
3590 		if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) {
3591 			status = ice_flow_rem_prof(hw, blk, prof->id);
3592 			if (status)
3593 				goto exit;
3594 		}
3595 	}
3596 
3597 	/* Search for a profile that has same match fields only. If this
3598 	 * exists then associate the VSI to this profile.
3599 	 */
3600 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
3601 					vsi_handle,
3602 					ICE_FLOW_FIND_PROF_CHK_FLDS);
3603 	if (prof) {
3604 		if (prof->cfg.symm == symm) {
3605 			status = ice_flow_assoc_prof(hw, blk, prof,
3606 						     vsi_handle);
3607 			if (!status)
3608 				status = ice_add_rss_list(hw, vsi_handle,
3609 							  prof);
3610 		} else {
3611 			/* if a profile exist but with different symmetric
3612 			 * requirement, just return error.
3613 			 */
3614 			status = ICE_ERR_NOT_SUPPORTED;
3615 		}
3616 		goto exit;
3617 	}
3618 
3619 	/* Create a new flow profile with generated profile and packet
3620 	 * segment information.
3621 	 */
3622 	status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
3623 				   ICE_FLOW_GEN_PROFID(hashed_flds,
3624 						       segs[segs_cnt - 1].hdrs,
3625 						       segs_cnt),
3626 				   segs, segs_cnt, NULL, 0, &prof);
3627 	if (status)
3628 		goto exit;
3629 
3630 	status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
3631 	/* If association to a new flow profile failed then this profile can
3632 	 * be removed.
3633 	 */
3634 	if (status) {
3635 		ice_flow_rem_prof(hw, blk, prof->id);
3636 		goto exit;
3637 	}
3638 
3639 	status = ice_add_rss_list(hw, vsi_handle, prof);
3640 
3641 	prof->cfg.symm = symm;
3642 
3643 update_symm:
3644 	ice_rss_update_symm(hw, prof);
3645 
3646 exit:
3647 	ice_free(hw, segs);
3648 	return status;
3649 }
3650 
3651 /**
3652  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
3653  * @hw: pointer to the hardware structure
3654  * @vsi_handle: software VSI handle
3655  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
3656  * @addl_hdrs: protocol header fields
3657  * @symm: symmetric hash enable/disable
3658  *
3659  * This function will generate a flow profile based on fields associated with
3660  * the input fields to hash on, the flow type and use the VSI number to add
3661  * a flow entry to the profile.
3662  */
3663 enum ice_status
3664 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
3665 		u32 addl_hdrs, bool symm)
3666 {
3667 	enum ice_status status;
3668 
3669 	if (hashed_flds == ICE_HASH_INVALID ||
3670 	    !ice_is_vsi_valid(hw, vsi_handle))
3671 		return ICE_ERR_PARAM;
3672 
3673 	ice_acquire_lock(&hw->rss_locks);
3674 	status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
3675 				      ICE_RSS_OUTER_HEADERS, symm);
3676 	if (!status)
3677 		status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
3678 					      addl_hdrs, ICE_RSS_INNER_HEADERS,
3679 					      symm);
3680 	ice_release_lock(&hw->rss_locks);
3681 
3682 	return status;
3683 }
3684 
3685 /**
3686  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
3687  * @hw: pointer to the hardware structure
3688  * @vsi_handle: software VSI handle
3689  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
3690  * @addl_hdrs: Protocol header fields within a packet segment
3691  * @segs_cnt: packet segment count
3692  *
3693  * Assumption: lock has already been acquired for RSS list
3694  */
3695 static enum ice_status
3696 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
3697 		     u32 addl_hdrs, u8 segs_cnt)
3698 {
3699 	const enum ice_block blk = ICE_BLK_RSS;
3700 	struct ice_flow_seg_info *segs;
3701 	struct ice_flow_prof *prof;
3702 	enum ice_status status;
3703 
3704 	segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
3705 						      sizeof(*segs));
3706 	if (!segs)
3707 		return ICE_ERR_NO_MEMORY;
3708 
3709 	/* Construct the packet segment info from the hashed fields */
3710 	status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
3711 					   addl_hdrs);
3712 	if (status)
3713 		goto out;
3714 
3715 	prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
3716 					vsi_handle,
3717 					ICE_FLOW_FIND_PROF_CHK_FLDS);
3718 	if (!prof) {
3719 		status = ICE_ERR_DOES_NOT_EXIST;
3720 		goto out;
3721 	}
3722 
3723 	status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
3724 	if (status)
3725 		goto out;
3726 
3727 	/* Remove RSS configuration from VSI context before deleting
3728 	 * the flow profile.
3729 	 */
3730 	ice_rem_rss_list(hw, vsi_handle, prof);
3731 
3732 	if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI))
3733 		status = ice_flow_rem_prof(hw, blk, prof->id);
3734 
3735 out:
3736 	ice_free(hw, segs);
3737 	return status;
3738 }
3739 
3740 /**
3741  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
3742  * @hw: pointer to the hardware structure
3743  * @vsi_handle: software VSI handle
3744  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
3745  * @addl_hdrs: Protocol header fields within a packet segment
3746  *
3747  * This function will lookup the flow profile based on the input
3748  * hash field bitmap, iterate through the profile entry list of
3749  * that profile and find entry associated with input VSI to be
3750  * removed. Calls are made to underlying flow apis which will in
3751  * turn build or update buffers for RSS XLT1 section.
3752  */
3753 enum ice_status
3754 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
3755 		u32 addl_hdrs)
3756 {
3757 	enum ice_status status;
3758 
3759 	if (hashed_flds == ICE_HASH_INVALID ||
3760 	    !ice_is_vsi_valid(hw, vsi_handle))
3761 		return ICE_ERR_PARAM;
3762 
3763 	ice_acquire_lock(&hw->rss_locks);
3764 	status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
3765 				      ICE_RSS_OUTER_HEADERS);
3766 	if (!status)
3767 		status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
3768 					      addl_hdrs, ICE_RSS_INNER_HEADERS);
3769 	ice_release_lock(&hw->rss_locks);
3770 
3771 	return status;
3772 }
3773 
3774 /**
3775  * ice_replay_rss_cfg - replay RSS configurations associated with VSI
3776  * @hw: pointer to the hardware structure
3777  * @vsi_handle: software VSI handle
3778  */
3779 enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
3780 {
3781 	enum ice_status status = ICE_SUCCESS;
3782 	struct ice_rss_cfg *r;
3783 
3784 	if (!ice_is_vsi_valid(hw, vsi_handle))
3785 		return ICE_ERR_PARAM;
3786 
3787 	ice_acquire_lock(&hw->rss_locks);
3788 	LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
3789 			    ice_rss_cfg, l_entry) {
3790 		if (ice_is_bit_set(r->vsis, vsi_handle)) {
3791 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
3792 						      r->hashed_flds,
3793 						      r->packet_hdr,
3794 						      ICE_RSS_OUTER_HEADERS,
3795 						      r->symm);
3796 			if (status)
3797 				break;
3798 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
3799 						      r->hashed_flds,
3800 						      r->packet_hdr,
3801 						      ICE_RSS_INNER_HEADERS,
3802 						      r->symm);
3803 			if (status)
3804 				break;
3805 		}
3806 	}
3807 	ice_release_lock(&hw->rss_locks);
3808 
3809 	return status;
3810 }
3811 
3812 /**
3813  * ice_get_rss_cfg - returns hashed fields for the given header types
3814  * @hw: pointer to the hardware structure
3815  * @vsi_handle: software VSI handle
3816  * @hdrs: protocol header type
3817  *
3818  * This function will return the match fields of the first instance of flow
3819  * profile having the given header types and containing input VSI
3820  */
3821 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
3822 {
3823 	u64 rss_hash = ICE_HASH_INVALID;
3824 	struct ice_rss_cfg *r;
3825 
3826 	/* verify if the protocol header is non zero and VSI is valid */
3827 	if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
3828 		return ICE_HASH_INVALID;
3829 
3830 	ice_acquire_lock(&hw->rss_locks);
3831 	LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
3832 			    ice_rss_cfg, l_entry)
3833 		if (ice_is_bit_set(r->vsis, vsi_handle) &&
3834 		    r->packet_hdr == hdrs) {
3835 			rss_hash = r->hashed_flds;
3836 			break;
3837 		}
3838 	ice_release_lock(&hw->rss_locks);
3839 
3840 	return rss_hash;
3841 }
3842