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