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

draco_arltest.c (263468B)


      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  * ARL Tests.
      8  *
      9  * Insert/Lookup/Delete, hashing, bucket overflow tests.
     10  */
     11 
     12 
     13 #ifdef BCM_ESW_SUPPORT
     14 #include <soc/mem.h>
     15 #include <soc/hash.h>
     16 #include <soc/l2x.h>
     17 #include <soc/l3x.h>
     18 #include <appl/diag/system.h>
     19 #include <appl/test/draco_arltest.h>
     20 #include <shared/bsl.h>
     21 #include "testlist.h"
     22 #include <bcm/init.h>
     23 #include <bcm/l2.h>
     24 #include <bcm/l3.h>
     25 #include <bcm/stack.h>
     26 #include <bcm/link.h>
     27 #include <bcm_int/esw/firebolt.h>
     28 #if defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
     29 #include <bcm_int/esw/triumph.h>
     30 #endif /* BCM_TRIUMPH_SUPPORT */
     31 #include <appl/diag/progress.h>
     32 #if defined(BCM_TRIDENT2_SUPPORT)
     33 #include <soc/trident2.h>
     34 #endif
     35 #if defined(BCM_TRIDENT3_SUPPORT)
     36 #include <soc/trident3.h>
     37 #endif
     38 #if defined(CANCUN_SUPPORT)
     39 #include "cancun.h"
     40 #endif
     41 
     42 #ifdef BCM_XGS_SWITCH_SUPPORT
     43 
     44 #if defined(BCM_TRIDENT2_SUPPORT)
     45 #define SOC_TD2_L2X_BUCKET_SIZE    4
     46 #define L2_MAX_BANKS               6
     47 #define SOC_TD2_L3X_BUCKET_SIZE    4
     48 #define L3_MAX_BANKS               8
     49 #endif
     50 
     51 /*
     52  * L2 work structure
     53  */
     54 
     55 STATIC draco_l2_test_t dl2_work[SOC_MAX_NUM_DEVICES];
     56 #ifdef INCLUDE_L3
     57 STATIC draco_l3_test_t dl3_work[SOC_MAX_NUM_DEVICES];
     58 #endif /* INCLUDE_L3 */
     59 
     60 sal_mac_addr_t dl_mac_src = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
     61 
     62 #ifdef BCM_TRIDENT3_SUPPORT
     63 STATIC int
     64 td3_entry_hash_control_set(int unit, uint32 opt_hash,
     65     soc_mem_t mem, uint32 *entry_hash_control)
     66 {
     67     uint32 tbl_mode = 0;
     68     uint32 hash_offset_0 = 0;
     69     uint32 hash_offset_1 = 32;
     70 
     71     switch(opt_hash) {
     72         case FB_HASH_ZERO:
     73             tbl_mode = 1;
     74             hash_offset_0 = hash_offset_1 = 48;
     75             break;
     76         case FB_HASH_CRC32_UPPER:
     77         case FB_HASH_CRC32_LOWER:
     78             break;
     79         case FB_HASH_LSB:
     80             tbl_mode = 1;
     81             hash_offset_0 = hash_offset_1 = 32;
     82             break;
     83         case FB_HASH_CRC16_LOWER:
     84         case FB_HASH_CRC16_UPPER:
     85             break;
     86         case FB_HASH_COUNT:
     87         default:
     88             test_error(unit, "Wrong Hash\n");
     89             return (-1);
     90     }
     91     soc_mem_field_set(unit, mem, entry_hash_control,
     92             HASH_TABLE_TEST_MODEf, &tbl_mode);
     93     soc_mem_field_set(unit, mem, entry_hash_control,
     94             HASH_OFFSET_DEDICATED_BANK_0f, &hash_offset_0);
     95     soc_mem_field_set(unit, mem, entry_hash_control,
     96             HASH_OFFSET_DEDICATED_BANK_1f, &hash_offset_1);
     97 
     98     return 0;
     99 }
    100 #endif
    101 
    102 #ifdef BCM_BRADLEY_SUPPORT
    103 STATIC void
    104 hbl2_setup(int unit, draco_l2_test_t *dw)
    105 {
    106     draco_l2_testdata_t *ad;
    107 
    108 
    109     /* Hash */
    110     ad = &dw->dlp_l2_hash;
    111 
    112     ad->opt_count      = soc_mem_index_count(unit, L2Xm);
    113     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    114     ad->hash_count     = FB_HASH_COUNT;
    115 
    116     /* Overflow */
    117     ad = &dw->dlp_l2_ov;
    118 
    119     ad->opt_count      = 2048;
    120     ad->opt_hash       = FB_L2_DEFAULT_HASH;
    121     ad->hash_count     = FB_HASH_COUNT;
    122 
    123     /* Lookup */
    124     ad = &dw->dlp_l2_lu;
    125 
    126     ad->opt_count      = soc_mem_index_count(unit, L2Xm);
    127     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    128     ad->hash_count     = FB_HASH_COUNT;
    129 
    130     /* Delete by port */
    131     ad = &dw->dlp_l2_dp;
    132 
    133     ad->opt_count      = 20;  /* 20 GX PORTS */
    134     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    135     ad->hash_count     = FB_HASH_COUNT;
    136 
    137     /* Delete by VLAN */
    138     ad = &dw->dlp_l2_dv;
    139 
    140     ad->opt_count      = soc_mem_index_count(unit, VLAN_TABm);
    141     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    142     ad->hash_count     = FB_HASH_COUNT;
    143 }
    144 
    145 #endif /* BCM_BRADLEY_SUPPORT */
    146 
    147 #ifdef BCM_FIREBOLT_SUPPORT
    148 STATIC void
    149 fbl2_setup(int unit, draco_l2_test_t *dw)
    150 {
    151     draco_l2_testdata_t *ad;
    152 
    153 
    154     /* Hash */
    155     ad = &dw->dlp_l2_hash;
    156 
    157     ad->opt_count      = soc_mem_index_count(unit, L2Xm);
    158     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    159     ad->hash_count     = FB_HASH_COUNT;
    160 
    161     /* Overflow */
    162     ad = &dw->dlp_l2_ov;
    163 
    164     ad->opt_count      = 2048;
    165     ad->opt_hash       = FB_L2_DEFAULT_HASH;
    166     ad->hash_count     = FB_HASH_COUNT;
    167 
    168     /* Lookup */
    169     ad = &dw->dlp_l2_lu;
    170 
    171     ad->opt_count      = soc_mem_index_count(unit, L2Xm);
    172     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    173     ad->hash_count     = FB_HASH_COUNT;
    174 
    175     /* Delete by port */
    176     ad = &dw->dlp_l2_dp;
    177 
    178     ad->opt_count      = 24;  /* 24 GE ports + N XE PORTS */
    179     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    180     ad->hash_count     = FB_HASH_COUNT;
    181 
    182     /* Delete by VLAN */
    183     ad = &dw->dlp_l2_dv;
    184 
    185     ad->opt_count      = soc_mem_index_count(unit, VLAN_TABm);
    186     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    187     ad->hash_count     = FB_HASH_COUNT;
    188 }
    189 
    190 #endif /* BCM_FIREBOLT_SUPPORT */
    191 
    192 #ifdef BCM_TRX_SUPPORT
    193 STATIC void
    194 trl2_setup(int unit, draco_l2_test_t *dw)
    195 {
    196     draco_l2_testdata_t *ad;
    197 
    198     /* Hash */
    199     ad = &dw->dlp_l2_hash;
    200 
    201     ad->opt_count      = soc_mem_index_count(unit, L2Xm);
    202     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    203     ad->hash_count     = FB_HASH_COUNT;
    204 
    205     /* Overflow */
    206     ad = &dw->dlp_l2_ov;
    207 
    208     ad->opt_count      = 2048;
    209     ad->opt_hash       = FB_L2_DEFAULT_HASH;
    210     ad->hash_count     = FB_HASH_COUNT;
    211 
    212     /* Lookup */
    213     ad = &dw->dlp_l2_lu;
    214 
    215     ad->opt_count      = soc_mem_index_count(unit, L2Xm);
    216     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    217     ad->hash_count     = FB_HASH_COUNT;
    218 
    219     /* Delete by port */
    220     ad = &dw->dlp_l2_dp;
    221 
    222     ad->opt_count      = 49;  /* 49 GE ports + N XE PORTS */
    223     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    224     ad->hash_count     = FB_HASH_COUNT;
    225 
    226     /* Delete by VLAN */
    227     ad = &dw->dlp_l2_dv;
    228 
    229     ad->opt_count      = soc_mem_index_count(unit, VLAN_TABm);
    230     ad->opt_hash       = FB_HASH_CRC16_LOWER;
    231     ad->hash_count     = FB_HASH_COUNT;
    232 }
    233 
    234 #endif /* BCM_TRX_SUPPORT */
    235 
    236 
    237 STATIC void
    238 dl2_setup(int unit, draco_l2_test_t *dw)
    239 {
    240     draco_l2_testdata_t *ad;
    241 
    242     if (dw->dlw_set_up) {
    243         return;
    244     }
    245 
    246     dw->dlw_set_up = TRUE;
    247     dw->dlw_unit = unit;
    248 
    249     /* Hash */
    250     ad = &dw->dlp_l2_hash;
    251 
    252     ad->unit           = unit;
    253     ad->opt_count      = 8191;
    254     ad->opt_verbose    = FALSE;
    255     ad->opt_reset      = TRUE;
    256     ad->opt_hash       = XGS_HASH_CRC16_LOWER;
    257     ad->opt_base_vid   = 0;
    258     ad->opt_vid_inc    = 1;
    259     ad->opt_mac_inc    = 1;
    260     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
    261     ad->hash_count = XGS_HASH_COUNT;
    262 
    263     /* Overflow */
    264     ad = &dw->dlp_l2_ov;
    265 
    266     ad->unit           = unit;
    267     ad->opt_count      = 1024;
    268     ad->opt_verbose    = FALSE;
    269     ad->opt_reset      = TRUE;
    270     ad->opt_hash       = DRACO_ARL_DEFAULT_HASH;
    271     ad->opt_base_vid   = 0;
    272     ad->opt_vid_inc    = 1;
    273     ad->opt_mac_inc    = 1;
    274     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
    275     ad->hash_count = XGS_HASH_COUNT;
    276 
    277     /* Lookup */
    278     ad = &dw->dlp_l2_lu;
    279 
    280     ad->unit           = unit;
    281     ad->opt_count      = 8191;
    282     ad->opt_verbose    = FALSE;
    283     ad->opt_reset      = TRUE;
    284     ad->opt_hash       = XGS_HASH_CRC16_LOWER;
    285     ad->opt_base_vid   = 0;
    286     ad->opt_vid_inc    = 1;
    287     ad->opt_mac_inc    = 1;
    288     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
    289     ad->hash_count = XGS_HASH_COUNT;
    290 
    291     /* Delete by port */
    292     ad = &dw->dlp_l2_dp;
    293 
    294     ad->unit           = unit;
    295     ad->opt_count      = 12;  /* Only 12 relevant ports? */
    296     ad->opt_verbose    = FALSE;
    297     ad->opt_reset      = TRUE;
    298     ad->opt_hash       = XGS_HASH_CRC16_LOWER;
    299     ad->opt_base_vid   = 0;
    300     ad->opt_vid_inc    = 1;
    301     ad->opt_mac_inc    = 1;
    302     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
    303     ad->hash_count = XGS_HASH_COUNT;
    304 
    305     /* Delete by VLAN */
    306     ad = &dw->dlp_l2_dv;
    307 
    308     ad->unit           = unit;
    309     ad->opt_count      = 4096;
    310     ad->opt_verbose    = FALSE;
    311     ad->opt_reset      = TRUE;
    312     ad->opt_hash       = XGS_HASH_CRC16_LOWER;
    313     ad->opt_base_vid   = 0;
    314     ad->opt_vid_inc    = 1;
    315     ad->opt_mac_inc    = 1;
    316     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
    317     ad->hash_count = XGS_HASH_COUNT;
    318 
    319 #ifdef BCM_BRADLEY_SUPPORT
    320     /* Bradley adjustments */
    321     if (SOC_IS_HB_GW(unit)) {
    322         hbl2_setup(unit, dw);
    323     }
    324 #endif /* BCM_BRADLEY_SUPPORT */
    325 #ifdef BCM_FIREBOLT_SUPPORT
    326     /* Firebolt adjustments */
    327     if (SOC_IS_FB_FX_HX(unit)) {
    328         fbl2_setup(unit, dw);
    329     }
    330 #endif /* BCM_FIREBOLT_SUPPORT */
    331 #ifdef BCM_TRX_SUPPORT
    332     /* Triumph adjustments */
    333     if (SOC_IS_TRX(unit)) {
    334         trl2_setup(unit, dw);
    335     }
    336 #endif /* BCM_TRX_SUPPORT */
    337 }
    338 
    339 
    340 /*
    341  * Test initialization routine used for all L2 tests
    342  */
    343 
    344 STATIC int
    345 draco_l2_test_init(int unit, draco_l2_testdata_t *ad, args_t *a)
    346 {
    347     int                         rv = -1;
    348     parse_table_t               pt;
    349     uint32                      hash_read;
    350     uint32                      l2_aux_hash_control;
    351     uint32                      l2_table_hash_control;
    352     uint32                      shared_table_hash_control;
    353 #ifdef BCM_TRIDENT3_SUPPORT
    354     l2_entry_hash_control_entry_t    l2_entry_hash_control;
    355     uft_shared_banks_control_entry_t shared_entry_hash_control;
    356 #endif
    357 
    358 
    359     parse_table_init(unit, &pt);
    360 
    361     parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL);
    362     parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL);
    363     parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL);
    364     parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL);
    365     parse_table_add(&pt, "BaseVID", PQ_INT|PQ_DFL, 0, &ad->opt_base_vid, NULL);
    366     parse_table_add(&pt, "VidIncrement", PQ_INT|PQ_DFL, 0,
    367                     &ad->opt_vid_inc, NULL);
    368     parse_table_add(&pt, "BaseMac",     PQ_DFL|PQ_MAC,  0,
    369                     &ad->opt_base_mac,  NULL);
    370     parse_table_add(&pt, "MacIncrement", PQ_INT|PQ_DFL, 0,
    371                     &ad->opt_mac_inc, NULL);
    372 
    373     /* Test the obvious parsings before wasting time with malloc */
    374     if (parse_arg_eq(a, &pt) < 0) {
    375         test_error(unit,
    376                    "%s: Error: Invalid option: %s\n", ARG_CMD(a),
    377                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    378         goto done;
    379     }
    380 
    381     if (ad->opt_count < 1) {
    382         test_error(unit, "Illegal count %d\n", ad->opt_count);
    383         goto done;
    384     }
    385 
    386     if (ad->opt_hash >= ad->hash_count) {
    387         test_error(unit, "Illegal hash selection %d\n", ad->opt_hash);
    388         goto done;
    389     }
    390 
    391     if (ad->opt_base_vid >= (1 << 12)) {
    392         test_error(unit, "Out of range VLAN ID selection %d\n",
    393                    ad->opt_base_vid);
    394         goto done;
    395     }
    396 
    397     /*
    398      * Re-initialize chip to ensure ARL and software ARL table are clear
    399      * at start of test.
    400      */
    401 
    402     if (ad->opt_reset) {
    403         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
    404         if (soc_reset_init(unit) < 0) {
    405             test_error(unit, "SOC initialization failed\n");
    406             goto done;
    407         }
    408 
    409 #if defined(CANCUN_SUPPORT)
    410         if (soc_cancun_pre_misc_init_load(unit) < 0) {
    411             test_error(unit, "CMH/CCH/CEH load failed");
    412             goto done;
    413         }
    414 #endif
    415 
    416         if (soc_misc_init(unit) < 0) {
    417             test_error(unit, "ARL initialization failed\n");
    418             goto done;
    419         }
    420 
    421 #if defined(CANCUN_SUPPORT)
    422         if (soc_cancun_post_misc_init_load(unit) < 0) {
    423             test_error(unit, "CIH/CFH load failed");
    424             goto done;
    425         }
    426 #endif
    427 
    428         if (soc_mmu_init(unit) < 0) {
    429             test_error(unit, "MMU initialization failed\n");
    430             goto done;
    431         }
    432 
    433         if (SOC_FUNCTIONS(unit)->soc_age_timer_set(unit, 0, 0) < 0) {
    434             test_error(unit, "Could not disable age timers\n");
    435             goto done;
    436         }
    437 
    438         if (mbcm_init(unit) < 0) { /* Needed for "delete by" tests */
    439             test_error(unit, "mBCM initialization failed\n");
    440             goto done;
    441         }
    442 
    443     }
    444 
    445     if (READ_HASH_CONTROLr(unit, &hash_read) < 0) {
    446         test_error(unit, "Hash select read failed\n");
    447         goto done;
    448     }
    449 
    450     ad->save_hash_control = hash_read;
    451 
    452     hash_read = ad->opt_hash;
    453 
    454 #ifdef BCM_XGS3_SWITCH_SUPPORT
    455     if (SOC_IS_XGS3_SWITCH(unit)) {
    456         hash_read = ad->save_hash_control;
    457         soc_reg_field_set(unit, HASH_CONTROLr, &hash_read,
    458                           L2_AND_VLAN_MAC_HASH_SELECTf, ad->opt_hash);
    459     }
    460 #endif /* BCM_XGS3_SWITCH_SUPPORT */
    461 
    462     if (WRITE_HASH_CONTROLr(unit, hash_read) < 0) {
    463         test_error(unit, "Hash select setting failed\n");
    464         goto done;
    465     }
    466 
    467     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
    468 #ifdef BCM_TRIDENT3_SUPPORT
    469         if (soc_mem_is_valid(unit, L2_ENTRY_HASH_CONTROLm)) {
    470             if (soc_mem_read(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY,
    471                              0, (void*)&l2_entry_hash_control) < 0) {
    472                 test_error(unit, "L2 Entry hash control read failed\n");
    473                 goto done;
    474             }
    475             ad->save_l2_entry_hash_control = l2_entry_hash_control;
    476             rv = td3_entry_hash_control_set(unit, ad->opt_hash,
    477                      L2_ENTRY_HASH_CONTROLm,
    478                      (uint32 *)&l2_entry_hash_control);
    479             if (rv < 0) {
    480                 test_error(unit, "Hash Control write failed");
    481                 goto done;
    482             }
    483             if (soc_mem_write(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY,
    484                              0, (void*)&l2_entry_hash_control) < 0) {
    485                 test_error(unit, "L2 Entry hash control setting failed\n");
    486                 goto done;
    487             }
    488             if (soc_mem_read(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY,
    489                              0, (void*)&shared_entry_hash_control) < 0) {
    490                 test_error(unit, "Shared Entry hash control read failed\n");
    491                 goto done;
    492             }
    493             ad->save_shared_entry_hash_control = shared_entry_hash_control;
    494         } else
    495 #endif /*  BCM_TRIDENT3_SUPPORT */
    496         {
    497         if (READ_L2_TABLE_HASH_CONTROLr(unit, &l2_table_hash_control) < 0) {
    498             test_error(unit, "L2 Table hash control read failed\n");
    499             goto done;
    500         }
    501         ad->save_l2_table_hash_control = l2_table_hash_control;
    502             soc_reg_field_set(unit, L2_TABLE_HASH_CONTROLr,
    503                               &l2_table_hash_control, HASH_ZERO_OR_LSBf, 1);
    504         if (WRITE_L2_TABLE_HASH_CONTROLr(unit, l2_table_hash_control) < 0) {
    505             test_error(unit, "L2 Table hash control setting failed\n");
    506             goto done;
    507         }
    508         if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) 
    509         {  
    510             if (READ_SHARED_TABLE_HASH_CONTROLr(unit, &shared_table_hash_control) < 0) {
    511                 test_error(unit, "Shared Table hash control read failed\n");
    512                  goto done;
    513             }
    514             ad->save_shared_table_hash_control = shared_table_hash_control;
    515         }
    516       } 
    517     } else {
    518         if (soc_feature(unit, soc_feature_dual_hash)) {
    519             if (READ_L2_AUX_HASH_CONTROLr(unit, &l2_aux_hash_control) < 0) {
    520                 test_error(unit, "L2 AUX hash control read failed\n");
    521                 goto done;
    522             }
    523 
    524             ad->save_l2_aux_hash_control = l2_aux_hash_control;
    525 
    526             soc_reg_field_set(unit, L2_AUX_HASH_CONTROLr,
    527                               &l2_aux_hash_control, HASH_SELECTf, FB_HASH_LSB);
    528 
    529             if ((SAL_BOOT_SIMULATION) && (!SAL_BOOT_QUICKTURN)) {
    530                 soc_reg_field_set(unit, L2_AUX_HASH_CONTROLr,
    531                                   &l2_aux_hash_control, ENABLEf, 0);
    532             }
    533 
    534             if (WRITE_L2_AUX_HASH_CONTROLr(unit, l2_aux_hash_control) < 0) {
    535                 test_error(unit, "L2 AUX hash control setting failed\n");
    536                 goto done;
    537             }
    538         }
    539     }
    540 
    541     rv = 0;
    542 
    543  done:
    544 
    545     parse_arg_eq_done(&pt);
    546     return rv;
    547 }
    548 
    549 /* Individual test init wrappers */
    550 int
    551 draco_l2_hash_test_init(int unit, args_t *a, void **p)
    552 {
    553     draco_l2_test_t        *dw = &dl2_work[unit];
    554     draco_l2_testdata_t    *dp = &dw->dlp_l2_hash;
    555     int                    rv;
    556 
    557     dl2_setup(unit, dw);
    558 
    559     /* Set working data to hash */
    560     dw->dlp_l2_cur = dp;
    561 
    562     if ((rv = draco_l2_test_init(unit, dp, a)) < 0) {
    563         return rv;
    564     } else {
    565         *p = dp;
    566     }
    567 
    568     return 0;
    569 }
    570 
    571 int
    572 draco_l2_ov_test_init(int unit, args_t *a, void **p)
    573 {
    574     draco_l2_test_t        *dw = &dl2_work[unit];
    575     draco_l2_testdata_t    *dp = &dw->dlp_l2_ov;
    576     int                    rv;
    577 
    578     dl2_setup(unit, dw);
    579 
    580     /* Set working data to overflow */
    581     dw->dlp_l2_cur = dp;
    582 
    583     if ((rv = draco_l2_test_init(unit, dp, a)) < 0) {
    584         return rv;
    585     } else {
    586         *p = dp;
    587     }
    588 
    589     return 0;
    590 }
    591 
    592 int
    593 draco_l2_lu_test_init(int unit, args_t *a, void **p)
    594 {
    595     draco_l2_test_t        *dw = &dl2_work[unit];
    596     draco_l2_testdata_t    *dp = &dw->dlp_l2_lu;
    597     int                    rv;
    598 
    599     dl2_setup(unit, dw);
    600 
    601     /* Set working data to lookup */
    602     dw->dlp_l2_cur = dp;
    603 
    604     if ((rv = draco_l2_test_init(unit, dp, a)) < 0) {
    605         return rv;
    606     } else {
    607         *p = dp;
    608     }
    609 
    610     return 0;
    611 }
    612 
    613 int
    614 draco_l2_dp_test_init(int unit, args_t *a, void **p)
    615 {
    616     draco_l2_test_t        *dw = &dl2_work[unit];
    617     draco_l2_testdata_t    *dp = &dw->dlp_l2_dp;
    618     int                    rv;
    619 
    620     dl2_setup(unit, dw);
    621 
    622     /* Set working data to delete by port */
    623     dw->dlp_l2_cur = dp;
    624 
    625     if ((rv = draco_l2_test_init(unit, dp, a)) < 0) {
    626         return rv;
    627     } else {
    628         *p = dp;
    629     }
    630 
    631     return 0;
    632 }
    633 
    634 int
    635 draco_l2_dv_test_init(int unit, args_t *a, void **p)
    636 {
    637     draco_l2_test_t        *dw = &dl2_work[unit];
    638     draco_l2_testdata_t    *dp = &dw->dlp_l2_dv;
    639     int                    rv;
    640 
    641     dl2_setup(unit, dw);
    642 
    643     /* Set working data to delete by VLAN */
    644     dw->dlp_l2_cur = dp;
    645 
    646     if ((rv = draco_l2_test_init(unit, dp, a)) < 0) {
    647         return rv;
    648     } else {
    649         *p = dp;
    650     }
    651 
    652     return 0;
    653 }
    654 
    655 /*
    656  * Utility routines for ARL testing
    657  */
    658 
    659 void
    660 draco_l2_time_start(draco_l2_testdata_t *ad)
    661 {
    662     ad->tm = SAL_TIME_DOUBLE();
    663 }
    664 
    665 void
    666 draco_l2_time_end(draco_l2_testdata_t *ad)
    667 {
    668     ad->tm = SAL_TIME_DOUBLE() - ad->tm;
    669     if (ad->opt_verbose) {
    670         cli_out("    time: %"COMPILER_DOUBLE_FORMAT" msec\n", ad->tm * 1000);
    671     }
    672 }
    673 
    674 
    675 #if defined(BCM_FIREBOLT_SUPPORT)
    676 static int
    677 draco_l2_bucket_search(int unit, draco_l2_testdata_t *ad, int bucket,
    678                         l2x_entry_t *expect)
    679 {
    680     l2x_entry_t chip_entry;
    681     int ix, mem_table_index;
    682     int rv = -1; /* Assume failed unless we find it */
    683     int validf;
    684     int bucket_size = SOC_L2X_BUCKET_SIZE;
    685     validf = VALIDf;
    686 
    687     if (soc_mem_field_valid(unit, L2Xm, BASE_VALIDf)) {
    688         validf = BASE_VALIDf;
    689     }
    690 
    691     /* Use soc_*_hash_bank_info_get() to make the test generic */
    692     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
    693         bucket_size = 4;
    694     }
    695 /*    
    696 #if defined(BCM_MONTEREY_SUPPORT)
    697     if (SOC_IS_MONTEREY(unit)) { 
    698         bucket_size = 2;
    699     }
    700 #endif
    701 */
    702     for (ix = 0; ix < bucket_size; ix++) {
    703         mem_table_index = (bucket * bucket_size) + ix;
    704 
    705         if (soc_mem_read(unit, L2Xm, MEM_BLOCK_ANY,
    706                              mem_table_index, &chip_entry) < 0) {
    707             test_error(unit,
    708                        "Read ARL failed at bucket %d, offset %d\n",
    709                        bucket, ix);
    710             break;
    711         }
    712 
    713         if (!soc_L2Xm_field32_get(unit, &chip_entry, validf)) {
    714             /* Valid bit unset, entry blank */
    715             continue;
    716         }
    717 
    718         if (soc_mem_compare_key(unit, L2Xm, expect, &chip_entry) == 0) {
    719             /* Found the matching entry */
    720             rv = 0;
    721             break;
    722         }
    723     }
    724 
    725     return rv;
    726 }
    727 
    728 /*
    729  * Test of L2X hashing
    730  *
    731  *   This test tries a number of keys against one of the hashing functions,
    732  *   checking a software hash against the hardware hash, then searching the
    733  *   bucket to find the entry after inserting.
    734  */
    735 int
    736 fb_l2_test_hash(int unit, args_t *a, void *p)
    737 {
    738     draco_l2_testdata_t         *ad = p;
    739     l2x_entry_t         entry;
    740     int r, rv = 0;
    741     int soft_bucket;
    742     int ix;
    743     int hash = ad->opt_hash;
    744     uint8 key[XGS_HASH_KEY_SIZE];
    745     int iterations;
    746     bcm_l2_addr_t addr;
    747     int vid_inc = ad->opt_vid_inc;
    748     int mac_inc = ad->opt_mac_inc;
    749 #ifdef BCM_TRIUMPH_SUPPORT
    750     int ext_index_max = -1;
    751 #endif /* BCM_TRIUMPH_SUPPORT */
    752 
    753     COMPILER_REFERENCE(a);
    754 
    755 #ifdef BCM_TRIUMPH_SUPPORT
    756     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
    757         ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max;
    758         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1;
    759     }
    760 #endif /* BCM_TRIUMPH_SUPPORT */
    761 
    762     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
    763 
    764     if (ad->opt_verbose) {
    765         cli_out("Starting ARL hash test\n");
    766     }
    767 
    768     iterations = ad->opt_count;
    769 
    770     for (ix = 0; ix < iterations; ix++) {
    771 #ifdef BCM_TRX_SUPPORT
    772         if (SOC_IS_TRX(unit)) {
    773             int num_bits;
    774 
    775             _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE);
    776             num_bits = soc_tr_l2x_base_entry_to_key(unit, &entry, key);
    777             soft_bucket = soc_tr_l2x_hash(unit, hash, num_bits, &entry, key);
    778         } else
    779 #endif /* BCM_TRX_SUPPORT */
    780         {
    781             _bcm_fb_l2_to_l2x(unit, &entry, &addr);
    782             soc_draco_l2x_base_entry_to_key(unit, &entry, key);
    783             soft_bucket = soc_fb_l2_hash(unit, hash, key);
    784         }
    785 
    786         if (ad->opt_verbose) {
    787             cli_out("Inserting ");
    788             soc_mem_entry_dump(unit, L2Xm, &entry, BSL_LSS_CLI);
    789             cli_out("\n");
    790             cli_out("into bucket 0x%x\n", soft_bucket);
    791         }
    792 
    793         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
    794             if (r == SOC_E_FULL) {
    795                 /* Bucket overflow, just pass on */
    796                 goto incr;
    797             } else {
    798                 test_error(unit,
    799                            "ARL insert failed at bucket %d\n", soft_bucket);
    800                 rv = -1;
    801                 goto done;
    802             }
    803         }
    804 
    805         /* Now we search for the entry */
    806 
    807         /* Only do a quick check vs. expected bucket here */
    808         if (draco_l2_bucket_search(unit, ad, soft_bucket, &entry) < 0) {
    809             test_error(unit,
    810                        "ARL entry with key "
    811                        "0x%02x%02x%02x%02x%02x%02x%02x%01x "
    812                        "not found in predicted bucket %d\n",
    813                        key[7], key[6], key[5], key[4],
    814                        key[3], key[2], key[1], (key[0] >> 4) & 0xf,
    815                        soft_bucket);
    816         }
    817 
    818         if (bcm_l2_addr_delete(unit, addr.mac, addr.vid) < 0) {
    819             test_error(unit, "ARL delete failed at bucket %d\n",
    820                        soft_bucket);
    821             rv = -1;
    822             goto done;
    823         }
    824 
    825     incr:
    826         addr.vid += vid_inc;
    827         if (addr.vid > FB_L2_VID_MAX) {
    828             addr.vid = 1;
    829         }
    830         increment_macaddr(addr.mac, mac_inc);
    831     }
    832 
    833  done:
    834 #ifdef BCM_TRIUMPH_SUPPORT
    835     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
    836         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max;
    837     }
    838 #endif /* BCM_TRIUMPH_SUPPORT */
    839     return rv;
    840 }
    841 
    842 /*
    843  * Test of ARL overflow behavior
    844  *
    845  *   This test fills each bucket of the ARL, then inserts another entry to see
    846  *   that the last entry fails to insert.
    847  */
    848 
    849 int
    850 fb_l2_test_ov(int unit, args_t *a, void *p)
    851 {
    852     draco_l2_testdata_t         *ad = p;
    853     l2x_entry_t         entry, result, entry_tmp[SOC_L2X_BUCKET_SIZE];
    854     int                 ix, jx, r, idx, rv = 0;
    855     int bucket = 0;
    856     uint32 hash = ad->opt_hash;
    857     bcm_l2_addr_t addr, addr_tmp;
    858     int vid_inc = ad->opt_vid_inc;
    859     int iter = ad->opt_count;
    860     uint8 key[XGS_HASH_KEY_SIZE];
    861 #ifdef BCM_TRIUMPH_SUPPORT
    862     int ext_index_max = -1;
    863 #endif /* BCM_TRIUMPH_SUPPORT */
    864 
    865     COMPILER_REFERENCE(a);
    866 
    867 #ifdef BCM_TRIUMPH_SUPPORT
    868     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
    869         ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max;
    870         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1;
    871     }
    872 #endif /* BCM_TRIUMPH_SUPPORT */
    873 
    874     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
    875 
    876     if (hash != FB_HASH_LSB) {
    877         if (ad->opt_verbose) {
    878             cli_out("Resetting hash selection to LSB\n");
    879         }
    880 
    881         hash = ad->save_hash_control;
    882         soc_reg_field_set(unit, HASH_CONTROLr, &hash,
    883                           L2_AND_VLAN_MAC_HASH_SELECTf, FB_HASH_LSB);
    884 
    885         if (WRITE_HASH_CONTROLr(unit, hash) < 0) {
    886             test_error(unit, "Hash select setting failed\n");
    887             goto done;
    888         }
    889 
    890         ad->opt_hash = hash = FB_HASH_LSB;
    891     }
    892 
    893     if (iter > soc_mem_index_count(unit, L2Xm)) {
    894         iter = soc_mem_index_count(unit, L2Xm);
    895     }
    896 
    897     while (iter--) {
    898         for (ix = 0; ix < SOC_L2X_BUCKET_SIZE; ix++) {
    899 #ifdef BCM_TRX_SUPPORT
    900             if (SOC_IS_TRX(unit)) {
    901                 _bcm_tr_l2_to_l2x(unit, &(entry_tmp[ix]), &addr, TRUE);
    902 
    903                 if (ix == 0) {
    904                     int num_bits;
    905 
    906                     num_bits = soc_tr_l2x_base_entry_to_key
    907                         (unit, &(entry_tmp[ix]), key);
    908                     bucket = soc_tr_l2x_hash(unit, hash, num_bits,
    909                                              &(entry_tmp[ix]), key);
    910     
    911                     if (ad->opt_verbose) {
    912                         cli_out("Filling bucket %d\n", bucket);
    913                     }
    914                 }
    915             } else
    916 #endif /* BCM_TRX_SUPPORT */
    917             {
    918                 _bcm_fb_l2_to_l2x(unit, &(entry_tmp[ix]), &addr);
    919 
    920                 if (ix == 0) {
    921                     soc_draco_l2x_base_entry_to_key(unit, &(entry_tmp[ix]), key);
    922                     bucket = soc_fb_l2_hash(unit, hash, key);
    923     
    924                     if (ad->opt_verbose) {
    925                         cli_out("Filling bucket %d\n", bucket);
    926                     }
    927                 }
    928             }
    929 
    930             if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
    931                 if (r == SOC_E_FULL) {
    932                     /* Already full, stop wasting time */
    933                     break;
    934                 } else {
    935                     test_error(unit,
    936                                "ARL insert failed at bucket %d\n", bucket);
    937                     rv = -1;
    938                     goto done;
    939                 }
    940             }
    941 
    942             /* key for LSB is the MAC address, so we must keep it constant */
    943             addr.vid += vid_inc;
    944             if (addr.vid > DRACO_L2_VID_MAX) {
    945                 addr.vid = 1;
    946             }
    947         }
    948 
    949         if (ad->opt_verbose) {
    950             cli_out("Inserting %dth entry in bucket %d, should fail\n",
    951                     (SOC_L2X_BUCKET_SIZE + 1), bucket);
    952         }
    953 
    954 #ifdef BCM_TRX_SUPPORT
    955         if (SOC_IS_TRX(unit)) {
    956             _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE);
    957         } else
    958 #endif /* BCM_TRX_SUPPORT */
    959         {
    960             _bcm_fb_l2_to_l2x(unit, &entry, &addr);
    961         }
    962 
    963         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
    964             if (r != SOC_E_FULL) {
    965                 test_error(unit,
    966                            "ARL insert failed\n");
    967                 rv = -1;
    968                 goto done;
    969             }
    970         } else {
    971             test_error(unit, "ARL insert to full bucket succeeded\n");
    972             rv = -1;
    973             goto done;
    974         }
    975 
    976         if (ad->opt_verbose) {
    977             cli_out("Verifying entries present\n");
    978         }
    979 
    980         /* Verify bucket contains our added entries */
    981         for (jx = 0; jx < ix; jx++) {
    982             if (draco_l2_bucket_search(unit, ad, bucket,
    983                                           &(entry_tmp[jx])) < 0) {
    984                 test_error(unit, "ARL entry missing at bucket %d\n", bucket);
    985                 rv = -1;
    986                 goto done;
    987             }
    988             if (soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &idx, 
    989                                &entry_tmp[jx], &result, 0) < 0) {
    990                 test_error(unit, "ARL entry missing at bucket %d\n", bucket);
    991                 rv = -1;
    992                 goto done;
    993             }
    994             if (bucket != (idx / SOC_L2X_BUCKET_SIZE)) {
    995                 test_error(unit, "ARL entry inserted into wrong bucket"
    996                            " Expected %d Actual %d\n", bucket, idx);
    997                 rv = -1;
    998                 goto done;
    999             }
   1000         }
   1001 
   1002         if (ad->opt_verbose) {
   1003             cli_out("Cleaning bucket %d\n", bucket);
   1004         }
   1005 
   1006         /* Remove the entries that we added */
   1007         for (jx = 0; jx < ix; jx++) {
   1008 #ifdef BCM_TRX_SUPPORT
   1009             if (SOC_IS_TRX(unit)) {
   1010                 _bcm_tr_l2_from_l2x(unit, &addr_tmp, &(entry_tmp[jx]));
   1011             } else
   1012 #endif /* BCM_TRX_SUPPORT */
   1013             {
   1014                 _bcm_fb_l2_from_l2x(unit, &addr_tmp, &(entry_tmp[jx]));
   1015             }
   1016             if (bcm_l2_addr_delete(unit, addr_tmp.mac, addr_tmp.vid) < 0) {
   1017                 test_error(unit, "ARL delete failed at bucket %d\n", bucket);
   1018                 rv = -1;
   1019                 goto done;
   1020             }
   1021         }
   1022 
   1023         /* We want the increment to change buckets by one */
   1024         increment_macaddr(addr.mac, 1);
   1025     }
   1026 
   1027  done:
   1028 #ifdef BCM_TRIUMPH_SUPPORT
   1029     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1030         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max;
   1031     }
   1032 #endif /* BCM_TRIUMPH_SUPPORT */
   1033     return rv;
   1034 }
   1035 
   1036 /*
   1037  * Test of ARL lookup
   1038  *
   1039  *   This test loops a given number of times.  It inserts a single ARL
   1040  *   entry, looks up the ARL entry, and deletes the ARL entry.
   1041  *   It is possible to run this test while heavy switching is going on.
   1042  */
   1043 
   1044 int
   1045 fb_l2_test_lu(int unit, args_t *a, void *p)
   1046 {
   1047     draco_l2_testdata_t *ad = p;
   1048     l2x_entry_t         entry, entry_tmp;
   1049     int                 i, r, rv = -1;
   1050     int                 found_times, bucket_full_times;
   1051     int                 index;
   1052     bcm_l2_addr_t addr;
   1053     int vid_inc = ad->opt_vid_inc;
   1054     int mac_inc = ad->opt_mac_inc;
   1055 #ifdef BCM_TRIUMPH_SUPPORT
   1056     int ext_index_max = -1;
   1057 #endif /* BCM_TRIUMPH_SUPPORT */
   1058 
   1059     COMPILER_REFERENCE(a);
   1060 
   1061     if (! soc_feature(unit, soc_feature_l2_lookup_cmd)) {
   1062         test_error(unit, "L2 lookup not supported by chip (unit %d)\n", unit);
   1063         return -1;
   1064     }
   1065 
   1066 #ifdef BCM_TRIUMPH_SUPPORT
   1067     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1068         ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max;
   1069         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1;
   1070     }
   1071 #endif /* BCM_TRIUMPH_SUPPORT */
   1072 
   1073     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
   1074 
   1075     draco_l2_time_start(ad);
   1076 
   1077     found_times = 0;
   1078     bucket_full_times = 0;
   1079 
   1080     for (i = 1; i <= ad->opt_count; i++) {
   1081 
   1082 #ifdef BCM_TRX_SUPPORT
   1083         if (SOC_IS_TRX(unit)) {
   1084             _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE);
   1085         } else
   1086 #endif /* BCM_TRX_SUPPORT */
   1087         {
   1088             _bcm_fb_l2_to_l2x(unit, &entry, &addr);
   1089         }
   1090 
   1091         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
   1092             if (r == SOC_E_FULL) {
   1093                 /* Bucket overflow, just pass on */
   1094                 bucket_full_times++;
   1095                 goto inc;
   1096             } else {
   1097                 test_error(unit,
   1098                            "ARL insert failed on loop %d: %s\n",
   1099                            i, soc_errmsg(r));
   1100                 break;
   1101             }
   1102         }
   1103 
   1104         if ((r = soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &index,
   1105                                 &entry, &entry_tmp, 0)) < 0) {
   1106             test_error(unit,
   1107                        "ARL lookup failure on loop %d: %s\n",
   1108                        i, soc_errmsg(r));
   1109             break;
   1110         } else  {
   1111             found_times++;
   1112         }
   1113 
   1114         if ((r = bcm_l2_addr_delete(unit, addr.mac, addr.vid)) < 0) {
   1115             test_error(unit,
   1116                        "ARL delete failed on loop %d: %s\n",
   1117                        i, soc_errmsg(r));
   1118             break;
   1119         }
   1120 
   1121         if ((r = soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &index,
   1122                                 &entry, &entry_tmp, 0)) < 0) {
   1123             if (r != SOC_E_NOT_FOUND) {
   1124                 test_error(unit,
   1125                            "ARL lookup failure on loop %d: %s\n",
   1126                            i, soc_errmsg(r));
   1127                 break;
   1128             }
   1129             /* else, OK */
   1130         } else  {
   1131             test_error(unit,
   1132                        "ARL lookup succeeded after delete on loop %d\n", i);
   1133             break;
   1134         }
   1135 
   1136     inc:
   1137         addr.vid += vid_inc;
   1138         if (addr.vid > DRACO_L2_VID_MAX) {
   1139             addr.vid = 1;
   1140         }
   1141         increment_macaddr(addr.mac, mac_inc);
   1142     }
   1143 
   1144     draco_l2_time_end(ad);
   1145 
   1146     if (i > ad->opt_count) {            /* All iterations passed */
   1147         if ((bucket_full_times + found_times) != ad->opt_count) {
   1148             test_error(unit,
   1149                        "Lookup succeeded only %d times out of %d\n",
   1150                        found_times, ad->opt_count);
   1151         } else {
   1152             rv = 0;                     /* Test passed */
   1153 
   1154             if (ad->opt_verbose) {
   1155                 cli_out("Passed:  %d lookups, %d bucket overflows\n",
   1156                         found_times, bucket_full_times);
   1157             }
   1158         }
   1159     }
   1160 
   1161 #ifdef BCM_TRIUMPH_SUPPORT
   1162     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1163         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max;
   1164     }
   1165 #endif /* BCM_TRIUMPH_SUPPORT */
   1166 
   1167     return rv;
   1168 }
   1169 
   1170 /*
   1171  * Test of ARL delete by port
   1172  *
   1173  * This test will insert a collection of entries with different ports,
   1174  * then try to delete them by port reference.
   1175  */
   1176 
   1177 int
   1178 fb_l2_test_dp(int unit, args_t *a, void *p)
   1179 {
   1180     draco_l2_testdata_t *ad = p;
   1181     l2x_entry_t         *entries = NULL;
   1182     int                 i, r, rv = 0;
   1183     int                 bucket_full_times;
   1184     int                 *bucket_full = NULL;
   1185     bcm_l2_addr_t       addr;
   1186     int                 vid_inc = ad->opt_vid_inc;
   1187     int                 mac_inc = ad->opt_mac_inc;
   1188     int                 modid, modid_hi;
   1189     uint8               key[XGS_HASH_KEY_SIZE];
   1190 #ifdef BCM_TRIUMPH_SUPPORT
   1191     int                 ext_index_max = -1;
   1192 #endif /* BCM_TRIUMPH_SUPPORT */
   1193 
   1194     COMPILER_REFERENCE(a);
   1195 
   1196 #ifdef BCM_TRIUMPH_SUPPORT
   1197     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1198         ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max;
   1199         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1;
   1200     }
   1201 #endif /* BCM_TRIUMPH_SUPPORT */
   1202 
   1203     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
   1204     if ((r = bcm_stk_my_modid_get(unit, &modid)) < 0) {
   1205         test_error(unit,
   1206                    "Modid retrieval failed: %s\n",
   1207                    soc_errmsg(r));
   1208         rv = -1;
   1209         goto done;
   1210     }
   1211     modid_hi = modid + 1;
   1212 
   1213     entries =
   1214         sal_alloc(sizeof(l2x_entry_t) * SOC_MAX_NUM_PORTS, "L2 entries");
   1215     if (!entries) {
   1216         test_error(unit,
   1217                    "Memory allocation failure\n");
   1218         rv = -1;
   1219         goto done;
   1220     }
   1221     sal_memset(entries, 0, sizeof(l2x_entry_t) * SOC_MAX_NUM_PORTS);
   1222 
   1223     bucket_full = sal_alloc(sizeof(int) * SOC_MAX_NUM_PORTS,
   1224                             "L2 full buckets");
   1225     if (!bucket_full) {
   1226         test_error(unit,
   1227                    "Memory allocation failure\n");
   1228         rv = -1;
   1229         goto done;
   1230     }
   1231     sal_memset(bucket_full, 0, sizeof(int) * SOC_MAX_NUM_PORTS);
   1232 
   1233     bucket_full_times = 0;
   1234 
   1235     if (ad->opt_verbose) {
   1236         cli_out("Inserting port entries\n");
   1237     }
   1238 
   1239     draco_l2_time_start(ad);
   1240 
   1241     PBMP_E_ITER(unit, i) {
   1242         if (SOC_PORT_MOD1(unit, i)) {
   1243             addr.modid = modid_hi;
   1244         } else {
   1245             addr.modid = modid;
   1246         }
   1247         addr.port = i & 0x1f;
   1248 #ifdef BCM_TRX_SUPPORT
   1249         if (SOC_IS_TRX(unit)) {
   1250             _bcm_tr_l2_to_l2x(unit, &(entries[i]), &addr, FALSE);
   1251         } else
   1252 #endif /* BCM_TRX_SUPPORT */
   1253         {
   1254             _bcm_fb_l2_to_l2x(unit, &(entries[i]), &addr);
   1255         }
   1256 
   1257         if (ad->opt_verbose) {
   1258             cli_out("Inserting port %d entry\n", i);
   1259         }
   1260 
   1261         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
   1262             if (r == SOC_E_FULL) {
   1263                 bucket_full_times++;
   1264                 bucket_full[i] = 1;
   1265                 continue;
   1266             } else {
   1267                 test_error(unit,
   1268                            "ARL insert failed on port entry %d: %s\n",
   1269                            i, soc_errmsg(r));
   1270                 rv = -1;
   1271                 goto done;
   1272             }
   1273         } else {
   1274             bucket_full[i] = 0;
   1275         }
   1276 
   1277         addr.vid += vid_inc;
   1278         if (addr.vid > DRACO_L2_VID_MAX) {
   1279             addr.vid = 1;
   1280         }
   1281         increment_macaddr(addr.mac, mac_inc);
   1282     }
   1283 
   1284     PBMP_E_ITER(unit, i) {
   1285         l2x_entry_t *cur_entry = &(entries[i]);
   1286         int local_modid;
   1287         int port;
   1288 
   1289         port = i & 0x1f;
   1290 
   1291         if (SOC_PORT_MOD1(unit, i)) {
   1292              local_modid = modid_hi;
   1293         } else {
   1294             local_modid = modid;
   1295         }
   1296         if (!bucket_full[i]) {
   1297             if (ad->opt_verbose) {
   1298                 cli_out("Attempting to delete by port %d\n", i);
   1299             }
   1300 
   1301             r = bcm_l2_addr_delete_by_port(unit, local_modid, port,
   1302                                                  BCM_L2_DELETE_STATIC);
   1303             if (r < 0) {
   1304                 test_error(unit,
   1305                            "ARL delete by port unsuccessful on modid %d, port %d\n",
   1306                            local_modid, port);
   1307                 rv = -1;
   1308                 goto done;
   1309             } else {
   1310                 /* Delete claims to be successful, check */
   1311                 int soft_bucket;
   1312 
   1313 #ifdef BCM_TRX_SUPPORT
   1314                 if (SOC_IS_TRX(unit)) {
   1315                     int num_bits;
   1316                     num_bits = soc_tr_l2x_base_entry_to_key(unit, cur_entry,
   1317                                                             key);
   1318                     soft_bucket = soc_tr_l2x_hash(unit, ad->opt_hash, num_bits,
   1319                                                   cur_entry, key);
   1320                 } else
   1321 #endif
   1322                 {
   1323                     soc_draco_l2x_base_entry_to_key(unit, cur_entry, key);
   1324                     soft_bucket = soc_fb_l2_hash(unit, ad->opt_hash, key);
   1325                 }
   1326 
   1327                 /* We should not find the entry when searching its bucket */
   1328                 if (draco_l2_bucket_search(unit, ad,
   1329                                               soft_bucket, cur_entry) == 0) {
   1330                     test_error(unit,
   1331                                "ARL delete by port failed on port %d\n", i);
   1332                     rv = -1;
   1333                     goto done;
   1334                 }
   1335             }
   1336         }
   1337     }
   1338 
   1339     draco_l2_time_end(ad);
   1340 
   1341  done:
   1342     if (bucket_full) {
   1343         sal_free(bucket_full);
   1344     }
   1345     if (entries) {
   1346         sal_free(entries);
   1347     }
   1348 #ifdef BCM_TRIUMPH_SUPPORT
   1349     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1350         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max;
   1351     }
   1352 #endif /* BCM_TRIUMPH_SUPPORT */
   1353 
   1354     return rv;
   1355 }
   1356 
   1357 /*
   1358  * Test of ARL delete by VLAN
   1359  *
   1360  * This test will insert a collection of entries with different VLAN ids,
   1361  * then try to delete them by VLAN.
   1362  */
   1363 
   1364 int
   1365 fb_l2_test_dv(int unit, args_t *a, void *p)
   1366 {
   1367     draco_l2_testdata_t *ad = p;
   1368     int                 count = ad->opt_count;
   1369     l2x_entry_t         *entries = NULL;
   1370     int                 i, vid, r = 0, rv = 0;
   1371     int                 bucket_full_times;
   1372     int                 *bucket_full = NULL;
   1373     bcm_l2_addr_t       addr;
   1374     int                 mac_inc = ad->opt_mac_inc;
   1375     int                 vid_inc = ad->opt_vid_inc;
   1376     uint8               key[XGS_HASH_KEY_SIZE];
   1377 #ifdef BCM_TRIUMPH_SUPPORT
   1378     int                 ext_index_max = -1;
   1379 #endif /* BCM_TRIUMPH_SUPPORT */
   1380 
   1381     COMPILER_REFERENCE(a);
   1382 
   1383     entries = sal_alloc(sizeof(l2x_entry_t) * count, "L2 entries");
   1384     if (!entries) {
   1385         test_error(unit,
   1386                    "Memory allocation failure\n");
   1387         rv = -1;
   1388         goto done;
   1389     }
   1390     sal_memset(entries, 0, sizeof(l2x_entry_t) * count);
   1391 
   1392     bucket_full = sal_alloc(sizeof(int) * count, "L2 full buckets");
   1393     if (!bucket_full) {
   1394         test_error(unit,
   1395                    "Memory allocation failure\n");
   1396         rv = -1;
   1397         goto done;
   1398     }
   1399     sal_memset(bucket_full, 0, sizeof(int) * count);
   1400 
   1401 #ifdef BCM_TRIUMPH_SUPPORT
   1402     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1403         ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max;
   1404         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1;
   1405     }
   1406 #endif /* BCM_TRIUMPH_SUPPORT */
   1407 
   1408     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
   1409 
   1410     draco_l2_time_start(ad);
   1411 
   1412     bucket_full_times = 0;
   1413 
   1414     if (ad->opt_verbose) {
   1415         cli_out("Inserting VLAN entries\n");
   1416     }
   1417 
   1418     for (i = 0; i < count; i++) {
   1419 #ifdef BCM_TRX_SUPPORT
   1420         if (SOC_IS_TRX(unit)) {
   1421             _bcm_tr_l2_to_l2x(unit, &(entries[i]), &addr, TRUE);
   1422         } else
   1423 #endif /* BCM_TRX_SUPPORT */
   1424         {
   1425             _bcm_fb_l2_to_l2x(unit, &(entries[i]), &addr);
   1426         }
   1427 
   1428         if (ad->opt_verbose) {
   1429             cli_out("Inserting VLAN %d entry\n", addr.vid);
   1430         }
   1431 
   1432         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
   1433             if (r == SOC_E_FULL) {
   1434                 bucket_full_times++;
   1435                 bucket_full[i] = 1;
   1436                 continue;
   1437             } else {
   1438                 test_error(unit,
   1439                            "ARL insert failed on VLAN entry %d: %s\n",
   1440                            i, soc_errmsg(r));
   1441                 rv = -1;
   1442                 goto done;
   1443             }
   1444         } else {
   1445             bucket_full[i] = 0;
   1446         }
   1447 
   1448         addr.vid += vid_inc;
   1449         if (addr.vid > DRACO_L2_VID_MAX) {
   1450             addr.vid = 1;
   1451         }
   1452         increment_macaddr(addr.mac, mac_inc);
   1453     }
   1454 
   1455     vid = ad->opt_base_vid;
   1456 
   1457     for (i = 0; i < count; i++) {
   1458         l2x_entry_t *cur_entry = &(entries[i]);
   1459         if (!bucket_full[i]) {
   1460             if (ad->opt_verbose) {
   1461                 cli_out("Attempting to delete by VLAN %d\n", vid);
   1462             }
   1463 
   1464             r = bcm_l2_addr_delete_by_vlan(unit, vid, BCM_L2_DELETE_STATIC);
   1465             if (r < 0) {
   1466                 test_error(unit,
   1467                            "ARL delete by VLAN unsuccessful on VLAN %d\n", vid);
   1468                 rv = -1;
   1469                 goto done;
   1470             } else {
   1471                 /* Delete claims to be successful, check */
   1472                 int soft_bucket;
   1473 
   1474 #ifdef BCM_TRX_SUPPORT
   1475                 if (SOC_IS_TRX(unit)) {
   1476                     int num_bits;
   1477 
   1478                     num_bits = soc_tr_l2x_base_entry_to_key(unit, cur_entry,
   1479                                                             key);
   1480                     soft_bucket = soc_tr_l2x_hash(unit, ad->opt_hash, num_bits,
   1481                                                   cur_entry, key);
   1482                 } else
   1483 #endif
   1484                 {
   1485                     soc_draco_l2x_base_entry_to_key(unit, cur_entry, key);
   1486                     soft_bucket = soc_fb_l2_hash(unit, ad->opt_hash, key);
   1487                 }
   1488                 /* We should not find the entry when searching its bucket */
   1489                 if (draco_l2_bucket_search(unit, ad,
   1490                                               soft_bucket, cur_entry) == 0) {
   1491                     test_error(unit,
   1492                                "ARL delete by VLAN failed on VLAN %d\n",
   1493                                vid);
   1494                     rv = -1;
   1495                     goto done;
   1496                 }
   1497             }
   1498         }
   1499 
   1500         vid += vid_inc;
   1501         if (vid > DRACO_L2_VID_MAX) {
   1502             vid = 1;
   1503         }
   1504     }
   1505 
   1506     draco_l2_time_end(ad);
   1507 
   1508  done:
   1509     if (bucket_full) {
   1510         sal_free(bucket_full);
   1511     }
   1512     if (entries) {
   1513         sal_free(entries);
   1514     }
   1515 
   1516 #ifdef BCM_TRIUMPH_SUPPORT
   1517     if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) {
   1518         SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max;
   1519     }
   1520 #endif /* BCM_TRIUMPH_SUPPORT */
   1521 
   1522     return rv;
   1523 }
   1524 
   1525 /*
   1526  * Test clean-up routine used for all ARL tests
   1527  */
   1528 
   1529 int
   1530 fb_l2_test_done(int unit, void *p)
   1531 {
   1532     draco_l2_testdata_t *ad = p;
   1533 
   1534     if (ad == NULL) {
   1535 	return 0;
   1536     }
   1537 
   1538     /* Check if empty at the end of the test */
   1539     if (ad->opt_reset) {
   1540         int rv, ix;
   1541         int index_min = soc_mem_index_min(unit, L2Xm);
   1542         int index_max = soc_mem_index_max(unit, L2Xm);
   1543         uint32 *buf = 0;
   1544         uint32 *ent;
   1545         uint32 count;
   1546 
   1547         buf = soc_cm_salloc(unit,
   1548                             SOC_MEM_TABLE_BYTES(unit, L2Xm),
   1549                             "l2x_test");
   1550         if (!buf) {
   1551             test_error(unit, "Memory allocation failed\n");
   1552             return (-1);
   1553         }
   1554 
   1555         if ((rv = soc_mem_read_range(unit, L2Xm, MEM_BLOCK_ANY,
   1556                           index_min, index_max, buf)) < 0) {
   1557             test_error(unit, "Memory DMA of L2X entries failed\n");
   1558             return (-1);
   1559         }
   1560 
   1561         count = soc_mem_index_count(unit, L2Xm);
   1562         for (ix = 0; ix < count; ix++) {
   1563             int vld_fld = VALIDf;
   1564 
   1565             if (soc_mem_field_valid(unit, L2Xm, BASE_VALIDf)) {
   1566                 vld_fld = BASE_VALIDf;
   1567             }
   1568 
   1569             ent = soc_mem_table_idx_to_pointer(unit, L2Xm,
   1570                                                uint32 *, buf, ix);
   1571             if (soc_L2Xm_field32_get(unit, ent, vld_fld)) {
   1572                 test_error(unit, "L2 table not empty after test entry = %d\n",
   1573                                 ix);
   1574                 soc_mem_entry_dump(unit, L2Xm, ent, BSL_LSS_CLI);
   1575                 return (-1);
   1576             }
   1577         }
   1578 
   1579         soc_cm_sfree(unit, buf);
   1580     }
   1581 
   1582     if (WRITE_HASH_CONTROLr(unit, ad->save_hash_control) < 0) {
   1583         test_error(unit, "Hash select restore failed\n");
   1584     }
   1585     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
   1586 #ifdef BCM_TRIDENT3_SUPPORT
   1587         if (soc_mem_is_valid(unit, L2_ENTRY_HASH_CONTROLm)) {
   1588             if (soc_mem_write(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY,
   1589                              0, (void*)&ad->save_l2_entry_hash_control) < 0) {
   1590                 test_error(unit, "L2 Entry hash control setting failed\n");
   1591             }
   1592             if (soc_mem_write(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY,
   1593                       0, (void*)&ad->save_shared_entry_hash_control) < 0) {
   1594                 test_error(unit, "Shared Entry hash control setting failed\n");
   1595             }
   1596         } else
   1597 #endif /* BCM_TRIDENT3_SUPPORT */
   1598         {
   1599             if (WRITE_L2_TABLE_HASH_CONTROLr(unit,
   1600                       ad->save_l2_table_hash_control) < 0) {
   1601             test_error(unit, "L2 Table hash control setting failed\n");
   1602         }
   1603         if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr))
   1604         {
   1605             if (WRITE_SHARED_TABLE_HASH_CONTROLr(unit, ad->save_shared_table_hash_control) < 0) {
   1606                 test_error(unit, "Shared Table hash control setting failed\n");
   1607             }
   1608        }
   1609       }
   1610     } else {
   1611         if (soc_feature(unit, soc_feature_dual_hash)) {
   1612             if (WRITE_L2_AUX_HASH_CONTROLr(unit, ad->save_l2_aux_hash_control) < 0) {
   1613                test_error(unit, "L2 AUX hash control restore failed\n");
   1614             }
   1615         }
   1616     }
   1617 
   1618     return 0;
   1619 }
   1620 #endif /* BCM_FIREBOLT_SUPPORT */
   1621 
   1622 #if defined(BCM_TRIDENT2_SUPPORT)
   1623 static int
   1624 td2_l2_bucket_search(int unit, draco_l2_testdata_t *ad, int bank, int *index_array,
   1625                         l2x_entry_t *expect)
   1626 {
   1627     l2x_entry_t chip_entry;
   1628     int ix, mem_table_index;
   1629     int rv = -1; /* Assume failed unless we find it */
   1630     int validf;
   1631     int bucket_size = SOC_TD2_L2X_BUCKET_SIZE;
   1632     validf = VALIDf;
   1633 
   1634     if (soc_feature(unit, soc_feature_base_valid)) {
   1635         validf = BASE_VALIDf;
   1636     }
   1637 
   1638     for (ix = 0; ix < bucket_size; ix++) {
   1639         mem_table_index = index_array[bank] + ix;
   1640 
   1641         if (soc_mem_read(unit, L2Xm, MEM_BLOCK_ANY,
   1642                              mem_table_index, &chip_entry) < 0) {
   1643             test_error(unit,
   1644                        "Read ARL failed at band %d, index %d, offset %d\n",
   1645                        bank, index_array[bank], ix);
   1646             break;
   1647         }
   1648 
   1649         if (!soc_L2Xm_field32_get(unit, &chip_entry, validf)) {
   1650             /* Valid bit unset, entry blank */
   1651             continue;
   1652         }
   1653 
   1654         if (soc_mem_compare_key(unit, L2Xm, expect, &chip_entry) == 0) {
   1655             /* Found the matching entry */
   1656             rv = 0;
   1657             break;
   1658         }
   1659     }
   1660 
   1661     return rv;
   1662 }
   1663 /*
   1664  * Test of L2X hashing
   1665  *
   1666  *   This test tries a number of keys against one of the hashing functions,
   1667  *   checking a software hash against the hardware hash, then searching the
   1668  *   bucket to find the entry after inserting.
   1669  */
   1670 int
   1671 td2_l2_test_hash(int unit, args_t *a, void *p)
   1672 {
   1673     draco_l2_testdata_t         *ad = p;
   1674     l2x_entry_t         entry;
   1675     int r, rv = 0;
   1676     int ix;
   1677     uint8 key[XGS_HASH_KEY_SIZE];
   1678     int iterations;
   1679     int num_l2_banks                  = 0;
   1680     int bank                          = 0;
   1681     int found;
   1682     int l2_index_array[L2_MAX_BANKS]  = {0};
   1683     int l2_bucket_array[L2_MAX_BANKS] = {0};
   1684     bcm_l2_addr_t addr;
   1685     int vid_inc = ad->opt_vid_inc;
   1686     int mac_inc = ad->opt_mac_inc;
   1687 
   1688     COMPILER_REFERENCE(a);
   1689 
   1690 #ifdef BCM_TRIDENT3_SUPPORT
   1691     if (soc_mem_is_valid(unit, L2_ENTRY_KEY_ATTRIBUTESm)) {
   1692         l2_entry_key_attributes_entry_t  l2_key_attr;
   1693 
   1694         /* Set L2 Entry Key Attributes */
   1695         sal_memset(&l2_key_attr, 0, sizeof(l2_key_attr));
   1696         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1697                             BUCKET_MODEf, 0);
   1698         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1699                             KEY_BASE_WIDTHf, 0);
   1700         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1701                             KEY_WIDTHf, 16);
   1702         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1703                             DATA_BASE_WIDTHf, 0);
   1704         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1705                             HASH_LSB_OFFSETf, 19);
   1706         if (soc_mem_write(unit, L2_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   1707                           TD3_L2_HASH_KEY_TYPE_BRIDGE,
   1708                           (uint32*)&l2_key_attr) < 0) {
   1709                 test_error(unit, "L2 Entry Key Attr setting failed\n");
   1710                 goto done;
   1711         }
   1712     }
   1713 #endif
   1714 
   1715     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
   1716 
   1717     if (ad->opt_verbose) {
   1718         cli_out("Starting ARL hash test\n");
   1719     }
   1720 
   1721     iterations = ad->opt_count;
   1722 
   1723     for (ix = 0; ix < iterations; ix++) {
   1724         _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE);
   1725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   1726     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   1727         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   1728             (SOC_IS_TRIDENT3X(unit))) {
   1729             if ((rv = soc_td2x_th_l2x_hash(unit, (uint32 *)&entry,
   1730                                            &num_l2_banks, l2_bucket_array,
   1731                                            l2_index_array, key)) < 0) {
   1732                 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   1733                 goto done;
   1734             }
   1735 
   1736             if (num_l2_banks > L2_MAX_BANKS) {
   1737                 cli_out("%s ERROR: the number of banks overflow\n",
   1738                         ARG_CMD(a));
   1739                 rv = -1;
   1740                 goto done;
   1741             }
   1742         } else
   1743 #endif
   1744         {
   1745             rv = -1;
   1746             goto done;
   1747         }
   1748 
   1749         if (ad->opt_verbose) {
   1750             cli_out("Inserting ");
   1751             soc_mem_entry_dump(unit, L2Xm, &entry, BSL_LSS_CLI);
   1752             cli_out("\n");
   1753             for (bank = 0; bank < num_l2_banks; bank++) {
   1754                 cli_out("bank%d bucket 0x%06x (%06d) index 0x%06x (%06d)\n",
   1755                          bank, l2_bucket_array[bank], l2_bucket_array[bank],
   1756                          l2_index_array[bank], l2_index_array[bank]);
   1757             }
   1758         }
   1759 
   1760         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
   1761             if (r == SOC_E_FULL) {
   1762                 /* Bucket overflow, just pass on */
   1763                 goto incr;
   1764             } else {
   1765                 test_error(unit,
   1766                            "ARL insert failed\n");
   1767                 rv = -1;
   1768                 goto done;
   1769             }
   1770         }
   1771 
   1772         /* Now we search for the entry */
   1773 
   1774         found = FALSE;
   1775         for (bank = 0; bank < num_l2_banks; bank++) {
   1776             /* Only do a quick check vs. expected bucket here */
   1777             if (td2_l2_bucket_search(unit, ad, bank, 
   1778                                      l2_index_array, &entry) == 0) {
   1779                 found = TRUE;
   1780                 break;
   1781             }
   1782         }
   1783         if (!found) {
   1784             test_error(unit,
   1785                        "ARL entry with key "
   1786                        "0x%02x%02x%02x%02x%02x%02x%02x%01x "
   1787                        "not found in predicted buckets\n",
   1788                        key[7], key[6], key[5], key[4],
   1789                        key[3], key[2], key[1], (key[0] >> 4) & 0xf);
   1790         }
   1791         if (bcm_l2_addr_delete(unit, addr.mac, addr.vid) < 0) {
   1792             test_error(unit, "ARL delete failed!\n");
   1793             rv = -1;
   1794             goto done;
   1795         }
   1796 
   1797     incr:
   1798         addr.vid += vid_inc;
   1799         if (addr.vid > FB_L2_VID_MAX) {
   1800             addr.vid = 1;
   1801         }
   1802         increment_macaddr(addr.mac, mac_inc);
   1803     }
   1804 
   1805  done:
   1806     return rv;
   1807 }
   1808 
   1809 /*
   1810  * Test of ARL overflow behavior
   1811  *
   1812  *   This test fills each bucket of the ARL, then inserts another entry to see
   1813  *   that the last entry fails to insert.
   1814  */
   1815 
   1816 int
   1817 td2_l2_test_ov(int unit, args_t *a, void *p)
   1818 {
   1819     draco_l2_testdata_t         *ad = p;
   1820     l2x_entry_t         entry, result, *entry_array = NULL;
   1821     int                 ix, jx, r, idx, rv = 0, alloc_sz;
   1822     int bucket_size = SOC_TD2_L2X_BUCKET_SIZE;
   1823     int bank;
   1824     int found;
   1825     uint32 bank_count;
   1826     uint32 hash = ad->opt_hash;
   1827     bcm_l2_addr_t addr, addr_tmp;
   1828     int vid_inc = ad->opt_vid_inc;
   1829     int iter = ad->opt_count;
   1830     uint8 key[XGS_HASH_KEY_SIZE];
   1831     int num_l2_banks                  = 0;
   1832     int l2_index_array[L2_MAX_BANKS]  = {0};
   1833     int l2_bucket_array[L2_MAX_BANKS] = {0};
   1834 
   1835     COMPILER_REFERENCE(a);
   1836 
   1837     bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid);
   1838 
   1839     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL2,
   1840                                            &bank_count)) < 0) {
   1841         test_error(unit, "Getting bank count for L2 table failed\n");
   1842         rv = -1;
   1843         goto done;
   1844     }
   1845     alloc_sz = sizeof(l2x_entry_t) * bucket_size * bank_count;
   1846     entry_array = sal_alloc(alloc_sz, "l2_entry_array");
   1847     if (entry_array == NULL) {
   1848         rv = -1;
   1849         goto done;
   1850     }
   1851     for (bank = 0; bank < bank_count; bank++) {
   1852         if (ad->opt_verbose) {
   1853             cli_out("Resetting hash bank %d selection to LSB\n", bank);
   1854         }
   1855         if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL2, bank,
   1856                                                   BCM_HASH_LSB, 48)) < 0) {
   1857             test_error(unit, "Hash bank setting failed\n");
   1858             rv = -1;
   1859             goto done;
   1860         }
   1861     }
   1862 
   1863     if (hash != FB_HASH_LSB) {
   1864         ad->opt_hash = hash = FB_HASH_LSB;
   1865     }
   1866 
   1867     if (iter > soc_mem_index_count(unit, L2Xm)) {
   1868         iter = soc_mem_index_count(unit, L2Xm);
   1869     }
   1870 #ifdef BCM_TRIDENT3_SUPPORT
   1871     if (soc_mem_is_valid(unit, L2_ENTRY_KEY_ATTRIBUTESm)) {
   1872         l2_entry_key_attributes_entry_t  l2_key_attr;
   1873 
   1874         /* Set L2 Entry Key Attributes */
   1875         sal_memset(&l2_key_attr, 0, sizeof(l2_key_attr));
   1876         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1877                             BUCKET_MODEf, 0);
   1878         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1879                             KEY_BASE_WIDTHf, 0);
   1880         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1881                             KEY_WIDTHf, 16);
   1882         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1883                             DATA_BASE_WIDTHf, 0);
   1884         soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr,
   1885                             HASH_LSB_OFFSETf, 19);
   1886         if (soc_mem_write(unit, L2_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   1887                           TD3_L2_HASH_KEY_TYPE_BRIDGE,
   1888                           (uint32*)&l2_key_attr) < 0) {
   1889                 test_error(unit, "L2 Entry Key Attr setting failed\n");
   1890                 goto done;
   1891         }
   1892     }
   1893 #endif
   1894 
   1895     while (iter--) {
   1896         sal_memset(entry_array, 0, alloc_sz);
   1897         for (ix = 0; ix < bucket_size * bank_count; ix++) {
   1898             _bcm_tr_l2_to_l2x(unit, &(entry_array[ix]), &addr, TRUE);
   1899 
   1900             if (ix == 0) {
   1901 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   1902     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   1903                 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   1904                     (SOC_IS_TRIDENT3X(unit))) {
   1905                     if ((rv = soc_td2x_th_l2x_hash(unit, (uint32 *)&(entry_array[ix]),
   1906                                                    &num_l2_banks, l2_bucket_array,
   1907                                                    l2_index_array, key)) < 0) {
   1908                         cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   1909                         goto done;
   1910                     }
   1911 
   1912                     if (num_l2_banks > L2_MAX_BANKS) {
   1913                         cli_out("%s ERROR: the number of banks overflow\n",
   1914                                 ARG_CMD(a));
   1915                         rv = -1;
   1916                         goto done;
   1917                     }
   1918                 } else
   1919 #endif
   1920                 {
   1921                     rv = -1;
   1922                     goto done;
   1923                 }
   1924 
   1925                 if (ad->opt_verbose) {
   1926                     for (bank = 0; bank < bank_count; bank++) {
   1927                         cli_out("bank%d bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   1928                                  bank, l2_bucket_array[bank], l2_bucket_array[bank],
   1929                                  l2_index_array[bank], l2_index_array[bank]);
   1930                     }
   1931                 }
   1932             }
   1933 
   1934             if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
   1935                 if (r == SOC_E_FULL) {
   1936                     /* Already full, stop wasting time */
   1937                     break;
   1938                 } else {
   1939                     test_error(unit,
   1940                                "ARL ix %d insert failed!\n", ix);
   1941                     rv = -1;
   1942                     goto done;
   1943                 }
   1944             }
   1945 
   1946             /* key for LSB is the MAC address, so we must keep it constant */
   1947             addr.vid += vid_inc;
   1948             if (addr.vid > DRACO_L2_VID_MAX) {
   1949                 addr.vid = 1;
   1950             }
   1951         }
   1952 
   1953         if (ad->opt_verbose) {
   1954             cli_out("Inserting %dth entry in banks should fail\n",
   1955                     (bucket_size * bank_count + 1));
   1956         }
   1957 
   1958         _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE);
   1959 
   1960         if ((r = bcm_l2_addr_add(unit, &addr)) < 0) {
   1961             if (r != SOC_E_FULL) {
   1962                 test_error(unit,
   1963                            "ARL insert failed\n");
   1964                 rv = -1;
   1965                 goto done;
   1966             }
   1967         } else {
   1968             test_error(unit, "ARL insert to full bucket succeeded\n");
   1969             rv = -1;
   1970             goto done;
   1971         }
   1972 
   1973         if (ad->opt_verbose) {
   1974             cli_out("Verifying entries present\n");
   1975         }
   1976 
   1977         /* Verify bucket contains our added entries */
   1978         for (jx = 0; jx < bucket_size * bank_count; jx++) {
   1979             found = 0;
   1980             for (bank = 0; bank < bank_count; bank++) {
   1981                 if (td2_l2_bucket_search(unit, ad, bank, l2_index_array,
   1982                                          &(entry_array[jx])) == 0) {
   1983                     found = 1;
   1984                     break;
   1985                 }
   1986             }
   1987             if (!found) {
   1988                 test_error(unit, 
   1989                            "ARL entry jx %d missing on all banks\n", jx);
   1990                 rv = -1;
   1991                 goto done;
   1992             }
   1993             if (soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &idx, 
   1994                                &entry_array[jx], &result, 0) < 0) {
   1995                 test_error(unit,
   1996                            "ARL entry missing at bucket %d index %d on bank %d\n",
   1997                            l2_bucket_array[bank], l2_index_array[bank], bank);
   1998                 rv = -1;
   1999                 goto done;
   2000             }
   2001             if (idx <  (l2_index_array[bank]) || 
   2002                 idx >= (l2_index_array[bank] + bucket_size)) {
   2003                 test_error(unit, "ARL entry inserted into wrong index"
   2004                            " Expected [%d-%d] Actual %d\n", 
   2005                            l2_index_array[bank],
   2006                            l2_index_array[bank] + bucket_size,
   2007                            idx);
   2008                 rv = -1;
   2009                 goto done;
   2010             }
   2011         }
   2012 
   2013         if (ad->opt_verbose) {
   2014             cli_out("Cleaning each entry on all banks...\n");
   2015         }
   2016         /* Remove the entries that we added */
   2017         for (jx = 0; jx < bucket_size * bank_count; jx++) {
   2018             _bcm_tr_l2_from_l2x(unit, &addr_tmp, &(entry_array[jx]));
   2019             if (bcm_l2_addr_delete(unit, addr_tmp.mac, addr_tmp.vid) < 0) {
   2020                 test_error(unit, 
   2021                            "ARL delete jx %d failed on all bank\n", jx);
   2022                 rv = -1;
   2023                 goto done;
   2024             }
   2025         }
   2026 
   2027         /* We want the increment to change buckets by one */
   2028         increment_macaddr(addr.mac, 1);
   2029     }
   2030 
   2031  done:
   2032     if (entry_array) {
   2033         sal_free(entry_array);
   2034         entry_array = NULL;
   2035     }
   2036     return rv;
   2037 }
   2038 
   2039 #endif /* BCM_TRIDENT2_SUPPORT */
   2040 
   2041 /*
   2042  * Test of ARL hashing
   2043  *
   2044  *   This test tries a number of keys against one of the hashing functions,
   2045  *   checking a software hash against the hardware hash, then searching the
   2046  *   bucket to find the entry after inserting.
   2047  */
   2048 int
   2049 draco_l2_test_hash(int unit, args_t *a, void *p)
   2050 {
   2051     int rv = 0;
   2052 
   2053     COMPILER_REFERENCE(a);
   2054 
   2055 #if defined(BCM_TRIDENT2_SUPPORT)
   2056     if (SOC_IS_TD2_TT2(unit)) {
   2057         return td2_l2_test_hash(unit, a, p);
   2058     }
   2059 #endif /* BCM_TRIDENT2_SUPPORT */
   2060 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2061     if (SOC_IS_FBX(unit)) {
   2062         return fb_l2_test_hash(unit, a, p);
   2063     }
   2064 #endif /* BCM_FIREBOLT_SUPPORT || BCM_BRADLEY_SUPPORT */
   2065 
   2066     return rv;
   2067 }
   2068 
   2069 
   2070 /*
   2071  * Test of ARL overflow behavior
   2072  *
   2073  *   This test fills each bucket of the ARL, then inserts another entry to see
   2074  *   that the last entry fails to insert.
   2075  */
   2076 
   2077 int
   2078 draco_l2_test_ov(int unit, args_t *a, void *p)
   2079 {
   2080     int rv = 0;
   2081 
   2082     COMPILER_REFERENCE(a);
   2083 
   2084 #if defined(BCM_TRIDENT2_SUPPORT)
   2085     if (SOC_IS_TD2_TT2(unit)) {
   2086         return td2_l2_test_ov(unit, a, p);
   2087     }
   2088 #endif /* BCM_TRIDENT2_SUPPORT */
   2089 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2090     if (SOC_IS_FBX(unit)) {
   2091         return fb_l2_test_ov(unit, a, p);
   2092     }
   2093 #endif /* BCM_FIREBOLT_SUPPORT || BCM_BRADLEY_SUPPORT */
   2094 
   2095     return rv;
   2096 }
   2097 
   2098 /*
   2099  * Test of ARL lookup
   2100  *
   2101  *   This test loops a given number of times.  It inserts a single ARL
   2102  *   entry, looks up the ARL entry, and deletes the ARL entry.
   2103  *   It is possible to run this test while heavy switching is going on.
   2104  */
   2105 
   2106 int
   2107 draco_l2_test_lu(int unit, args_t *a, void *p)
   2108 {
   2109     int         rv = -1;
   2110 
   2111     COMPILER_REFERENCE(a);
   2112 
   2113 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2114     if (SOC_IS_FBX(unit)) {
   2115         return fb_l2_test_lu(unit, a, p);
   2116     }
   2117 #endif /* BCM_FIREBOLT_SUPPORT */
   2118     if (! soc_feature(unit, soc_feature_arl_lookup_cmd)) {
   2119         test_error(unit, "ARL lookup not supported by chip (unit %d)\n", unit);
   2120         return -1;
   2121     }
   2122 
   2123     return rv;
   2124 }
   2125 
   2126 /*
   2127  * Test of ARL delete by port
   2128  *
   2129  * This test will insert a collection of entries with different ports,
   2130  * then try to delete them by port reference.
   2131  */
   2132 
   2133 int
   2134 draco_l2_test_dp(int unit, args_t *a, void *p)
   2135 {
   2136     int rv = 0;
   2137 
   2138     COMPILER_REFERENCE(a);
   2139 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2140     if (SOC_IS_FBX(unit)) {
   2141         return fb_l2_test_dp(unit, a, p);
   2142     }
   2143 #endif /* BCM_FIREBOLT_SUPPORT */
   2144 
   2145     return rv;
   2146 }
   2147 
   2148 /*
   2149  * Test of ARL delete by VLAN
   2150  *
   2151  * This test will insert a collection of entries with different VLAN ids,
   2152  * then try to delete them by VLAN.
   2153  */
   2154 
   2155 int
   2156 draco_l2_test_dv(int unit, args_t *a, void *p)
   2157 {
   2158     int rv = 0;
   2159 
   2160     COMPILER_REFERENCE(a);
   2161 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2162     if (SOC_IS_FBX(unit)) {
   2163         return fb_l2_test_dv(unit, a, p);
   2164     }
   2165 #endif /* BCM_FIREBOLT_SUPPORT */
   2166 
   2167     return rv;
   2168 }
   2169 
   2170 /*
   2171  * Test clean-up routine used for all ARL tests
   2172  */
   2173 
   2174 int
   2175 draco_l2_test_done(int unit, void *p)
   2176 {
   2177     draco_l2_testdata_t *ad = p;
   2178 
   2179     if (ad == NULL) {
   2180 	return 0;
   2181     }
   2182 
   2183 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2184     if (SOC_IS_FBX(unit)) {
   2185         return fb_l2_test_done(unit, p);
   2186     }
   2187 #endif /* BCM_FIREBOLT_SUPPORT */
   2188 
   2189     return 0;
   2190 }
   2191 
   2192 #ifdef INCLUDE_L3
   2193 #ifdef BCM_FIREBOLT_SUPPORT
   2194 STATIC void
   2195 fbl3_setup(int unit, draco_l3_test_t *dw)
   2196 {
   2197     draco_l3_testdata_t *ad;
   2198     int mem = L3_ENTRY_IPV6_MULTICASTm;
   2199 
   2200 #ifdef BCM_TRIDENT3_SUPPORT
   2201     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   2202         mem = L3_ENTRY_QUADm;
   2203     }
   2204 #endif
   2205     /* Hash */
   2206     ad = &dw->dlp_l3_hash;
   2207 
   2208     ad->opt_count      = soc_mem_index_count(unit, mem);
   2209     ad->opt_hash       = FB_HASH_CRC16_LOWER;
   2210     ad->opt_dual_hash  = -1;
   2211     ad->hash_count     = FB_HASH_COUNT;
   2212     sal_memset (ad->opt_src_ip6, 0, sizeof(ad->opt_src_ip6));
   2213     sal_memset (ad->opt_base_ip6, 0, sizeof(ad->opt_base_ip6));
   2214     ad->opt_base_ip6[15] = 1;
   2215     ad->opt_src_ip6[15] = 1;
   2216     ad->opt_ip6_inc =  1;
   2217     ad->opt_src_ip6_inc =  1;
   2218     ad->opt_base_vrf_id = 0;
   2219     ad->opt_vrf_id_inc = 1;
   2220 
   2221     /* Overflow */
   2222     ad = &dw->dlp_l3_ov;
   2223 
   2224     ad->opt_count      = soc_mem_index_count(unit, mem);
   2225     ad->opt_hash       = FB_L3_DEFAULT_HASH;
   2226     ad->opt_dual_hash  = -1;
   2227     ad->hash_count     = FB_HASH_COUNT;
   2228     sal_memset (ad->opt_src_ip6, 0, sizeof(ad->opt_src_ip6));
   2229     sal_memset (ad->opt_base_ip6, 0, sizeof(ad->opt_base_ip6));
   2230     ad->opt_base_ip6[15] = 1;
   2231     ad->opt_src_ip6[15] = 1;
   2232     ad->opt_ip6_inc =  1;
   2233     ad->opt_src_ip6_inc =  1;
   2234     ad->opt_base_vrf_id = 0;
   2235     ad->opt_vrf_id_inc = 1;
   2236 }
   2237 
   2238 #endif /* BCM_FIREBOLT_SUPPORT */
   2239 
   2240 STATIC void
   2241 dl3_setup(int unit, draco_l3_test_t *dw)
   2242 {
   2243     draco_l3_testdata_t *ad;
   2244     soc_mem_t           l3xm = INVALIDm;
   2245     soc_mem_t           l3x_validm = INVALIDm;
   2246     int mem = L3_ENTRY_IPV6_MULTICASTm;
   2247 
   2248 #ifdef BCM_TRIDENT3_SUPPORT
   2249     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   2250         mem = L3_ENTRY_QUADm;
   2251     }
   2252 #endif
   2253 
   2254     if (dw->dlw_set_up) {
   2255         return;
   2256     }
   2257 #ifdef BCM_FIREBOLT_SUPPORT
   2258     /* Firebolt adjustments */
   2259     if (SOC_IS_FBX(unit)) {
   2260         l3xm = mem;
   2261         l3x_validm = mem;
   2262     }
   2263 #endif /* BCM_FIREBOLT_SUPPORT */
   2264 
   2265     dw->dlw_set_up = TRUE;
   2266     dw->dlw_unit = unit;
   2267 
   2268     /* Hash */
   2269     ad = &dw->dlp_l3_hash;
   2270 
   2271     ad->unit           = unit;
   2272     ad->opt_count      = SOC_MEM_IS_VALID(unit, l3xm) ?
   2273         soc_mem_index_count(unit, l3xm) : 0;
   2274     ad->opt_verbose    = FALSE;
   2275     ad->opt_reset      = TRUE;
   2276     ad->opt_hash       = XGS_HASH_CRC16_LOWER;
   2277     ad->opt_ipmc_enable = TRUE;
   2278     ad->opt_key_src_ip = 1;
   2279     ad->opt_base_ip    = 0;
   2280     ad->opt_ip_inc     = 1;
   2281     ad->opt_src_ip     = 0;
   2282     ad->opt_src_ip_inc = 1;
   2283     ad->opt_base_vid   = 0;
   2284     ad->opt_vid_inc    = 1;
   2285     ad->opt_mac_inc    = 1;
   2286     ad->ipv6           = 0;
   2287     ad->hash_count     = XGS_HASH_COUNT;
   2288     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
   2289 
   2290     /* Overflow */
   2291     ad = &dw->dlp_l3_ov;
   2292 
   2293     ad->unit           = unit;
   2294     ad->opt_count      = SOC_MEM_IS_VALID(unit, l3x_validm) ?
   2295         soc_mem_index_count(unit, l3x_validm) : 0;
   2296     ad->opt_verbose    = FALSE;
   2297     ad->opt_reset      = TRUE;
   2298     ad->opt_hash       = DRACO_ARL_DEFAULT_HASH;
   2299     ad->opt_ipmc_enable = TRUE;
   2300     ad->opt_key_src_ip = 1;
   2301     ad->opt_base_ip    = 0;
   2302     ad->opt_ip_inc     = 1;
   2303     ad->opt_src_ip     = 0;
   2304     ad->opt_src_ip_inc = 1;
   2305     ad->opt_base_vid   = 0;
   2306     ad->opt_vid_inc    = 1;
   2307     ad->opt_mac_inc    = 1;
   2308     ad->ipv6           = 0;
   2309     ad->hash_count     = XGS_HASH_COUNT;
   2310     ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src);
   2311 
   2312 #ifdef BCM_FIREBOLT_SUPPORT
   2313     /* Firebolt adjustments */
   2314     if (SOC_IS_FBX(unit)) {
   2315         fbl3_setup(unit, dw);
   2316     }
   2317 #endif /* BCM_FIREBOLT_SUPPORT */
   2318 }
   2319 
   2320 STATIC int
   2321 _xgs_l3_hash_save(int unit, draco_l3_testdata_t *ad)
   2322 {
   2323     SOC_IF_ERROR_RETURN(_soc_mem_cmp_l3x_sync(unit));
   2324     ad->save_ipmc_config = SOC_CONTROL(unit)->hash_key_config;
   2325     return SOC_E_NONE;
   2326 }
   2327 
   2328 STATIC int
   2329 _xgs_l3_hash_set(int unit, draco_l3_testdata_t *ad)
   2330 {
   2331     ad->set_ipmc_config = ad->save_ipmc_config;
   2332     if (ad->opt_ipmc_enable) {
   2333         ad->set_ipmc_config |= L3X_IPMC_ENABLE;
   2334     } else {
   2335         ad->set_ipmc_config &= ~L3X_IPMC_ENABLE;
   2336     }
   2337     /* Turn off PIM_DM_SM mode */
   2338     ad->set_ipmc_config &= ~L3X_IPMC_SIP;
   2339     if (ad->opt_key_src_ip) {
   2340         ad->set_ipmc_config &= ~L3X_IPMC_SIP0;
   2341     } else {
   2342         ad->set_ipmc_config |= L3X_IPMC_SIP0;
   2343     }
   2344     
   2345 
   2346     if (ad->set_ipmc_config != ad->save_ipmc_config) {
   2347         SOC_IF_ERROR_RETURN(_soc_mem_cmp_l3x_set(unit, ad->set_ipmc_config));
   2348     }
   2349     return SOC_E_NONE;
   2350 }
   2351 
   2352 /*
   2353  * Test initialization routine used for all L3 tests
   2354  */
   2355 
   2356 STATIC int
   2357 draco_l3_test_init(int unit, draco_l3_testdata_t *ad, args_t *a)
   2358 {
   2359     int                 rv = -1, dual = 0;
   2360     parse_table_t       pt;
   2361     uint32              hash_read = 0;
   2362     uint32              dual_hash_read = 0;
   2363     uint32              l3_table_hash_control = 0;
   2364     uint32              shared_table_hash_control = 0;
   2365 #ifdef BCM_TRIDENT3_SUPPORT
   2366     l3_entry_hash_control_entry_t    l3_entry_hash_control;
   2367     uft_shared_banks_control_entry_t shared_entry_hash_control;
   2368 
   2369     sal_memset(&l3_entry_hash_control, 0, sizeof(l3_entry_hash_control));
   2370     sal_memset(&shared_entry_hash_control, 0, sizeof(shared_entry_hash_control));
   2371 #endif
   2372 
   2373     parse_table_init(unit, &pt);
   2374 
   2375     parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL);
   2376     parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL);
   2377     parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL);
   2378     parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL);
   2379     if (soc_feature(unit, soc_feature_dual_hash)) {
   2380         parse_table_add(&pt, "DualHash", PQ_INT|PQ_DFL, 0, &ad->opt_dual_hash, NULL);
   2381         parse_table_add(&pt, "DualEnable", PQ_INT|PQ_DFL, 0, &dual, NULL);
   2382     }
   2383     parse_table_add(&pt, "IPMCEnable", PQ_BOOL|PQ_DFL, 0,
   2384                     &ad->opt_ipmc_enable, NULL);
   2385     parse_table_add(&pt, "SrcIPKey", PQ_BOOL|PQ_DFL, 0,
   2386                     &ad->opt_key_src_ip, NULL);
   2387     if (ad->ipv6) {
   2388         parse_table_add(&pt, "BaseIP", PQ_IP6|PQ_DFL, 0, &ad->opt_base_ip6, NULL);
   2389         parse_table_add(&pt, "BIPIncrement", PQ_INT|PQ_DFL, 0,
   2390                         &ad->opt_ip6_inc, NULL);
   2391         parse_table_add(&pt, "SourceIP", PQ_IP6|PQ_DFL, 0,
   2392                         &ad->opt_src_ip6, NULL);
   2393         parse_table_add(&pt, "SrcIPIncrement", PQ_INT|PQ_DFL, 0,
   2394                         &ad->opt_src_ip6_inc, NULL);
   2395     } else {
   2396         parse_table_add(&pt, "BaseIP", PQ_IP|PQ_DFL, 0, &ad->opt_base_ip, NULL);
   2397         parse_table_add(&pt, "BIPIncrement", PQ_INT|PQ_DFL, 0,
   2398                         &ad->opt_ip_inc, NULL);
   2399         parse_table_add(&pt, "SourceIP", PQ_IP|PQ_DFL, 0, &ad->opt_src_ip, NULL);
   2400         parse_table_add(&pt, "SrcIPIncrement", PQ_INT|PQ_DFL, 0,
   2401                         &ad->opt_src_ip_inc, NULL);
   2402     }
   2403     parse_table_add(&pt, "BaseVID", PQ_HEX|PQ_DFL, 0, &ad->opt_base_vid, NULL);
   2404     parse_table_add(&pt, "VIDIncrement", PQ_INT|PQ_DFL, 0,
   2405                     &ad->opt_vid_inc, NULL);
   2406     parse_table_add(&pt, "BaseMac", PQ_DFL|PQ_MAC, 0, &ad->opt_base_mac, NULL);
   2407     parse_table_add(&pt, "MacIncrement", PQ_INT|PQ_DFL, 0,
   2408                     &ad->opt_mac_inc, NULL);
   2409 
   2410     parse_table_add(&pt, "BaseVRFID", PQ_INT|PQ_DFL, 0,
   2411                     &ad->opt_base_vrf_id, NULL);
   2412     parse_table_add(&pt, "VRFIDIncrement", PQ_INT|PQ_DFL, 0,
   2413                     &ad->opt_vrf_id_inc, NULL);
   2414 
   2415     /* Test the obvious parsings before wasting time with malloc */
   2416     if (parse_arg_eq(a, &pt) < 0) {
   2417         test_error(unit,
   2418                    "%s: Error: Invalid option: %s\n", ARG_CMD(a),
   2419                    ARG_CUR(a) ? ARG_CUR(a) : "*");
   2420         goto done;
   2421     }
   2422 
   2423     if (ad->opt_count < 1) {
   2424         test_error(unit, "Illegal count %d\n", ad->opt_count);
   2425         goto done;
   2426     }
   2427 
   2428     if (ad->opt_hash >= ad->hash_count) {
   2429         test_error(unit, "Illegal hash selection %d\n", ad->opt_hash);
   2430         goto done;
   2431     }
   2432 
   2433     if (dual == 1) {
   2434         if (ad->opt_dual_hash >= ad->hash_count) {
   2435             test_error(unit, "Illegal dual hash selection %d\n", ad->opt_dual_hash);
   2436             goto done;
   2437         }
   2438     } else {
   2439         ad->opt_dual_hash = -1;
   2440     }
   2441 
   2442     /*
   2443      * Re-initialize chip to ensure ARL and software ARL table are clear
   2444      * at start of test.
   2445      */
   2446 
   2447     if (ad->opt_reset) {
   2448         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
   2449         if (soc_reset_init(unit) < 0) {
   2450             test_error(unit, "SOC initialization failed\n");
   2451             goto done;
   2452         }
   2453 
   2454 #if defined(CANCUN_SUPPORT)
   2455         if (soc_cancun_pre_misc_init_load(unit) < 0) {
   2456             test_error(unit, "CMH/CCH/CEH load failed");
   2457             goto done;
   2458         }
   2459 #endif
   2460 
   2461         if (soc_misc_init(unit) < 0) {
   2462             test_error(unit, "ARL initialization failed\n");
   2463             goto done;
   2464         }
   2465 
   2466 #if defined(CANCUN_SUPPORT)
   2467         if (soc_cancun_post_misc_init_load(unit) < 0) {
   2468             test_error(unit, "CIH/CFH load failed");
   2469             goto done;
   2470         }
   2471 #endif
   2472 
   2473         if (soc_mmu_init(unit) < 0) {
   2474             test_error(unit, "MMU initialization failed\n");
   2475             goto done;
   2476         }
   2477 
   2478         /* Must initialize mbcm for L3 functions below */
   2479         if (bcm_init(unit) < 0) {
   2480             test_error(unit, "BCM layer initialization failed\n");
   2481             goto done;
   2482         }
   2483 
   2484         if (bcm_l3_init(unit) < 0) {
   2485             test_error(unit, "L3 initialization failed\n");
   2486             goto done;
   2487         }
   2488 
   2489         if (SOC_FUNCTIONS(unit)->soc_age_timer_set(unit, 0, 0) < 0) {
   2490             test_error(unit, "Could not disable age timers\n");
   2491             goto done;
   2492         }
   2493     }
   2494 
   2495     if (READ_HASH_CONTROLr(unit, &hash_read) < 0) {
   2496         test_error(unit, "Hash select read failed\n");
   2497         goto done;
   2498     }
   2499     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
   2500 #ifdef BCM_TRIDENT3_SUPPORT
   2501         if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) {
   2502             if (soc_mem_read(unit, L3_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY,
   2503                              0, (void*)&l3_entry_hash_control) < 0) {
   2504                 test_error(unit, "L3 Table hash control read failed\n");
   2505             goto done;
   2506         }
   2507             if (soc_mem_read(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY,
   2508                              0, (void*)&shared_entry_hash_control) < 0) {
   2509                 test_error(unit, "Shared Entry hash control read failed\n");
   2510                 goto done;
   2511             }
   2512         } else
   2513 #endif /* BCM_TRIDENT3_SUPPORT */
   2514         {
   2515             if (READ_L3_TABLE_HASH_CONTROLr(unit, 
   2516                                    &l3_table_hash_control) < 0) {
   2517                 test_error(unit, "L3 Table hash control read failed\n");
   2518                 goto done;
   2519             }
   2520         if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) 
   2521         {   	
   2522             if (READ_SHARED_TABLE_HASH_CONTROLr(unit, 
   2523                                    &shared_table_hash_control) < 0) {
   2524                 test_error(unit, "Shared Table hash control read failed\n");
   2525                 goto done;
   2526             }
   2527         }
   2528       }    
   2529     } else {
   2530         if (soc_feature(unit, soc_feature_dual_hash)) {
   2531             if (READ_L3_AUX_HASH_CONTROLr(unit, &dual_hash_read) < 0) {
   2532                 test_error(unit, "Dual Hash select read failed\n");
   2533                 goto done;
   2534             }
   2535         }
   2536     }
   2537 
   2538 
   2539     ad->save_hash_control = hash_read;
   2540     ad->save_dual_hash_control = dual_hash_read;
   2541     ad->save_l3_table_hash_control = l3_table_hash_control;
   2542     ad->save_shared_table_hash_control = shared_table_hash_control;
   2543 #ifdef BCM_TRIDENT3_SUPPORT
   2544     ad->save_l3_entry_hash_control = l3_entry_hash_control;
   2545     ad->save_shared_entry_hash_control = shared_entry_hash_control;
   2546 #endif /* BCM_TRIDENT3_SUPPORT */
   2547     hash_read = ad->opt_hash;
   2548     dual_hash_read = ad->opt_dual_hash;
   2549 #ifdef BCM_XGS3_SWITCH_SUPPORT
   2550     if (SOC_IS_XGS3_SWITCH(unit)) {
   2551         hash_read = ad->save_hash_control;
   2552         soc_reg_field_set(unit, HASH_CONTROLr, &hash_read,
   2553                           L3_HASH_SELECTf, ad->opt_hash);
   2554         if (soc_feature(unit, soc_feature_shared_hash_mem)) {
   2555 #ifdef BCM_TRIDENT3_SUPPORT
   2556             if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) {
   2557                 rv = td3_entry_hash_control_set(unit, ad->opt_hash,
   2558                         L3_ENTRY_HASH_CONTROLm,
   2559                         (uint32 *)&l3_entry_hash_control);
   2560                 if (rv < 0) {
   2561                     test_error(unit, "Hash Control write failed");
   2562                     goto done;
   2563                 }
   2564             } else
   2565 #endif /* BCM_TRIDENT3_SUPPORT */
   2566             {
   2567                 soc_reg_field_set(unit, L3_TABLE_HASH_CONTROLr, 
   2568                                   &l3_table_hash_control,
   2569                               HASH_ZERO_OR_LSBf, 1);
   2570             }
   2571         } else {
   2572             if (soc_feature(unit, soc_feature_dual_hash)) {
   2573                 dual_hash_read = ad->save_dual_hash_control;
   2574                 if (ad->opt_dual_hash != -1) {
   2575                     soc_reg_field_set(unit, L3_AUX_HASH_CONTROLr, &dual_hash_read,
   2576                                       HASH_SELECTf, ad->opt_dual_hash);
   2577                     soc_reg_field_set(unit, L3_AUX_HASH_CONTROLr, &dual_hash_read,
   2578                                       ENABLEf, 1);
   2579                 } else {
   2580                     soc_reg_field_set(unit, L3_AUX_HASH_CONTROLr, &dual_hash_read,
   2581                                       ENABLEf, 0);
   2582                 }
   2583             }
   2584         }
   2585     }
   2586 #endif /* BCM_XGS3_SWITCH_SUPPORT */
   2587 
   2588     if (WRITE_HASH_CONTROLr(unit, hash_read) < 0) {
   2589         test_error(unit, "Hash select set failed\n");
   2590         goto done;
   2591     }
   2592     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
   2593 #ifdef BCM_TRIDENT3_SUPPORT
   2594         if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) {
   2595             if (soc_mem_write(unit, L3_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY,
   2596                              0, (uint32*)&l3_entry_hash_control) < 0) {
   2597                 test_error(unit, "L3 Entry hash control setting failed\n");
   2598                 goto done;
   2599             }
   2600         } else 
   2601 #endif /* BCM_TRIDENT3_SUPPORT */
   2602         {
   2603         if (WRITE_L3_TABLE_HASH_CONTROLr(unit, l3_table_hash_control) < 0) {
   2604                 test_error(unit, "L3 Table hash control setting failed\n");
   2605             goto done;
   2606         }
   2607         }
   2608     } else {
   2609         if (soc_feature(unit, soc_feature_dual_hash)) {
   2610             if (WRITE_L3_AUX_HASH_CONTROLr(unit, dual_hash_read) < 0) {
   2611                 test_error(unit, "Dual Hash select set failed\n");
   2612                 goto done;
   2613             }
   2614         }
   2615     }
   2616 
   2617     if (!SOC_IS_FBX(unit)) {
   2618         if (_xgs_l3_hash_save(unit, ad) < 0) {
   2619             test_error(unit, "hash state save failed");
   2620             goto done;
   2621         }
   2622         if (_xgs_l3_hash_set(unit, ad) < 0) {
   2623             test_error(unit, "hash state set failed");
   2624             goto done;
   2625         }
   2626 
   2627         if (_soc_mem_cmp_l3x_sync(unit) < 0) {
   2628             test_error(unit, "Unable to sync L3 config\n");
   2629             goto done;
   2630         }
   2631     }
   2632 
   2633     rv = 0;
   2634 
   2635  done:
   2636 
   2637     parse_arg_eq_done(&pt);
   2638     return rv;
   2639 }
   2640 
   2641 /* Individual test init wrappers */
   2642 int
   2643 draco_l3_hash_test_init(int unit, args_t *a, void **p)
   2644 {
   2645     draco_l3_test_t        *dw = &dl3_work[unit];
   2646     draco_l3_testdata_t    *dp = &dw->dlp_l3_hash;
   2647     int                    rv;
   2648 
   2649     dl3_setup(unit, dw);
   2650 
   2651     /* Set working data to hash */
   2652     dw->dlp_l3_cur = dp;
   2653 
   2654     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2655         return rv;
   2656     } else {
   2657         *p = dp;
   2658     }
   2659 
   2660     return 0;
   2661 }
   2662 
   2663 int
   2664 draco_l3_ov_test_init(int unit, args_t *a, void **p)
   2665 {
   2666     draco_l3_test_t        *dw = &dl3_work[unit];
   2667     draco_l3_testdata_t    *dp = &dw->dlp_l3_ov;
   2668     int                    rv;
   2669 
   2670     dl3_setup(unit, dw);
   2671 
   2672     /* Set working data to overflow */
   2673     dw->dlp_l3_cur = dp;
   2674 
   2675     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2676         return rv;
   2677     } else {
   2678         *p = dp;
   2679     }
   2680 
   2681     return 0;
   2682 }
   2683 
   2684 #ifdef BCM_XGS3_SWITCH_SUPPORT
   2685 /* Individual test init wrappers */
   2686 int
   2687 fb_l3_hash_test_init(int unit, args_t *a, void **p)
   2688 {
   2689     draco_l3_test_t        *dw = &dl3_work[unit];
   2690     draco_l3_testdata_t    *dp = &dw->dlp_l3_hash;
   2691     int                    rv;
   2692 
   2693     dl3_setup(unit, dw);
   2694     dp->ipv6 = 0;
   2695 
   2696     /* Set working data to hash */
   2697     dw->dlp_l3_cur = dp;
   2698 
   2699     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2700         return rv;
   2701     } else {
   2702         *p = dp;
   2703     }
   2704 
   2705     return 0;
   2706 }
   2707 
   2708 int
   2709 fb_l3_ov_test_init(int unit, args_t *a, void **p)
   2710 {
   2711     draco_l3_test_t        *dw = &dl3_work[unit];
   2712     draco_l3_testdata_t    *dp = &dw->dlp_l3_ov;
   2713     int                    rv;
   2714 
   2715     dl3_setup(unit, dw);
   2716     dp->ipv6 = 0;
   2717 
   2718     /* Set working data to overflow */
   2719     dw->dlp_l3_cur = dp;
   2720 
   2721     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2722         return rv;
   2723     } else {
   2724         *p = dp;
   2725     }
   2726 
   2727     return 0;
   2728 }
   2729 
   2730 int
   2731 fb_l3ip6_hash_test_init(int unit, args_t *a, void **p)
   2732 {
   2733     draco_l3_test_t        *dw = &dl3_work[unit];
   2734     draco_l3_testdata_t    *dp = &dw->dlp_l3_hash;
   2735     int                    rv;
   2736 
   2737     dl3_setup(unit, dw);
   2738     dp->ipv6 = 1;
   2739 
   2740     /* Set working data to hash */
   2741     dw->dlp_l3_cur = dp;
   2742 
   2743     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2744         return rv;
   2745     } else {
   2746         *p = dp;
   2747     }
   2748 
   2749     return 0;
   2750 }
   2751 
   2752 int
   2753 fb_l3ip6_ov_test_init(int unit, args_t *a, void **p)
   2754 {
   2755     draco_l3_test_t        *dw = &dl3_work[unit];
   2756     draco_l3_testdata_t    *dp = &dw->dlp_l3_ov;
   2757     int                    rv;
   2758 
   2759     dl3_setup(unit, dw);
   2760     dp->ipv6 = 1;
   2761 
   2762     /* Set working data to overflow */
   2763     dw->dlp_l3_cur = dp;
   2764 
   2765     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2766         return rv;
   2767     } else {
   2768         *p = dp;
   2769     }
   2770 
   2771     return 0;
   2772 }
   2773 
   2774 int
   2775 fb_l3_ipv6_hash_test_init(int unit, args_t *a, void **p)
   2776 {
   2777     draco_l3_test_t        *dw = &dl3_work[unit];
   2778     draco_l3_testdata_t    *dp = &dw->dlp_l3_hash;
   2779     int                    rv;
   2780 
   2781     dl3_setup(unit, dw);
   2782     dp->ipv6 = 1;
   2783 
   2784     /* Set working data to hash */
   2785     dw->dlp_l3_cur = dp;
   2786 
   2787     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2788         return rv;
   2789     } else {
   2790         *p = dp;
   2791     }
   2792 
   2793     return 0;
   2794 }
   2795 
   2796 int
   2797 fb_l3_ipv6_ov_test_init(int unit, args_t *a, void **p)
   2798 {
   2799     draco_l3_test_t        *dw = &dl3_work[unit];
   2800     draco_l3_testdata_t    *dp = &dw->dlp_l3_ov;
   2801     int                    rv;
   2802 
   2803     dl3_setup(unit, dw);
   2804     dp->ipv6 = 1;
   2805 
   2806     /* Set working data to overflow */
   2807     dw->dlp_l3_cur = dp;
   2808 
   2809     if ((rv = draco_l3_test_init(unit, dp, a)) < 0) {
   2810         return rv;
   2811     } else {
   2812         *p = dp;
   2813     }
   2814 
   2815     return 0;
   2816 }
   2817 
   2818 #ifdef BCM_FIREBOLT_SUPPORT
   2819 static int
   2820 fb_l3_bucket_search(int unit, draco_l3_testdata_t *ad,
   2821                     int bucket, uint32 *expect, int dual, int bank)
   2822 {
   2823     uint32          entry[SOC_MAX_MEM_WORDS];
   2824     int             i, ix, mem_table_index;
   2825     int             num_vbits;
   2826     int             num_ent_per_bucket, iter_count;
   2827     soc_mem_t       mem;
   2828     int             valid_ix;
   2829     soc_field_t     valid_f[] = {VALIDf, VALID_0f, VALID_1f, VALID_2f, VALID_3f}; 
   2830     int rv = -1; /* Assume failed unless we find it */
   2831 
   2832 #ifdef BCM_TRIUMPH_SUPPORT
   2833     if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   2834         int key_type;
   2835 
   2836         key_type = soc_mem_field32_get(unit, L3_ENTRY_ONLYm, 
   2837                                        expect, KEY_TYPEf);
   2838         switch (key_type) {
   2839             case TR_L3_HASH_KEY_TYPE_V4UC:
   2840                 valid_ix = 0;
   2841                 num_vbits = 1;
   2842                 mem = L3_ENTRY_IPV4_UNICASTm;
   2843                 break;
   2844             case TR_L3_HASH_KEY_TYPE_V4MC:
   2845                 valid_ix = 1;
   2846                 num_vbits = 2;
   2847                 mem = L3_ENTRY_IPV4_MULTICASTm;
   2848                 break;
   2849             case TR_L3_HASH_KEY_TYPE_V6UC:
   2850                 valid_ix = 1;
   2851                 num_vbits = 2;
   2852                 mem = L3_ENTRY_IPV6_UNICASTm;
   2853                 break;
   2854             case TR_L3_HASH_KEY_TYPE_V6MC:
   2855                 valid_ix = 1;
   2856                 num_vbits = 4;
   2857                 mem = L3_ENTRY_IPV6_MULTICASTm;
   2858                 break;
   2859             default: 
   2860                 return -1;
   2861         }
   2862     } else
   2863 #endif /* BCM_TRIUMPH_SUPPORT */
   2864     if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, expect, V6f)) {
   2865         valid_ix = 1;
   2866         if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, expect, IPMCf)) {
   2867             mem = L3_ENTRY_IPV6_MULTICASTm;
   2868             num_vbits = 4;
   2869         } else {
   2870             mem = L3_ENTRY_IPV6_UNICASTm;
   2871             num_vbits = 2;
   2872         }
   2873     } else {
   2874         num_vbits = 1;
   2875         valid_ix = 0;
   2876         if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, expect, IPMCf)) {
   2877             mem = L3_ENTRY_IPV4_MULTICASTm;
   2878         } else {
   2879             mem = L3_ENTRY_IPV4_UNICASTm;
   2880         }
   2881     }
   2882 
   2883     num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits;
   2884     if (dual == TRUE) {
   2885         iter_count = num_ent_per_bucket / 2;
   2886     } else {
   2887         iter_count = num_ent_per_bucket;
   2888     }
   2889 
   2890     for (ix = 0; ix < iter_count; ix++) {
   2891         mem_table_index = (bucket * num_ent_per_bucket) + ix;
   2892         if (bank) {
   2893             mem_table_index += (num_ent_per_bucket / 2);
   2894         }
   2895 
   2896         if (soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   2897                              mem_table_index, entry) < 0) {
   2898             test_error(unit,
   2899                        "Read ARL failed at bucket %d, offset %d\n",
   2900                        bucket, ix);
   2901             break;
   2902         }
   2903 
   2904         for(i = 0; i < num_vbits; i++) {
   2905             if (!soc_mem_field32_get(unit, mem, entry, valid_f[valid_ix + i])) {
   2906                 break;
   2907             }
   2908         }
   2909         if (i != num_vbits) {
   2910             /* Valid bit not set, blank entry */
   2911             continue;
   2912         }
   2913 
   2914         if (soc_mem_compare_key(unit, mem, expect, entry) == 0) {
   2915             /* Found the matching entry */
   2916             rv = 0;
   2917             break;
   2918         }
   2919     }
   2920 
   2921     return rv;
   2922 }
   2923 
   2924 int
   2925 _fb_l3ip4ucast_test_hash(int unit, args_t *a, void *p)
   2926 {
   2927     draco_l3_testdata_t         *ad = p;
   2928     uint32                      entry[SOC_MAX_MEM_WORDS];
   2929     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   2930     soc_mem_t                   mem = L3_ENTRY_IPV4_UNICASTm;
   2931     ip_addr_t                   dst_ip;
   2932     ip_addr_t                   dst_ip_inc;
   2933     bcm_vlan_t                  vid;
   2934     int                         vid_inc;
   2935     int                         r, rv = 0;
   2936     int                         soft_bucket;
   2937     int                         hard_index;
   2938     int                         hard_bucket;
   2939     int                         ix;
   2940     int                         iterations;
   2941     int                         vrf_id;
   2942     int                         vrf_id_inc;
   2943     int                         vrf_id_max = 0;
   2944     int                         dual = FALSE;
   2945     int                         bank, banks, bank_count = 1;
   2946 
   2947     COMPILER_REFERENCE(a);
   2948     vrf_id_max = SOC_VRF_MAX(unit);
   2949 
   2950     dst_ip = ad->opt_base_ip; 
   2951     dst_ip_inc = ad->opt_ip_inc; 
   2952     vid = ad->opt_base_vid;
   2953     vid_inc = ad->opt_vid_inc;
   2954     
   2955     vrf_id = ad->opt_base_vrf_id;
   2956     vrf_id_inc = ad->opt_vrf_id_inc;
   2957 
   2958     if (ad->opt_verbose) {
   2959         cli_out("Starting L3 hash test\n");
   2960     }
   2961 
   2962     iterations = ad->opt_count;
   2963     if (soc_feature(unit, soc_feature_dual_hash)) {
   2964         if (ad->opt_dual_hash != -1) {
   2965             dual = TRUE;
   2966             bank_count = 2;
   2967         }
   2968     }
   2969 
   2970     sal_memset (entry, 0, sizeof(entry));
   2971 #ifdef BCM_TRIUMPH_SUPPORT 
   2972     if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   2973         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 
   2974                             TR_L3_HASH_KEY_TYPE_V4UC);
   2975     } else
   2976 #endif /* BCM_TRIUMPH_SUPPORT */
   2977     {
   2978         soc_mem_field32_set(unit, mem, entry, V6f, 0);
   2979         soc_mem_field32_set(unit, mem, entry, IPMCf, 0);
   2980     }
   2981     soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   2982     if (vrf_id_max) {
   2983         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   2984     }
   2985 
   2986     for (ix = 0; ix < iterations; ix++) {
   2987         for (bank = 0; bank < bank_count; bank++) {
   2988             soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip);
   2989             if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) {
   2990                 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   2991             }
   2992             if (vrf_id_max) {
   2993                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   2994             } 
   2995             soft_bucket = soc_fb_l3x2_entry_hash(unit, entry);
   2996             banks = 0x3;
   2997 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   2998             defined(BCM_TRX_SUPPORT)
   2999             if (dual == TRUE) {
   3000                 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry);
   3001                 banks = (bank == 0) ? 2 : 1;
   3002             }
   3003 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3004     
   3005             if (ad->opt_verbose) {
   3006                 cli_out("Inserting ");
   3007                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   3008                 cli_out("\n");
   3009                 if (dual) {
   3010                     cli_out("into bucket 0x%x (bank %d)\n",
   3011                             soft_bucket, bank);
   3012                 } else {
   3013                    cli_out("into bucket 0x%x\n", soft_bucket);
   3014                 }
   3015             }
   3016 
   3017 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3018             defined(BCM_TRX_SUPPORT)
   3019             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   3020 #else  /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3021             r = soc_mem_insert(unit, mem, COPYNO_ALL, entry);
   3022 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3023             if (SOC_FAILURE(r)) {
   3024                 if (r == SOC_E_FULL) {
   3025                     /* Bucket overflow, just pass on */
   3026                     continue;
   3027                 } else {
   3028                     test_error(unit, "L3 insert failed at bucket %d\n", soft_bucket);
   3029                     rv = -1;
   3030                     goto done;
   3031                 }
   3032             }
   3033 
   3034             /* Now we search for the entry */
   3035             hard_index = 0;
   3036             if (soc_mem_search(unit, mem, COPYNO_ALL,
   3037                                &hard_index, entry, entry_lkup, 0) < 0) {
   3038                 test_error(unit, "Entry lookup failed\n");
   3039                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3040                 goto done;
   3041             }
   3042     
   3043             hard_bucket = (hard_index >> (SOC_L3X_BUCKET_SIZE(unit) == 16 ? 4 : 3));
   3044 			    /* entries per bucket */
   3045             if (soft_bucket != hard_bucket) {
   3046                 test_error(unit,
   3047                            "Software Hash %d disagrees with  Hardware Hash %d\n",
   3048                            soft_bucket, hard_bucket);
   3049                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3050                 goto done;
   3051             }
   3052     
   3053             /* Only do a quick check vs. expected bucket here */
   3054             if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) {
   3055                 test_error(unit, "Entry not found in bucket %d\n", soft_bucket);
   3056                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3057                 rv = -1;
   3058                 goto done;
   3059             }
   3060     
   3061             /* Clean up afterward */
   3062             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   3063                 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket);
   3064                 rv = -1;
   3065                 goto done;
   3066             }
   3067     
   3068         }
   3069         dst_ip += dst_ip_inc;
   3070         vid += vid_inc;
   3071         if (vid > DRACO_L3_VID_MAX) {
   3072             vid = 1;
   3073         }
   3074         if (vrf_id_max) {
   3075             vrf_id += vrf_id_inc;
   3076             if (vrf_id > vrf_id_max) {
   3077                 vrf_id = 0;
   3078             }
   3079         } 
   3080     }
   3081 
   3082  done:
   3083     return rv;
   3084 }
   3085 
   3086 int
   3087 _fb_l3ip4mcast_test_hash(int unit, args_t *a, void *p)
   3088 {
   3089     draco_l3_testdata_t         *ad = p;
   3090     uint32                      entry[SOC_MAX_MEM_WORDS];
   3091     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   3092     soc_mem_t                   mem = L3_ENTRY_IPV4_MULTICASTm;
   3093     ip_addr_t                   src_ip;
   3094     ip_addr_t                   dst_ip;
   3095     ip_addr_t                   src_ip_inc;
   3096     ip_addr_t                   dst_ip_inc;
   3097     bcm_vlan_t                  vid;
   3098     int                         vid_inc;
   3099     int                         r, rv = 0;
   3100     int                         soft_bucket;
   3101     int                         hard_index;
   3102     int                         hard_bucket;
   3103     int                         ix;
   3104     int                         iterations;
   3105     int                         vrf_id;
   3106     int                         vrf_id_inc;
   3107     int                         vrf_id_max = 0;
   3108     int                         ent_per_bucket;
   3109     int                         dual = FALSE;
   3110     int                         bank, banks, bank_count = 1;
   3111 
   3112     COMPILER_REFERENCE(a);
   3113 #ifdef BCM_TRIDENT3_SUPPORT
   3114     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   3115         mem = L3_ENTRY_DOUBLEm;
   3116     }
   3117 #endif /* BCM_TRIDENT3_SUPPORT */
   3118 
   3119     vrf_id_max = SOC_VRF_MAX(unit);
   3120 
   3121     if (ad->opt_key_src_ip) {
   3122         src_ip_inc = ad->opt_src_ip_inc;
   3123         src_ip = ad->opt_src_ip;
   3124     } else {
   3125         src_ip_inc = 0;
   3126         src_ip = 0;
   3127     }
   3128     dst_ip = ad->opt_base_ip; 
   3129     dst_ip_inc = ad->opt_ip_inc; 
   3130     vid = ad->opt_base_vid;
   3131     vid_inc = ad->opt_vid_inc;
   3132 
   3133     vrf_id = ad->opt_base_vrf_id;
   3134     vrf_id_inc = ad->opt_vrf_id_inc;
   3135 
   3136     /*  Invalid IPMC/Unicast address checks required */
   3137 
   3138     if (ad->opt_verbose) {
   3139         cli_out("Starting L3 hash test\n");
   3140     }
   3141 
   3142     iterations = ad->opt_count;
   3143     if (soc_feature(unit, soc_feature_dual_hash)) {
   3144         if (ad->opt_dual_hash != -1) {
   3145             dual = TRUE;
   3146             bank_count = 2;
   3147         }
   3148     }
   3149 
   3150     sal_memset (entry, 0, sizeof(entry));
   3151 #ifdef BCM_TRIDENT3_SUPPORT
   3152     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   3153         l3_entry_key_attributes_entry_t  l3_key_attr;
   3154 
   3155         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   3156                             TD3_L3_HASH_KEY_TYPE_V4MC);
   3157         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   3158                             TD3_L3_HASH_DATA_TYPE_V4MC);
   3159         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   3160         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
   3161         if (vrf_id_max) {
   3162             soc_mem_field32_set(unit, mem, entry, IPV4MC__VRF_IDf, 1);
   3163         }
   3164 
   3165         /* Set L3 Entry Key Attributes */
   3166         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   3167         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   3168                             BUCKET_MODEf, 1);
   3169         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   3170                             KEY_BASE_WIDTHf, 0);
   3171         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   3172                             KEY_WIDTHf, 23);
   3173         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   3174                             DATA_BASE_WIDTHf, 1);
   3175         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   3176                             HASH_LSB_OFFSETf, 5);
   3177         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   3178                           TD3_L3_HASH_KEY_TYPE_V4MC,
   3179                           (uint32*)&l3_key_attr) < 0) {
   3180                 test_error(unit, "L3 Entry Key Attr setting failed\n");
   3181                 goto done;
   3182         }
   3183     } else
   3184 #endif
   3185     {
   3186 #ifdef BCM_TRIUMPH_SUPPORT
   3187     if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 
   3188         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   3189                             TR_L3_HASH_KEY_TYPE_V4MC);
   3190         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   3191                             TR_L3_HASH_KEY_TYPE_V4MC);
   3192         soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   3193         soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   3194     } else
   3195 #endif
   3196     {
   3197         soc_mem_field32_set(unit, mem, entry, V6f, 0);
   3198         soc_mem_field32_set(unit, mem, entry, IPMCf, 1);
   3199         soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   3200     }
   3201     }
   3202     if (vrf_id_max) {
   3203         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   3204     } 
   3205     for (ix = 0; ix < iterations; ix++) {
   3206         for (bank = 0; bank < bank_count; bank++) {
   3207             soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip);
   3208             soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip);
   3209             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   3210             if (vrf_id_max) {
   3211                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   3212             } 
   3213     
   3214             soft_bucket = soc_fb_l3x2_entry_hash(unit, entry);
   3215             banks = 0x3;
   3216 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3217             defined(BCM_TRX_SUPPORT)
   3218             if (dual == TRUE) {
   3219                 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry);
   3220                 banks = (bank == 0) ? 2 : 1;
   3221             }
   3222 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3223     
   3224             if (ad->opt_verbose) {
   3225                 cli_out("Inserting ");
   3226                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   3227                 if (dual) {
   3228                     cli_out("into bucket 0x%x (bank %d)",
   3229                             soft_bucket, bank);
   3230                 } else {
   3231                    cli_out("into bucket 0x%x", soft_bucket);
   3232                 }
   3233             }
   3234 
   3235 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3236             defined(BCM_TRX_SUPPORT)
   3237             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   3238 #else  /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3239             r = soc_mem_insert(unit, mem, COPYNO_ALL, entry);
   3240 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3241             if (SOC_FAILURE(r)) {
   3242                 if (r == SOC_E_FULL) {
   3243                     /* Bucket overflow, just pass on */
   3244                     continue;
   3245                 } else {
   3246                     test_error(unit,
   3247                                "L3 insert failed at bucket %d\n", soft_bucket);
   3248                     rv = -1;
   3249                     goto done;
   3250                 }
   3251             }
   3252     
   3253             /* Now we search for the entry */
   3254             hard_index = 0;
   3255             if (soc_mem_search(unit, mem, COPYNO_ALL,
   3256                                &hard_index, entry, entry_lkup, 0) < 0) {
   3257                 test_error(unit, "Entry lookup failed\n");
   3258                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3259                 goto done;
   3260             }
   3261 
   3262 #ifdef BCM_TRIUMPH_SUPPORT
   3263             if (SOC_IS_TR_VL(unit)) {
   3264                 ent_per_bucket = 8;
   3265             } else
   3266 #endif
   3267             if (SOC_L3X_BUCKET_SIZE(unit) == 16) {
   3268                 ent_per_bucket = 16;
   3269             } else {
   3270                 ent_per_bucket = 8;
   3271             }
   3272             hard_bucket = (hard_index / ent_per_bucket); /* entries per bucket */
   3273             if (soft_bucket != hard_bucket) {
   3274                 test_error(unit,
   3275                            "Software Hash %d disagrees with  Hardware Hash %d\n",
   3276                            soft_bucket, hard_bucket);
   3277                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3278                 goto done;
   3279             }
   3280     
   3281             /* Only do a quick check vs. expected bucket here */
   3282             if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) {
   3283                 test_error(unit, "Entry not found in bucket %d\n", soft_bucket);
   3284                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3285                 rv = -1;
   3286                 goto done;
   3287             }
   3288     
   3289             /* Clean up afterward */
   3290             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   3291                 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket);
   3292                 rv = -1;
   3293                 goto done;
   3294             }
   3295     
   3296             src_ip += src_ip_inc;
   3297             dst_ip += dst_ip_inc;
   3298             vid += vid_inc;
   3299             if (vid > DRACO_L3_VID_MAX) {
   3300                 vid = 1;
   3301             }
   3302             if (vrf_id_max) {
   3303                 vrf_id += vrf_id_inc;
   3304                 if (vrf_id > vrf_id_max) {
   3305                     vrf_id = 0;
   3306                 }
   3307             }
   3308         }
   3309     }
   3310 
   3311  done:
   3312     return rv;
   3313 }
   3314 
   3315 int
   3316 _fb_l3ip6ucast_test_hash(int unit, args_t *a, void *p)
   3317 {
   3318     draco_l3_testdata_t         *ad = p;
   3319     uint32                      entry[SOC_MAX_MEM_WORDS];
   3320     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   3321     soc_mem_t                   mem = L3_ENTRY_IPV6_UNICASTm;
   3322     ip6_addr_t                  dst_ip;
   3323     uint32                      ip_tmp[2];
   3324     int                         dst_ip_inc;
   3325     int                         r, rv = 0;
   3326     int                         soft_bucket;
   3327     int                         hard_index;
   3328     int                         hard_bucket;
   3329     int                         ix;
   3330     int                         iterations;
   3331     int                         vrf_id;
   3332     int                         vrf_id_inc;
   3333     int                         vrf_id_max = 0;
   3334     int                         dual = FALSE;
   3335     int                         bank, banks, bank_count = 1;
   3336 
   3337     COMPILER_REFERENCE(a);
   3338 
   3339     vrf_id_max = SOC_VRF_MAX(unit);
   3340 
   3341     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   3342     dst_ip_inc = ad->opt_ip6_inc;
   3343     vrf_id = ad->opt_base_vrf_id;
   3344     vrf_id_inc = ad->opt_vrf_id_inc;
   3345 
   3346     if (ad->opt_verbose) {
   3347         cli_out("Starting L3 hash test\n");
   3348     }
   3349 
   3350     iterations = ad->opt_count;
   3351     if (soc_feature(unit, soc_feature_dual_hash)) {
   3352         if (ad->opt_dual_hash != -1) {
   3353             dual = TRUE;
   3354             bank_count = 2;
   3355         }
   3356     }
   3357 
   3358     sal_memset (entry, 0, sizeof(entry));
   3359 #ifdef BCM_TRIUMPH_SUPPORT
   3360     if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 
   3361         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   3362                             TR_L3_HASH_KEY_TYPE_V6UC);
   3363         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   3364                             TR_L3_HASH_KEY_TYPE_V6UC);
   3365         if (vrf_id_max) {
   3366             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   3367         }
   3368     } else
   3369 #endif /* BCM_TRIUMPH_SUPPORT */
   3370     {
   3371         soc_mem_field32_set(unit, mem, entry, V6_0f, 1);
   3372         soc_mem_field32_set(unit, mem, entry, V6_1f, 1);
   3373         soc_mem_field32_set(unit, mem, entry, IPMC_0f, 0);
   3374         soc_mem_field32_set(unit, mem, entry, IPMC_1f, 0);
   3375 #if  defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   3376         defined(BCM_SCORPION_SUPPORT)
   3377         if (vrf_id_max) {
   3378             soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1);
   3379             soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1);
   3380         }
   3381 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   3382     }
   3383     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   3384     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   3385     for (ix = 0; ix < iterations; ix++) {
   3386         for (bank = 0; bank < bank_count; bank++) {
   3387             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   3388                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   3389             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   3390                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   3391             soc_mem_field_set(unit, mem, entry,
   3392                               IP_ADDR_LWR_64f, ip_tmp);
   3393     
   3394             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   3395                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   3396             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   3397                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   3398             soc_mem_field_set(unit, mem, entry,
   3399                               IP_ADDR_UPR_64f, ip_tmp);
   3400 
   3401 #ifdef BCM_TRIUMPH_SUPPORT
   3402             if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 
   3403                 if (vrf_id_max) {
   3404                     soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   3405                 } 
   3406             } else
   3407 #endif /* BCM_TRIUMPH_SUPPORT */
   3408             {
   3409 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   3410     defined(BCM_SCORPION_SUPPORT)
   3411                 if (vrf_id_max) {
   3412                     soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, vrf_id);
   3413                     soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, vrf_id);
   3414                 } 
   3415 #endif /*  BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   3416             }
   3417             soft_bucket = soc_fb_l3x2_entry_hash(unit, entry);
   3418             banks = 0x3;
   3419 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3420             defined(BCM_TRX_SUPPORT)
   3421             if (dual == TRUE) {
   3422                 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry);
   3423                 banks = (bank == 0) ? 2 : 1;
   3424             }
   3425 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3426     
   3427             if (ad->opt_verbose) {
   3428                 cli_out("Inserting ");
   3429                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   3430                 if (dual) {
   3431                     cli_out("into bucket 0x%x (bank %d)", soft_bucket, bank);
   3432                 } else {
   3433                    cli_out("into bucket 0x%x", soft_bucket);
   3434                 }
   3435             }
   3436     
   3437 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3438             defined(BCM_TRX_SUPPORT)
   3439             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   3440 #else  /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3441             r = soc_mem_insert(unit, mem, COPYNO_ALL, entry);
   3442 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3443             if (SOC_FAILURE(r)) {
   3444                 if (r == SOC_E_FULL) {
   3445                     /* Bucket overflow, just pass on */
   3446                     continue;
   3447                 } else {
   3448                     test_error(unit, "L3 insert failed at bucket %d\n", soft_bucket);
   3449                     rv = -1;
   3450                     goto done;
   3451                 }
   3452             }
   3453     
   3454             /* Now we search for the entry */
   3455             hard_index = 0;
   3456             if (soc_mem_search(unit, mem, COPYNO_ALL,
   3457                                &hard_index, entry, entry_lkup, 0) < 0) {
   3458                 test_error(unit, "Entry lookup failed\n");
   3459                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3460                 goto done;
   3461             }
   3462     
   3463             hard_bucket = (hard_index >> (SOC_L3X_BUCKET_SIZE(unit) == 16 ? 3 : 2)); 
   3464 			    /* entries per bucket */
   3465             if (soft_bucket != hard_bucket) {
   3466                 test_error(unit,
   3467                            "Software Hash %d disagrees with  Hardware Hash %d\n",
   3468                            soft_bucket, hard_bucket);
   3469                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3470                 goto done;
   3471             }
   3472     
   3473             /* Only do a quick check vs. expected bucket here */
   3474             if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) {
   3475                 test_error(unit, "Entry not found in bucket %d\n", soft_bucket);
   3476                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3477                 rv = -1;
   3478                 goto done;
   3479             }
   3480     
   3481             /* Clean up afterward */
   3482             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   3483                 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket);
   3484                 rv = -1;
   3485                 goto done;
   3486             }
   3487             increment_ip6addr(dst_ip, 15, dst_ip_inc);
   3488             if (vrf_id_max) {
   3489                 vrf_id += vrf_id_inc;
   3490                 if (vrf_id > vrf_id_max) {
   3491                     vrf_id = 0;
   3492                 }
   3493             } 
   3494         }
   3495     }
   3496 
   3497  done:
   3498     return rv;
   3499 }
   3500 
   3501 int
   3502 _fb_l3ip6mcast_test_hash(int unit, args_t *a, void *p)
   3503 {
   3504     draco_l3_testdata_t         *ad = p;
   3505     uint32                      entry[SOC_MAX_MEM_WORDS];
   3506     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   3507     soc_mem_t                   mem = L3_ENTRY_IPV6_MULTICASTm;
   3508     ip6_addr_t                  src_ip;
   3509     ip6_addr_t                  dst_ip;
   3510     uint32                      ip_tmp[2];
   3511     int                         src_ip_inc;
   3512     int                         dst_ip_inc;
   3513     bcm_vlan_t                  vid;
   3514     int                         vid_inc;
   3515     int                         r, rv = 0;
   3516     int                         soft_bucket;
   3517     int                         hard_index;
   3518     int                         hard_bucket;
   3519     int                         ix;
   3520     int                         iterations;
   3521     int                         vrf_id;
   3522     int                         vrf_id_inc;
   3523     int                         vrf_id_max = 0; 
   3524     int                         dual = FALSE;
   3525     int                         bank, banks, bank_count = 1;
   3526 
   3527     COMPILER_REFERENCE(a);
   3528     vrf_id_max = SOC_VRF_MAX(unit);
   3529 
   3530 #ifdef BCM_TRIDENT3_SUPPORT
   3531     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   3532         mem = L3_ENTRY_QUADm;
   3533     }
   3534 #endif
   3535     if (ad->opt_key_src_ip) {
   3536         memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t));
   3537         src_ip_inc = ad->opt_src_ip6_inc;
   3538     } else {
   3539         sal_memset (src_ip, 0, sizeof(src_ip));
   3540         src_ip_inc = 0;
   3541     }
   3542     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   3543     dst_ip_inc = ad->opt_ip6_inc;
   3544     vid = ad->opt_base_vid;
   3545     vid_inc = ad->opt_vid_inc;
   3546     vrf_id = ad->opt_base_vrf_id;
   3547     vrf_id_inc = ad->opt_vrf_id_inc;
   3548 
   3549     /*  Invalid IPMC/Unicast address checks required */
   3550 
   3551     if (ad->opt_verbose) {
   3552         cli_out("Starting L3 hash test\n");
   3553     }
   3554 
   3555     iterations = ad->opt_count;
   3556     if (soc_feature(unit, soc_feature_dual_hash)) {
   3557         if (ad->opt_dual_hash != -1) {
   3558             dual = TRUE;
   3559             bank_count = 2;
   3560         }
   3561     }
   3562 
   3563     sal_memset (entry, 0, sizeof(entry));
   3564 #ifdef BCM_TRIUMPH_SUPPORT
   3565     if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 
   3566         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   3567                             TR_L3_HASH_KEY_TYPE_V6MC);
   3568         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   3569                             TR_L3_HASH_KEY_TYPE_V6MC);
   3570         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f,
   3571                             TR_L3_HASH_KEY_TYPE_V6MC);
   3572         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f,
   3573                             TR_L3_HASH_KEY_TYPE_V6MC);
   3574         if (vrf_id_max) {
   3575             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   3576         }
   3577     } else 
   3578 #endif /* BCM_TRIUMPH_SUPPORT */
   3579     {
   3580         soc_mem_field32_set(unit, mem, entry, V6_0f, 1);
   3581         soc_mem_field32_set(unit, mem, entry, V6_1f, 1);
   3582         soc_mem_field32_set(unit, mem, entry, V6_2f, 1);
   3583         soc_mem_field32_set(unit, mem, entry, V6_3f, 1);
   3584         soc_mem_field32_set(unit, mem, entry, IPMC_0f, 1);
   3585         soc_mem_field32_set(unit, mem, entry, IPMC_1f, 1);
   3586         soc_mem_field32_set(unit, mem, entry, IPMC_2f, 1);
   3587         soc_mem_field32_set(unit, mem, entry, IPMC_3f, 1);
   3588 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||\
   3589     defined(BCM_SCORPION_SUPPORT)
   3590         if (vrf_id_max) {
   3591             soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1);
   3592             soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1);
   3593             soc_mem_field32_set(unit, mem, entry, VRF_ID_2f, 1);
   3594             soc_mem_field32_set(unit, mem, entry, VRF_ID_3f, 1);
   3595          }
   3596 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   3597     }
   3598     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   3599     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   3600     soc_mem_field32_set(unit, mem, entry, VALID_2f, 1);
   3601     soc_mem_field32_set(unit, mem, entry, VALID_3f, 1);
   3602     for (ix = 0; ix < iterations; ix++) {
   3603         for (bank = 0; bank < bank_count; bank++) {
   3604             dst_ip[0] = 0;
   3605             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   3606                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   3607             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   3608                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   3609             soc_mem_field_set(unit, mem, entry,
   3610                               GROUP_IP_ADDR_LWR_64f, ip_tmp);
   3611     
   3612             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   3613                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   3614             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   3615                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   3616             soc_mem_field_set(unit, mem, entry,
   3617                               GROUP_IP_ADDR_UPR_56f, ip_tmp);
   3618     
   3619             ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) |
   3620                          (src_ip[10] << 8) | (src_ip[11] << 0));
   3621             ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) |
   3622                          (src_ip[14] << 8) | (src_ip[15] << 0));
   3623             soc_mem_field_set(unit, mem, entry,
   3624                               SOURCE_IP_ADDR_LWR_64f, ip_tmp);
   3625     
   3626             ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) |
   3627                          (src_ip[2] << 8) | (src_ip[3] << 0));
   3628             ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) |
   3629                          (src_ip[6] << 8) | (src_ip[7] << 0));
   3630             soc_mem_field_set(unit, mem, entry,
   3631                               SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   3632 
   3633 
   3634 #ifdef BCM_TRIUMPH_SUPPORT
   3635             if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 
   3636                 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   3637                 if (vrf_id_max) {
   3638                     soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   3639                 } 
   3640             } else
   3641 #endif /* BCM_TRIUMPH_SUPPORT */
   3642             {
   3643                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_0f, vid);
   3644                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_1f, vid);
   3645                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_2f, vid);
   3646                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_3f, vid);
   3647 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   3648     defined(BCM_SCORPION_SUPPORT)
   3649                 if (vrf_id_max) {
   3650                     soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id);
   3651                     soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id);
   3652                     soc_mem_field32_set(unit, mem,entry, VRF_ID_2f, vrf_id);
   3653                     soc_mem_field32_set(unit, mem,entry, VRF_ID_3f, vrf_id);
   3654                 } 
   3655 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   3656             }
   3657             soft_bucket = soc_fb_l3x2_entry_hash(unit, entry);
   3658             banks = 0x3;
   3659 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3660             defined(BCM_TRX_SUPPORT)
   3661             if (dual == TRUE) {
   3662                 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry);
   3663                 banks = (bank == 0) ? 2 : 1;
   3664             }
   3665 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3666 
   3667             if (ad->opt_verbose) {
   3668                 cli_out("Inserting ");
   3669                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   3670                 if (dual) {
   3671                     cli_out("into bucket 0x%x (bank %d)", soft_bucket, bank);
   3672                 } else {
   3673                    cli_out("into bucket 0x%x", soft_bucket);
   3674                 }
   3675             }
   3676     
   3677 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||  \
   3678             defined(BCM_TRX_SUPPORT)
   3679             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   3680 #else  /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3681             r = soc_mem_insert(unit, mem, COPYNO_ALL, entry);
   3682 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   3683             if (SOC_FAILURE(r)) {
   3684                 if (r == SOC_E_FULL) {
   3685                     /* Bucket overflow, just pass on */
   3686                     continue;
   3687                 } else {
   3688                     test_error(unit,
   3689                                "L3 insert failed at bucket %d\n", soft_bucket);
   3690                     rv = -1;
   3691                     goto done;
   3692                 }
   3693             }
   3694     
   3695             /* Now we search for the entry */
   3696             hard_index = 0;
   3697             if (soc_mem_search(unit, mem, COPYNO_ALL,
   3698                                &hard_index, entry, entry_lkup, 0) < 0) {
   3699                 test_error(unit, "Entry lookup failed\n");
   3700                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3701                 goto done;
   3702             }
   3703     
   3704             hard_bucket = (hard_index >> (SOC_L3X_BUCKET_SIZE(unit) == 16 ? 2 : 1)); 
   3705 			    /* entries per bucket */
   3706             if (soft_bucket != hard_bucket) {
   3707                 test_error(unit,
   3708                            "Software Hash %d disagrees with  Hardware Hash %d\n",
   3709                            soft_bucket, hard_bucket);
   3710                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3711                 goto done;
   3712             }
   3713     
   3714             /* Only do a quick check vs. expected bucket here */
   3715             if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) {
   3716                 test_error(unit, "Entry not found in bucket %d\n", soft_bucket);
   3717                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   3718                 rv = -1;
   3719                 goto done;
   3720             }
   3721     
   3722             /* Clean up afterward */
   3723             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   3724                 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket);
   3725                 rv = -1;
   3726                 goto done;
   3727             }
   3728     
   3729             increment_ip6addr(src_ip, 15, src_ip_inc);
   3730             increment_ip6addr(dst_ip, 15, dst_ip_inc);
   3731             vid += vid_inc;
   3732             if (vid > DRACO_L3_VID_MAX) {
   3733                 vid = 1;
   3734             }
   3735             if (vrf_id_max) {
   3736                 vrf_id += vrf_id_inc;
   3737                 if (vrf_id > vrf_id_max) {
   3738                     vrf_id = 0;
   3739                 }
   3740             }
   3741         }
   3742     }
   3743 
   3744  done:
   3745     return rv;
   3746 }
   3747 
   3748 STATIC uint32 entry_tmp[SOC_L3X_MAX_BUCKET_SIZE][SOC_MAX_MEM_WORDS];
   3749 int
   3750 _fb_l3ip4ucast_test_ov(int unit, args_t *a, void *p)
   3751 {
   3752     uint32                      entry[SOC_MAX_MEM_WORDS];
   3753     soc_mem_t                   mem = L3_ENTRY_IPV4_UNICASTm;
   3754     int                         num_ent_per_bucket;
   3755     int                         num_vbits;
   3756     int                         num_buckets; 
   3757     ip_addr_t                   dst_ip;
   3758     bcm_vlan_t                  vid;
   3759     int                         vid_inc;
   3760     int                         r, rv = 0;
   3761     int                         bucket;
   3762     int                         i, j;
   3763     int                         iterations;
   3764     draco_l3_testdata_t         *ad = p;
   3765     int                         vrf_id;
   3766     int                         vrf_id_inc;
   3767     int                         vrf_id_max = 0;
   3768 
   3769 
   3770     COMPILER_REFERENCE(a);
   3771     vrf_id_max = SOC_VRF_MAX(unit);
   3772 
   3773     num_vbits = 1;
   3774     num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits;
   3775     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   3776     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   3777 
   3778     dst_ip = ad->opt_base_ip; 
   3779     vid = ad->opt_base_vid;
   3780     vid_inc = ad->opt_vid_inc;
   3781     vrf_id = ad->opt_base_vrf_id;
   3782     vrf_id_inc = ad->opt_vrf_id_inc;
   3783 
   3784     sal_memset (entry, 0, sizeof(entry));
   3785 #ifdef BCM_TRIUMPH_SUPPORT
   3786     if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   3787         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   3788                             TR_L3_HASH_KEY_TYPE_V4UC);
   3789     } else  
   3790 #endif /* BCM_TRIUMPH_SUPPORT */
   3791     {
   3792         soc_mem_field32_set(unit, mem, entry, V6f, 0);
   3793         soc_mem_field32_set(unit, mem, entry, IPMCf, 0);
   3794     }
   3795     soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   3796     if (vrf_id_max) { 
   3797         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   3798     }
   3799 
   3800     while (iterations--) {
   3801         soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip);
   3802         if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) {
   3803             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   3804         }
   3805         if (vrf_id_max) { 
   3806             soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   3807         } 
   3808 
   3809         bucket = soc_fb_l3x2_entry_hash(unit, entry);
   3810 
   3811         for (i = 0; i < num_ent_per_bucket; i++) {
   3812             memcpy(entry_tmp[i], entry, sizeof(entry));
   3813             if (ad->opt_verbose) {
   3814                 cli_out("Inserting ");
   3815                 soc_mem_entry_dump(unit, mem, entry_tmp[i], BSL_LSS_CLI);
   3816                 cli_out("into bucket 0x%x\n", bucket);
   3817             }
   3818 
   3819             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) {
   3820                 if (r == SOC_E_FULL) {
   3821                     /* Already full, stop wasting time */
   3822                     break;
   3823                 } else {
   3824                     test_error(unit, "L3 insert failed at bucket %d\n", bucket);
   3825                     rv = -1;
   3826                     goto done;
   3827                 }
   3828             }
   3829 
   3830             /* Increment key by number of buckets in the table */
   3831             dst_ip += num_buckets;
   3832             vid += vid_inc;
   3833             if (vid > DRACO_L3_VID_MAX) {
   3834                 vid = 1;
   3835             }
   3836             if (vrf_id_max) { 
   3837                 vrf_id += vrf_id_inc;
   3838                 if (vrf_id > vrf_id_max) {
   3839                     vrf_id = 0;
   3840                 }
   3841             }
   3842             soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip);
   3843             if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) {
   3844                 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   3845             }
   3846             if (vrf_id_max) { 
   3847                 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   3848             } 
   3849         }
   3850 
   3851         if (ad->opt_verbose) {
   3852             cli_out("Inserting %d entry in bucket %d, should fail\n",
   3853                     num_ent_per_bucket, bucket);
   3854         }
   3855 
   3856         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   3857             if (r != SOC_E_FULL) {
   3858                 test_error(unit, "L3 insert failed\n");
   3859                 rv = -1;
   3860                 goto done;
   3861             }
   3862         } else {
   3863             test_error(unit, "L3 insert to full bucket succeeded\n");
   3864             rv = -1;
   3865             goto done;
   3866         }
   3867 
   3868         if (ad->opt_verbose) {
   3869             cli_out("Verifying installed entries\n");
   3870         }
   3871 
   3872         /* Verify bucket contains added entries */
   3873         for (j = 0; j < i; j++) {
   3874             if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) {
   3875                 test_error(unit, "L3 entry missing at bucket %d\n", bucket);
   3876                 rv = -1;
   3877                 goto done;
   3878             }
   3879         }
   3880 
   3881         if (ad->opt_verbose) {
   3882             cli_out("Cleaning bucket %d\n", bucket);
   3883         }
   3884 
   3885         /* Remove the entries that we added */
   3886         for (j = 0; j < i; j++) {
   3887             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) {
   3888                 test_error(unit, "L3 delete failed at bucket %d\n", bucket);
   3889                 rv = -1;
   3890                 goto done;
   3891             }
   3892         }
   3893 
   3894         /* Do Next bucket */
   3895         dst_ip += 1;
   3896         vid += vid_inc;
   3897         if (vid > DRACO_L3_VID_MAX) {
   3898             vid = 1;
   3899         }
   3900         if (vrf_id_max) { 
   3901             vrf_id += vrf_id_inc;
   3902             if (vrf_id > vrf_id_max) {
   3903                 vrf_id = 0;
   3904             }
   3905         }
   3906     }
   3907 
   3908  done:
   3909 
   3910     return rv;
   3911 }
   3912 
   3913 int
   3914 _fb_l3ip4mcast_test_ov(int unit, args_t *a, void *p)
   3915 {
   3916     uint32                      entry[SOC_MAX_MEM_WORDS];
   3917     soc_mem_t                   mem = L3_ENTRY_IPV4_MULTICASTm;
   3918     int                         num_ent_per_bucket;
   3919     int                         num_vbits;
   3920     int                         num_buckets; 
   3921     ip_addr_t                   src_ip;
   3922     ip_addr_t                   dst_ip;
   3923     int                         src_ip_inc;
   3924     bcm_vlan_t                  vid;
   3925     int                         vid_inc;
   3926     int                         r, rv = 0;
   3927     int                         bucket;
   3928     int                         i, j;
   3929     int                         iterations;
   3930     draco_l3_testdata_t         *ad = p;
   3931     int                         vrf_id;
   3932     int                         vrf_id_inc;
   3933     int                         vrf_id_max = 0;
   3934     uint32 hash_read;
   3935 
   3936 
   3937     COMPILER_REFERENCE(a);
   3938     num_vbits = 1;
   3939     
   3940     vrf_id_max = SOC_VRF_MAX(unit);
   3941 #ifdef BCM_TRIUMPH_SUPPORT
   3942     if (SOC_IS_TR_VL(unit)) {
   3943         num_vbits = 2;
   3944     }
   3945 #endif
   3946 
   3947     num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits;
   3948     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   3949     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   3950 
   3951     if (ad->opt_key_src_ip) {
   3952         src_ip_inc = ad->opt_src_ip_inc;
   3953         src_ip = ad->opt_src_ip;
   3954     } else {
   3955         src_ip_inc = 0;
   3956         src_ip = 0;
   3957     }
   3958     dst_ip = ad->opt_base_ip; 
   3959     vid = ad->opt_base_vid;
   3960     vid_inc = ad->opt_vid_inc;
   3961     vrf_id = ad->opt_base_vrf_id;
   3962     vrf_id_inc = ad->opt_vrf_id_inc;
   3963 
   3964 
   3965     sal_memset (entry, 0, sizeof(entry));
   3966 #ifdef BCM_TRIUMPH_SUPPORT
   3967     if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   3968         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   3969                             TR_L3_HASH_KEY_TYPE_V4MC);
   3970         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   3971                             TR_L3_HASH_KEY_TYPE_V4MC);
   3972         soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   3973         soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   3974     } else
   3975 #endif /* BCM_TRIUMPH_SUPPORT */
   3976     {
   3977         soc_mem_field32_set(unit, mem, entry, V6f, 0);
   3978         soc_mem_field32_set(unit, mem, entry, IPMCf, 1);
   3979         soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   3980     }
   3981     if (vrf_id_max) {
   3982         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   3983     } 
   3984     while (iterations--) {
   3985         soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip);
   3986         soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip);
   3987         soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   3988         if (vrf_id_max) {
   3989             soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   3990         } 
   3991 
   3992         bucket = soc_fb_l3x2_entry_hash(unit, entry);
   3993 
   3994         for (i = 0; i < num_ent_per_bucket; i++) {
   3995             memcpy(entry_tmp[i], entry, sizeof(entry));
   3996             if (ad->opt_verbose) {
   3997                 cli_out("Inserting ");
   3998                 soc_mem_entry_dump(unit, mem, entry_tmp[i], BSL_LSS_CLI);
   3999                 cli_out("into bucket 0x%x\n", bucket);
   4000             }
   4001 
   4002             if (READ_HASH_CONTROLr(unit, &hash_read) < 0) {
   4003                 test_error(unit, "Hash select read failed\n");
   4004                 goto done;
   4005             }
   4006 
   4007             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) {
   4008                 if (r == SOC_E_FULL) {
   4009                     /* Already full, stop wasting time */
   4010                     break;
   4011                 } else {
   4012                     test_error(unit, "L3 insert failed at bucket %d\n", bucket);
   4013                     rv = -1;
   4014                     goto done;
   4015                 }
   4016             }
   4017 
   4018             if (READ_HASH_CONTROLr(unit, &hash_read) < 0) {
   4019                 test_error(unit, "Hash select read failed\n");
   4020                 goto done;
   4021             }
   4022 
   4023             /* Increment key by number of buckets in the table */
   4024             dst_ip += num_buckets;
   4025             src_ip += src_ip_inc;
   4026             vid += vid_inc;
   4027             if (vid > DRACO_L3_VID_MAX) {
   4028                 vid = 1;
   4029             }
   4030             if (vrf_id_max) {
   4031                 vrf_id += vrf_id_inc;
   4032                 if (vrf_id > vrf_id_max) {
   4033                     vrf_id = 0;
   4034                 }
   4035             }
   4036             soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip);
   4037             soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip);
   4038             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   4039             if (vrf_id_max) {
   4040                 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   4041             } 
   4042         }
   4043 
   4044         if (ad->opt_verbose) {
   4045             cli_out("Inserting %d entry in bucket %d, should fail\n",
   4046                     num_ent_per_bucket, bucket);
   4047         }
   4048 
   4049         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   4050             if (r != SOC_E_FULL) {
   4051                 test_error(unit, "L3 insert failed\n");
   4052                 rv = -1;
   4053                 goto done;
   4054             }
   4055         } else {
   4056             test_error(unit, "L3 insert to full bucket succeeded\n");
   4057             rv = -1;
   4058             goto done;
   4059         }
   4060 
   4061         if (ad->opt_verbose) {
   4062             cli_out("Verifying installed entries\n");
   4063         }
   4064 
   4065         /* Verify bucket contains added entries */
   4066         for (j = 0; j < i; j++) {
   4067             if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) {
   4068                 test_error(unit, "L3 entry missing at bucket %d\n", bucket);
   4069                 rv = -1;
   4070                 goto done;
   4071             }
   4072         }
   4073 
   4074         if (ad->opt_verbose) {
   4075             cli_out("Cleaning bucket %d\n", bucket);
   4076         }
   4077 
   4078         /* Remove the entries that we added */
   4079         for (j = 0; j < i; j++) {
   4080             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) {
   4081                 test_error(unit, "L3 delete failed at bucket %d\n", bucket);
   4082                 rv = -1;
   4083                 goto done;
   4084             }
   4085         }
   4086 
   4087         /* Do Next bucket */
   4088         dst_ip += 1;
   4089         src_ip += src_ip_inc;
   4090         vid += vid_inc;
   4091         if (vid > DRACO_L3_VID_MAX) {
   4092             vid = 1;
   4093         }
   4094         if (vrf_id_max) {
   4095             vrf_id += vrf_id_inc;
   4096             if (vrf_id > vrf_id_max) {
   4097                 vrf_id = 0;
   4098             }
   4099         }
   4100     }
   4101 
   4102  done:
   4103 
   4104     return rv;
   4105 }
   4106 
   4107 int
   4108 _fb_l3ip6ucast_test_ov(int unit, args_t *a, void *p)
   4109 {
   4110     uint32                      entry[SOC_MAX_MEM_WORDS];
   4111     soc_mem_t                   mem = L3_ENTRY_IPV6_UNICASTm;
   4112     int                         num_ent_per_bucket;
   4113     int                         num_vbits;
   4114     int                         num_buckets; 
   4115     ip6_addr_t                  dst_ip;
   4116     uint32                      ip_tmp[2];
   4117     bcm_vlan_t                  vid;
   4118     int                         vid_inc;
   4119     int                         r, rv = 0;
   4120     int                         bucket;
   4121     int                         i, j;
   4122     int                         iterations;
   4123     draco_l3_testdata_t         *ad = p;
   4124     int                         vrf_id;
   4125     int                         vrf_id_inc;
   4126     int                         vrf_id_max = 0; 
   4127 
   4128     COMPILER_REFERENCE(a);
   4129     vrf_id_max = SOC_VRF_MAX(unit);
   4130 
   4131     num_vbits = 2;
   4132     num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits;
   4133     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   4134     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   4135 
   4136     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   4137     vid = ad->opt_base_vid;
   4138     vid_inc = ad->opt_vid_inc;
   4139     vrf_id = ad->opt_base_vrf_id;
   4140     vrf_id_inc = ad->opt_vrf_id_inc;
   4141     sal_memset (entry, 0, sizeof(entry));
   4142 #ifdef BCM_TRIUMPH_SUPPORT
   4143     if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   4144         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   4145                             TR_L3_HASH_KEY_TYPE_V6UC);
   4146         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   4147                             TR_L3_HASH_KEY_TYPE_V6UC);
   4148         if (vrf_id_max) { 
   4149             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   4150         }
   4151     } else
   4152 #endif /* BCM_TRIUMPH_SUPPORT */
   4153     {
   4154         soc_mem_field32_set(unit, mem, entry, V6_0f, 1);
   4155         soc_mem_field32_set(unit, mem, entry, V6_1f, 1);
   4156         soc_mem_field32_set(unit, mem, entry, IPMC_0f, 0);
   4157         soc_mem_field32_set(unit, mem, entry, IPMC_1f, 0);
   4158 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   4159     defined(BCM_SCORPION_SUPPORT)
   4160         if (vrf_id_max) { 
   4161             soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1);
   4162             soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1);
   4163         }
   4164 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   4165     }
   4166     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   4167     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   4168     while (iterations--) {
   4169         ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   4170                      (dst_ip[10] << 8) | (dst_ip[11] << 0));
   4171         ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   4172                      (dst_ip[14] << 8) | (dst_ip[15] << 0));
   4173         soc_mem_field_set(unit, mem, entry,
   4174                           IP_ADDR_LWR_64f, ip_tmp);
   4175 
   4176         ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   4177                      (dst_ip[2] << 8) | (dst_ip[3] << 0));
   4178         ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   4179                      (dst_ip[6] << 8) | (dst_ip[7] << 0));
   4180         soc_mem_field_set(unit, mem, entry,
   4181                           IP_ADDR_UPR_64f, ip_tmp);
   4182 #ifdef BCM_TRIUMPH_SUPPORT
   4183         if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   4184             if (vrf_id_max) { 
   4185                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   4186             } 
   4187         } else
   4188 #endif /* BCM_TRIUMPH_SUPPORT */
   4189         {
   4190 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||\
   4191     defined(BCM_SCORPION_SUPPORT)
   4192             if (vrf_id_max) { 
   4193                 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id);
   4194                 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id);
   4195             } 
   4196 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   4197         }
   4198         bucket = soc_fb_l3x2_entry_hash(unit, entry);
   4199 
   4200         for (i = 0; i < num_ent_per_bucket; i++) {
   4201             if (ad->opt_verbose) {
   4202                 cli_out("Inserting ");
   4203                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   4204                 cli_out("into bucket 0x%x\n", bucket);
   4205             }
   4206 
   4207             memcpy(entry_tmp[i], entry, sizeof(entry));
   4208             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) {
   4209                 if (r == SOC_E_FULL) {
   4210                     /* Already full, stop wasting time */
   4211                     break;
   4212                 } else {
   4213                     test_error(unit, "L3 insert failed at bucket %d\n", bucket);
   4214                     rv = -1;
   4215                     goto done;
   4216                 }
   4217             }
   4218 
   4219             /* Increment key by number of buckets in the table */
   4220             increment_ip6addr(dst_ip, 15, num_buckets);
   4221             vid += vid_inc;
   4222             if (vid > DRACO_L3_VID_MAX) {
   4223                 vid = 1;
   4224             }
   4225             if (vrf_id_max) { 
   4226                 vrf_id += vrf_id_inc;
   4227                 if (vrf_id > vrf_id_max) {
   4228                     vrf_id = 0;
   4229                 }
   4230             }
   4231             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   4232                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   4233             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   4234                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   4235             soc_mem_field_set(unit, mem, entry,
   4236                               IP_ADDR_LWR_64f, ip_tmp);
   4237 
   4238             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   4239                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   4240             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   4241                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   4242             soc_mem_field_set(unit, mem, entry,
   4243                               IP_ADDR_UPR_64f, ip_tmp);
   4244 
   4245             if (vrf_id_max) { 
   4246 #ifdef BCM_TRIUMPH_SUPPORT
   4247                 if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   4248                     soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   4249                 } else
   4250 #endif /* BCM_TRIUMPH_SUPPORT */
   4251                 {
   4252 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   4253     defined(BCM_SCORPION_SUPPORT)
   4254                     soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id);
   4255                     soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id);
   4256 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   4257                 }
   4258             } 
   4259         }
   4260 
   4261         if (ad->opt_verbose) {
   4262             cli_out("Inserting %d entry in bucket %d, should fail\n",
   4263                     num_ent_per_bucket, bucket);
   4264         }
   4265 
   4266         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   4267             if (r != SOC_E_FULL) {
   4268                 test_error(unit, "L3 insert failed\n");
   4269                 rv = -1;
   4270                 goto done;
   4271             }
   4272         } else {
   4273             test_error(unit, "L3 insert to full bucket succeeded\n");
   4274             rv = -1;
   4275             goto done;
   4276         }
   4277 
   4278         if (ad->opt_verbose) {
   4279             cli_out("Verifying installed entries\n");
   4280         }
   4281 
   4282         /* Verify bucket contains added entries */
   4283         for (j = 0; j < i; j++) {
   4284             if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) {
   4285                 test_error(unit, "L3 entry missing at bucket %d\n", bucket);
   4286                 rv = -1;
   4287                 goto done;
   4288             }
   4289         }
   4290 
   4291         if (ad->opt_verbose) {
   4292             cli_out("Cleaning bucket %d\n", bucket);
   4293         }
   4294 
   4295         /* Remove the entries that we added */
   4296         for (j = 0; j < i; j++) {
   4297             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) {
   4298                 test_error(unit, "L3 delete failed at bucket %d\n", bucket);
   4299                 rv = -1;
   4300                 goto done;
   4301             }
   4302         }
   4303 
   4304         /* Do Next bucket */
   4305         increment_ip6addr(dst_ip, 15, 1);
   4306         vid += vid_inc;
   4307         if (vid > DRACO_L3_VID_MAX) {
   4308             vid = 1;
   4309         }
   4310         if (vrf_id_max) { 
   4311             vrf_id += vrf_id_inc;
   4312             if (vrf_id > vrf_id_max) {
   4313                 vrf_id = 0;
   4314             }
   4315         }
   4316     }
   4317 
   4318  done:
   4319 
   4320     return rv;
   4321 }
   4322 
   4323 int
   4324 _fb_l3ip6mcast_test_ov(int unit, args_t *a, void *p)
   4325 {
   4326     uint32                      entry[SOC_MAX_MEM_WORDS];
   4327     soc_mem_t                   mem = L3_ENTRY_IPV6_MULTICASTm;
   4328     int                         num_ent_per_bucket;
   4329     int                         num_vbits;
   4330     int                         num_buckets; 
   4331     ip6_addr_t                  src_ip;
   4332     ip6_addr_t                  dst_ip;
   4333     uint32                      ip_tmp[2];
   4334     int                         src_ip_inc;
   4335     bcm_vlan_t                  vid;
   4336     int                         vid_inc;
   4337     int                         r, rv = 0;
   4338     int                         bucket;
   4339     int                         i, j;
   4340     int                         iterations;
   4341     draco_l3_testdata_t         *ad = p;
   4342     int                         vrf_id;
   4343     int                         vrf_id_inc;
   4344     int                         vrf_id_max = 0;
   4345 
   4346     COMPILER_REFERENCE(a);
   4347     vrf_id_max = SOC_VRF_MAX(unit);
   4348 
   4349 #ifdef BCM_TRIDENT3_SUPPORT
   4350     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   4351         mem = L3_ENTRY_QUADm;
   4352     }
   4353 #endif
   4354     num_vbits = 4;
   4355     num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits;
   4356     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   4357     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   4358 
   4359     if (ad->opt_key_src_ip) {
   4360         memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t));
   4361         src_ip_inc = ad->opt_src_ip6_inc;
   4362     } else {
   4363         sal_memset (src_ip, 0, sizeof(src_ip));
   4364         src_ip_inc = 0;
   4365     }
   4366     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   4367     vid = ad->opt_base_vid;
   4368     vid_inc = ad->opt_vid_inc;
   4369     vrf_id = ad->opt_base_vrf_id;
   4370     vrf_id_inc = ad->opt_vrf_id_inc;
   4371 
   4372     sal_memset (entry, 0, sizeof(entry));
   4373 #ifdef BCM_TRIUMPH_SUPPORT
   4374     if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   4375         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   4376                             TR_L3_HASH_KEY_TYPE_V6MC);
   4377         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   4378                             TR_L3_HASH_KEY_TYPE_V6MC);
   4379         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f,
   4380                             TR_L3_HASH_KEY_TYPE_V6MC);
   4381         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f,
   4382                             TR_L3_HASH_KEY_TYPE_V6MC);
   4383         if (vrf_id_max) { 
   4384             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   4385         } 
   4386     } else
   4387 #endif /* BCM_TRIUMPH_SUPPORT */
   4388     {
   4389         soc_mem_field32_set(unit, mem, entry, V6_0f, 1);
   4390         soc_mem_field32_set(unit, mem, entry, V6_1f, 1);
   4391         soc_mem_field32_set(unit, mem, entry, V6_2f, 1);
   4392         soc_mem_field32_set(unit, mem, entry, V6_3f, 1);
   4393         soc_mem_field32_set(unit, mem, entry, IPMC_0f, 1);
   4394         soc_mem_field32_set(unit, mem, entry, IPMC_1f, 1);
   4395         soc_mem_field32_set(unit, mem, entry, IPMC_2f, 1);
   4396         soc_mem_field32_set(unit, mem, entry, IPMC_3f, 1);
   4397 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   4398     defined(BCM_SCORPION_SUPPORT)
   4399         if (vrf_id_max) { 
   4400             soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1);
   4401             soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1);
   4402             soc_mem_field32_set(unit, mem, entry, VRF_ID_2f, 1);
   4403             soc_mem_field32_set(unit, mem, entry, VRF_ID_3f, 1);
   4404         } 
   4405 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   4406     }
   4407     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   4408     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   4409     soc_mem_field32_set(unit, mem, entry, VALID_2f, 1);
   4410     soc_mem_field32_set(unit, mem, entry, VALID_3f, 1);
   4411     while (iterations--) {
   4412         dst_ip[0] = 0;
   4413         ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   4414                      (dst_ip[10] << 8) | (dst_ip[11] << 0));
   4415         ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   4416                      (dst_ip[14] << 8) | (dst_ip[15] << 0));
   4417         soc_mem_field_set(unit, mem, entry,
   4418                           GROUP_IP_ADDR_LWR_64f, ip_tmp);
   4419 
   4420         ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   4421                      (dst_ip[2] << 8) | (dst_ip[3] << 0));
   4422         ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   4423                      (dst_ip[6] << 8) | (dst_ip[7] << 0));
   4424         soc_mem_field_set(unit, mem, entry,
   4425                           GROUP_IP_ADDR_UPR_56f, ip_tmp);
   4426 
   4427         ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) |
   4428                      (src_ip[10] << 8) | (src_ip[11] << 0));
   4429         ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) |
   4430                      (src_ip[14] << 8) | (src_ip[15] << 0));
   4431         soc_mem_field_set(unit, mem, entry,
   4432                           SOURCE_IP_ADDR_LWR_64f, ip_tmp);
   4433 
   4434         ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) |
   4435                      (src_ip[2] << 8) | (src_ip[3] << 0));
   4436         ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) |
   4437                      (src_ip[6] << 8) | (src_ip[7] << 0));
   4438         soc_mem_field_set(unit, mem, entry,
   4439                           SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   4440 
   4441 #ifdef BCM_TRIUMPH_SUPPORT
   4442         if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   4443             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   4444             if (vrf_id_max) { 
   4445                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   4446             } 
   4447         } else
   4448 #endif /* BCM_TRIUMPH_SUPPORT */
   4449         {
   4450             soc_mem_field32_set(unit, mem, entry, VLAN_ID_0f, vid);
   4451             soc_mem_field32_set(unit, mem, entry, VLAN_ID_1f, vid);
   4452             soc_mem_field32_set(unit, mem, entry, VLAN_ID_2f, vid);
   4453             soc_mem_field32_set(unit, mem, entry, VLAN_ID_3f, vid);
   4454 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   4455     defined(BCM_SCORPION_SUPPORT)
   4456             if (vrf_id_max) { 
   4457                 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id);
   4458                 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id);
   4459                 soc_mem_field32_set(unit, mem,entry, VRF_ID_2f, vrf_id);
   4460                 soc_mem_field32_set(unit, mem,entry, VRF_ID_3f, vrf_id);
   4461             } 
   4462 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   4463         }
   4464         bucket = soc_fb_l3x2_entry_hash(unit, entry);
   4465 
   4466         for (i = 0; i < num_ent_per_bucket; i++) {
   4467             if (ad->opt_verbose) {
   4468                 cli_out("Inserting ");
   4469                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   4470                 cli_out("into bucket 0x%x\n", bucket);
   4471             }
   4472 
   4473             memcpy(entry_tmp[i], entry, sizeof(entry));
   4474             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) {
   4475                 if (r == SOC_E_FULL) {
   4476                     /* Already full, stop wasting time */
   4477                     break;
   4478                 } else {
   4479                     test_error(unit, "L3 insert failed at bucket %d\n", bucket);
   4480                     rv = -1;
   4481                     goto done;
   4482                 }
   4483             }
   4484 
   4485             /* Increment key by number of buckets in the table */
   4486             increment_ip6addr(dst_ip, 15, num_buckets);
   4487             increment_ip6addr(src_ip, 15, src_ip_inc);
   4488             vid += vid_inc;
   4489             if (vid > DRACO_L3_VID_MAX) {
   4490                 vid = 1;
   4491             }
   4492             if (vrf_id_max) { 
   4493                 vrf_id += vrf_id_inc;
   4494                 if (vrf_id > vrf_id_max) {
   4495                     vrf_id = 0;
   4496                 }
   4497             }  
   4498             dst_ip[0] = 0;
   4499             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   4500                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   4501             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   4502                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   4503             soc_mem_field_set(unit, mem, entry,
   4504                               GROUP_IP_ADDR_LWR_64f, ip_tmp);
   4505 
   4506             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   4507                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   4508             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   4509                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   4510             soc_mem_field_set(unit, mem, entry,
   4511                               GROUP_IP_ADDR_UPR_56f, ip_tmp);
   4512 
   4513             ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) |
   4514                          (src_ip[10] << 8) | (src_ip[11] << 0));
   4515             ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) |
   4516                          (src_ip[14] << 8) | (src_ip[15] << 0));
   4517             soc_mem_field_set(unit, mem, entry,
   4518                               SOURCE_IP_ADDR_LWR_64f, ip_tmp);
   4519 
   4520             ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) |
   4521                          (src_ip[2] << 8) | (src_ip[3] << 0));
   4522             ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) |
   4523                          (src_ip[6] << 8) | (src_ip[7] << 0));
   4524             soc_mem_field_set(unit, mem, entry,
   4525                               SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   4526 #ifdef BCM_TRIUMPH_SUPPORT
   4527             if (soc_feature(unit, soc_feature_l3_entry_key_type)) {
   4528                 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   4529                 if (vrf_id_max) { 
   4530                     soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   4531                 }
   4532             } else 
   4533 #endif /* BCM_TRIUMPH_SUPPORT */
   4534             {
   4535                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_0f, vid);
   4536                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_1f, vid);
   4537                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_2f, vid);
   4538                 soc_mem_field32_set(unit, mem, entry, VLAN_ID_3f, vid);
   4539 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
   4540     defined(BCM_SCORPION_SUPPORT)
   4541                 if (vrf_id_max) { 
   4542                     soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id);
   4543                     soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id);
   4544                     soc_mem_field32_set(unit, mem,entry, VRF_ID_2f, vrf_id);
   4545                     soc_mem_field32_set(unit, mem,entry, VRF_ID_3f, vrf_id);
   4546                 } 
   4547 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   4548             }
   4549         }
   4550 
   4551         if (ad->opt_verbose) {
   4552             cli_out("Inserting %d entry in bucket %d, should fail\n",
   4553                     num_ent_per_bucket, bucket);
   4554         }
   4555         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   4556             if (r != SOC_E_FULL) {
   4557                 test_error(unit, "L3 insert failed\n");
   4558                 rv = -1;
   4559                 goto done;
   4560             }
   4561         } else {
   4562             test_error(unit, "L3 insert to full bucket succeeded\n");
   4563             rv = -1;
   4564             goto done;
   4565         }
   4566 
   4567         if (ad->opt_verbose) {
   4568             cli_out("Verifying installed entries\n");
   4569         }
   4570 
   4571         /* Verify bucket contains added entries */
   4572         for (j = 0; j < i; j++) {
   4573             if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) {
   4574                 test_error(unit, "L3 entry missing at bucket %d\n", bucket);
   4575                 rv = -1;
   4576                 goto done;
   4577             }
   4578         }
   4579 
   4580         if (ad->opt_verbose) {
   4581             cli_out("Cleaning bucket %d\n", bucket);
   4582         }
   4583 
   4584         /* Remove the entries that we added */
   4585         for (j = 0; j < i; j++) {
   4586             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) {
   4587                 test_error(unit, "L3 delete failed at bucket %d\n", bucket);
   4588                 rv = -1;
   4589                 goto done;
   4590             }
   4591         }
   4592 
   4593         /* Do Next bucket */
   4594         increment_ip6addr(dst_ip, 15, 1);
   4595         increment_ip6addr(src_ip, 15, src_ip_inc);
   4596         vid += vid_inc;
   4597         if (vid > DRACO_L3_VID_MAX) {
   4598             vid = 1;
   4599         }
   4600         if (vrf_id_max) { 
   4601             vrf_id += vrf_id_inc;
   4602             if (vrf_id > vrf_id_max) {
   4603                 vrf_id = 0;
   4604             }
   4605         }
   4606     }
   4607 
   4608  done:
   4609 
   4610     return rv;
   4611 }
   4612 
   4613 #if defined(BCM_TRIDENT2_SUPPORT)
   4614 static int
   4615 td2_l3_bucket_search(int unit, draco_l3_testdata_t *ad, soc_mem_t mem, int bank, 
   4616                      int *index_array, uint32 *expect)
   4617 {
   4618     uint32          entry[SOC_MAX_MEM_WORDS];
   4619     int             i, ix, mem_table_index;
   4620     int             bucket_size = SOC_TD2_L3X_BUCKET_SIZE;
   4621     int             num_vbits;
   4622     int             num_ent_per_bucket;
   4623     int             valid_ix;
   4624     soc_field_t     valid_f[] = {VALIDf, VALID_0f, VALID_1f, VALID_2f, VALID_3f}; 
   4625     int rv = -1; /* Assume failed unless we find it */
   4626     int key_type;
   4627 
   4628 #ifdef BCM_TRIDENT3_SUPPORT
   4629     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   4630         key_type = soc_mem_field32_get(unit, mem, expect, KEY_TYPEf);
   4631     } else
   4632 #endif /* BCM_TRIDENT3_SUPPORT */
   4633     {
   4634     key_type = soc_mem_field32_get(unit, L3_ENTRY_ONLYm, 
   4635                                    expect, KEY_TYPEf);
   4636     }
   4637 
   4638     switch (key_type) {
   4639         case TD2_L3_HASH_KEY_TYPE_V4UC:
   4640 #ifdef BCM_TRIDENT3_SUPPORT
   4641             if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) {
   4642                 if (mem == L3_ENTRY_DOUBLEm) {
   4643                     valid_f[0] = BASE_VALID_0f;
   4644                     valid_f[1] = BASE_VALID_1f;
   4645                 } else if (mem == L3_ENTRY_SINGLEm) {
   4646                     valid_f[0] = BASE_VALIDf;
   4647                 } else {
   4648                     return rv;
   4649                 }
   4650                 valid_ix = 0;
   4651                 num_vbits = 1;
   4652             } else
   4653 #endif /* BCM_TRIDENT3_SUPPORT */
   4654             {
   4655             valid_ix = 0;
   4656             num_vbits = 1;
   4657             mem = L3_ENTRY_IPV4_UNICASTm;
   4658             }
   4659             break;
   4660         case TD2_L3_HASH_KEY_TYPE_V4MC:
   4661 #ifdef BCM_TRIDENT3_SUPPORT
   4662             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   4663                 valid_f[0] = BASE_VALID_0f;
   4664                 valid_f[1] = BASE_VALID_1f;
   4665                 valid_ix = 0;
   4666                 num_vbits = 1;
   4667             } else
   4668 #endif /* BCM_TRIDENT3_SUPPORT */
   4669             {
   4670             valid_ix = 1;
   4671             num_vbits = 2;
   4672             mem = L3_ENTRY_IPV4_MULTICASTm;
   4673             }
   4674             break;
   4675         case TD2_L3_HASH_KEY_TYPE_V6UC:
   4676 #ifdef BCM_TRIDENT3_SUPPORT
   4677             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   4678                 if (mem == L3_ENTRY_QUADm) {
   4679                     valid_f[0] = BASE_VALID_0f;
   4680                     valid_f[1] = BASE_VALID_1f;
   4681                     valid_f[2] = BASE_VALID_2f;
   4682                     valid_f[3] = BASE_VALID_3f;
   4683                     valid_ix = 0;
   4684                     num_vbits = 1;
   4685                 } else if (mem == L3_ENTRY_DOUBLEm) {
   4686                     valid_f[0] = BASE_VALID_0f;
   4687                     valid_f[1] = BASE_VALID_1f;
   4688                     valid_ix = 0;
   4689                     num_vbits = 1;
   4690                 } else {
   4691                     return rv;
   4692                 }
   4693             } else
   4694 #endif 
   4695             {
   4696             valid_ix = 1;
   4697             num_vbits = 2;
   4698             mem = L3_ENTRY_IPV6_UNICASTm;
   4699             }
   4700             break;
   4701         case TD2_L3_HASH_KEY_TYPE_V6MC:
   4702 #ifdef BCM_TRIDENT3_SUPPORT
   4703             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   4704                 valid_f[0] = BASE_VALID_0f;
   4705                 valid_f[1] = BASE_VALID_1f;
   4706                 valid_f[2] = BASE_VALID_2f;
   4707                 valid_f[3] = BASE_VALID_3f;
   4708                 valid_ix = 0;
   4709                 num_vbits = 1;
   4710                 mem = L3_ENTRY_QUADm;
   4711             } else
   4712 #endif /* BCM_TRIDENT3_SUPPORT */
   4713             {
   4714             valid_ix = 1;
   4715             num_vbits = 4;
   4716             mem = L3_ENTRY_IPV6_MULTICASTm;
   4717             }
   4718             break;
   4719         default: 
   4720             return -1;
   4721     }
   4722 
   4723     num_ent_per_bucket = bucket_size / num_vbits;
   4724 
   4725     for (ix = 0; ix < num_ent_per_bucket; ix++) {
   4726         mem_table_index = index_array[bank] + ix;
   4727 
   4728         if (soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   4729                              mem_table_index, entry) < 0) {
   4730             test_error(unit,
   4731                        "Read %s failed at band %d, index %d, offset %d\n",
   4732                        SOC_MEM_NAME(unit, mem), bank, index_array[bank], ix);
   4733             break;
   4734         }
   4735 
   4736         for(i = 0; i < num_vbits; i++) {
   4737             if (!soc_mem_field32_get(unit, mem, entry, valid_f[valid_ix + i])) {
   4738                 break;
   4739             }
   4740         }
   4741         if (i != num_vbits) {
   4742             /* Valid bit not set, blank entry */
   4743             continue;
   4744         }
   4745 
   4746         if (soc_mem_compare_key(unit, mem, expect, entry) == 0) {
   4747             /* Found the matching entry */
   4748             rv = 0;
   4749             break;
   4750         }
   4751     }
   4752 
   4753     return rv;
   4754 }
   4755 
   4756 int
   4757 _td2_l3ip4ucast_test_hash(int unit, args_t *a, void *p)
   4758 {
   4759     draco_l3_testdata_t         *ad = p;
   4760     uint32                      entry[SOC_MAX_MEM_WORDS];
   4761     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   4762     soc_mem_t                   mem = L3_ENTRY_IPV4_UNICASTm;
   4763     ip_addr_t                   dst_ip;
   4764     ip_addr_t                   dst_ip_inc;
   4765     bcm_vlan_t                  vid;
   4766     int                         vid_inc;
   4767     int                         r, rv = 0;
   4768     int                         hard_index;
   4769     int                         bucket_size, bucket_offset;
   4770     int                         ix;
   4771     int                         iterations;
   4772     int                         vrf_id;
   4773     int                         vrf_id_inc;
   4774     int                         vrf_id_max = 0;
   4775     int                         bank, banks, bi;
   4776     uint32                      bank_count;
   4777     int                         num_l3_banks = 0;
   4778     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   4779     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   4780     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   4781 
   4782     COMPILER_REFERENCE(a);
   4783     vrf_id_max = SOC_VRF_MAX(unit);
   4784     bucket_size = 4;
   4785 
   4786 #ifdef BCM_TRIDENT3_SUPPORT
   4787     if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) {
   4788         mem = L3_ENTRY_SINGLEm;
   4789     }
   4790 #endif /* BCM_TRIDENT3_SUPPORT */
   4791 
   4792     dst_ip = ad->opt_base_ip; 
   4793     dst_ip_inc = ad->opt_ip_inc; 
   4794     vid = ad->opt_base_vid;
   4795     vid_inc = ad->opt_vid_inc;
   4796     
   4797     vrf_id = ad->opt_base_vrf_id;
   4798     vrf_id_inc = ad->opt_vrf_id_inc;
   4799 
   4800     if (ad->opt_verbose) {
   4801         cli_out("Starting L3 hash test\n");
   4802     }
   4803 
   4804     iterations = ad->opt_count;
   4805 
   4806     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   4807                                            &bank_count)) < 0) {
   4808         test_error(unit, "Getting bank count for L3 table failed\n");
   4809         rv = -1;
   4810         goto done;
   4811     }
   4812 
   4813     sal_memset(entry, 0, sizeof(entry));
   4814 #ifdef BCM_TRIDENT3_SUPPORT
   4815     if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) {
   4816         l3_entry_key_attributes_entry_t  l3_key_attr;
   4817 
   4818         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   4819                             TD3_L3_HASH_KEY_TYPE_V4UC);
   4820         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   4821                             TD3_L3_HASH_DATA_TYPE_V4UC);
   4822         soc_mem_field32_set(unit, mem, entry, BASE_VALIDf, 1);
   4823         if (vrf_id_max) {
   4824             soc_mem_field32_set(unit, mem, entry, IPV4UC__VRF_IDf, 1);
   4825         }
   4826 
   4827         /* Set L3 Entry Key Attributes */
   4828         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   4829         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   4830                             BUCKET_MODEf, 0);
   4831         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   4832                             KEY_BASE_WIDTHf, 0);
   4833         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   4834                             KEY_WIDTHf, 12);
   4835         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   4836                             DATA_BASE_WIDTHf, 1);
   4837         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   4838                             HASH_LSB_OFFSETf, 5);
   4839         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   4840                           TD3_L3_HASH_KEY_TYPE_V4UC,
   4841                           (uint32*)&l3_key_attr) < 0) {
   4842             test_error(unit, "L3 Entry Key Attr setting failed\n");
   4843             goto done;
   4844         }
   4845     } else
   4846 #endif
   4847     {
   4848         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   4849                 TD2_L3_HASH_KEY_TYPE_V4UC);
   4850         soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   4851         if (vrf_id_max) {
   4852             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   4853         }
   4854     }
   4855 
   4856     for (ix = 0; ix < iterations; ix++) {
   4857         for (bank = 0; bank < bank_count; bank++) {
   4858             soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip);
   4859             if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) {
   4860                 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   4861             }
   4862             if (vrf_id_max) {
   4863                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   4864             } 
   4865 
   4866             if (bank == 0) {
   4867 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   4868     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   4869                 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) 
   4870                    || SOC_IS_TRIDENT3X(unit)) {
   4871                     if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   4872                                                &num_l3_banks, l3_bucket_array,
   4873                                                l3_index_array, phy_bank_array,
   4874                                                NULL)) < 0) {
   4875                         cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   4876                         goto done;
   4877                     }
   4878 
   4879                     if (num_l3_banks > L3_MAX_BANKS) {
   4880                         cli_out("%s ERROR: the number of banks overflow\n",
   4881                                 ARG_CMD(a));
   4882                         rv = -1;
   4883                         goto done;
   4884                     }
   4885                 } else
   4886 #endif
   4887                 {
   4888                     rv = -1;
   4889                     goto done;
   4890                 }
   4891 
   4892                 if (ad->opt_verbose) {
   4893                     cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   4894                     for (bi = 0; bi < bank_count; bi++) {
   4895                         cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   4896                                  bi, phy_bank_array[bi],
   4897                                  l3_bucket_array[bi], l3_bucket_array[bi],
   4898                                  l3_index_array[bi], l3_index_array[bi]);
   4899                     }
   4900                 }
   4901             }
   4902 
   4903             if (ad->opt_verbose) {
   4904                 cli_out("Inserting ");
   4905                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   4906                 cli_out("\n");
   4907                 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank);
   4908             }
   4909 
   4910             banks = 1 << phy_bank_array[bank];
   4911             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   4912             if (SOC_FAILURE(r)) {
   4913                 if (r == SOC_E_FULL) {
   4914                     /* Bucket overflow, just pass on */
   4915                     continue;
   4916                 } else {
   4917                     test_error(unit, "L3 insert failed at bucket %d bank %d\n", 
   4918                                l3_bucket_array[bank], bank);
   4919                     rv = -1;
   4920                     goto done;
   4921                 }
   4922             }
   4923 
   4924             /* Now we search for the entry */
   4925             hard_index = 0;
   4926             if (soc_mem_search(unit, mem, COPYNO_ALL,
   4927                                &hard_index, entry, entry_lkup, 0) < 0) {
   4928                 test_error(unit, "Entry lookup failed\n");
   4929                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   4930                 goto done;
   4931             }
   4932     
   4933             /* entries per bucket */
   4934             bucket_offset = hard_index - l3_index_array[bank];
   4935             if (bucket_offset < 0 || bucket_offset >= bucket_size) {
   4936                 test_error(unit,
   4937                            "Hardware Hash %d out range of Software Hash base %d (%d)\n",
   4938                            hard_index, l3_index_array[bank], bucket_offset);
   4939                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   4940                 goto done;
   4941             }
   4942     
   4943             /* Only do a quick check vs. expected bucket here */
   4944             if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) {
   4945                 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 
   4946                            bank, l3_index_array[bank]);
   4947                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   4948                 rv = -1;
   4949                 goto done;
   4950             }
   4951 
   4952             /* Clean up afterward */
   4953             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   4954                 test_error(unit, "L3 delete failed at bucket %d bank %d\n",
   4955                            l3_bucket_array[bank], bank);
   4956                 rv = -1;
   4957                 goto done;
   4958             }
   4959         }
   4960 
   4961         dst_ip += dst_ip_inc;
   4962         vid += vid_inc;
   4963         if (vid > DRACO_L3_VID_MAX) {
   4964             vid = 1;
   4965         }
   4966         if (vrf_id_max) {
   4967             vrf_id += vrf_id_inc;
   4968             if (vrf_id > vrf_id_max) {
   4969                 vrf_id = 0;
   4970             }
   4971         } 
   4972     }
   4973 
   4974  done:
   4975     return rv;
   4976 }
   4977 
   4978 int
   4979 _td2_l3ip4mcast_test_hash(int unit, args_t *a, void *p)
   4980 {
   4981     draco_l3_testdata_t         *ad = p;
   4982     uint32                      entry[SOC_MAX_MEM_WORDS];
   4983     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   4984     soc_mem_t                   mem = L3_ENTRY_IPV4_MULTICASTm;
   4985     ip_addr_t                   src_ip;
   4986     ip_addr_t                   dst_ip;
   4987     ip_addr_t                   src_ip_inc;
   4988     ip_addr_t                   dst_ip_inc;
   4989     bcm_vlan_t                  vid;
   4990     int                         vid_inc;
   4991     int                         r, rv = 0;
   4992     int                         hard_index;
   4993     int                         bucket_size, bucket_offset;
   4994     int                         ix;
   4995     int                         iterations;
   4996     int                         vrf_id;
   4997     int                         vrf_id_inc;
   4998     int                         vrf_id_max = 0;
   4999     int                         bank, banks, bi;
   5000     uint32                      bank_count;
   5001     int                         num_l3_banks = 0;
   5002     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   5003     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   5004     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   5005 
   5006     COMPILER_REFERENCE(a);
   5007     bucket_size = 2;
   5008 
   5009 #ifdef BCM_TRIDENT3_SUPPORT
   5010     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5011         mem = L3_ENTRY_DOUBLEm;
   5012         bucket_size = 4;
   5013     }
   5014 #endif /* BCM_TRIDENT3_SUPPORT */
   5015 
   5016     vrf_id_max = SOC_VRF_MAX(unit);
   5017     if (ad->opt_key_src_ip) {
   5018         src_ip_inc = ad->opt_src_ip_inc;
   5019         src_ip = ad->opt_src_ip;
   5020     } else {
   5021         src_ip_inc = 0;
   5022         src_ip = 0;
   5023     }
   5024     dst_ip = ad->opt_base_ip; 
   5025     dst_ip_inc = ad->opt_ip_inc; 
   5026     vid = ad->opt_base_vid;
   5027     vid_inc = ad->opt_vid_inc;
   5028 
   5029     vrf_id = ad->opt_base_vrf_id;
   5030     vrf_id_inc = ad->opt_vrf_id_inc;
   5031 
   5032     /*  Invalid IPMC/Unicast address checks required */
   5033 
   5034     if (ad->opt_verbose) {
   5035         cli_out("Starting L3 hash test\n");
   5036     }
   5037 
   5038     iterations = ad->opt_count;
   5039 
   5040     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   5041                                            &bank_count)) < 0) {
   5042         test_error(unit, "Getting bank count for L3 table failed\n");
   5043         rv = -1;
   5044         goto done;
   5045     }
   5046 
   5047     sal_memset(entry, 0, sizeof(entry));
   5048 #ifdef BCM_TRIDENT3_SUPPORT
   5049     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5050         l3_entry_key_attributes_entry_t  l3_key_attr;
   5051 
   5052         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   5053                             TD3_L3_HASH_KEY_TYPE_V4MC);
   5054         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   5055                             TD3_L3_HASH_DATA_TYPE_V4MC);
   5056         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   5057         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
   5058         if (vrf_id_max) {
   5059             soc_mem_field32_set(unit, mem, entry, IPV4MC__VRF_IDf, 1);
   5060         }
   5061         /* Set L3 Entry Key Attributes */
   5062         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   5063         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5064                             BUCKET_MODEf, 1);
   5065         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5066                             KEY_BASE_WIDTHf, 0);
   5067         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5068                             KEY_WIDTHf, 23);
   5069         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5070                             DATA_BASE_WIDTHf, 1);
   5071         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5072                             HASH_LSB_OFFSETf, 5);
   5073         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   5074                           TD3_L3_HASH_KEY_TYPE_V4MC,
   5075                           (uint32*)&l3_key_attr) < 0) {
   5076             test_error(unit, "L3 Entry Key Attr setting failed\n");
   5077             goto done;
   5078         }
   5079     } else
   5080 #endif 
   5081     {
   5082     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   5083                         TD2_L3_HASH_KEY_TYPE_V4MC);
   5084     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   5085                         TD2_L3_HASH_KEY_TYPE_V4MC);
   5086     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   5087     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   5088     if (vrf_id_max) {
   5089         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   5090     } 
   5091     }
   5092 
   5093     for (ix = 0; ix < iterations; ix++) {
   5094         for (bank = 0; bank < bank_count; bank++) {
   5095 #ifdef BCM_TRIDENT3_SUPPORT
   5096             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5097                 soc_mem_field_set(unit, mem, entry,
   5098                                   IPV4MC__GROUP_IP_ADDRf, &dst_ip);
   5099                 soc_mem_field_set(unit, mem, entry,
   5100                                   IPV4MC__SOURCE_IP_ADDRf, &src_ip);
   5101                 soc_mem_field32_set(unit, mem, entry,
   5102                                   IPV4MC__VLAN_IDf, vid);
   5103                 if (vrf_id_max) {
   5104                     soc_mem_field32_set(unit, mem,entry,
   5105                                   IPV4MC__VRF_IDf, vrf_id);
   5106                 }
   5107             } else
   5108 #endif
   5109             {
   5110             soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip);
   5111             soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip);
   5112             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   5113             if (vrf_id_max) {
   5114                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   5115             } 
   5116             } 
   5117     
   5118 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   5119     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   5120             if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   5121                 SOC_IS_TRIDENT3X(unit)) {
   5122                 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   5123                                                 &num_l3_banks, l3_bucket_array,
   5124                                                 l3_index_array, phy_bank_array,
   5125                                                 NULL)) < 0) {
   5126                     cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   5127                     goto done;
   5128                 }
   5129 
   5130                 if (num_l3_banks > L3_MAX_BANKS) {
   5131                     cli_out("%s ERROR: the number of banks overflow\n",
   5132                             ARG_CMD(a));
   5133                     rv = -1;
   5134                     goto done;
   5135                 }
   5136             } else
   5137 #endif
   5138             {
   5139                 rv = -1;
   5140                 goto done;
   5141             }
   5142 
   5143             if (ad->opt_verbose) {
   5144                 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   5145                 for (bi = 0; bi < bank_count; bi++) {
   5146                     cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   5147                              bi, phy_bank_array[bi],
   5148                              l3_bucket_array[bi], l3_bucket_array[bi],
   5149                              l3_index_array[bi], l3_index_array[bi]);
   5150                 }
   5151             }
   5152     
   5153             if (ad->opt_verbose) {
   5154                 cli_out("Inserting ");
   5155                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   5156                 cli_out("\n");
   5157                 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank);
   5158             }
   5159 
   5160             banks = 1 << phy_bank_array[bank];
   5161             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   5162             if (SOC_FAILURE(r)) {
   5163                 if (r == SOC_E_FULL) {
   5164                     /* Bucket overflow, just pass on */
   5165                     continue;
   5166                 } else {
   5167                     test_error(unit, "L3 insert failed at bucket %d bank %d\n",
   5168                                l3_bucket_array[bank], bank);
   5169                     rv = -1;
   5170                     goto done;
   5171                 }
   5172             }
   5173     
   5174             /* Now we search for the entry */
   5175             hard_index = 0;
   5176             if (soc_mem_search(unit, mem, COPYNO_ALL,
   5177                                &hard_index, entry, entry_lkup, 0) < 0) {
   5178                 test_error(unit, "Entry lookup failed\n");
   5179                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5180                 goto done;
   5181             }
   5182 
   5183             /* entries per bucket */
   5184             bucket_offset = hard_index - l3_index_array[bank];
   5185             if (bucket_offset < 0 || bucket_offset >= bucket_size) {
   5186                 test_error(unit,
   5187                            "Hardware Hash %d out range of Software Hash base %d (%d)\n",
   5188                            hard_index, l3_index_array[bank], bucket_offset);
   5189                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5190                 goto done;
   5191             }
   5192 
   5193             /* Only do a quick check vs. expected bucket here */
   5194             if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) {
   5195                 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 
   5196                            bank, l3_index_array[bank]);
   5197                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5198                 rv = -1;
   5199                 goto done;
   5200             }
   5201 
   5202             /* Clean up afterward */
   5203             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   5204                 test_error(unit, "L3 delete failed at bucket %d bank %d\n",
   5205                            l3_bucket_array[bank], bank);
   5206                 rv = -1;
   5207                 goto done;
   5208             }
   5209     
   5210             src_ip += src_ip_inc;
   5211             dst_ip += dst_ip_inc;
   5212             vid += vid_inc;
   5213             if (vid > DRACO_L3_VID_MAX) {
   5214                 vid = 1;
   5215             }
   5216             if (vrf_id_max) {
   5217                 vrf_id += vrf_id_inc;
   5218                 if (vrf_id > vrf_id_max) {
   5219                     vrf_id = 0;
   5220                 }
   5221             }
   5222         }
   5223     }
   5224 
   5225  done:
   5226     return rv;
   5227 }
   5228 
   5229 int
   5230 _td2_l3ip6ucast_test_hash(int unit, args_t *a, void *p)
   5231 {
   5232     draco_l3_testdata_t         *ad = p;
   5233     uint32                      entry[SOC_MAX_MEM_WORDS];
   5234     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   5235     soc_mem_t                   mem = L3_ENTRY_IPV6_UNICASTm;
   5236     ip6_addr_t                  dst_ip;
   5237     uint32                      ip_tmp[2];
   5238     int                         dst_ip_inc;
   5239     int                         r, rv = 0;
   5240     int                         hard_index;
   5241     int                         bucket_size, bucket_offset;
   5242     int                         ix;
   5243     int                         iterations;
   5244     int                         vrf_id;
   5245     int                         vrf_id_inc;
   5246     int                         vrf_id_max = 0;
   5247     int                         bank, banks, bi;
   5248     uint32                      bank_count;
   5249     int                         num_l3_banks = 0;
   5250     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   5251     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   5252     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   5253 
   5254     COMPILER_REFERENCE(a);
   5255     vrf_id_max = SOC_VRF_MAX(unit);
   5256     bucket_size = 2;
   5257 
   5258 #ifdef BCM_TRIDENT3_SUPPORT
   5259     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5260         mem = L3_ENTRY_DOUBLEm;
   5261         bucket_size = 4;
   5262     }
   5263 #endif
   5264 
   5265     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   5266     dst_ip_inc = ad->opt_ip6_inc;
   5267     vrf_id = ad->opt_base_vrf_id;
   5268     vrf_id_inc = ad->opt_vrf_id_inc;
   5269 
   5270     if (ad->opt_verbose) {
   5271         cli_out("Starting L3 hash test\n");
   5272     }
   5273 
   5274     iterations = ad->opt_count;
   5275 
   5276     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   5277                                            &bank_count)) < 0) {
   5278         test_error(unit, "Getting bank count for L3 table failed\n");
   5279         rv = -1;
   5280         goto done;
   5281     }
   5282 
   5283     sal_memset(entry, 0, sizeof(entry));
   5284 #ifdef BCM_TRIDENT3_SUPPORT
   5285     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5286         l3_entry_key_attributes_entry_t  l3_key_attr;
   5287         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   5288                             TD3_L3_HASH_KEY_TYPE_V6UC);
   5289         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   5290                             TD3_L3_HASH_DATA_TYPE_V6UC);
   5291         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   5292         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 4);
   5293         if (vrf_id_max) {
   5294             soc_mem_field32_set(unit, mem, entry, IPV6UC__VRF_IDf, 1);
   5295         }
   5296 
   5297         /* Set L3 Entry Key Attributes */
   5298         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   5299         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5300                             BUCKET_MODEf, 1);
   5301         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5302                             KEY_BASE_WIDTHf, 1);
   5303         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5304                             KEY_WIDTHf, 15);
   5305         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5306                             DATA_BASE_WIDTHf, 2);
   5307         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5308                             HASH_LSB_OFFSETf, 5);
   5309         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   5310                           TD3_L3_HASH_KEY_TYPE_V6UC,
   5311                           (uint32*)&l3_key_attr) < 0) {
   5312             test_error(unit, "L3 Entry Key Attr setting failed\n");
   5313             goto done;
   5314         }
   5315     } else
   5316 #endif
   5317     {
   5318         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   5319                 TD2_L3_HASH_KEY_TYPE_V6UC);
   5320         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   5321                 TD2_L3_HASH_KEY_TYPE_V6UC);
   5322         if (vrf_id_max) {
   5323             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   5324         }
   5325         soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   5326         soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   5327     }
   5328     for (ix = 0; ix < iterations; ix++) {
   5329         for (bank = 0; bank < bank_count; bank++) {
   5330             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   5331                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   5332             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   5333                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   5334 #ifdef BCM_TRIDENT3_SUPPORT
   5335             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5336                 soc_mem_field_set(unit, mem, entry,
   5337                               IPV6UC__IP_ADDR_LWR_64f, ip_tmp);
   5338             } else
   5339 #endif
   5340             {
   5341             soc_mem_field_set(unit, mem, entry,
   5342                               IP_ADDR_LWR_64f, ip_tmp);
   5343             }
   5344             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   5345                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   5346             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   5347                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   5348 #ifdef BCM_TRIDENT3_SUPPORT
   5349             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   5350                 soc_mem_field_set(unit, mem, entry,
   5351                               IPV6UC__IP_ADDR_UPR_64f, ip_tmp);
   5352             } else
   5353 #endif
   5354             {
   5355             soc_mem_field_set(unit, mem, entry,
   5356                               IP_ADDR_UPR_64f, ip_tmp);
   5357             }
   5358             if (vrf_id_max) {
   5359                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   5360             } 
   5361 
   5362 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   5363     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   5364             if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   5365                 (SOC_IS_TRIDENT3X(unit))) {
   5366                 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   5367                                                 &num_l3_banks, l3_bucket_array,
   5368                                                 l3_index_array, phy_bank_array,
   5369                                                 NULL)) < 0) {
   5370                     cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   5371                     goto done;
   5372                 }
   5373 
   5374                 if (num_l3_banks > L3_MAX_BANKS) {
   5375                     cli_out("%s ERROR: the number of banks overflow\n",
   5376                             ARG_CMD(a));
   5377                     rv = -1;
   5378                     goto done;
   5379                 }
   5380             } else
   5381 #endif
   5382             {
   5383                 rv = -1;
   5384                 goto done;
   5385             }
   5386 
   5387             if (ad->opt_verbose) {
   5388                 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   5389                 for (bi = 0; bi < bank_count; bi++) {
   5390                     cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   5391                              bi, phy_bank_array[bi],
   5392                              l3_bucket_array[bi], l3_bucket_array[bi],
   5393                              l3_index_array[bi], l3_index_array[bi]);
   5394                 }
   5395             }
   5396     
   5397             if (ad->opt_verbose) {
   5398                 cli_out("Inserting ");
   5399                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   5400                 cli_out("\n");
   5401                 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank);
   5402             }
   5403 
   5404             banks = 1 << phy_bank_array[bank];
   5405             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   5406             if (SOC_FAILURE(r)) {
   5407                 if (r == SOC_E_FULL) {
   5408                     /* Bucket overflow, just pass on */
   5409                     continue;
   5410                 } else {
   5411                     test_error(unit, "L3 insert failed at bucket %d bank %d\n",
   5412                                l3_bucket_array[bank], bank);
   5413                     rv = -1;
   5414                     goto done;
   5415                 }
   5416             }
   5417     
   5418             /* Now we search for the entry */
   5419             hard_index = 0;
   5420             if (soc_mem_search(unit, mem, COPYNO_ALL,
   5421                                &hard_index, entry, entry_lkup, 0) < 0) {
   5422                 test_error(unit, "Entry lookup failed\n");
   5423                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5424                 goto done;
   5425             }
   5426     
   5427             /* entries per bucket */
   5428             bucket_offset = hard_index - l3_index_array[bank];
   5429             if (bucket_offset < 0 || bucket_offset >= bucket_size) {
   5430                 test_error(unit,
   5431                            "Hardware Hash %d out range of Software Hash base %d (%d)\n",
   5432                            hard_index, l3_index_array[bank], bucket_offset);
   5433                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5434                 goto done;
   5435             }
   5436             
   5437             /* Only do a quick check vs. expected bucket here */
   5438             if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) {
   5439                 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 
   5440                            bank, l3_index_array[bank]);
   5441                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5442                 rv = -1;
   5443                 goto done;
   5444             }
   5445     
   5446             /* Clean up afterward */
   5447             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   5448                 test_error(unit, "L3 delete failed at bucket %d bank %d\n",
   5449                            l3_bucket_array[bank], bank);
   5450                 rv = -1;
   5451                 goto done;
   5452             }
   5453             increment_ip6addr(dst_ip, 15, dst_ip_inc);
   5454             if (vrf_id_max) {
   5455                 vrf_id += vrf_id_inc;
   5456                 if (vrf_id > vrf_id_max) {
   5457                     vrf_id = 0;
   5458                 }
   5459             } 
   5460         }
   5461     }
   5462 
   5463  done:
   5464     return rv;
   5465 }
   5466 
   5467 int
   5468 _td2_l3ip6mcast_test_hash(int unit, args_t *a, void *p)
   5469 {
   5470     draco_l3_testdata_t         *ad = p;
   5471     uint32                      entry[SOC_MAX_MEM_WORDS];
   5472     uint32                      entry_lkup[SOC_MAX_MEM_WORDS];
   5473     soc_mem_t                   mem = L3_ENTRY_IPV6_MULTICASTm;
   5474     ip6_addr_t                  src_ip;
   5475     ip6_addr_t                  dst_ip;
   5476     uint32                      ip_tmp[2];
   5477     int                         src_ip_inc;
   5478     int                         dst_ip_inc;
   5479     bcm_vlan_t                  vid;
   5480     int                         vid_inc;
   5481     int                         r, rv = 0;
   5482     int                         hard_index;
   5483     int                         bucket_size, bucket_offset;
   5484     int                         ix;
   5485     int                         iterations;
   5486     int                         vrf_id;
   5487     int                         vrf_id_inc;
   5488     int                         vrf_id_max = 0; 
   5489     int                         bank, banks, bi;
   5490     uint32                      bank_count;
   5491     int                         num_l3_banks = 0;
   5492     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   5493     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   5494     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   5495 
   5496     COMPILER_REFERENCE(a);
   5497     vrf_id_max = SOC_VRF_MAX(unit);
   5498     bucket_size = 1;
   5499 
   5500 #ifdef BCM_TRIDENT3_SUPPORT
   5501     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   5502         mem = L3_ENTRY_QUADm;
   5503         bucket_size = 4;
   5504     }
   5505 #endif
   5506 
   5507     if (ad->opt_key_src_ip) {
   5508         memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t));
   5509         src_ip_inc = ad->opt_src_ip6_inc;
   5510     } else {
   5511         sal_memset (src_ip, 0, sizeof(src_ip));
   5512         src_ip_inc = 0;
   5513     }
   5514     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   5515     dst_ip_inc = ad->opt_ip6_inc;
   5516     vid = ad->opt_base_vid;
   5517     vid_inc = ad->opt_vid_inc;
   5518     vrf_id = ad->opt_base_vrf_id;
   5519     vrf_id_inc = ad->opt_vrf_id_inc;
   5520 
   5521     /*  Invalid IPMC/Unicast address checks required */
   5522 
   5523     if (ad->opt_verbose) {
   5524         cli_out("Starting L3 hash test\n");
   5525     }
   5526 
   5527     iterations = ad->opt_count;
   5528 
   5529     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   5530                                            &bank_count)) < 0) {
   5531         test_error(unit, "Getting bank count for L3 table failed\n");
   5532         rv = -1;
   5533         goto done;
   5534     }
   5535 
   5536     sal_memset(entry, 0, sizeof(entry));
   5537 #ifdef BCM_TRIDENT3_SUPPORT
   5538     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   5539         l3_entry_key_attributes_entry_t  l3_key_attr;
   5540 
   5541         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   5542                             TD3_L3_HASH_KEY_TYPE_V6MC);
   5543         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   5544                             TD3_L3_HASH_DATA_TYPE_V6MC);
   5545         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 5);
   5546         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 6);
   5547         soc_mem_field32_set(unit, mem, entry, BASE_VALID_2f, 6);
   5548         soc_mem_field32_set(unit, mem, entry, BASE_VALID_3f, 7);
   5549         if (vrf_id_max) {
   5550             soc_mem_field32_set(unit, mem, entry, IPV6MC__VRF_IDf, 1);
   5551         }
   5552 
   5553         /* Set L3 Entry Key Attributes */
   5554         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   5555         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5556                             BUCKET_MODEf, 2);
   5557         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5558                             KEY_BASE_WIDTHf, 2);
   5559         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5560                             KEY_WIDTHf, 23);
   5561         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5562                             DATA_BASE_WIDTHf, 1);
   5563         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5564                             HASH_LSB_OFFSETf, 5);
   5565         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   5566                           TD3_L3_HASH_KEY_TYPE_V6MC,
   5567                           (uint32*)&l3_key_attr) < 0) {
   5568             test_error(unit, "L3 Entry Key Attr setting failed\n");
   5569             goto done;
   5570         }
   5571     } else
   5572 #endif /* BCM_TRIDENT3_SUPPORT */
   5573     {
   5574     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   5575                         TD2_L3_HASH_KEY_TYPE_V6MC);
   5576     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   5577                         TD2_L3_HASH_KEY_TYPE_V6MC);
   5578     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f,
   5579                         TD2_L3_HASH_KEY_TYPE_V6MC);
   5580     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f,
   5581                         TD2_L3_HASH_KEY_TYPE_V6MC);
   5582     if (vrf_id_max) {
   5583         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   5584     }
   5585     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   5586     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   5587     soc_mem_field32_set(unit, mem, entry, VALID_2f, 1);
   5588     soc_mem_field32_set(unit, mem, entry, VALID_3f, 1);
   5589     }
   5590     for (ix = 0; ix < iterations; ix++) {
   5591         for (bank = 0; bank < bank_count; bank++) {
   5592             soc_field_t fld_arr1[] = { GROUP_IP_ADDR_LWR_64f,
   5593                                        GROUP_IP_ADDR_UPR_56f,
   5594                                        SOURCE_IP_ADDR_LWR_64f,
   5595                                        SOURCE_IP_ADDR_UPR_64f,
   5596                                        VLAN_IDf, VRF_IDf};
   5597             soc_field_t *p_fld_arr = fld_arr1;
   5598 #ifdef BCM_TRIDENT3_SUPPORT
   5599             soc_field_t fld_arr2[] = { IPV6MC__GROUP_IP_ADDR_LWR_64f,
   5600                                        IPV6MC__GROUP_IP_ADDR_UPR_56f,
   5601                                        IPV6MC__SOURCE_IP_ADDR_BITS_31_0f,
   5602                                        IPV6MC__SOURCE_IP_ADDR_UPR_64f,
   5603                                        IPV6MC__VLAN_IDf, IPV6MC__VRF_IDf,
   5604                                        IPV6MC__SOURCE_IP_ADDR_BITS_63_32f};
   5605 
   5606             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   5607                 p_fld_arr = fld_arr2;
   5608             }
   5609 #endif /* BCM_TRIDENT3_SUPPORT */
   5610 
   5611             dst_ip[0] = 0;
   5612             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   5613                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   5614             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   5615                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   5616             soc_mem_field_set(unit, mem, entry, p_fld_arr[0], ip_tmp);
   5617             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   5618                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   5619             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   5620                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   5621             soc_mem_field_set(unit, mem, entry, p_fld_arr[1], ip_tmp);
   5622             ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) |
   5623                          (src_ip[10] << 8) | (src_ip[11] << 0));
   5624             ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) |
   5625                          (src_ip[14] << 8) | (src_ip[15] << 0));
   5626 #ifdef BCM_TRIDENT3_SUPPORT
   5627             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   5628                 soc_mem_field_set(unit, mem, entry, p_fld_arr[2], &ip_tmp[0]);
   5629                 soc_mem_field_set(unit, mem, entry, p_fld_arr[6], &ip_tmp[1]);
   5630             } else
   5631 #endif /* BCM_TRIDENT3_SUPPORT */
   5632             {
   5633                 soc_mem_field_set(unit, mem, entry, p_fld_arr[2], ip_tmp); 
   5634             }
   5635             ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) |
   5636                          (src_ip[2] << 8) | (src_ip[3] << 0));
   5637             ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) |
   5638                          (src_ip[6] << 8) | (src_ip[7] << 0));
   5639             soc_mem_field_set(unit, mem, entry, p_fld_arr[3], ip_tmp);
   5640             soc_mem_field32_set(unit, mem, entry, p_fld_arr[4], vid);
   5641             if (vrf_id_max) {
   5642                 soc_mem_field32_set(unit, mem,entry, p_fld_arr[5], vrf_id);
   5643             } 
   5644 
   5645 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   5646     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   5647             if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   5648                 (SOC_IS_TRIDENT3X(unit))) {
   5649                 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   5650                                                 &num_l3_banks, l3_bucket_array,
   5651                                                 l3_index_array, phy_bank_array,
   5652                                                 NULL)) < 0) {
   5653                     cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   5654                     goto done;
   5655                 }
   5656 
   5657                 if (num_l3_banks > L3_MAX_BANKS) {
   5658                     cli_out("%s ERROR: the number of banks overflow\n",
   5659                             ARG_CMD(a));
   5660                     rv = -1;
   5661                     goto done;
   5662                 }
   5663             } else
   5664 #endif
   5665             {
   5666                 rv = -1;
   5667                 goto done;
   5668             }
   5669 
   5670             if (ad->opt_verbose) {
   5671                 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   5672                 for (bi = 0; bi < bank_count; bi++) {
   5673                     cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   5674                              bi, phy_bank_array[bi],
   5675                              l3_bucket_array[bi], l3_bucket_array[bi],
   5676                              l3_index_array[bi], l3_index_array[bi]);
   5677                 }
   5678             }
   5679 
   5680             if (ad->opt_verbose) {
   5681                 cli_out("Inserting ");
   5682                 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI);
   5683                 cli_out("\n");
   5684                 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank);
   5685             }
   5686 
   5687             banks = 1 << phy_bank_array[bank];
   5688             r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL);
   5689             if (SOC_FAILURE(r)) {
   5690                 if (r == SOC_E_FULL) {
   5691                     /* Bucket overflow, just pass on */
   5692                     continue;
   5693                 } else {
   5694                     test_error(unit, "L3 insert failed at bucket %d bank %d\n",
   5695                                l3_bucket_array[bank], bank);
   5696                     rv = -1;
   5697                     goto done;
   5698                 }
   5699             }
   5700     
   5701             /* Now we search for the entry */
   5702             hard_index = 0;
   5703             if (soc_mem_search(unit, mem, COPYNO_ALL,
   5704                                &hard_index, entry, entry_lkup, 0) < 0) {
   5705                 test_error(unit, "Entry lookup failed\n");
   5706                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5707                 goto done;
   5708             }
   5709     
   5710             /* entries per bucket */
   5711             bucket_offset = hard_index - l3_index_array[bank];
   5712             if (bucket_offset < 0 || bucket_offset >= bucket_size) {
   5713                 test_error(unit,
   5714                            "Hardware Hash %d out range of Software Hash base %d (%d)\n",
   5715                            hard_index, l3_index_array[bank], bucket_offset);
   5716                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5717                 goto done;
   5718             }
   5719             
   5720             /* Only do a quick check vs. expected bucket here */
   5721             if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) {
   5722                 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 
   5723                            bank, l3_index_array[bank]);
   5724                 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI);
   5725                 rv = -1;
   5726                 goto done;
   5727             }
   5728     
   5729             /* Clean up afterward */
   5730             if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) {
   5731                 test_error(unit, "L3 delete failed at bucket %d bank %d\n",
   5732                            l3_bucket_array[bank], bank);
   5733                 rv = -1;
   5734                 goto done;
   5735             }
   5736     
   5737             increment_ip6addr(src_ip, 15, src_ip_inc);
   5738             increment_ip6addr(dst_ip, 15, dst_ip_inc);
   5739             vid += vid_inc;
   5740             if (vid > DRACO_L3_VID_MAX) {
   5741                 vid = 1;
   5742             }
   5743             if (vrf_id_max) {
   5744                 vrf_id += vrf_id_inc;
   5745                 if (vrf_id > vrf_id_max) {
   5746                     vrf_id = 0;
   5747                 }
   5748             }
   5749         }
   5750     }
   5751 
   5752  done:
   5753     return rv;
   5754 }
   5755 
   5756 int
   5757 _td2_l3ip4ucast_test_ov(int unit, args_t *a, void *p)
   5758 {
   5759     uint32                     *entry_array = NULL;
   5760     uint32                      entry[SOC_MAX_MEM_WORDS];
   5761     uint32                      result[SOC_MAX_MEM_WORDS];
   5762     soc_mem_t                   mem = L3_ENTRY_IPV4_UNICASTm;
   5763     int                         bank;
   5764     uint32                      bank_count;
   5765     int                         bucket_size = SOC_TD2_L3X_BUCKET_SIZE;
   5766     int                         num_ent_per_bucket;
   5767     int                         num_bucket_per_bank;
   5768     int                         num_vbits;
   5769     int                         num_buckets; 
   5770     ip_addr_t                   dst_ip;
   5771     int                         dst_ip_inc;
   5772     bcm_vlan_t                  vid;
   5773     int                         vid_inc;
   5774     int                         r, rv = 0;
   5775     int                         ix, offset, j, idx;
   5776     int                         iterations;
   5777     draco_l3_testdata_t         *ad = p;
   5778     int                         hash = ad->opt_hash;
   5779     int                         vrf_id;
   5780     int                         vrf_id_inc;
   5781     int                         vrf_id_max = 0;
   5782     int                         alloc_sz;
   5783     int                         found;
   5784     int                         num_l3_banks = 0;
   5785     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   5786     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   5787     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   5788     int                         entry_num_array[L3_MAX_BANKS] = {0};
   5789 
   5790 
   5791     COMPILER_REFERENCE(a);
   5792     vrf_id_max = SOC_VRF_MAX(unit);
   5793     num_vbits = 1;
   5794 
   5795 #ifdef BCM_TRIDENT3_SUPPORT
   5796     if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) {
   5797         mem = L3_ENTRY_SINGLEm;
   5798     }
   5799 #endif /* BCM_TRIDENT3_SUPPORT */
   5800 
   5801     num_ent_per_bucket = bucket_size / num_vbits;
   5802     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   5803     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   5804 
   5805     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   5806                                            &bank_count)) < 0) {
   5807         test_error(unit, "Getting bank count for L3 table failed\n");
   5808         rv = -1;
   5809         goto done;
   5810     }
   5811     alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count;
   5812     entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array");
   5813     if (entry_array == NULL) {
   5814         rv = -1;
   5815         goto done;
   5816     }
   5817     for (bank = 0; bank < bank_count; bank++) {
   5818         if (ad->opt_verbose) {
   5819             cli_out("Resetting hash bank %d selection to LSB\n", bank);
   5820         }
   5821         if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank,
   5822                                                   BCM_HASH_LSB, 48)) < 0) {
   5823             test_error(unit, "Hash bank setting failed: unit %d, bank %d\n",
   5824                        unit, bank);
   5825             rv = -1;
   5826             goto done;
   5827         }
   5828     }
   5829 
   5830     if (hash != FB_HASH_LSB) {
   5831         ad->opt_hash = hash = FB_HASH_LSB;
   5832     }
   5833 
   5834     dst_ip = ad->opt_base_ip; 
   5835     dst_ip_inc = ad->opt_ip_inc; 
   5836     vid = ad->opt_base_vid;
   5837     vid_inc = ad->opt_vid_inc;
   5838     vrf_id = ad->opt_base_vrf_id;
   5839     vrf_id_inc = ad->opt_vrf_id_inc;
   5840 
   5841     sal_memset(entry, 0, sizeof(entry));
   5842 #ifdef BCM_TRIDENT3_SUPPORT
   5843     if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) {
   5844         l3_entry_key_attributes_entry_t  l3_key_attr;
   5845         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   5846                             TD2_L3_HASH_KEY_TYPE_V4UC);
   5847         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   5848                             TD2_L3_HASH_KEY_TYPE_V4UC);
   5849         soc_mem_field32_set(unit, mem, entry, BASE_VALIDf, 1);
   5850         if (vrf_id_max) {
   5851             soc_mem_field32_set(unit, mem, entry, IPV4UC__VRF_IDf, 1);
   5852         }
   5853 
   5854         /* Set L3 Entry Key Attributes */
   5855         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   5856         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5857                             BUCKET_MODEf, 0);
   5858         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5859                             KEY_BASE_WIDTHf, 0);
   5860         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5861                             KEY_WIDTHf, 12);
   5862         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5863                             DATA_BASE_WIDTHf, 1);
   5864         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   5865                             HASH_LSB_OFFSETf, 5);
   5866         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   5867                           TD3_L3_HASH_KEY_TYPE_V4UC,
   5868                           (uint32*)&l3_key_attr) < 0) {
   5869                 test_error(unit, "L3 Entry Key Attr setting failed\n");
   5870                 goto done;
   5871         }
   5872     } else
   5873 #endif
   5874     {
   5875         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   5876                 TD2_L3_HASH_KEY_TYPE_V4UC);
   5877         soc_mem_field32_set(unit, mem, entry, VALIDf, 1);
   5878         if (vrf_id_max) {
   5879             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   5880         }
   5881     }
   5882 
   5883     while (iterations--) {
   5884         sal_memset(entry_array, 0, alloc_sz);
   5885         for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) {
   5886             soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip);
   5887             if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) {
   5888                 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   5889             }
   5890             if (vrf_id_max) { 
   5891                 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   5892             }
   5893 
   5894             if (ix == 0) {
   5895 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   5896     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   5897                 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   5898                     (SOC_IS_TRIDENT3X(unit))) {
   5899                     if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   5900                                                &num_l3_banks, l3_bucket_array,
   5901                                                l3_index_array, phy_bank_array,
   5902                                                entry_num_array)) < 0) {
   5903                         cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   5904                         goto done;
   5905                     }
   5906 
   5907                     if (num_l3_banks > L3_MAX_BANKS) {
   5908                         cli_out("%s ERROR: the number of banks overflow\n",
   5909                                 ARG_CMD(a));
   5910                         rv = -1;
   5911                         goto done;
   5912                     }
   5913                     for (bank = 0; bank < bank_count; bank++) {
   5914                         num_bucket_per_bank = entry_num_array[bank] /
   5915                                               num_ent_per_bucket;
   5916                         dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 
   5917                                      dst_ip_inc : num_bucket_per_bank;
   5918                     }
   5919                 } else
   5920 #endif
   5921                 {
   5922                     rv = -1;
   5923                     goto done;
   5924                 }
   5925 
   5926                 if (ad->opt_verbose) {
   5927                     cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   5928                     for (bank = 0; bank < bank_count; bank++) {
   5929                         cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   5930                                  bank, phy_bank_array[bank], 
   5931                                  l3_bucket_array[bank], l3_bucket_array[bank],
   5932                                  l3_index_array[bank], l3_index_array[bank]);
   5933                     }
   5934                 }
   5935             }
   5936 
   5937             offset = ix * SOC_MAX_MEM_WORDS;
   5938             memcpy(&entry_array[offset], entry, sizeof(entry));
   5939             if (ad->opt_verbose) {
   5940                 cli_out("Inserting ");
   5941                 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI);
   5942             }
   5943             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, 
   5944                                      &entry_array[offset])) < 0) {
   5945                 if (r == SOC_E_FULL) {
   5946                     /* Already full, stop wasting time */
   5947                     break;
   5948                 } else {
   5949                     test_error(unit, "L3 insert failed!\n");
   5950                     rv = -1;
   5951                     goto done;
   5952                 }
   5953             }
   5954 
   5955             /* Increment key by number of buckets in the table */
   5956             dst_ip += dst_ip_inc;
   5957             vid += vid_inc;
   5958             if (vid > DRACO_L3_VID_MAX) {
   5959                 vid = 1;
   5960             }
   5961             if (vrf_id_max) { 
   5962                 vrf_id += vrf_id_inc;
   5963                 if (vrf_id > vrf_id_max) {
   5964                     vrf_id = 0;
   5965                 }
   5966             }
   5967         }
   5968 
   5969         if (ad->opt_verbose) {
   5970             cli_out("Inserting %dth entry in banks should fail\n",
   5971                     (num_ent_per_bucket * bank_count + 1));
   5972         }
   5973 
   5974         soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip);
   5975         if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) {
   5976             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   5977         }
   5978         if (vrf_id_max) { 
   5979             soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   5980         }
   5981 
   5982         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   5983             if (r != SOC_E_FULL) {
   5984                 test_error(unit, "L3 insert failed\n");
   5985                 rv = -1;
   5986                 goto done;
   5987             }
   5988         } else {
   5989             test_error(unit, "L3 insert to full bucket succeeded\n");
   5990             rv = -1;
   5991             goto done;
   5992         }
   5993 
   5994         if (ad->opt_verbose) {
   5995             cli_out("Verifying installed entries\n");
   5996         }
   5997 
   5998         /* Verify bucket contains our added entries */
   5999         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   6000             found  = 0;
   6001             offset = j * SOC_MAX_MEM_WORDS;
   6002             for (bank = 0; bank < bank_count; bank++) {
   6003                 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array,
   6004                                          &(entry_array[offset])) == 0) {
   6005                     found = 1;
   6006                     break;
   6007                 }
   6008             }
   6009             if (!found) {
   6010                 test_error(unit, 
   6011                            "%s entry j %d missing on all banks\n", 
   6012                            SOC_MEM_NAME(unit, mem), j);
   6013                 rv = -1;
   6014                 goto done;
   6015             }
   6016             if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 
   6017                                &entry_array[offset], &result, 0) < 0) {
   6018                 test_error(unit,
   6019                            "%s entry missing at bucket %d index %d on bank %d\n",
   6020                            SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 
   6021                            l3_index_array[bank], bank);
   6022                 rv = -1;
   6023                 goto done;
   6024             }
   6025             if (idx <  (l3_index_array[bank]) || 
   6026                 idx >= (l3_index_array[bank] + num_ent_per_bucket)) {
   6027                 test_error(unit, "%s entry inserted into wrong index"
   6028                            " Expected [%d-%d] Actual %d\n",
   6029                            SOC_MEM_NAME(unit, mem),
   6030                            l3_index_array[bank],
   6031                            l3_index_array[bank] + num_ent_per_bucket,
   6032                            idx);
   6033                 rv = -1;
   6034                 goto done;
   6035             }
   6036         }
   6037 
   6038         if (ad->opt_verbose) {
   6039             cli_out("Cleaning each entry on all banks...\n");
   6040         }
   6041 
   6042         /* Remove the entries that we added */
   6043         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   6044             offset = j * SOC_MAX_MEM_WORDS;
   6045             if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) {
   6046                 test_error(unit, "L3 delete j %d failed on all banks\n", j);
   6047                 rv = -1;
   6048                 goto done;
   6049             }
   6050         }
   6051 
   6052         /* Do Next bucket */
   6053         dst_ip += 1;
   6054         vid += vid_inc;
   6055         if (vid > DRACO_L3_VID_MAX) {
   6056             vid = 1;
   6057         }
   6058         if (vrf_id_max) { 
   6059             vrf_id += vrf_id_inc;
   6060             if (vrf_id > vrf_id_max) {
   6061                 vrf_id = 0;
   6062             }
   6063         }
   6064     }
   6065 
   6066 done:
   6067     if (entry_array) {
   6068         sal_free(entry_array);
   6069         entry_array = NULL;
   6070     }
   6071     return rv;
   6072 }
   6073 
   6074 int
   6075 _td2_l3ip4mcast_test_ov(int unit, args_t *a, void *p)
   6076 {
   6077     uint32                     *entry_array = NULL;
   6078     uint32                      entry[SOC_MAX_MEM_WORDS];
   6079     uint32                      result[SOC_MAX_MEM_WORDS];
   6080     soc_mem_t                   mem = L3_ENTRY_IPV4_MULTICASTm;
   6081     int                         bank;
   6082     uint32                      bank_count;
   6083     int                         bucket_size = SOC_TD2_L3X_BUCKET_SIZE;
   6084     int                         num_ent_per_bucket;
   6085     int                         num_bucket_per_bank;
   6086     int                         num_vbits;
   6087     int                         num_buckets; 
   6088     ip_addr_t                   src_ip;
   6089     ip_addr_t                   dst_ip;
   6090     int                         src_ip_inc;
   6091     int                         dst_ip_inc;
   6092     bcm_vlan_t                  vid;
   6093     int                         vid_inc;
   6094     int                         r, rv = 0;
   6095     int                         ix, offset, j, idx;
   6096     int                         iterations;
   6097     draco_l3_testdata_t         *ad = p;
   6098     int                         hash = ad->opt_hash;
   6099     int                         vrf_id;
   6100     int                         vrf_id_inc;
   6101     int                         vrf_id_max = 0;
   6102     uint32                      hash_read;
   6103     int                         alloc_sz;
   6104     int                         found;
   6105     int                         num_l3_banks = 0;
   6106     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   6107     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   6108     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   6109     int                         entry_num_array[L3_MAX_BANKS] = {0};
   6110 
   6111 
   6112     COMPILER_REFERENCE(a);
   6113     
   6114     num_vbits = 2;
   6115 #ifdef BCM_TRIDENT3_SUPPORT
   6116     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6117         mem = L3_ENTRY_DOUBLEm;
   6118         num_vbits = 1;
   6119     }
   6120 #endif /* BCM_TRIDENT3_SUPPORT */
   6121 
   6122     vrf_id_max = SOC_VRF_MAX(unit);
   6123 
   6124     num_ent_per_bucket = bucket_size / num_vbits;
   6125     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   6126     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   6127 
   6128     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   6129                                            &bank_count)) < 0) {
   6130         test_error(unit, "Getting bank count for L3 table failed\n");
   6131         rv = -1;
   6132         goto done;
   6133     }
   6134     alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count;
   6135     entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array");
   6136     if (entry_array == NULL) {
   6137         rv = -1;
   6138         goto done;
   6139     }
   6140     for (bank = 0; bank < bank_count; bank++) {
   6141         if (ad->opt_verbose) {
   6142             cli_out("Resetting hash bank %d selection to LSB\n", bank);
   6143         }
   6144         if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank,
   6145                                                   BCM_HASH_LSB, 48)) < 0) {
   6146             test_error(unit, "Hash bank setting failed: unit %d, bank %d\n",
   6147                        unit, bank);
   6148             rv = -1;
   6149             goto done;
   6150         }
   6151     }
   6152 
   6153     if (hash != FB_HASH_LSB) {
   6154         ad->opt_hash = hash = FB_HASH_LSB;
   6155     }
   6156 
   6157     if (ad->opt_key_src_ip) {
   6158         src_ip_inc = ad->opt_src_ip_inc;
   6159         src_ip = ad->opt_src_ip;
   6160     } else {
   6161         src_ip_inc = 0;
   6162         src_ip = 0;
   6163     }
   6164     dst_ip = ad->opt_base_ip; 
   6165     dst_ip_inc = ad->opt_ip_inc; 
   6166     vid = ad->opt_base_vid;
   6167     vid_inc = ad->opt_vid_inc;
   6168     vrf_id = ad->opt_base_vrf_id;
   6169     vrf_id_inc = ad->opt_vrf_id_inc;
   6170 
   6171     sal_memset (entry, 0, sizeof(entry));
   6172 #ifdef BCM_TRIDENT3_SUPPORT
   6173     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6174         l3_entry_key_attributes_entry_t  l3_key_attr;
   6175         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   6176                             TD3_L3_HASH_KEY_TYPE_V4MC);
   6177         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   6178                             TD3_L3_HASH_DATA_TYPE_V4MC);
   6179         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   6180         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
   6181         if (vrf_id_max) {
   6182             soc_mem_field32_set(unit, mem, entry, IPV4MC__VRF_IDf, 1);
   6183         }
   6184 
   6185         /* Set L3 Entry Key Attributes */
   6186         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   6187         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6188                             BUCKET_MODEf, 1);
   6189         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6190                             KEY_BASE_WIDTHf, 0);
   6191         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6192                             KEY_WIDTHf, 23);
   6193         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6194                             DATA_BASE_WIDTHf, 1);
   6195         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6196                             HASH_LSB_OFFSETf, 5);
   6197         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   6198                           TD3_L3_HASH_KEY_TYPE_V4MC,
   6199                           (uint32*)&l3_key_attr) < 0) {
   6200                 test_error(unit, "L3 Entry Key Attr setting failed\n");
   6201                 goto done;
   6202         }
   6203     } else
   6204 #endif
   6205     {
   6206     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   6207                         TD2_L3_HASH_KEY_TYPE_V4MC);
   6208     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   6209                         TD2_L3_HASH_KEY_TYPE_V4MC);
   6210     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   6211     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   6212     if (vrf_id_max) {
   6213         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   6214     } 
   6215     }
   6216     while (iterations--) {
   6217         sal_memset(entry_array, 0, alloc_sz);
   6218         for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) {
   6219 #ifdef BCM_TRIDENT3_SUPPORT
   6220             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6221                 soc_mem_field_set(unit, mem, entry,
   6222                                   IPV4MC__GROUP_IP_ADDRf, &dst_ip);
   6223                 soc_mem_field_set(unit, mem, entry,
   6224                                   IPV4MC__SOURCE_IP_ADDRf, &src_ip);
   6225                 soc_mem_field32_set(unit, mem, entry,
   6226                                   IPV4MC__VLAN_IDf, vid);
   6227                 if (vrf_id_max) {
   6228                     soc_mem_field32_set(unit, mem,entry,
   6229                                   IPV4MC__VRF_IDf, vrf_id);
   6230                 }
   6231             } else
   6232 #endif
   6233             {
   6234             soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip);
   6235             soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip);
   6236             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   6237             if (vrf_id_max) {
   6238                 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   6239             } 
   6240             }
   6241 
   6242             if (ix == 0) {
   6243 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   6244     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   6245                 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   6246                     SOC_IS_TRIDENT3X(unit)) {
   6247                     if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   6248                                                &num_l3_banks, l3_bucket_array,
   6249                                                l3_index_array, phy_bank_array,
   6250                                                entry_num_array)) < 0) {
   6251                         cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   6252                         goto done;
   6253                     }
   6254 
   6255                     if (num_l3_banks > L3_MAX_BANKS) {
   6256                         cli_out("%s ERROR: the number of banks overflow\n",
   6257                                 ARG_CMD(a));
   6258                         rv = -1;
   6259                         goto done;
   6260                     }
   6261                     for (bank = 0; bank < bank_count; bank++) {
   6262                         num_bucket_per_bank = entry_num_array[bank] /
   6263                                               num_ent_per_bucket;
   6264                         dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 
   6265                                      dst_ip_inc : num_bucket_per_bank;
   6266                     }
   6267                 } else
   6268 #endif
   6269                 {
   6270                     rv = -1;
   6271                     goto done;
   6272                 }
   6273 
   6274                 if (ad->opt_verbose) {
   6275                     cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   6276                     for (bank = 0; bank < bank_count; bank++) {
   6277                         cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   6278                                  bank, phy_bank_array[bank], 
   6279                                  l3_bucket_array[bank], l3_bucket_array[bank],
   6280                                  l3_index_array[bank], l3_index_array[bank]);
   6281                     }
   6282                 }
   6283             }
   6284 
   6285             offset = ix * SOC_MAX_MEM_WORDS;
   6286             memcpy(&entry_array[offset], entry, sizeof(entry));
   6287             if (ad->opt_verbose) {
   6288                 cli_out("Inserting ");
   6289                 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI);
   6290             }
   6291             if (READ_HASH_CONTROLr(unit, &hash_read) < 0) {
   6292                 test_error(unit, "Hash select read failed\n");
   6293                 goto done;
   6294             }
   6295             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, &entry_array[offset])) < 0) {
   6296                 if (r == SOC_E_FULL) {
   6297                     /* Already full, stop wasting time */
   6298                     break;
   6299                 } else {
   6300                     test_error(unit, "L3 insert failed!\n");
   6301                     rv = -1;
   6302                     goto done;
   6303                 }
   6304             }
   6305             if (READ_HASH_CONTROLr(unit, &hash_read) < 0) {
   6306                 test_error(unit, "Hash select read failed\n");
   6307                 goto done;
   6308             }
   6309 
   6310             /* Increment key by number of buckets in the table */
   6311             dst_ip += dst_ip_inc;
   6312             src_ip += src_ip_inc;
   6313             vid += vid_inc;
   6314             if (vid > DRACO_L3_VID_MAX) {
   6315                 vid = 1;
   6316             }
   6317             if (vrf_id_max) {
   6318                 vrf_id += vrf_id_inc;
   6319                 if (vrf_id > vrf_id_max) {
   6320                     vrf_id = 0;
   6321                 }
   6322             }
   6323         }
   6324 
   6325         if (ad->opt_verbose) {
   6326             cli_out("Inserting %dth entry in banks should fail\n",
   6327                     (num_ent_per_bucket * bank_count + 1));
   6328         }
   6329 
   6330 #ifdef BCM_TRIDENT3_SUPPORT
   6331         if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6332             soc_mem_field_set(unit, mem, entry,
   6333                               IPV4MC__GROUP_IP_ADDRf, &dst_ip);
   6334             soc_mem_field_set(unit, mem, entry,
   6335                               IPV4MC__SOURCE_IP_ADDRf, &src_ip);
   6336             soc_mem_field32_set(unit, mem, entry,
   6337                               IPV4MC__VLAN_IDf, vid);
   6338             if (vrf_id_max) {
   6339                 soc_mem_field32_set(unit, mem,entry,
   6340                               IPV4MC__VRF_IDf, vrf_id);
   6341             }
   6342         } else
   6343 #endif
   6344         {
   6345         soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip);
   6346         soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip);
   6347         soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   6348         if (vrf_id_max) {
   6349             soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id);
   6350         } 
   6351         } 
   6352         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   6353             if (r != SOC_E_FULL) {
   6354                 test_error(unit, "L3 insert failed\n");
   6355                 rv = -1;
   6356                 goto done;
   6357             }
   6358         } else {
   6359             test_error(unit, "L3 insert to full bucket succeeded\n");
   6360             rv = -1;
   6361             goto done;
   6362         }
   6363 
   6364         if (ad->opt_verbose) {
   6365             cli_out("Verifying installed entries\n");
   6366         }
   6367 
   6368         /* Verify bucket contains our added entries */
   6369         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   6370             found  = 0;
   6371             offset = j * SOC_MAX_MEM_WORDS;
   6372             for (bank = 0; bank < bank_count; bank++) {
   6373                 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array,
   6374                                          &(entry_array[offset])) == 0) {
   6375                     found = 1;
   6376                     break;
   6377                 }
   6378             }
   6379             if (!found) {
   6380                 test_error(unit, 
   6381                            "%s entry j %d missing on all banks\n", 
   6382                            SOC_MEM_NAME(unit, mem), j);
   6383                 rv = -1;
   6384                 goto done;
   6385             }
   6386             if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 
   6387                                &entry_array[offset], &result, 0) < 0) {
   6388                 test_error(unit,
   6389                            "%s entry missing at bucket %d index %d on bank %d\n",
   6390                            SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 
   6391                            l3_index_array[bank], bank);
   6392                 rv = -1;
   6393                 goto done;
   6394             }
   6395             if (idx <  (l3_index_array[bank]) || 
   6396                 idx >= (l3_index_array[bank] + num_ent_per_bucket)) {
   6397                 test_error(unit, "%s entry inserted into wrong index"
   6398                            " Expected [%d-%d] Actual %d\n",
   6399                            SOC_MEM_NAME(unit, mem),
   6400                            l3_index_array[bank],
   6401                            l3_index_array[bank] + num_ent_per_bucket,
   6402                            idx);
   6403                 rv = -1;
   6404                 goto done;
   6405             }
   6406         }
   6407 
   6408         if (ad->opt_verbose) {
   6409             cli_out("Cleaning each entry on all banks...\n");
   6410         }
   6411 
   6412         /* Remove the entries that we added */
   6413         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   6414             offset = j * SOC_MAX_MEM_WORDS;
   6415             if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) {
   6416                 test_error(unit, "L3 delete j %d failed on all banks\n", j);
   6417                 rv = -1;
   6418                 goto done;
   6419             }
   6420         }
   6421 
   6422         /* Do Next bucket */
   6423         dst_ip += 1;
   6424         src_ip += src_ip_inc;
   6425         vid += vid_inc;
   6426         if (vid > DRACO_L3_VID_MAX) {
   6427             vid = 1;
   6428         }
   6429         if (vrf_id_max) {
   6430             vrf_id += vrf_id_inc;
   6431             if (vrf_id > vrf_id_max) {
   6432                 vrf_id = 0;
   6433             }
   6434         }
   6435     }
   6436 
   6437 done:
   6438     if (entry_array) {
   6439         sal_free(entry_array);
   6440         entry_array = NULL;
   6441     }
   6442     return rv;
   6443 }
   6444 
   6445 int
   6446 _td2_l3ip6ucast_test_ov(int unit, args_t *a, void *p)
   6447 {
   6448     uint32                     *entry_array = NULL;
   6449     uint32                      entry[SOC_MAX_MEM_WORDS];
   6450     uint32                      result[SOC_MAX_MEM_WORDS];
   6451     soc_mem_t                   mem = L3_ENTRY_IPV6_UNICASTm;
   6452     int                         bank;
   6453     uint32                      bank_count;
   6454     int                         bucket_size = SOC_TD2_L3X_BUCKET_SIZE;
   6455     int                         num_ent_per_bucket;
   6456     int                         num_bucket_per_bank;
   6457     int                         num_vbits;
   6458     int                         num_buckets; 
   6459     ip6_addr_t                  dst_ip;
   6460     int                         dst_ip_inc;
   6461     uint32                      ip_tmp[2];
   6462     bcm_vlan_t                  vid;
   6463     int                         vid_inc;
   6464     int                         r, rv = 0;
   6465     int                         ix, offset, j, idx;
   6466     int                         iterations;
   6467     draco_l3_testdata_t         *ad = p;
   6468     int                         hash = ad->opt_hash;
   6469     int                         vrf_id;
   6470     int                         vrf_id_inc;
   6471     int                         vrf_id_max = 0; 
   6472     int                         alloc_sz;
   6473     int                         found;
   6474     int                         num_l3_banks = 0;
   6475     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   6476     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   6477     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   6478     int                         entry_num_array[L3_MAX_BANKS] = {0};
   6479 
   6480     COMPILER_REFERENCE(a);
   6481     vrf_id_max = SOC_VRF_MAX(unit);
   6482     num_vbits = 2;
   6483 
   6484 #ifdef BCM_TRIDENT3_SUPPORT
   6485     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6486         mem = L3_ENTRY_DOUBLEm;
   6487         num_vbits = 1;
   6488     }
   6489 #endif
   6490 
   6491     num_ent_per_bucket = bucket_size / num_vbits;
   6492     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   6493     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   6494 
   6495     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   6496                                            &bank_count)) < 0) {
   6497         test_error(unit, "Getting bank count for L3 table failed\n");
   6498         rv = -1;
   6499         goto done;
   6500     }
   6501     alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count;
   6502     entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array");
   6503     if (entry_array == NULL) {
   6504         rv = -1;
   6505         goto done;
   6506     }
   6507     for (bank = 0; bank < bank_count; bank++) {
   6508         if (ad->opt_verbose) {
   6509             cli_out("Resetting hash bank %d selection to LSB\n", bank);
   6510         }
   6511         if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank,
   6512                                                   BCM_HASH_LSB, 48)) < 0) {
   6513             test_error(unit, "Hash bank setting failed: unit %d, bank %d\n",
   6514                        unit, bank);
   6515             rv = -1;
   6516             goto done;
   6517         }
   6518     }
   6519 
   6520     if (hash != FB_HASH_LSB) {
   6521         ad->opt_hash = hash = FB_HASH_LSB;
   6522     }
   6523 
   6524     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   6525     dst_ip_inc = ad->opt_ip_inc; 
   6526     vid = ad->opt_base_vid;
   6527     vid_inc = ad->opt_vid_inc;
   6528     vrf_id = ad->opt_base_vrf_id;
   6529     vrf_id_inc = ad->opt_vrf_id_inc;
   6530     sal_memset (entry, 0, sizeof(entry));
   6531 #ifdef BCM_TRIDENT3_SUPPORT
   6532     if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6533         l3_entry_key_attributes_entry_t  l3_key_attr;
   6534         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   6535                             TD3_L3_HASH_KEY_TYPE_V6UC);
   6536         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   6537                             TD3_L3_HASH_DATA_TYPE_V6UC);
   6538         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   6539         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 4);
   6540         if (vrf_id_max) {
   6541             soc_mem_field32_set(unit, mem, entry, IPV6UC__VRF_IDf, 1);
   6542         }
   6543 
   6544         /* Set L3 Entry Key Attributes */
   6545         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   6546         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6547                             BUCKET_MODEf, 1);
   6548         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6549                             KEY_BASE_WIDTHf, 1);
   6550         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6551                             KEY_WIDTHf, 15);
   6552         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6553                             DATA_BASE_WIDTHf, 2);
   6554         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6555                             HASH_LSB_OFFSETf, 5);
   6556         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   6557                           TD3_L3_HASH_KEY_TYPE_V6UC,
   6558                           (uint32*)&l3_key_attr) < 0) {
   6559             test_error(unit, "L3 Entry Key Attr setting failed\n");
   6560             goto done;
   6561         }
   6562     } else
   6563 #endif
   6564     {
   6565         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   6566                 TD2_L3_HASH_KEY_TYPE_V6UC);
   6567         soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   6568                 TD2_L3_HASH_KEY_TYPE_V6UC);
   6569         if (vrf_id_max) {
   6570             soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   6571         }
   6572         soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   6573         soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   6574     }
   6575     while (iterations--) {
   6576         sal_memset(entry_array, 0, alloc_sz);
   6577         for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) {
   6578             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   6579                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   6580             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   6581                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   6582 #ifdef BCM_TRIDENT3_SUPPORT
   6583             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6584                 soc_mem_field_set(unit, mem, entry,
   6585                               IPV6UC__IP_ADDR_LWR_64f, ip_tmp);
   6586             } else
   6587 #endif
   6588             {
   6589 
   6590             soc_mem_field_set(unit, mem, entry,
   6591                               IP_ADDR_LWR_64f, ip_tmp);
   6592             }
   6593             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   6594                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   6595             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   6596                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   6597 #ifdef BCM_TRIDENT3_SUPPORT
   6598             if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6599                 soc_mem_field_set(unit, mem, entry,
   6600                               IPV6UC__IP_ADDR_UPR_64f, ip_tmp);
   6601             } else
   6602 #endif
   6603             {
   6604             soc_mem_field_set(unit, mem, entry,
   6605                               IP_ADDR_UPR_64f, ip_tmp);
   6606             }
   6607             if (vrf_id_max) { 
   6608                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   6609             } 
   6610 
   6611             if (ix == 0) {
   6612 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   6613     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   6614                 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   6615                     SOC_IS_TRIDENT3X(unit)) {
   6616                     if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   6617                                                &num_l3_banks, l3_bucket_array,
   6618                                                l3_index_array, phy_bank_array,
   6619                                                entry_num_array)) < 0) {
   6620                         cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   6621                         goto done;
   6622                     }
   6623 
   6624                     if (num_l3_banks > L3_MAX_BANKS) {
   6625                         cli_out("%s ERROR: the number of banks overflow\n",
   6626                                 ARG_CMD(a));
   6627                         rv = -1;
   6628                         goto done;
   6629                     }
   6630                     for (bank = 0; bank < bank_count; bank++) {
   6631                         num_bucket_per_bank = entry_num_array[bank] /
   6632                                               num_ent_per_bucket;
   6633                         dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 
   6634                                      dst_ip_inc : num_bucket_per_bank;
   6635                     }
   6636                 } else
   6637 #endif
   6638                 {
   6639                     rv = -1;
   6640                     goto done;
   6641                 }
   6642 
   6643                 if (ad->opt_verbose) {
   6644                     cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   6645                     for (bank = 0; bank < bank_count; bank++) {
   6646                         cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   6647                                  bank, phy_bank_array[bank],
   6648                                  l3_bucket_array[bank], l3_bucket_array[bank],
   6649                                  l3_index_array[bank], l3_index_array[bank]);
   6650                     }
   6651                 }
   6652             }
   6653 
   6654             offset = ix * SOC_MAX_MEM_WORDS;
   6655             memcpy(&entry_array[offset], entry, sizeof(entry));
   6656             if (ad->opt_verbose) {
   6657                 cli_out("Inserting ");
   6658                 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI);
   6659             }
   6660             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, &entry_array[offset])) < 0) {
   6661                 if (r == SOC_E_FULL) {
   6662                     /* Already full, stop wasting time */
   6663                     break;
   6664                 } else {
   6665                     test_error(unit, "L3 insert failed!\n");
   6666                     rv = -1;
   6667                     goto done;
   6668                 }
   6669             }
   6670 
   6671             /* Increment key by number of buckets in the table */
   6672             increment_ip6addr(dst_ip, 15, dst_ip_inc);
   6673             vid += vid_inc;
   6674             if (vid > DRACO_L3_VID_MAX) {
   6675                 vid = 1;
   6676             }
   6677             if (vrf_id_max) { 
   6678                 vrf_id += vrf_id_inc;
   6679                 if (vrf_id > vrf_id_max) {
   6680                     vrf_id = 0;
   6681                 }
   6682             }
   6683         }
   6684 
   6685         if (ad->opt_verbose) {
   6686             cli_out("Inserting %dth entry in banks should fail\n",
   6687                     (num_ent_per_bucket * bank_count + 1));
   6688         }
   6689 
   6690         ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   6691                      (dst_ip[10] << 8) | (dst_ip[11] << 0));
   6692         ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   6693                      (dst_ip[14] << 8) | (dst_ip[15] << 0));
   6694 #ifdef BCM_TRIDENT3_SUPPORT
   6695         if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6696             soc_mem_field_set(unit, mem, entry,
   6697                           IPV6UC__IP_ADDR_LWR_64f, ip_tmp);
   6698         } else
   6699 #endif
   6700         {
   6701         soc_mem_field_set(unit, mem, entry,
   6702                           IP_ADDR_LWR_64f, ip_tmp);
   6703         }
   6704         ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   6705                      (dst_ip[2] << 8) | (dst_ip[3] << 0));
   6706         ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   6707                      (dst_ip[6] << 8) | (dst_ip[7] << 0));
   6708 #ifdef BCM_TRIDENT3_SUPPORT
   6709         if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   6710             soc_mem_field_set(unit, mem, entry,
   6711                          IPV6UC__IP_ADDR_UPR_64f, ip_tmp);
   6712         } else
   6713 #endif
   6714         {
   6715         soc_mem_field_set(unit, mem, entry,
   6716                           IP_ADDR_UPR_64f, ip_tmp);
   6717         }
   6718         if (vrf_id_max) { 
   6719             soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   6720         } 
   6721 
   6722         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   6723             if (r != SOC_E_FULL) {
   6724                 test_error(unit, "L3 insert failed\n");
   6725                 rv = -1;
   6726                 goto done;
   6727             }
   6728         } else {
   6729             test_error(unit, "L3 insert to full bucket succeeded\n");
   6730             rv = -1;
   6731             goto done;
   6732         }
   6733 
   6734         if (ad->opt_verbose) {
   6735             cli_out("Verifying installed entries\n");
   6736         }
   6737 
   6738         /* Verify bucket contains added entries */
   6739         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   6740             found  = 0;
   6741             offset = j * SOC_MAX_MEM_WORDS;
   6742             for (bank = 0; bank < bank_count; bank++) {
   6743                 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array,
   6744                                          &(entry_array[offset])) == 0) {
   6745                     found = 1;
   6746                     break;
   6747                 }
   6748             }
   6749             if (!found) {
   6750                 test_error(unit, 
   6751                            "%s entry j %d missing on all banks\n", 
   6752                            SOC_MEM_NAME(unit, mem), j);
   6753                 rv = -1;
   6754                 goto done;
   6755             }
   6756             if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 
   6757                                &entry_array[offset], &result, 0) < 0) {
   6758                 test_error(unit,
   6759                            "%s entry missing at bucket %d index %d on bank %d\n",
   6760                            SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 
   6761                            l3_index_array[bank], bank);
   6762                 rv = -1;
   6763                 goto done;
   6764             }
   6765             if (idx <  (l3_index_array[bank]) || 
   6766                 idx >= (l3_index_array[bank] + num_ent_per_bucket)) {
   6767                 test_error(unit, "%s entry inserted into wrong index"
   6768                            " Expected [%d-%d] Actual %d\n",
   6769                            SOC_MEM_NAME(unit, mem),
   6770                            l3_index_array[bank],
   6771                            l3_index_array[bank] + num_ent_per_bucket,
   6772                            idx);
   6773                 rv = -1;
   6774                 goto done;
   6775             }
   6776         }
   6777 
   6778         if (ad->opt_verbose) {
   6779             cli_out("Cleaning each entry on all banks...\n");
   6780         }
   6781 
   6782         /* Remove the entries that we added */
   6783         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   6784             offset = j * SOC_MAX_MEM_WORDS;
   6785             if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) {
   6786                 test_error(unit, "L3 delete j %d failed on all banks\n", j);
   6787                 rv = -1;
   6788                 goto done;
   6789             }
   6790         }
   6791 
   6792         /* Do Next bucket */
   6793         increment_ip6addr(dst_ip, 15, 1);
   6794         vid += vid_inc;
   6795         if (vid > DRACO_L3_VID_MAX) {
   6796             vid = 1;
   6797         }
   6798         if (vrf_id_max) { 
   6799             vrf_id += vrf_id_inc;
   6800             if (vrf_id > vrf_id_max) {
   6801                 vrf_id = 0;
   6802             }
   6803         }
   6804     }
   6805 
   6806 done:
   6807     if (entry_array) {
   6808         sal_free(entry_array);
   6809         entry_array = NULL;
   6810     }
   6811     return rv;
   6812 }
   6813 
   6814 int
   6815 _td2_l3ip6mcast_test_ov(int unit, args_t *a, void *p)
   6816 {
   6817     uint32                     *entry_array = NULL;
   6818     uint32                      entry[SOC_MAX_MEM_WORDS];
   6819     uint32                      result[SOC_MAX_MEM_WORDS];
   6820     soc_mem_t                   mem = L3_ENTRY_IPV6_MULTICASTm;
   6821     int                         bank;
   6822     uint32                      bank_count;
   6823     int                         bucket_size = SOC_TD2_L3X_BUCKET_SIZE;
   6824     int                         num_ent_per_bucket;
   6825     int                         num_bucket_per_bank;
   6826     int                         num_vbits;
   6827     int                         num_buckets; 
   6828     ip6_addr_t                  src_ip;
   6829     ip6_addr_t                  dst_ip;
   6830     uint32                      ip_tmp[2];
   6831     int                         src_ip_inc;
   6832     int                         dst_ip_inc;
   6833     bcm_vlan_t                  vid;
   6834     int                         vid_inc;
   6835     int                         r, rv = 0;
   6836     int                         ix, offset, j, idx;
   6837     int                         iterations;
   6838     draco_l3_testdata_t         *ad = p;
   6839     int                         hash = ad->opt_hash;
   6840     int                         vrf_id;
   6841     int                         vrf_id_inc;
   6842     int                         vrf_id_max = 0;
   6843     int                         alloc_sz;
   6844     int                         found;
   6845     int                         num_l3_banks = 0;
   6846     int                         l3_index_array[L3_MAX_BANKS]  = {0};
   6847     int                         l3_bucket_array[L3_MAX_BANKS] = {0};
   6848     int                         phy_bank_array[L3_MAX_BANKS] = {0};
   6849     int                         entry_num_array[L3_MAX_BANKS] = {0};
   6850 
   6851     COMPILER_REFERENCE(a);
   6852     vrf_id_max = SOC_VRF_MAX(unit);
   6853     num_vbits = 4;
   6854 
   6855 #ifdef BCM_TRIDENT3_SUPPORT
   6856     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   6857         mem = L3_ENTRY_QUADm;
   6858         num_vbits = 1;
   6859     }
   6860 #endif
   6861     num_ent_per_bucket = bucket_size / num_vbits;
   6862     num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket;
   6863     iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count;
   6864 
   6865     if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3,
   6866                                            &bank_count)) < 0) {
   6867         test_error(unit, "Getting bank count for L3 table failed\n");
   6868         rv = -1;
   6869         goto done;
   6870     }
   6871     alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count;
   6872     entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array");
   6873     if (entry_array == NULL) {
   6874         rv = -1;
   6875         goto done;
   6876     }
   6877     for (bank = 0; bank < bank_count; bank++) {
   6878         if (ad->opt_verbose) {
   6879             cli_out("Resetting hash bank %d selection to LSB\n", bank);
   6880         }
   6881         if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank,
   6882                                                   BCM_HASH_LSB, 48)) < 0) {
   6883             test_error(unit, "Hash bank setting failed: unit %d, bank %d\n",
   6884                        unit, bank);
   6885             rv = -1;
   6886             goto done;
   6887         }
   6888     }
   6889 
   6890     if (hash != FB_HASH_LSB) {
   6891         ad->opt_hash = hash = FB_HASH_LSB;
   6892     }
   6893 
   6894     if (ad->opt_key_src_ip) {
   6895         memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t));
   6896         src_ip_inc = ad->opt_src_ip6_inc;
   6897     } else {
   6898         sal_memset (src_ip, 0, sizeof(src_ip));
   6899         src_ip_inc = 0;
   6900     }
   6901     memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t));
   6902     dst_ip_inc = ad->opt_ip_inc; 
   6903     vid = ad->opt_base_vid;
   6904     vid_inc = ad->opt_vid_inc;
   6905     vrf_id = ad->opt_base_vrf_id;
   6906     vrf_id_inc = ad->opt_vrf_id_inc;
   6907 
   6908     sal_memset (entry, 0, sizeof(entry));
   6909 #ifdef BCM_TRIDENT3_SUPPORT
   6910     if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   6911         l3_entry_key_attributes_entry_t  l3_key_attr;
   6912         soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   6913                             TD3_L3_HASH_KEY_TYPE_V6MC);
   6914         soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   6915                             TD3_L3_HASH_DATA_TYPE_V6MC);
   6916         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 5);
   6917         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 6);
   6918         soc_mem_field32_set(unit, mem, entry, BASE_VALID_2f, 6);
   6919         soc_mem_field32_set(unit, mem, entry, BASE_VALID_3f, 7);
   6920         if (vrf_id_max) {
   6921             soc_mem_field32_set(unit, mem, entry, IPV6MC__VRF_IDf, 1);
   6922         }
   6923 
   6924         /* Set L3 Entry Key Attributes */
   6925         sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr));
   6926         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6927                             BUCKET_MODEf, 2);
   6928         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6929                             KEY_BASE_WIDTHf, 2);
   6930         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6931                             KEY_WIDTHf, 23);
   6932         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6933                             DATA_BASE_WIDTHf, 1);
   6934         soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr,
   6935                             HASH_LSB_OFFSETf, 5);
   6936         if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY,
   6937                           TD3_L3_HASH_KEY_TYPE_V6MC,
   6938                           (uint32*)&l3_key_attr) < 0) {
   6939             test_error(unit, "L3 Entry Key Attr setting failed\n");
   6940             goto done;
   6941         }
   6942     } else
   6943 #endif
   6944     {
   6945     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f,
   6946                         TD2_L3_HASH_KEY_TYPE_V6MC);
   6947     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f,
   6948                         TD2_L3_HASH_KEY_TYPE_V6MC);
   6949     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f,
   6950                         TD2_L3_HASH_KEY_TYPE_V6MC);
   6951     soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f,
   6952                         TD2_L3_HASH_KEY_TYPE_V6MC);
   6953     if (vrf_id_max) { 
   6954         soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1);
   6955     } 
   6956     soc_mem_field32_set(unit, mem, entry, VALID_0f, 1);
   6957     soc_mem_field32_set(unit, mem, entry, VALID_1f, 1);
   6958     soc_mem_field32_set(unit, mem, entry, VALID_2f, 1);
   6959     soc_mem_field32_set(unit, mem, entry, VALID_3f, 1);
   6960     }
   6961     while (iterations--) {
   6962         sal_memset(entry_array, 0, alloc_sz);
   6963         for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) {
   6964             dst_ip[0] = 0;
   6965             ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   6966                          (dst_ip[10] << 8) | (dst_ip[11] << 0));
   6967             ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   6968                          (dst_ip[14] << 8) | (dst_ip[15] << 0));
   6969 #ifdef BCM_TRIDENT3_SUPPORT
   6970             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   6971                 soc_mem_field_set(unit, mem, entry,
   6972                               IPV6MC__GROUP_IP_ADDR_LWR_64f, ip_tmp);
   6973             } else
   6974 #endif
   6975             {
   6976             soc_mem_field_set(unit, mem, entry,
   6977                               GROUP_IP_ADDR_LWR_64f, ip_tmp);
   6978             }
   6979             ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   6980                          (dst_ip[2] << 8) | (dst_ip[3] << 0));
   6981             ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   6982                          (dst_ip[6] << 8) | (dst_ip[7] << 0));
   6983 #ifdef BCM_TRIDENT3_SUPPORT
   6984             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   6985                 soc_mem_field_set(unit, mem, entry,
   6986                               IPV6MC__GROUP_IP_ADDR_UPR_56f, ip_tmp);
   6987             } else
   6988 #endif
   6989             {
   6990             soc_mem_field_set(unit, mem, entry,
   6991                               GROUP_IP_ADDR_UPR_56f, ip_tmp);
   6992             }
   6993             ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) |
   6994                          (src_ip[10] << 8) | (src_ip[11] << 0));
   6995             ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) |
   6996                          (src_ip[14] << 8) | (src_ip[15] << 0));
   6997 #ifdef BCM_TRIDENT3_SUPPORT
   6998             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   6999                 soc_mem_field_set(unit, mem, entry,
   7000                               IPV6MC__SOURCE_IP_ADDR_BITS_63_32f, &ip_tmp[1]);
   7001                 soc_mem_field_set(unit, mem, entry,
   7002                               IPV6MC__SOURCE_IP_ADDR_BITS_31_0f, &ip_tmp[0]);
   7003             } else
   7004 #endif
   7005             {
   7006             soc_mem_field_set(unit, mem, entry,
   7007                               SOURCE_IP_ADDR_LWR_64f, ip_tmp);
   7008             }
   7009             ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) |
   7010                          (src_ip[2] << 8) | (src_ip[3] << 0));
   7011             ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) |
   7012                          (src_ip[6] << 8) | (src_ip[7] << 0));
   7013 #ifdef BCM_TRIDENT3_SUPPORT
   7014             if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   7015                 soc_mem_field_set(unit, mem, entry,
   7016                                   IPV6MC__SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   7017                 soc_mem_field32_set(unit, mem, entry, IPV6MC__VLAN_IDf, vid);
   7018                 if (vrf_id_max) {
   7019                     soc_mem_field32_set(unit, mem,entry, IPV6MC__VRF_IDf, vrf_id);
   7020                 }
   7021             } else
   7022 #endif
   7023             {
   7024             soc_mem_field_set(unit, mem, entry,
   7025                               SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   7026             soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   7027             if (vrf_id_max) { 
   7028                 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   7029             } 
   7030             } 
   7031 
   7032             if (ix == 0) {
   7033 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||   \
   7034     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   7035                 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   7036                     SOC_IS_TRIDENT3X(unit)) {
   7037                     if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry,
   7038                                                &num_l3_banks, l3_bucket_array,
   7039                                                l3_index_array, phy_bank_array,
   7040                                                entry_num_array)) < 0) {
   7041                         cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv));
   7042                         goto done;
   7043                     }
   7044 
   7045                     if (num_l3_banks > L3_MAX_BANKS) {
   7046                         cli_out("%s ERROR: the number of banks overflow\n",
   7047                                 ARG_CMD(a));
   7048                         rv = -1;
   7049                         goto done;
   7050                     }
   7051                     for (bank = 0; bank < bank_count; bank++) {
   7052                         num_bucket_per_bank = entry_num_array[bank] /
   7053                                               num_ent_per_bucket;
   7054                         dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 
   7055                                      dst_ip_inc : num_bucket_per_bank;
   7056                     }
   7057                 } else
   7058 #endif
   7059                 {
   7060                     rv = -1;
   7061                     goto done;
   7062                 }
   7063 
   7064                 if (ad->opt_verbose) {
   7065                     cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem));
   7066                     for (bank = 0; bank < bank_count; bank++) {
   7067                         cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n",
   7068                                  bank, phy_bank_array[bank],
   7069                                  l3_bucket_array[bank], l3_bucket_array[bank],
   7070                                  l3_index_array[bank], l3_index_array[bank]);
   7071                     }
   7072                 }
   7073             }
   7074 
   7075             offset = ix * SOC_MAX_MEM_WORDS;
   7076             memcpy(&entry_array[offset], entry, sizeof(entry));
   7077             if (ad->opt_verbose) {
   7078                 cli_out("Inserting ");
   7079                 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI);
   7080             }
   7081             if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, &entry_array[offset])) < 0) {
   7082                 if (r == SOC_E_FULL) {
   7083                     /* Already full, stop wasting time */
   7084                     break;
   7085                 } else {
   7086                     test_error(unit, "L3 insert failed!\n");
   7087                     rv = -1;
   7088                     goto done;
   7089                 }
   7090             }
   7091 
   7092             /* Increment key by number of buckets in the table */
   7093             increment_ip6addr(dst_ip, 15, dst_ip_inc);
   7094             increment_ip6addr(src_ip, 15, src_ip_inc);
   7095             vid += vid_inc;
   7096             if (vid > DRACO_L3_VID_MAX) {
   7097                 vid = 1;
   7098             }
   7099             if (vrf_id_max) { 
   7100                 vrf_id += vrf_id_inc;
   7101                 if (vrf_id > vrf_id_max) {
   7102                     vrf_id = 0;
   7103                 }
   7104             }  
   7105         }
   7106 
   7107         if (ad->opt_verbose) {
   7108             cli_out("Inserting %dth entry in banks should fail\n",
   7109                     (num_ent_per_bucket * bank_count + 1));
   7110         }
   7111 
   7112         dst_ip[0] = 0;
   7113         ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) |
   7114                      (dst_ip[10] << 8) | (dst_ip[11] << 0));
   7115         ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) |
   7116                      (dst_ip[14] << 8) | (dst_ip[15] << 0));
   7117 #ifdef BCM_TRIDENT3_SUPPORT
   7118         if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   7119             soc_mem_field_set(unit, mem, entry,
   7120                           IPV6MC__GROUP_IP_ADDR_LWR_64f, ip_tmp);
   7121         } else
   7122 #endif
   7123         {
   7124         soc_mem_field_set(unit, mem, entry,
   7125                           GROUP_IP_ADDR_LWR_64f, ip_tmp);
   7126         }
   7127         ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) |
   7128                      (dst_ip[2] << 8) | (dst_ip[3] << 0));
   7129         ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) |
   7130                      (dst_ip[6] << 8) | (dst_ip[7] << 0));
   7131 #ifdef BCM_TRIDENT3_SUPPORT
   7132         if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   7133             soc_mem_field_set(unit, mem, entry,
   7134                           IPV6MC__GROUP_IP_ADDR_UPR_56f, ip_tmp);
   7135         } else
   7136 #endif
   7137         {
   7138         soc_mem_field_set(unit, mem, entry,
   7139                           GROUP_IP_ADDR_UPR_56f, ip_tmp);
   7140         }
   7141         ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) |
   7142                      (src_ip[10] << 8) | (src_ip[11] << 0));
   7143         ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) |
   7144                      (src_ip[14] << 8) | (src_ip[15] << 0));
   7145 #ifdef BCM_TRIDENT3_SUPPORT
   7146         if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   7147             soc_mem_field_set(unit, mem, entry,
   7148                           IPV6MC__SOURCE_IP_ADDR_BITS_63_32f, &ip_tmp[1]);
   7149             soc_mem_field_set(unit, mem, entry,
   7150                           IPV6MC__SOURCE_IP_ADDR_BITS_31_0f, &ip_tmp[0]);
   7151         } else
   7152 #endif
   7153         {
   7154         soc_mem_field_set(unit, mem, entry,
   7155                           SOURCE_IP_ADDR_LWR_64f, ip_tmp);
   7156         }
   7157         ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) |
   7158                      (src_ip[2] << 8) | (src_ip[3] << 0));
   7159         ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) |
   7160                      (src_ip[6] << 8) | (src_ip[7] << 0));
   7161 #ifdef BCM_TRIDENT3_SUPPORT
   7162         if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   7163             soc_mem_field_set(unit, mem, entry,
   7164                           IPV6MC__SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   7165         } else
   7166 #endif
   7167         {
   7168         soc_mem_field_set(unit, mem, entry,
   7169                           SOURCE_IP_ADDR_UPR_64f, ip_tmp);
   7170         }
   7171 #ifdef BCM_TRIDENT3_SUPPORT
   7172         if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) {
   7173             soc_mem_field32_set(unit, mem, entry, IPV6MC__VLAN_IDf, vid);
   7174             if (vrf_id_max) {
   7175                 soc_mem_field32_set(unit, mem,entry, IPV6MC__VRF_IDf, vrf_id);
   7176             }
   7177         } else
   7178 #endif
   7179         {
   7180         soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid);
   7181         if (vrf_id_max) { 
   7182             soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id);
   7183         }
   7184         }
   7185 
   7186         if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) {
   7187             if (r != SOC_E_FULL) {
   7188                 test_error(unit, "L3 insert failed\n");
   7189                 rv = -1;
   7190                 goto done;
   7191             }
   7192         } else {
   7193             test_error(unit, "L3 insert to full bucket succeeded\n");
   7194             rv = -1;
   7195             goto done;
   7196         }
   7197 
   7198         if (ad->opt_verbose) {
   7199             cli_out("Verifying installed entries\n");
   7200         }
   7201 
   7202         /* Verify bucket contains added entries */
   7203         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   7204             found  = 0;
   7205             offset = j * SOC_MAX_MEM_WORDS;
   7206             for (bank = 0; bank < bank_count; bank++) {
   7207                 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array,
   7208                                          &(entry_array[offset])) == 0) {
   7209                     found = 1;
   7210                     break;
   7211                 }
   7212             }
   7213             if (!found) {
   7214                 test_error(unit, 
   7215                            "%s entry j %d missing on all banks\n", 
   7216                            SOC_MEM_NAME(unit, mem), j);
   7217                 rv = -1;
   7218                 goto done;
   7219             }
   7220             if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 
   7221                                &entry_array[offset], &result, 0) < 0) {
   7222                 test_error(unit,
   7223                            "%s entry missing at bucket %d index %d on bank %d\n",
   7224                            SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 
   7225                            l3_index_array[bank], bank);
   7226                 rv = -1;
   7227                 goto done;
   7228             }
   7229             if (idx <  (l3_index_array[bank]) || 
   7230                 idx >= (l3_index_array[bank] + num_ent_per_bucket)) {
   7231                 test_error(unit, "%s entry inserted into wrong index"
   7232                            " Expected [%d-%d] Actual %d\n",
   7233                            SOC_MEM_NAME(unit, mem),
   7234                            l3_index_array[bank],
   7235                            l3_index_array[bank] + num_ent_per_bucket,
   7236                            idx);
   7237                 rv = -1;
   7238                 goto done;
   7239             }
   7240         }
   7241 
   7242         if (ad->opt_verbose) {
   7243             cli_out("Cleaning each entry on all banks...\n");
   7244         }
   7245 
   7246         /* Remove the entries that we added */
   7247         for (j = 0; j < num_ent_per_bucket * bank_count; j++) {
   7248             offset = j * SOC_MAX_MEM_WORDS;
   7249             if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) {
   7250                 test_error(unit, "L3 delete j %d failed on all banks\n", j);
   7251                 rv = -1;
   7252                 goto done;
   7253             }
   7254         }
   7255 
   7256         /* Do Next bucket */
   7257         increment_ip6addr(dst_ip, 15, 1);
   7258         increment_ip6addr(src_ip, 15, src_ip_inc);
   7259         vid += vid_inc;
   7260         if (vid > DRACO_L3_VID_MAX) {
   7261             vid = 1;
   7262         }
   7263         if (vrf_id_max) { 
   7264             vrf_id += vrf_id_inc;
   7265             if (vrf_id > vrf_id_max) {
   7266                 vrf_id = 0;
   7267             }
   7268         }
   7269     }
   7270 
   7271 done:
   7272     if (entry_array) {
   7273         sal_free(entry_array);
   7274         entry_array = NULL;
   7275     }
   7276     return rv;
   7277 }
   7278 
   7279 int
   7280 td2_l3_test_hash(int unit, args_t *a, void *p)
   7281 {
   7282     draco_l3_testdata_t         *ad = p;
   7283     int                         ipv6_enable = ad->ipv6;
   7284     int                         ipmc_enable = ad->opt_ipmc_enable;
   7285 
   7286     if (ipv6_enable) {
   7287         if (ipmc_enable) {
   7288             return (_td2_l3ip6mcast_test_hash(unit, a, p));
   7289         } else {
   7290             return (_td2_l3ip6ucast_test_hash(unit, a, p));
   7291         }
   7292     } else {
   7293         if (ipmc_enable) {
   7294             return (_td2_l3ip4mcast_test_hash(unit, a, p));
   7295         } else {
   7296             return (_td2_l3ip4ucast_test_hash(unit, a, p));
   7297         }
   7298     }
   7299 }
   7300 
   7301 int
   7302 td2_l3_test_ov(int unit, args_t *a, void *p)
   7303 {
   7304     draco_l3_testdata_t         *ad = p;
   7305     int                         ipv6_enable = ad->ipv6;
   7306     int                         ipmc_enable = ad->opt_ipmc_enable;
   7307 
   7308     if (ipv6_enable) {
   7309         if (ipmc_enable) {
   7310             return (_td2_l3ip6mcast_test_ov(unit, a, p));
   7311         } else {
   7312             return (_td2_l3ip6ucast_test_ov(unit, a, p));
   7313         }
   7314     } else {
   7315         if (ipmc_enable) {
   7316             return (_td2_l3ip4mcast_test_ov(unit, a, p));
   7317         } else {
   7318             return (_td2_l3ip4ucast_test_ov(unit, a, p));
   7319         }
   7320     }
   7321 }
   7322 #endif /* BCM_TRIDENT2_SUPPORT */
   7323 #endif /* BCM_FIREBOLT_SUPPORT */
   7324 
   7325 
   7326 /*
   7327  * Test of L3 hashing
   7328  *
   7329  *   This test tries a number of keys against one of the hashing functions,
   7330  *   checking a software hash against the hardware hash, then searching the
   7331  *   bucket to find the entry after inserting.
   7332  */
   7333 int
   7334 fb_l3_test_hash(int unit, args_t *a, void *p)
   7335 {
   7336     draco_l3_testdata_t         *ad = p;
   7337     int                         ipv6_enable = ad->ipv6;
   7338 #ifdef BCM_FIREBOLT_SUPPORT
   7339     int                         ipmc_enable = ad->opt_ipmc_enable;
   7340 #endif /* BCM_FIREBOLT_SUPPORT */
   7341 
   7342 #ifdef BCM_FIREBOLT_SUPPORT
   7343 #if defined(BCM_TRIDENT2_SUPPORT)
   7344     if (SOC_IS_TD2_TT2(unit)) {
   7345         return td2_l3_test_hash(unit, a, p);
   7346     }
   7347 #endif /* BCM_TRIDENT2_SUPPORT */
   7348 
   7349     if (ipv6_enable) {
   7350         if (ipmc_enable) {
   7351             return (_fb_l3ip6mcast_test_hash(unit, a, p));
   7352         } else {
   7353             return (_fb_l3ip6ucast_test_hash(unit, a, p));
   7354         }
   7355     } else {
   7356         if (ipmc_enable) {
   7357             return (_fb_l3ip4mcast_test_hash(unit, a, p));
   7358         } else {
   7359             return (_fb_l3ip4ucast_test_hash(unit, a, p));
   7360         }
   7361     }
   7362 #endif /* BCM_FIREBOLT_SUPPORT */
   7363     return SOC_E_NONE;
   7364 }
   7365 
   7366 /*
   7367  * Test of L3 overflow behavior
   7368  *
   7369  *   This test fills each bucket of the L3, then inserts another entry to see
   7370  *   that the last entry fails to insert.
   7371  */
   7372 
   7373 int
   7374 fb_l3_test_ov(int unit, args_t *a, void *p)
   7375 {
   7376     draco_l3_testdata_t         *ad = p;
   7377     int                         ipv6_enable = ad->ipv6;
   7378     uint32                      hash = ad->opt_hash;
   7379 #ifdef BCM_FIREBOLT_SUPPORT
   7380     int                         ipmc_enable = ad->opt_ipmc_enable;
   7381 #endif /* BCM_FIREBOLT_SUPPORT */
   7382 
   7383     if (hash != FB_HASH_LSB) {
   7384         if (ad->opt_verbose) {
   7385             cli_out("Resetting hash selection to LSB\n");
   7386         }
   7387 
   7388         hash = ad->save_hash_control;
   7389         soc_reg_field_set(unit, HASH_CONTROLr, &hash,
   7390                           L3_HASH_SELECTf, FB_HASH_LSB);
   7391 
   7392         if (WRITE_HASH_CONTROLr(unit, hash) < 0) {
   7393             test_error(unit, "Hash select setting failed\n");
   7394             return(-1);
   7395         }
   7396 
   7397 #ifdef BCM_TRIDENT3_SUPPORT
   7398         if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) {
   7399             int rv = 0;
   7400             rv = td3_entry_hash_control_set(unit, FB_HASH_LSB,
   7401                     L3_ENTRY_HASH_CONTROLm,
   7402                     (uint32 *)&ad->save_l3_entry_hash_control);
   7403             if (rv < 0) {
   7404                 test_error(unit, "Hash Control write failed");
   7405                 return rv;
   7406             }
   7407         }
   7408 #endif
   7409 
   7410         ad->opt_hash = hash = FB_HASH_LSB;
   7411     }
   7412 
   7413 #ifdef BCM_FIREBOLT_SUPPORT
   7414 #if defined(BCM_TRIDENT2_SUPPORT)
   7415     if (SOC_IS_TD2_TT2(unit)) {
   7416         return td2_l3_test_ov(unit, a, p);
   7417     }
   7418 #endif /* BCM_TRIDENT2_SUPPORT */
   7419 
   7420     if (ipv6_enable) {
   7421         if (ipmc_enable) {
   7422             return (_fb_l3ip6mcast_test_ov(unit, a, p));
   7423         } else {
   7424             return (_fb_l3ip6ucast_test_ov(unit, a, p));
   7425         }
   7426     } else {
   7427         if (ipmc_enable) {
   7428             return (_fb_l3ip4mcast_test_ov(unit, a, p));
   7429         } else {
   7430             return (_fb_l3ip4ucast_test_ov(unit, a, p));
   7431         }
   7432     }
   7433 #endif /* BCM_FIREBOLT_SUPPORT */
   7434     return SOC_E_NONE;
   7435 }
   7436 
   7437 int
   7438 fb_l3_test_done(int unit, void *p)
   7439 {
   7440     draco_l3_testdata_t *ad = p;
   7441     soc_mem_t tmem = INVALIDm;
   7442     soc_field_t      vldf = VALIDf;
   7443 
   7444     if (ad == NULL) {
   7445 	return 0;
   7446     }
   7447 
   7448     if (SOC_IS_FBX(unit)) {
   7449         tmem = L3_ENTRY_IPV4_UNICASTm;
   7450         if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) {
   7451             tmem = L3_ENTRY_DOUBLEm;
   7452             vldf = BASE_VALID_0f;
   7453         }
   7454     } else {
   7455         return (-1);
   7456     }
   7457 
   7458     /* Check if empty at the end of the test */
   7459     if (ad->opt_reset) {
   7460         int rv, ix;
   7461         int index_min = soc_mem_index_min(unit, tmem);
   7462         int index_max = soc_mem_index_max(unit, tmem);
   7463         uint32 *buf = 0;
   7464         uint32 *ent = 0;
   7465         uint32 count;
   7466 
   7467         buf = soc_cm_salloc(unit,
   7468                             SOC_MEM_TABLE_BYTES(unit, tmem),
   7469                             "fb_l3_test");
   7470         if (!buf) {
   7471             test_error(unit, "Memory allocation failed\n");
   7472             return (-1);
   7473         }
   7474 
   7475         if ((rv = soc_mem_read_range(unit, tmem,
   7476                         MEM_BLOCK_ANY, index_min, index_max, buf)) < 0) {
   7477             test_error(unit, "Memory DMA of L3 Entry failed\n");
   7478             return (-1);
   7479         }
   7480 
   7481         count = soc_mem_index_count(unit, tmem);
   7482         for (ix = 0; ix < count; ix++) {
   7483             ent = soc_mem_table_idx_to_pointer(unit, tmem, uint32 *, buf, ix);
   7484             if (soc_mem_field32_get(unit, tmem, ent, vldf)) {
   7485                 test_error(unit, "L3 table not empty after test ent = %d\n",
   7486                                 ix);
   7487                 soc_mem_entry_dump(unit, tmem, ent, BSL_LSS_CLI);
   7488                 return (-1);
   7489             }
   7490         }
   7491 
   7492         soc_cm_sfree(unit, buf);
   7493     }
   7494 
   7495     if (WRITE_HASH_CONTROLr(unit, ad->save_hash_control) < 0) {
   7496         test_error(unit, "Hash select restore failed\n");
   7497     }
   7498     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
   7499 #ifdef BCM_TRIDENT3_SUPPORT
   7500         if (soc_mem_is_valid(unit, L2_ENTRY_HASH_CONTROLm)) {
   7501             if (soc_mem_write(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY,
   7502                              0, &ad->save_l3_entry_hash_control) < 0) {
   7503                 test_error(unit, "L2 Entry hash control setting failed\n");
   7504             }
   7505             if (soc_mem_write(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY,
   7506                              0, &ad->save_shared_entry_hash_control) < 0) {
   7507                 test_error(unit, "Shared Table hash control setting failed\n");
   7508             }
   7509         } else
   7510 #endif /* BCM_TRIDENT3_SUPPORT */
   7511         {
   7512             if (WRITE_L2_TABLE_HASH_CONTROLr(unit,
   7513                       ad->save_l3_table_hash_control) < 0) {
   7514             test_error(unit, "L2 Table hash control setting failed\n");
   7515         }
   7516         if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr))
   7517         {
   7518             if (WRITE_SHARED_TABLE_HASH_CONTROLr(unit, ad->save_shared_table_hash_control) < 0) {
   7519                 test_error(unit, "Shared Table hash control setting failed\n");
   7520             }
   7521         } 
   7522       }
   7523     } else {
   7524         if (soc_feature(unit, soc_feature_dual_hash)) {
   7525             if (ad->save_dual_hash_control != ad->opt_dual_hash) {
   7526                 if (WRITE_L3_AUX_HASH_CONTROLr(unit,
   7527                                                ad->save_dual_hash_control) < 0) {
   7528                     test_error(unit, "Dual Hash select restore failed\n");
   7529                 }
   7530             }
   7531         }
   7532     }
   7533 
   7534     return 0;
   7535 }
   7536 #endif
   7537 
   7538 #endif /* INCLUDE_L3 */
   7539 
   7540 #endif /* BCM_XGS_SWITCH_SUPPORT */
   7541 #else
   7542 /*ISO C forbids an empty source file */
   7543 #include <bcm/types.h>
   7544 #endif /* BCM_ESW_SUPPORT */
   7545