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