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

tr_hash.c (74461B)


      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  * TRX Hash Table Tests.
      8  *
      9  * Insert/Lookup/Delete, hashing, bucket overflow tests.
     10  */
     11 
     12 
     13 
     14 #include <soc/mem.h>
     15 #include <soc/hash.h>
     16 #include <shared/bsl.h>
     17 #if defined(BCM_TRIUMPH_SUPPORT) /* DPPCOMPILEENABLE */
     18 #include <soc/triumph.h>
     19 #endif /* DPPCOMPILEENABLE */
     20 #include <appl/diag/system.h>
     21 #include <appl/test/tr_hash.h>
     22 #include "testlist.h"
     23 #include <bcm/init.h>
     24 #include <bcm/l2.h>
     25 #include <bcm/l3.h>
     26 #include <bcm/stack.h>
     27 #include <bcm/link.h>
     28 #ifdef BCM_ESW_SUPPORT 
     29 #include <bcm_int/esw/firebolt.h>
     30 #endif
     31 #if defined(BCM_TRIUMPH_SUPPORT)
     32 #include <bcm_int/esw/triumph.h>
     33 #endif /* BCM_TRIUMPH_SUPPORT */
     34 #ifdef BCM_TRIDENT2_SUPPORT
     35 #include <soc/trident2.h>
     36 #endif /* BCM_TRIDENT2_SUPPORT */
     37 #ifdef BCM_TOMAHAWK_SUPPORT
     38 #include <soc/tomahawk.h>
     39 #endif /* BCM_TOMAHAWK_SUPPORT */
     40 #ifdef BCM_APACHE_SUPPORT
     41 #include <soc/apache.h>
     42 #endif /* BCM_APACHE_SUPPORT */
     43 #ifdef BCM_MONTEREY_SUPPORT
     44 #include <soc/monterey.h>
     45 #endif /* BCM_APACHE_SUPPORT */
     46 #ifdef BCM_TRIDENT3_SUPPORT
     47 #include <soc/trident3.h>
     48 #endif /* BCM_TRIDENT3_SUPPORT */
     49 #ifdef BCM_HELIX5_SUPPORT
     50 #include <soc/helix5.h>
     51 #endif /* BCM_HELIX5_SUPPORT */
     52 #ifdef BCM_TOMAHAWK3_SUPPORT
     53 #include <soc/tomahawk3.h>
     54 #endif /* BCM_TOMAHAWK3_SUPPORT */
     55 
     56 #include <appl/diag/progress.h>
     57 
     58 #if defined (BCM_PETRA_SUPPORT)
     59 #include <soc/dpp/mbcm.h>
     60 #include <soc/dpp/ARAD/arad_api_action_cmd.h>
     61 #include <soc/dpp/ARAD/arad_ingress_traffic_mgmt.h>
     62 #include <soc/dpp/ARAD/arad_api_end2end_scheduler.h>
     63 #endif
     64 
     65 #if defined(BCM_ESW_SUPPORT) /* || defined (BCM_PETRA_SUPPORT)  */
     66 
     67 
     68 /*
     69  * work structure
     70  */
     71 
     72 STATIC tr_hash_test_t tr_vlan_xlate_work[SOC_MAX_NUM_DEVICES];
     73 STATIC tr_hash_test_t tr_egr_vlan_xlate_work[SOC_MAX_NUM_DEVICES];
     74 #ifdef BCM_TRIUMPH_SUPPORT
     75 STATIC tr_hash_test_t tr_mpls_work[SOC_MAX_NUM_DEVICES];
     76 #endif /* BCM_TRIUMPH_SUPPORT */
     77 
     78 /*
     79  * Utility routines for testing
     80  */
     81 
     82 void
     83 tr_hash_time_start(tr_hash_testdata_t *ad)
     84 {
     85     ad->tm = SAL_TIME_DOUBLE();
     86 }
     87 
     88 void
     89 tr_hash_time_end(tr_hash_testdata_t *ad)
     90 {
     91     ad->tm = SAL_TIME_DOUBLE() - ad->tm;
     92     if (ad->opt_verbose) {
     93         cli_out("    time: %"COMPILER_DOUBLE_FORMAT" msec\n", ad->tm * 1000);
     94     }
     95 }
     96 
     97 
     98 static int
     99 tr_hash_bucket_search(int unit, tr_hash_testdata_t *ad, soc_mem_t mem,
    100                       int bucket, int bucket_size, int validf, void *expect,
    101                       int dual, int bank)
    102 {
    103     uint32 chip_entry[SOC_MAX_MEM_FIELD_WORDS];
    104     int ix, mem_table_index, iter_count;
    105     int rv = -1; /* Assume failed unless we find it */
    106 
    107     if (dual == TRUE) {
    108         iter_count = bucket_size / 2;
    109     } else {
    110         iter_count = bucket_size;
    111     }
    112     for (ix = 0; ix < iter_count; ix++) {
    113         mem_table_index = (bucket * bucket_size) + ix;
    114         if (bank) {
    115             mem_table_index += (bucket_size / 2);
    116         }
    117 
    118         if (soc_mem_read(unit, mem, MEM_BLOCK_ANY,
    119                          mem_table_index, chip_entry) < 0) {
    120             test_error(unit,
    121                        "Read failed at bucket %d, offset %d\n",
    122                        bucket, ix);
    123             break;
    124         }
    125 
    126         if (validf != -1) {
    127             int validv = 0;
    128             if (soc_feature(unit, soc_feature_base_valid) &&
    129                 validf == VALIDf) {
    130                 validv = soc_mem_field32_get(unit, mem, chip_entry,
    131                                              BASE_VALID_0f) == 3 &&
    132                          soc_mem_field32_get(unit, mem, chip_entry,
    133                                              BASE_VALID_1f) == 7;
    134             } else {
    135                 validv = soc_mem_field32_get(unit, mem, chip_entry, validf);
    136             }
    137             if (!validv) {
    138                 /* Valid bit unset, entry blank */
    139                 continue;
    140             }
    141         }
    142 
    143         if (soc_mem_compare_key(unit, mem, expect, &chip_entry) == 0) {
    144             /* Found the matching entry */
    145             rv = 0;
    146             break;
    147         }
    148     }
    149 
    150     return rv;
    151 }
    152 
    153 /************************ START OF VLAN XLATE TESTS ************************/
    154 /*
    155  * Test initialization routine used for Vlan xlate tests
    156  */
    157 
    158 STATIC int
    159 tr_vlan_xlate_test_init(int unit, tr_hash_testdata_t *ad, args_t *a)
    160 {
    161     int                         rv = -1, dual = 0;
    162     parse_table_t               pt;
    163     uint32                      hash_read = 0;
    164 #if defined(BCM_ESW_SUPPORT) && defined(BCM_TRIDENT3_SUPPORT)
    165     l2_entry_hash_control_entry_t xlate_hash_read;
    166 #endif /* BCM_ESW_SUPPORT && BCM_TRIDENT3_SUPPORT */
    167     parse_table_init(unit, &pt);
    168 
    169     parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL);
    170     parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL);
    171     parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL);
    172     parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL);
    173     parse_table_add(&pt, "DualHash", PQ_INT|PQ_DFL, 0, &ad->opt_dual_hash, NULL);
    174     parse_table_add(&pt, "DualEnable", PQ_INT|PQ_DFL, 0, &dual, NULL);
    175     parse_table_add(&pt, "BaseOVID", PQ_INT|PQ_DFL, 0, &ad->opt_base_ovid, NULL);
    176     parse_table_add(&pt, "BaseIVID", PQ_INT|PQ_DFL, 0, &ad->opt_base_ivid, NULL);
    177     parse_table_add(&pt, "VidIncrement", PQ_INT|PQ_DFL, 0,
    178                     &ad->opt_vid_inc, NULL);
    179 
    180     /* Test the obvious parsings before wasting time with malloc */
    181     if (parse_arg_eq(a, &pt) < 0) {
    182         test_error(unit,
    183                    "%s: Error: Invalid option: %s\n", ARG_CMD(a),
    184                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    185         goto done;
    186     }
    187 
    188     if (ad->opt_count < 1) {
    189         test_error(unit, "Illegal count %d\n", ad->opt_count);
    190         goto done;
    191     }
    192 
    193     if (ad->opt_hash >= ad->hash_count) {
    194         test_error(unit, "Illegal hash selection %d\n", ad->opt_hash);
    195         goto done;
    196     }
    197 
    198     if (dual == 1) {
    199         if (ad->opt_dual_hash >= ad->hash_count) {
    200             test_error(unit, "Illegal dual hash selection %d\n", ad->opt_dual_hash);
    201             goto done;
    202         }
    203     } else {
    204         ad->opt_dual_hash = -1;
    205     }
    206 
    207     if (ad->opt_base_ovid >= (1 << 12)) {
    208         test_error(unit, "Out of range Outer VLAN ID selection %d\n",
    209                    ad->opt_base_ovid);
    210         goto done;
    211     }
    212 
    213     if (ad->opt_base_ivid >= (1 << 12)) {
    214         test_error(unit, "Out of range Inner VLAN ID selection %d\n",
    215                    ad->opt_base_ivid);
    216         goto done;
    217     }
    218 
    219     /*
    220      * Re-initialize chip to ensure tables are clear
    221      * at start of test.
    222      */
    223 
    224     if (ad->opt_reset) {
    225         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
    226         if (soc_reset_init(unit) < 0) {
    227             test_error(unit, "SOC initialization failed\n");
    228             goto done;
    229         }
    230 
    231         if (soc_misc_init(unit) < 0) {
    232             test_error(unit, "MISC initialization failed\n");
    233             goto done;
    234         }
    235 
    236         if (soc_mmu_init(unit) < 0) {
    237             test_error(unit, "MMU initialization failed\n");
    238             goto done;
    239         }
    240 #if defined (BCM_PETRA_SUPPORT)		
    241 		
    242 	  	if (mbcm_dpp_init(unit) < 0) { 
    243 	  		test_error(unit, "BCM initialization failed\n");
    244 	  		goto done;
    245 	  	}
    246 #else
    247         if (mbcm_init(unit) < 0) { 
    248             test_error(unit, "BCM initialization failed\n");
    249             goto done;
    250         }
    251 #endif
    252     }
    253 
    254 #if defined(BCM_ESW_SUPPORT) 
    255 #if defined(BCM_TRIDENT3_SUPPORT)
    256     if (soc_feature(unit, soc_feature_base_valid)) {
    257         if (soc_mem_read(unit, VLAN_XLATE_1_HASH_CONTROLm, MEM_BLOCK_ALL,
    258                          0, &xlate_hash_read) < 0) {
    259             test_error(unit, "Hash Control read failed\n");
    260             goto done;
    261         }
    262         sal_memcpy(&ad->save_xlate_hash_control, &xlate_hash_read,
    263                     sizeof(xlate_hash_read));
    264     } else
    265 #endif /* BCM_TRIDENT3_SUPPORT */
    266     {
    267     if (READ_VLAN_XLATE_HASH_CONTROLr(unit, &hash_read) < 0) {
    268         test_error(unit, "Hash select read failed\n");
    269         goto done;
    270     }
    271     }
    272 #endif
    273     ad->save_hash_control = hash_read;
    274 #if defined(BCM_ESW_SUPPORT) 
    275 
    276     if (!(soc_feature(unit, soc_feature_base_valid))) {
    277     soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash_read,
    278                       HASH_SELECT_Af, ad->opt_hash);
    279     if (ad->opt_dual_hash != -1) {
    280         soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash_read,
    281                           HASH_SELECT_Bf, ad->opt_dual_hash);
    282     } else {
    283         soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash_read,
    284                           HASH_SELECT_Bf, ad->opt_hash);
    285     }
    286 
    287     if (WRITE_VLAN_XLATE_HASH_CONTROLr(unit, hash_read) < 0) {
    288         test_error(unit, "Hash select setting failed\n");
    289         goto done;
    290     }
    291     }
    292 #endif
    293     rv = 0;
    294 
    295  done:
    296 
    297     parse_arg_eq_done(&pt);
    298     return rv;
    299 }
    300 
    301 STATIC void
    302 tr_vlan_xlate_hash_setup(int unit, tr_hash_test_t *dw)
    303 {
    304     tr_hash_testdata_t *ad;
    305     soc_mem_t mem = VLAN_XLATEm;
    306 
    307     if (dw->lw_set_up) {
    308         return;
    309     }
    310 
    311     dw->lw_set_up = TRUE;
    312     dw->lw_unit = unit;
    313 
    314 #ifdef BCM_TRIDENT3_SUPPORT
    315     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    316         mem = VLAN_XLATE_1_DOUBLEm;
    317     }
    318 #endif /* BCM_TRIDENT3_SUPPORT */
    319     dw->lp_hash.mem = mem;
    320     dw->lp_ov.mem = mem;
    321 
    322     /* Hash */
    323     ad = &dw->lp_hash;
    324 #if defined(BCM_ESW_SUPPORT) 
    325     ad->opt_count      = soc_mem_index_count(unit, mem);
    326 #elif defined(BCM_PETRA_SUPPORT)
    327     ad->opt_count      = soc_mem_index_count(unit, EGQ_VLAN_TABLEm);
    328 #endif
    329 #ifdef BCM_TRIDENT2_SUPPORT
    330     if (soc_feature(unit, soc_feature_extended_hash)) {
    331         ad->opt_hash       = FB_HASH_CRC32_LOWER;
    332         ad->opt_dual_hash  = FB_HASH_CRC32_UPPER;
    333     } else
    334 #endif /* BCM_TRIDENT2_SUPPORT */
    335     {
    336         ad->opt_hash       = FB_HASH_CRC16_LOWER;
    337         ad->opt_dual_hash  = -1;
    338     }
    339     ad->hash_count     = FB_HASH_COUNT;
    340     ad->opt_base_ovid  = 0;
    341     ad->opt_base_ivid  = 0;
    342     ad->opt_vid_inc    = 1;
    343 
    344     /* Overflow */
    345     ad = &dw->lp_ov;
    346 
    347     ad->opt_count      = 2048;
    348     ad->opt_hash       = TR_DEFAULT_HASH;
    349     ad->opt_dual_hash  = -1;
    350     ad->hash_count     = FB_HASH_COUNT;
    351     ad->opt_base_ovid  = 0;
    352     ad->opt_base_ivid  = 0;
    353     ad->opt_vid_inc    = 1;
    354 }
    355 
    356 /* Individual test init wrappers */
    357 int
    358 tr_vlan_xlate_hash_test_init(int unit, args_t *a, void **p)
    359 {
    360     tr_hash_test_t        *dw = &tr_vlan_xlate_work[unit];
    361     tr_hash_testdata_t    *dp = &dw->lp_hash;
    362     int                    rv;
    363 
    364     tr_vlan_xlate_hash_setup(unit, dw);
    365 
    366     /* Set working data to hash */
    367     dw->lp_cur = dp;
    368 
    369     if ((rv = tr_vlan_xlate_test_init(unit, dp, a)) < 0) {
    370         return rv;
    371     } else {
    372         *p = dp;
    373     }
    374 
    375     return 0;
    376 }
    377 
    378 int
    379 tr_vlan_xlate_ov_test_init(int unit, args_t *a, void **p)
    380 {
    381     tr_hash_test_t        *dw = &tr_vlan_xlate_work[unit];
    382     tr_hash_testdata_t    *dp = &dw->lp_ov;
    383     int                    rv;
    384 
    385     tr_vlan_xlate_hash_setup(unit, dw);
    386 
    387     /* Set working data to hash */
    388     dw->lp_cur = dp;
    389 
    390     if ((rv = tr_vlan_xlate_test_init(unit, dp, a)) < 0) {
    391         return rv; 
    392     } else {
    393         *p = dp;
    394     }
    395 
    396     return 0;
    397 }
    398 
    399 /*
    400  * Test of VLAN XLATE hashing
    401  *
    402  *   This test tries a number of keys against one of the hashing functions,
    403  *   checking a software hash against the hardware hash, then searching the
    404  *   bucket to find the entry after inserting.
    405  */
    406 int
    407 tr_vlan_xlate_test_hash(int unit, args_t *a, void *p)
    408 {
    409     tr_hash_testdata_t         *ad = p;
    410 
    411 #if defined(BCM_ESW_SUPPORT) 
    412     uint32 entry[SOC_MAX_MEM_FIELD_WORDS];
    413 #endif    
    414     int soft_bucket, ix, r, rv = 0;
    415     int hash = ad->opt_hash;
    416     uint8 key[XGS_HASH_KEY_SIZE];
    417     int iterations, ovid, ivid, num_bits;
    418     int vid_inc = ad->opt_vid_inc;
    419     int bucket_size;
    420     int index;
    421     int dual = FALSE;
    422     int bank, banks, bank_count = 1;
    423     soc_mem_t mem;
    424 
    425     COMPILER_REFERENCE(a);
    426 
    427     if (ad->opt_verbose) {
    428         cli_out("Starting VLAN xlate hash test\n");
    429     }
    430 
    431     sal_memset(key, 0, sizeof(key));
    432     mem = ad->mem;
    433 
    434     /* This seems to be a fair "guess". is there a way to find the bucket size used in the HW? */
    435     if (mem != VLAN_XLATEm) {
    436         bucket_size = 4;
    437     } else {
    438     bucket_size = (soc_mem_index_max(unit, VLAN_MACm) < 32767) ? 8 : 16;
    439     }
    440 
    441 #ifdef BCM_APACHE_SUPPORT
    442     if(SOC_IS_APACHE(unit)) {
    443         bucket_size = 8;
    444     }
    445 #endif
    446 
    447 #if defined(BCM_SABER2_SUPPORT)
    448     if(SOC_IS_SABER2(unit)) {
    449 	    /* Even though with the reduced table size saber2 has the same bucket size as KT2 for this table */
    450 	    bucket_size = 16;
    451     }
    452 #endif
    453 
    454     iterations = ad->opt_count;
    455     ovid = ad->opt_base_ovid;
    456     ivid = ad->opt_base_ivid;
    457     if (ad->opt_dual_hash != -1) {
    458         dual = TRUE;
    459         bank_count = 2;
    460     }
    461 
    462     for (ix = 0; ix < iterations; ix++) {
    463         for (bank = 0; bank < bank_count; bank++) {
    464             sal_memset(entry, 0, sizeof (entry));
    465             if (soc_feature(unit, soc_feature_base_valid)) {
    466                 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
    467                 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
    468             } else {
    469                 soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
    470             }
    471             soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 0);
    472             soc_mem_field32_set(unit, mem, entry, OVIDf, ovid);
    473             soc_mem_field32_set(unit, mem, entry, IVIDf, ivid);
    474 
    475 #ifdef BCM_TRIDENT3_SUPPORT
    476             if (SOC_IS_TRIDENT3X(unit)) {
    477                 soft_bucket = soc_td3_vlan_xlate_bank_entry_hash(unit, mem, bank,
    478                                                  (uint32 *) entry);
    479             } else
    480 #endif
    481             {
    482             num_bits = soc_tr_vlan_xlate_base_entry_to_key
    483                     (unit, (uint32 *) entry, key);
    484             soft_bucket = soc_tr_vlan_xlate_hash(unit, hash, num_bits, 
    485                                                  (uint32 *) entry, key);
    486             }
    487             banks = 0;
    488             if (dual == TRUE) {
    489 #ifdef BCM_TRIDENT2_SUPPORT
    490 #ifdef BCM_TRIDENT3_SUPPORT
    491                 if (SOC_IS_TRIDENT3X(unit)) {
    492                 } else
    493 #endif /* BCM_TRIDENT3_SUPPORT */
    494 #ifdef BCM_APACHE_SUPPORT
    495                 if (SOC_IS_APACHE(unit)) {
    496                     soft_bucket = soc_ap_vlan_xlate_bank_entry_hash(unit,
    497                                                     bank, (uint32 *) entry);
    498                 } else
    499 #endif /* BCM_APACHE_SUPPORT */
    500 #ifdef BCM_TOMAHAWK_SUPPORT
    501                 if (SOC_IS_TOMAHAWKX(unit)) {
    502                     soft_bucket = soc_th_vlan_xlate_bank_entry_hash(unit,
    503                                                     bank, (uint32 *) entry);
    504                 } else
    505 #endif /* BCM_TOMAHAWK_SUPPORT */
    506                 if (soc_feature(unit, soc_feature_extended_hash)) {
    507                     soft_bucket = soc_td2_vlan_xlate_bank_entry_hash(unit,
    508                                                     bank, (uint32 *) entry);
    509                 } else
    510 #endif /* BCM_TRIDENT2_SUPPORT */
    511                 {
    512                     soft_bucket = soc_tr_vlan_xlate_bank_entry_hash
    513                         (unit, bank, (uint32 *) entry);
    514                 }
    515                 banks = (bank == 0) ? 2 : 1;
    516             }
    517     
    518             if (ad->opt_verbose) {
    519                 cli_out("Inserting ");
    520                 soc_mem_entry_dump(unit, VLAN_XLATEm, &entry, BSL_LSS_CLI);
    521                 cli_out("\n");
    522                 if (dual) {
    523                     cli_out("into bucket 0x%x (bank %d)\n",
    524                             soft_bucket, bank);
    525                 } else {
    526                    cli_out("into bucket 0x%x\n", soft_bucket);
    527                 }
    528             }
    529     
    530             if ((r = soc_mem_bank_insert(unit, mem, banks,
    531                                          MEM_BLOCK_ALL, entry, NULL)) < 0) {
    532                 if (r == SOC_E_FULL) {
    533                     /* Bucket overflow, just pass on */
    534                     break;
    535                 } else {
    536                     test_error(unit,
    537                                "Vlan xlate insert failed at bucket %d\n", soft_bucket);
    538                     rv = -1;
    539                     goto done;
    540                 }
    541             }
    542     
    543             /* Now we search for the entry */
    544     
    545             /* Only do a quick check vs. expected bucket here */
    546             if (tr_hash_bucket_search(unit, ad, mem, soft_bucket,
    547                                       bucket_size, VALIDf, entry, dual, bank) < 0) {
    548                 test_error(unit,
    549                            "Vlan xlate entry with key "
    550                            "0x%02x%02x%02x%02x%02x%02x%02x%01x "
    551                            "not found in predicted bucket %d\n",
    552                            key[7], key[6], key[5], key[4],
    553                            key[3], key[2], key[1], (key[0] >> 4) & 0xf,
    554                            soft_bucket);
    555                 rv = -1;
    556                 goto done;
    557             }
    558     
    559             /* Search for the entry, should be found */
    560             if (soc_mem_search(unit, mem, MEM_BLOCK_ALL, &index,
    561                                entry, entry, 0) < 0) {
    562                 test_error(unit, "Vlan xlate search failed in bucket %d\n",
    563                            soft_bucket);
    564                 rv = -1;
    565                 goto done;
    566             }
    567     
    568             /* Insert the entry again, should fail. */
    569             if (soc_mem_bank_insert(unit, mem, banks,
    570                                     MEM_BLOCK_ALL, entry, NULL) != SOC_E_EXISTS) {
    571                 test_error(unit,
    572                            "Vlan xlate insert should have failed at bucket %d\n", soft_bucket);
    573                 rv = -1;
    574                 goto done;
    575             }
    576     
    577             /* Delete the entry */
    578             if (soc_mem_delete(unit, mem, MEM_BLOCK_ALL, entry) < 0) {
    579                 test_error(unit, "Vlan xlate delete failed at bucket %d\n",
    580                            soft_bucket);
    581                 rv = -1;
    582                 goto done;
    583             }
    584     
    585             /* Delete the entry again, should fail.*/
    586             if (soc_mem_delete(unit, mem,
    587                                MEM_BLOCK_ALL, entry) != SOC_E_NOT_FOUND) {
    588                 test_error(unit, "Vlan xlate delete should have failed in bucket %d\n",
    589                            soft_bucket);
    590                 rv = -1;
    591                 goto done;
    592             }
    593     
    594             /* Search for the entry again, should not be found */
    595             if (soc_mem_search(unit, mem, MEM_BLOCK_ALL, &index,
    596                                entry, entry, 0) != SOC_E_NOT_FOUND) {
    597                 test_error(unit, "Vlan xlate search should have failed in bucket %d\n",
    598                            soft_bucket);
    599                 rv = -1;
    600                 goto done;
    601             }
    602     
    603         }
    604         ovid += vid_inc;
    605         if (ovid > TR_VID_MAX) {
    606             ovid = 1;
    607         }
    608         ivid += vid_inc;
    609         if (ivid > TR_VID_MAX) {
    610             ivid = 1;
    611         }
    612     }
    613 
    614  done:
    615     return rv;
    616 }
    617 
    618 /*
    619  * Test of Vlan xlate overflow behavior
    620  *
    621  *   This test fills each bucket, then inserts another entry to see
    622  *   that the last entry fails to insert.
    623  */
    624 
    625 int
    626 tr_vlan_xlate_test_ov(int unit, args_t *a, void *p)
    627 {
    628     tr_hash_testdata_t  *ad = p;
    629 #if defined(BCM_ESW_SUPPORT) 
    630     uint32 entry[SOC_MAX_MEM_FIELD_WORDS];
    631     uint32 result[SOC_MAX_MEM_FIELD_WORDS];
    632     /* 20 is good enough for VLAN_XLATE TABLEs */
    633     uint32 entry_tmp[16][20];
    634 #endif    
    635     int                 ix, jx, r, idx, rv = 0;
    636     int ovid, ivid;
    637     int bucket = 0;
    638     uint32 hash = ad->opt_hash;
    639     int vid_inc = ad->opt_vid_inc;
    640     int iter = ad->opt_count;
    641     uint8 key[XGS_HASH_KEY_SIZE];
    642     int bucket_size;
    643     soc_mem_t mem;
    644 
    645     COMPILER_REFERENCE(a);
    646 
    647     mem = ad->mem;
    648 
    649     /* This seems to be a fair "guess". is there a way to find the bucket size used in the HW? */
    650     if (mem != VLAN_XLATEm) {
    651         bucket_size = 4;
    652     } else {
    653     bucket_size = (soc_mem_index_max(unit, VLAN_MACm) < 32767) ? 8 : 16;
    654     }
    655 
    656 #ifdef BCM_APACHE_SUPPORT
    657     if(SOC_IS_APACHE(unit)) {
    658         bucket_size = 8;
    659     }
    660 #endif
    661 
    662 #if defined(BCM_SABER2_SUPPORT)
    663     if(SOC_IS_SABER2(unit)) {
    664 	    /* Even though with the reduced table size saber2 has the same bucket size as KT2 for this table */
    665 	    bucket_size = 16;
    666     }
    667 #endif
    668 
    669     if (hash != FB_HASH_LSB) {
    670         if (ad->opt_verbose) {
    671             cli_out("Resetting hash selection to LSB\n");
    672         }
    673 
    674         hash = ad->save_hash_control;
    675         soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash,
    676                           HASH_SELECT_Af, FB_HASH_LSB);
    677         soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash,
    678                           HASH_SELECT_Bf, FB_HASH_LSB);
    679     
    680         if (WRITE_VLAN_XLATE_HASH_CONTROLr(unit, hash) < 0) {
    681             test_error(unit, "Hash select setting failed\n");
    682             goto done;
    683         }
    684 
    685         ad->opt_hash = hash = FB_HASH_LSB;
    686     }
    687 
    688     if (iter > soc_mem_index_count(unit, mem)) {
    689         iter = soc_mem_index_count(unit, mem);
    690     }
    691     ovid = 0;
    692     ivid = ad->opt_base_ivid;
    693 
    694     while (iter--) {
    695         for (ix = 0; ix < bucket_size; ix++) {
    696             sal_memset(entry_tmp[ix], 0, sizeof(entry_tmp[0]));
    697             if (soc_feature(unit, soc_feature_base_valid)) {
    698                 soc_mem_field32_set(unit, mem, entry_tmp[ix], BASE_VALID_0f, 3);
    699                 soc_mem_field32_set(unit, mem, entry_tmp[ix], BASE_VALID_1f, 7);
    700             } else {
    701                 soc_mem_field32_set(unit, mem, entry_tmp[ix], VALIDf, 1);
    702             }
    703             soc_mem_field32_set(unit, mem, entry_tmp[ix], OVIDf, ovid);
    704             soc_mem_field32_set(unit, mem, entry_tmp[ix], IVIDf, ivid);
    705             soc_mem_field32_set(unit, mem, entry_tmp[ix], KEY_TYPEf, 0);
    706 
    707             if (ix == 0) {
    708                 int num_bits;
    709                 num_bits = soc_tr_vlan_xlate_base_entry_to_key
    710                     (unit, (uint32 *) entry_tmp[ix], key);
    711                 bucket = soc_tr_vlan_xlate_hash
    712                     (unit, hash, num_bits, (uint32 *) entry_tmp[ix], key);
    713 
    714                 if (ad->opt_verbose) {
    715                     cli_out("Filling bucket %d\n", bucket);
    716                 }
    717             }
    718 
    719             if ((r = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, entry_tmp[ix])) < 0) {
    720                 if (r == SOC_E_FULL) {
    721                     /* Already full, stop wasting time */
    722                     break;
    723                 } else {
    724                     test_error(unit,
    725                                "Vlan xlate insert failed at bucket %d\n", bucket);
    726                     rv = -1;
    727                     goto done;
    728                 }
    729             }
    730 
    731             /* key for LSB is the OVID, so we must keep it constant */
    732             ivid += vid_inc;
    733             if (ivid > TR_VID_MAX) {
    734                 ivid = 1;
    735             }
    736         }
    737 
    738         if (ad->opt_verbose) {
    739             cli_out("Inserting %dth entry in bucket %d, should fail\n",
    740                     (bucket_size + 1), bucket);
    741         }
    742 
    743         sal_memset(entry, 0,  sizeof(entry));
    744         if (soc_feature(unit, soc_feature_base_valid)) {
    745             soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
    746             soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
    747         } else {
    748             soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
    749         }
    750         soc_mem_field32_set(unit, mem, entry, OVIDf, ovid);
    751         soc_mem_field32_set(unit, mem, entry, IVIDf, ivid);
    752         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 0);
    753 
    754         if ((r = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, entry)) < 0) {
    755             if (r != SOC_E_FULL) {
    756                 test_error(unit,
    757                            "Vlan xlate insert failed\n");
    758                 rv = -1;
    759                 goto done;
    760             }
    761         } else {
    762             test_error(unit, "Vlan xlate insert to full bucket succeeded\n");
    763             rv = -1;
    764             goto done;
    765         }
    766 
    767         if (ad->opt_verbose) {
    768             cli_out("Verifying entries present\n");
    769         }
    770 
    771         /* Verify bucket contains our added entries */
    772         for (jx = 0; jx < ix; jx++) {
    773             if (tr_hash_bucket_search(unit, ad, mem, bucket,
    774                                       bucket_size, VALIDf, entry_tmp[jx], 0, 0) < 0) {
    775                 test_error(unit, "VLAN xlate entry missing at bucket %d\n", bucket);
    776                 rv = -1;
    777                 goto done;
    778             }
    779             if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx,
    780                                entry_tmp[jx], result, 0) < 0) {
    781                 test_error(unit, "VLAN xlate entry missing at bucket %d\n", bucket);
    782                 rv = -1;
    783                 goto done;
    784             }
    785             if (bucket != (idx / bucket_size)) {
    786                 test_error(unit, "VLAN xlate entry inserted into wrong bucket"
    787                            " Expected %d Actual %d\n", bucket, idx);
    788                 rv = -1;
    789                 goto done;
    790             }
    791         }
    792 
    793         if (ad->opt_verbose) {
    794             cli_out("Cleaning bucket %d\n", bucket);
    795         }
    796 
    797         /* Remove the entries that we added */
    798         for (jx = 0; jx < ix; jx++) {
    799             if (soc_mem_delete(unit, mem, MEM_BLOCK_ALL, entry_tmp[jx]) < 0) {
    800                 test_error(unit, "Vlan xlate delete failed at bucket %d\n", bucket);
    801                 rv = -1;
    802                 goto done;
    803             }
    804         }
    805 
    806         /* We want the increment to change buckets by one. For VLAN XLATE,
    807          * the LSB hash bucket for KEY_TYPE 0 is determined by OVID. 
    808          */
    809         ovid += 1;
    810         if (ovid > TR_VID_MAX) {
    811             ovid = 0;
    812         }
    813     }
    814 
    815  done:
    816 
    817     return rv;
    818 }
    819 
    820 /*
    821  * Test clean-up routine used for all Vlan xlate tests
    822  */
    823 
    824 int
    825 tr_vlan_xlate_test_done(int unit, void *p)
    826 {
    827     tr_hash_testdata_t *ad = p;
    828     soc_mem_t mem;
    829 
    830     if (ad == NULL) {
    831 	return 0;
    832     }
    833 
    834     mem = ad->mem;
    835 
    836     /* Check if empty at the end of the test */
    837     if (ad->opt_reset) {
    838         int rv, ix;
    839         int index_min = soc_mem_index_min(unit, mem);
    840         int index_max = soc_mem_index_max(unit, mem);
    841         uint32 *buf = 0;
    842         uint32 *ent;
    843         uint32 count;
    844 
    845         buf = soc_cm_salloc(unit,
    846                             SOC_MEM_TABLE_BYTES(unit, mem),
    847                             "vlan_xlate_test");
    848         if (!buf) {
    849             test_error(unit, "Memory allocation failed\n");
    850             return (-1);
    851         }
    852 
    853         if ((rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
    854                           index_min, index_max, buf)) < 0) {
    855             test_error(unit, "Memory DMA of VLAN_XLATEm entries failed\n");
    856             return (-1);
    857         }
    858 
    859         count = soc_mem_index_count(unit, mem);
    860         for (ix = 0; ix < count; ix++) {
    861             int vld = 0;
    862             ent = soc_mem_table_idx_to_pointer(unit, mem,
    863                                                uint32 *, buf, ix);
    864 
    865             if (soc_feature(unit, soc_feature_base_valid)) {
    866                 vld = soc_mem_field32_get(unit, mem, ent, BASE_VALID_0f) == 3 &&
    867                       soc_mem_field32_get(unit, mem, ent, BASE_VALID_1f) == 7;
    868             } else
    869             {
    870                 vld = soc_mem_field32_get(unit, mem, ent, VALIDf);
    871             }
    872 
    873             if (vld) {
    874                 test_error(unit, "Vlan xlate table not empty after test entry = %d\n",
    875                                 ix);
    876                 soc_mem_entry_dump(unit, VLAN_XLATEm, ent, BSL_LSS_CLI);
    877                 return (-1);
    878             }
    879         }
    880 
    881         soc_cm_sfree(unit, buf);
    882     }
    883 
    884 #ifdef BCM_TRIDENT3_SUPPORT
    885     if (soc_feature(unit, soc_feature_base_valid)) {
    886         if (soc_mem_write(unit, VLAN_XLATE_1_HASH_CONTROLm, MEM_BLOCK_ALL,
    887                          0, &ad->save_xlate_hash_control) < 0) {
    888             test_error(unit, "Hash Control restore failed\n");
    889         }
    890     } else
    891 #endif /* BCM_TRIDENT3_SUPPORT */
    892     {
    893     if (WRITE_VLAN_XLATE_HASH_CONTROLr(unit, ad->save_hash_control) < 0) {
    894         test_error(unit, "Hash select restore failed\n");
    895     }
    896     }
    897 
    898     return 0;
    899 }
    900 
    901 /************************** END OF VLAN XLATE TESTS ************************/
    902 
    903 /************************ START OF EGR VLAN XLATE TESTS ********************/
    904 /*
    905  * Test initialization routine used for Egress Vlan xlate tests
    906  */
    907 
    908 STATIC int
    909 tr_egr_vlan_xlate_test_init(int unit, tr_hash_testdata_t *ad, args_t *a)
    910 {
    911     int                         rv = -1, dual = 0;
    912     parse_table_t               pt;
    913     uint32                      hash_read;
    914 #if defined(BCM_TRIDENT3_SUPPORT)
    915     l2_entry_hash_control_entry_t xlate_hash_read;
    916 #endif /* BCM_TRIDENT3_SUPPORT */
    917 
    918     parse_table_init(unit, &pt);
    919 
    920     parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL);
    921     parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL);
    922     parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL);
    923     parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL);
    924     parse_table_add(&pt, "DualHash", PQ_INT|PQ_DFL, 0, &ad->opt_dual_hash, NULL);
    925     parse_table_add(&pt, "DualEnable", PQ_INT|PQ_DFL, 0, &dual, NULL);
    926     parse_table_add(&pt, "BaseOVID", PQ_INT|PQ_DFL, 0, &ad->opt_base_ovid, NULL);
    927     parse_table_add(&pt, "BaseIVID", PQ_INT|PQ_DFL, 0, &ad->opt_base_ivid, NULL);
    928     parse_table_add(&pt, "VidIncrement", PQ_INT|PQ_DFL, 0,
    929                     &ad->opt_vid_inc, NULL);
    930 
    931     /* Test the obvious parsings before wasting time with malloc */
    932     if (parse_arg_eq(a, &pt) < 0) {
    933         test_error(unit,
    934                    "%s: Error: Invalid option: %s\n", ARG_CMD(a),
    935                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    936         goto done;
    937     }
    938 
    939     if (ad->opt_count < 1) {
    940         test_error(unit, "Illegal count %d\n", ad->opt_count);
    941         goto done;
    942     }
    943 
    944     if (ad->opt_hash >= ad->hash_count) {
    945         test_error(unit, "Illegal hash selection %d\n", ad->opt_hash);
    946         goto done;
    947     }
    948 
    949     if (dual == 1) {
    950         if (ad->opt_dual_hash >= ad->hash_count) {
    951             test_error(unit, "Illegal dual hash selection %d\n", ad->opt_dual_hash);
    952             goto done;
    953         }
    954     } else {
    955         ad->opt_dual_hash = -1;
    956     }
    957 
    958     if (ad->opt_base_ovid >= (1 << 12)) {
    959         test_error(unit, "Out of range Outer VLAN ID selection %d\n",
    960                    ad->opt_base_ovid);
    961         goto done;
    962     }
    963 
    964     if (ad->opt_base_ivid >= (1 << 12)) {
    965         test_error(unit, "Out of range Inner VLAN ID selection %d\n",
    966                    ad->opt_base_ivid);
    967         goto done;
    968     }
    969 
    970     /*
    971      * Re-initialize chip to ensure tables are clear
    972      * at start of test.
    973      */
    974 
    975     if (ad->opt_reset) {
    976         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
    977         if (soc_reset_init(unit) < 0) {
    978             test_error(unit, "SOC initialization failed\n");
    979             goto done;
    980         }
    981 
    982         if (soc_misc_init(unit) < 0) {
    983             test_error(unit, "MISC initialization failed\n");
    984             goto done;
    985         }
    986 
    987         if (soc_mmu_init(unit) < 0) {
    988             test_error(unit, "MMU initialization failed\n");
    989             goto done;
    990         }
    991 
    992         if (mbcm_init(unit) < 0) { 
    993             test_error(unit, "BCM initialization failed\n");
    994             goto done;
    995         }
    996 
    997     }
    998 #ifdef BCM_TRIDENT3_SUPPORT
    999     if (soc_feature(unit, soc_feature_base_valid)) {
   1000         if (soc_mem_read(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, MEM_BLOCK_ALL,
   1001                          0, &xlate_hash_read) < 0) {
   1002             test_error(unit, "Hash Control read failed\n");
   1003             goto done;
   1004         }
   1005 
   1006         sal_memcpy(&ad->save_xlate_hash_control, &xlate_hash_read,
   1007                    sizeof(xlate_hash_read));
   1008         /* Set robust hash, test mode settings if need be..,
   1009            For now - we are using default setting */
   1010     } else
   1011 #endif /* BCM_TRIDENT3_SUPPORT */
   1012     {
   1013     if (READ_EGR_VLAN_XLATE_HASH_CONTROLr(unit, &hash_read) < 0) {
   1014         test_error(unit, "Hash select read failed\n");
   1015         goto done;
   1016     }
   1017 
   1018     ad->save_hash_control = hash_read;
   1019 
   1020     soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash_read,
   1021                       HASH_SELECT_Af, ad->opt_hash);
   1022     if (ad->opt_dual_hash != -1) {
   1023         soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash_read,
   1024                           HASH_SELECT_Bf, ad->opt_dual_hash);
   1025     } else {
   1026         soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash_read,
   1027                           HASH_SELECT_Bf, ad->opt_hash);
   1028     }
   1029 
   1030     if (WRITE_EGR_VLAN_XLATE_HASH_CONTROLr(unit, hash_read) < 0) {
   1031         test_error(unit, "Hash select setting failed\n");
   1032         goto done;
   1033     }
   1034     }
   1035 
   1036     if ((rv = soc_mem_clear(unit, ad->mem, COPYNO_ALL, TRUE)) < 0) {
   1037         goto done;
   1038     }
   1039 
   1040     rv = 0;
   1041 
   1042  done:
   1043 
   1044     parse_arg_eq_done(&pt);
   1045     return rv;
   1046 }
   1047 
   1048 STATIC void
   1049 tr_egr_vlan_xlate_hash_setup(int unit, tr_hash_test_t *dw)
   1050 {
   1051     tr_hash_testdata_t *ad;
   1052     soc_mem_t mem = EGR_VLAN_XLATEm;
   1053 
   1054     if (dw->lw_set_up) {
   1055         return;
   1056     }
   1057 
   1058     dw->lw_set_up = TRUE;
   1059     dw->lw_unit = unit;
   1060 
   1061     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   1062         mem = EGR_VLAN_XLATE_1_DOUBLEm;
   1063     }
   1064     dw->lp_hash.mem = mem;
   1065     dw->lp_ov.mem = mem;
   1066 
   1067     /* Hash */
   1068     ad = &dw->lp_hash;
   1069 
   1070     ad->opt_count      = soc_mem_index_count(unit, mem);
   1071 #ifdef BCM_TRIDENT2_SUPPORT
   1072     if (soc_feature(unit, soc_feature_extended_hash)) {
   1073         ad->opt_hash       = FB_HASH_CRC32_LOWER;
   1074         ad->opt_dual_hash  = FB_HASH_CRC32_UPPER;
   1075     } else
   1076 #endif /* BCM_TRIDENT2_SUPPORT */
   1077     {
   1078         ad->opt_hash       = FB_HASH_CRC16_LOWER;
   1079         ad->opt_dual_hash  = -1;
   1080     }
   1081     ad->hash_count     = FB_HASH_COUNT;
   1082     ad->opt_base_ovid  = 0;
   1083     ad->opt_base_ivid  = 0;
   1084     ad->opt_vid_inc    = 1;
   1085 
   1086     /* Overflow */
   1087     ad = &dw->lp_ov;
   1088 
   1089     ad->opt_count      = 2048;
   1090     ad->opt_hash       = TR_DEFAULT_HASH;
   1091     ad->opt_dual_hash  = -1;
   1092     ad->hash_count     = FB_HASH_COUNT;
   1093     ad->opt_base_ovid  = 0;
   1094     ad->opt_base_ivid  = 0;
   1095     ad->opt_vid_inc    = 1;
   1096 }
   1097 
   1098 /* Individual test init wrappers */
   1099 int
   1100 tr_egr_vlan_xlate_hash_test_init(int unit, args_t *a, void **p)
   1101 {
   1102     tr_hash_test_t        *dw = &tr_egr_vlan_xlate_work[unit];
   1103     tr_hash_testdata_t    *dp = &dw->lp_hash;
   1104     int                    rv;
   1105 
   1106     tr_egr_vlan_xlate_hash_setup(unit, dw);
   1107 
   1108     /* Set working data to hash */
   1109     dw->lp_cur = dp;
   1110 
   1111     if ((rv = tr_egr_vlan_xlate_test_init(unit, dp, a)) < 0) {
   1112         return rv;
   1113     } else {
   1114         *p = dp;
   1115     }
   1116 
   1117     return 0;
   1118 }
   1119 
   1120 int
   1121 tr_egr_vlan_xlate_ov_test_init(int unit, args_t *a, void **p)
   1122 {
   1123     tr_hash_test_t        *dw = &tr_egr_vlan_xlate_work[unit];
   1124     tr_hash_testdata_t    *dp = &dw->lp_ov;
   1125     int                    rv;
   1126 
   1127     tr_egr_vlan_xlate_hash_setup(unit, dw);
   1128 
   1129     /* Set working data to hash */
   1130     dw->lp_cur = dp;
   1131 
   1132     if ((rv = tr_egr_vlan_xlate_test_init(unit, dp, a)) < 0) {
   1133         return rv; 
   1134     } else {
   1135         *p = dp;
   1136     }
   1137 
   1138     return 0;
   1139 }
   1140 
   1141 /*
   1142  * Test of EGRESS VLAN XLATE hashing
   1143  *
   1144  *   This test tries a number of keys against one of the hashing functions,
   1145  *   checking a software hash against the hardware hash, then searching the
   1146  *   bucket to find the entry after inserting.
   1147  */
   1148 int
   1149 tr_egr_vlan_xlate_test_hash(int unit, args_t *a, void *p)
   1150 {
   1151     tr_hash_testdata_t         *ad = p;
   1152     uint32 entry[SOC_MAX_MEM_FIELD_WORDS];
   1153     int soft_bucket, ix, r, rv = 0;
   1154     int hash = ad->opt_hash;
   1155     uint8 key[XGS_HASH_KEY_SIZE];
   1156     int iterations, ovid, ivid, num_bits;
   1157     int vid_inc = ad->opt_vid_inc;
   1158     int bucket_size;
   1159     int index;
   1160     int dual = FALSE;
   1161     int bank, banks, bank_count = 1;
   1162     soc_mem_t mem = ad->mem;
   1163 
   1164     COMPILER_REFERENCE(a);
   1165 
   1166     if (ad->opt_verbose) {
   1167         cli_out("Starting EGR VLAN xlate hash test\n");
   1168     }
   1169 
   1170     sal_memset(key, 0, sizeof(key));
   1171 
   1172     /* This seems to be a fair "guess". is there a way to find the bucket size used in the HW? */
   1173     bucket_size = (soc_mem_index_max(unit, mem) < 32767) ? 8 : 16;
   1174 
   1175     if (SOC_IS_TRIDENT3X(unit)) {
   1176         bucket_size = 4;
   1177     }
   1178 
   1179 #ifdef BCM_APACHE_SUPPORT
   1180     if(SOC_IS_APACHE(unit)) {
   1181         bucket_size = 8;
   1182     }
   1183 #endif
   1184 
   1185 #if defined(BCM_SABER2_SUPPORT)
   1186     if(SOC_IS_SABER2(unit)) {
   1187 	    /* Even though with the reduced table size saber2 has the same bucket size as KT2 for this table */
   1188 	    bucket_size = 16;
   1189     }
   1190 #endif
   1191 
   1192     iterations = ad->opt_count;
   1193     ovid = ad->opt_base_ovid;
   1194     ivid = ad->opt_base_ivid;
   1195     if (ad->opt_dual_hash != -1) {
   1196         dual = TRUE;
   1197         bank_count = 2;
   1198     }
   1199 
   1200 
   1201     for (ix = 0; ix < iterations; ix++) {
   1202         for (bank = 0; bank < bank_count; bank++) {
   1203             sal_memset(entry, 0, sizeof (entry));
   1204             if (soc_feature(unit, soc_feature_base_valid)) {
   1205                 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   1206                 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
   1207             } else {
   1208                 soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   1209             }
   1210             soc_mem_field32_set(unit, mem, entry, OVIDf, ovid);
   1211             soc_mem_field32_set(unit, mem, entry, IVIDf, ivid);
   1212 
   1213 #ifdef BCM_TRIDENT3_SUPPORT
   1214             if (SOC_IS_TRIDENT3X(unit)) {
   1215                 soft_bucket = soc_td3_egr_vlan_xlate_bank_entry_hash(unit, mem, bank,
   1216                                                  (uint32 *) entry);
   1217                 if (mem == EGR_VLAN_XLATE_1_DOUBLEm) {
   1218                     /* Double Wide Entry , extract 10 bits only */
   1219                     soft_bucket &= 0x3FF;
   1220                 }
   1221             } else
   1222 #endif
   1223             {
   1224             num_bits = soc_tr_egr_vlan_xlate_base_entry_to_key
   1225                     (unit, (uint32 *) entry, key);
   1226             soft_bucket = soc_tr_egr_vlan_xlate_hash(unit, hash, num_bits,
   1227                                                      (uint32 *)entry, key);
   1228             }
   1229             banks = 0;
   1230             if (dual == TRUE) {
   1231 #ifdef BCM_TRIDENT2_SUPPORT
   1232 #ifdef BCM_TRIDENT3_SUPPORT
   1233                 if (SOC_IS_TRIDENT3X(unit)) {
   1234                     /* soft_bucket is already computed on the top */
   1235                 } else
   1236 #endif /* BCM_TRIDENT3_SUPPORT */
   1237 #ifdef BCM_APACHE_SUPPORT
   1238                 if (SOC_IS_APACHE(unit)) {
   1239                     soft_bucket = soc_ap_egr_vlan_xlate_bank_entry_hash(unit,
   1240                                                     bank, (uint32 *) entry);
   1241                 } else
   1242 #endif /* BCM_APACHE_SUPPORT */
   1243 #ifdef BCM_TOMAHAWK_SUPPORT
   1244                 if (SOC_IS_TOMAHAWKX(unit)) {
   1245                     soft_bucket = soc_th_egr_vlan_xlate_bank_entry_hash(unit,
   1246                                                     bank, (uint32 *) entry);
   1247                 } else
   1248 #endif /* BCM_TOMAHAWK_SUPPORT */
   1249                 if (soc_feature(unit, soc_feature_extended_hash)) {
   1250                     soft_bucket = soc_td2_egr_vlan_xlate_bank_entry_hash(unit,
   1251                                                     bank, (uint32 *) entry);
   1252                 } else
   1253 #endif /* BCM_TRIDENT2_SUPPORT */
   1254                 {
   1255                     soft_bucket = soc_tr_egr_vlan_xlate_bank_entry_hash
   1256                         (unit, bank, (uint32 *) entry);
   1257                 }
   1258                 banks = (bank == 0) ? 2 : 1;
   1259             }
   1260     
   1261     
   1262             if (ad->opt_verbose) {
   1263                 cli_out("Inserting ");
   1264                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   1265                 cli_out("\n");
   1266                 if (dual) {
   1267                     cli_out("into bucket 0x%x (bank %d)\n",
   1268                             soft_bucket, bank);
   1269                 } else {
   1270                    cli_out("into bucket 0x%x\n", soft_bucket);
   1271                 }
   1272             }
   1273     
   1274             if ((r = soc_mem_bank_insert(unit, mem, banks,
   1275                                          MEM_BLOCK_ALL, entry, NULL)) < 0) {
   1276                 if (r == SOC_E_FULL) {
   1277                     /* Bucket overflow, just pass on */
   1278                     break;
   1279                 } else {
   1280                     test_error(unit,
   1281                                "EGR Vlan xlate insert failed at bucket %d\n", soft_bucket);
   1282                     rv = -1;
   1283                     goto done;
   1284                 }
   1285             }
   1286     
   1287             /* Now we search for the entry */
   1288     
   1289             /* Only do a quick check vs. expected bucket here */
   1290             if (tr_hash_bucket_search(unit, ad, mem, soft_bucket,
   1291                                       bucket_size, VALIDf, entry, dual, bank) < 0) {
   1292                 test_error(unit,
   1293                            "EGR Vlan xlate entry with key "
   1294                            "0x%02x%02x%02x%02x%02x%02x%02x%01x "
   1295                            "not found in predicted bucket %d\n",
   1296                            key[7], key[6], key[5], key[4],
   1297                            key[3], key[2], key[1], (key[0] >> 4) & 0xf,
   1298                            soft_bucket);
   1299                 rv = -1;
   1300                 goto done;
   1301             }
   1302     
   1303             /* Search for the entry, should be found */
   1304             if (soc_mem_search(unit, mem, MEM_BLOCK_ALL, &index,
   1305                                entry, entry, 0) < 0) {
   1306                 test_error(unit, "EGR Vlan xlate search failed in bucket %d\n",
   1307                            soft_bucket);
   1308                 rv = -1;
   1309                 goto done;
   1310             }
   1311     
   1312             /* Insert the entry again, should fail. */
   1313             if (soc_mem_bank_insert(unit, mem, banks,
   1314                                     MEM_BLOCK_ALL, entry, NULL) != SOC_E_EXISTS) {
   1315                 test_error(unit,
   1316                            "EGR Vlan xlate insert should have failed at bucket %d\n", 
   1317                             soft_bucket);
   1318                 rv = -1;
   1319                 goto done;
   1320             }
   1321     
   1322             /* Delete the entry */
   1323             if (soc_mem_delete(unit, mem, MEM_BLOCK_ALL, entry) < 0) {
   1324                 test_error(unit, "EGR Vlan xlate delete failed at bucket %d\n",
   1325                            soft_bucket);
   1326                 rv = -1;
   1327                 goto done;
   1328             }
   1329     
   1330             /* Delete the entry again, should fail.*/
   1331             if (soc_mem_delete(unit, mem,
   1332                                MEM_BLOCK_ALL, entry) != SOC_E_NOT_FOUND) {
   1333                 test_error(unit, "EGR Vlan xlate delete should have failed in bucket %d\n",
   1334                            soft_bucket);
   1335                 rv = -1;
   1336                 goto done;
   1337             }
   1338     
   1339             /* Search for the entry again, should not be found */
   1340             if (soc_mem_search(unit, mem, MEM_BLOCK_ALL, &index,
   1341                                entry, entry, 0) != SOC_E_NOT_FOUND) {
   1342                 test_error(unit, "EGR Vlan xlate search should have failed in bucket %d\n",
   1343                            soft_bucket);
   1344                 rv = -1;
   1345                 goto done;
   1346             }
   1347         }
   1348         ovid += vid_inc;
   1349         if (ovid > TR_VID_MAX) {
   1350             ovid = 1;
   1351         }
   1352         ivid += vid_inc;
   1353         if (ivid > TR_VID_MAX) {
   1354             ivid = 1;
   1355         }
   1356     }
   1357 
   1358  done:
   1359     return rv;
   1360 }
   1361 
   1362 /*
   1363  * Test of Egress Vlan xlate overflow behavior
   1364  *
   1365  *   This test fills each bucket, then inserts another entry to see
   1366  *   that the last entry fails to insert.
   1367  */
   1368 
   1369 int
   1370 tr_egr_vlan_xlate_test_ov(int unit, args_t *a, void *p)
   1371 {
   1372     tr_hash_testdata_t  *ad = p;
   1373 
   1374     uint32 entry[SOC_MAX_MEM_FIELD_WORDS];
   1375     uint32 result[SOC_MAX_MEM_FIELD_WORDS];
   1376     /* 20 is good enough for EGR_VLAN_XLATE TABLEs */
   1377     uint32 entry_tmp[16][20];
   1378 
   1379     int                 ix, jx, r, idx, rv = 0;
   1380     int ivid, port_group;
   1381     volatile int ovid;
   1382     int bucket = 0;
   1383     uint32 hash = ad->opt_hash;
   1384     volatile int iter = ad->opt_count;
   1385     uint8 key[XGS_HASH_KEY_SIZE];
   1386     int bucket_size;
   1387     soc_mem_t mem = ad->mem;
   1388 
   1389     COMPILER_REFERENCE(a);
   1390 
   1391     /* This seems to be a fair "guess". is there a way to find the bucket size used in the HW? */
   1392     bucket_size = (soc_mem_index_max(unit, mem) < 32767) ? 8 : 16;
   1393 
   1394     if (SOC_IS_TRIDENT3X(unit)) {
   1395         bucket_size = 4;
   1396     }
   1397 
   1398 #ifdef BCM_APACHE_SUPPORT
   1399     if(SOC_IS_APACHE(unit)) {
   1400         bucket_size = 8;
   1401     }
   1402 #endif
   1403 
   1404 #if defined(BCM_SABER2_SUPPORT)
   1405     if(SOC_IS_SABER2(unit)) {
   1406 	    /* Even though with the reduced table size saber2 has the same bucket size as KT2 for this table */
   1407 	    bucket_size = 16;
   1408     }
   1409 #endif
   1410 
   1411     if (hash != FB_HASH_LSB) {
   1412         if (ad->opt_verbose) {
   1413             cli_out("Resetting hash selection to LSB\n");
   1414         }
   1415 
   1416         hash = ad->save_hash_control;
   1417         soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash,
   1418                           HASH_SELECT_Af, FB_HASH_LSB);
   1419         soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash,
   1420                           HASH_SELECT_Bf, FB_HASH_LSB);
   1421     
   1422         if (WRITE_EGR_VLAN_XLATE_HASH_CONTROLr(unit, hash) < 0) {
   1423             test_error(unit, "Hash select setting failed\n");
   1424             goto done;
   1425         }
   1426 
   1427         ad->opt_hash = hash = FB_HASH_LSB;
   1428     }
   1429 
   1430     if (iter > soc_mem_index_count(unit, mem)) {
   1431         iter = soc_mem_index_count(unit, mem);
   1432     }
   1433     port_group = 0;
   1434     ovid = 0;
   1435     ivid = 0;
   1436 
   1437     while (iter--) {
   1438         for (ix = 0; ix < bucket_size; ix++) {
   1439             sal_memset(entry_tmp[ix], 0, sizeof(entry_tmp[0]));
   1440             if (soc_feature(unit, soc_feature_base_valid)) {
   1441                 soc_mem_field32_set(unit, mem, entry_tmp[ix], BASE_VALID_0f, 3);
   1442                 soc_mem_field32_set(unit, mem, entry_tmp[ix], BASE_VALID_1f, 7);
   1443             } else {
   1444                 soc_mem_field32_set(unit, mem, entry_tmp[ix], VALIDf, 1);
   1445             }
   1446             soc_mem_field32_set(unit, mem, entry_tmp[ix], OVIDf, ovid);
   1447             soc_mem_field32_set(unit, mem, entry_tmp[ix], IVIDf, ivid);
   1448             soc_mem_field32_set(unit, mem, entry_tmp[ix], PORT_GROUP_IDf, port_group);
   1449 
   1450             if (ix == 0) {
   1451                 int num_bits;
   1452                 num_bits = soc_tr_egr_vlan_xlate_base_entry_to_key
   1453                     (unit, (uint32 *) entry_tmp[ix], key);
   1454                 bucket = soc_tr_egr_vlan_xlate_hash(unit, hash, num_bits,
   1455                                                     (uint32 *)entry_tmp[ix],
   1456                                                     key);
   1457 
   1458                 if (ad->opt_verbose) {
   1459                     cli_out("Filling bucket %d\n", bucket);
   1460                 }
   1461             }
   1462 
   1463             if ((r = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, entry_tmp[ix])) < 0) {
   1464                 if (r == SOC_E_FULL) {
   1465                     /* Already full, stop wasting time */
   1466                     break;
   1467                 } else {
   1468                     test_error(unit,
   1469                                "EGR Vlan xlate insert failed at bucket %d\n", bucket);
   1470                     rv = -1;
   1471                     goto done;
   1472                 }
   1473             }
   1474 
   1475             /* key for LSB is the OVID , so we must keep it constant */
   1476             ivid += 1;
   1477             if (ivid > TR_VID_MAX) {
   1478                 ivid = 0;
   1479     /*    coverity[assignment : FALSE]    */
   1480                 port_group += 1;
   1481                 if (port_group > 0x3f) {
   1482                     port_group = 0;
   1483                 }
   1484             }
   1485         }
   1486 
   1487         if (ad->opt_verbose) {
   1488             cli_out("Inserting %dth entry in bucket %d, should fail\n",
   1489                     (bucket_size + 1), bucket);
   1490         }
   1491 
   1492         sal_memset(entry, 0,  sizeof(entry));
   1493         if (soc_feature(unit, soc_feature_base_valid)) {
   1494             soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   1495             soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
   1496         } else {
   1497             soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   1498         }
   1499         soc_mem_field32_set(unit, mem, entry, OVIDf, ovid);
   1500         soc_mem_field32_set(unit, mem, entry, IVIDf, ivid);
   1501         soc_mem_field32_set(unit, mem, entry, PORT_GROUP_IDf, port_group);
   1502 
   1503         if ((r = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, entry)) < 0) {
   1504             if (r != SOC_E_FULL) {
   1505                 test_error(unit,
   1506                            "EGR Vlan xlate insert failed\n");
   1507                 rv = -1;
   1508                 goto done;
   1509             }
   1510         } else {
   1511             test_error(unit, "EGR Vlan xlate insert to full bucket succeeded\n");
   1512             rv = -1;
   1513             goto done;
   1514         }
   1515 
   1516         if (ad->opt_verbose) {
   1517             cli_out("Verifying entries present\n");
   1518         }
   1519 
   1520         /* Verify bucket contains our added entries */
   1521         for (jx = 0; jx < ix; jx++) {
   1522             if (tr_hash_bucket_search(unit, ad, mem, bucket,
   1523                                       bucket_size, VALIDf, entry_tmp[jx], 0, 0) < 0) {
   1524                 test_error(unit, "EGR VLAN xlate entry missing at bucket %d\n", bucket);
   1525                 rv = -1;
   1526                 goto done;
   1527             }
   1528             if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx,
   1529                                entry_tmp[jx], result, 0) < 0) {
   1530                 test_error(unit, "EGR VLAN xlate entry missing at bucket %d\n", bucket);
   1531                 rv = -1;
   1532                 goto done;
   1533             }
   1534             if (bucket != (idx / bucket_size)) {
   1535                 test_error(unit, "EGR VLAN xlate entry inserted into wrong bucket"
   1536                            " Expected %d Actual %d\n", bucket, idx);
   1537                 rv = -1;
   1538                 goto done;
   1539             }
   1540         }
   1541 
   1542         if (ad->opt_verbose) {
   1543             cli_out("Cleaning bucket %d\n", bucket);
   1544         }
   1545 
   1546         /* Remove the entries that we added */
   1547         for (jx = 0; jx < ix; jx++) {
   1548             if (soc_mem_delete(unit, mem, MEM_BLOCK_ALL, entry_tmp[jx]) < 0) {
   1549                 test_error(unit, "EGR Vlan xlate delete failed at bucket %d\n", bucket);
   1550                 rv = -1;
   1551                 goto done;
   1552             }
   1553         }
   1554 
   1555         /* We want the increment to change buckets by one. For EGR VLAN XLATE,
   1556          * the LSB hash bucket is determined by {ovid}. 
   1557          */
   1558         ovid += 1;
   1559         if (ovid == TR_VID_MAX) {
   1560             ovid = 0;
   1561         }
   1562     }
   1563 
   1564  done:
   1565 
   1566     return rv;
   1567 }
   1568 
   1569 /*
   1570  * Test clean-up routine used for all EGR Vlan xlate tests
   1571  */
   1572 
   1573 int
   1574 tr_egr_vlan_xlate_test_done(int unit, void *p)
   1575 {
   1576     tr_hash_testdata_t *ad = p;
   1577     soc_mem_t mem;
   1578 
   1579     if (ad == NULL) {
   1580 	return 0;
   1581     }
   1582 
   1583     mem = ad->mem;
   1584 
   1585     /* Check if empty at the end of the test */
   1586     if (ad->opt_reset) {
   1587         int rv, ix;
   1588         int index_min = soc_mem_index_min(unit, mem);
   1589         int index_max = soc_mem_index_max(unit, mem);
   1590         uint32 *buf = 0;
   1591         uint32 *ent;
   1592         uint32 count;
   1593 
   1594         buf = soc_cm_salloc(unit,
   1595                             SOC_MEM_TABLE_BYTES(unit, mem),
   1596                             "egr_vlan_xlate_test");
   1597         if (!buf) {
   1598             test_error(unit, "Memory allocation failed\n");
   1599             return (-1);
   1600         }
   1601 
   1602         if ((rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   1603                           index_min, index_max, buf)) < 0) {
   1604             test_error(unit, "Memory DMA of EGR_VLAN_XLATEm entries failed\n");
   1605             return (-1);
   1606         }
   1607 
   1608         count = soc_mem_index_count(unit, mem);
   1609         for (ix = 0; ix < count; ix++) {
   1610             int vld = 0;
   1611             ent = soc_mem_table_idx_to_pointer(unit, mem,
   1612                                                uint32 *, buf, ix);
   1613             if (soc_feature(unit, soc_feature_base_valid)) {
   1614                 vld = soc_mem_field32_get(unit, mem, ent, BASE_VALID_0f) == 3 &&
   1615                       soc_mem_field32_get(unit, mem, ent, BASE_VALID_1f) == 7;
   1616             } else
   1617             {
   1618                 vld = soc_mem_field32_get(unit, mem, ent, VALIDf);
   1619             }
   1620 
   1621             if (vld) {
   1622                 test_error(unit, "EGR Vlan xlate table not empty after test entry = %d\n",
   1623                                 ix);
   1624                 soc_mem_entry_dump(unit, EGR_VLAN_XLATEm, ent, BSL_LSS_CLI);
   1625                 return (-1);
   1626             }
   1627         }
   1628 
   1629         soc_cm_sfree(unit, buf);
   1630     }
   1631 
   1632 #ifdef BCM_TRIDENT3_SUPPORT
   1633     if (soc_feature(unit, soc_feature_base_valid)) {
   1634         if (soc_mem_write(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, MEM_BLOCK_ALL,
   1635                          0, &ad->save_xlate_hash_control) < 0) {
   1636             test_error(unit, "Hash Control restore failed\n");
   1637         }
   1638     } else
   1639 #endif /* BCM_TRIDENT3_SUPPORT */
   1640     {
   1641     if (WRITE_EGR_VLAN_XLATE_HASH_CONTROLr(unit, ad->save_hash_control) < 0) {
   1642         test_error(unit, "Hash select restore failed\n");
   1643     }
   1644     }
   1645 
   1646     return 0;
   1647 }
   1648 /************************** END OF EGR VLAN XLATE TESTS ********************/
   1649 
   1650 /************************** START OF MPLS TESTS ****************************/
   1651 #ifdef BCM_TRIUMPH_SUPPORT
   1652 /*
   1653  * Test initialization routine used for MPLS tests
   1654  */
   1655 
   1656 STATIC int
   1657 tr_mpls_test_init(int unit, tr_hash_testdata_t *ad, args_t *a)
   1658 {
   1659     int                         rv = -1, dual = 0;
   1660     parse_table_t               pt;
   1661     uint32                      hash_read;
   1662 
   1663     parse_table_init(unit, &pt);
   1664 
   1665     parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL);
   1666     parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL);
   1667     parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL);
   1668     parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL);
   1669     parse_table_add(&pt, "DualHash", PQ_INT|PQ_DFL, 0, &ad->opt_dual_hash, NULL);
   1670     parse_table_add(&pt, "DualEnable", PQ_INT|PQ_DFL, 0, &dual, NULL);
   1671     parse_table_add(&pt, "BaseLabel", PQ_INT|PQ_DFL, 0, &ad->opt_base_label, NULL);
   1672     parse_table_add(&pt, "LabelIncrement", PQ_INT|PQ_DFL, 0,
   1673                     &ad->opt_label_inc, NULL);
   1674 
   1675     /* Test the obvious parsings before wasting time with malloc */
   1676     if (parse_arg_eq(a, &pt) < 0) {
   1677         test_error(unit,
   1678                    "%s: Error: Invalid option: %s\n", ARG_CMD(a),
   1679                    ARG_CUR(a) ? ARG_CUR(a) : "*");
   1680         goto done;
   1681     }
   1682 
   1683     if (ad->opt_count < 1) {
   1684         test_error(unit, "Illegal count %d\n", ad->opt_count);
   1685         goto done;
   1686     }
   1687 
   1688     if (ad->opt_hash >= ad->hash_count) {
   1689         test_error(unit, "Illegal hash selection %d\n", ad->opt_hash);
   1690         goto done;
   1691     }
   1692 
   1693     if (dual == 1) {
   1694         if (ad->opt_dual_hash >= ad->hash_count) {
   1695             test_error(unit, "Illegal dual hash selection %d\n", ad->opt_dual_hash);
   1696             goto done;
   1697         }
   1698     } else {
   1699         ad->opt_dual_hash = -1;
   1700     }
   1701 
   1702     if (ad->opt_base_label >= (1 << 20)) {
   1703         test_error(unit, "Out of range MPLS label selection %d\n",
   1704                    ad->opt_base_label);
   1705         goto done;
   1706     }
   1707 
   1708     /*
   1709      * Re-initialize chip to ensure tables are clear
   1710      * at start of test.
   1711      */
   1712 
   1713     if (ad->opt_reset) {
   1714         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
   1715         if (soc_reset_init(unit) < 0) {
   1716             test_error(unit, "SOC initialization failed\n");
   1717             goto done;
   1718         }
   1719 
   1720         if (soc_misc_init(unit) < 0) {
   1721             test_error(unit, "MISC initialization failed\n");
   1722             goto done;
   1723         }
   1724 
   1725         if (soc_mmu_init(unit) < 0) {
   1726             test_error(unit, "MMU initialization failed\n");
   1727             goto done;
   1728         }
   1729 
   1730         if (mbcm_init(unit) < 0) { 
   1731             test_error(unit, "BCM initialization failed\n");
   1732             goto done;
   1733         }
   1734 
   1735     }
   1736 
   1737 #if defined(BCM_TRIDENT3_SUPPORT)
   1738     if (soc_feature(unit, soc_feature_td3_style_mpls)) {
   1739         sal_memset(ad->td3_hash_tbl_data, 0, sizeof(ad->td3_hash_tbl_data));
   1740 #ifdef BCM_HELIX5_SUPPORT
   1741         if (SOC_IS_HELIX5(unit)) {
   1742             rv = soc_hx5_mpls_hash_control_set(ad->td3_hash_tbl_data);
   1743         } else
   1744 #endif
   1745         {
   1746             rv = soc_td3_mpls_hash_control_set(ad->td3_hash_tbl_data);
   1747         }
   1748         if (rv < 0) {
   1749             test_error(unit, "Hash select read failed\n");
   1750             goto done;
   1751         }
   1752     } else
   1753 #endif
   1754     {
   1755     if (READ_MPLS_ENTRY_HASH_CONTROLr(unit, &hash_read) < 0) {
   1756         test_error(unit, "Hash select read failed\n");
   1757         goto done;
   1758     }
   1759 
   1760     ad->save_hash_control = hash_read;
   1761 
   1762     soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash_read,
   1763                       HASH_SELECT_Af, ad->opt_hash);
   1764     if (ad->opt_dual_hash != -1) {
   1765         soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash_read,
   1766                           HASH_SELECT_Bf, ad->opt_dual_hash);
   1767     } else {
   1768         soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash_read,
   1769                           HASH_SELECT_Bf, ad->opt_hash);
   1770     }
   1771 
   1772     if (WRITE_MPLS_ENTRY_HASH_CONTROLr(unit, hash_read) < 0) {
   1773         test_error(unit, "Hash select setting failed\n");
   1774         goto done;
   1775     }
   1776     }
   1777     rv = 0;
   1778 
   1779  done:
   1780 
   1781     parse_arg_eq_done(&pt);
   1782     return rv;
   1783 }
   1784 
   1785 STATIC void
   1786 tr_mpls_hash_setup(int unit, tr_hash_test_t *dw)
   1787 {
   1788     tr_hash_testdata_t *ad;
   1789 
   1790     if (dw->lw_set_up) {
   1791         return;
   1792     }
   1793 
   1794     dw->lw_set_up = TRUE;
   1795     dw->lw_unit = unit;
   1796 
   1797     /* Hash */
   1798     ad = &dw->lp_hash;
   1799 
   1800     ad->opt_verbose = FALSE;
   1801     if (!SOC_MEM_IS_VALID (unit, MPLS_ENTRYm))
   1802     {
   1803         ad->opt_count = -1;
   1804         return;
   1805     } 
   1806     ad->opt_count      = soc_mem_index_count(unit, MPLS_ENTRYm);
   1807 #ifdef BCM_TRIDENT2_SUPPORT
   1808     if (soc_feature(unit, soc_feature_extended_hash)) {
   1809         ad->opt_hash       = FB_HASH_CRC32_LOWER;
   1810         ad->opt_dual_hash  = FB_HASH_CRC32_UPPER;
   1811     } else
   1812 #endif /* BCM_TRIDENT2_SUPPORT */
   1813     {
   1814         ad->opt_hash       = FB_HASH_CRC16_LOWER;
   1815         ad->opt_dual_hash  = -1;
   1816     }
   1817     ad->hash_count     = FB_HASH_COUNT;
   1818     ad->opt_base_label = 0;
   1819     ad->opt_label_inc  = 1;
   1820 
   1821     /* Overflow */
   1822     ad = &dw->lp_ov;
   1823 
   1824     ad->opt_count      = 2048;
   1825     ad->opt_hash       = TR_DEFAULT_HASH;
   1826     ad->opt_dual_hash  = -1;
   1827     ad->hash_count     = FB_HASH_COUNT;
   1828     ad->opt_base_label = 0;
   1829     ad->opt_label_inc  = 1;
   1830 }
   1831 
   1832 /* Individual test init wrappers */
   1833 int
   1834 tr_mpls_hash_test_init(int unit, args_t *a, void **p)
   1835 {
   1836     tr_hash_test_t        *dw = &tr_mpls_work[unit];
   1837     tr_hash_testdata_t    *dp = &dw->lp_hash;
   1838     int                    rv;
   1839 
   1840     tr_mpls_hash_setup(unit, dw);
   1841 
   1842     /* Set working data to hash */
   1843     dw->lp_cur = dp;
   1844 
   1845     if ((rv = tr_mpls_test_init(unit, dp, a)) < 0) {
   1846         return rv;
   1847     } else {
   1848         *p = dp;
   1849     }
   1850 
   1851     return 0;
   1852 }
   1853 
   1854 int
   1855 tr_mpls_ov_test_init(int unit, args_t *a, void **p)
   1856 {
   1857     tr_hash_test_t        *dw = &tr_mpls_work[unit];
   1858     tr_hash_testdata_t    *dp = &dw->lp_ov;
   1859     int                    rv;
   1860 
   1861     tr_mpls_hash_setup(unit, dw);
   1862 
   1863     /* Set working data to hash */
   1864     dw->lp_cur = dp;
   1865 
   1866     if ((rv = tr_mpls_test_init(unit, dp, a)) < 0) {
   1867         return rv; 
   1868     } else {
   1869         *p = dp;
   1870     }
   1871 
   1872     return 0;
   1873 }
   1874 
   1875 /*
   1876  * Test of MPLS XLATE hashing
   1877  *
   1878  *   This test tries a number of keys against one of the hashing functions,
   1879  *   checking a software hash against the hardware hash, then searching the
   1880  *   bucket to find the entry after inserting.
   1881  */
   1882 int
   1883 tr_mpls_test_hash(int unit, args_t *a, void *p)
   1884 {
   1885     tr_hash_testdata_t         *ad = p;
   1886     mpls_entry_entry_t         entry;
   1887     int soft_bucket, ix, r, rv = 0;
   1888     int hash = ad->opt_hash;
   1889     uint8 key[XGS_HASH_KEY_SIZE];
   1890     int iterations, label, num_bits;
   1891     int label_inc = ad->opt_label_inc;
   1892     int bucket_size = 8;
   1893     int index;
   1894     int dual = FALSE;
   1895     int bank, bank_count = 1;
   1896 
   1897     COMPILER_REFERENCE(a);
   1898 
   1899     if (ad->opt_verbose) {
   1900         cli_out("Starting MPLS hash test\n");
   1901     }
   1902 
   1903     iterations = ad->opt_count;
   1904     label = ad->opt_base_label;
   1905     if (ad->opt_dual_hash != -1) {
   1906         dual = TRUE;
   1907         bank_count = 2;
   1908     }
   1909 
   1910     for (ix = 0; ix < iterations; ix++) {
   1911         for (bank = 0; bank < bank_count; bank++) {
   1912             sal_memset(&entry, 0, sizeof (entry));
   1913             if (soc_feature(unit, soc_feature_td3_style_mpls)) {
   1914                 soc_MPLS_ENTRYm_field32_set(unit, &entry, BASE_VALID_0f, 3);
   1915                 soc_MPLS_ENTRYm_field32_set(unit, &entry, BASE_VALID_1f, 7);
   1916             } else {
   1917             soc_MPLS_ENTRYm_field32_set(unit, &entry, VALIDf, 1);
   1918             }
   1919             soc_MPLS_ENTRYm_field32_set(unit, &entry, MPLS_LABELf, label);
   1920             num_bits = soc_tr_mpls_base_entry_to_key
   1921                 (unit, (uint32 *) &entry, key);
   1922             soft_bucket = soc_tr_mpls_hash(unit, hash, num_bits, 
   1923                                            (uint32 *) &entry, key);
   1924             if (dual == TRUE) {
   1925 #ifdef BCM_TRIDENT2_SUPPORT
   1926 #ifdef BCM_APACHE_SUPPORT
   1927                 if (SOC_IS_APACHE(unit)) {
   1928                     soft_bucket = soc_ap_mpls_bank_entry_hash(unit, bank,
   1929                                                         (uint32 *) &entry);
   1930                 } else
   1931 #endif /* BCM_APACHE_SUPPORT */
   1932 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1933                 if (SOC_IS_TOMAHAWK3(unit) &&
   1934                     soc_feature(unit, soc_feature_base_valid)) {
   1935                     soft_bucket =
   1936                         soc_tomahawk3_mpls_bank_entry_hash(
   1937                                 unit, bank, (uint32 *) &entry);
   1938                 } else
   1939 #endif
   1940 #if defined(BCM_TRIDENT3_SUPPORT)
   1941                 if (soc_feature(unit, soc_feature_base_valid)) {
   1942                     soft_bucket = soc_td3_mpls_bank_entry_hash(unit, MPLS_ENTRYm, bank,
   1943                                 (uint32 *) &entry);
   1944                 } else
   1945 #endif /* BCM_TRIDENT3_SUPPORT */
   1946 #ifdef BCM_TOMAHAWK_SUPPORT
   1947                 if (SOC_IS_TOMAHAWKX(unit)) {
   1948                     soft_bucket = soc_th_mpls_bank_entry_hash(unit, bank,
   1949                                                         (uint32 *) &entry);
   1950                 } else
   1951 #endif /* BCM_TOMAHAWK_SUPPORT */
   1952                 if (soc_feature(unit, soc_feature_extended_hash)) {
   1953                     soft_bucket = soc_td2_mpls_bank_entry_hash(unit, bank,
   1954                                                         (uint32 *) &entry);
   1955                 } else
   1956 #endif /* BCM_TRIDENT2_SUPPORT */
   1957                 {
   1958                     soft_bucket = soc_tr_mpls_bank_entry_hash
   1959                         (unit, bank, (uint32 *) &entry);
   1960                 }
   1961             }
   1962     
   1963             if (ad->opt_verbose) {
   1964                 cli_out("Inserting ");
   1965                 soc_mem_entry_dump(unit, MPLS_ENTRYm, &entry, BSL_LSS_CLI);
   1966                 cli_out("\n");
   1967                 if (dual) {
   1968                     cli_out("into bucket 0x%x (bank %d)\n",
   1969                             soft_bucket, bank);
   1970                 } else {
   1971                    cli_out("into bucket 0x%x\n", soft_bucket);
   1972                 }
   1973             }
   1974     
   1975             if ((r = soc_mem_bank_insert(unit, MPLS_ENTRYm, bank,
   1976                                          MEM_BLOCK_ALL, &entry, NULL)) < 0) {
   1977                 if (r == SOC_E_FULL) {
   1978                     /* Bucket overflow, just pass on */
   1979                     break;
   1980                 } else {
   1981                     test_error(unit,
   1982                                "MPLS insert failed at bucket %d\n", soft_bucket);
   1983                     rv = -1;
   1984                     goto done;
   1985                 }
   1986             }
   1987     
   1988             /* Now we search for the entry */
   1989             if (!soc_feature(unit, soc_feature_shared_hash_mem)) {
   1990                 /* Only do a quick check vs. expected bucket here */
   1991                 if (tr_hash_bucket_search(unit, ad, MPLS_ENTRYm, soft_bucket,
   1992                                       bucket_size, VALIDf, &entry, dual, bank) < 0) {
   1993                     test_error(unit,
   1994                            "MPLS entry with key "
   1995                            "0x%02x%02x%02x%02x%02x%02x%02x%01x "
   1996                            "not found in predicted bucket %d\n",
   1997                            key[7], key[6], key[5], key[4],
   1998                            key[3], key[2], key[1], (key[0] >> 4) & 0xf,
   1999                            soft_bucket);
   2000                     rv = -1;
   2001                     goto done;
   2002                 }
   2003             }
   2004     
   2005             /* Search for the entry, should be found */
   2006             if (soc_mem_search(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &index,
   2007                                &entry, &entry, 0) < 0) {
   2008                 test_error(unit, "MPLS search failed in bucket %d\n",
   2009                            soft_bucket);
   2010                 rv = -1;
   2011                 goto done;
   2012             }
   2013     
   2014             /* Insert the entry again, should fail. */
   2015             if (soc_mem_bank_insert(unit, MPLS_ENTRYm, bank,
   2016                                     MEM_BLOCK_ALL, &entry, NULL) != SOC_E_EXISTS) {
   2017                 test_error(unit,
   2018                            "MPLS insert should have failed at bucket %d\n", soft_bucket);
   2019                 rv = -1;
   2020                 goto done;
   2021             }
   2022     
   2023             /* Delete the entry */
   2024             if (soc_mem_delete(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &entry) < 0) {
   2025                 test_error(unit, "MPLS delete failed at bucket %d\n",
   2026                            soft_bucket);
   2027                 rv = -1;
   2028                 goto done;
   2029             }
   2030     
   2031             /* Delete the entry again, should fail.*/
   2032             if (soc_mem_delete(unit, MPLS_ENTRYm,
   2033                                MEM_BLOCK_ALL, &entry) != SOC_E_NOT_FOUND) {
   2034                 test_error(unit, "MPLS delete should have failed in bucket %d\n",
   2035                            soft_bucket);
   2036                 rv = -1;
   2037                 goto done;
   2038             }
   2039     
   2040             /* Search for the entry again, should not be found */
   2041             if (soc_mem_search(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &index,
   2042                                &entry, &entry, 0) != SOC_E_NOT_FOUND) {
   2043                 test_error(unit, "MPLS search should have failed in bucket %d\n",
   2044                            soft_bucket);
   2045                 rv = -1;
   2046                 goto done;
   2047             }
   2048         }
   2049         label += label_inc;
   2050         if (label > TR_LABEL_MAX) {
   2051             label = 1;
   2052         }
   2053     }
   2054 
   2055  done:
   2056     return rv;
   2057 }
   2058 
   2059 /*
   2060  * Test of MPLS overflow behavior
   2061  *
   2062  *   This test fills each bucket, then inserts another entry to see
   2063  *   that the last entry fails to insert.
   2064  */
   2065 
   2066 int
   2067 tr_mpls_test_ov(int unit, args_t *a, void *p)
   2068 {
   2069     tr_hash_testdata_t  *ad = p;
   2070     mpls_entry_entry_t  entry, result, entry_tmp[8];
   2071     int                 ix, jx, r, idx, rv = 0;
   2072     int port, module, label;
   2073     int bucket = 0;
   2074     uint32 hash = ad->opt_hash;
   2075     int iter = ad->opt_count;
   2076     uint8 key[XGS_HASH_KEY_SIZE];
   2077     int bucket_size = 8;
   2078 
   2079     COMPILER_REFERENCE(a);
   2080 
   2081     if (hash != FB_HASH_LSB) {
   2082         if (ad->opt_verbose) {
   2083             cli_out("Resetting hash selection to LSB\n");
   2084         }
   2085 
   2086         hash = ad->save_hash_control;
   2087         soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash,
   2088                           HASH_SELECT_Af, FB_HASH_LSB);
   2089         soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash,
   2090                           HASH_SELECT_Bf, FB_HASH_LSB);
   2091     
   2092         if (WRITE_MPLS_ENTRY_HASH_CONTROLr(unit, hash) < 0) {
   2093             test_error(unit, "Hash select setting failed\n");
   2094             goto done;
   2095         }
   2096 
   2097         ad->opt_hash = hash = FB_HASH_LSB;
   2098     }
   2099 
   2100     if (iter > soc_mem_index_count(unit, MPLS_ENTRYm)) {
   2101         iter = soc_mem_index_count(unit, MPLS_ENTRYm);
   2102     }
   2103     port = 0;
   2104     module = 0;
   2105     label = 0;
   2106 
   2107     while (iter--) {
   2108         for (ix = 0; ix < bucket_size; ix++) {
   2109             sal_memset(&entry_tmp[ix], 0, sizeof(mpls_entry_entry_t));
   2110             if (soc_feature(unit, soc_feature_td3_style_mpls)) {
   2111                 soc_MPLS_ENTRYm_field32_set(unit, &(entry_tmp[ix]), BASE_VALID_0f, 3);
   2112                 soc_MPLS_ENTRYm_field32_set(unit, &(entry_tmp[ix]), BASE_VALID_1f, 7);
   2113             } else {
   2114                 soc_MPLS_ENTRYm_field32_set(unit, &(entry_tmp[ix]), VALIDf, 1);
   2115             }
   2116             soc_MPLS_ENTRYm_field32_set(unit, &(entry_tmp[ix]), PORT_NUMf, port);
   2117             soc_MPLS_ENTRYm_field32_set(unit, &(entry_tmp[ix]), MODULE_IDf, module);
   2118             soc_MPLS_ENTRYm_field32_set(unit, &(entry_tmp[ix]), MPLS_LABELf, label);
   2119 
   2120             if (ix == 0) {
   2121                 int num_bits;
   2122                 num_bits = soc_tr_mpls_base_entry_to_key
   2123                     (unit, (uint32 *) &(entry_tmp[ix]), key);
   2124                 bucket = soc_tr_mpls_hash(unit, hash, num_bits, 
   2125                                           (uint32 *) &(entry_tmp[ix]), key);
   2126                 if (ad->opt_verbose) {
   2127                     cli_out("Filling bucket %d\n", bucket);
   2128                 }
   2129             }
   2130 
   2131             if ((r = soc_mem_insert(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &entry_tmp[ix])) < 0) {
   2132                 if (r == SOC_E_FULL) {
   2133                     /* Already full, stop wasting time */
   2134                     break;
   2135                 } else {
   2136                     test_error(unit,
   2137                                "MPLS insert failed at bucket %d\n", bucket);
   2138                     rv = -1;
   2139                     goto done;
   2140                 }
   2141             }
   2142 
   2143             /* key for LSB is the label, so we must keep it constant */
   2144             port += 1;
   2145             if (port > 0x3f) {
   2146     /*    coverity[assignment : FALSE]    */
   2147                 port = 0;
   2148     /* coverity[assignment] */
   2149                 module += 1;
   2150                 if (module > 0x7f) {
   2151                     module = 0;
   2152                 }
   2153             }
   2154         }
   2155 
   2156         if (ad->opt_verbose) {
   2157             cli_out("Inserting %dth entry in bucket %d, should fail\n",
   2158                     (bucket_size + 1), bucket);
   2159         }
   2160 
   2161         sal_memset(&entry, 0,  sizeof(mpls_entry_entry_t));
   2162         if (soc_feature(unit, soc_feature_td3_style_mpls)) {
   2163                 soc_MPLS_ENTRYm_field32_set(unit, &entry, BASE_VALID_0f, 3);
   2164                 soc_MPLS_ENTRYm_field32_set(unit, &entry, BASE_VALID_1f, 7);
   2165             } else {
   2166                 soc_MPLS_ENTRYm_field32_set(unit, &entry, VALIDf, 1);
   2167         }
   2168         soc_MPLS_ENTRYm_field32_set(unit, &entry, PORT_NUMf, port);
   2169         soc_MPLS_ENTRYm_field32_set(unit, &entry, MODULE_IDf, module);
   2170         soc_MPLS_ENTRYm_field32_set(unit, &entry, MPLS_LABELf, label);
   2171 
   2172         if ((r = soc_mem_insert(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &entry)) < 0) {
   2173             if (r != SOC_E_FULL) {
   2174                 test_error(unit,
   2175                            "MPLS insert failed\n");
   2176                 rv = -1;
   2177                 goto done;
   2178             }
   2179         } else {
   2180             test_error(unit, "MPLS insert to full bucket succeeded\n");
   2181             rv = -1;
   2182             goto done;
   2183         }
   2184 
   2185         if (ad->opt_verbose) {
   2186             cli_out("Verifying entries present\n");
   2187         }
   2188 
   2189         /* Verify bucket contains our added entries */
   2190         for (jx = 0; jx < ix; jx++) {
   2191             if (tr_hash_bucket_search(unit, ad, MPLS_ENTRYm, bucket, 
   2192                                       bucket_size, VALIDf, &(entry_tmp[jx]), 0, 0) < 0) {
   2193                 test_error(unit, "MPLS entry missing at bucket %d\n", bucket);
   2194                 rv = -1;
   2195                 goto done;
   2196             }
   2197             if (soc_mem_search(unit, MPLS_ENTRYm, MEM_BLOCK_ANY, &idx, 
   2198                                &entry_tmp[jx], &result, 0) < 0) {
   2199                 test_error(unit, "MPLS entry missing at bucket %d\n", bucket);
   2200                 rv = -1;
   2201                 goto done;
   2202             }
   2203             if (bucket != (idx / bucket_size)) {
   2204                 test_error(unit, "MPLS entry inserted into wrong bucket"
   2205                            " Expected %d Actual %d\n", bucket, idx);
   2206                 rv = -1;
   2207                 goto done;
   2208             }
   2209         }
   2210 
   2211         if (ad->opt_verbose) {
   2212             cli_out("Cleaning bucket %d\n", bucket);
   2213         }
   2214 
   2215         /* Remove the entries that we added */
   2216         for (jx = 0; jx < ix; jx++) {
   2217             if (soc_mem_delete(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &(entry_tmp[jx])) < 0) {
   2218                 test_error(unit, "MPLS delete failed at bucket %d\n", bucket);
   2219                 rv = -1;
   2220                 goto done;
   2221             }
   2222         }
   2223 
   2224         /* We want the increment to change buckets by one. For MPLS_ENTRYm,
   2225          * the LSB hash bucket is determined by {label}. 
   2226          */
   2227         label += 1;
   2228         if (label > TR_LABEL_MAX) {
   2229             label = 0;
   2230         }
   2231     }
   2232 
   2233  done:
   2234 
   2235     return rv;
   2236 }
   2237 
   2238 /*
   2239  * Test clean-up routine used for all MPLS tests
   2240  */
   2241 
   2242 int
   2243 tr_mpls_test_done(int unit, void *p)
   2244 {
   2245     tr_hash_testdata_t *ad = p;
   2246 
   2247     if (ad == NULL) {
   2248 	return 0;
   2249     }
   2250 
   2251     /* Check if empty at the end of the test */
   2252     if (ad->opt_reset) {
   2253         int rv, ix;
   2254         int index_min = soc_mem_index_min(unit, MPLS_ENTRYm);
   2255         int index_max = soc_mem_index_max(unit, MPLS_ENTRYm);
   2256         uint32 *buf = 0;
   2257         uint32 *ent;
   2258         uint32 count;
   2259 
   2260         buf = soc_cm_salloc(unit,
   2261                             SOC_MEM_TABLE_BYTES(unit, MPLS_ENTRYm),
   2262                             "mpls_entry_test");
   2263         if (!buf) {
   2264             test_error(unit, "Memory allocation failed\n");
   2265             return (-1);
   2266         }
   2267 
   2268         if ((rv = soc_mem_read_range(unit, MPLS_ENTRYm, MEM_BLOCK_ANY,
   2269                           index_min, index_max, buf)) < 0) {
   2270             test_error(unit, "Memory DMA of MPLS_ENTRYm entries failed\n");
   2271             return (-1);
   2272         }
   2273 
   2274         count = soc_mem_index_count(unit, MPLS_ENTRYm);
   2275         for (ix = 0; ix < count; ix++) {
   2276             ent = soc_mem_table_idx_to_pointer(unit, MPLS_ENTRYm,
   2277                                                uint32 *, buf, ix);
   2278 
   2279 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   2280             if (soc_feature(unit, soc_feature_base_valid)) {
   2281                 if ((soc_MPLS_ENTRYm_field32_get(unit, ent, BASE_VALID_0f) == 3) &&
   2282                         (soc_MPLS_ENTRYm_field32_get(unit, ent, BASE_VALID_1f) == 7)) {
   2283                     test_error(unit, "MPLS_ENTRY table not empty after test entry = %d\n",
   2284                             ix);
   2285                     soc_mem_entry_dump(unit, MPLS_ENTRYm, ent, BSL_LSS_CLI);
   2286                     return (-1);
   2287                 }
   2288             } else
   2289 #endif
   2290             {
   2291             if (soc_MPLS_ENTRYm_field32_get(unit, ent, VALIDf)) {
   2292                 test_error(unit, "MPLS_ENTRY table not empty after test entry = %d\n",
   2293                                 ix);
   2294                 soc_mem_entry_dump(unit, MPLS_ENTRYm, ent, BSL_LSS_CLI);
   2295                 return (-1);
   2296             }
   2297         }
   2298         }
   2299 
   2300         soc_cm_sfree(unit, buf);
   2301     }
   2302 
   2303 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   2304     if (soc_feature(unit, soc_feature_base_valid)) {
   2305         if (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2306                     ad->td3_hash_tbl_data) < 0) {
   2307             test_error(unit, "Hash select restore failed\n");
   2308         }
   2309     } else
   2310 #endif
   2311     {
   2312     if (WRITE_MPLS_ENTRY_HASH_CONTROLr(unit, ad->save_hash_control) < 0) {
   2313         test_error(unit, "Hash select restore failed\n");
   2314     }
   2315     }
   2316 
   2317     return 0;
   2318 }
   2319 #endif /* BCM_TRIUMPH_SUPPORT */
   2320 /************************** END OF MPLS TESTS ******************************/
   2321 #endif /* BCM_TRX_SUPPORT */
   2322