1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2021 HiSilicon Limited.
3 */
4
5 #include <rte_ethdev.h>
6 #include <rte_io.h>
7 #include <rte_malloc.h>
8
9 #include "hns3_ethdev.h"
10 #include "hns3_logs.h"
11
12 /* Default hash keys */
13 const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE] = {
14 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
15 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
16 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
17 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
18 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA
19 };
20
21 const uint8_t hns3_hash_func_map[] = {
22 [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
23 [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
24 [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE,
25 [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP,
26 };
27
28 enum hns3_rss_tuple_type {
29 HNS3_RSS_IP_TUPLE,
30 HNS3_RSS_IP_L4_TUPLE,
31 };
32
33 static const struct {
34 uint64_t rss_types;
35 uint16_t tuple_type;
36 uint64_t rss_field;
37 uint64_t tuple_mask;
38 } hns3_set_tuple_table[] = {
39 /* IPV4-FRAG */
40 { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
41 HNS3_RSS_IP_TUPLE,
42 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S),
43 HNS3_RSS_TUPLE_IPV4_FLAG_M },
44 { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
45 HNS3_RSS_IP_TUPLE,
46 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D),
47 HNS3_RSS_TUPLE_IPV4_FLAG_M },
48 { RTE_ETH_RSS_FRAG_IPV4,
49 HNS3_RSS_IP_TUPLE,
50 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) |
51 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D),
52 HNS3_RSS_TUPLE_IPV4_FLAG_M },
53
54 /* IPV4 */
55 { RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
56 HNS3_RSS_IP_TUPLE,
57 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S),
58 HNS3_RSS_TUPLE_IPV4_NONF_M },
59 { RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
60 HNS3_RSS_IP_TUPLE,
61 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
62 HNS3_RSS_TUPLE_IPV4_NONF_M },
63 { RTE_ETH_RSS_IPV4,
64 HNS3_RSS_IP_TUPLE,
65 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
66 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
67 HNS3_RSS_TUPLE_IPV4_NONF_M },
68
69 /* IPV4-OTHER */
70 { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
71 HNS3_RSS_IP_TUPLE,
72 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S),
73 HNS3_RSS_TUPLE_IPV4_NONF_M },
74 { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
75 HNS3_RSS_IP_TUPLE,
76 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
77 HNS3_RSS_TUPLE_IPV4_NONF_M },
78 { RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
79 HNS3_RSS_IP_TUPLE,
80 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
81 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
82 HNS3_RSS_TUPLE_IPV4_NONF_M },
83
84 /* IPV4-TCP */
85 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
86 HNS3_RSS_IP_L4_TUPLE,
87 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S),
88 HNS3_RSS_TUPLE_IPV4_TCP_M },
89 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY,
90 HNS3_RSS_IP_L4_TUPLE,
91 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D),
92 HNS3_RSS_TUPLE_IPV4_TCP_M },
93 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
94 HNS3_RSS_IP_L4_TUPLE,
95 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S),
96 HNS3_RSS_TUPLE_IPV4_TCP_M },
97 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY,
98 HNS3_RSS_IP_L4_TUPLE,
99 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D),
100 HNS3_RSS_TUPLE_IPV4_TCP_M },
101 { RTE_ETH_RSS_NONFRAG_IPV4_TCP,
102 HNS3_RSS_IP_L4_TUPLE,
103 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) |
104 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) |
105 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) |
106 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D),
107 HNS3_RSS_TUPLE_IPV4_TCP_M },
108
109 /* IPV4-UDP */
110 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
111 HNS3_RSS_IP_L4_TUPLE,
112 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S),
113 HNS3_RSS_TUPLE_IPV4_UDP_M },
114 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY,
115 HNS3_RSS_IP_L4_TUPLE,
116 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D),
117 HNS3_RSS_TUPLE_IPV4_UDP_M },
118 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
119 HNS3_RSS_IP_L4_TUPLE,
120 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S),
121 HNS3_RSS_TUPLE_IPV4_UDP_M },
122 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY,
123 HNS3_RSS_IP_L4_TUPLE,
124 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D),
125 HNS3_RSS_TUPLE_IPV4_UDP_M },
126 { RTE_ETH_RSS_NONFRAG_IPV4_UDP,
127 HNS3_RSS_IP_L4_TUPLE,
128 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) |
129 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) |
130 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) |
131 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D),
132 HNS3_RSS_TUPLE_IPV4_UDP_M },
133
134 /* IPV4-SCTP */
135 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
136 HNS3_RSS_IP_L4_TUPLE,
137 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S),
138 HNS3_RSS_TUPLE_IPV4_SCTP_M },
139 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
140 HNS3_RSS_IP_L4_TUPLE,
141 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D),
142 HNS3_RSS_TUPLE_IPV4_SCTP_M },
143 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
144 HNS3_RSS_IP_L4_TUPLE,
145 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S),
146 HNS3_RSS_TUPLE_IPV4_SCTP_M },
147 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
148 HNS3_RSS_IP_L4_TUPLE,
149 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D),
150 HNS3_RSS_TUPLE_IPV4_SCTP_M },
151 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
152 HNS3_RSS_IP_L4_TUPLE,
153 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) |
154 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) |
155 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) |
156 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D),
157 HNS3_RSS_TUPLE_IPV4_SCTP_M },
158
159 /* IPV6-FRAG */
160 { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
161 HNS3_RSS_IP_TUPLE,
162 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S),
163 HNS3_RSS_TUPLE_IPV6_FLAG_M },
164 { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
165 HNS3_RSS_IP_TUPLE,
166 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D),
167 HNS3_RSS_TUPLE_IPV6_FLAG_M },
168 { RTE_ETH_RSS_FRAG_IPV6,
169 HNS3_RSS_IP_TUPLE,
170 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) |
171 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D),
172 HNS3_RSS_TUPLE_IPV6_FLAG_M },
173
174 /* IPV6 */
175 { RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
176 HNS3_RSS_IP_TUPLE,
177 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S),
178 HNS3_RSS_TUPLE_IPV6_NONF_M },
179 { RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
180 HNS3_RSS_IP_TUPLE,
181 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
182 HNS3_RSS_TUPLE_IPV6_NONF_M },
183 { RTE_ETH_RSS_IPV6,
184 HNS3_RSS_IP_TUPLE,
185 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
186 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
187 HNS3_RSS_TUPLE_IPV6_NONF_M },
188
189 /* IPV6-OTHER */
190 { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
191 HNS3_RSS_IP_TUPLE,
192 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S),
193 HNS3_RSS_TUPLE_IPV6_NONF_M },
194 { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
195 HNS3_RSS_IP_TUPLE,
196 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
197 HNS3_RSS_TUPLE_IPV6_NONF_M },
198 { RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
199 HNS3_RSS_IP_TUPLE,
200 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
201 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
202 HNS3_RSS_TUPLE_IPV6_NONF_M },
203
204 /* IPV6-TCP */
205 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
206 HNS3_RSS_IP_L4_TUPLE,
207 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S),
208 HNS3_RSS_TUPLE_IPV6_TCP_M },
209 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY,
210 HNS3_RSS_IP_L4_TUPLE,
211 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D),
212 HNS3_RSS_TUPLE_IPV6_TCP_M },
213 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
214 HNS3_RSS_IP_L4_TUPLE,
215 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S),
216 HNS3_RSS_TUPLE_IPV6_TCP_M },
217 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY,
218 HNS3_RSS_IP_L4_TUPLE,
219 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D),
220 HNS3_RSS_TUPLE_IPV6_TCP_M },
221 { RTE_ETH_RSS_NONFRAG_IPV6_TCP,
222 HNS3_RSS_IP_L4_TUPLE,
223 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) |
224 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) |
225 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) |
226 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D),
227 HNS3_RSS_TUPLE_IPV6_TCP_M },
228
229 /* IPV6-UDP */
230 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
231 HNS3_RSS_IP_L4_TUPLE,
232 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S),
233 HNS3_RSS_TUPLE_IPV6_UDP_M },
234 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY,
235 HNS3_RSS_IP_L4_TUPLE,
236 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D),
237 HNS3_RSS_TUPLE_IPV6_UDP_M },
238 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
239 HNS3_RSS_IP_L4_TUPLE,
240 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S),
241 HNS3_RSS_TUPLE_IPV6_UDP_M },
242 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY,
243 HNS3_RSS_IP_L4_TUPLE,
244 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D),
245 HNS3_RSS_TUPLE_IPV6_UDP_M },
246 { RTE_ETH_RSS_NONFRAG_IPV6_UDP,
247 HNS3_RSS_IP_L4_TUPLE,
248 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) |
249 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) |
250 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) |
251 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D),
252 HNS3_RSS_TUPLE_IPV6_UDP_M },
253
254 /* IPV6-SCTP */
255 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
256 HNS3_RSS_IP_L4_TUPLE,
257 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S),
258 HNS3_RSS_TUPLE_IPV6_SCTP_M },
259 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
260 HNS3_RSS_IP_L4_TUPLE,
261 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D),
262 HNS3_RSS_TUPLE_IPV6_SCTP_M },
263 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
264 HNS3_RSS_IP_L4_TUPLE,
265 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S),
266 HNS3_RSS_TUPLE_IPV6_SCTP_M },
267 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
268 HNS3_RSS_IP_L4_TUPLE,
269 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D),
270 HNS3_RSS_TUPLE_IPV6_SCTP_M },
271 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
272 HNS3_RSS_IP_L4_TUPLE,
273 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) |
274 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) |
275 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
276 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S),
277 HNS3_RSS_TUPLE_IPV6_SCTP_M },
278 };
279
280 /*
281 * rss_generic_config command function, opcode:0x0D01.
282 * Used to set algorithm and hash key of RSS.
283 */
284 static int
hns3_rss_set_algo_key(struct hns3_hw * hw,uint8_t hash_algo,const uint8_t * key,uint8_t key_len)285 hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
286 const uint8_t *key, uint8_t key_len)
287 {
288 struct hns3_rss_generic_config_cmd *req;
289 struct hns3_cmd_desc desc;
290 const uint8_t *cur_key;
291 uint16_t cur_key_size;
292 uint16_t max_bd_num;
293 uint16_t idx;
294 int ret;
295
296 req = (struct hns3_rss_generic_config_cmd *)desc.data;
297
298 max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
299 for (idx = 0; idx < max_bd_num; idx++) {
300 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
301 false);
302
303 req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK);
304 req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
305
306 if (idx == max_bd_num - 1 &&
307 (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
308 cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
309 else
310 cur_key_size = HNS3_RSS_HASH_KEY_NUM;
311
312 cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
313 memcpy(req->hash_key, cur_key, cur_key_size);
314
315 ret = hns3_cmd_send(hw, &desc, 1);
316 if (ret) {
317 hns3_err(hw, "Configure RSS algo key failed %d", ret);
318 return ret;
319 }
320 }
321
322 return 0;
323 }
324
325 static int
hns3_rss_get_algo_key(struct hns3_hw * hw,uint8_t * hash_algo,uint8_t * key,uint8_t key_len)326 hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo,
327 uint8_t *key, uint8_t key_len)
328 {
329 struct hns3_rss_generic_config_cmd *req;
330 struct hns3_cmd_desc desc;
331 uint16_t cur_key_size;
332 uint16_t max_bd_num;
333 uint8_t *cur_key;
334 uint16_t idx;
335 int ret;
336
337 req = (struct hns3_rss_generic_config_cmd *)desc.data;
338 max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
339 for (idx = 0; idx < max_bd_num; idx++) {
340 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
341 true);
342
343 req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
344 ret = hns3_cmd_send(hw, &desc, 1);
345 if (ret) {
346 hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d",
347 ret);
348 return ret;
349 }
350
351 if (idx == 0)
352 *hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK;
353
354 if (idx == max_bd_num - 1 &&
355 (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
356 cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
357 else
358 cur_key_size = HNS3_RSS_HASH_KEY_NUM;
359
360 cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
361 memcpy(cur_key, req->hash_key, cur_key_size);
362 }
363
364 return 0;
365 }
366
367 /*
368 * rss_indirection_table command function, opcode:0x0D07.
369 * Used to configure the indirection table of rss.
370 */
371 int
hns3_set_rss_indir_table(struct hns3_hw * hw,uint16_t * indir,uint16_t size)372 hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
373 {
374 struct hns3_rss_indirection_table_cmd *req;
375 uint16_t max_bd_num, cfg_tbl_size;
376 struct hns3_cmd_desc desc;
377 uint8_t qid_msb_off;
378 uint8_t qid_msb_val;
379 uint16_t q_id;
380 uint16_t i, j;
381 int ret;
382
383 req = (struct hns3_rss_indirection_table_cmd *)desc.data;
384 max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE);
385 for (i = 0; i < max_bd_num; i++) {
386 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
387 false);
388 req->start_table_index =
389 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
390 req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK);
391
392 if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0)
393 cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE;
394 else
395 cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE;
396
397 for (j = 0; j < cfg_tbl_size; j++) {
398 q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j];
399 req->rss_result_l[j] = q_id & 0xff;
400
401 qid_msb_off =
402 j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
403 qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1)
404 << (j * HNS3_RSS_CFG_TBL_BW_H %
405 HNS3_BITS_PER_BYTE);
406 req->rss_result_h[qid_msb_off] |= qid_msb_val;
407 }
408
409 ret = hns3_cmd_send(hw, &desc, 1);
410 if (ret) {
411 hns3_err(hw,
412 "Sets RSS indirection table failed %d size %u",
413 ret, size);
414 return ret;
415 }
416 }
417
418 return 0;
419 }
420
421 static int
hns3_get_rss_indir_table(struct hns3_hw * hw,uint16_t * indir,uint16_t size)422 hns3_get_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
423 {
424 struct hns3_rss_indirection_table_cmd *req;
425 uint16_t max_bd_num, cfg_tbl_size;
426 uint8_t qid_msb_off, qid_msb_idx;
427 struct hns3_cmd_desc desc;
428 uint16_t q_id, q_hi, q_lo;
429 uint8_t rss_result_h;
430 uint16_t i, j;
431 int ret;
432
433 req = (struct hns3_rss_indirection_table_cmd *)desc.data;
434 max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE);
435 for (i = 0; i < max_bd_num; i++) {
436 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
437 true);
438 req->start_table_index =
439 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
440 ret = hns3_cmd_send(hw, &desc, 1);
441 if (ret) {
442 hns3_err(hw, "fail to get RSS indirection table from firmware, ret = %d",
443 ret);
444 return ret;
445 }
446
447 if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0)
448 cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE;
449 else
450 cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE;
451
452 for (j = 0; j < cfg_tbl_size; j++) {
453 qid_msb_idx =
454 j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
455 rss_result_h = req->rss_result_h[qid_msb_idx];
456 qid_msb_off =
457 j * HNS3_RSS_CFG_TBL_BW_H % HNS3_BITS_PER_BYTE;
458 q_hi = (rss_result_h >> qid_msb_off) &
459 HNS3_RSS_CFG_TBL_BW_H_M;
460 q_lo = req->rss_result_l[j];
461 q_id = (q_hi << HNS3_RSS_CFG_TBL_BW_L) | q_lo;
462 indir[i * HNS3_RSS_CFG_TBL_SIZE + j] = q_id;
463 }
464 }
465
466 return 0;
467 }
468
469 int
hns3_rss_reset_indir_table(struct hns3_hw * hw)470 hns3_rss_reset_indir_table(struct hns3_hw *hw)
471 {
472 uint16_t *lut;
473 int ret;
474
475 lut = rte_zmalloc("hns3_rss_lut",
476 hw->rss_ind_tbl_size * sizeof(uint16_t), 0);
477 if (lut == NULL) {
478 hns3_err(hw, "No hns3_rss_lut memory can be allocated");
479 return -ENOMEM;
480 }
481
482 ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size);
483 if (ret != 0)
484 hns3_err(hw, "RSS uninit indir table failed, ret = %d.", ret);
485 else
486 memcpy(hw->rss_info.rss_indirection_tbl, lut,
487 sizeof(uint16_t) * hw->rss_ind_tbl_size);
488 rte_free(lut);
489
490 return ret;
491 }
492
493 bool
hns3_check_rss_types_valid(struct hns3_hw * hw,uint64_t types)494 hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types)
495 {
496 uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
497 RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
498 RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
499 RTE_ETH_RSS_NONFRAG_IPV6_OTHER;
500 uint64_t ip_l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP |
501 RTE_ETH_RSS_NONFRAG_IPV4_UDP |
502 RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
503 RTE_ETH_RSS_NONFRAG_IPV6_TCP |
504 RTE_ETH_RSS_NONFRAG_IPV6_UDP |
505 RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
506 bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST);
507 bool has_ip_pkt = !!(types & ip_mask);
508 uint64_t final_types;
509
510 if (types == 0)
511 return true;
512
513 if ((types & HNS3_ETH_RSS_SUPPORT) == 0) {
514 hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.",
515 types);
516 return false;
517 }
518
519 if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 &&
520 (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) {
521 hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set.");
522 return false;
523 }
524
525 if (has_l4_src_dst && (types & ip_l4_mask) == 0) {
526 if (!has_ip_pkt) {
527 hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set.");
528 return false;
529 }
530 /*
531 * For the case that the types has L4_SRC/DST_ONLY but hasn't
532 * IP-TCP/UDP/SCTP packet type, this types is considered valid
533 * if it also has IP packet type.
534 */
535 hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet.");
536 }
537
538 if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) {
539 final_types = types & HNS3_ETH_RSS_SUPPORT;
540 hns3_warn(hw, "set RSS types based on hardware support, requested:0x%" PRIx64 " configured:0x%" PRIx64 "",
541 types, final_types);
542 }
543
544 return true;
545 }
546
547 uint64_t
hns3_rss_calc_tuple_filed(uint64_t rss_hf)548 hns3_rss_calc_tuple_filed(uint64_t rss_hf)
549 {
550 uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY |
551 RTE_ETH_RSS_L3_DST_ONLY;
552 uint64_t l4_only_mask = RTE_ETH_RSS_L4_SRC_ONLY |
553 RTE_ETH_RSS_L4_DST_ONLY;
554 uint64_t l3_l4_only_mask = l3_only_mask | l4_only_mask;
555 bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask);
556 bool has_l3_only = !!(rss_hf & l3_only_mask);
557 uint64_t tuple = 0;
558 uint32_t i;
559
560 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
561 if ((rss_hf & hns3_set_tuple_table[i].rss_types) !=
562 hns3_set_tuple_table[i].rss_types)
563 continue;
564
565 if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) {
566 if (hns3_set_tuple_table[i].rss_types & l3_only_mask ||
567 !has_l3_only)
568 tuple |= hns3_set_tuple_table[i].rss_field;
569 continue;
570 }
571
572 /* For IP types with L4, we need check both L3 and L4 */
573 if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask ||
574 !has_l3_l4_only)
575 tuple |= hns3_set_tuple_table[i].rss_field;
576 }
577
578 return tuple;
579 }
580
581 int
hns3_set_rss_tuple_field(struct hns3_hw * hw,uint64_t tuple_fields)582 hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields)
583 {
584 struct hns3_rss_input_tuple_cmd *req;
585 struct hns3_cmd_desc desc;
586 int ret;
587
588 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
589 req = (struct hns3_rss_input_tuple_cmd *)desc.data;
590 req->tuple_field = rte_cpu_to_le_64(tuple_fields);
591 ret = hns3_cmd_send(hw, &desc, 1);
592 if (ret != 0)
593 hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret);
594
595 return ret;
596 }
597
598 int
hns3_set_rss_tuple_by_rss_hf(struct hns3_hw * hw,uint64_t rss_hf)599 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
600 {
601 uint64_t tuple_fields;
602 int ret;
603
604 tuple_fields = hns3_rss_calc_tuple_filed(rss_hf);
605 ret = hns3_set_rss_tuple_field(hw, tuple_fields);
606 if (ret != 0)
607 hns3_err(hw, "Update RSS flow types tuples failed, ret = %d",
608 ret);
609
610 return ret;
611 }
612
613 /*
614 * Configure RSS hash protocols and hash key.
615 * @param dev
616 * Pointer to Ethernet device.
617 * @praram rss_conf
618 * The configuration select of rss key size and tuple flow_types.
619 * @return
620 * 0 on success, a negative errno value otherwise is set.
621 */
622 int
hns3_dev_rss_hash_update(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)623 hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
624 struct rte_eth_rss_conf *rss_conf)
625 {
626 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
627 uint64_t rss_hf_bk = hw->rss_info.rss_hf;
628 uint8_t key_len = rss_conf->rss_key_len;
629 uint64_t rss_hf = rss_conf->rss_hf;
630 uint8_t *key = rss_conf->rss_key;
631 int ret;
632
633 if (key && key_len != hw->rss_key_size) {
634 hns3_err(hw, "the hash key len(%u) is invalid, must be %u",
635 key_len, hw->rss_key_size);
636 return -EINVAL;
637 }
638
639 if (!hns3_check_rss_types_valid(hw, rss_hf))
640 return -EINVAL;
641
642 rte_spinlock_lock(&hw->lock);
643 ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
644 if (ret)
645 goto set_tuple_fail;
646
647 ret = hns3_update_rss_algo_key(hw, rss_conf->algorithm, key, key_len);
648 if (ret != 0)
649 goto set_algo_key_fail;
650
651 if (rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_DEFAULT)
652 hw->rss_info.hash_algo = hns3_hash_func_map[rss_conf->algorithm];
653 if (key != NULL)
654 memcpy(hw->rss_info.key, key, hw->rss_key_size);
655 hw->rss_info.rss_hf = rss_hf;
656 rte_spinlock_unlock(&hw->lock);
657
658 return 0;
659
660 set_algo_key_fail:
661 (void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk);
662 set_tuple_fail:
663 rte_spinlock_unlock(&hw->lock);
664 return ret;
665 }
666
667 int
hns3_get_rss_tuple_field(struct hns3_hw * hw,uint64_t * tuple_fields)668 hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields)
669 {
670 struct hns3_rss_input_tuple_cmd *req;
671 struct hns3_cmd_desc desc;
672 int ret;
673
674 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true);
675 req = (struct hns3_rss_input_tuple_cmd *)desc.data;
676 ret = hns3_cmd_send(hw, &desc, 1);
677 if (ret != 0) {
678 hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d",
679 ret);
680 return ret;
681 }
682
683 *tuple_fields = rte_le_to_cpu_64(req->tuple_field);
684
685 return 0;
686 }
687
688 static uint64_t
hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw * hw,uint64_t tuple_fields)689 hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw *hw, uint64_t tuple_fields)
690 {
691 uint64_t ipv6_sctp_l4_mask =
692 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
693 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S);
694 uint64_t rss_hf = 0;
695 uint64_t tuple_mask;
696 uint32_t i;
697
698 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
699 tuple_mask = hns3_set_tuple_table[i].tuple_mask;
700 /*
701 * The RSS hash of the packet type is disabled if its tuples is
702 * zero.
703 */
704 if ((tuple_fields & tuple_mask) == 0)
705 continue;
706
707 /*
708 * Some hardware don't support to use src/dst port fields to
709 * hash for IPV6-SCTP packet.
710 */
711 if ((hns3_set_tuple_table[i].rss_types &
712 RTE_ETH_RSS_NONFRAG_IPV6_SCTP) &&
713 !hw->rss_info.ipv6_sctp_offload_supported)
714 tuple_mask &= ~ipv6_sctp_l4_mask;
715
716 /*
717 * The framework (ethdev ops) or driver (rte flow API) ensure
718 * that both L3_SRC/DST_ONLY and L4_SRC/DST_ONLY cannot be set
719 * to driver at the same time. But if user doesn't specify
720 * anything L3/L4_SRC/DST_ONLY, driver enables all tuple fields.
721 * In this case, driver should not report L3/L4_SRC/DST_ONLY.
722 */
723 if ((tuple_fields & tuple_mask) == tuple_mask) {
724 /* Skip the item enabled part tuples. */
725 if ((tuple_fields & hns3_set_tuple_table[i].rss_field) !=
726 tuple_mask)
727 continue;
728
729 rss_hf |= hns3_set_tuple_table[i].rss_types;
730 continue;
731 }
732
733 /* Match the item enabled part tuples.*/
734 if ((tuple_fields & hns3_set_tuple_table[i].rss_field) ==
735 hns3_set_tuple_table[i].rss_field)
736 rss_hf |= hns3_set_tuple_table[i].rss_types;
737 }
738
739 return rss_hf;
740 }
741
742 static int
hns3_rss_hash_get_rss_hf(struct hns3_hw * hw,uint64_t * rss_hf)743 hns3_rss_hash_get_rss_hf(struct hns3_hw *hw, uint64_t *rss_hf)
744 {
745 uint64_t tuple_fields;
746 int ret;
747
748 ret = hns3_get_rss_tuple_field(hw, &tuple_fields);
749 if (ret != 0)
750 return ret;
751
752 *rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields);
753
754 return 0;
755 }
756
757 /*
758 * Get rss key and rss_hf types set of RSS hash configuration.
759 * @param dev
760 * Pointer to Ethernet device.
761 * @praram rss_conf
762 * The buffer to get rss key size and tuple types.
763 * @return
764 * 0 on success.
765 */
766 int
hns3_dev_rss_hash_conf_get(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)767 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
768 struct rte_eth_rss_conf *rss_conf)
769 {
770 const uint8_t hash_func_map[] = {
771 [HNS3_RSS_HASH_ALGO_TOEPLITZ] = RTE_ETH_HASH_FUNCTION_TOEPLITZ,
772 [HNS3_RSS_HASH_ALGO_SIMPLE] = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR,
773 [HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP] = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ,
774 };
775 struct hns3_adapter *hns = dev->data->dev_private;
776 uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
777 struct hns3_hw *hw = &hns->hw;
778 uint8_t hash_algo = 0;
779 int ret;
780
781 rte_spinlock_lock(&hw->lock);
782 ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf);
783 if (ret != 0) {
784 rte_spinlock_unlock(&hw->lock);
785 hns3_err(hw, "obtain hash tuples failed, ret = %d", ret);
786 return ret;
787 }
788
789 ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
790 if (ret != 0) {
791 rte_spinlock_unlock(&hw->lock);
792 hns3_err(hw, "obtain hash algo and key failed, ret = %d", ret);
793 return ret;
794 }
795 rte_spinlock_unlock(&hw->lock);
796
797 /* Get the RSS Key if user required. */
798 if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
799 memcpy(rss_conf->rss_key, rss_key, hw->rss_key_size);
800 rss_conf->rss_key_len = hw->rss_key_size;
801 }
802 rss_conf->algorithm = hash_func_map[hash_algo];
803
804 return 0;
805 }
806
807 /*
808 * Update rss redirection table of RSS.
809 * @param dev
810 * Pointer to Ethernet device.
811 * @praram reta_conf
812 * Pointer to the configuration select of mask and redirection tables.
813 * @param reta_size
814 * Redirection table size.
815 * @return
816 * 0 on success, a negative errno value otherwise is set.
817 */
818 int
hns3_dev_rss_reta_update(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)819 hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
820 struct rte_eth_rss_reta_entry64 *reta_conf,
821 uint16_t reta_size)
822 {
823 struct hns3_adapter *hns = dev->data->dev_private;
824 struct hns3_hw *hw = &hns->hw;
825 struct hns3_rss_conf *rss_cfg = &hw->rss_info;
826 uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
827 uint16_t idx, shift;
828 uint16_t i;
829 int ret;
830
831 if (reta_size != hw->rss_ind_tbl_size) {
832 hns3_err(hw, "The size of hash lookup table configured (%u)"
833 "doesn't match the number hardware can supported"
834 "(%u)", reta_size, hw->rss_ind_tbl_size);
835 return -EINVAL;
836 }
837 rte_spinlock_lock(&hw->lock);
838 memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
839 sizeof(rss_cfg->rss_indirection_tbl));
840 for (i = 0; i < reta_size; i++) {
841 idx = i / RTE_ETH_RETA_GROUP_SIZE;
842 shift = i % RTE_ETH_RETA_GROUP_SIZE;
843 if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) {
844 hns3_err(hw, "queue id(%u) set to redirection table "
845 "exceeds queue number(%u) allocated to a TC",
846 reta_conf[idx].reta[shift],
847 hw->alloc_rss_size);
848 ret = -EINVAL;
849 goto out;
850 }
851
852 if (reta_conf[idx].mask & (1ULL << shift))
853 indirection_tbl[i] = reta_conf[idx].reta[shift];
854 }
855
856 ret = hns3_set_rss_indir_table(hw, indirection_tbl,
857 hw->rss_ind_tbl_size);
858 if (ret != 0)
859 goto out;
860
861 memcpy(rss_cfg->rss_indirection_tbl, indirection_tbl,
862 sizeof(uint16_t) * hw->rss_ind_tbl_size);
863
864 out:
865 rte_spinlock_unlock(&hw->lock);
866 return ret;
867 }
868
869 /*
870 * Get rss redirection table of RSS hash configuration.
871 * @param dev
872 * Pointer to Ethernet device.
873 * @praram reta_conf
874 * Pointer to the configuration select of mask and redirection tables.
875 * @param reta_size
876 * Redirection table size.
877 * @return
878 * 0 on success, a negative errno value otherwise is set.
879 */
880 int
hns3_dev_rss_reta_query(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)881 hns3_dev_rss_reta_query(struct rte_eth_dev *dev,
882 struct rte_eth_rss_reta_entry64 *reta_conf,
883 uint16_t reta_size)
884 {
885 struct hns3_adapter *hns = dev->data->dev_private;
886 uint16_t reta_table[HNS3_RSS_IND_TBL_SIZE_MAX];
887 struct hns3_hw *hw = &hns->hw;
888 uint16_t idx, shift;
889 uint16_t i;
890 int ret;
891
892 if (reta_size != hw->rss_ind_tbl_size) {
893 hns3_err(hw, "The size of hash lookup table configured (%u)"
894 " doesn't match the number hardware can supported"
895 "(%u)", reta_size, hw->rss_ind_tbl_size);
896 return -EINVAL;
897 }
898 rte_spinlock_lock(&hw->lock);
899 ret = hns3_get_rss_indir_table(hw, reta_table, reta_size);
900 if (ret != 0) {
901 rte_spinlock_unlock(&hw->lock);
902 hns3_err(hw, "query RSS redirection table failed, ret = %d.",
903 ret);
904 return ret;
905 }
906 rte_spinlock_unlock(&hw->lock);
907
908 for (i = 0; i < reta_size; i++) {
909 idx = i / RTE_ETH_RETA_GROUP_SIZE;
910 shift = i % RTE_ETH_RETA_GROUP_SIZE;
911 if (reta_conf[idx].mask & (1ULL << shift))
912 reta_conf[idx].reta[shift] = reta_table[i];
913 }
914
915 return 0;
916 }
917
918 static void
hns3_set_rss_tc_mode_entry(struct hns3_hw * hw,uint8_t * tc_valid,uint16_t * tc_size,uint16_t * tc_offset,uint8_t tc_num)919 hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid,
920 uint16_t *tc_size, uint16_t *tc_offset,
921 uint8_t tc_num)
922 {
923 struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
924 uint16_t rss_size = hw->alloc_rss_size;
925 uint16_t roundup_size;
926 uint16_t i;
927
928 roundup_size = roundup_pow_of_two(rss_size);
929 roundup_size = ilog2(roundup_size);
930
931 for (i = 0; i < tc_num; i++) {
932 if (hns->is_vf) {
933 /*
934 * For packets with VLAN priorities destined for the VF,
935 * hardware still assign Rx queue based on the Up-to-TC
936 * mapping PF configured. But VF has only one TC. If
937 * other TC don't enable, it causes that the priority
938 * packets that aren't destined for TC0 aren't received
939 * by RSS hash but is destined for queue 0. So driver
940 * has to enable the unused TC by using TC0 queue
941 * mapping configuration.
942 */
943 tc_valid[i] = (hw->hw_tc_map & BIT(i)) ?
944 !!(hw->hw_tc_map & BIT(i)) : 1;
945 tc_size[i] = roundup_size;
946 tc_offset[i] = (hw->hw_tc_map & BIT(i)) ?
947 rss_size * i : 0;
948 } else {
949 tc_valid[i] = !!(hw->hw_tc_map & BIT(i));
950 tc_size[i] = tc_valid[i] ? roundup_size : 0;
951 tc_offset[i] = tc_valid[i] ? rss_size * i : 0;
952 }
953 }
954 }
955
956 static int
hns3_set_rss_tc_mode(struct hns3_hw * hw)957 hns3_set_rss_tc_mode(struct hns3_hw *hw)
958 {
959 struct hns3_rss_tc_mode_cmd *req;
960 uint16_t tc_offset[HNS3_MAX_TC_NUM];
961 uint8_t tc_valid[HNS3_MAX_TC_NUM];
962 uint16_t tc_size[HNS3_MAX_TC_NUM];
963 struct hns3_cmd_desc desc;
964 uint16_t i;
965 int ret;
966
967 hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size,
968 tc_offset, HNS3_MAX_TC_NUM);
969
970 req = (struct hns3_rss_tc_mode_cmd *)desc.data;
971 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false);
972 for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
973 uint16_t mode = 0;
974
975 hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
976 hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S,
977 tc_size[i]);
978 if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0)
979 hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1);
980 hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S,
981 tc_offset[i]);
982
983 req->rss_tc_mode[i] = rte_cpu_to_le_16(mode);
984 }
985 ret = hns3_cmd_send(hw, &desc, 1);
986 if (ret)
987 hns3_err(hw, "Sets rss tc mode failed %d", ret);
988
989 return ret;
990 }
991
992 /*
993 * Note: the 'hash_algo' is defined by enum rte_eth_hash_function.
994 */
995 int
hns3_update_rss_algo_key(struct hns3_hw * hw,uint8_t hash_func,uint8_t * key,uint8_t key_len)996 hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func,
997 uint8_t *key, uint8_t key_len)
998 {
999 uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
1000 bool modify_key, modify_algo;
1001 uint8_t hash_algo = 0;
1002 int ret;
1003
1004 modify_key = (key != NULL && key_len > 0);
1005 modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT;
1006 if (!modify_key && !modify_algo)
1007 return 0;
1008
1009 if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) {
1010 hns3_err(hw, "hash func (%u) is unsupported.", hash_func);
1011 return -ENOTSUP;
1012 }
1013 if (modify_key && key_len != hw->rss_key_size) {
1014 hns3_err(hw, "hash key length (%u) is invalid.", key_len);
1015 return -EINVAL;
1016 }
1017
1018 ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
1019 if (ret != 0) {
1020 hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d",
1021 ret);
1022 return ret;
1023 }
1024
1025 if (modify_algo)
1026 hash_algo = hns3_hash_func_map[hash_func];
1027 if (modify_key)
1028 memcpy(rss_key, key, key_len);
1029
1030 ret = hns3_rss_set_algo_key(hw, hash_algo, rss_key, hw->rss_key_size);
1031 if (ret != 0)
1032 hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d",
1033 ret);
1034
1035 return ret;
1036 }
1037
1038 static void
hns3_rss_tuple_uninit(struct hns3_hw * hw)1039 hns3_rss_tuple_uninit(struct hns3_hw *hw)
1040 {
1041 struct hns3_cmd_desc desc;
1042 int ret;
1043
1044 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
1045
1046 ret = hns3_cmd_send(hw, &desc, 1);
1047 if (ret) {
1048 hns3_err(hw, "RSS uninit tuple failed %d", ret);
1049 return;
1050 }
1051 }
1052
1053 /*
1054 * Set the default rss configuration in the init of driver.
1055 */
1056 void
hns3_rss_set_default_args(struct hns3_hw * hw)1057 hns3_rss_set_default_args(struct hns3_hw *hw)
1058 {
1059 struct hns3_rss_conf *rss_cfg = &hw->rss_info;
1060 uint16_t queue_num = hw->alloc_rss_size;
1061 uint16_t i;
1062
1063 /* Default hash algorithm */
1064 rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
1065
1066 hw->rss_info.rss_hf = 0;
1067 memcpy(rss_cfg->key, hns3_hash_key,
1068 RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
1069
1070 /* Initialize RSS indirection table */
1071 for (i = 0; i < hw->rss_ind_tbl_size; i++)
1072 rss_cfg->rss_indirection_tbl[i] = i % queue_num;
1073 }
1074
1075 /*
1076 * RSS initialization for hns3 PMD.
1077 */
1078 int
hns3_config_rss(struct hns3_adapter * hns)1079 hns3_config_rss(struct hns3_adapter *hns)
1080 {
1081 struct hns3_hw *hw = &hns->hw;
1082 struct hns3_rss_conf *rss_cfg = &hw->rss_info;
1083 uint8_t *hash_key = rss_cfg->key;
1084 uint64_t rss_hf;
1085 int ret;
1086
1087 enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
1088
1089 ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo,
1090 hash_key, hw->rss_key_size);
1091 if (ret)
1092 return ret;
1093
1094 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
1095 hw->rss_ind_tbl_size);
1096 if (ret)
1097 return ret;
1098
1099 ret = hns3_set_rss_tc_mode(hw);
1100 if (ret)
1101 return ret;
1102
1103 /*
1104 * When multi-queue RSS mode flag is not set or unsupported tuples are
1105 * set, disable all tuples.
1106 */
1107 rss_hf = hw->rss_info.rss_hf;
1108 if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) ||
1109 !(rss_hf & HNS3_ETH_RSS_SUPPORT))
1110 rss_hf = 0;
1111
1112 ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
1113 if (ret != 0) {
1114 hns3_err(hw, "set RSS tuples failed, ret = %d.", ret);
1115 return ret;
1116 }
1117 hw->rss_info.rss_hf = rss_hf;
1118
1119 return 0;
1120 }
1121
1122 /*
1123 * RSS uninitialization for hns3 PMD.
1124 */
1125 void
hns3_rss_uninit(struct hns3_adapter * hns)1126 hns3_rss_uninit(struct hns3_adapter *hns)
1127 {
1128 struct hns3_hw *hw = &hns->hw;
1129 int ret;
1130
1131 hns3_rss_tuple_uninit(hw);
1132 ret = hns3_rss_reset_indir_table(hw);
1133 if (ret != 0)
1134 return;
1135
1136 /* Disable RSS */
1137 hw->rss_info.rss_hf = 0;
1138 }
1139