openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 */