crypto/qat: support DOCSIS protocol
[dpdk.git] / drivers / net / iavf / iavf_hash.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4
5 #include <sys/queue.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12
13 #include <rte_debug.h>
14 #include <rte_ether.h>
15 #include <rte_ethdev_driver.h>
16 #include <rte_log.h>
17 #include <rte_malloc.h>
18 #include <rte_eth_ctrl.h>
19 #include <rte_tailq.h>
20 #include <rte_flow_driver.h>
21
22 #include "iavf_log.h"
23 #include "iavf.h"
24 #include "iavf_generic_flow.h"
25
26 enum iavf_pattern_hint_type {
27         IAVF_PATTERN_HINT_NONE,
28         IAVF_PATTERN_HINT_IPV4,
29         IAVF_PATTERN_HINT_IPV4_UDP,
30         IAVF_PATTERN_HINT_IPV4_TCP,
31         IAVF_PATTERN_HINT_IPV4_SCTP,
32         IAVF_PATTERN_HINT_IPV6,
33         IAVF_PATTERN_HINT_IPV6_UDP,
34         IAVF_PATTERN_HINT_IPV6_TCP,
35         IAVF_PATTERN_HINT_IPV6_SCTP,
36 };
37
38 enum iavf_gtpu_hint {
39         IAVF_GTPU_HINT_DOWNLINK,
40         IAVF_GTPU_HINT_UPLINK,
41         IAVF_GTPU_HINT_NONE,
42 };
43
44 struct iavf_pattern_match_type {
45         enum iavf_pattern_hint_type phint_type;
46 };
47
48 struct iavf_hash_match_type {
49         enum iavf_pattern_hint_type phint_type;
50         uint64_t hash_type;
51         struct virtchnl_proto_hdrs *proto_hdrs;
52         enum iavf_gtpu_hint gtpu_hint;
53 };
54
55 struct iavf_rss_meta {
56         struct virtchnl_proto_hdrs *proto_hdrs;
57         enum virtchnl_rss_algorithm rss_algorithm;
58 };
59
60 struct iavf_hash_flow_cfg {
61         struct virtchnl_rss_cfg *rss_cfg;
62         bool simple_xor;
63 };
64
65 static int
66 iavf_hash_init(struct iavf_adapter *ad);
67 static int
68 iavf_hash_create(struct iavf_adapter *ad, struct rte_flow *flow, void *meta,
69                  struct rte_flow_error *error);
70 static int
71 iavf_hash_destroy(struct iavf_adapter *ad, struct rte_flow *flow,
72                   struct rte_flow_error *error);
73 static void
74 iavf_hash_uninit(struct iavf_adapter *ad);
75 static void
76 iavf_hash_free(struct rte_flow *flow);
77 static int
78 iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
79                                struct iavf_pattern_match_item *array,
80                                uint32_t array_len,
81                                const struct rte_flow_item pattern[],
82                                const struct rte_flow_action actions[],
83                                void **meta,
84                                struct rte_flow_error *error);
85
86 struct iavf_pattern_match_type phint_empty = {
87         IAVF_PATTERN_HINT_NONE};
88 struct iavf_pattern_match_type phint_eth_ipv4 = {
89         IAVF_PATTERN_HINT_IPV4};
90 struct iavf_pattern_match_type phint_eth_ipv4_udp = {
91         IAVF_PATTERN_HINT_IPV4_UDP};
92 struct iavf_pattern_match_type phint_eth_ipv4_tcp = {
93         IAVF_PATTERN_HINT_IPV4_TCP};
94 struct iavf_pattern_match_type phint_eth_ipv4_sctp = {
95         IAVF_PATTERN_HINT_IPV4_SCTP};
96 struct iavf_pattern_match_type phint_eth_ipv4_gtpu_eh = {
97         IAVF_PATTERN_HINT_IPV4_UDP};
98 struct iavf_pattern_match_type phint_eth_ipv4_esp = {
99         IAVF_PATTERN_HINT_IPV4};
100 struct iavf_pattern_match_type phint_eth_ipv4_ah = {
101         IAVF_PATTERN_HINT_IPV4};
102 struct iavf_pattern_match_type phint_eth_ipv4_l2tpv3 = {
103         IAVF_PATTERN_HINT_IPV4};
104 struct iavf_pattern_match_type phint_eth_ipv4_pfcp = {
105         IAVF_PATTERN_HINT_IPV4_UDP};
106 struct iavf_pattern_match_type phint_eth_ipv6 = {
107         IAVF_PATTERN_HINT_IPV6};
108 struct iavf_pattern_match_type phint_eth_ipv6_udp = {
109         IAVF_PATTERN_HINT_IPV6_UDP};
110 struct iavf_pattern_match_type phint_eth_ipv6_tcp = {
111         IAVF_PATTERN_HINT_IPV6_TCP};
112 struct iavf_pattern_match_type phint_eth_ipv6_sctp = {
113         IAVF_PATTERN_HINT_IPV6_SCTP};
114 struct iavf_pattern_match_type phint_eth_ipv6_esp = {
115         IAVF_PATTERN_HINT_IPV6};
116 struct iavf_pattern_match_type phint_eth_ipv6_ah = {
117         IAVF_PATTERN_HINT_IPV6};
118 struct iavf_pattern_match_type phint_eth_ipv6_l2tpv3 = {
119         IAVF_PATTERN_HINT_IPV6};
120 struct iavf_pattern_match_type phint_eth_ipv6_pfcp = {
121         IAVF_PATTERN_HINT_IPV6_UDP};
122
123 /**
124  * Supported pattern for hash.
125  * The first member is pattern item type,
126  * the second member is input set mask,
127  * the third member is pattern hint for hash.
128  */
129 static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
130         {iavf_pattern_eth_ipv4, IAVF_INSET_NONE, &phint_eth_ipv4},
131         {iavf_pattern_eth_ipv4_udp, IAVF_INSET_NONE, &phint_eth_ipv4_udp},
132         {iavf_pattern_eth_ipv4_tcp, IAVF_INSET_NONE, &phint_eth_ipv4_tcp},
133         {iavf_pattern_eth_ipv4_sctp, IAVF_INSET_NONE, &phint_eth_ipv4_sctp},
134         {iavf_pattern_eth_ipv6, IAVF_INSET_NONE, &phint_eth_ipv6},
135         {iavf_pattern_eth_ipv4_gtpu_eh_ipv4, IAVF_INSET_NONE,
136                                                 &phint_eth_ipv4_gtpu_eh},
137         {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_udp, IAVF_INSET_NONE,
138                                                 &phint_eth_ipv4_gtpu_eh},
139         {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_tcp, IAVF_INSET_NONE,
140                                                 &phint_eth_ipv4_gtpu_eh},
141         {iavf_pattern_eth_ipv4_esp, IAVF_INSET_NONE, &phint_eth_ipv4_esp},
142         {iavf_pattern_eth_ipv4_ah, IAVF_INSET_NONE, &phint_eth_ipv4_ah},
143         {iavf_pattern_eth_ipv4_l2tpv3, IAVF_INSET_NONE,
144                                                 &phint_eth_ipv4_l2tpv3},
145         {iavf_pattern_eth_ipv4_pfcp, IAVF_INSET_NONE, &phint_eth_ipv4_pfcp},
146         {iavf_pattern_eth_ipv6_udp, IAVF_INSET_NONE, &phint_eth_ipv6_udp},
147         {iavf_pattern_eth_ipv6_tcp, IAVF_INSET_NONE, &phint_eth_ipv6_tcp},
148         {iavf_pattern_eth_ipv6_sctp, IAVF_INSET_NONE, &phint_eth_ipv6_sctp},
149         {iavf_pattern_eth_ipv6_esp, IAVF_INSET_NONE, &phint_eth_ipv6_esp},
150         {iavf_pattern_eth_ipv6_ah, IAVF_INSET_NONE, &phint_eth_ipv6_ah},
151         {iavf_pattern_eth_ipv6_l2tpv3, IAVF_INSET_NONE,
152                                                 &phint_eth_ipv6_l2tpv3},
153         {iavf_pattern_eth_ipv6_pfcp, IAVF_INSET_NONE, &phint_eth_ipv6_pfcp},
154         {iavf_pattern_empty, IAVF_INSET_NONE, &phint_empty},
155 };
156
157 #define TUNNEL_LEVEL_OUTER              0
158 #define TUNNEL_LEVEL_FIRST_INNER        1
159
160 #define PROTO_COUNT_ONE                 1
161 #define PROTO_COUNT_TWO                 2
162 #define PROTO_COUNT_THREE               3
163
164 #define BUFF_NOUSED                     0
165 #define FIELD_FOR_PROTO_ONLY            0
166
167 #define FIELD_SELECTOR(proto_hdr_field) \
168                 (1UL << ((proto_hdr_field) & PROTO_HDR_FIELD_MASK))
169
170 #define proto_hint_eth_src { \
171         VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC), \
172         {BUFF_NOUSED } }
173
174 #define proto_hint_eth_dst { \
175         VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), \
176         {BUFF_NOUSED } }
177
178 #define proto_hint_eth_only { \
179         VIRTCHNL_PROTO_HDR_ETH, FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
180
181 #define proto_hint_eth { \
182         VIRTCHNL_PROTO_HDR_ETH, \
183         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | \
184         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), {BUFF_NOUSED } }
185
186 #define proto_hint_svlan { \
187         VIRTCHNL_PROTO_HDR_S_VLAN, \
188         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), {BUFF_NOUSED } }
189
190 #define proto_hint_cvlan { \
191         VIRTCHNL_PROTO_HDR_C_VLAN, \
192         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), {BUFF_NOUSED } }
193
194 #define proto_hint_ipv4_src { \
195         VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC), \
196         {BUFF_NOUSED } }
197
198 #define proto_hint_ipv4_dst { \
199         VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), \
200         {BUFF_NOUSED } }
201
202 #define proto_hint_ipv4_only { \
203         VIRTCHNL_PROTO_HDR_IPV4, FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
204
205 #define proto_hint_ipv4 { \
206         VIRTCHNL_PROTO_HDR_IPV4, \
207         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
208         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), {BUFF_NOUSED } }
209
210 #define proto_hint_udp_src_port { \
211         VIRTCHNL_PROTO_HDR_UDP, \
212         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT), {BUFF_NOUSED } }
213
214 #define proto_hint_udp_dst_port { \
215         VIRTCHNL_PROTO_HDR_UDP, \
216         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), {BUFF_NOUSED } }
217
218 #define proto_hint_udp_only { \
219         VIRTCHNL_PROTO_HDR_UDP, FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
220
221 #define proto_hint_udp { \
222         VIRTCHNL_PROTO_HDR_UDP, \
223         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | \
224         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), {BUFF_NOUSED } }
225
226 #define proto_hint_tcp_src_port { \
227         VIRTCHNL_PROTO_HDR_TCP, \
228         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT), {BUFF_NOUSED } }
229
230 #define proto_hint_tcp_dst_port { \
231         VIRTCHNL_PROTO_HDR_TCP, \
232         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), {BUFF_NOUSED } }
233
234 #define proto_hint_tcp_only { \
235         VIRTCHNL_PROTO_HDR_TCP, FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
236
237 #define proto_hint_tcp { \
238         VIRTCHNL_PROTO_HDR_TCP, \
239         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | \
240         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), {BUFF_NOUSED } }
241
242 #define proto_hint_sctp_src_port { \
243         VIRTCHNL_PROTO_HDR_SCTP, \
244         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT), {BUFF_NOUSED } }
245
246 #define proto_hint_sctp_dst_port { \
247         VIRTCHNL_PROTO_HDR_SCTP, \
248         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), {BUFF_NOUSED } }
249
250 #define proto_hint_sctp_only { \
251         VIRTCHNL_PROTO_HDR_SCTP, FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
252
253 #define proto_hint_sctp { \
254         VIRTCHNL_PROTO_HDR_SCTP, \
255         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | \
256         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), {BUFF_NOUSED } }
257
258 #define proto_hint_ipv6_src { \
259         VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC), \
260         {BUFF_NOUSED } }
261
262 #define proto_hint_ipv6_dst { \
263         VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), \
264         {BUFF_NOUSED } }
265
266 #define proto_hint_ipv6_only { \
267         VIRTCHNL_PROTO_HDR_IPV6, FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
268
269 #define proto_hint_ipv6 { \
270         VIRTCHNL_PROTO_HDR_IPV6, \
271         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
272         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), {BUFF_NOUSED } }
273
274 #define proto_hint_gtpu_up_only { \
275         VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP, \
276         FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
277
278 #define proto_hint_gtpu_dwn_only { \
279         VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN, \
280         FIELD_FOR_PROTO_ONLY, {BUFF_NOUSED } }
281
282 #define proto_hint_esp { \
283         VIRTCHNL_PROTO_HDR_ESP, \
284         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), {BUFF_NOUSED } }
285
286 #define proto_hint_ah { \
287         VIRTCHNL_PROTO_HDR_AH, \
288         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), {BUFF_NOUSED } }
289
290 #define proto_hint_l2tpv3 { \
291         VIRTCHNL_PROTO_HDR_L2TPV3, \
292         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), {BUFF_NOUSED } }
293
294 #define proto_hint_pfcp { \
295         VIRTCHNL_PROTO_HDR_PFCP, \
296         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), {BUFF_NOUSED } }
297
298 struct virtchnl_proto_hdrs hdrs_hint_eth_src = {
299         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_eth_src }
300 };
301
302 struct virtchnl_proto_hdrs hdrs_hint_eth_dst = {
303         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_eth_dst }
304 };
305
306 struct virtchnl_proto_hdrs hdrs_hint_eth = {
307         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_eth }
308 };
309
310 struct virtchnl_proto_hdrs hdrs_hint_svlan = {
311         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_svlan }
312 };
313
314 struct virtchnl_proto_hdrs hdrs_hint_cvlan = {
315         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_cvlan }
316 };
317
318 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src = {
319         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_ipv4_src }
320 };
321
322 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst = {
323         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_ipv4_dst }
324 };
325
326 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_gtpu_up = {
327         TUNNEL_LEVEL_FIRST_INNER, PROTO_COUNT_TWO, {proto_hint_gtpu_up_only,
328         proto_hint_ipv4_src }
329 };
330
331 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_gtpu_dwn = {
332         TUNNEL_LEVEL_FIRST_INNER, PROTO_COUNT_TWO, {proto_hint_gtpu_dwn_only,
333         proto_hint_ipv4_src }
334 };
335
336 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_gtpu_up = {
337         TUNNEL_LEVEL_FIRST_INNER, PROTO_COUNT_TWO, {proto_hint_gtpu_up_only,
338         proto_hint_ipv4_dst }
339 };
340
341 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_gtpu_dwn = {
342         TUNNEL_LEVEL_FIRST_INNER, PROTO_COUNT_TWO, {proto_hint_gtpu_dwn_only,
343         proto_hint_ipv4_dst }
344 };
345
346 struct virtchnl_proto_hdrs hdrs_hint_ipv4_esp = {
347         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
348         proto_hint_esp }
349 };
350
351 struct virtchnl_proto_hdrs hdrs_hint_ipv4_ah = {
352         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
353         proto_hint_ah }
354 };
355
356 struct virtchnl_proto_hdrs hdrs_hint_ipv4_l2tpv3 = {
357         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
358         proto_hint_l2tpv3 }
359 };
360
361 struct virtchnl_proto_hdrs hdrs_hint_ipv4_pfcp = {
362         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
363         proto_hint_pfcp }
364 };
365
366 struct virtchnl_proto_hdrs hdrs_hint_ipv4 = {
367         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_ipv4 }
368 };
369
370 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_udp_src_port = {
371         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_src,
372         proto_hint_udp_src_port }
373 };
374
375 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_udp_dst_port = {
376         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_src,
377         proto_hint_udp_dst_port }
378 };
379
380 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_udp_src_port = {
381         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_dst,
382         proto_hint_udp_src_port }
383 };
384
385 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_udp_dst_port = {
386         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_dst,
387         proto_hint_udp_dst_port }
388 };
389
390 struct virtchnl_proto_hdrs hdrs_hint_ipv4_udp_src_port = {
391         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
392         proto_hint_udp_src_port }
393 };
394
395 struct virtchnl_proto_hdrs hdrs_hint_ipv4_udp_dst_port = {
396         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
397         proto_hint_udp_dst_port }
398 };
399
400 struct virtchnl_proto_hdrs hdrs_hint_ipv4_udp = {
401         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4,
402         proto_hint_udp }
403 };
404
405 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_tcp_src_port = {
406         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_src,
407         proto_hint_tcp_src_port }
408 };
409
410 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_tcp_dst_port = {
411         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_src,
412         proto_hint_tcp_dst_port }
413 };
414
415 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_tcp_src_port = {
416         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_dst,
417         proto_hint_tcp_src_port }
418 };
419
420 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_tcp_dst_port = {
421         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_dst,
422         proto_hint_tcp_dst_port }
423 };
424
425 struct virtchnl_proto_hdrs hdrs_hint_ipv4_tcp_src_port = {
426         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
427         proto_hint_tcp_src_port }
428 };
429
430 struct virtchnl_proto_hdrs hdrs_hint_ipv4_tcp_dst_port = {
431         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
432         proto_hint_tcp_dst_port }
433 };
434
435 struct virtchnl_proto_hdrs hdrs_hint_ipv4_tcp = {
436         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4,
437         proto_hint_tcp }
438 };
439
440 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_sctp_src_port = {
441         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_src,
442         proto_hint_sctp_src_port }
443 };
444
445 struct virtchnl_proto_hdrs hdrs_hint_ipv4_src_sctp_dst_port = {
446         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_src,
447         proto_hint_sctp_dst_port }
448 };
449
450 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_sctp_src_port = {
451         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_dst,
452         proto_hint_sctp_src_port }
453 };
454
455 struct virtchnl_proto_hdrs hdrs_hint_ipv4_dst_sctp_dst_port = {
456         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_dst,
457         proto_hint_sctp_dst_port }
458 };
459
460 struct virtchnl_proto_hdrs hdrs_hint_ipv4_sctp_src_port = {
461         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
462         proto_hint_sctp_src_port }
463 };
464
465 struct virtchnl_proto_hdrs hdrs_hint_ipv4_sctp_dst_port = {
466         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4_only,
467         proto_hint_sctp_dst_port }
468 };
469
470 struct virtchnl_proto_hdrs hdrs_hint_ipv4_sctp = {
471         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv4,
472         proto_hint_sctp }
473 };
474
475 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src = {
476         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_ipv6_src }
477 };
478
479 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst = {
480         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_ipv6_dst }
481 };
482
483 struct virtchnl_proto_hdrs hdrs_hint_ipv6_esp = {
484         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_only,
485         proto_hint_esp }
486 };
487
488 struct virtchnl_proto_hdrs hdrs_hint_ipv6_ah = {
489         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_only,
490         proto_hint_ah }
491 };
492
493 struct virtchnl_proto_hdrs hdrs_hint_ipv6_l2tpv3 = {
494         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_only,
495         proto_hint_l2tpv3 }
496 };
497
498 struct virtchnl_proto_hdrs hdrs_hint_ipv6_pfcp = {
499         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_only,
500         proto_hint_pfcp }
501 };
502
503 struct virtchnl_proto_hdrs hdrs_hint_ipv6 = {
504         TUNNEL_LEVEL_OUTER, PROTO_COUNT_ONE, {proto_hint_ipv6 }
505 };
506
507 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src_udp_src_port = {
508         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_src,
509         proto_hint_udp_src_port }
510 };
511
512 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src_udp_dst_port = {
513         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_src,
514         proto_hint_udp_dst_port }
515 };
516
517 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst_udp_src_port = {
518         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_dst,
519         proto_hint_udp_src_port }
520 };
521
522 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst_udp_dst_port = {
523         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_dst,
524         proto_hint_udp_dst_port }
525 };
526
527 struct virtchnl_proto_hdrs hdrs_hint_ipv6_udp_src_port = {
528         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_udp_only,
529         proto_hint_udp_src_port }
530 };
531
532 struct virtchnl_proto_hdrs hdrs_hint_ipv6_udp_dst_port = {
533         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_udp_only,
534         proto_hint_udp_dst_port }
535 };
536
537 struct virtchnl_proto_hdrs hdrs_hint_ipv6_udp = {
538         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6,
539         proto_hint_udp }
540 };
541
542 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src_tcp_src_port = {
543         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_src,
544         proto_hint_tcp_src_port }
545 };
546
547 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src_tcp_dst_port = {
548         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_src,
549         proto_hint_tcp_dst_port }
550 };
551
552 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst_tcp_src_port = {
553         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_dst,
554         proto_hint_tcp_src_port }
555 };
556
557 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst_tcp_dst_port = {
558         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_dst,
559         proto_hint_tcp_dst_port }
560 };
561
562 struct virtchnl_proto_hdrs hdrs_hint_ipv6_tcp_src_port = {
563         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_udp_only,
564         proto_hint_tcp_src_port }
565 };
566
567 struct virtchnl_proto_hdrs hdrs_hint_ipv6_tcp_dst_port = {
568         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_udp_only,
569         proto_hint_tcp_dst_port }
570 };
571
572 struct virtchnl_proto_hdrs hdrs_hint_ipv6_tcp = {
573         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6,
574         proto_hint_tcp }
575 };
576
577 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src_sctp_src_port = {
578         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_src,
579         proto_hint_sctp_src_port }
580 };
581
582 struct virtchnl_proto_hdrs hdrs_hint_ipv6_src_sctp_dst_port = {
583         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_src,
584         proto_hint_sctp_dst_port }
585 };
586
587 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst_sctp_src_port = {
588         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_dst,
589         proto_hint_sctp_src_port }
590 };
591
592 struct virtchnl_proto_hdrs hdrs_hint_ipv6_dst_sctp_dst_port = {
593         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6_dst,
594         proto_hint_sctp_dst_port }
595 };
596
597 struct virtchnl_proto_hdrs hdrs_hint_ipv6_sctp_src_port = {
598         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_udp_only,
599         proto_hint_sctp_src_port }
600 };
601
602 struct virtchnl_proto_hdrs hdrs_hint_ipv6_sctp_dst_port = {
603         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_udp_only,
604         proto_hint_sctp_dst_port }
605 };
606
607 struct virtchnl_proto_hdrs hdrs_hint_ipv6_sctp = {
608         TUNNEL_LEVEL_OUTER, PROTO_COUNT_TWO, {proto_hint_ipv6,
609         proto_hint_sctp }
610 };
611
612 /**
613  * The first member is pattern hint type,
614  * the second member is hash type,
615  * the third member is virtchnl protocol hdrs.
616  * the forth member is downlink/uplink type.
617  */
618 struct iavf_hash_match_type iavf_hash_type_list[] = {
619         /* IPV4 */
620         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_L2_SRC_ONLY, &hdrs_hint_eth_src,
621                                                 IAVF_GTPU_HINT_NONE},
622         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_L2_DST_ONLY, &hdrs_hint_eth_dst,
623                                                 IAVF_GTPU_HINT_NONE},
624         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_ETH | ETH_RSS_L2_SRC_ONLY,
625                         &hdrs_hint_eth_src, IAVF_GTPU_HINT_NONE},
626         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_ETH | ETH_RSS_L2_DST_ONLY,
627                         &hdrs_hint_eth_dst, IAVF_GTPU_HINT_NONE},
628         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_ETH, &hdrs_hint_eth,
629                                                 IAVF_GTPU_HINT_NONE},
630         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_S_VLAN, &hdrs_hint_svlan,
631                                                 IAVF_GTPU_HINT_NONE},
632         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_C_VLAN, &hdrs_hint_cvlan,
633                                                 IAVF_GTPU_HINT_NONE},
634         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv4_src,
635                                                 IAVF_GTPU_HINT_NONE},
636         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv4_dst,
637                                                 IAVF_GTPU_HINT_NONE},
638         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_IPV4 | ETH_RSS_L3_SRC_ONLY,
639                         &hdrs_hint_ipv4_src, IAVF_GTPU_HINT_NONE},
640         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY,
641                         &hdrs_hint_ipv4_dst, IAVF_GTPU_HINT_NONE},
642         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_ESP, &hdrs_hint_ipv4_esp,
643         IAVF_GTPU_HINT_NONE},
644         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_AH, &hdrs_hint_ipv4_ah,
645         IAVF_GTPU_HINT_NONE},
646         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_L2TPV3, &hdrs_hint_ipv4_l2tpv3,
647         IAVF_GTPU_HINT_NONE},
648         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_IPV4, &hdrs_hint_ipv4,
649         IAVF_GTPU_HINT_NONE},
650         /* IPV4 UDP */
651         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
652                 &hdrs_hint_ipv4_src_udp_src_port, IAVF_GTPU_HINT_NONE},
653         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
654                 &hdrs_hint_ipv4_src_udp_dst_port, IAVF_GTPU_HINT_NONE},
655         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_SRC_ONLY | ETH_RSS_GTPU,
656                 &hdrs_hint_ipv4_src_gtpu_up, IAVF_GTPU_HINT_UPLINK},
657         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_SRC_ONLY | ETH_RSS_GTPU,
658                 &hdrs_hint_ipv4_src_gtpu_dwn, IAVF_GTPU_HINT_DOWNLINK},
659         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_SRC_ONLY,
660                 &hdrs_hint_ipv4_src, IAVF_GTPU_HINT_NONE},
661         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
662                 &hdrs_hint_ipv4_dst_udp_src_port, IAVF_GTPU_HINT_NONE},
663         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
664                 &hdrs_hint_ipv4_dst_udp_dst_port, IAVF_GTPU_HINT_NONE},
665         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_DST_ONLY | ETH_RSS_GTPU,
666                 &hdrs_hint_ipv4_dst_gtpu_up, IAVF_GTPU_HINT_UPLINK},
667         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_DST_ONLY | ETH_RSS_GTPU,
668                 &hdrs_hint_ipv4_dst_gtpu_dwn, IAVF_GTPU_HINT_DOWNLINK},
669         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L3_DST_ONLY,
670                 &hdrs_hint_ipv4_dst, IAVF_GTPU_HINT_NONE},
671         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
672                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
673                 &hdrs_hint_ipv4_src_udp_src_port, IAVF_GTPU_HINT_NONE},
674         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
675                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
676                 &hdrs_hint_ipv4_src_udp_dst_port, IAVF_GTPU_HINT_NONE},
677         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
678                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_GTPU,
679                 &hdrs_hint_ipv4_src_gtpu_up, IAVF_GTPU_HINT_UPLINK},
680         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
681                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_GTPU,
682                 &hdrs_hint_ipv4_src_gtpu_dwn, IAVF_GTPU_HINT_DOWNLINK},
683         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
684                 ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv4_src,
685                 IAVF_GTPU_HINT_NONE},
686         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
687                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
688                 &hdrs_hint_ipv4_dst_udp_src_port, IAVF_GTPU_HINT_NONE},
689         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
690                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
691                 &hdrs_hint_ipv4_dst_udp_dst_port, IAVF_GTPU_HINT_NONE},
692         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
693                 ETH_RSS_L3_DST_ONLY | ETH_RSS_GTPU,
694                 &hdrs_hint_ipv4_dst_gtpu_up, IAVF_GTPU_HINT_UPLINK},
695         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
696                 ETH_RSS_L3_DST_ONLY | ETH_RSS_GTPU,
697                 &hdrs_hint_ipv4_dst_gtpu_dwn, IAVF_GTPU_HINT_DOWNLINK},
698         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP |
699                 ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv4_dst,
700                 IAVF_GTPU_HINT_NONE},
701         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L4_SRC_ONLY,
702                 &hdrs_hint_ipv4_udp_src_port, IAVF_GTPU_HINT_NONE},
703         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_L4_DST_ONLY,
704                 &hdrs_hint_ipv4_udp_dst_port, IAVF_GTPU_HINT_NONE},
705         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_PFCP,
706                 &hdrs_hint_ipv4_pfcp, IAVF_GTPU_HINT_NONE},
707         {IAVF_PATTERN_HINT_IPV4_UDP, ETH_RSS_NONFRAG_IPV4_UDP,
708                 &hdrs_hint_ipv4_udp, IAVF_GTPU_HINT_NONE},
709         /* IPV4 TCP */
710         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
711                 &hdrs_hint_ipv4_src_tcp_src_port, IAVF_GTPU_HINT_NONE},
712         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
713                 &hdrs_hint_ipv4_src_tcp_dst_port, IAVF_GTPU_HINT_NONE},
714         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L3_SRC_ONLY,
715                 &hdrs_hint_ipv4_src, IAVF_GTPU_HINT_NONE},
716         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
717                 &hdrs_hint_ipv4_dst_tcp_src_port, IAVF_GTPU_HINT_NONE},
718         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
719                 &hdrs_hint_ipv4_dst_tcp_dst_port, IAVF_GTPU_HINT_NONE},
720         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L3_DST_ONLY,
721                 &hdrs_hint_ipv4_dst, IAVF_GTPU_HINT_NONE},
722         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP |
723                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
724                 &hdrs_hint_ipv4_src_tcp_src_port, IAVF_GTPU_HINT_NONE},
725         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP |
726                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
727                 &hdrs_hint_ipv4_src_tcp_dst_port, IAVF_GTPU_HINT_NONE},
728         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP |
729                 ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv4_src,
730                 IAVF_GTPU_HINT_NONE},
731         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP |
732                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
733                 &hdrs_hint_ipv4_dst_tcp_src_port, IAVF_GTPU_HINT_NONE},
734         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP |
735                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
736                 &hdrs_hint_ipv4_dst_tcp_dst_port, IAVF_GTPU_HINT_NONE},
737         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP |
738                 ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv4_dst,
739                 IAVF_GTPU_HINT_NONE},
740         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L4_SRC_ONLY,
741                 &hdrs_hint_ipv4_tcp_src_port, IAVF_GTPU_HINT_NONE},
742         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_L4_DST_ONLY,
743                 &hdrs_hint_ipv4_tcp_dst_port, IAVF_GTPU_HINT_NONE},
744         {IAVF_PATTERN_HINT_IPV4_TCP, ETH_RSS_NONFRAG_IPV4_TCP,
745                 &hdrs_hint_ipv4_tcp, IAVF_GTPU_HINT_NONE},
746         /* IPV4 SCTP */
747         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L3_SRC_ONLY |
748                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv4_src_sctp_src_port,
749                 IAVF_GTPU_HINT_NONE},
750         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L3_SRC_ONLY |
751                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv4_src_sctp_dst_port,
752                 IAVF_GTPU_HINT_NONE},
753         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L3_SRC_ONLY,
754                 &hdrs_hint_ipv4_src, IAVF_GTPU_HINT_NONE},
755         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L3_DST_ONLY |
756                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv4_dst_sctp_src_port,
757                 IAVF_GTPU_HINT_NONE},
758         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L3_DST_ONLY |
759                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv4_dst_sctp_dst_port,
760                 IAVF_GTPU_HINT_NONE},
761         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L3_DST_ONLY,
762                 &hdrs_hint_ipv4_dst, IAVF_GTPU_HINT_NONE},
763         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP |
764                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
765                 &hdrs_hint_ipv4_src_sctp_src_port, IAVF_GTPU_HINT_NONE},
766         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP |
767                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
768                 &hdrs_hint_ipv4_src_sctp_dst_port, IAVF_GTPU_HINT_NONE},
769         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP |
770                 ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv4_src,
771                 IAVF_GTPU_HINT_NONE},
772         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP |
773                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
774                 &hdrs_hint_ipv4_dst_sctp_src_port, IAVF_GTPU_HINT_NONE},
775         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP |
776                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
777                 &hdrs_hint_ipv4_dst_sctp_dst_port, IAVF_GTPU_HINT_NONE},
778         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP |
779                 ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv4_dst,
780                 IAVF_GTPU_HINT_NONE},
781         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L4_SRC_ONLY,
782                 &hdrs_hint_ipv4_sctp_src_port, IAVF_GTPU_HINT_NONE},
783         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_L4_DST_ONLY,
784                 &hdrs_hint_ipv4_sctp_dst_port, IAVF_GTPU_HINT_NONE},
785         {IAVF_PATTERN_HINT_IPV4_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP,
786                 &hdrs_hint_ipv4_sctp, IAVF_GTPU_HINT_NONE},
787         /* IPV6 */
788         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_L2_SRC_ONLY,
789                 &hdrs_hint_eth_src, IAVF_GTPU_HINT_NONE},
790         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_L2_DST_ONLY,
791                 &hdrs_hint_eth_dst, IAVF_GTPU_HINT_NONE},
792         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_IPV6 | ETH_RSS_L2_SRC_ONLY,
793                 &hdrs_hint_eth_src, IAVF_GTPU_HINT_NONE},
794         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_IPV6 | ETH_RSS_L2_DST_ONLY,
795                 &hdrs_hint_eth_dst, IAVF_GTPU_HINT_NONE},
796         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_ETH,
797                 &hdrs_hint_eth, IAVF_GTPU_HINT_NONE},
798         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_S_VLAN,
799                 &hdrs_hint_svlan, IAVF_GTPU_HINT_NONE},
800         {IAVF_PATTERN_HINT_IPV4, ETH_RSS_C_VLAN,
801                 &hdrs_hint_cvlan, IAVF_GTPU_HINT_NONE},
802         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_L3_SRC_ONLY,
803                 &hdrs_hint_ipv6_src, IAVF_GTPU_HINT_NONE},
804         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_L3_DST_ONLY,
805                 &hdrs_hint_ipv6_dst, IAVF_GTPU_HINT_NONE},
806         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_IPV6 | ETH_RSS_L3_SRC_ONLY,
807                 &hdrs_hint_ipv6_src, IAVF_GTPU_HINT_NONE},
808         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_IPV6 | ETH_RSS_L3_DST_ONLY,
809                 &hdrs_hint_ipv6_dst, IAVF_GTPU_HINT_NONE},
810         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_ESP,
811                 &hdrs_hint_ipv6_esp, IAVF_GTPU_HINT_NONE},
812         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_AH,
813                 &hdrs_hint_ipv6_ah, IAVF_GTPU_HINT_NONE},
814         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_L2TPV3,
815                 &hdrs_hint_ipv6_l2tpv3, IAVF_GTPU_HINT_NONE},
816         {IAVF_PATTERN_HINT_IPV6, ETH_RSS_IPV6,
817                 &hdrs_hint_ipv6, IAVF_GTPU_HINT_NONE},
818         /* IPV6 UDP */
819         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L3_SRC_ONLY |
820                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv6_src_udp_src_port,
821                 IAVF_GTPU_HINT_NONE},
822         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L3_SRC_ONLY |
823                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv6_src_udp_dst_port,
824                 IAVF_GTPU_HINT_NONE},
825         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L3_SRC_ONLY,
826                 &hdrs_hint_ipv6_src, IAVF_GTPU_HINT_NONE},
827         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L3_DST_ONLY |
828                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv6_dst_udp_src_port,
829                 IAVF_GTPU_HINT_NONE},
830         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L3_DST_ONLY |
831                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv6_dst_udp_dst_port,
832                 IAVF_GTPU_HINT_NONE},
833         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L3_DST_ONLY,
834                 &hdrs_hint_ipv6_dst, IAVF_GTPU_HINT_NONE},
835         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP |
836                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
837                 &hdrs_hint_ipv6_src_udp_src_port, IAVF_GTPU_HINT_NONE},
838         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP |
839                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
840                 &hdrs_hint_ipv6_src_udp_dst_port, IAVF_GTPU_HINT_NONE},
841         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP |
842                 ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv6_src,
843                 IAVF_GTPU_HINT_NONE},
844         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP |
845                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
846                 &hdrs_hint_ipv6_dst_udp_src_port, IAVF_GTPU_HINT_NONE},
847         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP |
848                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
849                 &hdrs_hint_ipv6_dst_udp_dst_port, IAVF_GTPU_HINT_NONE},
850         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP |
851                 ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv6_dst,
852                 IAVF_GTPU_HINT_NONE},
853         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L4_SRC_ONLY,
854                 &hdrs_hint_ipv6_udp_src_port, IAVF_GTPU_HINT_NONE},
855         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_L4_DST_ONLY,
856                 &hdrs_hint_ipv6_udp_dst_port, IAVF_GTPU_HINT_NONE},
857         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_PFCP,
858                 &hdrs_hint_ipv6_pfcp, IAVF_GTPU_HINT_NONE},
859         {IAVF_PATTERN_HINT_IPV6_UDP, ETH_RSS_NONFRAG_IPV6_UDP,
860                 &hdrs_hint_ipv6_udp, IAVF_GTPU_HINT_NONE},
861         /* IPV6 TCP */
862         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L3_SRC_ONLY |
863                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv6_src_tcp_src_port,
864                 IAVF_GTPU_HINT_NONE},
865         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L3_SRC_ONLY |
866                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv6_src_tcp_dst_port,
867                 IAVF_GTPU_HINT_NONE},
868         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L3_SRC_ONLY,
869                 &hdrs_hint_ipv6_src, IAVF_GTPU_HINT_NONE},
870         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L3_DST_ONLY |
871                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv6_dst_tcp_src_port,
872                 IAVF_GTPU_HINT_NONE},
873         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L3_DST_ONLY |
874                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv6_dst_tcp_dst_port,
875                 IAVF_GTPU_HINT_NONE},
876         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L3_DST_ONLY,
877                 &hdrs_hint_ipv6_dst, IAVF_GTPU_HINT_NONE},
878         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP |
879                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
880                 &hdrs_hint_ipv6_src_tcp_src_port, IAVF_GTPU_HINT_NONE},
881         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP |
882                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
883                 &hdrs_hint_ipv6_src_tcp_dst_port, IAVF_GTPU_HINT_NONE},
884         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP |
885                 ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv6_src,
886                 IAVF_GTPU_HINT_NONE},
887         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP |
888                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
889                 &hdrs_hint_ipv6_dst_tcp_src_port, IAVF_GTPU_HINT_NONE},
890         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP |
891                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
892                 &hdrs_hint_ipv6_dst_tcp_dst_port, IAVF_GTPU_HINT_NONE},
893         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP |
894                 ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv6_dst,
895                 IAVF_GTPU_HINT_NONE},
896         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L4_SRC_ONLY,
897                 &hdrs_hint_ipv6_tcp_src_port, IAVF_GTPU_HINT_NONE},
898         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_L4_DST_ONLY,
899                 &hdrs_hint_ipv6_tcp_dst_port, IAVF_GTPU_HINT_NONE},
900         {IAVF_PATTERN_HINT_IPV6_TCP, ETH_RSS_NONFRAG_IPV6_TCP,
901                 &hdrs_hint_ipv6_tcp, IAVF_GTPU_HINT_NONE},
902         /* IPV6 SCTP */
903         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L3_SRC_ONLY |
904                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv6_src_sctp_src_port,
905                 IAVF_GTPU_HINT_NONE},
906         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L3_SRC_ONLY |
907                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv6_src_sctp_dst_port,
908                 IAVF_GTPU_HINT_NONE},
909         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L3_SRC_ONLY,
910                 &hdrs_hint_ipv6_src, IAVF_GTPU_HINT_NONE},
911         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L3_DST_ONLY |
912                 ETH_RSS_L4_SRC_ONLY, &hdrs_hint_ipv6_dst_sctp_src_port,
913                 IAVF_GTPU_HINT_NONE},
914         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L3_DST_ONLY |
915                 ETH_RSS_L4_DST_ONLY, &hdrs_hint_ipv6_dst_sctp_dst_port,
916                 IAVF_GTPU_HINT_NONE},
917         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L3_DST_ONLY,
918                 &hdrs_hint_ipv6_dst, IAVF_GTPU_HINT_NONE},
919         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP |
920                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,
921                 &hdrs_hint_ipv6_src_sctp_src_port, IAVF_GTPU_HINT_NONE},
922         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP |
923                 ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,
924                 &hdrs_hint_ipv6_src_sctp_dst_port, IAVF_GTPU_HINT_NONE},
925         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP |
926                 ETH_RSS_L3_SRC_ONLY, &hdrs_hint_ipv6_src,
927                 IAVF_GTPU_HINT_NONE},
928         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP |
929                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,
930                 &hdrs_hint_ipv6_dst_sctp_src_port, IAVF_GTPU_HINT_NONE},
931         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP |
932                 ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,
933                 &hdrs_hint_ipv6_dst_sctp_dst_port, IAVF_GTPU_HINT_NONE},
934         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP |
935                 ETH_RSS_L3_DST_ONLY, &hdrs_hint_ipv6_dst,
936                 IAVF_GTPU_HINT_NONE},
937         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L4_SRC_ONLY,
938                 &hdrs_hint_ipv6_sctp_src_port, IAVF_GTPU_HINT_NONE},
939         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_L4_DST_ONLY,
940                 &hdrs_hint_ipv6_sctp_dst_port, IAVF_GTPU_HINT_NONE},
941         {IAVF_PATTERN_HINT_IPV6_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP,
942                 &hdrs_hint_ipv6_sctp, IAVF_GTPU_HINT_NONE},
943 };
944
945 struct virtchnl_proto_hdrs *iavf_hash_default_hdrs[] = {
946         &hdrs_hint_ipv4,
947         &hdrs_hint_ipv4_udp,
948         &hdrs_hint_ipv4_tcp,
949         &hdrs_hint_ipv4_sctp,
950         &hdrs_hint_ipv6,
951         &hdrs_hint_ipv6_udp,
952         &hdrs_hint_ipv6_tcp,
953         &hdrs_hint_ipv6_sctp,
954 };
955
956 static struct iavf_flow_engine iavf_hash_engine = {
957         .init = iavf_hash_init,
958         .create = iavf_hash_create,
959         .destroy = iavf_hash_destroy,
960         .uninit = iavf_hash_uninit,
961         .free = iavf_hash_free,
962         .type = IAVF_FLOW_ENGINE_HASH,
963 };
964
965 /* Register parser for comms package. */
966 static struct iavf_flow_parser iavf_hash_parser = {
967         .engine = &iavf_hash_engine,
968         .array = iavf_hash_pattern_list,
969         .array_len = RTE_DIM(iavf_hash_pattern_list),
970         .parse_pattern_action = iavf_hash_parse_pattern_action,
971         .stage = IAVF_FLOW_STAGE_RSS,
972 };
973
974 static int
975 iavf_hash_default_set(struct iavf_adapter *ad, bool add)
976 {
977         struct virtchnl_rss_cfg *rss_cfg;
978         uint16_t i;
979         int ret;
980
981         rss_cfg = rte_zmalloc("iavf rss rule",
982                               sizeof(struct virtchnl_rss_cfg), 0);
983         if (!rss_cfg)
984                 return -ENOMEM;
985
986         for (i = 0; i < RTE_DIM(iavf_hash_default_hdrs); i++) {
987                 rss_cfg->proto_hdrs = *iavf_hash_default_hdrs[i];
988                 rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
989
990                 ret = iavf_add_del_rss_cfg(ad, rss_cfg, add);
991                 if (ret) {
992                         PMD_DRV_LOG(ERR, "fail to %s RSS configure",
993                                     add ? "add" : "delete");
994                         rte_free(rss_cfg);
995                         return ret;
996                 }
997         }
998
999         return ret;
1000 }
1001
1002 RTE_INIT(iavf_hash_engine_init)
1003 {
1004         struct iavf_flow_engine *engine = &iavf_hash_engine;
1005
1006         iavf_register_flow_engine(engine);
1007 }
1008
1009 static int
1010 iavf_hash_init(struct iavf_adapter *ad)
1011 {
1012         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1013         struct iavf_flow_parser *parser;
1014         int ret;
1015
1016         if (!vf->vf_res)
1017                 return -EINVAL;
1018
1019         if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF))
1020                 return -ENOTSUP;
1021
1022         parser = &iavf_hash_parser;
1023
1024         ret = iavf_register_parser(parser, ad);
1025         if (ret) {
1026                 PMD_DRV_LOG(ERR, "fail to register hash parser");
1027                 return ret;
1028         }
1029
1030         ret = iavf_hash_default_set(ad, true);
1031         if (ret) {
1032                 PMD_DRV_LOG(ERR, "fail to set default RSS");
1033                 iavf_unregister_parser(parser, ad);
1034         }
1035
1036         return ret;
1037 }
1038
1039 static int
1040 iavf_hash_check_inset(const struct rte_flow_item pattern[],
1041                       struct rte_flow_error *error)
1042 {
1043         const struct rte_flow_item *item = pattern;
1044
1045         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
1046                 if (item->last) {
1047                         rte_flow_error_set(error, EINVAL,
1048                                            RTE_FLOW_ERROR_TYPE_ITEM, item,
1049                                            "Not support range");
1050                         return -rte_errno;
1051                 }
1052         }
1053
1054         return 0;
1055 }
1056
1057 static void
1058 iavf_hash_refine_type(uint64_t *rss_type, const struct rte_flow_item pattern[],
1059                       enum iavf_gtpu_hint *gtpu_hint)
1060 {
1061         const struct rte_flow_item *item;
1062
1063         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
1064                 if (item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
1065                         const struct rte_flow_item_gtp_psc *psc = item->spec;
1066
1067                         if (psc && (psc->pdu_type == IAVF_GTPU_HINT_UPLINK ||
1068                                     psc->pdu_type == IAVF_GTPU_HINT_DOWNLINK)) {
1069                                 *rss_type |= ETH_RSS_GTPU;
1070                                 *gtpu_hint = psc->pdu_type;
1071                         }
1072                 }
1073         }
1074 }
1075
1076 static int
1077 iavf_hash_parse_action(struct iavf_pattern_match_item *pattern_match_item,
1078                        const struct rte_flow_item pattern[],
1079                        const struct rte_flow_action actions[],
1080                        void **meta, struct rte_flow_error *error)
1081 {
1082         struct iavf_pattern_match_type *mt = (struct iavf_pattern_match_type *)
1083                                         (pattern_match_item->meta);
1084         struct iavf_rss_meta *rss_meta = (struct iavf_rss_meta *)*meta;
1085         uint32_t type_list_len = RTE_DIM(iavf_hash_type_list);
1086         struct iavf_hash_match_type *type_match_item;
1087         enum iavf_gtpu_hint gtpu_hint = IAVF_GTPU_HINT_NONE;
1088         enum rte_flow_action_type action_type;
1089         const struct rte_flow_action_rss *rss;
1090         const struct rte_flow_action *action;
1091         bool item_found = false;
1092         uint64_t rss_type;
1093         uint16_t i;
1094
1095         /* Supported action is RSS. */
1096         for (action = actions; action->type !=
1097                 RTE_FLOW_ACTION_TYPE_END; action++) {
1098                 action_type = action->type;
1099                 switch (action_type) {
1100                 case RTE_FLOW_ACTION_TYPE_RSS:
1101                         rss = action->conf;
1102                         rss_type = rss->types;
1103
1104                         /**
1105                          * Check simultaneous use of SRC_ONLY and DST_ONLY
1106                          * of the same level.
1107                          */
1108                         rss_type = rte_eth_rss_hf_refine(rss_type);
1109
1110                         /**
1111                          * Refine the hash type base on some specific item of
1112                          * the pattern, such as identify the gtpu hash.
1113                          */
1114                         iavf_hash_refine_type(&rss_type, pattern, &gtpu_hint);
1115
1116                         /* Check if pattern is empty. */
1117                         if (pattern_match_item->pattern_list !=
1118                                 iavf_pattern_empty && rss->func ==
1119                                 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
1120                                 return rte_flow_error_set(error, ENOTSUP,
1121                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1122                                         "Not supported flow");
1123
1124                         if (rss->level)
1125                                 return rte_flow_error_set(error, ENOTSUP,
1126                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1127                                         "a nonzero RSS encapsulation level is not supported");
1128
1129                         if (rss->key_len)
1130                                 return rte_flow_error_set(error, ENOTSUP,
1131                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1132                                         "a nonzero RSS key_len is not supported");
1133
1134                         if (rss->queue_num)
1135                                 return rte_flow_error_set(error, ENOTSUP,
1136                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1137                                         "a non-NULL RSS queue is not supported");
1138
1139                         /* Check hash function and save it to rss_meta. */
1140                         if (rss->func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
1141                                 rss_meta->rss_algorithm =
1142                                         VIRTCHNL_RSS_ALG_XOR_ASYMMETRIC;
1143                         else if (rss->func ==
1144                                  RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ)
1145                                 rss_meta->rss_algorithm =
1146                                         VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
1147                         else
1148                                 rss_meta->rss_algorithm =
1149                                         VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
1150
1151                         type_match_item =
1152                         rte_zmalloc("iavf_type_match_item",
1153                                     sizeof(struct iavf_hash_match_type), 0);
1154                         if (!type_match_item) {
1155                                 rte_flow_error_set(error, EINVAL,
1156                                                    RTE_FLOW_ERROR_TYPE_HANDLE,
1157                                                    NULL,
1158                                                    "No memory for type_match_item");
1159                                 return -ENOMEM;
1160                         }
1161
1162                         /* Find matched proto hdrs according to hash type. */
1163                         for (i = 0; i < type_list_len; i++) {
1164                                 struct iavf_hash_match_type *ht_map =
1165                                         &iavf_hash_type_list[i];
1166                                 if (rss_type == ht_map->hash_type &&
1167                                     mt->phint_type == ht_map->phint_type &&
1168                                     gtpu_hint == ht_map->gtpu_hint) {
1169                                         type_match_item->hash_type =
1170                                                 ht_map->hash_type;
1171                                         type_match_item->proto_hdrs =
1172                                                 ht_map->proto_hdrs;
1173                                         rss_meta->proto_hdrs =
1174                                                 type_match_item->proto_hdrs;
1175                                         item_found = true;
1176                                 }
1177                         }
1178
1179                         rte_free(type_match_item);
1180
1181                         if (!item_found)
1182                                 return rte_flow_error_set(error, ENOTSUP,
1183                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1184                                         "Not supported flow");
1185                         break;
1186
1187                 case RTE_FLOW_ACTION_TYPE_END:
1188                         break;
1189
1190                 default:
1191                         rte_flow_error_set(error, EINVAL,
1192                                            RTE_FLOW_ERROR_TYPE_ACTION, action,
1193                                            "Invalid action.");
1194                         return -rte_errno;
1195                 }
1196         }
1197
1198         return 0;
1199 }
1200
1201 static int
1202 iavf_hash_parse_pattern_action(__rte_unused struct iavf_adapter *ad,
1203                                struct iavf_pattern_match_item *array,
1204                                uint32_t array_len,
1205                                const struct rte_flow_item pattern[],
1206                                const struct rte_flow_action actions[],
1207                                void **meta,
1208                                struct rte_flow_error *error)
1209 {
1210         struct iavf_pattern_match_item *pattern_match_item;
1211         struct iavf_rss_meta *rss_meta_ptr;
1212         int ret = 0;
1213
1214         rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1215         if (!rss_meta_ptr) {
1216                 rte_flow_error_set(error, EINVAL,
1217                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1218                                    "No memory for rss_meta_ptr");
1219                 return -ENOMEM;
1220         }
1221
1222         /* Check rss supported pattern and find matched pattern. */
1223         pattern_match_item =
1224                 iavf_search_pattern_match_item(pattern, array, array_len,
1225                                                error);
1226         if (!pattern_match_item) {
1227                 ret = -rte_errno;
1228                 goto error;
1229         }
1230
1231         ret = iavf_hash_check_inset(pattern, error);
1232         if (ret)
1233                 goto error;
1234
1235         /* Check rss action. */
1236         ret = iavf_hash_parse_action(pattern_match_item, pattern, actions,
1237                                      (void **)&rss_meta_ptr, error);
1238
1239 error:
1240         if (!ret && meta)
1241                 *meta = rss_meta_ptr;
1242         else
1243                 rte_free(rss_meta_ptr);
1244
1245         rte_free(pattern_match_item);
1246
1247         return ret;
1248 }
1249
1250 static int
1251 iavf_hash_create(__rte_unused struct iavf_adapter *ad,
1252                  __rte_unused struct rte_flow *flow, void *meta,
1253                  __rte_unused struct rte_flow_error *error)
1254 {
1255         struct iavf_rss_meta *rss_meta = (struct iavf_rss_meta *)meta;
1256         struct virtchnl_rss_cfg *rss_cfg;
1257         int ret = 0;
1258
1259         rss_cfg = rte_zmalloc("iavf rss rule",
1260                               sizeof(struct virtchnl_rss_cfg), 0);
1261         if (!rss_cfg) {
1262                 rte_flow_error_set(error, EINVAL,
1263                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1264                                    "No memory for rss rule");
1265                 return -ENOMEM;
1266         }
1267
1268         rss_cfg->proto_hdrs = *rss_meta->proto_hdrs;
1269         rss_cfg->rss_algorithm = rss_meta->rss_algorithm;
1270
1271         ret = iavf_add_del_rss_cfg(ad, rss_cfg, true);
1272         if (!ret) {
1273                 flow->rule = rss_cfg;
1274         } else {
1275                 PMD_DRV_LOG(ERR, "fail to add RSS configure");
1276                 rte_flow_error_set(error, -ret,
1277                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1278                                    "Failed to add rss rule.");
1279                 rte_free(rss_cfg);
1280                 return -rte_errno;
1281         }
1282
1283         rte_free(meta);
1284
1285         return ret;
1286 }
1287
1288 static int
1289 iavf_hash_destroy(__rte_unused struct iavf_adapter *ad,
1290                   struct rte_flow *flow,
1291                   __rte_unused struct rte_flow_error *error)
1292 {
1293         struct virtchnl_rss_cfg *rss_cfg;
1294         int ret = 0;
1295
1296         rss_cfg = (struct virtchnl_rss_cfg *)flow->rule;
1297
1298         ret = iavf_add_del_rss_cfg(ad, rss_cfg, false);
1299         if (ret) {
1300                 PMD_DRV_LOG(ERR, "fail to del RSS configure");
1301                 rte_flow_error_set(error, -ret,
1302                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1303                                    "Failed to delete rss rule.");
1304                 return -rte_errno;
1305         }
1306         return ret;
1307 }
1308
1309 static void
1310 iavf_hash_uninit(struct iavf_adapter *ad)
1311 {
1312         if (iavf_hash_default_set(ad, false))
1313                 PMD_DRV_LOG(ERR, "fail to delete default RSS");
1314
1315         iavf_unregister_parser(&iavf_hash_parser, ad);
1316 }
1317
1318 static void
1319 iavf_hash_free(struct rte_flow *flow)
1320 {
1321         rte_free(flow->rule);
1322 }