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