net/ice: enable switch flow on DCF
[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 <rte_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 struct rss_type_match_hdr {
29         uint32_t hdr_mask;
30         uint64_t eth_rss_hint;
31 };
32
33 struct ice_hash_match_type {
34         uint64_t hash_type;
35         uint64_t hash_flds;
36 };
37
38 struct rss_meta {
39         uint32_t pkt_hdr;
40         uint64_t hash_flds;
41         uint8_t hash_function;
42 };
43
44 struct ice_hash_flow_cfg {
45         bool simple_xor;
46         struct ice_rss_cfg rss_cfg;
47 };
48
49 static int
50 ice_hash_init(struct ice_adapter *ad);
51
52 static int
53 ice_hash_create(struct ice_adapter *ad,
54                 struct rte_flow *flow,
55                 void *meta,
56                 struct rte_flow_error *error);
57
58 static int
59 ice_hash_destroy(struct ice_adapter *ad,
60                 struct rte_flow *flow,
61                 struct rte_flow_error *error);
62
63 static void
64 ice_hash_uninit(struct ice_adapter *ad);
65
66 static void
67 ice_hash_free(struct rte_flow *flow);
68
69 static int
70 ice_hash_parse_pattern_action(struct ice_adapter *ad,
71                         struct ice_pattern_match_item *array,
72                         uint32_t array_len,
73                         const struct rte_flow_item pattern[],
74                         const struct rte_flow_action actions[],
75                         void **meta,
76                         struct rte_flow_error *error);
77
78 /* The first member is protocol header, the second member is ETH_RSS_*. */
79 struct rss_type_match_hdr hint_0 = {
80         ICE_FLOW_SEG_HDR_NONE,  0};
81 struct rss_type_match_hdr hint_1 = {
82         ICE_FLOW_SEG_HDR_IPV4,  ETH_RSS_IPV4};
83 struct rss_type_match_hdr hint_2 = {
84         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_UDP, ETH_RSS_NONFRAG_IPV4_UDP};
85 struct rss_type_match_hdr hint_3 = {
86         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_TCP, ETH_RSS_NONFRAG_IPV4_TCP};
87 struct rss_type_match_hdr hint_4 = {
88         ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP};
89 struct rss_type_match_hdr hint_5 = {
90         ICE_FLOW_SEG_HDR_IPV6,  ETH_RSS_IPV6};
91 struct rss_type_match_hdr hint_6 = {
92         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_UDP, ETH_RSS_NONFRAG_IPV6_UDP};
93 struct rss_type_match_hdr hint_7 = {
94         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_TCP, ETH_RSS_NONFRAG_IPV6_TCP};
95 struct rss_type_match_hdr hint_8 = {
96         ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP};
97 struct rss_type_match_hdr hint_9 = {
98         ICE_FLOW_SEG_HDR_GTPU_IP,       ETH_RSS_IPV4};
99 struct rss_type_match_hdr hint_10 = {
100         ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_IPV4};
101 struct rss_type_match_hdr hint_11 = {
102         ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_NONFRAG_IPV4_UDP};
103 struct rss_type_match_hdr hint_12 = {
104         ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_NONFRAG_IPV4_TCP};
105 struct rss_type_match_hdr hint_13 = {
106         ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_NONFRAG_IPV4_SCTP};
107
108 /* Supported pattern for os default package. */
109 static struct ice_pattern_match_item ice_hash_pattern_list_os[] = {
110         {pattern_eth_ipv4,      ICE_INSET_NONE, &hint_1},
111         {pattern_eth_ipv4_udp,  ICE_INSET_NONE, &hint_2},
112         {pattern_eth_ipv4_tcp,  ICE_INSET_NONE, &hint_3},
113         {pattern_eth_ipv4_sctp, ICE_INSET_NONE, &hint_4},
114         {pattern_eth_ipv6,      ICE_INSET_NONE, &hint_5},
115         {pattern_eth_ipv6_udp,  ICE_INSET_NONE, &hint_6},
116         {pattern_eth_ipv6_tcp,  ICE_INSET_NONE, &hint_7},
117         {pattern_eth_ipv6_sctp, ICE_INSET_NONE, &hint_8},
118         {pattern_empty,         ICE_INSET_NONE, &hint_0},
119 };
120
121 /* Supported pattern for comms package. */
122 static struct ice_pattern_match_item ice_hash_pattern_list_comms[] = {
123         {pattern_eth_ipv4,                  ICE_INSET_NONE,  &hint_1},
124         {pattern_eth_ipv4_udp,              ICE_INSET_NONE,  &hint_2},
125         {pattern_eth_ipv4_tcp,              ICE_INSET_NONE,  &hint_3},
126         {pattern_eth_ipv4_sctp,             ICE_INSET_NONE,  &hint_4},
127         {pattern_eth_ipv6,                  ICE_INSET_NONE,  &hint_5},
128         {pattern_eth_ipv6_udp,              ICE_INSET_NONE,  &hint_6},
129         {pattern_eth_ipv6_tcp,              ICE_INSET_NONE,  &hint_7},
130         {pattern_eth_ipv6_sctp,             ICE_INSET_NONE,  &hint_8},
131         {pattern_empty,                     ICE_INSET_NONE,  &hint_0},
132         {pattern_eth_ipv4_gtpu_eh_ipv4,     ICE_INSET_NONE,  &hint_9},
133         {pattern_eth_ipv4_gtpu_eh_ipv4_udp, ICE_INSET_NONE,  &hint_9},
134         {pattern_eth_ipv4_gtpu_eh_ipv4_tcp, ICE_INSET_NONE,  &hint_9},
135         {pattern_eth_pppoes_ipv4,           ICE_INSET_NONE,  &hint_10},
136         {pattern_eth_pppoes_ipv4_udp,       ICE_INSET_NONE,  &hint_11},
137         {pattern_eth_pppoes_ipv4_tcp,       ICE_INSET_NONE,  &hint_12},
138         {pattern_eth_pppoes_ipv4_sctp,      ICE_INSET_NONE,  &hint_13},
139 };
140
141 /**
142  * The first member is input set combination,
143  * the second member is hash fields.
144  */
145 struct ice_hash_match_type ice_hash_type_list[] = {
146         {ETH_RSS_IPV4 | ETH_RSS_L3_SRC_ONLY,                                    BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
147         {ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY,                                    BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
148         {ETH_RSS_IPV4,                                                          ICE_FLOW_HASH_IPV4},
149         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
150         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
151         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
152         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
153         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
154         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
155         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
156         {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
157         {ETH_RSS_NONFRAG_IPV4_UDP,                                              ICE_HASH_UDP_IPV4},
158         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
159         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
160         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
161         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
162         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
163         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
164         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
165         {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
166         {ETH_RSS_NONFRAG_IPV4_TCP,                                              ICE_HASH_TCP_IPV4},
167         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
168         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
169         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
170         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
171         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
172         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
173         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
174         {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
175         {ETH_RSS_NONFRAG_IPV4_SCTP,                                             ICE_HASH_SCTP_IPV4},
176         {ETH_RSS_IPV6 | ETH_RSS_L3_SRC_ONLY,                                    BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
177         {ETH_RSS_IPV6 | ETH_RSS_L3_DST_ONLY,                                    BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
178         {ETH_RSS_IPV6,                                                          ICE_FLOW_HASH_IPV6},
179         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
180         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
181         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
182         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
183         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
184         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
185         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
186         {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
187         {ETH_RSS_NONFRAG_IPV6_UDP,                                              ICE_HASH_UDP_IPV6},
188         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
189         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
190         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
191         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
192         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY,  BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
193         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
194         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
195         {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY,                        BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
196         {ETH_RSS_NONFRAG_IPV6_TCP,                                              ICE_HASH_TCP_IPV6},
197         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
198         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
199         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
200         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
201         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
202         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
203         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_SRC_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
204         {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_DST_ONLY,                       BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
205         {ETH_RSS_NONFRAG_IPV6_SCTP,                                             ICE_HASH_SCTP_IPV6},
206 };
207
208 static struct ice_flow_engine ice_hash_engine = {
209         .init = ice_hash_init,
210         .create = ice_hash_create,
211         .destroy = ice_hash_destroy,
212         .uninit = ice_hash_uninit,
213         .free = ice_hash_free,
214         .type = ICE_FLOW_ENGINE_HASH,
215 };
216
217 /* Register parser for os package. */
218 static struct ice_flow_parser ice_hash_parser_os = {
219         .engine = &ice_hash_engine,
220         .array = ice_hash_pattern_list_os,
221         .array_len = RTE_DIM(ice_hash_pattern_list_os),
222         .parse_pattern_action = ice_hash_parse_pattern_action,
223         .stage = ICE_FLOW_STAGE_RSS,
224 };
225
226 /* Register parser for comms package. */
227 static struct ice_flow_parser ice_hash_parser_comms = {
228         .engine = &ice_hash_engine,
229         .array = ice_hash_pattern_list_comms,
230         .array_len = RTE_DIM(ice_hash_pattern_list_comms),
231         .parse_pattern_action = ice_hash_parse_pattern_action,
232         .stage = ICE_FLOW_STAGE_RSS,
233 };
234
235 RTE_INIT(ice_hash_engine_init)
236 {
237         struct ice_flow_engine *engine = &ice_hash_engine;
238         ice_register_flow_engine(engine);
239 }
240
241 static int
242 ice_hash_init(struct ice_adapter *ad)
243 {
244         struct ice_flow_parser *parser = NULL;
245
246         if (ad->hw.dcf_enabled)
247                 return 0;
248
249         if (ad->active_pkg_type == ICE_PKG_TYPE_OS_DEFAULT)
250                 parser = &ice_hash_parser_os;
251         else if (ad->active_pkg_type == ICE_PKG_TYPE_COMMS)
252                 parser = &ice_hash_parser_comms;
253         else
254                 return -EINVAL;
255
256         return ice_register_parser(parser, ad);
257 }
258
259 static int
260 ice_hash_check_inset(const struct rte_flow_item pattern[],
261                 struct rte_flow_error *error)
262 {
263         const struct rte_flow_item *item = pattern;
264
265         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
266                 if (item->last) {
267                         rte_flow_error_set(error, EINVAL,
268                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
269                                         "Not support range");
270                         return -rte_errno;
271                 }
272
273                 /* Ignore spec and mask. */
274                 if (item->spec || item->mask) {
275                         rte_flow_error_set(error, EINVAL,
276                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
277                                         "Invalid spec/mask.");
278                         return -rte_errno;
279                 }
280         }
281
282         return 0;
283 }
284
285 static int
286 ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item,
287                 const struct rte_flow_action actions[],
288                 void **meta,
289                 struct rte_flow_error *error)
290 {
291         const struct rte_flow_action *action;
292         enum rte_flow_action_type action_type;
293         const struct rte_flow_action_rss *rss;
294         struct rss_type_match_hdr *m = (struct rss_type_match_hdr *)
295                                 (pattern_match_item->meta);
296         uint32_t type_list_len = RTE_DIM(ice_hash_type_list);
297         struct ice_hash_match_type *type_match_item;
298         uint64_t rss_hf;
299         uint16_t i;
300
301         /* Supported action is RSS. */
302         for (action = actions; action->type !=
303                 RTE_FLOW_ACTION_TYPE_END; action++) {
304                 action_type = action->type;
305                 switch (action_type) {
306                 case RTE_FLOW_ACTION_TYPE_RSS:
307                         rss = action->conf;
308                         rss_hf = rss->types;
309
310                         /**
311                          * Check simultaneous use of SRC_ONLY and DST_ONLY
312                          * of the same level.
313                          */
314                         rss_hf = rte_eth_rss_hf_refine(rss_hf);
315
316                         /* Check if pattern is empty. */
317                         if (pattern_match_item->pattern_list !=
318                                 pattern_empty && rss->func ==
319                                 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
320                                 return rte_flow_error_set(error, ENOTSUP,
321                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
322                                         "Not supported flow");
323
324                         /* Check if rss types match pattern. */
325                         if (rss->func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
326                                 if (((rss_hf & ETH_RSS_IPV4) != m->eth_rss_hint) &&
327                                 ((rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) != m->eth_rss_hint) &&
328                                 ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != m->eth_rss_hint) &&
329                                 ((rss_hf & ETH_RSS_NONFRAG_IPV4_SCTP) != m->eth_rss_hint) &&
330                                 ((rss_hf & ETH_RSS_IPV6) != m->eth_rss_hint) &&
331                                 ((rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) != m->eth_rss_hint) &&
332                                 ((rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) != m->eth_rss_hint) &&
333                                 ((rss_hf & ETH_RSS_NONFRAG_IPV6_SCTP) != m->eth_rss_hint))
334                                         return rte_flow_error_set(error,
335                                         ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
336                                         action, "Not supported RSS types");
337                         }
338
339                         if (rss->level)
340                                 return rte_flow_error_set(error, ENOTSUP,
341                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
342                                         "a nonzero RSS encapsulation level is not supported");
343
344                         if (rss->key_len)
345                                 return rte_flow_error_set(error, ENOTSUP,
346                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
347                                         "a nonzero RSS key_len is not supported");
348
349                         if (rss->queue)
350                                 return rte_flow_error_set(error, ENOTSUP,
351                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
352                                         "a non-NULL RSS queue is not supported");
353
354                         /* Check hash function and save it to rss_meta. */
355                         if (rss->func ==
356                                 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
357                                 ((struct rss_meta *)*meta)->hash_function =
358                                 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
359
360                         if (rss->func ==
361                                 RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ)
362                                 ((struct rss_meta *)*meta)->hash_function =
363                                 RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
364
365                         type_match_item = rte_zmalloc("ice_type_match_item",
366                                         sizeof(struct ice_hash_match_type), 0);
367                         if (!type_match_item) {
368                                 rte_flow_error_set(error, EINVAL,
369                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
370                                         "No memory for type_match_item");
371                                 return -ENOMEM;
372                         }
373
374                         /* Find matched hash fields according to hash type. */
375                         for (i = 0; i < type_list_len; i++) {
376                                 if (rss_hf ==
377                                         ice_hash_type_list[i].hash_type) {
378                                         type_match_item->hash_type =
379                                                 ice_hash_type_list[i].hash_type;
380                                         type_match_item->hash_flds =
381                                                 ice_hash_type_list[i].hash_flds;
382                                 }
383                         }
384
385                         /* Save hash fileds to rss_meta. */
386                         ((struct rss_meta *)*meta)->hash_flds =
387                                         type_match_item->hash_flds;
388
389                         rte_free(type_match_item);
390                         break;
391
392                 case RTE_FLOW_ACTION_TYPE_END:
393                         break;
394
395                 default:
396                         rte_flow_error_set(error, EINVAL,
397                                         RTE_FLOW_ERROR_TYPE_ACTION, action,
398                                         "Invalid action.");
399                         return -rte_errno;
400                 }
401         }
402
403         return 0;
404 }
405
406 static int
407 ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
408                         struct ice_pattern_match_item *array,
409                         uint32_t array_len,
410                         const struct rte_flow_item pattern[],
411                         const struct rte_flow_action actions[],
412                         void **meta,
413                         struct rte_flow_error *error)
414 {
415         int ret = 0;
416         struct ice_pattern_match_item *pattern_match_item;
417         struct rss_meta *rss_meta_ptr;
418
419         rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
420         if (!rss_meta_ptr) {
421                 rte_flow_error_set(error, EINVAL,
422                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
423                                 "No memory for rss_meta_ptr");
424                 return -ENOMEM;
425         }
426
427         /* Check rss supported pattern and find matched pattern. */
428         pattern_match_item = ice_search_pattern_match_item(pattern,
429                                         array, array_len, error);
430         if (!pattern_match_item) {
431                 ret = -rte_errno;
432                 goto error;
433         }
434
435         ret = ice_hash_check_inset(pattern, error);
436         if (ret)
437                 goto error;
438
439         /* Save protocol header to rss_meta. */
440         rss_meta_ptr->pkt_hdr = ((struct rss_type_match_hdr *)
441                 (pattern_match_item->meta))->hdr_mask;
442
443         /* Check rss action. */
444         ret = ice_hash_parse_action(pattern_match_item, actions,
445                                     (void **)&rss_meta_ptr, error);
446
447 error:
448         if (!ret && meta)
449                 *meta = rss_meta_ptr;
450         else
451                 rte_free(rss_meta_ptr);
452         rte_free(pattern_match_item);
453
454         return ret;
455 }
456
457 static int
458 ice_hash_create(struct ice_adapter *ad,
459                 struct rte_flow *flow,
460                 void *meta,
461                 struct rte_flow_error *error)
462 {
463         struct ice_pf *pf = &ad->pf;
464         struct ice_hw *hw = ICE_PF_TO_HW(pf);
465         struct ice_vsi *vsi = pf->main_vsi;
466         int ret;
467         uint32_t reg;
468         struct ice_hash_flow_cfg *filter_ptr;
469
470         uint32_t headermask = ((struct rss_meta *)meta)->pkt_hdr;
471         uint64_t hash_field = ((struct rss_meta *)meta)->hash_flds;
472         uint8_t hash_function = ((struct rss_meta *)meta)->hash_function;
473
474         filter_ptr = rte_zmalloc("ice_rss_filter",
475                                 sizeof(struct ice_hash_flow_cfg), 0);
476         if (!filter_ptr) {
477                 rte_flow_error_set(error, EINVAL,
478                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
479                                 "No memory for filter_ptr");
480                 return -ENOMEM;
481         }
482
483         if (hash_function == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
484                 /* Enable registers for simple_xor hash function. */
485                 reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
486                 reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
487                         (2 << VSIQF_HASH_CTL_HASH_SCHEME_S);
488                 ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
489
490                 filter_ptr->simple_xor = 1;
491
492                 goto out;
493         } else {
494                 filter_ptr->rss_cfg.packet_hdr = headermask;
495                 filter_ptr->rss_cfg.hashed_flds = hash_field;
496                 filter_ptr->rss_cfg.symm =
497                         (hash_function ==
498                                 RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ);
499
500                 ret = ice_add_rss_cfg(hw, vsi->idx,
501                                 filter_ptr->rss_cfg.hashed_flds,
502                                 filter_ptr->rss_cfg.packet_hdr,
503                                 filter_ptr->rss_cfg.symm);
504                 if (ret) {
505                         rte_flow_error_set(error, EINVAL,
506                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
507                                         "rss flow create fail");
508                         goto error;
509                 }
510         }
511
512 out:
513         flow->rule = filter_ptr;
514         rte_free(meta);
515         return 0;
516
517 error:
518         rte_free(filter_ptr);
519         rte_free(meta);
520         return -rte_errno;
521 }
522
523 static int
524 ice_hash_destroy(struct ice_adapter *ad,
525                 struct rte_flow *flow,
526                 struct rte_flow_error *error)
527 {
528         struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(ad);
529         struct ice_hw *hw = ICE_PF_TO_HW(pf);
530         struct ice_vsi *vsi = pf->main_vsi;
531         int ret;
532         uint32_t reg;
533         struct ice_hash_flow_cfg *filter_ptr;
534
535         filter_ptr = (struct ice_hash_flow_cfg *)flow->rule;
536
537         if (filter_ptr->simple_xor == 1) {
538                 /* Return to symmetric_toeplitz state. */
539                 reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
540                 reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
541                         (1 << VSIQF_HASH_CTL_HASH_SCHEME_S);
542                 ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
543         } else {
544                 ret = ice_rem_rss_cfg(hw, vsi->idx,
545                                 filter_ptr->rss_cfg.hashed_flds,
546                                 filter_ptr->rss_cfg.packet_hdr);
547                 /* Fixme: Ignore the error if a rule does not exist.
548                  * Currently a rule for inputset change or symm turn on/off
549                  * will overwrite an exist rule, while application still
550                  * have 2 rte_flow handles.
551                  **/
552                 if (ret && ret != ICE_ERR_DOES_NOT_EXIST) {
553                         rte_flow_error_set(error, EINVAL,
554                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
555                                         "rss flow destroy fail");
556                         goto error;
557                 }
558         }
559
560         rte_free(filter_ptr);
561         return 0;
562
563 error:
564         rte_free(filter_ptr);
565         return -rte_errno;
566 }
567
568 static void
569 ice_hash_uninit(struct ice_adapter *ad)
570 {
571         if (ad->hw.dcf_enabled)
572                 return;
573
574         if (ad->active_pkg_type == ICE_PKG_TYPE_OS_DEFAULT)
575                 ice_unregister_parser(&ice_hash_parser_os, ad);
576         else if (ad->active_pkg_type == ICE_PKG_TYPE_COMMS)
577                 ice_unregister_parser(&ice_hash_parser_comms, ad);
578 }
579
580 static void
581 ice_hash_free(struct rte_flow *flow)
582 {
583         rte_free(flow->rule);
584 }