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