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 (68880B)


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