xref: /dpdk/drivers/net/intel/ice/ice_hash.c (revision c1d145834f287aa8cf53de914618a7312f2c360e)
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 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 __rte_unused)
591 {
592 	return 0;
593 }
594 
595 static int
596 ice_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
597 		       struct rte_flow_error *error)
598 {
599 	const struct rte_flow_item *item = pattern;
600 	const struct rte_flow_item_gtp_psc *psc;
601 
602 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
603 		if (item->last) {
604 			rte_flow_error_set(error, EINVAL,
605 					RTE_FLOW_ERROR_TYPE_ITEM, item,
606 					"Not support range");
607 			return -rte_errno;
608 		}
609 
610 		switch (item->type) {
611 		case RTE_FLOW_ITEM_TYPE_RAW:
612 			*phint |= ICE_PHINT_RAW;
613 			break;
614 		case RTE_FLOW_ITEM_TYPE_VLAN:
615 			*phint |= ICE_PHINT_VLAN;
616 			break;
617 		case RTE_FLOW_ITEM_TYPE_PPPOES:
618 			*phint |= ICE_PHINT_PPPOE;
619 			break;
620 		case RTE_FLOW_ITEM_TYPE_GTPU:
621 			*phint |= ICE_PHINT_GTPU;
622 			break;
623 		case RTE_FLOW_ITEM_TYPE_GTP_PSC:
624 			*phint |= ICE_PHINT_GTPU_EH;
625 			psc = item->spec;
626 			if (!psc)
627 				break;
628 			else if (psc->hdr.type == ICE_GTPU_EH_UPLINK)
629 				*phint |= ICE_PHINT_GTPU_EH_UP;
630 			else if (psc->hdr.type == ICE_GTPU_EH_DWNLINK)
631 				*phint |= ICE_PHINT_GTPU_EH_DWN;
632 			break;
633 		default:
634 			break;
635 		}
636 	}
637 
638 	return 0;
639 }
640 
641 static int
642 ice_hash_parse_raw_pattern(struct ice_adapter *ad,
643 				const struct rte_flow_item *item,
644 				struct ice_rss_meta *meta)
645 {
646 	const struct rte_flow_item_raw *raw_spec, *raw_mask;
647 	struct ice_parser_profile prof;
648 	struct ice_parser_result rslt;
649 	uint16_t spec_len, pkt_len;
650 	uint8_t *pkt_buf, *msk_buf;
651 	uint8_t tmp_val = 0;
652 	uint8_t tmp_c = 0;
653 	int i, j, ret = 0;
654 
655 	if (ad->psr == NULL)
656 		return -ENOTSUP;
657 
658 	raw_spec = item->spec;
659 	raw_mask = item->mask;
660 
661 	spec_len = strnlen((char *)(uintptr_t)raw_spec->pattern,
662 		raw_spec->length + 1);
663 	if (spec_len != raw_spec->length)
664 		return -EINVAL;
665 	if (strnlen((char *)(uintptr_t)raw_mask->pattern, raw_spec->length + 1) !=
666 			spec_len)
667 		return -EINVAL;
668 
669 	pkt_len = spec_len / 2;
670 
671 	pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
672 	if (!pkt_buf)
673 		return -ENOMEM;
674 
675 	msk_buf = rte_zmalloc(NULL, pkt_len, 0);
676 	if (!msk_buf) {
677 		rte_free(pkt_buf);
678 		return -ENOMEM;
679 	}
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 	ret = ice_parser_run(ad->psr, pkt_buf, pkt_len, &rslt);
717 	if (ret)
718 		goto free_mem;
719 
720 	ret = ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
721 			pkt_len, ICE_BLK_RSS, true, &prof);
722 	if (ret)
723 		goto free_mem;
724 
725 	rte_memcpy(&meta->raw.prof, &prof, sizeof(prof));
726 
727 free_mem:
728 	rte_free(pkt_buf);
729 	rte_free(msk_buf);
730 
731 	return ret;
732 }
733 
734 static void
735 ice_refine_hash_cfg_l234(struct ice_rss_hash_cfg *hash_cfg,
736 			 uint64_t rss_type)
737 {
738 	uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
739 	uint64_t *hash_flds = &hash_cfg->hash_flds;
740 
741 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH) {
742 		if (!(rss_type & RTE_ETH_RSS_ETH))
743 			*hash_flds &= ~ICE_FLOW_HASH_ETH;
744 		if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
745 			*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA));
746 		else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
747 			*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA));
748 		*addl_hdrs &= ~ICE_FLOW_SEG_HDR_ETH;
749 	}
750 
751 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
752 		if (rss_type & RTE_ETH_RSS_ETH)
753 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE);
754 	}
755 
756 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_VLAN) {
757 		if (rss_type & RTE_ETH_RSS_C_VLAN)
758 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN);
759 		else if (rss_type & RTE_ETH_RSS_S_VLAN)
760 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN);
761 	}
762 
763 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
764 		if (!(rss_type & RTE_ETH_RSS_PPPOE))
765 			*hash_flds &= ~ICE_FLOW_HASH_PPPOE_SESS_ID;
766 	}
767 
768 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV4) {
769 		if (rss_type &
770 		   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
771 		    RTE_ETH_RSS_NONFRAG_IPV4_UDP |
772 		    RTE_ETH_RSS_NONFRAG_IPV4_TCP |
773 		    RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
774 			if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
775 				*addl_hdrs |= ICE_FLOW_SEG_HDR_IPV_FRAG;
776 				*addl_hdrs &= ~(ICE_FLOW_SEG_HDR_IPV_OTHER);
777 				*hash_flds |=
778 					BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_ID);
779 			}
780 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
781 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA));
782 			else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
783 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA));
784 			else if (rss_type &
785 				(RTE_ETH_RSS_L4_SRC_ONLY |
786 				RTE_ETH_RSS_L4_DST_ONLY))
787 				*hash_flds &= ~ICE_FLOW_HASH_IPV4;
788 		} else {
789 			*hash_flds &= ~ICE_FLOW_HASH_IPV4;
790 		}
791 
792 		if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
793 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_CHKSUM);
794 	}
795 
796 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV6) {
797 		if (rss_type &
798 		   (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
799 		    RTE_ETH_RSS_NONFRAG_IPV6_UDP |
800 		    RTE_ETH_RSS_NONFRAG_IPV6_TCP |
801 		    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
802 			if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
803 				*hash_flds |=
804 					BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_ID);
805 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
806 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
807 			else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
808 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
809 			else if (rss_type &
810 				(RTE_ETH_RSS_L4_SRC_ONLY |
811 				RTE_ETH_RSS_L4_DST_ONLY))
812 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
813 		} else {
814 			*hash_flds &= ~ICE_FLOW_HASH_IPV6;
815 		}
816 
817 		if (rss_type & RTE_ETH_RSS_L3_PRE32) {
818 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
819 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
820 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA));
821 			} else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
822 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
823 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA));
824 			} else {
825 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
826 				*hash_flds |= ICE_FLOW_HASH_IPV6_PRE32;
827 			}
828 		}
829 		if (rss_type & RTE_ETH_RSS_L3_PRE48) {
830 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
831 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
832 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA));
833 			} else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
834 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
835 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA));
836 			} else {
837 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
838 				*hash_flds |= ICE_FLOW_HASH_IPV6_PRE48;
839 			}
840 		}
841 		if (rss_type & RTE_ETH_RSS_L3_PRE64) {
842 			if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
843 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
844 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA));
845 			} else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
846 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
847 				*hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA));
848 			} else {
849 				*hash_flds &= ~ICE_FLOW_HASH_IPV6;
850 				*hash_flds |= ICE_FLOW_HASH_IPV6_PRE64;
851 			}
852 		}
853 	}
854 
855 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_UDP) {
856 		if (rss_type &
857 		   (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
858 		    RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
859 			if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
860 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT));
861 			else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
862 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT));
863 			else if (rss_type &
864 				(RTE_ETH_RSS_L3_SRC_ONLY |
865 				  RTE_ETH_RSS_L3_DST_ONLY))
866 				*hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
867 		} else {
868 			*hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
869 		}
870 
871 		if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
872 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_CHKSUM);
873 	}
874 
875 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_TCP) {
876 		if (rss_type &
877 		   (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
878 		    RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
879 			if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
880 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT));
881 			else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
882 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT));
883 			else if (rss_type &
884 				(RTE_ETH_RSS_L3_SRC_ONLY |
885 				  RTE_ETH_RSS_L3_DST_ONLY))
886 				*hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
887 		} else {
888 			*hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
889 		}
890 
891 		if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
892 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_CHKSUM);
893 	}
894 
895 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_SCTP) {
896 		if (rss_type &
897 		   (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
898 		    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
899 			if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
900 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT));
901 			else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
902 				*hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT));
903 			else if (rss_type &
904 				(RTE_ETH_RSS_L3_SRC_ONLY |
905 				  RTE_ETH_RSS_L3_DST_ONLY))
906 				*hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
907 		} else {
908 			*hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
909 		}
910 
911 		if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
912 			*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_CHKSUM);
913 	}
914 
915 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
916 		if (!(rss_type & RTE_ETH_RSS_L2TPV3))
917 			*hash_flds &= ~ICE_FLOW_HASH_L2TPV3_SESS_ID;
918 	}
919 
920 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_ESP) {
921 		if (!(rss_type & RTE_ETH_RSS_ESP))
922 			*hash_flds &= ~ICE_FLOW_HASH_ESP_SPI;
923 	}
924 
925 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_AH) {
926 		if (!(rss_type & RTE_ETH_RSS_AH))
927 			*hash_flds &= ~ICE_FLOW_HASH_AH_SPI;
928 	}
929 
930 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_PFCP_SESSION) {
931 		if (!(rss_type & RTE_ETH_RSS_PFCP))
932 			*hash_flds &= ~ICE_FLOW_HASH_PFCP_SEID;
933 	}
934 }
935 
936 static void
937 ice_refine_proto_hdrs_by_pattern(struct ice_rss_hash_cfg *hash_cfg,
938 				 uint64_t phint)
939 {
940 	uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
941 	if (phint & ICE_PHINT_VLAN)
942 		*addl_hdrs |= ICE_FLOW_SEG_HDR_VLAN;
943 
944 	if (phint & ICE_PHINT_PPPOE)
945 		*addl_hdrs |= ICE_FLOW_SEG_HDR_PPPOE;
946 
947 	if (phint & ICE_PHINT_GTPU_EH_DWN)
948 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_DWN;
949 	else if (phint & ICE_PHINT_GTPU_EH_UP)
950 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_UP;
951 	else if (phint & ICE_PHINT_GTPU_EH)
952 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_EH;
953 	else if (phint & ICE_PHINT_GTPU)
954 		*addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_IP;
955 }
956 
957 static void
958 ice_refine_hash_cfg_gtpu(struct ice_rss_hash_cfg *hash_cfg,
959 			 uint64_t rss_type)
960 {
961 	uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
962 	uint64_t *hash_flds = &hash_cfg->hash_flds;
963 
964 	/* update hash field for gtpu eh/gtpu dwn/gtpu up. */
965 	if (!(rss_type & RTE_ETH_RSS_GTPU))
966 		return;
967 
968 	if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN)
969 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID);
970 	else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_UP)
971 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_UP_TEID);
972 	else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_EH)
973 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_EH_TEID);
974 	else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_IP)
975 		*hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID);
976 }
977 
978 static void ice_refine_hash_cfg(struct ice_rss_hash_cfg *hash_cfg,
979 				uint64_t rss_type, uint64_t phint)
980 {
981 	ice_refine_proto_hdrs_by_pattern(hash_cfg, phint);
982 	ice_refine_hash_cfg_l234(hash_cfg, rss_type);
983 	ice_refine_hash_cfg_gtpu(hash_cfg, rss_type);
984 }
985 
986 static uint64_t invalid_rss_comb[] = {
987 	RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
988 	RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
989 	RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
990 	RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
991 	RTE_ETH_RSS_L3_PRE40 |
992 	RTE_ETH_RSS_L3_PRE56 |
993 	RTE_ETH_RSS_L3_PRE96
994 };
995 
996 struct rss_attr_type {
997 	uint64_t attr;
998 	uint64_t type;
999 };
1000 
1001 static struct rss_attr_type rss_attr_to_valid_type[] = {
1002 	{RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,	RTE_ETH_RSS_ETH},
1003 	{RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,	VALID_RSS_L3},
1004 	{RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,	VALID_RSS_L4},
1005 	/* current ipv6 prefix only supports prefix 64 bits*/
1006 	{RTE_ETH_RSS_L3_PRE32,				VALID_RSS_IPV6},
1007 	{RTE_ETH_RSS_L3_PRE48,				VALID_RSS_IPV6},
1008 	{RTE_ETH_RSS_L3_PRE64,				VALID_RSS_IPV6},
1009 	{INVALID_RSS_ATTR,				0}
1010 };
1011 
1012 static bool
1013 ice_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1014 			 uint64_t rss_type, uint64_t allow_rss_type)
1015 {
1016 	uint32_t i;
1017 
1018 	/**
1019 	 * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1020 	 * hash function.
1021 	 */
1022 	if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1023 		if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1024 		    RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1025 			return true;
1026 
1027 		if (!(rss_type &
1028 		   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1029 		    RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6 |
1030 		    RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1031 		    RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1032 		    RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1033 			return true;
1034 	}
1035 
1036 	/* check invalid combination */
1037 	for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1038 		if (rte_popcount64(rss_type & invalid_rss_comb[i]) > 1)
1039 			return true;
1040 	}
1041 
1042 	/* check invalid RSS attribute */
1043 	for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1044 		struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1045 
1046 		if (rat->attr & rss_type && !(rat->type & rss_type))
1047 			return true;
1048 	}
1049 
1050 	/* check not allowed RSS type */
1051 	rss_type &= ~VALID_RSS_ATTR;
1052 
1053 	return ((rss_type & allow_rss_type) != rss_type);
1054 }
1055 
1056 static int
1057 ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item,
1058 		const struct rte_flow_action actions[],
1059 		uint64_t pattern_hint, struct ice_rss_meta *rss_meta,
1060 		struct rte_flow_error *error)
1061 {
1062 	struct ice_rss_hash_cfg *cfg = pattern_match_item->meta;
1063 	enum rte_flow_action_type action_type;
1064 	const struct rte_flow_action_rss *rss;
1065 	const struct rte_flow_action *action;
1066 	uint64_t rss_type;
1067 
1068 	/* Supported action is RSS. */
1069 	for (action = actions; action->type !=
1070 		RTE_FLOW_ACTION_TYPE_END; action++) {
1071 		action_type = action->type;
1072 		switch (action_type) {
1073 		case RTE_FLOW_ACTION_TYPE_RSS:
1074 			rss = action->conf;
1075 			rss_type = rss->types;
1076 
1077 			/* Check hash function and save it to rss_meta. */
1078 			if (pattern_match_item->pattern_list !=
1079 			    pattern_empty && rss->func ==
1080 			    RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1081 				return rte_flow_error_set(error, ENOTSUP,
1082 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1083 					"Not supported flow");
1084 			} else if (rss->func ==
1085 				   RTE_ETH_HASH_FUNCTION_SIMPLE_XOR){
1086 				rss_meta->hash_function =
1087 				RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
1088 				return 0;
1089 			} else if (rss->func ==
1090 				   RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1091 				rss_meta->hash_function =
1092 				RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
1093 				if (pattern_hint == ICE_PHINT_RAW)
1094 					rss_meta->raw.symm = true;
1095 				else
1096 					cfg->symm = true;
1097 			}
1098 
1099 			if (rss->level)
1100 				return rte_flow_error_set(error, ENOTSUP,
1101 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1102 					"a nonzero RSS encapsulation level is not supported");
1103 
1104 			if (rss->key_len)
1105 				return rte_flow_error_set(error, ENOTSUP,
1106 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1107 					"a nonzero RSS key_len is not supported");
1108 
1109 			if (rss->queue)
1110 				return rte_flow_error_set(error, ENOTSUP,
1111 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1112 					"a non-NULL RSS queue is not supported");
1113 
1114 			/* If pattern type is raw, no need to refine rss type */
1115 			if (pattern_hint == ICE_PHINT_RAW)
1116 				break;
1117 
1118 			/**
1119 			 * Check simultaneous use of SRC_ONLY and DST_ONLY
1120 			 * of the same level.
1121 			 */
1122 			rss_type = rte_eth_rss_hf_refine(rss_type);
1123 
1124 			if (ice_any_invalid_rss_type(rss->func, rss_type,
1125 					pattern_match_item->input_set_mask_o))
1126 				return rte_flow_error_set(error, ENOTSUP,
1127 					RTE_FLOW_ERROR_TYPE_ACTION,
1128 					action, "RSS type not supported");
1129 
1130 			rss_meta->cfg = *cfg;
1131 			ice_refine_hash_cfg(&rss_meta->cfg,
1132 					    rss_type, pattern_hint);
1133 			break;
1134 		case RTE_FLOW_ACTION_TYPE_END:
1135 			break;
1136 
1137 		default:
1138 			rte_flow_error_set(error, EINVAL,
1139 					RTE_FLOW_ERROR_TYPE_ACTION, action,
1140 					"Invalid action.");
1141 			return -rte_errno;
1142 		}
1143 	}
1144 
1145 	return 0;
1146 }
1147 
1148 static int
1149 ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
1150 			struct ice_pattern_match_item *array,
1151 			uint32_t array_len,
1152 			const struct rte_flow_item pattern[],
1153 			const struct rte_flow_action actions[],
1154 			uint32_t priority,
1155 			void **meta,
1156 			struct rte_flow_error *error)
1157 {
1158 	int ret = 0;
1159 	struct ice_pattern_match_item *pattern_match_item;
1160 	struct ice_rss_meta *rss_meta_ptr;
1161 	uint64_t phint = ICE_PHINT_NONE;
1162 
1163 	if (priority >= 1)
1164 		return -rte_errno;
1165 
1166 	rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1167 	if (!rss_meta_ptr) {
1168 		rte_flow_error_set(error, EINVAL,
1169 				RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1170 				"No memory for rss_meta_ptr");
1171 		return -ENOMEM;
1172 	}
1173 
1174 	/* Check rss supported pattern and find matched pattern. */
1175 	pattern_match_item = ice_search_pattern_match_item(ad, pattern, array,
1176 							   array_len, error);
1177 	if (!pattern_match_item) {
1178 		ret = -rte_errno;
1179 		goto error;
1180 	}
1181 
1182 	ret = ice_hash_parse_pattern(pattern, &phint, error);
1183 	if (ret)
1184 		goto error;
1185 
1186 	if (phint == ICE_PHINT_RAW) {
1187 		rss_meta_ptr->raw.raw_ena = true;
1188 		ret = ice_hash_parse_raw_pattern(ad, pattern, rss_meta_ptr);
1189 		if (ret) {
1190 			rte_flow_error_set(error, EINVAL,
1191 					   RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1192 					   "Parse raw pattern failed");
1193 			goto error;
1194 		}
1195 	}
1196 
1197 	/* Check rss action. */
1198 	ret = ice_hash_parse_action(pattern_match_item, actions, phint,
1199 				    rss_meta_ptr, error);
1200 
1201 error:
1202 	if (!ret && meta)
1203 		*meta = rss_meta_ptr;
1204 	else
1205 		rte_free(rss_meta_ptr);
1206 	rte_free(pattern_match_item);
1207 
1208 	return ret;
1209 }
1210 
1211 static int
1212 ice_hash_add_raw_cfg(struct ice_adapter *ad,
1213 		struct ice_rss_raw_cfg *cfg, u16 vsi_handle)
1214 {
1215 	struct ice_parser_profile *prof = &cfg->prof;
1216 	struct ice_rss_prof_info *rss_prof;
1217 	struct ice_hw *hw = &ad->hw;
1218 	int i, ptg, ret;
1219 	u64 id;
1220 
1221 	id = (u64)ice_find_first_bit(prof->ptypes, UINT16_MAX);
1222 
1223 	ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1224 	rss_prof = &ad->rss_prof_info[ptg];
1225 	/* check if ptg already has profile */
1226 	if (rss_prof->prof.fv_num) {
1227 		for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1228 			if (rss_prof->prof.fv[i].proto_id !=
1229 			    prof->fv[i].proto_id ||
1230 			    rss_prof->prof.fv[i].offset !=
1231 			    prof->fv[i].offset)
1232 				break;
1233 		}
1234 
1235 		/* current profile is matched, check symmetric hash */
1236 		if (i == ICE_MAX_FV_WORDS) {
1237 			if (rss_prof->symm != cfg->symm)
1238 				goto update_symm;
1239 
1240 			return 0;
1241 		}
1242 
1243 		/* current profile is not matched, remove it */
1244 		ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1245 					   ice_get_hw_vsi_num(hw, vsi_handle),
1246 					   id);
1247 		if (ret) {
1248 			PMD_DRV_LOG(ERR, "remove RSS flow failed");
1249 			return ret;
1250 		}
1251 
1252 		ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1253 		if (ret) {
1254 			PMD_DRV_LOG(ERR, "remove RSS profile failed");
1255 			return ret;
1256 		}
1257 	}
1258 
1259 	/* add new profile */
1260 	ret = ice_flow_set_hw_prof(hw, vsi_handle, 0, prof, ICE_BLK_RSS);
1261 	if (ret) {
1262 		PMD_DRV_LOG(ERR, "HW profile add failed");
1263 		return ret;
1264 	}
1265 
1266 	rss_prof->symm = cfg->symm;
1267 	ice_memcpy(&rss_prof->prof, prof,
1268 		   sizeof(struct ice_parser_profile),
1269 		   ICE_NONDMA_TO_NONDMA);
1270 
1271 update_symm:
1272 	ice_rss_update_raw_symm(hw, cfg, id);
1273 	return 0;
1274 }
1275 
1276 static int
1277 ice_hash_create(struct ice_adapter *ad,
1278 		struct rte_flow *flow,
1279 		void *meta,
1280 		struct rte_flow_error *error)
1281 {
1282 	struct ice_pf *pf = &ad->pf;
1283 	struct ice_hw *hw = ICE_PF_TO_HW(pf);
1284 	struct ice_vsi *vsi = pf->main_vsi;
1285 	int ret;
1286 	uint32_t reg;
1287 	struct ice_hash_flow_cfg *filter_ptr;
1288 	struct ice_rss_meta *rss_meta = (struct ice_rss_meta *)meta;
1289 	uint8_t hash_function = rss_meta->hash_function;
1290 
1291 	filter_ptr = rte_zmalloc("ice_rss_filter",
1292 				sizeof(struct ice_hash_flow_cfg), 0);
1293 	if (!filter_ptr) {
1294 		rte_flow_error_set(error, EINVAL,
1295 				RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1296 				"No memory for filter_ptr");
1297 		return -ENOMEM;
1298 	}
1299 
1300 	if (hash_function == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1301 		/* Enable registers for simple_xor hash function. */
1302 		reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1303 		reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1304 			(2 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1305 		ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1306 
1307 		filter_ptr->simple_xor = 1;
1308 
1309 		goto out;
1310 	} else {
1311 		if (rss_meta->raw.raw_ena) {
1312 			memcpy(&filter_ptr->rss_cfg.raw, &rss_meta->raw,
1313 			       sizeof(struct ice_rss_raw_cfg));
1314 			ret = ice_hash_add_raw_cfg(ad, &rss_meta->raw,
1315 						   pf->main_vsi->idx);
1316 			if (ret) {
1317 				rte_flow_error_set(error, EINVAL,
1318 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1319 						   NULL,
1320 						   "rss flow create fail");
1321 				goto error;
1322 			}
1323 		} else {
1324 			memcpy(&filter_ptr->rss_cfg.hash, &rss_meta->cfg,
1325 			       sizeof(struct ice_rss_hash_cfg));
1326 			ret = ice_add_rss_cfg_wrap(pf, vsi->idx,
1327 						   &filter_ptr->rss_cfg.hash);
1328 			if (ret) {
1329 				rte_flow_error_set(error, EINVAL,
1330 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1331 						   NULL,
1332 						   "rss flow create fail");
1333 				goto error;
1334 			}
1335 		}
1336 	}
1337 
1338 out:
1339 	flow->rule = filter_ptr;
1340 	rte_free(meta);
1341 	return 0;
1342 
1343 error:
1344 	rte_free(filter_ptr);
1345 	rte_free(meta);
1346 	return -rte_errno;
1347 }
1348 
1349 static int
1350 ice_hash_rem_raw_cfg(struct ice_adapter *ad,
1351 			struct ice_parser_profile *prof,
1352 		    u16 vsi_handle)
1353 {
1354 	struct ice_hw *hw = &ad->hw;
1355 	int ptg, ret;
1356 	u16 vsig;
1357 	u64 id;
1358 
1359 	id = (u64)ice_find_first_bit(prof->ptypes, 0xFFFF);
1360 
1361 	ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1362 
1363 	memset(&ad->rss_prof_info[ptg], 0,
1364 		sizeof(struct ice_rss_prof_info));
1365 
1366 	/* check if vsig is already removed */
1367 	ret = ice_vsig_find_vsi(hw, ICE_BLK_RSS,
1368 		ice_get_hw_vsi_num(hw, vsi_handle), &vsig);
1369 	if (!ret && vsig) {
1370 		ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1371 					   ice_get_hw_vsi_num(hw, vsi_handle),
1372 					   id);
1373 		if (ret)
1374 			goto err;
1375 
1376 		ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1377 		if (ret)
1378 			goto err;
1379 	}
1380 
1381 	return 0;
1382 
1383 err:
1384 	PMD_DRV_LOG(ERR, "HW profile remove failed");
1385 	return ret;
1386 }
1387 
1388 static int
1389 ice_hash_destroy(struct ice_adapter *ad,
1390 		struct rte_flow *flow,
1391 		struct rte_flow_error *error)
1392 {
1393 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(ad);
1394 	struct ice_hw *hw = ICE_PF_TO_HW(pf);
1395 	struct ice_vsi *vsi = pf->main_vsi;
1396 	int ret;
1397 	uint32_t reg;
1398 	struct ice_hash_flow_cfg *filter_ptr;
1399 
1400 	filter_ptr = (struct ice_hash_flow_cfg *)flow->rule;
1401 
1402 	if (filter_ptr->simple_xor == 1) {
1403 		/* Return to symmetric_toeplitz state. */
1404 		reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1405 		reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1406 			(1 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1407 		ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1408 	} else {
1409 		if (filter_ptr->rss_cfg.raw.raw_ena) {
1410 			ret =
1411 			ice_hash_rem_raw_cfg(ad, &filter_ptr->rss_cfg.raw.prof,
1412 					     pf->main_vsi->idx);
1413 			if (ret) {
1414 				rte_flow_error_set(error, EINVAL,
1415 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1416 						   NULL,
1417 						   "rss flow destroy fail");
1418 				goto error;
1419 			}
1420 		} else {
1421 			ret = ice_rem_rss_cfg_wrap(pf, vsi->idx,
1422 						   &filter_ptr->rss_cfg.hash);
1423 			/* Fixme: Ignore the error if a rule does not exist.
1424 			 * Currently a rule for inputset change or symm turn
1425 			 * on/off will overwrite an exist rule, while
1426 			 * application still have 2 rte_flow handles.
1427 			 **/
1428 			if (ret && ret != ICE_ERR_DOES_NOT_EXIST) {
1429 				rte_flow_error_set(error, EINVAL,
1430 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1431 						   NULL,
1432 						   "rss flow destroy fail");
1433 				goto error;
1434 			}
1435 		}
1436 	}
1437 
1438 	rte_free(filter_ptr);
1439 	return 0;
1440 
1441 error:
1442 	rte_free(filter_ptr);
1443 	return -rte_errno;
1444 }
1445 
1446 static void
1447 ice_hash_uninit(struct ice_adapter *ad __rte_unused)
1448 {
1449 }
1450 
1451 static void
1452 ice_hash_free(struct rte_flow *flow)
1453 {
1454 	rte_free(flow->rule);
1455 }
1456