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