hash.c (68880B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: hash.c 8 * Purpose: Tomahawk hash table calculation routines 9 * Requires: 10 */ 11 12 #include <shared/bsl.h> 13 14 #include <soc/drv.h> 15 #include <soc/mem.h> 16 #include <soc/debug.h> 17 #include <soc/hash.h> 18 19 #if defined(BCM_TOMAHAWK_SUPPORT) 20 21 #include <soc/tomahawk.h> 22 23 /* Get number of banks for the hash table according to the config */ 24 int 25 soc_tomahawk_hash_bank_count_get(int unit, soc_mem_t mem, int *num_banks) 26 { 27 int count; 28 29 switch (mem) { 30 case L2Xm: 31 /* 32 * 4k entries in each of 2 dedicated L2 bank 33 * 32k(TH)/64k(TH2) entries in each shared bank 34 */ 35 count = soc_mem_index_count(unit, L2Xm); 36 #if defined(BCM_TOMAHAWK2_SUPPORT) 37 if (SOC_IS_TOMAHAWK2(unit)) { 38 *num_banks = 2 + (count - 2 * 4 * 1024) / (64 * 1024); 39 } else 40 #endif 41 { 42 *num_banks = 2 + (count - 2 * 4 * 1024) / (32 * 1024); 43 } 44 break; 45 case L3_ENTRY_ONLYm: 46 case L3_ENTRY_IPV4_UNICASTm: 47 case L3_ENTRY_IPV4_MULTICASTm: 48 case L3_ENTRY_IPV6_UNICASTm: 49 case L3_ENTRY_IPV6_MULTICASTm: 50 /* 51 * 2k entries in each of 4 dedicated L3 bank 52 * 32k(TH)/64k(TH2) entries in each shared bank 53 */ 54 count = soc_mem_index_count(unit, L3_ENTRY_ONLYm); 55 #if defined(BCM_TOMAHAWK2_SUPPORT) 56 if (SOC_IS_TOMAHAWK2(unit)) { 57 *num_banks = 4 + (count - 4 * 2 * 1024) / (64 * 1024); 58 } else 59 #endif 60 { 61 *num_banks = 4 + (count - 4 * 2 * 1024) / (32 * 1024); 62 } 63 break; 64 case EXACT_MATCH_2m: 65 case EXACT_MATCH_2_PIPE0m: 66 case EXACT_MATCH_2_PIPE1m: 67 case EXACT_MATCH_2_PIPE2m: 68 case EXACT_MATCH_2_PIPE3m: 69 /* 70 * 16k(TH)/32k(TH2) entries in each shared bank 71 */ 72 count = soc_mem_index_count(unit, mem); 73 if (SOC_IS_TOMAHAWK2(unit)) { 74 *num_banks = count / (32 * 1024); 75 } else { 76 *num_banks = count / (16 * 1024); 77 } 78 break; 79 case EXACT_MATCH_4m: 80 case EXACT_MATCH_4_PIPE0m: 81 case EXACT_MATCH_4_PIPE1m: 82 case EXACT_MATCH_4_PIPE2m: 83 case EXACT_MATCH_4_PIPE3m: 84 /* 85 * 8k(TH)/16K(TH2) em4 entries in each shared bank 86 */ 87 count = soc_mem_index_count(unit, mem); 88 if (SOC_IS_TOMAHAWK2(unit)) { 89 *num_banks = count / (16 * 1024); 90 } else { 91 *num_banks = count / (8 * 1024); 92 } 93 break; 94 case MPLS_ENTRYm: 95 case VLAN_XLATEm: 96 case VLAN_MACm: 97 case EGR_VLAN_XLATEm: 98 case ING_VP_VLAN_MEMBERSHIPm: 99 case EGR_VP_VLAN_MEMBERSHIPm: 100 case ING_DNAT_ADDRESS_TYPEm: 101 *num_banks = 2; 102 break; 103 default: 104 return SOC_E_INTERNAL; 105 } 106 107 return SOC_E_NONE; 108 } 109 110 /* Map logical to physical bank mapping for a memory 111 * mem - memory 112 * log_bank - logical bank number (or sequence bank number) 113 * phy_bank_id - Physical bank id 114 */ 115 int 116 soc_tomahawk_log_to_phy_bank_map(int unit, soc_mem_t mem, int log_bank, 117 int *phy_bank_id) 118 { 119 uint32 val; 120 static const soc_field_t l2_fields[] = { 121 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 122 L2_ENTRY_BANK_5f 123 }; 124 static soc_field_t l3_fields[] = { 125 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 126 L3_ENTRY_BANK_7f 127 }; 128 static soc_field_t fpem_fields[] = { 129 FPEM_ENTRY_BANK_0f, FPEM_ENTRY_BANK_1f, FPEM_ENTRY_BANK_2f, 130 FPEM_ENTRY_BANK_3f 131 }; 132 133 SOC_IF_ERROR_RETURN(soc_th_iss_log_to_phy_bank_map_shadow_get(unit, &val)); 134 switch (mem) { 135 case L2Xm: 136 if (log_bank < 0 || log_bank > 5) { 137 return SOC_E_PARAM; 138 } 139 if (log_bank < 2) { 140 *phy_bank_id = log_bank; 141 } else { 142 /* Starts with 0 in the register which maps to Physical bank 2 */ 143 *phy_bank_id = 2 + soc_reg_field_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, val, 144 l2_fields[log_bank - 2]); 145 } 146 break; 147 case L3_ENTRY_ONLYm: 148 case L3_ENTRY_IPV4_UNICASTm: 149 case L3_ENTRY_IPV4_MULTICASTm: 150 case L3_ENTRY_IPV6_UNICASTm: 151 case L3_ENTRY_IPV6_MULTICASTm: 152 if (log_bank < 0 || log_bank > 7) { 153 return SOC_E_PARAM; 154 } 155 if (log_bank < 4) { 156 *phy_bank_id = 6 + log_bank; /* dedicated banks */ 157 } else { 158 /* Starts with 0 in the register which maps to Physical bank 2 */ 159 *phy_bank_id = 2 + soc_reg_field_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, val, 160 l3_fields[log_bank - 4]); 161 } 162 break; 163 case EXACT_MATCH_2m: 164 case EXACT_MATCH_2_PIPE0m: 165 case EXACT_MATCH_2_PIPE1m: 166 case EXACT_MATCH_2_PIPE2m: 167 case EXACT_MATCH_2_PIPE3m: 168 case EXACT_MATCH_4m: 169 case EXACT_MATCH_4_PIPE0m: 170 case EXACT_MATCH_4_PIPE1m: 171 case EXACT_MATCH_4_PIPE2m: 172 case EXACT_MATCH_4_PIPE3m: 173 if (log_bank < 0 || log_bank > 3) { 174 return SOC_E_PARAM; 175 } 176 else { 177 /* Starts with 0 in the register which maps to Physical bank 2 */ 178 *phy_bank_id = 2 + soc_reg_field_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, val, 179 fpem_fields[log_bank]); 180 } 181 break; 182 default: 183 *phy_bank_id = log_bank; 184 break; 185 } 186 return SOC_E_NONE; 187 } 188 189 /* Map physical to logical bank mapping for a memory 190 * mem - memory 191 * phy_bank - physical bank number 192 * log_bank - logical bank id 193 */ 194 int 195 soc_tomahawk_phy_to_log_bank_map(int unit, soc_mem_t mem, int phy_bank, int *log_bank) 196 { 197 uint32 val, i; 198 static const soc_field_t l2_fields[] = { 199 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 200 L2_ENTRY_BANK_5f 201 }; 202 static soc_field_t l3_fields[] = { 203 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 204 L3_ENTRY_BANK_7f 205 }; 206 static soc_field_t fpem_fields[] = { 207 FPEM_ENTRY_BANK_0f, FPEM_ENTRY_BANK_1f, FPEM_ENTRY_BANK_2f, 208 FPEM_ENTRY_BANK_3f 209 }; 210 211 SOC_IF_ERROR_RETURN(READ_ISS_LOG_TO_PHY_BANK_MAPr(unit, &val)); 212 switch (mem) { 213 case L2Xm: 214 if (phy_bank < 0 || phy_bank > 5) { 215 return SOC_E_PARAM; 216 } 217 if (phy_bank < 2) { 218 *log_bank = phy_bank; 219 } else { 220 for (i = 0; i < 4; i++) { 221 /* Starts with 0 in the register which maps to Physical bank 2 */ 222 if ((soc_reg_field_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, val, 223 l2_fields[i]) + 2) == phy_bank) { 224 *log_bank = 2 + i; 225 break; 226 } 227 } 228 } 229 break; 230 case L3_ENTRY_ONLYm: 231 case L3_ENTRY_IPV4_UNICASTm: 232 case L3_ENTRY_IPV4_MULTICASTm: 233 case L3_ENTRY_IPV6_UNICASTm: 234 case L3_ENTRY_IPV6_MULTICASTm: 235 if (phy_bank < 2 || phy_bank > 9) { 236 return SOC_E_PARAM; 237 } 238 if (phy_bank > 5) { 239 *log_bank = phy_bank - 6; 240 } else { 241 for (i = 0; i < 4; i++) { 242 /* Starts with 0 in the register which maps to Physical bank 2 */ 243 if ((soc_reg_field_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, val, 244 l3_fields[i]) + 2) == phy_bank) { 245 *log_bank = 4 + i; 246 break; 247 } 248 } 249 } 250 break; 251 case EXACT_MATCH_2m: 252 case EXACT_MATCH_2_PIPE0m: 253 case EXACT_MATCH_2_PIPE1m: 254 case EXACT_MATCH_2_PIPE2m: 255 case EXACT_MATCH_2_PIPE3m: 256 case EXACT_MATCH_4m: 257 case EXACT_MATCH_4_PIPE0m: 258 case EXACT_MATCH_4_PIPE1m: 259 case EXACT_MATCH_4_PIPE2m: 260 case EXACT_MATCH_4_PIPE3m: 261 if (phy_bank < 2 || phy_bank > 5) { 262 return SOC_E_PARAM; 263 } else { 264 for (i = 0; i < 4; i++) { 265 /* Starts with 0 in the register which maps to Physical bank 2 */ 266 if ((soc_reg_field_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, val, 267 fpem_fields[i]) + 2) == phy_bank) { 268 *log_bank = i; 269 break; 270 } 271 } 272 } 273 break; 274 default: 275 *log_bank = phy_bank; 276 break; 277 } 278 return SOC_E_NONE; 279 } 280 281 /* Get bank bitmap for the hash table according to the config */ 282 int 283 soc_tomahawk_hash_bank_phy_bitmap_get(int unit, soc_mem_t mem, uint32 *bitmap) 284 { 285 uint32 physical_bitmap = 0; 286 int count = 0; 287 int i, phy_bank_id = 0; 288 SOC_IF_ERROR_RETURN(soc_tomahawk_hash_bank_count_get(unit, mem, &count)); 289 for (i = 0; i < count; i++) { 290 SOC_IF_ERROR_RETURN( 291 soc_tomahawk_log_to_phy_bank_map(unit, mem, i, &phy_bank_id)); 292 physical_bitmap |= (1 << phy_bank_id); 293 } 294 *bitmap = physical_bitmap; 295 return SOC_E_NONE; 296 } 297 298 /* 299 * Map bank sequence number to bank number. 300 * Sequence number: 0 .. (number of bank - 1) 301 * bank number: bank id in hardware 302 * This is only useful for L3 table which has non-sequential bank number, 303 * sequence number equals to bank number for all other tables. 304 */ 305 int 306 soc_tomahawk_hash_bank_number_get(int unit, soc_mem_t mem, int seq_num, 307 int *bank_num) 308 { 309 int count; 310 311 SOC_IF_ERROR_RETURN(soc_tomahawk_hash_bank_count_get(unit, mem, &count)); 312 if (seq_num < 0 || seq_num >= count) { 313 return SOC_E_CONFIG; 314 } 315 SOC_IF_ERROR_RETURN(soc_tomahawk_log_to_phy_bank_map(unit, mem, seq_num, bank_num)); 316 317 return SOC_E_NONE; 318 } 319 320 /* 321 * Map bank bank number to sequence number. 322 * Sequence number: 0 .. (number of bank - 1) 323 * bank number: bank id in hardware 324 * This is only useful for L3 table which has non-sequential bank number, 325 * 326 * L3 seq_num bank_num 327 * 0 6 328 * 1 7 329 * 2 8 330 * 3 9 331 * 4 5 332 * 5 4 333 */ 334 int 335 soc_tomahawk_hash_seq_number_get(int unit, soc_mem_t mem, int bank_num, 336 int *seq_num) 337 { 338 int count; 339 340 SOC_IF_ERROR_RETURN(soc_tomahawk_phy_to_log_bank_map(unit, mem, bank_num, seq_num)); 341 342 SOC_IF_ERROR_RETURN(soc_tomahawk_hash_bank_count_get(unit, mem, &count)); 343 if (*seq_num < 0 || *seq_num >= count) { 344 return SOC_E_INTERNAL; 345 } 346 347 return SOC_E_NONE; 348 349 } 350 351 int 352 soc_tomahawk_hash_bank_info_get(int unit, soc_mem_t mem, int bank, 353 int *entries_per_bank, int *entries_per_row, 354 int *entries_per_bucket, int *bank_base, 355 int *bucket_offset) 356 { 357 int bank_size, row_size, bucket_size, base, offset; 358 int seq_num = 0; 359 360 /* Get logical bank number */ 361 SOC_IF_ERROR_RETURN(soc_tomahawk_phy_to_log_bank_map(unit, mem, bank, &seq_num)); 362 bank = seq_num; 363 364 /* 365 * entry index for bucket b, entry e = 366 * bank_base + b * entries_per_row + bucket_offset + e; 367 */ 368 switch (mem) { 369 case L2Xm: 370 /* 371 * 4 entries per bucket (1 bucket per row) 372 * bank 0: index 0- 4095 (4k entries in dedicated bank 0) 373 * bank 1: index 4096- 8191 (4k entries in dedicated bank 1) 374 * bank 2: index 8192- 40959 (32k entries in shared bank) 375 * bank 3: index 40960- 73727 (32k entries in shared bank) 376 * bank 4: index 73728-106495 (32k entries in shared bank) 377 * bank 5: index 106496-139263 (32k entries in shared bank) 378 * each bucket has 4 entries 379 */ 380 row_size = 4; 381 bucket_size = 4; 382 offset = 0; 383 if (bank < 0 || bank > 5) { 384 return SOC_E_INTERNAL; 385 } else if (bank < 2) { /* 4k entries for each dedicated bank */ 386 bank_size = 4096; 387 base = bank * bank_size; 388 } else { /* 32k entries for each shared bank */ 389 bank_size = SOC_IS_TOMAHAWK2(unit) ? 65536 : 32768; 390 base = 8192 + (bank - 2) * bank_size; 391 } 392 break; 393 case L3_ENTRY_ONLYm: 394 case L3_ENTRY_IPV4_UNICASTm: 395 /* 396 * 4 entries per bucket (1 bucket per row) 397 * bank 0: index 0- 2047 (2k entries in dedicated bank 6) 398 * bank 1: index 2048- 4095 (2k entries in dedicated bank 7) 399 * bank 2: index 4096- 6143 (2k entries in dedicated bank 8) 400 * bank 3: index 6144- 8191 (2k entries in dedicated bank 9) 401 * bank 4: index 8192- 40959 (32k entries in shared bank) 402 * bank 5: index 40960- 73727 (32k entries in shared bank) 403 * bank 6: index 73728-106495 (32k entries in shared bank) 404 * bank 7: index 106496-139263 (32k entries in shared bank) 405 * each bucket has 4 entries 406 */ 407 row_size = 4; 408 bucket_size = 4; 409 offset = 0; 410 if (bank < 0 || bank > 7) { 411 return SOC_E_INTERNAL; 412 } else if (bank < 4) { /* 2k entriess for each dedicated bank */ 413 bank_size = 2048; 414 base = bank * bank_size; 415 } else { /* 32k entries for each shared bank */ 416 bank_size = SOC_IS_TOMAHAWK2(unit) ? 65536 : 32768; 417 base = 8192 + (bank - 4) * bank_size; 418 } 419 break; 420 case L3_ENTRY_IPV4_MULTICASTm: 421 case L3_ENTRY_IPV6_UNICASTm: 422 row_size = 2; 423 bucket_size = 2; 424 offset = 0; 425 if (bank < 0 || bank > 7) { 426 return SOC_E_INTERNAL; 427 } else if (bank < 4) { /* 2k entriess for each dedicated bank */ 428 bank_size = 1024; 429 base = bank * bank_size; 430 } else { /* 32k entries for each shared bank */ 431 bank_size = SOC_IS_TOMAHAWK2(unit) ? 32768 : 16384; 432 base = 4096 + (bank - 4) * bank_size; 433 } 434 break; 435 case L3_ENTRY_IPV6_MULTICASTm: 436 row_size = 1; 437 bucket_size = 1; 438 offset = 0; 439 if (bank < 0 || bank > 7) { 440 return SOC_E_INTERNAL; 441 } else if (bank < 4) { /* 2k entriess for each dedicated bank */ 442 bank_size = 512; 443 base = bank * bank_size; 444 } else { /* 32k entries for each shared bank */ 445 bank_size = SOC_IS_TOMAHAWK2(unit) ? 16384 : 8192; 446 base = 2048 + (bank - 4) * bank_size; 447 } 448 break; 449 case EXACT_MATCH_2m: 450 /* for TH 451 * bank 0: index 0- 16383 (16k entries in shared bank) 452 * bank 1: index 16384- 32767 (16k entries in shared bank) 453 * bank 2: index 32768- 49151 (16k entries in shared bank) 454 * bank 3: index 49152- 65535 (16k entries in shared bank) 455 * each bucket has 2 sram entries 456 */ 457 bank_size = SOC_IS_TOMAHAWK2(unit) ? 32768 : 16384; 458 row_size = 2; 459 bucket_size = 4; 460 base = bank * bank_size; 461 offset = 0; 462 break; 463 case EXACT_MATCH_4m: 464 /* for TH 465 * bank 0: index 0- 16383 (16k entries in shared bank) 466 * bank 1: index 16384- 32767 (16k entries in shared bank) 467 * bank 2: index 32768- 49151 (16k entries in shared bank) 468 * bank 3: index 49152- 65535 (16k entries in shared bank) 469 * each bucket has 1 sram entry 470 */ 471 bank_size = SOC_IS_TOMAHAWK2(unit) ? 16384 : 8192; 472 row_size = 1; 473 bucket_size = 4; 474 base = bank * bank_size; 475 offset = 0; 476 break; 477 case MPLS_ENTRYm: 478 case VLAN_XLATEm: 479 case VLAN_MACm: 480 case EGR_VLAN_XLATEm: 481 case ING_VP_VLAN_MEMBERSHIPm: 482 case EGR_VP_VLAN_MEMBERSHIPm: 483 case ING_DNAT_ADDRESS_TYPEm: 484 /* 485 * first half of entries in each row are for bank 0 486 * the other half of entries in each row are for bank 1 487 */ 488 bank_size = soc_mem_index_count(unit, mem) / 2; 489 row_size = 8; 490 bucket_size = 4; 491 base = 0; 492 offset = bank * bucket_size; 493 break; 494 default: 495 return SOC_E_INTERNAL; 496 } 497 498 if (entries_per_bank != NULL) { 499 *entries_per_bank = bank_size; 500 } 501 if (entries_per_row != NULL) { 502 *entries_per_row = row_size; 503 } 504 if (entries_per_bucket != NULL) { 505 *entries_per_bucket = bucket_size; 506 } 507 if (bank_base != NULL) { 508 *bank_base = base; 509 } 510 if (bucket_offset != NULL) { 511 *bucket_offset = offset; 512 } 513 return SOC_E_NONE; 514 } 515 516 STATIC int 517 _soc_th_hash_entry_to_key(int unit, int bank, void *entry, uint8 *key, soc_mem_t mem, 518 soc_field_t *field_list) 519 { 520 soc_field_t field; 521 int index, key_index, val_index, fval_index; 522 int right_shift_count, left_shift_count; 523 uint32 val[SOC_MAX_MEM_WORDS], fval[SOC_MAX_MEM_WORDS]; 524 int bits, val_bits, fval_bits; 525 int8 field_length[16]; 526 #ifdef SOC_ROBUST_HASH 527 soc_robust_hash_config_t *rbh_cfg = NULL; 528 #endif /* SOC_ROBUST_HASH */ 529 530 val_bits = 0; 531 for (index = 0; field_list[index] != INVALIDf; index++) { 532 field = field_list[index]; 533 field_length[index] = soc_mem_field_length(unit, mem, field); 534 val_bits += field_length[index]; 535 } 536 537 switch (mem) { 538 case L2Xm: 539 val_bits = soc_mem_field_length(unit, L2Xm, 540 TRILL_NONUC_NETWORK_LONG__KEYf); 541 break; 542 case L3_ENTRY_ONLYm: 543 case L3_ENTRY_IPV4_UNICASTm: 544 case L3_ENTRY_IPV4_MULTICASTm: 545 case L3_ENTRY_IPV6_UNICASTm: 546 val_bits = soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 547 IPV6MC__KEY_0f) + 548 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 549 IPV6MC__KEY_1f) + 550 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 551 IPV6MC__KEY_2f) + 552 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 553 IPV6MC__KEY_3f); 554 break; 555 case EXACT_MATCH_2m: 556 val_bits = soc_mem_field_length(unit, EXACT_MATCH_4m, 557 MODE320__KEY_0f) + 558 soc_mem_field_length(unit, EXACT_MATCH_4m, MODE320__KEY_1f) + 559 soc_mem_field_length(unit, EXACT_MATCH_4m, MODE320__KEY_2f) + 560 soc_mem_field_length(unit, EXACT_MATCH_4m, MODE320__KEY_3f); 561 break; 562 case VLAN_XLATEm: 563 case VLAN_MACm: 564 val_bits = soc_mem_field_length(unit, VLAN_MACm, MAC_PORT__KEYf); 565 break; 566 case EGR_VLAN_XLATEm: 567 val_bits = soc_mem_field_length(unit, EGR_VLAN_XLATEm, XLATE__KEYf); 568 break; 569 case MPLS_ENTRYm: 570 val_bits = soc_mem_field_length(unit, MPLS_ENTRYm, L2GRE_VPNID__KEYf); 571 break; 572 default: 573 break; 574 } 575 576 #ifdef SOC_ROBUST_HASH 577 if (soc_feature(unit, soc_feature_robust_hash)) { 578 switch (mem) { 579 case VLAN_XLATEm: 580 case VLAN_MACm: 581 rbh_cfg = &(ROBUSTHASH(unit)->ing_xlate); 582 break; 583 case MPLS_ENTRYm: 584 rbh_cfg = &(ROBUSTHASH(unit)->mpls_entry); 585 break; 586 case EGR_VLAN_XLATEm: 587 rbh_cfg = &(ROBUSTHASH(unit)->egr_xlate); 588 break; 589 default: 590 break; 591 } 592 } 593 /* If robust hash is enabled, byte boundry is adjusted after robust 594 hash key computation */ 595 if (rbh_cfg && rbh_cfg->enable) { 596 bits = val_bits; 597 val_bits = 0; 598 } else 599 #endif /* SOC_ROBUST_HASH */ 600 { 601 bits = (val_bits + 7) & ~0x7; 602 val_bits = bits - val_bits; 603 } 604 605 sal_memset(val, 0, sizeof(val)); 606 for (index = 0; field_list[index] != INVALIDf; index++) { 607 field = field_list[index]; 608 soc_mem_field_get(unit, mem, entry, field, fval); 609 fval_bits = field_length[index]; 610 611 val_index = val_bits >> 5; 612 fval_index = 0; 613 left_shift_count = val_bits & 0x1f; 614 right_shift_count = 32 - left_shift_count; 615 val_bits += fval_bits; 616 617 if (left_shift_count) { 618 for (; fval_bits > 0; fval_bits -= 32) { 619 val[val_index++] |= fval[fval_index] << left_shift_count; 620 val[val_index] |= fval[fval_index++] >> right_shift_count; 621 } 622 } else { 623 for (; fval_bits > 0; fval_bits -= 32) { 624 val[val_index++] = fval[fval_index++]; 625 } 626 } 627 } 628 629 key_index = 0; 630 for (val_index = 0; val_bits > 0; val_index++) { 631 for (right_shift_count = 0; right_shift_count < 32; 632 right_shift_count += 8) { 633 if (val_bits <= 0) { 634 break; 635 } 636 key[key_index++] = (val[val_index] >> right_shift_count) & 0xff; 637 val_bits -= 8; 638 } 639 } 640 641 if ((bits + 7) / 8 > key_index) { 642 sal_memset(&key[key_index], 0, (bits + 7) / 8 - key_index); 643 } 644 645 #ifdef SOC_ROBUST_HASH 646 if (soc_feature(unit, soc_feature_robust_hash)) { 647 if (rbh_cfg) { 648 if (rbh_cfg->enable) { 649 (void) soc_robust_hash_get(unit, rbh_cfg, bank, key, bits); 650 } 651 /* crc generator has the same key length irrespective 652 * of whether robust hash is enabled 653 */ 654 bits = (bits + 7) & ~0x7; 655 bits += ROBUST_HASH_KEY_SPACE_WIDTH; 656 } 657 } 658 #endif /* SOC_ROBUST_HASH */ 659 660 return bits; 661 } 662 663 /* For non-UFT style hash (all tables except L2 and L3) */ 664 STATIC int 665 soc_th_hash_sel_get(int unit, soc_mem_t mem, int bank, int *hash_sel) 666 { 667 soc_reg_t reg; 668 soc_field_t field; 669 uint32 rval; 670 671 field = bank > 0 ? HASH_SELECT_Bf : HASH_SELECT_Af; 672 switch (mem) { 673 case VLAN_XLATEm: 674 case VLAN_MACm: 675 reg = VLAN_XLATE_HASH_CONTROLr; 676 break; 677 case EGR_VLAN_XLATEm: 678 reg = EGR_VLAN_XLATE_HASH_CONTROLr; 679 break; 680 case MPLS_ENTRYm: 681 reg = MPLS_ENTRY_HASH_CONTROLr; 682 break; 683 case ING_VP_VLAN_MEMBERSHIPm: 684 reg = ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr; 685 break; 686 case EGR_VP_VLAN_MEMBERSHIPm: 687 reg = EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr; 688 break; 689 case ING_DNAT_ADDRESS_TYPEm: 690 reg = ING_DNAT_ADDRESS_TYPE_HASH_CONTROLr; 691 break; 692 default: 693 return SOC_E_INTERNAL; 694 } 695 696 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 697 *hash_sel = soc_reg_field_get(unit, reg, rval, field); 698 699 return SOC_E_NONE; 700 } 701 702 /* For UFT style hash (L2 and L3 table) */ 703 int 704 soc_th_hash_offset_get(int unit, soc_mem_t mem, int bank, int *hash_offset, 705 int *use_lsb) 706 { 707 uint32 rval; 708 int is_shared = 0; 709 soc_reg_t reg; 710 soc_field_t field; 711 static const soc_field_t l2_fields[] = { 712 BANK0_HASH_OFFSETf, BANK1_HASH_OFFSETf, BANK2_HASH_OFFSETf, 713 BANK3_HASH_OFFSETf, BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf 714 }; 715 static const soc_field_t l3_fields[] = { 716 BANK6_HASH_OFFSETf, BANK7_HASH_OFFSETf, BANK8_HASH_OFFSETf, 717 BANK9_HASH_OFFSETf, BANK2_HASH_OFFSETf, BANK3_HASH_OFFSETf, 718 BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf 719 }; 720 static const soc_field_t fpem_fields[] = { 721 BANK2_HASH_OFFSETf, BANK3_HASH_OFFSETf, BANK4_HASH_OFFSETf, 722 BANK5_HASH_OFFSETf 723 }; 724 725 if (mem == L2Xm) { 726 if (bank < 0 || bank > 5) { 727 return SOC_E_PARAM; 728 } 729 is_shared = bank > 1; 730 reg = L2_TABLE_HASH_CONTROLr; 731 field = l2_fields[bank]; 732 } else if (mem == L3_ENTRY_ONLYm) { 733 if (bank < 2 || bank > 9) { 734 return SOC_E_PARAM; 735 } 736 if (bank >= 6 && bank <= 9) { /* Dedicated banks */ 737 bank = bank - 6; 738 } else if (bank >= 2 && bank <= 5) { /* Shared Banks */ 739 bank = 2 + bank; 740 is_shared = 1; 741 } 742 reg = L3_TABLE_HASH_CONTROLr; 743 field = l3_fields[bank]; 744 } else if (mem == EXACT_MATCH_2m) { 745 if (bank < 2 || bank > 5) { 746 return SOC_E_PARAM; 747 } 748 bank = bank - 2; 749 is_shared = 1; 750 reg = FPEM_CONTROLr; 751 field = fpem_fields[bank]; 752 } else { 753 return SOC_E_INTERNAL; 754 } 755 756 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 757 *use_lsb = soc_reg_field_get(unit, reg, rval, HASH_ZERO_OR_LSBf); 758 759 if (is_shared) { 760 reg = SHARED_TABLE_HASH_CONTROLr; 761 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 762 } 763 764 *hash_offset = soc_reg_field_get(unit, reg, rval, field); 765 766 return SOC_E_NONE; 767 } 768 769 int 770 soc_th_hash_offset_set(int unit, soc_mem_t mem, int bank, int hash_offset, 771 int use_lsb) 772 { 773 uint32 rval; 774 soc_reg_t reg; 775 static const soc_field_t fields[] = { 776 BANK0_HASH_OFFSETf, BANK1_HASH_OFFSETf, BANK2_HASH_OFFSETf, 777 BANK3_HASH_OFFSETf, BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf, 778 BANK6_HASH_OFFSETf, BANK7_HASH_OFFSETf, BANK8_HASH_OFFSETf, 779 BANK9_HASH_OFFSETf 780 }; 781 782 if (mem == L2Xm) { 783 if (bank < 0 || bank > 5) { 784 return SOC_E_PARAM; 785 } 786 reg = L2_TABLE_HASH_CONTROLr; 787 } else if (mem == L3_ENTRY_ONLYm) { 788 if (bank < 2 || bank > 9) { 789 return SOC_E_PARAM; 790 } 791 reg = L3_TABLE_HASH_CONTROLr; 792 } else if (mem == EXACT_MATCH_2m) { 793 if (bank < 2 || bank > 5) { 794 return SOC_E_PARAM; 795 } 796 reg = FPEM_CONTROLr; 797 } else { 798 return SOC_E_INTERNAL; 799 } 800 801 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 802 soc_reg_field_set(unit, reg, &rval, HASH_ZERO_OR_LSBf, use_lsb); 803 if (bank < 2 || bank > 5) { 804 soc_reg_field_set(unit, reg, &rval, fields[bank], hash_offset); 805 } 806 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 807 808 if (bank > 1 && bank < 6) { 809 reg = SHARED_TABLE_HASH_CONTROLr; 810 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 811 soc_reg_field_set(unit, reg, &rval, fields[bank], hash_offset); 812 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 813 } 814 return SOC_E_NONE; 815 } 816 817 STATIC int 818 _soc_th_shared_hash(int unit, int hash_offset, uint32 key_nbits, uint8 *key, 819 uint32 result_mask, uint16 lsb) 820 { 821 uint32 crc_hi, crc_lo; 822 823 if (hash_offset >= 48) { 824 if (hash_offset > 48) { 825 lsb >>= hash_offset - 48; 826 } 827 return lsb & result_mask; 828 } 829 830 crc_hi = soc_crc16b(key, key_nbits) | ((uint32)lsb << 16); 831 if (hash_offset >= 32) { 832 if (hash_offset > 32) { 833 crc_hi >>= hash_offset - 32; 834 } 835 return crc_hi & result_mask; 836 } 837 838 crc_lo = soc_crc32b(key, key_nbits); 839 if (hash_offset > 0) { 840 crc_lo >>= hash_offset; 841 crc_lo |= crc_hi << (32 - hash_offset); 842 } 843 return crc_lo & result_mask; 844 } 845 846 uint32 847 soc_th_l2x_hash(int unit, int bank, int hash_offset, int use_lsb, 848 int key_nbits, void *base_entry, uint8 *key) 849 { 850 uint32 lsb_val; 851 uint32 hash_mask; 852 uint32 hash_bits; 853 854 if (bank < 2) { 855 hash_mask = 0x03ff; /* 1k buckets per dedicated L2 bank */ 856 hash_bits = 10; 857 } else { 858 if (SOC_IS_TOMAHAWK2(unit)) { 859 hash_mask = 0x3fff; /* 16k buckets per shared bank */ 860 hash_bits = 14; 861 } else { 862 hash_mask = 0x1fff; /* 8k buckets per shared bank */ 863 hash_bits = 13; 864 } 865 } 866 867 if (use_lsb && (hash_offset + hash_bits > 48)) { 868 switch (soc_mem_field32_get(unit, L2Xm, base_entry, KEY_TYPEf)) { 869 case TH_L2_HASH_KEY_TYPE_BRIDGE: 870 case TH_L2_HASH_KEY_TYPE_VFI: 871 case TH_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 872 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 873 L2__HASH_LSBf); 874 break; 875 case TH_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 876 case TH_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 877 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 878 VLAN__HASH_LSBf); 879 break; 880 case TH_L2_HASH_KEY_TYPE_VIF: 881 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 882 VIF__HASH_LSBf); 883 break; 884 case TH_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 885 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 886 TRILL_NONUC_NETWORK_LONG__HASH_LSBf); 887 break; 888 case TH_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 889 lsb_val = soc_mem_field32_get 890 (unit, L2Xm, base_entry, TRILL_NONUC_NETWORK_SHORT__HASH_LSBf); 891 break; 892 case TH_L2_HASH_KEY_TYPE_BFD: 893 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 894 BFD__HASH_LSBf); 895 break; 896 case TH_L2_HASH_KEY_TYPE_PE_VID: 897 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 898 PE_VID__HASH_LSBf); 899 break; 900 default: 901 lsb_val = 0; 902 break; 903 } 904 } else { 905 lsb_val = 0; 906 } 907 908 return _soc_th_shared_hash(unit, hash_offset, key_nbits, key, hash_mask, 909 lsb_val); 910 } 911 912 int 913 soc_th_l2x_base_entry_to_key(int unit, int bank, uint32 *entry, uint8 *key) 914 { 915 soc_field_t field_list[2]; 916 917 switch (soc_mem_field32_get(unit, L2Xm, entry, KEY_TYPEf)) { 918 case TH_L2_HASH_KEY_TYPE_BRIDGE: 919 case TH_L2_HASH_KEY_TYPE_VFI: 920 case TH_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 921 field_list[0] = L2__KEYf; 922 break; 923 case TH_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 924 case TH_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 925 field_list[0] = VLAN__KEYf; 926 break; 927 case TH_L2_HASH_KEY_TYPE_VIF: 928 field_list[0] = VIF__KEYf; 929 break; 930 case TH_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 931 field_list[0] = TRILL_NONUC_NETWORK_LONG__KEYf; 932 break; 933 case TH_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 934 field_list[0] = TRILL_NONUC_NETWORK_SHORT__KEYf; 935 break; 936 case TH_L2_HASH_KEY_TYPE_BFD: 937 field_list[0] = BFD__KEYf; 938 break; 939 case TH_L2_HASH_KEY_TYPE_PE_VID: 940 field_list[0] = PE_VID__KEYf; 941 break; 942 default: 943 return 0; 944 } 945 field_list[1] = INVALIDf; 946 return _soc_th_hash_entry_to_key(unit, bank, entry, key, L2Xm, field_list); 947 } 948 949 uint32 950 soc_th_l2x_entry_hash(int unit, int bank, int hash_offset, int use_lsb, 951 uint32 *entry) 952 { 953 int key_nbits; 954 uint8 key[SOC_MAX_MEM_WORDS * 4]; 955 956 key_nbits = soc_th_l2x_base_entry_to_key(unit, bank, entry, key); 957 return soc_th_l2x_hash(unit, bank, hash_offset, use_lsb, key_nbits, entry, 958 key); 959 } 960 961 uint32 962 soc_th_l2x_bank_entry_hash(int unit, int bank, uint32 *entry) 963 { 964 int rv, hash_offset, use_lsb; 965 966 rv = soc_th_hash_offset_get(unit, L2Xm, bank, &hash_offset, &use_lsb); 967 if (SOC_FAILURE(rv)) { 968 return 0; 969 } 970 971 return soc_th_l2x_entry_hash(unit, bank, hash_offset, use_lsb, entry); 972 } 973 974 uint32 975 soc_th_l3x_hash(int unit, int bank, int hash_offset, int use_lsb, 976 int key_nbits, void *base_entry, uint8 *key) 977 { 978 uint32 lsb_val; 979 uint32 hash_mask; 980 uint32 hash_bits; 981 982 if (bank > 5) { 983 hash_mask = 0x1ff; /* 512 buckets per dedicated L3 bank */ 984 hash_bits = 9; 985 } else { 986 if (SOC_IS_TOMAHAWK2(unit)) { 987 hash_mask = 0x3fff; /* 16k buckets per shared bank */ 988 hash_bits = 14; 989 } else { 990 hash_mask = 0x1fff; /* 8k buckets per shared bank */ 991 hash_bits = 13; 992 } 993 } 994 995 if (use_lsb && (hash_offset + hash_bits > 48)) { 996 switch (soc_mem_field32_get(unit, L3_ENTRY_ONLYm, base_entry, 997 KEY_TYPEf)) { 998 case TH_L3_HASH_KEY_TYPE_V4UC: 999 case TH_L3_HASH_KEY_TYPE_V4UC_EXT: 1000 case TH_L3_HASH_KEY_TYPE_V4MC: 1001 case TH_L3_HASH_KEY_TYPE_V6UC: 1002 case TH_L3_HASH_KEY_TYPE_V6UC_EXT: 1003 case TH_L3_HASH_KEY_TYPE_V6MC: 1004 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, 1005 base_entry, IPV4UC__HASH_LSBf); 1006 break; 1007 case TH_L3_HASH_KEY_TYPE_TRILL: 1008 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, 1009 base_entry, TRILL__HASH_LSBf); 1010 break; 1011 case TH_L3_HASH_KEY_TYPE_DST_NAT: 1012 case TH_L3_HASH_KEY_TYPE_DST_NAPT: 1013 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_MULTICASTm, 1014 base_entry, NAT__HASH_LSBf); 1015 break; 1016 default: 1017 lsb_val = 0; 1018 break; 1019 } 1020 } else { 1021 lsb_val = 0; 1022 } 1023 1024 return _soc_th_shared_hash(unit, hash_offset, key_nbits, key, hash_mask, 1025 lsb_val); 1026 } 1027 1028 int 1029 soc_th_hash_bucket_get(int unit, int mem, int bank, uint32 *entry, uint32 *bucket) 1030 { 1031 switch(mem) { 1032 case L2Xm: 1033 *bucket = soc_th_l2x_bank_entry_hash(unit, bank, entry); 1034 return SOC_E_NONE; 1035 case L3_ENTRY_ONLYm: 1036 case L3_ENTRY_IPV4_UNICASTm: 1037 case L3_ENTRY_IPV4_MULTICASTm: 1038 case L3_ENTRY_IPV6_UNICASTm: 1039 case L3_ENTRY_IPV6_MULTICASTm: 1040 *bucket = soc_th_l3x_bank_entry_hash(unit, bank, entry); 1041 return SOC_E_NONE; 1042 case EXACT_MATCH_2m: 1043 case EXACT_MATCH_2_PIPE0m: 1044 case EXACT_MATCH_2_PIPE1m: 1045 case EXACT_MATCH_2_PIPE2m: 1046 case EXACT_MATCH_2_PIPE3m: 1047 case EXACT_MATCH_4m: 1048 case EXACT_MATCH_4_PIPE0m: 1049 case EXACT_MATCH_4_PIPE1m: 1050 case EXACT_MATCH_4_PIPE2m: 1051 case EXACT_MATCH_4_PIPE3m: 1052 *bucket = soc_th_exact_match_bank_entry_hash(unit, bank, entry); 1053 return SOC_E_NONE; 1054 case VLAN_XLATEm: 1055 *bucket = soc_th_vlan_xlate_bank_entry_hash(unit, bank, entry); 1056 return SOC_E_NONE; 1057 case EGR_VLAN_XLATEm: 1058 *bucket = soc_th_egr_vlan_xlate_bank_entry_hash(unit, bank, entry); 1059 return SOC_E_NONE; 1060 case MPLS_ENTRYm: 1061 *bucket = soc_th_mpls_bank_entry_hash(unit, bank, entry); 1062 return SOC_E_NONE; 1063 case ING_VP_VLAN_MEMBERSHIPm: 1064 *bucket = soc_th_ing_vp_vlan_member_bank_entry_hash(unit, bank, entry); 1065 return SOC_E_NONE; 1066 case EGR_VP_VLAN_MEMBERSHIPm: 1067 *bucket = soc_th_egr_vp_vlan_member_bank_entry_hash(unit, bank, entry); 1068 return SOC_E_NONE; 1069 case ING_DNAT_ADDRESS_TYPEm: 1070 *bucket = soc_th_ing_dnat_address_type_bank_entry_hash(unit, bank, entry); 1071 return SOC_E_NONE; 1072 default: 1073 return SOC_E_PARAM; 1074 } 1075 } 1076 1077 int 1078 soc_th_hash_index_get(int unit, int mem, int bank, int bucket) 1079 { 1080 int rv; 1081 int index; 1082 int entries_per_row, entries_per_bucket, bank_base, bucket_offset; 1083 1084 switch(mem) { 1085 case L2Xm: 1086 rv = soc_tomahawk_hash_bank_info_get(unit, mem, bank, NULL, 1087 &entries_per_row, NULL, 1088 &bank_base, &bucket_offset); 1089 if (SOC_SUCCESS(rv)) { 1090 return bank_base + bucket * entries_per_row + bucket_offset; 1091 } 1092 break; 1093 case L3_ENTRY_ONLYm: 1094 case L3_ENTRY_IPV4_UNICASTm: 1095 case L3_ENTRY_IPV4_MULTICASTm: 1096 case L3_ENTRY_IPV6_UNICASTm: 1097 case L3_ENTRY_IPV6_MULTICASTm: 1098 rv = soc_tomahawk_hash_bank_info_get(unit, L3_ENTRY_ONLYm, bank, NULL, 1099 &entries_per_row, NULL, 1100 &bank_base, &bucket_offset); 1101 if (SOC_SUCCESS(rv)) { 1102 index = bank_base + bucket * entries_per_row + bucket_offset; 1103 if (mem == L3_ENTRY_IPV4_MULTICASTm || mem == L3_ENTRY_IPV6_UNICASTm) { 1104 return index / 2; 1105 } else if (mem == L3_ENTRY_IPV6_MULTICASTm) { 1106 return index / 4; 1107 } 1108 return index; 1109 } 1110 break; 1111 case EXACT_MATCH_2m: 1112 case EXACT_MATCH_2_PIPE0m: 1113 case EXACT_MATCH_2_PIPE1m: 1114 case EXACT_MATCH_2_PIPE2m: 1115 case EXACT_MATCH_2_PIPE3m: 1116 rv = soc_tomahawk_hash_bank_info_get(unit, EXACT_MATCH_2m, bank, NULL, 1117 &entries_per_row, &entries_per_bucket, 1118 &bank_base, &bucket_offset); 1119 if (SOC_SUCCESS(rv)) { 1120 index = bank_base + bucket * entries_per_bucket + bucket_offset; 1121 return index; 1122 } 1123 break; 1124 case EXACT_MATCH_4m: 1125 case EXACT_MATCH_4_PIPE0m: 1126 case EXACT_MATCH_4_PIPE1m: 1127 case EXACT_MATCH_4_PIPE2m: 1128 case EXACT_MATCH_4_PIPE3m: 1129 rv = soc_tomahawk_hash_bank_info_get(unit, EXACT_MATCH_4m, bank, NULL, 1130 &entries_per_row, &entries_per_bucket, 1131 &bank_base, &bucket_offset); 1132 if (SOC_SUCCESS(rv)) { 1133 index = bank_base + bucket * entries_per_bucket + bucket_offset; 1134 return index; 1135 } 1136 break; 1137 default: 1138 break; 1139 } 1140 1141 return 0; 1142 } 1143 1144 int 1145 soc_th_l3x_base_entry_to_key(int unit, int bank, uint32 *entry, uint8 *key) 1146 { 1147 soc_mem_t mem = L3_ENTRY_ONLYm; 1148 soc_field_t field_list[5]; 1149 uint32 entry_words = 0; 1150 uint32 sanitized_entry[SOC_MAX_MEM_WORDS] = {0}; 1151 void *ptr = NULL; 1152 1153 ptr = (void *)entry; 1154 1155 if (!SOC_MEM_IS_VALID(unit, mem)) { 1156 mem = L3_ENTRY_ONLY_SINGLEm; 1157 } 1158 switch (soc_mem_field32_get(unit, mem, entry, KEY_TYPEf)) { 1159 case TH_L3_HASH_KEY_TYPE_V4UC_EXT: 1160 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV4_UNICASTm); 1161 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(uint32)); 1162 ptr = &sanitized_entry; 1163 soc_mem_field32_set(unit, L3_ENTRY_IPV4_UNICASTm, ptr, KEY_TYPEf, 1164 TH_L3_HASH_KEY_TYPE_V4UC); 1165 /* fall through */ 1166 case TH_L3_HASH_KEY_TYPE_V4UC: 1167 mem = L3_ENTRY_IPV4_UNICASTm; 1168 if (!SOC_MEM_IS_VALID(unit, L3_ENTRY_IPV4_UNICASTm)) { 1169 mem = L3_ENTRY_ONLY_SINGLEm; 1170 } 1171 field_list[0] = IPV4UC__KEYf; 1172 field_list[1] = INVALIDf; 1173 break; 1174 case TH_L3_HASH_KEY_TYPE_V6UC_EXT: 1175 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV6_UNICASTm); 1176 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(uint32)); 1177 ptr = &sanitized_entry; 1178 soc_mem_field32_set(unit, L3_ENTRY_IPV6_UNICASTm, ptr, KEY_TYPE_0f, 1179 TH_L3_HASH_KEY_TYPE_V6UC); 1180 /* fall through */ 1181 case TH_L3_HASH_KEY_TYPE_V6UC: 1182 mem = L3_ENTRY_IPV6_UNICASTm; 1183 if (!SOC_MEM_IS_VALID(unit, L3_ENTRY_IPV6_UNICASTm)) { 1184 mem = L3_ENTRY_ONLY_DOUBLEm; 1185 } 1186 field_list[0] = IPV6UC__KEY_0f; 1187 field_list[1] = IPV6UC__KEY_1f; 1188 field_list[2] = INVALIDf; 1189 break; 1190 case TH_L3_HASH_KEY_TYPE_V4MC: 1191 mem = L3_ENTRY_IPV4_MULTICASTm; 1192 if (!SOC_MEM_IS_VALID(unit, L3_ENTRY_IPV4_MULTICASTm)) { 1193 mem = L3_ENTRY_ONLY_DOUBLEm; 1194 } 1195 field_list[0] = IPV4MC__KEY_0f; 1196 field_list[1] = IPV4MC__KEY_1f; 1197 field_list[2] = INVALIDf; 1198 break; 1199 case TH_L3_HASH_KEY_TYPE_V6MC: 1200 mem = L3_ENTRY_IPV6_MULTICASTm; 1201 if (!SOC_MEM_IS_VALID(unit, L3_ENTRY_IPV6_MULTICASTm)) { 1202 mem = L3_ENTRY_ONLY_QUADm; 1203 } 1204 field_list[0] = IPV6MC__KEY_0f; 1205 field_list[1] = IPV6MC__KEY_1f; 1206 field_list[2] = IPV6MC__KEY_2f; 1207 field_list[3] = IPV6MC__KEY_3f; 1208 field_list[4] = INVALIDf; 1209 break; 1210 case TH_L3_HASH_KEY_TYPE_TRILL: 1211 mem = L3_ENTRY_IPV4_UNICASTm; 1212 field_list[0] = TRILL__KEYf; 1213 field_list[1] = INVALIDf; 1214 break; 1215 case TH_L3_HASH_KEY_TYPE_DST_NAT: 1216 case TH_L3_HASH_KEY_TYPE_DST_NAPT: 1217 mem = L3_ENTRY_IPV4_MULTICASTm; 1218 field_list[0] = NAT__KEY_0f; 1219 field_list[1] = INVALIDf; 1220 break; 1221 default: 1222 return 0; 1223 } 1224 return _soc_th_hash_entry_to_key(unit, bank, ptr, key, mem, field_list); 1225 } 1226 1227 uint32 1228 soc_th_l3x_entry_hash(int unit, int bank, int hash_offset, int use_lsb, 1229 uint32 *entry) 1230 { 1231 int key_nbits; 1232 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1233 1234 key_nbits = soc_th_l3x_base_entry_to_key(unit, bank, entry, key); 1235 return soc_th_l3x_hash(unit, bank, hash_offset, use_lsb, key_nbits, entry, key); 1236 } 1237 1238 uint32 1239 soc_th_l3x_bank_entry_hash(int unit, int bank, uint32 *entry) 1240 { 1241 int rv, hash_offset, use_lsb; 1242 1243 rv = soc_th_hash_offset_get(unit, L3_ENTRY_ONLYm, bank, &hash_offset, 1244 &use_lsb); 1245 if (SOC_FAILURE(rv)) { 1246 return 0; 1247 } 1248 1249 return soc_th_l3x_entry_hash(unit, bank, hash_offset, use_lsb, entry); 1250 } 1251 1252 uint32 1253 soc_th_exact_match_hash(int unit, int bank, int hash_offset, int use_lsb, 1254 int key_nbits, void *base_entry, uint8 *key) 1255 { 1256 uint32 lsb_val; 1257 uint32 hash_mask; 1258 uint32 hash_bits; 1259 if (SOC_IS_TOMAHAWK2(unit)) { 1260 hash_mask = 0x1fff; /* 8k buckets per shared bank */ 1261 hash_bits = 14; 1262 } else { 1263 hash_mask = 0xfff; /* 4k buckets per shared bank */ 1264 hash_bits = 13; 1265 } 1266 1267 if (use_lsb && (hash_offset + hash_bits > 48)) { 1268 switch (soc_mem_field32_get(unit, EXACT_MATCH_2m, base_entry, 1269 KEY_TYPE_0f)) { 1270 case TH_FPEM_HASH_KEY_TYPE_128B: 1271 lsb_val = soc_mem_field32_get(unit, EXACT_MATCH_2m, 1272 base_entry, MODE128__HASH_LSBf); 1273 break; 1274 case TH_FPEM_HASH_KEY_TYPE_160B: 1275 lsb_val = soc_mem_field32_get(unit, EXACT_MATCH_2m, 1276 base_entry, MODE160__HASH_LSBf); 1277 break; 1278 case TH_FPEM_HASH_KEY_TYPE_320B: 1279 lsb_val = soc_mem_field32_get(unit, EXACT_MATCH_4m, 1280 base_entry, MODE320__HASH_LSBf); 1281 break; 1282 default: 1283 lsb_val = 0; 1284 break; 1285 } 1286 } else { 1287 lsb_val = 0; 1288 } 1289 if (TH_FPEM_HASH_KEY_TYPE_320B == 1290 soc_mem_field32_get(unit, EXACT_MATCH_2m, base_entry, KEY_TYPE_0f)) { 1291 hash_mask >>= 1; /* for em quad mode, one bucket holds 4 sram entries */ 1292 } 1293 return _soc_th_shared_hash(unit, hash_offset, key_nbits, key, hash_mask, 1294 lsb_val); 1295 } 1296 1297 int 1298 soc_th_exact_match_base_entry_to_key(int unit, int bank, uint32 *entry, uint8 *key) 1299 { 1300 soc_mem_t mem; 1301 soc_field_t field_list[5]; 1302 1303 switch (soc_mem_field32_get(unit, EXACT_MATCH_2m, entry, KEY_TYPE_0f)) { 1304 case TH_FPEM_HASH_KEY_TYPE_128B: 1305 mem = EXACT_MATCH_2m; 1306 field_list[0] = MODE128__KEY_0f; 1307 field_list[1] = MODE128__KEY_1f; 1308 field_list[2] = INVALIDf; 1309 break; 1310 case TH_FPEM_HASH_KEY_TYPE_160B: 1311 mem = EXACT_MATCH_2m; 1312 field_list[0] = MODE160__KEY_0f; 1313 field_list[1] = MODE160__KEY_1f; 1314 field_list[2] = INVALIDf; 1315 break; 1316 case TH_FPEM_HASH_KEY_TYPE_320B: 1317 mem = EXACT_MATCH_4m; 1318 field_list[0] = MODE320__KEY_0f; 1319 field_list[1] = MODE320__KEY_1f; 1320 field_list[2] = MODE320__KEY_2f; 1321 field_list[3] = MODE320__KEY_3f; 1322 field_list[4] = INVALIDf; 1323 break; 1324 default: 1325 return 0; 1326 } 1327 return _soc_th_hash_entry_to_key(unit, bank, entry, key, mem, field_list); 1328 } 1329 1330 uint32 1331 soc_th_exact_match_entry_hash(int unit, int bank, int hash_offset, 1332 int use_lsb, uint32 *entry) 1333 { 1334 int key_nbits; 1335 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1336 1337 key_nbits = soc_th_exact_match_base_entry_to_key(unit, bank, entry, key); 1338 return soc_th_exact_match_hash(unit, bank, hash_offset, use_lsb, 1339 key_nbits, entry, key); 1340 } 1341 1342 uint32 1343 soc_th_exact_match_bank_entry_hash(int unit, int bank, uint32 *entry) 1344 { 1345 int rv, hash_offset, use_lsb; 1346 1347 rv = soc_th_hash_offset_get(unit, EXACT_MATCH_2m, bank, &hash_offset, 1348 &use_lsb); 1349 if (SOC_FAILURE(rv)) { 1350 return 0; 1351 } 1352 1353 return soc_th_exact_match_entry_hash(unit, bank, hash_offset, use_lsb, 1354 entry); 1355 } 1356 1357 uint32 1358 soc_th_mpls_hash(int unit, int hash_sel, int key_nbits, void *base_entry, 1359 uint8 *key) 1360 { 1361 uint32 rv = 0; 1362 1363 /* 1364 * Cache bucket mask and shift amount for upper crc 1365 */ 1366 if (SOC_CONTROL(unit)->hash_mask_mpls == 0) { 1367 uint32 mask; 1368 int bits; 1369 1370 /* 8 Entries per bucket */ 1371 mask = soc_mem_index_max(unit, MPLS_ENTRYm) >> 3; 1372 bits = 0; 1373 rv = 1; 1374 while (rv && (mask & rv)) { 1375 bits += 1; 1376 rv <<= 1; 1377 } 1378 SOC_CONTROL(unit)->hash_mask_mpls = mask; 1379 SOC_CONTROL(unit)->hash_bits_mpls = bits; 1380 } 1381 1382 switch (hash_sel) { 1383 case FB_HASH_CRC16_UPPER: 1384 rv = soc_crc16b(key, key_nbits); 1385 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_mpls; 1386 break; 1387 1388 case FB_HASH_CRC16_LOWER: 1389 rv = soc_crc16b(key, key_nbits); 1390 break; 1391 1392 case FB_HASH_LSB: 1393 if (key_nbits == 0) { 1394 return 0; 1395 } 1396 switch (soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1397 KEY_TYPEf)) { 1398 case TH_MPLS_HASH_KEY_TYPE_MPLS: 1399 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1400 MPLS__HASH_LSBf); 1401 break; 1402 case TH_MPLS_HASH_KEY_TYPE_MIM_NVP: 1403 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1404 MIM_NVP__HASH_LSBf); 1405 break; 1406 case TH_MPLS_HASH_KEY_TYPE_MIM_ISID: 1407 case TH_MPLS_HASH_KEY_TYPE_MIM_ISID_SVP: 1408 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1409 MIM_ISID__HASH_LSBf); 1410 break; 1411 case TH_MPLS_HASH_KEY_TYPE_TRILL: 1412 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1413 TRILL__HASH_LSBf); 1414 break; 1415 case TH_MPLS_HASH_KEY_TYPE_L2GRE_SIP: 1416 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1417 L2GRE_SIP__HASH_LSBf); 1418 break; 1419 case TH_MPLS_HASH_KEY_TYPE_L2GRE_VPNID_SIP: 1420 case TH_MPLS_HASH_KEY_TYPE_L2GRE_VPNID: 1421 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1422 L2GRE_VPNID__HASH_LSBf); 1423 break; 1424 case TH_MPLS_HASH_KEY_TYPE_VXLAN_SIP: 1425 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1426 VXLAN_SIP__HASH_LSBf); 1427 break; 1428 case TH_MPLS_HASH_KEY_TYPE_VXLAN_VPNID: 1429 case TH_MPLS_HASH_KEY_TYPE_VXLAN_VPNID_SIP: 1430 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 1431 VXLAN_VN_ID__HASH_LSBf); 1432 break; 1433 default: 1434 rv = 0; 1435 break; 1436 } 1437 break; 1438 1439 case FB_HASH_ZERO: 1440 rv = 0; 1441 break; 1442 1443 case FB_HASH_CRC32_UPPER: 1444 rv = soc_crc32b(key, key_nbits); 1445 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_mpls; 1446 break; 1447 1448 case FB_HASH_CRC32_LOWER: 1449 rv = soc_crc32b(key, key_nbits); 1450 break; 1451 1452 default: 1453 LOG_ERROR(BSL_LS_SOC_HASH, 1454 (BSL_META_U(unit, 1455 "soc_th_mpls_hash: invalid hash_sel %d\n"), 1456 hash_sel)); 1457 rv = 0; 1458 break; 1459 } 1460 1461 return rv & SOC_CONTROL(unit)->hash_mask_mpls; 1462 } 1463 1464 int 1465 soc_th_mpls_base_entry_to_key(int unit, int bank, void *entry, uint8 *key) 1466 { 1467 soc_field_t field_list[2]; 1468 1469 switch (soc_mem_field32_get(unit, MPLS_ENTRYm, entry, KEY_TYPEf)) { 1470 case TH_MPLS_HASH_KEY_TYPE_MPLS: 1471 field_list[0] = MPLS__KEYf; 1472 break; 1473 case TH_MPLS_HASH_KEY_TYPE_MIM_NVP: 1474 field_list[0] = MIM_NVP__KEYf; 1475 break; 1476 case TH_MPLS_HASH_KEY_TYPE_MIM_ISID: 1477 case TH_MPLS_HASH_KEY_TYPE_MIM_ISID_SVP: 1478 field_list[0] = MIM_ISID__KEYf; 1479 break; 1480 case TH_MPLS_HASH_KEY_TYPE_TRILL: 1481 field_list[0] = TRILL__KEYf; 1482 break; 1483 case TH_MPLS_HASH_KEY_TYPE_L2GRE_SIP: 1484 field_list[0] = L2GRE_SIP__KEYf; 1485 break; 1486 case TH_MPLS_HASH_KEY_TYPE_L2GRE_VPNID_SIP: 1487 case TH_MPLS_HASH_KEY_TYPE_L2GRE_VPNID: 1488 field_list[0] = L2GRE_VPNID__KEYf; 1489 break; 1490 case TH_MPLS_HASH_KEY_TYPE_VXLAN_SIP: 1491 field_list[0] = VXLAN_SIP__KEYf; 1492 break; 1493 case TH_MPLS_HASH_KEY_TYPE_VXLAN_VPNID: 1494 case TH_MPLS_HASH_KEY_TYPE_VXLAN_VPNID_SIP: 1495 field_list[0] = VXLAN_VN_ID__KEYf; 1496 break; 1497 default: 1498 return 0; 1499 } 1500 field_list[1] = INVALIDf; 1501 return _soc_th_hash_entry_to_key(unit, bank, entry, key, MPLS_ENTRYm, 1502 field_list); 1503 } 1504 1505 uint32 1506 soc_th_mpls_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1507 { 1508 int key_nbits; 1509 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1510 uint32 index; 1511 1512 sal_memset(key, 0, sizeof(key)); 1513 1514 key_nbits = soc_th_mpls_base_entry_to_key(unit, bank, entry, key); 1515 index = soc_th_mpls_hash(unit, hash_sel, key_nbits, entry, key); 1516 1517 return index; 1518 } 1519 1520 uint32 1521 soc_th_mpls_bank_entry_hash(int unit, int bank, uint32 *entry) 1522 { 1523 int rv, hash_sel; 1524 1525 rv = soc_th_hash_sel_get(unit, MPLS_ENTRYm, bank, &hash_sel); 1526 if (SOC_FAILURE(rv)) { 1527 return 0; 1528 } 1529 1530 return soc_th_mpls_entry_hash(unit, hash_sel, bank, entry); 1531 } 1532 1533 uint32 1534 soc_th_vlan_xlate_hash(int unit, int hash_sel, int key_nbits, 1535 void *base_entry, uint8 *key) 1536 { 1537 uint32 rv = 0; 1538 1539 /* 1540 * Cache bucket mask and shift amount for upper crc 1541 */ 1542 if (SOC_CONTROL(unit)->hash_mask_vlan_mac == 0) { 1543 uint32 mask; 1544 int bits; 1545 1546 /* 8 Entries per bucket */ 1547 mask = soc_mem_index_max(unit, VLAN_MACm) >> 3; 1548 bits = 0; 1549 rv = 1; 1550 while (rv && (mask & rv)) { 1551 bits += 1; 1552 rv <<= 1; 1553 } 1554 SOC_CONTROL(unit)->hash_mask_vlan_mac = mask; 1555 SOC_CONTROL(unit)->hash_bits_vlan_mac = bits; 1556 } 1557 1558 switch (hash_sel) { 1559 case FB_HASH_CRC16_UPPER: 1560 rv = soc_crc16b(key, key_nbits); 1561 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_vlan_mac; 1562 break; 1563 1564 case FB_HASH_CRC16_LOWER: 1565 rv = soc_crc16b(key, key_nbits); 1566 break; 1567 1568 case FB_HASH_LSB: 1569 if (key_nbits == 0) { 1570 return 0; 1571 } 1572 switch (soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1573 KEY_TYPEf)) { 1574 case TH_VLXLT_HASH_KEY_TYPE_IVID_OVID: 1575 case TH_VLXLT_HASH_KEY_TYPE_OTAG: 1576 case TH_VLXLT_HASH_KEY_TYPE_ITAG: 1577 case TH_VLXLT_HASH_KEY_TYPE_OVID: 1578 case TH_VLXLT_HASH_KEY_TYPE_IVID: 1579 case TH_VLXLT_HASH_KEY_TYPE_PRI_CFI: 1580 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1581 XLATE__HASH_LSBf); 1582 break; 1583 case TH_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 1584 rv = soc_mem_field32_get(unit, VLAN_MACm, base_entry, 1585 MAC__HASH_LSBf); 1586 break; 1587 case TH_VLXLT_HASH_KEY_TYPE_HPAE: 1588 rv = soc_mem_field32_get(unit, VLAN_MACm, base_entry, 1589 MAC_IP_BIND__HASH_LSBf); 1590 break; 1591 case TH_VLXLT_HASH_KEY_TYPE_VIF: 1592 case TH_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 1593 case TH_VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 1594 case TH_VLXLT_HASH_KEY_TYPE_VIF_OTAG: 1595 case TH_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 1596 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1597 VIF__HASH_LSBf); 1598 break; 1599 case TH_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 1600 rv = soc_mem_field32_get(unit, VLAN_MACm, base_entry, 1601 MAC_PORT__HASH_LSBf); 1602 break; 1603 case TH_VLXLT_HASH_KEY_TYPE_L2GRE_DIP: 1604 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1605 L2GRE_DIP__HASH_LSBf); 1606 break; 1607 case TH_VLXLT_HASH_KEY_TYPE_VXLAN_DIP: 1608 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1609 VXLAN_DIP__HASH_LSBf); 1610 break; 1611 default: 1612 rv = 0; 1613 break; 1614 } 1615 break; 1616 1617 case FB_HASH_ZERO: 1618 rv = 0; 1619 break; 1620 1621 case FB_HASH_CRC32_UPPER: 1622 rv = soc_crc32b(key, key_nbits); 1623 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_vlan_mac; 1624 break; 1625 1626 case FB_HASH_CRC32_LOWER: 1627 rv = soc_crc32b(key, key_nbits); 1628 break; 1629 1630 default: 1631 LOG_ERROR(BSL_LS_SOC_HASH, 1632 (BSL_META_U(unit, 1633 "soc_th_vlan_xlate_hash: invalid hash_sel %d\n"), 1634 hash_sel)); 1635 rv = 0; 1636 break; 1637 } 1638 1639 return rv & SOC_CONTROL(unit)->hash_mask_vlan_mac; 1640 } 1641 1642 int 1643 soc_th_vlan_xlate_base_entry_to_key(int unit, int bank, void *entry, uint8 *key) 1644 { 1645 soc_mem_t mem; 1646 soc_field_t field_list[2]; 1647 1648 switch (soc_mem_field32_get(unit, VLAN_XLATEm, entry, KEY_TYPEf)) { 1649 case TH_VLXLT_HASH_KEY_TYPE_IVID_OVID: 1650 case TH_VLXLT_HASH_KEY_TYPE_OTAG: 1651 case TH_VLXLT_HASH_KEY_TYPE_ITAG: 1652 case TH_VLXLT_HASH_KEY_TYPE_OVID: 1653 case TH_VLXLT_HASH_KEY_TYPE_IVID: 1654 case TH_VLXLT_HASH_KEY_TYPE_PRI_CFI: 1655 mem = VLAN_XLATEm; 1656 field_list[0] = XLATE__KEYf; 1657 break; 1658 case TH_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 1659 mem = VLAN_MACm; 1660 field_list[0] = MAC__KEYf; 1661 break; 1662 case TH_VLXLT_HASH_KEY_TYPE_HPAE: 1663 mem = VLAN_MACm; 1664 field_list[0] = MAC_IP_BIND__KEYf; 1665 break; 1666 case TH_VLXLT_HASH_KEY_TYPE_VIF: 1667 case TH_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 1668 case TH_VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 1669 case TH_VLXLT_HASH_KEY_TYPE_VIF_OTAG: 1670 case TH_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 1671 mem = VLAN_XLATEm; 1672 field_list[0] = VIF__KEYf; 1673 break; 1674 case TH_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 1675 mem = VLAN_MACm; 1676 field_list[0] = MAC_PORT__KEYf; 1677 break; 1678 case TH_VLXLT_HASH_KEY_TYPE_L2GRE_DIP: 1679 mem = VLAN_XLATEm; 1680 field_list[0] = L2GRE_DIP__KEYf; 1681 break; 1682 case TH_VLXLT_HASH_KEY_TYPE_VXLAN_DIP: 1683 mem = VLAN_XLATEm; 1684 field_list[0] = VXLAN_DIP__KEYf; 1685 break; 1686 default: 1687 return 0; 1688 } 1689 field_list[1] = INVALIDf; 1690 return _soc_th_hash_entry_to_key(unit, bank, entry, key, mem, field_list); 1691 } 1692 1693 uint32 1694 soc_th_vlan_xlate_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1695 { 1696 int key_nbits; 1697 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1698 uint32 index; 1699 1700 sal_memset(key, 0, sizeof(key)); 1701 key_nbits = soc_th_vlan_xlate_base_entry_to_key(unit, bank, entry, key); 1702 index = soc_th_vlan_xlate_hash(unit, hash_sel, key_nbits, entry, key); 1703 1704 return index; 1705 } 1706 1707 uint32 1708 soc_th_vlan_xlate_bank_entry_hash(int unit, int bank, uint32 *entry) 1709 { 1710 int rv, hash_sel; 1711 1712 rv = soc_th_hash_sel_get(unit, VLAN_XLATEm, bank, &hash_sel); 1713 if (SOC_FAILURE(rv)) { 1714 return 0; 1715 } 1716 1717 return soc_th_vlan_xlate_entry_hash(unit, hash_sel, bank, entry); 1718 } 1719 1720 uint32 1721 soc_th_egr_vlan_xlate_hash(int unit, int hash_sel, int key_nbits, 1722 void *base_entry, uint8 *key) 1723 { 1724 uint32 rv; 1725 1726 /* 1727 * Cache bucket mask and shift amount for upper crc 1728 */ 1729 if (SOC_CONTROL(unit)->hash_mask_egr_vlan_xlate == 0) { 1730 uint32 mask; 1731 int bits; 1732 1733 /* 8 Entries per bucket */ 1734 mask = soc_mem_index_max(unit, EGR_VLAN_XLATEm) >> 3; 1735 bits = 0; 1736 rv = 1; 1737 while (rv && (mask & rv)) { 1738 bits += 1; 1739 rv <<= 1; 1740 } 1741 SOC_CONTROL(unit)->hash_mask_egr_vlan_xlate = mask; 1742 SOC_CONTROL(unit)->hash_bits_egr_vlan_xlate = bits; 1743 } 1744 1745 switch (hash_sel) { 1746 case FB_HASH_CRC16_UPPER: 1747 rv = soc_crc16b(key, key_nbits); 1748 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_egr_vlan_xlate; 1749 break; 1750 1751 case FB_HASH_CRC16_LOWER: 1752 rv = soc_crc16b(key, key_nbits); 1753 break; 1754 1755 case FB_HASH_LSB: 1756 if (key_nbits == 0) { 1757 return 0; 1758 } 1759 switch (soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 1760 ENTRY_TYPEf)) { 1761 case TH_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE: 1762 case TH_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_DVP: 1763 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 1764 XLATE__HASH_LSBf); 1765 break; 1766 case TH_EVLXLT_HASH_KEY_TYPE_ISID_XLATE: 1767 case TH_EVLXLT_HASH_KEY_TYPE_ISID_DVP_XLATE: 1768 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 1769 MIM_ISID__HASH_LSBf); 1770 break; 1771 case TH_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI: 1772 case TH_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI_DVP: 1773 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 1774 L2GRE_VFI__HASH_LSBf); 1775 break; 1776 case TH_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI: 1777 case TH_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI_DVP: 1778 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 1779 VXLAN_VFI__HASH_LSBf); 1780 break; 1781 default: 1782 rv = 0; 1783 break; 1784 } 1785 break; 1786 1787 case FB_HASH_ZERO: 1788 rv = 0; 1789 break; 1790 1791 case FB_HASH_CRC32_UPPER: 1792 rv = soc_crc32b(key, key_nbits); 1793 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_egr_vlan_xlate; 1794 break; 1795 1796 case FB_HASH_CRC32_LOWER: 1797 rv = soc_crc32b(key, key_nbits); 1798 break; 1799 1800 default: 1801 LOG_ERROR(BSL_LS_SOC_HASH, 1802 (BSL_META_U(unit, 1803 "soc_th_egr_vlan_xlate_hash: invalid hash_sel %d\n"), 1804 hash_sel)); 1805 rv = 0; 1806 break; 1807 } 1808 1809 return rv & SOC_CONTROL(unit)->hash_mask_egr_vlan_xlate; 1810 } 1811 1812 int 1813 soc_th_egr_vlan_xlate_base_entry_to_key(int unit, int bank, void *entry, uint8 *key) 1814 { 1815 soc_field_t field_list[2]; 1816 1817 switch (soc_mem_field32_get(unit, EGR_VLAN_XLATEm, entry, ENTRY_TYPEf)) { 1818 case TH_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE: 1819 case TH_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_DVP: 1820 field_list[0] = XLATE__KEYf; 1821 break; 1822 case TH_EVLXLT_HASH_KEY_TYPE_ISID_XLATE: 1823 case TH_EVLXLT_HASH_KEY_TYPE_ISID_DVP_XLATE: 1824 field_list[0] = MIM_ISID__KEYf; 1825 break; 1826 case TH_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI: 1827 case TH_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI_DVP: 1828 field_list[0] = L2GRE_VFI__KEYf; 1829 break; 1830 case TH_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI: 1831 case TH_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI_DVP: 1832 field_list[0] = VXLAN_VFI__KEYf; 1833 break; 1834 default: 1835 return 0; 1836 } 1837 field_list[1] = INVALIDf; 1838 return _soc_th_hash_entry_to_key(unit, bank, entry, key, EGR_VLAN_XLATEm, 1839 field_list); 1840 } 1841 1842 uint32 1843 soc_th_egr_vlan_xlate_entry_hash(int unit, int hash_sel, int bank, 1844 uint32 *entry) 1845 { 1846 int key_nbits; 1847 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1848 uint32 index; 1849 1850 sal_memset(key, 0, sizeof(key)); 1851 1852 key_nbits = soc_th_egr_vlan_xlate_base_entry_to_key(unit, bank, entry, key); 1853 index = soc_th_egr_vlan_xlate_hash(unit, hash_sel, key_nbits, entry, key); 1854 1855 return index; 1856 } 1857 1858 uint32 1859 soc_th_egr_vlan_xlate_bank_entry_hash(int unit, int bank, uint32 *entry) 1860 { 1861 int rv, hash_sel; 1862 1863 rv = soc_th_hash_sel_get(unit, EGR_VLAN_XLATEm, bank, &hash_sel); 1864 if (SOC_FAILURE(rv)) { 1865 return 0; 1866 } 1867 1868 return soc_th_egr_vlan_xlate_entry_hash(unit, hash_sel, bank, entry); 1869 } 1870 1871 uint32 1872 soc_th_ing_vp_vlan_member_hash(int unit, int hash_sel, int key_nbits, 1873 void *base_entry, uint8 *key) 1874 { 1875 uint32 rv; 1876 1877 /* 1878 * Cache bucket mask and shift amount for upper crc 1879 */ 1880 if (SOC_CONTROL(unit)->hash_mask_ing_vp_vlan_member == 0) { 1881 uint32 mask; 1882 int bits; 1883 1884 /* 8 Entries per bucket */ 1885 mask = soc_mem_index_max(unit, ING_VP_VLAN_MEMBERSHIPm) >> 3; 1886 bits = 0; 1887 rv = 1; 1888 while (rv && (mask & rv)) { 1889 bits += 1; 1890 rv <<= 1; 1891 } 1892 SOC_CONTROL(unit)->hash_mask_ing_vp_vlan_member = mask; 1893 SOC_CONTROL(unit)->hash_bits_ing_vp_vlan_member = bits; 1894 } 1895 1896 switch (hash_sel) { 1897 case FB_HASH_CRC16_UPPER: 1898 rv = soc_crc16b(key, key_nbits); 1899 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_ing_vp_vlan_member; 1900 break; 1901 1902 case FB_HASH_CRC16_LOWER: 1903 rv = soc_crc16b(key, key_nbits); 1904 break; 1905 1906 case FB_HASH_LSB: 1907 if (key_nbits == 0) { 1908 return 0; 1909 } 1910 rv = soc_mem_field32_get(unit, ING_VP_VLAN_MEMBERSHIPm, base_entry, 1911 HASH_LSBf); 1912 break; 1913 1914 case FB_HASH_ZERO: 1915 rv = 0; 1916 break; 1917 1918 case FB_HASH_CRC32_UPPER: 1919 rv = soc_crc32b(key, key_nbits); 1920 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_ing_vp_vlan_member; 1921 break; 1922 1923 case FB_HASH_CRC32_LOWER: 1924 rv = soc_crc32b(key, key_nbits); 1925 break; 1926 1927 default: 1928 LOG_ERROR(BSL_LS_SOC_HASH, 1929 (BSL_META_U(unit, 1930 "soc_th_inv_vp_vlan_member_hash: invalid hash_sel %d\n"), 1931 hash_sel)); 1932 rv = 0; 1933 break; 1934 } 1935 1936 return rv & SOC_CONTROL(unit)->hash_mask_ing_vp_vlan_member; 1937 } 1938 1939 int 1940 soc_th_ing_vp_vlan_member_base_entry_to_key(int unit, int bank, void *entry, uint8 *key) 1941 { 1942 static soc_field_t field_list[] = { 1943 KEYf, 1944 INVALIDf 1945 }; 1946 1947 return _soc_th_hash_entry_to_key(unit, bank, entry, key, 1948 ING_VP_VLAN_MEMBERSHIPm, field_list); 1949 } 1950 1951 uint32 1952 soc_th_ing_vp_vlan_member_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1953 { 1954 int key_nbits; 1955 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1956 uint32 index; 1957 1958 key_nbits = soc_th_ing_vp_vlan_member_base_entry_to_key(unit, bank, entry, key); 1959 index = soc_th_ing_vp_vlan_member_hash(unit, hash_sel, key_nbits, entry, 1960 key); 1961 1962 return index; 1963 } 1964 1965 uint32 1966 soc_th_ing_vp_vlan_member_bank_entry_hash(int unit, int bank, uint32 *entry) 1967 { 1968 int rv, hash_sel; 1969 1970 rv = soc_th_hash_sel_get(unit, ING_VP_VLAN_MEMBERSHIPm, bank, &hash_sel); 1971 if (SOC_FAILURE(rv)) { 1972 return 0; 1973 } 1974 1975 return soc_th_ing_vp_vlan_member_entry_hash(unit, hash_sel, bank, entry); 1976 } 1977 1978 uint32 1979 soc_th_egr_vp_vlan_member_hash(int unit, int hash_sel, int key_nbits, 1980 void *base_entry, uint8 *key) 1981 { 1982 uint32 rv; 1983 1984 /* 1985 * Cache bucket mask and shift amount for upper crc 1986 */ 1987 if (SOC_CONTROL(unit)->hash_mask_egr_vp_vlan_member == 0) { 1988 uint32 mask; 1989 int bits; 1990 1991 /* 8 Entries per bucket */ 1992 mask = soc_mem_index_max(unit, EGR_VP_VLAN_MEMBERSHIPm) >> 3; 1993 bits = 0; 1994 rv = 1; 1995 while (rv && (mask & rv)) { 1996 bits += 1; 1997 rv <<= 1; 1998 } 1999 SOC_CONTROL(unit)->hash_mask_egr_vp_vlan_member = mask; 2000 SOC_CONTROL(unit)->hash_bits_egr_vp_vlan_member = bits; 2001 } 2002 2003 switch (hash_sel) { 2004 case FB_HASH_CRC16_UPPER: 2005 rv = soc_crc16b(key, key_nbits); 2006 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_egr_vp_vlan_member; 2007 break; 2008 2009 case FB_HASH_CRC16_LOWER: 2010 rv = soc_crc16b(key, key_nbits); 2011 break; 2012 2013 case FB_HASH_LSB: 2014 if (key_nbits == 0) { 2015 return 0; 2016 } 2017 rv = soc_mem_field32_get(unit, EGR_VP_VLAN_MEMBERSHIPm, base_entry, 2018 HASH_LSBf); 2019 break; 2020 2021 case FB_HASH_ZERO: 2022 rv = 0; 2023 break; 2024 2025 case FB_HASH_CRC32_UPPER: 2026 rv = soc_crc32b(key, key_nbits); 2027 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_egr_vp_vlan_member; 2028 break; 2029 2030 case FB_HASH_CRC32_LOWER: 2031 rv = soc_crc32b(key, key_nbits); 2032 break; 2033 2034 default: 2035 LOG_ERROR(BSL_LS_SOC_HASH, 2036 (BSL_META_U(unit, 2037 "soc_th_inv_vp_vlan_member_hash: invalid hash_sel %d\n"), 2038 hash_sel)); 2039 rv = 0; 2040 break; 2041 } 2042 2043 return rv & SOC_CONTROL(unit)->hash_mask_egr_vp_vlan_member; 2044 } 2045 2046 int 2047 soc_th_egr_vp_vlan_member_base_entry_to_key(int unit, int bank, void *entry, uint8 *key) 2048 { 2049 static soc_field_t field_list[] = { 2050 KEYf, 2051 INVALIDf 2052 }; 2053 2054 return _soc_th_hash_entry_to_key(unit, bank, entry, key, 2055 EGR_VP_VLAN_MEMBERSHIPm, field_list); 2056 } 2057 2058 uint32 2059 soc_th_egr_vp_vlan_member_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 2060 { 2061 int key_nbits; 2062 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2063 uint32 index; 2064 2065 key_nbits = soc_th_egr_vp_vlan_member_base_entry_to_key(unit, bank, entry, key); 2066 index = soc_th_egr_vp_vlan_member_hash(unit, hash_sel, key_nbits, entry, 2067 key); 2068 2069 return index; 2070 } 2071 2072 uint32 2073 soc_th_egr_vp_vlan_member_bank_entry_hash(int unit, int bank, uint32 *entry) 2074 { 2075 int rv, hash_sel; 2076 2077 rv = soc_th_hash_sel_get(unit, EGR_VP_VLAN_MEMBERSHIPm, bank, &hash_sel); 2078 if (SOC_FAILURE(rv)) { 2079 return 0; 2080 } 2081 2082 return soc_th_egr_vp_vlan_member_entry_hash(unit, hash_sel, bank, entry); 2083 } 2084 2085 uint32 2086 soc_th_ing_dnat_address_type_hash(int unit, int hash_sel, int key_nbits, 2087 void *base_entry, uint8 *key) 2088 { 2089 uint32 rv; 2090 2091 /* 2092 * Cache bucket mask and shift amount for upper crc 2093 */ 2094 if (SOC_CONTROL(unit)->hash_mask_ing_dnat_address_type == 0) { 2095 uint32 mask; 2096 int bits; 2097 2098 /* 8 Entries per bucket */ 2099 mask = soc_mem_index_max(unit, ING_DNAT_ADDRESS_TYPEm) >> 3; 2100 bits = 0; 2101 rv = 1; 2102 while (rv && (mask & rv)) { 2103 bits += 1; 2104 rv <<= 1; 2105 } 2106 SOC_CONTROL(unit)->hash_mask_ing_dnat_address_type = mask; 2107 SOC_CONTROL(unit)->hash_bits_ing_dnat_address_type = bits; 2108 } 2109 2110 switch (hash_sel) { 2111 case FB_HASH_CRC16_UPPER: 2112 rv = soc_crc16b(key, key_nbits); 2113 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_ing_dnat_address_type; 2114 break; 2115 2116 case FB_HASH_CRC16_LOWER: 2117 rv = soc_crc16b(key, key_nbits); 2118 break; 2119 2120 case FB_HASH_LSB: 2121 if (key_nbits == 0) { 2122 return 0; 2123 } 2124 rv = soc_mem_field32_get(unit, ING_DNAT_ADDRESS_TYPEm, base_entry, 2125 HASH_LSBf); 2126 break; 2127 2128 case FB_HASH_ZERO: 2129 rv = 0; 2130 break; 2131 2132 case FB_HASH_CRC32_UPPER: 2133 rv = soc_crc32b(key, key_nbits); 2134 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_ing_dnat_address_type; 2135 break; 2136 2137 case FB_HASH_CRC32_LOWER: 2138 rv = soc_crc32b(key, key_nbits); 2139 break; 2140 2141 default: 2142 LOG_ERROR(BSL_LS_SOC_HASH, 2143 (BSL_META_U(unit, 2144 "soc_th_inv_vp_vlan_member_hash: invalid hash_sel %d\n"), 2145 hash_sel)); 2146 rv = 0; 2147 break; 2148 } 2149 2150 return rv & SOC_CONTROL(unit)->hash_mask_ing_dnat_address_type; 2151 } 2152 2153 int 2154 soc_th_ing_dnat_address_type_base_entry_to_key(int unit, int bank, void *entry, 2155 uint8 *key) 2156 { 2157 static soc_field_t field_list[] = { 2158 KEYf, 2159 INVALIDf 2160 }; 2161 2162 return _soc_th_hash_entry_to_key(unit, bank, entry, key, ING_DNAT_ADDRESS_TYPEm, 2163 field_list); 2164 } 2165 2166 uint32 2167 soc_th_ing_dnat_address_type_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 2168 { 2169 int key_nbits; 2170 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2171 uint32 index; 2172 2173 key_nbits = soc_th_ing_dnat_address_type_base_entry_to_key(unit, bank, 2174 entry, key); 2175 index = soc_th_ing_dnat_address_type_hash(unit, hash_sel, key_nbits, 2176 entry, key); 2177 2178 return index; 2179 } 2180 2181 uint32 2182 soc_th_ing_dnat_address_type_bank_entry_hash(int unit, int bank, uint32 *entry) 2183 { 2184 int rv, hash_sel; 2185 2186 rv = soc_th_hash_sel_get(unit, ING_DNAT_ADDRESS_TYPEm, bank, &hash_sel); 2187 if (SOC_FAILURE(rv)) { 2188 return 0; 2189 } 2190 2191 return soc_th_ing_dnat_address_type_entry_hash(unit, hash_sel, bank, entry); 2192 } 2193 2194 #endif /* BCM_TOMAHAWK_SUPPORT */