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