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, key_offset and hash key of rss. 281 */ 282 int 283 hns3_rss_set_algo_key(struct hns3_hw *hw, const uint8_t *key) 284 { 285 #define HNS3_KEY_OFFSET_MAX 3 286 #define HNS3_SET_HASH_KEY_BYTE_FOUR 2 287 288 struct hns3_rss_generic_config_cmd *req; 289 struct hns3_cmd_desc desc; 290 uint32_t key_offset, key_size; 291 const uint8_t *key_cur; 292 uint8_t cur_offset; 293 int ret; 294 295 req = (struct hns3_rss_generic_config_cmd *)desc.data; 296 297 /* 298 * key_offset=0, hash key byte0~15 is set to hardware. 299 * key_offset=1, hash key byte16~31 is set to hardware. 300 * key_offset=2, hash key byte32~39 is set to hardware. 301 */ 302 for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) { 303 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, 304 false); 305 306 req->hash_config |= 307 (hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK); 308 req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B); 309 310 if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR) 311 key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM * 312 HNS3_SET_HASH_KEY_BYTE_FOUR; 313 else 314 key_size = HNS3_RSS_HASH_KEY_NUM; 315 316 cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM; 317 key_cur = key + cur_offset; 318 memcpy(req->hash_key, key_cur, key_size); 319 320 ret = hns3_cmd_send(hw, &desc, 1); 321 if (ret) { 322 hns3_err(hw, "Configure RSS algo key failed %d", ret); 323 return ret; 324 } 325 } 326 /* Update the shadow RSS key with user specified */ 327 memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE); 328 return 0; 329 } 330 331 /* 332 * rss_indirection_table command function, opcode:0x0D07. 333 * Used to configure the indirection table of rss. 334 */ 335 int 336 hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) 337 { 338 struct hns3_rss_indirection_table_cmd *req; 339 struct hns3_cmd_desc desc; 340 uint8_t qid_msb_off; 341 uint8_t qid_msb_val; 342 uint16_t q_id; 343 uint16_t i, j; 344 int ret; 345 346 req = (struct hns3_rss_indirection_table_cmd *)desc.data; 347 348 for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) { 349 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, 350 false); 351 req->start_table_index = 352 rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); 353 req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); 354 for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { 355 q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; 356 req->rss_result_l[j] = q_id & 0xff; 357 358 qid_msb_off = 359 j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; 360 qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1) 361 << (j * HNS3_RSS_CFG_TBL_BW_H % 362 HNS3_BITS_PER_BYTE); 363 req->rss_result_h[qid_msb_off] |= qid_msb_val; 364 } 365 366 ret = hns3_cmd_send(hw, &desc, 1); 367 if (ret) { 368 hns3_err(hw, 369 "Sets RSS indirection table failed %d size %u", 370 ret, size); 371 return ret; 372 } 373 } 374 375 /* Update redirection table of hw */ 376 memcpy(hw->rss_info.rss_indirection_tbl, indir, 377 sizeof(uint16_t) * size); 378 379 return 0; 380 } 381 382 int 383 hns3_rss_reset_indir_table(struct hns3_hw *hw) 384 { 385 uint16_t *lut; 386 int ret; 387 388 lut = rte_zmalloc("hns3_rss_lut", 389 hw->rss_ind_tbl_size * sizeof(uint16_t), 0); 390 if (lut == NULL) { 391 hns3_err(hw, "No hns3_rss_lut memory can be allocated"); 392 return -ENOMEM; 393 } 394 395 ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size); 396 if (ret) 397 hns3_err(hw, "RSS uninit indir table failed: %d", ret); 398 rte_free(lut); 399 400 return ret; 401 } 402 403 static void 404 hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf) 405 { 406 uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | 407 RTE_ETH_RSS_NONFRAG_IPV4_OTHER | 408 RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | 409 RTE_ETH_RSS_NONFRAG_IPV6_OTHER; 410 uint64_t l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP | 411 RTE_ETH_RSS_NONFRAG_IPV4_UDP | 412 RTE_ETH_RSS_NONFRAG_IPV4_SCTP | 413 RTE_ETH_RSS_NONFRAG_IPV6_TCP | 414 RTE_ETH_RSS_NONFRAG_IPV6_UDP | 415 RTE_ETH_RSS_NONFRAG_IPV6_SCTP; 416 uint64_t l3_src_dst_mask = RTE_ETH_RSS_L3_SRC_ONLY | 417 RTE_ETH_RSS_L3_DST_ONLY; 418 uint64_t l4_src_dst_mask = RTE_ETH_RSS_L4_SRC_ONLY | 419 RTE_ETH_RSS_L4_DST_ONLY; 420 421 if (rss_hf & l3_src_dst_mask && 422 !(rss_hf & ip_mask || rss_hf & l4_mask)) 423 hns3_warn(hw, "packet type isn't specified, L3_SRC/DST_ONLY is ignored."); 424 425 if (rss_hf & l4_src_dst_mask && !(rss_hf & l4_mask)) 426 hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored."); 427 } 428 429 static uint64_t 430 hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf) 431 { 432 uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY | 433 RTE_ETH_RSS_L3_DST_ONLY; 434 uint64_t l4_only_mask = RTE_ETH_RSS_L4_SRC_ONLY | 435 RTE_ETH_RSS_L4_DST_ONLY; 436 uint64_t l3_l4_only_mask = l3_only_mask | l4_only_mask; 437 bool has_l3_l4_only = !!(rss_hf & l3_l4_only_mask); 438 bool has_l3_only = !!(rss_hf & l3_only_mask); 439 uint64_t tuple = 0; 440 uint32_t i; 441 442 for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { 443 if ((rss_hf & hns3_set_tuple_table[i].rss_types) != 444 hns3_set_tuple_table[i].rss_types) 445 continue; 446 447 if (hns3_set_tuple_table[i].tuple_type == HNS3_RSS_IP_TUPLE) { 448 if (hns3_set_tuple_table[i].rss_types & l3_only_mask || 449 !has_l3_only) 450 tuple |= hns3_set_tuple_table[i].rss_field; 451 continue; 452 } 453 454 /* For IP types with L4, we need check both L3 and L4 */ 455 if (hns3_set_tuple_table[i].rss_types & l3_l4_only_mask || 456 !has_l3_l4_only) 457 tuple |= hns3_set_tuple_table[i].rss_field; 458 } 459 hns3_rss_check_l3l4_types(hw, rss_hf); 460 461 return tuple; 462 } 463 464 int 465 hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) 466 { 467 struct hns3_rss_input_tuple_cmd *req; 468 struct hns3_cmd_desc desc; 469 uint64_t tuple_field; 470 int ret; 471 472 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 473 req = (struct hns3_rss_input_tuple_cmd *)desc.data; 474 475 tuple_field = hns3_rss_calc_tuple_filed(hw, rss_hf); 476 req->tuple_field = rte_cpu_to_le_64(tuple_field); 477 ret = hns3_cmd_send(hw, &desc, 1); 478 if (ret) { 479 hns3_err(hw, "Update RSS flow types tuples failed %d", ret); 480 return ret; 481 } 482 483 /* Update supported flow types when set tuple success */ 484 hw->rss_info.conf.types = rss_hf; 485 486 return 0; 487 } 488 489 /* 490 * Configure RSS hash protocols and hash key. 491 * @param dev 492 * Pointer to Ethernet device. 493 * @praram rss_conf 494 * The configuration select of rss key size and tuple flow_types. 495 * @return 496 * 0 on success, a negative errno value otherwise is set. 497 */ 498 int 499 hns3_dev_rss_hash_update(struct rte_eth_dev *dev, 500 struct rte_eth_rss_conf *rss_conf) 501 { 502 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); 503 uint64_t rss_hf_bk = hw->rss_info.conf.types; 504 uint8_t key_len = rss_conf->rss_key_len; 505 uint64_t rss_hf = rss_conf->rss_hf; 506 uint8_t *key = rss_conf->rss_key; 507 int ret; 508 509 if (key && key_len != HNS3_RSS_KEY_SIZE) { 510 hns3_err(hw, "the hash key len(%u) is invalid, must be %u", 511 key_len, HNS3_RSS_KEY_SIZE); 512 return -EINVAL; 513 } 514 515 rte_spinlock_lock(&hw->lock); 516 ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); 517 if (ret) 518 goto set_tuple_fail; 519 520 if (key) { 521 ret = hns3_rss_set_algo_key(hw, key); 522 if (ret) 523 goto set_algo_key_fail; 524 } 525 rte_spinlock_unlock(&hw->lock); 526 527 return 0; 528 529 set_algo_key_fail: 530 (void)hns3_set_rss_tuple_by_rss_hf(hw, rss_hf_bk); 531 set_tuple_fail: 532 rte_spinlock_unlock(&hw->lock); 533 return ret; 534 } 535 536 /* 537 * Get rss key and rss_hf types set of RSS hash configuration. 538 * @param dev 539 * Pointer to Ethernet device. 540 * @praram rss_conf 541 * The buffer to get rss key size and tuple types. 542 * @return 543 * 0 on success. 544 */ 545 int 546 hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 547 struct rte_eth_rss_conf *rss_conf) 548 { 549 struct hns3_adapter *hns = dev->data->dev_private; 550 struct hns3_hw *hw = &hns->hw; 551 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 552 553 rte_spinlock_lock(&hw->lock); 554 rss_conf->rss_hf = rss_cfg->conf.types; 555 556 /* Get the RSS Key required by the user */ 557 if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { 558 memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); 559 rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; 560 } 561 rte_spinlock_unlock(&hw->lock); 562 563 return 0; 564 } 565 566 /* 567 * Update rss redirection table of RSS. 568 * @param dev 569 * Pointer to Ethernet device. 570 * @praram reta_conf 571 * Pointer to the configuration select of mask and redirection tables. 572 * @param reta_size 573 * Redirection table size. 574 * @return 575 * 0 on success, a negative errno value otherwise is set. 576 */ 577 int 578 hns3_dev_rss_reta_update(struct rte_eth_dev *dev, 579 struct rte_eth_rss_reta_entry64 *reta_conf, 580 uint16_t reta_size) 581 { 582 struct hns3_adapter *hns = dev->data->dev_private; 583 struct hns3_hw *hw = &hns->hw; 584 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 585 uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; 586 uint16_t idx, shift; 587 uint16_t i; 588 int ret; 589 590 if (reta_size != hw->rss_ind_tbl_size) { 591 hns3_err(hw, "The size of hash lookup table configured (%u)" 592 "doesn't match the number hardware can supported" 593 "(%u)", reta_size, hw->rss_ind_tbl_size); 594 return -EINVAL; 595 } 596 rte_spinlock_lock(&hw->lock); 597 memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, 598 sizeof(rss_cfg->rss_indirection_tbl)); 599 for (i = 0; i < reta_size; i++) { 600 idx = i / RTE_ETH_RETA_GROUP_SIZE; 601 shift = i % RTE_ETH_RETA_GROUP_SIZE; 602 if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) { 603 rte_spinlock_unlock(&hw->lock); 604 hns3_err(hw, "queue id(%u) set to redirection table " 605 "exceeds queue number(%u) allocated to a TC", 606 reta_conf[idx].reta[shift], 607 hw->alloc_rss_size); 608 return -EINVAL; 609 } 610 611 if (reta_conf[idx].mask & (1ULL << shift)) 612 indirection_tbl[i] = reta_conf[idx].reta[shift]; 613 } 614 615 ret = hns3_set_rss_indir_table(hw, indirection_tbl, 616 hw->rss_ind_tbl_size); 617 618 rte_spinlock_unlock(&hw->lock); 619 return ret; 620 } 621 622 /* 623 * Get rss redirection table of RSS hash configuration. 624 * @param dev 625 * Pointer to Ethernet device. 626 * @praram reta_conf 627 * Pointer to the configuration select of mask and redirection tables. 628 * @param reta_size 629 * Redirection table size. 630 * @return 631 * 0 on success, a negative errno value otherwise is set. 632 */ 633 int 634 hns3_dev_rss_reta_query(struct rte_eth_dev *dev, 635 struct rte_eth_rss_reta_entry64 *reta_conf, 636 uint16_t reta_size) 637 { 638 struct hns3_adapter *hns = dev->data->dev_private; 639 struct hns3_hw *hw = &hns->hw; 640 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 641 uint16_t idx, shift; 642 uint16_t i; 643 644 if (reta_size != hw->rss_ind_tbl_size) { 645 hns3_err(hw, "The size of hash lookup table configured (%u)" 646 " doesn't match the number hardware can supported" 647 "(%u)", reta_size, hw->rss_ind_tbl_size); 648 return -EINVAL; 649 } 650 rte_spinlock_lock(&hw->lock); 651 for (i = 0; i < reta_size; i++) { 652 idx = i / RTE_ETH_RETA_GROUP_SIZE; 653 shift = i % RTE_ETH_RETA_GROUP_SIZE; 654 if (reta_conf[idx].mask & (1ULL << shift)) 655 reta_conf[idx].reta[shift] = 656 rss_cfg->rss_indirection_tbl[i]; 657 } 658 rte_spinlock_unlock(&hw->lock); 659 return 0; 660 } 661 662 static void 663 hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid, 664 uint16_t *tc_size, uint16_t *tc_offset, 665 uint8_t tc_num) 666 { 667 struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); 668 uint16_t rss_size = hw->alloc_rss_size; 669 uint16_t roundup_size; 670 uint16_t i; 671 672 roundup_size = roundup_pow_of_two(rss_size); 673 roundup_size = ilog2(roundup_size); 674 675 for (i = 0; i < tc_num; i++) { 676 if (hns->is_vf) { 677 /* 678 * For packets with VLAN priorities destined for the VF, 679 * hardware still assign Rx queue based on the Up-to-TC 680 * mapping PF configured. But VF has only one TC. If 681 * other TC don't enable, it causes that the priority 682 * packets that aren't destined for TC0 aren't received 683 * by RSS hash but is destined for queue 0. So driver 684 * has to enable the unused TC by using TC0 queue 685 * mapping configuration. 686 */ 687 tc_valid[i] = (hw->hw_tc_map & BIT(i)) ? 688 !!(hw->hw_tc_map & BIT(i)) : 1; 689 tc_size[i] = roundup_size; 690 tc_offset[i] = (hw->hw_tc_map & BIT(i)) ? 691 rss_size * i : 0; 692 } else { 693 tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); 694 tc_size[i] = tc_valid[i] ? roundup_size : 0; 695 tc_offset[i] = tc_valid[i] ? rss_size * i : 0; 696 } 697 } 698 } 699 700 static int 701 hns3_set_rss_tc_mode(struct hns3_hw *hw) 702 { 703 struct hns3_rss_tc_mode_cmd *req; 704 uint16_t tc_offset[HNS3_MAX_TC_NUM]; 705 uint8_t tc_valid[HNS3_MAX_TC_NUM]; 706 uint16_t tc_size[HNS3_MAX_TC_NUM]; 707 struct hns3_cmd_desc desc; 708 uint16_t i; 709 int ret; 710 711 hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size, 712 tc_offset, HNS3_MAX_TC_NUM); 713 714 req = (struct hns3_rss_tc_mode_cmd *)desc.data; 715 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false); 716 for (i = 0; i < HNS3_MAX_TC_NUM; i++) { 717 uint16_t mode = 0; 718 719 hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1)); 720 hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S, 721 tc_size[i]); 722 if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0) 723 hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1); 724 hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S, 725 tc_offset[i]); 726 727 req->rss_tc_mode[i] = rte_cpu_to_le_16(mode); 728 } 729 ret = hns3_cmd_send(hw, &desc, 1); 730 if (ret) 731 hns3_err(hw, "Sets rss tc mode failed %d", ret); 732 733 return ret; 734 } 735 736 static void 737 hns3_rss_tuple_uninit(struct hns3_hw *hw) 738 { 739 struct hns3_cmd_desc desc; 740 int ret; 741 742 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); 743 744 ret = hns3_cmd_send(hw, &desc, 1); 745 if (ret) { 746 hns3_err(hw, "RSS uninit tuple failed %d", ret); 747 return; 748 } 749 } 750 751 /* 752 * Set the default rss configuration in the init of driver. 753 */ 754 void 755 hns3_rss_set_default_args(struct hns3_hw *hw) 756 { 757 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 758 uint16_t queue_num = hw->alloc_rss_size; 759 uint16_t i; 760 761 /* Default hash algorithm */ 762 rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 763 764 /* Default RSS key */ 765 memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); 766 767 /* Initialize RSS indirection table */ 768 for (i = 0; i < hw->rss_ind_tbl_size; i++) 769 rss_cfg->rss_indirection_tbl[i] = i % queue_num; 770 } 771 772 /* 773 * RSS initialization for hns3 PMD. 774 */ 775 int 776 hns3_config_rss(struct hns3_adapter *hns) 777 { 778 struct hns3_hw *hw = &hns->hw; 779 struct hns3_rss_conf *rss_cfg = &hw->rss_info; 780 uint8_t *hash_key = rss_cfg->key; 781 uint64_t rss_hf; 782 int ret; 783 784 enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; 785 786 switch (hw->rss_info.conf.func) { 787 case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: 788 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; 789 break; 790 case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: 791 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; 792 break; 793 default: 794 hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; 795 break; 796 } 797 798 /* Configure RSS hash algorithm and hash key offset */ 799 ret = hns3_rss_set_algo_key(hw, hash_key); 800 if (ret) 801 return ret; 802 803 ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, 804 hw->rss_ind_tbl_size); 805 if (ret) 806 return ret; 807 808 ret = hns3_set_rss_tc_mode(hw); 809 if (ret) 810 return ret; 811 812 /* 813 * When muli-queue RSS mode flag is not set or unsupported tuples are 814 * set, disable all tuples. 815 */ 816 rss_hf = hw->rss_info.conf.types; 817 if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) || 818 !(rss_hf & HNS3_ETH_RSS_SUPPORT)) 819 rss_hf = 0; 820 821 return hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); 822 } 823 824 /* 825 * RSS uninitialization for hns3 PMD. 826 */ 827 void 828 hns3_rss_uninit(struct hns3_adapter *hns) 829 { 830 struct hns3_hw *hw = &hns->hw; 831 int ret; 832 833 hns3_rss_tuple_uninit(hw); 834 ret = hns3_rss_reset_indir_table(hw); 835 if (ret != 0) 836 return; 837 838 /* Disable RSS */ 839 hw->rss_info.conf.types = 0; 840 } 841