1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018-2021 HiSilicon Limited. 3 */ 4 5 #include <rte_ethdev.h> 6 #include <rte_io.h> 7 #include <rte_malloc.h> 8 9 #include "hns3_ethdev.h" 10 #include "hns3_logs.h" 11 12 /* Default hash keys */ 13 const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE] = { 14 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 15 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0, 16 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, 17 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 18 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA 19 }; 20 21 const uint8_t hns3_hash_func_map[] = { 22 [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ, 23 [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ, 24 [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE, 25 [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP, 26 }; 27 28 enum hns3_rss_tuple_type { 29 HNS3_RSS_IP_TUPLE, 30 HNS3_RSS_IP_L4_TUPLE, 31 }; 32 33 static const struct { 34 uint64_t rss_types; 35 uint16_t tuple_type; 36 uint64_t rss_field; 37 uint64_t tuple_mask; 38 } hns3_set_tuple_table[] = { 39 /* IPV4-FRAG */ 40 { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY, 41 HNS3_RSS_IP_TUPLE, 42 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S), 43 HNS3_RSS_TUPLE_IPV4_FLAG_M }, 44 { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY, 45 HNS3_RSS_IP_TUPLE, 46 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D), 47 HNS3_RSS_TUPLE_IPV4_FLAG_M }, 48 { RTE_ETH_RSS_FRAG_IPV4, 49 HNS3_RSS_IP_TUPLE, 50 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) | 51 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D), 52 HNS3_RSS_TUPLE_IPV4_FLAG_M }, 53 54 /* IPV4 */ 55 { RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY, 56 HNS3_RSS_IP_TUPLE, 57 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S), 58 HNS3_RSS_TUPLE_IPV4_NONF_M }, 59 { RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_DST_ONLY, 60 HNS3_RSS_IP_TUPLE, 61 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), 62 HNS3_RSS_TUPLE_IPV4_NONF_M }, 63 { RTE_ETH_RSS_IPV4, 64 HNS3_RSS_IP_TUPLE, 65 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | 66 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), 67 HNS3_RSS_TUPLE_IPV4_NONF_M }, 68 69 /* IPV4-OTHER */ 70 { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY, 71 HNS3_RSS_IP_TUPLE, 72 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S), 73 HNS3_RSS_TUPLE_IPV4_NONF_M }, 74 { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY, 75 HNS3_RSS_IP_TUPLE, 76 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), 77 HNS3_RSS_TUPLE_IPV4_NONF_M }, 78 { RTE_ETH_RSS_NONFRAG_IPV4_OTHER, 79 HNS3_RSS_IP_TUPLE, 80 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | 81 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), 82 HNS3_RSS_TUPLE_IPV4_NONF_M }, 83 84 /* IPV4-TCP */ 85 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY, 86 HNS3_RSS_IP_L4_TUPLE, 87 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S), 88 HNS3_RSS_TUPLE_IPV4_TCP_M }, 89 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY, 90 HNS3_RSS_IP_L4_TUPLE, 91 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D), 92 HNS3_RSS_TUPLE_IPV4_TCP_M }, 93 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY, 94 HNS3_RSS_IP_L4_TUPLE, 95 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S), 96 HNS3_RSS_TUPLE_IPV4_TCP_M }, 97 { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY, 98 HNS3_RSS_IP_L4_TUPLE, 99 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D), 100 HNS3_RSS_TUPLE_IPV4_TCP_M }, 101 { RTE_ETH_RSS_NONFRAG_IPV4_TCP, 102 HNS3_RSS_IP_L4_TUPLE, 103 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | 104 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | 105 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | 106 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D), 107 HNS3_RSS_TUPLE_IPV4_TCP_M }, 108 109 /* IPV4-UDP */ 110 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY, 111 HNS3_RSS_IP_L4_TUPLE, 112 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S), 113 HNS3_RSS_TUPLE_IPV4_UDP_M }, 114 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY, 115 HNS3_RSS_IP_L4_TUPLE, 116 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D), 117 HNS3_RSS_TUPLE_IPV4_UDP_M }, 118 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY, 119 HNS3_RSS_IP_L4_TUPLE, 120 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S), 121 HNS3_RSS_TUPLE_IPV4_UDP_M }, 122 { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY, 123 HNS3_RSS_IP_L4_TUPLE, 124 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D), 125 HNS3_RSS_TUPLE_IPV4_UDP_M }, 126 { RTE_ETH_RSS_NONFRAG_IPV4_UDP, 127 HNS3_RSS_IP_L4_TUPLE, 128 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) | 129 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) | 130 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) | 131 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D), 132 HNS3_RSS_TUPLE_IPV4_UDP_M }, 133 134 /* IPV4-SCTP */ 135 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY, 136 HNS3_RSS_IP_L4_TUPLE, 137 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S), 138 HNS3_RSS_TUPLE_IPV4_SCTP_M }, 139 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY, 140 HNS3_RSS_IP_L4_TUPLE, 141 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D), 142 HNS3_RSS_TUPLE_IPV4_SCTP_M }, 143 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY, 144 HNS3_RSS_IP_L4_TUPLE, 145 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S), 146 HNS3_RSS_TUPLE_IPV4_SCTP_M }, 147 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY, 148 HNS3_RSS_IP_L4_TUPLE, 149 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D), 150 HNS3_RSS_TUPLE_IPV4_SCTP_M }, 151 { RTE_ETH_RSS_NONFRAG_IPV4_SCTP, 152 HNS3_RSS_IP_L4_TUPLE, 153 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) | 154 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) | 155 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) | 156 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) | 157 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER), 158 HNS3_RSS_TUPLE_IPV4_SCTP_M }, 159 160 /* IPV6-FRAG */ 161 { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY, 162 HNS3_RSS_IP_TUPLE, 163 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S), 164 HNS3_RSS_TUPLE_IPV6_FLAG_M }, 165 { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY, 166 HNS3_RSS_IP_TUPLE, 167 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D), 168 HNS3_RSS_TUPLE_IPV6_FLAG_M }, 169 { RTE_ETH_RSS_FRAG_IPV6, 170 HNS3_RSS_IP_TUPLE, 171 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) | 172 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D), 173 HNS3_RSS_TUPLE_IPV6_FLAG_M }, 174 175 /* IPV6 */ 176 { RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY, 177 HNS3_RSS_IP_TUPLE, 178 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S), 179 HNS3_RSS_TUPLE_IPV6_NONF_M }, 180 { RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_DST_ONLY, 181 HNS3_RSS_IP_TUPLE, 182 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), 183 HNS3_RSS_TUPLE_IPV6_NONF_M }, 184 { RTE_ETH_RSS_IPV6, 185 HNS3_RSS_IP_TUPLE, 186 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | 187 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), 188 HNS3_RSS_TUPLE_IPV6_NONF_M }, 189 190 /* IPV6-OTHER */ 191 { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY, 192 HNS3_RSS_IP_TUPLE, 193 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S), 194 HNS3_RSS_TUPLE_IPV6_NONF_M }, 195 { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY, 196 HNS3_RSS_IP_TUPLE, 197 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), 198 HNS3_RSS_TUPLE_IPV6_NONF_M }, 199 { RTE_ETH_RSS_NONFRAG_IPV6_OTHER, 200 HNS3_RSS_IP_TUPLE, 201 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | 202 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), 203 HNS3_RSS_TUPLE_IPV6_NONF_M }, 204 205 /* IPV6-TCP */ 206 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY, 207 HNS3_RSS_IP_L4_TUPLE, 208 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S), 209 HNS3_RSS_TUPLE_IPV6_TCP_M }, 210 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY, 211 HNS3_RSS_IP_L4_TUPLE, 212 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D), 213 HNS3_RSS_TUPLE_IPV6_TCP_M }, 214 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY, 215 HNS3_RSS_IP_L4_TUPLE, 216 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S), 217 HNS3_RSS_TUPLE_IPV6_TCP_M }, 218 { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY, 219 HNS3_RSS_IP_L4_TUPLE, 220 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D), 221 HNS3_RSS_TUPLE_IPV6_TCP_M }, 222 { RTE_ETH_RSS_NONFRAG_IPV6_TCP, 223 HNS3_RSS_IP_L4_TUPLE, 224 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) | 225 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) | 226 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) | 227 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D), 228 HNS3_RSS_TUPLE_IPV6_TCP_M }, 229 230 /* IPV6-UDP */ 231 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY, 232 HNS3_RSS_IP_L4_TUPLE, 233 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S), 234 HNS3_RSS_TUPLE_IPV6_UDP_M }, 235 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY, 236 HNS3_RSS_IP_L4_TUPLE, 237 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D), 238 HNS3_RSS_TUPLE_IPV6_UDP_M }, 239 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY, 240 HNS3_RSS_IP_L4_TUPLE, 241 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S), 242 HNS3_RSS_TUPLE_IPV6_UDP_M }, 243 { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY, 244 HNS3_RSS_IP_L4_TUPLE, 245 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D), 246 HNS3_RSS_TUPLE_IPV6_UDP_M }, 247 { RTE_ETH_RSS_NONFRAG_IPV6_UDP, 248 HNS3_RSS_IP_L4_TUPLE, 249 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) | 250 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) | 251 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) | 252 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D), 253 HNS3_RSS_TUPLE_IPV6_UDP_M }, 254 255 /* IPV6-SCTP */ 256 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY, 257 HNS3_RSS_IP_L4_TUPLE, 258 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S), 259 HNS3_RSS_TUPLE_IPV6_SCTP_M }, 260 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_DST_ONLY, 261 HNS3_RSS_IP_L4_TUPLE, 262 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D), 263 HNS3_RSS_TUPLE_IPV6_SCTP_M }, 264 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_SRC_ONLY, 265 HNS3_RSS_IP_L4_TUPLE, 266 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S), 267 HNS3_RSS_TUPLE_IPV6_SCTP_M }, 268 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY, 269 HNS3_RSS_IP_L4_TUPLE, 270 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D), 271 HNS3_RSS_TUPLE_IPV6_SCTP_M }, 272 { RTE_ETH_RSS_NONFRAG_IPV6_SCTP, 273 HNS3_RSS_IP_L4_TUPLE, 274 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) | 275 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) | 276 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) | 277 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) | 278 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER), 279 HNS3_RSS_TUPLE_IPV6_SCTP_M }, 280 }; 281 282 /* 283 * rss_generic_config command function, opcode:0x0D01. 284 * Used to set algorithm and hash key of RSS. 285 */ 286 static int 287 hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, 288 const uint8_t *key, uint8_t key_len) 289 { 290 struct hns3_rss_generic_config_cmd *req; 291 struct hns3_cmd_desc desc; 292 const uint8_t *cur_key; 293 uint16_t cur_key_size; 294 uint16_t max_bd_num; 295 uint16_t idx; 296 int ret; 297 298 req = (struct hns3_rss_generic_config_cmd *)desc.data; 299 300 max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM); 301 for (idx = 0; idx < max_bd_num; idx++) { 302 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, 303 false); 304 305 req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK); 306 req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); 307 308 if (idx == max_bd_num - 1 && 309 (key_len % HNS3_RSS_HASH_KEY_NUM) != 0) 310 cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; 311 else 312 cur_key_size = HNS3_RSS_HASH_KEY_NUM; 313 314 cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM; 315 memcpy(req->hash_key, cur_key, cur_key_size); 316 317 ret = hns3_cmd_send(hw, &desc, 1); 318 if (ret) { 319 hns3_err(hw, "Configure RSS algo key failed %d", ret); 320 return ret; 321 } 322 } 323 324 return 0; 325 } 326 327 static int 328 hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, 329 uint8_t *key, uint8_t key_len) 330 { 331 struct hns3_rss_generic_config_cmd *req; 332 struct hns3_cmd_desc desc; 333 uint16_t cur_key_size; 334 uint16_t max_bd_num; 335 uint8_t *cur_key; 336 uint16_t idx; 337 int ret; 338 339 req = (struct hns3_rss_generic_config_cmd *)desc.data; 340 max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM); 341 for (idx = 0; idx < max_bd_num; idx++) { 342 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, 343 true); 344 345 req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); 346 ret = hns3_cmd_send(hw, &desc, 1); 347 if (ret) { 348 hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d", 349 ret); 350 return ret; 351 } 352 353 if (idx == 0) 354 *hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK; 355 356 if (idx == max_bd_num - 1 && 357 (key_len % HNS3_RSS_HASH_KEY_NUM) != 0) 358 cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; 359 else 360 cur_key_size = HNS3_RSS_HASH_KEY_NUM; 361 362 cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM; 363 memcpy(cur_key, req->hash_key, cur_key_size); 364 } 365 366 return 0; 367 } 368 369 /* 370 * rss_indirection_table command function, opcode:0x0D07. 371 * Used to configure the indirection table of rss. 372 */ 373 int 374 hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) 375 { 376 struct hns3_rss_indirection_table_cmd *req; 377 uint16_t max_bd_num, cfg_tbl_size; 378 struct hns3_cmd_desc desc; 379 uint8_t qid_msb_off; 380 uint8_t qid_msb_val; 381 uint16_t q_id; 382 uint16_t i, j; 383 int ret; 384 385 req = (struct hns3_rss_indirection_table_cmd *)desc.data; 386 max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE); 387 for (i = 0; i < max_bd_num; i++) { 388 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, 389 false); 390 req->start_table_index = 391 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); 392 req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); 393 394 if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0) 395 cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE; 396 else 397 cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE; 398 399 for (j = 0; j < cfg_tbl_size; j++) { 400 q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; 401 req->rss_result_l[j] = q_id & 0xff; 402 403 qid_msb_off = 404 j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; 405 qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1) 406 << (j * HNS3_RSS_CFG_TBL_BW_H % 407 HNS3_BITS_PER_BYTE); 408 req->rss_result_h[qid_msb_off] |= qid_msb_val; 409 } 410 411 ret = hns3_cmd_send(hw, &desc, 1); 412 if (ret) { 413 hns3_err(hw, 414 "Sets RSS indirection table failed %d size %u", 415 ret, size); 416 return ret; 417 } 418 } 419 420 return 0; 421 } 422 423 static int 424 hns3_get_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) 425 { 426 struct hns3_rss_indirection_table_cmd *req; 427 uint16_t max_bd_num, cfg_tbl_size; 428 uint8_t qid_msb_off, qid_msb_idx; 429 struct hns3_cmd_desc desc; 430 uint16_t q_id, q_hi, q_lo; 431 uint8_t rss_result_h; 432 uint16_t i, j; 433 int ret; 434 435 req = (struct hns3_rss_indirection_table_cmd *)desc.data; 436 max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE); 437 for (i = 0; i < max_bd_num; i++) { 438 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, 439 true); 440 req->start_table_index = 441 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); 442 ret = hns3_cmd_send(hw, &desc, 1); 443 if (ret) { 444 hns3_err(hw, "fail to get RSS indirection table from firmware, ret = %d", 445 ret); 446 return ret; 447 } 448 449 if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0) 450 cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE; 451 else 452 cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE; 453 454 for (j = 0; j < cfg_tbl_size; j++) { 455 qid_msb_idx = 456 j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; 457 rss_result_h = req->rss_result_h[qid_msb_idx]; 458 qid_msb_off = 459 j * HNS3_RSS_CFG_TBL_BW_H % HNS3_BITS_PER_BYTE; 460 q_hi = (rss_result_h >> qid_msb_off) & 461 HNS3_RSS_CFG_TBL_BW_H_M; 462 q_lo = req->rss_result_l[j]; 463 q_id = (q_hi << HNS3_RSS_CFG_TBL_BW_L) | q_lo; 464 indir[i * HNS3_RSS_CFG_TBL_SIZE + j] = q_id; 465 } 466 } 467 468 return 0; 469 } 470 471 int 472 hns3_rss_reset_indir_table(struct hns3_hw *hw) 473 { 474 uint16_t *lut; 475 int ret; 476 477 lut = rte_zmalloc("hns3_rss_lut", 478 hw->rss_ind_tbl_size * sizeof(uint16_t), 0); 479 if (lut == NULL) { 480 hns3_err(hw, "No hns3_rss_lut memory can be allocated"); 481 return -ENOMEM; 482 } 483 484 ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size); 485 if (ret != 0) 486 hns3_err(hw, "RSS uninit indir table failed, ret = %d.", ret); 487 else 488 memcpy(hw->rss_info.rss_indirection_tbl, lut, 489 sizeof(uint16_t) * hw->rss_ind_tbl_size); 490 rte_free(lut); 491 492 return ret; 493 } 494 495 bool 496 hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types) 497 { 498 uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | 499 RTE_ETH_RSS_NONFRAG_IPV4_OTHER | 500 RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | 501 RTE_ETH_RSS_NONFRAG_IPV6_OTHER; 502 uint64_t ip_l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP | 503 RTE_ETH_RSS_NONFRAG_IPV4_UDP | 504 RTE_ETH_RSS_NONFRAG_IPV4_SCTP | 505 RTE_ETH_RSS_NONFRAG_IPV6_TCP | 506 RTE_ETH_RSS_NONFRAG_IPV6_UDP | 507 RTE_ETH_RSS_NONFRAG_IPV6_SCTP; 508 bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST); 509 bool has_ip_pkt = !!(types & ip_mask); 510 uint64_t final_types; 511 512 if (types == 0) 513 return true; 514 515 if ((types & HNS3_ETH_RSS_SUPPORT) == 0) { 516 hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.", 517 types); 518 return false; 519 } 520 521 if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 && 522 (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) { 523 hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set."); 524 return false; 525 } 526 527 if (has_l4_src_dst && (types & ip_l4_mask) == 0) { 528 if (!has_ip_pkt) { 529 hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set."); 530 return false; 531 } 532 /* 533 * For the case that the types has L4_SRC/DST_ONLY but hasn't 534 * IP-TCP/UDP/SCTP packet type, this types is considered valid 535 * if it also has IP packet type. 536 */ 537 hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet."); 538 } 539 540 if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) { 541 final_types = types & HNS3_ETH_RSS_SUPPORT; 542 hns3_warn(hw, "set RSS types based on hardware support, requested:0x%" PRIx64 " configured:0x%" PRIx64 "", 543 types, final_types); 544 } 545 546 return true; 547 } 548 549 uint64_t 550 hns3_rss_calc_tuple_filed(uint64_t rss_hf) 551 { 552 uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY | 553 RTE_ETH_RSS_L3_DST_ONLY; 554 uint64_t l4_only_mask = RTE_ETH_RSS_L4_SRC_ONLY | 555 RTE_ETH_RSS_L4_DST_ONLY; 556 uint64_t l3_l4_only_mask = l3_only_mask | l4_only_mask; 557 bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask); 558 bool has_l3_only = !!(rss_hf & l3_only_mask); 559 uint64_t tuple = 0; 560 uint32_t i; 561 562 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { 563 if ((rss_hf & hns3_set_tuple_table[i].rss_types) != 564 hns3_set_tuple_table[i].rss_types) 565 continue; 566 567 if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) { 568 if (hns3_set_tuple_table[i].rss_types & l3_only_mask || 569 !has_l3_only) 570 tuple |= hns3_set_tuple_table[i].rss_field; 571 continue; 572 } 573 574 /* For IP types with L4, we need check both L3 and L4 */ 575 if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask || 576 !has_l3_l4_only) 577 tuple |= hns3_set_tuple_table[i].rss_field; 578 } 579 580 return tuple; 581 } 582 583 int 584 hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields) 585 { 586 struct hns3_rss_input_tuple_cmd *req; 587 struct hns3_cmd_desc desc; 588 int ret; 589 590 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 591 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 592 req->tuple_field = rte_cpu_to_le_64(tuple_fields); 593 ret = hns3_cmd_send(hw, &desc, 1); 594 if (ret != 0) 595 hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret); 596 597 return ret; 598 } 599 600 int 601 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) 602 { 603 uint64_t tuple_fields; 604 int ret; 605 606 tuple_fields = hns3_rss_calc_tuple_filed(rss_hf); 607 ret = hns3_set_rss_tuple_field(hw, tuple_fields); 608 if (ret != 0) 609 hns3_err(hw, "Update RSS flow types tuples failed, ret = %d", 610 ret); 611 612 return ret; 613 } 614 615 /* 616 * Configure RSS hash protocols and hash key. 617 * @param dev 618 * Pointer to Ethernet device. 619 * @praram rss_conf 620 * The configuration select of rss key size and tuple flow_types. 621 * @return 622 * 0 on success, a negative errno value otherwise is set. 623 */ 624 int 625 hns3_dev_rss_hash_update(struct rte_eth_dev *dev, 626 struct rte_eth_rss_conf *rss_conf) 627 { 628 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); 629 uint64_t rss_hf_bk = hw->rss_info.rss_hf; 630 uint8_t key_len = rss_conf->rss_key_len; 631 uint64_t rss_hf = rss_conf->rss_hf; 632 uint8_t *key = rss_conf->rss_key; 633 int ret; 634 635 if (key && key_len != hw->rss_key_size) { 636 hns3_err(hw, "the hash key len(%u) is invalid, must be %u", 637 key_len, hw->rss_key_size); 638 return -EINVAL; 639 } 640 641 if (!hns3_check_rss_types_valid(hw, rss_hf)) 642 return -EINVAL; 643 644 rte_spinlock_lock(&hw->lock); 645 ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); 646 if (ret) 647 goto set_tuple_fail; 648 649 ret = hns3_update_rss_algo_key(hw, rss_conf->algorithm, key, key_len); 650 if (ret != 0) 651 goto set_algo_key_fail; 652 653 if (rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_DEFAULT) 654 hw->rss_info.hash_algo = hns3_hash_func_map[rss_conf->algorithm]; 655 if (key != NULL) 656 memcpy(hw->rss_info.key, key, hw->rss_key_size); 657 hw->rss_info.rss_hf = rss_hf; 658 rte_spinlock_unlock(&hw->lock); 659 660 return 0; 661 662 set_algo_key_fail: 663 (void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk); 664 set_tuple_fail: 665 rte_spinlock_unlock(&hw->lock); 666 return ret; 667 } 668 669 int 670 hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields) 671 { 672 struct hns3_rss_input_tuple_cmd *req; 673 struct hns3_cmd_desc desc; 674 int ret; 675 676 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true); 677 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 678 ret = hns3_cmd_send(hw, &desc, 1); 679 if (ret != 0) { 680 hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d", 681 ret); 682 return ret; 683 } 684 685 *tuple_fields = rte_le_to_cpu_64(req->tuple_field); 686 687 return 0; 688 } 689 690 static uint64_t 691 hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw *hw, uint64_t tuple_fields) 692 { 693 uint64_t ipv6_sctp_l4_mask = 694 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) | 695 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S); 696 uint64_t rss_hf = 0; 697 uint64_t tuple_mask; 698 uint32_t i; 699 700 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { 701 tuple_mask = hns3_set_tuple_table[i].tuple_mask; 702 /* 703 * The RSS hash of the packet type is disabled if its tuples is 704 * zero. 705 */ 706 if ((tuple_fields & tuple_mask) == 0) 707 continue; 708 709 /* 710 * Some hardware don't support to use src/dst port fields to 711 * hash for IPV6-SCTP packet. 712 */ 713 if ((hns3_set_tuple_table[i].rss_types & 714 RTE_ETH_RSS_NONFRAG_IPV6_SCTP) && 715 !hw->rss_info.ipv6_sctp_offload_supported) 716 tuple_mask &= ~ipv6_sctp_l4_mask; 717 718 /* 719 * The framework (ethdev ops) or driver (rte flow API) ensure 720 * that both L3_SRC/DST_ONLY and L4_SRC/DST_ONLY cannot be set 721 * to driver at the same time. But if user doesn't specify 722 * anything L3/L4_SRC/DST_ONLY, driver enables all tuple fields. 723 * In this case, driver should not report L3/L4_SRC/DST_ONLY. 724 */ 725 if ((tuple_fields & tuple_mask) == tuple_mask) { 726 /* Skip the item enabled part tuples. */ 727 if ((tuple_fields & hns3_set_tuple_table[i].rss_field) != 728 tuple_mask) 729 continue; 730 731 rss_hf |= hns3_set_tuple_table[i].rss_types; 732 continue; 733 } 734 735 /* Match the item enabled part tuples.*/ 736 if ((tuple_fields & hns3_set_tuple_table[i].rss_field) == 737 hns3_set_tuple_table[i].rss_field) 738 rss_hf |= hns3_set_tuple_table[i].rss_types; 739 } 740 741 return rss_hf; 742 } 743 744 static int 745 hns3_rss_hash_get_rss_hf(struct hns3_hw *hw, uint64_t *rss_hf) 746 { 747 uint64_t tuple_fields; 748 int ret; 749 750 ret = hns3_get_rss_tuple_field(hw, &tuple_fields); 751 if (ret != 0) 752 return ret; 753 754 *rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields); 755 756 return 0; 757 } 758 759 /* 760 * Get rss key and rss_hf types set of RSS hash configuration. 761 * @param dev 762 * Pointer to Ethernet device. 763 * @praram rss_conf 764 * The buffer to get rss key size and tuple types. 765 * @return 766 * 0 on success. 767 */ 768 int 769 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 770 struct rte_eth_rss_conf *rss_conf) 771 { 772 const uint8_t hash_func_map[] = { 773 [HNS3_RSS_HASH_ALGO_TOEPLITZ] = RTE_ETH_HASH_FUNCTION_TOEPLITZ, 774 [HNS3_RSS_HASH_ALGO_SIMPLE] = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR, 775 [HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP] = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ, 776 }; 777 struct hns3_adapter *hns = dev->data->dev_private; 778 uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; 779 struct hns3_hw *hw = &hns->hw; 780 uint8_t hash_algo = 0; 781 int ret; 782 783 rte_spinlock_lock(&hw->lock); 784 ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf); 785 if (ret != 0) { 786 rte_spinlock_unlock(&hw->lock); 787 hns3_err(hw, "obtain hash tuples failed, ret = %d", ret); 788 return ret; 789 } 790 791 ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size); 792 if (ret != 0) { 793 rte_spinlock_unlock(&hw->lock); 794 hns3_err(hw, "obtain hash algo and key failed, ret = %d", ret); 795 return ret; 796 } 797 rte_spinlock_unlock(&hw->lock); 798 799 /* Get the RSS Key if user required. */ 800 if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) { 801 memcpy(rss_conf->rss_key, rss_key, hw->rss_key_size); 802 rss_conf->rss_key_len = hw->rss_key_size; 803 } 804 rss_conf->algorithm = hash_func_map[hash_algo]; 805 806 return 0; 807 } 808 809 /* 810 * Update rss redirection table of RSS. 811 * @param dev 812 * Pointer to Ethernet device. 813 * @praram reta_conf 814 * Pointer to the configuration select of mask and redirection tables. 815 * @param reta_size 816 * Redirection table size. 817 * @return 818 * 0 on success, a negative errno value otherwise is set. 819 */ 820 int 821 hns3_dev_rss_reta_update(struct rte_eth_dev *dev, 822 struct rte_eth_rss_reta_entry64 *reta_conf, 823 uint16_t reta_size) 824 { 825 struct hns3_adapter *hns = dev->data->dev_private; 826 struct hns3_hw *hw = &hns->hw; 827 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 828 uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; 829 uint16_t idx, shift; 830 uint16_t i; 831 int ret; 832 833 if (reta_size != hw->rss_ind_tbl_size) { 834 hns3_err(hw, "The size of hash lookup table configured (%u)" 835 "doesn't match the number hardware can supported" 836 "(%u)", reta_size, hw->rss_ind_tbl_size); 837 return -EINVAL; 838 } 839 rte_spinlock_lock(&hw->lock); 840 memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, 841 sizeof(rss_cfg->rss_indirection_tbl)); 842 for (i = 0; i < reta_size; i++) { 843 idx = i / RTE_ETH_RETA_GROUP_SIZE; 844 shift = i % RTE_ETH_RETA_GROUP_SIZE; 845 if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) { 846 hns3_err(hw, "queue id(%u) set to redirection table " 847 "exceeds queue number(%u) allocated to a TC", 848 reta_conf[idx].reta[shift], 849 hw->alloc_rss_size); 850 ret = -EINVAL; 851 goto out; 852 } 853 854 if (reta_conf[idx].mask & (1ULL << shift)) 855 indirection_tbl[i] = reta_conf[idx].reta[shift]; 856 } 857 858 ret = hns3_set_rss_indir_table(hw, indirection_tbl, 859 hw->rss_ind_tbl_size); 860 if (ret != 0) 861 goto out; 862 863 memcpy(rss_cfg->rss_indirection_tbl, indirection_tbl, 864 sizeof(uint16_t) * hw->rss_ind_tbl_size); 865 866 out: 867 rte_spinlock_unlock(&hw->lock); 868 return ret; 869 } 870 871 /* 872 * Get rss redirection table of RSS hash configuration. 873 * @param dev 874 * Pointer to Ethernet device. 875 * @praram reta_conf 876 * Pointer to the configuration select of mask and redirection tables. 877 * @param reta_size 878 * Redirection table size. 879 * @return 880 * 0 on success, a negative errno value otherwise is set. 881 */ 882 int 883 hns3_dev_rss_reta_query(struct rte_eth_dev *dev, 884 struct rte_eth_rss_reta_entry64 *reta_conf, 885 uint16_t reta_size) 886 { 887 struct hns3_adapter *hns = dev->data->dev_private; 888 uint16_t reta_table[HNS3_RSS_IND_TBL_SIZE_MAX]; 889 struct hns3_hw *hw = &hns->hw; 890 uint16_t idx, shift; 891 uint16_t i; 892 int ret; 893 894 if (reta_size != hw->rss_ind_tbl_size) { 895 hns3_err(hw, "The size of hash lookup table configured (%u)" 896 " doesn't match the number hardware can supported" 897 "(%u)", reta_size, hw->rss_ind_tbl_size); 898 return -EINVAL; 899 } 900 rte_spinlock_lock(&hw->lock); 901 ret = hns3_get_rss_indir_table(hw, reta_table, reta_size); 902 if (ret != 0) { 903 rte_spinlock_unlock(&hw->lock); 904 hns3_err(hw, "query RSS redirection table failed, ret = %d.", 905 ret); 906 return ret; 907 } 908 rte_spinlock_unlock(&hw->lock); 909 910 for (i = 0; i < reta_size; i++) { 911 idx = i / RTE_ETH_RETA_GROUP_SIZE; 912 shift = i % RTE_ETH_RETA_GROUP_SIZE; 913 if (reta_conf[idx].mask & (1ULL << shift)) 914 reta_conf[idx].reta[shift] = reta_table[i]; 915 } 916 917 return 0; 918 } 919 920 static void 921 hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid, 922 uint16_t *tc_size, uint16_t *tc_offset, 923 uint8_t tc_num) 924 { 925 struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); 926 uint16_t rss_size = hw->alloc_rss_size; 927 uint16_t roundup_size; 928 uint16_t i; 929 930 roundup_size = roundup_pow_of_two(rss_size); 931 roundup_size = ilog2(roundup_size); 932 933 for (i = 0; i < tc_num; i++) { 934 if (hns->is_vf) { 935 /* 936 * For packets with VLAN priorities destined for the VF, 937 * hardware still assign Rx queue based on the Up-to-TC 938 * mapping PF configured. But VF has only one TC. If 939 * other TC don't enable, it causes that the priority 940 * packets that aren't destined for TC0 aren't received 941 * by RSS hash but is destined for queue 0. So driver 942 * has to enable the unused TC by using TC0 queue 943 * mapping configuration. 944 */ 945 tc_valid[i] = (hw->hw_tc_map & BIT(i)) ? 946 !!(hw->hw_tc_map & BIT(i)) : 1; 947 tc_size[i] = roundup_size; 948 tc_offset[i] = (hw->hw_tc_map & BIT(i)) ? 949 rss_size * i : 0; 950 } else { 951 tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); 952 tc_size[i] = tc_valid[i] ? roundup_size : 0; 953 tc_offset[i] = tc_valid[i] ? rss_size * i : 0; 954 } 955 } 956 } 957 958 static int 959 hns3_set_rss_tc_mode(struct hns3_hw *hw) 960 { 961 struct hns3_rss_tc_mode_cmd *req; 962 uint16_t tc_offset[HNS3_MAX_TC_NUM]; 963 uint8_t tc_valid[HNS3_MAX_TC_NUM]; 964 uint16_t tc_size[HNS3_MAX_TC_NUM]; 965 struct hns3_cmd_desc desc; 966 uint16_t i; 967 int ret; 968 969 hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size, 970 tc_offset, HNS3_MAX_TC_NUM); 971 972 req = (struct hns3_rss_tc_mode_cmd *)desc.data; 973 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false); 974 for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 975 uint16_t mode = 0; 976 977 hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1)); 978 hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S, 979 tc_size[i]); 980 if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0) 981 hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1); 982 hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S, 983 tc_offset[i]); 984 985 req->rss_tc_mode[i] = rte_cpu_to_le_16(mode); 986 } 987 ret = hns3_cmd_send(hw, &desc, 1); 988 if (ret) 989 hns3_err(hw, "Sets rss tc mode failed %d", ret); 990 991 return ret; 992 } 993 994 /* 995 * Note: the 'hash_algo' is defined by enum rte_eth_hash_function. 996 */ 997 int 998 hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func, 999 uint8_t *key, uint8_t key_len) 1000 { 1001 uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; 1002 bool modify_key, modify_algo; 1003 uint8_t hash_algo = 0; 1004 int ret; 1005 1006 modify_key = (key != NULL && key_len > 0); 1007 modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT; 1008 if (!modify_key && !modify_algo) 1009 return 0; 1010 1011 if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) { 1012 hns3_err(hw, "hash func (%u) is unsupported.", hash_func); 1013 return -ENOTSUP; 1014 } 1015 if (modify_key && key_len != hw->rss_key_size) { 1016 hns3_err(hw, "hash key length (%u) is invalid.", key_len); 1017 return -EINVAL; 1018 } 1019 1020 ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size); 1021 if (ret != 0) { 1022 hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d", 1023 ret); 1024 return ret; 1025 } 1026 1027 if (modify_algo) 1028 hash_algo = hns3_hash_func_map[hash_func]; 1029 if (modify_key) 1030 memcpy(rss_key, key, key_len); 1031 1032 ret = hns3_rss_set_algo_key(hw, hash_algo, rss_key, hw->rss_key_size); 1033 if (ret != 0) 1034 hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d", 1035 ret); 1036 1037 return ret; 1038 } 1039 1040 static void 1041 hns3_rss_tuple_uninit(struct hns3_hw *hw) 1042 { 1043 struct hns3_cmd_desc desc; 1044 int ret; 1045 1046 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 1047 1048 ret = hns3_cmd_send(hw, &desc, 1); 1049 if (ret) { 1050 hns3_err(hw, "RSS uninit tuple failed %d", ret); 1051 return; 1052 } 1053 } 1054 1055 /* 1056 * Set the default rss configuration in the init of driver. 1057 */ 1058 void 1059 hns3_rss_set_default_args(struct hns3_hw *hw) 1060 { 1061 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 1062 uint16_t queue_num = hw->alloc_rss_size; 1063 uint16_t i; 1064 1065 /* Default hash algorithm */ 1066 rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; 1067 1068 hw->rss_info.rss_hf = 0; 1069 memcpy(rss_cfg->key, hns3_hash_key, 1070 RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); 1071 1072 /* Initialize RSS indirection table */ 1073 for (i = 0; i < hw->rss_ind_tbl_size; i++) 1074 rss_cfg->rss_indirection_tbl[i] = i % queue_num; 1075 } 1076 1077 /* 1078 * RSS initialization for hns3 PMD. 1079 */ 1080 int 1081 hns3_config_rss(struct hns3_adapter *hns) 1082 { 1083 struct hns3_hw *hw = &hns->hw; 1084 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 1085 uint8_t *hash_key = rss_cfg->key; 1086 uint64_t rss_hf; 1087 int ret; 1088 1089 enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; 1090 1091 ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo, 1092 hash_key, hw->rss_key_size); 1093 if (ret) 1094 return ret; 1095 1096 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 1097 hw->rss_ind_tbl_size); 1098 if (ret) 1099 return ret; 1100 1101 ret = hns3_set_rss_tc_mode(hw); 1102 if (ret) 1103 return ret; 1104 1105 /* 1106 * When multi-queue RSS mode flag is not set or unsupported tuples are 1107 * set, disable all tuples. 1108 */ 1109 rss_hf = hw->rss_info.rss_hf; 1110 if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) || 1111 !(rss_hf & HNS3_ETH_RSS_SUPPORT)) 1112 rss_hf = 0; 1113 1114 ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); 1115 if (ret != 0) { 1116 hns3_err(hw, "set RSS tuples failed, ret = %d.", ret); 1117 return ret; 1118 } 1119 hw->rss_info.rss_hf = rss_hf; 1120 1121 return 0; 1122 } 1123 1124 /* 1125 * RSS uninitialization for hns3 PMD. 1126 */ 1127 void 1128 hns3_rss_uninit(struct hns3_adapter *hns) 1129 { 1130 struct hns3_hw *hw = &hns->hw; 1131 int ret; 1132 1133 hns3_rss_tuple_uninit(hw); 1134 ret = hns3_rss_reset_indir_table(hw); 1135 if (ret != 0) 1136 return; 1137 1138 /* Disable RSS */ 1139 hw->rss_info.rss_hf = 0; 1140 } 1141