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