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