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