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