xref: /dpdk/drivers/net/ice/ice_hash.c (revision 29fd052d)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 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 "ice_logs.h"
23 #include "base/ice_type.h"
24 #include "base/ice_flow.h"
25 #include "ice_ethdev.h"
26 #include "ice_generic_flow.h"
27 
28 #define ICE_PHINT_NONE				0
29 #define ICE_PHINT_VLAN				BIT_ULL(0)
30 #define ICE_PHINT_PPPOE				BIT_ULL(1)
31 #define ICE_PHINT_GTPU				BIT_ULL(2)
32 #define ICE_PHINT_GTPU_EH			BIT_ULL(3)
33 #define	ICE_PHINT_GTPU_EH_DWN			BIT_ULL(4)
34 #define	ICE_PHINT_GTPU_EH_UP			BIT_ULL(5)
35 #define ICE_PHINT_RAW				BIT_ULL(6)
36 
37 #define ICE_GTPU_EH_DWNLINK	0
38 #define ICE_GTPU_EH_UPLINK	1
39 
40 #define ICE_IPV4_PROT		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)
41 #define ICE_IPV6_PROT		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)
42 
43 #define VALID_RSS_IPV4_L4	(RTE_ETH_RSS_NONFRAG_IPV4_UDP	| \
44 				 RTE_ETH_RSS_NONFRAG_IPV4_TCP	| \
45 				 RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
46 
47 #define VALID_RSS_IPV6_L4	(RTE_ETH_RSS_NONFRAG_IPV6_UDP	| \
48 				 RTE_ETH_RSS_NONFRAG_IPV6_TCP	| \
49 				 RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
50 
51 #define VALID_RSS_IPV4		(RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | \
52 				 VALID_RSS_IPV4_L4)
53 #define VALID_RSS_IPV6		(RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | \
54 				 VALID_RSS_IPV6_L4)
55 #define VALID_RSS_L3		(VALID_RSS_IPV4 | VALID_RSS_IPV6)
56 #define VALID_RSS_L4		(VALID_RSS_IPV4_L4 | VALID_RSS_IPV6_L4)
57 
58 #define VALID_RSS_ATTR		(RTE_ETH_RSS_L3_SRC_ONLY	| \
59 				 RTE_ETH_RSS_L3_DST_ONLY	| \
60 				 RTE_ETH_RSS_L4_SRC_ONLY	| \
61 				 RTE_ETH_RSS_L4_DST_ONLY	| \
62 				 RTE_ETH_RSS_L2_SRC_ONLY	| \
63 				 RTE_ETH_RSS_L2_DST_ONLY	| \
64 				 RTE_ETH_RSS_L3_PRE32	| \
65 				 RTE_ETH_RSS_L3_PRE48	| \
66 				 RTE_ETH_RSS_L3_PRE64)
67 
68 #define INVALID_RSS_ATTR	(RTE_ETH_RSS_L3_PRE40	| \
69 				 RTE_ETH_RSS_L3_PRE56	| \
70 				 RTE_ETH_RSS_L3_PRE96)
71 
72 struct ice_rss_meta {
73 	uint8_t hash_function;
74 	struct ice_rss_hash_cfg cfg;
75 	struct ice_rss_raw_cfg raw;
76 };
77 
78 struct ice_hash_flow_cfg {
79 	bool simple_xor;
80 	struct ice_rss_cfg rss_cfg;
81 };
82 
83 static int
84 ice_hash_init(struct ice_adapter *ad);
85 
86 static int
87 ice_hash_create(struct ice_adapter *ad,
88 		struct rte_flow *flow,
89 		void *meta,
90 		struct rte_flow_error *error);
91 
92 static int
93 ice_hash_destroy(struct ice_adapter *ad,
94 		struct rte_flow *flow,
95 		struct rte_flow_error *error);
96 
97 static void
98 ice_hash_uninit(struct ice_adapter *ad);
99 
100 static void
101 ice_hash_free(struct rte_flow *flow);
102 
103 static int
104 ice_hash_parse_pattern_action(struct ice_adapter *ad,
105 			struct ice_pattern_match_item *array,
106 			uint32_t array_len,
107 			const struct rte_flow_item pattern[],
108 			const struct rte_flow_action actions[],
109 			uint32_t priority,
110 			void **meta,
111 			struct rte_flow_error *error);
112 
113 /* Rss configuration template */
114 struct ice_rss_hash_cfg ipv4_tmplt = {
115 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
116 	ICE_FLOW_SEG_HDR_IPV_OTHER,
117 	ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV4,
118 	ICE_RSS_OUTER_HEADERS,
119 	0
120 };
121 
122 struct ice_rss_hash_cfg ipv4_udp_tmplt = {
123 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
124 	ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_UDP,
125 	ICE_FLOW_HASH_ETH | ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
126 	ICE_RSS_OUTER_HEADERS,
127 	0
128 };
129 
130 struct ice_rss_hash_cfg ipv4_tcp_tmplt = {
131 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
132 	ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_TCP,
133 	ICE_FLOW_HASH_ETH | ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
134 	ICE_RSS_OUTER_HEADERS,
135 	0
136 };
137 
138 struct ice_rss_hash_cfg ipv4_sctp_tmplt = {
139 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
140 	ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_SCTP,
141 	ICE_FLOW_HASH_ETH | ICE_HASH_SCTP_IPV4 | ICE_IPV4_PROT,
142 	ICE_RSS_OUTER_HEADERS,
143 	0
144 };
145 
146 struct ice_rss_hash_cfg ipv6_tmplt = {
147 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
148 	ICE_FLOW_SEG_HDR_IPV_OTHER,
149 	ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV6,
150 	ICE_RSS_OUTER_HEADERS,
151 	0
152 };
153 
154 struct ice_rss_hash_cfg ipv6_frag_tmplt = {
155 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
156 	ICE_FLOW_SEG_HDR_IPV_FRAG,
157 	ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV6,
158 	ICE_RSS_OUTER_HEADERS,
159 	0
160 };
161 
162 struct ice_rss_hash_cfg ipv6_udp_tmplt = {
163 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
164 	ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_UDP,
165 	ICE_FLOW_HASH_ETH | ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
166 	ICE_RSS_OUTER_HEADERS,
167 	0
168 };
169 
170 struct ice_rss_hash_cfg ipv6_tcp_tmplt = {
171 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
172 	ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_TCP,
173 	ICE_FLOW_HASH_ETH | ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
174 	ICE_RSS_OUTER_HEADERS,
175 	0
176 };
177 
178 struct ice_rss_hash_cfg ipv6_sctp_tmplt = {
179 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
180 	ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_SCTP,
181 	ICE_FLOW_HASH_ETH | ICE_HASH_SCTP_IPV6 | ICE_IPV6_PROT,
182 	ICE_RSS_OUTER_HEADERS,
183 	0
184 };
185 
186 struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_tmplt = {
187 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER,
188 	ICE_FLOW_HASH_IPV4,
189 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
190 	0
191 };
192 struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_udp_tmplt = {
193 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
194 	ICE_FLOW_SEG_HDR_UDP,
195 	ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
196 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
197 	0
198 };
199 
200 struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_tcp_tmplt = {
201 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
202 	ICE_FLOW_SEG_HDR_TCP,
203 	ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
204 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
205 	0
206 };
207 
208 struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_tmplt = {
209 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER,
210 	ICE_FLOW_HASH_IPV4,
211 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
212 	0
213 };
214 
215 struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_udp_tmplt = {
216 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
217 	ICE_FLOW_SEG_HDR_UDP,
218 	ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
219 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
220 	0
221 };
222 
223 struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_tcp_tmplt = {
224 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
225 	ICE_FLOW_SEG_HDR_TCP,
226 	ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
227 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
228 	0
229 };
230 
231 struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_tmplt = {
232 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER,
233 	ICE_FLOW_HASH_IPV6,
234 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
235 	0
236 };
237 
238 struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_udp_tmplt = {
239 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
240 	ICE_FLOW_SEG_HDR_UDP,
241 	ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
242 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
243 	0
244 };
245 
246 struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_tcp_tmplt = {
247 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
248 	ICE_FLOW_SEG_HDR_TCP,
249 	ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
250 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
251 	0
252 };
253 
254 struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_tmplt = {
255 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER,
256 	ICE_FLOW_HASH_IPV6,
257 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
258 	0
259 };
260 struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_udp_tmplt = {
261 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
262 	ICE_FLOW_SEG_HDR_UDP,
263 	ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
264 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
265 	0
266 };
267 
268 struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_tcp_tmplt = {
269 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
270 	ICE_FLOW_SEG_HDR_TCP,
271 	ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
272 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
273 	0
274 };
275 
276 struct ice_rss_hash_cfg eth_ipv4_esp_tmplt = {
277 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
278 	ICE_FLOW_SEG_HDR_ESP,
279 	ICE_FLOW_HASH_ESP_SPI,
280 	ICE_RSS_OUTER_HEADERS,
281 	0
282 };
283 
284 struct ice_rss_hash_cfg eth_ipv4_udp_esp_tmplt = {
285 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
286 	ICE_FLOW_SEG_HDR_NAT_T_ESP,
287 	ICE_FLOW_HASH_NAT_T_ESP_SPI,
288 	ICE_RSS_OUTER_HEADERS,
289 	0
290 };
291 
292 struct ice_rss_hash_cfg eth_ipv4_ah_tmplt = {
293 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
294 	ICE_FLOW_SEG_HDR_AH,
295 	ICE_FLOW_HASH_AH_SPI,
296 	ICE_RSS_OUTER_HEADERS,
297 	0
298 };
299 
300 struct ice_rss_hash_cfg eth_ipv4_l2tpv3_tmplt = {
301 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
302 	ICE_FLOW_SEG_HDR_L2TPV3,
303 	ICE_FLOW_HASH_L2TPV3_SESS_ID,
304 	ICE_RSS_OUTER_HEADERS,
305 	0
306 };
307 
308 struct ice_rss_hash_cfg eth_ipv4_pfcp_tmplt = {
309 	ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
310 	ICE_FLOW_SEG_HDR_PFCP_SESSION,
311 	ICE_FLOW_HASH_PFCP_SEID,
312 	ICE_RSS_OUTER_HEADERS,
313 	0
314 };
315 
316 struct ice_rss_hash_cfg eth_ipv6_esp_tmplt = {
317 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
318 	ICE_FLOW_SEG_HDR_ESP,
319 	ICE_FLOW_HASH_ESP_SPI,
320 	ICE_RSS_OUTER_HEADERS,
321 	0
322 };
323 
324 struct ice_rss_hash_cfg eth_ipv6_udp_esp_tmplt = {
325 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
326 	ICE_FLOW_SEG_HDR_NAT_T_ESP,
327 	ICE_FLOW_HASH_NAT_T_ESP_SPI,
328 	ICE_RSS_OUTER_HEADERS,
329 	0
330 };
331 
332 struct ice_rss_hash_cfg eth_ipv6_ah_tmplt = {
333 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
334 	ICE_FLOW_SEG_HDR_AH,
335 	ICE_FLOW_HASH_AH_SPI,
336 	ICE_RSS_OUTER_HEADERS,
337 	0
338 };
339 
340 struct ice_rss_hash_cfg eth_ipv6_l2tpv3_tmplt = {
341 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
342 	ICE_FLOW_SEG_HDR_L2TPV3,
343 	ICE_FLOW_HASH_L2TPV3_SESS_ID,
344 	ICE_RSS_OUTER_HEADERS,
345 	0
346 };
347 
348 struct ice_rss_hash_cfg eth_ipv6_pfcp_tmplt = {
349 	ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
350 	ICE_FLOW_SEG_HDR_PFCP_SESSION,
351 	ICE_FLOW_HASH_PFCP_SEID,
352 	ICE_RSS_OUTER_HEADERS,
353 	0
354 };
355 
356 struct ice_rss_hash_cfg pppoe_tmplt = {
357 	ICE_FLOW_SEG_HDR_ETH,
358 	ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_PPPOE_SESS_ID,
359 	ICE_RSS_OUTER_HEADERS,
360 	0
361 };
362 
363 struct ice_rss_hash_cfg empty_tmplt = {
364 	ICE_FLOW_SEG_HDR_NONE,
365 	0,
366 	ICE_RSS_ANY_HEADERS,
367 	0
368 };
369 
370 struct ice_rss_hash_cfg eth_tmplt = {
371 	ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_ETH_NON_IP,
372 	ICE_FLOW_HASH_ETH,
373 	ICE_RSS_OUTER_HEADERS,
374 	0
375 };
376 
377 /* IPv4 */
378 #define ICE_RSS_TYPE_ETH_IPV4		(RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV4 | \
379 					 RTE_ETH_RSS_FRAG_IPV4 | \
380 					 RTE_ETH_RSS_IPV4_CHKSUM)
381 #define ICE_RSS_TYPE_ETH_IPV4_UDP	(ICE_RSS_TYPE_ETH_IPV4 | \
382 					 RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
383 					 RTE_ETH_RSS_L4_CHKSUM)
384 #define ICE_RSS_TYPE_ETH_IPV4_TCP	(ICE_RSS_TYPE_ETH_IPV4 | \
385 					 RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
386 					 RTE_ETH_RSS_L4_CHKSUM)
387 #define ICE_RSS_TYPE_ETH_IPV4_SCTP	(ICE_RSS_TYPE_ETH_IPV4 | \
388 					 RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
389 					 RTE_ETH_RSS_L4_CHKSUM)
390 #define ICE_RSS_TYPE_IPV4		RTE_ETH_RSS_IPV4
391 #define ICE_RSS_TYPE_IPV4_UDP		(RTE_ETH_RSS_IPV4 | \
392 					 RTE_ETH_RSS_NONFRAG_IPV4_UDP)
393 #define ICE_RSS_TYPE_IPV4_TCP		(RTE_ETH_RSS_IPV4 | \
394 					 RTE_ETH_RSS_NONFRAG_IPV4_TCP)
395 #define ICE_RSS_TYPE_IPV4_SCTP		(RTE_ETH_RSS_IPV4 | \
396 					 RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
397 
398 /* IPv6 */
399 #define ICE_RSS_TYPE_ETH_IPV6		(RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6)
400 #define ICE_RSS_TYPE_ETH_IPV6_FRAG	(RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6 | \
401 					 RTE_ETH_RSS_FRAG_IPV6)
402 #define ICE_RSS_TYPE_ETH_IPV6_UDP	(ICE_RSS_TYPE_ETH_IPV6 | \
403 					 RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
404 					 RTE_ETH_RSS_L4_CHKSUM)
405 #define ICE_RSS_TYPE_ETH_IPV6_TCP	(ICE_RSS_TYPE_ETH_IPV6 | \
406 					 RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
407 					 RTE_ETH_RSS_L4_CHKSUM)
408 #define ICE_RSS_TYPE_ETH_IPV6_SCTP	(ICE_RSS_TYPE_ETH_IPV6 | \
409 					 RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
410 					 RTE_ETH_RSS_L4_CHKSUM)
411 #define ICE_RSS_TYPE_IPV6		RTE_ETH_RSS_IPV6
412 #define ICE_RSS_TYPE_IPV6_UDP		(RTE_ETH_RSS_IPV6 | \
413 					 RTE_ETH_RSS_NONFRAG_IPV6_UDP)
414 #define ICE_RSS_TYPE_IPV6_TCP		(RTE_ETH_RSS_IPV6 | \
415 					 RTE_ETH_RSS_NONFRAG_IPV6_TCP)
416 #define ICE_RSS_TYPE_IPV6_SCTP		(RTE_ETH_RSS_IPV6 | \
417 					 RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
418 
419 /* VLAN IPV4 */
420 #define ICE_RSS_TYPE_VLAN_IPV4		(ICE_RSS_TYPE_IPV4 | \
421 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN | \
422 					 RTE_ETH_RSS_FRAG_IPV4)
423 #define ICE_RSS_TYPE_VLAN_IPV4_UDP	(ICE_RSS_TYPE_IPV4_UDP | \
424 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
425 #define ICE_RSS_TYPE_VLAN_IPV4_TCP	(ICE_RSS_TYPE_IPV4_TCP | \
426 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
427 #define ICE_RSS_TYPE_VLAN_IPV4_SCTP	(ICE_RSS_TYPE_IPV4_SCTP | \
428 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
429 /* VLAN IPv6 */
430 #define ICE_RSS_TYPE_VLAN_IPV6		(ICE_RSS_TYPE_IPV6 | \
431 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
432 #define ICE_RSS_TYPE_VLAN_IPV6_FRAG	(ICE_RSS_TYPE_IPV6 | \
433 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN | \
434 					 RTE_ETH_RSS_FRAG_IPV6)
435 #define ICE_RSS_TYPE_VLAN_IPV6_UDP	(ICE_RSS_TYPE_IPV6_UDP | \
436 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
437 #define ICE_RSS_TYPE_VLAN_IPV6_TCP	(ICE_RSS_TYPE_IPV6_TCP | \
438 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
439 #define ICE_RSS_TYPE_VLAN_IPV6_SCTP	(ICE_RSS_TYPE_IPV6_SCTP | \
440 					 RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
441 
442 /* GTPU IPv4 */
443 #define ICE_RSS_TYPE_GTPU_IPV4		(ICE_RSS_TYPE_IPV4 | \
444 					 RTE_ETH_RSS_GTPU)
445 #define ICE_RSS_TYPE_GTPU_IPV4_UDP	(ICE_RSS_TYPE_IPV4_UDP | \
446 					 RTE_ETH_RSS_GTPU)
447 #define ICE_RSS_TYPE_GTPU_IPV4_TCP	(ICE_RSS_TYPE_IPV4_TCP | \
448 					 RTE_ETH_RSS_GTPU)
449 /* GTPU IPv6 */
450 #define ICE_RSS_TYPE_GTPU_IPV6		(ICE_RSS_TYPE_IPV6 | \
451 					 RTE_ETH_RSS_GTPU)
452 #define ICE_RSS_TYPE_GTPU_IPV6_UDP	(ICE_RSS_TYPE_IPV6_UDP | \
453 					 RTE_ETH_RSS_GTPU)
454 #define ICE_RSS_TYPE_GTPU_IPV6_TCP	(ICE_RSS_TYPE_IPV6_TCP | \
455 					 RTE_ETH_RSS_GTPU)
456 
457 /* PPPOE */
458 #define ICE_RSS_TYPE_PPPOE		(RTE_ETH_RSS_ETH | RTE_ETH_RSS_PPPOE)
459 
460 /* PPPOE IPv4 */
461 #define ICE_RSS_TYPE_PPPOE_IPV4		(ICE_RSS_TYPE_IPV4 | \
462 					 ICE_RSS_TYPE_PPPOE)
463 #define ICE_RSS_TYPE_PPPOE_IPV4_UDP	(ICE_RSS_TYPE_IPV4_UDP | \
464 					 ICE_RSS_TYPE_PPPOE)
465 #define ICE_RSS_TYPE_PPPOE_IPV4_TCP	(ICE_RSS_TYPE_IPV4_TCP | \
466 					 ICE_RSS_TYPE_PPPOE)
467 
468 /* PPPOE IPv6 */
469 #define ICE_RSS_TYPE_PPPOE_IPV6		(ICE_RSS_TYPE_IPV6 | \
470 					 ICE_RSS_TYPE_PPPOE)
471 #define ICE_RSS_TYPE_PPPOE_IPV6_UDP	(ICE_RSS_TYPE_IPV6_UDP | \
472 					 ICE_RSS_TYPE_PPPOE)
473 #define ICE_RSS_TYPE_PPPOE_IPV6_TCP	(ICE_RSS_TYPE_IPV6_TCP | \
474 					 ICE_RSS_TYPE_PPPOE)
475 
476 /* ESP, AH, L2TPV3 and PFCP */
477 #define ICE_RSS_TYPE_IPV4_ESP		(RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV4)
478 #define ICE_RSS_TYPE_IPV6_ESP		(RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV6)
479 #define ICE_RSS_TYPE_IPV4_AH		(RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV4)
480 #define ICE_RSS_TYPE_IPV6_AH		(RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV6)
481 #define ICE_RSS_TYPE_IPV4_L2TPV3	(RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV4)
482 #define ICE_RSS_TYPE_IPV6_L2TPV3	(RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV6)
483 #define ICE_RSS_TYPE_IPV4_PFCP		(RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV4)
484 #define ICE_RSS_TYPE_IPV6_PFCP		(RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV6)
485 
486 /* MAC */
487 #define ICE_RSS_TYPE_ETH		RTE_ETH_RSS_ETH
488 
489 /**
490  * Supported pattern for hash.
491  * The first member is pattern item type,
492  * the second member is input set mask,
493  * the third member is ice_rss_hash_cfg template.
494  */
495 static struct ice_pattern_match_item ice_hash_pattern_list[] = {
496 	/* IPV4 */
497 	{pattern_raw,				ICE_INSET_NONE,				ICE_INSET_NONE,	NULL},
498 	{pattern_eth_ipv4,			ICE_RSS_TYPE_ETH_IPV4,		ICE_INSET_NONE,	&ipv4_tmplt},
499 	{pattern_eth_ipv4_udp,			ICE_RSS_TYPE_ETH_IPV4_UDP,	ICE_INSET_NONE,	&ipv4_udp_tmplt},
500 	{pattern_eth_ipv4_tcp,			ICE_RSS_TYPE_ETH_IPV4_TCP,	ICE_INSET_NONE,	&ipv4_tcp_tmplt},
501 	{pattern_eth_ipv4_sctp,			ICE_RSS_TYPE_ETH_IPV4_SCTP,	ICE_INSET_NONE,	&ipv4_sctp_tmplt},
502 	{pattern_eth_vlan_ipv4,			ICE_RSS_TYPE_VLAN_IPV4,		ICE_INSET_NONE,	&ipv4_tmplt},
503 	{pattern_eth_vlan_ipv4_udp,		ICE_RSS_TYPE_VLAN_IPV4_UDP,	ICE_INSET_NONE,	&ipv4_udp_tmplt},
504 	{pattern_eth_vlan_ipv4_tcp,		ICE_RSS_TYPE_VLAN_IPV4_TCP,	ICE_INSET_NONE,	&ipv4_tcp_tmplt},
505 	{pattern_eth_vlan_ipv4_sctp,		ICE_RSS_TYPE_VLAN_IPV4_SCTP,	ICE_INSET_NONE,	&ipv4_sctp_tmplt},
506 	{pattern_eth_ipv4_gtpu_ipv4,		ICE_RSS_TYPE_GTPU_IPV4,		ICE_INSET_NONE,	&outer_ipv4_inner_ipv4_tmplt},
507 	{pattern_eth_ipv4_gtpu_ipv4_udp,	ICE_RSS_TYPE_GTPU_IPV4_UDP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv4_udp_tmplt},
508 	{pattern_eth_ipv4_gtpu_ipv4_tcp,	ICE_RSS_TYPE_GTPU_IPV4_TCP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv4_tcp_tmplt},
509 	{pattern_eth_ipv6_gtpu_ipv4,		ICE_RSS_TYPE_GTPU_IPV4,		ICE_INSET_NONE,	&outer_ipv6_inner_ipv4_tmplt},
510 	{pattern_eth_ipv6_gtpu_ipv4_udp,	ICE_RSS_TYPE_GTPU_IPV4_UDP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv4_udp_tmplt},
511 	{pattern_eth_ipv6_gtpu_ipv4_tcp,	ICE_RSS_TYPE_GTPU_IPV4_TCP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv4_tcp_tmplt},
512 	{pattern_eth_ipv4_gtpu_eh_ipv4,		ICE_RSS_TYPE_GTPU_IPV4,		ICE_INSET_NONE,	&outer_ipv4_inner_ipv4_tmplt},
513 	{pattern_eth_ipv4_gtpu_eh_ipv4_udp,	ICE_RSS_TYPE_GTPU_IPV4_UDP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv4_udp_tmplt},
514 	{pattern_eth_ipv4_gtpu_eh_ipv4_tcp,	ICE_RSS_TYPE_GTPU_IPV4_TCP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv4_tcp_tmplt},
515 	{pattern_eth_ipv6_gtpu_eh_ipv4,		ICE_RSS_TYPE_GTPU_IPV4,		ICE_INSET_NONE,	&outer_ipv6_inner_ipv4_tmplt},
516 	{pattern_eth_ipv6_gtpu_eh_ipv4_udp,	ICE_RSS_TYPE_GTPU_IPV4_UDP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv4_udp_tmplt},
517 	{pattern_eth_ipv6_gtpu_eh_ipv4_tcp,	ICE_RSS_TYPE_GTPU_IPV4_TCP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv4_tcp_tmplt},
518 	{pattern_eth_pppoes_ipv4,		ICE_RSS_TYPE_PPPOE_IPV4,	ICE_INSET_NONE,	&ipv4_tmplt},
519 	{pattern_eth_pppoes_ipv4_udp,		ICE_RSS_TYPE_PPPOE_IPV4_UDP,	ICE_INSET_NONE,	&ipv4_udp_tmplt},
520 	{pattern_eth_pppoes_ipv4_tcp,		ICE_RSS_TYPE_PPPOE_IPV4_TCP,	ICE_INSET_NONE,	&ipv4_tcp_tmplt},
521 	{pattern_eth_ipv4_esp,			ICE_RSS_TYPE_IPV4_ESP,		ICE_INSET_NONE,	&eth_ipv4_esp_tmplt},
522 	{pattern_eth_ipv4_udp_esp,		ICE_RSS_TYPE_IPV4_ESP,		ICE_INSET_NONE,	&eth_ipv4_udp_esp_tmplt},
523 	{pattern_eth_ipv4_ah,			ICE_RSS_TYPE_IPV4_AH,		ICE_INSET_NONE,	&eth_ipv4_ah_tmplt},
524 	{pattern_eth_ipv4_l2tp,			ICE_RSS_TYPE_IPV4_L2TPV3,	ICE_INSET_NONE,	&eth_ipv4_l2tpv3_tmplt},
525 	{pattern_eth_ipv4_pfcp,			ICE_RSS_TYPE_IPV4_PFCP,		ICE_INSET_NONE,	&eth_ipv4_pfcp_tmplt},
526 	/* IPV6 */
527 	{pattern_eth_ipv6,			ICE_RSS_TYPE_ETH_IPV6,		ICE_INSET_NONE,	&ipv6_tmplt},
528 	{pattern_eth_ipv6_frag_ext,		ICE_RSS_TYPE_ETH_IPV6_FRAG,	ICE_INSET_NONE,	&ipv6_frag_tmplt},
529 	{pattern_eth_ipv6_udp,			ICE_RSS_TYPE_ETH_IPV6_UDP,	ICE_INSET_NONE,	&ipv6_udp_tmplt},
530 	{pattern_eth_ipv6_tcp,			ICE_RSS_TYPE_ETH_IPV6_TCP,	ICE_INSET_NONE,	&ipv6_tcp_tmplt},
531 	{pattern_eth_ipv6_sctp,			ICE_RSS_TYPE_ETH_IPV6_SCTP,	ICE_INSET_NONE,	&ipv6_sctp_tmplt},
532 	{pattern_eth_vlan_ipv6,			ICE_RSS_TYPE_VLAN_IPV6,		ICE_INSET_NONE,	&ipv6_tmplt},
533 	{pattern_eth_vlan_ipv6_frag_ext,	ICE_RSS_TYPE_VLAN_IPV6_FRAG,	ICE_INSET_NONE, &ipv6_frag_tmplt},
534 	{pattern_eth_vlan_ipv6_udp,		ICE_RSS_TYPE_VLAN_IPV6_UDP,	ICE_INSET_NONE,	&ipv6_udp_tmplt},
535 	{pattern_eth_vlan_ipv6_tcp,		ICE_RSS_TYPE_VLAN_IPV6_TCP,	ICE_INSET_NONE,	&ipv6_tcp_tmplt},
536 	{pattern_eth_vlan_ipv6_sctp,		ICE_RSS_TYPE_VLAN_IPV6_SCTP,	ICE_INSET_NONE,	&ipv6_sctp_tmplt},
537 	{pattern_eth_ipv4_gtpu_ipv6,		ICE_RSS_TYPE_GTPU_IPV6,		ICE_INSET_NONE,	&outer_ipv4_inner_ipv6_tmplt},
538 	{pattern_eth_ipv4_gtpu_ipv6_udp,	ICE_RSS_TYPE_GTPU_IPV6_UDP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv6_udp_tmplt},
539 	{pattern_eth_ipv4_gtpu_ipv6_tcp,	ICE_RSS_TYPE_GTPU_IPV6_TCP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv6_tcp_tmplt},
540 	{pattern_eth_ipv6_gtpu_ipv6,		ICE_RSS_TYPE_GTPU_IPV6,		ICE_INSET_NONE,	&outer_ipv6_inner_ipv6_tmplt},
541 	{pattern_eth_ipv6_gtpu_ipv6_udp,	ICE_RSS_TYPE_GTPU_IPV6_UDP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv6_udp_tmplt},
542 	{pattern_eth_ipv6_gtpu_ipv6_tcp,	ICE_RSS_TYPE_GTPU_IPV6_TCP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv6_tcp_tmplt},
543 	{pattern_eth_ipv4_gtpu_eh_ipv6,		ICE_RSS_TYPE_GTPU_IPV6,		ICE_INSET_NONE,	&outer_ipv4_inner_ipv6_tmplt},
544 	{pattern_eth_ipv4_gtpu_eh_ipv6_udp,	ICE_RSS_TYPE_GTPU_IPV6_UDP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv6_udp_tmplt},
545 	{pattern_eth_ipv4_gtpu_eh_ipv6_tcp,	ICE_RSS_TYPE_GTPU_IPV6_TCP,	ICE_INSET_NONE,	&outer_ipv4_inner_ipv6_tcp_tmplt},
546 	{pattern_eth_ipv6_gtpu_eh_ipv6,		ICE_RSS_TYPE_GTPU_IPV6,		ICE_INSET_NONE,	&outer_ipv6_inner_ipv6_tmplt},
547 	{pattern_eth_ipv6_gtpu_eh_ipv6_udp,	ICE_RSS_TYPE_GTPU_IPV6_UDP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv6_udp_tmplt},
548 	{pattern_eth_ipv6_gtpu_eh_ipv6_tcp,	ICE_RSS_TYPE_GTPU_IPV6_TCP,	ICE_INSET_NONE,	&outer_ipv6_inner_ipv6_tcp_tmplt},
549 	{pattern_eth_pppoes_ipv6,		ICE_RSS_TYPE_PPPOE_IPV6,	ICE_INSET_NONE,	&ipv6_tmplt},
550 	{pattern_eth_pppoes_ipv6_udp,		ICE_RSS_TYPE_PPPOE_IPV6_UDP,	ICE_INSET_NONE,	&ipv6_udp_tmplt},
551 	{pattern_eth_pppoes_ipv6_tcp,		ICE_RSS_TYPE_PPPOE_IPV6_TCP,	ICE_INSET_NONE,	&ipv6_tcp_tmplt},
552 	{pattern_eth_ipv6_esp,			ICE_RSS_TYPE_IPV6_ESP,		ICE_INSET_NONE,	&eth_ipv6_esp_tmplt},
553 	{pattern_eth_ipv6_udp_esp,		ICE_RSS_TYPE_IPV6_ESP,		ICE_INSET_NONE,	&eth_ipv6_udp_esp_tmplt},
554 	{pattern_eth_ipv6_ah,			ICE_RSS_TYPE_IPV6_AH,		ICE_INSET_NONE,	&eth_ipv6_ah_tmplt},
555 	{pattern_eth_ipv6_l2tp,			ICE_RSS_TYPE_IPV6_L2TPV3,	ICE_INSET_NONE,	&eth_ipv6_l2tpv3_tmplt},
556 	{pattern_eth_ipv6_pfcp,			ICE_RSS_TYPE_IPV6_PFCP,		ICE_INSET_NONE,	&eth_ipv6_pfcp_tmplt},
557 	/* PPPOE */
558 	{pattern_eth_pppoes,			ICE_RSS_TYPE_PPPOE,		ICE_INSET_NONE,	&pppoe_tmplt},
559 	/* MAC */
560 	{pattern_ethertype,			ICE_RSS_TYPE_ETH,		ICE_INSET_NONE, &eth_tmplt},
561 	/* EMPTY */
562 	{pattern_empty,				ICE_INSET_NONE,			ICE_INSET_NONE,	&empty_tmplt},
563 };
564 
565 static struct ice_flow_engine ice_hash_engine = {
566 	.init = ice_hash_init,
567 	.create = ice_hash_create,
568 	.destroy = ice_hash_destroy,
569 	.uninit = ice_hash_uninit,
570 	.free = ice_hash_free,
571 	.type = ICE_FLOW_ENGINE_HASH,
572 };
573 
574 /* Register parser for os package. */
575 static struct ice_flow_parser ice_hash_parser = {
576 	.engine = &ice_hash_engine,
577 	.array = ice_hash_pattern_list,
578 	.array_len = RTE_DIM(ice_hash_pattern_list),
579 	.parse_pattern_action = ice_hash_parse_pattern_action,
580 	.stage = ICE_FLOW_STAGE_RSS,
581 };
582 
583 RTE_INIT(ice_hash_engine_init)
584 {
585 	struct ice_flow_engine *engine = &ice_hash_engine;
586 	ice_register_flow_engine(engine);
587 }
588 
589 static int
590 ice_hash_init(struct ice_adapter *ad)
591 {
592 	struct ice_flow_parser *parser = NULL;
593 
594 	if (ad->hw.dcf_enabled)
595 		return 0;
596 
597 	parser = &ice_hash_parser;
598 
599 	return ice_register_parser(parser, ad);
600 }
601 
602 static int
603 ice_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
604 		       struct rte_flow_error *error)
605 {
606 	const struct rte_flow_item *item = pattern;
607 	const struct rte_flow_item_gtp_psc *psc;
608 
609 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
610 		if (item->last) {
611 			rte_flow_error_set(error, EINVAL,
612 					RTE_FLOW_ERROR_TYPE_ITEM, item,
613 					"Not support range");
614 			return -rte_errno;
615 		}
616 
617 		switch (item->type) {
618 		case RTE_FLOW_ITEM_TYPE_RAW:
619 			*phint |= ICE_PHINT_RAW;
620 			break;
621 		case RTE_FLOW_ITEM_TYPE_VLAN:
622 			*phint |= ICE_PHINT_VLAN;
623 			break;
624 		case RTE_FLOW_ITEM_TYPE_PPPOES:
625 			*phint |= ICE_PHINT_PPPOE;
626 			break;
627 		case RTE_FLOW_ITEM_TYPE_GTPU:
628 			*phint |= ICE_PHINT_GTPU;
629 			break;
630 		case RTE_FLOW_ITEM_TYPE_GTP_PSC:
631 			*phint |= ICE_PHINT_GTPU_EH;
632 			psc = item->spec;
633 			if (!psc)
634 				break;
635 			else if (psc->hdr.type == ICE_GTPU_EH_UPLINK)
636 				*phint |= ICE_PHINT_GTPU_EH_UP;
637 			else if (psc->hdr.type == ICE_GTPU_EH_DWNLINK)
638 				*phint |= ICE_PHINT_GTPU_EH_DWN;
639 			break;
640 		default:
641 			break;
642 		}
643 	}
644 
645 	return 0;
646 }
647 
648 static int
649 ice_hash_parse_raw_pattern(struct ice_adapter *ad,
650 				const struct rte_flow_item *item,
651 				struct ice_rss_meta *meta)
652 {
653 	const struct rte_flow_item_raw *raw_spec, *raw_mask;
654 	struct ice_parser_profile prof;
655 	struct ice_parser_result rslt;
656 	struct ice_parser *psr;
657 	uint8_t *pkt_buf, *msk_buf;
658 	uint8_t spec_len, pkt_len;
659 	uint8_t tmp_val = 0;
660 	uint8_t tmp_c = 0;
661 	int i, j;
662 
663 	raw_spec = item->spec;
664 	raw_mask = item->mask;
665 
666 	spec_len = strlen((char *)(uintptr_t)raw_spec->pattern);
667 	if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
668 		spec_len)
669 		return -rte_errno;
670 
671 	pkt_len = spec_len / 2;
672 
673 	pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
674 	if (!pkt_buf)
675 		return -ENOMEM;
676 
677 	msk_buf = rte_zmalloc(NULL, pkt_len, 0);
678 	if (!msk_buf)
679 		return -ENOMEM;
680 
681 	/* convert string to int array */
682 	for (i = 0, j = 0; i < spec_len; i += 2, j++) {
683 		tmp_c = raw_spec->pattern[i];
684 		if (tmp_c >= 'a' && tmp_c <= 'f')
685 			tmp_val = tmp_c - 'a' + 10;
686 		if (tmp_c >= 'A' && tmp_c <= 'F')
687 			tmp_val = tmp_c - 'A' + 10;
688 		if (tmp_c >= '0' && tmp_c <= '9')
689 			tmp_val = tmp_c - '0';
690 
691 		tmp_c = raw_spec->pattern[i + 1];
692 		if (tmp_c >= 'a' && tmp_c <= 'f')
693 			pkt_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
694 		if (tmp_c >= 'A' && tmp_c <= 'F')
695 			pkt_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
696 		if (tmp_c >= '0' && tmp_c <= '9')
697 			pkt_buf[j] = tmp_val * 16 + tmp_c - '0';
698 
699 		tmp_c = raw_mask->pattern[i];
700 		if (tmp_c >= 'a' && tmp_c <= 'f')
701 			tmp_val = tmp_c - 0x57;
702 		if (tmp_c >= 'A' && tmp_c <= 'F')
703 			tmp_val = tmp_c - 0x37;
704 		if (tmp_c >= '0' && tmp_c <= '9')
705 			tmp_val = tmp_c - '0';
706 
707 		tmp_c = raw_mask->pattern[i + 1];
708 		if (tmp_c >= 'a' && tmp_c <= 'f')
709 			msk_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
710 		if (tmp_c >= 'A' && tmp_c <= 'F')
711 			msk_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
712 		if (tmp_c >= '0' && tmp_c <= '9')
713 			msk_buf[j] = tmp_val * 16 + tmp_c - '0';
714 	}
715 
716 	if (ice_parser_create(&ad->hw, &psr))
717 		return -rte_errno;
718 	if (ice_parser_run(psr, pkt_buf, pkt_len, &rslt))
719 		return -rte_errno;
720 	ice_parser_destroy(psr);
721 
722 	if (ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
723 		pkt_len, ICE_BLK_RSS, true, &prof))
724 		return -rte_errno;
725 
726 	rte_memcpy(&meta->raw.prof, &prof, sizeof(prof));
727 
728 	rte_free(pkt_buf);
729 	rte_free(msk_buf);
730 	return 0;
731 }
732 
733 static void
734 ice_refine_hash_cfg_l234(struct ice_rss_hash_cfg *hash_cfg,
735 			 uint64_t rss_type)
736 {
737 	uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
738 	uint64_t *hash_flds = &hash_cfg->hash_flds;
739 
740 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH) {
741 		if (!(rss_type & RTE_ETH_RSS_ETH))
742 			*hash_flds &= ~ICE_FLOW_HASH_ETH;
743 		if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
744 			*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA));
745 		else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
746 			*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA));
747 		*addl_hdrs &= ~ICE_FLOW_SEG_HDR_ETH;
748 	}
749 
750 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
751 		if (rss_type & RTE_ETH_RSS_ETH)
752 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE);
753 	}
754 
755 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_VLAN) {
756 		if (rss_type & RTE_ETH_RSS_C_VLAN)
757 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN);
758 		else if (rss_type & RTE_ETH_RSS_S_VLAN)
759 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN);
760 	}
761 
762 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
763 		if (!(rss_type & RTE_ETH_RSS_PPPOE))
764 			*hash_flds &= ~ICE_FLOW_HASH_PPPOE_SESS_ID;
765 	}
766 
767 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV4) {
768 		if (rss_type &
769 		   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
770 		    RTE_ETH_RSS_NONFRAG_IPV4_UDP |
771 		    RTE_ETH_RSS_NONFRAG_IPV4_TCP |
772 		    RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
773 			if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
774 				*addl_hdrs |= ICE_FLOW_SEG_HDR_IPV_FRAG;
775 				*addl_hdrs &= ~(ICE_FLOW_SEG_HDR_IPV_OTHER);
776 				*hash_flds |=
777 					BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_ID);
778 			}
779 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
780 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA));
781 			else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
782 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA));
783 			else if (rss_type &
784 				(RTE_ETH_RSS_L4_SRC_ONLY |
785 				RTE_ETH_RSS_L4_DST_ONLY))
786 				*hash_flds &= ~ICE_FLOW_HASH_IPV4;
787 		} else {
788 			*hash_flds &= ~ICE_FLOW_HASH_IPV4;
789 		}
790 
791 		if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
792 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_CHKSUM);
793 	}
794 
795 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV6) {
796 		if (rss_type &
797 		   (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
798 		    RTE_ETH_RSS_NONFRAG_IPV6_UDP |
799 		    RTE_ETH_RSS_NONFRAG_IPV6_TCP |
800 		    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
801 			if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
802 				*hash_flds |=
803 					BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_ID);
804 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
805 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
806 			else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
807 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
808 			else if (rss_type &
809 				(RTE_ETH_RSS_L4_SRC_ONLY |
810 				RTE_ETH_RSS_L4_DST_ONLY))
811 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
812 		} else {
813 			*hash_flds &= ~ICE_FLOW_HASH_IPV6;
814 		}
815 
816 		if (rss_type & RTE_ETH_RSS_L3_PRE32) {
817 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
818 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
819 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA));
820 			} else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
821 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
822 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA));
823 			} else {
824 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
825 				*hash_flds |= ICE_FLOW_HASH_IPV6_PRE32;
826 			}
827 		}
828 		if (rss_type & RTE_ETH_RSS_L3_PRE48) {
829 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
830 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
831 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA));
832 			} else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
833 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
834 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA));
835 			} else {
836 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
837 				*hash_flds |= ICE_FLOW_HASH_IPV6_PRE48;
838 			}
839 		}
840 		if (rss_type & RTE_ETH_RSS_L3_PRE64) {
841 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
842 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
843 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA));
844 			} else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
845 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
846 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA));
847 			} else {
848 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
849 				*hash_flds |= ICE_FLOW_HASH_IPV6_PRE64;
850 			}
851 		}
852 	}
853 
854 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_UDP) {
855 		if (rss_type &
856 		   (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
857 		    RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
858 			if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
859 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT));
860 			else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
861 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT));
862 			else if (rss_type &
863 				(RTE_ETH_RSS_L3_SRC_ONLY |
864 				  RTE_ETH_RSS_L3_DST_ONLY))
865 				*hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
866 		} else {
867 			*hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
868 		}
869 
870 		if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
871 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_CHKSUM);
872 	}
873 
874 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_TCP) {
875 		if (rss_type &
876 		   (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
877 		    RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
878 			if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
879 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT));
880 			else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
881 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT));
882 			else if (rss_type &
883 				(RTE_ETH_RSS_L3_SRC_ONLY |
884 				  RTE_ETH_RSS_L3_DST_ONLY))
885 				*hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
886 		} else {
887 			*hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
888 		}
889 
890 		if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
891 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_CHKSUM);
892 	}
893 
894 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_SCTP) {
895 		if (rss_type &
896 		   (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
897 		    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
898 			if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
899 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT));
900 			else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
901 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT));
902 			else if (rss_type &
903 				(RTE_ETH_RSS_L3_SRC_ONLY |
904 				  RTE_ETH_RSS_L3_DST_ONLY))
905 				*hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
906 		} else {
907 			*hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
908 		}
909 
910 		if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
911 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_CHKSUM);
912 	}
913 
914 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
915 		if (!(rss_type & RTE_ETH_RSS_L2TPV3))
916 			*hash_flds &= ~ICE_FLOW_HASH_L2TPV3_SESS_ID;
917 	}
918 
919 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_ESP) {
920 		if (!(rss_type & RTE_ETH_RSS_ESP))
921 			*hash_flds &= ~ICE_FLOW_HASH_ESP_SPI;
922 	}
923 
924 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_AH) {
925 		if (!(rss_type & RTE_ETH_RSS_AH))
926 			*hash_flds &= ~ICE_FLOW_HASH_AH_SPI;
927 	}
928 
929 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_PFCP_SESSION) {
930 		if (!(rss_type & RTE_ETH_RSS_PFCP))
931 			*hash_flds &= ~ICE_FLOW_HASH_PFCP_SEID;
932 	}
933 }
934 
935 static void
936 ice_refine_proto_hdrs_by_pattern(struct ice_rss_hash_cfg *hash_cfg,
937 				 uint64_t phint)
938 {
939 	uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
940 	if (phint & ICE_PHINT_VLAN)
941 		*addl_hdrs |= ICE_FLOW_SEG_HDR_VLAN;
942 
943 	if (phint & ICE_PHINT_PPPOE)
944 		*addl_hdrs |= ICE_FLOW_SEG_HDR_PPPOE;
945 
946 	if (phint & ICE_PHINT_GTPU_EH_DWN)
947 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_DWN;
948 	else if (phint & ICE_PHINT_GTPU_EH_UP)
949 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_UP;
950 	else if (phint & ICE_PHINT_GTPU_EH)
951 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_EH;
952 	else if (phint & ICE_PHINT_GTPU)
953 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_IP;
954 }
955 
956 static void
957 ice_refine_hash_cfg_gtpu(struct ice_rss_hash_cfg *hash_cfg,
958 			 uint64_t rss_type)
959 {
960 	uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
961 	uint64_t *hash_flds = &hash_cfg->hash_flds;
962 
963 	/* update hash field for gtpu eh/gtpu dwn/gtpu up. */
964 	if (!(rss_type & RTE_ETH_RSS_GTPU))
965 		return;
966 
967 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN)
968 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID);
969 	else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_UP)
970 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_UP_TEID);
971 	else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_EH)
972 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_EH_TEID);
973 	else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_IP)
974 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID);
975 }
976 
977 static void ice_refine_hash_cfg(struct ice_rss_hash_cfg *hash_cfg,
978 				uint64_t rss_type, uint64_t phint)
979 {
980 	ice_refine_proto_hdrs_by_pattern(hash_cfg, phint);
981 	ice_refine_hash_cfg_l234(hash_cfg, rss_type);
982 	ice_refine_hash_cfg_gtpu(hash_cfg, rss_type);
983 }
984 
985 static uint64_t invalid_rss_comb[] = {
986 	RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
987 	RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
988 	RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
989 	RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
990 	RTE_ETH_RSS_L3_PRE40 |
991 	RTE_ETH_RSS_L3_PRE56 |
992 	RTE_ETH_RSS_L3_PRE96
993 };
994 
995 struct rss_attr_type {
996 	uint64_t attr;
997 	uint64_t type;
998 };
999 
1000 static struct rss_attr_type rss_attr_to_valid_type[] = {
1001 	{RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,	RTE_ETH_RSS_ETH},
1002 	{RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,	VALID_RSS_L3},
1003 	{RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,	VALID_RSS_L4},
1004 	/* current ipv6 prefix only supports prefix 64 bits*/
1005 	{RTE_ETH_RSS_L3_PRE32,				VALID_RSS_IPV6},
1006 	{RTE_ETH_RSS_L3_PRE48,				VALID_RSS_IPV6},
1007 	{RTE_ETH_RSS_L3_PRE64,				VALID_RSS_IPV6},
1008 	{INVALID_RSS_ATTR,				0}
1009 };
1010 
1011 static bool
1012 ice_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1013 			 uint64_t rss_type, uint64_t allow_rss_type)
1014 {
1015 	uint32_t i;
1016 
1017 	/**
1018 	 * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1019 	 * hash function.
1020 	 */
1021 	if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1022 		if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1023 		    RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1024 			return true;
1025 
1026 		if (!(rss_type &
1027 		   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1028 		    RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6 |
1029 		    RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1030 		    RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1031 		    RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1032 			return true;
1033 	}
1034 
1035 	/* check invalid combination */
1036 	for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1037 		if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
1038 			return true;
1039 	}
1040 
1041 	/* check invalid RSS attribute */
1042 	for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1043 		struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1044 
1045 		if (rat->attr & rss_type && !(rat->type & rss_type))
1046 			return true;
1047 	}
1048 
1049 	/* check not allowed RSS type */
1050 	rss_type &= ~VALID_RSS_ATTR;
1051 
1052 	return ((rss_type & allow_rss_type) != rss_type);
1053 }
1054 
1055 static int
1056 ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item,
1057 		const struct rte_flow_action actions[],
1058 		uint64_t pattern_hint, struct ice_rss_meta *rss_meta,
1059 		struct rte_flow_error *error)
1060 {
1061 	struct ice_rss_hash_cfg *cfg = pattern_match_item->meta;
1062 	enum rte_flow_action_type action_type;
1063 	const struct rte_flow_action_rss *rss;
1064 	const struct rte_flow_action *action;
1065 	uint64_t rss_type;
1066 
1067 	/* Supported action is RSS. */
1068 	for (action = actions; action->type !=
1069 		RTE_FLOW_ACTION_TYPE_END; action++) {
1070 		action_type = action->type;
1071 		switch (action_type) {
1072 		case RTE_FLOW_ACTION_TYPE_RSS:
1073 			rss = action->conf;
1074 			rss_type = rss->types;
1075 
1076 			/* Check hash function and save it to rss_meta. */
1077 			if (pattern_match_item->pattern_list !=
1078 			    pattern_empty && rss->func ==
1079 			    RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1080 				return rte_flow_error_set(error, ENOTSUP,
1081 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1082 					"Not supported flow");
1083 			} else if (rss->func ==
1084 				   RTE_ETH_HASH_FUNCTION_SIMPLE_XOR){
1085 				rss_meta->hash_function =
1086 				RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
1087 				return 0;
1088 			} else if (rss->func ==
1089 				   RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1090 				rss_meta->hash_function =
1091 				RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
1092 				if (pattern_hint == ICE_PHINT_RAW)
1093 					rss_meta->raw.symm = true;
1094 				else
1095 					cfg->symm = true;
1096 			}
1097 
1098 			if (rss->level)
1099 				return rte_flow_error_set(error, ENOTSUP,
1100 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1101 					"a nonzero RSS encapsulation level is not supported");
1102 
1103 			if (rss->key_len)
1104 				return rte_flow_error_set(error, ENOTSUP,
1105 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1106 					"a nonzero RSS key_len is not supported");
1107 
1108 			if (rss->queue)
1109 				return rte_flow_error_set(error, ENOTSUP,
1110 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1111 					"a non-NULL RSS queue is not supported");
1112 
1113 			/* If pattern type is raw, no need to refine rss type */
1114 			if (pattern_hint == ICE_PHINT_RAW)
1115 				break;
1116 
1117 			/**
1118 			 * Check simultaneous use of SRC_ONLY and DST_ONLY
1119 			 * of the same level.
1120 			 */
1121 			rss_type = rte_eth_rss_hf_refine(rss_type);
1122 
1123 			if (ice_any_invalid_rss_type(rss->func, rss_type,
1124 					pattern_match_item->input_set_mask_o))
1125 				return rte_flow_error_set(error, ENOTSUP,
1126 					RTE_FLOW_ERROR_TYPE_ACTION,
1127 					action, "RSS type not supported");
1128 
1129 			rss_meta->cfg = *cfg;
1130 			ice_refine_hash_cfg(&rss_meta->cfg,
1131 					    rss_type, pattern_hint);
1132 			break;
1133 		case RTE_FLOW_ACTION_TYPE_END:
1134 			break;
1135 
1136 		default:
1137 			rte_flow_error_set(error, EINVAL,
1138 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1139 					"Invalid action.");
1140 			return -rte_errno;
1141 		}
1142 	}
1143 
1144 	return 0;
1145 }
1146 
1147 static int
1148 ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
1149 			struct ice_pattern_match_item *array,
1150 			uint32_t array_len,
1151 			const struct rte_flow_item pattern[],
1152 			const struct rte_flow_action actions[],
1153 			uint32_t priority,
1154 			void **meta,
1155 			struct rte_flow_error *error)
1156 {
1157 	int ret = 0;
1158 	struct ice_pattern_match_item *pattern_match_item;
1159 	struct ice_rss_meta *rss_meta_ptr;
1160 	uint64_t phint = ICE_PHINT_NONE;
1161 
1162 	if (priority >= 1)
1163 		return -rte_errno;
1164 
1165 	rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1166 	if (!rss_meta_ptr) {
1167 		rte_flow_error_set(error, EINVAL,
1168 				RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1169 				"No memory for rss_meta_ptr");
1170 		return -ENOMEM;
1171 	}
1172 
1173 	/* Check rss supported pattern and find matched pattern. */
1174 	pattern_match_item = ice_search_pattern_match_item(ad, pattern, array,
1175 							   array_len, error);
1176 	if (!pattern_match_item) {
1177 		ret = -rte_errno;
1178 		goto error;
1179 	}
1180 
1181 	ret = ice_hash_parse_pattern(pattern, &phint, error);
1182 	if (ret)
1183 		goto error;
1184 
1185 	if (phint == ICE_PHINT_RAW) {
1186 		rss_meta_ptr->raw.raw_ena = true;
1187 		ret = ice_hash_parse_raw_pattern(ad, pattern, rss_meta_ptr);
1188 		if (ret) {
1189 			rte_flow_error_set(error, EINVAL,
1190 					   RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1191 					   "Parse raw pattern failed");
1192 			goto error;
1193 		}
1194 	}
1195 
1196 	/* Check rss action. */
1197 	ret = ice_hash_parse_action(pattern_match_item, actions, phint,
1198 				    rss_meta_ptr, error);
1199 
1200 error:
1201 	if (!ret && meta)
1202 		*meta = rss_meta_ptr;
1203 	else
1204 		rte_free(rss_meta_ptr);
1205 	rte_free(pattern_match_item);
1206 
1207 	return ret;
1208 }
1209 
1210 static int
1211 ice_hash_add_raw_cfg(struct ice_adapter *ad,
1212 		struct ice_rss_raw_cfg *cfg, u16 vsi_handle)
1213 {
1214 	struct ice_parser_profile *prof = &cfg->prof;
1215 	struct ice_rss_prof_info *rss_prof;
1216 	struct ice_hw *hw = &ad->hw;
1217 	int i, ptg, ret;
1218 	u64 id;
1219 
1220 	id = (u64)ice_find_first_bit(prof->ptypes, UINT16_MAX);
1221 
1222 	ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1223 	rss_prof = &ad->rss_prof_info[ptg];
1224 	/* check if ptg already has profile */
1225 	if (rss_prof->prof.fv_num) {
1226 		for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1227 			if (rss_prof->prof.fv[i].proto_id !=
1228 			    prof->fv[i].proto_id ||
1229 			    rss_prof->prof.fv[i].offset !=
1230 			    prof->fv[i].offset)
1231 				break;
1232 		}
1233 
1234 		/* current profile is matched, check symmetric hash */
1235 		if (i == ICE_MAX_FV_WORDS) {
1236 			if (rss_prof->symm != cfg->symm)
1237 				goto update_symm;
1238 
1239 			return 0;
1240 		}
1241 
1242 		/* current profile is not matched, remove it */
1243 		ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1244 					   ice_get_hw_vsi_num(hw, vsi_handle),
1245 					   id);
1246 		if (ret) {
1247 			PMD_DRV_LOG(ERR, "remove RSS flow failed\n");
1248 			return ret;
1249 		}
1250 
1251 		ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1252 		if (ret) {
1253 			PMD_DRV_LOG(ERR, "remove RSS profile failed\n");
1254 			return ret;
1255 		}
1256 	}
1257 
1258 	/* add new profile */
1259 	ret = ice_flow_set_hw_prof(hw, vsi_handle, 0, prof, ICE_BLK_RSS);
1260 	if (ret) {
1261 		PMD_DRV_LOG(ERR, "HW profile add failed\n");
1262 		return ret;
1263 	}
1264 
1265 	rss_prof->symm = cfg->symm;
1266 	ice_memcpy(&rss_prof->prof, prof,
1267 		   sizeof(struct ice_parser_profile),
1268 		   ICE_NONDMA_TO_NONDMA);
1269 
1270 update_symm:
1271 	ice_rss_update_raw_symm(hw, cfg, id);
1272 	return 0;
1273 }
1274 
1275 static int
1276 ice_hash_create(struct ice_adapter *ad,
1277 		struct rte_flow *flow,
1278 		void *meta,
1279 		struct rte_flow_error *error)
1280 {
1281 	struct ice_pf *pf = &ad->pf;
1282 	struct ice_hw *hw = ICE_PF_TO_HW(pf);
1283 	struct ice_vsi *vsi = pf->main_vsi;
1284 	int ret;
1285 	uint32_t reg;
1286 	struct ice_hash_flow_cfg *filter_ptr;
1287 	struct ice_rss_meta *rss_meta = (struct ice_rss_meta *)meta;
1288 	uint8_t hash_function = rss_meta->hash_function;
1289 
1290 	filter_ptr = rte_zmalloc("ice_rss_filter",
1291 				sizeof(struct ice_hash_flow_cfg), 0);
1292 	if (!filter_ptr) {
1293 		rte_flow_error_set(error, EINVAL,
1294 				RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1295 				"No memory for filter_ptr");
1296 		return -ENOMEM;
1297 	}
1298 
1299 	if (hash_function == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1300 		/* Enable registers for simple_xor hash function. */
1301 		reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1302 		reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1303 			(2 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1304 		ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1305 
1306 		filter_ptr->simple_xor = 1;
1307 
1308 		goto out;
1309 	} else {
1310 		if (rss_meta->raw.raw_ena) {
1311 			memcpy(&filter_ptr->rss_cfg.raw, &rss_meta->raw,
1312 			       sizeof(struct ice_rss_raw_cfg));
1313 			ret = ice_hash_add_raw_cfg(ad, &rss_meta->raw,
1314 						   pf->main_vsi->idx);
1315 			if (ret) {
1316 				rte_flow_error_set(error, EINVAL,
1317 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1318 						   NULL,
1319 						   "rss flow create fail");
1320 				goto error;
1321 			}
1322 		} else {
1323 			memcpy(&filter_ptr->rss_cfg.hash, &rss_meta->cfg,
1324 			       sizeof(struct ice_rss_hash_cfg));
1325 			ret = ice_add_rss_cfg_wrap(pf, vsi->idx,
1326 						   &filter_ptr->rss_cfg.hash);
1327 			if (ret) {
1328 				rte_flow_error_set(error, EINVAL,
1329 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1330 						   NULL,
1331 						   "rss flow create fail");
1332 				goto error;
1333 			}
1334 		}
1335 	}
1336 
1337 out:
1338 	flow->rule = filter_ptr;
1339 	rte_free(meta);
1340 	return 0;
1341 
1342 error:
1343 	rte_free(filter_ptr);
1344 	rte_free(meta);
1345 	return -rte_errno;
1346 }
1347 
1348 static int
1349 ice_hash_rem_raw_cfg(struct ice_adapter *ad,
1350 			struct ice_parser_profile *prof,
1351 		    u16 vsi_handle)
1352 {
1353 	struct ice_hw *hw = &ad->hw;
1354 	int ptg, ret;
1355 	u16 vsig;
1356 	u64 id;
1357 
1358 	id = (u64)ice_find_first_bit(prof->ptypes, 0xFFFF);
1359 
1360 	ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1361 
1362 	memset(&ad->rss_prof_info[ptg], 0,
1363 		sizeof(struct ice_rss_prof_info));
1364 
1365 	/* check if vsig is already removed */
1366 	ret = ice_vsig_find_vsi(hw, ICE_BLK_RSS,
1367 		ice_get_hw_vsi_num(hw, vsi_handle), &vsig);
1368 	if (!ret && vsig) {
1369 		ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1370 					   ice_get_hw_vsi_num(hw, vsi_handle),
1371 					   id);
1372 		if (ret)
1373 			goto err;
1374 
1375 		ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1376 		if (ret)
1377 			goto err;
1378 	}
1379 
1380 	return 0;
1381 
1382 err:
1383 	PMD_DRV_LOG(ERR, "HW profile remove failed\n");
1384 	return ret;
1385 }
1386 
1387 static int
1388 ice_hash_destroy(struct ice_adapter *ad,
1389 		struct rte_flow *flow,
1390 		struct rte_flow_error *error)
1391 {
1392 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(ad);
1393 	struct ice_hw *hw = ICE_PF_TO_HW(pf);
1394 	struct ice_vsi *vsi = pf->main_vsi;
1395 	int ret;
1396 	uint32_t reg;
1397 	struct ice_hash_flow_cfg *filter_ptr;
1398 
1399 	filter_ptr = (struct ice_hash_flow_cfg *)flow->rule;
1400 
1401 	if (filter_ptr->simple_xor == 1) {
1402 		/* Return to symmetric_toeplitz state. */
1403 		reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1404 		reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1405 			(1 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1406 		ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1407 	} else {
1408 		if (filter_ptr->rss_cfg.raw.raw_ena) {
1409 			ret =
1410 			ice_hash_rem_raw_cfg(ad, &filter_ptr->rss_cfg.raw.prof,
1411 					     pf->main_vsi->idx);
1412 			if (ret) {
1413 				rte_flow_error_set(error, EINVAL,
1414 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1415 						   NULL,
1416 						   "rss flow destroy fail");
1417 				goto error;
1418 			}
1419 		} else {
1420 			ret = ice_rem_rss_cfg_wrap(pf, vsi->idx,
1421 						   &filter_ptr->rss_cfg.hash);
1422 			/* Fixme: Ignore the error if a rule does not exist.
1423 			 * Currently a rule for inputset change or symm turn
1424 			 * on/off will overwrite an exist rule, while
1425 			 * application still have 2 rte_flow handles.
1426 			 **/
1427 			if (ret && ret != ICE_ERR_DOES_NOT_EXIST) {
1428 				rte_flow_error_set(error, EINVAL,
1429 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1430 						   NULL,
1431 						   "rss flow destroy fail");
1432 				goto error;
1433 			}
1434 		}
1435 	}
1436 
1437 	rte_free(filter_ptr);
1438 	return 0;
1439 
1440 error:
1441 	rte_free(filter_ptr);
1442 	return -rte_errno;
1443 }
1444 
1445 static void
1446 ice_hash_uninit(struct ice_adapter *ad)
1447 {
1448 	if (ad->hw.dcf_enabled)
1449 		return;
1450 
1451 	ice_unregister_parser(&ice_hash_parser, ad);
1452 }
1453 
1454 static void
1455 ice_hash_free(struct rte_flow *flow)
1456 {
1457 	rte_free(flow->rule);
1458 }
1459