Branch data Line data Source code
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
285 : 0 : 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 : 0 : max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
299 [ # # ]: 0 : for (idx = 0; idx < max_bd_num; idx++) {
300 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
301 : : false);
302 : :
303 : 0 : req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK);
304 : 0 : req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
305 : :
306 [ # # ]: 0 : if (idx == max_bd_num - 1 &&
307 [ # # ]: 0 : (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
308 : 0 : cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
309 : : else
310 : : cur_key_size = HNS3_RSS_HASH_KEY_NUM;
311 : :
312 : 0 : cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
313 : 0 : memcpy(req->hash_key, cur_key, cur_key_size);
314 : :
315 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
316 [ # # ]: 0 : if (ret) {
317 : 0 : hns3_err(hw, "Configure RSS algo key failed %d", ret);
318 : 0 : return ret;
319 : : }
320 : : }
321 : :
322 : : return 0;
323 : : }
324 : :
325 : : static int
326 : 0 : 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 : 0 : max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
339 [ # # ]: 0 : for (idx = 0; idx < max_bd_num; idx++) {
340 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
341 : : true);
342 : :
343 : 0 : req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
344 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
345 [ # # ]: 0 : if (ret) {
346 : 0 : hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d",
347 : : ret);
348 : 0 : return ret;
349 : : }
350 : :
351 [ # # ]: 0 : if (idx == 0)
352 : 0 : *hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK;
353 : :
354 [ # # ]: 0 : if (idx == max_bd_num - 1 &&
355 [ # # ]: 0 : (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
356 : 0 : cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
357 : : else
358 : : cur_key_size = HNS3_RSS_HASH_KEY_NUM;
359 : :
360 : 0 : cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
361 : 0 : 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
372 : 0 : 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 : 0 : max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE);
385 [ # # ]: 0 : for (i = 0; i < max_bd_num; i++) {
386 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
387 : : false);
388 : 0 : req->start_table_index =
389 : : rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
390 : 0 : req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK);
391 : :
392 [ # # # # ]: 0 : if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0)
393 : 0 : cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE;
394 : : else
395 : : cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE;
396 : :
397 [ # # ]: 0 : for (j = 0; j < cfg_tbl_size; j++) {
398 : 0 : q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j];
399 : 0 : req->rss_result_l[j] = q_id & 0xff;
400 : :
401 : : qid_msb_off =
402 : 0 : j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
403 : 0 : qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1)
404 : 0 : << (j * HNS3_RSS_CFG_TBL_BW_H %
405 : : HNS3_BITS_PER_BYTE);
406 : 0 : req->rss_result_h[qid_msb_off] |= qid_msb_val;
407 : : }
408 : :
409 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
410 [ # # ]: 0 : if (ret) {
411 : 0 : hns3_err(hw,
412 : : "Sets RSS indirection table failed %d size %u",
413 : : ret, size);
414 : 0 : return ret;
415 : : }
416 : : }
417 : :
418 : : return 0;
419 : : }
420 : :
421 : : static int
422 : 0 : 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 : 0 : max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE);
435 [ # # ]: 0 : for (i = 0; i < max_bd_num; i++) {
436 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
437 : : true);
438 : 0 : req->start_table_index =
439 : : rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
440 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
441 [ # # ]: 0 : if (ret) {
442 : 0 : hns3_err(hw, "fail to get RSS indirection table from firmware, ret = %d",
443 : : ret);
444 : 0 : return ret;
445 : : }
446 : :
447 [ # # # # ]: 0 : if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0)
448 : 0 : cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE;
449 : : else
450 : : cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE;
451 : :
452 [ # # ]: 0 : for (j = 0; j < cfg_tbl_size; j++) {
453 : : qid_msb_idx =
454 : 0 : j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
455 : 0 : rss_result_h = req->rss_result_h[qid_msb_idx];
456 : 0 : qid_msb_off =
457 : 0 : j * HNS3_RSS_CFG_TBL_BW_H % HNS3_BITS_PER_BYTE;
458 : 0 : q_hi = (rss_result_h >> qid_msb_off) &
459 : : HNS3_RSS_CFG_TBL_BW_H_M;
460 : 0 : q_lo = req->rss_result_l[j];
461 : 0 : q_id = (q_hi << HNS3_RSS_CFG_TBL_BW_L) | q_lo;
462 : 0 : indir[i * HNS3_RSS_CFG_TBL_SIZE + j] = q_id;
463 : : }
464 : : }
465 : :
466 : : return 0;
467 : : }
468 : :
469 : : int
470 : 0 : hns3_rss_reset_indir_table(struct hns3_hw *hw)
471 : : {
472 : : uint16_t *lut;
473 : : int ret;
474 : :
475 : 0 : lut = rte_zmalloc("hns3_rss_lut",
476 : 0 : hw->rss_ind_tbl_size * sizeof(uint16_t), 0);
477 [ # # ]: 0 : if (lut == NULL) {
478 : 0 : hns3_err(hw, "No hns3_rss_lut memory can be allocated");
479 : 0 : return -ENOMEM;
480 : : }
481 : :
482 : 0 : ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size);
483 [ # # ]: 0 : if (ret != 0)
484 : 0 : hns3_err(hw, "RSS uninit indir table failed, ret = %d.", ret);
485 : : else
486 : 0 : memcpy(hw->rss_info.rss_indirection_tbl, lut,
487 : 0 : sizeof(uint16_t) * hw->rss_ind_tbl_size);
488 : 0 : rte_free(lut);
489 : :
490 : 0 : return ret;
491 : : }
492 : :
493 : : bool
494 : 0 : 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 : 0 : bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST);
507 : 0 : bool has_ip_pkt = !!(types & ip_mask);
508 : : uint64_t final_types;
509 : :
510 [ # # ]: 0 : if (types == 0)
511 : : return true;
512 : :
513 [ # # ]: 0 : if ((types & HNS3_ETH_RSS_SUPPORT) == 0) {
514 : 0 : hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.",
515 : : types);
516 : 0 : return false;
517 : : }
518 : :
519 [ # # ]: 0 : if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 &&
520 [ # # ]: 0 : (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) {
521 : 0 : hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set.");
522 : 0 : return false;
523 : : }
524 : :
525 [ # # # # ]: 0 : if (has_l4_src_dst && (types & ip_l4_mask) == 0) {
526 [ # # ]: 0 : if (!has_ip_pkt) {
527 : 0 : hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set.");
528 : 0 : 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 : 0 : hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet.");
536 : : }
537 : :
538 [ # # ]: 0 : if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) {
539 : : final_types = types & HNS3_ETH_RSS_SUPPORT;
540 : 0 : 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
548 : 0 : 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 : 0 : bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask);
556 : 0 : bool has_l3_only = !!(rss_hf & l3_only_mask);
557 : : uint64_t tuple = 0;
558 : : uint32_t i;
559 : :
560 [ # # ]: 0 : for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
561 [ # # ]: 0 : if ((rss_hf & hns3_set_tuple_table[i].rss_types) !=
562 : : hns3_set_tuple_table[i].rss_types)
563 : 0 : continue;
564 : :
565 [ # # ]: 0 : if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) {
566 [ # # # # ]: 0 : if (hns3_set_tuple_table[i].rss_types & l3_only_mask ||
567 : : !has_l3_only)
568 : 0 : tuple |= hns3_set_tuple_table[i].rss_field;
569 : 0 : continue;
570 : : }
571 : :
572 : : /* For IP types with L4, we need check both L3 and L4 */
573 [ # # # # ]: 0 : if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask ||
574 : : !has_l3_l4_only)
575 : 0 : tuple |= hns3_set_tuple_table[i].rss_field;
576 : : }
577 : :
578 : 0 : return tuple;
579 : : }
580 : :
581 : : int
582 : 0 : 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 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
589 : : req = (struct hns3_rss_input_tuple_cmd *)desc.data;
590 : 0 : req->tuple_field = rte_cpu_to_le_64(tuple_fields);
591 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
592 [ # # ]: 0 : if (ret != 0)
593 : 0 : hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret);
594 : :
595 : 0 : return ret;
596 : : }
597 : :
598 : : int
599 : 0 : 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 : 0 : tuple_fields = hns3_rss_calc_tuple_filed(rss_hf);
605 : 0 : ret = hns3_set_rss_tuple_field(hw, tuple_fields);
606 [ # # ]: 0 : if (ret != 0)
607 : 0 : hns3_err(hw, "Update RSS flow types tuples failed, ret = %d",
608 : : ret);
609 : :
610 : 0 : 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
623 : 0 : hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
624 : : struct rte_eth_rss_conf *rss_conf)
625 : : {
626 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
627 : 0 : uint64_t rss_hf_bk = hw->rss_info.rss_hf;
628 : 0 : uint8_t key_len = rss_conf->rss_key_len;
629 : 0 : uint64_t rss_hf = rss_conf->rss_hf;
630 : 0 : uint8_t *key = rss_conf->rss_key;
631 : : int ret;
632 : :
633 [ # # # # ]: 0 : if (key && key_len != hw->rss_key_size) {
634 : 0 : hns3_err(hw, "the hash key len(%u) is invalid, must be %u",
635 : : key_len, hw->rss_key_size);
636 : 0 : return -EINVAL;
637 : : }
638 : :
639 [ # # ]: 0 : if (!hns3_check_rss_types_valid(hw, rss_hf))
640 : : return -EINVAL;
641 : :
642 : 0 : rte_spinlock_lock(&hw->lock);
643 : 0 : ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
644 [ # # ]: 0 : if (ret)
645 : 0 : goto set_tuple_fail;
646 : :
647 : 0 : ret = hns3_update_rss_algo_key(hw, rss_conf->algorithm, key, key_len);
648 [ # # ]: 0 : if (ret != 0)
649 : 0 : goto set_algo_key_fail;
650 : :
651 [ # # ]: 0 : if (rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_DEFAULT)
652 : 0 : hw->rss_info.hash_algo = hns3_hash_func_map[rss_conf->algorithm];
653 [ # # ]: 0 : if (key != NULL)
654 : 0 : memcpy(hw->rss_info.key, key, hw->rss_key_size);
655 : 0 : hw->rss_info.rss_hf = rss_hf;
656 : : rte_spinlock_unlock(&hw->lock);
657 : :
658 : 0 : return 0;
659 : :
660 : : set_algo_key_fail:
661 : 0 : (void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk);
662 : 0 : set_tuple_fail:
663 : : rte_spinlock_unlock(&hw->lock);
664 : 0 : return ret;
665 : : }
666 : :
667 : : int
668 : 0 : 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 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true);
675 : : req = (struct hns3_rss_input_tuple_cmd *)desc.data;
676 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
677 [ # # ]: 0 : if (ret != 0) {
678 : 0 : hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d",
679 : : ret);
680 : 0 : return ret;
681 : : }
682 : :
683 : 0 : *tuple_fields = rte_le_to_cpu_64(req->tuple_field);
684 : :
685 : 0 : return 0;
686 : : }
687 : :
688 : : static uint64_t
689 : 0 : 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 [ # # ]: 0 : for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
699 : 0 : 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 [ # # ]: 0 : if ((tuple_fields & tuple_mask) == 0)
705 : 0 : continue;
706 : :
707 : : /*
708 : : * Some hardware don't support to use src/dst port fields to
709 : : * hash for IPV6-SCTP packet.
710 : : */
711 [ # # ]: 0 : if ((hns3_set_tuple_table[i].rss_types &
712 : 0 : RTE_ETH_RSS_NONFRAG_IPV6_SCTP) &&
713 [ # # ]: 0 : !hw->rss_info.ipv6_sctp_offload_supported)
714 : 0 : 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 [ # # ]: 0 : if ((tuple_fields & tuple_mask) == tuple_mask) {
724 : : /* Skip the item enabled part tuples. */
725 [ # # ]: 0 : if ((tuple_fields & hns3_set_tuple_table[i].rss_field) !=
726 : : tuple_mask)
727 : 0 : continue;
728 : :
729 : 0 : rss_hf |= hns3_set_tuple_table[i].rss_types;
730 : 0 : continue;
731 : : }
732 : :
733 : : /* Match the item enabled part tuples.*/
734 [ # # ]: 0 : if ((tuple_fields & hns3_set_tuple_table[i].rss_field) ==
735 : : hns3_set_tuple_table[i].rss_field)
736 : 0 : rss_hf |= hns3_set_tuple_table[i].rss_types;
737 : : }
738 : :
739 : 0 : return rss_hf;
740 : : }
741 : :
742 : : static int
743 : 0 : 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 : 0 : ret = hns3_get_rss_tuple_field(hw, &tuple_fields);
749 [ # # ]: 0 : if (ret != 0)
750 : : return ret;
751 : :
752 : 0 : *rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields);
753 : :
754 : 0 : 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
767 : 0 : hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
768 : : struct rte_eth_rss_conf *rss_conf)
769 : : {
770 : 0 : 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 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
776 : 0 : uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
777 : 0 : struct hns3_hw *hw = &hns->hw;
778 : 0 : uint8_t hash_algo = 0;
779 : : int ret;
780 : :
781 : 0 : rte_spinlock_lock(&hw->lock);
782 : 0 : ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf);
783 [ # # ]: 0 : if (ret != 0) {
784 : : rte_spinlock_unlock(&hw->lock);
785 : 0 : hns3_err(hw, "obtain hash tuples failed, ret = %d", ret);
786 : 0 : return ret;
787 : : }
788 : :
789 : 0 : ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
790 [ # # ]: 0 : if (ret != 0) {
791 : : rte_spinlock_unlock(&hw->lock);
792 : 0 : hns3_err(hw, "obtain hash algo and key failed, ret = %d", ret);
793 : 0 : return ret;
794 : : }
795 : : rte_spinlock_unlock(&hw->lock);
796 : :
797 : : /* Get the RSS Key if user required. */
798 [ # # # # ]: 0 : if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
799 : 0 : memcpy(rss_conf->rss_key, rss_key, hw->rss_key_size);
800 : 0 : rss_conf->rss_key_len = hw->rss_key_size;
801 : : }
802 : 0 : rss_conf->algorithm = hash_func_map[hash_algo];
803 : :
804 : 0 : 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
819 : 0 : 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 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
824 : 0 : 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 [ # # ]: 0 : if (reta_size != hw->rss_ind_tbl_size) {
832 : 0 : 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 : 0 : return -EINVAL;
836 : : }
837 : 0 : rte_spinlock_lock(&hw->lock);
838 : 0 : memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
839 : : sizeof(rss_cfg->rss_indirection_tbl));
840 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
841 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
842 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
843 [ # # ]: 0 : if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) {
844 : 0 : 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 : 0 : goto out;
850 : : }
851 : :
852 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
853 : 0 : indirection_tbl[i] = reta_conf[idx].reta[shift];
854 : : }
855 : :
856 : 0 : ret = hns3_set_rss_indir_table(hw, indirection_tbl,
857 : 0 : hw->rss_ind_tbl_size);
858 [ # # ]: 0 : if (ret != 0)
859 : 0 : goto out;
860 : :
861 : 0 : memcpy(rss_cfg->rss_indirection_tbl, indirection_tbl,
862 : 0 : sizeof(uint16_t) * hw->rss_ind_tbl_size);
863 : :
864 : 0 : out:
865 : : rte_spinlock_unlock(&hw->lock);
866 : 0 : 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
881 : 0 : 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 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
886 : : uint16_t reta_table[HNS3_RSS_IND_TBL_SIZE_MAX];
887 : 0 : struct hns3_hw *hw = &hns->hw;
888 : : uint16_t idx, shift;
889 : : uint16_t i;
890 : : int ret;
891 : :
892 [ # # ]: 0 : if (reta_size != hw->rss_ind_tbl_size) {
893 : 0 : 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 : 0 : return -EINVAL;
897 : : }
898 : 0 : rte_spinlock_lock(&hw->lock);
899 : 0 : ret = hns3_get_rss_indir_table(hw, reta_table, reta_size);
900 [ # # ]: 0 : if (ret != 0) {
901 : : rte_spinlock_unlock(&hw->lock);
902 : 0 : hns3_err(hw, "query RSS redirection table failed, ret = %d.",
903 : : ret);
904 : 0 : return ret;
905 : : }
906 : : rte_spinlock_unlock(&hw->lock);
907 : :
908 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
909 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
910 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
911 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
912 : 0 : reta_conf[idx].reta[shift] = reta_table[i];
913 : : }
914 : :
915 : : return 0;
916 : : }
917 : :
918 : : static void
919 : 0 : 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 : 0 : uint16_t rss_size = hw->alloc_rss_size;
925 : : uint16_t roundup_size;
926 : : uint16_t i;
927 : :
928 [ # # ]: 0 : roundup_size = roundup_pow_of_two(rss_size);
929 : 0 : roundup_size = ilog2(roundup_size);
930 : :
931 [ # # ]: 0 : for (i = 0; i < tc_num; i++) {
932 [ # # ]: 0 : 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 : 0 : tc_valid[i] = (hw->hw_tc_map & BIT(i)) ?
944 : : !!(hw->hw_tc_map & BIT(i)) : 1;
945 : 0 : tc_size[i] = roundup_size;
946 [ # # ]: 0 : tc_offset[i] = (hw->hw_tc_map & BIT(i)) ?
947 : : rss_size * i : 0;
948 : : } else {
949 : 0 : tc_valid[i] = !!(hw->hw_tc_map & BIT(i));
950 [ # # ]: 0 : tc_size[i] = tc_valid[i] ? roundup_size : 0;
951 [ # # ]: 0 : tc_offset[i] = tc_valid[i] ? rss_size * i : 0;
952 : : }
953 : : }
954 : 0 : }
955 : :
956 : : static int
957 : 0 : 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 : 0 : 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 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false);
972 [ # # ]: 0 : for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
973 : : uint16_t mode = 0;
974 : :
975 : 0 : hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
976 : 0 : hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S,
977 : : tc_size[i]);
978 [ # # ]: 0 : if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0)
979 : 0 : hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1);
980 : 0 : hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S,
981 : : tc_offset[i]);
982 : :
983 : 0 : req->rss_tc_mode[i] = rte_cpu_to_le_16(mode);
984 : : }
985 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
986 [ # # ]: 0 : if (ret)
987 : 0 : hns3_err(hw, "Sets rss tc mode failed %d", ret);
988 : :
989 : 0 : return ret;
990 : : }
991 : :
992 : : /*
993 : : * Note: the 'hash_algo' is defined by enum rte_eth_hash_function.
994 : : */
995 : : int
996 : 0 : hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func,
997 : : uint8_t *key, uint8_t key_len)
998 : : {
999 : 0 : uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
1000 : : bool modify_key, modify_algo;
1001 : 0 : uint8_t hash_algo = 0;
1002 : : int ret;
1003 : :
1004 : 0 : modify_key = (key != NULL && key_len > 0);
1005 : : modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT;
1006 [ # # ]: 0 : if (!modify_key && !modify_algo)
1007 : : return 0;
1008 : :
1009 [ # # ]: 0 : if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) {
1010 : 0 : hns3_err(hw, "hash func (%u) is unsupported.", hash_func);
1011 : 0 : return -ENOTSUP;
1012 : : }
1013 [ # # # # ]: 0 : if (modify_key && key_len != hw->rss_key_size) {
1014 : 0 : hns3_err(hw, "hash key length (%u) is invalid.", key_len);
1015 : 0 : return -EINVAL;
1016 : : }
1017 : :
1018 : 0 : ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
1019 [ # # ]: 0 : if (ret != 0) {
1020 : 0 : hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d",
1021 : : ret);
1022 : 0 : return ret;
1023 : : }
1024 : :
1025 [ # # ]: 0 : if (modify_algo)
1026 : 0 : hash_algo = hns3_hash_func_map[hash_func];
1027 [ # # ]: 0 : if (modify_key)
1028 : 0 : memcpy(rss_key, key, key_len);
1029 : :
1030 : 0 : ret = hns3_rss_set_algo_key(hw, hash_algo, rss_key, hw->rss_key_size);
1031 [ # # ]: 0 : if (ret != 0)
1032 : 0 : hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d",
1033 : : ret);
1034 : :
1035 : : return ret;
1036 : : }
1037 : :
1038 : : static void
1039 : 0 : hns3_rss_tuple_uninit(struct hns3_hw *hw)
1040 : : {
1041 : : struct hns3_cmd_desc desc;
1042 : : int ret;
1043 : :
1044 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
1045 : :
1046 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
1047 [ # # ]: 0 : if (ret) {
1048 : 0 : hns3_err(hw, "RSS uninit tuple failed %d", ret);
1049 : 0 : return;
1050 : : }
1051 : : }
1052 : :
1053 : : /*
1054 : : * Set the default rss configuration in the init of driver.
1055 : : */
1056 : : void
1057 : 0 : hns3_rss_set_default_args(struct hns3_hw *hw)
1058 : : {
1059 : : struct hns3_rss_conf *rss_cfg = &hw->rss_info;
1060 : 0 : uint16_t queue_num = hw->alloc_rss_size;
1061 : : uint16_t i;
1062 : :
1063 : : /* Default hash algorithm */
1064 : 0 : rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
1065 : :
1066 : 0 : hw->rss_info.rss_hf = 0;
1067 : 0 : memcpy(rss_cfg->key, hns3_hash_key,
1068 : 0 : RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
1069 : :
1070 : : /* Initialize RSS indirection table */
1071 [ # # ]: 0 : for (i = 0; i < hw->rss_ind_tbl_size; i++)
1072 : 0 : rss_cfg->rss_indirection_tbl[i] = i % queue_num;
1073 : 0 : }
1074 : :
1075 : : /*
1076 : : * RSS initialization for hns3 PMD.
1077 : : */
1078 : : int
1079 : 0 : hns3_config_rss(struct hns3_adapter *hns)
1080 : : {
1081 : 0 : struct hns3_hw *hw = &hns->hw;
1082 : : struct hns3_rss_conf *rss_cfg = &hw->rss_info;
1083 : 0 : uint8_t *hash_key = rss_cfg->key;
1084 : : uint64_t rss_hf;
1085 : : int ret;
1086 : :
1087 : 0 : enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
1088 : :
1089 : 0 : ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo,
1090 : 0 : hash_key, hw->rss_key_size);
1091 [ # # ]: 0 : if (ret)
1092 : : return ret;
1093 : :
1094 : 0 : ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
1095 : 0 : hw->rss_ind_tbl_size);
1096 [ # # ]: 0 : if (ret)
1097 : : return ret;
1098 : :
1099 : 0 : ret = hns3_set_rss_tc_mode(hw);
1100 [ # # ]: 0 : 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 : 0 : rss_hf = hw->rss_info.rss_hf;
1108 [ # # ]: 0 : if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) ||
1109 [ # # ]: 0 : !(rss_hf & HNS3_ETH_RSS_SUPPORT))
1110 : : rss_hf = 0;
1111 : :
1112 : 0 : ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
1113 [ # # ]: 0 : if (ret != 0) {
1114 : 0 : hns3_err(hw, "set RSS tuples failed, ret = %d.", ret);
1115 : 0 : return ret;
1116 : : }
1117 : 0 : hw->rss_info.rss_hf = rss_hf;
1118 : :
1119 : 0 : return 0;
1120 : : }
1121 : :
1122 : : /*
1123 : : * RSS uninitialization for hns3 PMD.
1124 : : */
1125 : : void
1126 : 0 : hns3_rss_uninit(struct hns3_adapter *hns)
1127 : : {
1128 : 0 : struct hns3_hw *hw = &hns->hw;
1129 : : int ret;
1130 : :
1131 : 0 : hns3_rss_tuple_uninit(hw);
1132 : 0 : ret = hns3_rss_reset_indir_table(hw);
1133 [ # # ]: 0 : if (ret != 0)
1134 : : return;
1135 : :
1136 : : /* Disable RSS */
1137 : 0 : hw->rss_info.rss_hf = 0;
1138 : : }
|