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