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, uint16_t *indir, uint16_t size) 270 { 271 struct hns3_rss_indirection_table_cmd *req; 272 struct hns3_cmd_desc desc; 273 uint8_t qid_msb_off; 274 uint8_t qid_msb_val; 275 uint16_t q_id; 276 uint16_t i, j; 277 int ret; 278 279 req = (struct hns3_rss_indirection_table_cmd *)desc.data; 280 281 for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) { 282 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, 283 false); 284 req->start_table_index = 285 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); 286 req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); 287 for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { 288 q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; 289 req->rss_result_l[j] = q_id & 0xff; 290 291 qid_msb_off = 292 j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; 293 qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1) 294 << (j * HNS3_RSS_CFG_TBL_BW_H % 295 HNS3_BITS_PER_BYTE); 296 req->rss_result_h[qid_msb_off] |= qid_msb_val; 297 } 298 299 ret = hns3_cmd_send(hw, &desc, 1); 300 if (ret) { 301 hns3_err(hw, 302 "Sets RSS indirection table failed %d size %u", 303 ret, size); 304 return ret; 305 } 306 } 307 308 /* Update redirection table of hw */ 309 memcpy(hw->rss_info.rss_indirection_tbl, indir, 310 sizeof(hw->rss_info.rss_indirection_tbl)); 311 312 return 0; 313 } 314 315 int 316 hns3_rss_reset_indir_table(struct hns3_hw *hw) 317 { 318 uint16_t *lut; 319 int ret; 320 321 lut = rte_zmalloc("hns3_rss_lut", 322 HNS3_RSS_IND_TBL_SIZE * sizeof(uint16_t), 0); 323 if (lut == NULL) { 324 hns3_err(hw, "No hns3_rss_lut memory can be allocated"); 325 return -ENOMEM; 326 } 327 328 ret = hns3_set_rss_indir_table(hw, lut, HNS3_RSS_IND_TBL_SIZE); 329 if (ret) 330 hns3_err(hw, "RSS uninit indir table failed: %d", ret); 331 rte_free(lut); 332 333 return ret; 334 } 335 336 int 337 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, 338 struct hns3_rss_tuple_cfg *tuple, uint64_t rss_hf) 339 { 340 struct hns3_rss_input_tuple_cmd *req; 341 struct hns3_cmd_desc desc; 342 uint32_t fields_count = 0; /* count times for setting tuple fields */ 343 uint32_t i; 344 int ret; 345 346 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 347 348 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 349 350 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { 351 if ((rss_hf & hns3_set_tuple_table[i].rss_types) == 352 hns3_set_tuple_table[i].rss_types) { 353 req->tuple_field |= 354 rte_cpu_to_le_64(hns3_set_tuple_table[i].rss_field); 355 fields_count++; 356 } 357 } 358 359 /* 360 * When user does not specify the following types or a combination of 361 * the following types, it enables all fields for the supported RSS 362 * types. the following types as: 363 * - ETH_RSS_L3_SRC_ONLY 364 * - ETH_RSS_L3_DST_ONLY 365 * - ETH_RSS_L4_SRC_ONLY 366 * - ETH_RSS_L4_DST_ONLY 367 */ 368 if (fields_count == 0) { 369 for (i = 0; i < RTE_DIM(hns3_set_rss_types); i++) { 370 if ((rss_hf & hns3_set_rss_types[i].rss_types) == 371 hns3_set_rss_types[i].rss_types) 372 req->tuple_field |= rte_cpu_to_le_64( 373 hns3_set_rss_types[i].rss_field); 374 } 375 } 376 377 ret = hns3_cmd_send(hw, &desc, 1); 378 if (ret) { 379 hns3_err(hw, "Update RSS flow types tuples failed %d", ret); 380 return ret; 381 } 382 383 tuple->rss_tuple_fields = rte_le_to_cpu_64(req->tuple_field); 384 385 return 0; 386 } 387 388 /* 389 * Configure RSS hash protocols and hash key. 390 * @param dev 391 * Pointer to Ethernet device. 392 * @praram rss_conf 393 * The configuration select of rss key size and tuple flow_types. 394 * @return 395 * 0 on success, a negative errno value otherwise is set. 396 */ 397 int 398 hns3_dev_rss_hash_update(struct rte_eth_dev *dev, 399 struct rte_eth_rss_conf *rss_conf) 400 { 401 struct hns3_adapter *hns = dev->data->dev_private; 402 struct hns3_hw *hw = &hns->hw; 403 struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets; 404 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 405 uint8_t key_len = rss_conf->rss_key_len; 406 uint64_t rss_hf = rss_conf->rss_hf; 407 uint8_t *key = rss_conf->rss_key; 408 int ret; 409 410 if (hw->rss_dis_flag) 411 return -EINVAL; 412 413 rte_spinlock_lock(&hw->lock); 414 ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_hf); 415 if (ret) 416 goto conf_err; 417 418 if (rss_cfg->conf.types && rss_hf == 0) { 419 /* Disable RSS, reset indirection table by local variable */ 420 ret = hns3_rss_reset_indir_table(hw); 421 if (ret) 422 goto conf_err; 423 } else if (rss_hf && rss_cfg->conf.types == 0) { 424 /* Enable RSS, restore indirection table by hw's config */ 425 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 426 HNS3_RSS_IND_TBL_SIZE); 427 if (ret) 428 goto conf_err; 429 } 430 431 /* Update supported flow types when set tuple success */ 432 rss_cfg->conf.types = rss_hf; 433 434 if (key) { 435 if (key_len != HNS3_RSS_KEY_SIZE) { 436 hns3_err(hw, "The hash key len(%u) is invalid", 437 key_len); 438 ret = -EINVAL; 439 goto conf_err; 440 } 441 ret = hns3_set_rss_algo_key(hw, key); 442 if (ret) 443 goto conf_err; 444 } 445 rte_spinlock_unlock(&hw->lock); 446 447 return 0; 448 449 conf_err: 450 rte_spinlock_unlock(&hw->lock); 451 return ret; 452 } 453 454 /* 455 * Get rss key and rss_hf types set of RSS hash configuration. 456 * @param dev 457 * Pointer to Ethernet device. 458 * @praram rss_conf 459 * The buffer to get rss key size and tuple types. 460 * @return 461 * 0 on success. 462 */ 463 int 464 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 465 struct rte_eth_rss_conf *rss_conf) 466 { 467 struct hns3_adapter *hns = dev->data->dev_private; 468 struct hns3_hw *hw = &hns->hw; 469 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 470 471 rte_spinlock_lock(&hw->lock); 472 rss_conf->rss_hf = rss_cfg->conf.types; 473 474 /* Get the RSS Key required by the user */ 475 if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { 476 memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); 477 rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; 478 } 479 rte_spinlock_unlock(&hw->lock); 480 481 return 0; 482 } 483 484 /* 485 * Update rss redirection table of RSS. 486 * @param dev 487 * Pointer to Ethernet device. 488 * @praram reta_conf 489 * Pointer to the configuration select of mask and redirection tables. 490 * @param reta_size 491 * Redirection table size. 492 * @return 493 * 0 on success, a negative errno value otherwise is set. 494 */ 495 int 496 hns3_dev_rss_reta_update(struct rte_eth_dev *dev, 497 struct rte_eth_rss_reta_entry64 *reta_conf, 498 uint16_t reta_size) 499 { 500 struct hns3_adapter *hns = dev->data->dev_private; 501 struct hns3_hw *hw = &hns->hw; 502 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 503 uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ 504 uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; 505 uint16_t idx, shift, allow_rss_queues; 506 int ret; 507 508 if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { 509 hns3_err(hw, "The size of hash lookup table configured (%u)" 510 "doesn't match the number hardware can supported" 511 "(%u)", reta_size, indir_size); 512 return -EINVAL; 513 } 514 rte_spinlock_lock(&hw->lock); 515 memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, 516 sizeof(rss_cfg->rss_indirection_tbl)); 517 allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max); 518 for (i = 0; i < reta_size; i++) { 519 idx = i / RTE_RETA_GROUP_SIZE; 520 shift = i % RTE_RETA_GROUP_SIZE; 521 if (reta_conf[idx].reta[shift] >= allow_rss_queues) { 522 rte_spinlock_unlock(&hw->lock); 523 hns3_err(hw, "Invalid queue id(%u) to be set in " 524 "redirection table, max number of rss " 525 "queues: %u", reta_conf[idx].reta[shift], 526 allow_rss_queues); 527 return -EINVAL; 528 } 529 530 if (reta_conf[idx].mask & (1ULL << shift)) 531 indirection_tbl[i] = reta_conf[idx].reta[shift]; 532 } 533 534 ret = hns3_set_rss_indir_table(hw, indirection_tbl, 535 HNS3_RSS_IND_TBL_SIZE); 536 537 rte_spinlock_unlock(&hw->lock); 538 return ret; 539 } 540 541 /* 542 * Get rss redirection table of RSS hash configuration. 543 * @param dev 544 * Pointer to Ethernet device. 545 * @praram reta_conf 546 * Pointer to the configuration select of mask and redirection tables. 547 * @param reta_size 548 * Redirection table size. 549 * @return 550 * 0 on success, a negative errno value otherwise is set. 551 */ 552 int 553 hns3_dev_rss_reta_query(struct rte_eth_dev *dev, 554 struct rte_eth_rss_reta_entry64 *reta_conf, 555 uint16_t reta_size) 556 { 557 struct hns3_adapter *hns = dev->data->dev_private; 558 struct hns3_hw *hw = &hns->hw; 559 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 560 uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ 561 uint16_t idx, shift; 562 563 if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { 564 hns3_err(hw, "The size of hash lookup table configured (%u)" 565 " doesn't match the number hardware can supported" 566 "(%u)", reta_size, indir_size); 567 return -EINVAL; 568 } 569 rte_spinlock_lock(&hw->lock); 570 for (i = 0; i < reta_size; i++) { 571 idx = i / RTE_RETA_GROUP_SIZE; 572 shift = i % RTE_RETA_GROUP_SIZE; 573 if (reta_conf[idx].mask & (1ULL << shift)) 574 reta_conf[idx].reta[shift] = 575 rss_cfg->rss_indirection_tbl[i]; 576 } 577 rte_spinlock_unlock(&hw->lock); 578 return 0; 579 } 580 581 /* 582 * Used to configure the tc_size and tc_offset. 583 */ 584 static int 585 hns3_set_rss_tc_mode(struct hns3_hw *hw) 586 { 587 uint16_t rss_size = hw->alloc_rss_size; 588 struct hns3_rss_tc_mode_cmd *req; 589 uint16_t tc_offset[HNS3_MAX_TC_NUM]; 590 uint8_t tc_valid[HNS3_MAX_TC_NUM]; 591 uint16_t tc_size[HNS3_MAX_TC_NUM]; 592 struct hns3_cmd_desc desc; 593 uint16_t roundup_size; 594 uint16_t i; 595 int ret; 596 597 req = (struct hns3_rss_tc_mode_cmd *)desc.data; 598 599 roundup_size = roundup_pow_of_two(rss_size); 600 roundup_size = ilog2(roundup_size); 601 602 for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 603 tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); 604 tc_size[i] = roundup_size; 605 tc_offset[i] = rss_size * i; 606 } 607 608 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false); 609 for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 610 uint16_t mode = 0; 611 612 hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1)); 613 hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S, 614 tc_size[i]); 615 if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0) 616 hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1); 617 hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S, 618 tc_offset[i]); 619 620 req->rss_tc_mode[i] = rte_cpu_to_le_16(mode); 621 } 622 ret = hns3_cmd_send(hw, &desc, 1); 623 if (ret) 624 hns3_err(hw, "Sets rss tc mode failed %d", ret); 625 626 return ret; 627 } 628 629 static void 630 hns3_rss_tuple_uninit(struct hns3_hw *hw) 631 { 632 struct hns3_rss_input_tuple_cmd *req; 633 struct hns3_cmd_desc desc; 634 int ret; 635 636 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 637 638 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 639 640 memset(req, 0, sizeof(struct hns3_rss_tuple_cfg)); 641 642 ret = hns3_cmd_send(hw, &desc, 1); 643 if (ret) { 644 hns3_err(hw, "RSS uninit tuple failed %d", ret); 645 return; 646 } 647 } 648 649 /* 650 * Set the default rss configuration in the init of driver. 651 */ 652 void 653 hns3_set_default_rss_args(struct hns3_hw *hw) 654 { 655 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 656 uint16_t queue_num = hw->alloc_rss_size; 657 int i; 658 659 /* Default hash algorithm */ 660 rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 661 662 /* Default RSS key */ 663 memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); 664 665 /* Initialize RSS indirection table */ 666 for (i = 0; i < HNS3_RSS_IND_TBL_SIZE; i++) 667 rss_cfg->rss_indirection_tbl[i] = i % queue_num; 668 } 669 670 /* 671 * RSS initialization for hns3 pmd driver. 672 */ 673 int 674 hns3_config_rss(struct hns3_adapter *hns) 675 { 676 struct hns3_hw *hw = &hns->hw; 677 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 678 uint8_t *hash_key = rss_cfg->key; 679 int ret, ret1; 680 681 enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; 682 683 switch (hw->rss_info.conf.func) { 684 case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: 685 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; 686 break; 687 case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: 688 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; 689 break; 690 default: 691 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; 692 break; 693 } 694 695 /* When RSS is off, redirect the packet queue 0 */ 696 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) == 0) 697 hns3_rss_uninit(hns); 698 699 /* Configure RSS hash algorithm and hash key offset */ 700 ret = hns3_set_rss_algo_key(hw, hash_key); 701 if (ret) 702 return ret; 703 704 /* Configure the tuple selection for RSS hash input */ 705 ret = hns3_set_rss_input_tuple(hw); 706 if (ret) 707 return ret; 708 709 /* 710 * When RSS is off, it doesn't need to configure rss redirection table 711 * to hardware. 712 */ 713 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) { 714 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 715 HNS3_RSS_IND_TBL_SIZE); 716 if (ret) 717 goto rss_tuple_uninit; 718 } 719 720 ret = hns3_set_rss_tc_mode(hw); 721 if (ret) 722 goto rss_indir_table_uninit; 723 724 return ret; 725 726 rss_indir_table_uninit: 727 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) { 728 ret1 = hns3_rss_reset_indir_table(hw); 729 if (ret1 != 0) 730 return ret; 731 } 732 733 rss_tuple_uninit: 734 hns3_rss_tuple_uninit(hw); 735 736 /* Disable RSS */ 737 hw->rss_info.conf.types = 0; 738 739 return ret; 740 } 741 742 /* 743 * RSS uninitialization for hns3 pmd driver. 744 */ 745 void 746 hns3_rss_uninit(struct hns3_adapter *hns) 747 { 748 struct hns3_hw *hw = &hns->hw; 749 int ret; 750 751 hns3_rss_tuple_uninit(hw); 752 ret = hns3_rss_reset_indir_table(hw); 753 if (ret != 0) 754 return; 755 756 /* Disable RSS */ 757 hw->rss_info.conf.types = 0; 758 } 759