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