net/hns3: fix rollback on RSS hash update
[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         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
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
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
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
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
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
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
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
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
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
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
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
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
1454 ice_hash_free(struct rte_flow *flow)
1455 {
1456         rte_free(flow->rule);
1457 }