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