6c413e307ed513316093d1edb9a29b08d1bb24df
[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_EH) {
590                         src = (const ice_bitmap_t *)ice_ptypes_gtpu;
591                         ice_and_bitmap(params->ptypes, params->ptypes,
592                                        src, ICE_FLOW_PTYPE_MAX);
593
594                         /* Attributes for GTP packet with Extension Header */
595                         params->attr = ice_attr_gtpu_eh;
596                         params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
597                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
598                         src = (const ice_bitmap_t *)ice_ptypes_gtpu;
599                         ice_and_bitmap(params->ptypes, params->ptypes,
600                                        src, ICE_FLOW_PTYPE_MAX);
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                 enum ice_flow_field 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(hw, params, i, j,
947                                                              match);
948                                 if (status)
949                                         return status;
950                                 match &= ~bit;
951                         }
952                 }
953
954                 /* Process raw matching bytes */
955                 status = ice_flow_xtract_raws(hw, params, i);
956                 if (status)
957                         return status;
958         }
959
960         return status;
961 }
962
963 /**
964  * ice_flow_proc_segs - process all packet segments associated with a profile
965  * @hw: pointer to the HW struct
966  * @params: information about the flow to be processed
967  */
968 static enum ice_status
969 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
970 {
971         enum ice_status status;
972
973         status = ice_flow_proc_seg_hdrs(params);
974         if (status)
975                 return status;
976
977         status = ice_flow_create_xtrct_seq(hw, params);
978         if (status)
979                 return status;
980
981         switch (params->blk) {
982         case ICE_BLK_RSS:
983                 /* Only header information is provided for RSS configuration.
984                  * No further processing is needed.
985                  */
986                 status = ICE_SUCCESS;
987                 break;
988         case ICE_BLK_FD:
989                 status = ICE_SUCCESS;
990                 break;
991         case ICE_BLK_SW:
992         default:
993                 return ICE_ERR_NOT_IMPL;
994         }
995
996         return status;
997 }
998
999 #define ICE_FLOW_FIND_PROF_CHK_FLDS     0x00000001
1000 #define ICE_FLOW_FIND_PROF_CHK_VSI      0x00000002
1001 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR  0x00000004
1002
1003 /**
1004  * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1005  * @hw: pointer to the HW struct
1006  * @blk: classification stage
1007  * @dir: flow direction
1008  * @segs: array of one or more packet segments that describe the flow
1009  * @segs_cnt: number of packet segments provided
1010  * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1011  * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1012  */
1013 static struct ice_flow_prof *
1014 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1015                          enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1016                          u8 segs_cnt, u16 vsi_handle, u32 conds)
1017 {
1018         struct ice_flow_prof *p, *prof = NULL;
1019
1020         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1021         LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) {
1022                 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1023                     segs_cnt && segs_cnt == p->segs_cnt) {
1024                         u8 i;
1025
1026                         /* Check for profile-VSI association if specified */
1027                         if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1028                             ice_is_vsi_valid(hw, vsi_handle) &&
1029                             !ice_is_bit_set(p->vsis, vsi_handle))
1030                                 continue;
1031
1032                         /* Protocol headers must be checked. Matched fields are
1033                          * checked if specified.
1034                          */
1035                         for (i = 0; i < segs_cnt; i++)
1036                                 if (segs[i].hdrs != p->segs[i].hdrs ||
1037                                     ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1038                                      segs[i].match != p->segs[i].match))
1039                                         break;
1040
1041                         /* A match is found if all segments are matched */
1042                         if (i == segs_cnt) {
1043                                 prof = p;
1044                                 break;
1045                         }
1046                 }
1047         }
1048         ice_release_lock(&hw->fl_profs_locks[blk]);
1049
1050         return prof;
1051 }
1052
1053 /**
1054  * ice_flow_find_prof - Look up a profile matching headers and matched fields
1055  * @hw: pointer to the HW struct
1056  * @blk: classification stage
1057  * @dir: flow direction
1058  * @segs: array of one or more packet segments that describe the flow
1059  * @segs_cnt: number of packet segments provided
1060  */
1061 u64
1062 ice_flow_find_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1063                    struct ice_flow_seg_info *segs, u8 segs_cnt)
1064 {
1065         struct ice_flow_prof *p;
1066
1067         p = ice_flow_find_prof_conds(hw, blk, dir, segs, segs_cnt,
1068                                      ICE_MAX_VSI, ICE_FLOW_FIND_PROF_CHK_FLDS);
1069
1070         return p ? p->id : ICE_FLOW_PROF_ID_INVAL;
1071 }
1072
1073 /**
1074  * ice_flow_find_prof_id - Look up a profile with given profile ID
1075  * @hw: pointer to the HW struct
1076  * @blk: classification stage
1077  * @prof_id: unique ID to identify this flow profile
1078  */
1079 static struct ice_flow_prof *
1080 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1081 {
1082         struct ice_flow_prof *p;
1083
1084         LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) {
1085                 if (p->id == prof_id)
1086                         return p;
1087         }
1088
1089         return NULL;
1090 }
1091
1092 /**
1093  * ice_dealloc_flow_entry - Deallocate flow entry memory
1094  * @hw: pointer to the HW struct
1095  * @entry: flow entry to be removed
1096  */
1097 static void
1098 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1099 {
1100         if (!entry)
1101                 return;
1102
1103         if (entry->entry)
1104                 ice_free(hw, entry->entry);
1105
1106         if (entry->acts) {
1107                 ice_free(hw, entry->acts);
1108                 entry->acts = NULL;
1109                 entry->acts_cnt = 0;
1110         }
1111
1112         ice_free(hw, entry);
1113 }
1114
1115 /**
1116  * ice_flow_rem_entry_sync - Remove a flow entry
1117  * @hw: pointer to the HW struct
1118  * @entry: flow entry to be removed
1119  */
1120 static enum ice_status
1121 ice_flow_rem_entry_sync(struct ice_hw *hw, struct ice_flow_entry *entry)
1122 {
1123         if (!entry)
1124                 return ICE_ERR_BAD_PTR;
1125
1126         LIST_DEL(&entry->l_entry);
1127
1128         ice_dealloc_flow_entry(hw, entry);
1129
1130         return ICE_SUCCESS;
1131 }
1132
1133 /**
1134  * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1135  * @hw: pointer to the HW struct
1136  * @blk: classification stage
1137  * @dir: flow direction
1138  * @prof_id: unique ID to identify this flow profile
1139  * @segs: array of one or more packet segments that describe the flow
1140  * @segs_cnt: number of packet segments provided
1141  * @acts: array of default actions
1142  * @acts_cnt: number of default actions
1143  * @prof: stores the returned flow profile added
1144  *
1145  * Assumption: the caller has acquired the lock to the profile list
1146  */
1147 static enum ice_status
1148 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1149                        enum ice_flow_dir dir, u64 prof_id,
1150                        struct ice_flow_seg_info *segs, u8 segs_cnt,
1151                        struct ice_flow_action *acts, u8 acts_cnt,
1152                        struct ice_flow_prof **prof)
1153 {
1154         struct ice_flow_prof_params params;
1155         enum ice_status status = ICE_SUCCESS;
1156         u8 i;
1157
1158         if (!prof || (acts_cnt && !acts))
1159                 return ICE_ERR_BAD_PTR;
1160
1161         ice_memset(&params, 0, sizeof(params), ICE_NONDMA_MEM);
1162         params.prof = (struct ice_flow_prof *)
1163                 ice_malloc(hw, sizeof(*params.prof));
1164         if (!params.prof)
1165                 return ICE_ERR_NO_MEMORY;
1166
1167         /* initialize extraction sequence to all invalid (0xff) */
1168         for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1169                 params.es[i].prot_id = ICE_PROT_INVALID;
1170                 params.es[i].off = ICE_FV_OFFSET_INVAL;
1171         }
1172
1173         params.blk = blk;
1174         params.prof->id = prof_id;
1175         params.prof->dir = dir;
1176         params.prof->segs_cnt = segs_cnt;
1177
1178         /* Make a copy of the segments that need to be persistent in the flow
1179          * profile instance
1180          */
1181         for (i = 0; i < segs_cnt; i++)
1182                 ice_memcpy(&params.prof->segs[i], &segs[i], sizeof(*segs),
1183                            ICE_NONDMA_TO_NONDMA);
1184
1185         /* Make a copy of the actions that need to be persistent in the flow
1186          * profile instance.
1187          */
1188         if (acts_cnt) {
1189                 params.prof->acts = (struct ice_flow_action *)
1190                         ice_memdup(hw, acts, acts_cnt * sizeof(*acts),
1191                                    ICE_NONDMA_TO_NONDMA);
1192
1193                 if (!params.prof->acts) {
1194                         status = ICE_ERR_NO_MEMORY;
1195                         goto out;
1196                 }
1197         }
1198
1199         status = ice_flow_proc_segs(hw, &params);
1200         if (status) {
1201                 ice_debug(hw, ICE_DBG_FLOW,
1202                           "Error processing a flow's packet segments\n");
1203                 goto out;
1204         }
1205
1206         /* Add a HW profile for this flow profile */
1207         status = ice_add_prof(hw, blk, prof_id, (u8 *)params.ptypes,
1208                               params.attr, params.attr_cnt, params.es,
1209                               params.mask);
1210         if (status) {
1211                 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1212                 goto out;
1213         }
1214
1215         INIT_LIST_HEAD(&params.prof->entries);
1216         ice_init_lock(&params.prof->entries_lock);
1217         *prof = params.prof;
1218
1219 out:
1220         if (status) {
1221                 if (params.prof->acts)
1222                         ice_free(hw, params.prof->acts);
1223                 ice_free(hw, params.prof);
1224         }
1225
1226         return status;
1227 }
1228
1229 /**
1230  * ice_flow_rem_prof_sync - remove a flow profile
1231  * @hw: pointer to the hardware structure
1232  * @blk: classification stage
1233  * @prof: pointer to flow profile to remove
1234  *
1235  * Assumption: the caller has acquired the lock to the profile list
1236  */
1237 static enum ice_status
1238 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1239                        struct ice_flow_prof *prof)
1240 {
1241         enum ice_status status = ICE_SUCCESS;
1242
1243         /* Remove all remaining flow entries before removing the flow profile */
1244         if (!LIST_EMPTY(&prof->entries)) {
1245                 struct ice_flow_entry *e, *t;
1246
1247                 ice_acquire_lock(&prof->entries_lock);
1248
1249                 LIST_FOR_EACH_ENTRY_SAFE(e, t, &prof->entries, ice_flow_entry,
1250                                          l_entry) {
1251                         status = ice_flow_rem_entry_sync(hw, e);
1252                         if (status)
1253                                 break;
1254                 }
1255
1256                 ice_release_lock(&prof->entries_lock);
1257         }
1258
1259         /* Remove all hardware profiles associated with this flow profile */
1260         status = ice_rem_prof(hw, blk, prof->id);
1261         if (!status) {
1262                 LIST_DEL(&prof->l_entry);
1263                 ice_destroy_lock(&prof->entries_lock);
1264                 if (prof->acts)
1265                         ice_free(hw, prof->acts);
1266                 ice_free(hw, prof);
1267         }
1268
1269         return status;
1270 }
1271
1272 /**
1273  * ice_flow_assoc_vsig_vsi - associate a VSI with VSIG
1274  * @hw: pointer to the hardware structure
1275  * @blk: classification stage
1276  * @vsi_handle: software VSI handle
1277  * @vsig: target VSI group
1278  *
1279  * Assumption: the caller has already verified that the VSI to
1280  * be added has the same characteristics as the VSIG and will
1281  * thereby have access to all resources added to that VSIG.
1282  */
1283 enum ice_status
1284 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
1285                         u16 vsig)
1286 {
1287         enum ice_status status;
1288
1289         if (!ice_is_vsi_valid(hw, vsi_handle) || blk >= ICE_BLK_COUNT)
1290                 return ICE_ERR_PARAM;
1291
1292         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1293         status = ice_add_vsi_flow(hw, blk, ice_get_hw_vsi_num(hw, vsi_handle),
1294                                   vsig);
1295         ice_release_lock(&hw->fl_profs_locks[blk]);
1296
1297         return status;
1298 }
1299
1300 /**
1301  * ice_flow_assoc_prof - associate a VSI with a flow profile
1302  * @hw: pointer to the hardware structure
1303  * @blk: classification stage
1304  * @prof: pointer to flow profile
1305  * @vsi_handle: software VSI handle
1306  *
1307  * Assumption: the caller has acquired the lock to the profile list
1308  * and the software VSI handle has been validated
1309  */
1310 static enum ice_status
1311 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1312                     struct ice_flow_prof *prof, u16 vsi_handle)
1313 {
1314         enum ice_status status = ICE_SUCCESS;
1315
1316         if (!ice_is_bit_set(prof->vsis, vsi_handle)) {
1317                 status = ice_add_prof_id_flow(hw, blk,
1318                                               ice_get_hw_vsi_num(hw,
1319                                                                  vsi_handle),
1320                                               prof->id);
1321                 if (!status)
1322                         ice_set_bit(vsi_handle, prof->vsis);
1323                 else
1324                         ice_debug(hw, ICE_DBG_FLOW,
1325                                   "HW profile add failed, %d\n",
1326                                   status);
1327         }
1328
1329         return status;
1330 }
1331
1332 /**
1333  * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1334  * @hw: pointer to the hardware structure
1335  * @blk: classification stage
1336  * @prof: pointer to flow profile
1337  * @vsi_handle: software VSI handle
1338  *
1339  * Assumption: the caller has acquired the lock to the profile list
1340  * and the software VSI handle has been validated
1341  */
1342 static enum ice_status
1343 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1344                        struct ice_flow_prof *prof, u16 vsi_handle)
1345 {
1346         enum ice_status status = ICE_SUCCESS;
1347
1348         if (ice_is_bit_set(prof->vsis, vsi_handle)) {
1349                 status = ice_rem_prof_id_flow(hw, blk,
1350                                               ice_get_hw_vsi_num(hw,
1351                                                                  vsi_handle),
1352                                               prof->id);
1353                 if (!status)
1354                         ice_clear_bit(vsi_handle, prof->vsis);
1355                 else
1356                         ice_debug(hw, ICE_DBG_FLOW,
1357                                   "HW profile remove failed, %d\n",
1358                                   status);
1359         }
1360
1361         return status;
1362 }
1363
1364 /**
1365  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1366  * @hw: pointer to the HW struct
1367  * @blk: classification stage
1368  * @dir: flow direction
1369  * @prof_id: unique ID to identify this flow profile
1370  * @segs: array of one or more packet segments that describe the flow
1371  * @segs_cnt: number of packet segments provided
1372  * @acts: array of default actions
1373  * @acts_cnt: number of default actions
1374  * @prof: stores the returned flow profile added
1375  */
1376 enum ice_status
1377 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1378                   u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1379                   struct ice_flow_action *acts, u8 acts_cnt,
1380                   struct ice_flow_prof **prof)
1381 {
1382         enum ice_status status;
1383
1384         if (segs_cnt > ICE_FLOW_SEG_MAX)
1385                 return ICE_ERR_MAX_LIMIT;
1386
1387         if (!segs_cnt)
1388                 return ICE_ERR_PARAM;
1389
1390         if (!segs)
1391                 return ICE_ERR_BAD_PTR;
1392
1393         status = ice_flow_val_hdrs(segs, segs_cnt);
1394         if (status)
1395                 return status;
1396
1397         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1398
1399         status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1400                                         acts, acts_cnt, prof);
1401         if (!status)
1402                 LIST_ADD(&(*prof)->l_entry, &hw->fl_profs[blk]);
1403
1404         ice_release_lock(&hw->fl_profs_locks[blk]);
1405
1406         return status;
1407 }
1408
1409 /**
1410  * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1411  * @hw: pointer to the HW struct
1412  * @blk: the block for which the flow profile is to be removed
1413  * @prof_id: unique ID of the flow profile to be removed
1414  */
1415 enum ice_status
1416 ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1417 {
1418         struct ice_flow_prof *prof;
1419         enum ice_status status;
1420
1421         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1422
1423         prof = ice_flow_find_prof_id(hw, blk, prof_id);
1424         if (!prof) {
1425                 status = ICE_ERR_DOES_NOT_EXIST;
1426                 goto out;
1427         }
1428
1429         /* prof becomes invalid after the call */
1430         status = ice_flow_rem_prof_sync(hw, blk, prof);
1431
1432 out:
1433         ice_release_lock(&hw->fl_profs_locks[blk]);
1434
1435         return status;
1436 }
1437
1438 /**
1439  * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle
1440  * @hw: pointer to the HW struct
1441  * @blk: classification stage
1442  * @prof_id: the profile ID handle
1443  * @hw_prof_id: pointer to variable to receive the HW profile ID
1444  */
1445 enum ice_status
1446 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1447                      u8 *hw_prof_id)
1448 {
1449         struct ice_prof_map *map;
1450
1451         map = ice_search_prof_id(hw, blk, prof_id);
1452         if (map) {
1453                 *hw_prof_id = map->prof_id;
1454                 return ICE_SUCCESS;
1455         }
1456
1457         return ICE_ERR_DOES_NOT_EXIST;
1458 }
1459
1460 /**
1461  * ice_flow_find_entry - look for a flow entry using its unique ID
1462  * @hw: pointer to the HW struct
1463  * @blk: classification stage
1464  * @entry_id: unique ID to identify this flow entry
1465  *
1466  * This function looks for the flow entry with the specified unique ID in all
1467  * flow profiles of the specified classification stage. If the entry is found,
1468  * and it returns the handle to the flow entry. Otherwise, it returns
1469  * ICE_FLOW_ENTRY_ID_INVAL.
1470  */
1471 u64 ice_flow_find_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_id)
1472 {
1473         struct ice_flow_entry *found = NULL;
1474         struct ice_flow_prof *p;
1475
1476         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1477
1478         LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) {
1479                 struct ice_flow_entry *e;
1480
1481                 ice_acquire_lock(&p->entries_lock);
1482                 LIST_FOR_EACH_ENTRY(e, &p->entries, ice_flow_entry, l_entry)
1483                         if (e->id == entry_id) {
1484                                 found = e;
1485                                 break;
1486                         }
1487                 ice_release_lock(&p->entries_lock);
1488
1489                 if (found)
1490                         break;
1491         }
1492
1493         ice_release_lock(&hw->fl_profs_locks[blk]);
1494
1495         return found ? ICE_FLOW_ENTRY_HNDL(found) : ICE_FLOW_ENTRY_HANDLE_INVAL;
1496 }
1497
1498 /**
1499  * ice_flow_add_entry - Add a flow entry
1500  * @hw: pointer to the HW struct
1501  * @blk: classification stage
1502  * @prof_id: ID of the profile to add a new flow entry to
1503  * @entry_id: unique ID to identify this flow entry
1504  * @vsi_handle: software VSI handle for the flow entry
1505  * @prio: priority of the flow entry
1506  * @data: pointer to a data buffer containing flow entry's match values/masks
1507  * @acts: arrays of actions to be performed on a match
1508  * @acts_cnt: number of actions
1509  * @entry_h: pointer to buffer that receives the new flow entry's handle
1510  */
1511 enum ice_status
1512 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1513                    u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1514                    void *data, struct ice_flow_action *acts, u8 acts_cnt,
1515                    u64 *entry_h)
1516 {
1517         struct ice_flow_prof *prof = NULL;
1518         struct ice_flow_entry *e = NULL;
1519         enum ice_status status = ICE_SUCCESS;
1520
1521         if (acts_cnt && !acts)
1522                 return ICE_ERR_PARAM;
1523
1524         /* No flow entry data is expected for RSS */
1525         if (!entry_h || (!data && blk != ICE_BLK_RSS))
1526                 return ICE_ERR_BAD_PTR;
1527
1528         if (!ice_is_vsi_valid(hw, vsi_handle))
1529                 return ICE_ERR_PARAM;
1530
1531         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1532
1533         prof = ice_flow_find_prof_id(hw, blk, prof_id);
1534         if (!prof) {
1535                 status = ICE_ERR_DOES_NOT_EXIST;
1536         } else {
1537                 /* Allocate memory for the entry being added and associate
1538                  * the VSI to the found flow profile
1539                  */
1540                 e = (struct ice_flow_entry *)ice_malloc(hw, sizeof(*e));
1541                 if (!e)
1542                         status = ICE_ERR_NO_MEMORY;
1543                 else
1544                         status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1545         }
1546
1547         ice_release_lock(&hw->fl_profs_locks[blk]);
1548         if (status)
1549                 goto out;
1550
1551         e->id = entry_id;
1552         e->vsi_handle = vsi_handle;
1553         e->prof = prof;
1554         e->priority = prio;
1555
1556         switch (blk) {
1557         case ICE_BLK_RSS:
1558                 /* RSS will add only one entry per VSI per profile */
1559                 break;
1560         case ICE_BLK_FD:
1561                 break;
1562         case ICE_BLK_SW:
1563         case ICE_BLK_PE:
1564         default:
1565                 status = ICE_ERR_NOT_IMPL;
1566                 goto out;
1567         }
1568
1569         if (blk != ICE_BLK_ACL) {
1570                 /* ACL will handle the entry management */
1571                 ice_acquire_lock(&prof->entries_lock);
1572                 LIST_ADD(&e->l_entry, &prof->entries);
1573                 ice_release_lock(&prof->entries_lock);
1574         }
1575
1576         *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1577
1578 out:
1579         if (status && e) {
1580                 if (e->entry)
1581                         ice_free(hw, e->entry);
1582                 ice_free(hw, e);
1583         }
1584
1585         return status;
1586 }
1587
1588 /**
1589  * ice_flow_rem_entry - Remove a flow entry
1590  * @hw: pointer to the HW struct
1591  * @entry_h: handle to the flow entry to be removed
1592  */
1593 enum ice_status ice_flow_rem_entry(struct ice_hw *hw, u64 entry_h)
1594 {
1595         struct ice_flow_entry *entry;
1596         struct ice_flow_prof *prof;
1597         enum ice_status status;
1598
1599         if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1600                 return ICE_ERR_PARAM;
1601
1602         entry = ICE_FLOW_ENTRY_PTR((unsigned long)entry_h);
1603
1604         /* Retain the pointer to the flow profile as the entry will be freed */
1605         prof = entry->prof;
1606
1607         ice_acquire_lock(&prof->entries_lock);
1608         status = ice_flow_rem_entry_sync(hw, entry);
1609         ice_release_lock(&prof->entries_lock);
1610
1611         return status;
1612 }
1613
1614 /**
1615  * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1616  * @seg: packet segment the field being set belongs to
1617  * @fld: field to be set
1618  * @type: type of the field
1619  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1620  *           entry's input buffer
1621  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1622  *            input buffer
1623  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1624  *            entry's input buffer
1625  *
1626  * This helper function stores information of a field being matched, including
1627  * the type of the field and the locations of the value to match, the mask, and
1628  * and the upper-bound value in the start of the input buffer for a flow entry.
1629  * This function should only be used for fixed-size data structures.
1630  *
1631  * This function also opportunistically determines the protocol headers to be
1632  * present based on the fields being set. Some fields cannot be used alone to
1633  * determine the protocol headers present. Sometimes, fields for particular
1634  * protocol headers are not matched. In those cases, the protocol headers
1635  * must be explicitly set.
1636  */
1637 static void
1638 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1639                      enum ice_flow_fld_match_type type, u16 val_loc,
1640                      u16 mask_loc, u16 last_loc)
1641 {
1642         u64 bit = BIT_ULL(fld);
1643
1644         seg->match |= bit;
1645         if (type == ICE_FLOW_FLD_TYPE_RANGE)
1646                 seg->range |= bit;
1647
1648         seg->fields[fld].type = type;
1649         seg->fields[fld].src.val = val_loc;
1650         seg->fields[fld].src.mask = mask_loc;
1651         seg->fields[fld].src.last = last_loc;
1652
1653         ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1654 }
1655
1656 /**
1657  * ice_flow_set_fld - specifies locations of field from entry's input buffer
1658  * @seg: packet segment the field being set belongs to
1659  * @fld: field to be set
1660  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1661  *           entry's input buffer
1662  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1663  *            input buffer
1664  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1665  *            entry's input buffer
1666  * @range: indicate if field being matched is to be in a range
1667  *
1668  * This function specifies the locations, in the form of byte offsets from the
1669  * start of the input buffer for a flow entry, from where the value to match,
1670  * the mask value, and upper value can be extracted. These locations are then
1671  * stored in the flow profile. When adding a flow entry associated with the
1672  * flow profile, these locations will be used to quickly extract the values and
1673  * create the content of a match entry. This function should only be used for
1674  * fixed-size data structures.
1675  */
1676 void
1677 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1678                  u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1679 {
1680         enum ice_flow_fld_match_type t = range ?
1681                 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1682
1683         ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1684 }
1685
1686 /**
1687  * ice_flow_set_fld_prefix - sets locations of prefix field from entry's buf
1688  * @seg: packet segment the field being set belongs to
1689  * @fld: field to be set
1690  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1691  *           entry's input buffer
1692  * @pref_loc: location of prefix value from entry's input buffer
1693  * @pref_sz: size of the location holding the prefix value
1694  *
1695  * This function specifies the locations, in the form of byte offsets from the
1696  * start of the input buffer for a flow entry, from where the value to match
1697  * and the IPv4 prefix value can be extracted. These locations are then stored
1698  * in the flow profile. When adding flow entries to the associated flow profile,
1699  * these locations can be used to quickly extract the values to create the
1700  * content of a match entry. This function should only be used for fixed-size
1701  * data structures.
1702  */
1703 void
1704 ice_flow_set_fld_prefix(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1705                         u16 val_loc, u16 pref_loc, u8 pref_sz)
1706 {
1707         /* For this type of field, the "mask" location is for the prefix value's
1708          * location and the "last" location is for the size of the location of
1709          * the prefix value.
1710          */
1711         ice_flow_set_fld_ext(seg, fld, ICE_FLOW_FLD_TYPE_PREFIX, val_loc,
1712                              pref_loc, (u16)pref_sz);
1713 }
1714
1715 /**
1716  * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1717  * @seg: packet segment the field being set belongs to
1718  * @off: offset of the raw field from the beginning of the segment in bytes
1719  * @len: length of the raw pattern to be matched
1720  * @val_loc: location of the value to match from entry's input buffer
1721  * @mask_loc: location of mask value from entry's input buffer
1722  *
1723  * This function specifies the offset of the raw field to be match from the
1724  * beginning of the specified packet segment, and the locations, in the form of
1725  * byte offsets from the start of the input buffer for a flow entry, from where
1726  * the value to match and the mask value to be extracted. These locations are
1727  * then stored in the flow profile. When adding flow entries to the associated
1728  * flow profile, these locations can be used to quickly extract the values to
1729  * create the content of a match entry. This function should only be used for
1730  * fixed-size data structures.
1731  */
1732 void
1733 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1734                      u16 val_loc, u16 mask_loc)
1735 {
1736         if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1737                 seg->raws[seg->raws_cnt].off = off;
1738                 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1739                 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1740                 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1741                 /* The "last" field is used to store the length of the field */
1742                 seg->raws[seg->raws_cnt].info.src.last = len;
1743         }
1744
1745         /* Overflows of "raws" will be handled as an error condition later in
1746          * the flow when this information is processed.
1747          */
1748         seg->raws_cnt++;
1749 }
1750
1751 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1752 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1753
1754 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1755         (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1756
1757 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1758         (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
1759          ICE_FLOW_SEG_HDR_SCTP)
1760
1761 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1762         (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1763          ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1764          ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1765
1766 /**
1767  * ice_flow_set_rss_seg_info - setup packet segments for RSS
1768  * @segs: pointer to the flow field segment(s)
1769  * @hash_fields: fields to be hashed on for the segment(s)
1770  * @flow_hdr: protocol header fields within a packet segment
1771  *
1772  * Helper function to extract fields from hash bitmap and use flow
1773  * header value to set flow field segment for further use in flow
1774  * profile entry or removal.
1775  */
1776 static enum ice_status
1777 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1778                           u32 flow_hdr)
1779 {
1780         u64 val = hash_fields;
1781         u8 i;
1782
1783         for (i = 0; val && i < ICE_FLOW_FIELD_IDX_MAX; i++) {
1784                 u64 bit = BIT_ULL(i);
1785
1786                 if (val & bit) {
1787                         ice_flow_set_fld(segs, (enum ice_flow_field)i,
1788                                          ICE_FLOW_FLD_OFF_INVAL,
1789                                          ICE_FLOW_FLD_OFF_INVAL,
1790                                          ICE_FLOW_FLD_OFF_INVAL, false);
1791                         val &= ~bit;
1792                 }
1793         }
1794         ICE_FLOW_SET_HDRS(segs, flow_hdr);
1795
1796         if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1797             ~ICE_FLOW_RSS_HDRS_INNER_MASK)
1798                 return ICE_ERR_PARAM;
1799
1800         val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1801         if (val && !ice_is_pow2(val))
1802                 return ICE_ERR_CFG;
1803
1804         val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1805         if (val && !ice_is_pow2(val))
1806                 return ICE_ERR_CFG;
1807
1808         return ICE_SUCCESS;
1809 }
1810
1811 /**
1812  * ice_rem_vsi_rss_list - remove VSI from RSS list
1813  * @hw: pointer to the hardware structure
1814  * @vsi_handle: software VSI handle
1815  *
1816  * Remove the VSI from all RSS configurations in the list.
1817  */
1818 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1819 {
1820         struct ice_rss_cfg *r, *tmp;
1821
1822         if (LIST_EMPTY(&hw->rss_list_head))
1823                 return;
1824
1825         ice_acquire_lock(&hw->rss_locks);
1826         LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
1827                                  ice_rss_cfg, l_entry) {
1828                 if (ice_is_bit_set(r->vsis, vsi_handle)) {
1829                         ice_clear_bit(vsi_handle, r->vsis);
1830
1831                         if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
1832                                 LIST_DEL(&r->l_entry);
1833                                 ice_free(hw, r);
1834                         }
1835                 }
1836         }
1837         ice_release_lock(&hw->rss_locks);
1838 }
1839
1840 /**
1841  * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1842  * @hw: pointer to the hardware structure
1843  * @vsi_handle: software VSI handle
1844  *
1845  * This function will iterate through all flow profiles and disassociate
1846  * the VSI from that profile. If the flow profile has no VSIs it will
1847  * be removed.
1848  */
1849 enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1850 {
1851         const enum ice_block blk = ICE_BLK_RSS;
1852         struct ice_flow_prof *p, *t;
1853         enum ice_status status = ICE_SUCCESS;
1854
1855         if (!ice_is_vsi_valid(hw, vsi_handle))
1856                 return ICE_ERR_PARAM;
1857
1858         if (LIST_EMPTY(&hw->fl_profs[blk]))
1859                 return ICE_SUCCESS;
1860
1861         ice_acquire_lock(&hw->fl_profs_locks[blk]);
1862         LIST_FOR_EACH_ENTRY_SAFE(p, t, &hw->fl_profs[blk], ice_flow_prof,
1863                                  l_entry) {
1864                 if (ice_is_bit_set(p->vsis, vsi_handle)) {
1865                         status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1866                         if (status)
1867                                 break;
1868
1869                         if (!ice_is_any_bit_set(p->vsis, ICE_MAX_VSI)) {
1870                                 status = ice_flow_rem_prof_sync(hw, blk, p);
1871                                 if (status)
1872                                         break;
1873                         }
1874                 }
1875         }
1876         ice_release_lock(&hw->fl_profs_locks[blk]);
1877
1878         return status;
1879 }
1880
1881 /**
1882  * ice_rem_rss_list - remove RSS configuration from list
1883  * @hw: pointer to the hardware structure
1884  * @vsi_handle: software VSI handle
1885  * @prof: pointer to flow profile
1886  *
1887  * Assumption: lock has already been acquired for RSS list
1888  */
1889 static void
1890 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1891 {
1892         struct ice_rss_cfg *r, *tmp;
1893
1894         /* Search for RSS hash fields associated to the VSI that match the
1895          * hash configurations associated to the flow profile. If found
1896          * remove from the RSS entry list of the VSI context and delete entry.
1897          */
1898         LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
1899                                  ice_rss_cfg, l_entry) {
1900                 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1901                     r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1902                         ice_clear_bit(vsi_handle, r->vsis);
1903                         if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
1904                                 LIST_DEL(&r->l_entry);
1905                                 ice_free(hw, r);
1906                         }
1907                         return;
1908                 }
1909         }
1910 }
1911
1912 /**
1913  * ice_add_rss_list - add RSS configuration to list
1914  * @hw: pointer to the hardware structure
1915  * @vsi_handle: software VSI handle
1916  * @prof: pointer to flow profile
1917  *
1918  * Assumption: lock has already been acquired for RSS list
1919  */
1920 static enum ice_status
1921 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1922 {
1923         struct ice_rss_cfg *r, *rss_cfg;
1924
1925         LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
1926                             ice_rss_cfg, l_entry)
1927                 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1928                     r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1929                         ice_set_bit(vsi_handle, r->vsis);
1930                         return ICE_SUCCESS;
1931                 }
1932
1933         rss_cfg = (struct ice_rss_cfg *)ice_malloc(hw, sizeof(*rss_cfg));
1934         if (!rss_cfg)
1935                 return ICE_ERR_NO_MEMORY;
1936
1937         rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
1938         rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
1939         rss_cfg->symm = prof->cfg.symm;
1940         ice_set_bit(vsi_handle, rss_cfg->vsis);
1941
1942         LIST_ADD_TAIL(&rss_cfg->l_entry, &hw->rss_list_head);
1943
1944         return ICE_SUCCESS;
1945 }
1946
1947 #define ICE_FLOW_PROF_HASH_S    0
1948 #define ICE_FLOW_PROF_HASH_M    (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
1949 #define ICE_FLOW_PROF_HDR_S     32
1950 #define ICE_FLOW_PROF_HDR_M     (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
1951 #define ICE_FLOW_PROF_ENCAP_S   63
1952 #define ICE_FLOW_PROF_ENCAP_M   (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
1953
1954 #define ICE_RSS_OUTER_HEADERS   1
1955 #define ICE_RSS_INNER_HEADERS   2
1956
1957 /* Flow profile ID format:
1958  * [0:31] - Packet match fields
1959  * [32:62] - Protocol header
1960  * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
1961  */
1962 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
1963         (u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
1964               (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
1965               ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0))
1966
1967 static void
1968 ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst)
1969 {
1970         u32 s = ((src % 4) << 3); /* byte shift */
1971         u32 v = dst | 0x80; /* value to program */
1972         u8 i = src / 4; /* register index */
1973         u32 reg;
1974
1975         reg = rd32(hw, GLQF_HSYMM(prof_id, i));
1976         reg = (reg & ~(0xff << s)) | (v << s);
1977         wr32(hw, GLQF_HSYMM(prof_id, i), reg);
1978 }
1979
1980 static void
1981 ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len)
1982 {
1983         int fv_last_word =
1984                 ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1;
1985         int i;
1986
1987         for (i = 0; i < len; i++) {
1988                 ice_rss_config_xor_word(hw, prof_id,
1989                                         /* Yes, field vector in GLQF_HSYMM and
1990                                          * GLQF_HINSET is inversed!
1991                                          */
1992                                         fv_last_word - (src + i),
1993                                         fv_last_word - (dst + i));
1994                 ice_rss_config_xor_word(hw, prof_id,
1995                                         fv_last_word - (dst + i),
1996                                         fv_last_word - (src + i));
1997         }
1998 }
1999
2000 static void
2001 ice_rss_update_symm(struct ice_hw *hw,
2002                     struct ice_flow_prof *prof)
2003 {
2004         struct ice_prof_map *map;
2005         u8 prof_id, m;
2006
2007         map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id);
2008         prof_id = map->prof_id;
2009
2010         /* clear to default */
2011         for (m = 0; m < 6; m++)
2012                 wr32(hw, GLQF_HSYMM(prof_id, m), 0);
2013         if (prof->cfg.symm) {
2014                 struct ice_flow_seg_info *seg =
2015                         &prof->segs[prof->segs_cnt - 1];
2016
2017                 struct ice_flow_seg_xtrct *ipv4_src =
2018                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct;
2019                 struct ice_flow_seg_xtrct *ipv4_dst =
2020                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct;
2021                 struct ice_flow_seg_xtrct *ipv6_src =
2022                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct;
2023                 struct ice_flow_seg_xtrct *ipv6_dst =
2024                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct;
2025
2026                 struct ice_flow_seg_xtrct *tcp_src =
2027                         &seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct;
2028                 struct ice_flow_seg_xtrct *tcp_dst =
2029                         &seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct;
2030
2031                 struct ice_flow_seg_xtrct *udp_src =
2032                         &seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct;
2033                 struct ice_flow_seg_xtrct *udp_dst =
2034                         &seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct;
2035
2036                 struct ice_flow_seg_xtrct *sctp_src =
2037                         &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct;
2038                 struct ice_flow_seg_xtrct *sctp_dst =
2039                         &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct;
2040
2041                 /* xor IPv4 */
2042                 if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0)
2043                         ice_rss_config_xor(hw, prof_id,
2044                                            ipv4_src->idx, ipv4_dst->idx, 2);
2045
2046                 /* xor IPv6 */
2047                 if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0)
2048                         ice_rss_config_xor(hw, prof_id,
2049                                            ipv6_src->idx, ipv6_dst->idx, 8);
2050
2051                 /* xor TCP */
2052                 if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0)
2053                         ice_rss_config_xor(hw, prof_id,
2054                                            tcp_src->idx, tcp_dst->idx, 1);
2055
2056                 /* xor UDP */
2057                 if (udp_src->prot_id != 0 && udp_dst->prot_id != 0)
2058                         ice_rss_config_xor(hw, prof_id,
2059                                            udp_src->idx, udp_dst->idx, 1);
2060
2061                 /* xor SCTP */
2062                 if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0)
2063                         ice_rss_config_xor(hw, prof_id,
2064                                            sctp_src->idx, sctp_dst->idx, 1);
2065         }
2066 }
2067
2068 /**
2069  * ice_add_rss_cfg_sync - add an RSS configuration
2070  * @hw: pointer to the hardware structure
2071  * @vsi_handle: software VSI handle
2072  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2073  * @addl_hdrs: protocol header fields
2074  * @segs_cnt: packet segment count
2075  * @symm: symmetric hash enable/disable
2076  *
2077  * Assumption: lock has already been acquired for RSS list
2078  */
2079 static enum ice_status
2080 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2081                      u32 addl_hdrs, u8 segs_cnt, bool symm)
2082 {
2083         const enum ice_block blk = ICE_BLK_RSS;
2084         struct ice_flow_prof *prof = NULL;
2085         struct ice_flow_seg_info *segs;
2086         enum ice_status status = ICE_SUCCESS;
2087
2088         if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2089                 return ICE_ERR_PARAM;
2090
2091         segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
2092                                                       sizeof(*segs));
2093         if (!segs)
2094                 return ICE_ERR_NO_MEMORY;
2095
2096         /* Construct the packet segment info from the hashed fields */
2097         status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2098                                            addl_hdrs);
2099         if (status)
2100                 goto exit;
2101
2102         /* Search for a flow profile that has matching headers, hash fields
2103          * and has the input VSI associated to it. If found, no further
2104          * operations required and exit.
2105          */
2106         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2107                                         vsi_handle,
2108                                         ICE_FLOW_FIND_PROF_CHK_FLDS |
2109                                         ICE_FLOW_FIND_PROF_CHK_VSI);
2110         if (prof) {
2111                 if (prof->cfg.symm == symm)
2112                         goto exit;
2113                 prof->cfg.symm = symm;
2114                 goto update_symm;
2115         }
2116
2117         /* Check if a flow profile exists with the same protocol headers and
2118          * associated with the input VSI. If so disasscociate the VSI from
2119          * this profile. The VSI will be added to a new profile created with
2120          * the protocol header and new hash field configuration.
2121          */
2122         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2123                                         vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2124         if (prof) {
2125                 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2126                 if (!status)
2127                         ice_rem_rss_list(hw, vsi_handle, prof);
2128                 else
2129                         goto exit;
2130
2131                 /* Remove profile if it has no VSIs associated */
2132                 if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) {
2133                         status = ice_flow_rem_prof(hw, blk, prof->id);
2134                         if (status)
2135                                 goto exit;
2136                 }
2137         }
2138
2139         /* Search for a profile that has same match fields only. If this
2140          * exists then associate the VSI to this profile.
2141          */
2142         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2143                                         vsi_handle,
2144                                         ICE_FLOW_FIND_PROF_CHK_FLDS);
2145         if (prof) {
2146                 if (prof->cfg.symm == symm) {
2147                         status = ice_flow_assoc_prof(hw, blk, prof,
2148                                                      vsi_handle);
2149                         if (!status)
2150                                 status = ice_add_rss_list(hw, vsi_handle,
2151                                                           prof);
2152                 } else {
2153                         /* if a profile exist but with different symmetric
2154                          * requirement, just return error.
2155                          */
2156                         status = ICE_ERR_NOT_SUPPORTED;
2157                 }
2158                 goto exit;
2159         }
2160
2161         /* Create a new flow profile with generated profile and packet
2162          * segment information.
2163          */
2164         status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2165                                    ICE_FLOW_GEN_PROFID(hashed_flds,
2166                                                        segs[segs_cnt - 1].hdrs,
2167                                                        segs_cnt),
2168                                    segs, segs_cnt, NULL, 0, &prof);
2169         if (status)
2170                 goto exit;
2171
2172         status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2173         /* If association to a new flow profile failed then this profile can
2174          * be removed.
2175          */
2176         if (status) {
2177                 ice_flow_rem_prof(hw, blk, prof->id);
2178                 goto exit;
2179         }
2180
2181         status = ice_add_rss_list(hw, vsi_handle, prof);
2182
2183         prof->cfg.symm = symm;
2184
2185 update_symm:
2186         ice_rss_update_symm(hw, prof);
2187
2188 exit:
2189         ice_free(hw, segs);
2190         return status;
2191 }
2192
2193 /**
2194  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2195  * @hw: pointer to the hardware structure
2196  * @vsi_handle: software VSI handle
2197  * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2198  * @addl_hdrs: protocol header fields
2199  * @symm: symmetric hash enable/disable
2200  *
2201  * This function will generate a flow profile based on fields associated with
2202  * the input fields to hash on, the flow type and use the VSI number to add
2203  * a flow entry to the profile.
2204  */
2205 enum ice_status
2206 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2207                 u32 addl_hdrs, bool symm)
2208 {
2209         enum ice_status status;
2210
2211         if (hashed_flds == ICE_HASH_INVALID ||
2212             !ice_is_vsi_valid(hw, vsi_handle))
2213                 return ICE_ERR_PARAM;
2214
2215         ice_acquire_lock(&hw->rss_locks);
2216         status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2217                                       ICE_RSS_OUTER_HEADERS, symm);
2218         if (!status)
2219                 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2220                                               addl_hdrs, ICE_RSS_INNER_HEADERS,
2221                                               symm);
2222         ice_release_lock(&hw->rss_locks);
2223
2224         return status;
2225 }
2226
2227 /**
2228  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2229  * @hw: pointer to the hardware structure
2230  * @vsi_handle: software VSI handle
2231  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2232  * @addl_hdrs: Protocol header fields within a packet segment
2233  * @segs_cnt: packet segment count
2234  *
2235  * Assumption: lock has already been acquired for RSS list
2236  */
2237 static enum ice_status
2238 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2239                      u32 addl_hdrs, u8 segs_cnt)
2240 {
2241         const enum ice_block blk = ICE_BLK_RSS;
2242         struct ice_flow_seg_info *segs;
2243         struct ice_flow_prof *prof;
2244         enum ice_status status;
2245
2246         segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
2247                                                       sizeof(*segs));
2248         if (!segs)
2249                 return ICE_ERR_NO_MEMORY;
2250
2251         /* Construct the packet segment info from the hashed fields */
2252         status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2253                                            addl_hdrs);
2254         if (status)
2255                 goto out;
2256
2257         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2258                                         vsi_handle,
2259                                         ICE_FLOW_FIND_PROF_CHK_FLDS);
2260         if (!prof) {
2261                 status = ICE_ERR_DOES_NOT_EXIST;
2262                 goto out;
2263         }
2264
2265         status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2266         if (status)
2267                 goto out;
2268
2269         /* Remove RSS configuration from VSI context before deleting
2270          * the flow profile.
2271          */
2272         ice_rem_rss_list(hw, vsi_handle, prof);
2273
2274         if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI))
2275                 status = ice_flow_rem_prof(hw, blk, prof->id);
2276
2277 out:
2278         ice_free(hw, segs);
2279         return status;
2280 }
2281
2282 /**
2283  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2284  * @hw: pointer to the hardware structure
2285  * @vsi_handle: software VSI handle
2286  * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2287  * @addl_hdrs: Protocol header fields within a packet segment
2288  *
2289  * This function will lookup the flow profile based on the input
2290  * hash field bitmap, iterate through the profile entry list of
2291  * that profile and find entry associated with input VSI to be
2292  * removed. Calls are made to underlying flow apis which will in
2293  * turn build or update buffers for RSS XLT1 section.
2294  */
2295 enum ice_status
2296 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2297                 u32 addl_hdrs)
2298 {
2299         enum ice_status status;
2300
2301         if (hashed_flds == ICE_HASH_INVALID ||
2302             !ice_is_vsi_valid(hw, vsi_handle))
2303                 return ICE_ERR_PARAM;
2304
2305         ice_acquire_lock(&hw->rss_locks);
2306         status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2307                                       ICE_RSS_OUTER_HEADERS);
2308         if (!status)
2309                 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2310                                               addl_hdrs, ICE_RSS_INNER_HEADERS);
2311         ice_release_lock(&hw->rss_locks);
2312
2313         return status;
2314 }
2315
2316 /**
2317  * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2318  * @hw: pointer to the hardware structure
2319  * @vsi_handle: software VSI handle
2320  */
2321 enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2322 {
2323         enum ice_status status = ICE_SUCCESS;
2324         struct ice_rss_cfg *r;
2325
2326         if (!ice_is_vsi_valid(hw, vsi_handle))
2327                 return ICE_ERR_PARAM;
2328
2329         ice_acquire_lock(&hw->rss_locks);
2330         LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
2331                             ice_rss_cfg, l_entry) {
2332                 if (ice_is_bit_set(r->vsis, vsi_handle)) {
2333                         status = ice_add_rss_cfg_sync(hw, vsi_handle,
2334                                                       r->hashed_flds,
2335                                                       r->packet_hdr,
2336                                                       ICE_RSS_OUTER_HEADERS,
2337                                                       r->symm);
2338                         if (status)
2339                                 break;
2340                         status = ice_add_rss_cfg_sync(hw, vsi_handle,
2341                                                       r->hashed_flds,
2342                                                       r->packet_hdr,
2343                                                       ICE_RSS_INNER_HEADERS,
2344                                                       r->symm);
2345                         if (status)
2346                                 break;
2347                 }
2348         }
2349         ice_release_lock(&hw->rss_locks);
2350
2351         return status;
2352 }
2353
2354 /**
2355  * ice_get_rss_cfg - returns hashed fields for the given header types
2356  * @hw: pointer to the hardware structure
2357  * @vsi_handle: software VSI handle
2358  * @hdrs: protocol header type
2359  *
2360  * This function will return the match fields of the first instance of flow
2361  * profile having the given header types and containing input VSI
2362  */
2363 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2364 {
2365         struct ice_rss_cfg *r, *rss_cfg = NULL;
2366
2367         /* verify if the protocol header is non zero and VSI is valid */
2368         if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2369                 return ICE_HASH_INVALID;
2370
2371         ice_acquire_lock(&hw->rss_locks);
2372         LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
2373                             ice_rss_cfg, l_entry)
2374                 if (ice_is_bit_set(r->vsis, vsi_handle) &&
2375                     r->packet_hdr == hdrs) {
2376                         rss_cfg = r;
2377                         break;
2378                 }
2379         ice_release_lock(&hw->rss_locks);
2380
2381         return rss_cfg ? rss_cfg->hashed_flds : ICE_HASH_INVALID;
2382 }