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_L2_MASK \
613 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
614#define ICE_FLOW_SEG_HDRS_L3_MASK \
615 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
616#define ICE_FLOW_SEG_HDRS_L4_MASK \
617 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
618 ICE_FLOW_SEG_HDR_SCTP)
619
620#define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
621 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
622
623
624
625
626
627
628static enum ice_status
629ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
630{
631 u8 i;
632
633 for (i = 0; i < segs_cnt; i++) {
634
635 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
636 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
637 return ICE_ERR_PARAM;
638
639
640 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
641 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
642 return ICE_ERR_PARAM;
643 }
644
645 return 0;
646}
647
648
649#define ICE_FLOW_PROT_HDR_SZ_MAC 14
650#define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
651#define ICE_FLOW_PROT_HDR_SZ_IPV4 20
652#define ICE_FLOW_PROT_HDR_SZ_IPV6 40
653#define ICE_FLOW_PROT_HDR_SZ_ARP 28
654#define ICE_FLOW_PROT_HDR_SZ_ICMP 8
655#define ICE_FLOW_PROT_HDR_SZ_TCP 20
656#define ICE_FLOW_PROT_HDR_SZ_UDP 8
657#define ICE_FLOW_PROT_HDR_SZ_SCTP 12
658
659
660
661
662
663
664static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
665{
666 u16 sz;
667
668
669 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
670 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
671
672
673 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
674 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
675 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
676 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
677 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
678 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
679 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
680
681 return 0;
682
683
684 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
685 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
686 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
687 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
688 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
689 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
690 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
691 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
692
693 return sz;
694}
695
696
697
698
699
700
701
702
703static enum ice_status
704ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
705{
706 struct ice_flow_prof *prof;
707 u8 i;
708
709 memset(params->ptypes, 0xff, sizeof(params->ptypes));
710
711 prof = params->prof;
712
713 for (i = 0; i < params->prof->segs_cnt; i++) {
714 const unsigned long *src;
715 u32 hdrs;
716
717 hdrs = prof->segs[i].hdrs;
718
719 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
720 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
721 (const unsigned long *)ice_ptypes_mac_il;
722 bitmap_and(params->ptypes, params->ptypes, src,
723 ICE_FLOW_PTYPE_MAX);
724 }
725
726 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
727 src = (const unsigned long *)ice_ptypes_macvlan_il;
728 bitmap_and(params->ptypes, params->ptypes, src,
729 ICE_FLOW_PTYPE_MAX);
730 }
731
732 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
733 bitmap_and(params->ptypes, params->ptypes,
734 (const unsigned long *)ice_ptypes_arp_of,
735 ICE_FLOW_PTYPE_MAX);
736 }
737
738 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
739 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
740 src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
741 (const unsigned long *)ice_ptypes_ipv4_ofos_all;
742 bitmap_and(params->ptypes, params->ptypes, src,
743 ICE_FLOW_PTYPE_MAX);
744 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
745 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
746 src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
747 (const unsigned long *)ice_ptypes_ipv6_ofos_all;
748 bitmap_and(params->ptypes, params->ptypes, src,
749 ICE_FLOW_PTYPE_MAX);
750 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
751 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
752 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
753 (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
754 bitmap_and(params->ptypes, params->ptypes, src,
755 ICE_FLOW_PTYPE_MAX);
756 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
757 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
758 (const unsigned long *)ice_ptypes_ipv4_il;
759 bitmap_and(params->ptypes, params->ptypes, src,
760 ICE_FLOW_PTYPE_MAX);
761 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
762 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
763 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
764 (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
765 bitmap_and(params->ptypes, params->ptypes, src,
766 ICE_FLOW_PTYPE_MAX);
767 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
768 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
769 (const unsigned long *)ice_ptypes_ipv6_il;
770 bitmap_and(params->ptypes, params->ptypes, src,
771 ICE_FLOW_PTYPE_MAX);
772 }
773
774 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
775 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
776 bitmap_and(params->ptypes, params->ptypes, src,
777 ICE_FLOW_PTYPE_MAX);
778 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
779 src = (const unsigned long *)ice_ptypes_pppoe;
780 bitmap_and(params->ptypes, params->ptypes, src,
781 ICE_FLOW_PTYPE_MAX);
782 } else {
783 src = (const unsigned long *)ice_ptypes_pppoe;
784 bitmap_andnot(params->ptypes, params->ptypes, src,
785 ICE_FLOW_PTYPE_MAX);
786 }
787
788 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
789 src = (const unsigned long *)ice_ptypes_udp_il;
790 bitmap_and(params->ptypes, params->ptypes, src,
791 ICE_FLOW_PTYPE_MAX);
792 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
793 bitmap_and(params->ptypes, params->ptypes,
794 (const unsigned long *)ice_ptypes_tcp_il,
795 ICE_FLOW_PTYPE_MAX);
796 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
797 src = (const unsigned long *)ice_ptypes_sctp_il;
798 bitmap_and(params->ptypes, params->ptypes, src,
799 ICE_FLOW_PTYPE_MAX);
800 }
801
802 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
803 src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
804 (const unsigned long *)ice_ptypes_icmp_il;
805 bitmap_and(params->ptypes, params->ptypes, src,
806 ICE_FLOW_PTYPE_MAX);
807 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
808 if (!i) {
809 src = (const unsigned long *)ice_ptypes_gre_of;
810 bitmap_and(params->ptypes, params->ptypes,
811 src, ICE_FLOW_PTYPE_MAX);
812 }
813 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
814 src = (const unsigned long *)ice_ptypes_gtpc;
815 bitmap_and(params->ptypes, params->ptypes, src,
816 ICE_FLOW_PTYPE_MAX);
817 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
818 src = (const unsigned long *)ice_ptypes_gtpc_tid;
819 bitmap_and(params->ptypes, params->ptypes, src,
820 ICE_FLOW_PTYPE_MAX);
821 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
822 src = (const unsigned long *)ice_ptypes_gtpu;
823 bitmap_and(params->ptypes, params->ptypes, src,
824 ICE_FLOW_PTYPE_MAX);
825
826
827 params->attr = ice_attr_gtpu_down;
828 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
829 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
830 src = (const unsigned long *)ice_ptypes_gtpu;
831 bitmap_and(params->ptypes, params->ptypes, src,
832 ICE_FLOW_PTYPE_MAX);
833
834
835 params->attr = ice_attr_gtpu_up;
836 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
837 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
838 src = (const unsigned long *)ice_ptypes_gtpu;
839 bitmap_and(params->ptypes, params->ptypes, src,
840 ICE_FLOW_PTYPE_MAX);
841
842
843 params->attr = ice_attr_gtpu_eh;
844 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
845 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
846 src = (const unsigned long *)ice_ptypes_gtpu;
847 bitmap_and(params->ptypes, params->ptypes, src,
848 ICE_FLOW_PTYPE_MAX);
849 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
850 src = (const unsigned long *)ice_ptypes_l2tpv3;
851 bitmap_and(params->ptypes, params->ptypes, src,
852 ICE_FLOW_PTYPE_MAX);
853 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
854 src = (const unsigned long *)ice_ptypes_esp;
855 bitmap_and(params->ptypes, params->ptypes, src,
856 ICE_FLOW_PTYPE_MAX);
857 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
858 src = (const unsigned long *)ice_ptypes_ah;
859 bitmap_and(params->ptypes, params->ptypes, src,
860 ICE_FLOW_PTYPE_MAX);
861 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
862 src = (const unsigned long *)ice_ptypes_nat_t_esp;
863 bitmap_and(params->ptypes, params->ptypes, src,
864 ICE_FLOW_PTYPE_MAX);
865 }
866
867 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
868 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
869 src = (const unsigned long *)ice_ptypes_pfcp_node;
870 else
871 src = (const unsigned long *)ice_ptypes_pfcp_session;
872
873 bitmap_and(params->ptypes, params->ptypes, src,
874 ICE_FLOW_PTYPE_MAX);
875 } else {
876 src = (const unsigned long *)ice_ptypes_pfcp_node;
877 bitmap_andnot(params->ptypes, params->ptypes, src,
878 ICE_FLOW_PTYPE_MAX);
879
880 src = (const unsigned long *)ice_ptypes_pfcp_session;
881 bitmap_andnot(params->ptypes, params->ptypes, src,
882 ICE_FLOW_PTYPE_MAX);
883 }
884 }
885
886 return 0;
887}
888
889
890
891
892
893
894
895
896
897
898
899
900
901static enum ice_status
902ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
903 u8 seg, enum ice_flow_field fld, u64 match)
904{
905 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
906 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
907 u8 fv_words = hw->blk[params->blk].es.fvw;
908 struct ice_flow_fld_info *flds;
909 u16 cnt, ese_bits, i;
910 u16 sib_mask = 0;
911 u16 mask;
912 u16 off;
913
914 flds = params->prof->segs[seg].fields;
915
916 switch (fld) {
917 case ICE_FLOW_FIELD_IDX_ETH_DA:
918 case ICE_FLOW_FIELD_IDX_ETH_SA:
919 case ICE_FLOW_FIELD_IDX_S_VLAN:
920 case ICE_FLOW_FIELD_IDX_C_VLAN:
921 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
922 break;
923 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
924 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
925 break;
926 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
927 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
928 break;
929 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
930 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
931 break;
932 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
933 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
934 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
935
936
937
938
939
940 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
941 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
942 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
943 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
944
945
946
947
948 if (match & BIT(sib))
949 sib_mask = ice_flds_info[sib].mask;
950 break;
951 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
952 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
953 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
954
955
956
957
958
959 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
960 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
961 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
962 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
963
964
965
966
967 if (match & BIT(sib))
968 sib_mask = ice_flds_info[sib].mask;
969 break;
970 case ICE_FLOW_FIELD_IDX_IPV4_SA:
971 case ICE_FLOW_FIELD_IDX_IPV4_DA:
972 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
973 break;
974 case ICE_FLOW_FIELD_IDX_IPV6_SA:
975 case ICE_FLOW_FIELD_IDX_IPV6_DA:
976 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
977 break;
978 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
979 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
980 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
981 prot_id = ICE_PROT_TCP_IL;
982 break;
983 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
984 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
985 prot_id = ICE_PROT_UDP_IL_OR_S;
986 break;
987 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
988 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
989 prot_id = ICE_PROT_SCTP_IL;
990 break;
991 case ICE_FLOW_FIELD_IDX_GTPC_TEID:
992 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
993 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
994 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
995 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
996 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
997
998 prot_id = ICE_PROT_UDP_OF;
999 break;
1000 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
1001 prot_id = ICE_PROT_PPPOE;
1002 break;
1003 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1004 prot_id = ICE_PROT_UDP_IL_OR_S;
1005 break;
1006 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1007 prot_id = ICE_PROT_L2TPV3;
1008 break;
1009 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1010 prot_id = ICE_PROT_ESP_F;
1011 break;
1012 case ICE_FLOW_FIELD_IDX_AH_SPI:
1013 prot_id = ICE_PROT_ESP_2;
1014 break;
1015 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1016 prot_id = ICE_PROT_UDP_IL_OR_S;
1017 break;
1018 case ICE_FLOW_FIELD_IDX_ARP_SIP:
1019 case ICE_FLOW_FIELD_IDX_ARP_DIP:
1020 case ICE_FLOW_FIELD_IDX_ARP_SHA:
1021 case ICE_FLOW_FIELD_IDX_ARP_DHA:
1022 case ICE_FLOW_FIELD_IDX_ARP_OP:
1023 prot_id = ICE_PROT_ARP_OF;
1024 break;
1025 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1026 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1027
1028 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1029 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1030 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1031 ICE_FLOW_FIELD_IDX_ICMP_CODE :
1032 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1033 break;
1034 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1035 prot_id = ICE_PROT_GRE_OF;
1036 break;
1037 default:
1038 return ICE_ERR_NOT_IMPL;
1039 }
1040
1041
1042
1043
1044 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1045
1046 flds[fld].xtrct.prot_id = prot_id;
1047 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1048 ICE_FLOW_FV_EXTRACT_SZ;
1049 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1050 flds[fld].xtrct.idx = params->es_cnt;
1051 flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1052
1053
1054
1055
1056 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1057 ese_bits);
1058
1059
1060 off = flds[fld].xtrct.off;
1061 mask = flds[fld].xtrct.mask;
1062 for (i = 0; i < cnt; i++) {
1063
1064
1065
1066
1067 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1068 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1069 flds[sib].xtrct.off != off) {
1070 u8 idx;
1071
1072
1073
1074
1075 if (params->es_cnt >= fv_words)
1076 return ICE_ERR_MAX_LIMIT;
1077
1078
1079 if (hw->blk[params->blk].es.reverse)
1080 idx = fv_words - params->es_cnt - 1;
1081 else
1082 idx = params->es_cnt;
1083
1084 params->es[idx].prot_id = prot_id;
1085 params->es[idx].off = off;
1086 params->mask[idx] = mask | sib_mask;
1087 params->es_cnt++;
1088 }
1089
1090 off += ICE_FLOW_FV_EXTRACT_SZ;
1091 }
1092
1093 return 0;
1094}
1095
1096
1097
1098
1099
1100
1101
1102static enum ice_status
1103ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1104 u8 seg)
1105{
1106 u16 fv_words;
1107 u16 hdrs_sz;
1108 u8 i;
1109
1110 if (!params->prof->segs[seg].raws_cnt)
1111 return 0;
1112
1113 if (params->prof->segs[seg].raws_cnt >
1114 ARRAY_SIZE(params->prof->segs[seg].raws))
1115 return ICE_ERR_MAX_LIMIT;
1116
1117
1118 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1119 if (!hdrs_sz)
1120 return ICE_ERR_PARAM;
1121
1122 fv_words = hw->blk[params->blk].es.fvw;
1123
1124 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1125 struct ice_flow_seg_fld_raw *raw;
1126 u16 off, cnt, j;
1127
1128 raw = ¶ms->prof->segs[seg].raws[i];
1129
1130
1131 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1132 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1133 ICE_FLOW_FV_EXTRACT_SZ;
1134 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1135 BITS_PER_BYTE;
1136 raw->info.xtrct.idx = params->es_cnt;
1137
1138
1139
1140
1141 cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1142 (raw->info.src.last * BITS_PER_BYTE),
1143 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1144 off = raw->info.xtrct.off;
1145 for (j = 0; j < cnt; j++) {
1146 u16 idx;
1147
1148
1149
1150
1151 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1152 params->es_cnt >= ICE_MAX_FV_WORDS)
1153 return ICE_ERR_MAX_LIMIT;
1154
1155
1156 if (hw->blk[params->blk].es.reverse)
1157 idx = fv_words - params->es_cnt - 1;
1158 else
1159 idx = params->es_cnt;
1160
1161 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1162 params->es[idx].off = off;
1163 params->es_cnt++;
1164 off += ICE_FLOW_FV_EXTRACT_SZ;
1165 }
1166 }
1167
1168 return 0;
1169}
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179static enum ice_status
1180ice_flow_create_xtrct_seq(struct ice_hw *hw,
1181 struct ice_flow_prof_params *params)
1182{
1183 struct ice_flow_prof *prof = params->prof;
1184 enum ice_status status = 0;
1185 u8 i;
1186
1187 for (i = 0; i < prof->segs_cnt; i++) {
1188 u64 match = params->prof->segs[i].match;
1189 enum ice_flow_field j;
1190
1191 for_each_set_bit(j, (unsigned long *)&match,
1192 ICE_FLOW_FIELD_IDX_MAX) {
1193 status = ice_flow_xtract_fld(hw, params, i, j, match);
1194 if (status)
1195 return status;
1196 clear_bit(j, (unsigned long *)&match);
1197 }
1198
1199
1200 status = ice_flow_xtract_raws(hw, params, i);
1201 if (status)
1202 return status;
1203 }
1204
1205 return status;
1206}
1207
1208
1209
1210
1211
1212
1213static enum ice_status
1214ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1215{
1216 enum ice_status status;
1217
1218 status = ice_flow_proc_seg_hdrs(params);
1219 if (status)
1220 return status;
1221
1222 status = ice_flow_create_xtrct_seq(hw, params);
1223 if (status)
1224 return status;
1225
1226 switch (params->blk) {
1227 case ICE_BLK_FD:
1228 case ICE_BLK_RSS:
1229 status = 0;
1230 break;
1231 default:
1232 return ICE_ERR_NOT_IMPL;
1233 }
1234
1235 return status;
1236}
1237
1238#define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
1239#define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
1240#define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252static struct ice_flow_prof *
1253ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1254 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1255 u8 segs_cnt, u16 vsi_handle, u32 conds)
1256{
1257 struct ice_flow_prof *p, *prof = NULL;
1258
1259 mutex_lock(&hw->fl_profs_locks[blk]);
1260 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1261 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1262 segs_cnt && segs_cnt == p->segs_cnt) {
1263 u8 i;
1264
1265
1266 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1267 ice_is_vsi_valid(hw, vsi_handle) &&
1268 !test_bit(vsi_handle, p->vsis))
1269 continue;
1270
1271
1272
1273
1274 for (i = 0; i < segs_cnt; i++)
1275 if (segs[i].hdrs != p->segs[i].hdrs ||
1276 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1277 segs[i].match != p->segs[i].match))
1278 break;
1279
1280
1281 if (i == segs_cnt) {
1282 prof = p;
1283 break;
1284 }
1285 }
1286 mutex_unlock(&hw->fl_profs_locks[blk]);
1287
1288 return prof;
1289}
1290
1291
1292
1293
1294
1295
1296
1297static struct ice_flow_prof *
1298ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1299{
1300 struct ice_flow_prof *p;
1301
1302 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1303 if (p->id == prof_id)
1304 return p;
1305
1306 return NULL;
1307}
1308
1309
1310
1311
1312
1313
1314static void
1315ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1316{
1317 if (!entry)
1318 return;
1319
1320 if (entry->entry)
1321 devm_kfree(ice_hw_to_dev(hw), entry->entry);
1322
1323 devm_kfree(ice_hw_to_dev(hw), entry);
1324}
1325
1326
1327
1328
1329
1330
1331
1332static enum ice_status
1333ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1334 struct ice_flow_entry *entry)
1335{
1336 if (!entry)
1337 return ICE_ERR_BAD_PTR;
1338
1339 list_del(&entry->l_entry);
1340
1341 ice_dealloc_flow_entry(hw, entry);
1342
1343 return 0;
1344}
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358static enum ice_status
1359ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1360 enum ice_flow_dir dir, u64 prof_id,
1361 struct ice_flow_seg_info *segs, u8 segs_cnt,
1362 struct ice_flow_prof **prof)
1363{
1364 struct ice_flow_prof_params *params;
1365 enum ice_status status;
1366 u8 i;
1367
1368 if (!prof)
1369 return ICE_ERR_BAD_PTR;
1370
1371 params = kzalloc(sizeof(*params), GFP_KERNEL);
1372 if (!params)
1373 return ICE_ERR_NO_MEMORY;
1374
1375 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1376 GFP_KERNEL);
1377 if (!params->prof) {
1378 status = ICE_ERR_NO_MEMORY;
1379 goto free_params;
1380 }
1381
1382
1383 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1384 params->es[i].prot_id = ICE_PROT_INVALID;
1385 params->es[i].off = ICE_FV_OFFSET_INVAL;
1386 }
1387
1388 params->blk = blk;
1389 params->prof->id = prof_id;
1390 params->prof->dir = dir;
1391 params->prof->segs_cnt = segs_cnt;
1392
1393
1394
1395
1396 for (i = 0; i < segs_cnt; i++)
1397 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1398
1399 status = ice_flow_proc_segs(hw, params);
1400 if (status) {
1401 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1402 goto out;
1403 }
1404
1405
1406 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1407 params->attr, params->attr_cnt, params->es,
1408 params->mask);
1409 if (status) {
1410 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1411 goto out;
1412 }
1413
1414 INIT_LIST_HEAD(¶ms->prof->entries);
1415 mutex_init(¶ms->prof->entries_lock);
1416 *prof = params->prof;
1417
1418out:
1419 if (status)
1420 devm_kfree(ice_hw_to_dev(hw), params->prof);
1421free_params:
1422 kfree(params);
1423
1424 return status;
1425}
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435static enum ice_status
1436ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1437 struct ice_flow_prof *prof)
1438{
1439 enum ice_status status;
1440
1441
1442 if (!list_empty(&prof->entries)) {
1443 struct ice_flow_entry *e, *t;
1444
1445 mutex_lock(&prof->entries_lock);
1446
1447 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1448 status = ice_flow_rem_entry_sync(hw, blk, e);
1449 if (status)
1450 break;
1451 }
1452
1453 mutex_unlock(&prof->entries_lock);
1454 }
1455
1456
1457 status = ice_rem_prof(hw, blk, prof->id);
1458 if (!status) {
1459 list_del(&prof->l_entry);
1460 mutex_destroy(&prof->entries_lock);
1461 devm_kfree(ice_hw_to_dev(hw), prof);
1462 }
1463
1464 return status;
1465}
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477static enum ice_status
1478ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1479 struct ice_flow_prof *prof, u16 vsi_handle)
1480{
1481 enum ice_status status = 0;
1482
1483 if (!test_bit(vsi_handle, prof->vsis)) {
1484 status = ice_add_prof_id_flow(hw, blk,
1485 ice_get_hw_vsi_num(hw,
1486 vsi_handle),
1487 prof->id);
1488 if (!status)
1489 set_bit(vsi_handle, prof->vsis);
1490 else
1491 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1492 status);
1493 }
1494
1495 return status;
1496}
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508static enum ice_status
1509ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1510 struct ice_flow_prof *prof, u16 vsi_handle)
1511{
1512 enum ice_status status = 0;
1513
1514 if (test_bit(vsi_handle, prof->vsis)) {
1515 status = ice_rem_prof_id_flow(hw, blk,
1516 ice_get_hw_vsi_num(hw,
1517 vsi_handle),
1518 prof->id);
1519 if (!status)
1520 clear_bit(vsi_handle, prof->vsis);
1521 else
1522 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1523 status);
1524 }
1525
1526 return status;
1527}
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539enum ice_status
1540ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1541 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1542 struct ice_flow_prof **prof)
1543{
1544 enum ice_status status;
1545
1546 if (segs_cnt > ICE_FLOW_SEG_MAX)
1547 return ICE_ERR_MAX_LIMIT;
1548
1549 if (!segs_cnt)
1550 return ICE_ERR_PARAM;
1551
1552 if (!segs)
1553 return ICE_ERR_BAD_PTR;
1554
1555 status = ice_flow_val_hdrs(segs, segs_cnt);
1556 if (status)
1557 return status;
1558
1559 mutex_lock(&hw->fl_profs_locks[blk]);
1560
1561 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1562 prof);
1563 if (!status)
1564 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1565
1566 mutex_unlock(&hw->fl_profs_locks[blk]);
1567
1568 return status;
1569}
1570
1571
1572
1573
1574
1575
1576
1577enum ice_status
1578ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1579{
1580 struct ice_flow_prof *prof;
1581 enum ice_status status;
1582
1583 mutex_lock(&hw->fl_profs_locks[blk]);
1584
1585 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1586 if (!prof) {
1587 status = ICE_ERR_DOES_NOT_EXIST;
1588 goto out;
1589 }
1590
1591
1592 status = ice_flow_rem_prof_sync(hw, blk, prof);
1593
1594out:
1595 mutex_unlock(&hw->fl_profs_locks[blk]);
1596
1597 return status;
1598}
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611enum ice_status
1612ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1613 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1614 void *data, u64 *entry_h)
1615{
1616 struct ice_flow_entry *e = NULL;
1617 struct ice_flow_prof *prof;
1618 enum ice_status status;
1619
1620
1621 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1622 return ICE_ERR_BAD_PTR;
1623
1624 if (!ice_is_vsi_valid(hw, vsi_handle))
1625 return ICE_ERR_PARAM;
1626
1627 mutex_lock(&hw->fl_profs_locks[blk]);
1628
1629 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1630 if (!prof) {
1631 status = ICE_ERR_DOES_NOT_EXIST;
1632 } else {
1633
1634
1635
1636 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1637 if (!e)
1638 status = ICE_ERR_NO_MEMORY;
1639 else
1640 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1641 }
1642
1643 mutex_unlock(&hw->fl_profs_locks[blk]);
1644 if (status)
1645 goto out;
1646
1647 e->id = entry_id;
1648 e->vsi_handle = vsi_handle;
1649 e->prof = prof;
1650 e->priority = prio;
1651
1652 switch (blk) {
1653 case ICE_BLK_FD:
1654 case ICE_BLK_RSS:
1655 break;
1656 default:
1657 status = ICE_ERR_NOT_IMPL;
1658 goto out;
1659 }
1660
1661 mutex_lock(&prof->entries_lock);
1662 list_add(&e->l_entry, &prof->entries);
1663 mutex_unlock(&prof->entries_lock);
1664
1665 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1666
1667out:
1668 if (status && e) {
1669 if (e->entry)
1670 devm_kfree(ice_hw_to_dev(hw), e->entry);
1671 devm_kfree(ice_hw_to_dev(hw), e);
1672 }
1673
1674 return status;
1675}
1676
1677
1678
1679
1680
1681
1682
1683enum ice_status ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk,
1684 u64 entry_h)
1685{
1686 struct ice_flow_entry *entry;
1687 struct ice_flow_prof *prof;
1688 enum ice_status status = 0;
1689
1690 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1691 return ICE_ERR_PARAM;
1692
1693 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1694
1695
1696 prof = entry->prof;
1697
1698 if (prof) {
1699 mutex_lock(&prof->entries_lock);
1700 status = ice_flow_rem_entry_sync(hw, blk, entry);
1701 mutex_unlock(&prof->entries_lock);
1702 }
1703
1704 return status;
1705}
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730static void
1731ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1732 enum ice_flow_fld_match_type field_type, u16 val_loc,
1733 u16 mask_loc, u16 last_loc)
1734{
1735 u64 bit = BIT_ULL(fld);
1736
1737 seg->match |= bit;
1738 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1739 seg->range |= bit;
1740
1741 seg->fields[fld].type = field_type;
1742 seg->fields[fld].src.val = val_loc;
1743 seg->fields[fld].src.mask = mask_loc;
1744 seg->fields[fld].src.last = last_loc;
1745
1746 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1747}
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769void
1770ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1771 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1772{
1773 enum ice_flow_fld_match_type t = range ?
1774 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1775
1776 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1777}
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796void
1797ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1798 u16 val_loc, u16 mask_loc)
1799{
1800 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1801 seg->raws[seg->raws_cnt].off = off;
1802 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1803 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1804 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1805
1806 seg->raws[seg->raws_cnt].info.src.last = len;
1807 }
1808
1809
1810
1811
1812 seg->raws_cnt++;
1813}
1814
1815#define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1816 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1817
1818#define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1819 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1820
1821#define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1822 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1823
1824#define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1825 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1826 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1827 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839static enum ice_status
1840ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1841 u32 flow_hdr)
1842{
1843 u64 val;
1844 u8 i;
1845
1846 for_each_set_bit(i, (unsigned long *)&hash_fields,
1847 ICE_FLOW_FIELD_IDX_MAX)
1848 ice_flow_set_fld(segs, (enum ice_flow_field)i,
1849 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1850 ICE_FLOW_FLD_OFF_INVAL, false);
1851
1852 ICE_FLOW_SET_HDRS(segs, flow_hdr);
1853
1854 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1855 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1856 return ICE_ERR_PARAM;
1857
1858 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1859 if (val && !is_power_of_2(val))
1860 return ICE_ERR_CFG;
1861
1862 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1863 if (val && !is_power_of_2(val))
1864 return ICE_ERR_CFG;
1865
1866 return 0;
1867}
1868
1869
1870
1871
1872
1873
1874
1875
1876void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1877{
1878 struct ice_rss_cfg *r, *tmp;
1879
1880 if (list_empty(&hw->rss_list_head))
1881 return;
1882
1883 mutex_lock(&hw->rss_locks);
1884 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1885 if (test_and_clear_bit(vsi_handle, r->vsis))
1886 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1887 list_del(&r->l_entry);
1888 devm_kfree(ice_hw_to_dev(hw), r);
1889 }
1890 mutex_unlock(&hw->rss_locks);
1891}
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1903{
1904 const enum ice_block blk = ICE_BLK_RSS;
1905 struct ice_flow_prof *p, *t;
1906 enum ice_status status = 0;
1907
1908 if (!ice_is_vsi_valid(hw, vsi_handle))
1909 return ICE_ERR_PARAM;
1910
1911 if (list_empty(&hw->fl_profs[blk]))
1912 return 0;
1913
1914 mutex_lock(&hw->rss_locks);
1915 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1916 if (test_bit(vsi_handle, p->vsis)) {
1917 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1918 if (status)
1919 break;
1920
1921 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1922 status = ice_flow_rem_prof(hw, blk, p->id);
1923 if (status)
1924 break;
1925 }
1926 }
1927 mutex_unlock(&hw->rss_locks);
1928
1929 return status;
1930}
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940static void
1941ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1942{
1943 struct ice_rss_cfg *r, *tmp;
1944
1945
1946
1947
1948
1949 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1950 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1951 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1952 clear_bit(vsi_handle, r->vsis);
1953 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1954 list_del(&r->l_entry);
1955 devm_kfree(ice_hw_to_dev(hw), r);
1956 }
1957 return;
1958 }
1959}
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969static enum ice_status
1970ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1971{
1972 struct ice_rss_cfg *r, *rss_cfg;
1973
1974 list_for_each_entry(r, &hw->rss_list_head, l_entry)
1975 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1976 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1977 set_bit(vsi_handle, r->vsis);
1978 return 0;
1979 }
1980
1981 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
1982 GFP_KERNEL);
1983 if (!rss_cfg)
1984 return ICE_ERR_NO_MEMORY;
1985
1986 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
1987 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
1988 set_bit(vsi_handle, rss_cfg->vsis);
1989
1990 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
1991
1992 return 0;
1993}
1994
1995#define ICE_FLOW_PROF_HASH_S 0
1996#define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
1997#define ICE_FLOW_PROF_HDR_S 32
1998#define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
1999#define ICE_FLOW_PROF_ENCAP_S 63
2000#define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2001
2002#define ICE_RSS_OUTER_HEADERS 1
2003#define ICE_RSS_INNER_HEADERS 2
2004
2005
2006
2007
2008
2009
2010#define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2011 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2012 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2013 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025static enum ice_status
2026ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2027 u32 addl_hdrs, u8 segs_cnt)
2028{
2029 const enum ice_block blk = ICE_BLK_RSS;
2030 struct ice_flow_prof *prof = NULL;
2031 struct ice_flow_seg_info *segs;
2032 enum ice_status status;
2033
2034 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2035 return ICE_ERR_PARAM;
2036
2037 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2038 if (!segs)
2039 return ICE_ERR_NO_MEMORY;
2040
2041
2042 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2043 addl_hdrs);
2044 if (status)
2045 goto exit;
2046
2047
2048
2049
2050
2051 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2052 vsi_handle,
2053 ICE_FLOW_FIND_PROF_CHK_FLDS |
2054 ICE_FLOW_FIND_PROF_CHK_VSI);
2055 if (prof)
2056 goto exit;
2057
2058
2059
2060
2061
2062
2063 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2064 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2065 if (prof) {
2066 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2067 if (!status)
2068 ice_rem_rss_list(hw, vsi_handle, prof);
2069 else
2070 goto exit;
2071
2072
2073 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2074 status = ice_flow_rem_prof(hw, blk, prof->id);
2075 if (status)
2076 goto exit;
2077 }
2078 }
2079
2080
2081
2082
2083 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2084 vsi_handle,
2085 ICE_FLOW_FIND_PROF_CHK_FLDS);
2086 if (prof) {
2087 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2088 if (!status)
2089 status = ice_add_rss_list(hw, vsi_handle, prof);
2090 goto exit;
2091 }
2092
2093
2094
2095
2096 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2097 ICE_FLOW_GEN_PROFID(hashed_flds,
2098 segs[segs_cnt - 1].hdrs,
2099 segs_cnt),
2100 segs, segs_cnt, &prof);
2101 if (status)
2102 goto exit;
2103
2104 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2105
2106
2107
2108 if (status) {
2109 ice_flow_rem_prof(hw, blk, prof->id);
2110 goto exit;
2111 }
2112
2113 status = ice_add_rss_list(hw, vsi_handle, prof);
2114
2115exit:
2116 kfree(segs);
2117 return status;
2118}
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131enum ice_status
2132ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2133 u32 addl_hdrs)
2134{
2135 enum ice_status status;
2136
2137 if (hashed_flds == ICE_HASH_INVALID ||
2138 !ice_is_vsi_valid(hw, vsi_handle))
2139 return ICE_ERR_PARAM;
2140
2141 mutex_lock(&hw->rss_locks);
2142 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2143 ICE_RSS_OUTER_HEADERS);
2144 if (!status)
2145 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2146 addl_hdrs, ICE_RSS_INNER_HEADERS);
2147 mutex_unlock(&hw->rss_locks);
2148
2149 return status;
2150}
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162static enum ice_status
2163ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2164 u32 addl_hdrs, u8 segs_cnt)
2165{
2166 const enum ice_block blk = ICE_BLK_RSS;
2167 struct ice_flow_seg_info *segs;
2168 struct ice_flow_prof *prof;
2169 enum ice_status status;
2170
2171 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2172 if (!segs)
2173 return ICE_ERR_NO_MEMORY;
2174
2175
2176 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2177 addl_hdrs);
2178 if (status)
2179 goto out;
2180
2181 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2182 vsi_handle,
2183 ICE_FLOW_FIND_PROF_CHK_FLDS);
2184 if (!prof) {
2185 status = ICE_ERR_DOES_NOT_EXIST;
2186 goto out;
2187 }
2188
2189 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2190 if (status)
2191 goto out;
2192
2193
2194
2195
2196 ice_rem_rss_list(hw, vsi_handle, prof);
2197
2198 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2199 status = ice_flow_rem_prof(hw, blk, prof->id);
2200
2201out:
2202 kfree(segs);
2203 return status;
2204}
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219enum ice_status __maybe_unused
2220ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2221 u32 addl_hdrs)
2222{
2223 enum ice_status status;
2224
2225 if (hashed_flds == ICE_HASH_INVALID ||
2226 !ice_is_vsi_valid(hw, vsi_handle))
2227 return ICE_ERR_PARAM;
2228
2229 mutex_lock(&hw->rss_locks);
2230 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2231 ICE_RSS_OUTER_HEADERS);
2232 if (!status)
2233 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2234 addl_hdrs, ICE_RSS_INNER_HEADERS);
2235 mutex_unlock(&hw->rss_locks);
2236
2237 return status;
2238}
2239
2240
2241
2242
2243
2244#define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2245 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2246 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2247#define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2248 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2249 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2250#define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2251 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2252 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2253 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2254#define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2255 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2256 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2257
2258#define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2259 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2260 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2261#define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2262 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2263 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2264 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2265#define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2266 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2267 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2268#define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2269 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2270 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282enum ice_status
2283ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2284{
2285 enum ice_status status = 0;
2286 u64 hash_flds;
2287
2288 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2289 !ice_is_vsi_valid(hw, vsi_handle))
2290 return ICE_ERR_PARAM;
2291
2292
2293 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2294 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2295 return ICE_ERR_CFG;
2296
2297 hash_flds = avf_hash;
2298
2299
2300 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2301 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2302
2303 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2304 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2305
2306
2307 while (hash_flds) {
2308 u64 rss_hash = ICE_HASH_INVALID;
2309
2310 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2311 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2312 rss_hash = ICE_FLOW_HASH_IPV4;
2313 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2314 } else if (hash_flds &
2315 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2316 rss_hash = ICE_FLOW_HASH_IPV4 |
2317 ICE_FLOW_HASH_TCP_PORT;
2318 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2319 } else if (hash_flds &
2320 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2321 rss_hash = ICE_FLOW_HASH_IPV4 |
2322 ICE_FLOW_HASH_UDP_PORT;
2323 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2324 } else if (hash_flds &
2325 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2326 rss_hash = ICE_FLOW_HASH_IPV4 |
2327 ICE_FLOW_HASH_SCTP_PORT;
2328 hash_flds &=
2329 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2330 }
2331 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2332 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2333 rss_hash = ICE_FLOW_HASH_IPV6;
2334 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2335 } else if (hash_flds &
2336 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2337 rss_hash = ICE_FLOW_HASH_IPV6 |
2338 ICE_FLOW_HASH_TCP_PORT;
2339 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2340 } else if (hash_flds &
2341 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2342 rss_hash = ICE_FLOW_HASH_IPV6 |
2343 ICE_FLOW_HASH_UDP_PORT;
2344 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2345 } else if (hash_flds &
2346 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2347 rss_hash = ICE_FLOW_HASH_IPV6 |
2348 ICE_FLOW_HASH_SCTP_PORT;
2349 hash_flds &=
2350 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2351 }
2352 }
2353
2354 if (rss_hash == ICE_HASH_INVALID)
2355 return ICE_ERR_OUT_OF_RANGE;
2356
2357 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2358 ICE_FLOW_SEG_HDR_NONE);
2359 if (status)
2360 break;
2361 }
2362
2363 return status;
2364}
2365
2366
2367
2368
2369
2370
2371enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2372{
2373 enum ice_status status = 0;
2374 struct ice_rss_cfg *r;
2375
2376 if (!ice_is_vsi_valid(hw, vsi_handle))
2377 return ICE_ERR_PARAM;
2378
2379 mutex_lock(&hw->rss_locks);
2380 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2381 if (test_bit(vsi_handle, r->vsis)) {
2382 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2383 r->hashed_flds,
2384 r->packet_hdr,
2385 ICE_RSS_OUTER_HEADERS);
2386 if (status)
2387 break;
2388 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2389 r->hashed_flds,
2390 r->packet_hdr,
2391 ICE_RSS_INNER_HEADERS);
2392 if (status)
2393 break;
2394 }
2395 }
2396 mutex_unlock(&hw->rss_locks);
2397
2398 return status;
2399}
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2411{
2412 u64 rss_hash = ICE_HASH_INVALID;
2413 struct ice_rss_cfg *r;
2414
2415
2416 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2417 return ICE_HASH_INVALID;
2418
2419 mutex_lock(&hw->rss_locks);
2420 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2421 if (test_bit(vsi_handle, r->vsis) &&
2422 r->packet_hdr == hdrs) {
2423 rss_hash = r->hashed_flds;
2424 break;
2425 }
2426 mutex_unlock(&hw->rss_locks);
2427
2428 return rss_hash;
2429}
2430