xref: /dpdk/drivers/net/hns3/hns3_rss.c (revision 665b49c51639a10c553433bc2bcd85c7331c631e)
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 enum hns3_tuple_field {
22 	/* IPV4_TCP ENABLE FIELD */
23 	HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0,
24 	HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S,
25 	HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D,
26 	HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S,
27 
28 	/* IPV4_UDP ENABLE FIELD */
29 	HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8,
30 	HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S,
31 	HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D,
32 	HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S,
33 
34 	/* IPV4_SCTP ENABLE FIELD */
35 	HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16,
36 	HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S,
37 	HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D,
38 	HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S,
39 	HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER,
40 
41 	/* IPV4 ENABLE FIELD */
42 	HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24,
43 	HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S,
44 	HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D,
45 	HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S,
46 
47 	/* IPV6_TCP ENABLE FIELD */
48 	HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32,
49 	HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S,
50 	HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D,
51 	HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S,
52 
53 	/* IPV6_UDP ENABLE FIELD */
54 	HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40,
55 	HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S,
56 	HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D,
57 	HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S,
58 
59 	/* IPV6_SCTP ENABLE FIELD */
60 	HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48,
61 	HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S,
62 	HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D,
63 	HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S,
64 	HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER,
65 
66 	/* IPV6 ENABLE FIELD */
67 	HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56,
68 	HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S,
69 	HNS3_RSS_FIELD_IPV6_FRAG_IP_D,
70 	HNS3_RSS_FIELD_IPV6_FRAG_IP_S
71 };
72 
73 enum hns3_rss_tuple_type {
74 	HNS3_RSS_IP_TUPLE,
75 	HNS3_RSS_IP_L4_TUPLE,
76 };
77 
78 static const struct {
79 	uint64_t rss_types;
80 	uint16_t tuple_type;
81 	uint64_t rss_field;
82 } hns3_set_tuple_table[] = {
83 	/* IPV4-FRAG */
84 	{ RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
85 	  HNS3_RSS_IP_TUPLE,
86 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) },
87 	{ RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
88 	  HNS3_RSS_IP_TUPLE,
89 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) },
90 	{ RTE_ETH_RSS_FRAG_IPV4,
91 	  HNS3_RSS_IP_TUPLE,
92 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) |
93 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) },
94 
95 	/* IPV4 */
96 	{ RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
97 	  HNS3_RSS_IP_TUPLE,
98 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) },
99 	{ RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
100 	  HNS3_RSS_IP_TUPLE,
101 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
102 	{ RTE_ETH_RSS_IPV4,
103 	  HNS3_RSS_IP_TUPLE,
104 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
105 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
106 
107 	/* IPV4-OTHER */
108 	{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
109 	  HNS3_RSS_IP_TUPLE,
110 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) },
111 	{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
112 	  HNS3_RSS_IP_TUPLE,
113 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
114 	{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
115 	  HNS3_RSS_IP_TUPLE,
116 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
117 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
118 
119 	/* IPV4-TCP */
120 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
121 	  HNS3_RSS_IP_L4_TUPLE,
122 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) },
123 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY,
124 	  HNS3_RSS_IP_L4_TUPLE,
125 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) },
126 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
127 	  HNS3_RSS_IP_L4_TUPLE,
128 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) },
129 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY,
130 	  HNS3_RSS_IP_L4_TUPLE,
131 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
132 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP,
133 	  HNS3_RSS_IP_L4_TUPLE,
134 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) |
135 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) |
136 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) |
137 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
138 
139 	/* IPV4-UDP */
140 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
141 	  HNS3_RSS_IP_L4_TUPLE,
142 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) },
143 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY,
144 	  HNS3_RSS_IP_L4_TUPLE,
145 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) },
146 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
147 	  HNS3_RSS_IP_L4_TUPLE,
148 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) },
149 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY,
150 	  HNS3_RSS_IP_L4_TUPLE,
151 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) },
152 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP,
153 	  HNS3_RSS_IP_L4_TUPLE,
154 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) |
155 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) |
156 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) |
157 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) },
158 
159 	/* IPV4-SCTP */
160 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
161 	  HNS3_RSS_IP_L4_TUPLE,
162 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) },
163 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
164 	  HNS3_RSS_IP_L4_TUPLE,
165 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) },
166 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
167 	  HNS3_RSS_IP_L4_TUPLE,
168 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) },
169 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
170 	  HNS3_RSS_IP_L4_TUPLE,
171 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) },
172 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
173 	  HNS3_RSS_IP_L4_TUPLE,
174 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) |
175 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) |
176 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) |
177 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) |
178 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) },
179 
180 	/* IPV6-FRAG */
181 	{ RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
182 	  HNS3_RSS_IP_TUPLE,
183 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) },
184 	{ RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
185 	  HNS3_RSS_IP_TUPLE,
186 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) },
187 	{ RTE_ETH_RSS_FRAG_IPV6,
188 	  HNS3_RSS_IP_TUPLE,
189 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) |
190 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) },
191 
192 	/* IPV6 */
193 	{ RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
194 	  HNS3_RSS_IP_TUPLE,
195 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) },
196 	{ RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
197 	  HNS3_RSS_IP_TUPLE,
198 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
199 	{ RTE_ETH_RSS_IPV6,
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 
204 	/* IPV6-OTHER */
205 	{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
206 	  HNS3_RSS_IP_TUPLE,
207 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) },
208 	{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
209 	  HNS3_RSS_IP_TUPLE,
210 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
211 	{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
212 	  HNS3_RSS_IP_TUPLE,
213 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
214 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
215 
216 	/* IPV6-TCP */
217 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
218 	  HNS3_RSS_IP_L4_TUPLE,
219 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) },
220 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY,
221 	  HNS3_RSS_IP_L4_TUPLE,
222 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) },
223 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
224 	  HNS3_RSS_IP_L4_TUPLE,
225 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) },
226 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY,
227 	  HNS3_RSS_IP_L4_TUPLE,
228 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) },
229 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP,
230 	  HNS3_RSS_IP_L4_TUPLE,
231 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) |
232 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) |
233 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) |
234 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) },
235 
236 	/* IPV6-UDP */
237 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
238 	  HNS3_RSS_IP_L4_TUPLE,
239 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) },
240 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY,
241 	  HNS3_RSS_IP_L4_TUPLE,
242 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) },
243 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
244 	  HNS3_RSS_IP_L4_TUPLE,
245 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) },
246 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY,
247 	  HNS3_RSS_IP_L4_TUPLE,
248 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) },
249 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP,
250 	  HNS3_RSS_IP_L4_TUPLE,
251 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) |
252 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) |
253 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) |
254 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) },
255 
256 	/* IPV6-SCTP */
257 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
258 	  HNS3_RSS_IP_L4_TUPLE,
259 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) },
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 	{ 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 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
267 	  HNS3_RSS_IP_L4_TUPLE,
268 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) },
269 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
270 	  HNS3_RSS_IP_L4_TUPLE,
271 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) |
272 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) |
273 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
274 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) |
275 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) },
276 };
277 
278 /*
279  * rss_generic_config command function, opcode:0x0D01.
280  * Used to set algorithm and hash key of RSS.
281  */
282 int
283 hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
284 		      const uint8_t *key, uint8_t key_len)
285 {
286 	struct hns3_rss_generic_config_cmd *req;
287 	struct hns3_cmd_desc desc;
288 	const uint8_t *cur_key;
289 	uint16_t cur_key_size;
290 	uint16_t max_bd_num;
291 	uint16_t idx;
292 	int ret;
293 
294 	req = (struct hns3_rss_generic_config_cmd *)desc.data;
295 
296 	max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
297 	for (idx = 0; idx < max_bd_num; idx++) {
298 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
299 					  false);
300 
301 		req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK);
302 		req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
303 
304 		if (idx == max_bd_num - 1)
305 			cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
306 		else
307 			cur_key_size = HNS3_RSS_HASH_KEY_NUM;
308 
309 		cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
310 		memcpy(req->hash_key, cur_key, cur_key_size);
311 
312 		ret = hns3_cmd_send(hw, &desc, 1);
313 		if (ret) {
314 			hns3_err(hw, "Configure RSS algo key failed %d", ret);
315 			return ret;
316 		}
317 	}
318 	/* Update the shadow RSS key with user specified */
319 	memcpy(hw->rss_info.key, key, hw->rss_key_size);
320 	return 0;
321 }
322 
323 /*
324  * rss_indirection_table command function, opcode:0x0D07.
325  * Used to configure the indirection table of rss.
326  */
327 int
328 hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
329 {
330 	struct hns3_rss_indirection_table_cmd *req;
331 	struct hns3_cmd_desc desc;
332 	uint8_t qid_msb_off;
333 	uint8_t qid_msb_val;
334 	uint16_t q_id;
335 	uint16_t i, j;
336 	int ret;
337 
338 	req = (struct hns3_rss_indirection_table_cmd *)desc.data;
339 
340 	for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) {
341 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
342 					  false);
343 		req->start_table_index =
344 				rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
345 		req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK);
346 		for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) {
347 			q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j];
348 			req->rss_result_l[j] = q_id & 0xff;
349 
350 			qid_msb_off =
351 				j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
352 			qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1)
353 					<< (j * HNS3_RSS_CFG_TBL_BW_H %
354 					HNS3_BITS_PER_BYTE);
355 			req->rss_result_h[qid_msb_off] |= qid_msb_val;
356 		}
357 
358 		ret = hns3_cmd_send(hw, &desc, 1);
359 		if (ret) {
360 			hns3_err(hw,
361 				 "Sets RSS indirection table failed %d size %u",
362 				 ret, size);
363 			return ret;
364 		}
365 	}
366 
367 	/* Update redirection table of hw */
368 	memcpy(hw->rss_info.rss_indirection_tbl, indir,
369 	       sizeof(uint16_t) * size);
370 
371 	return 0;
372 }
373 
374 int
375 hns3_rss_reset_indir_table(struct hns3_hw *hw)
376 {
377 	uint16_t *lut;
378 	int ret;
379 
380 	lut = rte_zmalloc("hns3_rss_lut",
381 			  hw->rss_ind_tbl_size * sizeof(uint16_t), 0);
382 	if (lut == NULL) {
383 		hns3_err(hw, "No hns3_rss_lut memory can be allocated");
384 		return -ENOMEM;
385 	}
386 
387 	ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size);
388 	if (ret)
389 		hns3_err(hw, "RSS uninit indir table failed: %d", ret);
390 	rte_free(lut);
391 
392 	return ret;
393 }
394 
395 static void
396 hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf)
397 {
398 	uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
399 			   RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
400 			   RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
401 			   RTE_ETH_RSS_NONFRAG_IPV6_OTHER;
402 	uint64_t l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP |
403 			   RTE_ETH_RSS_NONFRAG_IPV4_UDP |
404 			   RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
405 			   RTE_ETH_RSS_NONFRAG_IPV6_TCP |
406 			   RTE_ETH_RSS_NONFRAG_IPV6_UDP |
407 			   RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
408 	uint64_t l3_src_dst_mask = RTE_ETH_RSS_L3_SRC_ONLY |
409 				   RTE_ETH_RSS_L3_DST_ONLY;
410 	uint64_t l4_src_dst_mask = RTE_ETH_RSS_L4_SRC_ONLY |
411 				   RTE_ETH_RSS_L4_DST_ONLY;
412 
413 	if (rss_hf & l3_src_dst_mask &&
414 	    !(rss_hf & ip_mask || rss_hf & l4_mask))
415 		hns3_warn(hw, "packet type isn't specified, L3_SRC/DST_ONLY is ignored.");
416 
417 	if (rss_hf & l4_src_dst_mask && !(rss_hf & l4_mask))
418 		hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored.");
419 }
420 
421 static uint64_t
422 hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
423 {
424 	uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY |
425 				RTE_ETH_RSS_L3_DST_ONLY;
426 	uint64_t l4_only_mask = RTE_ETH_RSS_L4_SRC_ONLY |
427 				RTE_ETH_RSS_L4_DST_ONLY;
428 	uint64_t l3_l4_only_mask = l3_only_mask | l4_only_mask;
429 	bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask);
430 	bool has_l3_only = !!(rss_hf & l3_only_mask);
431 	uint64_t tuple = 0;
432 	uint32_t i;
433 
434 	for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
435 		if ((rss_hf & hns3_set_tuple_table[i].rss_types) !=
436 		    hns3_set_tuple_table[i].rss_types)
437 			continue;
438 
439 		if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) {
440 			if (hns3_set_tuple_table[i].rss_types & l3_only_mask ||
441 			    !has_l3_only)
442 				tuple |= hns3_set_tuple_table[i].rss_field;
443 			continue;
444 		}
445 
446 		/* For IP types with L4, we need check both L3 and L4 */
447 		if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask ||
448 		    !has_l3_l4_only)
449 			tuple |= hns3_set_tuple_table[i].rss_field;
450 	}
451 	hns3_rss_check_l3l4_types(hw, rss_hf);
452 
453 	return tuple;
454 }
455 
456 int
457 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
458 {
459 	struct hns3_rss_input_tuple_cmd *req;
460 	struct hns3_cmd_desc desc;
461 	uint64_t tuple_field;
462 	int ret;
463 
464 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
465 	req = (struct hns3_rss_input_tuple_cmd *)desc.data;
466 
467 	tuple_field = hns3_rss_calc_tuple_filed(hw, rss_hf);
468 	req->tuple_field = rte_cpu_to_le_64(tuple_field);
469 	ret = hns3_cmd_send(hw, &desc, 1);
470 	if (ret) {
471 		hns3_err(hw, "Update RSS flow types tuples failed %d", ret);
472 		return ret;
473 	}
474 
475 	/* Update supported flow types when set tuple success */
476 	hw->rss_info.conf.types = rss_hf;
477 
478 	return 0;
479 }
480 
481 /*
482  * Configure RSS hash protocols and hash key.
483  * @param dev
484  *   Pointer to Ethernet device.
485  * @praram rss_conf
486  *   The configuration select of  rss key size and tuple flow_types.
487  * @return
488  *   0 on success, a negative errno value otherwise is set.
489  */
490 int
491 hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
492 			 struct rte_eth_rss_conf *rss_conf)
493 {
494 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
495 	uint64_t rss_hf_bk = hw->rss_info.conf.types;
496 	uint8_t key_len = rss_conf->rss_key_len;
497 	uint64_t rss_hf = rss_conf->rss_hf;
498 	uint8_t *key = rss_conf->rss_key;
499 	int ret;
500 
501 	if (key && key_len != hw->rss_key_size) {
502 		hns3_err(hw, "the hash key len(%u) is invalid, must be %u",
503 			 key_len, hw->rss_key_size);
504 		return -EINVAL;
505 	}
506 
507 	rte_spinlock_lock(&hw->lock);
508 	ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
509 	if (ret)
510 		goto set_tuple_fail;
511 
512 	if (key) {
513 		ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo,
514 					    key, hw->rss_key_size);
515 		if (ret)
516 			goto set_algo_key_fail;
517 	}
518 	rte_spinlock_unlock(&hw->lock);
519 
520 	return 0;
521 
522 set_algo_key_fail:
523 	(void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk);
524 set_tuple_fail:
525 	rte_spinlock_unlock(&hw->lock);
526 	return ret;
527 }
528 
529 /*
530  * Get rss key and rss_hf types set of RSS hash configuration.
531  * @param dev
532  *   Pointer to Ethernet device.
533  * @praram rss_conf
534  *   The buffer to get rss key size and tuple types.
535  * @return
536  *   0 on success.
537  */
538 int
539 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
540 			   struct rte_eth_rss_conf *rss_conf)
541 {
542 	struct hns3_adapter *hns = dev->data->dev_private;
543 	struct hns3_hw *hw = &hns->hw;
544 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
545 
546 	rte_spinlock_lock(&hw->lock);
547 	rss_conf->rss_hf = rss_cfg->conf.types;
548 
549 	/* Get the RSS Key required by the user */
550 	if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
551 		memcpy(rss_conf->rss_key, rss_cfg->key, hw->rss_key_size);
552 		rss_conf->rss_key_len = hw->rss_key_size;
553 	}
554 	rte_spinlock_unlock(&hw->lock);
555 
556 	return 0;
557 }
558 
559 /*
560  * Update rss redirection table of RSS.
561  * @param dev
562  *   Pointer to Ethernet device.
563  * @praram reta_conf
564  *   Pointer to the configuration select of mask and redirection tables.
565  * @param reta_size
566  *   Redirection table size.
567  * @return
568  *   0 on success, a negative errno value otherwise is set.
569  */
570 int
571 hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
572 			 struct rte_eth_rss_reta_entry64 *reta_conf,
573 			 uint16_t reta_size)
574 {
575 	struct hns3_adapter *hns = dev->data->dev_private;
576 	struct hns3_hw *hw = &hns->hw;
577 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
578 	uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
579 	uint16_t idx, shift;
580 	uint16_t i;
581 	int ret;
582 
583 	if (reta_size != hw->rss_ind_tbl_size) {
584 		hns3_err(hw, "The size of hash lookup table configured (%u)"
585 			 "doesn't match the number hardware can supported"
586 			 "(%u)", reta_size, hw->rss_ind_tbl_size);
587 		return -EINVAL;
588 	}
589 	rte_spinlock_lock(&hw->lock);
590 	memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
591 	       sizeof(rss_cfg->rss_indirection_tbl));
592 	for (i = 0; i < reta_size; i++) {
593 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
594 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
595 		if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) {
596 			rte_spinlock_unlock(&hw->lock);
597 			hns3_err(hw, "queue id(%u) set to redirection table "
598 				 "exceeds queue number(%u) allocated to a TC",
599 				 reta_conf[idx].reta[shift],
600 				 hw->alloc_rss_size);
601 			return -EINVAL;
602 		}
603 
604 		if (reta_conf[idx].mask & (1ULL << shift))
605 			indirection_tbl[i] = reta_conf[idx].reta[shift];
606 	}
607 
608 	ret = hns3_set_rss_indir_table(hw, indirection_tbl,
609 				       hw->rss_ind_tbl_size);
610 
611 	rte_spinlock_unlock(&hw->lock);
612 	return ret;
613 }
614 
615 /*
616  * Get rss redirection table of RSS hash configuration.
617  * @param dev
618  *   Pointer to Ethernet device.
619  * @praram reta_conf
620  *   Pointer to the configuration select of mask and redirection tables.
621  * @param reta_size
622  *   Redirection table size.
623  * @return
624  *   0 on success, a negative errno value otherwise is set.
625  */
626 int
627 hns3_dev_rss_reta_query(struct rte_eth_dev *dev,
628 			struct rte_eth_rss_reta_entry64 *reta_conf,
629 			uint16_t reta_size)
630 {
631 	struct hns3_adapter *hns = dev->data->dev_private;
632 	struct hns3_hw *hw = &hns->hw;
633 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
634 	uint16_t idx, shift;
635 	uint16_t i;
636 
637 	if (reta_size != hw->rss_ind_tbl_size) {
638 		hns3_err(hw, "The size of hash lookup table configured (%u)"
639 			 " doesn't match the number hardware can supported"
640 			 "(%u)", reta_size, hw->rss_ind_tbl_size);
641 		return -EINVAL;
642 	}
643 	rte_spinlock_lock(&hw->lock);
644 	for (i = 0; i < reta_size; i++) {
645 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
646 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
647 		if (reta_conf[idx].mask & (1ULL << shift))
648 			reta_conf[idx].reta[shift] =
649 						rss_cfg->rss_indirection_tbl[i];
650 	}
651 	rte_spinlock_unlock(&hw->lock);
652 	return 0;
653 }
654 
655 static void
656 hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid,
657 			   uint16_t *tc_size, uint16_t *tc_offset,
658 			   uint8_t tc_num)
659 {
660 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
661 	uint16_t rss_size = hw->alloc_rss_size;
662 	uint16_t roundup_size;
663 	uint16_t i;
664 
665 	roundup_size = roundup_pow_of_two(rss_size);
666 	roundup_size = ilog2(roundup_size);
667 
668 	for (i = 0; i < tc_num; i++) {
669 		if (hns->is_vf) {
670 			/*
671 			 * For packets with VLAN priorities destined for the VF,
672 			 * hardware still assign Rx queue based on the Up-to-TC
673 			 * mapping PF configured. But VF has only one TC. If
674 			 * other TC don't enable, it causes that the priority
675 			 * packets that aren't destined for TC0 aren't received
676 			 * by RSS hash but is destined for queue 0. So driver
677 			 * has to enable the unused TC by using TC0 queue
678 			 * mapping configuration.
679 			 */
680 			tc_valid[i] = (hw->hw_tc_map & BIT(i)) ?
681 					!!(hw->hw_tc_map & BIT(i)) : 1;
682 			tc_size[i] = roundup_size;
683 			tc_offset[i] = (hw->hw_tc_map & BIT(i)) ?
684 					rss_size * i : 0;
685 		} else {
686 			tc_valid[i] = !!(hw->hw_tc_map & BIT(i));
687 			tc_size[i] = tc_valid[i] ? roundup_size : 0;
688 			tc_offset[i] = tc_valid[i] ? rss_size * i : 0;
689 		}
690 	}
691 }
692 
693 static int
694 hns3_set_rss_tc_mode(struct hns3_hw *hw)
695 {
696 	struct hns3_rss_tc_mode_cmd *req;
697 	uint16_t tc_offset[HNS3_MAX_TC_NUM];
698 	uint8_t tc_valid[HNS3_MAX_TC_NUM];
699 	uint16_t tc_size[HNS3_MAX_TC_NUM];
700 	struct hns3_cmd_desc desc;
701 	uint16_t i;
702 	int ret;
703 
704 	hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size,
705 				   tc_offset, HNS3_MAX_TC_NUM);
706 
707 	req = (struct hns3_rss_tc_mode_cmd *)desc.data;
708 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false);
709 	for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
710 		uint16_t mode = 0;
711 
712 		hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
713 		hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S,
714 			       tc_size[i]);
715 		if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0)
716 			hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1);
717 		hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S,
718 			       tc_offset[i]);
719 
720 		req->rss_tc_mode[i] = rte_cpu_to_le_16(mode);
721 	}
722 	ret = hns3_cmd_send(hw, &desc, 1);
723 	if (ret)
724 		hns3_err(hw, "Sets rss tc mode failed %d", ret);
725 
726 	return ret;
727 }
728 
729 static void
730 hns3_rss_tuple_uninit(struct hns3_hw *hw)
731 {
732 	struct hns3_cmd_desc desc;
733 	int ret;
734 
735 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
736 
737 	ret = hns3_cmd_send(hw, &desc, 1);
738 	if (ret) {
739 		hns3_err(hw, "RSS uninit tuple failed %d", ret);
740 		return;
741 	}
742 }
743 
744 /*
745  * Set the default rss configuration in the init of driver.
746  */
747 void
748 hns3_rss_set_default_args(struct hns3_hw *hw)
749 {
750 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
751 	uint16_t queue_num = hw->alloc_rss_size;
752 	uint16_t i;
753 
754 	/* Default hash algorithm */
755 	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
756 
757 	memcpy(rss_cfg->key, hns3_hash_key,
758 		RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
759 
760 	/* Initialize RSS indirection table */
761 	for (i = 0; i < hw->rss_ind_tbl_size; i++)
762 		rss_cfg->rss_indirection_tbl[i] = i % queue_num;
763 }
764 
765 /*
766  * RSS initialization for hns3 PMD.
767  */
768 int
769 hns3_config_rss(struct hns3_adapter *hns)
770 {
771 	struct hns3_hw *hw = &hns->hw;
772 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
773 	uint8_t *hash_key = rss_cfg->key;
774 	uint64_t rss_hf;
775 	int ret;
776 
777 	enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
778 
779 	switch (hw->rss_info.conf.func) {
780 	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
781 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
782 		break;
783 	case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
784 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
785 		break;
786 	default:
787 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
788 		break;
789 	}
790 
791 	ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo,
792 				    hash_key, hw->rss_key_size);
793 	if (ret)
794 		return ret;
795 
796 	ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
797 				       hw->rss_ind_tbl_size);
798 	if (ret)
799 		return ret;
800 
801 	ret = hns3_set_rss_tc_mode(hw);
802 	if (ret)
803 		return ret;
804 
805 	/*
806 	 * When muli-queue RSS mode flag is not set or unsupported tuples are
807 	 * set, disable all tuples.
808 	 */
809 	rss_hf = hw->rss_info.conf.types;
810 	if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) ||
811 	    !(rss_hf & HNS3_ETH_RSS_SUPPORT))
812 		rss_hf = 0;
813 
814 	return hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
815 }
816 
817 /*
818  * RSS uninitialization for hns3 PMD.
819  */
820 void
821 hns3_rss_uninit(struct hns3_adapter *hns)
822 {
823 	struct hns3_hw *hw = &hns->hw;
824 	int ret;
825 
826 	hns3_rss_tuple_uninit(hw);
827 	ret = hns3_rss_reset_indir_table(hw);
828 	if (ret != 0)
829 		return;
830 
831 	/* Disable RSS */
832 	hw->rss_info.conf.types = 0;
833 }
834