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