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) 12c37ca66fSWei Hu (Xavier) /* 13c37ca66fSWei Hu (Xavier) * The hash key used for rss initialization. 14c37ca66fSWei Hu (Xavier) */ 15c37ca66fSWei Hu (Xavier) static const uint8_t hns3_hash_key[] = { 16c37ca66fSWei Hu (Xavier) 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 17c37ca66fSWei Hu (Xavier) 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0, 18c37ca66fSWei Hu (Xavier) 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, 19c37ca66fSWei Hu (Xavier) 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 20c37ca66fSWei Hu (Xavier) 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA 21c37ca66fSWei Hu (Xavier) }; 22c37ca66fSWei Hu (Xavier) 23806f1d5aSLijun Ou enum hns3_tuple_field { 24806f1d5aSLijun Ou /* IPV4_TCP ENABLE FIELD */ 25806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, 26806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, 27806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, 28806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, 29806f1d5aSLijun Ou 30806f1d5aSLijun Ou /* IPV4_UDP ENABLE FIELD */ 31806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, 32806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, 33806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, 34806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, 35806f1d5aSLijun Ou 36806f1d5aSLijun Ou /* IPV4_SCTP ENABLE FIELD */ 37806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, 38806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, 39806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, 40806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, 41806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, 42806f1d5aSLijun Ou 43806f1d5aSLijun Ou /* IPV4 ENABLE FIELD */ 44806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, 45806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, 46806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, 47806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, 48806f1d5aSLijun Ou 49806f1d5aSLijun Ou /* IPV6_TCP ENABLE FIELD */ 50806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, 51806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, 52806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, 53806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, 54806f1d5aSLijun Ou 55806f1d5aSLijun Ou /* IPV6_UDP ENABLE FIELD */ 56806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, 57806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, 58806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, 59806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, 60806f1d5aSLijun Ou 611bc633c3SLijun Ou /* IPV6_SCTP ENABLE FIELD */ 621bc633c3SLijun Ou HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_D = 48, 631bc633c3SLijun Ou HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_S, 641bc633c3SLijun Ou HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D, 65806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, 66806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, 67806f1d5aSLijun Ou 68806f1d5aSLijun Ou /* IPV6 ENABLE FIELD */ 69806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, 70806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, 71806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_FRAG_IP_D, 72806f1d5aSLijun Ou HNS3_RSS_FIELD_IPV6_FRAG_IP_S 73806f1d5aSLijun Ou }; 74806f1d5aSLijun Ou 75806f1d5aSLijun Ou static const struct { 76806f1d5aSLijun Ou uint64_t rss_types; 77806f1d5aSLijun Ou uint64_t rss_field; 78806f1d5aSLijun Ou } hns3_set_tuple_table[] = { 79295968d1SFerruh Yigit { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY, 80806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, 81295968d1SFerruh Yigit { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY, 82806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, 83295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY, 84806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) }, 85295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY, 86806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) }, 87295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY, 88806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) }, 89295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY, 90806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, 91295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY, 92806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) }, 93295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY, 94806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) }, 95295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY, 96806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) }, 97295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY, 98806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, 99295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY, 100806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) }, 101295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY, 102806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) }, 103295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY, 104806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) }, 105295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY, 106806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) }, 107295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY, 108806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, 109295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY, 110806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, 111295968d1SFerruh Yigit { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY, 112806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) }, 113295968d1SFerruh Yigit { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY, 114806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, 115295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY, 116806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) }, 117295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY, 118806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) }, 119295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY, 120806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) }, 121295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY, 122806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, 123295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY, 124806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) }, 125295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY, 126806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) }, 127295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY, 128806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) }, 129295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY, 130806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, 131295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY, 132806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) }, 133295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_DST_ONLY, 134806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) }, 135295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_SRC_ONLY, 1361bc633c3SLijun Ou BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_S) }, 137295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY, 1381bc633c3SLijun Ou BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_D) }, 139295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY, 140806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, 141295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY, 142806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, 143806f1d5aSLijun Ou }; 144806f1d5aSLijun Ou 145806f1d5aSLijun Ou static const struct { 146806f1d5aSLijun Ou uint64_t rss_types; 147806f1d5aSLijun Ou uint64_t rss_field; 148806f1d5aSLijun Ou } hns3_set_rss_types[] = { 149295968d1SFerruh Yigit { RTE_ETH_RSS_FRAG_IPV4, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) | 150806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, 151295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | 152806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | 153806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | 154806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, 155295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | 156806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | 157806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | 158806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, 159295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) | 160806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) | 161806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) | 162806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, 163295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) | 164806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) | 165806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) | 166806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) | 167806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) }, 168295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV4_OTHER, 169806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | 170806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, 171295968d1SFerruh Yigit { RTE_ETH_RSS_FRAG_IPV6, BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) | 172806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, 173295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) | 174806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) | 175806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) | 176806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, 177295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) | 178806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) | 179806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) | 180806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, 181295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) | 182806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) | 1831bc633c3SLijun Ou BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_D) | 1841bc633c3SLijun Ou BIT_ULL(HNS3_RSS_FILED_IPV6_SCTP_EN_SCTP_S) | 185806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) }, 186295968d1SFerruh Yigit { RTE_ETH_RSS_NONFRAG_IPV6_OTHER, 187806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | 188806f1d5aSLijun Ou BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) } 189806f1d5aSLijun Ou }; 190806f1d5aSLijun Ou 191c37ca66fSWei Hu (Xavier) /* 192c37ca66fSWei Hu (Xavier) * rss_generic_config command function, opcode:0x0D01. 193c37ca66fSWei Hu (Xavier) * Used to set algorithm, key_offset and hash key of rss. 194c37ca66fSWei Hu (Xavier) */ 195c37ca66fSWei Hu (Xavier) int 196a39e67ffSLijun Ou hns3_rss_set_algo_key(struct hns3_hw *hw, const uint8_t *key) 197c37ca66fSWei Hu (Xavier) { 198c37ca66fSWei Hu (Xavier) #define HNS3_KEY_OFFSET_MAX 3 199c37ca66fSWei Hu (Xavier) #define HNS3_SET_HASH_KEY_BYTE_FOUR 2 200c37ca66fSWei Hu (Xavier) 201c37ca66fSWei Hu (Xavier) struct hns3_rss_generic_config_cmd *req; 202c37ca66fSWei Hu (Xavier) struct hns3_cmd_desc desc; 203c37ca66fSWei Hu (Xavier) uint32_t key_offset, key_size; 204c37ca66fSWei Hu (Xavier) const uint8_t *key_cur; 205c37ca66fSWei Hu (Xavier) uint8_t cur_offset; 206c37ca66fSWei Hu (Xavier) int ret; 207c37ca66fSWei Hu (Xavier) 208c37ca66fSWei Hu (Xavier) req = (struct hns3_rss_generic_config_cmd *)desc.data; 209c37ca66fSWei Hu (Xavier) 210c37ca66fSWei Hu (Xavier) /* 211c37ca66fSWei Hu (Xavier) * key_offset=0, hash key byte0~15 is set to hardware. 212c37ca66fSWei Hu (Xavier) * key_offset=1, hash key byte16~31 is set to hardware. 213c37ca66fSWei Hu (Xavier) * key_offset=2, hash key byte32~39 is set to hardware. 214c37ca66fSWei Hu (Xavier) */ 215c37ca66fSWei Hu (Xavier) for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) { 216c37ca66fSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, 217c37ca66fSWei Hu (Xavier) false); 218c37ca66fSWei Hu (Xavier) 21978b37190SLijun Ou req->hash_config |= 22078b37190SLijun Ou (hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK); 221c37ca66fSWei Hu (Xavier) req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B); 222c37ca66fSWei Hu (Xavier) 223c37ca66fSWei Hu (Xavier) if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR) 224c37ca66fSWei Hu (Xavier) key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM * 225c37ca66fSWei Hu (Xavier) HNS3_SET_HASH_KEY_BYTE_FOUR; 226c37ca66fSWei Hu (Xavier) else 227c37ca66fSWei Hu (Xavier) key_size = HNS3_RSS_HASH_KEY_NUM; 228c37ca66fSWei Hu (Xavier) 229c37ca66fSWei Hu (Xavier) cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM; 230c37ca66fSWei Hu (Xavier) key_cur = key + cur_offset; 231c37ca66fSWei Hu (Xavier) memcpy(req->hash_key, key_cur, key_size); 232c37ca66fSWei Hu (Xavier) 233c37ca66fSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 234c37ca66fSWei Hu (Xavier) if (ret) { 235c37ca66fSWei Hu (Xavier) hns3_err(hw, "Configure RSS algo key failed %d", ret); 236c37ca66fSWei Hu (Xavier) return ret; 237c37ca66fSWei Hu (Xavier) } 238c37ca66fSWei Hu (Xavier) } 239c37ca66fSWei Hu (Xavier) /* Update the shadow RSS key with user specified */ 240c37ca66fSWei Hu (Xavier) memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE); 241c37ca66fSWei Hu (Xavier) return 0; 242c37ca66fSWei Hu (Xavier) } 243c37ca66fSWei Hu (Xavier) 244c37ca66fSWei Hu (Xavier) /* 245c37ca66fSWei Hu (Xavier) * Used to configure the tuple selection for RSS hash input. 246c37ca66fSWei Hu (Xavier) */ 247c37ca66fSWei Hu (Xavier) static int 248a39e67ffSLijun Ou hns3_rss_set_input_tuple(struct hns3_hw *hw) 249c37ca66fSWei Hu (Xavier) { 250c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_config = &hw->rss_info; 251c37ca66fSWei Hu (Xavier) struct hns3_rss_input_tuple_cmd *req; 252c37ca66fSWei Hu (Xavier) struct hns3_cmd_desc desc_tuple; 253c37ca66fSWei Hu (Xavier) int ret; 254c37ca66fSWei Hu (Xavier) 255c37ca66fSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc_tuple, HNS3_OPC_RSS_INPUT_TUPLE, false); 256c37ca66fSWei Hu (Xavier) 257c37ca66fSWei Hu (Xavier) req = (struct hns3_rss_input_tuple_cmd *)desc_tuple.data; 258c37ca66fSWei Hu (Xavier) 259806f1d5aSLijun Ou req->tuple_field = 260806f1d5aSLijun Ou rte_cpu_to_le_64(rss_config->rss_tuple_sets.rss_tuple_fields); 261c37ca66fSWei Hu (Xavier) 262c37ca66fSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc_tuple, 1); 263c37ca66fSWei Hu (Xavier) if (ret) 264c37ca66fSWei Hu (Xavier) hns3_err(hw, "Configure RSS input tuple mode failed %d", ret); 265c37ca66fSWei Hu (Xavier) 266c37ca66fSWei Hu (Xavier) return ret; 267c37ca66fSWei Hu (Xavier) } 268c37ca66fSWei Hu (Xavier) 269c37ca66fSWei Hu (Xavier) /* 270c37ca66fSWei Hu (Xavier) * rss_indirection_table command function, opcode:0x0D07. 271c37ca66fSWei Hu (Xavier) * Used to configure the indirection table of rss. 272c37ca66fSWei Hu (Xavier) */ 273c37ca66fSWei Hu (Xavier) int 2749a7d3af2SHuisong Li hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) 275c37ca66fSWei Hu (Xavier) { 276c37ca66fSWei Hu (Xavier) struct hns3_rss_indirection_table_cmd *req; 277c37ca66fSWei Hu (Xavier) struct hns3_cmd_desc desc; 2789a7d3af2SHuisong Li uint8_t qid_msb_off; 2799a7d3af2SHuisong Li uint8_t qid_msb_val; 2809a7d3af2SHuisong Li uint16_t q_id; 2819a7d3af2SHuisong Li uint16_t i, j; 2829a7d3af2SHuisong Li int ret; 283c37ca66fSWei Hu (Xavier) 284c37ca66fSWei Hu (Xavier) req = (struct hns3_rss_indirection_table_cmd *)desc.data; 285c37ca66fSWei Hu (Xavier) 286c37ca66fSWei Hu (Xavier) for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) { 287c37ca66fSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, 288c37ca66fSWei Hu (Xavier) false); 289c37ca66fSWei Hu (Xavier) req->start_table_index = 290c37ca66fSWei Hu (Xavier) rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); 291c37ca66fSWei Hu (Xavier) req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); 292c37ca66fSWei Hu (Xavier) for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { 2939a7d3af2SHuisong Li q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; 2949a7d3af2SHuisong Li req->rss_result_l[j] = q_id & 0xff; 2959a7d3af2SHuisong Li 2969a7d3af2SHuisong Li qid_msb_off = 2979a7d3af2SHuisong Li j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; 2989a7d3af2SHuisong Li qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1) 2999a7d3af2SHuisong Li << (j * HNS3_RSS_CFG_TBL_BW_H % 3009a7d3af2SHuisong Li HNS3_BITS_PER_BYTE); 3019a7d3af2SHuisong Li req->rss_result_h[qid_msb_off] |= qid_msb_val; 302c37ca66fSWei Hu (Xavier) } 3039a7d3af2SHuisong Li 304c37ca66fSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 305c37ca66fSWei Hu (Xavier) if (ret) { 306c37ca66fSWei Hu (Xavier) hns3_err(hw, 307c37ca66fSWei Hu (Xavier) "Sets RSS indirection table failed %d size %u", 308c37ca66fSWei Hu (Xavier) ret, size); 309c37ca66fSWei Hu (Xavier) return ret; 310c37ca66fSWei Hu (Xavier) } 311c37ca66fSWei Hu (Xavier) } 312c37ca66fSWei Hu (Xavier) 313c37ca66fSWei Hu (Xavier) /* Update redirection table of hw */ 3149a7d3af2SHuisong Li memcpy(hw->rss_info.rss_indirection_tbl, indir, 3150fce2c46SLijun Ou sizeof(uint16_t) * size); 316c37ca66fSWei Hu (Xavier) 317c37ca66fSWei Hu (Xavier) return 0; 318c37ca66fSWei Hu (Xavier) } 319c37ca66fSWei Hu (Xavier) 320c37ca66fSWei Hu (Xavier) int 321c37ca66fSWei Hu (Xavier) hns3_rss_reset_indir_table(struct hns3_hw *hw) 322c37ca66fSWei Hu (Xavier) { 3239a7d3af2SHuisong Li uint16_t *lut; 324c37ca66fSWei Hu (Xavier) int ret; 325c37ca66fSWei Hu (Xavier) 3269a7d3af2SHuisong Li lut = rte_zmalloc("hns3_rss_lut", 3270fce2c46SLijun Ou hw->rss_ind_tbl_size * sizeof(uint16_t), 0); 328c37ca66fSWei Hu (Xavier) if (lut == NULL) { 329c37ca66fSWei Hu (Xavier) hns3_err(hw, "No hns3_rss_lut memory can be allocated"); 330c37ca66fSWei Hu (Xavier) return -ENOMEM; 331c37ca66fSWei Hu (Xavier) } 332c37ca66fSWei Hu (Xavier) 3330fce2c46SLijun Ou ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size); 334c37ca66fSWei Hu (Xavier) if (ret) 335c37ca66fSWei Hu (Xavier) hns3_err(hw, "RSS uninit indir table failed: %d", ret); 336c37ca66fSWei Hu (Xavier) rte_free(lut); 337c37ca66fSWei Hu (Xavier) 338c37ca66fSWei Hu (Xavier) return ret; 339c37ca66fSWei Hu (Xavier) } 340c37ca66fSWei Hu (Xavier) 341c37ca66fSWei Hu (Xavier) int 342c37ca66fSWei Hu (Xavier) hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, 343c37ca66fSWei Hu (Xavier) struct hns3_rss_tuple_cfg *tuple, uint64_t rss_hf) 344c37ca66fSWei Hu (Xavier) { 345c37ca66fSWei Hu (Xavier) struct hns3_rss_input_tuple_cmd *req; 346c37ca66fSWei Hu (Xavier) struct hns3_cmd_desc desc; 347806f1d5aSLijun Ou uint32_t fields_count = 0; /* count times for setting tuple fields */ 348c37ca66fSWei Hu (Xavier) uint32_t i; 349c37ca66fSWei Hu (Xavier) int ret; 350c37ca66fSWei Hu (Xavier) 351c37ca66fSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 352c37ca66fSWei Hu (Xavier) 353c37ca66fSWei Hu (Xavier) req = (struct hns3_rss_input_tuple_cmd *)desc.data; 354c37ca66fSWei Hu (Xavier) 355806f1d5aSLijun Ou for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { 356806f1d5aSLijun Ou if ((rss_hf & hns3_set_tuple_table[i].rss_types) == 357806f1d5aSLijun Ou hns3_set_tuple_table[i].rss_types) { 358806f1d5aSLijun Ou req->tuple_field |= 359806f1d5aSLijun Ou rte_cpu_to_le_64(hns3_set_tuple_table[i].rss_field); 360806f1d5aSLijun Ou fields_count++; 361806f1d5aSLijun Ou } 362806f1d5aSLijun Ou } 363806f1d5aSLijun Ou 3648834849aSHao Chen /* 365806f1d5aSLijun Ou * When user does not specify the following types or a combination of 366806f1d5aSLijun Ou * the following types, it enables all fields for the supported RSS 367806f1d5aSLijun Ou * types. the following types as: 368295968d1SFerruh Yigit * - RTE_ETH_RSS_L3_SRC_ONLY 369295968d1SFerruh Yigit * - RTE_ETH_RSS_L3_DST_ONLY 370295968d1SFerruh Yigit * - RTE_ETH_RSS_L4_SRC_ONLY 371295968d1SFerruh Yigit * - RTE_ETH_RSS_L4_DST_ONLY 3728834849aSHao Chen */ 373806f1d5aSLijun Ou if (fields_count == 0) { 374806f1d5aSLijun Ou for (i = 0; i < RTE_DIM(hns3_set_rss_types); i++) { 375806f1d5aSLijun Ou if ((rss_hf & hns3_set_rss_types[i].rss_types) == 376806f1d5aSLijun Ou hns3_set_rss_types[i].rss_types) 377806f1d5aSLijun Ou req->tuple_field |= rte_cpu_to_le_64( 378806f1d5aSLijun Ou hns3_set_rss_types[i].rss_field); 379c37ca66fSWei Hu (Xavier) } 380c37ca66fSWei Hu (Xavier) } 381c37ca66fSWei Hu (Xavier) 382c37ca66fSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 383c37ca66fSWei Hu (Xavier) if (ret) { 384c37ca66fSWei Hu (Xavier) hns3_err(hw, "Update RSS flow types tuples failed %d", ret); 385c37ca66fSWei Hu (Xavier) return ret; 386c37ca66fSWei Hu (Xavier) } 387c37ca66fSWei Hu (Xavier) 388806f1d5aSLijun Ou tuple->rss_tuple_fields = rte_le_to_cpu_64(req->tuple_field); 389c37ca66fSWei Hu (Xavier) 390c37ca66fSWei Hu (Xavier) return 0; 391c37ca66fSWei Hu (Xavier) } 392c37ca66fSWei Hu (Xavier) 393c37ca66fSWei Hu (Xavier) /* 394c37ca66fSWei Hu (Xavier) * Configure RSS hash protocols and hash key. 395c37ca66fSWei Hu (Xavier) * @param dev 396c37ca66fSWei Hu (Xavier) * Pointer to Ethernet device. 397c37ca66fSWei Hu (Xavier) * @praram rss_conf 398c37ca66fSWei Hu (Xavier) * The configuration select of rss key size and tuple flow_types. 399c37ca66fSWei Hu (Xavier) * @return 400c37ca66fSWei Hu (Xavier) * 0 on success, a negative errno value otherwise is set. 401c37ca66fSWei Hu (Xavier) */ 402c37ca66fSWei Hu (Xavier) int 403c37ca66fSWei Hu (Xavier) hns3_dev_rss_hash_update(struct rte_eth_dev *dev, 404c37ca66fSWei Hu (Xavier) struct rte_eth_rss_conf *rss_conf) 405c37ca66fSWei Hu (Xavier) { 406c37ca66fSWei Hu (Xavier) struct hns3_adapter *hns = dev->data->dev_private; 407c37ca66fSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 408c37ca66fSWei Hu (Xavier) struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets; 409c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_cfg = &hw->rss_info; 410c37ca66fSWei Hu (Xavier) uint8_t key_len = rss_conf->rss_key_len; 411c37ca66fSWei Hu (Xavier) uint64_t rss_hf = rss_conf->rss_hf; 412c37ca66fSWei Hu (Xavier) uint8_t *key = rss_conf->rss_key; 413c37ca66fSWei Hu (Xavier) int ret; 414c37ca66fSWei Hu (Xavier) 4155e782bc2SLijun Ou if (hw->rss_dis_flag) 4165e782bc2SLijun Ou return -EINVAL; 4175e782bc2SLijun Ou 418c37ca66fSWei Hu (Xavier) rte_spinlock_lock(&hw->lock); 419c37ca66fSWei Hu (Xavier) ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_hf); 420c37ca66fSWei Hu (Xavier) if (ret) 421c37ca66fSWei Hu (Xavier) goto conf_err; 422c37ca66fSWei Hu (Xavier) 423c37ca66fSWei Hu (Xavier) if (rss_cfg->conf.types && rss_hf == 0) { 424c37ca66fSWei Hu (Xavier) /* Disable RSS, reset indirection table by local variable */ 425c37ca66fSWei Hu (Xavier) ret = hns3_rss_reset_indir_table(hw); 426c37ca66fSWei Hu (Xavier) if (ret) 427c37ca66fSWei Hu (Xavier) goto conf_err; 428c37ca66fSWei Hu (Xavier) } else if (rss_hf && rss_cfg->conf.types == 0) { 429c37ca66fSWei Hu (Xavier) /* Enable RSS, restore indirection table by hw's config */ 430c37ca66fSWei Hu (Xavier) ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 4310fce2c46SLijun Ou hw->rss_ind_tbl_size); 432c37ca66fSWei Hu (Xavier) if (ret) 433c37ca66fSWei Hu (Xavier) goto conf_err; 434c37ca66fSWei Hu (Xavier) } 435c37ca66fSWei Hu (Xavier) 436c37ca66fSWei Hu (Xavier) /* Update supported flow types when set tuple success */ 437c37ca66fSWei Hu (Xavier) rss_cfg->conf.types = rss_hf; 438c37ca66fSWei Hu (Xavier) 439c37ca66fSWei Hu (Xavier) if (key) { 440c37ca66fSWei Hu (Xavier) if (key_len != HNS3_RSS_KEY_SIZE) { 441c37ca66fSWei Hu (Xavier) hns3_err(hw, "The hash key len(%u) is invalid", 442c37ca66fSWei Hu (Xavier) key_len); 443c37ca66fSWei Hu (Xavier) ret = -EINVAL; 444c37ca66fSWei Hu (Xavier) goto conf_err; 445c37ca66fSWei Hu (Xavier) } 446a39e67ffSLijun Ou ret = hns3_rss_set_algo_key(hw, key); 447c37ca66fSWei Hu (Xavier) if (ret) 448c37ca66fSWei Hu (Xavier) goto conf_err; 449c37ca66fSWei Hu (Xavier) } 450c37ca66fSWei Hu (Xavier) rte_spinlock_unlock(&hw->lock); 451c37ca66fSWei Hu (Xavier) 452c37ca66fSWei Hu (Xavier) return 0; 453c37ca66fSWei Hu (Xavier) 454c37ca66fSWei Hu (Xavier) conf_err: 455c37ca66fSWei Hu (Xavier) rte_spinlock_unlock(&hw->lock); 456c37ca66fSWei Hu (Xavier) return ret; 457c37ca66fSWei Hu (Xavier) } 458c37ca66fSWei Hu (Xavier) 459c37ca66fSWei Hu (Xavier) /* 460c37ca66fSWei Hu (Xavier) * Get rss key and rss_hf types set of RSS hash configuration. 461c37ca66fSWei Hu (Xavier) * @param dev 462c37ca66fSWei Hu (Xavier) * Pointer to Ethernet device. 463c37ca66fSWei Hu (Xavier) * @praram rss_conf 464c37ca66fSWei Hu (Xavier) * The buffer to get rss key size and tuple types. 465c37ca66fSWei Hu (Xavier) * @return 466c37ca66fSWei Hu (Xavier) * 0 on success. 467c37ca66fSWei Hu (Xavier) */ 468c37ca66fSWei Hu (Xavier) int 469c37ca66fSWei Hu (Xavier) hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 470c37ca66fSWei Hu (Xavier) struct rte_eth_rss_conf *rss_conf) 471c37ca66fSWei Hu (Xavier) { 472c37ca66fSWei Hu (Xavier) struct hns3_adapter *hns = dev->data->dev_private; 473c37ca66fSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 474c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_cfg = &hw->rss_info; 475c37ca66fSWei Hu (Xavier) 476c37ca66fSWei Hu (Xavier) rte_spinlock_lock(&hw->lock); 477c37ca66fSWei Hu (Xavier) rss_conf->rss_hf = rss_cfg->conf.types; 478c37ca66fSWei Hu (Xavier) 479c37ca66fSWei Hu (Xavier) /* Get the RSS Key required by the user */ 480708e60a4SLijun Ou if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { 481c37ca66fSWei Hu (Xavier) memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); 482708e60a4SLijun Ou rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; 483708e60a4SLijun Ou } 484c37ca66fSWei Hu (Xavier) rte_spinlock_unlock(&hw->lock); 485c37ca66fSWei Hu (Xavier) 486c37ca66fSWei Hu (Xavier) return 0; 487c37ca66fSWei Hu (Xavier) } 488c37ca66fSWei Hu (Xavier) 489c37ca66fSWei Hu (Xavier) /* 490c37ca66fSWei Hu (Xavier) * Update rss redirection table of RSS. 491c37ca66fSWei Hu (Xavier) * @param dev 492c37ca66fSWei Hu (Xavier) * Pointer to Ethernet device. 493c37ca66fSWei Hu (Xavier) * @praram reta_conf 494c37ca66fSWei Hu (Xavier) * Pointer to the configuration select of mask and redirection tables. 495c37ca66fSWei Hu (Xavier) * @param reta_size 496c37ca66fSWei Hu (Xavier) * Redirection table size. 497c37ca66fSWei Hu (Xavier) * @return 498c37ca66fSWei Hu (Xavier) * 0 on success, a negative errno value otherwise is set. 499c37ca66fSWei Hu (Xavier) */ 500c37ca66fSWei Hu (Xavier) int 501c37ca66fSWei Hu (Xavier) hns3_dev_rss_reta_update(struct rte_eth_dev *dev, 502c37ca66fSWei Hu (Xavier) struct rte_eth_rss_reta_entry64 *reta_conf, 503c37ca66fSWei Hu (Xavier) uint16_t reta_size) 504c37ca66fSWei Hu (Xavier) { 505c37ca66fSWei Hu (Xavier) struct hns3_adapter *hns = dev->data->dev_private; 506c37ca66fSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 507c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_cfg = &hw->rss_info; 5080fce2c46SLijun Ou uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; 5095e76dfc3SHuisong Li uint16_t idx, shift; 5100fce2c46SLijun Ou uint16_t i; 511c37ca66fSWei Hu (Xavier) int ret; 512c37ca66fSWei Hu (Xavier) 5130fce2c46SLijun Ou if (reta_size != hw->rss_ind_tbl_size) { 514c37ca66fSWei Hu (Xavier) hns3_err(hw, "The size of hash lookup table configured (%u)" 515c37ca66fSWei Hu (Xavier) "doesn't match the number hardware can supported" 5160fce2c46SLijun Ou "(%u)", reta_size, hw->rss_ind_tbl_size); 517c37ca66fSWei Hu (Xavier) return -EINVAL; 518c37ca66fSWei Hu (Xavier) } 519c37ca66fSWei Hu (Xavier) rte_spinlock_lock(&hw->lock); 520c37ca66fSWei Hu (Xavier) memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, 5219a7d3af2SHuisong Li sizeof(rss_cfg->rss_indirection_tbl)); 522c37ca66fSWei Hu (Xavier) for (i = 0; i < reta_size; i++) { 523295968d1SFerruh Yigit idx = i / RTE_ETH_RETA_GROUP_SIZE; 524295968d1SFerruh Yigit shift = i % RTE_ETH_RETA_GROUP_SIZE; 5255e76dfc3SHuisong Li if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) { 526c37ca66fSWei Hu (Xavier) rte_spinlock_unlock(&hw->lock); 5275e76dfc3SHuisong Li hns3_err(hw, "queue id(%u) set to redirection table " 5285e76dfc3SHuisong Li "exceeds queue number(%u) allocated to a TC", 5295e76dfc3SHuisong Li reta_conf[idx].reta[shift], 5305e76dfc3SHuisong Li hw->alloc_rss_size); 531c37ca66fSWei Hu (Xavier) return -EINVAL; 532c37ca66fSWei Hu (Xavier) } 533c37ca66fSWei Hu (Xavier) 534c37ca66fSWei Hu (Xavier) if (reta_conf[idx].mask & (1ULL << shift)) 535c37ca66fSWei Hu (Xavier) indirection_tbl[i] = reta_conf[idx].reta[shift]; 536c37ca66fSWei Hu (Xavier) } 537c37ca66fSWei Hu (Xavier) 538c37ca66fSWei Hu (Xavier) ret = hns3_set_rss_indir_table(hw, indirection_tbl, 5390fce2c46SLijun Ou hw->rss_ind_tbl_size); 540c37ca66fSWei Hu (Xavier) 541c37ca66fSWei Hu (Xavier) rte_spinlock_unlock(&hw->lock); 542c37ca66fSWei Hu (Xavier) return ret; 543c37ca66fSWei Hu (Xavier) } 544c37ca66fSWei Hu (Xavier) 545c37ca66fSWei Hu (Xavier) /* 546c37ca66fSWei Hu (Xavier) * Get rss redirection table of RSS hash configuration. 547c37ca66fSWei Hu (Xavier) * @param dev 548c37ca66fSWei Hu (Xavier) * Pointer to Ethernet device. 549c37ca66fSWei Hu (Xavier) * @praram reta_conf 550c37ca66fSWei Hu (Xavier) * Pointer to the configuration select of mask and redirection tables. 551c37ca66fSWei Hu (Xavier) * @param reta_size 552c37ca66fSWei Hu (Xavier) * Redirection table size. 553c37ca66fSWei Hu (Xavier) * @return 554c37ca66fSWei Hu (Xavier) * 0 on success, a negative errno value otherwise is set. 555c37ca66fSWei Hu (Xavier) */ 556c37ca66fSWei Hu (Xavier) int 557c37ca66fSWei Hu (Xavier) hns3_dev_rss_reta_query(struct rte_eth_dev *dev, 558c37ca66fSWei Hu (Xavier) struct rte_eth_rss_reta_entry64 *reta_conf, 559c37ca66fSWei Hu (Xavier) uint16_t reta_size) 560c37ca66fSWei Hu (Xavier) { 561c37ca66fSWei Hu (Xavier) struct hns3_adapter *hns = dev->data->dev_private; 562c37ca66fSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 563c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_cfg = &hw->rss_info; 564c37ca66fSWei Hu (Xavier) uint16_t idx, shift; 5650fce2c46SLijun Ou uint16_t i; 566c37ca66fSWei Hu (Xavier) 5670fce2c46SLijun Ou if (reta_size != hw->rss_ind_tbl_size) { 568c37ca66fSWei Hu (Xavier) hns3_err(hw, "The size of hash lookup table configured (%u)" 569c37ca66fSWei Hu (Xavier) " doesn't match the number hardware can supported" 5700fce2c46SLijun Ou "(%u)", reta_size, hw->rss_ind_tbl_size); 571c37ca66fSWei Hu (Xavier) return -EINVAL; 572c37ca66fSWei Hu (Xavier) } 573c37ca66fSWei Hu (Xavier) rte_spinlock_lock(&hw->lock); 574c37ca66fSWei Hu (Xavier) for (i = 0; i < reta_size; i++) { 575295968d1SFerruh Yigit idx = i / RTE_ETH_RETA_GROUP_SIZE; 576295968d1SFerruh Yigit shift = i % RTE_ETH_RETA_GROUP_SIZE; 577c37ca66fSWei Hu (Xavier) if (reta_conf[idx].mask & (1ULL << shift)) 578c37ca66fSWei Hu (Xavier) reta_conf[idx].reta[shift] = 579920be799SLijun Ou rss_cfg->rss_indirection_tbl[i]; 580c37ca66fSWei Hu (Xavier) } 581c37ca66fSWei Hu (Xavier) rte_spinlock_unlock(&hw->lock); 582c37ca66fSWei Hu (Xavier) return 0; 583c37ca66fSWei Hu (Xavier) } 584c37ca66fSWei Hu (Xavier) 585c37ca66fSWei Hu (Xavier) /* 586c37ca66fSWei Hu (Xavier) * Used to configure the tc_size and tc_offset. 587c37ca66fSWei Hu (Xavier) */ 588c37ca66fSWei Hu (Xavier) static int 589c37ca66fSWei Hu (Xavier) hns3_set_rss_tc_mode(struct hns3_hw *hw) 590c37ca66fSWei Hu (Xavier) { 591c37ca66fSWei Hu (Xavier) uint16_t rss_size = hw->alloc_rss_size; 592c37ca66fSWei Hu (Xavier) struct hns3_rss_tc_mode_cmd *req; 593c37ca66fSWei Hu (Xavier) uint16_t tc_offset[HNS3_MAX_TC_NUM]; 594c37ca66fSWei Hu (Xavier) uint8_t tc_valid[HNS3_MAX_TC_NUM]; 595c37ca66fSWei Hu (Xavier) uint16_t tc_size[HNS3_MAX_TC_NUM]; 596c37ca66fSWei Hu (Xavier) struct hns3_cmd_desc desc; 597c37ca66fSWei Hu (Xavier) uint16_t roundup_size; 598c37ca66fSWei Hu (Xavier) uint16_t i; 599c37ca66fSWei Hu (Xavier) int ret; 600c37ca66fSWei Hu (Xavier) 601c37ca66fSWei Hu (Xavier) req = (struct hns3_rss_tc_mode_cmd *)desc.data; 602c37ca66fSWei Hu (Xavier) 603c37ca66fSWei Hu (Xavier) roundup_size = roundup_pow_of_two(rss_size); 604c37ca66fSWei Hu (Xavier) roundup_size = ilog2(roundup_size); 605c37ca66fSWei Hu (Xavier) 606c37ca66fSWei Hu (Xavier) for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 607c37ca66fSWei Hu (Xavier) tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); 608c37ca66fSWei Hu (Xavier) tc_size[i] = roundup_size; 609c37ca66fSWei Hu (Xavier) tc_offset[i] = rss_size * i; 610c37ca66fSWei Hu (Xavier) } 611c37ca66fSWei Hu (Xavier) 612c37ca66fSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false); 613c37ca66fSWei Hu (Xavier) for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 614c37ca66fSWei Hu (Xavier) uint16_t mode = 0; 615c37ca66fSWei Hu (Xavier) 616c37ca66fSWei Hu (Xavier) hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1)); 617c37ca66fSWei Hu (Xavier) hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S, 618c37ca66fSWei Hu (Xavier) tc_size[i]); 6199a7d3af2SHuisong Li if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0) 6209a7d3af2SHuisong Li hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1); 621c37ca66fSWei Hu (Xavier) hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S, 622c37ca66fSWei Hu (Xavier) tc_offset[i]); 623c37ca66fSWei Hu (Xavier) 624c37ca66fSWei Hu (Xavier) req->rss_tc_mode[i] = rte_cpu_to_le_16(mode); 625c37ca66fSWei Hu (Xavier) } 626c37ca66fSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 627c37ca66fSWei Hu (Xavier) if (ret) 628c37ca66fSWei Hu (Xavier) hns3_err(hw, "Sets rss tc mode failed %d", ret); 629c37ca66fSWei Hu (Xavier) 630c37ca66fSWei Hu (Xavier) return ret; 631c37ca66fSWei Hu (Xavier) } 632c37ca66fSWei Hu (Xavier) 633c37ca66fSWei Hu (Xavier) static void 634c37ca66fSWei Hu (Xavier) hns3_rss_tuple_uninit(struct hns3_hw *hw) 635c37ca66fSWei Hu (Xavier) { 636c37ca66fSWei Hu (Xavier) struct hns3_cmd_desc desc; 637c37ca66fSWei Hu (Xavier) int ret; 638c37ca66fSWei Hu (Xavier) 639c37ca66fSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 640c37ca66fSWei Hu (Xavier) 641c37ca66fSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 642c37ca66fSWei Hu (Xavier) if (ret) { 643c37ca66fSWei Hu (Xavier) hns3_err(hw, "RSS uninit tuple failed %d", ret); 644c37ca66fSWei Hu (Xavier) return; 645c37ca66fSWei Hu (Xavier) } 646c37ca66fSWei Hu (Xavier) } 647c37ca66fSWei Hu (Xavier) 648c37ca66fSWei Hu (Xavier) /* 649c37ca66fSWei Hu (Xavier) * Set the default rss configuration in the init of driver. 650c37ca66fSWei Hu (Xavier) */ 651c37ca66fSWei Hu (Xavier) void 652a39e67ffSLijun Ou hns3_rss_set_default_args(struct hns3_hw *hw) 653c37ca66fSWei Hu (Xavier) { 654c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_cfg = &hw->rss_info; 655c37ca66fSWei Hu (Xavier) uint16_t queue_num = hw->alloc_rss_size; 656c37ca66fSWei Hu (Xavier) int i; 657c37ca66fSWei Hu (Xavier) 658c37ca66fSWei Hu (Xavier) /* Default hash algorithm */ 6598834849aSHao Chen rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 6608834849aSHao Chen 6618834849aSHao Chen /* Default RSS key */ 662c37ca66fSWei Hu (Xavier) memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); 663c37ca66fSWei Hu (Xavier) 664c37ca66fSWei Hu (Xavier) /* Initialize RSS indirection table */ 6650fce2c46SLijun Ou for (i = 0; i < hw->rss_ind_tbl_size; i++) 666c37ca66fSWei Hu (Xavier) rss_cfg->rss_indirection_tbl[i] = i % queue_num; 667c37ca66fSWei Hu (Xavier) } 668c37ca66fSWei Hu (Xavier) 669c37ca66fSWei Hu (Xavier) /* 670*f8dbaebbSSean Morrissey * RSS initialization for hns3 PMD. 671c37ca66fSWei Hu (Xavier) */ 672c37ca66fSWei Hu (Xavier) int 673c37ca66fSWei Hu (Xavier) hns3_config_rss(struct hns3_adapter *hns) 674c37ca66fSWei Hu (Xavier) { 675c37ca66fSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 676c37ca66fSWei Hu (Xavier) struct hns3_rss_conf *rss_cfg = &hw->rss_info; 677c37ca66fSWei Hu (Xavier) uint8_t *hash_key = rss_cfg->key; 678c37ca66fSWei Hu (Xavier) int ret, ret1; 679c37ca66fSWei Hu (Xavier) 680c37ca66fSWei Hu (Xavier) enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; 681c37ca66fSWei Hu (Xavier) 68278b37190SLijun Ou switch (hw->rss_info.conf.func) { 68378b37190SLijun Ou case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: 68478b37190SLijun Ou hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; 68578b37190SLijun Ou break; 68678b37190SLijun Ou case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: 68778b37190SLijun Ou hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; 68878b37190SLijun Ou break; 68978b37190SLijun Ou default: 69078b37190SLijun Ou hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; 69178b37190SLijun Ou break; 69278b37190SLijun Ou } 69378b37190SLijun Ou 694920be799SLijun Ou /* When RSS is off, redirect the packet queue 0 */ 695295968d1SFerruh Yigit if (((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) == 0) 696c37ca66fSWei Hu (Xavier) hns3_rss_uninit(hns); 697c37ca66fSWei Hu (Xavier) 698c37ca66fSWei Hu (Xavier) /* Configure RSS hash algorithm and hash key offset */ 699a39e67ffSLijun Ou ret = hns3_rss_set_algo_key(hw, hash_key); 700c37ca66fSWei Hu (Xavier) if (ret) 701c37ca66fSWei Hu (Xavier) return ret; 702c37ca66fSWei Hu (Xavier) 703c37ca66fSWei Hu (Xavier) /* Configure the tuple selection for RSS hash input */ 704a39e67ffSLijun Ou ret = hns3_rss_set_input_tuple(hw); 705c37ca66fSWei Hu (Xavier) if (ret) 706c37ca66fSWei Hu (Xavier) return ret; 707c37ca66fSWei Hu (Xavier) 708920be799SLijun Ou /* 709920be799SLijun Ou * When RSS is off, it doesn't need to configure rss redirection table 710920be799SLijun Ou * to hardware. 711920be799SLijun Ou */ 712295968d1SFerruh Yigit if (((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)) { 713c37ca66fSWei Hu (Xavier) ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 7140fce2c46SLijun Ou hw->rss_ind_tbl_size); 715c37ca66fSWei Hu (Xavier) if (ret) 716c37ca66fSWei Hu (Xavier) goto rss_tuple_uninit; 717920be799SLijun Ou } 718c37ca66fSWei Hu (Xavier) 719c37ca66fSWei Hu (Xavier) ret = hns3_set_rss_tc_mode(hw); 720c37ca66fSWei Hu (Xavier) if (ret) 721c37ca66fSWei Hu (Xavier) goto rss_indir_table_uninit; 722c37ca66fSWei Hu (Xavier) 723c37ca66fSWei Hu (Xavier) return ret; 724c37ca66fSWei Hu (Xavier) 725c37ca66fSWei Hu (Xavier) rss_indir_table_uninit: 726295968d1SFerruh Yigit if (((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)) { 727c37ca66fSWei Hu (Xavier) ret1 = hns3_rss_reset_indir_table(hw); 728c37ca66fSWei Hu (Xavier) if (ret1 != 0) 729c37ca66fSWei Hu (Xavier) return ret; 730920be799SLijun Ou } 731c37ca66fSWei Hu (Xavier) 732c37ca66fSWei Hu (Xavier) rss_tuple_uninit: 733c37ca66fSWei Hu (Xavier) hns3_rss_tuple_uninit(hw); 734c37ca66fSWei Hu (Xavier) 735c37ca66fSWei Hu (Xavier) /* Disable RSS */ 736c37ca66fSWei Hu (Xavier) hw->rss_info.conf.types = 0; 737c37ca66fSWei Hu (Xavier) 738c37ca66fSWei Hu (Xavier) return ret; 739c37ca66fSWei Hu (Xavier) } 740c37ca66fSWei Hu (Xavier) 741c37ca66fSWei Hu (Xavier) /* 742*f8dbaebbSSean Morrissey * RSS uninitialization for hns3 PMD. 743c37ca66fSWei Hu (Xavier) */ 744c37ca66fSWei Hu (Xavier) void 745c37ca66fSWei Hu (Xavier) hns3_rss_uninit(struct hns3_adapter *hns) 746c37ca66fSWei Hu (Xavier) { 747c37ca66fSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 748c37ca66fSWei Hu (Xavier) int ret; 749c37ca66fSWei Hu (Xavier) 750c37ca66fSWei Hu (Xavier) hns3_rss_tuple_uninit(hw); 751c37ca66fSWei Hu (Xavier) ret = hns3_rss_reset_indir_table(hw); 752c37ca66fSWei Hu (Xavier) if (ret != 0) 753c37ca66fSWei Hu (Xavier) return; 754c37ca66fSWei Hu (Xavier) 755c37ca66fSWei Hu (Xavier) /* Disable RSS */ 756c37ca66fSWei Hu (Xavier) hw->rss_info.conf.types = 0; 757c37ca66fSWei Hu (Xavier) } 758