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


      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:     Trident3 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 #include <soc/esw/flow_db.h>
     19 
     20 #if defined(BCM_TRIDENT3_SUPPORT)
     21 
     22 #include <soc/trident3.h>
     23 
     24 int
     25 soc_td3_tbl_entries_per_sram_entry_get(int unit, soc_mem_t mem,
     26                        int *table_entries_per_sram_entry)
     27 {
     28     switch (mem) {
     29     case L3_ENTRY_SINGLEm:
     30     case L3_ENTRY_ONLY_SINGLEm:
     31          *table_entries_per_sram_entry = 4;
     32          break;
     33 
     34     case L3_ENTRY_DOUBLEm:
     35     case EXACT_MATCH_2m:
     36     case EXACT_MATCH_2_PIPE0m:
     37     case EXACT_MATCH_2_PIPE1m:
     38          *table_entries_per_sram_entry = 2;
     39          break;
     40 
     41     case L3_ENTRY_QUADm:
     42     case EXACT_MATCH_4m:
     43     case EXACT_MATCH_4_PIPE0m:
     44     case EXACT_MATCH_4_PIPE1m:
     45          *table_entries_per_sram_entry = 1;
     46          break;
     47 
     48     case VLAN_XLATE_1_SINGLEm:
     49     case VLAN_XLATE_2_SINGLEm:
     50     case EGR_VLAN_XLATE_1_SINGLEm:
     51     case EGR_VLAN_XLATE_2_SINGLEm:
     52     case MPLS_ENTRY_SINGLEm:
     53          *table_entries_per_sram_entry = 2;
     54          break;
     55 
     56     case VLAN_XLATE_1_DOUBLEm:
     57     case VLAN_XLATE_2_DOUBLEm:
     58     case EGR_VLAN_XLATE_1_DOUBLEm:
     59     case EGR_VLAN_XLATE_2_DOUBLEm:
     60     case MPLS_ENTRYm:
     61          *table_entries_per_sram_entry = 1;
     62          break;
     63 
     64     default:
     65         return SOC_E_PARAM;
     66     }
     67 
     68     return SOC_E_NONE;
     69 }
     70 
     71 int
     72 soc_td3_shared_hash_mem_bucket_read(int unit, int ent, int entry_width, int *width,
     73                                     soc_mem_t base_mem, soc_mem_t *mem, 
     74                                     void *bkt_entry, void *entry)
     75 {
     76 
     77     soc_mem_info_t meminfo;
     78     soc_field_info_t fieldinfo;
     79     /* Exclude HIT bit */
     80     int entry_bits = 0, hit_bits=0;
     81     if (entry_width <= 0) {
     82         return (SOC_E_PARAM);
     83     }
     84 
     85     switch (base_mem) {
     86     case L3_ENTRY_SINGLEm:
     87     case L3_ENTRY_ONLY_SINGLEm:
     88     case L3_ENTRY_DOUBLEm:
     89     case L3_ENTRY_QUADm:
     90         switch (entry_width) {
     91         case 1:  /* 1 base_entry wide */
     92             *width = 1;
     93             *mem = L3_ENTRY_SINGLEm;
     94             break;
     95         case 2:  /* 2 base entries wide */
     96             *width = 2;
     97             *mem = L3_ENTRY_DOUBLEm;
     98             break;
     99         default:
    100             *width = 4; /* 4 base_entries wide */
    101             *mem = L3_ENTRY_QUADm;
    102         }
    103         hit_bits = *width;
    104         break;
    105 
    106     case EXACT_MATCH_2_PIPE0m:
    107     case EXACT_MATCH_4_PIPE0m:
    108         switch (entry_width) {
    109             case 2:
    110                 *width = 1;
    111                 *mem = EXACT_MATCH_2_PIPE0m;
    112                 break;
    113             case 4:
    114             default:
    115                 *width = 2;
    116                 *mem = EXACT_MATCH_4_PIPE0m;
    117         }
    118         hit_bits = *width;
    119         break;
    120 
    121     case EXACT_MATCH_2_PIPE1m:
    122     case EXACT_MATCH_4_PIPE1m:
    123         switch (entry_width) {
    124             case 2:
    125                 *width = 1;
    126                 *mem = EXACT_MATCH_2_PIPE1m;
    127                 break;
    128             case 4:
    129             default:
    130                 *width = 2;
    131                 *mem = EXACT_MATCH_4_PIPE1m;
    132         }
    133         hit_bits = *width;
    134         break;
    135 
    136     case EXACT_MATCH_2m:
    137     case EXACT_MATCH_4m:
    138         switch (entry_width) {
    139             case 2:
    140                 *width = 1;
    141                 *mem = EXACT_MATCH_2m;
    142                 break;
    143             case 4:
    144             default:
    145                 *width = 2;
    146                 *mem = EXACT_MATCH_4m;
    147         }
    148         hit_bits = *width;
    149         break;
    150 
    151     case VLAN_XLATE_1_SINGLEm:
    152     case VLAN_XLATE_1_DOUBLEm:
    153         switch (entry_width) {
    154         case 1:
    155             *width = 1;
    156             *mem = VLAN_XLATE_1_SINGLEm;
    157             break;
    158         case 2:
    159         default:
    160             *width = 2;
    161             *mem = VLAN_XLATE_1_DOUBLEm;
    162         }
    163         break;
    164 
    165     case VLAN_XLATE_2_SINGLEm:
    166     case VLAN_XLATE_2_DOUBLEm:
    167         switch (entry_width) {
    168         case 1:
    169             *width = 1;
    170             *mem = VLAN_XLATE_2_SINGLEm;
    171             break;
    172         case 2:
    173         default:
    174             *width = 2;
    175             *mem = VLAN_XLATE_2_DOUBLEm;
    176         }
    177         break;
    178 
    179     case EGR_VLAN_XLATE_1_SINGLEm:
    180     case EGR_VLAN_XLATE_1_DOUBLEm:
    181         switch (entry_width) {
    182         case 1:
    183             *width = 1;
    184             *mem = EGR_VLAN_XLATE_1_SINGLEm;
    185             break;
    186         case 2:
    187         default:
    188             *width = 2;
    189             *mem = EGR_VLAN_XLATE_1_DOUBLEm;
    190         }
    191         break;
    192 
    193     case EGR_VLAN_XLATE_2_SINGLEm:
    194     case EGR_VLAN_XLATE_2_DOUBLEm:
    195         switch (entry_width) {
    196         case 1:
    197             *width = 1;
    198             *mem = EGR_VLAN_XLATE_2_SINGLEm;
    199             break;
    200         case 2:
    201         default:
    202             *width = 2;
    203             *mem = EGR_VLAN_XLATE_2_DOUBLEm;
    204         }
    205         break;
    206 
    207     case MPLS_ENTRY_SINGLEm:
    208     case MPLS_ENTRYm:
    209         switch (entry_width) {
    210         case 1:
    211             *width = 1;
    212             *mem = MPLS_ENTRY_SINGLEm;
    213             break;
    214         case 2:
    215         default:
    216             *width = 2;
    217             *mem = MPLS_ENTRYm;
    218         }
    219         break;
    220 
    221     default:
    222         return SOC_E_PARAM;
    223     }
    224 
    225     entry_bits = soc_mem_entry_bits(unit, *mem) - hit_bits;
    226 
    227     meminfo.flags = 0;
    228     meminfo.bytes = SOC_MEM_WORDS(unit, base_mem) * 4;
    229     fieldinfo.flags = SOCF_LE;
    230     fieldinfo.len = entry_bits;
    231 
    232     fieldinfo.bp =  entry_bits * (ent/entry_width);
    233     (void)soc_meminfo_fieldinfo_field_get(bkt_entry, &meminfo,
    234                                           &fieldinfo, entry);
    235     return SOC_E_NONE;
    236 
    237 }
    238 
    239 
    240 int
    241 soc_td3_hash_mem_status_get(int unit, soc_mem_t mem, void* entry, uint32 *v) {
    242     int i;
    243     v[0] = v[1] = v[2] = v[3] = 0;
    244 
    245     switch (mem) {
    246     case L3_ENTRY_QUADm:
    247     case EXACT_MATCH_4m:
    248         soc_mem_field_get(unit, mem, entry, BASE_VALID_3f, &v[3]);
    249         soc_mem_field_get(unit, mem, entry, BASE_VALID_2f, &v[2]);
    250         /* pass through */
    251     case L3_ENTRY_DOUBLEm:
    252     case EXACT_MATCH_2m:
    253     case MPLS_ENTRYm:
    254     case VLAN_XLATE_1_DOUBLEm:
    255     case VLAN_XLATE_2_DOUBLEm:
    256     case EGR_VLAN_XLATE_1_DOUBLEm:
    257     case EGR_VLAN_XLATE_2_DOUBLEm:
    258         soc_mem_field_get(unit, mem, entry, BASE_VALID_1f, &v[1]);
    259         soc_mem_field_get(unit, mem, entry, BASE_VALID_0f, &v[0]);
    260         break;
    261     case L3_ENTRY_SINGLEm:
    262     case L3_ENTRY_ONLY_SINGLEm:
    263     case MPLS_ENTRY_SINGLEm:
    264     case VLAN_XLATE_1_SINGLEm:
    265     case VLAN_XLATE_2_SINGLEm:
    266     case EGR_VLAN_XLATE_1_SINGLEm:
    267     case EGR_VLAN_XLATE_2_SINGLEm:
    268         soc_mem_field_get(unit, mem, entry, BASE_VALIDf, &v[0]);
    269         break;
    270     default:
    271         v[0] = v[1] = v[2] = v[3] = 1;
    272         break;
    273 
    274     }
    275     /* Use v[i] for constructing a valid bitmap */
    276     for (i = 0; i < 4; i++) {
    277         v[i] = (v[i] > 0);
    278     }
    279     return SOC_E_NONE;
    280 }
    281 
    282 STATIC int
    283 soc_td3_iuat_hash_bank_count_get(int unit, soc_mem_t mem, int *num_16k_banks,
    284                                  int *num_8k_banks) {
    285     int count;
    286     int uat_16k_banks_other, uat_8k_banks_other;
    287     int uat_16k_banks = 0, uat_8k_banks = 0;
    288     
    289     switch (mem) {
    290     case MPLS_ENTRY_SINGLEm:
    291     case MPLS_ENTRYm:
    292         count = soc_mem_index_count(unit, MPLS_ENTRY_SINGLEm);
    293         SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, count,
    294                                             &uat_16k_banks, &uat_8k_banks));
    295         *num_16k_banks = uat_16k_banks;
    296         *num_8k_banks = uat_8k_banks;
    297         break;
    298 
    299     case VLAN_XLATE_1_SINGLEm:
    300     case VLAN_XLATE_1_DOUBLEm:
    301         count = soc_mem_index_count(unit, VLAN_XLATE_1_SINGLEm);
    302         SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, count,
    303                                             &uat_16k_banks, &uat_8k_banks));
    304         uat_16k_banks_other = uat_16k_banks;
    305         uat_8k_banks_other = uat_8k_banks;
    306         count = soc_mem_index_count(unit, VLAN_XLATE_1_SINGLEm);
    307         SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, count,
    308                                             &uat_16k_banks, &uat_8k_banks));
    309         *num_16k_banks = uat_16k_banks - uat_16k_banks_other;
    310         *num_8k_banks = uat_8k_banks - uat_8k_banks_other;
    311         break;
    312 
    313     case VLAN_XLATE_2_SINGLEm:
    314     case VLAN_XLATE_2_DOUBLEm:
    315         count = soc_mem_index_count(unit, VLAN_XLATE_2_SINGLEm);
    316         SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, count,
    317                                             &uat_16k_banks, &uat_8k_banks));
    318         count = soc_mem_index_count(unit, VLAN_XLATE_1_SINGLEm);
    319         SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, count,
    320                                             &uat_16k_banks, &uat_8k_banks));
    321         uat_16k_banks_other = uat_16k_banks;
    322         uat_8k_banks_other = uat_8k_banks;
    323         count = soc_mem_index_count(unit, VLAN_XLATE_2_SINGLEm);
    324         SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, count,
    325                                             &uat_16k_banks, &uat_8k_banks));
    326         *num_16k_banks = uat_16k_banks - uat_16k_banks_other;
    327         *num_8k_banks = uat_8k_banks - uat_8k_banks_other;
    328         break;
    329     }
    330     return SOC_E_NONE;
    331 }
    332 
    333 /* Get number of banks for the hash table according to the config
    334  */
    335 int
    336 soc_trident3_hash_bank_count_get(int unit, soc_mem_t mem, int *num_banks)
    337 {
    338     int count;
    339     int uat_16k_banks = 0, uat_8k_banks = 0;
    340 
    341     switch (mem) {
    342     case L2Xm:
    343         /*
    344          * 16k single wide entries in each of 2 dedicated L2 bank
    345          * 32k single wide entries in each shared bank (8 shared banks max)
    346          */
    347         count = soc_mem_index_count(unit, mem);
    348         *num_banks = 2 + (count - 2 * 16 * 1024) / (32 * 1024);
    349         break;
    350     case L3_ENTRY_ONLY_SINGLEm:
    351     case L3_ENTRY_ONLY_DOUBLEm:
    352     case L3_ENTRY_ONLY_QUADm:
    353     case L3_ENTRY_SINGLEm:
    354     case L3_ENTRY_DOUBLEm:
    355     case L3_ENTRY_QUADm:
    356         /*
    357          * 8k single wide entries in each of 2 dedicated L3 bank
    358          * 32k entries in each shared bank (8 shared banks max)
    359          */
    360         count = soc_mem_index_count(unit, L3_ENTRY_ONLY_SINGLEm);
    361         *num_banks = 2 + (count - 2 * 8 * 1024) / (32 * 1024);
    362         break;
    363 
    364     case EXACT_MATCH_2m:
    365     case EXACT_MATCH_2_PIPE0m:
    366     case EXACT_MATCH_2_PIPE1m:
    367     case EXACT_MATCH_2_ENTRY_ONLYm:
    368     case EXACT_MATCH_4m:
    369     case EXACT_MATCH_4_PIPE0m:
    370     case EXACT_MATCH_4_PIPE1m:
    371     case EXACT_MATCH_4_ENTRY_ONLYm:
    372         /*
    373          * 16k double wide entries in each shared bank
    374          */
    375         count = soc_mem_index_count(unit, EXACT_MATCH_2m);
    376         *num_banks = count / (16 * 1024);
    377         break;
    378 
    379     /* EUAT */
    380     case EGR_VLAN_XLATE_1_SINGLEm:
    381     case EGR_VLAN_XLATE_1_DOUBLEm:
    382         /*
    383          * 8k single wide entries in each shared bank
    384          */
    385         count = soc_mem_index_count(unit, EGR_VLAN_XLATE_1_SINGLEm);
    386         *num_banks = count / (8 * 1024);
    387         break;
    388 
    389     case EGR_VLAN_XLATE_2_SINGLEm:
    390     case EGR_VLAN_XLATE_2_DOUBLEm:
    391         /*
    392          * 8k single wide entries in each shared bank
    393          */
    394         count = soc_mem_index_count(unit, EGR_VLAN_XLATE_2_SINGLEm);
    395         *num_banks = count / (8 * 1024);
    396         break;
    397 
    398     case ING_VP_VLAN_MEMBERSHIPm:
    399     case EGR_VP_VLAN_MEMBERSHIPm:
    400     case ING_DNAT_ADDRESS_TYPEm:
    401     case SUBPORT_ID_TO_SGPP_MAPm:
    402         *num_banks = 2;
    403         break;
    404 
    405     case MPLS_ENTRY_SINGLEm:
    406     case MPLS_ENTRYm:
    407     case VLAN_XLATE_1_SINGLEm:
    408     case VLAN_XLATE_1_DOUBLEm:
    409     case VLAN_XLATE_2_SINGLEm:
    410     case VLAN_XLATE_2_DOUBLEm:
    411         SOC_IF_ERROR_RETURN(soc_td3_iuat_hash_bank_count_get(unit, mem,
    412                                                 &uat_16k_banks, &uat_8k_banks));
    413         *num_banks = uat_16k_banks + uat_8k_banks;
    414         break;
    415 
    416     default:
    417         return SOC_E_INTERNAL;
    418     }
    419 
    420     return SOC_E_NONE;
    421 }
    422 
    423 /* Map logical bank to physical bank for a memory 
    424  * mem          - memory
    425  * log_bank     - logical bank number
    426  * phy_bank_id  - physical bank number
    427  */
    428 int
    429 soc_td3_log_to_phy_bank_map(int unit, soc_mem_t mem, int log_bank,
    430                             int *phy_bank_id)
    431 {
    432     uint32 hash_control_entry[4];
    433     int done = 0;
    434     static const soc_field_t logical_to_physical_fields[] = {
    435         LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf,
    436         LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf,
    437         LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf,
    438         LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf,
    439         LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf,
    440         LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf,
    441         LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf,
    442         LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf,
    443         LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf,
    444         LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf
    445     };
    446     int logical_to_physical_fields_num = sizeof(logical_to_physical_fields)/
    447                                          sizeof(soc_field_t );
    448 
    449     if(log_bank < 0 || log_bank >= logical_to_physical_fields_num) {
    450         return SOC_E_PARAM;
    451     }
    452 
    453     sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
    454 
    455     switch(mem) {
    456     case L2Xm:
    457         /* Dedicated Banks */
    458         if (log_bank < 2) {
    459             *phy_bank_id = log_bank;
    460             done = 1;
    461         } else { /* Shared Banks */
    462             mem = L2_ENTRY_HASH_CONTROLm;
    463         }
    464         break;
    465     case L3_ENTRY_SINGLEm:
    466     case L3_ENTRY_ONLY_SINGLEm:
    467     case L3_ENTRY_DOUBLEm:
    468     case L3_ENTRY_ONLY_DOUBLEm:
    469     case L3_ENTRY_QUADm:
    470     case L3_ENTRY_ONLY_QUADm:
    471         /* Dedicated Banks */
    472         if (log_bank < 2) {
    473             *phy_bank_id = log_bank + 10;
    474             done = 1;
    475         } else { /* Shared Banks */
    476             mem = L3_ENTRY_HASH_CONTROLm;
    477         }
    478         break;
    479     case EXACT_MATCH_2m:
    480     case EXACT_MATCH_2_PIPE0m:
    481     case EXACT_MATCH_2_PIPE1m:
    482     case EXACT_MATCH_4m:
    483     case EXACT_MATCH_4_PIPE0m:
    484     case EXACT_MATCH_4_PIPE1m:
    485         if (log_bank < 0 || log_bank > 7) {
    486             return SOC_E_PARAM;
    487         } else {
    488             mem = EXACT_MATCH_HASH_CONTROLm;
    489         }
    490         break;
    491     case MPLS_ENTRY_SINGLEm:
    492     case MPLS_ENTRYm:
    493         if (log_bank < 0 || log_bank > 7) {
    494             return SOC_E_PARAM;
    495         } else {
    496             mem = MPLS_ENTRY_HASH_CONTROLm;
    497         }
    498         break;
    499     case VLAN_XLATE_1_SINGLEm:
    500     case VLAN_XLATE_1_DOUBLEm:
    501         if (log_bank < 0 || log_bank > 7) {
    502             return SOC_E_PARAM;
    503         } else {
    504             mem = VLAN_XLATE_1_HASH_CONTROLm;
    505         }
    506         break;
    507     case VLAN_XLATE_2_SINGLEm:
    508     case VLAN_XLATE_2_DOUBLEm:
    509         if (log_bank < 0 || log_bank > 7) {
    510             return SOC_E_PARAM;
    511         } else {
    512             mem = VLAN_XLATE_2_HASH_CONTROLm;
    513         }
    514         break;
    515     case EGR_VLAN_XLATE_1_SINGLEm:
    516     case EGR_VLAN_XLATE_1_DOUBLEm:
    517         if (log_bank < 0 || log_bank > 3) {
    518             return SOC_E_PARAM;
    519         } else {
    520             mem = EGR_VLAN_XLATE_1_HASH_CONTROLm;
    521         }
    522         break;
    523     case EGR_VLAN_XLATE_2_SINGLEm:
    524     case EGR_VLAN_XLATE_2_DOUBLEm:
    525         if (log_bank < 0 || log_bank > 3) {
    526             return SOC_E_PARAM;
    527         } else {
    528             mem = EGR_VLAN_XLATE_2_HASH_CONTROLm;
    529         }
    530         break;
    531     default:
    532         *phy_bank_id = log_bank;
    533         done = 1;
    534     }
    535     /* Shared Banks */
    536     if (done == 0) {
    537         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0,
    538                                          hash_control_entry));
    539         *phy_bank_id = soc_mem_field32_get(unit, mem, hash_control_entry,
    540                                            logical_to_physical_fields[log_bank]);
    541     }
    542     return SOC_E_NONE;
    543 }
    544 
    545 /* Map physical to logical bank for a memory 
    546  * mem      - memory
    547  * phy_bank - physical bank number
    548  * log_bank - logical bank number
    549  */
    550 int
    551 soc_td3_phy_to_log_bank_map(int unit, soc_mem_t mem, int phy_bank,
    552                             int *log_bank)
    553 {
    554     uint32 hash_control_entry[4];
    555     int i, done = 0;
    556     int bank_min, bank_max;
    557     static const soc_field_t logical_to_physical_fields[] = {
    558         LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf,
    559         LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf,
    560         LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf,
    561         LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf,
    562         LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf,
    563         LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf,
    564         LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf,
    565         LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf,
    566         LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf,
    567         LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf
    568     };
    569 
    570     sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
    571 
    572     switch(mem) {
    573     case L2Xm:
    574         bank_min = 2;
    575         bank_max = 9;
    576         /* Dedicated Banks */
    577         if (phy_bank < 2) {
    578             *log_bank = phy_bank;
    579             done = 1;
    580         } else { /* Shared Banks */
    581             mem = L2_ENTRY_HASH_CONTROLm;
    582         }
    583         break;
    584     case L3_ENTRY_SINGLEm:
    585     case L3_ENTRY_ONLY_SINGLEm:
    586     case L3_ENTRY_DOUBLEm:
    587     case L3_ENTRY_ONLY_DOUBLEm:
    588     case L3_ENTRY_QUADm:
    589     case L3_ENTRY_ONLY_QUADm:
    590         bank_min = 2;
    591         bank_max = 11;
    592         /* Dedicated Banks */
    593         if (phy_bank > 9) {
    594             *log_bank = phy_bank - 10;
    595             done = 1;
    596         } else { /* Shared Banks */
    597             mem = L3_ENTRY_HASH_CONTROLm;
    598         }
    599         break;
    600     case EXACT_MATCH_2m:
    601     case EXACT_MATCH_2_PIPE0m:
    602     case EXACT_MATCH_2_PIPE1m:
    603     case EXACT_MATCH_4m:
    604     case EXACT_MATCH_4_PIPE0m:
    605     case EXACT_MATCH_4_PIPE1m:
    606         bank_min = 0;
    607         bank_max = 7;
    608         mem = EXACT_MATCH_HASH_CONTROLm;
    609         break;
    610     case MPLS_ENTRY_SINGLEm:
    611     case MPLS_ENTRYm:
    612         bank_min = 0;
    613         bank_max = 7;
    614         mem = MPLS_ENTRY_HASH_CONTROLm;
    615         break;
    616     case VLAN_XLATE_1_SINGLEm:
    617     case VLAN_XLATE_1_DOUBLEm:
    618         bank_min = 0;
    619         bank_max = 7;
    620         mem = VLAN_XLATE_1_HASH_CONTROLm;
    621         break;
    622     case VLAN_XLATE_2_SINGLEm:
    623     case VLAN_XLATE_2_DOUBLEm:
    624         bank_min = 0;
    625         bank_max = 7;
    626         mem = VLAN_XLATE_2_HASH_CONTROLm;
    627         break;
    628     case EGR_VLAN_XLATE_1_SINGLEm:
    629     case EGR_VLAN_XLATE_1_DOUBLEm:
    630         bank_min = 0;
    631         bank_max = 7;
    632         mem = EGR_VLAN_XLATE_1_HASH_CONTROLm;
    633         break;
    634     case EGR_VLAN_XLATE_2_SINGLEm:
    635     case EGR_VLAN_XLATE_2_DOUBLEm:
    636         bank_min = 0;
    637         bank_max = 7;
    638         mem = EGR_VLAN_XLATE_2_HASH_CONTROLm;
    639         break;
    640     default:
    641         *log_bank = phy_bank;
    642         done = 1;
    643     }
    644 
    645     /* Shared Banks */
    646     if (done == 0) {
    647         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0,
    648                                          hash_control_entry));
    649         /* If Shared banks are used between ALPM and non-ALPM memories,
    650          * then ALPM uses Shared Bank B2, B3, B4, B5 and non-ALPM uses
    651          * B6, B7, B8, B9 banks. Max physical bank number used for UFT is 9.
    652          */
    653         if (_soc_alpm_mode[unit] && ((mem == L2_ENTRY_HASH_CONTROLm) ||
    654                             (mem == L3_ENTRY_HASH_CONTROLm) ||
    655                             (mem == EXACT_MATCH_HASH_CONTROLm)) &&
    656                             (phy_bank <=5)) {
    657             phy_bank += 4;
    658         }
    659         for (i = bank_min; i <= bank_max; i++) {
    660             if(soc_mem_field32_get(unit, mem, hash_control_entry,
    661                                    logical_to_physical_fields[i]) == phy_bank) {
    662                 *log_bank = i;
    663                 done = 1;
    664                 break;
    665             }
    666         }
    667     }
    668     return (done ? SOC_E_NONE : SOC_E_PARAM);
    669 }
    670 
    671 /* Get bank bitmap for the hash table 
    672  * Required only for shared hash tables
    673  */
    674 int
    675 soc_td3_hash_bank_phy_bitmap_get(int unit, soc_mem_t mem, uint32 *bitmap)
    676 {
    677     uint32 hash_control_entry[4];
    678     switch(mem) {
    679     case L2Xm:
    680         mem = L2_ENTRY_HASH_CONTROLm;
    681         break;
    682     case L3_ENTRY_SINGLEm:
    683     case L3_ENTRY_ONLY_SINGLEm:
    684     case L3_ENTRY_DOUBLEm:
    685     case L3_ENTRY_ONLY_DOUBLEm:
    686     case L3_ENTRY_QUADm:
    687     case L3_ENTRY_ONLY_QUADm:
    688         mem = L3_ENTRY_HASH_CONTROLm;
    689         break;
    690     case EXACT_MATCH_2m:
    691     case EXACT_MATCH_2_PIPE0m:
    692     case EXACT_MATCH_2_PIPE1m:
    693     case EXACT_MATCH_4m:
    694     case EXACT_MATCH_4_PIPE0m:
    695     case EXACT_MATCH_4_PIPE1m:
    696         mem = EXACT_MATCH_HASH_CONTROLm;
    697         break;
    698     case MPLS_ENTRY_SINGLEm:
    699     case MPLS_ENTRYm:
    700         mem = MPLS_ENTRY_HASH_CONTROLm;
    701         break;
    702     case VLAN_XLATE_1_SINGLEm:
    703     case VLAN_XLATE_1_DOUBLEm:
    704         mem = VLAN_XLATE_1_HASH_CONTROLm;
    705         break;
    706     case VLAN_XLATE_2_SINGLEm:
    707     case VLAN_XLATE_2_DOUBLEm:
    708         mem = VLAN_XLATE_2_HASH_CONTROLm;
    709         break;
    710     case EGR_VLAN_XLATE_1_SINGLEm:
    711     case EGR_VLAN_XLATE_1_DOUBLEm:
    712         mem = EGR_VLAN_XLATE_1_HASH_CONTROLm;
    713         break;
    714     case EGR_VLAN_XLATE_2_SINGLEm:
    715     case EGR_VLAN_XLATE_2_DOUBLEm:
    716         mem = EGR_VLAN_XLATE_2_HASH_CONTROLm;
    717         break;
    718     default:
    719         return SOC_E_PARAM;
    720     }
    721 
    722     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0,
    723                                      hash_control_entry));
    724     *bitmap = soc_mem_field32_get(unit, mem, hash_control_entry,
    725                                   HASH_TABLE_BANK_CONFIGf);
    726 
    727     return SOC_E_NONE;
    728 }
    729 
    730 /* Map bank sequence number to physical bank number */
    731 int
    732 soc_td3_hash_bank_number_get(int unit, soc_mem_t mem, int seq_num,
    733                              int *bank_num) {
    734     int count;
    735 
    736     SOC_IF_ERROR_RETURN(soc_trident3_hash_bank_count_get(unit, mem, &count));
    737     if (seq_num < 0 || seq_num >= count) {
    738         return SOC_E_INTERNAL;
    739     }
    740     SOC_IF_ERROR_RETURN(soc_td3_log_to_phy_bank_map(unit, mem, seq_num,
    741                                                         bank_num));
    742 
    743     return SOC_E_NONE;
    744 }
    745 
    746 int
    747 soc_td3_hash_seq_number_get(int unit, soc_mem_t mem, int bank_num, int *seq_num)
    748 {
    749     int count;
    750 
    751     SOC_IF_ERROR_RETURN(soc_td3_phy_to_log_bank_map(unit, mem, bank_num,
    752                                                     seq_num));
    753 
    754     SOC_IF_ERROR_RETURN(soc_trident3_hash_bank_count_get(unit, mem, &count));
    755     if (*seq_num < 0 || *seq_num >= count) {
    756         return SOC_E_INTERNAL;
    757     }
    758 
    759     return SOC_E_NONE;
    760 }
    761 
    762 
    763 int
    764 soc_td3_hash_bank_info_get(int unit, soc_mem_t mem, int bank,
    765                            int *entries_per_bank, int *entries_per_row,
    766                            int *entries_per_bucket, int *bank_base,
    767                            int *bucket_offset)
    768 {
    769     int bank_size, row_size, bucket_size, base, offset;
    770     int seq_num = 0;
    771     int uat_8k_banks = 0, uat_16k_banks = 0;
    772 
    773     /* Get logical bank number from input physical bank number */
    774     SOC_IF_ERROR_RETURN(soc_td3_phy_to_log_bank_map(unit, mem, bank, &seq_num));
    775     bank = seq_num;
    776 
    777     switch(mem) {
    778     case L2Xm:
    779         /*
    780          * 4 entries per bucket (1 bucket per row)
    781          * bank 0 - 1 -> dedicated banks - 16k entries each
    782          * bank 2 - 9 -> shared banks - 32k entries each
    783          */
    784         row_size = 4;
    785         bucket_size = 4;
    786         offset = 0;
    787         if (bank < 0 || bank > 9) {
    788             return SOC_E_INTERNAL;
    789         } else if (bank < 2) { /* Dedicated bank */
    790             bank_size = 16384;
    791             base = bank * bank_size;
    792         } else { /* Shared bank */
    793             bank_size = 32768;
    794             base = 32768 + (bank - 2) * bank_size;
    795         }
    796         break;
    797     case L3_ENTRY_ONLY_SINGLEm:
    798 #ifdef BCM_TRIDENT3_SUPPORT
    799     case L3_ENTRY_SINGLEm:
    800     case L3_ENTRY_DOUBLEm:
    801     case L3_ENTRY_QUADm:
    802 #endif /* BCM_TRIDENT3_SUPPORT */
    803         /*
    804          * 4 entries per bucket (1 bucket per row)
    805          * bank 0 - 1 -> dedicated banks - 8k entries each
    806          * bank 2 - 9 -> shared banks - 32k entries each
    807          */
    808         row_size = 4;
    809         bucket_size = 4;
    810         offset = 0;
    811         if (bank < 0 || bank > 9) {
    812             return SOC_E_INTERNAL;
    813         } else if(bank < 2) { /* Dedicated bank */
    814             if (mem == L3_ENTRY_QUADm) {
    815                 bank_size = 8192/4;
    816                 base = bank * bank_size;
    817             } else if (mem == L3_ENTRY_DOUBLEm) {
    818                 bank_size = 8192/2;
    819                 base = bank * bank_size;
    820             } else {
    821                 bank_size = 8192;
    822                 base = bank * bank_size;
    823             }
    824         } else { /* Shared bank */
    825             bank_size = 32768;
    826             if (mem == L3_ENTRY_QUADm) {
    827                 bank_size = bank_size/4;
    828                 base = 16384/4;
    829             } else if (mem == L3_ENTRY_DOUBLEm) {
    830                 bank_size = bank_size/2;
    831                 base = 16384/2;
    832             } else {
    833                 base = 16384;
    834             }
    835             base += ((bank-2)*bank_size);
    836         }
    837         break;
    838     case EXACT_MATCH_2m:
    839     case EXACT_MATCH_2_PIPE0m:
    840     case EXACT_MATCH_2_PIPE1m:
    841         /* 2 entries per row
    842          * bank 0 - 7 -> shared banks - 16k entries each
    843          */
    844         row_size = 2;
    845         bucket_size = 4;
    846         offset = 0;
    847         bank_size = 16384;
    848         base = bank * bank_size;
    849         break;
    850     case EXACT_MATCH_4m:
    851     case EXACT_MATCH_4_PIPE0m:
    852     case EXACT_MATCH_4_PIPE1m:
    853         /* 1 entries per row
    854          * bank 0 - 7 -> shared banks - 8k entries each
    855          */
    856         row_size = 1;
    857         bucket_size = 4;
    858         offset = 0;
    859         bank_size = 8192;
    860         base = bank * bank_size;
    861         break;        
    862     case EGR_VLAN_XLATE_1_DOUBLEm:
    863     case EGR_VLAN_XLATE_2_DOUBLEm:
    864     case EGR_VLAN_XLATE_1_SINGLEm:
    865     case EGR_VLAN_XLATE_2_SINGLEm:
    866         /* 4 entries per bucket
    867          * bank 0 - 3 -> shared banks - 8k entries each
    868          */
    869         row_size = ((mem == EGR_VLAN_XLATE_1_DOUBLEm) ||
    870                     (mem == EGR_VLAN_XLATE_2_DOUBLEm)) ? 2 : 4;
    871         bucket_size = 4;
    872         offset = 0;
    873         bank_size = 8192;
    874         if ((mem == EGR_VLAN_XLATE_1_DOUBLEm) ||
    875             (mem == EGR_VLAN_XLATE_2_DOUBLEm)) {
    876             bank_size /= 2;
    877         }
    878         base = bank * bank_size;
    879         break;
    880     case MPLS_ENTRY_SINGLEm:
    881     case MPLS_ENTRYm:
    882     case VLAN_XLATE_1_DOUBLEm:
    883     case VLAN_XLATE_2_DOUBLEm:
    884     case VLAN_XLATE_1_SINGLEm:
    885     case VLAN_XLATE_2_SINGLEm:
    886         SOC_IF_ERROR_RETURN(soc_td3_iuat_hash_bank_count_get(unit, mem,
    887                                             &uat_16k_banks, &uat_8k_banks));
    888         row_size = ((mem == VLAN_XLATE_1_DOUBLEm) ||
    889                     (mem == VLAN_XLATE_2_DOUBLEm) ||
    890                     (mem == MPLS_ENTRYm)) ? 2 : 4;
    891         bucket_size = 4;
    892         offset = 0;
    893         if (bank < uat_8k_banks) {
    894             bank_size = 8192;
    895             base = bank * bank_size;
    896         } else {
    897             bank_size = 16384;
    898             base = 8192 * uat_8k_banks + bank_size * (bank - uat_8k_banks);
    899         }
    900         if ((mem == MPLS_ENTRYm) ||
    901             (mem == VLAN_XLATE_1_DOUBLEm) ||
    902             (mem == VLAN_XLATE_2_DOUBLEm)) {
    903             base /= 2;
    904         }
    905         break;
    906     case ING_VP_VLAN_MEMBERSHIPm:
    907     case EGR_VP_VLAN_MEMBERSHIPm:
    908     case ING_DNAT_ADDRESS_TYPEm:
    909     case SUBPORT_ID_TO_SGPP_MAPm:
    910         /* 
    911          * First half of entries in each row are for bank 0
    912          * Second half of entries are for bank 1
    913          */
    914         bank_size = soc_mem_index_count(unit, mem) / 2;
    915         row_size = 4;
    916         bucket_size = 4;
    917         base = bank * bank_size;
    918         offset = 0;
    919         break;
    920     default:
    921         return SOC_E_INTERNAL;
    922     }
    923 
    924     if (entries_per_bank != NULL) {
    925         *entries_per_bank = bank_size;
    926     }
    927     if (entries_per_row != NULL) {
    928         *entries_per_row = row_size;
    929     }
    930     if (entries_per_bucket != NULL) {
    931         *entries_per_bucket = bucket_size;
    932     }
    933     if (bank_base != NULL) {
    934         *bank_base = base;
    935     }
    936     if (bucket_offset != NULL) {
    937         *bucket_offset = offset;
    938     }
    939     return SOC_E_NONE;
    940 }
    941 
    942 STATIC int
    943 _soc_td3_hash_entry_to_key(int unit, int bank, void *entry, uint8 *key,
    944           soc_mem_t mem, soc_field_t *field_list, soc_mem_t mem_view)
    945 {
    946     soc_field_t field;
    947     int index, key_index, val_index, fval_index;
    948     int right_shift_count, left_shift_count;
    949     uint32 val[SOC_MAX_MEM_WORDS], fval[SOC_MAX_MEM_WORDS];
    950     int bits, val_bits, fval_bits, nbits;
    951     int8 field_length[16];
    952 
    953 #ifdef SOC_ROBUST_HASH
    954     soc_robust_hash_config_t *rbh_cfg = NULL;
    955 #endif /* SOC_ROBUST_HASH */
    956 
    957     val_bits = 0;
    958     for (index = 0; field_list[index] != INVALIDf; index++) {
    959         field = field_list[index];
    960         if (mem_view) {
    961             field_length[index] = soc_mem_field_length(unit, mem_view, field);
    962         } else {
    963             field_length[index] = soc_mem_field_length(unit, mem, field);
    964         }
    965         val_bits += field_length[index];
    966     }
    967 
    968     switch (mem) {
    969     case L2Xm:
    970         val_bits = SOC_TD3_L2_MAX_KEY_WIDTH;
    971         break;
    972     case L3_ENTRY_ONLY_SINGLEm:
    973     case L3_ENTRY_SINGLEm:
    974     case L3_ENTRY_DOUBLEm:
    975     case L3_ENTRY_QUADm:
    976         val_bits = SOC_TD3_L3_MAX_KEY_WIDTH;
    977         break;
    978     case EXACT_MATCH_2m:
    979     case EXACT_MATCH_4m:
    980         val_bits = SOC_TD3_EXACT_MATCH_MAX_KEY_WIDTH;
    981         break;
    982     case MPLS_ENTRY_SINGLEm:
    983     case MPLS_ENTRYm:
    984         val_bits = SOC_TD3_MPLS_MAX_KEY_WIDTH;
    985         break;
    986     case VLAN_XLATE_1_SINGLEm:
    987     case VLAN_XLATE_1_DOUBLEm:
    988     case VLAN_XLATE_2_SINGLEm:
    989     case VLAN_XLATE_2_DOUBLEm:
    990         val_bits = SOC_TD3_VLAN_XLATE_MAX_KEY_WIDTH;
    991         break;
    992     case EGR_VLAN_XLATE_1_SINGLEm:
    993     case EGR_VLAN_XLATE_1_DOUBLEm:
    994     case EGR_VLAN_XLATE_2_SINGLEm:
    995     case EGR_VLAN_XLATE_2_DOUBLEm:
    996         val_bits = SOC_TD3_EGR_VLAN_XLATE_MAX_KEY_WIDTH;
    997         break;
    998     case ING_VP_VLAN_MEMBERSHIPm:
    999         val_bits = SOC_TD3_ING_VP_VLAN_MEMBERSHIP_MAX_KEY_WIDTH;
   1000         break;
   1001     case EGR_VP_VLAN_MEMBERSHIPm:
   1002         val_bits = SOC_TD3_EGR_VP_VLAN_MEMBERSHIP_MAX_KEY_WIDTH;
   1003         break;
   1004     case ING_DNAT_ADDRESS_TYPEm:
   1005         val_bits = SOC_TD3_ING_DNAT_ADDRESS_TYPE_MAX_KEY_WIDTH;
   1006         break;
   1007     case SUBPORT_ID_TO_SGPP_MAPm:
   1008         val_bits = SOC_TD3_SUBPORT_ID_SGPP_MAP_MAX_KEY_WIDTH;
   1009         break;
   1010     default:
   1011         break;
   1012     }
   1013 
   1014     nbits = val_bits;
   1015 
   1016 #ifdef SOC_ROBUST_HASH
   1017     if (soc_feature(unit, soc_feature_robust_hash)) {
   1018         switch (mem) {
   1019         case L2Xm:
   1020             rbh_cfg = &(ROBUSTHASH(unit)->l2);
   1021             break;
   1022         case L3_ENTRY_ONLY_SINGLEm:
   1023         case L3_ENTRY_SINGLEm:
   1024         case L3_ENTRY_DOUBLEm:
   1025         case L3_ENTRY_QUADm:
   1026             rbh_cfg = &(ROBUSTHASH(unit)->l3);
   1027             break;
   1028         case EXACT_MATCH_4m:
   1029         case EXACT_MATCH_2m:
   1030             rbh_cfg = &(ROBUSTHASH(unit)->exact_match);
   1031             break;
   1032         case VLAN_XLATE_1_SINGLEm:
   1033         case VLAN_XLATE_1_DOUBLEm:
   1034             rbh_cfg = &(ROBUSTHASH(unit)->ing_xlate_1);
   1035             break;
   1036         case VLAN_XLATE_2_SINGLEm:
   1037         case VLAN_XLATE_2_DOUBLEm:
   1038             rbh_cfg = &(ROBUSTHASH(unit)->ing_xlate_2);
   1039             break;
   1040         case MPLS_ENTRY_SINGLEm:
   1041         case MPLS_ENTRYm:
   1042             rbh_cfg = &(ROBUSTHASH(unit)->mpls_entry);
   1043             break;
   1044         case EGR_VLAN_XLATE_1_SINGLEm:
   1045         case EGR_VLAN_XLATE_1_DOUBLEm:
   1046             rbh_cfg = &(ROBUSTHASH(unit)->egr_xlate_1);
   1047             break;
   1048         case EGR_VLAN_XLATE_2_SINGLEm:
   1049         case EGR_VLAN_XLATE_2_DOUBLEm:
   1050             rbh_cfg = &(ROBUSTHASH(unit)->egr_xlate_2);
   1051             break;
   1052         case ING_VP_VLAN_MEMBERSHIPm:
   1053             rbh_cfg = &(ROBUSTHASH(unit)->ing_vp_vlan_member);
   1054             break;
   1055         case EGR_VP_VLAN_MEMBERSHIPm:
   1056             rbh_cfg = &(ROBUSTHASH(unit)->egr_vp_vlan_member);
   1057             break;
   1058         case ING_DNAT_ADDRESS_TYPEm:
   1059             rbh_cfg = &(ROBUSTHASH(unit)->ing_dnat_address);
   1060             break;
   1061         case SUBPORT_ID_TO_SGPP_MAPm:
   1062             rbh_cfg = &(ROBUSTHASH(unit)->subport_id_sgpp_map);
   1063             break;
   1064         default:
   1065             break;
   1066         }
   1067     }
   1068 
   1069 #endif /* SOC_ROBUST_HASH */
   1070     bits = val_bits;
   1071     val_bits = 0;
   1072 
   1073     sal_memset(val, 0, sizeof(val));
   1074     for (index = 0; field_list[index] != INVALIDf; index++) {
   1075         field = field_list[index];
   1076         if (mem_view) {
   1077             soc_mem_field_get(unit, mem_view, entry, field, fval);
   1078         } else {
   1079             soc_mem_field_get(unit, mem, entry, field, fval);
   1080         }
   1081         fval_bits = field_length[index];
   1082 
   1083         val_index = val_bits >> 5;
   1084         fval_index = 0;
   1085         left_shift_count = val_bits & 0x1f;
   1086         right_shift_count = 32 - left_shift_count;
   1087         val_bits += fval_bits;
   1088 
   1089         if (left_shift_count) {
   1090             for (; fval_bits > 0; fval_bits -= 32) {
   1091                 val[val_index++] |= fval[fval_index] << left_shift_count;
   1092                 val[val_index] |= fval[fval_index++] >> right_shift_count;
   1093             }
   1094         } else {
   1095             for (; fval_bits > 0; fval_bits -= 32) {
   1096                 val[val_index++] = fval[fval_index++];
   1097             }
   1098         }
   1099     }
   1100 
   1101     key_index = 0;
   1102     for (val_index = 0; val_bits > 0; val_index++) {
   1103         for (right_shift_count = 0; right_shift_count < 32;
   1104              right_shift_count += 8) {
   1105             if (val_bits <= 0) {
   1106                 break;
   1107             }
   1108             key[key_index++] = (val[val_index] >> right_shift_count) & 0xff;
   1109             val_bits -= 8;
   1110         }
   1111     }
   1112 
   1113     if ((bits + 7) / 8 > key_index) {
   1114         sal_memset(&key[key_index], 0, (bits + 7) / 8 - key_index);
   1115     }
   1116 
   1117     bits = (((nbits - 1) / 32) + 1) * 32;
   1118 
   1119 #ifdef SOC_ROBUST_HASH
   1120     if (soc_feature(unit, soc_feature_robust_hash)) {
   1121         if (rbh_cfg) {
   1122             if (rbh_cfg->enable) {
   1123                 (void) soc_robust_hash_get(unit, rbh_cfg, bank, key, nbits);
   1124             }
   1125 
   1126         }
   1127     }
   1128 
   1129 #endif /* SOC_ROBUST_HASH */
   1130 
   1131     bits += ROBUST_HASH_KEY_SPACE_WIDTH;
   1132     return bits;
   1133 }
   1134 
   1135 int
   1136 soc_td3_hash_offset_get(int unit, soc_mem_t mem, int bank, int *hash_offset,
   1137                         int *use_lsb)
   1138 {
   1139     uint32 hash_control_entry[4];
   1140     int is_shared = 1;
   1141     soc_mem_t shared_mem = INVALIDm;
   1142     soc_field_t field;    
   1143     static const soc_field_t uft_fields[] = {
   1144         HASH_OFFSET_DEDICATED_BANK_0f, HASH_OFFSET_DEDICATED_BANK_1f,
   1145         B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf,
   1146         B4_HASH_OFFSETf, B5_HASH_OFFSETf, B6_HASH_OFFSETf, B7_HASH_OFFSETf
   1147 
   1148     };
   1149     static const soc_field_t uat_fields[] = {
   1150         B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf
   1151     };
   1152 
   1153     sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
   1154 
   1155     switch(mem) {
   1156     case L2Xm:
   1157         /* Sanity Check */
   1158         if (bank < 0 || bank > 9) {
   1159             return SOC_E_PARAM;
   1160         }
   1161         mem = L2_ENTRY_HASH_CONTROLm;
   1162         shared_mem = UFT_SHARED_BANKS_CONTROLm;
   1163         is_shared = bank > 1;
   1164         field = uft_fields[bank];
   1165         break;
   1166     case L3_ENTRY_ONLY_SINGLEm:
   1167 #ifdef BCM_TRIDENT3_SUPPORT
   1168     case L3_ENTRY_SINGLEm:
   1169     case L3_ENTRY_DOUBLEm:
   1170     case L3_ENTRY_QUADm:
   1171 #endif /* BCM_TRIDENT3_SUPPORT */
   1172         if (bank < 2 || bank > 11) {
   1173             return SOC_E_PARAM;
   1174         }
   1175         /* Dedicated banks */
   1176         if (bank >= 10 && bank <= 11) {
   1177             bank = bank - 10;
   1178             is_shared = 0;
   1179         }
   1180         mem = L3_ENTRY_HASH_CONTROLm;
   1181         shared_mem = UFT_SHARED_BANKS_CONTROLm;
   1182         field = uft_fields[bank];
   1183         break;
   1184     case EXACT_MATCH_2m:
   1185         if (bank < 2 || bank > 9) {
   1186             return SOC_E_PARAM;
   1187         }
   1188         mem = EXACT_MATCH_HASH_CONTROLm;
   1189         shared_mem = UFT_SHARED_BANKS_CONTROLm;
   1190         field = uft_fields[bank];
   1191         break;
   1192     case EGR_VLAN_XLATE_1_SINGLEm:
   1193     case EGR_VLAN_XLATE_1_DOUBLEm:
   1194         if (bank < 0 || bank > 3) {
   1195             return SOC_E_PARAM;
   1196         }
   1197         mem = EGR_VLAN_XLATE_1_HASH_CONTROLm;
   1198         shared_mem = EP_UAT_SHARED_BANKS_CONTROLm;
   1199         field = uat_fields[bank];
   1200         break;
   1201     case EGR_VLAN_XLATE_2_SINGLEm:
   1202     case EGR_VLAN_XLATE_2_DOUBLEm:
   1203         if (bank < 0 || bank > 3) {
   1204             return SOC_E_PARAM;
   1205         }
   1206         mem = EGR_VLAN_XLATE_2_HASH_CONTROLm;
   1207         shared_mem = EP_UAT_SHARED_BANKS_CONTROLm;
   1208         field = uat_fields[bank];
   1209         break;
   1210     case MPLS_ENTRY_SINGLEm:
   1211     case MPLS_ENTRYm:
   1212         if (bank < 0 || bank > 7) {
   1213             return SOC_E_PARAM;
   1214         }
   1215         mem = MPLS_ENTRY_HASH_CONTROLm;
   1216         if (bank >= 4) { /* 16k size bank */
   1217             bank = bank - 4;
   1218             shared_mem = IP_UAT_16K_SHARED_BANKS_CONTROLm;
   1219         } else { /* 8k size bank */
   1220             shared_mem = IP_UAT_8K_SHARED_BANKS_CONTROLm;
   1221         }
   1222         field = uat_fields[bank];
   1223         break;
   1224     case VLAN_XLATE_1_SINGLEm:
   1225     case VLAN_XLATE_1_DOUBLEm:
   1226         if (bank < 0 || bank > 7) {
   1227             return SOC_E_PARAM;
   1228         }
   1229         mem = VLAN_XLATE_1_HASH_CONTROLm;
   1230         if (bank >= 4) { /* 16k size bank */
   1231             bank = bank - 4;
   1232             shared_mem = IP_UAT_16K_SHARED_BANKS_CONTROLm;
   1233         } else { /* 8k size bank */
   1234             shared_mem = IP_UAT_8K_SHARED_BANKS_CONTROLm;
   1235         }
   1236         field = uat_fields[bank];
   1237         break;
   1238     case VLAN_XLATE_2_SINGLEm:
   1239     case VLAN_XLATE_2_DOUBLEm:
   1240         if (bank < 0 || bank > 7) {
   1241             return SOC_E_PARAM;
   1242         }
   1243         mem = VLAN_XLATE_2_HASH_CONTROLm;
   1244         if (bank >= 4) { /* 16k size bank */
   1245             bank = bank - 4;
   1246             shared_mem = IP_UAT_16K_SHARED_BANKS_CONTROLm;
   1247         } else { /* 8k size bank */
   1248             shared_mem = IP_UAT_8K_SHARED_BANKS_CONTROLm;
   1249         }
   1250         field = uat_fields[bank];
   1251         break;
   1252     case ING_VP_VLAN_MEMBERSHIPm:
   1253         if (bank < 0 || bank > 2) {
   1254             return SOC_E_PARAM;
   1255         }
   1256         mem = ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm;
   1257         field = uft_fields[bank];
   1258         is_shared = 0;
   1259         break;
   1260     case EGR_VP_VLAN_MEMBERSHIPm:
   1261         if (bank < 0 || bank > 2) {
   1262             return SOC_E_PARAM;
   1263         }
   1264         mem = EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm;
   1265         field = uft_fields[bank];
   1266         is_shared = 0;  
   1267         break;
   1268     case ING_DNAT_ADDRESS_TYPEm:
   1269         if (bank < 0 || bank > 2) {
   1270             return SOC_E_PARAM;
   1271         }
   1272         mem = ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm;
   1273         field = uft_fields[bank];
   1274         is_shared = 0; 
   1275         break;
   1276     case SUBPORT_ID_TO_SGPP_MAPm:
   1277         if (bank < 0 || bank > 2) {
   1278             return SOC_E_PARAM;
   1279         }
   1280         mem = SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm;
   1281         field = uft_fields[bank];
   1282         is_shared = 0; 
   1283         break;
   1284     default:
   1285         return SOC_E_INTERNAL;
   1286     }
   1287 
   1288     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0,
   1289                                      hash_control_entry));
   1290     *use_lsb = soc_mem_field32_get(unit, mem, hash_control_entry,
   1291                                    HASH_TABLE_TEST_MODEf);
   1292 
   1293     /* Shared Banks */
   1294     if (is_shared > 0) {
   1295         sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
   1296         SOC_IF_ERROR_RETURN(soc_mem_read(unit, shared_mem, MEM_BLOCK_ALL, 0,
   1297                                          hash_control_entry));
   1298         /* If Shared banks are used between ALPM and non-ALPM memories,
   1299          * then ALPM uses Shared Bank B2, B3, B4, B5 and non-ALPM uses
   1300          * B6, B7, B8, B9 banks. Maximum phy bank number for UFT is 9.
   1301          */
   1302         if (_soc_alpm_mode[unit] && ((mem == L2_ENTRY_HASH_CONTROLm) ||
   1303                             (mem == L3_ENTRY_HASH_CONTROLm) ||
   1304                             (mem == EXACT_MATCH_HASH_CONTROLm)) &&
   1305                             (bank <=5)) {
   1306             field = uft_fields[bank + 4];
   1307         }
   1308         *hash_offset = soc_mem_field32_get(unit, shared_mem,
   1309                                            hash_control_entry, field);
   1310     } else {
   1311         *hash_offset = soc_mem_field32_get(unit, mem, hash_control_entry, field);
   1312     }
   1313 
   1314     return SOC_E_NONE;
   1315 
   1316 }
   1317 
   1318 int
   1319 soc_td3_hash_offset_set(int unit, soc_mem_t mem, int bank, int hash_offset,
   1320                         int use_lsb)
   1321 {
   1322     uint32 hash_control_entry[4];
   1323     int is_shared = 1;
   1324     soc_mem_t shared_mem = INVALIDm;
   1325     soc_field_t field;
   1326     static const soc_field_t uft_fields[] = {
   1327         HASH_OFFSET_DEDICATED_BANK_0f, HASH_OFFSET_DEDICATED_BANK_1f,
   1328         B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf,
   1329         B4_HASH_OFFSETf, B5_HASH_OFFSETf, B6_HASH_OFFSETf, B7_HASH_OFFSETf
   1330 
   1331     };
   1332     static const soc_field_t uat_fields[] = {
   1333         B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf
   1334     };
   1335 
   1336     sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
   1337 
   1338     switch(mem) {
   1339     case L2Xm:
   1340         /* Sanity Check */
   1341         if (bank < 0 || bank > 9) {
   1342             return SOC_E_PARAM;
   1343         }
   1344         mem = L2_ENTRY_HASH_CONTROLm;
   1345         shared_mem = UFT_SHARED_BANKS_CONTROLm;
   1346         is_shared = bank > 1;
   1347         field = uft_fields[bank];
   1348         break;
   1349     case L3_ENTRY_ONLY_SINGLEm:
   1350         if (bank < 2 || bank > 11) {
   1351             return SOC_E_PARAM;
   1352         }
   1353         /* Dedicated banks */
   1354         if (bank >= 10 && bank <= 11) {
   1355             is_shared = 0;
   1356         }
   1357         mem = L3_ENTRY_HASH_CONTROLm;
   1358         shared_mem = UFT_SHARED_BANKS_CONTROLm;
   1359         field = uft_fields[(bank > 9)? (bank - 10) : bank];
   1360         break;
   1361     case EXACT_MATCH_2m:
   1362     case EXACT_MATCH_4m:
   1363         if (bank < 2 || bank > 9) {
   1364             return SOC_E_PARAM;
   1365         }
   1366         mem = EXACT_MATCH_HASH_CONTROLm;
   1367         shared_mem = UFT_SHARED_BANKS_CONTROLm;
   1368         field = uft_fields[bank];
   1369         break;
   1370     case EGR_VLAN_XLATE_1_SINGLEm:
   1371         if (bank < 0 || bank > 3) {
   1372             return SOC_E_PARAM;
   1373         }
   1374         mem = EGR_VLAN_XLATE_1_HASH_CONTROLm;
   1375         shared_mem = EP_UAT_SHARED_BANKS_CONTROLm;
   1376         field = uat_fields[bank];
   1377         break;
   1378     case EGR_VLAN_XLATE_2_SINGLEm:
   1379         if (bank < 0 || bank > 3) {
   1380             return SOC_E_PARAM;
   1381         }
   1382         mem = EGR_VLAN_XLATE_2_HASH_CONTROLm;
   1383         shared_mem = EP_UAT_SHARED_BANKS_CONTROLm;
   1384         field = uat_fields[bank];
   1385         break;
   1386     case MPLS_ENTRY_SINGLEm:
   1387     case MPLS_ENTRYm:
   1388         if (bank < 0 || bank > 7) {
   1389             return SOC_E_PARAM;
   1390         }
   1391         mem = MPLS_ENTRY_HASH_CONTROLm;
   1392         if (bank >= 4) { /* 16k size bank */
   1393             bank = bank - 4;
   1394             shared_mem = IP_UAT_16K_SHARED_BANKS_CONTROLm;
   1395         } else { /* 8k size bank */
   1396             shared_mem = IP_UAT_8K_SHARED_BANKS_CONTROLm;
   1397         }
   1398         field = uat_fields[bank];
   1399         break;
   1400     case VLAN_XLATE_1_SINGLEm:
   1401         if (bank < 0 || bank > 7) {
   1402             return SOC_E_PARAM;
   1403         }
   1404         mem = VLAN_XLATE_1_HASH_CONTROLm;
   1405         if (bank >= 4) { /* 16k size bank */
   1406             bank = bank - 4;
   1407             shared_mem = IP_UAT_16K_SHARED_BANKS_CONTROLm;
   1408         } else { /* 8k size bank */
   1409             shared_mem = IP_UAT_8K_SHARED_BANKS_CONTROLm;
   1410         }
   1411         field = uat_fields[bank];
   1412         break;
   1413     case VLAN_XLATE_2_SINGLEm:
   1414         if (bank < 0 || bank > 7) {
   1415             return SOC_E_PARAM;
   1416         }
   1417         mem = VLAN_XLATE_2_HASH_CONTROLm;
   1418         if (bank >= 4) { /* 16k size bank */
   1419             bank = bank - 4;
   1420             shared_mem = IP_UAT_16K_SHARED_BANKS_CONTROLm;
   1421         } else { /* 8k size bank */
   1422             shared_mem = IP_UAT_8K_SHARED_BANKS_CONTROLm;
   1423         }
   1424         field = uat_fields[bank];
   1425         break;
   1426     case ING_VP_VLAN_MEMBERSHIPm:
   1427         if (bank < 0 || bank > 2) {
   1428             return SOC_E_PARAM;
   1429         }
   1430         mem = ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm;
   1431         field = uft_fields[bank];
   1432         is_shared = 0;
   1433         break;
   1434     case EGR_VP_VLAN_MEMBERSHIPm:
   1435         if (bank < 0 || bank > 2) {
   1436             return SOC_E_PARAM;
   1437         }
   1438         mem = EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm;
   1439         field = uft_fields[bank];
   1440         is_shared = 0;  
   1441         break;
   1442     case ING_DNAT_ADDRESS_TYPEm:
   1443         if (bank < 0 || bank > 2) {
   1444             return SOC_E_PARAM;
   1445         }
   1446         mem = ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm;
   1447         field = uft_fields[bank];
   1448         is_shared = 0; 
   1449         break;
   1450     case SUBPORT_ID_TO_SGPP_MAPm:
   1451         if (bank < 0 || bank > 2) {
   1452             return SOC_E_PARAM;
   1453         }
   1454         mem = SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm;
   1455         field = uft_fields[bank];
   1456         is_shared = 0; 
   1457         break;
   1458     default:
   1459         return SOC_E_INTERNAL;
   1460     }
   1461 
   1462     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0,
   1463                                      hash_control_entry));
   1464     soc_mem_field32_set(unit, mem, hash_control_entry, HASH_TABLE_TEST_MODEf,
   1465                         use_lsb);
   1466     if (is_shared == 0) {
   1467         soc_mem_field32_set(unit, mem, hash_control_entry, field, hash_offset);
   1468     }
   1469     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0,
   1470                                         hash_control_entry));
   1471 
   1472     if (is_shared > 0) {
   1473         sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
   1474         SOC_IF_ERROR_RETURN(soc_mem_read(unit, shared_mem, MEM_BLOCK_ALL, 0,
   1475                                             hash_control_entry));
   1476         soc_mem_field32_set(unit, shared_mem, hash_control_entry, field,
   1477                                 hash_offset);
   1478         SOC_IF_ERROR_RETURN(soc_mem_write(unit, shared_mem, MEM_BLOCK_ALL, 0,
   1479                                             hash_control_entry));
   1480     }
   1481     return SOC_E_NONE;
   1482 }
   1483 
   1484 STATIC int
   1485 _soc_td3_shared_hash(int unit, int hash_offset, uint32 key_nbits, uint8 *keyA,
   1486                      uint8 *keyB, uint32 result_mask, uint16 lsb, int use_lsb)
   1487 {
   1488    uint32 crc_hi, crc_lo;
   1489    uint64 hash_vector, mask;
   1490 
   1491    if (use_lsb) {
   1492        /* Debug Mode 
   1493         * Hash Vector [63:48] ->  Zero
   1494         * Hash Vector [47:32] ->  Hash LSB
   1495         */
   1496        crc_hi = lsb;
   1497    } else {
   1498        crc_hi = soc_crc32b(keyB, key_nbits);
   1499    }
   1500 
   1501    crc_lo = soc_crc32b(keyA, key_nbits);
   1502 
   1503    COMPILER_64_SET(hash_vector, crc_hi, crc_lo);
   1504    COMPILER_64_SET(mask, 0, result_mask);
   1505    COMPILER_64_SHR(hash_vector, hash_offset);
   1506    COMPILER_64_AND(hash_vector, mask);
   1507    return (int)COMPILER_64_LO(hash_vector);
   1508 }
   1509 
   1510 int
   1511 soc_td3_hash_index_get(int unit, int mem, int bank, int bucket)
   1512 {
   1513     int rv;
   1514     int index;
   1515     int entries_per_row, bank_base, bucket_offset, entries_per_bucket;
   1516 
   1517     switch(mem) {
   1518     case L2Xm:
   1519         rv = soc_td3_hash_bank_info_get(unit, mem, bank, NULL, &entries_per_row,
   1520                                         NULL, &bank_base, &bucket_offset);
   1521         if (SOC_SUCCESS(rv)) {
   1522             return bank_base + bucket * entries_per_row + bucket_offset;
   1523         }
   1524         break;
   1525     case L3_ENTRY_ONLY_SINGLEm:
   1526     case L3_ENTRY_SINGLEm:
   1527     case L3_ENTRY_DOUBLEm:
   1528     case L3_ENTRY_QUADm:
   1529         rv = soc_td3_hash_bank_info_get(unit, mem, bank, NULL,
   1530                                         &entries_per_row, NULL, &bank_base,
   1531                                         &bucket_offset);
   1532         if (SOC_SUCCESS(rv)) {
   1533             index = bank_base + bucket * entries_per_row + bucket_offset;
   1534             return index;
   1535         }
   1536         break;
   1537     case EXACT_MATCH_2m:
   1538     case EXACT_MATCH_2_PIPE0m:
   1539     case EXACT_MATCH_2_PIPE1m:
   1540     case EXACT_MATCH_4m:
   1541     case EXACT_MATCH_4_PIPE0m:
   1542     case EXACT_MATCH_4_PIPE1m:
   1543     case VLAN_XLATE_1_SINGLEm:
   1544     case VLAN_XLATE_1_DOUBLEm:
   1545     case VLAN_XLATE_2_SINGLEm:
   1546     case VLAN_XLATE_2_DOUBLEm:
   1547     case EGR_VLAN_XLATE_1_SINGLEm:
   1548     case EGR_VLAN_XLATE_1_DOUBLEm:
   1549     case EGR_VLAN_XLATE_2_SINGLEm:
   1550     case EGR_VLAN_XLATE_2_DOUBLEm:
   1551     case MPLS_ENTRY_SINGLEm:
   1552     case MPLS_ENTRYm:
   1553         rv = soc_td3_hash_bank_info_get(unit, mem, bank, NULL,
   1554                                         &entries_per_row, &entries_per_bucket,
   1555                                         &bank_base, &bucket_offset);
   1556         if (SOC_SUCCESS(rv)) {
   1557             index = bank_base + bucket * entries_per_bucket + bucket_offset;
   1558             return index;
   1559         }
   1560         break;
   1561     case ING_VP_VLAN_MEMBERSHIPm:
   1562     case EGR_VP_VLAN_MEMBERSHIPm:
   1563     case ING_DNAT_ADDRESS_TYPEm:
   1564     case SUBPORT_ID_TO_SGPP_MAPm:
   1565         rv = soc_td3_hash_bank_info_get(unit, mem, bank, NULL,
   1566                                     &entries_per_row, NULL, &bank_base,
   1567                                     &bucket_offset);
   1568         if (SOC_SUCCESS(rv)) {
   1569             index = bank_base + bucket * entries_per_row + bucket_offset;
   1570             return index;
   1571         }
   1572         break;
   1573     default:
   1574         break;
   1575     }
   1576 
   1577     return 0;
   1578 
   1579 }
   1580 
   1581 #define SOC_FLEX_HASH_KEY_NUM 4
   1582 extern
   1583 int soc_flex_hash_mem_view_get(int unit, soc_mem_t mem,uint32 *entry,
   1584                        soc_mem_t *mem_view, soc_field_t *field_list)
   1585 {
   1586     int data_type = 0;
   1587     int key_type = 0;
   1588     int rv, i=0;
   1589     soc_mem_t mem_view_id;
   1590     soc_field_t key_fields[SOC_FLEX_HASH_KEY_NUM] =
   1591         {KEY_0f, KEY_1f, KEY_2f, KEY_3f};
   1592 
   1593 
   1594     if (SOC_MEM_FIELD_VALID(unit,mem,KEY_TYPEf)) {
   1595         key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPEf);
   1596     }
   1597     if (SOC_MEM_FIELD_VALID(unit,mem,DATA_TYPEf)) {
   1598         data_type = soc_mem_field32_get(unit, mem, entry, DATA_TYPEf);
   1599     }
   1600 
   1601     /* find the memory view based on the memory and key type */
   1602     rv = soc_flow_db_mem_to_view_id_get (unit, mem, key_type, data_type,
   1603                     0, NULL, (uint32 *)&mem_view_id);
   1604 
   1605     SOC_IF_ERROR_RETURN(rv);
   1606 
   1607     *mem_view = mem_view_id;
   1608 
   1609     for (i = 0; i < SOC_FLEX_HASH_KEY_NUM; i++) {
   1610         if (soc_mem_view_field_valid(unit, mem_view_id, key_fields[i])) {
   1611             field_list[i] = key_fields[i];
   1612         } else {
   1613             break;
   1614         }
   1615     }
   1616     field_list[i] = INVALIDf;
   1617     return SOC_E_NONE;
   1618 }
   1619 
   1620 uint32
   1621 soc_td3_l2x_hash(int unit, int bank, int hash_offset, int use_lsb,
   1622                  int key_nbits, void *base_entry, uint8 *key1, uint8 *key2)
   1623 {
   1624     uint32 lsb_val;
   1625     uint32 hash_mask;
   1626     uint32 hash_bits;
   1627 
   1628     if (bank < 2) {
   1629         hash_mask = 0x0FFF; /* 4k buckets per dedicated L2 bank */
   1630         hash_bits = 12;
   1631     } else {
   1632         hash_mask = 0x1FFF; /* 8k buckets per shared bank */
   1633         hash_bits = 13;
   1634     }
   1635 
   1636     if (use_lsb && (hash_offset + hash_bits > 32)) {
   1637         switch (soc_mem_field32_get(unit, L2Xm, base_entry, KEY_TYPEf)) {
   1638         case TD3_L2_HASH_KEY_TYPE_BRIDGE:
   1639         case TD3_L2_HASH_KEY_TYPE_VFI:
   1640         case TD3_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS:
   1641             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1642                                           L2__HASH_LSBf);
   1643             break;
   1644         case TD3_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT:
   1645         case TD3_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT:
   1646             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1647                                           VLAN__HASH_LSBf);
   1648             break;
   1649         case TD3_L2_HASH_KEY_TYPE_VIF:
   1650             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1651                                           VIF__HASH_LSBf);
   1652             break;
   1653         case TD3_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG:
   1654             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1655                                           TRILL_NONUC_NETWORK_LONG__HASH_LSBf);
   1656             break;
   1657         case TD3_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT:
   1658             lsb_val = soc_mem_field32_get
   1659                 (unit, L2Xm, base_entry, TRILL_NONUC_NETWORK_SHORT__HASH_LSBf);
   1660             break;
   1661         case TD3_L2_HASH_KEY_TYPE_BFD:
   1662             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1663                                           BFD__HASH_LSBf);
   1664             break;
   1665         case TD3_L2_HASH_KEY_TYPE_PE_VID:
   1666             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1667                                           PE_VID__HASH_LSBf);
   1668             break;
   1669         case TD3_L2_HASH_KEY_TYPE_FCOE_ZONE:
   1670             lsb_val = soc_mem_field32_get(unit, L2Xm, base_entry,
   1671                                           FCOE_ZONE__HASH_LSBf);
   1672             break;
   1673         default:
   1674             lsb_val = 0;
   1675             break;
   1676         }
   1677     } else {
   1678         lsb_val = 0;
   1679     }
   1680 
   1681     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   1682                                 hash_mask, lsb_val, use_lsb);
   1683 }
   1684 
   1685 int
   1686 soc_td3_l2x_base_entry_to_key(int unit, int bank, uint32 *entry, uint8 *key)
   1687 {
   1688     soc_field_t field_list[5];
   1689     soc_mem_t   flex_mem_view = 0;
   1690 
   1691     field_list[1] = INVALIDf;
   1692 
   1693     switch (soc_mem_field32_get(unit, L2Xm, entry, KEY_TYPEf)) {
   1694     case TD3_L2_HASH_KEY_TYPE_BRIDGE:
   1695     case TD3_L2_HASH_KEY_TYPE_VFI:
   1696     case TD3_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS:
   1697         field_list[0] = L2__KEYf;
   1698         break;
   1699     case TD3_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT:
   1700     case TD3_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT:
   1701         field_list[0] = VLAN__KEYf;
   1702         break;
   1703     case TD3_L2_HASH_KEY_TYPE_VIF:
   1704         field_list[0] = VIF__KEYf;
   1705         break;
   1706     case TD3_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG:
   1707         field_list[0] = TRILL_NONUC_NETWORK_LONG__KEYf;
   1708         break;
   1709     case TD3_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT:
   1710         field_list[0] = TRILL_NONUC_NETWORK_SHORT__KEYf;
   1711         break;
   1712     case TD3_L2_HASH_KEY_TYPE_BFD:
   1713         field_list[0] = BFD__KEYf;
   1714         break;
   1715     case TD3_L2_HASH_KEY_TYPE_PE_VID:
   1716         field_list[0] = PE_VID__KEYf;
   1717         break;
   1718     case TD3_L2_HASH_KEY_TYPE_FCOE_ZONE:
   1719         field_list[0] = FCOE_ZONE__KEYf;
   1720         break;
   1721     default:
   1722         SOC_IF_ERROR_RETURN(soc_flex_hash_mem_view_get(unit,
   1723                    L2Xm, entry, &flex_mem_view, field_list));
   1724         break;
   1725     }
   1726 
   1727     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   1728                             L2Xm, field_list, flex_mem_view);
   1729 }
   1730 
   1731 uint32
   1732 soc_td3_l2x_entry_hash(int unit, int bank, int hash_offset, int use_lsb,
   1733                       uint32 *entry) {
   1734     int key_nbits;
   1735     uint8 key1[SOC_MAX_MEM_WORDS * 4] = {0};
   1736     uint8 key2[SOC_MAX_MEM_WORDS * 4] = {0};
   1737 
   1738     /* Robust Hashed Key using Remap and Action Tables A */
   1739     key_nbits = soc_td3_l2x_base_entry_to_key(unit, 0, entry, key1);
   1740     /* Robust Hashed Key using Remap and Action Tables B */
   1741     key_nbits = soc_td3_l2x_base_entry_to_key(unit, 1, entry, key2);
   1742     
   1743     return soc_td3_l2x_hash(unit, bank, hash_offset, use_lsb, key_nbits, entry,
   1744                             key1, key2);
   1745 }
   1746 
   1747 uint32
   1748 soc_td3_l2x_bank_entry_hash(int unit, int bank, uint32 *entry) {
   1749     int rv, hash_offset, use_lsb;
   1750 
   1751     rv = soc_td3_hash_offset_get(unit, L2Xm, bank, &hash_offset, &use_lsb);
   1752     if (SOC_FAILURE(rv)) {
   1753         return 0;
   1754     }
   1755     return soc_td3_l2x_entry_hash(unit, bank, hash_offset, use_lsb, entry);
   1756 }
   1757 
   1758 uint32
   1759 soc_td3_l3x_hash(int unit, int bank, int hash_offset, int use_lsb,
   1760                  int key_nbits, void *base_entry, uint8 *key1, uint8 *key2)
   1761 {
   1762     uint32 lsb_val;
   1763     uint32 hash_mask;
   1764     uint32 hash_bits;
   1765 
   1766     if (bank > 9) {
   1767         hash_mask = 0x7FF; /* 2k buckets per dedicated banks */
   1768         hash_bits = 11;
   1769     } else {
   1770         hash_mask = 0x1FFF; /* 8k buckets per shared bank */
   1771         hash_bits = 13;
   1772     }
   1773 
   1774     if (use_lsb && (hash_offset + hash_bits > 32)) {
   1775         switch (soc_mem_field32_get(unit, L3_ENTRY_ONLY_SINGLEm, base_entry,
   1776                                     KEY_TYPEf)) {
   1777         case TD3_L3_HASH_KEY_TYPE_V4UC:
   1778         case TD3_L3_HASH_KEY_TYPE_V4MC:
   1779         case TD3_L3_HASH_KEY_TYPE_V6UC:
   1780         case TD3_L3_HASH_KEY_TYPE_V6MC:
   1781             lsb_val = soc_mem_field32_get(unit, L3_ENTRY_SINGLEm,
   1782                                           base_entry, IPV4UC__HASH_LSBf);
   1783             break;
   1784         case TD3_L3_HASH_KEY_TYPE_TRILL:
   1785             lsb_val = soc_mem_field32_get(unit, L3_ENTRY_SINGLEm,
   1786                                           base_entry, TRILL__HASH_LSBf);
   1787             break;
   1788         case TD3_L3_HASH_KEY_TYPE_DST_NAT:
   1789         case TD3_L3_HASH_KEY_TYPE_DST_NAPT:
   1790             lsb_val = soc_mem_field32_get(unit, L3_ENTRY_DOUBLEm,
   1791                                           base_entry, NAT__HASH_LSBf);
   1792             break;
   1793         case TD3_L3_HASH_KEY_TYPE_FCOE_DOMAIN:
   1794         case TD3_L3_HASH_KEY_TYPE_FCOE_HOST:
   1795         case TD3_L3_HASH_KEY_TYPE_FCOE_SOURCE_MAP:
   1796             lsb_val = soc_mem_field32_get(unit, L3_ENTRY_SINGLEm, base_entry,
   1797                                           FCOE__HASH_LSBf);
   1798             break;
   1799         default:
   1800             lsb_val = 0;
   1801             break;
   1802         }
   1803     } else {
   1804         lsb_val = 0;
   1805     }
   1806     
   1807     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   1808                                 hash_mask, lsb_val, use_lsb);
   1809 }
   1810 
   1811 int
   1812 soc_td3_l3x_base_entry_to_key(int unit, int bank, uint32 *entry, uint8 *key)
   1813 {
   1814     soc_mem_t mem;
   1815     soc_field_t field_list[5];
   1816     soc_mem_t   flex_mem_view = 0;
   1817     
   1818     switch (soc_mem_field32_get(unit, L3_ENTRY_ONLY_SINGLEm, entry, KEY_TYPEf)) {
   1819     case TD3_L3_HASH_KEY_TYPE_V4UC:
   1820         mem = L3_ENTRY_SINGLEm;
   1821         field_list[0] = IPV4UC__KEYf;
   1822         field_list[1] = INVALIDf;
   1823         break;
   1824     case TD3_L3_HASH_KEY_TYPE_V6UC:
   1825         mem = L3_ENTRY_DOUBLEm;
   1826         field_list[0] = IPV6UC__KEY_0f;
   1827         field_list[1] = IPV6UC__KEY_1f;
   1828         field_list[2] = INVALIDf;
   1829         break;
   1830     case TD3_L3_HASH_KEY_TYPE_V4MC:
   1831     case TD3_L3_HASH_KEY_TYPE_L2_IPV4_MULTICAST:
   1832     case TD3_L3_HASH_KEY_TYPE_L2VP_IPV4_MULTICAST:
   1833         mem = L3_ENTRY_DOUBLEm;
   1834         field_list[0] = IPV4MC__KEYf;
   1835         field_list[1] = INVALIDf;
   1836         break;
   1837     case TD3_L3_HASH_KEY_TYPE_V6MC:
   1838     case TD3_L3_HASH_KEY_TYPE_L2_IPV6_MULTICAST:
   1839     case TD3_L3_HASH_KEY_TYPE_L2VP_IPV6_MULTICAST:
   1840         mem = L3_ENTRY_QUADm;
   1841         field_list[0] = IPV6MC__KEY_0f;
   1842         field_list[1] = IPV6MC__KEY_1f;
   1843         field_list[2] = IPV6MC__KEY_2f;
   1844         field_list[3] = INVALIDf;
   1845         break;
   1846     case TD3_L3_HASH_KEY_TYPE_TRILL:
   1847         mem = L3_ENTRY_SINGLEm;
   1848         field_list[0] = TRILL__KEYf;
   1849         field_list[1] = INVALIDf;
   1850         break;
   1851     case TD3_L3_HASH_KEY_TYPE_FCOE_DOMAIN:
   1852     case TD3_L3_HASH_KEY_TYPE_FCOE_HOST:
   1853     case TD3_L3_HASH_KEY_TYPE_FCOE_SOURCE_MAP:
   1854         mem = L3_ENTRY_SINGLEm;
   1855         field_list[0] = FCOE__KEYf;
   1856         field_list[1] = INVALIDf;
   1857         break;
   1858     case TD3_L3_HASH_KEY_TYPE_DST_NAT:
   1859     case TD3_L3_HASH_KEY_TYPE_DST_NAPT:
   1860         mem = L3_ENTRY_DOUBLEm;
   1861         field_list[0] = NAT__KEY_0f;
   1862         field_list[1] = INVALIDf;
   1863         break;
   1864 
   1865     default:
   1866         mem = L3_ENTRY_DOUBLEm;
   1867         SOC_IF_ERROR_RETURN(soc_flex_hash_mem_view_get(unit,
   1868                    mem, entry, &flex_mem_view, field_list));
   1869         break;
   1870     }
   1871     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   1872                              mem, field_list, flex_mem_view);
   1873 }
   1874 
   1875 uint32
   1876 soc_td3_l3x_entry_hash(int unit, int bank, int hash_offset, int use_lsb,
   1877                       uint32 *entry)
   1878 {
   1879     int             key_nbits;
   1880     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   1881     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   1882 
   1883     /* Robust Hashed Key using Remap and Action Tables A */
   1884     key_nbits = soc_td3_l3x_base_entry_to_key(unit, 0, entry, key1);
   1885     /* Robust Hashed Key using Remap and Action Tables B */
   1886     key_nbits = soc_td3_l3x_base_entry_to_key(unit, 1, entry, key2);
   1887 
   1888     return soc_td3_l3x_hash(unit, bank, hash_offset, use_lsb, key_nbits,
   1889                             entry, key1, key2);
   1890 }
   1891 
   1892 uint32
   1893 soc_td3_l3x_bank_entry_hash(int unit, int bank, uint32 *entry)
   1894 {
   1895     int rv, hash_offset, use_lsb;
   1896 
   1897     rv = soc_td3_hash_offset_get(unit, L3_ENTRY_ONLY_SINGLEm, bank, &hash_offset,
   1898                                 &use_lsb);
   1899     if (SOC_FAILURE(rv)) {
   1900         return 0;
   1901     }
   1902 
   1903     return soc_td3_l3x_entry_hash(unit, bank, hash_offset, use_lsb, entry);
   1904 }
   1905 
   1906 uint32
   1907 soc_td3_exact_match_hash(int unit, int bank, int hash_offset, int use_lsb,
   1908                          int key_nbits, void *base_entry, uint8 *key1,
   1909                          uint8 *key2)
   1910 {
   1911     uint32 lsb_val;
   1912     uint32 hash_mask;
   1913     uint32 hash_bits;
   1914 
   1915     hash_mask = 0xfff; /* 4k buckets per shared bank for EXACT_MATCH_2m */
   1916     hash_bits = 12;
   1917 
   1918     if (use_lsb && (hash_offset + hash_bits > 32)) {
   1919         switch (soc_mem_field32_get(unit, EXACT_MATCH_2m, base_entry,
   1920                                     KEY_TYPEf)) {
   1921         case TD3_FPEM_HASH_KEY_TYPE_128B:
   1922             lsb_val = soc_mem_field32_get(unit, EXACT_MATCH_2m, base_entry,
   1923                                           MODE128__HASH_LSBf);
   1924             break;
   1925         case TD3_FPEM_HASH_KEY_TYPE_160B:
   1926             lsb_val = soc_mem_field32_get(unit, EXACT_MATCH_2m, base_entry,
   1927                                           MODE160__HASH_LSBf);
   1928             break;
   1929         case TD3_FPEM_HASH_KEY_TYPE_320B:
   1930             lsb_val = soc_mem_field32_get(unit, EXACT_MATCH_4m, base_entry,
   1931                                           MODE320__HASH_LSBf);
   1932             break;
   1933         default:
   1934             lsb_val = 0;
   1935             break;
   1936         }
   1937     } else {
   1938         lsb_val = 0;
   1939     }
   1940 
   1941     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   1942                                 hash_mask, lsb_val, use_lsb);
   1943 }
   1944 
   1945 int
   1946 soc_td3_exact_match_base_entry_to_key(int unit, int bank, uint32 *entry,
   1947                                       uint8 *key) {
   1948     soc_mem_t mem;
   1949     soc_field_t field_list[5];
   1950     soc_mem_t   flex_mem_view = 0;
   1951 
   1952     switch (soc_mem_field32_get(unit, EXACT_MATCH_2m, entry, KEY_TYPEf)) {
   1953         case TD3_FPEM_HASH_KEY_TYPE_128B:
   1954             mem = EXACT_MATCH_2m;
   1955             field_list[0] = MODE128__KEY_0f;
   1956             field_list[1] = MODE128__KEY_1f;
   1957             field_list[2] = INVALIDf;
   1958             break;
   1959         case TD3_FPEM_HASH_KEY_TYPE_160B:
   1960             mem = EXACT_MATCH_2m;
   1961             field_list[0] = MODE160__KEY_0f;
   1962             field_list[1] = MODE160__KEY_1f;
   1963             field_list[2] = INVALIDf;
   1964             break;
   1965         case TD3_FPEM_HASH_KEY_TYPE_320B:
   1966             mem = EXACT_MATCH_4m;
   1967             field_list[0] = MODE320__KEY_0f;
   1968             field_list[1] = MODE320__KEY_1f;
   1969             field_list[2] = MODE320__KEY_2f;
   1970             field_list[3] = MODE320__KEY_3f;
   1971             field_list[4] = INVALIDf;
   1972             break;
   1973         default:
   1974             mem = EXACT_MATCH_4m;
   1975             SOC_IF_ERROR_RETURN(soc_flex_hash_mem_view_get(unit,
   1976                    mem, entry, &flex_mem_view, field_list));
   1977         break;
   1978     }
   1979     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   1980                              mem, field_list, flex_mem_view);
   1981 }
   1982 
   1983 uint32
   1984 soc_td3_exact_match_entry_hash(int unit, int bank, int hash_offset,
   1985                               int use_lsb, uint32 *entry)
   1986 {
   1987     int             key_nbits;
   1988     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   1989     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   1990 
   1991     /* Robust Hashed Key using Remap and Action Tables A */
   1992     key_nbits = soc_td3_exact_match_base_entry_to_key(unit, 0, entry, key1);
   1993     /* Robust Hashed Key using Remap and Action Tables B */
   1994     key_nbits = soc_td3_exact_match_base_entry_to_key(unit, 1, entry, key2);
   1995 
   1996     return soc_td3_exact_match_hash(unit, bank, hash_offset, use_lsb,
   1997                                     key_nbits, entry, key1, key2);
   1998 }
   1999 
   2000 uint32
   2001 soc_td3_exact_match_bank_entry_hash(int unit, int bank, uint32 *entry)
   2002 {
   2003     int rv, hash_offset, use_lsb;
   2004 
   2005     rv = soc_td3_hash_offset_get(unit, EXACT_MATCH_2m, bank, &hash_offset,
   2006                                  &use_lsb);
   2007     if (SOC_FAILURE(rv)) {
   2008         return 0;
   2009     }
   2010 
   2011     return soc_td3_exact_match_entry_hash(unit, bank, hash_offset, use_lsb,
   2012                                           entry);
   2013 }
   2014 
   2015 uint32
   2016 soc_td3_mpls_hash(int unit, soc_mem_t mem, int bank, int hash_offset, int use_lsb,
   2017                   int key_nbits, void *base_entry, uint8 *key1, uint8 *key2)
   2018 {
   2019     uint32 lsb_val;
   2020     uint32 hash_mask;
   2021     uint32 hash_bits;
   2022 
   2023     if (bank < 4) {
   2024         hash_mask = 0x7FF; /* 2k buckets per shared bank of size 8k */
   2025         hash_bits = 11;
   2026     } else {
   2027         hash_mask = 0xFFF; /* 4k buckets per shared bank of size 16k */
   2028         hash_bits = 12;
   2029     }
   2030 
   2031     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2032         switch (soc_mem_field32_get(unit, mem, base_entry,
   2033                                     KEY_TYPEf)) {
   2034         case TD3_MPLS_HASH_KEY_TYPE_MPLS:
   2035             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2036                                           MPLS__HASH_LSBf);
   2037             break;
   2038         case TD3_MPLS_HASH_KEY_TYPE_MIM_NVP:
   2039             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2040                                           MIM_NVP__HASH_LSBf);
   2041             break;
   2042         case TD3_MPLS_HASH_KEY_TYPE_MIM_ISID:
   2043         case TD3_MPLS_HASH_KEY_TYPE_MIM_ISID_SVP:
   2044             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2045                                           MIM_ISID__HASH_LSBf);
   2046             break;
   2047         case TD3_MPLS_HASH_KEY_TYPE_TRILL:
   2048             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2049                                           TRILL__HASH_LSBf);
   2050             break;
   2051         case TD3_MPLS_HASH_KEY_TYPE_L2GRE_SIP:
   2052             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2053                                           L2GRE_SIP__HASH_LSBf);
   2054         break;
   2055         case TD3_MPLS_HASH_KEY_TYPE_L2GRE_VPNID_SIP:
   2056         case TD3_MPLS_HASH_KEY_TYPE_L2GRE_VPNID:
   2057             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2058                                           L2GRE_VPNID__HASH_LSBf);
   2059             break;
   2060         case TD3_MPLS_HASH_KEY_TYPE_VXLAN_SIP:
   2061             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2062                                           VXLAN_SIP__HASH_LSBf);
   2063             break;
   2064         case TD3_MPLS_HASH_KEY_TYPE_VXLAN_VPNID:
   2065         case TD3_MPLS_HASH_KEY_TYPE_VXLAN_VPNID_SIP:
   2066             lsb_val = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry,
   2067                                           VXLAN_VN_ID__HASH_LSBf);
   2068             break;
   2069 
   2070         default:
   2071             lsb_val = 0;
   2072             break;
   2073         }
   2074     } else {
   2075         lsb_val = 0;
   2076     }
   2077 
   2078     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2079                                 hash_mask, lsb_val, use_lsb);
   2080 }
   2081 
   2082 int
   2083 soc_td3_mpls_base_entry_to_key(int unit, soc_mem_t mem, int bank, void *entry, uint8 *key) {
   2084     
   2085     soc_field_t field_list[5];
   2086     soc_mem_t   flex_mem_view = 0;
   2087 
   2088     field_list[1] = INVALIDf;
   2089     switch (soc_mem_field32_get(unit, mem, entry, KEY_TYPEf)) {
   2090     case TD3_MPLS_HASH_KEY_TYPE_MPLS:
   2091         field_list[0] = MPLS__KEYf;
   2092         break;
   2093     case TD3_MPLS_HASH_KEY_TYPE_MIM_NVP:
   2094         field_list[0] = MIM_NVP__KEYf;
   2095         break;
   2096     case TD3_MPLS_HASH_KEY_TYPE_MIM_ISID:
   2097     case TD3_MPLS_HASH_KEY_TYPE_MIM_ISID_SVP:
   2098         field_list[0] = MIM_ISID__KEYf;
   2099         break;
   2100     case TD3_MPLS_HASH_KEY_TYPE_TRILL:
   2101         field_list[0] = TRILL__KEYf;
   2102         break;
   2103     case TD3_MPLS_HASH_KEY_TYPE_L2GRE_SIP:
   2104         field_list[0] = L2GRE_SIP__KEYf;
   2105         break;
   2106     case TD3_MPLS_HASH_KEY_TYPE_L2GRE_VPNID_SIP:
   2107     case TD3_MPLS_HASH_KEY_TYPE_L2GRE_VPNID:
   2108         field_list[0] = L2GRE_VPNID__KEYf;
   2109         break;
   2110     case TD3_MPLS_HASH_KEY_TYPE_VXLAN_SIP:
   2111         if (soc_feature(unit, soc_feature_vxlan_decoupled_mode) &&
   2112             (mem == MPLS_ENTRY_SINGLEm)) {
   2113             field_list[0] = KEY_TYPEf;
   2114             field_list[1] = VXLAN_FLEX_IPV4_SIP__SIPf;
   2115             field_list[2] = INVALIDf;
   2116         }
   2117         else {
   2118             field_list[0] = VXLAN_SIP__KEYf;
   2119         }
   2120         break;
   2121     case TD3_MPLS_HASH_KEY_TYPE_VXLAN_VPNID:
   2122     case TD3_MPLS_HASH_KEY_TYPE_VXLAN_VPNID_SIP:
   2123         field_list[0] = VXLAN_VN_ID__KEYf;
   2124         break;
   2125     case TD3_MPLS_HASH_KEY_TYPE_VXLAN_FLEX_IPV4_DIP:
   2126         field_list[0] = KEY_TYPEf;
   2127         field_list[1] = VXLAN_FLEX_IPV4_DIP__DIPf;
   2128         field_list[2] = INVALIDf;
   2129         break;
   2130     default:
   2131         SOC_IF_ERROR_RETURN(soc_flex_hash_mem_view_get(unit,
   2132             mem, entry, &flex_mem_view, field_list));
   2133         break;
   2134     }
   2135     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   2136                       mem, field_list, flex_mem_view);
   2137 }
   2138 
   2139 uint32
   2140 soc_td3_mpls_entry_hash(int unit, soc_mem_t mem, int bank,
   2141                         int hash_offset, int use_lsb, uint32 *entry)
   2142 {
   2143     int             key_nbits;
   2144     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2145     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2146 
   2147     /* Robust Hashed Key using Remap and Action Tables A */
   2148     key_nbits = soc_td3_mpls_base_entry_to_key(unit, mem, 0, entry, key1);
   2149     /* Robust Hashed Key using Remap and Action Tables B */
   2150     key_nbits = soc_td3_mpls_base_entry_to_key(unit, mem, 1, entry, key2);
   2151 
   2152     return soc_td3_mpls_hash(unit, mem, bank, hash_offset, use_lsb,
   2153                              key_nbits, entry, key1, key2);
   2154 }
   2155 
   2156 uint32
   2157 soc_td3_mpls_bank_entry_hash(int unit, soc_mem_t mem,
   2158                              int bank, uint32 *entry)
   2159 {
   2160     int rv, hash_offset, use_lsb;
   2161 
   2162     rv = soc_td3_hash_offset_get(unit, mem, bank, &hash_offset,
   2163                                  &use_lsb);
   2164     if (SOC_FAILURE(rv)) {
   2165         return 0;
   2166     }
   2167 
   2168     return soc_td3_mpls_entry_hash(unit, mem, bank, hash_offset, use_lsb, entry);
   2169 }
   2170 
   2171 uint32
   2172 soc_td3_vlan_xlate_hash(int unit, soc_mem_t mem, int bank, int hash_offset,
   2173                         int use_lsb, int key_nbits, void *base_entry,
   2174                         uint8 *key1, uint8 *key2)
   2175 {
   2176     uint32 lsb_val;
   2177     uint32 hash_mask;
   2178     uint32 hash_bits;
   2179 
   2180     if (bank < 4) {
   2181         hash_mask = 0x7FF; /* 2k buckets per shared bank of size 8k */
   2182         hash_bits = 11;
   2183     } else {
   2184         hash_mask = 0xFFF; /* 4k buckets per shared bank of size 16k */
   2185         hash_bits = 12;
   2186     }
   2187 
   2188     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2189         switch (soc_mem_field32_get(unit, mem, base_entry,
   2190                                     KEY_TYPEf)) {
   2191         case TD3_VLXLT_HASH_KEY_TYPE_IVID_OVID:
   2192         case TD3_VLXLT_HASH_KEY_TYPE_OTAG:
   2193         case TD3_VLXLT_HASH_KEY_TYPE_ITAG:
   2194         case TD3_VLXLT_HASH_KEY_TYPE_OVID:
   2195         case TD3_VLXLT_HASH_KEY_TYPE_IVID:
   2196         case TD3_VLXLT_HASH_KEY_TYPE_PRI_CFI:
   2197         case TD3_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
   2198         case TD3_VLXLT_HASH_KEY_TYPE_IVID_VSAN:
   2199         case TD3_VLXLT_HASH_KEY_TYPE_OVID_VSAN:
   2200             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2201                                           XLATE__HASH_LSBf);
   2202             break;
   2203         case TD3_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
   2204             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2205                                           MAC__HASH_LSBf);
   2206             break;
   2207         case TD3_VLXLT_HASH_KEY_TYPE_HPAE:
   2208             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2209                                           MAC_IP_BIND__HASH_LSBf);
   2210             break;
   2211         case TD3_VLXLT_HASH_KEY_TYPE_VIF:
   2212         case TD3_VLXLT_HASH_KEY_TYPE_VIF_VLAN:
   2213         case TD3_VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
   2214         case TD3_VLXLT_HASH_KEY_TYPE_VIF_OTAG:
   2215         case TD3_VLXLT_HASH_KEY_TYPE_VIF_ITAG:
   2216             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2217                                           VIF__HASH_LSBf);
   2218             break;
   2219         case TD3_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
   2220             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2221                                           MAC_PORT__HASH_LSBf);
   2222             break;
   2223         case TD3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP:
   2224             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2225                                           L2GRE_DIP__HASH_LSBf);
   2226             break;
   2227         case TD3_VLXLT_HASH_KEY_TYPE_VXLAN_DIP:
   2228             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2229                                           VXLAN_DIP__HASH_LSBf);
   2230             break;
   2231         default:
   2232             lsb_val = 0;
   2233             break;
   2234         }
   2235     } else {
   2236         lsb_val = 0;
   2237     }
   2238 
   2239     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2240                                 hash_mask, lsb_val, use_lsb);
   2241 }
   2242 
   2243 int
   2244 soc_td3_vlan_xlate_base_entry_to_key(int unit, soc_mem_t mem, int bank,
   2245                                      void *entry, uint8 *key)
   2246 {
   2247     soc_field_t field_list[5];
   2248     soc_mem_t   flex_mem_view = 0;
   2249 
   2250     field_list[1] = INVALIDf;
   2251     switch (soc_mem_field32_get(unit, mem, entry, KEY_TYPEf)) {
   2252     case TD3_VLXLT_HASH_KEY_TYPE_IVID_OVID:
   2253     case TD3_VLXLT_HASH_KEY_TYPE_OTAG:
   2254     case TD3_VLXLT_HASH_KEY_TYPE_ITAG:
   2255     case TD3_VLXLT_HASH_KEY_TYPE_OVID:
   2256     case TD3_VLXLT_HASH_KEY_TYPE_IVID:
   2257     case TD3_VLXLT_HASH_KEY_TYPE_PRI_CFI:
   2258     case TD3_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
   2259     case TD3_VLXLT_HASH_KEY_TYPE_OVID_VSAN:
   2260     case TD3_VLXLT_HASH_KEY_TYPE_IVID_VSAN:
   2261         field_list[0] = XLATE__KEY_0f;
   2262         break;
   2263     case TD3_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
   2264         field_list[0] = MAC__KEY_0f;
   2265         break;
   2266     case TD3_VLXLT_HASH_KEY_TYPE_HPAE:
   2267         field_list[0] = MAC_IP_BIND__KEY_0f;
   2268         break;
   2269     case TD3_VLXLT_HASH_KEY_TYPE_VIF:
   2270     case TD3_VLXLT_HASH_KEY_TYPE_VIF_VLAN:
   2271     case TD3_VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
   2272     case TD3_VLXLT_HASH_KEY_TYPE_VIF_OTAG:
   2273     case TD3_VLXLT_HASH_KEY_TYPE_VIF_ITAG:
   2274         field_list[0] = VIF__KEY_0f;
   2275         break;
   2276     case TD3_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
   2277         field_list[0] = MAC_PORT__KEY_0f;
   2278         break;
   2279     case TD3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP:
   2280         field_list[0] = L2GRE_DIP__KEY_0f;
   2281         break;
   2282     case TD3_VLXLT_HASH_KEY_TYPE_VXLAN_DIP:
   2283         field_list[0] = VXLAN_DIP__KEY_0f;
   2284         break;
   2285     case TD3_VLXLT_HASH_KEY_TYPE_VXLAN_FLEX_VNID:
   2286         field_list[0] = KEY_TYPEf;
   2287         field_list[1] = VXLAN_FLEX__VNIDf;
   2288         field_list[2] = INVALIDf;
   2289         break;
   2290     case TD3_VLXLT_HASH_KEY_TYPE_VXLAN_FLEX_SIP_VNID:
   2291         field_list[0] = KEY_TYPEf;
   2292         field_list[1] = VXLAN_FLEX__VNIDf;
   2293         field_list[2] = VXLAN_FLEX__SIPf;
   2294         field_list[3] = INVALIDf;
   2295         break;
   2296     default:
   2297         SOC_IF_ERROR_RETURN(soc_flex_hash_mem_view_get(unit,
   2298                    mem, entry, &flex_mem_view, field_list));
   2299         break;
   2300     }
   2301     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   2302                              mem, field_list, flex_mem_view);
   2303 }
   2304 
   2305 uint32
   2306 soc_td3_vlan_xlate_entry_hash(int unit, soc_mem_t mem, int bank, int hash_offset,
   2307                               int use_lsb, uint32 *entry)
   2308 {
   2309     int             key_nbits;
   2310     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2311     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2312 
   2313     /* Robust Hashed Key using Remap and Action Tables A */
   2314     key_nbits = soc_td3_vlan_xlate_base_entry_to_key(unit, mem, 0, entry, key1);
   2315     /* Robust Hashed Key using Remap and Action Tables B */
   2316     key_nbits = soc_td3_vlan_xlate_base_entry_to_key(unit, mem, 1, entry, key2);
   2317 
   2318     return soc_td3_vlan_xlate_hash(unit, mem, bank, hash_offset, use_lsb,
   2319                                    key_nbits, entry, key1, key2);
   2320 }
   2321 
   2322 uint32
   2323 soc_td3_vlan_xlate_bank_entry_hash(int unit, soc_mem_t mem, int bank,
   2324                                    uint32 *entry)
   2325 {
   2326     int rv, hash_offset, use_lsb;
   2327 
   2328     rv = soc_td3_hash_offset_get(unit, mem, bank, &hash_offset,
   2329                                  &use_lsb);
   2330     if (SOC_FAILURE(rv)) {
   2331         return 0;
   2332     }
   2333 
   2334     return soc_td3_vlan_xlate_entry_hash(unit, mem, bank, hash_offset, 
   2335                                          use_lsb, entry);
   2336 }
   2337 
   2338 uint32
   2339 soc_td3_egr_vlan_xlate_hash(int unit, soc_mem_t mem, int bank, int hash_offset,
   2340                             int use_lsb, int key_nbits, void *base_entry,
   2341                             uint8 *key1, uint8 *key2)
   2342 {
   2343     uint32 lsb_val;
   2344     uint32 hash_mask;
   2345     uint32 hash_bits;
   2346 
   2347     hash_mask = 0x7FF; /* 2k buckets per shared bank of size 8k */
   2348     hash_bits = 11;
   2349 
   2350     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2351         switch (soc_mem_field32_get(unit, mem, base_entry,
   2352                                     KEY_TYPEf)) {
   2353         case TD3_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE:
   2354         case TD3_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_DVP:
   2355         case TD3_EVLXLT_HASH_KEY_TYPE_FCOE_XLATE:
   2356         case TD3_EVLXLT_HASH_KEY_TYPE_FCOE_XLATE_DVP:
   2357             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2358                                           XLATE__HASH_LSBf);
   2359             break;
   2360         case TD3_EVLXLT_HASH_KEY_TYPE_ISID_XLATE:
   2361         case TD3_EVLXLT_HASH_KEY_TYPE_ISID_DVP_XLATE:
   2362             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2363                                           MIM_ISID__HASH_LSBf);
   2364             break;
   2365         case TD3_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI:
   2366         case TD3_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI_DVP:
   2367             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2368                                           L2GRE_VFI__HASH_LSBf);
   2369             break;
   2370         case TD3_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI:
   2371         case TD3_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI_DVP:
   2372             lsb_val = soc_mem_field32_get(unit, mem, base_entry,
   2373                                           VXLAN_VFI__HASH_LSBf);
   2374             break;
   2375         default:
   2376             lsb_val = 0;
   2377             break;
   2378         }
   2379     } else {
   2380         lsb_val = 0;
   2381     }
   2382 
   2383     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2384                                 hash_mask, lsb_val, use_lsb);
   2385 }
   2386 
   2387 int
   2388 soc_td3_egr_vlan_xlate_base_entry_to_key(int unit, soc_mem_t mem, int bank,
   2389                                          void *entry, uint8 *key)
   2390 {
   2391     soc_field_t field_list[5];
   2392     soc_mem_t   flex_mem_view = 0;
   2393 
   2394     field_list[1] = INVALIDf;
   2395     switch (soc_mem_field32_get(unit, mem, entry, KEY_TYPEf)) {
   2396     case TD3_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE:
   2397     case TD3_EVLXLT_HASH_KEY_TYPE_FCOE_XLATE:
   2398     case TD3_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_DVP:
   2399     case TD3_EVLXLT_HASH_KEY_TYPE_FCOE_XLATE_DVP:
   2400         field_list[0] = XLATE__KEY_0f;
   2401         break;
   2402     case TD3_EVLXLT_HASH_KEY_TYPE_ISID_XLATE:
   2403     case TD3_EVLXLT_HASH_KEY_TYPE_ISID_DVP_XLATE:
   2404         field_list[0] = MIM_ISID__KEY_0f;
   2405         break;
   2406     case TD3_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI:
   2407     case TD3_EVLXLT_HASH_KEY_TYPE_L2GRE_VFI_DVP:
   2408         field_list[0] = L2GRE_VFI__KEY_0f;
   2409         break;
   2410     case TD3_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI:
   2411     case TD3_EVLXLT_HASH_KEY_TYPE_VXLAN_VFI_DVP:
   2412          if (soc_feature(unit, soc_feature_vxlan_decoupled_mode) &&
   2413             (mem == EGR_VLAN_XLATE_1_SINGLEm)) {
   2414             field_list[0] = VXLAN_VFI_FLEX__KEY_0f;
   2415          } else {
   2416             field_list[0] = VXLAN_VFI__KEY_0f;
   2417          }
   2418         break;
   2419     case TD3_ELVXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI:
   2420         field_list[0] = VLAN_XLATE_VFI__KEY_0f;
   2421         break;
   2422     case TD3_ELVXLT_HASH_KEY_TYPE_VFI_DVP_GROUP:
   2423         field_list[0] = VFI_DVP_GROUP__KEY_0f;
   2424         break;
   2425     case TD3_ELVXLT_HASH_KEY_TYPE_VRF_MAPPING:
   2426         field_list[0] = VRF_MAPPING__KEY_0f;
   2427         break;
   2428     default:
   2429         SOC_IF_ERROR_RETURN(soc_flex_hash_mem_view_get(unit,
   2430                    mem, entry, &flex_mem_view, field_list));
   2431     }
   2432     return _soc_td3_hash_entry_to_key(unit, bank, entry,
   2433                    key, mem, field_list, flex_mem_view);
   2434 }
   2435 
   2436 uint32
   2437 soc_td3_egr_vlan_xlate_entry_hash(int unit, soc_mem_t mem, int bank,
   2438                                   int hash_offset, int use_lsb, uint32 *entry)
   2439 {
   2440     int             key_nbits;
   2441     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2442     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2443 
   2444     /* Robust Hashed Key using Remap and Action Tables A */
   2445     key_nbits = soc_td3_egr_vlan_xlate_base_entry_to_key(unit, mem, 0,
   2446                                                             entry, key1);
   2447     /* Robust Hashed Key using Remap and Action Tables B */
   2448     key_nbits = soc_td3_egr_vlan_xlate_base_entry_to_key(unit, mem, 1,
   2449                                                             entry, key2);
   2450 
   2451     return soc_td3_egr_vlan_xlate_hash(unit, mem, bank, hash_offset, use_lsb,
   2452                                        key_nbits, entry, key1, key2);
   2453 }
   2454 
   2455 uint32
   2456 soc_td3_egr_vlan_xlate_bank_entry_hash(int unit, soc_mem_t mem, int bank,
   2457                                        uint32 *entry)
   2458 {
   2459     int rv, hash_offset, use_lsb;
   2460 
   2461     rv = soc_td3_hash_offset_get(unit, mem, bank, &hash_offset,
   2462                                  &use_lsb);
   2463     if (SOC_FAILURE(rv)) {
   2464         return 0;
   2465     }
   2466 
   2467     return soc_td3_egr_vlan_xlate_entry_hash(unit, mem, bank, hash_offset, 
   2468                                              use_lsb, entry);
   2469 }
   2470 
   2471 uint32
   2472 soc_td3_ing_vp_vlan_member_hash(int unit, int bank, int hash_offset,
   2473                                 int use_lsb, int key_nbits, void *base_entry,
   2474                                 uint8 *key1, uint8 *key2)
   2475 {
   2476     uint32 lsb_val;
   2477     uint32 hash_mask;
   2478     uint32 hash_bits;
   2479 
   2480         hash_mask = 0x7FF; /* 2k buckets per dedicated bank of size 8k */
   2481         hash_bits = 11;
   2482 
   2483     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2484         lsb_val = soc_mem_field32_get(unit, ING_VP_VLAN_MEMBERSHIPm,
   2485                                       base_entry, HASH_LSBf);
   2486     } else {
   2487         lsb_val = 0;
   2488     }
   2489 
   2490     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2491                                 hash_mask, lsb_val, use_lsb);
   2492 }
   2493 
   2494 int
   2495 soc_td3_ing_vp_vlan_member_base_entry_to_key(int unit, int bank, void *entry, uint8 *key)
   2496 {
   2497     static soc_field_t field_list[] = {
   2498         KEYf,
   2499         INVALIDf
   2500     };
   2501 
   2502     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   2503                                       ING_VP_VLAN_MEMBERSHIPm, field_list, 0);
   2504 }
   2505 
   2506 uint32
   2507 soc_td3_ing_vp_vlan_member_entry_hash(int unit, int bank, int hash_offset,
   2508                                       int use_lsb, uint32 *entry)
   2509 {
   2510     int             key_nbits;
   2511     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2512     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2513 
   2514     /* Robust Hashed Key using Remap and Action Tables A */
   2515     key_nbits = soc_td3_ing_vp_vlan_member_base_entry_to_key(unit, 0,
   2516                                                              entry, key1);
   2517     /* Robust Hashed Key using Remap and Action Tables B */
   2518     key_nbits = soc_td3_ing_vp_vlan_member_base_entry_to_key(unit, 1, 
   2519                                                              entry, key2);
   2520 
   2521     return soc_td3_ing_vp_vlan_member_hash(unit, bank, hash_offset, use_lsb,
   2522                                            key_nbits, entry, key1, key2);
   2523 }
   2524 
   2525 uint32
   2526 soc_td3_ing_vp_vlan_member_bank_entry_hash(int unit, int bank, uint32 *entry)
   2527 {
   2528     int rv, hash_offset, use_lsb;
   2529 
   2530     rv = soc_td3_hash_offset_get(unit, ING_VP_VLAN_MEMBERSHIPm, bank,
   2531                                  &hash_offset, &use_lsb);
   2532     if (SOC_FAILURE(rv)) {
   2533         return 0;
   2534     }
   2535 
   2536     return soc_td3_ing_vp_vlan_member_entry_hash(unit, bank, hash_offset,
   2537                                                  use_lsb, entry);
   2538 }
   2539 
   2540 uint32
   2541 soc_td3_egr_vp_vlan_member_hash(int unit, int bank, int hash_offset,
   2542                                 int use_lsb, int key_nbits, void *base_entry,
   2543                                 uint8 *key1, uint8 *key2)
   2544 {
   2545     uint32 lsb_val;
   2546     uint32 hash_mask;
   2547     uint32 hash_bits;
   2548 
   2549         hash_mask = 0x7FF; /* 2k buckets per dedicated bank of size 8k */
   2550         hash_bits = 11;
   2551 
   2552     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2553         lsb_val = soc_mem_field32_get(unit, EGR_VP_VLAN_MEMBERSHIPm,
   2554                                       base_entry, HASH_LSBf);
   2555     } else {
   2556         lsb_val = 0;
   2557     }
   2558 
   2559     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2560                                 hash_mask, lsb_val, use_lsb);
   2561 }
   2562 
   2563 int
   2564 soc_td3_egr_vp_vlan_member_base_entry_to_key(int unit, int bank, void *entry, uint8 *key)
   2565 {
   2566     static soc_field_t field_list[] = {
   2567         KEYf,
   2568         INVALIDf
   2569     };
   2570 
   2571     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   2572                                       EGR_VP_VLAN_MEMBERSHIPm, field_list, 0);
   2573 }
   2574 
   2575 uint32
   2576 soc_td3_egr_vp_vlan_member_entry_hash(int unit, int bank, int hash_offset,
   2577                                       int use_lsb, uint32 *entry)
   2578 {
   2579     int             key_nbits;
   2580     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2581     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2582 
   2583     /* Robust Hashed Key using Remap and Action Tables A */
   2584     key_nbits = soc_td3_egr_vp_vlan_member_base_entry_to_key(unit, 0,
   2585                                                              entry, key1);
   2586     /* Robust Hashed Key using Remap and Action Tables B */
   2587     key_nbits = soc_td3_egr_vp_vlan_member_base_entry_to_key(unit, 1, 
   2588                                                              entry, key2);
   2589 
   2590     return soc_td3_egr_vp_vlan_member_hash(unit, bank, hash_offset, use_lsb,
   2591                                            key_nbits, entry, key1, key2);
   2592 }
   2593 
   2594 uint32
   2595 soc_td3_egr_vp_vlan_member_bank_entry_hash(int unit, int bank, uint32 *entry)
   2596 {
   2597     int rv, hash_offset, use_lsb;
   2598 
   2599     rv = soc_td3_hash_offset_get(unit, EGR_VP_VLAN_MEMBERSHIPm, bank,
   2600                                  &hash_offset, &use_lsb);
   2601     if (SOC_FAILURE(rv)) {
   2602         return 0;
   2603     }
   2604 
   2605     return soc_td3_egr_vp_vlan_member_entry_hash(unit, bank, hash_offset,
   2606                                                  use_lsb, entry);
   2607 }
   2608 
   2609 uint32
   2610 soc_td3_ing_dnat_address_type_hash(int unit, int bank, int hash_offset,
   2611                                    int use_lsb, int key_nbits,
   2612                                    void *base_entry, uint8 *key1, uint8 *key2)
   2613 {
   2614     uint32 lsb_val;
   2615     uint32 hash_mask;
   2616     uint32 hash_bits;
   2617 
   2618     hash_mask = 0xFF; /* 256 buckets per dedicated bank of size 1k */
   2619     hash_bits = 8;
   2620 
   2621     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2622         lsb_val = soc_mem_field32_get(unit, ING_DNAT_ADDRESS_TYPEm,
   2623                                       base_entry, HASH_LSBf);
   2624     } else {
   2625         lsb_val = 0;
   2626     }
   2627 
   2628     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2629                                 hash_mask, lsb_val, use_lsb);
   2630 }
   2631 
   2632 int
   2633 soc_td3_ing_dnat_address_type_base_entry_to_key(int unit, int bank, void *entry,
   2634                                                 uint8 *key)
   2635 {
   2636     static soc_field_t field_list[] = {
   2637         KEYf,
   2638         INVALIDf
   2639     };
   2640 
   2641     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   2642                                       ING_DNAT_ADDRESS_TYPEm, field_list, 0);
   2643 }
   2644 
   2645 uint32
   2646 soc_td3_ing_dnat_address_type_entry_hash(int unit, int bank, int hash_offset,
   2647                                          int use_lsb, uint32 *entry)
   2648 {
   2649     int             key_nbits;
   2650     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2651     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2652 
   2653     /* Robust Hashed Key using Remap and Action Tables A */
   2654     key_nbits = soc_td3_ing_dnat_address_type_base_entry_to_key(unit, 0,
   2655                                                                 entry, key1);
   2656     /* Robust Hashed Key using Remap and Action Tables B */
   2657     key_nbits = soc_td3_ing_dnat_address_type_base_entry_to_key(unit, 1, 
   2658                                                                 entry, key2);
   2659 
   2660     return soc_td3_ing_dnat_address_type_hash(unit, bank, hash_offset,
   2661                                               use_lsb, key_nbits, entry,
   2662                                               key1, key2);
   2663 }
   2664 
   2665 uint32
   2666 soc_td3_ing_dnat_address_type_bank_entry_hash(int unit, int bank, uint32 *entry)
   2667 {
   2668     int rv, hash_offset, use_lsb;
   2669 
   2670     rv = soc_td3_hash_offset_get(unit, ING_DNAT_ADDRESS_TYPEm, bank,
   2671                                  &hash_offset, &use_lsb);
   2672     if (SOC_FAILURE(rv)) {
   2673         return 0;
   2674     }
   2675 
   2676     return soc_td3_ing_dnat_address_type_entry_hash(unit, bank, hash_offset,
   2677                                                     use_lsb, entry);
   2678 }
   2679 
   2680 uint32
   2681 soc_td3_subport_id_to_sgpp_map_hash(int unit, int bank, int hash_offset,
   2682                                     int use_lsb, int key_nbits,
   2683                                     void *base_entry, uint8 *key1, uint8 *key2)
   2684 {
   2685     uint32 lsb_val;
   2686     uint32 hash_mask;
   2687     uint32 hash_bits;
   2688 
   2689     hash_mask = 0x3FF; /* 1k buckets per dedicated bank of size 4k */
   2690     hash_bits = 10;
   2691 
   2692     if (use_lsb && (hash_offset + hash_bits > 32)) {
   2693         lsb_val = soc_mem_field32_get(unit, SUBPORT_ID_TO_SGPP_MAPm,
   2694                                       base_entry, HASH_LSBf);
   2695     } else {
   2696         lsb_val = 0;
   2697     }
   2698 
   2699     return _soc_td3_shared_hash(unit, hash_offset, key_nbits, key1, key2,
   2700                                 hash_mask, lsb_val, use_lsb);
   2701 }
   2702 
   2703 int
   2704 soc_td3_subport_id_to_sgpp_map_base_entry_to_key(int unit, int bank,
   2705                                                  void *entry, uint8 *key)
   2706 {
   2707     static soc_field_t field_list[] = {
   2708         KEYf,
   2709         INVALIDf
   2710     };
   2711 
   2712     return _soc_td3_hash_entry_to_key(unit, bank, entry, key,
   2713                                       SUBPORT_ID_TO_SGPP_MAPm, field_list, 0);
   2714 }
   2715 
   2716 uint32
   2717 soc_td3_subport_id_to_sgpp_map_entry_hash(int unit, int bank, int hash_offset,
   2718                                           int use_lsb, uint32 *entry)
   2719 {
   2720     int             key_nbits;
   2721     uint8           key1[SOC_MAX_MEM_WORDS * 4] = {0};
   2722     uint8           key2[SOC_MAX_MEM_WORDS * 4] = {0};
   2723 
   2724     /* Robust Hashed Key using Remap and Action Tables A */
   2725     key_nbits = soc_td3_subport_id_to_sgpp_map_base_entry_to_key(unit, 0,
   2726                                                                  entry, key1);
   2727     /* Robust Hashed Key using Remap and Action Tables B */
   2728     key_nbits = soc_td3_subport_id_to_sgpp_map_base_entry_to_key(unit, 1, 
   2729                                                                  entry, key2);
   2730 
   2731     return soc_td3_subport_id_to_sgpp_map_hash(unit, bank, hash_offset,
   2732                                                       use_lsb, key_nbits, entry,
   2733                                                       key1, key2);
   2734 }
   2735 
   2736 uint32
   2737 soc_td3_subport_id_to_sgpp_map_bank_entry_hash(int unit, int bank,
   2738                                                uint32 *entry)
   2739 {
   2740     int rv, hash_offset, use_lsb;
   2741 
   2742     rv = soc_td3_hash_offset_get(unit, SUBPORT_ID_TO_SGPP_MAPm, bank,
   2743                                  &hash_offset, &use_lsb);
   2744     if (SOC_FAILURE(rv)) {
   2745         return 0;
   2746     }
   2747 
   2748     return soc_td3_subport_id_to_sgpp_map_entry_hash(unit, bank, hash_offset,
   2749                                                      use_lsb, entry);
   2750 }
   2751 
   2752 int
   2753 soc_td3_hash_bucket_get(int unit, int mem, int bank, uint32 *entry,
   2754                         uint32 *bucket)
   2755 {
   2756     switch (mem) {
   2757     case L2Xm:
   2758         *bucket = soc_td3_l2x_bank_entry_hash(unit, bank, entry);
   2759         break;
   2760     case L3_ENTRY_ONLY_SINGLEm:
   2761     case L3_ENTRY_SINGLEm:
   2762         *bucket = soc_td3_l3x_bank_entry_hash(unit, bank, entry);
   2763         break;
   2764     case L3_ENTRY_DOUBLEm:
   2765         *bucket = soc_td3_l3x_bank_entry_hash(unit, bank, entry);
   2766         *bucket &= (bank > 9) ? 0x3FF : 0xFFF;
   2767         break;
   2768     case L3_ENTRY_QUADm:
   2769         *bucket = soc_td3_l3x_bank_entry_hash(unit, bank, entry);
   2770         *bucket &= (bank > 9) ? 0x1FF : 0x7FF;
   2771         break;
   2772     case EXACT_MATCH_2m:
   2773     case EXACT_MATCH_2_PIPE0m:
   2774     case EXACT_MATCH_2_PIPE1m:
   2775         /* 16K entries => 4K buckets => 0x1000 buckets */ 
   2776         *bucket = soc_td3_exact_match_bank_entry_hash(unit, bank, entry);
   2777         break;
   2778     case EXACT_MATCH_4m:
   2779     case EXACT_MATCH_4_PIPE0m:
   2780     case EXACT_MATCH_4_PIPE1m:
   2781         /* 8K entries => 2K buckets => 0x800 buckets */ 
   2782         *bucket = soc_td3_exact_match_bank_entry_hash(unit, bank, entry) & 0x7ff;
   2783         break;
   2784     case MPLS_ENTRY_SINGLEm:
   2785     case MPLS_ENTRYm:
   2786         *bucket = soc_td3_mpls_bank_entry_hash(unit, mem, bank, entry);
   2787         if (bank < 4) {
   2788             *bucket &= 0x3FF;
   2789         } else {
   2790             *bucket &= 0x7FF;
   2791         }
   2792         break;
   2793     case VLAN_XLATE_1_SINGLEm:
   2794     case VLAN_XLATE_2_SINGLEm:
   2795         *bucket = soc_td3_vlan_xlate_bank_entry_hash(unit, mem, bank, entry);
   2796         break;
   2797     case VLAN_XLATE_1_DOUBLEm:
   2798     case VLAN_XLATE_2_DOUBLEm:
   2799         *bucket = soc_td3_vlan_xlate_bank_entry_hash(unit, mem, bank, entry);
   2800         if (bank < 4) {
   2801             *bucket &= 0x3FF;
   2802         } else {
   2803             *bucket &= 0x7FF;
   2804         }
   2805         break;
   2806     case EGR_VLAN_XLATE_1_SINGLEm:
   2807     case EGR_VLAN_XLATE_2_SINGLEm:
   2808         *bucket = soc_td3_egr_vlan_xlate_bank_entry_hash(unit, mem,
   2809                                                          bank, entry);
   2810         break;
   2811     case EGR_VLAN_XLATE_1_DOUBLEm:
   2812     case EGR_VLAN_XLATE_2_DOUBLEm:
   2813         *bucket = soc_td3_egr_vlan_xlate_bank_entry_hash(unit, mem,
   2814                                               bank, entry) & 0x3FF;
   2815         break;
   2816     case ING_VP_VLAN_MEMBERSHIPm:
   2817         *bucket = soc_td3_ing_vp_vlan_member_bank_entry_hash(unit,
   2818                                                              bank, entry);
   2819         break;
   2820     case EGR_VP_VLAN_MEMBERSHIPm:
   2821         *bucket = soc_td3_egr_vp_vlan_member_bank_entry_hash(unit, 
   2822                                                              bank, entry);
   2823         break;
   2824     case ING_DNAT_ADDRESS_TYPEm:
   2825         *bucket = soc_td3_ing_dnat_address_type_bank_entry_hash(unit,
   2826                                                                 bank, entry);
   2827         break;
   2828     case SUBPORT_ID_TO_SGPP_MAPm:
   2829         *bucket = soc_td3_subport_id_to_sgpp_map_bank_entry_hash(unit,
   2830                                                                  bank, entry);
   2831         break;
   2832     default:
   2833         return SOC_E_PARAM;
   2834     }
   2835     return SOC_E_NONE;
   2836 }
   2837 #endif /* BCM_TRIDENT3_SUPPORT */