xref: /dpdk/drivers/net/hns3/hns3_rss.c (revision bb1f4717636f5b7d27f4f2fe30469b69d8910bd0)
1c37ca66fSWei Hu (Xavier) /* SPDX-License-Identifier: BSD-3-Clause
253e6f86cSMin Hu (Connor)  * Copyright(c) 2018-2021 HiSilicon Limited.
3c37ca66fSWei Hu (Xavier)  */
4c37ca66fSWei Hu (Xavier) 
5c37ca66fSWei Hu (Xavier) #include <rte_ethdev.h>
6c37ca66fSWei Hu (Xavier) #include <rte_io.h>
7c37ca66fSWei Hu (Xavier) #include <rte_malloc.h>
8c37ca66fSWei Hu (Xavier) 
9c37ca66fSWei Hu (Xavier) #include "hns3_ethdev.h"
10c37ca66fSWei Hu (Xavier) #include "hns3_logs.h"
11c37ca66fSWei Hu (Xavier) 
12d7050da8SHuisong Li /* Default hash keys */
1382c2ca6dSMin Hu (Connor) const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE] = {
14c37ca66fSWei Hu (Xavier) 	0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
15c37ca66fSWei Hu (Xavier) 	0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
16c37ca66fSWei Hu (Xavier) 	0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
17c37ca66fSWei Hu (Xavier) 	0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
18c37ca66fSWei Hu (Xavier) 	0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA
19c37ca66fSWei Hu (Xavier) };
20c37ca66fSWei Hu (Xavier) 
21e3069658SHuisong Li const uint8_t hns3_hash_func_map[] = {
22e3069658SHuisong Li 	[RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
23e3069658SHuisong Li 	[RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
24e3069658SHuisong Li 	[RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE,
25e3069658SHuisong Li 	[RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP,
26806f1d5aSLijun Ou };
27806f1d5aSLijun Ou 
282bd90635SHuisong Li enum hns3_rss_tuple_type {
292bd90635SHuisong Li 	HNS3_RSS_IP_TUPLE,
302bd90635SHuisong Li 	HNS3_RSS_IP_L4_TUPLE,
31806f1d5aSLijun Ou };
32806f1d5aSLijun Ou 
33806f1d5aSLijun Ou static const struct {
34806f1d5aSLijun Ou 	uint64_t rss_types;
352bd90635SHuisong Li 	uint16_t tuple_type;
36806f1d5aSLijun Ou 	uint64_t rss_field;
37406b25c7SHuisong Li 	uint64_t tuple_mask;
382bd90635SHuisong Li } hns3_set_tuple_table[] = {
392bd90635SHuisong Li 	/* IPV4-FRAG */
402bd90635SHuisong Li 	{ RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
412bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
42406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S),
43406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_FLAG_M },
442bd90635SHuisong Li 	{ RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
452bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
46406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D),
47406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_FLAG_M },
482bd90635SHuisong Li 	{ RTE_ETH_RSS_FRAG_IPV4,
492bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
502bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) |
51406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D),
52406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_FLAG_M },
532bd90635SHuisong Li 
542bd90635SHuisong Li 	/* IPV4 */
552bd90635SHuisong Li 	{ RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
562bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
57406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S),
58406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_NONF_M },
592bd90635SHuisong Li 	{ RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
602bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
61406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
62406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_NONF_M },
632bd90635SHuisong Li 	{ RTE_ETH_RSS_IPV4,
642bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
652bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
66406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
67406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_NONF_M },
682bd90635SHuisong Li 
692bd90635SHuisong Li 	/* IPV4-OTHER */
702bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
712bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
72406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S),
73406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_NONF_M },
742bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
752bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
76406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
77406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_NONF_M },
782bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
792bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
802bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
81406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
82406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_NONF_M },
832bd90635SHuisong Li 
842bd90635SHuisong Li 	/* IPV4-TCP */
852bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
862bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
87406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S),
88406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_TCP_M },
892bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY,
902bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
91406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D),
92406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_TCP_M },
932bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
942bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
95406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S),
96406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_TCP_M },
972bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY,
982bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
99406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D),
100406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_TCP_M },
1012bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_TCP,
1022bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
1032bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) |
104806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) |
105806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) |
106406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D),
107406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_TCP_M },
1082bd90635SHuisong Li 
1092bd90635SHuisong Li 	/* IPV4-UDP */
1102bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
1112bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
112406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S),
113406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_UDP_M },
1142bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY,
1152bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
116406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D),
117406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_UDP_M },
1182bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
1192bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
120406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S),
121406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_UDP_M },
1222bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY,
1232bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
124406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D),
125406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_UDP_M },
1262bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_UDP,
1272bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
1282bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) |
129806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) |
130806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) |
131406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D),
132406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_UDP_M },
1332bd90635SHuisong Li 
1342bd90635SHuisong Li 	/* IPV4-SCTP */
1352bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
1362bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
137406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S),
138406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_SCTP_M },
1392bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
1402bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
141406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D),
142406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_SCTP_M },
1432bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
1442bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
145406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S),
146406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_SCTP_M },
1472bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
1482bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
149406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D),
150406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_SCTP_M },
1512bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
1522bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
1532bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) |
154806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) |
155806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) |
156*bb1f4717SJie Hai 	  BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D),
157406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV4_SCTP_M },
1582bd90635SHuisong Li 
1592bd90635SHuisong Li 	/* IPV6-FRAG */
1602bd90635SHuisong Li 	{ RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
1612bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
162406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S),
163406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_FLAG_M },
1642bd90635SHuisong Li 	{ RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
1652bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
166406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D),
167406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_FLAG_M },
1682bd90635SHuisong Li 	{ RTE_ETH_RSS_FRAG_IPV6,
1692bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
1702bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) |
171406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D),
172406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_FLAG_M },
1732bd90635SHuisong Li 
1742bd90635SHuisong Li 	/* IPV6 */
1752bd90635SHuisong Li 	{ RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
1762bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
177406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S),
178406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_NONF_M },
1792bd90635SHuisong Li 	{ RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
1802bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
181406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
182406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_NONF_M },
1832bd90635SHuisong Li 	{ RTE_ETH_RSS_IPV6,
1842bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
1852bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
186406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
187406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_NONF_M },
1882bd90635SHuisong Li 
1892bd90635SHuisong Li 	/* IPV6-OTHER */
1902bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
1912bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
192406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S),
193406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_NONF_M },
1942bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
1952bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
196406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
197406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_NONF_M },
1982bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
1992bd90635SHuisong Li 	  HNS3_RSS_IP_TUPLE,
2002bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
201406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
202406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_NONF_M },
2032bd90635SHuisong Li 
2042bd90635SHuisong Li 	/* IPV6-TCP */
2052bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
2062bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
207406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S),
208406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_TCP_M },
2092bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY,
2102bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
211406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D),
212406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_TCP_M },
2132bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
2142bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
215406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S),
216406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_TCP_M },
2172bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY,
2182bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
219406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D),
220406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_TCP_M },
2212bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_TCP,
2222bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
2232bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) |
224806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) |
225806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) |
226406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D),
227406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_TCP_M },
2282bd90635SHuisong Li 
2292bd90635SHuisong Li 	/* IPV6-UDP */
2302bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
2312bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
232406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S),
233406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_UDP_M },
2342bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY,
2352bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
236406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D),
237406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_UDP_M },
2382bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
2392bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
240406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S),
241406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_UDP_M },
2422bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY,
2432bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
244406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D),
245406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_UDP_M },
2462bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_UDP,
2472bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
2482bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) |
249806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) |
250806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) |
251406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D),
252406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_UDP_M },
2532bd90635SHuisong Li 
2542bd90635SHuisong Li 	/* IPV6-SCTP */
2552bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
2562bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
257406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S),
258406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_SCTP_M },
2592bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
2602bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
261406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D),
262406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_SCTP_M },
2632bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
2642bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
265406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S),
266406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_SCTP_M },
2672bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
2682bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
269406b25c7SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D),
270406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_SCTP_M },
2712bd90635SHuisong Li 	{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
2722bd90635SHuisong Li 	  HNS3_RSS_IP_L4_TUPLE,
2732bd90635SHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) |
274806f1d5aSLijun Ou 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) |
2752ecfc36cSHuisong Li 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
276*bb1f4717SJie Hai 	  BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S),
277406b25c7SHuisong Li 	  HNS3_RSS_TUPLE_IPV6_SCTP_M },
278806f1d5aSLijun Ou };
279806f1d5aSLijun Ou 
280c37ca66fSWei Hu (Xavier) /*
281c37ca66fSWei Hu (Xavier)  * rss_generic_config command function, opcode:0x0D01.
28288347111SHuisong Li  * Used to set algorithm and hash key of RSS.
283c37ca66fSWei Hu (Xavier)  */
2844d996f3bSJie Hai static int
hns3_rss_set_algo_key(struct hns3_hw * hw,uint8_t hash_algo,const uint8_t * key,uint8_t key_len)28588347111SHuisong Li hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
28688347111SHuisong Li 		      const uint8_t *key, uint8_t key_len)
287c37ca66fSWei Hu (Xavier) {
288c37ca66fSWei Hu (Xavier) 	struct hns3_rss_generic_config_cmd *req;
289c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
29088347111SHuisong Li 	const uint8_t *cur_key;
29188347111SHuisong Li 	uint16_t cur_key_size;
29288347111SHuisong Li 	uint16_t max_bd_num;
29388347111SHuisong Li 	uint16_t idx;
294c37ca66fSWei Hu (Xavier) 	int ret;
295c37ca66fSWei Hu (Xavier) 
296c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_generic_config_cmd *)desc.data;
297c37ca66fSWei Hu (Xavier) 
29888347111SHuisong Li 	max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
29988347111SHuisong Li 	for (idx = 0; idx < max_bd_num; idx++) {
300c37ca66fSWei Hu (Xavier) 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
301c37ca66fSWei Hu (Xavier) 					  false);
302c37ca66fSWei Hu (Xavier) 
30388347111SHuisong Li 		req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK);
30488347111SHuisong Li 		req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
305c37ca66fSWei Hu (Xavier) 
306bb38316eSHuisong Li 		if (idx == max_bd_num - 1 &&
307bb38316eSHuisong Li 		    (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
30888347111SHuisong Li 			cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
309c37ca66fSWei Hu (Xavier) 		else
31088347111SHuisong Li 			cur_key_size = HNS3_RSS_HASH_KEY_NUM;
311c37ca66fSWei Hu (Xavier) 
31288347111SHuisong Li 		cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
31388347111SHuisong Li 		memcpy(req->hash_key, cur_key, cur_key_size);
314c37ca66fSWei Hu (Xavier) 
315c37ca66fSWei Hu (Xavier) 		ret = hns3_cmd_send(hw, &desc, 1);
316c37ca66fSWei Hu (Xavier) 		if (ret) {
317c37ca66fSWei Hu (Xavier) 			hns3_err(hw, "Configure RSS algo key failed %d", ret);
318c37ca66fSWei Hu (Xavier) 			return ret;
319c37ca66fSWei Hu (Xavier) 		}
320c37ca66fSWei Hu (Xavier) 	}
321fe9cc8b8SHuisong Li 
322c37ca66fSWei Hu (Xavier) 	return 0;
323c37ca66fSWei Hu (Xavier) }
324c37ca66fSWei Hu (Xavier) 
3254d996f3bSJie Hai static int
hns3_rss_get_algo_key(struct hns3_hw * hw,uint8_t * hash_algo,uint8_t * key,uint8_t key_len)3267da415d2SHuisong Li hns3_rss_get_algo_key(struct hns3_hw *hw,  uint8_t *hash_algo,
3277da415d2SHuisong Li 		      uint8_t *key, uint8_t key_len)
3287da415d2SHuisong Li {
3297da415d2SHuisong Li 	struct hns3_rss_generic_config_cmd *req;
3307da415d2SHuisong Li 	struct hns3_cmd_desc desc;
3317da415d2SHuisong Li 	uint16_t cur_key_size;
3327da415d2SHuisong Li 	uint16_t max_bd_num;
3337da415d2SHuisong Li 	uint8_t *cur_key;
3347da415d2SHuisong Li 	uint16_t idx;
3357da415d2SHuisong Li 	int ret;
3367da415d2SHuisong Li 
3377da415d2SHuisong Li 	req = (struct hns3_rss_generic_config_cmd *)desc.data;
3387da415d2SHuisong Li 	max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
3397da415d2SHuisong Li 	for (idx = 0; idx < max_bd_num; idx++) {
3407da415d2SHuisong Li 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
3417da415d2SHuisong Li 					  true);
3427da415d2SHuisong Li 
3437da415d2SHuisong Li 		req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
3447da415d2SHuisong Li 		ret = hns3_cmd_send(hw, &desc, 1);
3457da415d2SHuisong Li 		if (ret) {
3467da415d2SHuisong Li 			hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d",
3477da415d2SHuisong Li 				 ret);
3487da415d2SHuisong Li 			return ret;
3497da415d2SHuisong Li 		}
3507da415d2SHuisong Li 
3517da415d2SHuisong Li 		if (idx == 0)
3527da415d2SHuisong Li 			*hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK;
3537da415d2SHuisong Li 
3547da415d2SHuisong Li 		if (idx == max_bd_num - 1 &&
3557da415d2SHuisong Li 		    (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
3567da415d2SHuisong Li 			cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
3577da415d2SHuisong Li 		else
3587da415d2SHuisong Li 			cur_key_size = HNS3_RSS_HASH_KEY_NUM;
3597da415d2SHuisong Li 
3607da415d2SHuisong Li 		cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
3617da415d2SHuisong Li 		memcpy(cur_key, req->hash_key, cur_key_size);
3627da415d2SHuisong Li 	}
3637da415d2SHuisong Li 
3647da415d2SHuisong Li 	return 0;
3657da415d2SHuisong Li }
3667da415d2SHuisong Li 
367c37ca66fSWei Hu (Xavier) /*
368c37ca66fSWei Hu (Xavier)  * rss_indirection_table command function, opcode:0x0D07.
369c37ca66fSWei Hu (Xavier)  * Used to configure the indirection table of rss.
370c37ca66fSWei Hu (Xavier)  */
371c37ca66fSWei Hu (Xavier) int
hns3_set_rss_indir_table(struct hns3_hw * hw,uint16_t * indir,uint16_t size)3729a7d3af2SHuisong Li hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
373c37ca66fSWei Hu (Xavier) {
374c37ca66fSWei Hu (Xavier) 	struct hns3_rss_indirection_table_cmd *req;
3754729376eSHuisong Li 	uint16_t max_bd_num, cfg_tbl_size;
376c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
3779a7d3af2SHuisong Li 	uint8_t qid_msb_off;
3789a7d3af2SHuisong Li 	uint8_t qid_msb_val;
3799a7d3af2SHuisong Li 	uint16_t q_id;
3809a7d3af2SHuisong Li 	uint16_t i, j;
3819a7d3af2SHuisong Li 	int ret;
382c37ca66fSWei Hu (Xavier) 
383c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_indirection_table_cmd *)desc.data;
3844729376eSHuisong Li 	max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE);
3854729376eSHuisong Li 	for (i = 0; i < max_bd_num; i++) {
386c37ca66fSWei Hu (Xavier) 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
387c37ca66fSWei Hu (Xavier) 					  false);
388c37ca66fSWei Hu (Xavier) 		req->start_table_index =
389c37ca66fSWei Hu (Xavier) 				rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
390c37ca66fSWei Hu (Xavier) 		req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK);
3914729376eSHuisong Li 
3924729376eSHuisong Li 		if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0)
3934729376eSHuisong Li 			cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE;
3944729376eSHuisong Li 		else
3954729376eSHuisong Li 			cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE;
3964729376eSHuisong Li 
3974729376eSHuisong Li 		for (j = 0; j < cfg_tbl_size; j++) {
3989a7d3af2SHuisong Li 			q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j];
3999a7d3af2SHuisong Li 			req->rss_result_l[j] = q_id & 0xff;
4009a7d3af2SHuisong Li 
4019a7d3af2SHuisong Li 			qid_msb_off =
4029a7d3af2SHuisong Li 				j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
4039a7d3af2SHuisong Li 			qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1)
4049a7d3af2SHuisong Li 					<< (j * HNS3_RSS_CFG_TBL_BW_H %
4059a7d3af2SHuisong Li 					HNS3_BITS_PER_BYTE);
4069a7d3af2SHuisong Li 			req->rss_result_h[qid_msb_off] |= qid_msb_val;
407c37ca66fSWei Hu (Xavier) 		}
4089a7d3af2SHuisong Li 
409c37ca66fSWei Hu (Xavier) 		ret = hns3_cmd_send(hw, &desc, 1);
410c37ca66fSWei Hu (Xavier) 		if (ret) {
411c37ca66fSWei Hu (Xavier) 			hns3_err(hw,
412c37ca66fSWei Hu (Xavier) 				 "Sets RSS indirection table failed %d size %u",
413c37ca66fSWei Hu (Xavier) 				 ret, size);
414c37ca66fSWei Hu (Xavier) 			return ret;
415c37ca66fSWei Hu (Xavier) 		}
416c37ca66fSWei Hu (Xavier) 	}
417c37ca66fSWei Hu (Xavier) 
418c37ca66fSWei Hu (Xavier) 	return 0;
419c37ca66fSWei Hu (Xavier) }
420c37ca66fSWei Hu (Xavier) 
421d1e37d1cSHuisong Li static int
hns3_get_rss_indir_table(struct hns3_hw * hw,uint16_t * indir,uint16_t size)422d1e37d1cSHuisong Li hns3_get_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size)
423d1e37d1cSHuisong Li {
424d1e37d1cSHuisong Li 	struct hns3_rss_indirection_table_cmd *req;
425d1e37d1cSHuisong Li 	uint16_t max_bd_num, cfg_tbl_size;
426d1e37d1cSHuisong Li 	uint8_t qid_msb_off, qid_msb_idx;
427d1e37d1cSHuisong Li 	struct hns3_cmd_desc desc;
428d1e37d1cSHuisong Li 	uint16_t q_id, q_hi, q_lo;
429d1e37d1cSHuisong Li 	uint8_t rss_result_h;
430d1e37d1cSHuisong Li 	uint16_t i, j;
431d1e37d1cSHuisong Li 	int ret;
432d1e37d1cSHuisong Li 
433d1e37d1cSHuisong Li 	req = (struct hns3_rss_indirection_table_cmd *)desc.data;
434d1e37d1cSHuisong Li 	max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE);
435d1e37d1cSHuisong Li 	for (i = 0; i < max_bd_num; i++) {
436d1e37d1cSHuisong Li 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE,
437d1e37d1cSHuisong Li 					  true);
438d1e37d1cSHuisong Li 		req->start_table_index =
439d1e37d1cSHuisong Li 				rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE);
440d1e37d1cSHuisong Li 		ret = hns3_cmd_send(hw, &desc, 1);
441d1e37d1cSHuisong Li 		if (ret) {
442d1e37d1cSHuisong Li 			hns3_err(hw, "fail to get RSS indirection table from firmware, ret = %d",
443d1e37d1cSHuisong Li 				 ret);
444d1e37d1cSHuisong Li 			return ret;
445d1e37d1cSHuisong Li 		}
446d1e37d1cSHuisong Li 
447d1e37d1cSHuisong Li 		if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0)
448d1e37d1cSHuisong Li 			cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE;
449d1e37d1cSHuisong Li 		else
450d1e37d1cSHuisong Li 			cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE;
451d1e37d1cSHuisong Li 
452d1e37d1cSHuisong Li 		for (j = 0; j < cfg_tbl_size; j++) {
453d1e37d1cSHuisong Li 			qid_msb_idx =
454d1e37d1cSHuisong Li 				j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE;
455d1e37d1cSHuisong Li 			rss_result_h = req->rss_result_h[qid_msb_idx];
456d1e37d1cSHuisong Li 			qid_msb_off =
457d1e37d1cSHuisong Li 				j * HNS3_RSS_CFG_TBL_BW_H % HNS3_BITS_PER_BYTE;
458d1e37d1cSHuisong Li 			q_hi = (rss_result_h >> qid_msb_off) &
459d1e37d1cSHuisong Li 						HNS3_RSS_CFG_TBL_BW_H_M;
460d1e37d1cSHuisong Li 			q_lo = req->rss_result_l[j];
461d1e37d1cSHuisong Li 			q_id = (q_hi << HNS3_RSS_CFG_TBL_BW_L) | q_lo;
462d1e37d1cSHuisong Li 			indir[i * HNS3_RSS_CFG_TBL_SIZE + j] = q_id;
463d1e37d1cSHuisong Li 		}
464d1e37d1cSHuisong Li 	}
465d1e37d1cSHuisong Li 
466d1e37d1cSHuisong Li 	return 0;
467d1e37d1cSHuisong Li }
468d1e37d1cSHuisong Li 
469c37ca66fSWei Hu (Xavier) int
hns3_rss_reset_indir_table(struct hns3_hw * hw)470c37ca66fSWei Hu (Xavier) hns3_rss_reset_indir_table(struct hns3_hw *hw)
471c37ca66fSWei Hu (Xavier) {
4729a7d3af2SHuisong Li 	uint16_t *lut;
473c37ca66fSWei Hu (Xavier) 	int ret;
474c37ca66fSWei Hu (Xavier) 
4759a7d3af2SHuisong Li 	lut = rte_zmalloc("hns3_rss_lut",
4760fce2c46SLijun Ou 			  hw->rss_ind_tbl_size * sizeof(uint16_t), 0);
477c37ca66fSWei Hu (Xavier) 	if (lut == NULL) {
478c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "No hns3_rss_lut memory can be allocated");
479c37ca66fSWei Hu (Xavier) 		return -ENOMEM;
480c37ca66fSWei Hu (Xavier) 	}
481c37ca66fSWei Hu (Xavier) 
4820fce2c46SLijun Ou 	ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size);
483a421cb93SHuisong Li 	if (ret != 0)
484a421cb93SHuisong Li 		hns3_err(hw, "RSS uninit indir table failed, ret = %d.", ret);
485a421cb93SHuisong Li 	else
486a421cb93SHuisong Li 		memcpy(hw->rss_info.rss_indirection_tbl, lut,
487a421cb93SHuisong Li 		       sizeof(uint16_t) * hw->rss_ind_tbl_size);
488c37ca66fSWei Hu (Xavier) 	rte_free(lut);
489c37ca66fSWei Hu (Xavier) 
490c37ca66fSWei Hu (Xavier) 	return ret;
491c37ca66fSWei Hu (Xavier) }
492c37ca66fSWei Hu (Xavier) 
493eb3ef9e0SHuisong Li bool
hns3_check_rss_types_valid(struct hns3_hw * hw,uint64_t types)494eb3ef9e0SHuisong Li hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types)
49513c39932SHuisong Li {
49613c39932SHuisong Li 	uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
49713c39932SHuisong Li 			   RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
49813c39932SHuisong Li 			   RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
49913c39932SHuisong Li 			   RTE_ETH_RSS_NONFRAG_IPV6_OTHER;
500eb3ef9e0SHuisong Li 	uint64_t ip_l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP |
50113c39932SHuisong Li 			      RTE_ETH_RSS_NONFRAG_IPV4_UDP |
50213c39932SHuisong Li 			      RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
50313c39932SHuisong Li 			      RTE_ETH_RSS_NONFRAG_IPV6_TCP |
50413c39932SHuisong Li 			      RTE_ETH_RSS_NONFRAG_IPV6_UDP |
50513c39932SHuisong Li 			      RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
506eb3ef9e0SHuisong Li 	bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST);
507eb3ef9e0SHuisong Li 	bool has_ip_pkt = !!(types & ip_mask);
508eb3ef9e0SHuisong Li 	uint64_t final_types;
50913c39932SHuisong Li 
510eb3ef9e0SHuisong Li 	if (types == 0)
511eb3ef9e0SHuisong Li 		return true;
51213c39932SHuisong Li 
513eb3ef9e0SHuisong Li 	if ((types & HNS3_ETH_RSS_SUPPORT) == 0) {
514eb3ef9e0SHuisong Li 		hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.",
515eb3ef9e0SHuisong Li 			 types);
516eb3ef9e0SHuisong Li 		return false;
517eb3ef9e0SHuisong Li 	}
518eb3ef9e0SHuisong Li 
519eb3ef9e0SHuisong Li 	if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 &&
520eb3ef9e0SHuisong Li 	    (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) {
521eb3ef9e0SHuisong Li 		hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set.");
522eb3ef9e0SHuisong Li 		return false;
523eb3ef9e0SHuisong Li 	}
524eb3ef9e0SHuisong Li 
525eb3ef9e0SHuisong Li 	if (has_l4_src_dst && (types & ip_l4_mask) == 0) {
526eb3ef9e0SHuisong Li 		if (!has_ip_pkt) {
527eb3ef9e0SHuisong Li 			hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set.");
528eb3ef9e0SHuisong Li 			return false;
529eb3ef9e0SHuisong Li 		}
530eb3ef9e0SHuisong Li 		/*
531eb3ef9e0SHuisong Li 		 * For the case that the types has L4_SRC/DST_ONLY but hasn't
532eb3ef9e0SHuisong Li 		 * IP-TCP/UDP/SCTP packet type, this types is considered valid
533eb3ef9e0SHuisong Li 		 * if it also has IP packet type.
534eb3ef9e0SHuisong Li 		 */
535eb3ef9e0SHuisong Li 		hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet.");
536eb3ef9e0SHuisong Li 	}
537eb3ef9e0SHuisong Li 
538eb3ef9e0SHuisong Li 	if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) {
539eb3ef9e0SHuisong Li 		final_types = types & HNS3_ETH_RSS_SUPPORT;
540eb3ef9e0SHuisong Li 		hns3_warn(hw, "set RSS types based on hardware support, requested:0x%" PRIx64 " configured:0x%" PRIx64 "",
541eb3ef9e0SHuisong Li 			  types, final_types);
542eb3ef9e0SHuisong Li 	}
543eb3ef9e0SHuisong Li 
544eb3ef9e0SHuisong Li 	return true;
54513c39932SHuisong Li }
54613c39932SHuisong Li 
547e3069658SHuisong Li uint64_t
hns3_rss_calc_tuple_filed(uint64_t rss_hf)548eb3ef9e0SHuisong Li hns3_rss_calc_tuple_filed(uint64_t rss_hf)
5492bd90635SHuisong Li {
5502bd90635SHuisong Li 	uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY |
5512bd90635SHuisong Li 				RTE_ETH_RSS_L3_DST_ONLY;
5522bd90635SHuisong Li 	uint64_t l4_only_mask = RTE_ETH_RSS_L4_SRC_ONLY |
5532bd90635SHuisong Li 				RTE_ETH_RSS_L4_DST_ONLY;
5542bd90635SHuisong Li 	uint64_t l3_l4_only_mask = l3_only_mask | l4_only_mask;
5552bd90635SHuisong Li 	bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask);
5562bd90635SHuisong Li 	bool has_l3_only = !!(rss_hf & l3_only_mask);
5572bd90635SHuisong Li 	uint64_t tuple = 0;
5582bd90635SHuisong Li 	uint32_t i;
5592bd90635SHuisong Li 
5602bd90635SHuisong Li 	for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
5612bd90635SHuisong Li 		if ((rss_hf & hns3_set_tuple_table[i].rss_types) !=
5622bd90635SHuisong Li 		    hns3_set_tuple_table[i].rss_types)
5632bd90635SHuisong Li 			continue;
5642bd90635SHuisong Li 
5652bd90635SHuisong Li 		if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) {
5662bd90635SHuisong Li 			if (hns3_set_tuple_table[i].rss_types & l3_only_mask ||
5672bd90635SHuisong Li 			    !has_l3_only)
5682bd90635SHuisong Li 				tuple |= hns3_set_tuple_table[i].rss_field;
5692bd90635SHuisong Li 			continue;
5702bd90635SHuisong Li 		}
5712bd90635SHuisong Li 
5722bd90635SHuisong Li 		/* For IP types with L4, we need check both L3 and L4 */
5732bd90635SHuisong Li 		if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask ||
5742bd90635SHuisong Li 		    !has_l3_l4_only)
5752bd90635SHuisong Li 			tuple |= hns3_set_tuple_table[i].rss_field;
5762bd90635SHuisong Li 	}
5772bd90635SHuisong Li 
5782bd90635SHuisong Li 	return tuple;
5792bd90635SHuisong Li }
5802bd90635SHuisong Li 
581c37ca66fSWei Hu (Xavier) int
hns3_set_rss_tuple_field(struct hns3_hw * hw,uint64_t tuple_fields)582e3069658SHuisong Li hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields)
583c37ca66fSWei Hu (Xavier) {
584c37ca66fSWei Hu (Xavier) 	struct hns3_rss_input_tuple_cmd *req;
585c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
586c37ca66fSWei Hu (Xavier) 	int ret;
587c37ca66fSWei Hu (Xavier) 
588c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
589c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_input_tuple_cmd *)desc.data;
590e3069658SHuisong Li 	req->tuple_field = rte_cpu_to_le_64(tuple_fields);
591c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc, 1);
592e3069658SHuisong Li 	if (ret != 0)
593e3069658SHuisong Li 		hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret);
594e3069658SHuisong Li 
595c37ca66fSWei Hu (Xavier) 	return ret;
596c37ca66fSWei Hu (Xavier) }
597c37ca66fSWei Hu (Xavier) 
598e3069658SHuisong Li int
hns3_set_rss_tuple_by_rss_hf(struct hns3_hw * hw,uint64_t rss_hf)599e3069658SHuisong Li hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
600e3069658SHuisong Li {
601e3069658SHuisong Li 	uint64_t tuple_fields;
602e3069658SHuisong Li 	int ret;
603e3069658SHuisong Li 
604eb3ef9e0SHuisong Li 	tuple_fields = hns3_rss_calc_tuple_filed(rss_hf);
605e3069658SHuisong Li 	ret = hns3_set_rss_tuple_field(hw, tuple_fields);
606e3069658SHuisong Li 	if (ret != 0)
607e3069658SHuisong Li 		hns3_err(hw, "Update RSS flow types tuples failed, ret = %d",
608e3069658SHuisong Li 			 ret);
609e3069658SHuisong Li 
610e3069658SHuisong Li 	return ret;
611c37ca66fSWei Hu (Xavier) }
612c37ca66fSWei Hu (Xavier) 
613c37ca66fSWei Hu (Xavier) /*
614c37ca66fSWei Hu (Xavier)  * Configure RSS hash protocols and hash key.
615c37ca66fSWei Hu (Xavier)  * @param dev
616c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
617c37ca66fSWei Hu (Xavier)  * @praram rss_conf
618c37ca66fSWei Hu (Xavier)  *   The configuration select of  rss key size and tuple flow_types.
619c37ca66fSWei Hu (Xavier)  * @return
620c37ca66fSWei Hu (Xavier)  *   0 on success, a negative errno value otherwise is set.
621c37ca66fSWei Hu (Xavier)  */
622c37ca66fSWei Hu (Xavier) int
hns3_dev_rss_hash_update(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)623c37ca66fSWei Hu (Xavier) hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
624c37ca66fSWei Hu (Xavier) 			 struct rte_eth_rss_conf *rss_conf)
625c37ca66fSWei Hu (Xavier) {
62607f64b5fSHuisong Li 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
627791e5693SHuisong Li 	uint64_t rss_hf_bk = hw->rss_info.rss_hf;
628c37ca66fSWei Hu (Xavier) 	uint8_t key_len = rss_conf->rss_key_len;
629c37ca66fSWei Hu (Xavier) 	uint64_t rss_hf = rss_conf->rss_hf;
630c37ca66fSWei Hu (Xavier) 	uint8_t *key = rss_conf->rss_key;
631c37ca66fSWei Hu (Xavier) 	int ret;
632c37ca66fSWei Hu (Xavier) 
6335172f9c4SHuisong Li 	if (key && key_len != hw->rss_key_size) {
63407f64b5fSHuisong Li 		hns3_err(hw, "the hash key len(%u) is invalid, must be %u",
6355172f9c4SHuisong Li 			 key_len, hw->rss_key_size);
63607f64b5fSHuisong Li 		return -EINVAL;
63707f64b5fSHuisong Li 	}
63807f64b5fSHuisong Li 
639eb3ef9e0SHuisong Li 	if (!hns3_check_rss_types_valid(hw, rss_hf))
640eb3ef9e0SHuisong Li 		return -EINVAL;
641eb3ef9e0SHuisong Li 
642c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
643bfd0b54dSHuisong Li 	ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
644c37ca66fSWei Hu (Xavier) 	if (ret)
64507f64b5fSHuisong Li 		goto set_tuple_fail;
646c37ca66fSWei Hu (Xavier) 
6479913a55dSHuisong Li 	ret = hns3_update_rss_algo_key(hw, rss_conf->algorithm, key, key_len);
6489913a55dSHuisong Li 	if (ret != 0)
64907f64b5fSHuisong Li 		goto set_algo_key_fail;
6509913a55dSHuisong Li 
6519913a55dSHuisong Li 	if (rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_DEFAULT)
6529913a55dSHuisong Li 		hw->rss_info.hash_algo = hns3_hash_func_map[rss_conf->algorithm];
6539913a55dSHuisong Li 	if (key != NULL)
654fe9cc8b8SHuisong Li 		memcpy(hw->rss_info.key, key, hw->rss_key_size);
655791e5693SHuisong Li 	hw->rss_info.rss_hf = rss_hf;
656c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
657c37ca66fSWei Hu (Xavier) 
658c37ca66fSWei Hu (Xavier) 	return 0;
659c37ca66fSWei Hu (Xavier) 
66007f64b5fSHuisong Li set_algo_key_fail:
661bfd0b54dSHuisong Li 	(void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk);
66207f64b5fSHuisong Li set_tuple_fail:
663c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
664c37ca66fSWei Hu (Xavier) 	return ret;
665c37ca66fSWei Hu (Xavier) }
666c37ca66fSWei Hu (Xavier) 
667406b25c7SHuisong Li int
hns3_get_rss_tuple_field(struct hns3_hw * hw,uint64_t * tuple_fields)668406b25c7SHuisong Li hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields)
669406b25c7SHuisong Li {
670406b25c7SHuisong Li 	struct hns3_rss_input_tuple_cmd *req;
671406b25c7SHuisong Li 	struct hns3_cmd_desc desc;
672406b25c7SHuisong Li 	int ret;
673406b25c7SHuisong Li 
674406b25c7SHuisong Li 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true);
675406b25c7SHuisong Li 	req = (struct hns3_rss_input_tuple_cmd *)desc.data;
676406b25c7SHuisong Li 	ret = hns3_cmd_send(hw, &desc, 1);
677406b25c7SHuisong Li 	if (ret != 0) {
678406b25c7SHuisong Li 		hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d",
679406b25c7SHuisong Li 			 ret);
680406b25c7SHuisong Li 		return ret;
681406b25c7SHuisong Li 	}
682406b25c7SHuisong Li 
683406b25c7SHuisong Li 	*tuple_fields = rte_le_to_cpu_64(req->tuple_field);
684406b25c7SHuisong Li 
685406b25c7SHuisong Li 	return 0;
686406b25c7SHuisong Li }
687406b25c7SHuisong Li 
688406b25c7SHuisong Li static uint64_t
hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw * hw,uint64_t tuple_fields)689406b25c7SHuisong Li hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw *hw, uint64_t tuple_fields)
690406b25c7SHuisong Li {
691406b25c7SHuisong Li 	uint64_t ipv6_sctp_l4_mask =
692406b25c7SHuisong Li 				BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
693406b25c7SHuisong Li 				BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S);
694406b25c7SHuisong Li 	uint64_t rss_hf = 0;
695406b25c7SHuisong Li 	uint64_t tuple_mask;
696406b25c7SHuisong Li 	uint32_t i;
697406b25c7SHuisong Li 
698406b25c7SHuisong Li 	for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
699406b25c7SHuisong Li 		tuple_mask = hns3_set_tuple_table[i].tuple_mask;
700406b25c7SHuisong Li 		/*
701406b25c7SHuisong Li 		 * The RSS hash of the packet type is disabled if its tuples is
702406b25c7SHuisong Li 		 * zero.
703406b25c7SHuisong Li 		 */
704406b25c7SHuisong Li 		if ((tuple_fields & tuple_mask) == 0)
705406b25c7SHuisong Li 			continue;
706406b25c7SHuisong Li 
707406b25c7SHuisong Li 		/*
708406b25c7SHuisong Li 		 * Some hardware don't support to use src/dst port fields to
709406b25c7SHuisong Li 		 * hash for IPV6-SCTP packet.
710406b25c7SHuisong Li 		 */
711406b25c7SHuisong Li 		if ((hns3_set_tuple_table[i].rss_types &
712406b25c7SHuisong Li 					RTE_ETH_RSS_NONFRAG_IPV6_SCTP) &&
713406b25c7SHuisong Li 		    !hw->rss_info.ipv6_sctp_offload_supported)
714406b25c7SHuisong Li 			tuple_mask &= ~ipv6_sctp_l4_mask;
715406b25c7SHuisong Li 
716406b25c7SHuisong Li 		/*
717406b25c7SHuisong Li 		 * The framework (ethdev ops) or driver (rte flow API) ensure
718406b25c7SHuisong Li 		 * that both L3_SRC/DST_ONLY and L4_SRC/DST_ONLY cannot be set
719406b25c7SHuisong Li 		 * to driver at the same time. But if user doesn't specify
720406b25c7SHuisong Li 		 * anything L3/L4_SRC/DST_ONLY, driver enables all tuple fields.
721406b25c7SHuisong Li 		 * In this case, driver should not report L3/L4_SRC/DST_ONLY.
722406b25c7SHuisong Li 		 */
723406b25c7SHuisong Li 		if ((tuple_fields & tuple_mask) == tuple_mask) {
724406b25c7SHuisong Li 			/* Skip the item enabled part tuples. */
725406b25c7SHuisong Li 			if ((tuple_fields & hns3_set_tuple_table[i].rss_field) !=
726406b25c7SHuisong Li 					tuple_mask)
727406b25c7SHuisong Li 				continue;
728406b25c7SHuisong Li 
729406b25c7SHuisong Li 			rss_hf |= hns3_set_tuple_table[i].rss_types;
730406b25c7SHuisong Li 			continue;
731406b25c7SHuisong Li 		}
732406b25c7SHuisong Li 
733406b25c7SHuisong Li 		/* Match the item enabled part tuples.*/
734406b25c7SHuisong Li 		if ((tuple_fields & hns3_set_tuple_table[i].rss_field) ==
735406b25c7SHuisong Li 					hns3_set_tuple_table[i].rss_field)
736406b25c7SHuisong Li 			rss_hf |= hns3_set_tuple_table[i].rss_types;
737406b25c7SHuisong Li 	}
738406b25c7SHuisong Li 
739406b25c7SHuisong Li 	return rss_hf;
740406b25c7SHuisong Li }
741406b25c7SHuisong Li 
742406b25c7SHuisong Li static int
hns3_rss_hash_get_rss_hf(struct hns3_hw * hw,uint64_t * rss_hf)743406b25c7SHuisong Li hns3_rss_hash_get_rss_hf(struct hns3_hw *hw, uint64_t *rss_hf)
744406b25c7SHuisong Li {
745406b25c7SHuisong Li 	uint64_t tuple_fields;
746406b25c7SHuisong Li 	int ret;
747406b25c7SHuisong Li 
748406b25c7SHuisong Li 	ret = hns3_get_rss_tuple_field(hw, &tuple_fields);
749406b25c7SHuisong Li 	if (ret != 0)
750406b25c7SHuisong Li 		return ret;
751406b25c7SHuisong Li 
752406b25c7SHuisong Li 	*rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields);
753406b25c7SHuisong Li 
754406b25c7SHuisong Li 	return 0;
755406b25c7SHuisong Li }
756406b25c7SHuisong Li 
757c37ca66fSWei Hu (Xavier) /*
758c37ca66fSWei Hu (Xavier)  * Get rss key and rss_hf types set of RSS hash configuration.
759c37ca66fSWei Hu (Xavier)  * @param dev
760c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
761c37ca66fSWei Hu (Xavier)  * @praram rss_conf
762c37ca66fSWei Hu (Xavier)  *   The buffer to get rss key size and tuple types.
763c37ca66fSWei Hu (Xavier)  * @return
764c37ca66fSWei Hu (Xavier)  *   0 on success.
765c37ca66fSWei Hu (Xavier)  */
766c37ca66fSWei Hu (Xavier) int
hns3_dev_rss_hash_conf_get(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)767c37ca66fSWei Hu (Xavier) hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
768c37ca66fSWei Hu (Xavier) 			   struct rte_eth_rss_conf *rss_conf)
769c37ca66fSWei Hu (Xavier) {
7709913a55dSHuisong Li 	const uint8_t hash_func_map[] = {
7719913a55dSHuisong Li 		[HNS3_RSS_HASH_ALGO_TOEPLITZ] = RTE_ETH_HASH_FUNCTION_TOEPLITZ,
7729913a55dSHuisong Li 		[HNS3_RSS_HASH_ALGO_SIMPLE] = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR,
7739913a55dSHuisong Li 		[HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP] = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ,
7749913a55dSHuisong Li 	};
775c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
7769913a55dSHuisong Li 	uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
777c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
778177cf5c9SJie Hai 	uint8_t hash_algo = 0;
7797da415d2SHuisong Li 	int ret;
780c37ca66fSWei Hu (Xavier) 
781c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
782406b25c7SHuisong Li 	ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf);
783406b25c7SHuisong Li 	if (ret != 0) {
7849913a55dSHuisong Li 		rte_spinlock_unlock(&hw->lock);
785406b25c7SHuisong Li 		hns3_err(hw, "obtain hash tuples failed, ret = %d", ret);
7869913a55dSHuisong Li 		return ret;
787406b25c7SHuisong Li 	}
788c37ca66fSWei Hu (Xavier) 
7899913a55dSHuisong Li 	ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
7907da415d2SHuisong Li 	if (ret != 0) {
7919913a55dSHuisong Li 		rte_spinlock_unlock(&hw->lock);
7929913a55dSHuisong Li 		hns3_err(hw, "obtain hash algo and key failed, ret = %d", ret);
7939913a55dSHuisong Li 		return ret;
7947da415d2SHuisong Li 	}
795c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
796c37ca66fSWei Hu (Xavier) 
7979913a55dSHuisong Li 	/* Get the RSS Key if user required. */
7989913a55dSHuisong Li 	if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
7999913a55dSHuisong Li 		memcpy(rss_conf->rss_key, rss_key, hw->rss_key_size);
8009913a55dSHuisong Li 		rss_conf->rss_key_len = hw->rss_key_size;
8019913a55dSHuisong Li 	}
8029913a55dSHuisong Li 	rss_conf->algorithm = hash_func_map[hash_algo];
8039913a55dSHuisong Li 
8049913a55dSHuisong Li 	return 0;
805c37ca66fSWei Hu (Xavier) }
806c37ca66fSWei Hu (Xavier) 
807c37ca66fSWei Hu (Xavier) /*
808c37ca66fSWei Hu (Xavier)  * Update rss redirection table of RSS.
809c37ca66fSWei Hu (Xavier)  * @param dev
810c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
811c37ca66fSWei Hu (Xavier)  * @praram reta_conf
812c37ca66fSWei Hu (Xavier)  *   Pointer to the configuration select of mask and redirection tables.
813c37ca66fSWei Hu (Xavier)  * @param reta_size
814c37ca66fSWei Hu (Xavier)  *   Redirection table size.
815c37ca66fSWei Hu (Xavier)  * @return
816c37ca66fSWei Hu (Xavier)  *   0 on success, a negative errno value otherwise is set.
817c37ca66fSWei Hu (Xavier)  */
818c37ca66fSWei Hu (Xavier) int
hns3_dev_rss_reta_update(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)819c37ca66fSWei Hu (Xavier) hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
820c37ca66fSWei Hu (Xavier) 			 struct rte_eth_rss_reta_entry64 *reta_conf,
821c37ca66fSWei Hu (Xavier) 			 uint16_t reta_size)
822c37ca66fSWei Hu (Xavier) {
823c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
824c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
825c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
8260fce2c46SLijun Ou 	uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
8275e76dfc3SHuisong Li 	uint16_t idx, shift;
8280fce2c46SLijun Ou 	uint16_t i;
829c37ca66fSWei Hu (Xavier) 	int ret;
830c37ca66fSWei Hu (Xavier) 
8310fce2c46SLijun Ou 	if (reta_size != hw->rss_ind_tbl_size) {
832c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "The size of hash lookup table configured (%u)"
833c37ca66fSWei Hu (Xavier) 			 "doesn't match the number hardware can supported"
8340fce2c46SLijun Ou 			 "(%u)", reta_size, hw->rss_ind_tbl_size);
835c37ca66fSWei Hu (Xavier) 		return -EINVAL;
836c37ca66fSWei Hu (Xavier) 	}
837c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
838c37ca66fSWei Hu (Xavier) 	memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
8399a7d3af2SHuisong Li 	       sizeof(rss_cfg->rss_indirection_tbl));
840c37ca66fSWei Hu (Xavier) 	for (i = 0; i < reta_size; i++) {
841295968d1SFerruh Yigit 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
842295968d1SFerruh Yigit 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
8435e76dfc3SHuisong Li 		if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) {
8445e76dfc3SHuisong Li 			hns3_err(hw, "queue id(%u) set to redirection table "
8455e76dfc3SHuisong Li 				 "exceeds queue number(%u) allocated to a TC",
8465e76dfc3SHuisong Li 				 reta_conf[idx].reta[shift],
8475e76dfc3SHuisong Li 				 hw->alloc_rss_size);
848a421cb93SHuisong Li 			ret = -EINVAL;
849a421cb93SHuisong Li 			goto out;
850c37ca66fSWei Hu (Xavier) 		}
851c37ca66fSWei Hu (Xavier) 
852c37ca66fSWei Hu (Xavier) 		if (reta_conf[idx].mask & (1ULL << shift))
853c37ca66fSWei Hu (Xavier) 			indirection_tbl[i] = reta_conf[idx].reta[shift];
854c37ca66fSWei Hu (Xavier) 	}
855c37ca66fSWei Hu (Xavier) 
856c37ca66fSWei Hu (Xavier) 	ret = hns3_set_rss_indir_table(hw, indirection_tbl,
8570fce2c46SLijun Ou 				       hw->rss_ind_tbl_size);
858a421cb93SHuisong Li 	if (ret != 0)
859a421cb93SHuisong Li 		goto out;
860c37ca66fSWei Hu (Xavier) 
861a421cb93SHuisong Li 	memcpy(rss_cfg->rss_indirection_tbl, indirection_tbl,
862a421cb93SHuisong Li 	       sizeof(uint16_t) * hw->rss_ind_tbl_size);
863a421cb93SHuisong Li 
864a421cb93SHuisong Li out:
865c37ca66fSWei Hu (Xavier) 	rte_spinlock_unlock(&hw->lock);
866c37ca66fSWei Hu (Xavier) 	return ret;
867c37ca66fSWei Hu (Xavier) }
868c37ca66fSWei Hu (Xavier) 
869c37ca66fSWei Hu (Xavier) /*
870c37ca66fSWei Hu (Xavier)  * Get rss redirection table of RSS hash configuration.
871c37ca66fSWei Hu (Xavier)  * @param dev
872c37ca66fSWei Hu (Xavier)  *   Pointer to Ethernet device.
873c37ca66fSWei Hu (Xavier)  * @praram reta_conf
874c37ca66fSWei Hu (Xavier)  *   Pointer to the configuration select of mask and redirection tables.
875c37ca66fSWei Hu (Xavier)  * @param reta_size
876c37ca66fSWei Hu (Xavier)  *   Redirection table size.
877c37ca66fSWei Hu (Xavier)  * @return
878c37ca66fSWei Hu (Xavier)  *   0 on success, a negative errno value otherwise is set.
879c37ca66fSWei Hu (Xavier)  */
880c37ca66fSWei Hu (Xavier) int
hns3_dev_rss_reta_query(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)881c37ca66fSWei Hu (Xavier) hns3_dev_rss_reta_query(struct rte_eth_dev *dev,
882c37ca66fSWei Hu (Xavier) 			struct rte_eth_rss_reta_entry64 *reta_conf,
883c37ca66fSWei Hu (Xavier) 			uint16_t reta_size)
884c37ca66fSWei Hu (Xavier) {
885c37ca66fSWei Hu (Xavier) 	struct hns3_adapter *hns = dev->data->dev_private;
886d1e37d1cSHuisong Li 	uint16_t reta_table[HNS3_RSS_IND_TBL_SIZE_MAX];
887c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
888c37ca66fSWei Hu (Xavier) 	uint16_t idx, shift;
8890fce2c46SLijun Ou 	uint16_t i;
890d1e37d1cSHuisong Li 	int ret;
891c37ca66fSWei Hu (Xavier) 
8920fce2c46SLijun Ou 	if (reta_size != hw->rss_ind_tbl_size) {
893c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "The size of hash lookup table configured (%u)"
894c37ca66fSWei Hu (Xavier) 			 " doesn't match the number hardware can supported"
8950fce2c46SLijun Ou 			 "(%u)", reta_size, hw->rss_ind_tbl_size);
896c37ca66fSWei Hu (Xavier) 		return -EINVAL;
897c37ca66fSWei Hu (Xavier) 	}
898c37ca66fSWei Hu (Xavier) 	rte_spinlock_lock(&hw->lock);
899d1e37d1cSHuisong Li 	ret = hns3_get_rss_indir_table(hw, reta_table, reta_size);
900d1e37d1cSHuisong Li 	if (ret != 0) {
901d1e37d1cSHuisong Li 		rte_spinlock_unlock(&hw->lock);
902d1e37d1cSHuisong Li 		hns3_err(hw, "query RSS redirection table failed, ret = %d.",
903d1e37d1cSHuisong Li 			 ret);
904d1e37d1cSHuisong Li 		return ret;
905d1e37d1cSHuisong Li 	}
906d1e37d1cSHuisong Li 	rte_spinlock_unlock(&hw->lock);
907d1e37d1cSHuisong Li 
908c37ca66fSWei Hu (Xavier) 	for (i = 0; i < reta_size; i++) {
909295968d1SFerruh Yigit 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
910295968d1SFerruh Yigit 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
911c37ca66fSWei Hu (Xavier) 		if (reta_conf[idx].mask & (1ULL << shift))
912d1e37d1cSHuisong Li 			reta_conf[idx].reta[shift] = reta_table[i];
913c37ca66fSWei Hu (Xavier) 	}
914d1e37d1cSHuisong Li 
915c37ca66fSWei Hu (Xavier) 	return 0;
916c37ca66fSWei Hu (Xavier) }
917c37ca66fSWei Hu (Xavier) 
91887f9628eSHuisong Li static void
hns3_set_rss_tc_mode_entry(struct hns3_hw * hw,uint8_t * tc_valid,uint16_t * tc_size,uint16_t * tc_offset,uint8_t tc_num)91987f9628eSHuisong Li hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid,
92087f9628eSHuisong Li 			   uint16_t *tc_size, uint16_t *tc_offset,
92187f9628eSHuisong Li 			   uint8_t tc_num)
92287f9628eSHuisong Li {
92387f9628eSHuisong Li 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
92487f9628eSHuisong Li 	uint16_t rss_size = hw->alloc_rss_size;
92587f9628eSHuisong Li 	uint16_t roundup_size;
92687f9628eSHuisong Li 	uint16_t i;
92787f9628eSHuisong Li 
92887f9628eSHuisong Li 	roundup_size = roundup_pow_of_two(rss_size);
92987f9628eSHuisong Li 	roundup_size = ilog2(roundup_size);
93087f9628eSHuisong Li 
93187f9628eSHuisong Li 	for (i = 0; i < tc_num; i++) {
93287f9628eSHuisong Li 		if (hns->is_vf) {
933c37ca66fSWei Hu (Xavier) 			/*
93487f9628eSHuisong Li 			 * For packets with VLAN priorities destined for the VF,
93587f9628eSHuisong Li 			 * hardware still assign Rx queue based on the Up-to-TC
93687f9628eSHuisong Li 			 * mapping PF configured. But VF has only one TC. If
93787f9628eSHuisong Li 			 * other TC don't enable, it causes that the priority
93887f9628eSHuisong Li 			 * packets that aren't destined for TC0 aren't received
93987f9628eSHuisong Li 			 * by RSS hash but is destined for queue 0. So driver
94087f9628eSHuisong Li 			 * has to enable the unused TC by using TC0 queue
94187f9628eSHuisong Li 			 * mapping configuration.
942c37ca66fSWei Hu (Xavier) 			 */
94387f9628eSHuisong Li 			tc_valid[i] = (hw->hw_tc_map & BIT(i)) ?
94487f9628eSHuisong Li 					!!(hw->hw_tc_map & BIT(i)) : 1;
94587f9628eSHuisong Li 			tc_size[i] = roundup_size;
94687f9628eSHuisong Li 			tc_offset[i] = (hw->hw_tc_map & BIT(i)) ?
94787f9628eSHuisong Li 					rss_size * i : 0;
94887f9628eSHuisong Li 		} else {
94987f9628eSHuisong Li 			tc_valid[i] = !!(hw->hw_tc_map & BIT(i));
95087f9628eSHuisong Li 			tc_size[i] = tc_valid[i] ? roundup_size : 0;
95187f9628eSHuisong Li 			tc_offset[i] = tc_valid[i] ? rss_size * i : 0;
95287f9628eSHuisong Li 		}
95387f9628eSHuisong Li 	}
95487f9628eSHuisong Li }
95587f9628eSHuisong Li 
956c37ca66fSWei Hu (Xavier) static int
hns3_set_rss_tc_mode(struct hns3_hw * hw)957c37ca66fSWei Hu (Xavier) hns3_set_rss_tc_mode(struct hns3_hw *hw)
958c37ca66fSWei Hu (Xavier) {
959c37ca66fSWei Hu (Xavier) 	struct hns3_rss_tc_mode_cmd *req;
960c37ca66fSWei Hu (Xavier) 	uint16_t tc_offset[HNS3_MAX_TC_NUM];
961c37ca66fSWei Hu (Xavier) 	uint8_t tc_valid[HNS3_MAX_TC_NUM];
962c37ca66fSWei Hu (Xavier) 	uint16_t tc_size[HNS3_MAX_TC_NUM];
963c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
964c37ca66fSWei Hu (Xavier) 	uint16_t i;
965c37ca66fSWei Hu (Xavier) 	int ret;
966c37ca66fSWei Hu (Xavier) 
96787f9628eSHuisong Li 	hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size,
96887f9628eSHuisong Li 				   tc_offset, HNS3_MAX_TC_NUM);
96987f9628eSHuisong Li 
970c37ca66fSWei Hu (Xavier) 	req = (struct hns3_rss_tc_mode_cmd *)desc.data;
971c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false);
972c37ca66fSWei Hu (Xavier) 	for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
973c37ca66fSWei Hu (Xavier) 		uint16_t mode = 0;
974c37ca66fSWei Hu (Xavier) 
975c37ca66fSWei Hu (Xavier) 		hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
976c37ca66fSWei Hu (Xavier) 		hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S,
977c37ca66fSWei Hu (Xavier) 			       tc_size[i]);
9789a7d3af2SHuisong Li 		if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0)
9799a7d3af2SHuisong Li 			hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1);
980c37ca66fSWei Hu (Xavier) 		hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S,
981c37ca66fSWei Hu (Xavier) 			       tc_offset[i]);
982c37ca66fSWei Hu (Xavier) 
983c37ca66fSWei Hu (Xavier) 		req->rss_tc_mode[i] = rte_cpu_to_le_16(mode);
984c37ca66fSWei Hu (Xavier) 	}
985c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc, 1);
986c37ca66fSWei Hu (Xavier) 	if (ret)
987c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "Sets rss tc mode failed %d", ret);
988c37ca66fSWei Hu (Xavier) 
989c37ca66fSWei Hu (Xavier) 	return ret;
990c37ca66fSWei Hu (Xavier) }
991c37ca66fSWei Hu (Xavier) 
992e3069658SHuisong Li /*
993e3069658SHuisong Li  * Note: the 'hash_algo' is defined by enum rte_eth_hash_function.
994e3069658SHuisong Li  */
995e3069658SHuisong Li int
hns3_update_rss_algo_key(struct hns3_hw * hw,uint8_t hash_func,uint8_t * key,uint8_t key_len)996e3069658SHuisong Li hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func,
997e3069658SHuisong Li 			 uint8_t *key, uint8_t key_len)
998e3069658SHuisong Li {
999e3069658SHuisong Li 	uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
1000e3069658SHuisong Li 	bool modify_key, modify_algo;
1001177cf5c9SJie Hai 	uint8_t hash_algo = 0;
1002e3069658SHuisong Li 	int ret;
1003e3069658SHuisong Li 
1004e3069658SHuisong Li 	modify_key = (key != NULL && key_len > 0);
1005e3069658SHuisong Li 	modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT;
1006e3069658SHuisong Li 	if (!modify_key && !modify_algo)
1007e3069658SHuisong Li 		return 0;
1008e3069658SHuisong Li 
1009e3069658SHuisong Li 	if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) {
1010e3069658SHuisong Li 		hns3_err(hw, "hash func (%u) is unsupported.", hash_func);
1011e3069658SHuisong Li 		return -ENOTSUP;
1012e3069658SHuisong Li 	}
1013e3069658SHuisong Li 	if (modify_key && key_len != hw->rss_key_size) {
1014e3069658SHuisong Li 		hns3_err(hw, "hash key length (%u) is invalid.", key_len);
1015e3069658SHuisong Li 		return -EINVAL;
1016e3069658SHuisong Li 	}
1017e3069658SHuisong Li 
1018e3069658SHuisong Li 	ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
1019e3069658SHuisong Li 	if (ret != 0) {
1020e3069658SHuisong Li 		hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d",
1021e3069658SHuisong Li 			 ret);
1022e3069658SHuisong Li 		return ret;
1023e3069658SHuisong Li 	}
1024e3069658SHuisong Li 
1025e3069658SHuisong Li 	if (modify_algo)
1026e3069658SHuisong Li 		hash_algo = hns3_hash_func_map[hash_func];
1027e3069658SHuisong Li 	if (modify_key)
1028e3069658SHuisong Li 		memcpy(rss_key, key, key_len);
1029e3069658SHuisong Li 
1030e3069658SHuisong Li 	ret = hns3_rss_set_algo_key(hw, hash_algo, rss_key, hw->rss_key_size);
1031e3069658SHuisong Li 	if (ret != 0)
1032e3069658SHuisong Li 		hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d",
1033e3069658SHuisong Li 			 ret);
1034e3069658SHuisong Li 
1035e3069658SHuisong Li 	return ret;
1036e3069658SHuisong Li }
1037e3069658SHuisong Li 
1038c37ca66fSWei Hu (Xavier) static void
hns3_rss_tuple_uninit(struct hns3_hw * hw)1039c37ca66fSWei Hu (Xavier) hns3_rss_tuple_uninit(struct hns3_hw *hw)
1040c37ca66fSWei Hu (Xavier) {
1041c37ca66fSWei Hu (Xavier) 	struct hns3_cmd_desc desc;
1042c37ca66fSWei Hu (Xavier) 	int ret;
1043c37ca66fSWei Hu (Xavier) 
1044c37ca66fSWei Hu (Xavier) 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
1045c37ca66fSWei Hu (Xavier) 
1046c37ca66fSWei Hu (Xavier) 	ret = hns3_cmd_send(hw, &desc, 1);
1047c37ca66fSWei Hu (Xavier) 	if (ret) {
1048c37ca66fSWei Hu (Xavier) 		hns3_err(hw, "RSS uninit tuple failed %d", ret);
1049c37ca66fSWei Hu (Xavier) 		return;
1050c37ca66fSWei Hu (Xavier) 	}
1051c37ca66fSWei Hu (Xavier) }
1052c37ca66fSWei Hu (Xavier) 
1053c37ca66fSWei Hu (Xavier) /*
1054c37ca66fSWei Hu (Xavier)  * Set the default rss configuration in the init of driver.
1055c37ca66fSWei Hu (Xavier)  */
1056c37ca66fSWei Hu (Xavier) void
hns3_rss_set_default_args(struct hns3_hw * hw)1057a39e67ffSLijun Ou hns3_rss_set_default_args(struct hns3_hw *hw)
1058c37ca66fSWei Hu (Xavier) {
1059c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
1060c37ca66fSWei Hu (Xavier) 	uint16_t queue_num = hw->alloc_rss_size;
106167d01034SHuisong Li 	uint16_t i;
1062c37ca66fSWei Hu (Xavier) 
1063c37ca66fSWei Hu (Xavier) 	/* Default hash algorithm */
10641fcbef5cSHuisong Li 	rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
10658834849aSHao Chen 
1066791e5693SHuisong Li 	hw->rss_info.rss_hf = 0;
10675172f9c4SHuisong Li 	memcpy(rss_cfg->key, hns3_hash_key,
10685172f9c4SHuisong Li 		RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
1069c37ca66fSWei Hu (Xavier) 
1070c37ca66fSWei Hu (Xavier) 	/* Initialize RSS indirection table */
10710fce2c46SLijun Ou 	for (i = 0; i < hw->rss_ind_tbl_size; i++)
1072c37ca66fSWei Hu (Xavier) 		rss_cfg->rss_indirection_tbl[i] = i % queue_num;
1073c37ca66fSWei Hu (Xavier) }
1074c37ca66fSWei Hu (Xavier) 
1075c37ca66fSWei Hu (Xavier) /*
1076f8dbaebbSSean Morrissey  * RSS initialization for hns3 PMD.
1077c37ca66fSWei Hu (Xavier)  */
1078c37ca66fSWei Hu (Xavier) int
hns3_config_rss(struct hns3_adapter * hns)1079c37ca66fSWei Hu (Xavier) hns3_config_rss(struct hns3_adapter *hns)
1080c37ca66fSWei Hu (Xavier) {
1081c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
1082c37ca66fSWei Hu (Xavier) 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
1083c37ca66fSWei Hu (Xavier) 	uint8_t *hash_key = rss_cfg->key;
108475ccc3f3SHuisong Li 	uint64_t rss_hf;
108575ccc3f3SHuisong Li 	int ret;
1086c37ca66fSWei Hu (Xavier) 
1087c37ca66fSWei Hu (Xavier) 	enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
1088c37ca66fSWei Hu (Xavier) 
10895172f9c4SHuisong Li 	ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo,
10905172f9c4SHuisong Li 				    hash_key, hw->rss_key_size);
1091c37ca66fSWei Hu (Xavier) 	if (ret)
1092c37ca66fSWei Hu (Xavier) 		return ret;
1093c37ca66fSWei Hu (Xavier) 
109475ccc3f3SHuisong Li 	ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl,
109575ccc3f3SHuisong Li 				       hw->rss_ind_tbl_size);
109675ccc3f3SHuisong Li 	if (ret)
109775ccc3f3SHuisong Li 		return ret;
109875ccc3f3SHuisong Li 
109975ccc3f3SHuisong Li 	ret = hns3_set_rss_tc_mode(hw);
1100c37ca66fSWei Hu (Xavier) 	if (ret)
1101c37ca66fSWei Hu (Xavier) 		return ret;
1102c37ca66fSWei Hu (Xavier) 
1103920be799SLijun Ou 	/*
1104791e5693SHuisong Li 	 * When multi-queue RSS mode flag is not set or unsupported tuples are
110575ccc3f3SHuisong Li 	 * set, disable all tuples.
1106920be799SLijun Ou 	 */
1107791e5693SHuisong Li 	rss_hf = hw->rss_info.rss_hf;
110875ccc3f3SHuisong Li 	if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) ||
110975ccc3f3SHuisong Li 	    !(rss_hf & HNS3_ETH_RSS_SUPPORT))
111075ccc3f3SHuisong Li 		rss_hf = 0;
1111c37ca66fSWei Hu (Xavier) 
1112791e5693SHuisong Li 	ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
1113791e5693SHuisong Li 	if (ret != 0) {
1114791e5693SHuisong Li 		hns3_err(hw, "set RSS tuples failed, ret = %d.", ret);
1115791e5693SHuisong Li 		return ret;
1116791e5693SHuisong Li 	}
1117791e5693SHuisong Li 	hw->rss_info.rss_hf = rss_hf;
1118791e5693SHuisong Li 
1119791e5693SHuisong Li 	return 0;
1120c37ca66fSWei Hu (Xavier) }
1121c37ca66fSWei Hu (Xavier) 
1122c37ca66fSWei Hu (Xavier) /*
1123f8dbaebbSSean Morrissey  * RSS uninitialization for hns3 PMD.
1124c37ca66fSWei Hu (Xavier)  */
1125c37ca66fSWei Hu (Xavier) void
hns3_rss_uninit(struct hns3_adapter * hns)1126c37ca66fSWei Hu (Xavier) hns3_rss_uninit(struct hns3_adapter *hns)
1127c37ca66fSWei Hu (Xavier) {
1128c37ca66fSWei Hu (Xavier) 	struct hns3_hw *hw = &hns->hw;
1129c37ca66fSWei Hu (Xavier) 	int ret;
1130c37ca66fSWei Hu (Xavier) 
1131c37ca66fSWei Hu (Xavier) 	hns3_rss_tuple_uninit(hw);
1132c37ca66fSWei Hu (Xavier) 	ret = hns3_rss_reset_indir_table(hw);
1133c37ca66fSWei Hu (Xavier) 	if (ret != 0)
1134c37ca66fSWei Hu (Xavier) 		return;
1135c37ca66fSWei Hu (Xavier) 
1136c37ca66fSWei Hu (Xavier) 	/* Disable RSS */
1137791e5693SHuisong Li 	hw->rss_info.rss_hf = 0;
1138c37ca66fSWei Hu (Xavier) }
1139