xref: /dpdk/drivers/net/hns3/hns3_rss.c (revision 02d36ef6a9528e0f4a3403956e66bcea5fadbf8c)
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, key_offset and hash key of rss.
281  */
282 int
283 hns3_rss_set_algo_key(struct hns3_hw *hw, const uint8_t *key)
284 {
285 #define HNS3_KEY_OFFSET_MAX	3
286 #define HNS3_SET_HASH_KEY_BYTE_FOUR	2
287 
288 	struct hns3_rss_generic_config_cmd *req;
289 	struct hns3_cmd_desc desc;
290 	uint32_t key_offset, key_size;
291 	const uint8_t *key_cur;
292 	uint8_t cur_offset;
293 	int ret;
294 
295 	req = (struct hns3_rss_generic_config_cmd *)desc.data;
296 
297 	/*
298 	 * key_offset=0, hash key byte0~15 is set to hardware.
299 	 * key_offset=1, hash key byte16~31 is set to hardware.
300 	 * key_offset=2, hash key byte32~39 is set to hardware.
301 	 */
302 	for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) {
303 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
304 					  false);
305 
306 		req->hash_config |=
307 			(hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK);
308 		req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B);
309 
310 		if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR)
311 			key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM *
312 			HNS3_SET_HASH_KEY_BYTE_FOUR;
313 		else
314 			key_size = HNS3_RSS_HASH_KEY_NUM;
315 
316 		cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM;
317 		key_cur = key + cur_offset;
318 		memcpy(req->hash_key, key_cur, key_size);
319 
320 		ret = hns3_cmd_send(hw, &desc, 1);
321 		if (ret) {
322 			hns3_err(hw, "Configure RSS algo key failed %d", ret);
323 			return ret;
324 		}
325 	}
326 	/* Update the shadow RSS key with user specified */
327 	memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE);
328 	return 0;
329 }
330 
331 /*
332  * rss_indirection_table command function, opcode:0x0D07.
333  * Used to configure the indirection table of rss.
334  */
335 int
336 hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
337 {
338 	struct hns3_rss_indirection_table_cmd *req;
339 	struct hns3_cmd_desc desc;
340 	uint8_t qid_msb_off;
341 	uint8_t qid_msb_val;
342 	uint16_t q_id;
343 	uint16_t i, j;
344 	int ret;
345 
346 	req = (struct hns3_rss_indirection_table_cmd *)desc.data;
347 
348 	for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) {
349 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
350 					  false);
351 		req->start_table_index =
352 				rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
353 		req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK);
354 		for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) {
355 			q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j];
356 			req->rss_result_l[j] = q_id & 0xff;
357 
358 			qid_msb_off =
359 				j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
360 			qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1)
361 					<< (j * HNS3_RSS_CFG_TBL_BW_H %
362 					HNS3_BITS_PER_BYTE);
363 			req->rss_result_h[qid_msb_off] |= qid_msb_val;
364 		}
365 
366 		ret = hns3_cmd_send(hw, &desc, 1);
367 		if (ret) {
368 			hns3_err(hw,
369 				 "Sets RSS indirection table failed %d size %u",
370 				 ret, size);
371 			return ret;
372 		}
373 	}
374 
375 	/* Update redirection table of hw */
376 	memcpy(hw->rss_info.rss_indirection_tbl, indir,
377 	       sizeof(uint16_t) * size);
378 
379 	return 0;
380 }
381 
382 int
383 hns3_rss_reset_indir_table(struct hns3_hw *hw)
384 {
385 	uint16_t *lut;
386 	int ret;
387 
388 	lut = rte_zmalloc("hns3_rss_lut",
389 			  hw->rss_ind_tbl_size * sizeof(uint16_t), 0);
390 	if (lut == NULL) {
391 		hns3_err(hw, "No hns3_rss_lut memory can be allocated");
392 		return -ENOMEM;
393 	}
394 
395 	ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size);
396 	if (ret)
397 		hns3_err(hw, "RSS uninit indir table failed: %d", ret);
398 	rte_free(lut);
399 
400 	return ret;
401 }
402 
403 static void
404 hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf)
405 {
406 	uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
407 			   RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
408 			   RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
409 			   RTE_ETH_RSS_NONFRAG_IPV6_OTHER;
410 	uint64_t l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP |
411 			   RTE_ETH_RSS_NONFRAG_IPV4_UDP |
412 			   RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
413 			   RTE_ETH_RSS_NONFRAG_IPV6_TCP |
414 			   RTE_ETH_RSS_NONFRAG_IPV6_UDP |
415 			   RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
416 	uint64_t l3_src_dst_mask = RTE_ETH_RSS_L3_SRC_ONLY |
417 				   RTE_ETH_RSS_L3_DST_ONLY;
418 	uint64_t l4_src_dst_mask = RTE_ETH_RSS_L4_SRC_ONLY |
419 				   RTE_ETH_RSS_L4_DST_ONLY;
420 
421 	if (rss_hf & l3_src_dst_mask &&
422 	    !(rss_hf & ip_mask || rss_hf & l4_mask))
423 		hns3_warn(hw, "packet type isn't specified, L3_SRC/DST_ONLY is ignored.");
424 
425 	if (rss_hf & l4_src_dst_mask && !(rss_hf & l4_mask))
426 		hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored.");
427 }
428 
429 static uint64_t
430 hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
431 {
432 	uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY |
433 				RTE_ETH_RSS_L3_DST_ONLY;
434 	uint64_t l4_only_mask = RTE_ETH_RSS_L4_SRC_ONLY |
435 				RTE_ETH_RSS_L4_DST_ONLY;
436 	uint64_t l3_l4_only_mask = l3_only_mask | l4_only_mask;
437 	bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask);
438 	bool has_l3_only = !!(rss_hf & l3_only_mask);
439 	uint64_t tuple = 0;
440 	uint32_t i;
441 
442 	for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
443 		if ((rss_hf & hns3_set_tuple_table[i].rss_types) !=
444 		    hns3_set_tuple_table[i].rss_types)
445 			continue;
446 
447 		if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) {
448 			if (hns3_set_tuple_table[i].rss_types & l3_only_mask ||
449 			    !has_l3_only)
450 				tuple |= hns3_set_tuple_table[i].rss_field;
451 			continue;
452 		}
453 
454 		/* For IP types with L4, we need check both L3 and L4 */
455 		if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask ||
456 		    !has_l3_l4_only)
457 			tuple |= hns3_set_tuple_table[i].rss_field;
458 	}
459 	hns3_rss_check_l3l4_types(hw, rss_hf);
460 
461 	return tuple;
462 }
463 
464 int
465 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
466 {
467 	struct hns3_rss_input_tuple_cmd *req;
468 	struct hns3_cmd_desc desc;
469 	uint64_t tuple_field;
470 	int ret;
471 
472 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
473 	req = (struct hns3_rss_input_tuple_cmd *)desc.data;
474 
475 	tuple_field = hns3_rss_calc_tuple_filed(hw, rss_hf);
476 	req->tuple_field = rte_cpu_to_le_64(tuple_field);
477 	ret = hns3_cmd_send(hw, &desc, 1);
478 	if (ret) {
479 		hns3_err(hw, "Update RSS flow types tuples failed %d", ret);
480 		return ret;
481 	}
482 
483 	/* Update supported flow types when set tuple success */
484 	hw->rss_info.conf.types = rss_hf;
485 
486 	return 0;
487 }
488 
489 /*
490  * Configure RSS hash protocols and hash key.
491  * @param dev
492  *   Pointer to Ethernet device.
493  * @praram rss_conf
494  *   The configuration select of  rss key size and tuple flow_types.
495  * @return
496  *   0 on success, a negative errno value otherwise is set.
497  */
498 int
499 hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
500 			 struct rte_eth_rss_conf *rss_conf)
501 {
502 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
503 	uint64_t rss_hf_bk = hw->rss_info.conf.types;
504 	uint8_t key_len = rss_conf->rss_key_len;
505 	uint64_t rss_hf = rss_conf->rss_hf;
506 	uint8_t *key = rss_conf->rss_key;
507 	int ret;
508 
509 	if (key && key_len != HNS3_RSS_KEY_SIZE) {
510 		hns3_err(hw, "the hash key len(%u) is invalid, must be %u",
511 			 key_len, HNS3_RSS_KEY_SIZE);
512 		return -EINVAL;
513 	}
514 
515 	rte_spinlock_lock(&hw->lock);
516 	ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
517 	if (ret)
518 		goto set_tuple_fail;
519 
520 	if (key) {
521 		ret = hns3_rss_set_algo_key(hw, key);
522 		if (ret)
523 			goto set_algo_key_fail;
524 	}
525 	rte_spinlock_unlock(&hw->lock);
526 
527 	return 0;
528 
529 set_algo_key_fail:
530 	(void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk);
531 set_tuple_fail:
532 	rte_spinlock_unlock(&hw->lock);
533 	return ret;
534 }
535 
536 /*
537  * Get rss key and rss_hf types set of RSS hash configuration.
538  * @param dev
539  *   Pointer to Ethernet device.
540  * @praram rss_conf
541  *   The buffer to get rss key size and tuple types.
542  * @return
543  *   0 on success.
544  */
545 int
546 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
547 			   struct rte_eth_rss_conf *rss_conf)
548 {
549 	struct hns3_adapter *hns = dev->data->dev_private;
550 	struct hns3_hw *hw = &hns->hw;
551 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
552 
553 	rte_spinlock_lock(&hw->lock);
554 	rss_conf->rss_hf = rss_cfg->conf.types;
555 
556 	/* Get the RSS Key required by the user */
557 	if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) {
558 		memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE);
559 		rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE;
560 	}
561 	rte_spinlock_unlock(&hw->lock);
562 
563 	return 0;
564 }
565 
566 /*
567  * Update rss redirection table of RSS.
568  * @param dev
569  *   Pointer to Ethernet device.
570  * @praram reta_conf
571  *   Pointer to the configuration select of mask and redirection tables.
572  * @param reta_size
573  *   Redirection table size.
574  * @return
575  *   0 on success, a negative errno value otherwise is set.
576  */
577 int
578 hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
579 			 struct rte_eth_rss_reta_entry64 *reta_conf,
580 			 uint16_t reta_size)
581 {
582 	struct hns3_adapter *hns = dev->data->dev_private;
583 	struct hns3_hw *hw = &hns->hw;
584 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
585 	uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
586 	uint16_t idx, shift;
587 	uint16_t i;
588 	int ret;
589 
590 	if (reta_size != hw->rss_ind_tbl_size) {
591 		hns3_err(hw, "The size of hash lookup table configured (%u)"
592 			 "doesn't match the number hardware can supported"
593 			 "(%u)", reta_size, hw->rss_ind_tbl_size);
594 		return -EINVAL;
595 	}
596 	rte_spinlock_lock(&hw->lock);
597 	memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
598 	       sizeof(rss_cfg->rss_indirection_tbl));
599 	for (i = 0; i < reta_size; i++) {
600 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
601 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
602 		if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) {
603 			rte_spinlock_unlock(&hw->lock);
604 			hns3_err(hw, "queue id(%u) set to redirection table "
605 				 "exceeds queue number(%u) allocated to a TC",
606 				 reta_conf[idx].reta[shift],
607 				 hw->alloc_rss_size);
608 			return -EINVAL;
609 		}
610 
611 		if (reta_conf[idx].mask & (1ULL << shift))
612 			indirection_tbl[i] = reta_conf[idx].reta[shift];
613 	}
614 
615 	ret = hns3_set_rss_indir_table(hw, indirection_tbl,
616 				       hw->rss_ind_tbl_size);
617 
618 	rte_spinlock_unlock(&hw->lock);
619 	return ret;
620 }
621 
622 /*
623  * Get rss redirection table of RSS hash configuration.
624  * @param dev
625  *   Pointer to Ethernet device.
626  * @praram reta_conf
627  *   Pointer to the configuration select of mask and redirection tables.
628  * @param reta_size
629  *   Redirection table size.
630  * @return
631  *   0 on success, a negative errno value otherwise is set.
632  */
633 int
634 hns3_dev_rss_reta_query(struct rte_eth_dev *dev,
635 			struct rte_eth_rss_reta_entry64 *reta_conf,
636 			uint16_t reta_size)
637 {
638 	struct hns3_adapter *hns = dev->data->dev_private;
639 	struct hns3_hw *hw = &hns->hw;
640 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
641 	uint16_t idx, shift;
642 	uint16_t i;
643 
644 	if (reta_size != hw->rss_ind_tbl_size) {
645 		hns3_err(hw, "The size of hash lookup table configured (%u)"
646 			 " doesn't match the number hardware can supported"
647 			 "(%u)", reta_size, hw->rss_ind_tbl_size);
648 		return -EINVAL;
649 	}
650 	rte_spinlock_lock(&hw->lock);
651 	for (i = 0; i < reta_size; i++) {
652 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
653 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
654 		if (reta_conf[idx].mask & (1ULL << shift))
655 			reta_conf[idx].reta[shift] =
656 						rss_cfg->rss_indirection_tbl[i];
657 	}
658 	rte_spinlock_unlock(&hw->lock);
659 	return 0;
660 }
661 
662 static void
663 hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid,
664 			   uint16_t *tc_size, uint16_t *tc_offset,
665 			   uint8_t tc_num)
666 {
667 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
668 	uint16_t rss_size = hw->alloc_rss_size;
669 	uint16_t roundup_size;
670 	uint16_t i;
671 
672 	roundup_size = roundup_pow_of_two(rss_size);
673 	roundup_size = ilog2(roundup_size);
674 
675 	for (i = 0; i < tc_num; i++) {
676 		if (hns->is_vf) {
677 			/*
678 			 * For packets with VLAN priorities destined for the VF,
679 			 * hardware still assign Rx queue based on the Up-to-TC
680 			 * mapping PF configured. But VF has only one TC. If
681 			 * other TC don't enable, it causes that the priority
682 			 * packets that aren't destined for TC0 aren't received
683 			 * by RSS hash but is destined for queue 0. So driver
684 			 * has to enable the unused TC by using TC0 queue
685 			 * mapping configuration.
686 			 */
687 			tc_valid[i] = (hw->hw_tc_map & BIT(i)) ?
688 					!!(hw->hw_tc_map & BIT(i)) : 1;
689 			tc_size[i] = roundup_size;
690 			tc_offset[i] = (hw->hw_tc_map & BIT(i)) ?
691 					rss_size * i : 0;
692 		} else {
693 			tc_valid[i] = !!(hw->hw_tc_map & BIT(i));
694 			tc_size[i] = tc_valid[i] ? roundup_size : 0;
695 			tc_offset[i] = tc_valid[i] ? rss_size * i : 0;
696 		}
697 	}
698 }
699 
700 static int
701 hns3_set_rss_tc_mode(struct hns3_hw *hw)
702 {
703 	struct hns3_rss_tc_mode_cmd *req;
704 	uint16_t tc_offset[HNS3_MAX_TC_NUM];
705 	uint8_t tc_valid[HNS3_MAX_TC_NUM];
706 	uint16_t tc_size[HNS3_MAX_TC_NUM];
707 	struct hns3_cmd_desc desc;
708 	uint16_t i;
709 	int ret;
710 
711 	hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size,
712 				   tc_offset, HNS3_MAX_TC_NUM);
713 
714 	req = (struct hns3_rss_tc_mode_cmd *)desc.data;
715 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false);
716 	for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
717 		uint16_t mode = 0;
718 
719 		hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
720 		hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S,
721 			       tc_size[i]);
722 		if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0)
723 			hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1);
724 		hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S,
725 			       tc_offset[i]);
726 
727 		req->rss_tc_mode[i] = rte_cpu_to_le_16(mode);
728 	}
729 	ret = hns3_cmd_send(hw, &desc, 1);
730 	if (ret)
731 		hns3_err(hw, "Sets rss tc mode failed %d", ret);
732 
733 	return ret;
734 }
735 
736 static void
737 hns3_rss_tuple_uninit(struct hns3_hw *hw)
738 {
739 	struct hns3_cmd_desc desc;
740 	int ret;
741 
742 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
743 
744 	ret = hns3_cmd_send(hw, &desc, 1);
745 	if (ret) {
746 		hns3_err(hw, "RSS uninit tuple failed %d", ret);
747 		return;
748 	}
749 }
750 
751 /*
752  * Set the default rss configuration in the init of driver.
753  */
754 void
755 hns3_rss_set_default_args(struct hns3_hw *hw)
756 {
757 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
758 	uint16_t queue_num = hw->alloc_rss_size;
759 	uint16_t i;
760 
761 	/* Default hash algorithm */
762 	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
763 
764 	/* Default RSS key */
765 	memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE);
766 
767 	/* Initialize RSS indirection table */
768 	for (i = 0; i < hw->rss_ind_tbl_size; i++)
769 		rss_cfg->rss_indirection_tbl[i] = i % queue_num;
770 }
771 
772 /*
773  * RSS initialization for hns3 PMD.
774  */
775 int
776 hns3_config_rss(struct hns3_adapter *hns)
777 {
778 	struct hns3_hw *hw = &hns->hw;
779 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
780 	uint8_t *hash_key = rss_cfg->key;
781 	uint64_t rss_hf;
782 	int ret;
783 
784 	enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
785 
786 	switch (hw->rss_info.conf.func) {
787 	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
788 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
789 		break;
790 	case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
791 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
792 		break;
793 	default:
794 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
795 		break;
796 	}
797 
798 	/* Configure RSS hash algorithm and hash key offset */
799 	ret = hns3_rss_set_algo_key(hw, hash_key);
800 	if (ret)
801 		return ret;
802 
803 	ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
804 				       hw->rss_ind_tbl_size);
805 	if (ret)
806 		return ret;
807 
808 	ret = hns3_set_rss_tc_mode(hw);
809 	if (ret)
810 		return ret;
811 
812 	/*
813 	 * When muli-queue RSS mode flag is not set or unsupported tuples are
814 	 * set, disable all tuples.
815 	 */
816 	rss_hf = hw->rss_info.conf.types;
817 	if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) ||
818 	    !(rss_hf & HNS3_ETH_RSS_SUPPORT))
819 		rss_hf = 0;
820 
821 	return hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
822 }
823 
824 /*
825  * RSS uninitialization for hns3 PMD.
826  */
827 void
828 hns3_rss_uninit(struct hns3_adapter *hns)
829 {
830 	struct hns3_hw *hw = &hns->hw;
831 	int ret;
832 
833 	hns3_rss_tuple_uninit(hw);
834 	ret = hns3_rss_reset_indir_table(hw);
835 	if (ret != 0)
836 		return;
837 
838 	/* Disable RSS */
839 	hw->rss_info.conf.types = 0;
840 }
841