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

tabledma.c (68396B)


      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  * Table DMA Test
      8  */
      9 #include <shared/bsl.h>
     10 #include <sal/appl/sal.h>
     11 #include <appl/diag/system.h>
     12 #include <appl/diag/parse.h>
     13 #include <soc/mem.h>
     14 #include <soc/debug.h>
     15 #include <soc/dma.h>
     16 #include <soc/l2x.h>
     17 #include "testlist.h"
     18 
     19 #if defined (BCM_TOMAHAWK_SUPPORT)
     20 #include <soc/tomahawk.h>
     21 #endif
     22 
     23 #if defined (BCM_TOMAHAWK2_SUPPORT)
     24 #include <soc/tomahawk2.h>
     25 #endif
     26 
     27 #if defined (BCM_TRIDENT3_SUPPORT)
     28 #include <soc/trident3.h>
     29 #endif
     30 
     31 #if defined (BCM_HELIX5_SUPPORT)
     32 #include <soc/helix5.h>
     33 #endif
     34 
     35 #if defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TRIDENT3_SUPPORT)
     36 #include <soc/pstats.h>
     37 #endif
     38 
     39 #ifdef BCM_PETRA_SUPPORT
     40 #include <soc/dpp/drv.h>
     41 #endif /* BCM_PETRA_SUPPORT */
     42 #ifdef BCM_DFE_SUPPORT
     43 #include <soc/dfe/cmn/dfe_drv.h>
     44 #endif /* BCM_DFE_SUPPORT */
     45 #ifdef BCM_DNXF_SUPPORT
     46 #include <soc/dnxf/cmn/dnxf_drv.h>
     47 #endif /* BCM_DNXF_SUPPORT */
     48 #ifdef BCM_SAND_SUPPORT
     49 #include <soc/sand/sand_mem.h>
     50 #endif
     51 #if defined(BCM_DFE_SUPPORT)  || defined(BCM_PETRA_SUPPORT) || defined(BCM_DNXF_SUPPORT)
     52 extern int bcm_common_linkscan_enable_set(int,int);
     53 #endif
     54 
     55 int compare_with_mask(const void *m1_void, const void *m2_void, size_t len);
     56 
     57 #define TD_DEFAULT_ROM_VER_COUNT     10
     58 #define TD_DEFAULT_DUMP_ENTRY_COUNT  10
     59 
     60 #if defined(BCM_XGS_SWITCH_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined (BCM_PETRA_SUPPORT) || defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT)
     61 
     62 typedef struct tdt_data_s {
     63     int             init_done;
     64     int             orig_enable;
     65     int             saved_tcam_protect_write;
     66     int             mem_scan;
     67     int             scan_rate;
     68     sal_usecs_t     scan_interval;
     69     int             sram_scan;
     70     int             sram_scan_rate;
     71     sal_usecs_t     sram_scan_interval;
     72     char           *mem_str;
     73     soc_mem_t       mem;
     74     soc_mem_t       mem_write;
     75     int             copyno;
     76     int             index_min;
     77     int             index_max;
     78     int             count;
     79     int             rom_ver_count;
     80 
     81     uint32         *source;
     82     uint32          srcaddr;
     83     uint32         *dma_ed;
     84     uint32          dstaddr;
     85 
     86     soc_mem_cmp_t   comp_fn;
     87     int             bufwords;
     88     int             entwords;
     89 
     90     uint32          rnum;
     91     int             ecc_as_data; /* treat ecc field as regular field */
     92 
     93     uint32         datamask[SOC_MAX_MEM_WORDS];
     94     uint32         tcammask[SOC_MAX_MEM_WORDS];
     95     uint32         eccmask[SOC_MAX_MEM_WORDS];
     96     uint32         forcemask[SOC_MAX_MEM_WORDS];
     97     uint32         forcedata[SOC_MAX_MEM_WORDS];
     98     uint32         accum_tcammask;
     99     uint32         accum_forcemask;
    100     int            ccm;
    101     int            tslam_en;    /* Table slam Enable */
    102     int            tslam_dir;   /* Table slam direction */
    103     int            tdma_en;     /* Table dma enable */
    104     int            mor_en;
    105     int            pstats_ucq;
    106     int            td_check_data;
    107 } td_test_data_t;
    108 
    109 
    110 static td_test_data_t td_test_data;
    111 
    112 static int td_test_mem_cmp_fn(int, void*, void*);
    113 
    114 STATIC int
    115 td_rand_common_clear(int unit, soc_mem_t mem, int copyno)
    116 {
    117     int rv;
    118 
    119     SOC_MEM_TEST_SKIP_CACHE_SET(unit, 1);
    120     if ((rv = soc_mem_parity_control(unit, mem, copyno, FALSE)) < 0) {
    121         test_error(unit, "Could not disable parity warnings on memory %s\n",
    122                    SOC_MEM_UFNAME(unit, mem));
    123         return -1;
    124     }
    125 #ifdef INCLUDE_MEM_SCAN
    126     if(!SOC_IS_DNX(unit)) {
    127         if ((td_test_data.mem_scan =
    128                  soc_mem_scan_running(unit, &td_test_data.scan_rate,
    129                                       &td_test_data.scan_interval)) > 0) {
    130             if (soc_mem_scan_stop(unit)) {
    131                 return -1;
    132             }
    133         }
    134     }
    135 #endif /* INCLUDE_MEM_SCAN */
    136 #ifdef BCM_SRAM_SCAN_SUPPORT
    137     if(!SOC_IS_DNX(unit)) {
    138         if ((td_test_data.sram_scan =
    139                  soc_sram_scan_running(unit, &td_test_data.sram_scan_rate,
    140                                       &td_test_data.sram_scan_interval)) > 0) {
    141             if (soc_sram_scan_stop(unit)) {
    142                 return -1;
    143             }
    144         }
    145     }
    146 #endif /* BCM_SRAM_SCAN_SUPPORT */
    147     return 0;
    148 }
    149 
    150 STATIC int
    151 td_rand_common_restore(int unit, soc_mem_t mem, int copyno)
    152 {
    153     SOC_MEM_TEST_SKIP_CACHE_SET(unit, 0);
    154     if (soc_mem_parity_restore(unit, mem, copyno) < 0) {
    155         test_error(unit, "Could not enable parity warnings on memory %s\n",
    156                    SOC_MEM_UFNAME(unit, mem));
    157         return -1;
    158     }
    159 #ifdef INCLUDE_MEM_SCAN
    160     if (td_test_data.mem_scan) {
    161         if (soc_mem_scan_start(unit, td_test_data.scan_rate,
    162             td_test_data.scan_interval)) {
    163             return -1;
    164         }
    165     }
    166 #endif /* INCLUDE_MEM_SCAN */
    167 #ifdef BCM_SRAM_SCAN_SUPPORT
    168     if (td_test_data.sram_scan) {
    169         if (soc_sram_scan_start(unit, td_test_data.sram_scan_rate,
    170             td_test_data.sram_scan_interval)) {
    171             return -1;
    172         }
    173     }
    174 #endif /* BCM_SRAM_SCAN_SUPPORT */
    175     return 0;
    176 }
    177 
    178 static int
    179 td_test_data_init(int unit, int alloc)
    180 {
    181     int i;
    182 
    183     if (!td_test_data.init_done) {
    184 #ifdef BCM_FIREBOLT_SUPPORT
    185          if (SOC_IS_FBX(unit)) {
    186 #ifdef BCM_TRIUMPH3_SUPPORT
    187             if (SOC_IS_TRIUMPH3(unit)) {
    188                 td_test_data.mem = L2_ENTRY_1m;
    189                 td_test_data.mem_str = sal_strdup("l2_entry_1");
    190                 td_test_data.count = soc_mem_index_count(unit, L2_ENTRY_1m);
    191             } else
    192 #endif
    193 #ifdef BCM_TRIDENT3_SUPPORT
    194             if (SOC_IS_TRIDENT3X(unit)) {
    195                 td_test_data.mem = L2_ENTRY_ONLY_SINGLEm;
    196                 td_test_data.mem_str = sal_strdup("l2_entry_only_single");
    197                 td_test_data.count = soc_mem_index_count(unit, L2_ENTRY_ONLY_SINGLEm);
    198             } else
    199 #endif
    200             if (SOC_MEM_IS_VALID(unit, L2_ENTRY_ONLYm)) {
    201                 td_test_data.mem = L2_ENTRY_ONLYm;
    202                 td_test_data.mem_str = sal_strdup("l2_entry_only");
    203                 td_test_data.count = soc_mem_index_count(unit, L2_ENTRY_ONLYm);
    204             }
    205         } else
    206 #endif /* BCM_FIREBOLT_SUPPORT */
    207 #ifdef BCM_SAND_SUPPORT
    208          if (SOC_IS_SAND(unit)) {
    209        /* no default for dfe */
    210         } else
    211 #endif /* BCM_SAND_SUPPORT */
    212         {
    213             test_error(unit, "Table DMA Error:  Invalid SOC type\n");
    214             return -1;
    215         }
    216         td_test_data.init_done = TRUE;
    217         td_test_data.tslam_en = FALSE;
    218         td_test_data.tslam_dir = TRUE; /* SLAM from low to high */
    219         td_test_data.tdma_en = TRUE;
    220         td_test_data.ccm = FALSE;
    221         td_test_data.rnum        = sal_rand();
    222         td_test_data.srcaddr = 0;
    223         td_test_data.dstaddr = 0;
    224         td_test_data.td_check_data = TRUE;
    225         td_test_data.ecc_as_data = TRUE;
    226     }
    227 #ifdef BCM_XGS3_SWITCH_SUPPORT
    228     if (!SOC_IS_XGS3_SWITCH(unit)) {
    229         td_test_data.tslam_en = FALSE;
    230     }
    231 #endif /* BCM_XGS3_SWITCH_SUPPORT */
    232 
    233     /*
    234      *  Gets reset for every run.
    235      */
    236     td_test_data.rom_ver_count = TD_DEFAULT_ROM_VER_COUNT;
    237 
    238     if (!alloc) {
    239         return 0;
    240     }
    241 
    242     td_test_data.entwords    = soc_mem_entry_words(unit, td_test_data.mem);
    243     td_test_data.bufwords    = td_test_data.entwords * td_test_data.count;
    244     if (0 == td_test_data.srcaddr) {
    245         td_test_data.source      = soc_cm_salloc(unit,
    246                                          WORDS2BYTES(td_test_data.bufwords),
    247                                          "td_test_data source");
    248     } else {
    249         td_test_data.source = INT_TO_PTR(td_test_data.srcaddr);
    250     }
    251 
    252     if (0 == td_test_data.dstaddr) {
    253         td_test_data.dma_ed      = soc_cm_salloc(unit,
    254                                          WORDS2BYTES(td_test_data.bufwords),
    255                                          "td_test_data dma_ed");
    256     } else {
    257         td_test_data.dma_ed = INT_TO_PTR(td_test_data.dstaddr);
    258     }
    259     if ((td_test_data.source == NULL) ||
    260         (td_test_data.dma_ed == NULL)) {
    261         if (td_test_data.source && (0 == td_test_data.srcaddr)) {
    262             soc_cm_sfree(unit, td_test_data.source);
    263             td_test_data.source = NULL;
    264         }
    265         if (td_test_data.dma_ed && (0 == td_test_data.dstaddr)) {
    266             soc_cm_sfree(unit, td_test_data.dma_ed);
    267             td_test_data.dma_ed = NULL;
    268         }
    269         test_error(unit, "Table DMA Error:  Failed to allocate DMA memory\n");
    270         return -1;
    271     }
    272 
    273     if (0 != td_test_data.rnum) {
    274         sal_memset(td_test_data.source, 0xff, WORDS2BYTES(td_test_data.bufwords));
    275         sal_memset(td_test_data.dma_ed, 0xff, WORDS2BYTES(td_test_data.bufwords));
    276     }
    277 #if defined(BCM_GREYHOUND2_SUPPORT)  || defined(BCM_SAND_SUPPORT)
    278     if(SOC_IS_GREYHOUND2(unit) || SOC_IS_SAND(unit)) {
    279         soc_mem_datamask_rw_get(unit, td_test_data.mem, td_test_data.datamask);
    280     } else
    281 #endif /* BCM_PETRA_SUPPORT || BCM_DFE_SUPPORT */
    282     {
    283         soc_mem_datamask_get(unit, td_test_data.mem, td_test_data.datamask);
    284     }
    285     soc_mem_tcammask_get(unit, td_test_data.mem, td_test_data.tcammask);
    286     soc_mem_eccmask_get(unit, td_test_data.mem, td_test_data.eccmask);
    287     soc_mem_forcedata_get(unit, td_test_data.mem, td_test_data.forcemask,
    288                           td_test_data.forcedata);
    289     td_test_data.accum_tcammask = 0;
    290     for (i = 0; i < td_test_data.entwords; i++) {
    291         td_test_data.accum_tcammask |= td_test_data.tcammask[i];
    292     }
    293     td_test_data.accum_forcemask = 0;
    294     for (i = 0; i < td_test_data.entwords; i++) {
    295         td_test_data.accum_forcemask |= td_test_data.forcemask[i];
    296     }
    297     if (!td_test_data.ecc_as_data) {
    298         for (i = 0; i < td_test_data.entwords; i++) {
    299             td_test_data.datamask[i] &= ~td_test_data.eccmask[i];
    300         }
    301     }
    302     soc_mem_datamask_memtest(unit, td_test_data.mem, td_test_data.datamask);
    303 
    304     td_test_data.comp_fn = td_test_mem_cmp_fn;
    305 
    306     return 0;
    307 }
    308 
    309 static void
    310 td_test_dump_data(int unit, int entry_cnt)
    311 {
    312     int     i, base_index, idx;
    313     uint32 *s, *d;
    314 
    315     cli_out("Table DMA test for %s.%s: index_min %d index_max %d\n"
    316             "    bufwords %d entwords %d rnum %d count %d\n",
    317             SOC_MEM_UFNAME(unit, td_test_data.mem),
    318             SOC_BLOCK_NAME(unit, td_test_data.copyno),
    319             td_test_data.index_min,
    320             td_test_data.index_max, td_test_data.bufwords,
    321             td_test_data.entwords, td_test_data.rnum, td_test_data.count);
    322 
    323     cli_out("    Datamask: ");
    324     for (idx = 0; idx < td_test_data.entwords; idx++) {
    325         cli_out(" %08x", td_test_data.datamask[idx]);
    326     }
    327     cli_out("\n\n");
    328 
    329     s = td_test_data.source;
    330     d = td_test_data.dma_ed;
    331 
    332     assert(s && d);
    333 
    334     base_index = td_test_data.index_min;
    335     s += td_test_data.index_min;
    336 
    337     for (i = td_test_data.index_min;
    338          i <= td_test_data.index_max && i - base_index < entry_cnt;
    339          ++i) {
    340         cli_out("    Table index %d: "
    341                 "source entry %d, dma_ed entry %d\n",
    342                 i, i - base_index, i - td_test_data.index_min);
    343         cli_out("    Source:  ");
    344         for (idx = 0; idx < td_test_data.entwords; idx++) {
    345             cli_out(" %08x", s[idx]);
    346         }
    347         cli_out("\n");
    348         cli_out("    DMA_ed:  ");
    349         for (idx = 0; idx < td_test_data.entwords; idx++) {
    350             cli_out(" %08x", d[idx]);
    351         }
    352         cli_out("\n\n");
    353         d += td_test_data.entwords;
    354         s += td_test_data.entwords;
    355     }
    356 }
    357 
    358 static void
    359 td_test_data_clear(int unit)
    360 {
    361     if (td_test_data.source && (0 == td_test_data.srcaddr)) {
    362         soc_cm_sfree(unit, td_test_data.source);
    363         td_test_data.source = NULL;
    364     }
    365     if (td_test_data.dma_ed && (0 == td_test_data.dstaddr)) {
    366         soc_cm_sfree(unit, td_test_data.dma_ed);
    367         td_test_data.dma_ed = NULL;
    368     }
    369 }
    370 
    371 static uint32
    372 td_test_get_curr_rnum(void)
    373 {
    374     return td_test_data.rnum;
    375 }
    376 
    377 static uint32
    378 td_test_rand32(uint32 prev)
    379 {
    380     return td_test_data.rnum = 1664525L * prev + 1013904223L;
    381 }
    382 
    383 #define BSAND_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0x00ff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24)))
    384 #define BSAND_WORD_SWAP(x) ( (((x) & 0xFFff0000) >> 16) | (((x) & 0x0000FFff) << 16) )
    385 
    386 static uint32 *
    387 td_test_random_entry(int unit, soc_mem_t mem, uint32 *entbuf)
    388 {
    389     int i;
    390 
    391     for (i = 0; i < td_test_data.entwords; ++i) {
    392         uint32 prev = td_test_get_curr_rnum();
    393 #ifdef BCM_PETRA_SUPPORT
    394         if (SOC_IS_ARAD(unit)) {
    395             entbuf[i]   = td_test_rand32(prev) & BSAND_BYTE_SWAP(td_test_data.datamask[i]);
    396         } else
    397 #endif /* BCM_PETRA_SUPPORT */
    398         {
    399             entbuf[i]   = td_test_rand32(prev) & td_test_data.datamask[i];
    400         }
    401     }
    402 
    403     return entbuf;
    404 }
    405 
    406 static int
    407 td_test_write_entry(int unit, soc_mem_t mem, int copyno,
    408                  int index, uint32 *entbuf)
    409 {
    410     int rv = 0;
    411 
    412     if (SOC_MEM_IS_VALID(unit, mem)) {
    413         rv = soc_mem_write(unit, mem, copyno, index, entbuf);
    414     }
    415     if (rv < 0) {
    416         test_error(unit,
    417                    "Write entry (copyno %d) failed: %s",
    418                    copyno, soc_errmsg(rv));
    419     }
    420     return rv;
    421 }
    422 
    423 static int
    424 td_test_read_entry(int unit, soc_mem_t mem, int copyno,
    425                    int index, uint32 *entbuf)
    426 {
    427     int rv = 0;
    428 
    429     if (SOC_MEM_IS_VALID(unit, mem)) {
    430         rv = soc_mem_read(unit, mem, copyno, index, entbuf);
    431     }
    432     if (rv < 0) {
    433         test_error(unit,
    434                    "Read entry (copyno %d) failed: %s",
    435                    copyno, soc_errmsg(rv));
    436     }
    437     return rv;
    438 }
    439 
    440 static int
    441 td_test_verify(int unit)
    442 {
    443     int rv         = 0;
    444     int rv_comp = 0;
    445     soc_mem_t mem  = td_test_data.mem;
    446     int base_index = soc_mem_index_min(unit, mem);
    447     int index_min  = td_test_data.index_min;
    448     int index_max  = td_test_data.index_max;
    449     int ent_words  = soc_mem_entry_words(unit, mem);
    450     int i, j;
    451     int idx;
    452     uint32 *d;
    453     uint32 *s;
    454 
    455     /*
    456      * For readonly mem, compare a few dma-ed entries with
    457      * entries in hardware from direct reading.
    458      */
    459     if (soc_mem_is_readonly(unit, mem)) {
    460         int error = 0;
    461         s = td_test_data.source;
    462         d = td_test_data.dma_ed;
    463         for (i = 0; i < td_test_data.rom_ver_count; ++i) {
    464             if (i >= td_test_data.count) {
    465                 break;
    466             }
    467             if (soc_mem_read(unit, mem, td_test_data.copyno,
    468                              i+td_test_data.index_min,
    469                              s) < 0) {
    470                 cli_out("Cannot read entry %d\n", i+td_test_data.index_min);
    471                 return -1;
    472             }
    473             if (td_test_data.comp_fn(unit, d, s) != 0) {
    474                 error = -1;
    475                 cli_out("%s.%s diff entry index %d: \n",
    476                         SOC_MEM_UFNAME(unit, mem),
    477                         SOC_BLOCK_NAME(unit, td_test_data.copyno),
    478                         i+td_test_data.index_min);
    479                 cli_out("Read directly:\n");
    480                 soc_mem_entry_dump(unit, mem, s, BSL_LSS_CLI);
    481                 cli_out("\n");
    482                 cli_out("Read by table dma:\n");
    483                 soc_mem_entry_dump(unit, mem, d, BSL_LSS_CLI);
    484                 cli_out("\n");
    485             }
    486             d += ent_words;
    487             s += ent_words;
    488         }
    489         return error;
    490     }
    491 
    492     if (!td_test_data.ecc_as_data) {
    493         for (i = 0; i <= index_max - index_min; i++) {
    494             for (idx = 0; idx < td_test_data.entwords; idx++) {
    495                 td_test_data.dma_ed[i * ent_words + idx] &=
    496                     ~td_test_data.eccmask[idx];
    497                 td_test_data.source[i * ent_words + idx] &=
    498                     ~td_test_data.eccmask[idx];
    499             }
    500         }
    501     }
    502 
    503 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNXF_SUPPORT)
    504         if (SOC_IS_DPP(unit) || SOC_IS_DFE(unit) || SOC_IS_DNXF(unit)) {
    505             rv_comp = compare_with_mask(td_test_data.dma_ed, td_test_data.source, (index_max - index_min + 1) * ent_words * 4);
    506         } else
    507 #endif /* BCM_PETRA_SUPPORT defined(BCM_DFE_SUPPORT */
    508     {
    509 #if defined(BCM_XGS3_SWITCH_SUPPORT)
    510         if (soc_feature(unit, soc_feature_sbusdma)) {
    511             if ((td_test_data.tslam_dir == 0) && td_test_data.tslam_en &&
    512                 soc_mem_slamable(unit, mem, td_test_data.copyno)) {
    513                 /* swap the source buffer */
    514                 uint32 temp[SOC_MAX_MEM_WORDS];
    515                 s = td_test_data.source;
    516                 d = s + ((index_max - index_min) * ent_words);
    517                 for (i = 0; i < (index_max - index_min + 1)/2; ++i) {
    518                     sal_memcpy(temp, s + i * ent_words, ent_words * 4);
    519                     sal_memcpy(s + i * ent_words, d - i * ent_words, ent_words * 4);
    520                     sal_memcpy(d - i * ent_words, temp, ent_words * 4);
    521                 }
    522             }
    523         }
    524 #endif
    525         rv_comp = compare_with_mask(td_test_data.dma_ed, td_test_data.source,
    526                                     (index_max - index_min + 1) * ent_words * 4);
    527     }
    528 
    529     if (rv_comp != 0) { 
    530 
    531         cli_out("Mismatch found\n");
    532         s = td_test_data.source;
    533         d = td_test_data.dma_ed;
    534         for (i = index_min; i <= index_max; ++i) {
    535             if (td_test_data.comp_fn(unit, d, s) != 0) {
    536                 cli_out("%s.%s diff entry index %d: "
    537                         "source entry %d, dma_ed entry %d\n",
    538                         SOC_MEM_UFNAME(unit, mem),
    539                         SOC_BLOCK_NAME(unit, td_test_data.copyno),
    540                         i, i - base_index, i - index_min);
    541                 cli_out("Source:");
    542                 for (j = 0; j < ent_words; j++) {
    543                     cli_out(" 0x%08x = 0x%08x", (PTR_TO_INT(s+j)), s[j]);
    544                 }
    545                 cli_out("\nDMA_ed:");
    546                 for (j = 0; j < ent_words; j++) {
    547                     cli_out(" 0x%08x = 0x%08x", (PTR_TO_INT(d+j)), d[j]);
    548                 }
    549 
    550                 cli_out("\nMask");
    551                 for (j = 0; j < ent_words; j++) {
    552                     cli_out("  = 0x%08x", (uint32)BSAND_BYTE_SWAP(td_test_data.datamask[j]));                    
    553                 }
    554                 cli_out("\n");
    555 
    556                 return -1;
    557             }
    558             d += ent_words;
    559             s += ent_words;
    560         }
    561         /* If get here, something is wrong, dump for inspection */
    562         td_test_dump_data(unit, TD_DEFAULT_DUMP_ENTRY_COUNT);
    563     }
    564 
    565     return rv;
    566 }
    567 
    568 
    569 int
    570 compare_with_mask(const void *m1_void, const void *m2_void, size_t len)
    571 {
    572     const uint32 *m1 = m1_void, *m2 = m2_void;
    573     uint32  *mask_start;
    574     uint32  *mask;
    575     uint32 i;
    576 
    577      mask_start = (uint32 *)td_test_data.datamask;
    578 /*    cli_out("Compare with mask  entwords= 0x%08x  len=0x%08x", td_test_data.entwords, (uint32) len);  */
    579     /* while (len != 0) */
    580 	{
    581       /*  mask = td_test_data.datamask; */
    582         mask = mask_start;
    583         for (i = 0; i < td_test_data.entwords; i++) {
    584             len--;
    585 /*            cli_out("Mask  i=%d maskvalue = 0x%08x  ", i, *mask);  */
    586             if ((*m1 & *mask) < (*m2 & *mask)) {
    587               /*  cli_out("*m1=0x%08x < *m2 = 0x%08x \n", *m1, *m2); */
    588                 return -1;
    589             } else if ((*m1 & *mask) > (*m2 & *mask)) {
    590                /* cli_out("*m1=0x%08x > *m2 = 0x%08x \n", *m1, *m2); */
    591                 return 1;
    592             }
    593             /* cli_out("*m1=0x%08x == *m2 = 0x%08x \n", *m1, *m2); */
    594             m1++;
    595             m2++;
    596             mask++;
    597         }
    598     }
    599 
    600     return 0;
    601 }
    602 
    603 
    604 static int
    605 td_test_mem_cmp_fn(int unit, void *s, void*d)
    606 {
    607     soc_mem_t mem  = td_test_data.mem;
    608     int ent_words  = soc_mem_entry_words(unit, mem);
    609 
    610     assert(s && d);
    611 
    612     return sal_memcmp(s, d, ent_words * 4);
    613 }
    614 
    615 
    616 static int
    617 td_test_dma_verify_helper(int unit)
    618 {
    619     int        i, rv = 0;
    620     uint32    *entbuf, *entbuf_source;
    621     int        index_offset;
    622 
    623 #ifdef BCM_CMICM_SUPPORT
    624     if(td_test_data.ccm) {
    625         if (TRUE == td_test_data.td_check_data) {
    626             if (sal_memcmp(td_test_data.dma_ed, td_test_data.source,
    627                            (td_test_data.count * 4)) != 0) {
    628                 test_error(unit, "CCM DMA Compare failed\n");
    629                 td_test_dump_data(unit, TD_DEFAULT_DUMP_ENTRY_COUNT);
    630                 return -1;
    631             }
    632         }
    633     } else
    634 #endif
    635     {
    636         if (0 != td_test_data.rnum) {
    637             sal_memset(td_test_data.dma_ed, 0xff, td_test_data.bufwords * 4);
    638         }
    639 
    640         if (!SOC_IS_XGS_SWITCH(unit) && !SOC_IS_SAND(unit)) {
    641             test_error(unit, "Chip type not supported for table DMA test\n");
    642             return -1;
    643         }
    644         entbuf = td_test_data.dma_ed;
    645         entbuf_source = td_test_data.source;
    646 
    647         if (td_test_data.tdma_en) {
    648             rv = soc_mem_read_range(unit, td_test_data.mem, td_test_data.copyno,
    649                                     td_test_data.index_min, td_test_data.index_max,
    650                                     td_test_data.dma_ed);
    651             if (rv < 0) {
    652                 test_error(unit, "Table DMA Error: Memory %s.%d %s\n",
    653                            td_test_data.mem_str, td_test_data.copyno,
    654                            soc_errmsg(rv));
    655                 return -1;
    656             }
    657 
    658             for (i = td_test_data.index_min; i <= td_test_data.index_max; i++) {
    659                 if (soc_mem_test_skip(unit, td_test_data.mem, i)) {
    660                     index_offset = (td_test_data.tslam_dir) ? 
    661                                     (i - td_test_data.index_min) :
    662                                     (td_test_data.index_max - i);
    663                     sal_memcpy((void *)entbuf,
    664                                (void *)(entbuf_source + index_offset * td_test_data.entwords),
    665                                WORDS2BYTES(td_test_data.entwords));
    666                 }
    667                 entbuf += td_test_data.entwords;
    668             }
    669         } else {
    670             for (i = td_test_data.index_min; i <= td_test_data.index_max; i++) {
    671                 if (soc_mem_test_skip(unit, td_test_data.mem, i)) {
    672                     index_offset = (td_test_data.tslam_dir) ? 
    673                                     (i - td_test_data.index_min) :
    674                                     (td_test_data.index_max - i); 
    675                     sal_memcpy((void *)entbuf,
    676                                (void *)(entbuf_source + index_offset * td_test_data.entwords),
    677                                WORDS2BYTES(td_test_data.entwords));
    678                     entbuf += td_test_data.entwords;
    679                     continue;
    680                 }
    681                 if (td_test_read_entry(unit, td_test_data.mem,
    682                                        td_test_data.copyno, i, entbuf) < 0) {
    683                     return -1;
    684                 }
    685                 entbuf += td_test_data.entwords;
    686             }
    687         }
    688 
    689         if (TRUE == td_test_data.td_check_data) {
    690             /*
    691              * Verifing received results
    692              */
    693             if ((rv = td_test_verify(unit)) < 0) {
    694                 test_error(unit,
    695                            "Table DMA failed: inconsistency observed\n");
    696                 td_test_dump_data(unit, TD_DEFAULT_DUMP_ENTRY_COUNT);
    697                 return -1;
    698             }
    699         }
    700     }
    701     return 0;
    702 }
    703 
    704 #if defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TRIDENT3_SUPPORT)
    705 int pstats_tr_init(int unit) {
    706     soc_mem_t   mem = INVALIDm;
    707     int         found = 0, pipe, xpe;
    708 
    709     /* Tomahawk2/Trident3 MMU_THDU_UCQ_STATS_TABLE memory need special process */
    710     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    711         for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    712             mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, MMU_THDU_UCQ_STATS_TABLEm,
    713                                               xpe, pipe);
    714             if ((mem == INVALIDm) || (mem != td_test_data.mem)) {
    715                 continue;
    716             } else {
    717                 found = 1;
    718                 td_test_data.pstats_ucq = 1;
    719                 /* set memory for write */
    720                 td_test_data.mem_write =
    721                     SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, MMU_THDU_UCQ_STATSm,
    722                                                 xpe, pipe);
    723                 break;
    724             }
    725         }
    726         if (found) {
    727             break;
    728         }
    729     }
    730 
    731 #if defined (BCM_TOMAHAWK2_SUPPORT)
    732     if (SOC_IS_TOMAHAWK2(unit)) {
    733         if (soc_tomahawk2_mmu_pstats_mode_set(unit, 0) < 0) {
    734             return -1;
    735         }
    736     }
    737 #endif /* BCM_TOMAHAWK2_SUPPORT */
    738 
    739 #if defined (BCM_HELIX5_SUPPORT)
    740     if (SOC_IS_HELIX5(unit)) {
    741         if (soc_helix5_mmu_pstats_mode_set(unit, 0) < 0) {
    742             return -1;
    743         }
    744     }
    745 #endif /* BCM_HELIX5_SUPPORT */
    746 
    747 #if defined (BCM_TRIDENT3_SUPPORT)
    748     if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_HELIX5(unit)) {
    749         if (soc_trident3_mmu_pstats_mode_set(unit, 0) < 0) {
    750             return -1;
    751         }
    752     }
    753 #endif /* BCM_TRIDENT3_SUPPORT */
    754 
    755     return 0;
    756 }
    757 
    758 int pstats_mor_init(int unit) {
    759     uint32      flag;
    760 
    761     if (td_test_data.tdma_en) {
    762         return -1;
    763     }
    764 
    765     /* invalid memory for mor */
    766     if (!td_test_data.pstats_ucq) {
    767         return -1;
    768     }
    769 
    770     soc_pstats_deinit(unit);
    771     if(soc_pstats_init(unit) < 0) {
    772         return -1;
    773     }
    774 
    775 #if defined (BCM_TOMAHAWK2_SUPPORT)
    776     /* call soc function */
    777     if (SOC_IS_TOMAHAWK2(unit)) {
    778         flag = _TH2_MMU_PSTATS_ENABLE |
    779                _TH2_MMU_PSTATS_PKT_MOD |
    780                _TH2_MMU_PSTATS_SYNC |
    781                _TH2_MMU_PSTATS_HWM_MOD |
    782                _TH2_MMU_PSTATS_MOR_EN;
    783         if (soc_tomahawk2_mmu_pstats_mode_set(unit, flag) < 0) {
    784             return -1;
    785         }
    786     }
    787 #endif /* BCM_TOMAHAWK2_SUPPORT */
    788 
    789 #if defined (BCM_HELIX5_SUPPORT)
    790     if (SOC_IS_HELIX5(unit)) {
    791         flag = _HX5_MMU_PSTATS_ENABLE |
    792                _HX5_MMU_PSTATS_SYNC |
    793                _HX5_MMU_PSTATS_HWM_MOD |
    794                _HX5_MMU_PSTATS_MOR_EN;
    795         if (soc_helix5_mmu_pstats_mode_set(unit, flag) < 0) {
    796             return -1;
    797         }
    798     }
    799 #endif /* BCM_HELIX5_SUPPORT */
    800 
    801 #if defined (BCM_TRIDENT3_SUPPORT)
    802     if ((SOC_IS_TRIDENT3X(unit)) && !(SOC_IS_HELIX5(unit))) {
    803         flag = _TD3_MMU_PSTATS_ENABLE |
    804                _TD3_MMU_PSTATS_PKT_MOD |
    805                _TD3_MMU_PSTATS_SYNC |
    806                _TD3_MMU_PSTATS_HWM_MOD |
    807                _TD3_MMU_PSTATS_MOR_EN;
    808         if (soc_trident3_mmu_pstats_mode_set(unit, flag) < 0) {
    809             return -1;
    810         }
    811     }
    812 #endif /* BCM_TRIDENT3_SUPPORT */
    813 
    814     return 0;
    815 }
    816 
    817 int pstats_ucq_test(int unit, int index, uint32 *entbuf) {
    818     soc_field_t     ucq_field[4] = {UCQ_COUNT0f, UCQ_COUNT1f,
    819                                     UCQ_COUNT2f, UCQ_COUNT3f};
    820     uint32          fval;
    821     int             field_len;
    822     int             i, idx;
    823     uint32          entry_w[SOC_MAX_MEM_WORDS];
    824 
    825     field_len = soc_mem_field_length(unit, td_test_data.mem_write, UCQ_COUNTf);
    826     for (i = 0; i < 4; i++) {
    827         idx = index * 4 + i;
    828 
    829         /* field length need to be adjusted. */
    830         fval = soc_mem_field32_get(unit, td_test_data.mem, (void *)entbuf,
    831                                    ucq_field[i]);
    832         LOG_INFO(BSL_LS_APPL_TESTS,
    833                  (BSL_META_U(unit, "fval %d is %x\n"), i, fval));
    834         fval &= (1 << field_len) - 1;
    835         soc_mem_field32_set(unit, td_test_data.mem, entbuf, ucq_field[i], fval);
    836         LOG_INFO(BSL_LS_APPL_TESTS,
    837                  (BSL_META_U(unit, "adjusted fval %d is %x\n"), i, fval));
    838 
    839         if (td_test_read_entry(unit, td_test_data.mem_write,
    840                                td_test_data.copyno, idx, entry_w) < 0) {
    841             return -1;
    842         }
    843         soc_mem_field32_set(unit, td_test_data.mem_write, entry_w, UCQ_COUNTf, fval);
    844         if (td_test_write_entry(unit, td_test_data.mem_write,
    845                                 td_test_data.copyno, idx, entry_w) < 0) {
    846             return -1;
    847         }
    848     }
    849 
    850     return 0;
    851 }
    852 
    853 int pstat_mor_test_verify(int unit) {
    854     soc_mem_t   mem = td_test_data.mem;
    855     uint8       *buf = NULL;
    856     int         alloc_size, num_entries, i;
    857     void        *pentry;
    858     uint32      *entbuf;
    859 
    860     if (soc_pstats_sync(unit) < 0){
    861         return -1;
    862     }
    863 
    864     num_entries = soc_mem_index_max(unit, mem) + 1;
    865     alloc_size = sizeof(uint32) * soc_mem_entry_words(unit, mem);
    866     alloc_size *= num_entries;
    867 
    868     buf = sal_alloc(alloc_size, "pstats buffer");
    869     if (buf == NULL) {
    870         return -1;
    871     }
    872 
    873     if (soc_pstats_mem_get(unit, mem, buf, 0) < 0) {
    874         sal_free(buf);
    875         return -1;
    876     }
    877 
    878     entbuf = td_test_data.dma_ed;
    879 
    880     for (i = td_test_data.index_min; i <= td_test_data.index_max; i++) {
    881         pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, buf, i);
    882         sal_memcpy(entbuf, (uint32*)pentry,
    883                    sizeof(uint32) * td_test_data.entwords);
    884         entbuf += td_test_data.entwords;
    885     }
    886 
    887     if (TRUE == td_test_data.td_check_data) {
    888         /*
    889          * Verifing received results
    890          */
    891         if (td_test_verify(unit) < 0) {
    892             test_error(unit,
    893                        "Table DMA failed: inconsistency observed\n");
    894             td_test_dump_data(unit, TD_DEFAULT_DUMP_ENTRY_COUNT);
    895             sal_free(buf);
    896             return -1;
    897         }
    898     }
    899 
    900     sal_free(buf);
    901     return 0;
    902 }
    903 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
    904 
    905 int
    906 td_test_test(int unit, args_t *a, void *pa)
    907 {
    908     int        i, j;
    909     uint32    *entbuf;
    910 
    911 #ifdef BCM_SAND_SUPPORT
    912     if (SOC_IS_SAND(unit))
    913     {
    914         return dnx_table_dma_test(unit, a, &pa);
    915     }
    916 #endif
    917 
    918 #ifdef BCM_CMICM_SUPPORT
    919     if(td_test_data.ccm) {
    920         LOG_INFO(BSL_LS_APPL_TESTS,
    921                  (BSL_META_U(unit,
    922                              "Note:  Cross Coupled Memory \n")));
    923     } else 
    924 #endif
    925     {
    926         LOG_INFO(BSL_LS_APPL_TESTS,
    927                  (BSL_META_U(unit,
    928                              "Table DMA %s: copy %d, from entry %d for %d entries SEED = %d\n"),
    929                   td_test_data.mem_str,
    930                   td_test_data.copyno,
    931                   td_test_data.index_min,
    932                   td_test_data.count,
    933                   td_test_data.rnum));
    934         if (!soc_mem_dmaable(unit, td_test_data.mem, td_test_data.copyno)) {
    935             cli_out("WARNING: DMA will not be used for memory %s.%d.\n",
    936                     td_test_data.mem_str, td_test_data.copyno);
    937         }
    938 #if 0
    939         /* NOTE: The following is not valid anymore as we always dma from h/w and
    940                  we bypass cache for mem tests */
    941         if (soc_mem_cache_get(unit, td_test_data.mem, td_test_data.copyno)) {
    942             cli_out("WARNING: All reads from memory %s.%d will come from cache.\n",
    943                     td_test_data.mem_str, td_test_data.copyno);
    944         }
    945 #endif
    946     }
    947 
    948     td_test_data_clear(unit);
    949     if (td_test_data_init(unit, 1) < 0) {
    950         return -1;
    951     }
    952 #ifdef BCM_CMICM_SUPPORT
    953     if(td_test_data.ccm) {
    954         if (soc_host_ccm_copy(unit, td_test_data.source, td_test_data.dma_ed,
    955                             td_test_data.count, 0) < 0) {
    956             test_error(unit, "CCM DMA Error\n");
    957             return -1;
    958         }
    959     } else
    960 #endif
    961     /* If not a RO memory, write random data into table and hardware */
    962     if (!soc_mem_is_readonly(unit, td_test_data.mem)) {
    963         entbuf = td_test_data.source;
    964         if (0 != td_test_data.rnum) {
    965             sal_memset(entbuf, 0xff, WORDS2BYTES(td_test_data.bufwords));
    966         }
    967 
    968 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
    969         if ((SOC_IS_XGS3_SWITCH(unit) &&
    970              td_test_data.tslam_en && !td_test_data.pstats_ucq &&
    971              (soc_mem_slamable(unit, td_test_data.mem, td_test_data.copyno))) ||
    972             (SOC_IS_DFE(unit) || SOC_IS_DPP(unit) || SOC_IS_DNXF(unit) || SOC_IS_DNX(unit))) {
    973             sal_usecs_t btime, etime;
    974             int rv = SOC_E_NONE;
    975 
    976             for (i = 0; i < td_test_data.count; i++) {
    977                 td_test_random_entry(unit, td_test_data.mem, entbuf);
    978                 if (td_test_data.accum_tcammask) {
    979                     /* data read back has dependency on mask */
    980                     if ((SOC_BLOCK_TYPE(unit, td_test_data.copyno) ==
    981                           SOC_BLK_ESM) ||
    982                         (SOC_BLOCK_TYPE(unit, td_test_data.copyno) ==
    983                                SOC_BLK_ETU)) {
    984                         for (j = 0; j < td_test_data.entwords; j++) {
    985                             entbuf[j] &= ~td_test_data.tcammask[j];
    986                         }
    987                     } else if (soc_feature(unit, soc_feature_xy_tcam)) {
    988                         for (j = 0; j < td_test_data.entwords; j++) {
    989                             entbuf[j] |= td_test_data.tcammask[j];
    990                         }
    991                     }
    992                 }
    993                 if (td_test_data.accum_forcemask) {
    994                     for (j = 0; j < td_test_data.entwords; j++) {
    995                         entbuf[j] &= ~td_test_data.forcemask[j];
    996                         entbuf[j] |= td_test_data.forcedata[j];
    997                     }
    998                 }
    999                 entbuf += td_test_data.entwords;
   1000             }
   1001             soc_cm_sflush(unit, (void *)td_test_data.source,
   1002                           WORDS2BYTES(td_test_data.bufwords));
   1003             btime = sal_time_usecs();
   1004             rv = soc_mem_write_range(unit, td_test_data.mem, td_test_data.copyno,
   1005                                      (td_test_data.tslam_dir ?
   1006                                      td_test_data.index_min : td_test_data.index_max),
   1007                                      (td_test_data.tslam_dir ?
   1008                                      td_test_data.index_max : td_test_data.index_min),
   1009                                      td_test_data.source);
   1010             etime = sal_time_usecs();
   1011             LOG_INFO(BSL_LS_APPL_TESTS,
   1012                      (BSL_META_U(unit,
   1013                         "Memory: %s Count: %d TSLAM time in usec: %d\n"),
   1014                      td_test_data.mem_str, td_test_data.count, etime - btime));
   1015             if (rv < 0) {
   1016                 test_error(unit,
   1017                            "Table SLAM DMA Error:  Memory %s.%d\n",
   1018                            td_test_data.mem_str, td_test_data.copyno);
   1019                 return -1;
   1020             }
   1021         } else
   1022 #endif /* BCM_XGS3_SWITCH_SUPPORT || BCM_DFE_SUPPORT || BCM_PETRA_SUPPORT */
   1023         {
   1024             for (i = td_test_data.index_min; i <= td_test_data.index_max; i++) {
   1025                 td_test_random_entry(unit, td_test_data.mem, entbuf);
   1026                 if (td_test_data.accum_tcammask) {
   1027                     /* data read back has dependency on mask */
   1028                     if ((SOC_BLOCK_TYPE(unit, td_test_data.copyno) ==
   1029                          SOC_BLK_ESM) ||
   1030                         (SOC_BLOCK_TYPE(unit, td_test_data.copyno) ==
   1031                          SOC_BLK_ETU)) {
   1032                         for (j = 0; j < td_test_data.entwords; j++) {
   1033                             entbuf[j] &= ~td_test_data.tcammask[j];
   1034                         }
   1035                     } else if (soc_feature(unit, soc_feature_xy_tcam)) {
   1036                         for (j = 0; j < td_test_data.entwords; j++) {
   1037                             entbuf[j] |= td_test_data.tcammask[j];
   1038                         }
   1039                     }
   1040                 }
   1041                 if (td_test_data.accum_forcemask) {
   1042                     for (j = 0; j < td_test_data.entwords; j++) {
   1043                         entbuf[j] &= ~td_test_data.forcemask[j];
   1044                         entbuf[j] |= td_test_data.forcedata[j];
   1045                     }
   1046                 }
   1047 
   1048                 if (td_test_data.pstats_ucq) {
   1049 #if defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TRIDENT3_SUPPORT)
   1050                     if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) {
   1051                         if (pstats_ucq_test(unit, i, entbuf) < 0) {
   1052                             return -1;
   1053                         }
   1054                     }
   1055 #endif
   1056                 } else if (soc_mem_test_skip(unit, td_test_data.mem, i)) {
   1057                     entbuf += td_test_data.entwords;
   1058                     continue;
   1059                 }
   1060 
   1061                 if (td_test_write_entry(unit, td_test_data.mem,
   1062                                         td_test_data.copyno, i,
   1063                                         entbuf) < 0) {
   1064                     return -1;
   1065                 }
   1066                 entbuf += td_test_data.entwords;
   1067             }
   1068         }
   1069         if (td_test_data.mor_en) {
   1070 #if defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TRIDENT3_SUPPORT)
   1071             if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) {
   1072                 if (pstat_mor_test_verify(unit) < 0) {
   1073                     return -1;
   1074                 }
   1075             }
   1076 #endif
   1077         } else
   1078         if (td_test_dma_verify_helper(unit) < 0) {
   1079             return -1;
   1080         }
   1081     } else {
   1082         cli_out("Note:  memory %s is read only, so verifying a few\n",
   1083                 td_test_data.mem_str);
   1084         cli_out("entries directly.\n");
   1085     }
   1086 
   1087     return 0;
   1088 }
   1089 
   1090 
   1091 char tr71_test_usage[] = 
   1092 "TR71 (single memory write dma test) usage:\n"
   1093 " \n"
   1094  #ifdef COMPILER_STRING_CONST_LIMIT
   1095     "\nFull documentation cannot be displayed with -pedantic compiler\n";
   1096  #else
   1097 
   1098   "Mem=<value> Memory - The memory to be checked\n"
   1099   "Start=<value>  - Starting index\n"
   1100   "Count=<value> how many rows\n"
   1101   "readonlymemVerifyCount=<value> \n"
   1102   "SEED=<value> the seed to use in the random function\n"
   1103   "EccAsData=<value> use ecc as part of the data\n"
   1104   "CheckData=<value> \n"
   1105   "Help=<1/0>                      -  Specifies if tr 71 help is on and exit or off (off by default)\n"
   1106   "To enable printing values (write/read) of each memory proceed: debug +test +verb\n"
   1107   "\n";
   1108   #endif
   1109 
   1110 
   1111 
   1112 int
   1113 td_test_init(int unit, args_t *a, void **pa)
   1114 {
   1115     parse_table_t  pt;
   1116     int            index_min, index_max;
   1117     int count_arg;
   1118     uint32 help_status_default = 0;
   1119     uint32 help_status=0;
   1120 #ifdef BCM_SAND_SUPPORT
   1121     if (SOC_IS_SAND(unit))
   1122     {
   1123         return 0;
   1124     }
   1125 #endif
   1126     if (td_test_data_init(unit, 0) < 0) {
   1127         return -1;
   1128     }
   1129 
   1130     parse_table_init(unit, &pt);
   1131 
   1132     parse_table_add(&pt, "Mem", PQ_DFL|PQ_STRING|PQ_STATIC,
   1133                     0, &td_test_data.mem_str, NULL);
   1134     parse_table_add(&pt, "Start", PQ_DFL|PQ_INT,
   1135                     0, &td_test_data.index_min, NULL);
   1136     parse_table_add(&pt, "Count", PQ_DFL|PQ_INT,
   1137                     (void *)(-1), &count_arg, NULL);
   1138     parse_table_add(&pt, "readonlymemVerifyCount", PQ_DFL|PQ_INT,
   1139                     0, &td_test_data.rom_ver_count, NULL);
   1140     parse_table_add(&pt, "SEED",        PQ_INT|PQ_DFL,  0,
   1141                     &td_test_data.rnum,       NULL);
   1142     parse_table_add(&pt, "EccAsData", PQ_BOOL|PQ_DFL,  (void *)1,
   1143                     &td_test_data.ecc_as_data, NULL);
   1144 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1145     if (SOC_IS_XGS3_SWITCH(unit)) {
   1146         parse_table_add(&pt, "TSlamEnable", PQ_BOOL|PQ_DFL,
   1147                         0, &td_test_data.tslam_en, NULL);
   1148         parse_table_add(&pt, "SlamLowToHigh", PQ_BOOL|PQ_DFL,
   1149                         0, &td_test_data.tslam_dir, NULL);
   1150         parse_table_add(&pt, "TDmaEnable", PQ_BOOL|PQ_DFL,
   1151                         0, &td_test_data.tdma_en, NULL);
   1152     }
   1153 #endif /* BCM_XGS3_SWITCH_SUPPORT */
   1154 #ifdef BCM_CMICM_SUPPORT
   1155     parse_table_add(&pt, "CrossCoupledMemory", PQ_BOOL|PQ_DFL,
   1156                     0, &td_test_data.ccm, NULL);
   1157 #endif
   1158 #ifdef BCM_XGS3_SWITCH_SUPPORT /* For now implement only for katana */
   1159     if (SOC_IS_KATANA(unit)) {
   1160         parse_table_add(&pt, "SourceAddressOverride", PQ_INT|PQ_DFL,
   1161                         0, &td_test_data.srcaddr, NULL);
   1162         parse_table_add(&pt, "DestAddressOverride", PQ_INT|PQ_DFL,
   1163                         0, &td_test_data.dstaddr, NULL);
   1164     }
   1165     if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) {
   1166         td_test_data.pstats_ucq = 0;
   1167         td_test_data.mor_en = 0;
   1168         parse_table_add(&pt, "DmaMOR", PQ_BOOL|PQ_DFL,
   1169                         0, &td_test_data.mor_en, NULL);
   1170     }
   1171 #endif /* BCM_XGS3_SWITCH_SUPPORT */
   1172     parse_table_add(&pt, "CheckData",   PQ_BOOL|PQ_DFL, 0,
   1173                     &td_test_data.td_check_data, NULL);
   1174 
   1175     parse_table_add(&pt, "Help",    PQ_DFL|PQ_INT, &help_status_default, &help_status,           NULL);
   1176 
   1177     if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) {
   1178         test_error(unit,
   1179                    "%s: Invalid option: %s\n", ARG_CMD(a),
   1180                    ARG_CUR(a) ? ARG_CUR(a) : "*");
   1181         parse_arg_eq_done(&pt);
   1182         return -1;
   1183     }
   1184     if (help_status == 1) {
   1185         cli_out("%s\n",tr71_test_usage);
   1186         return -1;
   1187     }
   1188 
   1189     if (parse_memory_name(unit, &td_test_data.mem, td_test_data.mem_str,
   1190                           &td_test_data.copyno, 0) < 0) {
   1191         test_error(unit, "Memory \"%s\" is invalid\n",
   1192                    td_test_data.mem_str);
   1193         parse_arg_eq_done(&pt);
   1194         return -1;
   1195     }
   1196 #ifdef BCM_PETRA_SUPPORT
   1197 if (SOC_IS_ARAD(unit) ) {
   1198     if (!soc_mem_is_valid(unit, td_test_data.mem) ||
   1199         soc_mem_is_readonly(unit, td_test_data.mem)
   1200 
   1201         || (SOC_IS_ARAD(unit) && (soc_mem_is_writeonly(unit, td_test_data.mem) || soc_mem_is_signal(unit, td_test_data.mem)))
   1202 
   1203         ) {
   1204         test_error(unit, "Memory %s is invalid/readonly/writeonly/signal \n",
   1205                    SOC_MEM_UFNAME(unit, td_test_data.mem));
   1206         return -1;
   1207     }
   1208 
   1209     if(SOC_IS_ARAD(unit)) {
   1210         switch(td_test_data.mem) {
   1211             case BRDC_FSRD_FSRD_WL_EXT_MEMm:
   1212             case IQM_MEM_8000000m:
   1213             case NBI_TBINS_MEMm:
   1214             case NBI_RBINS_MEMm:
   1215             case PORT_WC_UCMEM_DATAm:
   1216                 test_error(unit, "Memory %s is invalid/readonly/writeonly/signal \n",
   1217                            SOC_MEM_UFNAME(unit, td_test_data.mem));
   1218                 return -1;
   1219             default:
   1220                 break;
   1221         }
   1222     }
   1223 }
   1224 #endif
   1225 #if defined (BCM_TOMAHAWK2_SUPPORT)
   1226     if (soc_feature(unit,soc_feature_no_vfp) &&
   1227         ((td_test_data.mem >= VFP_TCAMm && td_test_data.mem <= VFP_TCAM_PIPE3m) ||
   1228          (td_test_data.mem >= VFP_POLICY_TABLEm && td_test_data.mem <= VFP_POLICY_TABLE_PIPE3m))) {
   1229         test_msg("VFP is not supported.Cannot test memory %s \n", SOC_MEM_UFNAME(unit, td_test_data.mem));
   1230         return -1;
   1231     }
   1232 #endif /*BCM_TOMAHAWK2_SUPPORT*/
   1233 #ifdef BCM_DNXF_SUPPORT
   1234     if (SOC_IS_DNXF(unit))
   1235     {
   1236         if (!SOC_MEM_IS_VALID(unit, td_test_data.mem)
   1237             || (soc_mem_flags(unit, td_test_data.mem) & (SOC_MEM_FLAG_READONLY | SOC_MEM_FLAG_WRITEONLY | SOC_MEM_FLAG_SIGNAL)) != 0)
   1238         {
   1239             return -1;
   1240         }
   1241         switch (td_test_data.mem)
   1242         {
   1243             case BRDC_QRH_FFLBm:
   1244             case BRDC_QRH_MCLBTm:
   1245             case BRDC_QRH_MCSFFm:
   1246             case BRDC_QRH_MNOLm:
   1247             case FSRD_FSRD_PROM_MEMm:
   1248             case QRH_FFLBm:
   1249             case QRH_MCLBTm:
   1250             case QRH_MCSFFm:
   1251             case QRH_MNOLm:
   1252                 test_error(unit, "Memory %s is invalid/readonly/writeonly/signal \n",
   1253                            SOC_MEM_UFNAME(unit, td_test_data.mem));
   1254                 return -1;       /* Skip these tables */
   1255             default:
   1256                 break;
   1257         }
   1258     }
   1259 #endif
   1260 #if defined (BCM_DFE_SUPPORT)
   1261     if (SOC_IS_DFE(unit))
   1262     {
   1263         int rv;
   1264         int is_filtered = 0;
   1265 
   1266         if (!soc_mem_is_valid(unit, td_test_data.mem) || soc_mem_is_readonly(unit, td_test_data.mem) ||
   1267              (soc_mem_is_writeonly(unit, td_test_data.mem) || soc_mem_is_signal(unit, td_test_data.mem)))
   1268         {
   1269             test_error(unit, "Memory %s is invalid/readonly/writeonly/signal \n",
   1270                        SOC_MEM_UFNAME(unit, td_test_data.mem));
   1271             return -1;
   1272         }
   1273 
   1274         rv = MBCM_DFE_DRIVER_CALL(unit, mbcm_dfe_drv_test_mem_filter, (unit,  td_test_data.mem, &is_filtered));
   1275         if (rv != SOC_E_NONE)
   1276         {
   1277             return rv;
   1278         }
   1279         if (is_filtered)
   1280         {
   1281                test_error(unit, "Memory %s is invalid/readonly/writeonly/signal \n",
   1282                        SOC_MEM_UFNAME(unit,  td_test_data.mem));
   1283                return -1;
   1284         }
   1285     }
   1286 #endif /*BCM_DFE_SUPPORT*/
   1287 
   1288     if (count_arg != -1) {
   1289         td_test_data.count = count_arg;
   1290     }
   1291 
   1292 #if defined(BCM_TOMAHAWK_SUPPORT)
   1293     if (SOC_IS_TOMAHAWKX(unit)) {
   1294       /* if Count is entered use that, otherwise set to zero
   1295        * to allow full range of memory to be tested */
   1296         if (count_arg == -1) {
   1297             td_test_data.count = 0;
   1298         }
   1299     }
   1300 #endif /* defined(BCM_TOMAHAWK_SUPPORT) */
   1301 
   1302     if (td_test_data.srcaddr || td_test_data.dstaddr) {
   1303         test_msg("Overriding buffers can potentially corrupt the system\n");
   1304         test_msg("Don't do it unless you know what you're doing\n");
   1305     }
   1306 
   1307     if (td_test_data.copyno == COPYNO_ALL) {
   1308         td_test_data.copyno = SOC_MEM_BLOCK_ANY(unit, td_test_data.mem);
   1309     }
   1310     if (!SOC_MEM_BLOCK_VALID(unit, td_test_data.mem, td_test_data.copyno)) {
   1311         test_error(unit,
   1312                    "Invalid copyno %d specified in %s\n",
   1313                    td_test_data.copyno, td_test_data.mem_str);
   1314         parse_arg_eq_done(&pt);
   1315         return -1;
   1316     }
   1317 
   1318     index_min = soc_mem_index_min(unit, td_test_data.mem);
   1319     index_max = soc_mem_index_max(unit, td_test_data.mem);
   1320 
   1321     if (td_test_data.index_min <= 0) {
   1322         td_test_data.index_min = index_min;
   1323     }
   1324     if (td_test_data.index_min > index_max) {
   1325         cli_out("Min index out of range: %d\n",  td_test_data.index_min);
   1326         td_test_data.index_min = index_min;
   1327         cli_out("Changed to %d\n", td_test_data.index_min);
   1328     }
   1329 
   1330     if (td_test_data.count <= 0) {
   1331     /*
   1332      * do not use soc_mem_index_count,index_max may have been,
   1333      * index_max may have been modified above
   1334      */
   1335         td_test_data.count = index_max - index_min + 1;
   1336     }
   1337 
   1338     if (td_test_data.index_min + td_test_data.count - 1 > index_max) {
   1339         td_test_data.count = index_max - td_test_data.index_min + 1;
   1340         cli_out("Reduced the count to %d\n", td_test_data.count);
   1341     }
   1342 
   1343     if (td_test_data.count == 0) {
   1344         if (soc_feature(unit,soc_feature_esm_support)) {
   1345               if ((td_test_data.mem == L3_DEFIPm && SOC_MEM_IS_ENABLED(unit, L3_DEFIPm)) ||
   1346                   (td_test_data.mem == L3_DEFIP_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_ONLYm)) ||
   1347                   (td_test_data.mem == L3_DEFIP_DATA_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_DATA_ONLYm)) ||
   1348                   (td_test_data.mem == L3_DEFIP_HIT_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_DATA_ONLYm)) ||
   1349                   (td_test_data.mem == L3_DEFIP_PAIR_128_DATA_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_PAIR_128_DATA_ONLYm)) ||
   1350                   (td_test_data.mem == L3_DEFIP_PAIR_128_HIT_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_PAIR_128_HIT_ONLYm))) {
   1351                   /* The above internal memories will not be supported if External TCAM is present.
   1352                   These internal memories are set to 0 and hence can not run the test on these memories.*/
   1353                   return BCM_E_UNAVAIL;
   1354               } else {
   1355                   test_error(unit,
   1356                      "Cannot test memory %s:  No entries.\n",
   1357                         SOC_MEM_UFNAME(unit, td_test_data.mem));
   1358                   parse_arg_eq_done(&pt);
   1359                   return -1;
   1360 	      }
   1361        } else {
   1362            test_error(unit,
   1363            "Cannot test memory %s:  No entries.\n",
   1364            SOC_MEM_UFNAME(unit, td_test_data.mem));
   1365            parse_arg_eq_done(&pt);
   1366            return -1;
   1367         }
   1368     }
   1369 
   1370     /* for read only memory, number of entries to verify */
   1371     if (td_test_data.rom_ver_count < 0) {
   1372         td_test_data.rom_ver_count = TD_DEFAULT_ROM_VER_COUNT;
   1373     }
   1374     if (td_test_data.rom_ver_count > td_test_data.count) {
   1375         td_test_data.rom_ver_count = td_test_data.count;
   1376     }
   1377 
   1378     /* Disable non-atomic TCAM write handling */
   1379     td_test_data.saved_tcam_protect_write =
   1380         SOC_CONTROL(unit)->tcam_protect_write;
   1381     SOC_CONTROL(unit)->tcam_protect_write = FALSE;
   1382 
   1383     if(SOC_IS_DFE(unit) || SOC_IS_DNXF(unit)){
   1384         SOC_MEM_TEST_SKIP_CACHE_SET(unit, 1);
   1385         if (soc_mem_parity_control(unit, td_test_data.mem, td_test_data.copyno,
   1386                                FALSE) < 0) {
   1387             test_error(unit, "Could not disable parity warnings on memory %s\n",
   1388                    SOC_MEM_UFNAME(unit, td_test_data.mem));
   1389             parse_arg_eq_done(&pt);
   1390             return -1;
   1391         }
   1392     } else {
   1393             if (td_rand_common_clear(unit, td_test_data.mem, td_test_data.copyno)) {
   1394                 parse_arg_eq_done(&pt);
   1395                 return -1;
   1396             }
   1397     }
   1398 
   1399     if (soc_mem_cpu_write_control(unit, td_test_data.mem, td_test_data.copyno,
   1400                                   TRUE, &td_test_data.orig_enable) < 0) {
   1401         test_error(unit, "Could not enable exclusive cpu write on memory %s\n",
   1402                    SOC_MEM_UFNAME(unit, td_test_data.mem));
   1403         parse_arg_eq_done(&pt);
   1404         return -1;
   1405     }
   1406 
   1407     /*
   1408      * Turn off L2 task to keep it from going crazy if L2 memory is
   1409      * being tested.
   1410      */
   1411 
   1412 #ifdef BCM_XGS_SWITCH_SUPPORT
   1413     if (soc_feature(unit, soc_feature_arl_hashed)) {
   1414         (void)soc_l2x_stop(unit);
   1415     }
   1416 #endif
   1417 
   1418 #ifdef BCM_TRIUMPH_SUPPORT
   1419     if (soc_feature(unit, soc_feature_esm_support)) {
   1420         /* Some tables have dependency on the content of other table */
   1421         switch (td_test_data.mem) {
   1422         case EXT_ACL360_TCAM_DATAm:
   1423         case EXT_ACL360_TCAM_DATA_IPV6_SHORTm:
   1424             if (SOC_FAILURE(soc_mem_clear(unit, EXT_ACL360_TCAM_MASKm,
   1425                 MEM_BLOCK_ALL, TRUE)))
   1426             {
   1427                 test_error(unit, "Failed to clear EXT_ACL360_TCAM_MASKm\n");
   1428                 parse_arg_eq_done(&pt);
   1429                 return -1;
   1430             }
   1431             break;
   1432         case EXT_ACL432_TCAM_DATAm:
   1433         case EXT_ACL432_TCAM_DATA_IPV6_LONGm:
   1434         case EXT_ACL432_TCAM_DATA_L2_IPV4m:
   1435         case EXT_ACL432_TCAM_DATA_L2_IPV6m:
   1436             if (SOC_FAILURE(soc_mem_clear(unit, EXT_ACL432_TCAM_MASKm,
   1437                 MEM_BLOCK_ALL, TRUE)))
   1438             {
   1439                 test_error(unit, "Failed to clear EXT_ACL432_TCAM_MASKm\n");
   1440                 parse_arg_eq_done(&pt);
   1441                 return -1;
   1442             }
   1443             break;
   1444         default:
   1445             break;
   1446         }
   1447     }
   1448 #endif /* BCM_TRIUMPH_SUPPORT */
   1449 
   1450     td_test_data.index_max = td_test_data.index_min +
   1451         td_test_data.count - 1;
   1452 
   1453 #if defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TRIDENT3_SUPPORT)
   1454         if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) {
   1455             if (pstats_tr_init(unit) < 0) {
   1456                 parse_arg_eq_done(&pt);
   1457                 return -1;
   1458             }
   1459         }
   1460 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
   1461 
   1462     if (td_test_data.mor_en) {
   1463 #if defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TRIDENT3_SUPPORT)
   1464         if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) {
   1465             if (pstats_mor_init(unit) < 0) {
   1466                 test_error(unit, "Table DMA mor init error\n");
   1467                 parse_arg_eq_done(&pt);
   1468                 return -1;
   1469             }
   1470         }
   1471 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
   1472     }
   1473 
   1474     parse_arg_eq_done(&pt);
   1475 #ifdef BCM_PETRA_SUPPORT
   1476     if (SOC_IS_ARAD(unit))
   1477     {
   1478       bcm_common_linkscan_enable_set(unit,0);
   1479       soc_counter_stop(unit);
   1480     }
   1481 #endif
   1482 
   1483 #ifdef BCM_TOMAHAWK_SUPPORT
   1484     if (SOC_IS_TOMAHAWK(unit) &&
   1485         !soc_feature(unit, soc_feature_advanced_flex_counter)) {
   1486         if ((td_test_data.mem >= ING_FLEX_CTR_COUNTER_TABLE_0m &&
   1487              td_test_data.mem <= ING_FLEX_CTR_COUNTER_TABLE_9_PIPE3m) ||
   1488             (td_test_data.mem >= EGR_FLEX_CTR_COUNTER_TABLE_0m &&
   1489              td_test_data.mem <= EGR_FLEX_CTR_COUNTER_TABLE_3_Ym)) {
   1490             return SOC_E_UNAVAIL;
   1491         }
   1492     }
   1493 #endif /* BCM_TOMAHAWK_SUPPORT */
   1494     return 0;
   1495 }
   1496 
   1497 int
   1498 td_test_done(int unit, void *pa)
   1499 {
   1500     td_test_data_clear(unit);
   1501 #ifdef BCM_CMICM_SUPPORT
   1502     if(td_test_data.ccm) {
   1503         return 0;
   1504     }
   1505 #endif
   1506 
   1507 #ifdef BCM_SAND_SUPPORT
   1508     if (SOC_IS_SAND(unit))
   1509     {
   1510         return 0;
   1511     }
   1512 #endif
   1513     /* Restore non-atomic TCAM write handling status */
   1514     SOC_CONTROL(unit)->tcam_protect_write =
   1515         td_test_data.saved_tcam_protect_write;
   1516 
   1517     if (soc_mem_cpu_write_control(unit, td_test_data.mem, td_test_data.copyno,
   1518                                   td_test_data.orig_enable,
   1519                                   &td_test_data.orig_enable) < 0) {
   1520         test_error(unit, "Could not disable exclusive cpu write on memory "
   1521                    "%s\n",
   1522                    SOC_MEM_UFNAME(unit, td_test_data.mem));
   1523         return -1;
   1524     }
   1525 
   1526     if(SOC_IS_DFE(unit) || SOC_IS_DNXF(unit)) {
   1527         SOC_MEM_TEST_SKIP_CACHE_SET(unit, 0);
   1528         if (soc_mem_parity_restore(unit, td_test_data.mem,
   1529                                td_test_data.copyno) < 0) {
   1530             test_error(unit, "Could not restore parity warnings on memory %s\n",
   1531                    SOC_MEM_UFNAME(unit, td_test_data.mem));
   1532             return -1;
   1533         }
   1534     } else {
   1535         if (td_rand_common_restore(unit, td_test_data.mem, td_test_data.copyno)) {
   1536             return -1;
   1537         }
   1538     }
   1539 
   1540     return 0;
   1541 }
   1542 
   1543 #endif /* BCM_XGS_SWITCH_SUPPORT */
   1544 
   1545 #ifdef BCM_SAND_SUPPORT
   1546 
   1547 /* Compare the memory entry values and return 0 id if they are the same
   1548  * The first nof_data_bits bits in the entries are compared.
   1549  */
   1550 static int compare_mem_entry(int unit, soc_mem_t mem, int array_index, int index, int blk, uint32 *pattern, uint32 *entry_buf, int nof_data_bits, char *test) {
   1551     int rv=0;
   1552     if (!(SHR_BITEQ_RANGE(entry_buf, pattern, 0, nof_data_bits))) { /*Compare only the amount of bits in the memory */
   1553         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%s: Memory %s[%d].%s: entry %d read with a different value than the one written to it\n"),
   1554           test, SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk), index));
   1555         rv = -1;
   1556     }
   1557     return rv;
   1558 }
   1559 
   1560 /* test DMA to the given memory using the given pettern for one entry */
   1561 STATIC int
   1562 dnx_table_dma_test_a_pattern(
   1563   int unit,
   1564   soc_mem_t mem,         /* The memory to be tested */
   1565   int nof_data_bits,     /* This number of bits will be tested in each memory entry */
   1566   uint32 *pattern,       /* The patter to use for testing, of one memory entry */
   1567   uint32 *write_dma_buf, /* input: DMA buffer fitting one array index of the memory */
   1568   uint32 *read_dma_buf)  /* input: DMA buffer fitting one array index of the memory */
   1569 {
   1570     int rv = -1;
   1571     int entry_words;
   1572 
   1573     int last_entry_in_buffer; /* last entry array index in a buffer holding memory entries of one array index */
   1574 
   1575     int index, index_min, index_max, array_index_min, array_index_max, array_index;
   1576     int blk;
   1577     int j;
   1578     uint32 * p;
   1579     uint32 * q;
   1580     int compare_error_cnt=0;
   1581     uint32 entry_buf[SOC_MAX_MEM_WORDS] = {0};
   1582     array_index_min = array_index_max = 0;
   1583 
   1584     if (SOC_MEM_IS_ARRAY(unit, mem))
   1585     {
   1586         soc_mem_array_info_t *maip = SOC_MEM_ARRAY_INFOP(unit, mem);
   1587         if (maip)
   1588         {
   1589             array_index_max = (maip->numels - 1) + maip->first_array_index;
   1590             array_index_min = maip->first_array_index;
   1591         }
   1592     }
   1593     index_min = soc_mem_index_min(unit, mem);
   1594     if (index_min != 0)
   1595     {
   1596         LOG_VERBOSE(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s min index is not correct\n"), SOC_MEM_NAME(unit, mem)));
   1597     }
   1598     index_max = soc_mem_index_max(unit, mem);
   1599     entry_words = soc_mem_entry_words(unit, mem);
   1600     last_entry_in_buffer = (index_max - index_min) * entry_words; /* Number of words to fill */
   1601 
   1602     /* test 1: write the pattern using table DMA and read it entry by entry */
   1603     /* Fill the buffer for writing */
   1604     for (index = index_max, p = write_dma_buf; index >= 0;  --index) {
   1605         for (j = 0; j < entry_words; ++j) {
   1606             *(p++) = pattern[j];
   1607         }
   1608     }
   1609     for (array_index = array_index_min; array_index <= array_index_max; array_index++) {
   1610         rv = soc_mem_array_write_range(unit, 0, mem, array_index, MEM_BLOCK_ALL, index_min, index_max, write_dma_buf);
   1611         if (rv < 0)
   1612         {
   1613             LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to DMA write %s[%d]\n"),
   1614               SOC_MEM_NAME(unit, mem), array_index));
   1615             return rv;
   1616         }
   1617         SOC_MEM_BLOCK_ITER(unit, mem, blk) {
   1618             for (index = index_max; index >= 0;  --index) {
   1619                 if (soc_mem_array_read(unit, mem, array_index, blk, index, entry_buf) != 0) {
   1620                     LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to read %s[%d].%s entry %d\n"),
   1621                       SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk), index));
   1622                     return rv;
   1623                 }
   1624                 if (compare_mem_entry(unit, mem, array_index, index, blk, pattern, entry_buf, nof_data_bits, "DMA write, regular read")) {
   1625                     LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s[%d].%s entry %d read with a different value than the one written to it\n"),
   1626                      SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk), index));
   1627                     compare_error_cnt++;
   1628                 }
   1629             }
   1630         }
   1631     }
   1632 
   1633     /* test 2: write the ~pattern using table DMA and read it using table DMA */
   1634     SHR_BITNEGATE_RANGE(pattern, 0, nof_data_bits, entry_buf);
   1635     /* Fill the buffer for writing */
   1636     for (index = index_max, p = write_dma_buf; index >= 0; --index) {
   1637         for (j = 0; j < entry_words; ++j) {
   1638             *(p++) = entry_buf[j];
   1639         }
   1640     }
   1641     for (array_index = array_index_min; array_index <= array_index_max; array_index++) {
   1642         rv = soc_mem_array_write_range(unit, 0, mem, array_index, MEM_BLOCK_ALL, index_min, index_max, write_dma_buf);
   1643         if (rv < 0)
   1644         {
   1645             LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to DMA write %s[%d]\n"),
   1646               SOC_MEM_NAME(unit, mem), array_index));
   1647             return rv;
   1648         }
   1649         SOC_MEM_BLOCK_ITER(unit, mem, blk) {
   1650             rv = soc_mem_array_read_range(unit, mem, array_index, blk, index_min, index_max, read_dma_buf);
   1651             if (rv < 0)
   1652             {
   1653                 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to DMA read %s[%d].%s\n"),
   1654                   SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk)));
   1655                 return rv;
   1656             }
   1657             for (index = index_max, p = read_dma_buf; index >= 0; --index, p += entry_words) {
   1658                 if (compare_mem_entry(unit, mem, array_index, index, blk, p, entry_buf, nof_data_bits, "DMA write, DMA read")) {
   1659                     LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s[%d].%s entry %d read with a different value than the one written to it\n"),
   1660                             SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk), index));
   1661                     compare_error_cnt++;
   1662                 }
   1663             }
   1664         }
   1665     }
   1666 
   1667     /* test 3: write the pattern using SLAM DMA and read it using table DMA */
   1668     /* Fill the table including all array indices and block instances */
   1669     if (sand_fill_table_with_entry(unit, mem, MEM_BLOCK_ALL, pattern) != 0) {
   1670         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to write %s using SLAM DMA\n"),
   1671           SOC_MEM_NAME(unit, mem)));
   1672             return rv;
   1673     }
   1674 
   1675     for (array_index = array_index_min; array_index <= array_index_max; array_index++) {
   1676         SOC_MEM_BLOCK_ITER(unit, mem, blk) {
   1677             rv = soc_mem_array_read_range(unit, mem, array_index, blk, index_min, index_max, read_dma_buf);
   1678             if (rv < 0)
   1679             {
   1680                 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to DMA read %s[%d].%s\n"),
   1681                   SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk)));
   1682                 return rv;
   1683             }
   1684             for (index = index_max, p = read_dma_buf; index >= 0; --index, p += entry_words) {
   1685                 if (compare_mem_entry(unit, mem, array_index, index, blk, pattern, p, nof_data_bits, "SLAM DMA write, DMA read")) {
   1686                     LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s[%d].%s entry %d read with a different value than the one written to it\n"),
   1687                             SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk), index));
   1688                     compare_error_cnt++;
   1689                 }
   1690             }
   1691         }
   1692     }
   1693 
   1694     /* test 4: write the ~pattern using SLAM DMA and read it using table DMA */
   1695     /* Fill the table including all array indices anf block instances */
   1696     if (sand_fill_table_with_entry(unit, mem, MEM_BLOCK_ALL, entry_buf) != 0) {
   1697         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to write %s using SLAM DMA\n"),
   1698           SOC_MEM_NAME(unit, mem)));
   1699             return rv;
   1700     }
   1701 
   1702     /* test 5: write the pattern changing each entry using table DMA and read it using table DMA */
   1703     /* Fill the buffer for writing */
   1704     for (index = index_max, p = write_dma_buf; index >= 0; --index, p += entry_words) {
   1705         j = index % nof_data_bits;
   1706         p[j / 32] ^= ((uint32)1) << (j % 32); /* flip bit number J in the entry */
   1707     }
   1708     for (array_index = array_index_min; array_index <= array_index_max; array_index++) {
   1709         j = array_index % nof_data_bits; /* Make each array index test using a different first entry value */
   1710         write_dma_buf[j / 32] ^=((uint32)1) << (j % 32); /* Flip bit number j in the entry */
   1711         rv = soc_mem_array_write_range(unit, 0, mem, array_index, MEM_BLOCK_ALL, index_min, index_max, write_dma_buf);
   1712         if (rv < 0)
   1713         {
   1714             LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to DMA write %s[%d]\n"),
   1715               SOC_MEM_NAME(unit, mem), array_index));
   1716             return rv;
   1717         }
   1718         SOC_MEM_BLOCK_ITER(unit, mem, blk) {
   1719             rv = soc_mem_array_read_range(unit, mem, array_index, blk, index_min, index_max, read_dma_buf);
   1720             if (rv < 0)
   1721             {
   1722                 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Failed to DMA read %s[%d].%s\n"),
   1723                   SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk)));
   1724                 
   1725             }
   1726             for (index = index_max, p = read_dma_buf, q = write_dma_buf; index >= 0; --index, p += entry_words, q += entry_words) {
   1727                 if (compare_mem_entry(unit, mem, array_index, index, blk, p, q, nof_data_bits, "DMA write different values, DMA read")) {
   1728                     LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s[%d].%s entry %d read with a different value than the one written to it\n"),
   1729                             SOC_MEM_NAME(unit, mem), array_index, SOC_BLOCK_NAME(unit, blk), index));
   1730                     compare_error_cnt++;
   1731                 }
   1732             }
   1733             read_dma_buf[0] ^= (uint32)(-1); /* Make sure next read is actually reading the buffer */
   1734             read_dma_buf[last_entry_in_buffer] ^=(uint32)(-1);
   1735         }
   1736     }
   1737     if (compare_error_cnt > 0)
   1738     {
   1739         rv = -1;
   1740     }
   1741     return rv;
   1742 }
   1743 
   1744 /* Test DMA on a given memory - TR 71 implementation for Dune devices */
   1745 int
   1746 dnx_table_dma_test(int unit, args_t *a, void *p)
   1747 {
   1748     soc_mem_t mem = 0;
   1749     int entry_words, leftover=0;
   1750     int index_min, index_max;
   1751     int copyno;
   1752     char        *mem_name;
   1753     int i, f, size=0;
   1754     soc_field_info_t  *fieldp;
   1755     soc_field_info_t  *last_field_p = NULL;
   1756     uint32 *dma_buf=NULL;
   1757     void *temp_p=NULL;
   1758     uint32 *read_buf;
   1759 
   1760     soc_mem_info_t      *memp;
   1761     uint32 nof_data_bits = 0; /* number of bits in a memory entry excluding ECC/parity that may exist in the last memory field */
   1762     uint32 nof_bits_in_mem = 0, last_bit_of_field = 0; /* number of bits in a memory entry */
   1763     int            rv = -1;
   1764     uint32 help_status_default = 0;
   1765     uint32 help_status=0;
   1766     uint32 pattern_seed = 0xaa55;
   1767     uint32 pattern_buf[SOC_MAX_MEM_WORDS] = {0};
   1768 
   1769     parse_table_t    pt;
   1770     sal_srand(sal_time());
   1771     parse_table_init(unit, &pt);
   1772     parse_table_add(&pt, "Memory", PQ_STRING, "", &mem_name, NULL);
   1773     parse_table_add(&pt, "Help", PQ_DFL|PQ_INT, &help_status_default, &help_status, NULL);
   1774 
   1775     if (parse_arg_eq(a, &pt) < 0) {
   1776         cli_out("%s: Invalid option: %s\n",
   1777                 ARG_CMD(a), ARG_CUR(a));
   1778     }
   1779     /* Parsing the memory name */
   1780     if (mem_name == 0 || *mem_name == 0 ||
   1781     parse_memory_name(unit,
   1782               &mem,
   1783               mem_name,
   1784               &copyno,
   1785               0) < 0) {
   1786         test_error(unit,
   1787             "Missing or unknown memory name "
   1788             "(use listmem for list)\n");
   1789     }
   1790 
   1791     if (!soc_mem_is_valid(unit, mem) || soc_mem_is_readonly(unit, mem)
   1792     || soc_mem_is_writeonly(unit, mem))
   1793     {
   1794         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Can not test memory:%s which is not valid or read-only or write-only\n"), SOC_MEM_NAME(unit, mem)));
   1795         goto exit;
   1796     }
   1797     if (2 + soc_mem_entry_words(unit, mem) > CMIC_SCHAN_WORDS(unit))
   1798     {
   1799         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Can not perform DMA on wide memory %s, not testing\n"), SOC_MEM_NAME(unit, mem)));
   1800         goto exit;
   1801     }
   1802     if (soc_mem_is_signal(unit, mem))
   1803     {
   1804         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s will fail because it is Dynamic, still testing\n"), SOC_MEM_NAME(unit, mem)));
   1805     }
   1806 
   1807     memp = &SOC_MEM_INFO(unit, mem);
   1808 
   1809     index_min = soc_mem_index_min(unit, mem);
   1810     if (index_min != 0)
   1811     {
   1812         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s min index is not correct, should be zero\n"), SOC_MEM_NAME(unit, mem)));
   1813         goto exit;
   1814     }
   1815     if (!soc_mem_dmaable(unit, mem, copyno) || !soc_mem_slamable(unit, mem, copyno))
   1816     {
   1817         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Memory %s not enabled for DMA\n"), SOC_MEM_NAME(unit, mem)));
   1818         goto exit;
   1819     }
   1820     index_max = soc_mem_index_max(unit, mem);
   1821     entry_words = soc_mem_entry_words(unit, mem);
   1822     size = (index_max - index_min + 1) * entry_words; /* Number of words to fill */
   1823     /* Allocating DMA buffer */
   1824     rv = sand_alloc_dma_mem(unit, FALSE, &temp_p, size * (2 * sizeof(uint32)), "DMA buffer");
   1825     if (rv < 0)
   1826     {
   1827         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "allocation failed %s min index is not correct\n"), SOC_MEM_NAME(unit, mem)));
   1828         rv = -1;
   1829         goto exit;
   1830     }
   1831     dma_buf = (uint32*)temp_p;
   1832     read_buf = dma_buf + size * 2;
   1833 
   1834     /* Check the entry width with and without the last ECCf or PARITYf field */
   1835     for (f = 0; f < memp->nFields; f++)
   1836     {
   1837         fieldp = &(memp->fields[f]);
   1838 
   1839         last_bit_of_field = fieldp->bp + fieldp->len;
   1840         if (last_bit_of_field > nof_bits_in_mem) {
   1841             nof_bits_in_mem = last_bit_of_field;
   1842             last_field_p = fieldp;
   1843         }
   1844 
   1845     }
   1846     nof_data_bits = nof_bits_in_mem;
   1847     if (last_field_p != NULL)
   1848     {
   1849         if ((last_field_p->field == ECCf) || (last_field_p->field == PARITYf))
   1850         {
   1851             nof_data_bits -= last_field_p->len;
   1852         }
   1853     }
   1854 
   1855     /* Check if the bits in field are calculated correctly */
   1856     if (((nof_bits_in_mem + 7) / 8 != soc_mem_entry_bytes(unit, mem)) || (nof_data_bits <= 0 || nof_data_bits > nof_bits_in_mem))
   1857     {
   1858         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Entry width is not calculated correctly for mem: %s, found %u bits according to fields, and memory reports having %u bytes\n"), SOC_MEM_NAME(unit, mem), nof_bits_in_mem, (unsigned)soc_mem_entry_bytes(unit, mem)));
   1859         rv =-1;
   1860         goto exit;
   1861     }
   1862 
   1863     /* test with a zero patten */
   1864     rv = dnx_table_dma_test_a_pattern(unit, mem, nof_data_bits, pattern_buf, dma_buf, read_buf);
   1865     if (rv < 0)
   1866     {
   1867         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Test failed %s memory DMA test\n"), SOC_MEM_NAME(unit, mem)));
   1868     }
   1869 
   1870     /* Filling the pattern in the pattern buffer */
   1871     for (i = 0, leftover = nof_data_bits; leftover >= 17; i += 17, leftover -= 17) {
   1872         SHR_BITCOPY_RANGE(pattern_buf, i, &pattern_seed, 0, 17);
   1873     }
   1874     if (leftover > 0 ) {
   1875         SHR_BITCOPY_RANGE(pattern_buf, i, &pattern_seed, 0, leftover);
   1876     }
   1877 
   1878     /* Testing the DMA with the pattern */
   1879     rv = dnx_table_dma_test_a_pattern(unit, mem, nof_data_bits, pattern_buf, dma_buf, read_buf);
   1880     if (rv < 0)
   1881     {
   1882         LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "Test failed %s memory DMA test\n"), SOC_MEM_NAME(unit, mem)));
   1883     }
   1884 
   1885 exit:
   1886     /* Free the buffers */
   1887     if (temp_p != NULL)
   1888     {
   1889         sand_free_dma_mem(unit, 0, &temp_p);
   1890     }
   1891     parse_arg_eq_done(&pt);
   1892     return rv;
   1893 }
   1894 
   1895 #endif