xref: /dpdk/drivers/net/hns3/hns3_rss.c (revision 1bc633c3400851a7244f6608e05d37068a78cd5c)
1c37ca66fSWei Hu (Xavier) /* SPDX-License-Identifier: BSD-3-Clause
2c37ca66fSWei Hu (Xavier)  * Copyright(c) 2018-2019 Hisilicon Limited.
3c37ca66fSWei Hu (Xavier)  */
4c37ca66fSWei Hu (Xavier) 
5c37ca66fSWei Hu (Xavier) #include <stdbool.h>
6c37ca66fSWei Hu (Xavier) #include <rte_ethdev.h>
7c37ca66fSWei Hu (Xavier) #include <rte_io.h>
8c37ca66fSWei Hu (Xavier) #include <rte_malloc.h>
9c37ca66fSWei Hu (Xavier) #include <rte_memcpy.h>
10c37ca66fSWei Hu (Xavier) #include <rte_spinlock.h>
11c37ca66fSWei Hu (Xavier) 
12c37ca66fSWei Hu (Xavier) #include "hns3_ethdev.h"
13c37ca66fSWei Hu (Xavier) #include "hns3_logs.h"
14c37ca66fSWei Hu (Xavier) 
15c37ca66fSWei Hu (Xavier) /*
16c37ca66fSWei Hu (Xavier)  * The hash key used for rss initialization.
17c37ca66fSWei Hu (Xavier)  */
18c37ca66fSWei Hu (Xavier) static const uint8_t hns3_hash_key[] = {
19c37ca66fSWei Hu (Xavier) 	0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
20c37ca66fSWei Hu (Xavier) 	0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
21c37ca66fSWei Hu (Xavier) 	0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
22c37ca66fSWei Hu (Xavier) 	0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
23c37ca66fSWei Hu (Xavier) 	0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA
24c37ca66fSWei Hu (Xavier) };
25c37ca66fSWei Hu (Xavier) 
26806f1d5aSLijun Ou enum hns3_tuple_field {
27806f1d5aSLijun Ou 	/* IPV4_TCP ENABLE FIELD */
28806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0,
29806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S,
30806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D,
31806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S,
32806f1d5aSLijun Ou 
33806f1d5aSLijun Ou 	/* IPV4_UDP ENABLE FIELD */
34806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8,
35806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S,
36806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D,
37806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S,
38806f1d5aSLijun Ou 
39806f1d5aSLijun Ou 	/* IPV4_SCTP ENABLE FIELD */
40806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16,
41806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S,
42806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D,
43806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S,
44806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER,
45806f1d5aSLijun Ou 
46806f1d5aSLijun Ou 	/* IPV4 ENABLE FIELD */
47806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24,
48806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S,
49806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D,
50806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S,
51806f1d5aSLijun Ou 
52806f1d5aSLijun Ou 	/* IPV6_TCP ENABLE FIELD */
53806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32,
54806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S,
55806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D,
56806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S,
57806f1d5aSLijun Ou 
58806f1d5aSLijun Ou 	/* IPV6_UDP ENABLE FIELD */
59806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40,
60806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S,
61806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D,
62806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S,
63806f1d5aSLijun Ou 
64*1bc633c3SLijun Ou 	/* IPV6_SCTP ENABLE FIELD */
65*1bc633c3SLijun Ou 	HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_D = 48,
66*1bc633c3SLijun Ou 	HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_S,
67*1bc633c3SLijun Ou 	HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D,
68806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S,
69806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER,
70806f1d5aSLijun Ou 
71806f1d5aSLijun Ou 	/* IPV6 ENABLE FIELD */
72806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56,
73806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S,
74806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_FRAG_IP_D,
75806f1d5aSLijun Ou 	HNS3_RSS_FIELD_IPV6_FRAG_IP_S
76806f1d5aSLijun Ou };
77806f1d5aSLijun Ou 
78806f1d5aSLijun Ou static const struct {
79806f1d5aSLijun Ou 	uint64_t rss_types;
80806f1d5aSLijun Ou 	uint64_t rss_field;
81806f1d5aSLijun Ou } hns3_set_tuple_table[] = {
82806f1d5aSLijun Ou 	{ ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_SRC_ONLY,
83806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) },
84806f1d5aSLijun Ou 	{ ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_DST_ONLY,
85806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) },
86806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY,
87806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) },
88806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY,
89806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) },
90806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY,
91806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) },
92806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY,
93806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
94806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY,
95806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) },
96806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY,
97806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) },
98806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY,
99806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) },
100806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY,
101806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) },
102806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY,
103806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) },
104806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY,
105806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) },
106806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY,
107806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) },
108806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY,
109806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) },
110806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_SRC_ONLY,
111806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) },
112806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_DST_ONLY,
113806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
114806f1d5aSLijun Ou 	{ ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_SRC_ONLY,
115806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) },
116806f1d5aSLijun Ou 	{ ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_DST_ONLY,
117806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) },
118806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY,
119806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) },
120806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY,
121806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) },
122806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY,
123806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) },
124806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY,
125806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) },
126806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY,
127806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) },
128806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY,
129806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) },
130806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY,
131806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) },
132806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY,
133806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) },
134806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY,
135806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) },
136806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY,
137806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) },
138*1bc633c3SLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_SRC_ONLY,
139*1bc633c3SLijun Ou 	  BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_S) },
140*1bc633c3SLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_DST_ONLY,
141*1bc633c3SLijun Ou 	  BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_D) },
142806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_SRC_ONLY,
143806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) },
144806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_DST_ONLY,
145806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
146806f1d5aSLijun Ou };
147806f1d5aSLijun Ou 
148806f1d5aSLijun Ou static const struct {
149806f1d5aSLijun Ou 	uint64_t rss_types;
150806f1d5aSLijun Ou 	uint64_t rss_field;
151806f1d5aSLijun Ou } hns3_set_rss_types[] = {
152806f1d5aSLijun Ou 	{ ETH_RSS_FRAG_IPV4, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) |
153806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) },
154806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) |
155806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) |
156806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) |
157806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
158806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) |
159806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) |
160806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) |
161806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
162806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) |
163806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) |
164806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) |
165806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) },
166806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) |
167806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) |
168806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) |
169806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) |
170806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) },
171806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV4_OTHER,
172806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
173806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
174806f1d5aSLijun Ou 	{ ETH_RSS_FRAG_IPV6, BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) |
175806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) },
176806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) |
177806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) |
178806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) |
179806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) },
180806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) |
181806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) |
182806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) |
183806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) },
184806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) |
185806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) |
186*1bc633c3SLijun Ou 	  BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_D) |
187*1bc633c3SLijun Ou 	  BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_S) |
188806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) },
189806f1d5aSLijun Ou 	{ ETH_RSS_NONFRAG_IPV6_OTHER,
190806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
191806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }
192806f1d5aSLijun Ou };
193806f1d5aSLijun Ou 
194c37ca66fSWei Hu (Xavier) /*
195c37ca66fSWei Hu (Xavier)  * rss_generic_config command function, opcode:0x0D01.
196c37ca66fSWei Hu (Xavier)  * Used to set algorithm, key_offset and hash key of rss.
197c37ca66fSWei Hu (Xavier)  */
198c37ca66fSWei Hu (Xavier) int
19978b37190SLijun Ou hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key)
200c37ca66fSWei Hu (Xavier) {
201c37ca66fSWei Hu (Xavier) #define HNS3_KEY_OFFSET_MAX	3
202c37ca66fSWei Hu (Xavier) #define HNS3_SET_HASH_KEY_BYTE_FOUR	2
203c37ca66fSWei Hu (Xavier) 
204c37ca66fSWei Hu (Xavier) 	struct hns3_rss_generic_config_cmd *req;
205c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
206c37ca66fSWei Hu (Xavier) 	uint32_t key_offset, key_size;
207c37ca66fSWei Hu (Xavier) 	const uint8_t *key_cur;
208c37ca66fSWei Hu (Xavier) 	uint8_t cur_offset;
209c37ca66fSWei Hu (Xavier) 	int ret;
210c37ca66fSWei Hu (Xavier) 
211c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_generic_config_cmd *)desc.data;
212c37ca66fSWei Hu (Xavier) 
213c37ca66fSWei Hu (Xavier) 	/*
214c37ca66fSWei Hu (Xavier) 	 * key_offset=0, hash key byte0~15 is set to hardware.
215c37ca66fSWei Hu (Xavier) 	 * key_offset=1, hash key byte16~31 is set to hardware.
216c37ca66fSWei Hu (Xavier) 	 * key_offset=2, hash key byte32~39 is set to hardware.
217c37ca66fSWei Hu (Xavier) 	 */
218c37ca66fSWei Hu (Xavier) 	for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) {
219c37ca66fSWei Hu (Xavier) 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
220c37ca66fSWei Hu (Xavier) 					  false);
221c37ca66fSWei Hu (Xavier) 
22278b37190SLijun Ou 		req->hash_config |=
22378b37190SLijun Ou 			(hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK);
224c37ca66fSWei Hu (Xavier) 		req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B);
225c37ca66fSWei Hu (Xavier) 
226c37ca66fSWei Hu (Xavier) 		if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR)
227c37ca66fSWei Hu (Xavier) 			key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM *
228c37ca66fSWei Hu (Xavier) 			HNS3_SET_HASH_KEY_BYTE_FOUR;
229c37ca66fSWei Hu (Xavier) 		else
230c37ca66fSWei Hu (Xavier) 			key_size = HNS3_RSS_HASH_KEY_NUM;
231c37ca66fSWei Hu (Xavier) 
232c37ca66fSWei Hu (Xavier) 		cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM;
233c37ca66fSWei Hu (Xavier) 		key_cur = key + cur_offset;
234c37ca66fSWei Hu (Xavier) 		memcpy(req->hash_key, key_cur, key_size);
235c37ca66fSWei Hu (Xavier) 
236c37ca66fSWei Hu (Xavier) 		ret = hns3_cmd_send(hw, &desc, 1);
237c37ca66fSWei Hu (Xavier) 		if (ret) {
238c37ca66fSWei Hu (Xavier) 			hns3_err(hw, "Configure RSS algo key failed %d", ret);
239c37ca66fSWei Hu (Xavier) 			return ret;
240c37ca66fSWei Hu (Xavier) 		}
241c37ca66fSWei Hu (Xavier) 	}
242c37ca66fSWei Hu (Xavier) 	/* Update the shadow RSS key with user specified */
243c37ca66fSWei Hu (Xavier) 	memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE);
244c37ca66fSWei Hu (Xavier) 	return 0;
245c37ca66fSWei Hu (Xavier) }
246c37ca66fSWei Hu (Xavier) 
247c37ca66fSWei Hu (Xavier) /*
248c37ca66fSWei Hu (Xavier)  * Used to configure the tuple selection for RSS hash input.
249c37ca66fSWei Hu (Xavier)  */
250c37ca66fSWei Hu (Xavier) static int
251c37ca66fSWei Hu (Xavier) hns3_set_rss_input_tuple(struct hns3_hw *hw)
252c37ca66fSWei Hu (Xavier) {
253c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_config = &hw->rss_info;
254c37ca66fSWei Hu (Xavier) 	struct hns3_rss_input_tuple_cmd *req;
255c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc_tuple;
256c37ca66fSWei Hu (Xavier) 	int ret;
257c37ca66fSWei Hu (Xavier) 
258c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc_tuple, HNS3_OPC_RSS_INPUT_TUPLE, false);
259c37ca66fSWei Hu (Xavier) 
260c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_input_tuple_cmd *)desc_tuple.data;
261c37ca66fSWei Hu (Xavier) 
262806f1d5aSLijun Ou 	req->tuple_field =
263806f1d5aSLijun Ou 		rte_cpu_to_le_64(rss_config->rss_tuple_sets.rss_tuple_fields);
264c37ca66fSWei Hu (Xavier) 
265c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc_tuple, 1);
266c37ca66fSWei Hu (Xavier) 	if (ret)
267c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "Configure RSS input tuple mode failed %d", ret);
268c37ca66fSWei Hu (Xavier) 
269c37ca66fSWei Hu (Xavier) 	return ret;
270c37ca66fSWei Hu (Xavier) }
271c37ca66fSWei Hu (Xavier) 
272c37ca66fSWei Hu (Xavier) /*
273c37ca66fSWei Hu (Xavier)  * rss_indirection_table command function, opcode:0x0D07.
274c37ca66fSWei Hu (Xavier)  * Used to configure the indirection table of rss.
275c37ca66fSWei Hu (Xavier)  */
276c37ca66fSWei Hu (Xavier) int
2779a7d3af2SHuisong Li hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
278c37ca66fSWei Hu (Xavier) {
279c37ca66fSWei Hu (Xavier) 	struct hns3_rss_indirection_table_cmd *req;
280c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
2819a7d3af2SHuisong Li 	uint8_t qid_msb_off;
2829a7d3af2SHuisong Li 	uint8_t qid_msb_val;
2839a7d3af2SHuisong Li 	uint16_t q_id;
2849a7d3af2SHuisong Li 	uint16_t i, j;
2859a7d3af2SHuisong Li 	int ret;
286c37ca66fSWei Hu (Xavier) 
287c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_indirection_table_cmd *)desc.data;
288c37ca66fSWei Hu (Xavier) 
289c37ca66fSWei Hu (Xavier) 	for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) {
290c37ca66fSWei Hu (Xavier) 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
291c37ca66fSWei Hu (Xavier) 					  false);
292c37ca66fSWei Hu (Xavier) 		req->start_table_index =
293c37ca66fSWei Hu (Xavier) 				rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
294c37ca66fSWei Hu (Xavier) 		req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK);
295c37ca66fSWei Hu (Xavier) 		for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) {
2969a7d3af2SHuisong Li 			q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j];
2979a7d3af2SHuisong Li 			req->rss_result_l[j] = q_id & 0xff;
2989a7d3af2SHuisong Li 
2999a7d3af2SHuisong Li 			qid_msb_off =
3009a7d3af2SHuisong Li 				j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
3019a7d3af2SHuisong Li 			qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1)
3029a7d3af2SHuisong Li 					<< (j * HNS3_RSS_CFG_TBL_BW_H %
3039a7d3af2SHuisong Li 					HNS3_BITS_PER_BYTE);
3049a7d3af2SHuisong Li 			req->rss_result_h[qid_msb_off] |= qid_msb_val;
305c37ca66fSWei Hu (Xavier) 		}
3069a7d3af2SHuisong Li 
307c37ca66fSWei Hu (Xavier) 		ret = hns3_cmd_send(hw, &desc, 1);
308c37ca66fSWei Hu (Xavier) 		if (ret) {
309c37ca66fSWei Hu (Xavier) 			hns3_err(hw,
310c37ca66fSWei Hu (Xavier) 				 "Sets RSS indirection table failed %d size %u",
311c37ca66fSWei Hu (Xavier) 				 ret, size);
312c37ca66fSWei Hu (Xavier) 			return ret;
313c37ca66fSWei Hu (Xavier) 		}
314c37ca66fSWei Hu (Xavier) 	}
315c37ca66fSWei Hu (Xavier) 
316c37ca66fSWei Hu (Xavier) 	/* Update redirection table of hw */
3179a7d3af2SHuisong Li 	memcpy(hw->rss_info.rss_indirection_tbl, indir,
3189a7d3af2SHuisong Li 	       sizeof(hw->rss_info.rss_indirection_tbl));
319c37ca66fSWei Hu (Xavier) 
320c37ca66fSWei Hu (Xavier) 	return 0;
321c37ca66fSWei Hu (Xavier) }
322c37ca66fSWei Hu (Xavier) 
323c37ca66fSWei Hu (Xavier) int
324c37ca66fSWei Hu (Xavier) hns3_rss_reset_indir_table(struct hns3_hw *hw)
325c37ca66fSWei Hu (Xavier) {
3269a7d3af2SHuisong Li 	uint16_t *lut;
327c37ca66fSWei Hu (Xavier) 	int ret;
328c37ca66fSWei Hu (Xavier) 
3299a7d3af2SHuisong Li 	lut = rte_zmalloc("hns3_rss_lut",
3309a7d3af2SHuisong Li 			  HNS3_RSS_IND_TBL_SIZE * sizeof(uint16_t), 0);
331c37ca66fSWei Hu (Xavier) 	if (lut == NULL) {
332c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "No hns3_rss_lut memory can be allocated");
333c37ca66fSWei Hu (Xavier) 		return -ENOMEM;
334c37ca66fSWei Hu (Xavier) 	}
335c37ca66fSWei Hu (Xavier) 
336c37ca66fSWei Hu (Xavier) 	ret = hns3_set_rss_indir_table(hw, lut, HNS3_RSS_IND_TBL_SIZE);
337c37ca66fSWei Hu (Xavier) 	if (ret)
338c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "RSS uninit indir table failed: %d", ret);
339c37ca66fSWei Hu (Xavier) 	rte_free(lut);
340c37ca66fSWei Hu (Xavier) 
341c37ca66fSWei Hu (Xavier) 	return ret;
342c37ca66fSWei Hu (Xavier) }
343c37ca66fSWei Hu (Xavier) 
344c37ca66fSWei Hu (Xavier) int
345c37ca66fSWei Hu (Xavier) hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw,
346c37ca66fSWei Hu (Xavier) 			     struct hns3_rss_tuple_cfg *tuple, uint64_t rss_hf)
347c37ca66fSWei Hu (Xavier) {
348c37ca66fSWei Hu (Xavier) 	struct hns3_rss_input_tuple_cmd *req;
349c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
350806f1d5aSLijun Ou 	uint32_t fields_count = 0; /* count times for setting tuple fields */
351c37ca66fSWei Hu (Xavier) 	uint32_t i;
352c37ca66fSWei Hu (Xavier) 	int ret;
353c37ca66fSWei Hu (Xavier) 
354c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
355c37ca66fSWei Hu (Xavier) 
356c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_input_tuple_cmd *)desc.data;
357c37ca66fSWei Hu (Xavier) 
358806f1d5aSLijun Ou 	for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
359806f1d5aSLijun Ou 		if ((rss_hf & hns3_set_tuple_table[i].rss_types) ==
360806f1d5aSLijun Ou 		     hns3_set_tuple_table[i].rss_types) {
361806f1d5aSLijun Ou 			req->tuple_field |=
362806f1d5aSLijun Ou 			    rte_cpu_to_le_64(hns3_set_tuple_table[i].rss_field);
363806f1d5aSLijun Ou 			fields_count++;
364806f1d5aSLijun Ou 		}
365806f1d5aSLijun Ou 	}
366806f1d5aSLijun Ou 
3678834849aSHao Chen 	/*
368806f1d5aSLijun Ou 	 * When user does not specify the following types or a combination of
369806f1d5aSLijun Ou 	 * the following types, it enables all fields for the supported RSS
370806f1d5aSLijun Ou 	 * types. the following types as:
371806f1d5aSLijun Ou 	 * - ETH_RSS_L3_SRC_ONLY
372806f1d5aSLijun Ou 	 * - ETH_RSS_L3_DST_ONLY
373806f1d5aSLijun Ou 	 * - ETH_RSS_L4_SRC_ONLY
374806f1d5aSLijun Ou 	 * - ETH_RSS_L4_DST_ONLY
3758834849aSHao Chen 	 */
376806f1d5aSLijun Ou 	if (fields_count == 0) {
377806f1d5aSLijun Ou 		for (i = 0; i < RTE_DIM(hns3_set_rss_types); i++) {
378806f1d5aSLijun Ou 			if ((rss_hf & hns3_set_rss_types[i].rss_types) ==
379806f1d5aSLijun Ou 			     hns3_set_rss_types[i].rss_types)
380806f1d5aSLijun Ou 				req->tuple_field |= rte_cpu_to_le_64(
381806f1d5aSLijun Ou 					hns3_set_rss_types[i].rss_field);
382c37ca66fSWei Hu (Xavier) 		}
383c37ca66fSWei Hu (Xavier) 	}
384c37ca66fSWei Hu (Xavier) 
385c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc, 1);
386c37ca66fSWei Hu (Xavier) 	if (ret) {
387c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "Update RSS flow types tuples failed %d", ret);
388c37ca66fSWei Hu (Xavier) 		return ret;
389c37ca66fSWei Hu (Xavier) 	}
390c37ca66fSWei Hu (Xavier) 
391806f1d5aSLijun Ou 	tuple->rss_tuple_fields = rte_le_to_cpu_64(req->tuple_field);
392c37ca66fSWei Hu (Xavier) 
393c37ca66fSWei Hu (Xavier) 	return 0;
394c37ca66fSWei Hu (Xavier) }
395c37ca66fSWei Hu (Xavier) 
396c37ca66fSWei Hu (Xavier) /*
397c37ca66fSWei Hu (Xavier)  * Configure RSS hash protocols and hash key.
398c37ca66fSWei Hu (Xavier)  * @param dev
399c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
400c37ca66fSWei Hu (Xavier)  * @praram rss_conf
401c37ca66fSWei Hu (Xavier)  *   The configuration select of  rss key size and tuple flow_types.
402c37ca66fSWei Hu (Xavier)  * @return
403c37ca66fSWei Hu (Xavier)  *   0 on success, a negative errno value otherwise is set.
404c37ca66fSWei Hu (Xavier)  */
405c37ca66fSWei Hu (Xavier) int
406c37ca66fSWei Hu (Xavier) hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
407c37ca66fSWei Hu (Xavier) 			 struct rte_eth_rss_conf *rss_conf)
408c37ca66fSWei Hu (Xavier) {
409c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
410c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
411c37ca66fSWei Hu (Xavier) 	struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets;
412c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
413c37ca66fSWei Hu (Xavier) 	uint8_t key_len = rss_conf->rss_key_len;
414c37ca66fSWei Hu (Xavier) 	uint64_t rss_hf = rss_conf->rss_hf;
415c37ca66fSWei Hu (Xavier) 	uint8_t *key = rss_conf->rss_key;
416c37ca66fSWei Hu (Xavier) 	int ret;
417c37ca66fSWei Hu (Xavier) 
4185e782bc2SLijun Ou 	if (hw->rss_dis_flag)
4195e782bc2SLijun Ou 		return -EINVAL;
4205e782bc2SLijun Ou 
421c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
422c37ca66fSWei Hu (Xavier) 	ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_hf);
423c37ca66fSWei Hu (Xavier) 	if (ret)
424c37ca66fSWei Hu (Xavier) 		goto conf_err;
425c37ca66fSWei Hu (Xavier) 
426c37ca66fSWei Hu (Xavier) 	if (rss_cfg->conf.types && rss_hf == 0) {
427c37ca66fSWei Hu (Xavier) 		/* Disable RSS, reset indirection table by local variable */
428c37ca66fSWei Hu (Xavier) 		ret = hns3_rss_reset_indir_table(hw);
429c37ca66fSWei Hu (Xavier) 		if (ret)
430c37ca66fSWei Hu (Xavier) 			goto conf_err;
431c37ca66fSWei Hu (Xavier) 	} else if (rss_hf && rss_cfg->conf.types == 0) {
432c37ca66fSWei Hu (Xavier) 		/* Enable RSS, restore indirection table by hw's config */
433c37ca66fSWei Hu (Xavier) 		ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
434c37ca66fSWei Hu (Xavier) 					       HNS3_RSS_IND_TBL_SIZE);
435c37ca66fSWei Hu (Xavier) 		if (ret)
436c37ca66fSWei Hu (Xavier) 			goto conf_err;
437c37ca66fSWei Hu (Xavier) 	}
438c37ca66fSWei Hu (Xavier) 
439c37ca66fSWei Hu (Xavier) 	/* Update supported flow types when set tuple success */
440c37ca66fSWei Hu (Xavier) 	rss_cfg->conf.types = rss_hf;
441c37ca66fSWei Hu (Xavier) 
442c37ca66fSWei Hu (Xavier) 	if (key) {
443c37ca66fSWei Hu (Xavier) 		if (key_len != HNS3_RSS_KEY_SIZE) {
444c37ca66fSWei Hu (Xavier) 			hns3_err(hw, "The hash key len(%u) is invalid",
445c37ca66fSWei Hu (Xavier) 				 key_len);
446c37ca66fSWei Hu (Xavier) 			ret = -EINVAL;
447c37ca66fSWei Hu (Xavier) 			goto conf_err;
448c37ca66fSWei Hu (Xavier) 		}
44978b37190SLijun Ou 		ret = hns3_set_rss_algo_key(hw, key);
450c37ca66fSWei Hu (Xavier) 		if (ret)
451c37ca66fSWei Hu (Xavier) 			goto conf_err;
452c37ca66fSWei Hu (Xavier) 	}
453c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
454c37ca66fSWei Hu (Xavier) 
455c37ca66fSWei Hu (Xavier) 	return 0;
456c37ca66fSWei Hu (Xavier) 
457c37ca66fSWei Hu (Xavier) conf_err:
458c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
459c37ca66fSWei Hu (Xavier) 	return ret;
460c37ca66fSWei Hu (Xavier) }
461c37ca66fSWei Hu (Xavier) 
462c37ca66fSWei Hu (Xavier) /*
463c37ca66fSWei Hu (Xavier)  * Get rss key and rss_hf types set of RSS hash configuration.
464c37ca66fSWei Hu (Xavier)  * @param dev
465c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
466c37ca66fSWei Hu (Xavier)  * @praram rss_conf
467c37ca66fSWei Hu (Xavier)  *   The buffer to get rss key size and tuple types.
468c37ca66fSWei Hu (Xavier)  * @return
469c37ca66fSWei Hu (Xavier)  *   0 on success.
470c37ca66fSWei Hu (Xavier)  */
471c37ca66fSWei Hu (Xavier) int
472c37ca66fSWei Hu (Xavier) hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
473c37ca66fSWei Hu (Xavier) 			   struct rte_eth_rss_conf *rss_conf)
474c37ca66fSWei Hu (Xavier) {
475c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
476c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
477c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
478c37ca66fSWei Hu (Xavier) 
479c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
480c37ca66fSWei Hu (Xavier) 	rss_conf->rss_hf = rss_cfg->conf.types;
481c37ca66fSWei Hu (Xavier) 
482c37ca66fSWei Hu (Xavier) 	/* Get the RSS Key required by the user */
483708e60a4SLijun Ou 	if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) {
484c37ca66fSWei Hu (Xavier) 		memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE);
485708e60a4SLijun Ou 		rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE;
486708e60a4SLijun Ou 	}
487c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
488c37ca66fSWei Hu (Xavier) 
489c37ca66fSWei Hu (Xavier) 	return 0;
490c37ca66fSWei Hu (Xavier) }
491c37ca66fSWei Hu (Xavier) 
492c37ca66fSWei Hu (Xavier) /*
493c37ca66fSWei Hu (Xavier)  * Update rss redirection table of RSS.
494c37ca66fSWei Hu (Xavier)  * @param dev
495c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
496c37ca66fSWei Hu (Xavier)  * @praram reta_conf
497c37ca66fSWei Hu (Xavier)  *   Pointer to the configuration select of mask and redirection tables.
498c37ca66fSWei Hu (Xavier)  * @param reta_size
499c37ca66fSWei Hu (Xavier)  *   Redirection table size.
500c37ca66fSWei Hu (Xavier)  * @return
501c37ca66fSWei Hu (Xavier)  *   0 on success, a negative errno value otherwise is set.
502c37ca66fSWei Hu (Xavier)  */
503c37ca66fSWei Hu (Xavier) int
504c37ca66fSWei Hu (Xavier) hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
505c37ca66fSWei Hu (Xavier) 			 struct rte_eth_rss_reta_entry64 *reta_conf,
506c37ca66fSWei Hu (Xavier) 			 uint16_t reta_size)
507c37ca66fSWei Hu (Xavier) {
508c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
509c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
510c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
511c37ca66fSWei Hu (Xavier) 	uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */
5129a7d3af2SHuisong Li 	uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE];
513c37ca66fSWei Hu (Xavier) 	uint16_t idx, shift, allow_rss_queues;
514c37ca66fSWei Hu (Xavier) 	int ret;
515c37ca66fSWei Hu (Xavier) 
516c37ca66fSWei Hu (Xavier) 	if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) {
517c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "The size of hash lookup table configured (%u)"
518c37ca66fSWei Hu (Xavier) 			 "doesn't match the number hardware can supported"
519c37ca66fSWei Hu (Xavier) 			 "(%u)", reta_size, indir_size);
520c37ca66fSWei Hu (Xavier) 		return -EINVAL;
521c37ca66fSWei Hu (Xavier) 	}
522c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
523c37ca66fSWei Hu (Xavier) 	memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
5249a7d3af2SHuisong Li 	       sizeof(rss_cfg->rss_indirection_tbl));
525c37ca66fSWei Hu (Xavier) 	allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max);
526c37ca66fSWei Hu (Xavier) 	for (i = 0; i < reta_size; i++) {
527c37ca66fSWei Hu (Xavier) 		idx = i / RTE_RETA_GROUP_SIZE;
528c37ca66fSWei Hu (Xavier) 		shift = i % RTE_RETA_GROUP_SIZE;
529c37ca66fSWei Hu (Xavier) 		if (reta_conf[idx].reta[shift] >= allow_rss_queues) {
530c37ca66fSWei Hu (Xavier) 			rte_spinlock_unlock(&hw->lock);
531c37ca66fSWei Hu (Xavier) 			hns3_err(hw, "Invalid queue id(%u) to be set in "
532c37ca66fSWei Hu (Xavier) 				 "redirection table, max number of rss "
533c37ca66fSWei Hu (Xavier) 				 "queues: %u", reta_conf[idx].reta[shift],
534c37ca66fSWei Hu (Xavier) 				 allow_rss_queues);
535c37ca66fSWei Hu (Xavier) 			return -EINVAL;
536c37ca66fSWei Hu (Xavier) 		}
537c37ca66fSWei Hu (Xavier) 
538c37ca66fSWei Hu (Xavier) 		if (reta_conf[idx].mask & (1ULL << shift))
539c37ca66fSWei Hu (Xavier) 			indirection_tbl[i] = reta_conf[idx].reta[shift];
540c37ca66fSWei Hu (Xavier) 	}
541c37ca66fSWei Hu (Xavier) 
542c37ca66fSWei Hu (Xavier) 	ret = hns3_set_rss_indir_table(hw, indirection_tbl,
543c37ca66fSWei Hu (Xavier) 				       HNS3_RSS_IND_TBL_SIZE);
544c37ca66fSWei Hu (Xavier) 
545c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
546c37ca66fSWei Hu (Xavier) 	return ret;
547c37ca66fSWei Hu (Xavier) }
548c37ca66fSWei Hu (Xavier) 
549c37ca66fSWei Hu (Xavier) /*
550c37ca66fSWei Hu (Xavier)  * Get rss redirection table of RSS hash configuration.
551c37ca66fSWei Hu (Xavier)  * @param dev
552c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
553c37ca66fSWei Hu (Xavier)  * @praram reta_conf
554c37ca66fSWei Hu (Xavier)  *   Pointer to the configuration select of mask and redirection tables.
555c37ca66fSWei Hu (Xavier)  * @param reta_size
556c37ca66fSWei Hu (Xavier)  *   Redirection table size.
557c37ca66fSWei Hu (Xavier)  * @return
558c37ca66fSWei Hu (Xavier)  *   0 on success, a negative errno value otherwise is set.
559c37ca66fSWei Hu (Xavier)  */
560c37ca66fSWei Hu (Xavier) int
561c37ca66fSWei Hu (Xavier) hns3_dev_rss_reta_query(struct rte_eth_dev *dev,
562c37ca66fSWei Hu (Xavier) 			struct rte_eth_rss_reta_entry64 *reta_conf,
563c37ca66fSWei Hu (Xavier) 			uint16_t reta_size)
564c37ca66fSWei Hu (Xavier) {
565c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
566c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
567c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
568c37ca66fSWei Hu (Xavier) 	uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */
569c37ca66fSWei Hu (Xavier) 	uint16_t idx, shift;
570c37ca66fSWei Hu (Xavier) 
571c37ca66fSWei Hu (Xavier) 	if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) {
572c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "The size of hash lookup table configured (%u)"
573c37ca66fSWei Hu (Xavier) 			 " doesn't match the number hardware can supported"
574c37ca66fSWei Hu (Xavier) 			 "(%u)", reta_size, indir_size);
575c37ca66fSWei Hu (Xavier) 		return -EINVAL;
576c37ca66fSWei Hu (Xavier) 	}
577c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
578c37ca66fSWei Hu (Xavier) 	for (i = 0; i < reta_size; i++) {
579c37ca66fSWei Hu (Xavier) 		idx = i / RTE_RETA_GROUP_SIZE;
580c37ca66fSWei Hu (Xavier) 		shift = i % RTE_RETA_GROUP_SIZE;
581c37ca66fSWei Hu (Xavier) 		if (reta_conf[idx].mask & (1ULL << shift))
582c37ca66fSWei Hu (Xavier) 			reta_conf[idx].reta[shift] =
583920be799SLijun Ou 						rss_cfg->rss_indirection_tbl[i];
584c37ca66fSWei Hu (Xavier) 	}
585c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
586c37ca66fSWei Hu (Xavier) 	return 0;
587c37ca66fSWei Hu (Xavier) }
588c37ca66fSWei Hu (Xavier) 
589c37ca66fSWei Hu (Xavier) /*
590c37ca66fSWei Hu (Xavier)  * Used to configure the tc_size and tc_offset.
591c37ca66fSWei Hu (Xavier)  */
592c37ca66fSWei Hu (Xavier) static int
593c37ca66fSWei Hu (Xavier) hns3_set_rss_tc_mode(struct hns3_hw *hw)
594c37ca66fSWei Hu (Xavier) {
595c37ca66fSWei Hu (Xavier) 	uint16_t rss_size = hw->alloc_rss_size;
596c37ca66fSWei Hu (Xavier) 	struct hns3_rss_tc_mode_cmd *req;
597c37ca66fSWei Hu (Xavier) 	uint16_t tc_offset[HNS3_MAX_TC_NUM];
598c37ca66fSWei Hu (Xavier) 	uint8_t tc_valid[HNS3_MAX_TC_NUM];
599c37ca66fSWei Hu (Xavier) 	uint16_t tc_size[HNS3_MAX_TC_NUM];
600c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
601c37ca66fSWei Hu (Xavier) 	uint16_t roundup_size;
602c37ca66fSWei Hu (Xavier) 	uint16_t i;
603c37ca66fSWei Hu (Xavier) 	int ret;
604c37ca66fSWei Hu (Xavier) 
605c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_tc_mode_cmd *)desc.data;
606c37ca66fSWei Hu (Xavier) 
607c37ca66fSWei Hu (Xavier) 	roundup_size = roundup_pow_of_two(rss_size);
608c37ca66fSWei Hu (Xavier) 	roundup_size = ilog2(roundup_size);
609c37ca66fSWei Hu (Xavier) 
610c37ca66fSWei Hu (Xavier) 	for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
611c37ca66fSWei Hu (Xavier) 		tc_valid[i] = !!(hw->hw_tc_map & BIT(i));
612c37ca66fSWei Hu (Xavier) 		tc_size[i] = roundup_size;
613c37ca66fSWei Hu (Xavier) 		tc_offset[i] = rss_size * i;
614c37ca66fSWei Hu (Xavier) 	}
615c37ca66fSWei Hu (Xavier) 
616c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false);
617c37ca66fSWei Hu (Xavier) 	for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
618c37ca66fSWei Hu (Xavier) 		uint16_t mode = 0;
619c37ca66fSWei Hu (Xavier) 
620c37ca66fSWei Hu (Xavier) 		hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
621c37ca66fSWei Hu (Xavier) 		hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S,
622c37ca66fSWei Hu (Xavier) 			       tc_size[i]);
6239a7d3af2SHuisong Li 		if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0)
6249a7d3af2SHuisong Li 			hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1);
625c37ca66fSWei Hu (Xavier) 		hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S,
626c37ca66fSWei Hu (Xavier) 			       tc_offset[i]);
627c37ca66fSWei Hu (Xavier) 
628c37ca66fSWei Hu (Xavier) 		req->rss_tc_mode[i] = rte_cpu_to_le_16(mode);
629c37ca66fSWei Hu (Xavier) 	}
630c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc, 1);
631c37ca66fSWei Hu (Xavier) 	if (ret)
632c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "Sets rss tc mode failed %d", ret);
633c37ca66fSWei Hu (Xavier) 
634c37ca66fSWei Hu (Xavier) 	return ret;
635c37ca66fSWei Hu (Xavier) }
636c37ca66fSWei Hu (Xavier) 
637c37ca66fSWei Hu (Xavier) static void
638c37ca66fSWei Hu (Xavier) hns3_rss_tuple_uninit(struct hns3_hw *hw)
639c37ca66fSWei Hu (Xavier) {
640c37ca66fSWei Hu (Xavier) 	struct hns3_rss_input_tuple_cmd *req;
641c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
642c37ca66fSWei Hu (Xavier) 	int ret;
643c37ca66fSWei Hu (Xavier) 
644c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
645c37ca66fSWei Hu (Xavier) 
646c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_input_tuple_cmd *)desc.data;
647c37ca66fSWei Hu (Xavier) 
648c37ca66fSWei Hu (Xavier) 	memset(req, 0, sizeof(struct hns3_rss_tuple_cfg));
649c37ca66fSWei Hu (Xavier) 
650c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc, 1);
651c37ca66fSWei Hu (Xavier) 	if (ret) {
652c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "RSS uninit tuple failed %d", ret);
653c37ca66fSWei Hu (Xavier) 		return;
654c37ca66fSWei Hu (Xavier) 	}
655c37ca66fSWei Hu (Xavier) }
656c37ca66fSWei Hu (Xavier) 
657c37ca66fSWei Hu (Xavier) /*
658c37ca66fSWei Hu (Xavier)  * Set the default rss configuration in the init of driver.
659c37ca66fSWei Hu (Xavier)  */
660c37ca66fSWei Hu (Xavier) void
661c37ca66fSWei Hu (Xavier) hns3_set_default_rss_args(struct hns3_hw *hw)
662c37ca66fSWei Hu (Xavier) {
663c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
664c37ca66fSWei Hu (Xavier) 	uint16_t queue_num = hw->alloc_rss_size;
665c37ca66fSWei Hu (Xavier) 	int i;
666c37ca66fSWei Hu (Xavier) 
667c37ca66fSWei Hu (Xavier) 	/* Default hash algorithm */
6688834849aSHao Chen 	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
6698834849aSHao Chen 
6708834849aSHao Chen 	/* Default RSS key */
671c37ca66fSWei Hu (Xavier) 	memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE);
672c37ca66fSWei Hu (Xavier) 
673c37ca66fSWei Hu (Xavier) 	/* Initialize RSS indirection table */
674c37ca66fSWei Hu (Xavier) 	for (i = 0; i < HNS3_RSS_IND_TBL_SIZE; i++)
675c37ca66fSWei Hu (Xavier) 		rss_cfg->rss_indirection_tbl[i] = i % queue_num;
676c37ca66fSWei Hu (Xavier) }
677c37ca66fSWei Hu (Xavier) 
678c37ca66fSWei Hu (Xavier) /*
679c37ca66fSWei Hu (Xavier)  * RSS initialization for hns3 pmd driver.
680c37ca66fSWei Hu (Xavier)  */
681c37ca66fSWei Hu (Xavier) int
682c37ca66fSWei Hu (Xavier) hns3_config_rss(struct hns3_adapter *hns)
683c37ca66fSWei Hu (Xavier) {
684c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
685c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
686c37ca66fSWei Hu (Xavier) 	uint8_t *hash_key = rss_cfg->key;
687c37ca66fSWei Hu (Xavier) 	int ret, ret1;
688c37ca66fSWei Hu (Xavier) 
689c37ca66fSWei Hu (Xavier) 	enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
690c37ca66fSWei Hu (Xavier) 
69178b37190SLijun Ou 	switch (hw->rss_info.conf.func) {
69278b37190SLijun Ou 	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
69378b37190SLijun Ou 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
69478b37190SLijun Ou 		break;
69578b37190SLijun Ou 	case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
69678b37190SLijun Ou 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
69778b37190SLijun Ou 		break;
69878b37190SLijun Ou 	default:
69978b37190SLijun Ou 		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
70078b37190SLijun Ou 		break;
70178b37190SLijun Ou 	}
70278b37190SLijun Ou 
703920be799SLijun Ou 	/* When RSS is off, redirect the packet queue 0 */
704ccf93f56SHao Chen 	if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) == 0)
705c37ca66fSWei Hu (Xavier) 		hns3_rss_uninit(hns);
706c37ca66fSWei Hu (Xavier) 
707c37ca66fSWei Hu (Xavier) 	/* Configure RSS hash algorithm and hash key offset */
70878b37190SLijun Ou 	ret = hns3_set_rss_algo_key(hw, hash_key);
709c37ca66fSWei Hu (Xavier) 	if (ret)
710c37ca66fSWei Hu (Xavier) 		return ret;
711c37ca66fSWei Hu (Xavier) 
712c37ca66fSWei Hu (Xavier) 	/* Configure the tuple selection for RSS hash input */
713c37ca66fSWei Hu (Xavier) 	ret = hns3_set_rss_input_tuple(hw);
714c37ca66fSWei Hu (Xavier) 	if (ret)
715c37ca66fSWei Hu (Xavier) 		return ret;
716c37ca66fSWei Hu (Xavier) 
717920be799SLijun Ou 	/*
718920be799SLijun Ou 	 * When RSS is off, it doesn't need to configure rss redirection table
719920be799SLijun Ou 	 * to hardware.
720920be799SLijun Ou 	 */
721920be799SLijun Ou 	if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) {
722c37ca66fSWei Hu (Xavier) 		ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
723c37ca66fSWei Hu (Xavier) 					       HNS3_RSS_IND_TBL_SIZE);
724c37ca66fSWei Hu (Xavier) 		if (ret)
725c37ca66fSWei Hu (Xavier) 			goto rss_tuple_uninit;
726920be799SLijun Ou 	}
727c37ca66fSWei Hu (Xavier) 
728c37ca66fSWei Hu (Xavier) 	ret = hns3_set_rss_tc_mode(hw);
729c37ca66fSWei Hu (Xavier) 	if (ret)
730c37ca66fSWei Hu (Xavier) 		goto rss_indir_table_uninit;
731c37ca66fSWei Hu (Xavier) 
732c37ca66fSWei Hu (Xavier) 	return ret;
733c37ca66fSWei Hu (Xavier) 
734c37ca66fSWei Hu (Xavier) rss_indir_table_uninit:
735920be799SLijun Ou 	if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) {
736c37ca66fSWei Hu (Xavier) 		ret1 = hns3_rss_reset_indir_table(hw);
737c37ca66fSWei Hu (Xavier) 		if (ret1 != 0)
738c37ca66fSWei Hu (Xavier) 			return ret;
739920be799SLijun Ou 	}
740c37ca66fSWei Hu (Xavier) 
741c37ca66fSWei Hu (Xavier) rss_tuple_uninit:
742c37ca66fSWei Hu (Xavier) 	hns3_rss_tuple_uninit(hw);
743c37ca66fSWei Hu (Xavier) 
744c37ca66fSWei Hu (Xavier) 	/* Disable RSS */
745c37ca66fSWei Hu (Xavier) 	hw->rss_info.conf.types = 0;
746c37ca66fSWei Hu (Xavier) 
747c37ca66fSWei Hu (Xavier) 	return ret;
748c37ca66fSWei Hu (Xavier) }
749c37ca66fSWei Hu (Xavier) 
750c37ca66fSWei Hu (Xavier) /*
751c37ca66fSWei Hu (Xavier)  * RSS uninitialization for hns3 pmd driver.
752c37ca66fSWei Hu (Xavier)  */
753c37ca66fSWei Hu (Xavier) void
754c37ca66fSWei Hu (Xavier) hns3_rss_uninit(struct hns3_adapter *hns)
755c37ca66fSWei Hu (Xavier) {
756c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
757c37ca66fSWei Hu (Xavier) 	int ret;
758c37ca66fSWei Hu (Xavier) 
759c37ca66fSWei Hu (Xavier) 	hns3_rss_tuple_uninit(hw);
760c37ca66fSWei Hu (Xavier) 	ret = hns3_rss_reset_indir_table(hw);
761c37ca66fSWei Hu (Xavier) 	if (ret != 0)
762c37ca66fSWei Hu (Xavier) 		return;
763c37ca66fSWei Hu (Xavier) 
764c37ca66fSWei Hu (Xavier) 	/* Disable RSS */
765c37ca66fSWei Hu (Xavier) 	hw->rss_info.conf.types = 0;
766c37ca66fSWei Hu (Xavier) }
767