net/mlx5: fix RSS expansion for patterns with ICMP item
[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 <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 #define IAVF_PHINT_NONE                         0
27 #define IAVF_PHINT_GTPU                         BIT_ULL(0)
28 #define IAVF_PHINT_GTPU_EH                      BIT_ULL(1)
29 #define IAVF_PHINT_GTPU_EH_DWN                  BIT_ULL(2)
30 #define IAVF_PHINT_GTPU_EH_UP                   BIT_ULL(3)
31 #define IAVF_PHINT_OUTER_IPV4                   BIT_ULL(4)
32 #define IAVF_PHINT_OUTER_IPV6                   BIT_ULL(5)
33 #define IAVF_PHINT_GRE                          BIT_ULL(6)
34 /* the second IP header of GTPoGRE */
35 #define IAVF_PHINT_MID_IPV4                     BIT_ULL(7)
36 #define IAVF_PHINT_MID_IPV6                     BIT_ULL(8)
37 /* L2TPv2 */
38 #define IAVF_PHINT_L2TPV2                       BIT_ULL(9)
39 #define IAVF_PHINT_L2TPV2_LEN                   BIT_ULL(10)
40 /* Raw */
41 #define IAVF_PHINT_RAW                          BIT_ULL(11)
42
43 #define IAVF_PHINT_GTPU_MSK     (IAVF_PHINT_GTPU        | \
44                                  IAVF_PHINT_GTPU_EH     | \
45                                  IAVF_PHINT_GTPU_EH_DWN | \
46                                  IAVF_PHINT_GTPU_EH_UP)
47
48 #define IAVF_PHINT_LAYERS_MSK   (IAVF_PHINT_OUTER_IPV4  | \
49                                  IAVF_PHINT_OUTER_IPV6)
50
51 #define IAVF_GTPU_EH_DWNLINK    0
52 #define IAVF_GTPU_EH_UPLINK     1
53
54 struct iavf_hash_match_type {
55         uint64_t hash_type;
56         struct virtchnl_proto_hdrs *proto_hdrs;
57         uint64_t pattern_hint;
58 };
59
60 struct iavf_rss_meta {
61         struct virtchnl_proto_hdrs proto_hdrs;
62         enum virtchnl_rss_algorithm rss_algorithm;
63         bool raw_ena;
64 };
65
66 struct iavf_hash_flow_cfg {
67         struct virtchnl_rss_cfg *rss_cfg;
68         bool simple_xor;
69 };
70
71 static int
72 iavf_hash_init(struct iavf_adapter *ad);
73 static int
74 iavf_hash_create(struct iavf_adapter *ad, struct rte_flow *flow, void *meta,
75                  struct rte_flow_error *error);
76 static int
77 iavf_hash_destroy(struct iavf_adapter *ad, struct rte_flow *flow,
78                   struct rte_flow_error *error);
79 static void
80 iavf_hash_uninit(struct iavf_adapter *ad);
81 static void
82 iavf_hash_free(struct rte_flow *flow);
83 static int
84 iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
85                                struct iavf_pattern_match_item *array,
86                                uint32_t array_len,
87                                const struct rte_flow_item pattern[],
88                                const struct rte_flow_action actions[],
89                                void **meta,
90                                struct rte_flow_error *error);
91
92 #define FIELD_SELECTOR(proto_hdr_field) \
93                 (1UL << ((proto_hdr_field) & PROTO_HDR_FIELD_MASK))
94 #define BUFF_NOUSED                     0
95
96 #define proto_hdr_eth { \
97         VIRTCHNL_PROTO_HDR_ETH, \
98         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | \
99         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), {BUFF_NOUSED} }
100
101 #define proto_hdr_svlan { \
102         VIRTCHNL_PROTO_HDR_S_VLAN, \
103         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), {BUFF_NOUSED} }
104
105 #define proto_hdr_cvlan { \
106         VIRTCHNL_PROTO_HDR_C_VLAN, \
107         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), {BUFF_NOUSED} }
108
109 #define proto_hdr_ipv4 { \
110         VIRTCHNL_PROTO_HDR_IPV4, \
111         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
112         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), {BUFF_NOUSED} }
113
114 #define proto_hdr_ipv4_with_prot { \
115         VIRTCHNL_PROTO_HDR_IPV4, \
116         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
117         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | \
118         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), {BUFF_NOUSED} }
119
120 #define proto_hdr_ipv6 { \
121         VIRTCHNL_PROTO_HDR_IPV6, \
122         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
123         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), {BUFF_NOUSED} }
124
125 #define proto_hdr_ipv6_frag { \
126         VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG, \
127         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG_PKID), {BUFF_NOUSED} }
128
129 #define proto_hdr_ipv6_with_prot { \
130         VIRTCHNL_PROTO_HDR_IPV6, \
131         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
132         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | \
133         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), {BUFF_NOUSED} }
134
135 #define proto_hdr_udp { \
136         VIRTCHNL_PROTO_HDR_UDP, \
137         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | \
138         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), {BUFF_NOUSED} }
139
140 #define proto_hdr_tcp { \
141         VIRTCHNL_PROTO_HDR_TCP, \
142         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | \
143         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), {BUFF_NOUSED} }
144
145 #define proto_hdr_sctp { \
146         VIRTCHNL_PROTO_HDR_SCTP, \
147         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | \
148         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), {BUFF_NOUSED} }
149
150 #define proto_hdr_esp { \
151         VIRTCHNL_PROTO_HDR_ESP, \
152         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), {BUFF_NOUSED} }
153
154 #define proto_hdr_ah { \
155         VIRTCHNL_PROTO_HDR_AH, \
156         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), {BUFF_NOUSED} }
157
158 #define proto_hdr_l2tpv3 { \
159         VIRTCHNL_PROTO_HDR_L2TPV3, \
160         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), {BUFF_NOUSED} }
161
162 #define proto_hdr_pfcp { \
163         VIRTCHNL_PROTO_HDR_PFCP, \
164         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), {BUFF_NOUSED} }
165
166 #define proto_hdr_gtpc { \
167         VIRTCHNL_PROTO_HDR_GTPC, 0, {BUFF_NOUSED} }
168
169 #define proto_hdr_ecpri { \
170         VIRTCHNL_PROTO_HDR_ECPRI, \
171         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
172
173 #define proto_hdr_l2tpv2 { \
174         VIRTCHNL_PROTO_HDR_L2TPV2, \
175         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV2_SESS_ID) | \
176         FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV2_LEN_SESS_ID), {BUFF_NOUSED} }
177
178 #define proto_hdr_ppp { \
179         VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
180
181 #define TUNNEL_LEVEL_OUTER              0
182 #define TUNNEL_LEVEL_INNER              1
183
184 /* proto_hdrs template */
185 struct virtchnl_proto_hdrs outer_ipv4_tmplt = {
186         TUNNEL_LEVEL_OUTER, 4,
187         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv4}}
188 };
189
190 struct virtchnl_proto_hdrs outer_ipv4_udp_tmplt = {
191         TUNNEL_LEVEL_OUTER, 5,
192         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
193           proto_hdr_ipv4_with_prot,
194           proto_hdr_udp}}
195 };
196
197 struct virtchnl_proto_hdrs outer_ipv4_tcp_tmplt = {
198         TUNNEL_LEVEL_OUTER, 5,
199         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
200           proto_hdr_ipv4_with_prot,
201           proto_hdr_tcp}}
202 };
203
204 struct virtchnl_proto_hdrs outer_ipv4_sctp_tmplt = {
205         TUNNEL_LEVEL_OUTER, 5,
206         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv4,
207           proto_hdr_sctp}}
208 };
209
210 struct virtchnl_proto_hdrs outer_ipv6_tmplt = {
211         TUNNEL_LEVEL_OUTER, 4,
212         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv6}}
213 };
214
215 struct virtchnl_proto_hdrs outer_ipv6_frag_tmplt = {
216         TUNNEL_LEVEL_OUTER, 5,
217         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
218           proto_hdr_ipv6, proto_hdr_ipv6_frag}}
219 };
220
221 struct virtchnl_proto_hdrs outer_ipv6_udp_tmplt = {
222         TUNNEL_LEVEL_OUTER, 5,
223         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
224           proto_hdr_ipv6_with_prot,
225           proto_hdr_udp}}
226 };
227
228 struct virtchnl_proto_hdrs outer_ipv6_tcp_tmplt = {
229         TUNNEL_LEVEL_OUTER, 5,
230         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
231           proto_hdr_ipv6_with_prot,
232           proto_hdr_tcp}}
233 };
234
235 struct virtchnl_proto_hdrs outer_ipv6_sctp_tmplt = {
236         TUNNEL_LEVEL_OUTER, 5,
237         {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv6,
238           proto_hdr_sctp}}
239 };
240
241 struct virtchnl_proto_hdrs inner_ipv4_tmplt = {
242         TUNNEL_LEVEL_INNER, 1, {{proto_hdr_ipv4}}
243 };
244
245 struct virtchnl_proto_hdrs inner_ipv4_udp_tmplt = {
246         TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_udp}}
247 };
248
249 struct virtchnl_proto_hdrs inner_ipv4_tcp_tmplt = {
250         TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_tcp}}
251 };
252
253 struct virtchnl_proto_hdrs second_inner_ipv4_tmplt = {
254         2, 1, {{proto_hdr_ipv4}}
255 };
256
257 struct virtchnl_proto_hdrs second_inner_ipv4_udp_tmplt = {
258         2, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_udp}}
259 };
260
261 struct virtchnl_proto_hdrs second_inner_ipv4_tcp_tmplt = {
262         2, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_tcp}}
263 };
264
265 struct virtchnl_proto_hdrs second_inner_ipv6_tmplt = {
266         2, 1, {{proto_hdr_ipv6}}
267 };
268
269 struct virtchnl_proto_hdrs second_inner_ipv6_udp_tmplt = {
270         2, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_udp}}
271 };
272
273 struct virtchnl_proto_hdrs second_inner_ipv6_tcp_tmplt = {
274         2, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_tcp}}
275 };
276
277 struct virtchnl_proto_hdrs inner_ipv4_sctp_tmplt = {
278         TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv4, proto_hdr_sctp}}
279 };
280
281 struct virtchnl_proto_hdrs inner_ipv6_tmplt = {
282         TUNNEL_LEVEL_INNER, 1, {{proto_hdr_ipv6}}
283 };
284
285 struct virtchnl_proto_hdrs inner_ipv6_udp_tmplt = {
286         TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_udp}}
287 };
288
289 struct virtchnl_proto_hdrs inner_ipv6_tcp_tmplt = {
290         TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_tcp}}
291 };
292
293 struct virtchnl_proto_hdrs inner_ipv6_sctp_tmplt = {
294         TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv6, proto_hdr_sctp}}
295 };
296
297 struct virtchnl_proto_hdrs ipv4_esp_tmplt = {
298         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_esp}}
299 };
300
301 struct virtchnl_proto_hdrs ipv4_udp_esp_tmplt = {
302         TUNNEL_LEVEL_OUTER, 3,
303         {{proto_hdr_ipv4, proto_hdr_udp, proto_hdr_esp}}
304 };
305
306 struct virtchnl_proto_hdrs ipv4_ah_tmplt = {
307         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_ah}}
308 };
309
310 struct virtchnl_proto_hdrs ipv6_esp_tmplt = {
311         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_esp}}
312 };
313
314 struct virtchnl_proto_hdrs ipv6_udp_esp_tmplt = {
315         TUNNEL_LEVEL_OUTER, 3,
316         {{proto_hdr_ipv6, proto_hdr_udp, proto_hdr_esp}}
317 };
318
319 struct virtchnl_proto_hdrs ipv6_ah_tmplt = {
320         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_ah}}
321 };
322
323 struct virtchnl_proto_hdrs ipv4_l2tpv3_tmplt = {
324         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_l2tpv3}}
325 };
326
327 struct virtchnl_proto_hdrs ipv6_l2tpv3_tmplt = {
328         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_l2tpv3}}
329 };
330
331 struct virtchnl_proto_hdrs ipv4_pfcp_tmplt = {
332         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_pfcp}}
333 };
334
335 struct virtchnl_proto_hdrs ipv6_pfcp_tmplt = {
336         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_pfcp}}
337 };
338
339 struct virtchnl_proto_hdrs ipv4_udp_gtpc_tmplt = {
340         TUNNEL_LEVEL_OUTER, 3,
341         {{proto_hdr_ipv4, proto_hdr_udp, proto_hdr_gtpc}}
342 };
343
344 struct virtchnl_proto_hdrs ipv6_udp_gtpc_tmplt = {
345         TUNNEL_LEVEL_OUTER, 3,
346         {{proto_hdr_ipv6, proto_hdr_udp, proto_hdr_gtpc}}
347 };
348
349 struct virtchnl_proto_hdrs eth_ecpri_tmplt = {
350         TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_eth, proto_hdr_ecpri}}
351 };
352
353 struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
354         TUNNEL_LEVEL_OUTER, 3,
355         {{proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}}
356 };
357
358 struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
359         TUNNEL_LEVEL_INNER, 3,
360         {{proto_hdr_l2tpv2,
361           proto_hdr_ppp,
362           proto_hdr_ipv4}}
363 };
364
365 struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
366         TUNNEL_LEVEL_INNER, 3,
367         {{proto_hdr_l2tpv2,
368           proto_hdr_ppp,
369           proto_hdr_ipv6}}
370 };
371
372 struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
373         TUNNEL_LEVEL_INNER, 4,
374         {{proto_hdr_l2tpv2,
375           proto_hdr_ppp,
376           proto_hdr_ipv4_with_prot,
377           proto_hdr_udp}}
378 };
379
380 struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
381         TUNNEL_LEVEL_INNER, 4,
382         {{proto_hdr_l2tpv2,
383           proto_hdr_ppp,
384           proto_hdr_ipv4_with_prot,
385           proto_hdr_tcp}}
386 };
387
388 struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
389         TUNNEL_LEVEL_INNER, 4,
390         {{proto_hdr_l2tpv2,
391           proto_hdr_ppp,
392           proto_hdr_ipv6_with_prot,
393           proto_hdr_udp}}
394 };
395
396 struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
397         TUNNEL_LEVEL_INNER, 4,
398         {{proto_hdr_l2tpv2,
399           proto_hdr_ppp,
400           proto_hdr_ipv6_with_prot,
401           proto_hdr_tcp}}
402
403 };
404
405 struct virtchnl_proto_hdrs ipv4_l2tpv2_tmplt = {
406         TUNNEL_LEVEL_OUTER, 4,
407         {{proto_hdr_eth,
408           proto_hdr_ipv4,
409           proto_hdr_udp,
410           proto_hdr_l2tpv2}}
411 };
412
413 struct virtchnl_proto_hdrs ipv6_l2tpv2_tmplt = {
414         TUNNEL_LEVEL_OUTER, 4,
415         {{proto_hdr_eth,
416           proto_hdr_ipv6,
417           proto_hdr_udp,
418           proto_hdr_l2tpv2}}
419 };
420
421 struct virtchnl_proto_hdrs ipv4_l2tpv2_ppp_tmplt = {
422         TUNNEL_LEVEL_OUTER, 5,
423         {{proto_hdr_eth,
424           proto_hdr_ipv4,
425           proto_hdr_udp,
426           proto_hdr_l2tpv2,
427           proto_hdr_ppp}}
428 };
429
430 struct virtchnl_proto_hdrs ipv6_l2tpv2_ppp_tmplt = {
431         TUNNEL_LEVEL_OUTER, 5,
432         {{proto_hdr_eth,
433           proto_hdr_ipv6,
434           proto_hdr_udp,
435           proto_hdr_l2tpv2,
436           proto_hdr_ppp}}
437 };
438
439 /* rss type super set */
440
441 /* IPv4 outer */
442 #define IAVF_RSS_TYPE_OUTER_IPV4        (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV4 | \
443                                          RTE_ETH_RSS_FRAG_IPV4 | \
444                                          RTE_ETH_RSS_IPV4_CHKSUM)
445 #define IAVF_RSS_TYPE_OUTER_IPV4_UDP    (IAVF_RSS_TYPE_OUTER_IPV4 | \
446                                          RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
447                                          RTE_ETH_RSS_L4_CHKSUM)
448 #define IAVF_RSS_TYPE_OUTER_IPV4_TCP    (IAVF_RSS_TYPE_OUTER_IPV4 | \
449                                          RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
450                                          RTE_ETH_RSS_L4_CHKSUM)
451 #define IAVF_RSS_TYPE_OUTER_IPV4_SCTP   (IAVF_RSS_TYPE_OUTER_IPV4 | \
452                                          RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
453                                          RTE_ETH_RSS_L4_CHKSUM)
454 /* IPv6 outer */
455 #define IAVF_RSS_TYPE_OUTER_IPV6        (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6)
456 #define IAVF_RSS_TYPE_OUTER_IPV6_FRAG   (IAVF_RSS_TYPE_OUTER_IPV6 | \
457                                          RTE_ETH_RSS_FRAG_IPV6)
458 #define IAVF_RSS_TYPE_OUTER_IPV6_UDP    (IAVF_RSS_TYPE_OUTER_IPV6 | \
459                                          RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
460                                          RTE_ETH_RSS_L4_CHKSUM)
461 #define IAVF_RSS_TYPE_OUTER_IPV6_TCP    (IAVF_RSS_TYPE_OUTER_IPV6 | \
462                                          RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
463                                          RTE_ETH_RSS_L4_CHKSUM)
464 #define IAVF_RSS_TYPE_OUTER_IPV6_SCTP   (IAVF_RSS_TYPE_OUTER_IPV6 | \
465                                          RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
466                                          RTE_ETH_RSS_L4_CHKSUM)
467 /* VLAN IPV4 */
468 #define IAVF_RSS_TYPE_VLAN_IPV4         (IAVF_RSS_TYPE_OUTER_IPV4 | \
469                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
470 #define IAVF_RSS_TYPE_VLAN_IPV4_UDP     (IAVF_RSS_TYPE_OUTER_IPV4_UDP | \
471                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
472 #define IAVF_RSS_TYPE_VLAN_IPV4_TCP     (IAVF_RSS_TYPE_OUTER_IPV4_TCP | \
473                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
474 #define IAVF_RSS_TYPE_VLAN_IPV4_SCTP    (IAVF_RSS_TYPE_OUTER_IPV4_SCTP | \
475                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
476 /* VLAN IPv6 */
477 #define IAVF_RSS_TYPE_VLAN_IPV6         (IAVF_RSS_TYPE_OUTER_IPV6 | \
478                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
479 #define IAVF_RSS_TYPE_VLAN_IPV6_FRAG    (IAVF_RSS_TYPE_OUTER_IPV6_FRAG | \
480                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
481 #define IAVF_RSS_TYPE_VLAN_IPV6_UDP     (IAVF_RSS_TYPE_OUTER_IPV6_UDP | \
482                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
483 #define IAVF_RSS_TYPE_VLAN_IPV6_TCP     (IAVF_RSS_TYPE_OUTER_IPV6_TCP | \
484                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
485 #define IAVF_RSS_TYPE_VLAN_IPV6_SCTP    (IAVF_RSS_TYPE_OUTER_IPV6_SCTP | \
486                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
487 /* IPv4 inner */
488 #define IAVF_RSS_TYPE_INNER_IPV4        RTE_ETH_RSS_IPV4
489 #define IAVF_RSS_TYPE_INNER_IPV4_UDP    (RTE_ETH_RSS_IPV4 | \
490                                          RTE_ETH_RSS_NONFRAG_IPV4_UDP)
491 #define IAVF_RSS_TYPE_INNER_IPV4_TCP    (RTE_ETH_RSS_IPV4 | \
492                                          RTE_ETH_RSS_NONFRAG_IPV4_TCP)
493 #define IAVF_RSS_TYPE_INNER_IPV4_SCTP   (RTE_ETH_RSS_IPV4 | \
494                                          RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
495 /* IPv6 inner */
496 #define IAVF_RSS_TYPE_INNER_IPV6        RTE_ETH_RSS_IPV6
497 #define IAVF_RSS_TYPE_INNER_IPV6_UDP    (RTE_ETH_RSS_IPV6 | \
498                                          RTE_ETH_RSS_NONFRAG_IPV6_UDP)
499 #define IAVF_RSS_TYPE_INNER_IPV6_TCP    (RTE_ETH_RSS_IPV6 | \
500                                          RTE_ETH_RSS_NONFRAG_IPV6_TCP)
501 #define IAVF_RSS_TYPE_INNER_IPV6_SCTP   (RTE_ETH_RSS_IPV6 | \
502                                          RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
503 /* GTPU IPv4 */
504 #define IAVF_RSS_TYPE_GTPU_IPV4         (IAVF_RSS_TYPE_INNER_IPV4 | \
505                                          RTE_ETH_RSS_GTPU)
506 #define IAVF_RSS_TYPE_GTPU_IPV4_UDP     (IAVF_RSS_TYPE_INNER_IPV4_UDP | \
507                                          RTE_ETH_RSS_GTPU)
508 #define IAVF_RSS_TYPE_GTPU_IPV4_TCP     (IAVF_RSS_TYPE_INNER_IPV4_TCP | \
509                                          RTE_ETH_RSS_GTPU)
510 /* GTPU IPv6 */
511 #define IAVF_RSS_TYPE_GTPU_IPV6         (IAVF_RSS_TYPE_INNER_IPV6 | \
512                                          RTE_ETH_RSS_GTPU)
513 #define IAVF_RSS_TYPE_GTPU_IPV6_UDP     (IAVF_RSS_TYPE_INNER_IPV6_UDP | \
514                                          RTE_ETH_RSS_GTPU)
515 #define IAVF_RSS_TYPE_GTPU_IPV6_TCP     (IAVF_RSS_TYPE_INNER_IPV6_TCP | \
516                                          RTE_ETH_RSS_GTPU)
517 /* ESP, AH, L2TPV3 and PFCP */
518 #define IAVF_RSS_TYPE_IPV4_ESP          (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV4)
519 #define IAVF_RSS_TYPE_IPV4_AH           (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV4)
520 #define IAVF_RSS_TYPE_IPV6_ESP          (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV6)
521 #define IAVF_RSS_TYPE_IPV6_AH           (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV6)
522 #define IAVF_RSS_TYPE_IPV4_L2TPV3       (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV4)
523 #define IAVF_RSS_TYPE_IPV6_L2TPV3       (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV6)
524 #define IAVF_RSS_TYPE_IPV4_PFCP         (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV4)
525 #define IAVF_RSS_TYPE_IPV6_PFCP         (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV6)
526
527 /* L2TPv2 */
528 #define IAVF_RSS_TYPE_ETH_L2TPV2        (RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2TPV2)
529
530 /**
531  * Supported pattern for hash.
532  * The first member is pattern item type,
533  * the second member is input set mask,
534  * the third member is virtchnl_proto_hdrs template
535  */
536 static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
537         /* IPv4 */
538         {iavf_pattern_raw,                              IAVF_INSET_NONE,                NULL},
539         {iavf_pattern_eth_ipv4,                         IAVF_RSS_TYPE_OUTER_IPV4,       &outer_ipv4_tmplt},
540         {iavf_pattern_eth_ipv4_udp,                     IAVF_RSS_TYPE_OUTER_IPV4_UDP,   &outer_ipv4_udp_tmplt},
541         {iavf_pattern_eth_ipv4_tcp,                     IAVF_RSS_TYPE_OUTER_IPV4_TCP,   &outer_ipv4_tcp_tmplt},
542         {iavf_pattern_eth_ipv4_sctp,                    IAVF_RSS_TYPE_OUTER_IPV4_SCTP,  &outer_ipv4_sctp_tmplt},
543         {iavf_pattern_eth_vlan_ipv4,                    IAVF_RSS_TYPE_VLAN_IPV4,        &outer_ipv4_tmplt},
544         {iavf_pattern_eth_vlan_ipv4_udp,                IAVF_RSS_TYPE_VLAN_IPV4_UDP,    &outer_ipv4_udp_tmplt},
545         {iavf_pattern_eth_vlan_ipv4_tcp,                IAVF_RSS_TYPE_VLAN_IPV4_TCP,    &outer_ipv4_tcp_tmplt},
546         {iavf_pattern_eth_vlan_ipv4_sctp,               IAVF_RSS_TYPE_VLAN_IPV4_SCTP,   &outer_ipv4_sctp_tmplt},
547         {iavf_pattern_eth_ipv4_gtpu,                    RTE_ETH_RSS_IPV4,                       &outer_ipv4_udp_tmplt},
548         {iavf_pattern_eth_ipv4_gtpu_ipv4,               IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
549         {iavf_pattern_eth_ipv4_gtpu_ipv4_udp,           IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
550         {iavf_pattern_eth_ipv4_gtpu_ipv4_tcp,           IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
551         {iavf_pattern_eth_ipv6_gtpu_ipv4,               IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
552         {iavf_pattern_eth_ipv6_gtpu_ipv4_udp,           IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
553         {iavf_pattern_eth_ipv6_gtpu_ipv4_tcp,           IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
554         {iavf_pattern_eth_ipv4_gtpu_eh_ipv4,            IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
555         {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_udp,        IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
556         {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_tcp,        IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
557         {iavf_pattern_eth_ipv6_gtpu_eh_ipv4,            IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
558         {iavf_pattern_eth_ipv6_gtpu_eh_ipv4_udp,        IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
559         {iavf_pattern_eth_ipv6_gtpu_eh_ipv4_tcp,        IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
560         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
561         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
562         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
563         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
564         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
565         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
566         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
567         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
568         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
569         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
570         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
571         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
572         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
573         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
574         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
575         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
576         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
577         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
578         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
579         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
580         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
581         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
582         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
583         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
584         {iavf_pattern_eth_ipv4_esp,                     IAVF_RSS_TYPE_IPV4_ESP,         &ipv4_esp_tmplt},
585         {iavf_pattern_eth_ipv4_udp_esp,                 IAVF_RSS_TYPE_IPV4_ESP,         &ipv4_udp_esp_tmplt},
586         {iavf_pattern_eth_ipv4_ah,                      IAVF_RSS_TYPE_IPV4_AH,          &ipv4_ah_tmplt},
587         {iavf_pattern_eth_ipv4_l2tpv3,                  IAVF_RSS_TYPE_IPV4_L2TPV3,      &ipv4_l2tpv3_tmplt},
588         {iavf_pattern_eth_ipv4_pfcp,                    IAVF_RSS_TYPE_IPV4_PFCP,        &ipv4_pfcp_tmplt},
589         {iavf_pattern_eth_ipv4_gtpc,                    RTE_ETH_RSS_IPV4,                       &ipv4_udp_gtpc_tmplt},
590         {iavf_pattern_eth_ecpri,                        RTE_ETH_RSS_ECPRI,                      &eth_ecpri_tmplt},
591         {iavf_pattern_eth_ipv4_ecpri,                   RTE_ETH_RSS_ECPRI,                      &ipv4_ecpri_tmplt},
592         {iavf_pattern_eth_ipv4_gre_ipv4,                IAVF_RSS_TYPE_INNER_IPV4,       &inner_ipv4_tmplt},
593         {iavf_pattern_eth_ipv6_gre_ipv4,                IAVF_RSS_TYPE_INNER_IPV4, &inner_ipv4_tmplt},
594         {iavf_pattern_eth_ipv4_gre_ipv4_tcp,    IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
595         {iavf_pattern_eth_ipv6_gre_ipv4_tcp,    IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
596         {iavf_pattern_eth_ipv4_gre_ipv4_udp,    IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
597         {iavf_pattern_eth_ipv6_gre_ipv4_udp,    IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
598         {iavf_pattern_eth_ipv4_udp_l2tpv2,              IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv4_l2tpv2_tmplt},
599         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp,          IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv4_l2tpv2_ppp_tmplt},
600         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,     IAVF_RSS_TYPE_INNER_IPV4,       &udp_l2tpv2_ppp_ipv4_tmplt},
601         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP,   &udp_l2tpv2_ppp_ipv4_udp_tmplt},
602         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP,   &udp_l2tpv2_ppp_ipv4_tcp_tmplt},
603         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,     IAVF_RSS_TYPE_INNER_IPV4,       &udp_l2tpv2_ppp_ipv4_tmplt},
604         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP,   &udp_l2tpv2_ppp_ipv4_udp_tmplt},
605         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP,   &udp_l2tpv2_ppp_ipv4_tcp_tmplt},
606
607         /* IPv6 */
608         {iavf_pattern_eth_ipv6,                         IAVF_RSS_TYPE_OUTER_IPV6,       &outer_ipv6_tmplt},
609         {iavf_pattern_eth_ipv6_frag_ext,                IAVF_RSS_TYPE_OUTER_IPV6_FRAG,  &outer_ipv6_frag_tmplt},
610         {iavf_pattern_eth_ipv6_udp,                     IAVF_RSS_TYPE_OUTER_IPV6_UDP,   &outer_ipv6_udp_tmplt},
611         {iavf_pattern_eth_ipv6_tcp,                     IAVF_RSS_TYPE_OUTER_IPV6_TCP,   &outer_ipv6_tcp_tmplt},
612         {iavf_pattern_eth_ipv6_sctp,                    IAVF_RSS_TYPE_OUTER_IPV6_SCTP,  &outer_ipv6_sctp_tmplt},
613         {iavf_pattern_eth_vlan_ipv6,                    IAVF_RSS_TYPE_VLAN_IPV6,        &outer_ipv6_tmplt},
614         {iavf_pattern_eth_vlan_ipv6_frag_ext,           IAVF_RSS_TYPE_OUTER_IPV6_FRAG,  &outer_ipv6_frag_tmplt},
615         {iavf_pattern_eth_vlan_ipv6_udp,                IAVF_RSS_TYPE_VLAN_IPV6_UDP,    &outer_ipv6_udp_tmplt},
616         {iavf_pattern_eth_vlan_ipv6_tcp,                IAVF_RSS_TYPE_VLAN_IPV6_TCP,    &outer_ipv6_tcp_tmplt},
617         {iavf_pattern_eth_vlan_ipv6_sctp,               IAVF_RSS_TYPE_VLAN_IPV6_SCTP,   &outer_ipv6_sctp_tmplt},
618         {iavf_pattern_eth_ipv6_gtpu,                    RTE_ETH_RSS_IPV6,                       &outer_ipv6_udp_tmplt},
619         {iavf_pattern_eth_ipv4_gtpu_ipv6,               IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
620         {iavf_pattern_eth_ipv4_gtpu_ipv6_udp,           IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
621         {iavf_pattern_eth_ipv4_gtpu_ipv6_tcp,           IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
622         {iavf_pattern_eth_ipv6_gtpu_ipv6,               IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
623         {iavf_pattern_eth_ipv6_gtpu_ipv6_udp,           IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
624         {iavf_pattern_eth_ipv6_gtpu_ipv6_tcp,           IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
625         {iavf_pattern_eth_ipv4_gtpu_eh_ipv6,            IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
626         {iavf_pattern_eth_ipv4_gtpu_eh_ipv6_udp,        IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
627         {iavf_pattern_eth_ipv4_gtpu_eh_ipv6_tcp,        IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
628         {iavf_pattern_eth_ipv6_gtpu_eh_ipv6,            IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
629         {iavf_pattern_eth_ipv6_gtpu_eh_ipv6_udp,        IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
630         {iavf_pattern_eth_ipv6_gtpu_eh_ipv6_tcp,        IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
631         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
632         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
633         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
634         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
635         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
636         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
637         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
638         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
639         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
640         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
641         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
642         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
643         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
644         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
645         {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
646         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
647         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
648         {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
649         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
650         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
651         {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
652         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
653         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
654         {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
655         {iavf_pattern_eth_ipv6_esp,                     IAVF_RSS_TYPE_IPV6_ESP,         &ipv6_esp_tmplt},
656         {iavf_pattern_eth_ipv6_udp_esp,                 IAVF_RSS_TYPE_IPV6_ESP,         &ipv6_udp_esp_tmplt},
657         {iavf_pattern_eth_ipv6_ah,                      IAVF_RSS_TYPE_IPV6_AH,          &ipv6_ah_tmplt},
658         {iavf_pattern_eth_ipv6_l2tpv3,                  IAVF_RSS_TYPE_IPV6_L2TPV3,      &ipv6_l2tpv3_tmplt},
659         {iavf_pattern_eth_ipv6_pfcp,                    IAVF_RSS_TYPE_IPV6_PFCP,        &ipv6_pfcp_tmplt},
660         {iavf_pattern_eth_ipv6_gtpc,                    RTE_ETH_RSS_IPV6,                       &ipv6_udp_gtpc_tmplt},
661         {iavf_pattern_eth_ipv4_gre_ipv6,                IAVF_RSS_TYPE_INNER_IPV6,       &inner_ipv6_tmplt},
662         {iavf_pattern_eth_ipv6_gre_ipv6,                IAVF_RSS_TYPE_INNER_IPV6, &inner_ipv6_tmplt},
663         {iavf_pattern_eth_ipv4_gre_ipv6_tcp,    IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
664         {iavf_pattern_eth_ipv6_gre_ipv6_tcp,    IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
665         {iavf_pattern_eth_ipv4_gre_ipv6_udp,    IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
666         {iavf_pattern_eth_ipv6_gre_ipv6_udp,    IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
667         {iavf_pattern_eth_ipv6_udp_l2tpv2,              IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv6_l2tpv2_tmplt},
668         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp,          IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv6_l2tpv2_ppp_tmplt},
669         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,     IAVF_RSS_TYPE_INNER_IPV6,       &udp_l2tpv2_ppp_ipv6_tmplt},
670         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP,   &udp_l2tpv2_ppp_ipv6_udp_tmplt},
671         {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP,   &udp_l2tpv2_ppp_ipv6_tcp_tmplt},
672         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,     IAVF_RSS_TYPE_INNER_IPV6,       &udp_l2tpv2_ppp_ipv6_tmplt},
673         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP,   &udp_l2tpv2_ppp_ipv6_udp_tmplt},
674         {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP,   &udp_l2tpv2_ppp_ipv6_tcp_tmplt},
675
676 };
677
678 static struct iavf_flow_engine iavf_hash_engine = {
679         .init = iavf_hash_init,
680         .create = iavf_hash_create,
681         .destroy = iavf_hash_destroy,
682         .uninit = iavf_hash_uninit,
683         .free = iavf_hash_free,
684         .type = IAVF_FLOW_ENGINE_HASH,
685 };
686
687 /* Register parser for comms package. */
688 static struct iavf_flow_parser iavf_hash_parser = {
689         .engine = &iavf_hash_engine,
690         .array = iavf_hash_pattern_list,
691         .array_len = RTE_DIM(iavf_hash_pattern_list),
692         .parse_pattern_action = iavf_hash_parse_pattern_action,
693         .stage = IAVF_FLOW_STAGE_RSS,
694 };
695
696 int
697 iavf_rss_hash_set(struct iavf_adapter *ad, uint64_t rss_hf, bool add)
698 {
699         struct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(ad);
700         struct virtchnl_rss_cfg rss_cfg;
701
702 #define IAVF_RSS_HF_ALL ( \
703         RTE_ETH_RSS_IPV4 | \
704         RTE_ETH_RSS_IPV6 | \
705         RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
706         RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
707         RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
708         RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
709         RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
710         RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
711
712         rss_cfg.rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
713         if (rss_hf & RTE_ETH_RSS_IPV4) {
714                 rss_cfg.proto_hdrs = inner_ipv4_tmplt;
715                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
716         }
717
718         if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) {
719                 rss_cfg.proto_hdrs = inner_ipv4_udp_tmplt;
720                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
721         }
722
723         if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) {
724                 rss_cfg.proto_hdrs = inner_ipv4_tcp_tmplt;
725                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
726         }
727
728         if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) {
729                 rss_cfg.proto_hdrs = inner_ipv4_sctp_tmplt;
730                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
731         }
732
733         if (rss_hf & RTE_ETH_RSS_IPV6) {
734                 rss_cfg.proto_hdrs = inner_ipv6_tmplt;
735                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
736         }
737
738         if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) {
739                 rss_cfg.proto_hdrs = inner_ipv6_udp_tmplt;
740                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
741         }
742
743         if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) {
744                 rss_cfg.proto_hdrs = inner_ipv6_tcp_tmplt;
745                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
746         }
747
748         if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) {
749                 rss_cfg.proto_hdrs = inner_ipv6_sctp_tmplt;
750                 iavf_add_del_rss_cfg(ad, &rss_cfg, add);
751         }
752
753         vf->rss_hf = rss_hf & IAVF_RSS_HF_ALL;
754         return 0;
755 }
756
757 RTE_INIT(iavf_hash_engine_init)
758 {
759         struct iavf_flow_engine *engine = &iavf_hash_engine;
760
761         iavf_register_flow_engine(engine);
762 }
763
764 static int
765 iavf_hash_init(struct iavf_adapter *ad)
766 {
767         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
768         struct iavf_flow_parser *parser;
769         int ret;
770
771         if (vf->vf_reset)
772                 return -EIO;
773
774         if (!vf->vf_res)
775                 return -EINVAL;
776
777         if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF))
778                 return -ENOTSUP;
779
780         parser = &iavf_hash_parser;
781
782         ret = iavf_register_parser(parser, ad);
783         if (ret) {
784                 PMD_DRV_LOG(ERR, "fail to register hash parser");
785                 return ret;
786         }
787
788         return ret;
789 }
790
791 static int
792 iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
793                         struct rte_flow_error *error)
794 {
795         const struct rte_flow_item *item = pattern;
796         const struct rte_flow_item_gtp_psc *psc;
797         const struct rte_flow_item_ecpri *ecpri;
798         struct rte_ecpri_common_hdr ecpri_common;
799         const struct rte_flow_item_l2tpv2 *l2tpv2;
800         uint16_t flags_version;
801
802         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
803                 if (item->last) {
804                         rte_flow_error_set(error, EINVAL,
805                                            RTE_FLOW_ERROR_TYPE_ITEM, item,
806                                            "Not support range");
807                         return -rte_errno;
808                 }
809
810                 switch (item->type) {
811                 case RTE_FLOW_ITEM_TYPE_RAW:
812                         *phint |= IAVF_PHINT_RAW;
813                         break;
814                 case RTE_FLOW_ITEM_TYPE_IPV4:
815                         if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
816                             !(*phint & IAVF_PHINT_GRE) &&
817                             !(*phint & IAVF_PHINT_L2TPV2))
818                                 *phint |= IAVF_PHINT_OUTER_IPV4;
819                         if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
820                                 *phint |= IAVF_PHINT_MID_IPV4;
821                         break;
822                 case RTE_FLOW_ITEM_TYPE_IPV6:
823                         if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
824                             !(*phint & IAVF_PHINT_GRE) &&
825                             !(*phint & IAVF_PHINT_L2TPV2))
826                                 *phint |= IAVF_PHINT_OUTER_IPV6;
827                         if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
828                                 *phint |= IAVF_PHINT_MID_IPV6;
829                         break;
830                 case RTE_FLOW_ITEM_TYPE_GTPU:
831                         *phint |= IAVF_PHINT_GTPU;
832                         break;
833                 case RTE_FLOW_ITEM_TYPE_GTP_PSC:
834                         *phint |= IAVF_PHINT_GTPU_EH;
835                         psc = item->spec;
836                         if (!psc)
837                                 break;
838                         else if (psc->hdr.type == IAVF_GTPU_EH_UPLINK)
839                                 *phint |= IAVF_PHINT_GTPU_EH_UP;
840                         else if (psc->hdr.type == IAVF_GTPU_EH_DWNLINK)
841                                 *phint |= IAVF_PHINT_GTPU_EH_DWN;
842                         break;
843                 case RTE_FLOW_ITEM_TYPE_ECPRI:
844                         ecpri = item->spec;
845                         if (!ecpri)
846                                 break;
847
848                         ecpri_common.u32 = rte_be_to_cpu_32(ecpri->hdr.common.u32);
849
850                         if (ecpri_common.type !=
851                                  RTE_ECPRI_MSG_TYPE_IQ_DATA) {
852                                 rte_flow_error_set(error, EINVAL,
853                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
854                                         "Unsupported common type.");
855                                 return -rte_errno;
856                         }
857                         break;
858                 case RTE_FLOW_ITEM_TYPE_GRE:
859                         *phint |= IAVF_PHINT_GRE;
860                         break;
861                 case RTE_FLOW_ITEM_TYPE_L2TPV2:
862                         l2tpv2 = item->spec;
863
864                         if (l2tpv2) {
865                                 flags_version =
866                                         rte_be_to_cpu_16(l2tpv2->hdr.common.flags_version);
867                                 if (flags_version & IAVF_L2TPV2_FLAGS_LEN)
868                                         *phint |= IAVF_PHINT_L2TPV2_LEN;
869                                 else
870                                         *phint |= IAVF_PHINT_L2TPV2;
871                         } else {
872                                 *phint |= IAVF_PHINT_L2TPV2;
873                         }
874                         break;
875                 default:
876                         break;
877                 }
878         }
879
880         return 0;
881 }
882
883 static int
884 iavf_hash_parse_raw_pattern(const struct rte_flow_item *item,
885                         struct iavf_rss_meta *meta)
886 {
887         const struct rte_flow_item_raw *raw_spec, *raw_mask;
888         uint8_t *pkt_buf, *msk_buf;
889         uint8_t spec_len, pkt_len;
890         uint8_t tmp_val = 0;
891         uint8_t tmp_c = 0;
892         int i, j;
893
894         raw_spec = item->spec;
895         raw_mask = item->mask;
896
897         spec_len = strlen((char *)(uintptr_t)raw_spec->pattern);
898         if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
899                 spec_len)
900                 return -rte_errno;
901
902         pkt_len = spec_len / 2;
903
904         pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
905         if (!pkt_buf)
906                 return -ENOMEM;
907
908         msk_buf = rte_zmalloc(NULL, pkt_len, 0);
909         if (!msk_buf)
910                 return -ENOMEM;
911
912         /* convert string to int array */
913         for (i = 0, j = 0; i < spec_len; i += 2, j++) {
914                 tmp_c = raw_spec->pattern[i];
915                 if (tmp_c >= 'a' && tmp_c <= 'f')
916                         tmp_val = tmp_c - 'a' + 10;
917                 if (tmp_c >= 'A' && tmp_c <= 'F')
918                         tmp_val = tmp_c - 'A' + 10;
919                 if (tmp_c >= '0' && tmp_c <= '9')
920                         tmp_val = tmp_c - '0';
921
922                 tmp_c = raw_spec->pattern[i + 1];
923                 if (tmp_c >= 'a' && tmp_c <= 'f')
924                         pkt_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
925                 if (tmp_c >= 'A' && tmp_c <= 'F')
926                         pkt_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
927                 if (tmp_c >= '0' && tmp_c <= '9')
928                         pkt_buf[j] = tmp_val * 16 + tmp_c - '0';
929
930                 tmp_c = raw_mask->pattern[i];
931                 if (tmp_c >= 'a' && tmp_c <= 'f')
932                         tmp_val = tmp_c - 0x57;
933                 if (tmp_c >= 'A' && tmp_c <= 'F')
934                         tmp_val = tmp_c - 0x37;
935                 if (tmp_c >= '0' && tmp_c <= '9')
936                         tmp_val = tmp_c - '0';
937
938                 tmp_c = raw_mask->pattern[i + 1];
939                 if (tmp_c >= 'a' && tmp_c <= 'f')
940                         msk_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
941                 if (tmp_c >= 'A' && tmp_c <= 'F')
942                         msk_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
943                 if (tmp_c >= '0' && tmp_c <= '9')
944                         msk_buf[j] = tmp_val * 16 + tmp_c - '0';
945         }
946
947         rte_memcpy(meta->proto_hdrs.raw.spec, pkt_buf, pkt_len);
948         rte_memcpy(meta->proto_hdrs.raw.mask, msk_buf, pkt_len);
949         meta->proto_hdrs.raw.pkt_len = pkt_len;
950
951         rte_free(pkt_buf);
952         rte_free(msk_buf);
953
954         return 0;
955 }
956
957 #define REFINE_PROTO_FLD(op, fld) \
958         VIRTCHNL_##op##_PROTO_HDR_FIELD(hdr, VIRTCHNL_PROTO_HDR_##fld)
959 #define REPALCE_PROTO_FLD(fld_1, fld_2) \
960 do { \
961         REFINE_PROTO_FLD(DEL, fld_1);   \
962         REFINE_PROTO_FLD(ADD, fld_2);   \
963 } while (0)
964
965 static void
966 iavf_hash_add_fragment_hdr(struct virtchnl_proto_hdrs *hdrs, int layer)
967 {
968         struct virtchnl_proto_hdr *hdr1;
969         struct virtchnl_proto_hdr *hdr2;
970         int i;
971
972         if (layer < 0 || layer > hdrs->count)
973                 return;
974
975         /* shift headers layer */
976         for (i = hdrs->count; i >= layer; i--) {
977                 hdr1 = &hdrs->proto_hdr[i];
978                 hdr2 = &hdrs->proto_hdr[i - 1];
979                 *hdr1 = *hdr2;
980         }
981
982         /* adding dummy fragment header */
983         hdr1 = &hdrs->proto_hdr[layer];
984         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4_FRAG);
985         hdrs->count = ++layer;
986 }
987
988 /* refine proto hdrs base on l2, l3, l4 rss type */
989 static void
990 iavf_refine_proto_hdrs_l234(struct virtchnl_proto_hdrs *proto_hdrs,
991                             uint64_t rss_type)
992 {
993         struct virtchnl_proto_hdr *hdr;
994         int i;
995
996         for (i = 0; i < proto_hdrs->count; i++) {
997                 hdr = &proto_hdrs->proto_hdr[i];
998                 switch (hdr->type) {
999                 case VIRTCHNL_PROTO_HDR_ETH:
1000                         if (!(rss_type & RTE_ETH_RSS_ETH))
1001                                 hdr->field_selector = 0;
1002                         else if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
1003                                 REFINE_PROTO_FLD(DEL, ETH_DST);
1004                         else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
1005                                 REFINE_PROTO_FLD(DEL, ETH_SRC);
1006                         break;
1007                 case VIRTCHNL_PROTO_HDR_IPV4:
1008                         if (rss_type &
1009                             (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
1010                              RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1011                              RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1012                              RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
1013                                 if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
1014                                         iavf_hash_add_fragment_hdr(proto_hdrs, i + 1);
1015                                 } else if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
1016                                         REFINE_PROTO_FLD(DEL, IPV4_DST);
1017                                 } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
1018                                         REFINE_PROTO_FLD(DEL, IPV4_SRC);
1019                                 } else if (rss_type &
1020                                            (RTE_ETH_RSS_L4_SRC_ONLY |
1021                                             RTE_ETH_RSS_L4_DST_ONLY)) {
1022                                         REFINE_PROTO_FLD(DEL, IPV4_DST);
1023                                         REFINE_PROTO_FLD(DEL, IPV4_SRC);
1024                                 }
1025                         } else {
1026                                 hdr->field_selector = 0;
1027                         }
1028
1029                         if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
1030                                 REFINE_PROTO_FLD(ADD, IPV4_CHKSUM);
1031
1032                         break;
1033                 case VIRTCHNL_PROTO_HDR_IPV4_FRAG:
1034                         if (rss_type &
1035                             (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
1036                              RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1037                              RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1038                              RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
1039                                 if (rss_type & RTE_ETH_RSS_FRAG_IPV4)
1040                                         REFINE_PROTO_FLD(ADD, IPV4_FRAG_PKID);
1041                         } else {
1042                                 hdr->field_selector = 0;
1043                         }
1044
1045                         if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
1046                                 REFINE_PROTO_FLD(ADD, IPV4_CHKSUM);
1047
1048                         break;
1049                 case VIRTCHNL_PROTO_HDR_IPV6:
1050                         if (rss_type &
1051                             (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
1052                              RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1053                              RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1054                              RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
1055                                 if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
1056                                         REFINE_PROTO_FLD(DEL, IPV6_DST);
1057                                 } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
1058                                         REFINE_PROTO_FLD(DEL, IPV6_SRC);
1059                                 } else if (rss_type &
1060                                            (RTE_ETH_RSS_L4_SRC_ONLY |
1061                                             RTE_ETH_RSS_L4_DST_ONLY)) {
1062                                         REFINE_PROTO_FLD(DEL, IPV6_DST);
1063                                         REFINE_PROTO_FLD(DEL, IPV6_SRC);
1064                                 }
1065                         } else {
1066                                 hdr->field_selector = 0;
1067                         }
1068                         if (rss_type & RTE_ETH_RSS_L3_PRE64) {
1069                                 if (REFINE_PROTO_FLD(TEST, IPV6_SRC))
1070                                         REPALCE_PROTO_FLD(IPV6_SRC,
1071                                                           IPV6_PREFIX64_SRC);
1072                                 if (REFINE_PROTO_FLD(TEST, IPV6_DST))
1073                                         REPALCE_PROTO_FLD(IPV6_DST,
1074                                                           IPV6_PREFIX64_DST);
1075                         }
1076                         break;
1077                 case VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG:
1078                         if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
1079                                 REFINE_PROTO_FLD(ADD, IPV6_EH_FRAG_PKID);
1080                         else
1081                                 hdr->field_selector = 0;
1082
1083                         break;
1084                 case VIRTCHNL_PROTO_HDR_UDP:
1085                         if (rss_type &
1086                             (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1087                              RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
1088                                 if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
1089                                         REFINE_PROTO_FLD(DEL, UDP_DST_PORT);
1090                                 else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
1091                                         REFINE_PROTO_FLD(DEL, UDP_SRC_PORT);
1092                                 else if (rss_type &
1093                                          (RTE_ETH_RSS_L3_SRC_ONLY |
1094                                           RTE_ETH_RSS_L3_DST_ONLY))
1095                                         hdr->field_selector = 0;
1096                         } else {
1097                                 hdr->field_selector = 0;
1098                         }
1099
1100                         if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
1101                                 REFINE_PROTO_FLD(ADD, UDP_CHKSUM);
1102                         break;
1103                 case VIRTCHNL_PROTO_HDR_TCP:
1104                         if (rss_type &
1105                             (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1106                              RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
1107                                 if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
1108                                         REFINE_PROTO_FLD(DEL, TCP_DST_PORT);
1109                                 else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
1110                                         REFINE_PROTO_FLD(DEL, TCP_SRC_PORT);
1111                                 else if (rss_type &
1112                                          (RTE_ETH_RSS_L3_SRC_ONLY |
1113                                           RTE_ETH_RSS_L3_DST_ONLY))
1114                                         hdr->field_selector = 0;
1115                         } else {
1116                                 hdr->field_selector = 0;
1117                         }
1118
1119                         if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
1120                                 REFINE_PROTO_FLD(ADD, TCP_CHKSUM);
1121                         break;
1122                 case VIRTCHNL_PROTO_HDR_SCTP:
1123                         if (rss_type &
1124                             (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
1125                              RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
1126                                 if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
1127                                         REFINE_PROTO_FLD(DEL, SCTP_DST_PORT);
1128                                 else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
1129                                         REFINE_PROTO_FLD(DEL, SCTP_SRC_PORT);
1130                                 else if (rss_type &
1131                                          (RTE_ETH_RSS_L3_SRC_ONLY |
1132                                           RTE_ETH_RSS_L3_DST_ONLY))
1133                                         hdr->field_selector = 0;
1134                         } else {
1135                                 hdr->field_selector = 0;
1136                         }
1137
1138                         if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
1139                                 REFINE_PROTO_FLD(ADD, SCTP_CHKSUM);
1140                         break;
1141                 case VIRTCHNL_PROTO_HDR_S_VLAN:
1142                         if (!(rss_type & RTE_ETH_RSS_S_VLAN))
1143                                 hdr->field_selector = 0;
1144                         break;
1145                 case VIRTCHNL_PROTO_HDR_C_VLAN:
1146                         if (!(rss_type & RTE_ETH_RSS_C_VLAN))
1147                                 hdr->field_selector = 0;
1148                         break;
1149                 case VIRTCHNL_PROTO_HDR_L2TPV3:
1150                         if (!(rss_type & RTE_ETH_RSS_L2TPV3))
1151                                 hdr->field_selector = 0;
1152                         break;
1153                 case VIRTCHNL_PROTO_HDR_ESP:
1154                         if (!(rss_type & RTE_ETH_RSS_ESP))
1155                                 hdr->field_selector = 0;
1156                         break;
1157                 case VIRTCHNL_PROTO_HDR_AH:
1158                         if (!(rss_type & RTE_ETH_RSS_AH))
1159                                 hdr->field_selector = 0;
1160                         break;
1161                 case VIRTCHNL_PROTO_HDR_PFCP:
1162                         if (!(rss_type & RTE_ETH_RSS_PFCP))
1163                                 hdr->field_selector = 0;
1164                         break;
1165                 case VIRTCHNL_PROTO_HDR_ECPRI:
1166                         if (!(rss_type & RTE_ETH_RSS_ECPRI))
1167                                 hdr->field_selector = 0;
1168                         break;
1169                 case VIRTCHNL_PROTO_HDR_L2TPV2:
1170                         if (!(rss_type & RTE_ETH_RSS_L2TPV2))
1171                                 hdr->field_selector = 0;
1172                         break;
1173                 default:
1174                         break;
1175                 }
1176         }
1177 }
1178
1179 /* refine proto hdrs base on gtpu rss type */
1180 static void
1181 iavf_refine_proto_hdrs_gtpu(struct virtchnl_proto_hdrs *proto_hdrs,
1182                             uint64_t rss_type)
1183 {
1184         struct virtchnl_proto_hdr *hdr;
1185         int i;
1186
1187         if (!(rss_type & RTE_ETH_RSS_GTPU))
1188                 return;
1189
1190         for (i = 0; i < proto_hdrs->count; i++) {
1191                 hdr = &proto_hdrs->proto_hdr[i];
1192                 switch (hdr->type) {
1193                 case VIRTCHNL_PROTO_HDR_GTPU_IP:
1194                         REFINE_PROTO_FLD(ADD, GTPU_IP_TEID);
1195                         break;
1196                 default:
1197                         break;
1198                 }
1199         }
1200 }
1201
1202 static void
1203 iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
1204                                   uint64_t phint)
1205 {
1206         struct virtchnl_proto_hdr *hdr1;
1207         struct virtchnl_proto_hdr *hdr2;
1208         int i, shift_count = 1;
1209         int tun_lvl = proto_hdrs->tunnel_level;
1210
1211         if (!(phint & IAVF_PHINT_GTPU_MSK) && !(phint & IAVF_PHINT_GRE))
1212                 return;
1213
1214         while (tun_lvl) {
1215                 if (phint & IAVF_PHINT_LAYERS_MSK)
1216                         shift_count = 2;
1217
1218                 /* shift headers layer */
1219                 for (i = proto_hdrs->count - 1 + shift_count;
1220                      i > shift_count - 1; i--) {
1221                         hdr1 = &proto_hdrs->proto_hdr[i];
1222                         hdr2 = &proto_hdrs->proto_hdr[i - shift_count];
1223                         *hdr1 = *hdr2;
1224                 }
1225
1226                 if (shift_count == 1) {
1227                         /* adding tunnel header at layer 0 */
1228                         hdr1 = &proto_hdrs->proto_hdr[0];
1229                 } else {
1230                         /* adding tunnel header and outer ip header */
1231                         hdr1 = &proto_hdrs->proto_hdr[1];
1232                         hdr2 = &proto_hdrs->proto_hdr[0];
1233                         hdr2->field_selector = 0;
1234                         proto_hdrs->count++;
1235                         tun_lvl--;
1236
1237                         if (tun_lvl == TUNNEL_LEVEL_OUTER) {
1238                                 if (phint & IAVF_PHINT_OUTER_IPV4)
1239                                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV4);
1240                                 else if (phint & IAVF_PHINT_OUTER_IPV6)
1241                                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV6);
1242                         } else if (tun_lvl == TUNNEL_LEVEL_INNER) {
1243                                 if (phint & IAVF_PHINT_MID_IPV4)
1244                                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV4);
1245                                 else if (phint & IAVF_PHINT_MID_IPV6)
1246                                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV6);
1247                         }
1248                 }
1249
1250                 hdr1->field_selector = 0;
1251                 proto_hdrs->count++;
1252
1253                 if (phint & IAVF_PHINT_GTPU_EH_DWN)
1254                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_EH_PDU_DWN);
1255                 else if (phint & IAVF_PHINT_GTPU_EH_UP)
1256                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_EH_PDU_UP);
1257                 else if (phint & IAVF_PHINT_GTPU_EH)
1258                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_EH);
1259                 else if (phint & IAVF_PHINT_GTPU)
1260                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_IP);
1261
1262                 if (phint & IAVF_PHINT_GRE) {
1263                         if (phint & IAVF_PHINT_GTPU) {
1264                                 /* if GTPoGRE, add GRE header at the outer tunnel  */
1265                                 if (tun_lvl == TUNNEL_LEVEL_OUTER)
1266                                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GRE);
1267                         } else {
1268                                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GRE);
1269                         }
1270                 }
1271         }
1272         proto_hdrs->tunnel_level = tun_lvl;
1273 }
1274
1275 static void
1276 iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
1277                               uint64_t phint)
1278 {
1279         struct virtchnl_proto_hdr *hdr, *hdr1;
1280         int i;
1281
1282         if (!(phint & IAVF_PHINT_L2TPV2) && !(phint & IAVF_PHINT_L2TPV2_LEN))
1283                 return;
1284
1285         if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
1286                 /* shift headers layer */
1287                 for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
1288                         proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
1289
1290                 /* adding outer ip header at layer 0 */
1291                 hdr1 = &proto_hdrs->proto_hdr[0];
1292                 hdr1->field_selector = 0;
1293                 proto_hdrs->count++;
1294                 proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
1295                 if (phint & IAVF_PHINT_OUTER_IPV4)
1296                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
1297                 else if (phint & IAVF_PHINT_OUTER_IPV6)
1298                         VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
1299         } else {
1300                 for (i = 0; i < proto_hdrs->count; i++) {
1301                         hdr = &proto_hdrs->proto_hdr[i];
1302                         if (hdr->type == VIRTCHNL_PROTO_HDR_L2TPV2) {
1303                                 if (phint & IAVF_PHINT_L2TPV2) {
1304                                         REFINE_PROTO_FLD(DEL, L2TPV2_LEN_SESS_ID);
1305                                 } else if (phint & IAVF_PHINT_L2TPV2_LEN) {
1306                                         REFINE_PROTO_FLD(DEL, L2TPV2_SESS_ID);
1307                                 }
1308                         }
1309                 }
1310         }
1311
1312 }
1313
1314 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
1315                                    uint64_t rss_type, uint64_t phint)
1316 {
1317         iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
1318         iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
1319         iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
1320         iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
1321 }
1322
1323 static uint64_t invalid_rss_comb[] = {
1324         RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
1325         RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
1326         RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
1327         RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
1328         RTE_ETH_RSS_L3_PRE32 | RTE_ETH_RSS_L3_PRE40 |
1329         RTE_ETH_RSS_L3_PRE48 | RTE_ETH_RSS_L3_PRE56 |
1330         RTE_ETH_RSS_L3_PRE96
1331 };
1332
1333 struct rss_attr_type {
1334         uint64_t attr;
1335         uint64_t type;
1336 };
1337
1338 #define VALID_RSS_IPV4_L4       (RTE_ETH_RSS_NONFRAG_IPV4_UDP   | \
1339                                  RTE_ETH_RSS_NONFRAG_IPV4_TCP   | \
1340                                  RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
1341
1342 #define VALID_RSS_IPV6_L4       (RTE_ETH_RSS_NONFRAG_IPV6_UDP   | \
1343                                  RTE_ETH_RSS_NONFRAG_IPV6_TCP   | \
1344                                  RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
1345
1346 #define VALID_RSS_IPV4          (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | \
1347                                  VALID_RSS_IPV4_L4)
1348 #define VALID_RSS_IPV6          (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | \
1349                                  VALID_RSS_IPV6_L4)
1350 #define VALID_RSS_L3            (VALID_RSS_IPV4 | VALID_RSS_IPV6)
1351 #define VALID_RSS_L4            (VALID_RSS_IPV4_L4 | VALID_RSS_IPV6_L4)
1352
1353 #define VALID_RSS_ATTR          (RTE_ETH_RSS_L3_SRC_ONLY        | \
1354                                  RTE_ETH_RSS_L3_DST_ONLY        | \
1355                                  RTE_ETH_RSS_L4_SRC_ONLY        | \
1356                                  RTE_ETH_RSS_L4_DST_ONLY        | \
1357                                  RTE_ETH_RSS_L2_SRC_ONLY        | \
1358                                  RTE_ETH_RSS_L2_DST_ONLY        | \
1359                                  RTE_ETH_RSS_L3_PRE64)
1360
1361 #define INVALID_RSS_ATTR        (RTE_ETH_RSS_L3_PRE32   | \
1362                                  RTE_ETH_RSS_L3_PRE40   | \
1363                                  RTE_ETH_RSS_L3_PRE48   | \
1364                                  RTE_ETH_RSS_L3_PRE56   | \
1365                                  RTE_ETH_RSS_L3_PRE96)
1366
1367 static struct rss_attr_type rss_attr_to_valid_type[] = {
1368         {RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,     RTE_ETH_RSS_ETH},
1369         {RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,     VALID_RSS_L3},
1370         {RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,     VALID_RSS_L4},
1371         /* current ipv6 prefix only supports prefix 64 bits*/
1372         {RTE_ETH_RSS_L3_PRE64,                          VALID_RSS_IPV6},
1373         {INVALID_RSS_ATTR,                              0}
1374 };
1375
1376 static bool
1377 iavf_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1378                           uint64_t rss_type, uint64_t allow_rss_type)
1379 {
1380         uint32_t i;
1381
1382         /**
1383          * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1384          * hash function.
1385          */
1386         if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1387                 if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1388                     RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1389                         return true;
1390
1391                 if (!(rss_type &
1392                    (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1393                     RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1394                     RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1395                     RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1396                         return true;
1397         }
1398
1399         /* check invalid combination */
1400         for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1401                 if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
1402                         return true;
1403         }
1404
1405         /* check invalid RSS attribute */
1406         for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1407                 struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1408
1409                 if (rat->attr & rss_type && !(rat->type & rss_type))
1410                         return true;
1411         }
1412
1413         /* check not allowed RSS type */
1414         rss_type &= ~VALID_RSS_ATTR;
1415
1416         return ((rss_type & allow_rss_type) != rss_type);
1417 }
1418
1419 static int
1420 iavf_hash_parse_action(struct iavf_pattern_match_item *match_item,
1421                        const struct rte_flow_action actions[],
1422                        uint64_t pattern_hint, struct iavf_rss_meta *rss_meta,
1423                        struct rte_flow_error *error)
1424 {
1425         struct virtchnl_proto_hdrs *proto_hdrs;
1426         enum rte_flow_action_type action_type;
1427         const struct rte_flow_action_rss *rss;
1428         const struct rte_flow_action *action;
1429         uint64_t rss_type;
1430
1431         /* Supported action is RSS. */
1432         for (action = actions; action->type !=
1433                 RTE_FLOW_ACTION_TYPE_END; action++) {
1434                 action_type = action->type;
1435                 switch (action_type) {
1436                 case RTE_FLOW_ACTION_TYPE_RSS:
1437                         rss = action->conf;
1438                         rss_type = rss->types;
1439
1440                         if (rss->func ==
1441                             RTE_ETH_HASH_FUNCTION_SIMPLE_XOR){
1442                                 rss_meta->rss_algorithm =
1443                                         VIRTCHNL_RSS_ALG_XOR_ASYMMETRIC;
1444                                 return rte_flow_error_set(error, ENOTSUP,
1445                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1446                                         "function simple_xor is not supported");
1447                         } else if (rss->func ==
1448                                    RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1449                                 rss_meta->rss_algorithm =
1450                                         VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
1451                         } else {
1452                                 rss_meta->rss_algorithm =
1453                                         VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
1454                         }
1455
1456                         if (rss->level)
1457                                 return rte_flow_error_set(error, ENOTSUP,
1458                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1459                                         "a nonzero RSS encapsulation level is not supported");
1460
1461                         if (rss->key_len)
1462                                 return rte_flow_error_set(error, ENOTSUP,
1463                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1464                                         "a nonzero RSS key_len is not supported");
1465
1466                         if (rss->queue_num)
1467                                 return rte_flow_error_set(error, ENOTSUP,
1468                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
1469                                         "a non-NULL RSS queue is not supported");
1470
1471                         /* If pattern type is raw, no need to refine rss type */
1472                         if (pattern_hint == IAVF_PHINT_RAW)
1473                                 break;
1474
1475                         /**
1476                          * Check simultaneous use of SRC_ONLY and DST_ONLY
1477                          * of the same level.
1478                          */
1479                         rss_type = rte_eth_rss_hf_refine(rss_type);
1480
1481                         if (iavf_any_invalid_rss_type(rss->func, rss_type,
1482                                         match_item->input_set_mask))
1483                                 return rte_flow_error_set(error, ENOTSUP,
1484                                                 RTE_FLOW_ERROR_TYPE_ACTION,
1485                                                 action, "RSS type not supported");
1486                         proto_hdrs = match_item->meta;
1487                         rss_meta->proto_hdrs = *proto_hdrs;
1488                         iavf_refine_proto_hdrs(&rss_meta->proto_hdrs,
1489                                                rss_type, pattern_hint);
1490                         break;
1491
1492                 case RTE_FLOW_ACTION_TYPE_END:
1493                         break;
1494
1495                 default:
1496                         rte_flow_error_set(error, EINVAL,
1497                                            RTE_FLOW_ERROR_TYPE_ACTION, action,
1498                                            "Invalid action.");
1499                         return -rte_errno;
1500                 }
1501         }
1502
1503         return 0;
1504 }
1505
1506 static int
1507 iavf_hash_parse_pattern_action(__rte_unused struct iavf_adapter *ad,
1508                                struct iavf_pattern_match_item *array,
1509                                uint32_t array_len,
1510                                const struct rte_flow_item pattern[],
1511                                const struct rte_flow_action actions[],
1512                                void **meta,
1513                                struct rte_flow_error *error)
1514 {
1515         struct iavf_pattern_match_item *pattern_match_item;
1516         struct iavf_rss_meta *rss_meta_ptr;
1517         uint64_t phint = IAVF_PHINT_NONE;
1518         int ret = 0;
1519
1520         rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1521         if (!rss_meta_ptr) {
1522                 rte_flow_error_set(error, EINVAL,
1523                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1524                                    "No memory for rss_meta_ptr");
1525                 return -ENOMEM;
1526         }
1527
1528         /* Check rss supported pattern and find matched pattern. */
1529         pattern_match_item =
1530                 iavf_search_pattern_match_item(pattern, array, array_len,
1531                                                error);
1532         if (!pattern_match_item) {
1533                 ret = -rte_errno;
1534                 goto error;
1535         }
1536
1537         ret = iavf_hash_parse_pattern(pattern, &phint, error);
1538         if (ret)
1539                 goto error;
1540
1541         if (phint == IAVF_PHINT_RAW) {
1542                 rss_meta_ptr->raw_ena = true;
1543                 ret = iavf_hash_parse_raw_pattern(pattern, rss_meta_ptr);
1544                 if (ret) {
1545                         rte_flow_error_set(error, EINVAL,
1546                                            RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1547                                            "Parse raw pattern failed");
1548                         goto error;
1549                 }
1550         }
1551
1552         ret = iavf_hash_parse_action(pattern_match_item, actions, phint,
1553                                      rss_meta_ptr, error);
1554
1555 error:
1556         if (!ret && meta)
1557                 *meta = rss_meta_ptr;
1558         else
1559                 rte_free(rss_meta_ptr);
1560
1561         rte_free(pattern_match_item);
1562
1563         return ret;
1564 }
1565
1566 static int
1567 iavf_hash_create(__rte_unused struct iavf_adapter *ad,
1568                  __rte_unused struct rte_flow *flow, void *meta,
1569                  __rte_unused struct rte_flow_error *error)
1570 {
1571         struct iavf_rss_meta *rss_meta = (struct iavf_rss_meta *)meta;
1572         struct virtchnl_rss_cfg *rss_cfg;
1573         int ret = 0;
1574
1575         rss_cfg = rte_zmalloc("iavf rss rule",
1576                               sizeof(struct virtchnl_rss_cfg), 0);
1577         if (!rss_cfg) {
1578                 rte_flow_error_set(error, EINVAL,
1579                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1580                                    "No memory for rss rule");
1581                 return -ENOMEM;
1582         }
1583
1584         rss_cfg->proto_hdrs = rss_meta->proto_hdrs;
1585         rss_cfg->rss_algorithm = rss_meta->rss_algorithm;
1586
1587         ret = iavf_add_del_rss_cfg(ad, rss_cfg, true);
1588         if (!ret) {
1589                 flow->rule = rss_cfg;
1590         } else {
1591                 PMD_DRV_LOG(ERR, "fail to add RSS configure");
1592                 rte_flow_error_set(error, -ret,
1593                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1594                                    "Failed to add rss rule.");
1595                 rte_free(rss_cfg);
1596                 return -rte_errno;
1597         }
1598
1599         rte_free(meta);
1600
1601         return ret;
1602 }
1603
1604 static int
1605 iavf_hash_destroy(__rte_unused struct iavf_adapter *ad,
1606                   struct rte_flow *flow,
1607                   __rte_unused struct rte_flow_error *error)
1608 {
1609         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1610         struct virtchnl_rss_cfg *rss_cfg;
1611         int ret = 0;
1612
1613         if (vf->vf_reset)
1614                 return 0;
1615
1616         rss_cfg = (struct virtchnl_rss_cfg *)flow->rule;
1617
1618         ret = iavf_add_del_rss_cfg(ad, rss_cfg, false);
1619         if (ret) {
1620                 PMD_DRV_LOG(ERR, "fail to del RSS configure");
1621                 rte_flow_error_set(error, -ret,
1622                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1623                                    "Failed to delete rss rule.");
1624                 return -rte_errno;
1625         }
1626         return ret;
1627 }
1628
1629 static void
1630 iavf_hash_uninit(struct iavf_adapter *ad)
1631 {
1632         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1633         struct rte_eth_rss_conf *rss_conf;
1634
1635         if (vf->vf_reset)
1636                 return;
1637
1638         if (!vf->vf_res)
1639                 return;
1640
1641         if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF))
1642                 return;
1643
1644         rss_conf = &ad->dev_data->dev_conf.rx_adv_conf.rss_conf;
1645         if (iavf_rss_hash_set(ad, rss_conf->rss_hf, false))
1646                 PMD_DRV_LOG(ERR, "fail to delete default RSS");
1647
1648         iavf_unregister_parser(&iavf_hash_parser, ad);
1649 }
1650
1651 static void
1652 iavf_hash_free(struct rte_flow *flow)
1653 {
1654         rte_free(flow->rule);
1655 }