hash.c (43936B)
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: Apache 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_APACHE_SUPPORT) 20 21 #include <soc/apache.h> 22 #include <soc/trident2.h> 23 #include <soc/bondoptions.h> 24 25 /* Get number of banks for the hash table according to the config */ 26 int 27 soc_apache_hash_bank_count_get(int unit, soc_mem_t mem, int *num_banks) 28 { 29 int count; 30 31 int shared_bank_size = 64; 32 #if defined(BCM_MONTEREY_SUPPORT) 33 if (SOC_IS_MONTEREY(unit)) { 34 shared_bank_size = 0; 35 } 36 else 37 #endif 38 if (soc_feature(unit, soc_feature_untethered_otp)) { 39 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureUft128k)) { 40 shared_bank_size = 32; 41 } 42 } 43 switch (mem) { 44 case L2Xm: 45 /* 46 * 8k entries in each of 2 dedicated L2 bank 47 * 64k entries in each shared bank 48 */ 49 count = soc_mem_index_count(unit, L2Xm); 50 if (SOC_IS_MONTEREY(unit)) { 51 *num_banks = 2; 52 } else { 53 *num_banks = 2 + (count - 2 * 8 * 1024) / (shared_bank_size * 1024); 54 } 55 break; 56 case L3_ENTRY_ONLYm: 57 case L3_ENTRY_IPV4_UNICASTm: 58 case L3_ENTRY_IPV4_MULTICASTm: 59 case L3_ENTRY_IPV6_UNICASTm: 60 case L3_ENTRY_IPV6_MULTICASTm: 61 /* 62 * 1k entries in each of 4 dedicated L3 bank 63 * 64k entries in each shared bank 64 */ 65 count = soc_mem_index_count(unit, L3_ENTRY_ONLYm); 66 #if defined(BCM_MONTEREY_SUPPORT) 67 if (SOC_IS_MONTEREY(unit)) { 68 *num_banks = 4; 69 } else 70 #endif 71 { 72 *num_banks = 4 + (count - 4 * 1 * 1024) / (shared_bank_size * 1024); 73 } 74 break; 75 case MPLS_ENTRYm: 76 case VLAN_XLATEm: 77 case VLAN_MACm: 78 case EGR_VLAN_XLATEm: 79 case ING_VP_VLAN_MEMBERSHIPm: 80 case EGR_VP_VLAN_MEMBERSHIPm: 81 case ING_DNAT_ADDRESS_TYPEm: 82 case L2_ENDPOINT_IDm: 83 case ENDPOINT_QUEUE_MAPm: 84 *num_banks = 2; 85 break; 86 default: 87 return SOC_E_INTERNAL; 88 } 89 90 return SOC_E_NONE; 91 } 92 93 /* Map logical to physical bank mapping for a memory 94 * mem - memory 95 * log_bank - logical bank number (or sequence bank number) 96 * phy_bank_id - Physical bank id 97 */ 98 int 99 soc_apache_log_to_phy_bank_map(int unit, soc_mem_t mem, int log_bank, 100 int *phy_bank_id) 101 { 102 uint32 val; 103 static const soc_field_t l2_fields[] = { 104 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 105 L2_ENTRY_BANK_5f 106 }; 107 static soc_field_t l3_fields[] = { 108 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 109 L3_ENTRY_BANK_7f 110 }; 111 112 switch (mem) { 113 case L2Xm: 114 if (log_bank < 0 || log_bank > 5) { 115 return SOC_E_PARAM; 116 } 117 if (log_bank < 2) { 118 *phy_bank_id = log_bank; 119 } else { 120 SOC_IF_ERROR_RETURN(READ_L2_ISS_LOG_TO_PHY_BANK_MAPr(unit, &val)); 121 /* Starts with 0 in the register which maps to Physical bank 2 */ 122 *phy_bank_id = 2 + soc_reg_field_get(unit, 123 L2_ISS_LOG_TO_PHY_BANK_MAPr, val, 124 l2_fields[log_bank - 2]); 125 } 126 break; 127 case L3_ENTRY_ONLYm: 128 case L3_ENTRY_IPV4_UNICASTm: 129 case L3_ENTRY_IPV4_MULTICASTm: 130 case L3_ENTRY_IPV6_UNICASTm: 131 case L3_ENTRY_IPV6_MULTICASTm: 132 if (log_bank < 0 || log_bank > 7) { 133 return SOC_E_PARAM; 134 } 135 if (log_bank < 4) { 136 *phy_bank_id = 6 + log_bank; /* dedicated banks */ 137 } else { 138 SOC_IF_ERROR_RETURN(READ_L3_ISS_LOG_TO_PHY_BANK_MAPr(unit, &val)); 139 /* Starts with 0 in the register which maps to Physical bank 2 */ 140 *phy_bank_id = 2 + soc_reg_field_get(unit, 141 L3_ISS_LOG_TO_PHY_BANK_MAPr, val, 142 l3_fields[log_bank - 4]); 143 } 144 break; 145 default: 146 *phy_bank_id = log_bank; 147 break; 148 } 149 return SOC_E_NONE; 150 } 151 152 /* Map physical to logical bank mapping for a memory 153 * mem - memory 154 * phy_bank - physical bank number 155 * log_bank - logical bank id 156 */ 157 int 158 soc_apache_phy_to_log_bank_map(int unit, soc_mem_t mem, int phy_bank, int *log_bank) 159 { 160 uint32 val, i; 161 static const soc_field_t l2_fields[] = { 162 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 163 L2_ENTRY_BANK_5f 164 }; 165 static soc_field_t l3_fields[] = { 166 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 167 L3_ENTRY_BANK_7f 168 }; 169 170 switch (mem) { 171 case L2Xm: 172 if (phy_bank < 0 || phy_bank > 5) { 173 return SOC_E_PARAM; 174 } 175 if (phy_bank < 2) { 176 *log_bank = phy_bank; 177 } else { 178 SOC_IF_ERROR_RETURN(READ_L2_ISS_LOG_TO_PHY_BANK_MAPr(unit, &val)); 179 for (i = 0; i < 4; i++) { 180 /* Starts with 0 in the register which maps to Physical bank 2 */ 181 if ((soc_reg_field_get(unit, L2_ISS_LOG_TO_PHY_BANK_MAPr, val, 182 l2_fields[i]) + 2) == phy_bank) { 183 *log_bank = 2 + i; 184 break; 185 } 186 } 187 } 188 break; 189 case L3_ENTRY_ONLYm: 190 case L3_ENTRY_IPV4_UNICASTm: 191 case L3_ENTRY_IPV4_MULTICASTm: 192 case L3_ENTRY_IPV6_UNICASTm: 193 case L3_ENTRY_IPV6_MULTICASTm: 194 if (phy_bank < 2 || phy_bank > 9) { 195 return SOC_E_PARAM; 196 } 197 if (phy_bank > 5) { 198 *log_bank = phy_bank - 6; 199 } else { 200 SOC_IF_ERROR_RETURN(READ_L3_ISS_LOG_TO_PHY_BANK_MAPr(unit, &val)); 201 for (i = 0; i < 4; i++) { 202 /* Starts with 0 in the register which maps to Physical bank 2 */ 203 if ((soc_reg_field_get(unit, L3_ISS_LOG_TO_PHY_BANK_MAPr, val, 204 l3_fields[i]) + 2) == phy_bank) { 205 *log_bank = 4 + i; 206 break; 207 } 208 } 209 } 210 break; 211 default: 212 *log_bank = phy_bank; 213 break; 214 } 215 return SOC_E_NONE; 216 } 217 218 /* Get bank bitmap for the hash table according to the config */ 219 int 220 soc_apache_hash_bank_phy_bitmap_get(int unit, soc_mem_t mem, uint32 *bitmap) 221 { 222 uint32 physical_bitmap = 0; 223 int count = 0; 224 int i, phy_bank_id = 0; 225 SOC_IF_ERROR_RETURN(soc_apache_hash_bank_count_get(unit, mem, &count)); 226 for (i = 0; i < count; i++) { 227 SOC_IF_ERROR_RETURN( 228 soc_apache_log_to_phy_bank_map(unit, mem, i, &phy_bank_id)); 229 physical_bitmap |= (1 << phy_bank_id); 230 } 231 *bitmap = physical_bitmap; 232 return SOC_E_NONE; 233 } 234 235 /* 236 * Map bank sequence number to bank number. 237 * Sequence number: 0 .. (number of bank - 1) 238 * bank number: bank id in hardware 239 * This is only useful for L3 table which has non-sequential bank number, 240 * sequence number equals to bank number for all other tables. 241 */ 242 int 243 soc_apache_hash_bank_number_get(int unit, soc_mem_t mem, int seq_num, 244 int *bank_num) 245 { 246 int count; 247 248 SOC_IF_ERROR_RETURN(soc_apache_hash_bank_count_get(unit, mem, &count)); 249 if (seq_num < 0 || seq_num >= count) { 250 return SOC_E_CONFIG; 251 } 252 SOC_IF_ERROR_RETURN(soc_apache_log_to_phy_bank_map(unit, mem, seq_num, bank_num)); 253 254 return SOC_E_NONE; 255 } 256 257 /* 258 * Map bank number to bank sequence number. 259 * Sequence number: 0 .. (number of bank - 1) 260 * bank number: bank id in hardware 261 * This is only useful for L3 table which has non-sequential bank number, 262 * 263 * L3 seq_num bank_num 264 * 0 6 265 * 1 7 266 * 2 8 267 * 3 9 268 * 4 5 269 * 5 4 270 */ 271 int 272 soc_apache_hash_seq_number_get(int unit, soc_mem_t mem, int bank_num, 273 int *seq_num) 274 { 275 int count; 276 277 SOC_IF_ERROR_RETURN(soc_apache_phy_to_log_bank_map(unit, mem, bank_num, seq_num)); 278 279 SOC_IF_ERROR_RETURN(soc_apache_hash_bank_count_get(unit, mem, &count)); 280 if (*seq_num < 0 || *seq_num >= count) { 281 return SOC_E_INTERNAL; 282 } 283 284 return SOC_E_NONE; 285 286 } 287 288 int 289 soc_apache_hash_bank_info_get(int unit, soc_mem_t mem, int bank, 290 int *entries_per_bank, int *entries_per_row, 291 int *entries_per_bucket, int *bank_base, 292 int *bucket_offset) 293 { 294 int bank_size = 0, row_size = 0, bucket_size = 0, base = 0, offset; 295 int seq_num = 0; 296 297 int shared_bank_size = 65536; 298 299 #if defined(BCM_MONTEREY_SUPPORT) 300 if(SOC_IS_MONTEREY(unit)) { 301 shared_bank_size = 0; 302 } 303 else 304 #endif 305 if (soc_feature(unit, soc_feature_untethered_otp)) { 306 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureUft128k)) { 307 shared_bank_size = 32768; 308 } 309 } 310 311 /* Get logical bank number */ 312 SOC_IF_ERROR_RETURN(soc_apache_phy_to_log_bank_map(unit, mem, bank, &seq_num)); 313 bank = seq_num; 314 315 /* 316 * entry index for bucket b, entry e = 317 * bank_base + b * entries_per_row + bucket_offset + e; 318 */ 319 switch (mem) { 320 case L2Xm: 321 /* 322 * 4 entries per bucket (1 bucket per row) 323 * bank 0: index 0- 8191 (8k entries in dedicated bank 0) 324 * bank 1: index 8192- 16383 (8k entries in dedicated bank 1) 325 * bank 2: index 16384- 81919 (64k entries in shared bank) 326 * bank 3: index 81920-147455 (64k entries in shared bank) 327 * bank 4: index 147456-212991 (64k entries in shared bank) 328 * bank 5: index 212992-278527 (64k entries in shared bank) 329 * each bucket has 4 entries 330 */ 331 row_size = 4; 332 bucket_size = 4; 333 offset = 0; 334 if (bank < 0 || bank > 5) { 335 return SOC_E_INTERNAL; 336 } else if (bank < 2) { /* 4k entries for each dedicated bank */ 337 bank_size = 8192; 338 #if defined(BCM_MONTEREY_SUPPORT) 339 if(SOC_IS_MONTEREY(unit)) { 340 bank_size = 16384; 341 } 342 #endif 343 base = bank * bank_size; 344 } else { /* 64k entries for each shared bank */ 345 bank_size = shared_bank_size; 346 base = 16384 + (bank - 2) * bank_size; 347 } 348 break; 349 case L3_ENTRY_ONLYm: 350 case L3_ENTRY_IPV4_UNICASTm: 351 /* 352 * 4 entries per bucket (1 bucket per row) 353 * bank 0: index 0- 1023 (1k entries in dedicated bank 6) 354 * bank 1: index 1024- 2047 (1k entries in dedicated bank 7) 355 * bank 2: index 2048- 3071 (1k entries in dedicated bank 8) 356 * bank 3: index 3072- 4095 (1k entries in dedicated bank 9) 357 * bank 4: index 4096- 69631 (64k entries in shared bank) 358 * bank 5: index 69632-135167 (64k entries in shared bank) 359 * bank 6: index 135168-200703 (64k entries in shared bank) 360 * bank 7: index 200704-266239 (64k entries in shared bank) 361 * each bucket has 4 entries 362 */ 363 row_size = 4; 364 bucket_size = 4; 365 offset = 0; 366 if (bank < 0 || bank > 7) { 367 return SOC_E_INTERNAL; 368 } else if (bank < 4) { /* 1k entriess for each dedicated bank */ 369 #if defined(BCM_MONTEREY_SUPPORT) 370 if (SOC_IS_MONTEREY(unit)) { 371 bank_size = 2048; 372 } else 373 #endif 374 { 375 bank_size = 1024; 376 } 377 base = bank * bank_size; 378 } else { /* 64k entries for each shared bank */ 379 bank_size = shared_bank_size; 380 base = 4096 + (bank - 4) * bank_size; 381 } 382 break; 383 case L3_ENTRY_IPV4_MULTICASTm: 384 case L3_ENTRY_IPV6_UNICASTm: 385 #if defined(BCM_MONTEREY_SUPPORT) 386 if (SOC_IS_MONTEREY(unit)) { 387 row_size = 2; 388 bucket_size = 2; 389 offset = 0; 390 if (bank < 0 || bank > 7) { 391 return SOC_E_INTERNAL; 392 } else if (bank < 4) { /* 1k entriess for each dedicated bank */ 393 bank_size = 1024; 394 base = bank * bank_size; 395 } else { /* 64k entries for each shared bank */ 396 bank_size = shared_bank_size; 397 base = 4096 + (bank - 4) * bank_size; 398 } 399 } else 400 #endif 401 { 402 row_size = 4; 403 bucket_size = 4; 404 offset = 0; 405 if (bank < 0 || bank > 7) { 406 return SOC_E_INTERNAL; 407 } else if (bank < 4) { /* 1k entriess for each dedicated bank */ 408 bank_size = 1024; 409 base = bank * bank_size; 410 } else { /* 64k entries for each shared bank */ 411 bank_size = shared_bank_size; 412 base = 4096 + (bank - 4) * bank_size; 413 } 414 415 } 416 break; 417 case L3_ENTRY_IPV6_MULTICASTm: 418 #if defined(BCM_MONTEREY_SUPPORT) 419 if (SOC_IS_MONTEREY(unit)) { 420 row_size = 1; 421 bucket_size = 1; 422 offset = 0; 423 if (bank < 0 || bank > 7) { 424 return SOC_E_INTERNAL; 425 } else if (bank < 4) { /* 1k entriess for each dedicated bank */ 426 bank_size = 512; 427 base = bank * bank_size; 428 } 429 } else 430 431 #endif 432 { 433 row_size = 4; 434 bucket_size = 4; 435 offset = 0; 436 if (bank < 0 || bank > 7) { 437 return SOC_E_INTERNAL; 438 } else if (bank < 4) { /* 1k entriess for each dedicated bank */ 439 bank_size = 1024; 440 base = bank * bank_size; 441 } else { /* 64k entries for each shared bank */ 442 bank_size = shared_bank_size; 443 base = 4096 + (bank - 4) * bank_size; 444 } 445 } 446 break; 447 case MPLS_ENTRYm: 448 case VLAN_XLATEm: 449 case VLAN_MACm: 450 case EGR_VLAN_XLATEm: 451 case ING_VP_VLAN_MEMBERSHIPm: 452 case EGR_VP_VLAN_MEMBERSHIPm: 453 case ING_DNAT_ADDRESS_TYPEm: 454 case L2_ENDPOINT_IDm: 455 case ENDPOINT_QUEUE_MAPm: 456 /* 457 * first half of entries in each row are for bank 0 458 * the other half of entries in each row are for bank 1 459 */ 460 bank_size = soc_mem_index_count(unit, mem) / 2; 461 row_size = 8; 462 bucket_size = 4; 463 base = 0; 464 offset = bank * bucket_size; 465 break; 466 default: 467 return SOC_E_INTERNAL; 468 } 469 470 if (entries_per_bank != NULL) { 471 *entries_per_bank = bank_size; 472 } 473 if (entries_per_row != NULL) { 474 *entries_per_row = row_size; 475 } 476 if (entries_per_bucket != NULL) { 477 *entries_per_bucket = bucket_size; 478 } 479 if (bank_base != NULL) { 480 *bank_base = base; 481 } 482 if (bucket_offset != NULL) { 483 *bucket_offset = offset; 484 } 485 return SOC_E_NONE; 486 } 487 488 STATIC int 489 _soc_ap_hash_entry_to_key(int unit, void *entry, uint8 *key, soc_mem_t mem, 490 soc_field_t *field_list) 491 { 492 soc_field_t field; 493 int index, key_index, val_index, fval_index; 494 int right_shift_count, left_shift_count; 495 uint32 val[SOC_MAX_MEM_WORDS], fval[SOC_MAX_MEM_WORDS]; 496 int bits, val_bits, fval_bits; 497 int8 field_length[16]; 498 499 val_bits = 0; 500 for (index = 0; field_list[index] != INVALIDf; index++) { 501 field = field_list[index]; 502 field_length[index] = soc_mem_field_length(unit, mem, field); 503 val_bits += field_length[index]; 504 } 505 506 switch (mem) { 507 case L2Xm: 508 val_bits = soc_mem_field_length(unit, L2Xm, 509 TRILL_NONUC_NETWORK_LONG__KEYf); 510 break; 511 case L3_ENTRY_ONLYm: 512 case L3_ENTRY_IPV4_UNICASTm: 513 case L3_ENTRY_IPV4_MULTICASTm: 514 case L3_ENTRY_IPV6_UNICASTm: 515 val_bits = soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 516 IPV6MC__KEY_0f) + 517 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 518 IPV6MC__KEY_1f) + 519 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 520 IPV6MC__KEY_2f) + 521 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 522 IPV6MC__KEY_3f); 523 break; 524 case VLAN_XLATEm: 525 case VLAN_MACm: 526 val_bits = soc_mem_field_length(unit, VLAN_MACm, MAC_PORT__KEYf); 527 break; 528 case EGR_VLAN_XLATEm: 529 val_bits = soc_mem_field_length(unit, EGR_VLAN_XLATEm, XLATE__KEYf); 530 break; 531 case MPLS_ENTRYm: 532 val_bits = soc_mem_field_length(unit, MPLS_ENTRYm, L2GRE_VPNID__KEYf); 533 break; 534 case L2_ENDPOINT_IDm: 535 val_bits = soc_mem_field_length(unit, L2_ENDPOINT_IDm, L2__KEYf); 536 break; 537 default: 538 break; 539 } 540 541 bits = (val_bits + 7) & ~0x7; 542 val_bits = bits - val_bits; 543 544 sal_memset(val, 0, sizeof(val)); 545 for (index = 0; field_list[index] != INVALIDf; index++) { 546 field = field_list[index]; 547 soc_mem_field_get(unit, mem, entry, field, fval); 548 fval_bits = field_length[index]; 549 550 val_index = val_bits >> 5; 551 fval_index = 0; 552 left_shift_count = val_bits & 0x1f; 553 right_shift_count = 32 - left_shift_count; 554 val_bits += fval_bits; 555 556 if (left_shift_count) { 557 for (; fval_bits > 0; fval_bits -= 32) { 558 val[val_index++] |= fval[fval_index] << left_shift_count; 559 val[val_index] |= fval[fval_index++] >> right_shift_count; 560 } 561 } else { 562 for (; fval_bits > 0; fval_bits -= 32) { 563 val[val_index++] = fval[fval_index++]; 564 } 565 } 566 } 567 568 key_index = 0; 569 for (val_index = 0; val_bits > 0; val_index++) { 570 for (right_shift_count = 0; right_shift_count < 32; 571 right_shift_count += 8) { 572 if (val_bits <= 0) { 573 break; 574 } 575 key[key_index++] = (val[val_index] >> right_shift_count) & 0xff; 576 val_bits -= 8; 577 } 578 } 579 580 if ((bits + 7) / 8 > key_index) { 581 sal_memset(&key[key_index], 0, (bits + 7) / 8 - key_index); 582 } 583 584 return bits; 585 } 586 587 588 /* For UFT style hash (L2 and L3 table) */ 589 int 590 soc_ap_hash_offset_get(int unit, soc_mem_t mem, int bank, int *hash_offset, 591 int *use_lsb) 592 { 593 uint32 rval; 594 int is_shared = 0; 595 soc_reg_t reg; 596 soc_field_t field; 597 static const soc_field_t l2_fields[] = { 598 BANK0_HASH_OFFSETf, BANK1_HASH_OFFSETf, BANK2_HASH_OFFSETf, 599 BANK3_HASH_OFFSETf, BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf 600 }; 601 static const soc_field_t l3_fields[] = { 602 BANK6_HASH_OFFSETf, BANK7_HASH_OFFSETf, BANK8_HASH_OFFSETf, 603 BANK9_HASH_OFFSETf, BANK2_HASH_OFFSETf, BANK3_HASH_OFFSETf, 604 BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf 605 }; 606 607 if (mem == L2Xm) { 608 if (bank < 0 || bank > 5) { 609 return SOC_E_PARAM; 610 } 611 is_shared = bank > 1; 612 reg = L2_TABLE_HASH_CONTROLr; 613 field = l2_fields[bank]; 614 } else if (mem == L3_ENTRY_ONLYm) { 615 if (bank < 2 || bank > 9) { 616 return SOC_E_PARAM; 617 } 618 if (bank >= 6 && bank <= 9) { /* Dedicated banks */ 619 bank = bank - 6; 620 } else if (bank >= 2 && bank <= 5) { /* Shared Banks */ 621 bank = 2 + bank; 622 is_shared = 1; 623 } 624 reg = L3_TABLE_HASH_CONTROLr; 625 field = l3_fields[bank]; 626 } else { 627 return SOC_E_INTERNAL; 628 } 629 630 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 631 *use_lsb = soc_reg_field_get(unit, reg, rval, HASH_ZERO_OR_LSBf); 632 633 if (is_shared) { 634 reg = SHARED_TABLE_HASH_CONTROLr; 635 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 636 } 637 638 *hash_offset = soc_reg_field_get(unit, reg, rval, field); 639 640 return SOC_E_NONE; 641 } 642 643 int 644 soc_ap_hash_offset_set(int unit, soc_mem_t mem, int bank, int hash_offset, 645 int use_lsb) 646 { 647 uint32 rval; 648 int is_shared = 0; 649 soc_reg_t reg; 650 soc_field_t field; 651 static const soc_field_t l2_fields[] = { 652 BANK0_HASH_OFFSETf, BANK1_HASH_OFFSETf, BANK2_HASH_OFFSETf, 653 BANK3_HASH_OFFSETf, BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf 654 }; 655 static const soc_field_t l3_fields[] = { 656 BANK6_HASH_OFFSETf, BANK7_HASH_OFFSETf, BANK8_HASH_OFFSETf, 657 BANK9_HASH_OFFSETf, BANK2_HASH_OFFSETf, BANK3_HASH_OFFSETf, 658 BANK4_HASH_OFFSETf, BANK5_HASH_OFFSETf 659 }; 660 661 if (mem == L2Xm) { 662 if (bank < 0 || bank > 5) { 663 return SOC_E_PARAM; 664 } 665 is_shared = bank > 1; 666 reg = L2_TABLE_HASH_CONTROLr; 667 field = l2_fields[bank]; 668 } else if (mem == L3_ENTRY_ONLYm) { 669 if (bank < 2 || bank > 9) { 670 return SOC_E_PARAM; 671 } 672 if (bank >= 6 && bank <= 9) { /* Dedicated banks */ 673 bank = bank - 6; 674 } else if (bank >= 2 && bank <= 5) { /* Shared Banks */ 675 bank = 2 + bank; 676 is_shared = 1; 677 } 678 reg = L3_TABLE_HASH_CONTROLr; 679 field = l3_fields[bank]; 680 } else { 681 return SOC_E_INTERNAL; 682 } 683 684 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 685 soc_reg_field_set(unit, reg, &rval, HASH_ZERO_OR_LSBf, use_lsb); 686 if (!is_shared) { 687 soc_reg_field_set(unit, reg, &rval, field, hash_offset); 688 } 689 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 690 691 if (is_shared) { 692 reg = SHARED_TABLE_HASH_CONTROLr; 693 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 694 soc_reg_field_set(unit, reg, &rval, field, hash_offset); 695 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 696 } 697 return SOC_E_NONE; 698 } 699 700 STATIC int 701 _soc_ap_shared_hash(int unit, int hash_offset, uint32 key_nbits, uint8 *key, 702 uint32 result_mask, uint16 lsb) 703 { 704 uint32 crc_hi, crc_lo; 705 706 if (hash_offset >= 48) { 707 if (hash_offset > 48) { 708 lsb >>= hash_offset - 48; 709 } 710 return lsb & result_mask; 711 } 712 713 crc_hi = soc_crc16b(key, key_nbits) | ((uint32)lsb << 16); 714 if (hash_offset >= 32) { 715 if (hash_offset > 32) { 716 crc_hi >>= hash_offset - 32; 717 } 718 return crc_hi & result_mask; 719 } 720 721 crc_lo = soc_crc32b(key, key_nbits); 722 if (hash_offset > 0) { 723 crc_lo >>= hash_offset; 724 crc_lo |= crc_hi << (32 - hash_offset); 725 } 726 return crc_lo & result_mask; 727 } 728 729 uint32 730 soc_ap_l2x_hash(int unit, int bank, int hash_offset, int use_lsb, 731 int key_nbits, void *base_entry, uint8 *key) 732 { 733 uint32 lsb_val; 734 uint32 hash_mask; 735 uint32 hash_bits; 736 737 if (bank < 2) { 738 739 #if defined(BCM_MONTEREY_SUPPORT) 740 if (SOC_IS_MONTEREY(unit)) { 741 hash_mask = 0x0fff; /* 4k buckets per dedicated L2 bank */ 742 } else 743 #endif 744 { 745 hash_mask = 0x07ff; /* 2k buckets per dedicated L2 bank */ 746 } 747 hash_bits = 11; 748 } else { 749 hash_mask = 0x3fff; /*16k buckets per shared bank */ 750 hash_bits = 14; 751 } 752 753 if (use_lsb && (hash_offset + hash_bits > 48)) { 754 switch (soc_mem_field32_get(unit, L2Xm, base_entry, KEY_TYPEf)) { 755 case TD2_L2_HASH_KEY_TYPE_BRIDGE: 756 case TD2_L2_HASH_KEY_TYPE_VFI: 757 case TD2_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 758 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 759 L2__HASH_LSBf); 760 break; 761 case TD2_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 762 case TD2_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 763 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 764 VLAN__HASH_LSBf); 765 break; 766 case TD2_L2_HASH_KEY_TYPE_VIF: 767 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 768 VIF__HASH_LSBf); 769 break; 770 case TD2_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 771 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 772 TRILL_NONUC_NETWORK_LONG__HASH_LSBf); 773 break; 774 case TD2_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 775 lsb_val = soc_mem_field32_get 776 (unit, L2Xm, base_entry, TRILL_NONUC_NETWORK_SHORT__HASH_LSBf); 777 break; 778 case TD2_L2_HASH_KEY_TYPE_BFD: 779 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 780 BFD__HASH_LSBf); 781 break; 782 case TD2_L2_HASH_KEY_TYPE_PE_VID: 783 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 784 PE_VID__HASH_LSBf); 785 break; 786 case TD2_L2_HASH_KEY_TYPE_FCOE_ZONE: 787 lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry, 788 FCOE_ZONE__HASH_LSBf); 789 break; 790 default: 791 lsb_val = 0; 792 break; 793 } 794 } else { 795 lsb_val = 0; 796 } 797 798 return _soc_ap_shared_hash(unit, hash_offset, key_nbits, key, hash_mask, 799 lsb_val); 800 } 801 802 int 803 soc_ap_l2x_base_entry_to_key(int unit, uint32 *entry, uint8 *key) 804 { 805 soc_field_t field_list[2]; 806 807 switch (soc_mem_field32_get(unit, L2Xm, entry, KEY_TYPEf)) { 808 case TD2_L2_HASH_KEY_TYPE_BRIDGE: 809 case TD2_L2_HASH_KEY_TYPE_VFI: 810 case TD2_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 811 field_list[0] = L2__KEYf; 812 break; 813 case TD2_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 814 case TD2_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 815 field_list[0] = VLAN__KEYf; 816 break; 817 case TD2_L2_HASH_KEY_TYPE_VIF: 818 field_list[0] = VIF__KEYf; 819 break; 820 case TD2_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 821 field_list[0] = TRILL_NONUC_NETWORK_LONG__KEYf; 822 break; 823 case TD2_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 824 field_list[0] = TRILL_NONUC_NETWORK_SHORT__KEYf; 825 break; 826 case TD2_L2_HASH_KEY_TYPE_BFD: 827 field_list[0] = BFD__KEYf; 828 break; 829 case TD2_L2_HASH_KEY_TYPE_PE_VID: 830 field_list[0] = PE_VID__KEYf; 831 break; 832 case TD2_L2_HASH_KEY_TYPE_FCOE_ZONE: 833 field_list[0] = FCOE_ZONE__KEYf; 834 break; 835 default: 836 return 0; 837 } 838 field_list[1] = INVALIDf; 839 return _soc_ap_hash_entry_to_key(unit, entry, key, L2Xm, field_list); 840 } 841 842 uint32 843 soc_ap_l2x_entry_hash(int unit, int bank, int hash_offset, int use_lsb, 844 uint32 *entry) 845 { 846 int key_nbits; 847 uint8 key[SOC_MAX_MEM_WORDS * 4]; 848 849 key_nbits = soc_ap_l2x_base_entry_to_key(unit, entry, key); 850 return soc_ap_l2x_hash(unit, bank, hash_offset, use_lsb, key_nbits, entry, 851 key); 852 } 853 854 uint32 855 soc_ap_l2x_bank_entry_hash(int unit, int bank, uint32 *entry) 856 { 857 int rv, hash_offset, use_lsb; 858 859 rv = soc_ap_hash_offset_get(unit, L2Xm, bank, &hash_offset, &use_lsb); 860 if (SOC_FAILURE(rv)) { 861 return 0; 862 } 863 864 return soc_ap_l2x_entry_hash(unit, bank, hash_offset, use_lsb, entry); 865 } 866 867 uint32 868 soc_ap_l3x_hash(int unit, int bank, int hash_offset, int use_lsb, 869 int key_nbits, void *base_entry, uint8 *key) 870 { 871 uint32 lsb_val; 872 uint32 hash_mask; 873 uint32 hash_bits; 874 875 if (bank > 5) { 876 #if defined(BCM_MONTEREY_SUPPORT) 877 if (SOC_IS_MONTEREY(unit)) { 878 hash_mask = 0x1ff; /* 256 buckets per dedicated L3 bank */ 879 hash_bits = 9; 880 } else 881 #endif 882 { 883 hash_mask = 0xff; /* 256 buckets per dedicated L3 bank */ 884 hash_bits = 8; 885 } 886 887 } else { 888 hash_mask = 0x3fff; /*16k buckets per shared bank */ 889 hash_bits = 14; 890 } 891 892 if (use_lsb && (hash_offset + hash_bits > 48)) { 893 switch (soc_mem_field32_get(unit, L3_ENTRY_ONLYm, base_entry, 894 KEY_TYPEf)) { 895 case TD2_L3_HASH_KEY_TYPE_V4UC: 896 case TD2_L3_HASH_KEY_TYPE_V4UC_EXT: 897 case TD2_L3_HASH_KEY_TYPE_V4MC: 898 case TD2_L3_HASH_KEY_TYPE_V6UC: 899 case TD2_L3_HASH_KEY_TYPE_V6UC_EXT: 900 case TD2_L3_HASH_KEY_TYPE_V6MC: 901 case TD2_L3_HASH_KEY_TYPE_V4L2MC: 902 case TD2_L3_HASH_KEY_TYPE_V4L2VPMC: 903 case TD2_L3_HASH_KEY_TYPE_V6L2MC: 904 case TD2_L3_HASH_KEY_TYPE_V6L2VPMC: 905 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, 906 base_entry, IPV4UC__HASH_LSBf); 907 break; 908 case TD2_L3_HASH_KEY_TYPE_TRILL: 909 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, 910 base_entry, TRILL__HASH_LSBf); 911 break; 912 case TD2_L3_HASH_KEY_TYPE_FCOE_DOMAIN: 913 case TD2_L3_HASH_KEY_TYPE_FCOE_DOMAIN_EXT: 914 case TD2_L3_HASH_KEY_TYPE_FCOE_HOST: 915 case TD2_L3_HASH_KEY_TYPE_FCOE_HOST_EXT: 916 case TD2_L3_HASH_KEY_TYPE_FCOE_SRC_MAP: 917 case TD2_L3_HASH_KEY_TYPE_FCOE_SRC_MAP_EXT: 918 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, 919 base_entry, FCOE__HASH_LSBf); 920 break; 921 case TD2_L3_HASH_KEY_TYPE_DST_NAT: 922 case TD2_L3_HASH_KEY_TYPE_DST_NAPT: 923 lsb_val = soc_mem_field32_get(unit, L3_ENTRY_IPV4_MULTICASTm, 924 base_entry, NAT__HASH_LSBf); 925 break; 926 default: 927 lsb_val = 0; 928 break; 929 } 930 } else { 931 lsb_val = 0; 932 } 933 934 return _soc_ap_shared_hash(unit, hash_offset, key_nbits, key, hash_mask, 935 lsb_val); 936 } 937 938 939 int 940 soc_ap_l3x_base_entry_to_key(int unit, uint32 *entry, uint8 *key) 941 { 942 soc_mem_t mem; 943 soc_field_t field_list[5]; 944 uint32 entry_words = 0; 945 uint32 sanitized_entry[SOC_MAX_MEM_WORDS] = {0}; 946 void *ptr = NULL; 947 948 ptr = (void *) entry; 949 950 switch (soc_mem_field32_get(unit, L3_ENTRY_ONLYm, entry, KEY_TYPEf)) { 951 case TD2_L3_HASH_KEY_TYPE_V4UC_EXT: 952 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV4_UNICASTm); 953 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(entry_words)); 954 ptr = &sanitized_entry; 955 soc_mem_field32_set(unit, L3_ENTRY_IPV4_UNICASTm, ptr, KEY_TYPEf, 956 TD2_L3_HASH_KEY_TYPE_V4UC); 957 /* fall through */ 958 case TD2_L3_HASH_KEY_TYPE_V4UC: 959 mem = L3_ENTRY_IPV4_UNICASTm; 960 field_list[0] = IPV4UC__KEYf; 961 field_list[1] = INVALIDf; 962 break; 963 case TD2_L3_HASH_KEY_TYPE_V6UC_EXT: 964 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV6_UNICASTm); 965 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(entry_words)); 966 ptr = &sanitized_entry; 967 soc_mem_field32_set(unit, L3_ENTRY_IPV6_UNICASTm, ptr, KEY_TYPE_0f, 968 TD2_L3_HASH_KEY_TYPE_V6UC); 969 /* fall through */ 970 case TD2_L3_HASH_KEY_TYPE_V6UC: 971 mem = L3_ENTRY_IPV6_UNICASTm; 972 field_list[0] = IPV6UC__KEY_0f; 973 field_list[1] = IPV6UC__KEY_1f; 974 field_list[2] = INVALIDf; 975 break; 976 case TD2_L3_HASH_KEY_TYPE_V4MC: 977 case TD2_L3_HASH_KEY_TYPE_V4L2MC: 978 case TD2_L3_HASH_KEY_TYPE_V4L2VPMC: 979 mem = L3_ENTRY_IPV4_MULTICASTm; 980 field_list[0] = IPV4MC__KEY_0f; 981 field_list[1] = IPV4MC__KEY_1f; 982 field_list[2] = INVALIDf; 983 break; 984 case TD2_L3_HASH_KEY_TYPE_V6MC: 985 case TD2_L3_HASH_KEY_TYPE_V6L2MC: 986 case TD2_L3_HASH_KEY_TYPE_V6L2VPMC: 987 mem = L3_ENTRY_IPV6_MULTICASTm; 988 field_list[0] = IPV6MC__KEY_0f; 989 field_list[1] = IPV6MC__KEY_1f; 990 field_list[2] = IPV6MC__KEY_2f; 991 field_list[3] = IPV6MC__KEY_3f; 992 field_list[4] = INVALIDf; 993 break; 994 case TD2_L3_HASH_KEY_TYPE_TRILL: 995 mem = L3_ENTRY_IPV4_UNICASTm; 996 field_list[0] = TRILL__KEYf; 997 field_list[1] = INVALIDf; 998 break; 999 case TD2_L3_HASH_KEY_TYPE_FCOE_DOMAIN_EXT: 1000 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV4_UNICASTm); 1001 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(entry_words)); 1002 ptr = &sanitized_entry; 1003 soc_mem_field32_set(unit, L3_ENTRY_IPV4_UNICASTm, ptr, KEY_TYPEf, 1004 TD2_L3_HASH_KEY_TYPE_FCOE_DOMAIN); 1005 /* fall through */ 1006 case TD2_L3_HASH_KEY_TYPE_FCOE_DOMAIN: 1007 mem = L3_ENTRY_IPV4_UNICASTm; 1008 field_list[0] = FCOE__KEYf; 1009 field_list[1] = INVALIDf; 1010 break; 1011 case TD2_L3_HASH_KEY_TYPE_FCOE_HOST_EXT: 1012 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV4_UNICASTm); 1013 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(entry_words)); 1014 ptr = &sanitized_entry; 1015 soc_mem_field32_set(unit, L3_ENTRY_IPV4_UNICASTm, ptr, KEY_TYPEf, 1016 TD2_L3_HASH_KEY_TYPE_FCOE_HOST); 1017 /* fall through */ 1018 case TD2_L3_HASH_KEY_TYPE_FCOE_HOST: 1019 mem = L3_ENTRY_IPV4_UNICASTm; 1020 field_list[0] = FCOE__KEYf; 1021 field_list[1] = INVALIDf; 1022 break; 1023 case TD2_L3_HASH_KEY_TYPE_FCOE_SRC_MAP_EXT: 1024 entry_words = SOC_MEM_WORDS(unit, L3_ENTRY_IPV4_UNICASTm); 1025 sal_memcpy(&sanitized_entry, entry, entry_words * sizeof(entry_words)); 1026 ptr = &sanitized_entry; 1027 soc_mem_field32_set(unit, L3_ENTRY_IPV4_UNICASTm, ptr, KEY_TYPEf, 1028 TD2_L3_HASH_KEY_TYPE_FCOE_SRC_MAP); 1029 /* fall through */ 1030 case TD2_L3_HASH_KEY_TYPE_FCOE_SRC_MAP: 1031 mem = L3_ENTRY_IPV4_UNICASTm; 1032 field_list[0] = FCOE__KEYf; 1033 field_list[1] = INVALIDf; 1034 break; 1035 1036 1037 case TD2_L3_HASH_KEY_TYPE_DST_NAT: 1038 case TD2_L3_HASH_KEY_TYPE_DST_NAPT: 1039 mem = L3_ENTRY_IPV4_MULTICASTm; 1040 field_list[0] = NAT__KEY_0f; 1041 field_list[1] = INVALIDf; 1042 break; 1043 default: 1044 return 0; 1045 } 1046 return _soc_ap_hash_entry_to_key(unit, ptr, key, mem, field_list); 1047 } 1048 1049 uint32 1050 soc_ap_l3x_entry_hash(int unit, int bank, int hash_offset, int use_lsb, 1051 uint32 *entry) 1052 { 1053 int key_nbits; 1054 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1055 1056 key_nbits = soc_ap_l3x_base_entry_to_key(unit, entry, key); 1057 return soc_ap_l3x_hash(unit, bank, hash_offset, use_lsb, key_nbits, entry, key); 1058 } 1059 1060 uint32 1061 soc_ap_l3x_bank_entry_hash(int unit, int bank, uint32 *entry) 1062 { 1063 int rv, hash_offset, use_lsb; 1064 1065 rv = soc_ap_hash_offset_get(unit, L3_ENTRY_ONLYm, bank, &hash_offset, 1066 &use_lsb); 1067 if (SOC_FAILURE(rv)) { 1068 return 0; 1069 } 1070 1071 return soc_ap_l3x_entry_hash(unit, bank, hash_offset, use_lsb, entry); 1072 } 1073 1074 uint32 1075 soc_ap_mpls_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1076 { 1077 int key_nbits; 1078 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1079 uint32 index; 1080 1081 sal_memset(key, 0, sizeof(key)); 1082 1083 key_nbits = soc_td2_mpls_base_entry_to_key(unit, bank, entry, key); 1084 index = soc_td2_mpls_hash(unit, hash_sel, key_nbits, entry, key); 1085 1086 return index; 1087 } 1088 1089 uint32 1090 soc_ap_mpls_bank_entry_hash(int unit, int bank, uint32 *entry) 1091 { 1092 int rv, hash_sel; 1093 1094 rv = soc_td2_hash_sel_get(unit, MPLS_ENTRYm, bank, &hash_sel); 1095 if (SOC_FAILURE(rv)) { 1096 return 0; 1097 } 1098 1099 return soc_ap_mpls_entry_hash(unit, hash_sel, bank, entry); 1100 } 1101 1102 uint32 1103 soc_ap_vlan_xlate_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1104 { 1105 int key_nbits; 1106 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1107 uint32 index; 1108 1109 sal_memset(key, 0, sizeof(key)); 1110 key_nbits = soc_td2_vlan_xlate_base_entry_to_key(unit, bank, entry, key); 1111 index = soc_td2_vlan_xlate_hash(unit, hash_sel, key_nbits, entry, key); 1112 1113 return index; 1114 } 1115 1116 uint32 1117 soc_ap_vlan_xlate_bank_entry_hash(int unit, int bank, uint32 *entry) 1118 { 1119 int rv, hash_sel; 1120 1121 rv = soc_td2_hash_sel_get(unit, VLAN_XLATEm, bank, &hash_sel); 1122 if (SOC_FAILURE(rv)) { 1123 return 0; 1124 } 1125 1126 return soc_ap_vlan_xlate_entry_hash(unit, hash_sel, bank, entry); 1127 } 1128 1129 uint32 1130 soc_ap_egr_vlan_xlate_entry_hash(int unit, int hash_sel, int bank, 1131 uint32 *entry) 1132 { 1133 int key_nbits; 1134 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1135 uint32 index; 1136 1137 sal_memset(key, 0, sizeof(key)); 1138 1139 key_nbits = soc_td2_egr_vlan_xlate_base_entry_to_key(unit, bank, entry, key); 1140 index = soc_td2_egr_vlan_xlate_hash(unit, hash_sel, key_nbits, entry, key); 1141 1142 return index; 1143 } 1144 1145 uint32 1146 soc_ap_egr_vlan_xlate_bank_entry_hash(int unit, int bank, uint32 *entry) 1147 { 1148 int rv, hash_sel; 1149 1150 rv = soc_td2_hash_sel_get(unit, EGR_VLAN_XLATEm, bank, &hash_sel); 1151 if (SOC_FAILURE(rv)) { 1152 return 0; 1153 } 1154 1155 return soc_ap_egr_vlan_xlate_entry_hash(unit, hash_sel, bank, entry); 1156 } 1157 1158 uint32 1159 soc_ap_ing_vp_vlan_member_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1160 { 1161 int key_nbits; 1162 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1163 uint32 index; 1164 1165 key_nbits = soc_td2_ing_vp_vlan_member_base_entry_to_key(unit, bank, entry, key); 1166 index = soc_td2_ing_vp_vlan_member_hash(unit, hash_sel, key_nbits, entry, 1167 key); 1168 1169 return index; 1170 } 1171 1172 uint32 1173 soc_ap_ing_vp_vlan_member_bank_entry_hash(int unit, int bank, uint32 *entry) 1174 { 1175 int rv, hash_sel; 1176 1177 rv = soc_td2_hash_sel_get(unit, ING_VP_VLAN_MEMBERSHIPm, bank, &hash_sel); 1178 if (SOC_FAILURE(rv)) { 1179 return 0; 1180 } 1181 1182 return soc_ap_ing_vp_vlan_member_entry_hash(unit, hash_sel, bank, entry); 1183 } 1184 1185 uint32 1186 soc_ap_egr_vp_vlan_member_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1187 { 1188 int key_nbits; 1189 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1190 uint32 index; 1191 1192 key_nbits = soc_td2_egr_vp_vlan_member_base_entry_to_key(unit, bank, entry, key); 1193 index = soc_td2_egr_vp_vlan_member_hash(unit, hash_sel, key_nbits, entry, 1194 key); 1195 1196 return index; 1197 } 1198 1199 uint32 1200 soc_ap_egr_vp_vlan_member_bank_entry_hash(int unit, int bank, uint32 *entry) 1201 { 1202 int rv, hash_sel; 1203 1204 rv = soc_td2_hash_sel_get(unit, EGR_VP_VLAN_MEMBERSHIPm, bank, &hash_sel); 1205 if (SOC_FAILURE(rv)) { 1206 return 0; 1207 } 1208 1209 return soc_ap_egr_vp_vlan_member_entry_hash(unit, hash_sel, bank, entry); 1210 } 1211 1212 uint32 1213 soc_ap_ing_dnat_address_type_entry_hash(int unit, int hash_sel, 1214 int bank, uint32 *entry) 1215 { 1216 int key_nbits; 1217 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1218 uint32 index; 1219 1220 key_nbits = soc_td2_ing_dnat_address_type_base_entry_to_key(unit, bank, 1221 entry, key); 1222 index = soc_td2_ing_dnat_address_type_hash(unit, hash_sel, key_nbits, 1223 entry, key); 1224 1225 return index; 1226 } 1227 1228 uint32 1229 soc_ap_ing_dnat_address_type_bank_entry_hash(int unit, int bank, uint32 *entry) 1230 { 1231 int rv, hash_sel; 1232 1233 rv = soc_td2_hash_sel_get(unit, ING_DNAT_ADDRESS_TYPEm, bank, &hash_sel); 1234 if (SOC_FAILURE(rv)) { 1235 return 0; 1236 } 1237 1238 return soc_ap_ing_dnat_address_type_entry_hash(unit, hash_sel, bank, entry); 1239 } 1240 1241 uint32 1242 soc_ap_l2_endpoint_id_entry_hash(int unit, int hash_sel, int bank, uint32 *entry) 1243 { 1244 int key_nbits; 1245 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1246 uint32 index; 1247 1248 key_nbits = soc_td2_l2_endpoint_id_base_entry_to_key(unit, bank, entry, key); 1249 index = soc_td2_l2_endpoint_id_hash(unit, hash_sel, key_nbits, entry, key); 1250 1251 return index; 1252 } 1253 1254 uint32 1255 soc_ap_l2_endpoint_id_bank_entry_hash(int unit, int bank, uint32 *entry) 1256 { 1257 int rv, hash_sel; 1258 1259 rv = soc_td2_hash_sel_get(unit, L2_ENDPOINT_IDm, bank, &hash_sel); 1260 if (SOC_FAILURE(rv)) { 1261 return 0; 1262 } 1263 1264 return soc_ap_l2_endpoint_id_entry_hash(unit, hash_sel, bank, entry); 1265 } 1266 1267 uint32 1268 soc_ap_endpoint_queue_map_entry_hash(int unit, int hash_sel, 1269 int bank, uint32 *entry) 1270 { 1271 int key_nbits; 1272 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1273 uint32 index; 1274 1275 key_nbits = soc_td2_endpoint_queue_map_base_entry_to_key(unit, bank, 1276 entry, key); 1277 index = soc_td2_endpoint_queue_map_hash(unit, hash_sel, key_nbits, entry, 1278 key); 1279 1280 return index; 1281 } 1282 1283 uint32 1284 soc_ap_endpoint_queue_map_bank_entry_hash(int unit, int bank, uint32 *entry) 1285 { 1286 int rv, hash_sel; 1287 1288 rv = soc_td2_hash_sel_get(unit, ENDPOINT_QUEUE_MAPm, bank, &hash_sel); 1289 if (SOC_FAILURE(rv)) { 1290 return 0; 1291 } 1292 1293 return soc_ap_endpoint_queue_map_entry_hash(unit, hash_sel, bank, entry); 1294 } 1295 1296 int 1297 soc_ap_hash_bucket_get(int unit, int mem, int bank, uint32 *entry, uint32 *bucket) 1298 { 1299 switch(mem) { 1300 case L2Xm: 1301 *bucket = soc_ap_l2x_bank_entry_hash(unit, bank, entry); 1302 return SOC_E_NONE; 1303 case L3_ENTRY_ONLYm: 1304 case L3_ENTRY_IPV4_UNICASTm: 1305 case L3_ENTRY_IPV4_MULTICASTm: 1306 case L3_ENTRY_IPV6_UNICASTm: 1307 case L3_ENTRY_IPV6_MULTICASTm: 1308 *bucket = soc_ap_l3x_bank_entry_hash(unit, bank, entry); 1309 return SOC_E_NONE; 1310 case ING_VP_VLAN_MEMBERSHIPm: 1311 *bucket = soc_ap_ing_vp_vlan_member_bank_entry_hash(unit, bank, entry); 1312 return SOC_E_NONE; 1313 case EGR_VP_VLAN_MEMBERSHIPm: 1314 *bucket = soc_ap_egr_vp_vlan_member_bank_entry_hash(unit, bank, entry); 1315 return SOC_E_NONE; 1316 case ING_DNAT_ADDRESS_TYPEm: 1317 *bucket = soc_ap_ing_dnat_address_type_bank_entry_hash(unit, bank, entry); 1318 return SOC_E_NONE; 1319 case L2_ENDPOINT_IDm: 1320 *bucket = soc_ap_l2_endpoint_id_bank_entry_hash(unit, bank, entry); 1321 return SOC_E_NONE; 1322 case ENDPOINT_QUEUE_MAPm: 1323 *bucket = soc_ap_endpoint_queue_map_bank_entry_hash(unit, bank, entry); 1324 return SOC_E_NONE; 1325 case VLAN_XLATEm: 1326 *bucket = soc_ap_vlan_xlate_bank_entry_hash(unit, bank, entry); 1327 return SOC_E_NONE; 1328 case EGR_VLAN_XLATEm: 1329 *bucket = soc_ap_egr_vlan_xlate_bank_entry_hash(unit, bank, entry); 1330 return SOC_E_NONE; 1331 case MPLS_ENTRYm: 1332 *bucket = soc_ap_mpls_bank_entry_hash(unit, bank, entry); 1333 return SOC_E_NONE; 1334 default: 1335 return SOC_E_PARAM; 1336 } 1337 } 1338 1339 int 1340 soc_ap_hash_index_get(int unit, int mem, int bank, int bucket) 1341 { 1342 int rv; 1343 int index; 1344 int entries_per_row, bank_base, bucket_offset; 1345 1346 switch(mem) { 1347 case L2Xm: 1348 rv = soc_apache_hash_bank_info_get(unit, mem, bank, NULL, 1349 &entries_per_row, NULL, 1350 &bank_base, &bucket_offset); 1351 if (SOC_SUCCESS(rv)) { 1352 return bank_base + bucket * entries_per_row + bucket_offset; 1353 } 1354 break; 1355 case L3_ENTRY_ONLYm: 1356 case L3_ENTRY_IPV4_UNICASTm: 1357 case L3_ENTRY_IPV4_MULTICASTm: 1358 case L3_ENTRY_IPV6_UNICASTm: 1359 case L3_ENTRY_IPV6_MULTICASTm: 1360 rv = soc_apache_hash_bank_info_get(unit, L3_ENTRY_ONLYm, bank, NULL, 1361 &entries_per_row, NULL, 1362 &bank_base, &bucket_offset); 1363 if (SOC_SUCCESS(rv)) { 1364 index = bank_base + bucket * entries_per_row + bucket_offset; 1365 if (mem == L3_ENTRY_IPV4_MULTICASTm || mem == L3_ENTRY_IPV6_UNICASTm) { 1366 return index / 2; 1367 } else if (mem == L3_ENTRY_IPV6_MULTICASTm) { 1368 return index / 4; 1369 } 1370 return index; 1371 } 1372 break; 1373 default: 1374 break; 1375 } 1376 1377 return 0; 1378 } 1379 1380 #endif /* BCM_APACHE_SUPPORT */