1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018-2019 Hisilicon Limited. 3 */ 4 5 #include <stdbool.h> 6 #include <rte_ethdev.h> 7 #include <rte_io.h> 8 #include <rte_malloc.h> 9 #include <rte_memcpy.h> 10 #include <rte_spinlock.h> 11 12 #include "hns3_ethdev.h" 13 #include "hns3_logs.h" 14 15 /* 16 * The hash key used for rss initialization. 17 */ 18 static const uint8_t hns3_hash_key[] = { 19 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 20 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0, 21 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, 22 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 23 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA 24 }; 25 26 enum hns3_tuple_field { 27 /* IPV4_TCP ENABLE FIELD */ 28 HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, 29 HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, 30 HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, 31 HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, 32 33 /* IPV4_UDP ENABLE FIELD */ 34 HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, 35 HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, 36 HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, 37 HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, 38 39 /* IPV4_SCTP ENABLE FIELD */ 40 HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, 41 HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, 42 HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, 43 HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, 44 HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, 45 46 /* IPV4 ENABLE FIELD */ 47 HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, 48 HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, 49 HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, 50 HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, 51 52 /* IPV6_TCP ENABLE FIELD */ 53 HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, 54 HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, 55 HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, 56 HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, 57 58 /* IPV6_UDP ENABLE FIELD */ 59 HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, 60 HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, 61 HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, 62 HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, 63 64 /* IPV6_UDP ENABLE FIELD */ 65 HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D = 50, 66 HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, 67 HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, 68 69 /* IPV6 ENABLE FIELD */ 70 HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, 71 HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, 72 HNS3_RSS_FIELD_IPV6_FRAG_IP_D, 73 HNS3_RSS_FIELD_IPV6_FRAG_IP_S 74 }; 75 76 static const struct { 77 uint64_t rss_types; 78 uint64_t rss_field; 79 } hns3_set_tuple_table[] = { 80 { ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_SRC_ONLY, 81 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, 82 { ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_DST_ONLY, 83 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, 84 { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY, 85 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) }, 86 { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY, 87 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) }, 88 { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY, 89 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) }, 90 { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY, 91 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, 92 { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY, 93 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) }, 94 { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY, 95 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) }, 96 { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY, 97 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) }, 98 { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY, 99 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, 100 { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY, 101 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) }, 102 { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY, 103 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) }, 104 { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY, 105 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) }, 106 { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY, 107 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) }, 108 { ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_SRC_ONLY, 109 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, 110 { ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_DST_ONLY, 111 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, 112 { ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_SRC_ONLY, 113 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) }, 114 { ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_DST_ONLY, 115 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, 116 { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY, 117 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) }, 118 { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY, 119 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) }, 120 { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY, 121 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) }, 122 { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY, 123 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, 124 { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY, 125 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) }, 126 { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY, 127 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) }, 128 { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY, 129 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) }, 130 { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY, 131 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, 132 { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY, 133 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) }, 134 { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY, 135 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) }, 136 { ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_SRC_ONLY, 137 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, 138 { ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_DST_ONLY, 139 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, 140 }; 141 142 static const struct { 143 uint64_t rss_types; 144 uint64_t rss_field; 145 } hns3_set_rss_types[] = { 146 { ETH_RSS_FRAG_IPV4, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) | 147 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, 148 { ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | 149 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | 150 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | 151 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, 152 { ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | 153 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | 154 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | 155 BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, 156 { ETH_RSS_NONFRAG_IPV4_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) | 157 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) | 158 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) | 159 BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, 160 { ETH_RSS_NONFRAG_IPV4_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) | 161 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) | 162 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) | 163 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) | 164 BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) }, 165 { ETH_RSS_NONFRAG_IPV4_OTHER, 166 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | 167 BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, 168 { ETH_RSS_FRAG_IPV6, BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) | 169 BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, 170 { ETH_RSS_NONFRAG_IPV6_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) | 171 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) | 172 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) | 173 BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, 174 { ETH_RSS_NONFRAG_IPV6_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) | 175 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) | 176 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) | 177 BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, 178 { ETH_RSS_NONFRAG_IPV6_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) | 179 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) | 180 BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) }, 181 { ETH_RSS_NONFRAG_IPV6_OTHER, 182 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | 183 BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) } 184 }; 185 186 /* 187 * rss_generic_config command function, opcode:0x0D01. 188 * Used to set algorithm, key_offset and hash key of rss. 189 */ 190 int 191 hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key) 192 { 193 #define HNS3_KEY_OFFSET_MAX 3 194 #define HNS3_SET_HASH_KEY_BYTE_FOUR 2 195 196 struct hns3_rss_generic_config_cmd *req; 197 struct hns3_cmd_desc desc; 198 uint32_t key_offset, key_size; 199 const uint8_t *key_cur; 200 uint8_t cur_offset; 201 int ret; 202 203 req = (struct hns3_rss_generic_config_cmd *)desc.data; 204 205 /* 206 * key_offset=0, hash key byte0~15 is set to hardware. 207 * key_offset=1, hash key byte16~31 is set to hardware. 208 * key_offset=2, hash key byte32~39 is set to hardware. 209 */ 210 for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) { 211 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, 212 false); 213 214 req->hash_config |= 215 (hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK); 216 req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B); 217 218 if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR) 219 key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM * 220 HNS3_SET_HASH_KEY_BYTE_FOUR; 221 else 222 key_size = HNS3_RSS_HASH_KEY_NUM; 223 224 cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM; 225 key_cur = key + cur_offset; 226 memcpy(req->hash_key, key_cur, key_size); 227 228 ret = hns3_cmd_send(hw, &desc, 1); 229 if (ret) { 230 hns3_err(hw, "Configure RSS algo key failed %d", ret); 231 return ret; 232 } 233 } 234 /* Update the shadow RSS key with user specified */ 235 memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE); 236 return 0; 237 } 238 239 /* 240 * Used to configure the tuple selection for RSS hash input. 241 */ 242 static int 243 hns3_set_rss_input_tuple(struct hns3_hw *hw) 244 { 245 struct hns3_rss_conf *rss_config = &hw->rss_info; 246 struct hns3_rss_input_tuple_cmd *req; 247 struct hns3_cmd_desc desc_tuple; 248 int ret; 249 250 hns3_cmd_setup_basic_desc(&desc_tuple, HNS3_OPC_RSS_INPUT_TUPLE, false); 251 252 req = (struct hns3_rss_input_tuple_cmd *)desc_tuple.data; 253 254 req->tuple_field = 255 rte_cpu_to_le_64(rss_config->rss_tuple_sets.rss_tuple_fields); 256 257 ret = hns3_cmd_send(hw, &desc_tuple, 1); 258 if (ret) 259 hns3_err(hw, "Configure RSS input tuple mode failed %d", ret); 260 261 return ret; 262 } 263 264 /* 265 * rss_indirection_table command function, opcode:0x0D07. 266 * Used to configure the indirection table of rss. 267 */ 268 int 269 hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) 270 { 271 struct hns3_rss_indirection_table_cmd *req; 272 struct hns3_cmd_desc desc; 273 int ret, i, j, num; 274 275 req = (struct hns3_rss_indirection_table_cmd *)desc.data; 276 277 for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) { 278 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, 279 false); 280 req->start_table_index = 281 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); 282 req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); 283 for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { 284 num = i * HNS3_RSS_CFG_TBL_SIZE + j; 285 req->rss_result[j] = indir[num]; 286 } 287 ret = hns3_cmd_send(hw, &desc, 1); 288 if (ret) { 289 hns3_err(hw, 290 "Sets RSS indirection table failed %d size %u", 291 ret, size); 292 return ret; 293 } 294 } 295 296 /* Update redirection table of hw */ 297 memcpy(hw->rss_info.rss_indirection_tbl, indir, HNS3_RSS_IND_TBL_SIZE); 298 299 return 0; 300 } 301 302 int 303 hns3_rss_reset_indir_table(struct hns3_hw *hw) 304 { 305 uint8_t *lut; 306 int ret; 307 308 lut = rte_zmalloc("hns3_rss_lut", HNS3_RSS_IND_TBL_SIZE, 0); 309 if (lut == NULL) { 310 hns3_err(hw, "No hns3_rss_lut memory can be allocated"); 311 return -ENOMEM; 312 } 313 314 ret = hns3_set_rss_indir_table(hw, lut, HNS3_RSS_IND_TBL_SIZE); 315 if (ret) 316 hns3_err(hw, "RSS uninit indir table failed: %d", ret); 317 rte_free(lut); 318 319 return ret; 320 } 321 322 int 323 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, 324 struct hns3_rss_tuple_cfg *tuple, uint64_t rss_hf) 325 { 326 struct hns3_rss_input_tuple_cmd *req; 327 struct hns3_cmd_desc desc; 328 uint32_t fields_count = 0; /* count times for setting tuple fields */ 329 uint32_t i; 330 int ret; 331 332 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 333 334 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 335 336 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { 337 if ((rss_hf & hns3_set_tuple_table[i].rss_types) == 338 hns3_set_tuple_table[i].rss_types) { 339 req->tuple_field |= 340 rte_cpu_to_le_64(hns3_set_tuple_table[i].rss_field); 341 fields_count++; 342 } 343 } 344 345 /* 346 * When user does not specify the following types or a combination of 347 * the following types, it enables all fields for the supported RSS 348 * types. the following types as: 349 * - ETH_RSS_L3_SRC_ONLY 350 * - ETH_RSS_L3_DST_ONLY 351 * - ETH_RSS_L4_SRC_ONLY 352 * - ETH_RSS_L4_DST_ONLY 353 */ 354 if (fields_count == 0) { 355 for (i = 0; i < RTE_DIM(hns3_set_rss_types); i++) { 356 if ((rss_hf & hns3_set_rss_types[i].rss_types) == 357 hns3_set_rss_types[i].rss_types) 358 req->tuple_field |= rte_cpu_to_le_64( 359 hns3_set_rss_types[i].rss_field); 360 } 361 } 362 363 ret = hns3_cmd_send(hw, &desc, 1); 364 if (ret) { 365 hns3_err(hw, "Update RSS flow types tuples failed %d", ret); 366 return ret; 367 } 368 369 tuple->rss_tuple_fields = rte_le_to_cpu_64(req->tuple_field); 370 371 return 0; 372 } 373 374 /* 375 * Configure RSS hash protocols and hash key. 376 * @param dev 377 * Pointer to Ethernet device. 378 * @praram rss_conf 379 * The configuration select of rss key size and tuple flow_types. 380 * @return 381 * 0 on success, a negative errno value otherwise is set. 382 */ 383 int 384 hns3_dev_rss_hash_update(struct rte_eth_dev *dev, 385 struct rte_eth_rss_conf *rss_conf) 386 { 387 struct hns3_adapter *hns = dev->data->dev_private; 388 struct hns3_hw *hw = &hns->hw; 389 struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets; 390 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 391 uint8_t key_len = rss_conf->rss_key_len; 392 uint64_t rss_hf = rss_conf->rss_hf; 393 uint8_t *key = rss_conf->rss_key; 394 int ret; 395 396 if (hw->rss_dis_flag) 397 return -EINVAL; 398 399 rte_spinlock_lock(&hw->lock); 400 ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_hf); 401 if (ret) 402 goto conf_err; 403 404 if (rss_cfg->conf.types && rss_hf == 0) { 405 /* Disable RSS, reset indirection table by local variable */ 406 ret = hns3_rss_reset_indir_table(hw); 407 if (ret) 408 goto conf_err; 409 } else if (rss_hf && rss_cfg->conf.types == 0) { 410 /* Enable RSS, restore indirection table by hw's config */ 411 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 412 HNS3_RSS_IND_TBL_SIZE); 413 if (ret) 414 goto conf_err; 415 } 416 417 /* Update supported flow types when set tuple success */ 418 rss_cfg->conf.types = rss_hf; 419 420 if (key) { 421 if (key_len != HNS3_RSS_KEY_SIZE) { 422 hns3_err(hw, "The hash key len(%u) is invalid", 423 key_len); 424 ret = -EINVAL; 425 goto conf_err; 426 } 427 ret = hns3_set_rss_algo_key(hw, key); 428 if (ret) 429 goto conf_err; 430 } 431 rte_spinlock_unlock(&hw->lock); 432 433 return 0; 434 435 conf_err: 436 rte_spinlock_unlock(&hw->lock); 437 return ret; 438 } 439 440 /* 441 * Get rss key and rss_hf types set of RSS hash configuration. 442 * @param dev 443 * Pointer to Ethernet device. 444 * @praram rss_conf 445 * The buffer to get rss key size and tuple types. 446 * @return 447 * 0 on success. 448 */ 449 int 450 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 451 struct rte_eth_rss_conf *rss_conf) 452 { 453 struct hns3_adapter *hns = dev->data->dev_private; 454 struct hns3_hw *hw = &hns->hw; 455 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 456 457 rte_spinlock_lock(&hw->lock); 458 rss_conf->rss_hf = rss_cfg->conf.types; 459 460 /* Get the RSS Key required by the user */ 461 if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { 462 memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); 463 rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; 464 } 465 rte_spinlock_unlock(&hw->lock); 466 467 return 0; 468 } 469 470 /* 471 * Update rss redirection table of RSS. 472 * @param dev 473 * Pointer to Ethernet device. 474 * @praram reta_conf 475 * Pointer to the configuration select of mask and redirection tables. 476 * @param reta_size 477 * Redirection table size. 478 * @return 479 * 0 on success, a negative errno value otherwise is set. 480 */ 481 int 482 hns3_dev_rss_reta_update(struct rte_eth_dev *dev, 483 struct rte_eth_rss_reta_entry64 *reta_conf, 484 uint16_t reta_size) 485 { 486 struct hns3_adapter *hns = dev->data->dev_private; 487 struct hns3_hw *hw = &hns->hw; 488 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 489 uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ 490 uint8_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; 491 uint16_t idx, shift, allow_rss_queues; 492 int ret; 493 494 if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { 495 hns3_err(hw, "The size of hash lookup table configured (%u)" 496 "doesn't match the number hardware can supported" 497 "(%u)", reta_size, indir_size); 498 return -EINVAL; 499 } 500 rte_spinlock_lock(&hw->lock); 501 memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, 502 HNS3_RSS_IND_TBL_SIZE); 503 allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max); 504 for (i = 0; i < reta_size; i++) { 505 idx = i / RTE_RETA_GROUP_SIZE; 506 shift = i % RTE_RETA_GROUP_SIZE; 507 if (reta_conf[idx].reta[shift] >= allow_rss_queues) { 508 rte_spinlock_unlock(&hw->lock); 509 hns3_err(hw, "Invalid queue id(%u) to be set in " 510 "redirection table, max number of rss " 511 "queues: %u", reta_conf[idx].reta[shift], 512 allow_rss_queues); 513 return -EINVAL; 514 } 515 516 if (reta_conf[idx].mask & (1ULL << shift)) 517 indirection_tbl[i] = reta_conf[idx].reta[shift]; 518 } 519 520 ret = hns3_set_rss_indir_table(hw, indirection_tbl, 521 HNS3_RSS_IND_TBL_SIZE); 522 523 rte_spinlock_unlock(&hw->lock); 524 return ret; 525 } 526 527 /* 528 * Get rss redirection table of RSS hash configuration. 529 * @param dev 530 * Pointer to Ethernet device. 531 * @praram reta_conf 532 * Pointer to the configuration select of mask and redirection tables. 533 * @param reta_size 534 * Redirection table size. 535 * @return 536 * 0 on success, a negative errno value otherwise is set. 537 */ 538 int 539 hns3_dev_rss_reta_query(struct rte_eth_dev *dev, 540 struct rte_eth_rss_reta_entry64 *reta_conf, 541 uint16_t reta_size) 542 { 543 struct hns3_adapter *hns = dev->data->dev_private; 544 struct hns3_hw *hw = &hns->hw; 545 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 546 uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ 547 uint16_t idx, shift; 548 549 if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { 550 hns3_err(hw, "The size of hash lookup table configured (%u)" 551 " doesn't match the number hardware can supported" 552 "(%u)", reta_size, indir_size); 553 return -EINVAL; 554 } 555 rte_spinlock_lock(&hw->lock); 556 for (i = 0; i < reta_size; i++) { 557 idx = i / RTE_RETA_GROUP_SIZE; 558 shift = i % RTE_RETA_GROUP_SIZE; 559 if (reta_conf[idx].mask & (1ULL << shift)) 560 reta_conf[idx].reta[shift] = 561 rss_cfg->rss_indirection_tbl[i]; 562 } 563 rte_spinlock_unlock(&hw->lock); 564 return 0; 565 } 566 567 /* 568 * Used to configure the tc_size and tc_offset. 569 */ 570 static int 571 hns3_set_rss_tc_mode(struct hns3_hw *hw) 572 { 573 uint16_t rss_size = hw->alloc_rss_size; 574 struct hns3_rss_tc_mode_cmd *req; 575 uint16_t tc_offset[HNS3_MAX_TC_NUM]; 576 uint8_t tc_valid[HNS3_MAX_TC_NUM]; 577 uint16_t tc_size[HNS3_MAX_TC_NUM]; 578 struct hns3_cmd_desc desc; 579 uint16_t roundup_size; 580 uint16_t i; 581 int ret; 582 583 req = (struct hns3_rss_tc_mode_cmd *)desc.data; 584 585 roundup_size = roundup_pow_of_two(rss_size); 586 roundup_size = ilog2(roundup_size); 587 588 for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 589 tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); 590 tc_size[i] = roundup_size; 591 tc_offset[i] = rss_size * i; 592 } 593 594 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false); 595 for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 596 uint16_t mode = 0; 597 598 hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1)); 599 hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S, 600 tc_size[i]); 601 hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S, 602 tc_offset[i]); 603 604 req->rss_tc_mode[i] = rte_cpu_to_le_16(mode); 605 } 606 ret = hns3_cmd_send(hw, &desc, 1); 607 if (ret) 608 hns3_err(hw, "Sets rss tc mode failed %d", ret); 609 610 return ret; 611 } 612 613 static void 614 hns3_rss_tuple_uninit(struct hns3_hw *hw) 615 { 616 struct hns3_rss_input_tuple_cmd *req; 617 struct hns3_cmd_desc desc; 618 int ret; 619 620 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 621 622 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 623 624 memset(req, 0, sizeof(struct hns3_rss_tuple_cfg)); 625 626 ret = hns3_cmd_send(hw, &desc, 1); 627 if (ret) { 628 hns3_err(hw, "RSS uninit tuple failed %d", ret); 629 return; 630 } 631 } 632 633 /* 634 * Set the default rss configuration in the init of driver. 635 */ 636 void 637 hns3_set_default_rss_args(struct hns3_hw *hw) 638 { 639 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 640 uint16_t queue_num = hw->alloc_rss_size; 641 int i; 642 643 /* Default hash algorithm */ 644 rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 645 646 /* Default RSS key */ 647 memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); 648 649 /* Initialize RSS indirection table */ 650 for (i = 0; i < HNS3_RSS_IND_TBL_SIZE; i++) 651 rss_cfg->rss_indirection_tbl[i] = i % queue_num; 652 } 653 654 /* 655 * RSS initialization for hns3 pmd driver. 656 */ 657 int 658 hns3_config_rss(struct hns3_adapter *hns) 659 { 660 struct hns3_hw *hw = &hns->hw; 661 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 662 uint8_t *hash_key = rss_cfg->key; 663 int ret, ret1; 664 665 enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; 666 667 switch (hw->rss_info.conf.func) { 668 case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: 669 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; 670 break; 671 case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: 672 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; 673 break; 674 default: 675 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; 676 break; 677 } 678 679 /* When RSS is off, redirect the packet queue 0 */ 680 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) == 0) 681 hns3_rss_uninit(hns); 682 683 /* Configure RSS hash algorithm and hash key offset */ 684 ret = hns3_set_rss_algo_key(hw, hash_key); 685 if (ret) 686 return ret; 687 688 /* Configure the tuple selection for RSS hash input */ 689 ret = hns3_set_rss_input_tuple(hw); 690 if (ret) 691 return ret; 692 693 /* 694 * When RSS is off, it doesn't need to configure rss redirection table 695 * to hardware. 696 */ 697 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) { 698 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 699 HNS3_RSS_IND_TBL_SIZE); 700 if (ret) 701 goto rss_tuple_uninit; 702 } 703 704 ret = hns3_set_rss_tc_mode(hw); 705 if (ret) 706 goto rss_indir_table_uninit; 707 708 return ret; 709 710 rss_indir_table_uninit: 711 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) { 712 ret1 = hns3_rss_reset_indir_table(hw); 713 if (ret1 != 0) 714 return ret; 715 } 716 717 rss_tuple_uninit: 718 hns3_rss_tuple_uninit(hw); 719 720 /* Disable RSS */ 721 hw->rss_info.conf.types = 0; 722 723 return ret; 724 } 725 726 /* 727 * RSS uninitialization for hns3 pmd driver. 728 */ 729 void 730 hns3_rss_uninit(struct hns3_adapter *hns) 731 { 732 struct hns3_hw *hw = &hns->hw; 733 int ret; 734 735 hns3_rss_tuple_uninit(hw); 736 ret = hns3_rss_reset_indir_table(hw); 737 if (ret != 0) 738 return; 739 740 /* Disable RSS */ 741 hw->rss_info.conf.types = 0; 742 } 743