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