xref: /dpdk/drivers/net/iavf/iavf_hash.c (revision 01d90256)
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
iavf_rss_hash_set(struct iavf_adapter * ad,uint64_t rss_hf,bool add)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 
RTE_INIT(iavf_hash_engine_init)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
iavf_hash_init(struct iavf_adapter * ad)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
iavf_hash_parse_pattern(const struct rte_flow_item pattern[],uint64_t * phint,struct rte_flow_error * error)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
iavf_hash_add_fragment_hdr(struct virtchnl_proto_hdrs * hdrs,int layer)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
iavf_refine_proto_hdrs_l234(struct virtchnl_proto_hdrs * proto_hdrs,uint64_t rss_type)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
iavf_refine_proto_hdrs_gtpu(struct virtchnl_proto_hdrs * proto_hdrs,uint64_t rss_type)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
iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs * proto_hdrs,uint64_t phint)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
iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs * proto_hdrs,uint64_t phint)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 
iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs * proto_hdrs,uint64_t rss_type,uint64_t phint)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
iavf_any_invalid_rss_type(enum rte_eth_hash_function rss_func,uint64_t rss_type,uint64_t allow_rss_type)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
iavf_hash_parse_action(struct iavf_pattern_match_item * match_item,const struct rte_flow_action actions[],uint64_t pattern_hint,struct iavf_rss_meta * rss_meta,struct rte_flow_error * error)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
iavf_hash_parse_pattern_action(__rte_unused struct iavf_adapter * ad,struct iavf_pattern_match_item * array,uint32_t array_len,const struct rte_flow_item pattern[],const struct rte_flow_action actions[],void ** meta,struct rte_flow_error * error)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
iavf_hash_create(__rte_unused struct iavf_adapter * ad,__rte_unused struct rte_flow * flow,void * meta,__rte_unused struct rte_flow_error * error)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
iavf_hash_destroy(__rte_unused struct iavf_adapter * ad,struct rte_flow * flow,__rte_unused struct rte_flow_error * error)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
iavf_hash_uninit(struct iavf_adapter * ad)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
iavf_hash_free(struct rte_flow * flow)1552 iavf_hash_free(struct rte_flow *flow)
1553 {
1554 	rte_free(flow->rule);
1555 }
1556