net/ice: fix flow redirect
[dpdk.git] / drivers / net / ice / ice_hash.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #include <sys/queue.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12
13 #include <rte_debug.h>
14 #include <rte_ether.h>
15 #include <ethdev_driver.h>
16 #include <rte_log.h>
17 #include <rte_malloc.h>
18 #include <rte_eth_ctrl.h>
19 #include <rte_tailq.h>
20 #include <rte_flow_driver.h>
21
22 #include "ice_logs.h"
23 #include "base/ice_type.h"
24 #include "base/ice_flow.h"
25 #include "ice_ethdev.h"
26 #include "ice_generic_flow.h"
27
28 #define ICE_PHINT_NONE                          0
29 #define ICE_PHINT_VLAN                          BIT_ULL(0)
30 #define ICE_PHINT_PPPOE                         BIT_ULL(1)
31 #define ICE_PHINT_GTPU                          BIT_ULL(2)
32 #define ICE_PHINT_GTPU_EH                       BIT_ULL(3)
33 #define ICE_PHINT_GTPU_EH_DWN                   BIT_ULL(4)
34 #define ICE_PHINT_GTPU_EH_UP                    BIT_ULL(5)
35 #define ICE_PHINT_RAW                           BIT_ULL(6)
36
37 #define ICE_GTPU_EH_DWNLINK     0
38 #define ICE_GTPU_EH_UPLINK      1
39
40 #define ICE_IPV4_PROT           BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)
41 #define ICE_IPV6_PROT           BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)
42
43 #define VALID_RSS_IPV4_L4       (RTE_ETH_RSS_NONFRAG_IPV4_UDP   | \
44                                  RTE_ETH_RSS_NONFRAG_IPV4_TCP   | \
45                                  RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
46
47 #define VALID_RSS_IPV6_L4       (RTE_ETH_RSS_NONFRAG_IPV6_UDP   | \
48                                  RTE_ETH_RSS_NONFRAG_IPV6_TCP   | \
49                                  RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
50
51 #define VALID_RSS_IPV4          (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | \
52                                  VALID_RSS_IPV4_L4)
53 #define VALID_RSS_IPV6          (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | \
54                                  VALID_RSS_IPV6_L4)
55 #define VALID_RSS_L3            (VALID_RSS_IPV4 | VALID_RSS_IPV6)
56 #define VALID_RSS_L4            (VALID_RSS_IPV4_L4 | VALID_RSS_IPV6_L4)
57
58 #define VALID_RSS_ATTR          (RTE_ETH_RSS_L3_SRC_ONLY        | \
59                                  RTE_ETH_RSS_L3_DST_ONLY        | \
60                                  RTE_ETH_RSS_L4_SRC_ONLY        | \
61                                  RTE_ETH_RSS_L4_DST_ONLY        | \
62                                  RTE_ETH_RSS_L2_SRC_ONLY        | \
63                                  RTE_ETH_RSS_L2_DST_ONLY        | \
64                                  RTE_ETH_RSS_L3_PRE32   | \
65                                  RTE_ETH_RSS_L3_PRE48   | \
66                                  RTE_ETH_RSS_L3_PRE64)
67
68 #define INVALID_RSS_ATTR        (RTE_ETH_RSS_L3_PRE40   | \
69                                  RTE_ETH_RSS_L3_PRE56   | \
70                                  RTE_ETH_RSS_L3_PRE96)
71
72 struct ice_rss_meta {
73         uint8_t hash_function;
74         struct ice_rss_hash_cfg cfg;
75         struct ice_rss_raw_cfg raw;
76 };
77
78 struct ice_hash_flow_cfg {
79         bool simple_xor;
80         struct ice_rss_cfg rss_cfg;
81 };
82
83 static int
84 ice_hash_init(struct ice_adapter *ad);
85
86 static int
87 ice_hash_create(struct ice_adapter *ad,
88                 struct rte_flow *flow,
89                 void *meta,
90                 struct rte_flow_error *error);
91
92 static int
93 ice_hash_destroy(struct ice_adapter *ad,
94                 struct rte_flow *flow,
95                 struct rte_flow_error *error);
96
97 static void
98 ice_hash_uninit(struct ice_adapter *ad);
99
100 static void
101 ice_hash_free(struct rte_flow *flow);
102
103 static int
104 ice_hash_parse_pattern_action(struct ice_adapter *ad,
105                         struct ice_pattern_match_item *array,
106                         uint32_t array_len,
107                         const struct rte_flow_item pattern[],
108                         const struct rte_flow_action actions[],
109                         uint32_t priority,
110                         void **meta,
111                         struct rte_flow_error *error);
112
113 /* Rss configuration template */
114 struct ice_rss_hash_cfg ipv4_tmplt = {
115         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
116         ICE_FLOW_SEG_HDR_IPV_OTHER,
117         ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV4,
118         ICE_RSS_OUTER_HEADERS,
119         0
120 };
121
122 struct ice_rss_hash_cfg ipv4_udp_tmplt = {
123         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
124         ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_UDP,
125         ICE_FLOW_HASH_ETH | ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
126         ICE_RSS_OUTER_HEADERS,
127         0
128 };
129
130 struct ice_rss_hash_cfg ipv4_tcp_tmplt = {
131         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
132         ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_TCP,
133         ICE_FLOW_HASH_ETH | ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
134         ICE_RSS_OUTER_HEADERS,
135         0
136 };
137
138 struct ice_rss_hash_cfg ipv4_sctp_tmplt = {
139         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
140         ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_SCTP,
141         ICE_FLOW_HASH_ETH | ICE_HASH_SCTP_IPV4 | ICE_IPV4_PROT,
142         ICE_RSS_OUTER_HEADERS,
143         0
144 };
145
146 struct ice_rss_hash_cfg ipv6_tmplt = {
147         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
148         ICE_FLOW_SEG_HDR_IPV_OTHER,
149         ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV6,
150         ICE_RSS_OUTER_HEADERS,
151         0
152 };
153
154 struct ice_rss_hash_cfg ipv6_frag_tmplt = {
155         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
156         ICE_FLOW_SEG_HDR_IPV_FRAG,
157         ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV6,
158         ICE_RSS_OUTER_HEADERS,
159         0
160 };
161
162 struct ice_rss_hash_cfg ipv6_udp_tmplt = {
163         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
164         ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_UDP,
165         ICE_FLOW_HASH_ETH | ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
166         ICE_RSS_OUTER_HEADERS,
167         0
168 };
169
170 struct ice_rss_hash_cfg ipv6_tcp_tmplt = {
171         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
172         ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_TCP,
173         ICE_FLOW_HASH_ETH | ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
174         ICE_RSS_OUTER_HEADERS,
175         0
176 };
177
178 struct ice_rss_hash_cfg ipv6_sctp_tmplt = {
179         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
180         ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_SCTP,
181         ICE_FLOW_HASH_ETH | ICE_HASH_SCTP_IPV6 | ICE_IPV6_PROT,
182         ICE_RSS_OUTER_HEADERS,
183         0
184 };
185
186 struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_tmplt = {
187         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER,
188         ICE_FLOW_HASH_IPV4,
189         ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
190         0
191 };
192 struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_udp_tmplt = {
193         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
194         ICE_FLOW_SEG_HDR_UDP,
195         ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
196         ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
197         0
198 };
199
200 struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_tcp_tmplt = {
201         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
202         ICE_FLOW_SEG_HDR_TCP,
203         ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
204         ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
205         0
206 };
207
208 struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_tmplt = {
209         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER,
210         ICE_FLOW_HASH_IPV4,
211         ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
212         0
213 };
214
215 struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_udp_tmplt = {
216         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
217         ICE_FLOW_SEG_HDR_UDP,
218         ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
219         ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
220         0
221 };
222
223 struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_tcp_tmplt = {
224         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
225         ICE_FLOW_SEG_HDR_TCP,
226         ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
227         ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
228         0
229 };
230
231 struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_tmplt = {
232         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER,
233         ICE_FLOW_HASH_IPV6,
234         ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
235         0
236 };
237
238 struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_udp_tmplt = {
239         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
240         ICE_FLOW_SEG_HDR_UDP,
241         ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
242         ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
243         0
244 };
245
246 struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_tcp_tmplt = {
247         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
248         ICE_FLOW_SEG_HDR_TCP,
249         ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
250         ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
251         0
252 };
253
254 struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_tmplt = {
255         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER,
256         ICE_FLOW_HASH_IPV6,
257         ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
258         0
259 };
260 struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_udp_tmplt = {
261         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
262         ICE_FLOW_SEG_HDR_UDP,
263         ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
264         ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
265         0
266 };
267
268 struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_tcp_tmplt = {
269         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
270         ICE_FLOW_SEG_HDR_TCP,
271         ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
272         ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
273         0
274 };
275
276 struct ice_rss_hash_cfg eth_ipv4_esp_tmplt = {
277         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
278         ICE_FLOW_SEG_HDR_ESP,
279         ICE_FLOW_HASH_ESP_SPI,
280         ICE_RSS_OUTER_HEADERS,
281         0
282 };
283
284 struct ice_rss_hash_cfg eth_ipv4_udp_esp_tmplt = {
285         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
286         ICE_FLOW_SEG_HDR_NAT_T_ESP,
287         ICE_FLOW_HASH_NAT_T_ESP_SPI,
288         ICE_RSS_OUTER_HEADERS,
289         0
290 };
291
292 struct ice_rss_hash_cfg eth_ipv4_ah_tmplt = {
293         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
294         ICE_FLOW_SEG_HDR_AH,
295         ICE_FLOW_HASH_AH_SPI,
296         ICE_RSS_OUTER_HEADERS,
297         0
298 };
299
300 struct ice_rss_hash_cfg eth_ipv4_l2tpv3_tmplt = {
301         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
302         ICE_FLOW_SEG_HDR_L2TPV3,
303         ICE_FLOW_HASH_L2TPV3_SESS_ID,
304         ICE_RSS_OUTER_HEADERS,
305         0
306 };
307
308 struct ice_rss_hash_cfg eth_ipv4_pfcp_tmplt = {
309         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
310         ICE_FLOW_SEG_HDR_PFCP_SESSION,
311         ICE_FLOW_HASH_PFCP_SEID,
312         ICE_RSS_OUTER_HEADERS,
313         0
314 };
315
316 struct ice_rss_hash_cfg eth_ipv6_esp_tmplt = {
317         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
318         ICE_FLOW_SEG_HDR_ESP,
319         ICE_FLOW_HASH_ESP_SPI,
320         ICE_RSS_OUTER_HEADERS,
321         0
322 };
323
324 struct ice_rss_hash_cfg eth_ipv6_udp_esp_tmplt = {
325         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
326         ICE_FLOW_SEG_HDR_NAT_T_ESP,
327         ICE_FLOW_HASH_NAT_T_ESP_SPI,
328         ICE_RSS_OUTER_HEADERS,
329         0
330 };
331
332 struct ice_rss_hash_cfg eth_ipv6_ah_tmplt = {
333         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
334         ICE_FLOW_SEG_HDR_AH,
335         ICE_FLOW_HASH_AH_SPI,
336         ICE_RSS_OUTER_HEADERS,
337         0
338 };
339
340 struct ice_rss_hash_cfg eth_ipv6_l2tpv3_tmplt = {
341         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
342         ICE_FLOW_SEG_HDR_L2TPV3,
343         ICE_FLOW_HASH_L2TPV3_SESS_ID,
344         ICE_RSS_OUTER_HEADERS,
345         0
346 };
347
348 struct ice_rss_hash_cfg eth_ipv6_pfcp_tmplt = {
349         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
350         ICE_FLOW_SEG_HDR_PFCP_SESSION,
351         ICE_FLOW_HASH_PFCP_SEID,
352         ICE_RSS_OUTER_HEADERS,
353         0
354 };
355
356 struct ice_rss_hash_cfg pppoe_tmplt = {
357         ICE_FLOW_SEG_HDR_ETH,
358         ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_PPPOE_SESS_ID,
359         ICE_RSS_OUTER_HEADERS,
360         0
361 };
362
363 struct ice_rss_hash_cfg empty_tmplt = {
364         ICE_FLOW_SEG_HDR_NONE,
365         0,
366         ICE_RSS_ANY_HEADERS,
367         0
368 };
369
370 struct ice_rss_hash_cfg eth_tmplt = {
371         ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_ETH_NON_IP,
372         ICE_FLOW_HASH_ETH,
373         ICE_RSS_OUTER_HEADERS,
374         0
375 };
376
377 /* IPv4 */
378 #define ICE_RSS_TYPE_ETH_IPV4           (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV4 | \
379                                          RTE_ETH_RSS_FRAG_IPV4 | \
380                                          RTE_ETH_RSS_IPV4_CHKSUM)
381 #define ICE_RSS_TYPE_ETH_IPV4_UDP       (ICE_RSS_TYPE_ETH_IPV4 | \
382                                          RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
383                                          RTE_ETH_RSS_L4_CHKSUM)
384 #define ICE_RSS_TYPE_ETH_IPV4_TCP       (ICE_RSS_TYPE_ETH_IPV4 | \
385                                          RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
386                                          RTE_ETH_RSS_L4_CHKSUM)
387 #define ICE_RSS_TYPE_ETH_IPV4_SCTP      (ICE_RSS_TYPE_ETH_IPV4 | \
388                                          RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
389                                          RTE_ETH_RSS_L4_CHKSUM)
390 #define ICE_RSS_TYPE_IPV4               RTE_ETH_RSS_IPV4
391 #define ICE_RSS_TYPE_IPV4_UDP           (RTE_ETH_RSS_IPV4 | \
392                                          RTE_ETH_RSS_NONFRAG_IPV4_UDP)
393 #define ICE_RSS_TYPE_IPV4_TCP           (RTE_ETH_RSS_IPV4 | \
394                                          RTE_ETH_RSS_NONFRAG_IPV4_TCP)
395 #define ICE_RSS_TYPE_IPV4_SCTP          (RTE_ETH_RSS_IPV4 | \
396                                          RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
397
398 /* IPv6 */
399 #define ICE_RSS_TYPE_ETH_IPV6           (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6)
400 #define ICE_RSS_TYPE_ETH_IPV6_FRAG      (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6 | \
401                                          RTE_ETH_RSS_FRAG_IPV6)
402 #define ICE_RSS_TYPE_ETH_IPV6_UDP       (ICE_RSS_TYPE_ETH_IPV6 | \
403                                          RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
404                                          RTE_ETH_RSS_L4_CHKSUM)
405 #define ICE_RSS_TYPE_ETH_IPV6_TCP       (ICE_RSS_TYPE_ETH_IPV6 | \
406                                          RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
407                                          RTE_ETH_RSS_L4_CHKSUM)
408 #define ICE_RSS_TYPE_ETH_IPV6_SCTP      (ICE_RSS_TYPE_ETH_IPV6 | \
409                                          RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
410                                          RTE_ETH_RSS_L4_CHKSUM)
411 #define ICE_RSS_TYPE_IPV6               RTE_ETH_RSS_IPV6
412 #define ICE_RSS_TYPE_IPV6_UDP           (RTE_ETH_RSS_IPV6 | \
413                                          RTE_ETH_RSS_NONFRAG_IPV6_UDP)
414 #define ICE_RSS_TYPE_IPV6_TCP           (RTE_ETH_RSS_IPV6 | \
415                                          RTE_ETH_RSS_NONFRAG_IPV6_TCP)
416 #define ICE_RSS_TYPE_IPV6_SCTP          (RTE_ETH_RSS_IPV6 | \
417                                          RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
418
419 /* VLAN IPV4 */
420 #define ICE_RSS_TYPE_VLAN_IPV4          (ICE_RSS_TYPE_IPV4 | \
421                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN | \
422                                          RTE_ETH_RSS_FRAG_IPV4)
423 #define ICE_RSS_TYPE_VLAN_IPV4_UDP      (ICE_RSS_TYPE_IPV4_UDP | \
424                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
425 #define ICE_RSS_TYPE_VLAN_IPV4_TCP      (ICE_RSS_TYPE_IPV4_TCP | \
426                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
427 #define ICE_RSS_TYPE_VLAN_IPV4_SCTP     (ICE_RSS_TYPE_IPV4_SCTP | \
428                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
429 /* VLAN IPv6 */
430 #define ICE_RSS_TYPE_VLAN_IPV6          (ICE_RSS_TYPE_IPV6 | \
431                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
432 #define ICE_RSS_TYPE_VLAN_IPV6_FRAG     (ICE_RSS_TYPE_IPV6 | \
433                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN | \
434                                          RTE_ETH_RSS_FRAG_IPV6)
435 #define ICE_RSS_TYPE_VLAN_IPV6_UDP      (ICE_RSS_TYPE_IPV6_UDP | \
436                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
437 #define ICE_RSS_TYPE_VLAN_IPV6_TCP      (ICE_RSS_TYPE_IPV6_TCP | \
438                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
439 #define ICE_RSS_TYPE_VLAN_IPV6_SCTP     (ICE_RSS_TYPE_IPV6_SCTP | \
440                                          RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
441
442 /* GTPU IPv4 */
443 #define ICE_RSS_TYPE_GTPU_IPV4          (ICE_RSS_TYPE_IPV4 | \
444                                          RTE_ETH_RSS_GTPU)
445 #define ICE_RSS_TYPE_GTPU_IPV4_UDP      (ICE_RSS_TYPE_IPV4_UDP | \
446                                          RTE_ETH_RSS_GTPU)
447 #define ICE_RSS_TYPE_GTPU_IPV4_TCP      (ICE_RSS_TYPE_IPV4_TCP | \
448                                          RTE_ETH_RSS_GTPU)
449 /* GTPU IPv6 */
450 #define ICE_RSS_TYPE_GTPU_IPV6          (ICE_RSS_TYPE_IPV6 | \
451                                          RTE_ETH_RSS_GTPU)
452 #define ICE_RSS_TYPE_GTPU_IPV6_UDP      (ICE_RSS_TYPE_IPV6_UDP | \
453                                          RTE_ETH_RSS_GTPU)
454 #define ICE_RSS_TYPE_GTPU_IPV6_TCP      (ICE_RSS_TYPE_IPV6_TCP | \
455                                          RTE_ETH_RSS_GTPU)
456
457 /* PPPOE */
458 #define ICE_RSS_TYPE_PPPOE              (RTE_ETH_RSS_ETH | RTE_ETH_RSS_PPPOE)
459
460 /* PPPOE IPv4 */
461 #define ICE_RSS_TYPE_PPPOE_IPV4         (ICE_RSS_TYPE_IPV4 | \
462                                          ICE_RSS_TYPE_PPPOE)
463 #define ICE_RSS_TYPE_PPPOE_IPV4_UDP     (ICE_RSS_TYPE_IPV4_UDP | \
464                                          ICE_RSS_TYPE_PPPOE)
465 #define ICE_RSS_TYPE_PPPOE_IPV4_TCP     (ICE_RSS_TYPE_IPV4_TCP | \
466                                          ICE_RSS_TYPE_PPPOE)
467
468 /* PPPOE IPv6 */
469 #define ICE_RSS_TYPE_PPPOE_IPV6         (ICE_RSS_TYPE_IPV6 | \
470                                          ICE_RSS_TYPE_PPPOE)
471 #define ICE_RSS_TYPE_PPPOE_IPV6_UDP     (ICE_RSS_TYPE_IPV6_UDP | \
472                                          ICE_RSS_TYPE_PPPOE)
473 #define ICE_RSS_TYPE_PPPOE_IPV6_TCP     (ICE_RSS_TYPE_IPV6_TCP | \
474                                          ICE_RSS_TYPE_PPPOE)
475
476 /* ESP, AH, L2TPV3 and PFCP */
477 #define ICE_RSS_TYPE_IPV4_ESP           (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV4)
478 #define ICE_RSS_TYPE_IPV6_ESP           (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV6)
479 #define ICE_RSS_TYPE_IPV4_AH            (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV4)
480 #define ICE_RSS_TYPE_IPV6_AH            (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV6)
481 #define ICE_RSS_TYPE_IPV4_L2TPV3        (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV4)
482 #define ICE_RSS_TYPE_IPV6_L2TPV3        (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV6)
483 #define ICE_RSS_TYPE_IPV4_PFCP          (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV4)
484 #define ICE_RSS_TYPE_IPV6_PFCP          (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV6)
485
486 /* MAC */
487 #define ICE_RSS_TYPE_ETH                RTE_ETH_RSS_ETH
488
489 /**
490  * Supported pattern for hash.
491  * The first member is pattern item type,
492  * the second member is input set mask,
493  * the third member is ice_rss_hash_cfg template.
494  */
495 static struct ice_pattern_match_item ice_hash_pattern_list[] = {
496         /* IPV4 */
497         {pattern_raw,                           ICE_INSET_NONE,                         ICE_INSET_NONE, NULL},
498         {pattern_eth_ipv4,                      ICE_RSS_TYPE_ETH_IPV4,          ICE_INSET_NONE, &ipv4_tmplt},
499         {pattern_eth_ipv4_udp,                  ICE_RSS_TYPE_ETH_IPV4_UDP,      ICE_INSET_NONE, &ipv4_udp_tmplt},
500         {pattern_eth_ipv4_tcp,                  ICE_RSS_TYPE_ETH_IPV4_TCP,      ICE_INSET_NONE, &ipv4_tcp_tmplt},
501         {pattern_eth_ipv4_sctp,                 ICE_RSS_TYPE_ETH_IPV4_SCTP,     ICE_INSET_NONE, &ipv4_sctp_tmplt},
502         {pattern_eth_vlan_ipv4,                 ICE_RSS_TYPE_VLAN_IPV4,         ICE_INSET_NONE, &ipv4_tmplt},
503         {pattern_eth_vlan_ipv4_udp,             ICE_RSS_TYPE_VLAN_IPV4_UDP,     ICE_INSET_NONE, &ipv4_udp_tmplt},
504         {pattern_eth_vlan_ipv4_tcp,             ICE_RSS_TYPE_VLAN_IPV4_TCP,     ICE_INSET_NONE, &ipv4_tcp_tmplt},
505         {pattern_eth_vlan_ipv4_sctp,            ICE_RSS_TYPE_VLAN_IPV4_SCTP,    ICE_INSET_NONE, &ipv4_sctp_tmplt},
506         {pattern_eth_ipv4_gtpu_ipv4,            ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tmplt},
507         {pattern_eth_ipv4_gtpu_ipv4_udp,        ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_udp_tmplt},
508         {pattern_eth_ipv4_gtpu_ipv4_tcp,        ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tcp_tmplt},
509         {pattern_eth_ipv6_gtpu_ipv4,            ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tmplt},
510         {pattern_eth_ipv6_gtpu_ipv4_udp,        ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_udp_tmplt},
511         {pattern_eth_ipv6_gtpu_ipv4_tcp,        ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tcp_tmplt},
512         {pattern_eth_ipv4_gtpu_eh_ipv4,         ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tmplt},
513         {pattern_eth_ipv4_gtpu_eh_ipv4_udp,     ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_udp_tmplt},
514         {pattern_eth_ipv4_gtpu_eh_ipv4_tcp,     ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tcp_tmplt},
515         {pattern_eth_ipv6_gtpu_eh_ipv4,         ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tmplt},
516         {pattern_eth_ipv6_gtpu_eh_ipv4_udp,     ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_udp_tmplt},
517         {pattern_eth_ipv6_gtpu_eh_ipv4_tcp,     ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tcp_tmplt},
518         {pattern_eth_pppoes_ipv4,               ICE_RSS_TYPE_PPPOE_IPV4,        ICE_INSET_NONE, &ipv4_tmplt},
519         {pattern_eth_pppoes_ipv4_udp,           ICE_RSS_TYPE_PPPOE_IPV4_UDP,    ICE_INSET_NONE, &ipv4_udp_tmplt},
520         {pattern_eth_pppoes_ipv4_tcp,           ICE_RSS_TYPE_PPPOE_IPV4_TCP,    ICE_INSET_NONE, &ipv4_tcp_tmplt},
521         {pattern_eth_ipv4_esp,                  ICE_RSS_TYPE_IPV4_ESP,          ICE_INSET_NONE, &eth_ipv4_esp_tmplt},
522         {pattern_eth_ipv4_udp_esp,              ICE_RSS_TYPE_IPV4_ESP,          ICE_INSET_NONE, &eth_ipv4_udp_esp_tmplt},
523         {pattern_eth_ipv4_ah,                   ICE_RSS_TYPE_IPV4_AH,           ICE_INSET_NONE, &eth_ipv4_ah_tmplt},
524         {pattern_eth_ipv4_l2tp,                 ICE_RSS_TYPE_IPV4_L2TPV3,       ICE_INSET_NONE, &eth_ipv4_l2tpv3_tmplt},
525         {pattern_eth_ipv4_pfcp,                 ICE_RSS_TYPE_IPV4_PFCP,         ICE_INSET_NONE, &eth_ipv4_pfcp_tmplt},
526         /* IPV6 */
527         {pattern_eth_ipv6,                      ICE_RSS_TYPE_ETH_IPV6,          ICE_INSET_NONE, &ipv6_tmplt},
528         {pattern_eth_ipv6_frag_ext,             ICE_RSS_TYPE_ETH_IPV6_FRAG,     ICE_INSET_NONE, &ipv6_frag_tmplt},
529         {pattern_eth_ipv6_udp,                  ICE_RSS_TYPE_ETH_IPV6_UDP,      ICE_INSET_NONE, &ipv6_udp_tmplt},
530         {pattern_eth_ipv6_tcp,                  ICE_RSS_TYPE_ETH_IPV6_TCP,      ICE_INSET_NONE, &ipv6_tcp_tmplt},
531         {pattern_eth_ipv6_sctp,                 ICE_RSS_TYPE_ETH_IPV6_SCTP,     ICE_INSET_NONE, &ipv6_sctp_tmplt},
532         {pattern_eth_vlan_ipv6,                 ICE_RSS_TYPE_VLAN_IPV6,         ICE_INSET_NONE, &ipv6_tmplt},
533         {pattern_eth_vlan_ipv6_frag_ext,        ICE_RSS_TYPE_VLAN_IPV6_FRAG,    ICE_INSET_NONE, &ipv6_frag_tmplt},
534         {pattern_eth_vlan_ipv6_udp,             ICE_RSS_TYPE_VLAN_IPV6_UDP,     ICE_INSET_NONE, &ipv6_udp_tmplt},
535         {pattern_eth_vlan_ipv6_tcp,             ICE_RSS_TYPE_VLAN_IPV6_TCP,     ICE_INSET_NONE, &ipv6_tcp_tmplt},
536         {pattern_eth_vlan_ipv6_sctp,            ICE_RSS_TYPE_VLAN_IPV6_SCTP,    ICE_INSET_NONE, &ipv6_sctp_tmplt},
537         {pattern_eth_ipv4_gtpu_ipv6,            ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tmplt},
538         {pattern_eth_ipv4_gtpu_ipv6_udp,        ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_udp_tmplt},
539         {pattern_eth_ipv4_gtpu_ipv6_tcp,        ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tcp_tmplt},
540         {pattern_eth_ipv6_gtpu_ipv6,            ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tmplt},
541         {pattern_eth_ipv6_gtpu_ipv6_udp,        ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_udp_tmplt},
542         {pattern_eth_ipv6_gtpu_ipv6_tcp,        ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tcp_tmplt},
543         {pattern_eth_ipv4_gtpu_eh_ipv6,         ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tmplt},
544         {pattern_eth_ipv4_gtpu_eh_ipv6_udp,     ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_udp_tmplt},
545         {pattern_eth_ipv4_gtpu_eh_ipv6_tcp,     ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tcp_tmplt},
546         {pattern_eth_ipv6_gtpu_eh_ipv6,         ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tmplt},
547         {pattern_eth_ipv6_gtpu_eh_ipv6_udp,     ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_udp_tmplt},
548         {pattern_eth_ipv6_gtpu_eh_ipv6_tcp,     ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tcp_tmplt},
549         {pattern_eth_pppoes_ipv6,               ICE_RSS_TYPE_PPPOE_IPV6,        ICE_INSET_NONE, &ipv6_tmplt},
550         {pattern_eth_pppoes_ipv6_udp,           ICE_RSS_TYPE_PPPOE_IPV6_UDP,    ICE_INSET_NONE, &ipv6_udp_tmplt},
551         {pattern_eth_pppoes_ipv6_tcp,           ICE_RSS_TYPE_PPPOE_IPV6_TCP,    ICE_INSET_NONE, &ipv6_tcp_tmplt},
552         {pattern_eth_ipv6_esp,                  ICE_RSS_TYPE_IPV6_ESP,          ICE_INSET_NONE, &eth_ipv6_esp_tmplt},
553         {pattern_eth_ipv6_udp_esp,              ICE_RSS_TYPE_IPV6_ESP,          ICE_INSET_NONE, &eth_ipv6_udp_esp_tmplt},
554         {pattern_eth_ipv6_ah,                   ICE_RSS_TYPE_IPV6_AH,           ICE_INSET_NONE, &eth_ipv6_ah_tmplt},
555         {pattern_eth_ipv6_l2tp,                 ICE_RSS_TYPE_IPV6_L2TPV3,       ICE_INSET_NONE, &eth_ipv6_l2tpv3_tmplt},
556         {pattern_eth_ipv6_pfcp,                 ICE_RSS_TYPE_IPV6_PFCP,         ICE_INSET_NONE, &eth_ipv6_pfcp_tmplt},
557         /* PPPOE */
558         {pattern_eth_pppoes,                    ICE_RSS_TYPE_PPPOE,             ICE_INSET_NONE, &pppoe_tmplt},
559         /* MAC */
560         {pattern_ethertype,                     ICE_RSS_TYPE_ETH,               ICE_INSET_NONE, &eth_tmplt},
561         /* EMPTY */
562         {pattern_empty,                         ICE_INSET_NONE,                 ICE_INSET_NONE, &empty_tmplt},
563 };
564
565 static struct ice_flow_engine ice_hash_engine = {
566         .init = ice_hash_init,
567         .create = ice_hash_create,
568         .destroy = ice_hash_destroy,
569         .uninit = ice_hash_uninit,
570         .free = ice_hash_free,
571         .type = ICE_FLOW_ENGINE_HASH,
572 };
573
574 /* Register parser for os package. */
575 static struct ice_flow_parser ice_hash_parser = {
576         .engine = &ice_hash_engine,
577         .array = ice_hash_pattern_list,
578         .array_len = RTE_DIM(ice_hash_pattern_list),
579         .parse_pattern_action = ice_hash_parse_pattern_action,
580         .stage = ICE_FLOW_STAGE_RSS,
581 };
582
583 RTE_INIT(ice_hash_engine_init)
584 {
585         struct ice_flow_engine *engine = &ice_hash_engine;
586         ice_register_flow_engine(engine);
587 }
588
589 static int
590 ice_hash_init(struct ice_adapter *ad)
591 {
592         struct ice_flow_parser *parser = NULL;
593
594         if (ad->hw.dcf_enabled)
595                 return 0;
596
597         parser = &ice_hash_parser;
598
599         return ice_register_parser(parser, ad);
600 }
601
602 static int
603 ice_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
604                        struct rte_flow_error *error)
605 {
606         const struct rte_flow_item *item = pattern;
607         const struct rte_flow_item_gtp_psc *psc;
608
609         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
610                 if (item->last) {
611                         rte_flow_error_set(error, EINVAL,
612                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
613                                         "Not support range");
614                         return -rte_errno;
615                 }
616
617                 switch (item->type) {
618                 case RTE_FLOW_ITEM_TYPE_RAW:
619                         *phint |= ICE_PHINT_RAW;
620                         break;
621                 case RTE_FLOW_ITEM_TYPE_VLAN:
622                         *phint |= ICE_PHINT_VLAN;
623                         break;
624                 case RTE_FLOW_ITEM_TYPE_PPPOES:
625                         *phint |= ICE_PHINT_PPPOE;
626                         break;
627                 case RTE_FLOW_ITEM_TYPE_GTPU:
628                         *phint |= ICE_PHINT_GTPU;
629                         break;
630                 case RTE_FLOW_ITEM_TYPE_GTP_PSC:
631                         *phint |= ICE_PHINT_GTPU_EH;
632                         psc = item->spec;
633                         if (!psc)
634                                 break;
635                         else if (psc->hdr.type == ICE_GTPU_EH_UPLINK)
636                                 *phint |= ICE_PHINT_GTPU_EH_UP;
637                         else if (psc->hdr.type == ICE_GTPU_EH_DWNLINK)
638                                 *phint |= ICE_PHINT_GTPU_EH_DWN;
639                         break;
640                 default:
641                         break;
642                 }
643         }
644
645         return 0;
646 }
647
648 static int
649 ice_hash_parse_raw_pattern(struct ice_adapter *ad,
650                                 const struct rte_flow_item *item,
651                                 struct ice_rss_meta *meta)
652 {
653         const struct rte_flow_item_raw *raw_spec, *raw_mask;
654         struct ice_parser_profile prof;
655         struct ice_parser_result rslt;
656         struct ice_parser *psr;
657         uint8_t *pkt_buf, *msk_buf;
658         uint8_t spec_len, pkt_len;
659         uint8_t tmp_val = 0;
660         uint8_t tmp_c = 0;
661         int i, j;
662
663         raw_spec = item->spec;
664         raw_mask = item->mask;
665
666         spec_len = strlen((char *)(uintptr_t)raw_spec->pattern);
667         if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
668                 spec_len)
669                 return -rte_errno;
670
671         pkt_len = spec_len / 2;
672
673         pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
674         if (!pkt_buf)
675                 return -ENOMEM;
676
677         msk_buf = rte_zmalloc(NULL, pkt_len, 0);
678         if (!msk_buf)
679                 return -ENOMEM;
680
681         /* convert string to int array */
682         for (i = 0, j = 0; i < spec_len; i += 2, j++) {
683                 tmp_c = raw_spec->pattern[i];
684                 if (tmp_c >= 'a' && tmp_c <= 'f')
685                         tmp_val = tmp_c - 'a' + 10;
686                 if (tmp_c >= 'A' && tmp_c <= 'F')
687                         tmp_val = tmp_c - 'A' + 10;
688                 if (tmp_c >= '0' && tmp_c <= '9')
689                         tmp_val = tmp_c - '0';
690
691                 tmp_c = raw_spec->pattern[i + 1];
692                 if (tmp_c >= 'a' && tmp_c <= 'f')
693                         pkt_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
694                 if (tmp_c >= 'A' && tmp_c <= 'F')
695                         pkt_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
696                 if (tmp_c >= '0' && tmp_c <= '9')
697                         pkt_buf[j] = tmp_val * 16 + tmp_c - '0';
698
699                 tmp_c = raw_mask->pattern[i];
700                 if (tmp_c >= 'a' && tmp_c <= 'f')
701                         tmp_val = tmp_c - 0x57;
702                 if (tmp_c >= 'A' && tmp_c <= 'F')
703                         tmp_val = tmp_c - 0x37;
704                 if (tmp_c >= '0' && tmp_c <= '9')
705                         tmp_val = tmp_c - '0';
706
707                 tmp_c = raw_mask->pattern[i + 1];
708                 if (tmp_c >= 'a' && tmp_c <= 'f')
709                         msk_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
710                 if (tmp_c >= 'A' && tmp_c <= 'F')
711                         msk_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
712                 if (tmp_c >= '0' && tmp_c <= '9')
713                         msk_buf[j] = tmp_val * 16 + tmp_c - '0';
714         }
715
716         if (ice_parser_create(&ad->hw, &psr))
717                 return -rte_errno;
718         if (ice_parser_run(psr, pkt_buf, pkt_len, &rslt))
719                 return -rte_errno;
720         ice_parser_destroy(psr);
721
722         if (ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
723                 pkt_len, ICE_BLK_RSS, true, &prof))
724                 return -rte_errno;
725
726         rte_memcpy(&meta->raw.prof, &prof, sizeof(prof));
727
728         rte_free(pkt_buf);
729         rte_free(msk_buf);
730         return 0;
731 }
732
733 static void
734 ice_refine_hash_cfg_l234(struct ice_rss_hash_cfg *hash_cfg,
735                          uint64_t rss_type)
736 {
737         uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
738         uint64_t *hash_flds = &hash_cfg->hash_flds;
739
740         if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH) {
741                 if (!(rss_type & RTE_ETH_RSS_ETH))
742                         *hash_flds &= ~ICE_FLOW_HASH_ETH;
743                 if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
744                         *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA));
745                 else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
746                         *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA));
747                 *addl_hdrs &= ~ICE_FLOW_SEG_HDR_ETH;
748         }
749
750         if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
751                 if (rss_type & RTE_ETH_RSS_ETH)
752                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE);
753         }
754
755         if (*addl_hdrs & ICE_FLOW_SEG_HDR_VLAN) {
756                 if (rss_type & RTE_ETH_RSS_C_VLAN)
757                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN);
758                 else if (rss_type & RTE_ETH_RSS_S_VLAN)
759                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN);
760         }
761
762         if (*addl_hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
763                 if (!(rss_type & RTE_ETH_RSS_PPPOE))
764                         *hash_flds &= ~ICE_FLOW_HASH_PPPOE_SESS_ID;
765         }
766
767         if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV4) {
768                 if (rss_type &
769                    (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
770                     RTE_ETH_RSS_NONFRAG_IPV4_UDP |
771                     RTE_ETH_RSS_NONFRAG_IPV4_TCP |
772                     RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
773                         if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
774                                 *addl_hdrs |= ICE_FLOW_SEG_HDR_IPV_FRAG;
775                                 *addl_hdrs &= ~(ICE_FLOW_SEG_HDR_IPV_OTHER);
776                                 *hash_flds |=
777                                         BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_ID);
778                         }
779                         if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
780                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA));
781                         else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
782                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA));
783                         else if (rss_type &
784                                 (RTE_ETH_RSS_L4_SRC_ONLY |
785                                 RTE_ETH_RSS_L4_DST_ONLY))
786                                 *hash_flds &= ~ICE_FLOW_HASH_IPV4;
787                 } else {
788                         *hash_flds &= ~ICE_FLOW_HASH_IPV4;
789                 }
790
791                 if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
792                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_CHKSUM);
793         }
794
795         if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV6) {
796                 if (rss_type &
797                    (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
798                     RTE_ETH_RSS_NONFRAG_IPV6_UDP |
799                     RTE_ETH_RSS_NONFRAG_IPV6_TCP |
800                     RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
801                         if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
802                                 *hash_flds |=
803                                         BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_ID);
804                         if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
805                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
806                         else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
807                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
808                         else if (rss_type &
809                                 (RTE_ETH_RSS_L4_SRC_ONLY |
810                                 RTE_ETH_RSS_L4_DST_ONLY))
811                                 *hash_flds &= ~ICE_FLOW_HASH_IPV6;
812                 } else {
813                         *hash_flds &= ~ICE_FLOW_HASH_IPV6;
814                 }
815
816                 if (rss_type & RTE_ETH_RSS_L3_PRE32) {
817                         if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
818                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
819                                 *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA));
820                         } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
821                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
822                                 *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA));
823                         } else {
824                                 *hash_flds &= ~ICE_FLOW_HASH_IPV6;
825                                 *hash_flds |= ICE_FLOW_HASH_IPV6_PRE32;
826                         }
827                 }
828                 if (rss_type & RTE_ETH_RSS_L3_PRE48) {
829                         if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
830                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
831                                 *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA));
832                         } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
833                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
834                                 *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA));
835                         } else {
836                                 *hash_flds &= ~ICE_FLOW_HASH_IPV6;
837                                 *hash_flds |= ICE_FLOW_HASH_IPV6_PRE48;
838                         }
839                 }
840                 if (rss_type & RTE_ETH_RSS_L3_PRE64) {
841                         if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
842                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
843                                 *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA));
844                         } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
845                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
846                                 *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA));
847                         } else {
848                                 *hash_flds &= ~ICE_FLOW_HASH_IPV6;
849                                 *hash_flds |= ICE_FLOW_HASH_IPV6_PRE64;
850                         }
851                 }
852         }
853
854         if (*addl_hdrs & ICE_FLOW_SEG_HDR_UDP) {
855                 if (rss_type &
856                    (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
857                     RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
858                         if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
859                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT));
860                         else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
861                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT));
862                         else if (rss_type &
863                                 (RTE_ETH_RSS_L3_SRC_ONLY |
864                                   RTE_ETH_RSS_L3_DST_ONLY))
865                                 *hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
866                 } else {
867                         *hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
868                 }
869
870                 if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
871                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_CHKSUM);
872         }
873
874         if (*addl_hdrs & ICE_FLOW_SEG_HDR_TCP) {
875                 if (rss_type &
876                    (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
877                     RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
878                         if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
879                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT));
880                         else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
881                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT));
882                         else if (rss_type &
883                                 (RTE_ETH_RSS_L3_SRC_ONLY |
884                                   RTE_ETH_RSS_L3_DST_ONLY))
885                                 *hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
886                 } else {
887                         *hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
888                 }
889
890                 if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
891                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_CHKSUM);
892         }
893
894         if (*addl_hdrs & ICE_FLOW_SEG_HDR_SCTP) {
895                 if (rss_type &
896                    (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
897                     RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
898                         if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
899                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT));
900                         else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
901                                 *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT));
902                         else if (rss_type &
903                                 (RTE_ETH_RSS_L3_SRC_ONLY |
904                                   RTE_ETH_RSS_L3_DST_ONLY))
905                                 *hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
906                 } else {
907                         *hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
908                 }
909
910                 if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
911                         *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_CHKSUM);
912         }
913
914         if (*addl_hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
915                 if (!(rss_type & RTE_ETH_RSS_L2TPV3))
916                         *hash_flds &= ~ICE_FLOW_HASH_L2TPV3_SESS_ID;
917         }
918
919         if (*addl_hdrs & ICE_FLOW_SEG_HDR_ESP) {
920                 if (!(rss_type & RTE_ETH_RSS_ESP))
921                         *hash_flds &= ~ICE_FLOW_HASH_ESP_SPI;
922         }
923
924         if (*addl_hdrs & ICE_FLOW_SEG_HDR_AH) {
925                 if (!(rss_type & RTE_ETH_RSS_AH))
926                         *hash_flds &= ~ICE_FLOW_HASH_AH_SPI;
927         }
928
929         if (*addl_hdrs & ICE_FLOW_SEG_HDR_PFCP_SESSION) {
930                 if (!(rss_type & RTE_ETH_RSS_PFCP))
931                         *hash_flds &= ~ICE_FLOW_HASH_PFCP_SEID;
932         }
933 }
934
935 static void
936 ice_refine_proto_hdrs_by_pattern(struct ice_rss_hash_cfg *hash_cfg,
937                                  uint64_t phint)
938 {
939         uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
940         if (phint & ICE_PHINT_VLAN)
941                 *addl_hdrs |= ICE_FLOW_SEG_HDR_VLAN;
942
943         if (phint & ICE_PHINT_PPPOE)
944                 *addl_hdrs |= ICE_FLOW_SEG_HDR_PPPOE;
945
946         if (phint & ICE_PHINT_GTPU_EH_DWN)
947                 *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_DWN;
948         else if (phint & ICE_PHINT_GTPU_EH_UP)
949                 *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_UP;
950         else if (phint & ICE_PHINT_GTPU_EH)
951                 *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_EH;
952         else if (phint & ICE_PHINT_GTPU)
953                 *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_IP;
954 }
955
956 static void
957 ice_refine_hash_cfg_gtpu(struct ice_rss_hash_cfg *hash_cfg,
958                          uint64_t rss_type)
959 {
960         uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
961         uint64_t *hash_flds = &hash_cfg->hash_flds;
962
963         /* update hash field for gtpu eh/gtpu dwn/gtpu up. */
964         if (!(rss_type & RTE_ETH_RSS_GTPU))
965                 return;
966
967         if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN)
968                 *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID);
969         else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_UP)
970                 *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_UP_TEID);
971         else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_EH)
972                 *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_EH_TEID);
973         else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_IP)
974                 *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID);
975 }
976
977 static void ice_refine_hash_cfg(struct ice_rss_hash_cfg *hash_cfg,
978                                 uint64_t rss_type, uint64_t phint)
979 {
980         ice_refine_proto_hdrs_by_pattern(hash_cfg, phint);
981         ice_refine_hash_cfg_l234(hash_cfg, rss_type);
982         ice_refine_hash_cfg_gtpu(hash_cfg, rss_type);
983 }
984
985 static uint64_t invalid_rss_comb[] = {
986         RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
987         RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
988         RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
989         RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
990         RTE_ETH_RSS_L3_PRE40 |
991         RTE_ETH_RSS_L3_PRE56 |
992         RTE_ETH_RSS_L3_PRE96
993 };
994
995 struct rss_attr_type {
996         uint64_t attr;
997         uint64_t type;
998 };
999
1000 static struct rss_attr_type rss_attr_to_valid_type[] = {
1001         {RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,     RTE_ETH_RSS_ETH},
1002         {RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,     VALID_RSS_L3},
1003         {RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,     VALID_RSS_L4},
1004         /* current ipv6 prefix only supports prefix 64 bits*/
1005         {RTE_ETH_RSS_L3_PRE32,                          VALID_RSS_IPV6},
1006         {RTE_ETH_RSS_L3_PRE48,                          VALID_RSS_IPV6},
1007         {RTE_ETH_RSS_L3_PRE64,                          VALID_RSS_IPV6},
1008         {INVALID_RSS_ATTR,                              0}
1009 };
1010
1011 static bool
1012 ice_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1013                          uint64_t rss_type, uint64_t allow_rss_type)
1014 {
1015         uint32_t i;
1016
1017         /**
1018          * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1019          * hash function.
1020          */
1021         if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1022                 if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1023                     RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1024                         return true;
1025
1026                 if (!(rss_type &
1027                    (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1028                     RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6 |
1029                     RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1030                     RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1031                     RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1032                         return true;
1033         }
1034
1035         /* check invalid combination */
1036         for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1037                 if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
1038                         return true;
1039         }
1040
1041         /* check invalid RSS attribute */
1042         for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1043                 struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1044
1045                 if (rat->attr & rss_type && !(rat->type & rss_type))
1046                         return true;
1047         }
1048
1049         /* check not allowed RSS type */
1050         rss_type &= ~VALID_RSS_ATTR;
1051
1052         return ((rss_type & allow_rss_type) != rss_type);
1053 }
1054
1055 static int
1056 ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item,
1057                 const struct rte_flow_action actions[],
1058                 uint64_t pattern_hint, void **meta,
1059                 struct rte_flow_error *error)
1060 {
1061         struct ice_rss_meta *rss_meta = (struct ice_rss_meta *)*meta;
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                                     (void **)&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\n");
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\n");
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\n");
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\n");
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)
1448 {
1449         if (ad->hw.dcf_enabled)
1450                 return;
1451
1452         ice_unregister_parser(&ice_hash_parser, ad);
1453 }
1454
1455 static void
1456 ice_hash_free(struct rte_flow *flow)
1457 {
1458         rte_free(flow->rule);
1459 }