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)
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 : : return inset;
612 : : }
613 : :
614 : : static int
615 : 0 : i40e_hash_config_func(struct i40e_hw *hw, enum rte_eth_hash_function func)
616 : : {
617 : : struct i40e_pf *pf;
618 : : uint32_t reg;
619 : : uint8_t symmetric = 0;
620 : :
621 : 0 : reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
622 : :
623 [ # # ]: 0 : if (func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
624 [ # # ]: 0 : if (!(reg & I40E_GLQF_CTL_HTOEP_MASK))
625 : 0 : goto set_symmetric;
626 : :
627 : 0 : reg &= ~I40E_GLQF_CTL_HTOEP_MASK;
628 : : } else {
629 [ # # ]: 0 : if (func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ)
630 : : symmetric = 1;
631 : :
632 [ # # ]: 0 : if (reg & I40E_GLQF_CTL_HTOEP_MASK)
633 : 0 : goto set_symmetric;
634 : :
635 : 0 : reg |= I40E_GLQF_CTL_HTOEP_MASK;
636 : : }
637 : :
638 : 0 : pf = &((struct i40e_adapter *)hw->back)->pf;
639 [ # # ]: 0 : if (pf->support_multi_driver) {
640 : 0 : PMD_DRV_LOG(ERR,
641 : : "Modify hash function is not permitted when multi-driver enabled");
642 : 0 : return -EPERM;
643 : : }
644 : :
645 : 0 : PMD_DRV_LOG(INFO, "NIC hash function is setting to %d", func);
646 : 0 : i40e_write_rx_ctl(hw, I40E_GLQF_CTL, reg);
647 : 0 : I40E_WRITE_FLUSH(hw);
648 : :
649 : 0 : set_symmetric:
650 : 0 : i40e_set_symmetric_hash_enable_per_port(hw, symmetric);
651 : 0 : return 0;
652 : : }
653 : :
654 : : static int
655 : 0 : i40e_hash_config_pctype_symmetric(struct i40e_hw *hw,
656 : : uint32_t pctype,
657 : : bool symmetric)
658 : : {
659 : 0 : struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
660 : : uint32_t reg;
661 : :
662 : 0 : reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
663 [ # # ]: 0 : if (symmetric) {
664 [ # # ]: 0 : if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
665 : : return 0;
666 : 0 : reg |= I40E_GLQF_HSYM_SYMH_ENA_MASK;
667 : : } else {
668 [ # # ]: 0 : if (!(reg & I40E_GLQF_HSYM_SYMH_ENA_MASK))
669 : : return 0;
670 : 0 : reg &= ~I40E_GLQF_HSYM_SYMH_ENA_MASK;
671 : : }
672 : :
673 [ # # ]: 0 : if (pf->support_multi_driver) {
674 : 0 : PMD_DRV_LOG(ERR,
675 : : "Enable/Disable symmetric hash is not permitted when multi-driver enabled");
676 : 0 : return -EPERM;
677 : : }
678 : :
679 : 0 : i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
680 : 0 : I40E_WRITE_FLUSH(hw);
681 : 0 : return 0;
682 : : }
683 : :
684 : : static void
685 : 0 : i40e_hash_enable_pctype(struct i40e_hw *hw,
686 : : uint32_t pctype, bool enable)
687 : : {
688 : : uint32_t reg, reg_val, mask;
689 : :
690 [ # # ]: 0 : if (pctype < 32) {
691 : 0 : mask = BIT(pctype);
692 : : reg = I40E_PFQF_HENA(0);
693 : : } else {
694 : 0 : mask = BIT(pctype - 32);
695 : : reg = I40E_PFQF_HENA(1);
696 : : }
697 : :
698 : 0 : reg_val = i40e_read_rx_ctl(hw, reg);
699 : :
700 [ # # ]: 0 : if (enable) {
701 [ # # ]: 0 : if (reg_val & mask)
702 : : return;
703 : :
704 : 0 : reg_val |= mask;
705 : : } else {
706 [ # # ]: 0 : if (!(reg_val & mask))
707 : : return;
708 : :
709 : 0 : reg_val &= ~mask;
710 : : }
711 : :
712 : 0 : i40e_write_rx_ctl(hw, reg, reg_val);
713 : 0 : I40E_WRITE_FLUSH(hw);
714 : : }
715 : :
716 : : static int
717 : 0 : i40e_hash_config_pctype(struct i40e_hw *hw,
718 : : struct i40e_rte_flow_rss_conf *rss_conf,
719 : : uint32_t pctype)
720 : : {
721 : 0 : uint64_t rss_types = rss_conf->conf.types;
722 : : int ret;
723 : :
724 [ # # ]: 0 : if (rss_types == 0) {
725 : 0 : i40e_hash_enable_pctype(hw, pctype, false);
726 : 0 : return 0;
727 : : }
728 : :
729 [ # # ]: 0 : if (rss_conf->inset) {
730 : 0 : ret = i40e_set_hash_inset(hw, rss_conf->inset, pctype, false);
731 [ # # ]: 0 : if (ret)
732 : : return ret;
733 : : }
734 : :
735 : 0 : i40e_hash_enable_pctype(hw, pctype, true);
736 : 0 : return 0;
737 : : }
738 : :
739 : : static int
740 : 0 : i40e_hash_config_region(struct i40e_pf *pf,
741 : : const struct i40e_rte_flow_rss_conf *rss_conf)
742 : : {
743 : 0 : struct i40e_hw *hw = &pf->adapter->hw;
744 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
745 : 0 : struct i40e_queue_region_info *regions = pf->queue_region.region;
746 : 0 : uint32_t num = pf->queue_region.queue_region_number;
747 : : uint32_t i, region_id_mask = 0;
748 : :
749 : : /* Use a 32 bit variable to represent all regions */
750 : : RTE_BUILD_BUG_ON(I40E_REGION_MAX_INDEX > 31);
751 : :
752 : : /* Re-configure the region if it existed */
753 [ # # ]: 0 : for (i = 0; i < num; i++) {
754 : 0 : if (rss_conf->region_queue_start ==
755 [ # # ]: 0 : regions[i].queue_start_index &&
756 [ # # ]: 0 : rss_conf->region_queue_num == regions[i].queue_num) {
757 : : uint32_t j;
758 : :
759 [ # # ]: 0 : for (j = 0; j < regions[i].user_priority_num; j++) {
760 : 0 : if (regions[i].user_priority[j] ==
761 [ # # ]: 0 : rss_conf->region_priority)
762 : : return 0;
763 : : }
764 : :
765 [ # # ]: 0 : if (j >= I40E_MAX_USER_PRIORITY) {
766 : 0 : PMD_DRV_LOG(ERR,
767 : : "Priority number exceed the maximum %d",
768 : : I40E_MAX_USER_PRIORITY);
769 : 0 : return -ENOSPC;
770 : : }
771 : :
772 : 0 : regions[i].user_priority[j] = rss_conf->region_priority;
773 : 0 : regions[i].user_priority_num++;
774 : 0 : return i40e_flush_queue_region_all_conf(dev, hw, pf, 1);
775 : : }
776 : :
777 : 0 : region_id_mask |= BIT(regions[i].region_id);
778 : : }
779 : :
780 [ # # ]: 0 : if (num > I40E_REGION_MAX_INDEX) {
781 : 0 : PMD_DRV_LOG(ERR, "Queue region resource used up");
782 : 0 : return -ENOSPC;
783 : : }
784 : :
785 : : /* Add a new region */
786 : :
787 : 0 : pf->queue_region.queue_region_number++;
788 : 0 : memset(®ions[num], 0, sizeof(regions[0]));
789 : :
790 : 0 : regions[num].region_id = rte_bsf32(~region_id_mask);
791 : 0 : regions[num].queue_num = rss_conf->region_queue_num;
792 : 0 : regions[num].queue_start_index = rss_conf->region_queue_start;
793 : 0 : regions[num].user_priority[0] = rss_conf->region_priority;
794 : 0 : regions[num].user_priority_num = 1;
795 : :
796 : 0 : return i40e_flush_queue_region_all_conf(dev, hw, pf, 1);
797 : : }
798 : :
799 : : static int
800 : 0 : i40e_hash_config(struct i40e_pf *pf,
801 : : struct i40e_rte_flow_rss_conf *rss_conf)
802 : : {
803 : : struct rte_flow_action_rss *rss_info = &rss_conf->conf;
804 : 0 : struct i40e_hw *hw = &pf->adapter->hw;
805 : : uint64_t pctypes;
806 : : int ret;
807 : :
808 [ # # ]: 0 : if (rss_info->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
809 : 0 : ret = i40e_hash_config_func(hw, rss_info->func);
810 [ # # ]: 0 : if (ret)
811 : : return ret;
812 : :
813 [ # # ]: 0 : if (rss_info->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ)
814 : 0 : rss_conf->misc_reset_flags |=
815 : : I40E_HASH_FLOW_RESET_FLAG_FUNC;
816 : : }
817 : :
818 [ # # ]: 0 : if (rss_conf->region_queue_num > 0) {
819 : 0 : ret = i40e_hash_config_region(pf, rss_conf);
820 [ # # ]: 0 : if (ret)
821 : : return ret;
822 : :
823 : 0 : rss_conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_REGION;
824 : : }
825 : :
826 [ # # ]: 0 : if (rss_info->key_len > 0) {
827 : 0 : ret = i40e_set_rss_key(pf->main_vsi, rss_conf->key,
828 : : rss_info->key_len);
829 [ # # ]: 0 : if (ret)
830 : : return ret;
831 : :
832 : 0 : rss_conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_KEY;
833 : : }
834 : :
835 : : /* Update lookup table */
836 [ # # ]: 0 : if (rss_info->queue_num > 0) {
837 : : uint8_t lut[RTE_ETH_RSS_RETA_SIZE_512];
838 : : uint32_t i, j = 0;
839 : :
840 [ # # ]: 0 : for (i = 0; i < hw->func_caps.rss_table_size; i++) {
841 : 0 : lut[i] = (uint8_t)rss_info->queue[j];
842 [ # # ]: 0 : j = (j == rss_info->queue_num - 1) ? 0 : (j + 1);
843 : : }
844 : :
845 : 0 : ret = i40e_set_rss_lut(pf->main_vsi, lut, (uint16_t)i);
846 [ # # ]: 0 : if (ret)
847 : 0 : return ret;
848 : :
849 : 0 : pf->hash_enabled_queues = 0;
850 [ # # ]: 0 : for (i = 0; i < rss_info->queue_num; i++)
851 : 0 : pf->hash_enabled_queues |= BIT_ULL(lut[i]);
852 : :
853 : 0 : pf->adapter->rss_reta_updated = 0;
854 : 0 : rss_conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_QUEUE;
855 : : }
856 : :
857 : : /* The codes behind configure the input sets and symmetric hash
858 : : * function of the packet types and enable hash on them.
859 : : */
860 : 0 : pctypes = rss_conf->config_pctypes;
861 [ # # ]: 0 : if (!pctypes)
862 : : return 0;
863 : :
864 : : /* For first flow that will enable hash on any packet type, we clean
865 : : * the RSS sets that by legacy configuration commands and parameters.
866 : : */
867 [ # # ]: 0 : if (!pf->hash_filter_enabled) {
868 : 0 : i40e_pf_disable_rss(pf);
869 : 0 : pf->hash_filter_enabled = true;
870 : : }
871 : :
872 : : do {
873 : : uint32_t idx = rte_bsf64(pctypes);
874 : 0 : uint64_t bit = BIT_ULL(idx);
875 : :
876 [ # # ]: 0 : if (rss_conf->symmetric_enable) {
877 : 0 : ret = i40e_hash_config_pctype_symmetric(hw, idx, true);
878 [ # # ]: 0 : if (ret)
879 : 0 : return ret;
880 : :
881 : 0 : rss_conf->reset_symmetric_pctypes |= bit;
882 : : }
883 : :
884 : 0 : ret = i40e_hash_config_pctype(hw, rss_conf, idx);
885 [ # # ]: 0 : if (ret)
886 : 0 : return ret;
887 : :
888 : 0 : rss_conf->reset_config_pctypes |= bit;
889 : 0 : pctypes &= ~bit;
890 [ # # ]: 0 : } while (pctypes);
891 : :
892 : : return 0;
893 : : }
894 : :
895 : : static void
896 : 0 : i40e_hash_parse_key(const struct rte_flow_action_rss *rss_act,
897 : : struct i40e_rte_flow_rss_conf *rss_conf)
898 : : {
899 : 0 : const uint8_t *key = rss_act->key;
900 : :
901 [ # # # # ]: 0 : if (!key || rss_act->key_len != sizeof(rss_conf->key)) {
902 : 0 : const uint32_t rss_key_default[] = {0x6b793944,
903 : : 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8,
904 : : 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605,
905 : : 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581};
906 : :
907 [ # # ]: 0 : if (rss_act->key_len != sizeof(rss_conf->key))
908 : 0 : PMD_DRV_LOG(WARNING,
909 : : "RSS key length invalid, must be %u bytes, now set key to default",
910 : : (uint32_t)sizeof(rss_conf->key));
911 : :
912 : 0 : memcpy(rss_conf->key, rss_key_default, sizeof(rss_conf->key));
913 : : } else {
914 : 0 : memcpy(rss_conf->key, key, sizeof(rss_conf->key));
915 : : }
916 : :
917 : 0 : rss_conf->conf.key = rss_conf->key;
918 : 0 : rss_conf->conf.key_len = sizeof(rss_conf->key);
919 : 0 : }
920 : :
921 : : static int
922 : 0 : i40e_hash_parse_queues(const struct rte_eth_dev *dev,
923 : : const struct rte_flow_action_rss *rss_act,
924 : : struct i40e_rte_flow_rss_conf *rss_conf,
925 : : struct rte_flow_error *error)
926 : : {
927 : : struct i40e_pf *pf;
928 : : struct i40e_hw *hw;
929 : : uint16_t i;
930 : : int max_queue;
931 : :
932 : 0 : hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
933 [ # # ]: 0 : if (!rss_act->queue_num ||
934 [ # # ]: 0 : rss_act->queue_num > hw->func_caps.rss_table_size)
935 : 0 : return rte_flow_error_set(error, EINVAL,
936 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
937 : : NULL, "Invalid RSS queue number");
938 : :
939 [ # # ]: 0 : if (rss_act->key_len)
940 : 0 : PMD_DRV_LOG(WARNING,
941 : : "RSS key is ignored when queues specified");
942 : :
943 : 0 : pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
944 [ # # ]: 0 : if (pf->dev_data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG)
945 : 0 : max_queue = i40e_pf_calc_configured_queues_num(pf);
946 : : else
947 : 0 : max_queue = pf->dev_data->nb_rx_queues;
948 : :
949 : 0 : max_queue = RTE_MIN(max_queue, I40E_MAX_Q_PER_TC);
950 : :
951 [ # # ]: 0 : for (i = 0; i < rss_act->queue_num; i++) {
952 [ # # ]: 0 : if ((int)rss_act->queue[i] >= max_queue)
953 : : break;
954 : : }
955 : :
956 [ # # ]: 0 : if (i < rss_act->queue_num)
957 : 0 : return rte_flow_error_set(error, EINVAL,
958 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
959 : : NULL, "Invalid RSS queues");
960 : :
961 : 0 : memcpy(rss_conf->queue, rss_act->queue,
962 : 0 : rss_act->queue_num * sizeof(rss_conf->queue[0]));
963 : 0 : rss_conf->conf.queue = rss_conf->queue;
964 : 0 : rss_conf->conf.queue_num = rss_act->queue_num;
965 : 0 : return 0;
966 : : }
967 : :
968 : : static int
969 : 0 : i40e_hash_parse_queue_region(const struct rte_eth_dev *dev,
970 : : const struct rte_flow_item pattern[],
971 : : const struct rte_flow_action_rss *rss_act,
972 : : struct i40e_rte_flow_rss_conf *rss_conf,
973 : : struct rte_flow_error *error)
974 : : {
975 : : struct i40e_pf *pf;
976 : : const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
977 : : uint64_t hash_queues;
978 : : uint32_t i;
979 : :
980 [ # # ]: 0 : if (pattern[1].type != RTE_FLOW_ITEM_TYPE_END)
981 : 0 : return rte_flow_error_set(error, ENOTSUP,
982 : : RTE_FLOW_ERROR_TYPE_ITEM_NUM,
983 : 0 : &pattern[1],
984 : : "Pattern not supported.");
985 : :
986 : 0 : vlan_spec = pattern->spec;
987 : 0 : vlan_mask = pattern->mask;
988 [ # # ]: 0 : if (!vlan_spec || !vlan_mask ||
989 [ # # # # : 0 : (rte_be_to_cpu_16(vlan_mask->hdr.vlan_tci) >> 13) != 7)
# # ]
990 : 0 : return rte_flow_error_set(error, EINVAL,
991 : : RTE_FLOW_ERROR_TYPE_ITEM, pattern,
992 : : "Pattern error.");
993 : :
994 [ # # ]: 0 : if (!rss_act->queue)
995 : 0 : return rte_flow_error_set(error, EINVAL,
996 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
997 : : NULL, "Queues not specified");
998 : :
999 [ # # ]: 0 : if (rss_act->key_len)
1000 : 0 : PMD_DRV_LOG(WARNING,
1001 : : "RSS key is ignored when configure queue region");
1002 : :
1003 : : /* Use a 64 bit variable to represent all queues in a region. */
1004 : : RTE_BUILD_BUG_ON(I40E_MAX_Q_PER_TC > 64);
1005 : :
1006 [ # # ]: 0 : if (!rss_act->queue_num ||
1007 : 0 : !rte_is_power_of_2(rss_act->queue_num) ||
1008 [ # # ]: 0 : rss_act->queue_num + rss_act->queue[0] > I40E_MAX_Q_PER_TC)
1009 : 0 : return rte_flow_error_set(error, EINVAL,
1010 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1011 : : NULL, "Queue number error");
1012 : :
1013 [ # # ]: 0 : for (i = 1; i < rss_act->queue_num; i++) {
1014 [ # # ]: 0 : if (rss_act->queue[i - 1] + 1 != rss_act->queue[i])
1015 : : break;
1016 : : }
1017 : :
1018 [ # # ]: 0 : if (i < rss_act->queue_num)
1019 : 0 : return rte_flow_error_set(error, EINVAL,
1020 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1021 : : NULL,
1022 : : "Queues must be incremented continuously");
1023 : :
1024 : : /* Map all queues to bits of uint64_t */
1025 : 0 : hash_queues = (BIT_ULL(rss_act->queue[0] + rss_act->queue_num) - 1) &
1026 : 0 : ~(BIT_ULL(rss_act->queue[0]) - 1);
1027 : :
1028 : 0 : pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1029 [ # # ]: 0 : if (hash_queues & ~pf->hash_enabled_queues)
1030 : 0 : return rte_flow_error_set(error, EINVAL,
1031 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1032 : : NULL, "Some queues are not in LUT");
1033 : :
1034 : 0 : rss_conf->region_queue_num = (uint8_t)rss_act->queue_num;
1035 : 0 : rss_conf->region_queue_start = rss_act->queue[0];
1036 [ # # ]: 0 : rss_conf->region_priority = rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci) >> 13;
1037 : 0 : return 0;
1038 : : }
1039 : :
1040 : : static int
1041 : 0 : i40e_hash_parse_global_conf(const struct rte_eth_dev *dev,
1042 : : const struct rte_flow_item pattern[],
1043 : : const struct rte_flow_action_rss *rss_act,
1044 : : struct i40e_rte_flow_rss_conf *rss_conf,
1045 : : struct rte_flow_error *error)
1046 : : {
1047 [ # # ]: 0 : if (rss_act->func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ)
1048 : 0 : return rte_flow_error_set(error, EINVAL,
1049 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1050 : : NULL,
1051 : : "Symmetric function should be set with pattern types");
1052 : :
1053 : 0 : rss_conf->conf.func = rss_act->func;
1054 : :
1055 [ # # ]: 0 : if (rss_act->types)
1056 : 0 : PMD_DRV_LOG(WARNING,
1057 : : "RSS types are ignored when no pattern specified");
1058 : :
1059 [ # # ]: 0 : if (pattern[0].type == RTE_FLOW_ITEM_TYPE_VLAN)
1060 : 0 : return i40e_hash_parse_queue_region(dev, pattern, rss_act,
1061 : : rss_conf, error);
1062 : :
1063 [ # # ]: 0 : if (rss_act->queue)
1064 : 0 : return i40e_hash_parse_queues(dev, rss_act, rss_conf, error);
1065 : :
1066 [ # # ]: 0 : if (rss_act->key_len) {
1067 : 0 : i40e_hash_parse_key(rss_act, rss_conf);
1068 : 0 : return 0;
1069 : : }
1070 : :
1071 [ # # ]: 0 : if (rss_act->func == RTE_ETH_HASH_FUNCTION_DEFAULT)
1072 : 0 : PMD_DRV_LOG(WARNING, "Nothing change");
1073 : : return 0;
1074 : : }
1075 : :
1076 : : static bool
1077 : 0 : i40e_hash_validate_rss_types(uint64_t rss_types)
1078 : : {
1079 : : uint64_t type, mask;
1080 : :
1081 : : /* Validate L2 */
1082 : 0 : type = RTE_ETH_RSS_ETH & rss_types;
1083 : 0 : mask = (RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY) & rss_types;
1084 [ # # ]: 0 : if (!type && mask)
1085 : : return false;
1086 : :
1087 : : /* Validate L3 */
1088 : 0 : type = (I40E_HASH_L4_TYPES | RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
1089 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_IPV6 |
1090 : : RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_OTHER) & rss_types;
1091 : 0 : mask = (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY) & rss_types;
1092 [ # # ]: 0 : if (!type && mask)
1093 : : return false;
1094 : :
1095 : : /* Validate L4 */
1096 : 0 : type = (I40E_HASH_L4_TYPES | RTE_ETH_RSS_PORT) & rss_types;
1097 : 0 : mask = (RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY) & rss_types;
1098 [ # # ]: 0 : if (!type && mask)
1099 : 0 : return false;
1100 : :
1101 : : return true;
1102 : : }
1103 : :
1104 : : static int
1105 : 0 : i40e_hash_parse_pattern_act(const struct rte_eth_dev *dev,
1106 : : const struct rte_flow_item pattern[],
1107 : : const struct rte_flow_action_rss *rss_act,
1108 : : struct i40e_rte_flow_rss_conf *rss_conf,
1109 : : struct rte_flow_error *error)
1110 : : {
1111 [ # # ]: 0 : if (rss_act->queue)
1112 : 0 : return rte_flow_error_set(error, EINVAL,
1113 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1114 : : NULL,
1115 : : "RSS Queues not supported when pattern specified");
1116 : :
1117 [ # # # ]: 0 : switch (rss_act->func) {
1118 : 0 : case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
1119 : 0 : rss_conf->symmetric_enable = true;
1120 : 0 : break;
1121 : : case RTE_ETH_HASH_FUNCTION_DEFAULT:
1122 : : case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
1123 : : case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
1124 : : break;
1125 : 0 : default:
1126 : 0 : return rte_flow_error_set(error, EINVAL,
1127 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1128 : : NULL,
1129 : : "RSS hash function not supported "
1130 : : "when pattern specified");
1131 : : }
1132 : :
1133 [ # # ]: 0 : if (!i40e_hash_validate_rss_types(rss_act->types))
1134 : 0 : return rte_flow_error_set(error, EINVAL,
1135 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1136 : : NULL, "RSS types are invalid");
1137 : :
1138 [ # # ]: 0 : if (rss_act->key_len)
1139 : 0 : i40e_hash_parse_key(rss_act, rss_conf);
1140 : :
1141 : 0 : rss_conf->conf.func = rss_act->func;
1142 : 0 : rss_conf->conf.types = rss_act->types;
1143 : 0 : rss_conf->inset = i40e_hash_get_inset(rss_act->types);
1144 : :
1145 : 0 : return i40e_hash_get_pattern_pctypes(dev, pattern, rss_act,
1146 : : rss_conf, error);
1147 : : }
1148 : :
1149 : : int
1150 : 0 : i40e_hash_parse(const struct rte_eth_dev *dev,
1151 : : const struct rte_flow_item pattern[],
1152 : : const struct rte_flow_action actions[],
1153 : : struct i40e_rte_flow_rss_conf *rss_conf,
1154 : : struct rte_flow_error *error)
1155 : : {
1156 : : const struct rte_flow_action_rss *rss_act;
1157 : :
1158 [ # # ]: 0 : if (actions[1].type != RTE_FLOW_ACTION_TYPE_END)
1159 : 0 : return rte_flow_error_set(error, EINVAL,
1160 : : RTE_FLOW_ERROR_TYPE_ACTION,
1161 : 0 : &actions[1],
1162 : : "Only support one action for RSS.");
1163 : :
1164 : 0 : rss_act = (const struct rte_flow_action_rss *)actions[0].conf;
1165 [ # # ]: 0 : if (rss_act->level)
1166 : 0 : return rte_flow_error_set(error, ENOTSUP,
1167 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF,
1168 : : actions,
1169 : : "RSS level is not supported");
1170 : :
1171 [ # # ]: 0 : while (pattern->type == RTE_FLOW_ITEM_TYPE_VOID)
1172 : 0 : pattern++;
1173 : :
1174 [ # # ]: 0 : if (pattern[0].type == RTE_FLOW_ITEM_TYPE_END ||
1175 : : pattern[0].type == RTE_FLOW_ITEM_TYPE_VLAN)
1176 : 0 : return i40e_hash_parse_global_conf(dev, pattern, rss_act,
1177 : : rss_conf, error);
1178 : :
1179 : 0 : return i40e_hash_parse_pattern_act(dev, pattern, rss_act,
1180 : : rss_conf, error);
1181 : : }
1182 : :
1183 : : static void
1184 : 0 : i40e_invalid_rss_filter(const struct i40e_rte_flow_rss_conf *ref_conf,
1185 : : struct i40e_rte_flow_rss_conf *conf)
1186 : : {
1187 : 0 : uint32_t reset_flags = conf->misc_reset_flags;
1188 : :
1189 : 0 : conf->misc_reset_flags &= ~ref_conf->misc_reset_flags;
1190 : :
1191 [ # # ]: 0 : if ((reset_flags & I40E_HASH_FLOW_RESET_FLAG_REGION) &&
1192 [ # # ]: 0 : (ref_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_REGION) &&
1193 [ # # ]: 0 : (conf->region_queue_start != ref_conf->region_queue_start ||
1194 : : conf->region_queue_num != ref_conf->region_queue_num))
1195 : 0 : conf->misc_reset_flags |= I40E_HASH_FLOW_RESET_FLAG_REGION;
1196 : :
1197 : 0 : conf->reset_config_pctypes &= ~ref_conf->reset_config_pctypes;
1198 : 0 : conf->reset_symmetric_pctypes &= ~ref_conf->reset_symmetric_pctypes;
1199 : 0 : }
1200 : :
1201 : : int
1202 : 0 : i40e_hash_filter_restore(struct i40e_pf *pf)
1203 : : {
1204 : : struct i40e_rss_filter *filter;
1205 : : int ret;
1206 : :
1207 [ # # ]: 0 : TAILQ_FOREACH(filter, &pf->rss_config_list, next) {
1208 : 0 : struct i40e_rte_flow_rss_conf *rss_conf =
1209 : : &filter->rss_filter_info;
1210 : : struct i40e_rss_filter *prev;
1211 : :
1212 : 0 : rss_conf->misc_reset_flags = 0;
1213 : 0 : rss_conf->reset_config_pctypes = 0;
1214 : 0 : rss_conf->reset_symmetric_pctypes = 0;
1215 : :
1216 : 0 : ret = i40e_hash_config(pf, rss_conf);
1217 [ # # ]: 0 : if (ret) {
1218 : 0 : pf->hash_filter_enabled = 0;
1219 : 0 : i40e_pf_disable_rss(pf);
1220 : 0 : PMD_DRV_LOG(ERR,
1221 : : "Re-configure RSS failed, RSS has been disabled");
1222 : 0 : return ret;
1223 : : }
1224 : :
1225 : : /* Invalid previous RSS filter */
1226 [ # # ]: 0 : TAILQ_FOREACH(prev, &pf->rss_config_list, next) {
1227 [ # # ]: 0 : if (prev == filter)
1228 : : break;
1229 : 0 : i40e_invalid_rss_filter(rss_conf,
1230 : : &prev->rss_filter_info);
1231 : : }
1232 : : }
1233 : :
1234 : : return 0;
1235 : : }
1236 : :
1237 : : int
1238 : 0 : i40e_hash_filter_create(struct i40e_pf *pf,
1239 : : struct i40e_rte_flow_rss_conf *rss_conf)
1240 : : {
1241 : : struct i40e_rss_filter *filter, *prev;
1242 : : struct i40e_rte_flow_rss_conf *new_conf;
1243 : : int ret;
1244 : :
1245 : 0 : filter = rte_zmalloc("i40e_rss_filter", sizeof(*filter), 0);
1246 [ # # ]: 0 : if (!filter) {
1247 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory.");
1248 : 0 : return -ENOMEM;
1249 : : }
1250 : :
1251 [ # # ]: 0 : new_conf = &filter->rss_filter_info;
1252 : :
1253 : : memcpy(new_conf, rss_conf, sizeof(*new_conf));
1254 [ # # ]: 0 : if (new_conf->conf.queue_num)
1255 : 0 : new_conf->conf.queue = new_conf->queue;
1256 [ # # ]: 0 : if (new_conf->conf.key_len)
1257 : 0 : new_conf->conf.key = new_conf->key;
1258 : :
1259 : 0 : ret = i40e_hash_config(pf, new_conf);
1260 [ # # ]: 0 : if (ret) {
1261 : 0 : rte_free(filter);
1262 [ # # ]: 0 : if (i40e_pf_config_rss(pf))
1263 : : return ret;
1264 : :
1265 : 0 : (void)i40e_hash_filter_restore(pf);
1266 : 0 : return ret;
1267 : : }
1268 : :
1269 : : /* Invalid previous RSS filter */
1270 [ # # ]: 0 : TAILQ_FOREACH(prev, &pf->rss_config_list, next)
1271 : 0 : i40e_invalid_rss_filter(new_conf, &prev->rss_filter_info);
1272 : :
1273 : 0 : TAILQ_INSERT_TAIL(&pf->rss_config_list, filter, next);
1274 : 0 : return 0;
1275 : : }
1276 : :
1277 : : static int
1278 : 0 : i40e_hash_reset_conf(struct i40e_pf *pf,
1279 : : struct i40e_rte_flow_rss_conf *rss_conf)
1280 : : {
1281 : 0 : struct i40e_hw *hw = &pf->adapter->hw;
1282 : : struct rte_eth_dev *dev;
1283 : : uint64_t inset;
1284 : : uint32_t idx;
1285 : : int ret;
1286 : :
1287 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_FUNC) {
1288 : 0 : ret = i40e_hash_config_func(hw, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
1289 [ # # ]: 0 : if (ret)
1290 : : return ret;
1291 : :
1292 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_FUNC;
1293 : : }
1294 : :
1295 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_REGION) {
1296 : 0 : dev = &rte_eth_devices[pf->dev_data->port_id];
1297 : 0 : ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
1298 [ # # ]: 0 : if (ret)
1299 : : return ret;
1300 : :
1301 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_REGION;
1302 : : }
1303 : :
1304 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_KEY) {
1305 : 0 : ret = i40e_pf_reset_rss_key(pf);
1306 [ # # ]: 0 : if (ret)
1307 : : return ret;
1308 : :
1309 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_KEY;
1310 : : }
1311 : :
1312 [ # # ]: 0 : if (rss_conf->misc_reset_flags & I40E_HASH_FLOW_RESET_FLAG_QUEUE) {
1313 [ # # ]: 0 : if (!pf->adapter->rss_reta_updated) {
1314 : 0 : ret = i40e_pf_reset_rss_reta(pf);
1315 [ # # ]: 0 : if (ret)
1316 : : return ret;
1317 : : }
1318 : :
1319 : 0 : pf->hash_enabled_queues = 0;
1320 : 0 : rss_conf->misc_reset_flags &= ~I40E_HASH_FLOW_RESET_FLAG_QUEUE;
1321 : : }
1322 : :
1323 [ # # ]: 0 : while (rss_conf->reset_config_pctypes) {
1324 : : idx = rte_bsf64(rss_conf->reset_config_pctypes);
1325 : :
1326 : 0 : i40e_hash_enable_pctype(hw, idx, false);
1327 : 0 : inset = i40e_get_default_input_set(idx);
1328 [ # # ]: 0 : if (inset) {
1329 : 0 : ret = i40e_set_hash_inset(hw, inset, idx, false);
1330 [ # # ]: 0 : if (ret)
1331 : 0 : return ret;
1332 : : }
1333 : :
1334 : 0 : rss_conf->reset_config_pctypes &= ~BIT_ULL(idx);
1335 : : }
1336 : :
1337 [ # # ]: 0 : while (rss_conf->reset_symmetric_pctypes) {
1338 : : idx = rte_bsf64(rss_conf->reset_symmetric_pctypes);
1339 : :
1340 : 0 : ret = i40e_hash_config_pctype_symmetric(hw, idx, false);
1341 [ # # ]: 0 : if (ret)
1342 : 0 : return ret;
1343 : :
1344 : 0 : rss_conf->reset_symmetric_pctypes &= ~BIT_ULL(idx);
1345 : : }
1346 : :
1347 : : return 0;
1348 : : }
1349 : :
1350 : : int
1351 : 0 : i40e_hash_filter_destroy(struct i40e_pf *pf,
1352 : : const struct i40e_rss_filter *rss_filter)
1353 : : {
1354 : : struct i40e_rss_filter *filter;
1355 : : int ret;
1356 : :
1357 [ # # ]: 0 : TAILQ_FOREACH(filter, &pf->rss_config_list, next) {
1358 [ # # ]: 0 : if (rss_filter == filter) {
1359 : 0 : ret = i40e_hash_reset_conf(pf,
1360 : : &filter->rss_filter_info);
1361 [ # # ]: 0 : if (ret)
1362 : : return ret;
1363 : :
1364 [ # # ]: 0 : TAILQ_REMOVE(&pf->rss_config_list, filter, next);
1365 : 0 : rte_free(filter);
1366 : 0 : return 0;
1367 : : }
1368 : : }
1369 : :
1370 : : return -ENOENT;
1371 : : }
1372 : :
1373 : : int
1374 : 0 : i40e_hash_filter_flush(struct i40e_pf *pf)
1375 : : {
1376 : : struct rte_flow *flow, *next;
1377 : :
1378 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(flow, &pf->flow_list, node, next) {
1379 [ # # ]: 0 : if (flow->filter_type != RTE_ETH_FILTER_HASH)
1380 : 0 : continue;
1381 : :
1382 [ # # ]: 0 : if (flow->rule) {
1383 : : struct i40e_rss_filter *filter = flow->rule;
1384 : : int ret;
1385 : :
1386 : 0 : ret = i40e_hash_reset_conf(pf,
1387 : : &filter->rss_filter_info);
1388 [ # # ]: 0 : if (ret)
1389 : 0 : return ret;
1390 : :
1391 [ # # ]: 0 : TAILQ_REMOVE(&pf->rss_config_list, filter, next);
1392 : 0 : rte_free(filter);
1393 : : }
1394 : :
1395 [ # # ]: 0 : TAILQ_REMOVE(&pf->flow_list, flow, node);
1396 : 0 : rte_free(flow);
1397 : : }
1398 : :
1399 [ # # ]: 0 : assert(!pf->rss_config_list.tqh_first);
1400 : : return 0;
1401 : : }
|