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