Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020 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 <assert.h>
11 : :
12 : : #include <rte_malloc.h>
13 : : #include <rte_tailq.h>
14 : : #include "base/i40e_prototype.h"
15 : : #include "i40e_logs.h"
16 : : #include "i40e_ethdev.h"
17 : : #include "i40e_hash.h"
18 : :
19 : : #ifndef BIT
20 : : #define BIT(n) (1UL << (n))
21 : : #endif
22 : :
23 : : #ifndef BIT_ULL
24 : : #define BIT_ULL(n) (1ULL << (n))
25 : : #endif
26 : :
27 : : /* Pattern item headers */
28 : : #define I40E_HASH_HDR_ETH 0x01ULL
29 : : #define I40E_HASH_HDR_IPV4 0x10ULL
30 : : #define I40E_HASH_HDR_IPV6 0x20ULL
31 : : #define I40E_HASH_HDR_IPV6_FRAG 0x40ULL
32 : : #define I40E_HASH_HDR_TCP 0x100ULL
33 : : #define I40E_HASH_HDR_UDP 0x200ULL
34 : : #define I40E_HASH_HDR_SCTP 0x400ULL
35 : : #define I40E_HASH_HDR_ESP 0x10000ULL
36 : : #define I40E_HASH_HDR_L2TPV3 0x20000ULL
37 : : #define I40E_HASH_HDR_AH 0x40000ULL
38 : : #define I40E_HASH_HDR_GTPC 0x100000ULL
39 : : #define I40E_HASH_HDR_GTPU 0x200000ULL
40 : :
41 : : #define I40E_HASH_HDR_INNER_SHIFT 32
42 : : #define I40E_HASH_HDR_IPV4_INNER (I40E_HASH_HDR_IPV4 << \
43 : : I40E_HASH_HDR_INNER_SHIFT)
44 : : #define I40E_HASH_HDR_IPV6_INNER (I40E_HASH_HDR_IPV6 << \
45 : : I40E_HASH_HDR_INNER_SHIFT)
46 : :
47 : : /* ETH */
48 : : #define I40E_PHINT_ETH I40E_HASH_HDR_ETH
49 : :
50 : : /* IPv4 */
51 : : #define I40E_PHINT_IPV4 (I40E_HASH_HDR_ETH | I40E_HASH_HDR_IPV4)
52 : : #define I40E_PHINT_IPV4_TCP (I40E_PHINT_IPV4 | I40E_HASH_HDR_TCP)
53 : : #define I40E_PHINT_IPV4_UDP (I40E_PHINT_IPV4 | I40E_HASH_HDR_UDP)
54 : : #define I40E_PHINT_IPV4_SCTP (I40E_PHINT_IPV4 | I40E_HASH_HDR_SCTP)
55 : :
56 : : /* IPv6 */
57 : : #define I40E_PHINT_IPV6 (I40E_HASH_HDR_ETH | I40E_HASH_HDR_IPV6)
58 : : #define I40E_PHINT_IPV6_FRAG (I40E_PHINT_IPV6 | \
59 : : I40E_HASH_HDR_IPV6_FRAG)
60 : : #define I40E_PHINT_IPV6_TCP (I40E_PHINT_IPV6 | I40E_HASH_HDR_TCP)
61 : : #define I40E_PHINT_IPV6_UDP (I40E_PHINT_IPV6 | I40E_HASH_HDR_UDP)
62 : : #define I40E_PHINT_IPV6_SCTP (I40E_PHINT_IPV6 | I40E_HASH_HDR_SCTP)
63 : :
64 : : /* ESP */
65 : : #define I40E_PHINT_IPV4_ESP (I40E_PHINT_IPV4 | I40E_HASH_HDR_ESP)
66 : : #define I40E_PHINT_IPV6_ESP (I40E_PHINT_IPV6 | I40E_HASH_HDR_ESP)
67 : : #define I40E_PHINT_IPV4_UDP_ESP (I40E_PHINT_IPV4_UDP | \
68 : : I40E_HASH_HDR_ESP)
69 : : #define I40E_PHINT_IPV6_UDP_ESP (I40E_PHINT_IPV6_UDP | \
70 : : I40E_HASH_HDR_ESP)
71 : :
72 : : /* GTPC */
73 : : #define I40E_PHINT_IPV4_GTPC (I40E_PHINT_IPV4_UDP | \
74 : : I40E_HASH_HDR_GTPC)
75 : : #define I40E_PHINT_IPV6_GTPC (I40E_PHINT_IPV6_UDP | \
76 : : I40E_HASH_HDR_GTPC)
77 : :
78 : : /* GTPU */
79 : : #define I40E_PHINT_IPV4_GTPU (I40E_PHINT_IPV4_UDP | \
80 : : I40E_HASH_HDR_GTPU)
81 : : #define I40E_PHINT_IPV4_GTPU_IPV4 (I40E_PHINT_IPV4_GTPU | \
82 : : I40E_HASH_HDR_IPV4_INNER)
83 : : #define I40E_PHINT_IPV4_GTPU_IPV6 (I40E_PHINT_IPV4_GTPU | \
84 : : I40E_HASH_HDR_IPV6_INNER)
85 : : #define I40E_PHINT_IPV6_GTPU (I40E_PHINT_IPV6_UDP | \
86 : : I40E_HASH_HDR_GTPU)
87 : : #define I40E_PHINT_IPV6_GTPU_IPV4 (I40E_PHINT_IPV6_GTPU | \
88 : : I40E_HASH_HDR_IPV4_INNER)
89 : : #define I40E_PHINT_IPV6_GTPU_IPV6 (I40E_PHINT_IPV6_GTPU | \
90 : : I40E_HASH_HDR_IPV6_INNER)
91 : :
92 : : /* L2TPV3 */
93 : : #define I40E_PHINT_IPV4_L2TPV3 (I40E_PHINT_IPV4 | I40E_HASH_HDR_L2TPV3)
94 : : #define I40E_PHINT_IPV6_L2TPV3 (I40E_PHINT_IPV6 | I40E_HASH_HDR_L2TPV3)
95 : :
96 : : /* AH */
97 : : #define I40E_PHINT_IPV4_AH (I40E_PHINT_IPV4 | I40E_HASH_HDR_AH)
98 : : #define I40E_PHINT_IPV6_AH (I40E_PHINT_IPV6 | I40E_HASH_HDR_AH)
99 : :
100 : : /* Structure of mapping RSS type to input set */
101 : : struct i40e_hash_map_rss_inset {
102 : : uint64_t rss_type;
103 : : uint64_t inset;
104 : : };
105 : :
106 : : const struct i40e_hash_map_rss_inset i40e_hash_rss_inset[] = {
107 : : /* IPv4 */
108 : : { RTE_ETH_RSS_IPV4, I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST },
109 : : { RTE_ETH_RSS_FRAG_IPV4, I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST },
110 : :
111 : : { RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
112 : : I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST },
113 : :
114 : : { RTE_ETH_RSS_NONFRAG_IPV4_TCP, I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
115 : : I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT },
116 : :
117 : : { RTE_ETH_RSS_NONFRAG_IPV4_UDP, I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
118 : : I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT },
119 : :
120 : : { RTE_ETH_RSS_NONFRAG_IPV4_SCTP, I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
121 : : I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | I40E_INSET_SCTP_VT },
122 : :
123 : : /* IPv6 */
124 : : { RTE_ETH_RSS_IPV6, I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST },
125 : : { RTE_ETH_RSS_FRAG_IPV6, I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST },
126 : :
127 : : { RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
128 : : I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST },
129 : :
130 : : { RTE_ETH_RSS_NONFRAG_IPV6_TCP, I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
131 : : I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT },
132 : :
133 : : { RTE_ETH_RSS_NONFRAG_IPV6_UDP, I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
134 : : I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT },
135 : :
136 : : { RTE_ETH_RSS_NONFRAG_IPV6_SCTP, I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
137 : : I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | I40E_INSET_SCTP_VT },
138 : :
139 : : /* Port */
140 : : { RTE_ETH_RSS_PORT, I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT },
141 : :
142 : : /* Ether */
143 : : { RTE_ETH_RSS_L2_PAYLOAD, I40E_INSET_LAST_ETHER_TYPE },
144 : : { RTE_ETH_RSS_ETH, I40E_INSET_DMAC | I40E_INSET_SMAC },
145 : :
146 : : /* VLAN */
147 : : { RTE_ETH_RSS_S_VLAN, I40E_INSET_VLAN_OUTER },
148 : : { RTE_ETH_RSS_C_VLAN, I40E_INSET_VLAN_INNER },
149 : : };
150 : :
151 : : #define I40E_HASH_VOID_NEXT_ALLOW BIT_ULL(RTE_FLOW_ITEM_TYPE_ETH)
152 : :
153 : : #define I40E_HASH_ETH_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV4) | \
154 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6) | \
155 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_VLAN))
156 : :
157 : : #define I40E_HASH_IP_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_TCP) | \
158 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_UDP) | \
159 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_SCTP) | \
160 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_ESP) | \
161 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_L2TPV3OIP) |\
162 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_AH))
163 : :
164 : : #define I40E_HASH_IPV6_NEXT_ALLOW (I40E_HASH_IP_NEXT_ALLOW | \
165 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT))
166 : :
167 : : #define I40E_HASH_UDP_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_GTPU) | \
168 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_GTPC))
169 : :
170 : : #define I40E_HASH_GTPU_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV4) | \
171 : : BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6))
172 : :
173 : : static const uint64_t pattern_next_allow_items[] = {
174 : : [RTE_FLOW_ITEM_TYPE_VOID] = I40E_HASH_VOID_NEXT_ALLOW,
175 : : [RTE_FLOW_ITEM_TYPE_ETH] = I40E_HASH_ETH_NEXT_ALLOW,
176 : : [RTE_FLOW_ITEM_TYPE_IPV4] = I40E_HASH_IP_NEXT_ALLOW,
177 : : [RTE_FLOW_ITEM_TYPE_IPV6] = I40E_HASH_IPV6_NEXT_ALLOW,
178 : : [RTE_FLOW_ITEM_TYPE_UDP] = I40E_HASH_UDP_NEXT_ALLOW,
179 : : [RTE_FLOW_ITEM_TYPE_GTPU] = I40E_HASH_GTPU_NEXT_ALLOW,
180 : : };
181 : :
182 : : static const uint64_t pattern_item_header[] = {
183 : : [RTE_FLOW_ITEM_TYPE_ETH] = I40E_HASH_HDR_ETH,
184 : : [RTE_FLOW_ITEM_TYPE_IPV4] = I40E_HASH_HDR_IPV4,
185 : : [RTE_FLOW_ITEM_TYPE_IPV6] = I40E_HASH_HDR_IPV6,
186 : : [RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT] = I40E_HASH_HDR_IPV6_FRAG,
187 : : [RTE_FLOW_ITEM_TYPE_TCP] = I40E_HASH_HDR_TCP,
188 : : [RTE_FLOW_ITEM_TYPE_UDP] = I40E_HASH_HDR_UDP,
189 : : [RTE_FLOW_ITEM_TYPE_SCTP] = I40E_HASH_HDR_SCTP,
190 : : [RTE_FLOW_ITEM_TYPE_ESP] = I40E_HASH_HDR_ESP,
191 : : [RTE_FLOW_ITEM_TYPE_GTPC] = I40E_HASH_HDR_GTPC,
192 : : [RTE_FLOW_ITEM_TYPE_GTPU] = I40E_HASH_HDR_GTPU,
193 : : [RTE_FLOW_ITEM_TYPE_L2TPV3OIP] = I40E_HASH_HDR_L2TPV3,
194 : : [RTE_FLOW_ITEM_TYPE_AH] = I40E_HASH_HDR_AH,
195 : : };
196 : :
197 : : /* Structure of matched pattern */
198 : : struct i40e_hash_match_pattern {
199 : : uint64_t pattern_type;
200 : : uint64_t rss_mask; /* Supported RSS type for this pattern */
201 : : bool custom_pctype_flag;/* true for custom packet type */
202 : : uint8_t pctype;
203 : : };
204 : :
205 : : #define I40E_HASH_MAP_PATTERN(pattern, rss_mask, pctype) { \
206 : : pattern, rss_mask, false, pctype }
207 : :
208 : : #define I40E_HASH_MAP_CUS_PATTERN(pattern, rss_mask, cus_pctype) { \
209 : : pattern, rss_mask, true, cus_pctype }
210 : :
211 : : #define I40E_HASH_L2_RSS_MASK (RTE_ETH_RSS_VLAN | RTE_ETH_RSS_ETH | \
212 : : RTE_ETH_RSS_L2_SRC_ONLY | \
213 : : RTE_ETH_RSS_L2_DST_ONLY)
214 : :
215 : : #define I40E_HASH_L23_RSS_MASK (I40E_HASH_L2_RSS_MASK | \
216 : : RTE_ETH_RSS_L3_SRC_ONLY | \
217 : : RTE_ETH_RSS_L3_DST_ONLY)
218 : :
219 : : #define I40E_HASH_IPV4_L23_RSS_MASK (RTE_ETH_RSS_IPV4 | I40E_HASH_L23_RSS_MASK)
220 : : #define I40E_HASH_IPV6_L23_RSS_MASK (RTE_ETH_RSS_IPV6 | I40E_HASH_L23_RSS_MASK)
221 : :
222 : : #define I40E_HASH_L234_RSS_MASK (I40E_HASH_L23_RSS_MASK | \
223 : : RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY | \
224 : : RTE_ETH_RSS_L4_DST_ONLY)
225 : :
226 : : #define I40E_HASH_IPV4_L234_RSS_MASK (I40E_HASH_L234_RSS_MASK | RTE_ETH_RSS_IPV4)
227 : : #define I40E_HASH_IPV6_L234_RSS_MASK (I40E_HASH_L234_RSS_MASK | RTE_ETH_RSS_IPV6)
228 : :
229 : : #define I40E_HASH_L4_TYPES (RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
230 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
231 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
232 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
233 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
234 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
235 : :
236 : : /* Current supported patterns and RSS types.
237 : : * All items that have the same pattern types are together.
238 : : */
239 : : static const struct i40e_hash_match_pattern match_patterns[] = {
240 : : /* Ether */
241 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_ETH,
242 : : RTE_ETH_RSS_L2_PAYLOAD | I40E_HASH_L2_RSS_MASK,
243 : : I40E_FILTER_PCTYPE_L2_PAYLOAD),
244 : :
245 : : /* IPv4 */
246 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV4,
247 : : RTE_ETH_RSS_FRAG_IPV4 | I40E_HASH_IPV4_L23_RSS_MASK,
248 : : I40E_FILTER_PCTYPE_FRAG_IPV4),
249 : :
250 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV4,
251 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
252 : : I40E_HASH_IPV4_L23_RSS_MASK,
253 : : I40E_FILTER_PCTYPE_NONF_IPV4_OTHER),
254 : :
255 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV4_TCP,
256 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP |
257 : : I40E_HASH_IPV4_L234_RSS_MASK,
258 : : I40E_FILTER_PCTYPE_NONF_IPV4_TCP),
259 : :
260 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV4_UDP,
261 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP |
262 : : I40E_HASH_IPV4_L234_RSS_MASK,
263 : : I40E_FILTER_PCTYPE_NONF_IPV4_UDP),
264 : :
265 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV4_SCTP,
266 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
267 : : I40E_HASH_IPV4_L234_RSS_MASK,
268 : : I40E_FILTER_PCTYPE_NONF_IPV4_SCTP),
269 : :
270 : : /* IPv6 */
271 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV6,
272 : : RTE_ETH_RSS_FRAG_IPV6 | I40E_HASH_IPV6_L23_RSS_MASK,
273 : : I40E_FILTER_PCTYPE_FRAG_IPV6),
274 : :
275 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV6,
276 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
277 : : I40E_HASH_IPV6_L23_RSS_MASK,
278 : : I40E_FILTER_PCTYPE_NONF_IPV6_OTHER),
279 : :
280 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV6_FRAG,
281 : : RTE_ETH_RSS_FRAG_IPV6 | I40E_HASH_L23_RSS_MASK,
282 : : I40E_FILTER_PCTYPE_FRAG_IPV6),
283 : :
284 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV6_TCP,
285 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP |
286 : : I40E_HASH_IPV6_L234_RSS_MASK,
287 : : I40E_FILTER_PCTYPE_NONF_IPV6_TCP),
288 : :
289 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV6_UDP,
290 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP |
291 : : I40E_HASH_IPV6_L234_RSS_MASK,
292 : : I40E_FILTER_PCTYPE_NONF_IPV6_UDP),
293 : :
294 : : I40E_HASH_MAP_PATTERN(I40E_PHINT_IPV6_SCTP,
295 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP |
296 : : I40E_HASH_IPV6_L234_RSS_MASK,
297 : : I40E_FILTER_PCTYPE_NONF_IPV6_SCTP),
298 : :
299 : : /* ESP */
300 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_ESP,
301 : : RTE_ETH_RSS_ESP, I40E_CUSTOMIZED_ESP_IPV4),
302 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_ESP,
303 : : RTE_ETH_RSS_ESP, I40E_CUSTOMIZED_ESP_IPV6),
304 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_UDP_ESP,
305 : : RTE_ETH_RSS_ESP, I40E_CUSTOMIZED_ESP_IPV4_UDP),
306 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_UDP_ESP,
307 : : RTE_ETH_RSS_ESP, I40E_CUSTOMIZED_ESP_IPV6_UDP),
308 : :
309 : : /* GTPC */
310 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_GTPC,
311 : : I40E_HASH_IPV4_L234_RSS_MASK,
312 : : I40E_CUSTOMIZED_GTPC),
313 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_GTPC,
314 : : I40E_HASH_IPV6_L234_RSS_MASK,
315 : : I40E_CUSTOMIZED_GTPC),
316 : :
317 : : /* GTPU */
318 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_GTPU,
319 : : I40E_HASH_IPV4_L234_RSS_MASK,
320 : : I40E_CUSTOMIZED_GTPU),
321 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_GTPU_IPV4,
322 : : RTE_ETH_RSS_GTPU, I40E_CUSTOMIZED_GTPU_IPV4),
323 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_GTPU_IPV6,
324 : : RTE_ETH_RSS_GTPU, I40E_CUSTOMIZED_GTPU_IPV6),
325 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_GTPU,
326 : : I40E_HASH_IPV6_L234_RSS_MASK,
327 : : I40E_CUSTOMIZED_GTPU),
328 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_GTPU_IPV4,
329 : : RTE_ETH_RSS_GTPU, I40E_CUSTOMIZED_GTPU_IPV4),
330 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_GTPU_IPV6,
331 : : RTE_ETH_RSS_GTPU, I40E_CUSTOMIZED_GTPU_IPV6),
332 : :
333 : : /* L2TPV3 */
334 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_L2TPV3,
335 : : RTE_ETH_RSS_L2TPV3, I40E_CUSTOMIZED_IPV4_L2TPV3),
336 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_L2TPV3,
337 : : RTE_ETH_RSS_L2TPV3, I40E_CUSTOMIZED_IPV6_L2TPV3),
338 : :
339 : : /* AH */
340 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV4_AH, RTE_ETH_RSS_AH,
341 : : I40E_CUSTOMIZED_AH_IPV4),
342 : : I40E_HASH_MAP_CUS_PATTERN(I40E_PHINT_IPV6_AH, RTE_ETH_RSS_AH,
343 : : I40E_CUSTOMIZED_AH_IPV6),
344 : : };
345 : :
346 : : static int
347 : 0 : i40e_hash_get_pattern_type(const struct rte_flow_item pattern[],
348 : : uint64_t *pattern_types,
349 : : struct rte_flow_error *error)
350 : : {
351 : : const char *message = "Pattern not supported";
352 : : enum rte_flow_item_type prev_item_type = RTE_FLOW_ITEM_TYPE_VOID;
353 : : enum rte_flow_item_type last_item_type = prev_item_type;
354 : : uint64_t item_hdr, pattern_hdrs = 0;
355 : : bool inner_flag = false;
356 : : int vlan_count = 0;
357 : :
358 [ # # ]: 0 : for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
359 [ # # ]: 0 : if (pattern->type == RTE_FLOW_ITEM_TYPE_VOID)
360 : 0 : continue;
361 : :
362 [ # # # # : 0 : if (pattern->mask || pattern->spec || pattern->last) {
# # ]
363 : : message = "Header info should not be specified";
364 : 0 : goto not_sup;
365 : : }
366 : :
367 : : /* Check the previous item allows this sub-item. */
368 [ # # ]: 0 : if (prev_item_type >= (enum rte_flow_item_type)
369 : 0 : RTE_DIM(pattern_next_allow_items) ||
370 [ # # ]: 0 : !(pattern_next_allow_items[prev_item_type] &
371 : : BIT_ULL(pattern->type)))
372 : 0 : goto not_sup;
373 : :
374 : : /* For VLAN item, it does no matter about to pattern type
375 : : * recognition. So just count the number of VLAN and do not
376 : : * change the value of variable `prev_item_type`.
377 : : */
378 : : last_item_type = pattern->type;
379 [ # # ]: 0 : if (last_item_type == RTE_FLOW_ITEM_TYPE_VLAN) {
380 [ # # ]: 0 : if (vlan_count >= 2)
381 : 0 : goto not_sup;
382 : 0 : vlan_count++;
383 : 0 : continue;
384 : : }
385 : :
386 : : prev_item_type = last_item_type;
387 [ # # ]: 0 : if (last_item_type >= (enum rte_flow_item_type)
388 : : RTE_DIM(pattern_item_header))
389 : 0 : goto not_sup;
390 : :
391 : 0 : item_hdr = pattern_item_header[last_item_type];
392 [ # # ]: 0 : assert(item_hdr);
393 : :
394 [ # # ]: 0 : if (inner_flag) {
395 : 0 : item_hdr <<= I40E_HASH_HDR_INNER_SHIFT;
396 : :
397 : : /* Inner layer should not have GTPU item */
398 [ # # ]: 0 : if (last_item_type == RTE_FLOW_ITEM_TYPE_GTPU)
399 : 0 : goto not_sup;
400 : : } else {
401 [ # # ]: 0 : if (last_item_type == RTE_FLOW_ITEM_TYPE_GTPU) {
402 : : inner_flag = true;
403 : : vlan_count = 0;
404 : : }
405 : : }
406 : :
407 [ # # ]: 0 : if (item_hdr & pattern_hdrs)
408 : 0 : goto not_sup;
409 : :
410 : 0 : pattern_hdrs |= item_hdr;
411 : : }
412 : :
413 [ # # ]: 0 : if (pattern_hdrs && last_item_type != RTE_FLOW_ITEM_TYPE_VLAN) {
414 : 0 : *pattern_types = pattern_hdrs;
415 : 0 : return 0;
416 : : }
417 : :
418 : 0 : not_sup:
419 : 0 : return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
420 : : pattern, message);
421 : : }
422 : :
423 : : static uint64_t
424 : : i40e_hash_get_x722_ext_pctypes(uint8_t match_pctype)
425 : : {
426 : : uint64_t pctypes = 0;
427 : :
428 : : switch (match_pctype) {
429 : : case I40E_FILTER_PCTYPE_NONF_IPV4_TCP:
430 : : pctypes = BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
431 : : break;
432 : :
433 : : case I40E_FILTER_PCTYPE_NONF_IPV4_UDP:
434 : : pctypes = BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
435 : : BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
436 : : break;
437 : :
438 : : case I40E_FILTER_PCTYPE_NONF_IPV6_TCP:
439 : : pctypes = BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
440 : : break;
441 : :
442 : : case I40E_FILTER_PCTYPE_NONF_IPV6_UDP:
443 : : pctypes = BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
444 : : BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
445 : : break;
446 : : }
447 : :
448 : : return pctypes;
449 : : }
450 : :
451 : : static int
452 : 0 : i40e_hash_translate_gtp_inset(struct i40e_rte_flow_rss_conf *rss_conf,
453 : : struct rte_flow_error *error)
454 : : {
455 [ # # ]: 0 : if (rss_conf->inset &
456 : : (I40E_INSET_IPV4_SRC | I40E_INSET_IPV6_SRC |
457 : : I40E_INSET_DST_PORT | I40E_INSET_SRC_PORT))
458 : 0 : return rte_flow_error_set(error, ENOTSUP,
459 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
460 : : NULL,
461 : : "Only support external destination IP");
462 : :
463 [ # # ]: 0 : if (rss_conf->inset & I40E_INSET_IPV4_DST)
464 : 0 : rss_conf->inset = (rss_conf->inset & ~I40E_INSET_IPV4_DST) |
465 : : I40E_INSET_TUNNEL_IPV4_DST;
466 : :
467 [ # # ]: 0 : if (rss_conf->inset & I40E_INSET_IPV6_DST)
468 : 0 : rss_conf->inset = (rss_conf->inset & ~I40E_INSET_IPV6_DST) |
469 : : I40E_INSET_TUNNEL_IPV6_DST;
470 : :
471 : : return 0;
472 : : }
473 : :
474 : : static int
475 : 0 : i40e_hash_get_pctypes(const struct rte_eth_dev *dev,
476 : : const struct i40e_hash_match_pattern *match,
477 : : struct i40e_rte_flow_rss_conf *rss_conf,
478 : : struct rte_flow_error *error)
479 : : {
480 [ # # ]: 0 : if (match->custom_pctype_flag) {
481 : : struct i40e_pf *pf;
482 : : struct i40e_customized_pctype *custom_type;
483 : :
484 : 0 : pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
485 : 0 : custom_type = i40e_find_customized_pctype(pf, match->pctype);
486 [ # # # # ]: 0 : if (!custom_type || !custom_type->valid)
487 : 0 : return rte_flow_error_set(error, ENOTSUP,
488 : : RTE_FLOW_ERROR_TYPE_ITEM,
489 : : NULL, "PCTYPE not supported");
490 : :
491 : 0 : rss_conf->config_pctypes |= BIT_ULL(custom_type->pctype);
492 : :
493 [ # # ]: 0 : if (match->pctype == I40E_CUSTOMIZED_GTPU ||
494 : : match->pctype == I40E_CUSTOMIZED_GTPC)
495 : 0 : return i40e_hash_translate_gtp_inset(rss_conf, error);
496 : : } else {
497 : : struct i40e_hw *hw =
498 : 0 : I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
499 : : uint64_t types;
500 : :
501 : 0 : rss_conf->config_pctypes |= BIT_ULL(match->pctype);
502 [ # # ]: 0 : if (hw->mac.type == I40E_MAC_X722) {
503 : : types = i40e_hash_get_x722_ext_pctypes(match->pctype);
504 : 0 : rss_conf->config_pctypes |= types;
505 : : }
506 : : }
507 : :
508 : : return 0;
509 : : }
510 : :
511 : : static int
512 : 0 : i40e_hash_get_pattern_pctypes(const struct rte_eth_dev *dev,
513 : : const struct rte_flow_item pattern[],
514 : : const struct rte_flow_action_rss *rss_act,
515 : : struct i40e_rte_flow_rss_conf *rss_conf,
516 : : struct rte_flow_error *error)
517 : : {
518 : 0 : uint64_t pattern_types = 0;
519 : : bool match_flag = false;
520 : : int i, ret;
521 : :
522 : 0 : ret = i40e_hash_get_pattern_type(pattern, &pattern_types, error);
523 [ # # ]: 0 : if (ret)
524 : : return ret;
525 : :
526 [ # # ]: 0 : for (i = 0; i < (int)RTE_DIM(match_patterns); i++) {
527 : 0 : const struct i40e_hash_match_pattern *match =
528 : : &match_patterns[i];
529 : :
530 : : /* Check pattern types match. All items that have the same
531 : : * pattern types are together, so if the pattern types match
532 : : * previous item but they doesn't match current item, it means
533 : : * the pattern types do not match all remain items.
534 : : */
535 [ # # ]: 0 : if (pattern_types != match->pattern_type) {
536 [ # # ]: 0 : if (match_flag)
537 : : break;
538 : 0 : continue;
539 : : }
540 : : match_flag = true;
541 : :
542 : : /* Check RSS types match */
543 [ # # ]: 0 : if (!(rss_act->types & ~match->rss_mask)) {
544 : 0 : ret = i40e_hash_get_pctypes(dev, match,
545 : : rss_conf, error);
546 [ # # ]: 0 : if (ret)
547 : 0 : return ret;
548 : : }
549 : : }
550 : :
551 [ # # ]: 0 : if (rss_conf->config_pctypes)
552 : : return 0;
553 : :
554 [ # # ]: 0 : if (match_flag)
555 : 0 : return rte_flow_error_set(error, ENOTSUP,
556 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
557 : : NULL, "RSS types not supported");
558 : :
559 : 0 : return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
560 : : NULL, "Pattern not supported");
561 : : }
562 : :
563 : : static uint64_t
564 : 0 : i40e_hash_get_inset(uint64_t rss_types, bool symmetric_enable)
565 : : {
566 : : uint64_t mask, inset = 0;
567 : : int i;
568 : :
569 [ # # ]: 0 : for (i = 0; i < (int)RTE_DIM(i40e_hash_rss_inset); i++) {
570 [ # # ]: 0 : if (rss_types & i40e_hash_rss_inset[i].rss_type)
571 : 0 : inset |= i40e_hash_rss_inset[i].inset;
572 : : }
573 : :
574 [ # # ]: 0 : if (!inset)
575 : : return 0;
576 : :
577 : : /* If SRC_ONLY and DST_ONLY of the same level are used simultaneously,
578 : : * it is the same case as none of them are added.
579 : : */
580 : 0 : mask = rss_types & (RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY);
581 [ # # ]: 0 : if (mask == RTE_ETH_RSS_L2_SRC_ONLY)
582 : 0 : inset &= ~I40E_INSET_DMAC;
583 [ # # ]: 0 : else if (mask == RTE_ETH_RSS_L2_DST_ONLY)
584 : 0 : inset &= ~I40E_INSET_SMAC;
585 : :
586 : 0 : mask = rss_types & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY);
587 [ # # ]: 0 : if (mask == RTE_ETH_RSS_L3_SRC_ONLY)
588 : 0 : inset &= ~(I40E_INSET_IPV4_DST | I40E_INSET_IPV6_DST);
589 [ # # ]: 0 : else if (mask == RTE_ETH_RSS_L3_DST_ONLY)
590 : 0 : inset &= ~(I40E_INSET_IPV4_SRC | I40E_INSET_IPV6_SRC);
591 : :
592 : 0 : mask = rss_types & (RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY);
593 [ # # ]: 0 : if (mask == RTE_ETH_RSS_L4_SRC_ONLY)
594 : 0 : inset &= ~I40E_INSET_DST_PORT;
595 [ # # ]: 0 : else if (mask == RTE_ETH_RSS_L4_DST_ONLY)
596 : 0 : inset &= ~I40E_INSET_SRC_PORT;
597 : :
598 [ # # ]: 0 : if (rss_types & I40E_HASH_L4_TYPES) {
599 : : uint64_t l3_mask = rss_types &
600 : : (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY);
601 : : uint64_t l4_mask = rss_types &
602 : : (RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY);
603 : :
604 [ # # ]: 0 : if (l3_mask && !l4_mask)
605 : 0 : inset &= ~(I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT);
606 [ # # ]: 0 : else if (!l3_mask && l4_mask)
607 : 0 : inset &= ~(I40E_INSET_IPV4_DST | I40E_INSET_IPV6_DST |
608 : : I40E_INSET_IPV4_SRC | I40E_INSET_IPV6_SRC);
609 : : }
610 : :
611 : : /* SCTP Verification Tag is not required in hash computation for SYMMETRIC_TOEPLITZ */
612 [ # # ]: 0 : if (symmetric_enable) {
613 : 0 : mask = rss_types & RTE_ETH_RSS_NONFRAG_IPV4_SCTP;
614 [ # # ]: 0 : if (mask == RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
615 : 0 : inset &= ~I40E_INSET_SCTP_VT;
616 : :
617 : 0 : mask = rss_types & RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
618 [ # # ]: 0 : if (mask == RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
619 : 0 : inset &= ~I40E_INSET_SCTP_VT;
620 : : }
621 : :
622 : : return inset;
623 : : }
624 : :
625 : : static int
626 : 0 : i40e_hash_config_func(struct i40e_hw *hw, enum rte_eth_hash_function func)
627 : : {
628 : : struct i40e_pf *pf;
629 : : uint32_t reg;
630 : : uint8_t symmetric = 0;
631 : :
632 : 0 : reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
633 : :
634 [ # # ]: 0 : if (func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
635 [ # # ]: 0 : if (!(reg & I40E_GLQF_CTL_HTOEP_MASK))
636 : 0 : goto set_symmetric;
637 : :
638 : 0 : reg &= ~I40E_GLQF_CTL_HTOEP_MASK;
639 : : } else {
640 [ # # ]: 0 : if (func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ)
641 : : symmetric = 1;
642 : :
643 [ # # ]: 0 : if (reg & I40E_GLQF_CTL_HTOEP_MASK)
644 : 0 : goto set_symmetric;
645 : :
646 : 0 : reg |= I40E_GLQF_CTL_HTOEP_MASK;
647 : : }
648 : :
649 : 0 : pf = &((struct i40e_adapter *)hw->back)->pf;
650 [ # # ]: 0 : if (pf->support_multi_driver) {
651 : 0 : PMD_DRV_LOG(ERR,
652 : : "Modify hash function is not permitted when multi-driver enabled");
653 : 0 : return -EPERM;
654 : : }
655 : :
656 : 0 : PMD_DRV_LOG(INFO, "NIC hash function is setting to %d", func);
657 : 0 : i40e_write_rx_ctl(hw, I40E_GLQF_CTL, reg);
658 : 0 : I40E_WRITE_FLUSH(hw);
659 : :
660 : 0 : set_symmetric:
661 : 0 : i40e_set_symmetric_hash_enable_per_port(hw, symmetric);
662 : 0 : return 0;
663 : : }
664 : :
665 : : static int
666 : 0 : i40e_hash_config_pctype_symmetric(struct i40e_hw *hw,
667 : : uint32_t pctype,
668 : : bool symmetric)
669 : : {
670 : 0 : struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
671 : : uint32_t reg;
672 : :
673 : 0 : reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
674 [ # # ]: 0 : if (symmetric) {
675 [ # # ]: 0 : if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
676 : : return 0;
677 : 0 : reg |= I40E_GLQF_HSYM_SYMH_ENA_MASK;
678 : : } else {
679 [ # # ]: 0 : if (!(reg & I40E_GLQF_HSYM_SYMH_ENA_MASK))
680 : : return 0;
681 : 0 : reg &= ~I40E_GLQF_HSYM_SYMH_ENA_MASK;
682 : : }
683 : :
684 [ # # ]: 0 : if (pf->support_multi_driver) {
685 : 0 : PMD_DRV_LOG(ERR,
686 : : "Enable/Disable symmetric hash is not permitted when multi-driver enabled");
687 : 0 : return -EPERM;
688 : : }
689 : :
690 : 0 : i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
691 : 0 : I40E_WRITE_FLUSH(hw);
692 : 0 : return 0;
693 : : }
694 : :
695 : : static void
696 : 0 : i40e_hash_enable_pctype(struct i40e_hw *hw,
697 : : uint32_t pctype, bool enable)
698 : : {
699 : : uint32_t reg, reg_val, mask;
700 : :
701 [ # # ]: 0 : if (pctype < 32) {
702 : 0 : mask = BIT(pctype);
703 : : reg = I40E_PFQF_HENA(0);
704 : : } else {
705 : 0 : mask = BIT(pctype - 32);
706 : : reg = I40E_PFQF_HENA(1);
707 : : }
708 : :
709 : 0 : reg_val = i40e_read_rx_ctl(hw, reg);
710 : :
711 [ # # ]: 0 : if (enable) {
712 [ # # ]: 0 : if (reg_val & mask)
713 : : return;
714 : :
715 : 0 : reg_val |= mask;
716 : : } else {
717 [ # # ]: 0 : if (!(reg_val & mask))
718 : : return;
719 : :
720 : 0 : reg_val &= ~mask;
721 : : }
722 : :
723 : 0 : i40e_write_rx_ctl(hw, reg, reg_val);
724 : 0 : I40E_WRITE_FLUSH(hw);
725 : : }
726 : :
727 : : static int
728 : 0 : i40e_hash_config_pctype(struct i40e_hw *hw,
729 : : struct i40e_rte_flow_rss_conf *rss_conf,
730 : : uint32_t pctype)
731 : : {
732 : 0 : uint64_t rss_types = rss_conf->conf.types;
733 : : int ret;
734 : :
735 [ # # ]: 0 : if (rss_types == 0) {
736 : 0 : i40e_hash_enable_pctype(hw, pctype, false);
737 : 0 : return 0;
738 : : }
739 : :
740 [ # # ]: 0 : if (rss_conf->inset) {
741 : 0 : ret = i40e_set_hash_inset(hw, rss_conf->inset, pctype, false);
742 [ # # ]: 0 : if (ret)
743 : : return ret;
744 : : }
745 : :
746 : 0 : i40e_hash_enable_pctype(hw, pctype, true);
747 : 0 : return 0;
748 : : }
749 : :
750 : : static int
751 : 0 : i40e_hash_config_region(struct i40e_pf *pf,
752 : : const struct i40e_rte_flow_rss_conf *rss_conf)
753 : : {
754 : 0 : struct i40e_hw *hw = &pf->adapter->hw;
755 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
756 : 0 : struct i40e_queue_region_info *regions = pf->queue_region.region;
757 : 0 : uint32_t num = pf->queue_region.queue_region_number;
758 : : uint32_t i, region_id_mask = 0;
759 : :
760 : : /* Use a 32 bit variable to represent all regions */
761 : : RTE_BUILD_BUG_ON(I40E_REGION_MAX_INDEX > 31);
762 : :
763 : : /* Re-configure the region if it existed */
764 [ # # ]: 0 : for (i = 0; i < num; i++) {
765 : 0 : if (rss_conf->region_queue_start ==
766 [ # # ]: 0 : regions[i].queue_start_index &&
767 [ # # ]: 0 : rss_conf->region_queue_num == regions[i].queue_num) {
768 : : uint32_t j;
769 : :
770 [ # # ]: 0 : for (j = 0; j < regions[i].user_priority_num; j++) {
771 : 0 : if (regions[i].user_priority[j] ==
772 [ # # ]: 0 : rss_conf->region_priority)
773 : : return 0;
774 : : }
775 : :
776 [ # # ]: 0 : if (j >= I40E_MAX_USER_PRIORITY) {
777 : 0 : PMD_DRV_LOG(ERR,
778 : : "Priority number exceed the maximum %d",
779 : : I40E_MAX_USER_PRIORITY);
780 : 0 : return -ENOSPC;
781 : : }
782 : :
783 : 0 : regions[i].user_priority[j] = rss_conf->region_priority;
784 : 0 : regions[i].user_priority_num++;
785 : 0 : return i40e_flush_queue_region_all_conf(dev, hw, pf, 1);
786 : : }
787 : :
788 : 0 : region_id_mask |= BIT(regions[i].region_id);
789 : : }
790 : :
791 [ # # ]: 0 : if (num > I40E_REGION_MAX_INDEX) {
792 : 0 : PMD_DRV_LOG(ERR, "Queue region resource used up");
793 : 0 : return -ENOSPC;
794 : : }
795 : :
796 : : /* Add a new region */
797 : :
798 : 0 : pf->queue_region.queue_region_number++;
799 : 0 : memset(®ions[num], 0, sizeof(regions[0]));
800 : :
801 : 0 : regions[num].region_id = rte_bsf32(~region_id_mask);
802 : 0 : regions[num].queue_num = rss_conf->region_queue_num;
803 : 0 : regions[num].queue_start_index = rss_conf->region_queue_start;
804 : 0 : regions[num].user_priority[0] = rss_conf->region_priority;
805 : 0 : regions[num].user_priority_num = 1;
806 : :
807 : 0 : return i40e_flush_queue_region_all_conf(dev, hw, pf, 1);
808 : : }
809 : :
810 : : static int
811 : 0 : i40e_hash_config(struct i40e_pf *pf,
812 : : struct i40e_rte_flow_rss_conf *rss_conf)
813 : : {
814 : : struct rte_flow_action_rss *rss_info = &rss_conf->conf;
815 : 0 : struct i40e_hw *hw = &pf->adapter->hw;
816 : : uint64_t pctypes;
817 : : int ret;
818 : :
819 [ # # ]: 0 : if (rss_info->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
820 : 0 : ret = i40e_hash_config_func(hw, rss_info->func);
821 [ # # ]: 0 : if (ret)
822 : : return ret;
823 : :
824 [ # # ]: 0 : if (rss_info->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ)
825 : 0 : rss_conf->misc_reset_flags |=
826 : : I40E_HASH_FLOW_RESET_FLAG_FUNC;
827 : : }
828 : :
829 [ # # ]: 0 : if (rss_conf->region_queue_num > 0) {
830 : 0 : ret = i40e_hash_config_region(pf, rss_conf);
831 [ # # ]: 0 : if (ret)
832 : : return ret;
833 : :
834 : 0 : rss_conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_REGION;
835 : : }
836 : :
837 [ # # ]: 0 : if (rss_info->key_len > 0) {
838 : 0 : ret = i40e_set_rss_key(pf->main_vsi, rss_conf->key,
839 : : rss_info->key_len);
840 [ # # ]: 0 : if (ret)
841 : : return ret;
842 : :
843 : 0 : rss_conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_KEY;
844 : : }
845 : :
846 : : /* Update lookup table */
847 [ # # ]: 0 : if (rss_info->queue_num > 0) {
848 : : uint8_t lut[RTE_ETH_RSS_RETA_SIZE_512];
849 : : uint32_t i, j = 0;
850 : :
851 [ # # ]: 0 : for (i = 0; i < hw->func_caps.rss_table_size; i++) {
852 : 0 : lut[i] = (uint8_t)rss_info->queue[j];
853 [ # # ]: 0 : j = (j == rss_info->queue_num - 1) ? 0 : (j + 1);
854 : : }
855 : :
856 : 0 : ret = i40e_set_rss_lut(pf->main_vsi, lut, (uint16_t)i);
857 [ # # ]: 0 : if (ret)
858 : 0 : return ret;
859 : :
860 : 0 : pf->hash_enabled_queues = 0;
861 [ # # ]: 0 : for (i = 0; i < rss_info->queue_num; i++)
862 : 0 : pf->hash_enabled_queues |= BIT_ULL(lut[i]);
863 : :
864 : 0 : pf->adapter->rss_reta_updated = 0;
865 : 0 : rss_conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_QUEUE;
866 : : }
867 : :
868 : : /* The codes behind configure the input sets and symmetric hash
869 : : * function of the packet types and enable hash on them.
870 : : */
871 : 0 : pctypes = rss_conf->config_pctypes;
872 [ # # ]: 0 : if (!pctypes)
873 : : return 0;
874 : :
875 : : /* For first flow that will enable hash on any packet type, we clean
876 : : * the RSS sets that by legacy configuration commands and parameters.
877 : : */
878 [ # # ]: 0 : if (!pf->hash_filter_enabled) {
879 : 0 : i40e_pf_disable_rss(pf);
880 : 0 : pf->hash_filter_enabled = true;
881 : : }
882 : :
883 : : do {
884 : : uint32_t idx = rte_bsf64(pctypes);
885 : 0 : uint64_t bit = BIT_ULL(idx);
886 : :
887 [ # # ]: 0 : if (rss_conf->symmetric_enable) {
888 : 0 : ret = i40e_hash_config_pctype_symmetric(hw, idx, true);
889 [ # # ]: 0 : if (ret)
890 : 0 : return ret;
891 : :
892 : 0 : rss_conf->reset_symmetric_pctypes |= bit;
893 : : }
894 : :
895 : 0 : ret = i40e_hash_config_pctype(hw, rss_conf, idx);
896 [ # # ]: 0 : if (ret)
897 : 0 : return ret;
898 : :
899 : 0 : rss_conf->reset_config_pctypes |= bit;
900 : 0 : pctypes &= ~bit;
901 [ # # ]: 0 : } while (pctypes);
902 : :
903 : : return 0;
904 : : }
905 : :
906 : : static void
907 : 0 : i40e_hash_parse_key(const struct rte_flow_action_rss *rss_act,
908 : : struct i40e_rte_flow_rss_conf *rss_conf)
909 : : {
910 : 0 : const uint8_t *key = rss_act->key;
911 : :
912 [ # # # # ]: 0 : if (!key || rss_act->key_len != sizeof(rss_conf->key)) {
913 : 0 : const uint32_t rss_key_default[] = {0x6b793944,
914 : : 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8,
915 : : 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605,
916 : : 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581};
917 : :
918 [ # # ]: 0 : if (rss_act->key_len != sizeof(rss_conf->key))
919 : 0 : PMD_DRV_LOG(WARNING,
920 : : "RSS key length invalid, must be %u bytes, now set key to default",
921 : : (uint32_t)sizeof(rss_conf->key));
922 : :
923 : 0 : memcpy(rss_conf->key, rss_key_default, sizeof(rss_conf->key));
924 : : } else {
925 : 0 : memcpy(rss_conf->key, key, sizeof(rss_conf->key));
926 : : }
927 : :
928 : 0 : rss_conf->conf.key = rss_conf->key;
929 : 0 : rss_conf->conf.key_len = sizeof(rss_conf->key);
930 : 0 : }
931 : :
932 : : static int
933 : 0 : i40e_hash_parse_queues(const struct rte_eth_dev *dev,
934 : : const struct rte_flow_action_rss *rss_act,
935 : : struct i40e_rte_flow_rss_conf *rss_conf,
936 : : struct rte_flow_error *error)
937 : : {
938 : : struct i40e_pf *pf;
939 : : struct i40e_hw *hw;
940 : : uint16_t i;
941 : : int max_queue;
942 : :
943 : 0 : hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
944 [ # # ]: 0 : if (!rss_act->queue_num ||
945 [ # # ]: 0 : rss_act->queue_num > hw->func_caps.rss_table_size)
946 : 0 : return rte_flow_error_set(error, EINVAL,
947 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
948 : : NULL, "Invalid RSS queue number");
949 : :
950 [ # # ]: 0 : if (rss_act->key_len)
951 : 0 : PMD_DRV_LOG(WARNING,
952 : : "RSS key is ignored when queues specified");
953 : :
954 : 0 : pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
955 [ # # ]: 0 : if (pf->dev_data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG)
956 : 0 : max_queue = i40e_pf_calc_configured_queues_num(pf);
957 : : else
958 : 0 : max_queue = pf->dev_data->nb_rx_queues;
959 : :
960 : 0 : max_queue = RTE_MIN(max_queue, I40E_MAX_Q_PER_TC);
961 : :
962 [ # # ]: 0 : for (i = 0; i < rss_act->queue_num; i++) {
963 [ # # ]: 0 : if ((int)rss_act->queue[i] >= max_queue)
964 : : break;
965 : : }
966 : :
967 [ # # ]: 0 : if (i < rss_act->queue_num)
968 : 0 : return rte_flow_error_set(error, EINVAL,
969 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
970 : : NULL, "Invalid RSS queues");
971 : :
972 : 0 : memcpy(rss_conf->queue, rss_act->queue,
973 : 0 : rss_act->queue_num * sizeof(rss_conf->queue[0]));
974 : 0 : rss_conf->conf.queue = rss_conf->queue;
975 : 0 : rss_conf->conf.queue_num = rss_act->queue_num;
976 : 0 : return 0;
977 : : }
978 : :
979 : : static int
980 : 0 : i40e_hash_parse_queue_region(const struct rte_eth_dev *dev,
981 : : const struct rte_flow_item pattern[],
982 : : const struct rte_flow_action_rss *rss_act,
983 : : struct i40e_rte_flow_rss_conf *rss_conf,
984 : : struct rte_flow_error *error)
985 : : {
986 : : struct i40e_pf *pf;
987 : : const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
988 : : uint64_t hash_queues;
989 : : uint32_t i;
990 : :
991 [ # # ]: 0 : if (pattern[1].type != RTE_FLOW_ITEM_TYPE_END)
992 : 0 : return rte_flow_error_set(error, ENOTSUP,
993 : : RTE_FLOW_ERROR_TYPE_ITEM_NUM,
994 : 0 : &pattern[1],
995 : : "Pattern not supported.");
996 : :
997 : 0 : vlan_spec = pattern->spec;
998 : 0 : vlan_mask = pattern->mask;
999 [ # # ]: 0 : if (!vlan_spec || !vlan_mask ||
1000 [ # # # # : 0 : (rte_be_to_cpu_16(vlan_mask->hdr.vlan_tci) >> 13) != 7)
# # ]
1001 : 0 : return rte_flow_error_set(error, EINVAL,
1002 : : RTE_FLOW_ERROR_TYPE_ITEM, pattern,
1003 : : "Pattern error.");
1004 : :
1005 [ # # ]: 0 : if (!rss_act->queue)
1006 : 0 : return rte_flow_error_set(error, EINVAL,
1007 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1008 : : NULL, "Queues not specified");
1009 : :
1010 [ # # ]: 0 : if (rss_act->key_len)
1011 : 0 : PMD_DRV_LOG(WARNING,
1012 : : "RSS key is ignored when configure queue region");
1013 : :
1014 : : /* Use a 64 bit variable to represent all queues in a region. */
1015 : : RTE_BUILD_BUG_ON(I40E_MAX_Q_PER_TC > 64);
1016 : :
1017 [ # # ]: 0 : if (!rss_act->queue_num ||
1018 : 0 : !rte_is_power_of_2(rss_act->queue_num) ||
1019 [ # # ]: 0 : rss_act->queue_num + rss_act->queue[0] > I40E_MAX_Q_PER_TC)
1020 : 0 : return rte_flow_error_set(error, EINVAL,
1021 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1022 : : NULL, "Queue number error");
1023 : :
1024 [ # # ]: 0 : for (i = 1; i < rss_act->queue_num; i++) {
1025 [ # # ]: 0 : if (rss_act->queue[i - 1] + 1 != rss_act->queue[i])
1026 : : break;
1027 : : }
1028 : :
1029 [ # # ]: 0 : if (i < rss_act->queue_num)
1030 : 0 : return rte_flow_error_set(error, EINVAL,
1031 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1032 : : NULL,
1033 : : "Queues must be incremented continuously");
1034 : :
1035 : : /* Map all queues to bits of uint64_t */
1036 : 0 : hash_queues = (BIT_ULL(rss_act->queue[0] + rss_act->queue_num) - 1) &
1037 : 0 : ~(BIT_ULL(rss_act->queue[0]) - 1);
1038 : :
1039 : 0 : pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1040 [ # # ]: 0 : if (hash_queues & ~pf->hash_enabled_queues)
1041 : 0 : return rte_flow_error_set(error, EINVAL,
1042 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1043 : : NULL, "Some queues are not in LUT");
1044 : :
1045 : 0 : rss_conf->region_queue_num = (uint8_t)rss_act->queue_num;
1046 : 0 : rss_conf->region_queue_start = rss_act->queue[0];
1047 [ # # ]: 0 : rss_conf->region_priority = rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci) >> 13;
1048 : 0 : return 0;
1049 : : }
1050 : :
1051 : : static int
1052 : 0 : i40e_hash_parse_global_conf(const struct rte_eth_dev *dev,
1053 : : const struct rte_flow_item pattern[],
1054 : : const struct rte_flow_action_rss *rss_act,
1055 : : struct i40e_rte_flow_rss_conf *rss_conf,
1056 : : struct rte_flow_error *error)
1057 : : {
1058 [ # # ]: 0 : if (rss_act->func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ)
1059 : 0 : return rte_flow_error_set(error, EINVAL,
1060 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1061 : : NULL,
1062 : : "Symmetric function should be set with pattern types");
1063 : :
1064 : 0 : rss_conf->conf.func = rss_act->func;
1065 : :
1066 [ # # ]: 0 : if (rss_act->types)
1067 : 0 : PMD_DRV_LOG(WARNING,
1068 : : "RSS types are ignored when no pattern specified");
1069 : :
1070 [ # # ]: 0 : if (pattern[0].type == RTE_FLOW_ITEM_TYPE_VLAN)
1071 : 0 : return i40e_hash_parse_queue_region(dev, pattern, rss_act,
1072 : : rss_conf, error);
1073 : :
1074 [ # # ]: 0 : if (rss_act->queue)
1075 : 0 : return i40e_hash_parse_queues(dev, rss_act, rss_conf, error);
1076 : :
1077 [ # # ]: 0 : if (rss_act->key_len) {
1078 : 0 : i40e_hash_parse_key(rss_act, rss_conf);
1079 : 0 : return 0;
1080 : : }
1081 : :
1082 [ # # ]: 0 : if (rss_act->func == RTE_ETH_HASH_FUNCTION_DEFAULT)
1083 : 0 : PMD_DRV_LOG(WARNING, "Nothing change");
1084 : : return 0;
1085 : : }
1086 : :
1087 : : static bool
1088 : 0 : i40e_hash_validate_rss_types(uint64_t rss_types)
1089 : : {
1090 : : uint64_t type, mask;
1091 : :
1092 : : /* Validate L2 */
1093 : 0 : type = RTE_ETH_RSS_ETH & rss_types;
1094 : 0 : mask = (RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY) & rss_types;
1095 [ # # ]: 0 : if (!type && mask)
1096 : : return false;
1097 : :
1098 : : /* Validate L3 */
1099 : 0 : type = (I40E_HASH_L4_TYPES | RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
1100 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_IPV6 |
1101 : : RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_OTHER) & rss_types;
1102 : 0 : mask = (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY) & rss_types;
1103 [ # # ]: 0 : if (!type && mask)
1104 : : return false;
1105 : :
1106 : : /* Validate L4 */
1107 : 0 : type = (I40E_HASH_L4_TYPES | RTE_ETH_RSS_PORT) & rss_types;
1108 : 0 : mask = (RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY) & rss_types;
1109 [ # # ]: 0 : if (!type && mask)
1110 : 0 : return false;
1111 : :
1112 : : return true;
1113 : : }
1114 : :
1115 : : static int
1116 : 0 : i40e_hash_parse_pattern_act(const struct rte_eth_dev *dev,
1117 : : const struct rte_flow_item pattern[],
1118 : : const struct rte_flow_action_rss *rss_act,
1119 : : struct i40e_rte_flow_rss_conf *rss_conf,
1120 : : struct rte_flow_error *error)
1121 : : {
1122 [ # # ]: 0 : if (rss_act->queue)
1123 : 0 : return rte_flow_error_set(error, EINVAL,
1124 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1125 : : NULL,
1126 : : "RSS Queues not supported when pattern specified");
1127 : 0 : rss_conf->symmetric_enable = false; /* by default, symmetric is disabled */
1128 : :
1129 [ # # # ]: 0 : switch (rss_act->func) {
1130 : 0 : case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
1131 : 0 : rss_conf->symmetric_enable = true;
1132 : 0 : break;
1133 : : case RTE_ETH_HASH_FUNCTION_DEFAULT:
1134 : : case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
1135 : : case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
1136 : : break;
1137 : 0 : default:
1138 : 0 : return rte_flow_error_set(error, EINVAL,
1139 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1140 : : NULL,
1141 : : "RSS hash function not supported "
1142 : : "when pattern specified");
1143 : : }
1144 : :
1145 [ # # ]: 0 : if (!i40e_hash_validate_rss_types(rss_act->types))
1146 : 0 : return rte_flow_error_set(error, EINVAL,
1147 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1148 : : NULL, "RSS types are invalid");
1149 : :
1150 [ # # ]: 0 : if (rss_act->key_len)
1151 : 0 : i40e_hash_parse_key(rss_act, rss_conf);
1152 : :
1153 : 0 : rss_conf->conf.func = rss_act->func;
1154 : 0 : rss_conf->conf.types = rss_act->types;
1155 : 0 : rss_conf->inset = i40e_hash_get_inset(rss_act->types, rss_conf->symmetric_enable);
1156 : :
1157 : 0 : return i40e_hash_get_pattern_pctypes(dev, pattern, rss_act,
1158 : : rss_conf, error);
1159 : : }
1160 : :
1161 : : int
1162 : 0 : i40e_hash_parse(const struct rte_eth_dev *dev,
1163 : : const struct rte_flow_item pattern[],
1164 : : const struct rte_flow_action actions[],
1165 : : struct i40e_rte_flow_rss_conf *rss_conf,
1166 : : struct rte_flow_error *error)
1167 : : {
1168 : : const struct rte_flow_action_rss *rss_act;
1169 : :
1170 [ # # ]: 0 : if (actions[1].type != RTE_FLOW_ACTION_TYPE_END)
1171 : 0 : return rte_flow_error_set(error, EINVAL,
1172 : : RTE_FLOW_ERROR_TYPE_ACTION,
1173 : 0 : &actions[1],
1174 : : "Only support one action for RSS.");
1175 : :
1176 : 0 : rss_act = (const struct rte_flow_action_rss *)actions[0].conf;
1177 [ # # ]: 0 : if (rss_act->level)
1178 : 0 : return rte_flow_error_set(error, ENOTSUP,
1179 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1180 : : actions,
1181 : : "RSS level is not supported");
1182 : :
1183 [ # # ]: 0 : while (pattern->type == RTE_FLOW_ITEM_TYPE_VOID)
1184 : 0 : pattern++;
1185 : :
1186 [ # # ]: 0 : if (pattern[0].type == RTE_FLOW_ITEM_TYPE_END ||
1187 : : pattern[0].type == RTE_FLOW_ITEM_TYPE_VLAN)
1188 : 0 : return i40e_hash_parse_global_conf(dev, pattern, rss_act,
1189 : : rss_conf, error);
1190 : :
1191 : 0 : return i40e_hash_parse_pattern_act(dev, pattern, rss_act,
1192 : : rss_conf, error);
1193 : : }
1194 : :
1195 : : static void
1196 : 0 : i40e_invalid_rss_filter(const struct i40e_rte_flow_rss_conf *ref_conf,
1197 : : struct i40e_rte_flow_rss_conf *conf)
1198 : : {
1199 : 0 : uint32_t reset_flags = conf->misc_reset_flags;
1200 : :
1201 : 0 : conf->misc_reset_flags &= ~ref_conf->misc_reset_flags;
1202 : :
1203 [ # # ]: 0 : if ((reset_flags & I40E_HASH_FLOW_RESET_FLAG_REGION) &&
1204 [ # # ]: 0 : (ref_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_REGION) &&
1205 [ # # ]: 0 : (conf->region_queue_start != ref_conf->region_queue_start ||
1206 : : conf->region_queue_num != ref_conf->region_queue_num))
1207 : 0 : conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_REGION;
1208 : :
1209 : 0 : conf->reset_config_pctypes &= ~ref_conf->reset_config_pctypes;
1210 : 0 : conf->reset_symmetric_pctypes &= ~ref_conf->reset_symmetric_pctypes;
1211 : 0 : }
1212 : :
1213 : : int
1214 : 0 : i40e_hash_filter_restore(struct i40e_pf *pf)
1215 : : {
1216 : : struct i40e_rss_filter *filter;
1217 : : int ret;
1218 : :
1219 [ # # ]: 0 : TAILQ_FOREACH(filter, &pf->rss_config_list, next) {
1220 : 0 : struct i40e_rte_flow_rss_conf *rss_conf =
1221 : : &filter->rss_filter_info;
1222 : : struct i40e_rss_filter *prev;
1223 : :
1224 : 0 : rss_conf->misc_reset_flags = 0;
1225 : 0 : rss_conf->reset_config_pctypes = 0;
1226 : 0 : rss_conf->reset_symmetric_pctypes = 0;
1227 : :
1228 : 0 : ret = i40e_hash_config(pf, rss_conf);
1229 [ # # ]: 0 : if (ret) {
1230 : 0 : pf->hash_filter_enabled = 0;
1231 : 0 : i40e_pf_disable_rss(pf);
1232 : 0 : PMD_DRV_LOG(ERR,
1233 : : "Re-configure RSS failed, RSS has been disabled");
1234 : 0 : return ret;
1235 : : }
1236 : :
1237 : : /* Invalid previous RSS filter */
1238 [ # # ]: 0 : TAILQ_FOREACH(prev, &pf->rss_config_list, next) {
1239 [ # # ]: 0 : if (prev == filter)
1240 : : break;
1241 : 0 : i40e_invalid_rss_filter(rss_conf,
1242 : : &prev->rss_filter_info);
1243 : : }
1244 : : }
1245 : :
1246 : : return 0;
1247 : : }
1248 : :
1249 : : int
1250 : 0 : i40e_hash_filter_create(struct i40e_pf *pf,
1251 : : struct i40e_rte_flow_rss_conf *rss_conf)
1252 : : {
1253 : : struct i40e_rss_filter *filter, *prev;
1254 : : struct i40e_rte_flow_rss_conf *new_conf;
1255 : : int ret;
1256 : :
1257 : 0 : filter = rte_zmalloc("i40e_rss_filter", sizeof(*filter), 0);
1258 [ # # ]: 0 : if (!filter) {
1259 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory.");
1260 : 0 : return -ENOMEM;
1261 : : }
1262 : :
1263 [ # # ]: 0 : new_conf = &filter->rss_filter_info;
1264 : :
1265 : : memcpy(new_conf, rss_conf, sizeof(*new_conf));
1266 [ # # ]: 0 : if (new_conf->conf.queue_num)
1267 : 0 : new_conf->conf.queue = new_conf->queue;
1268 [ # # ]: 0 : if (new_conf->conf.key_len)
1269 : 0 : new_conf->conf.key = new_conf->key;
1270 : :
1271 : 0 : ret = i40e_hash_config(pf, new_conf);
1272 [ # # ]: 0 : if (ret) {
1273 : 0 : rte_free(filter);
1274 [ # # ]: 0 : if (i40e_pf_config_rss(pf))
1275 : : return ret;
1276 : :
1277 : 0 : (void)i40e_hash_filter_restore(pf);
1278 : 0 : return ret;
1279 : : }
1280 : :
1281 : : /* Invalid previous RSS filter */
1282 [ # # ]: 0 : TAILQ_FOREACH(prev, &pf->rss_config_list, next)
1283 : 0 : i40e_invalid_rss_filter(new_conf, &prev->rss_filter_info);
1284 : :
1285 : 0 : TAILQ_INSERT_TAIL(&pf->rss_config_list, filter, next);
1286 : 0 : return 0;
1287 : : }
1288 : :
1289 : : static int
1290 : 0 : i40e_hash_reset_conf(struct i40e_pf *pf,
1291 : : struct i40e_rte_flow_rss_conf *rss_conf)
1292 : : {
1293 : 0 : struct i40e_hw *hw = &pf->adapter->hw;
1294 : : struct rte_eth_dev *dev;
1295 : : uint64_t inset;
1296 : : uint32_t idx;
1297 : : int ret;
1298 : :
1299 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_FUNC) {
1300 : 0 : ret = i40e_hash_config_func(hw, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
1301 [ # # ]: 0 : if (ret)
1302 : : return ret;
1303 : :
1304 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_FUNC;
1305 : : }
1306 : :
1307 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_REGION) {
1308 : 0 : dev = &rte_eth_devices[pf->dev_data->port_id];
1309 : 0 : ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
1310 [ # # ]: 0 : if (ret)
1311 : : return ret;
1312 : :
1313 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_REGION;
1314 : : }
1315 : :
1316 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_KEY) {
1317 : 0 : ret = i40e_pf_reset_rss_key(pf);
1318 [ # # ]: 0 : if (ret)
1319 : : return ret;
1320 : :
1321 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_KEY;
1322 : : }
1323 : :
1324 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_QUEUE) {
1325 [ # # ]: 0 : if (!pf->adapter->rss_reta_updated) {
1326 : 0 : ret = i40e_pf_reset_rss_reta(pf);
1327 [ # # ]: 0 : if (ret)
1328 : : return ret;
1329 : : }
1330 : :
1331 : 0 : pf->hash_enabled_queues = 0;
1332 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_QUEUE;
1333 : : }
1334 : :
1335 [ # # ]: 0 : while (rss_conf->reset_config_pctypes) {
1336 : : idx = rte_bsf64(rss_conf->reset_config_pctypes);
1337 : :
1338 : 0 : i40e_hash_enable_pctype(hw, idx, false);
1339 : 0 : inset = i40e_get_default_input_set(idx);
1340 [ # # ]: 0 : if (inset) {
1341 : 0 : ret = i40e_set_hash_inset(hw, inset, idx, false);
1342 [ # # ]: 0 : if (ret)
1343 : 0 : return ret;
1344 : : }
1345 : :
1346 : 0 : rss_conf->reset_config_pctypes &= ~BIT_ULL(idx);
1347 : : }
1348 : :
1349 [ # # ]: 0 : while (rss_conf->reset_symmetric_pctypes) {
1350 : : idx = rte_bsf64(rss_conf->reset_symmetric_pctypes);
1351 : :
1352 : 0 : ret = i40e_hash_config_pctype_symmetric(hw, idx, false);
1353 [ # # ]: 0 : if (ret)
1354 : 0 : return ret;
1355 : :
1356 : 0 : rss_conf->reset_symmetric_pctypes &= ~BIT_ULL(idx);
1357 : : }
1358 : :
1359 : : return 0;
1360 : : }
1361 : :
1362 : : int
1363 : 0 : i40e_hash_filter_destroy(struct i40e_pf *pf,
1364 : : const struct i40e_rss_filter *rss_filter)
1365 : : {
1366 : : struct i40e_rss_filter *filter;
1367 : : int ret;
1368 : :
1369 [ # # ]: 0 : TAILQ_FOREACH(filter, &pf->rss_config_list, next) {
1370 [ # # ]: 0 : if (rss_filter == filter) {
1371 : 0 : ret = i40e_hash_reset_conf(pf,
1372 : : &filter->rss_filter_info);
1373 [ # # ]: 0 : if (ret)
1374 : : return ret;
1375 : :
1376 [ # # ]: 0 : TAILQ_REMOVE(&pf->rss_config_list, filter, next);
1377 : 0 : rte_free(filter);
1378 : 0 : return 0;
1379 : : }
1380 : : }
1381 : :
1382 : : return -ENOENT;
1383 : : }
1384 : :
1385 : : int
1386 : 0 : i40e_hash_filter_flush(struct i40e_pf *pf)
1387 : : {
1388 : : struct rte_flow *flow, *next;
1389 : :
1390 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(flow, &pf->flow_list, node, next) {
1391 [ # # ]: 0 : if (flow->filter_type != RTE_ETH_FILTER_HASH)
1392 : 0 : continue;
1393 : :
1394 [ # # ]: 0 : if (flow->rule) {
1395 : : struct i40e_rss_filter *filter = flow->rule;
1396 : : int ret;
1397 : :
1398 : 0 : ret = i40e_hash_reset_conf(pf,
1399 : : &filter->rss_filter_info);
1400 [ # # ]: 0 : if (ret)
1401 : 0 : return ret;
1402 : :
1403 [ # # ]: 0 : TAILQ_REMOVE(&pf->rss_config_list, filter, next);
1404 : 0 : rte_free(filter);
1405 : : }
1406 : :
1407 [ # # ]: 0 : TAILQ_REMOVE(&pf->flow_list, flow, node);
1408 : 0 : rte_free(flow);
1409 : : }
1410 : :
1411 [ # # ]: 0 : assert(!pf->rss_config_list.tqh_first);
1412 : : return 0;
1413 : : }
|