xref: /linux/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2021-2021 Hisilicon Limited.
3 #include <linux/skbuff.h>
4 
5 #include "hnae3.h"
6 #include "hclge_comm_cmd.h"
7 #include "hclge_comm_rss.h"
8 
9 static const u8 hclge_comm_hash_key[] = {
10 	0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
11 	0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
12 	0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
13 	0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
14 	0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA
15 };
16 
17 static void
hclge_comm_init_rss_tuple(struct hnae3_ae_dev * ae_dev,struct hclge_comm_rss_tuple_cfg * rss_tuple_cfg)18 hclge_comm_init_rss_tuple(struct hnae3_ae_dev *ae_dev,
19 			  struct hclge_comm_rss_tuple_cfg *rss_tuple_cfg)
20 {
21 	rss_tuple_cfg->ipv4_tcp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
22 	rss_tuple_cfg->ipv4_udp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
23 	rss_tuple_cfg->ipv4_sctp_en = HCLGE_COMM_RSS_INPUT_TUPLE_SCTP;
24 	rss_tuple_cfg->ipv4_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
25 	rss_tuple_cfg->ipv6_tcp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
26 	rss_tuple_cfg->ipv6_udp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
27 	rss_tuple_cfg->ipv6_sctp_en =
28 		ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ?
29 		HCLGE_COMM_RSS_INPUT_TUPLE_SCTP_NO_PORT :
30 		HCLGE_COMM_RSS_INPUT_TUPLE_SCTP;
31 	rss_tuple_cfg->ipv6_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
32 }
33 
hclge_comm_rss_init_cfg(struct hnae3_handle * nic,struct hnae3_ae_dev * ae_dev,struct hclge_comm_rss_cfg * rss_cfg)34 int hclge_comm_rss_init_cfg(struct hnae3_handle *nic,
35 			    struct hnae3_ae_dev *ae_dev,
36 			    struct hclge_comm_rss_cfg *rss_cfg)
37 {
38 	u16 rss_ind_tbl_size = ae_dev->dev_specs.rss_ind_tbl_size;
39 	int rss_algo = HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ;
40 	u16 *rss_ind_tbl;
41 
42 	if (nic->flags & HNAE3_SUPPORT_VF)
43 		rss_cfg->rss_size = nic->kinfo.rss_size;
44 
45 	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2)
46 		rss_algo = HCLGE_COMM_RSS_HASH_ALGO_SIMPLE;
47 
48 	hclge_comm_init_rss_tuple(ae_dev, &rss_cfg->rss_tuple_sets);
49 
50 	rss_cfg->rss_algo = rss_algo;
51 
52 	rss_ind_tbl = devm_kcalloc(&ae_dev->pdev->dev, rss_ind_tbl_size,
53 				   sizeof(*rss_ind_tbl), GFP_KERNEL);
54 	if (!rss_ind_tbl)
55 		return -ENOMEM;
56 
57 	rss_cfg->rss_indirection_tbl = rss_ind_tbl;
58 	memcpy(rss_cfg->rss_hash_key, hclge_comm_hash_key,
59 	       HCLGE_COMM_RSS_KEY_SIZE);
60 
61 	hclge_comm_rss_indir_init_cfg(ae_dev, rss_cfg);
62 
63 	return 0;
64 }
65 EXPORT_SYMBOL_GPL(hclge_comm_rss_init_cfg);
66 
hclge_comm_get_rss_tc_info(u16 rss_size,u8 hw_tc_map,u16 * tc_offset,u16 * tc_valid,u16 * tc_size)67 void hclge_comm_get_rss_tc_info(u16 rss_size, u8 hw_tc_map, u16 *tc_offset,
68 				u16 *tc_valid, u16 *tc_size)
69 {
70 	u16 roundup_size;
71 	u32 i;
72 
73 	roundup_size = roundup_pow_of_two(rss_size);
74 	roundup_size = ilog2(roundup_size);
75 
76 	for (i = 0; i < HCLGE_COMM_MAX_TC_NUM; i++) {
77 		tc_valid[i] = 1;
78 		tc_size[i] = roundup_size;
79 		tc_offset[i] = (hw_tc_map & BIT(i)) ? rss_size * i : 0;
80 	}
81 }
82 EXPORT_SYMBOL_GPL(hclge_comm_get_rss_tc_info);
83 
hclge_comm_set_rss_tc_mode(struct hclge_comm_hw * hw,u16 * tc_offset,u16 * tc_valid,u16 * tc_size)84 int hclge_comm_set_rss_tc_mode(struct hclge_comm_hw *hw, u16 *tc_offset,
85 			       u16 *tc_valid, u16 *tc_size)
86 {
87 	struct hclge_comm_rss_tc_mode_cmd *req;
88 	struct hclge_desc desc;
89 	unsigned int i;
90 	int ret;
91 
92 	req = (struct hclge_comm_rss_tc_mode_cmd *)desc.data;
93 
94 	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_TC_MODE, false);
95 	for (i = 0; i < HCLGE_COMM_MAX_TC_NUM; i++) {
96 		u16 mode = 0;
97 
98 		hnae3_set_bit(mode, HCLGE_COMM_RSS_TC_VALID_B,
99 			      (tc_valid[i] & 0x1));
100 		hnae3_set_field(mode, HCLGE_COMM_RSS_TC_SIZE_M,
101 				HCLGE_COMM_RSS_TC_SIZE_S, tc_size[i]);
102 		hnae3_set_bit(mode, HCLGE_COMM_RSS_TC_SIZE_MSB_B,
103 			      tc_size[i] >> HCLGE_COMM_RSS_TC_SIZE_MSB_OFFSET &
104 			      0x1);
105 		hnae3_set_field(mode, HCLGE_COMM_RSS_TC_OFFSET_M,
106 				HCLGE_COMM_RSS_TC_OFFSET_S, tc_offset[i]);
107 
108 		req->rss_tc_mode[i] = cpu_to_le16(mode);
109 	}
110 
111 	ret = hclge_comm_cmd_send(hw, &desc, 1);
112 	if (ret)
113 		dev_err(&hw->cmq.csq.pdev->dev,
114 			"failed to set rss tc mode, ret = %d.\n", ret);
115 
116 	return ret;
117 }
118 EXPORT_SYMBOL_GPL(hclge_comm_set_rss_tc_mode);
119 
hclge_comm_set_rss_hash_key(struct hclge_comm_rss_cfg * rss_cfg,struct hclge_comm_hw * hw,const u8 * key,const u8 hfunc)120 int hclge_comm_set_rss_hash_key(struct hclge_comm_rss_cfg *rss_cfg,
121 				struct hclge_comm_hw *hw, const u8 *key,
122 				const u8 hfunc)
123 {
124 	u8 hash_algo;
125 	int ret;
126 
127 	ret = hclge_comm_parse_rss_hfunc(rss_cfg, hfunc, &hash_algo);
128 	if (ret)
129 		return ret;
130 
131 	/* Set the RSS Hash Key if specififed by the user */
132 	if (key) {
133 		ret = hclge_comm_set_rss_algo_key(hw, hash_algo, key);
134 		if (ret)
135 			return ret;
136 
137 		/* Update the shadow RSS key with user specified qids */
138 		memcpy(rss_cfg->rss_hash_key, key, HCLGE_COMM_RSS_KEY_SIZE);
139 	} else {
140 		ret = hclge_comm_set_rss_algo_key(hw, hash_algo,
141 						  rss_cfg->rss_hash_key);
142 		if (ret)
143 			return ret;
144 	}
145 	rss_cfg->rss_algo = hash_algo;
146 
147 	return 0;
148 }
149 EXPORT_SYMBOL_GPL(hclge_comm_set_rss_hash_key);
150 
hclge_comm_set_rss_tuple(struct hnae3_ae_dev * ae_dev,struct hclge_comm_hw * hw,struct hclge_comm_rss_cfg * rss_cfg,struct ethtool_rxnfc * nfc)151 int hclge_comm_set_rss_tuple(struct hnae3_ae_dev *ae_dev,
152 			     struct hclge_comm_hw *hw,
153 			     struct hclge_comm_rss_cfg *rss_cfg,
154 			     struct ethtool_rxnfc *nfc)
155 {
156 	struct hclge_comm_rss_input_tuple_cmd *req;
157 	struct hclge_desc desc;
158 	int ret;
159 
160 	if (nfc->data &
161 	    ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
162 		return -EINVAL;
163 
164 	req = (struct hclge_comm_rss_input_tuple_cmd *)desc.data;
165 	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE,
166 					false);
167 
168 	ret = hclge_comm_init_rss_tuple_cmd(rss_cfg, nfc, ae_dev, req);
169 	if (ret) {
170 		dev_err(&hw->cmq.csq.pdev->dev,
171 			"failed to init rss tuple cmd, ret = %d.\n", ret);
172 		return ret;
173 	}
174 
175 	ret = hclge_comm_cmd_send(hw, &desc, 1);
176 	if (ret) {
177 		dev_err(&hw->cmq.csq.pdev->dev,
178 			"failed to set rss tuple, ret = %d.\n", ret);
179 		return ret;
180 	}
181 
182 	rss_cfg->rss_tuple_sets.ipv4_tcp_en = req->ipv4_tcp_en;
183 	rss_cfg->rss_tuple_sets.ipv4_udp_en = req->ipv4_udp_en;
184 	rss_cfg->rss_tuple_sets.ipv4_sctp_en = req->ipv4_sctp_en;
185 	rss_cfg->rss_tuple_sets.ipv4_fragment_en = req->ipv4_fragment_en;
186 	rss_cfg->rss_tuple_sets.ipv6_tcp_en = req->ipv6_tcp_en;
187 	rss_cfg->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en;
188 	rss_cfg->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en;
189 	rss_cfg->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en;
190 	return 0;
191 }
192 EXPORT_SYMBOL_GPL(hclge_comm_set_rss_tuple);
193 
hclge_comm_get_rss_key_size(struct hnae3_handle * handle)194 u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle)
195 {
196 	return HCLGE_COMM_RSS_KEY_SIZE;
197 }
198 EXPORT_SYMBOL_GPL(hclge_comm_get_rss_key_size);
199 
hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg * rss_cfg,const u8 hfunc,u8 * hash_algo)200 int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg,
201 			       const u8 hfunc, u8 *hash_algo)
202 {
203 	switch (hfunc) {
204 	case ETH_RSS_HASH_TOP:
205 		*hash_algo = HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ;
206 		return 0;
207 	case ETH_RSS_HASH_XOR:
208 		*hash_algo = HCLGE_COMM_RSS_HASH_ALGO_SIMPLE;
209 		return 0;
210 	case ETH_RSS_HASH_NO_CHANGE:
211 		*hash_algo = rss_cfg->rss_algo;
212 		return 0;
213 	default:
214 		return -EINVAL;
215 	}
216 }
217 
hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev * ae_dev,struct hclge_comm_rss_cfg * rss_cfg)218 void hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev *ae_dev,
219 				   struct hclge_comm_rss_cfg *rss_cfg)
220 {
221 	u16 i;
222 	/* Initialize RSS indirect table */
223 	for (i = 0; i < ae_dev->dev_specs.rss_ind_tbl_size; i++)
224 		rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size;
225 }
226 EXPORT_SYMBOL_GPL(hclge_comm_rss_indir_init_cfg);
227 
hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg * rss_cfg,int flow_type,u8 * tuple_sets)228 int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type,
229 			     u8 *tuple_sets)
230 {
231 	switch (flow_type) {
232 	case TCP_V4_FLOW:
233 		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_tcp_en;
234 		break;
235 	case UDP_V4_FLOW:
236 		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_udp_en;
237 		break;
238 	case TCP_V6_FLOW:
239 		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_tcp_en;
240 		break;
241 	case UDP_V6_FLOW:
242 		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_udp_en;
243 		break;
244 	case SCTP_V4_FLOW:
245 		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_sctp_en;
246 		break;
247 	case SCTP_V6_FLOW:
248 		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
249 		break;
250 	case IPV4_FLOW:
251 	case IPV6_FLOW:
252 		*tuple_sets = HCLGE_COMM_S_IP_BIT | HCLGE_COMM_D_IP_BIT;
253 		break;
254 	default:
255 		return -EINVAL;
256 	}
257 
258 	return 0;
259 }
260 EXPORT_SYMBOL_GPL(hclge_comm_get_rss_tuple);
261 
262 static void
hclge_comm_append_rss_msb_info(struct hclge_comm_rss_ind_tbl_cmd * req,u16 qid,u32 j)263 hclge_comm_append_rss_msb_info(struct hclge_comm_rss_ind_tbl_cmd *req,
264 			       u16 qid, u32 j)
265 {
266 	u8 rss_msb_oft;
267 	u8 rss_msb_val;
268 
269 	rss_msb_oft =
270 		j * HCLGE_COMM_RSS_CFG_TBL_BW_H / BITS_PER_BYTE;
271 	rss_msb_val = (qid >> HCLGE_COMM_RSS_CFG_TBL_BW_L & 0x1) <<
272 		(j * HCLGE_COMM_RSS_CFG_TBL_BW_H % BITS_PER_BYTE);
273 	req->rss_qid_h[rss_msb_oft] |= rss_msb_val;
274 }
275 
hclge_comm_set_rss_indir_table(struct hnae3_ae_dev * ae_dev,struct hclge_comm_hw * hw,const u16 * indir)276 int hclge_comm_set_rss_indir_table(struct hnae3_ae_dev *ae_dev,
277 				   struct hclge_comm_hw *hw, const u16 *indir)
278 {
279 	struct hclge_comm_rss_ind_tbl_cmd *req;
280 	struct hclge_desc desc;
281 	u16 rss_cfg_tbl_num;
282 	int ret;
283 	u16 qid;
284 	u16 i;
285 	u32 j;
286 
287 	req = (struct hclge_comm_rss_ind_tbl_cmd *)desc.data;
288 	rss_cfg_tbl_num = ae_dev->dev_specs.rss_ind_tbl_size /
289 			  HCLGE_COMM_RSS_CFG_TBL_SIZE;
290 
291 	for (i = 0; i < rss_cfg_tbl_num; i++) {
292 		hclge_comm_cmd_setup_basic_desc(&desc,
293 						HCLGE_OPC_RSS_INDIR_TABLE,
294 						false);
295 
296 		req->start_table_index =
297 			cpu_to_le16(i * HCLGE_COMM_RSS_CFG_TBL_SIZE);
298 		req->rss_set_bitmap =
299 			cpu_to_le16(HCLGE_COMM_RSS_SET_BITMAP_MSK);
300 		for (j = 0; j < HCLGE_COMM_RSS_CFG_TBL_SIZE; j++) {
301 			qid = indir[i * HCLGE_COMM_RSS_CFG_TBL_SIZE + j];
302 			req->rss_qid_l[j] = qid & 0xff;
303 			hclge_comm_append_rss_msb_info(req, qid, j);
304 		}
305 		ret = hclge_comm_cmd_send(hw, &desc, 1);
306 		if (ret) {
307 			dev_err(&hw->cmq.csq.pdev->dev,
308 				"failed to configure rss table, ret = %d.\n",
309 				ret);
310 			return ret;
311 		}
312 	}
313 	return 0;
314 }
315 EXPORT_SYMBOL_GPL(hclge_comm_set_rss_indir_table);
316 
hclge_comm_set_rss_input_tuple(struct hclge_comm_hw * hw,struct hclge_comm_rss_cfg * rss_cfg)317 int hclge_comm_set_rss_input_tuple(struct hclge_comm_hw *hw,
318 				   struct hclge_comm_rss_cfg *rss_cfg)
319 {
320 	struct hclge_comm_rss_input_tuple_cmd *req;
321 	struct hclge_desc desc;
322 	int ret;
323 
324 	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE,
325 					false);
326 
327 	req = (struct hclge_comm_rss_input_tuple_cmd *)desc.data;
328 
329 	req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en;
330 	req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en;
331 	req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en;
332 	req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en;
333 	req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en;
334 	req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en;
335 	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
336 	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;
337 
338 	ret = hclge_comm_cmd_send(hw, &desc, 1);
339 	if (ret)
340 		dev_err(&hw->cmq.csq.pdev->dev,
341 			"failed to configure rss input, ret = %d.\n", ret);
342 	return ret;
343 }
344 EXPORT_SYMBOL_GPL(hclge_comm_set_rss_input_tuple);
345 
hclge_comm_get_rss_hash_info(struct hclge_comm_rss_cfg * rss_cfg,u8 * key,u8 * hfunc)346 void hclge_comm_get_rss_hash_info(struct hclge_comm_rss_cfg *rss_cfg, u8 *key,
347 				  u8 *hfunc)
348 {
349 	/* Get hash algorithm */
350 	if (hfunc) {
351 		switch (rss_cfg->rss_algo) {
352 		case HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ:
353 			*hfunc = ETH_RSS_HASH_TOP;
354 			break;
355 		case HCLGE_COMM_RSS_HASH_ALGO_SIMPLE:
356 			*hfunc = ETH_RSS_HASH_XOR;
357 			break;
358 		default:
359 			*hfunc = ETH_RSS_HASH_UNKNOWN;
360 			break;
361 		}
362 	}
363 
364 	/* Get the RSS Key required by the user */
365 	if (key)
366 		memcpy(key, rss_cfg->rss_hash_key, HCLGE_COMM_RSS_KEY_SIZE);
367 }
368 EXPORT_SYMBOL_GPL(hclge_comm_get_rss_hash_info);
369 
hclge_comm_get_rss_indir_tbl(struct hclge_comm_rss_cfg * rss_cfg,u32 * indir,u16 rss_ind_tbl_size)370 void hclge_comm_get_rss_indir_tbl(struct hclge_comm_rss_cfg *rss_cfg,
371 				  u32 *indir, u16 rss_ind_tbl_size)
372 {
373 	u16 i;
374 
375 	if (!indir)
376 		return;
377 
378 	for (i = 0; i < rss_ind_tbl_size; i++)
379 		indir[i] = rss_cfg->rss_indirection_tbl[i];
380 }
381 EXPORT_SYMBOL_GPL(hclge_comm_get_rss_indir_tbl);
382 
hclge_comm_set_rss_algo_key(struct hclge_comm_hw * hw,const u8 hfunc,const u8 * key)383 int hclge_comm_set_rss_algo_key(struct hclge_comm_hw *hw, const u8 hfunc,
384 				const u8 *key)
385 {
386 	struct hclge_comm_rss_config_cmd *req;
387 	unsigned int key_offset = 0;
388 	struct hclge_desc desc;
389 	int key_counts;
390 	int key_size;
391 	int ret;
392 
393 	key_counts = HCLGE_COMM_RSS_KEY_SIZE;
394 	req = (struct hclge_comm_rss_config_cmd *)desc.data;
395 
396 	while (key_counts) {
397 		hclge_comm_cmd_setup_basic_desc(&desc,
398 						HCLGE_OPC_RSS_GENERIC_CONFIG,
399 						false);
400 
401 		req->hash_config |= (hfunc & HCLGE_COMM_RSS_HASH_ALGO_MASK);
402 		req->hash_config |=
403 			(key_offset << HCLGE_COMM_RSS_HASH_KEY_OFFSET_B);
404 
405 		key_size = min(HCLGE_COMM_RSS_HASH_KEY_NUM, key_counts);
406 		memcpy(req->hash_key,
407 		       key + key_offset * HCLGE_COMM_RSS_HASH_KEY_NUM,
408 		       key_size);
409 
410 		key_counts -= key_size;
411 		key_offset++;
412 		ret = hclge_comm_cmd_send(hw, &desc, 1);
413 		if (ret) {
414 			dev_err(&hw->cmq.csq.pdev->dev,
415 				"failed to configure RSS key, ret = %d.\n",
416 				ret);
417 			return ret;
418 		}
419 	}
420 
421 	return 0;
422 }
423 EXPORT_SYMBOL_GPL(hclge_comm_set_rss_algo_key);
424 
hclge_comm_get_rss_hash_bits(struct ethtool_rxnfc * nfc)425 static u8 hclge_comm_get_rss_hash_bits(struct ethtool_rxnfc *nfc)
426 {
427 	u8 hash_sets = nfc->data & RXH_L4_B_0_1 ? HCLGE_COMM_S_PORT_BIT : 0;
428 
429 	if (nfc->data & RXH_L4_B_2_3)
430 		hash_sets |= HCLGE_COMM_D_PORT_BIT;
431 	else
432 		hash_sets &= ~HCLGE_COMM_D_PORT_BIT;
433 
434 	if (nfc->data & RXH_IP_SRC)
435 		hash_sets |= HCLGE_COMM_S_IP_BIT;
436 	else
437 		hash_sets &= ~HCLGE_COMM_S_IP_BIT;
438 
439 	if (nfc->data & RXH_IP_DST)
440 		hash_sets |= HCLGE_COMM_D_IP_BIT;
441 	else
442 		hash_sets &= ~HCLGE_COMM_D_IP_BIT;
443 
444 	if (nfc->flow_type == SCTP_V4_FLOW || nfc->flow_type == SCTP_V6_FLOW)
445 		hash_sets |= HCLGE_COMM_V_TAG_BIT;
446 
447 	return hash_sets;
448 }
449 
hclge_comm_init_rss_tuple_cmd(struct hclge_comm_rss_cfg * rss_cfg,struct ethtool_rxnfc * nfc,struct hnae3_ae_dev * ae_dev,struct hclge_comm_rss_input_tuple_cmd * req)450 int hclge_comm_init_rss_tuple_cmd(struct hclge_comm_rss_cfg *rss_cfg,
451 				  struct ethtool_rxnfc *nfc,
452 				  struct hnae3_ae_dev *ae_dev,
453 				  struct hclge_comm_rss_input_tuple_cmd *req)
454 {
455 	u8 tuple_sets;
456 
457 	req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en;
458 	req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en;
459 	req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en;
460 	req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en;
461 	req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en;
462 	req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en;
463 	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
464 	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;
465 
466 	tuple_sets = hclge_comm_get_rss_hash_bits(nfc);
467 	switch (nfc->flow_type) {
468 	case TCP_V4_FLOW:
469 		req->ipv4_tcp_en = tuple_sets;
470 		break;
471 	case TCP_V6_FLOW:
472 		req->ipv6_tcp_en = tuple_sets;
473 		break;
474 	case UDP_V4_FLOW:
475 		req->ipv4_udp_en = tuple_sets;
476 		break;
477 	case UDP_V6_FLOW:
478 		req->ipv6_udp_en = tuple_sets;
479 		break;
480 	case SCTP_V4_FLOW:
481 		req->ipv4_sctp_en = tuple_sets;
482 		break;
483 	case SCTP_V6_FLOW:
484 		if (ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&
485 		    (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)))
486 			return -EINVAL;
487 
488 		req->ipv6_sctp_en = tuple_sets;
489 		break;
490 	case IPV4_FLOW:
491 		req->ipv4_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
492 		break;
493 	case IPV6_FLOW:
494 		req->ipv6_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
495 		break;
496 	default:
497 		return -EINVAL;
498 	}
499 
500 	return 0;
501 }
502 
hclge_comm_convert_rss_tuple(u8 tuple_sets)503 u64 hclge_comm_convert_rss_tuple(u8 tuple_sets)
504 {
505 	u64 tuple_data = 0;
506 
507 	if (tuple_sets & HCLGE_COMM_D_PORT_BIT)
508 		tuple_data |= RXH_L4_B_2_3;
509 	if (tuple_sets & HCLGE_COMM_S_PORT_BIT)
510 		tuple_data |= RXH_L4_B_0_1;
511 	if (tuple_sets & HCLGE_COMM_D_IP_BIT)
512 		tuple_data |= RXH_IP_DST;
513 	if (tuple_sets & HCLGE_COMM_S_IP_BIT)
514 		tuple_data |= RXH_IP_SRC;
515 
516 	return tuple_data;
517 }
518 EXPORT_SYMBOL_GPL(hclge_comm_convert_rss_tuple);
519