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

sbusdma_test.c (64620B)


      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  * SBUS DMA Test
      8  *
      9  * The SBUS DMA test writes/reads a table with one or more CMC/channel. It
     10  * initializes a source memory image with random values. Then, it kicks off a
     11  * register/descriptor based SBUS DMA write from the source memory to the table.
     12  * As soon as the write finishes, it kicks off another register/descriptor based
     13  * SBUS DMA read from the table to a destination memory. Data integrity check is
     14  * done by comparing the source and destination memories are compared with the
     15  * reserved and parity/ECC fields excluded. Write and read performance in MB/s
     16  * and transfer/s are calculated from the set up of the first DMA to the finish
     17  * of the second DMA.
     18  */
     19 
     20 #include <shared/bsl.h>
     21 #include <sal/appl/sal.h>
     22 #include <sal/core/time.h>
     23 #include <appl/diag/system.h>
     24 #include <appl/diag/parse.h>
     25 #include <soc/mem.h>
     26 #include <soc/register.h>
     27 #include <soc/debug.h>
     28 #include <soc/dma.h>
     29 #include <soc/l2x.h>
     30 #include <soc/schanmsg_internal.h>
     31 #include <soc/sbusdma_internal.h>
     32 #include "testlist.h"
     33 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT)
     34 #include <soc/cmicm.h>
     35 #endif
     36 
     37 #if defined (BCM_TOMAHAWK_SUPPORT)
     38 #include <soc/tomahawk.h>
     39 #endif
     40 
     41 extern int compare_with_mask(const void *m1_void, const void *m2_void,
     42                              size_t len);
     43 
     44 #define SOC_SBUSDMA_CH_MAX  SOC_CMCS_NUM_MAX * SOC_SBUSDMA_CH_PER_CMC
     45 #define NUM_SBUSDMA_CH_PER_CMC (sb_test_data.max_num_ch)
     46 #define TD_DEFAULT_DUMP_ENTRY_COUNT  10
     47 #define INT_FRAC_4PT(x) (x) / 10000, (x) % 10000
     48 
     49 #if defined(BCM_ESW_SUPPORT) && defined(BCM_SBUSDMA_SUPPORT) && \
     50     (defined(BCM_CMICM_SUPPORT)|| defined(BCM_CMICX_SUPPORT))
     51 
     52 typedef struct sbt_data_s {
     53     int             init_done;
     54     int             run[SOC_SBUSDMA_CH_MAX];
     55     int             mem_done[SOC_SBUSDMA_CH_MAX];
     56 
     57     uint32          rnum;
     58     int             rate_calc_int;
     59     int             ecc_as_data;/* treat ecc field as regular field */
     60     int             big_endian;
     61     int             big_pio;
     62     int             slam_en;    /* Slam Enable */
     63     int             slam_dir;   /* Slam direction */
     64     int             check_data; /* Enable data integrity check */
     65     int             desc_mode;  /* Descriptor based SBUS DMA mode */
     66     uint32          cmc_ch_bm;  /* CMC# and channel# bitmap for SBUS DMA */
     67     int             dma_wr_en;  /* SBUS DMA write enable */
     68     int             dma_rd_en;  /* SBUS DMA read enable */
     69     int             test_mode;  /* Test mode: 1->write, 2->read, 3->write&read (default) */
     70     int             num_mem;    /* Number of memories to be tested in parallel */
     71     int             verbose;    /* Turn on verbose messages */
     72     int             debug;      /* Turn on debug messages */
     73                                 /* Map cmc_ch_bm to memory index */
     74     int             ch_mem_map[SOC_SBUSDMA_CH_MAX];
     75     uint32          max_num_ch;
     76 } sb_test_data_t;
     77 
     78 typedef struct sbt_mem_s {
     79     char           *mem_str;
     80     soc_mem_t       mem;
     81     int             copyno;
     82     int             index_min;
     83     int             index_max;
     84     int             count;
     85     int             frag_count;
     86     int             frag_index_max[32768];
     87     int             frag_index_min[32768];
     88 
     89     uint32         *source;
     90     uint32         *dma_ed;
     91 
     92     int             bufwords;
     93     int             entwords;
     94 
     95     uint32          datamask[SOC_MAX_MEM_WORDS];
     96     uint32          tcammask[SOC_MAX_MEM_WORDS];
     97     uint32          eccmask[SOC_MAX_MEM_WORDS];
     98     uint32          forcemask[SOC_MAX_MEM_WORDS];
     99     uint32          forcedata[SOC_MAX_MEM_WORDS];
    100     uint32          accum_tcammask;
    101     uint32          accum_forcemask;
    102 
    103     uint32          mem_cmc_ch_bm;
    104 } sb_test_mem_t;
    105 
    106 static sb_test_data_t sb_test_data;
    107 
    108 static sb_test_mem_t sb_test_mem[SOC_SBUSDMA_CH_MAX];
    109 
    110 static sbusdma_desc_handle_t sbusdma_desc_handle[SOC_SBUSDMA_CH_MAX];
    111 
    112 static int sb_test_mem_cmp_fn(int, int, void*, void*);
    113 
    114 static int
    115 sb_test_data_init(int unit, int alloc)
    116 {
    117     int i, n;
    118 
    119     if (!sb_test_data.init_done) {
    120         sb_test_mem[0].mem = L2Xm;
    121         sb_test_mem[0].mem_str = sal_strdup("l2_entry");
    122 #ifdef BCM_FIREBOLT_SUPPORT
    123         if (SOC_IS_FBX(unit)) {
    124 #ifdef BCM_TRIUMPH3_SUPPORT
    125             if (SOC_IS_TRIUMPH3(unit)) {
    126                 sb_test_mem[0].mem = L2_ENTRY_1m;
    127                 sb_test_mem[0].mem_str = sal_strdup("l2_entry_1");
    128                 sb_test_mem[0].count = soc_mem_index_count(unit, L2_ENTRY_1m);
    129             } else
    130 #endif /* BCM_TRIUMPH3_SUPPORT */
    131             if (SOC_MEM_IS_VALID(unit, L2_ENTRY_ONLYm)) {
    132                 sb_test_mem[0].mem = L2_ENTRY_ONLYm;
    133                 sb_test_mem[0].mem_str = sal_strdup("l2_entry_only");
    134                 sb_test_mem[0].count = soc_mem_index_count(unit, L2_ENTRY_ONLYm);
    135             }
    136         } else
    137 #endif /* BCM_FIREBOLT_SUPPORT */
    138         {
    139             test_error(unit, "SBUS DMA Error:  Invalid SOC type\n");
    140             return BCM_E_FAIL;
    141         }
    142         sb_test_data.init_done     = TRUE;
    143         sb_test_data.slam_en       = FALSE;
    144         sb_test_data.slam_dir      = TRUE;  /* SLAM from low to high */
    145         sb_test_data.ecc_as_data   = TRUE;
    146         sb_test_data.desc_mode     = 0;
    147         sb_test_data.cmc_ch_bm     = 0;
    148         sb_test_mem[0].frag_count  = 0;
    149         sb_test_data.dma_wr_en     = TRUE;
    150         sb_test_data.dma_rd_en     = TRUE;
    151         sb_test_data.test_mode     = 3;
    152         sb_test_data.num_mem       = 1;
    153         sb_test_data.verbose       = FALSE;
    154         sb_test_data.debug         = FALSE;
    155         sb_test_data.rnum          = sal_rand();
    156         sb_test_data.rate_calc_int = 10;
    157         sb_test_data.check_data    = TRUE;
    158         for (i = 0; i < SOC_SBUSDMA_CH_MAX; i++) {
    159             sb_test_data.run[i] = FALSE;
    160             sb_test_data.mem_done[i] = TRUE;
    161         }
    162     }
    163 
    164     sb_test_data.max_num_ch = soc_sbusdma_cmc_max_num_ch_get(unit);
    165 
    166     if (!alloc) {
    167         return SOC_E_NONE;
    168     }
    169 
    170     for (n = 0; n < sb_test_data.num_mem; n++) {
    171         sb_test_mem[n].entwords = soc_mem_entry_words(unit, sb_test_mem[n].mem);
    172         sb_test_mem[n].bufwords = sb_test_mem[n].entwords * sb_test_mem[n].count;
    173         sb_test_mem[n].source = soc_cm_salloc(unit,
    174                                               WORDS2BYTES(sb_test_mem[n].bufwords),
    175                                               "sb_test_data source");
    176         sb_test_mem[n].dma_ed = soc_cm_salloc(unit,
    177                                               WORDS2BYTES(sb_test_mem[n].bufwords),
    178                                               "sb_test_data dma_ed");
    179         if ((sb_test_mem[n].source == NULL) ||
    180                 (sb_test_mem[n].dma_ed == NULL)) {
    181             if (sb_test_mem[n].source) {
    182                 soc_cm_sfree(unit, sb_test_mem[n].source);
    183                 sb_test_mem[n].source = NULL;
    184             }
    185             if (sb_test_mem[n].dma_ed) {
    186                 soc_cm_sfree(unit, sb_test_mem[n].dma_ed);
    187                 sb_test_mem[n].dma_ed = NULL;
    188             }
    189             test_error(unit, "SBUS DMA Error:  Failed to allocate DMA memory\n");
    190             return BCM_E_FAIL;
    191         }
    192 
    193         if (sb_test_data.rnum != 0) {
    194             sal_memset(sb_test_mem[n].source, 0xff,
    195                        WORDS2BYTES(sb_test_mem[n].bufwords));
    196             sal_memset(sb_test_mem[n].dma_ed, 0xff,
    197                        WORDS2BYTES(sb_test_mem[n].bufwords));
    198         }
    199         soc_mem_datamask_get(unit, sb_test_mem[n].mem, sb_test_mem[n].datamask);
    200         soc_mem_tcammask_get(unit, sb_test_mem[n].mem, sb_test_mem[n].tcammask);
    201         soc_mem_eccmask_get(unit, sb_test_mem[n].mem, sb_test_mem[n].eccmask);
    202         soc_mem_forcedata_get(unit, sb_test_mem[n].mem, sb_test_mem[n].forcemask,
    203                               sb_test_mem[n].forcedata);
    204         sb_test_mem[n].accum_tcammask = 0;
    205         for (i = 0; i < sb_test_mem[n].entwords; i++) {
    206             sb_test_mem[n].accum_tcammask |= sb_test_mem[n].tcammask[i];
    207         }
    208         sb_test_mem[n].accum_forcemask = 0;
    209         for (i = 0; i < sb_test_mem[n].entwords; i++) {
    210             sb_test_mem[n].accum_forcemask |= sb_test_mem[n].forcemask[i];
    211         }
    212         if (!sb_test_data.ecc_as_data) {
    213             for (i = 0; i < sb_test_mem[n].entwords; i++) {
    214                 sb_test_mem[n].datamask[i] &= ~sb_test_mem[n].eccmask[i];
    215             }
    216         }
    217         soc_mem_datamask_memtest(unit, sb_test_mem[n].mem, sb_test_mem[n].datamask);
    218     }
    219 
    220     return SOC_E_NONE;
    221 }
    222 
    223 static void
    224 sb_test_dump_data(int unit, int n, int entry_cnt)
    225 {
    226     int     i, base_index, idx;
    227     uint32 *s, *d;
    228 
    229     cli_out("SBUS DMA test for %s.%s: index_min %d index_max %d\n"
    230             "    bufwords %d entwords %d rnum %d count %d\n",
    231             SOC_MEM_UFNAME(unit, sb_test_mem[n].mem),
    232             SOC_BLOCK_NAME(unit, sb_test_mem[n].copyno),
    233             sb_test_mem[n].index_min,
    234             sb_test_mem[n].index_max, sb_test_mem[n].bufwords,
    235             sb_test_mem[n].entwords, sb_test_data.rnum, sb_test_mem[n].count);
    236 
    237     cli_out("    Datamask: ");
    238     for (idx = 0; idx < sb_test_mem[n].entwords; idx++) {
    239         cli_out(" %08x", sb_test_mem[n].datamask[idx]);
    240     }
    241     cli_out("\n\n");
    242 
    243     s = sb_test_mem[n].source;
    244     d = sb_test_mem[n].dma_ed;
    245 
    246     assert(s && d);
    247 
    248     base_index = sb_test_mem[n].index_min;
    249     s += sb_test_mem[n].index_min;
    250 
    251     for (i = sb_test_mem[n].index_min;
    252             i <= sb_test_mem[n].index_max && i - base_index < entry_cnt;
    253             ++i) {
    254         cli_out("    SBUS index %d: "
    255                 "source entry %d, dma_ed entry %d\n",
    256                 i, i - base_index, i - sb_test_mem[n].index_min);
    257         cli_out("    Source:  ");
    258         for (idx = 0; idx < sb_test_mem[n].entwords; idx++) {
    259             cli_out(" %08x", s[idx]);
    260         }
    261         cli_out("\n");
    262         cli_out("    DMA_ed:  ");
    263         for (idx = 0; idx < sb_test_mem[n].entwords; idx++) {
    264             cli_out(" %08x", d[idx]);
    265         }
    266         cli_out("\n\n");
    267         d += sb_test_mem[n].entwords;
    268         s += sb_test_mem[n].entwords;
    269     }
    270 }
    271 
    272 static void
    273 sb_test_data_clear(int unit)
    274 {
    275     int n;
    276 
    277     for (n = 0; n < sb_test_data.num_mem; n++) {
    278         if (sb_test_mem[n].source) {
    279             soc_cm_sfree(unit, sb_test_mem[n].source);
    280             sb_test_mem[n].source = NULL;
    281         }
    282         if (sb_test_mem[n].dma_ed) {
    283             soc_cm_sfree(unit, sb_test_mem[n].dma_ed);
    284             sb_test_mem[n].dma_ed = NULL;
    285         }
    286     }
    287 }
    288 
    289 static uint32
    290 sb_test_get_curr_rnum(void)
    291 {
    292     return sb_test_data.rnum;
    293 }
    294 
    295 static uint32
    296 sb_test_rand32(uint32 prev)
    297 {
    298     return sb_test_data.rnum = 1664525L * prev + 1013904223L;
    299 }
    300 
    301 #define BSAND_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0x00ff00) << 8) | \
    302                             (((x) & 0xff0000) >> 8) | (((x) >> 24)))
    303 #define BSAND_WORD_SWAP(x) ((((x) & 0xFFff0000) >> 16) | \
    304                             (((x) & 0x0000FFff) << 16) )
    305 
    306 static uint32 *
    307 sb_test_random_entry(int unit, soc_mem_t mem, uint32 *entbuf)
    308 {
    309     int i, n;
    310 
    311     for (n = 0; n < sb_test_data.num_mem; n++) {
    312         for (i = 0; i < sb_test_mem[n].entwords; ++i) {
    313             uint32 prev = sb_test_get_curr_rnum();
    314             entbuf[i] = sb_test_rand32(prev) & sb_test_mem[n].datamask[i];
    315         }
    316     }
    317 
    318     return entbuf;
    319 }
    320 
    321 static int
    322 sb_test_write_entry(int unit, int cmc, soc_mem_t mem, int copyno,
    323                     int index, uint32 *entbuf)
    324 {
    325     int rv = 0;
    326 
    327     if (SOC_MEM_IS_VALID(unit, mem)) {
    328         if (soc_feature(unit, soc_feature_cmicm)) {
    329             cmicm_schan_ch_put(unit, cmc);
    330         }
    331         rv = soc_mem_array_write(unit, mem, 0, copyno, index, entbuf);
    332         if (soc_feature(unit, soc_feature_cmicm)) {
    333             if (cmicm_schan_ch_try_get(unit, cmc) != SOC_E_NONE) {
    334                 test_error(unit, "Failed to reserved schan from cmc %0d\n",
    335                 cmc);
    336             }
    337         }
    338     }
    339     if (rv < 0) {
    340         test_error(unit,
    341                    "Write entry (copyno %d) failed: %s",
    342                    copyno, soc_errmsg(rv));
    343     }
    344     return rv;
    345 }
    346 
    347 static int
    348 sb_test_read_entry(int unit, int cmc, soc_mem_t mem, int copyno,
    349                    int index, uint32 *entbuf)
    350 {
    351     int rv = 0;
    352 
    353     if (SOC_MEM_IS_VALID(unit, mem)) {
    354         if (soc_feature(unit, soc_feature_cmicm)) {
    355             cmicm_schan_ch_put(unit, cmc);
    356         }
    357         rv = soc_mem_array_read(unit, mem, 0, copyno, index, entbuf);
    358         if (soc_feature(unit, soc_feature_cmicm)) {
    359             if (cmicm_schan_ch_try_get(unit, cmc) != SOC_E_NONE) {
    360                 test_error(unit, "Failed to reserved schan from cmc %0d\n",
    361                 cmc);
    362             }
    363         }
    364     }
    365     if (rv < 0) {
    366         test_error(unit,
    367                    "Read entry (copyno %d) failed: %s",
    368                    copyno, soc_errmsg(rv));
    369     }
    370     return rv;
    371 }
    372 
    373 static int
    374 sb_test_verify(int unit, int n)
    375 {
    376     int rv_comp    = SOC_E_NONE;
    377     soc_mem_t mem  = sb_test_mem[n].mem;
    378     int base_index = soc_mem_index_min(unit, mem);
    379     int index_min  = sb_test_mem[n].index_min;
    380     int index_max  = sb_test_mem[n].index_max;
    381     int ent_words  = soc_mem_entry_words(unit, mem);
    382     int i;
    383     int idx;
    384     uint32 *d;
    385     uint32 *s;
    386     uint32 ecc_mask;
    387 
    388     if (!sb_test_data.ecc_as_data) {
    389         for (i = 0; i <= index_max - index_min; i++) {
    390             for (idx = 0; idx < sb_test_mem[n].entwords; idx++) {
    391                 ecc_mask = (~sb_test_mem[n].eccmask[idx]);
    392                 sb_test_mem[n].dma_ed[i * ent_words + idx] &= ecc_mask;
    393                 sb_test_mem[n].source[i * ent_words + idx] &= ecc_mask;
    394             }
    395         }
    396     }
    397 
    398     if (soc_feature(unit, soc_feature_sbusdma)) {
    399         if ((sb_test_data.slam_dir == 0) && sb_test_data.slam_en &&
    400             soc_mem_slamable(unit, mem, sb_test_mem[n].copyno)) {
    401             /* swap the source buffer */
    402             uint32 temp[SOC_MAX_MEM_WORDS];
    403             s = sb_test_mem[n].source;
    404             d = s + ((index_max - index_min) * ent_words);
    405             for (i = 0; i < (index_max - index_min + 1) / 2; ++i) {
    406                 sal_memcpy(temp, s + i * ent_words, ent_words * 4);
    407                 sal_memcpy(s + i * ent_words, d - i * ent_words, ent_words * 4);
    408                 sal_memcpy(d - i * ent_words, temp, ent_words * 4);
    409             }
    410         }
    411         rv_comp = sal_memcmp(sb_test_mem[n].dma_ed, sb_test_mem[n].source,
    412                                  (index_max - index_min + 1) * ent_words * 4);
    413     } else {
    414         rv_comp = sal_memcmp(sb_test_mem[n].dma_ed, sb_test_mem[n].source,
    415                              (index_max - index_min + 1) * ent_words * 4);
    416     }
    417 
    418     if (rv_comp != SOC_E_NONE) {
    419 
    420         cli_out("Mismatch found\n");
    421         s = sb_test_mem[n].source;
    422         d = sb_test_mem[n].dma_ed;
    423         for (i = index_min; i <= index_max; ++i) {
    424             if (sb_test_mem_cmp_fn(unit, n, s, d) != 0) {
    425                 cli_out("%s.%s diff entry index %d: "
    426                         "source entry %d, dma_ed entry %d\n",
    427                         SOC_MEM_UFNAME(unit, mem),
    428                         SOC_BLOCK_NAME(unit, sb_test_mem[n].copyno),
    429                         i, i - base_index, i - index_min);
    430                 cli_out("Source:");
    431                 for (i = 0; i < ent_words; i++) {
    432                     cli_out(" 0x%08x = 0x%08x", (PTR_TO_INT(s+i)), s[i]);
    433                 }
    434                 cli_out("\nDMA_ed:");
    435                 for (i = 0; i < ent_words; i++) {
    436                     cli_out(" 0x%08x = 0x%08x", (PTR_TO_INT(d+i)), d[i]);
    437                 }
    438 
    439                 cli_out("\nMask");
    440                 for (i = 0; i < ent_words; i++) {
    441                     cli_out("  = 0x%08x",
    442                             (uint32)BSAND_BYTE_SWAP(sb_test_mem[n].datamask[i]));
    443                 }
    444                 cli_out("\n");
    445 
    446                 return BCM_E_FAIL;
    447             }
    448             d += ent_words;
    449             s += ent_words;
    450         }
    451         /* If get here, something is wrong, dump for inspection */
    452         sb_test_dump_data(unit, n, TD_DEFAULT_DUMP_ENTRY_COUNT);
    453     }
    454 
    455     return SOC_E_NONE;
    456 }
    457 
    458 
    459 static int
    460 sb_test_mem_cmp_fn(int unit, int n, void *s, void *d)
    461 {
    462     soc_mem_t mem  = sb_test_mem[n].mem;
    463     int ent_words  = soc_mem_entry_words(unit, mem);
    464 
    465     assert(s && d);
    466 
    467     return sal_memcmp(s, d, ent_words * 4);
    468 }
    469 
    470 
    471 static void
    472 sb_test_sbusdma_cb(int unit, int status, sbusdma_desc_handle_t handle,
    473                    void *data)
    474 {
    475     int i, cmc, ch;
    476 
    477     if (status != SOC_E_NONE) {
    478         LOG_ERROR(BSL_LS_APPL_TESTS,
    479                   (BSL_META_U(unit,
    480                               "SBUS DMA failed: type %d\n"),
    481                    PTR_TO_INT(data)));
    482         if (status == SOC_E_TIMEOUT)
    483             (void)soc_sbusdma_desc_delete(unit, handle);
    484     }
    485     for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC; i++) {
    486         if (sbusdma_desc_handle[i] == handle) {
    487             sbusdma_desc_handle[i] = 0;
    488             cmc = i / NUM_SBUSDMA_CH_PER_CMC;
    489             ch  = i % NUM_SBUSDMA_CH_PER_CMC;
    490             if (soc_sbusdma_ch_try_get(unit, cmc, ch) != SOC_E_NONE) {
    491                 test_error(unit, "Failed to reserved sbusdma from cmc %0d ch %0d\n",
    492                            cmc, ch);
    493             }
    494         }
    495     }
    496 }
    497 
    498 
    499 static int
    500 sb_test_sbusdma_setup(int unit, int cmc, int ch, uint32 *entbuf, int index_min,
    501                       int index_max, int frag, int write)
    502 {
    503     /* for soc_sbusdma_desc_create and soc_sbusdma_desc_run */
    504     soc_sbusdma_desc_ctrl_t ctrl;
    505     soc_sbusdma_desc_cfg_t cfg;
    506     soc_sbusdma_desc_cfg_t *cfg_array;
    507     int vchan = cmc * NUM_SBUSDMA_CH_PER_CMC + ch;
    508     int n = sb_test_data.ch_mem_map[vchan];
    509     int rv = SOC_E_NONE;
    510     int         i;
    511     uint8       at;
    512 
    513     if (n == -1) {
    514         test_error(unit, "sb_test_sbusdma_setup detected invalid ch_mem_map[%0d]\n",
    515                    vchan);
    516         return BCM_E_FAIL;
    517     }
    518 
    519     soc_sbusdma_ch_put(unit, cmc, ch);
    520     if (sb_test_data.desc_mode > 0) {
    521         /* descriptor based sbus dma mode through sdk api */
    522         sal_memset(&ctrl, 0, sizeof(soc_sbusdma_desc_ctrl_t));
    523         sal_memset(&cfg, 0, sizeof(soc_sbusdma_desc_cfg_t));
    524         cfg_array = soc_cm_salloc(unit, sizeof(soc_sbusdma_desc_cfg_t) *
    525                                   sb_test_data.desc_mode, "sbusdma_desc_cfg");
    526         if (write == 0) {
    527             ctrl.flags = SOC_SBUSDMA_MEMORY_CMD_MSG;
    528         } else {
    529             ctrl.flags = SOC_SBUSDMA_WRITE_CMD_MSG | SOC_SBUSDMA_MEMORY_CMD_MSG;
    530         }
    531         ctrl.cfg_count = sb_test_data.desc_mode;
    532         ctrl.cb = sb_test_sbusdma_cb;
    533         ctrl.data = entbuf;
    534         sal_strncpy(ctrl.name, sb_test_mem[n].mem_str, sizeof(ctrl.name)-1);
    535         cfg.acc_type = SOC_MEM_ACC_TYPE(unit, sb_test_mem[n].mem);
    536         cfg.blk = SOC_BLOCK2SCH(unit, sb_test_mem[n].copyno);
    537         cfg.addr = soc_mem_addr_get(unit, sb_test_mem[n].mem, 0,
    538                                     sb_test_mem[n].copyno, index_min, &at);
    539         cfg.width = sb_test_mem[n].entwords;
    540         cfg.count = index_max - index_min + 1;
    541         cfg.buff = entbuf;
    542         cfg.addr_shift = 0;
    543         for (i = 0; i < sb_test_data.desc_mode; i++) {
    544             sal_memcpy(cfg_array + i, &cfg, sizeof(soc_sbusdma_desc_cfg_t));
    545         }
    546 
    547         if (SOC_FAILURE((rv = (soc_sbusdma_desc_create(unit, &ctrl, cfg_array,
    548                                                        &sbusdma_desc_handle[vchan]))))) {
    549             _SHR_ERROR_TRACE(rv);
    550         }
    551         soc_cm_sfree(unit, cfg_array);
    552     } else {
    553         /* register based sbus dma mode through sdk api */
    554         if (write == 0) {
    555             rv = soc_mem_read_range_multi_cmc(unit, sb_test_mem[n].mem,
    556                                               sb_test_mem[n].copyno,
    557                                               index_min, index_max, entbuf,
    558                                               vchan);
    559         } else {
    560             rv = soc_mem_write_range_multi_cmc(unit, sb_test_mem[n].mem,
    561                                                sb_test_mem[n].copyno,
    562                                                index_min, index_max, entbuf,
    563                                                vchan);
    564         }
    565         if (rv < 0) {
    566             test_error(unit, "SBUS SLAM DMA Error:  Memory %s.%d\n",
    567                        sb_test_mem[n].mem_str, sb_test_mem[n].copyno);
    568             rv = BCM_E_FAIL;
    569         }
    570         if (soc_sbusdma_ch_try_get(unit, cmc, ch) != SOC_E_NONE) {
    571             test_error(unit, "Failed to reserved sbusdma from cmc %0d ch %0d\n",
    572                        cmc, ch);
    573         }
    574     }
    575     return rv;
    576 }
    577 
    578 
    579 static void
    580 sbusdma_write(void* up)
    581 {
    582     int         unit = PTR_TO_INT(up) & 0xff;
    583     int         i, j, loop_cnt;
    584     uint32      *entbuf;
    585     int         frag;
    586     int         index_min, index_max;
    587     sal_usecs_t stime, etime, td;
    588     int         entry_per_sec, mb_per_sec;
    589     char        *access_type;
    590 
    591     uint32      avail_bm;
    592     int         cmc, ch, n;
    593     sal_usecs_t dma_timeout = 1000000;
    594     int         ret;
    595 
    596     if (sb_test_data.dma_wr_en) {
    597         access_type = sal_strdup("SBUS DMA");
    598     } else {
    599         access_type = sal_strdup("SBUS    ");
    600     }
    601     loop_cnt = 0;
    602     cmc = 0;
    603     ch = 0;
    604 
    605     n = PTR_TO_INT(up) >> 8;
    606     avail_bm = sb_test_mem[n].mem_cmc_ch_bm;
    607     for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC; i++) {
    608         if (avail_bm & (0x1 << i)) {
    609             LOG_INFO(BSL_LS_APPL_TESTS,
    610                      (BSL_META_U(unit,
    611                                  "writing mem[%0d] with vchan %0d\n"), n, i));
    612             if (sb_test_data.ch_mem_map[i] != n) {;
    613                 test_error(unit, "sbusdma_write called with more than one memory\n");
    614             }
    615         }
    616     }
    617 
    618     /* If not a RO memory, write random data into table and hardware */
    619     if (!soc_mem_is_readonly(unit, sb_test_mem[n].mem)) {
    620         entbuf = sb_test_mem[n].source;
    621         if (0 != sb_test_data.rnum) {
    622             sal_memset(entbuf, 0xff, WORDS2BYTES(sb_test_mem[n].bufwords));
    623         }
    624 
    625         if (sb_test_data.slam_en &&
    626             soc_mem_slamable(unit, sb_test_mem[n].mem, sb_test_mem[n].copyno)) {
    627             for (i = 0; i < sb_test_mem[n].count; i++) {
    628                 sb_test_random_entry(unit, sb_test_mem[n].mem, entbuf);
    629                 if (sb_test_mem[n].accum_tcammask) {
    630                     /* data read back has dependency on mask */
    631                     if ((SOC_BLOCK_TYPE(unit, sb_test_mem[n].copyno) ==
    632                             SOC_BLK_ESM) ||
    633                             (SOC_BLOCK_TYPE(unit, sb_test_mem[n].copyno) ==
    634                              SOC_BLK_ETU)) {
    635                         for (j = 0; j < sb_test_mem[n].entwords; j++) {
    636                             entbuf[j] &= ~sb_test_mem[n].tcammask[j];
    637                         }
    638                     } else if (soc_feature(unit, soc_feature_xy_tcam)) {
    639                         for (j = 0; j < sb_test_mem[n].entwords; j++) {
    640                             entbuf[j] |= sb_test_mem[n].tcammask[j];
    641                         }
    642                     }
    643                 }
    644                 if (sb_test_mem[n].accum_forcemask) {
    645                     for (j = 0; j < sb_test_mem[n].entwords; j++) {
    646                         entbuf[j] &= ~sb_test_mem[n].forcemask[j];
    647                         entbuf[j] |= sb_test_mem[n].forcedata[j];
    648                     }
    649                 }
    650                 entbuf += sb_test_mem[n].entwords;
    651             }
    652             soc_cm_sflush(unit, (void *)sb_test_mem[n].source,
    653                           WORDS2BYTES(sb_test_mem[n].bufwords));
    654             stime = sal_time_usecs();
    655             for (frag = 0; frag < sb_test_mem[n].frag_count; frag++) {
    656                 index_min = sb_test_mem[n].frag_index_min[frag];
    657                 index_max = sb_test_mem[n].frag_index_max[frag];
    658                 entbuf = sb_test_mem[n].source +
    659                          (sb_test_mem[n].frag_index_min[frag] -
    660                           sb_test_mem[n].index_min) * sb_test_mem[n].entwords;
    661                 if (soc_mem_write_range(unit, sb_test_mem[n].mem,
    662                                         sb_test_mem[n].copyno,
    663                                         (sb_test_data.slam_dir ?
    664                                          index_min : index_max),
    665                                         (sb_test_data.slam_dir ?
    666                                          index_max : index_min),
    667                                         entbuf) < 0) {
    668                     test_error(unit,
    669                                "SBUS SLAM DMA Error:  Memory %s.%d\n",
    670                                sb_test_mem[n].mem_str, sb_test_mem[n].copyno);
    671                 }
    672             }
    673         } else {
    674             /* fill the source buffer with random values */
    675             entbuf = sb_test_mem[n].source;
    676             for (i = sb_test_mem[n].index_min; i <= sb_test_mem[n].index_max; i++) {
    677                 sb_test_random_entry(unit, sb_test_mem[n].mem, entbuf);
    678                 if (sb_test_mem[n].accum_tcammask) {
    679                     /* data read back has dependency on mask */
    680                     if ((SOC_BLOCK_TYPE(unit, sb_test_mem[n].copyno) == SOC_BLK_ESM) ||
    681                         (SOC_BLOCK_TYPE(unit, sb_test_mem[n].copyno) == SOC_BLK_ETU)) {
    682                         for (j = 0; j < sb_test_mem[n].entwords; j++) {
    683                             entbuf[j] &= ~sb_test_mem[n].tcammask[j];
    684                         }
    685                     } else if (soc_feature(unit, soc_feature_xy_tcam)) {
    686                         for (j = 0; j < sb_test_mem[n].entwords; j++) {
    687                             entbuf[j] |= sb_test_mem[n].tcammask[j];
    688                         }
    689                     }
    690                 }
    691                 if (sb_test_mem[n].accum_forcemask) {
    692                     for (j = 0; j < sb_test_mem[n].entwords; j++) {
    693                         entbuf[j] &= ~sb_test_mem[n].forcemask[j];
    694                         entbuf[j] |= sb_test_mem[n].forcedata[j];
    695                     }
    696                 }
    697                 entbuf += sb_test_mem[n].entwords;
    698             }
    699             while (sb_test_data.run[n] == FALSE) {
    700                 sal_usleep(10);
    701             }
    702             stime = sal_time_usecs();
    703             while (sb_test_data.run[n]) {
    704                 for (frag = 0; frag < sb_test_mem[n].frag_count; frag++) {
    705                     index_min = sb_test_mem[n].frag_index_min[frag];
    706                     index_max = sb_test_mem[n].frag_index_max[frag];
    707                     entbuf = sb_test_mem[n].source +
    708                              (sb_test_mem[n].frag_index_min[frag] -
    709                               sb_test_mem[n].index_min) * sb_test_mem[n].entwords;
    710                     if (sb_test_data.verbose || sb_test_data.debug) {
    711                         cli_out("%s writing from address 0x%08x to %s[%0d..%0d]\n",
    712                                 access_type, PTR_TO_INT(entbuf),
    713                                 sb_test_mem[n].mem_str, index_max, index_min);
    714                     }
    715                     if (sb_test_data.debug) {
    716                         for (i = index_min; i <= index_max; i++) {
    717                             cli_out("DEBUG: Writing %s[%0d]:",
    718                                     sb_test_mem[n].mem_str, i);
    719                             for (j = 0; j < sb_test_mem[n].entwords; j++) {
    720                                 cli_out(" 0x%08x", *(entbuf+j));
    721                             }
    722                             cli_out("\n");
    723                         }
    724                     }
    725                     if (sb_test_data.dma_wr_en) {
    726                         /* sbus dma write */
    727                         for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC; i++) {
    728                             if (avail_bm & (0x1 << i)) {
    729                                 cmc = i / NUM_SBUSDMA_CH_PER_CMC;
    730                                 ch  = i % NUM_SBUSDMA_CH_PER_CMC;
    731                                 sb_test_sbusdma_setup(unit, cmc, ch, entbuf,
    732                                                       index_min, index_max,
    733                                                       frag, 1);
    734                                 avail_bm &= ~(1 << i);
    735                                 break;
    736                             }
    737                         }
    738                     } else {
    739                         /* schan write */
    740                         for (cmc = 0; cmc < SOC_CMCS_NUM_MAX + 1; cmc++) {
    741                             i = cmc * NUM_SBUSDMA_CH_PER_CMC;
    742                             if ((avail_bm & (0x1 << i)) &&
    743                                 (SCHAN_CH_MASK & (0x1 << cmc))) {
    744                                 avail_bm &= ~(1 << i);
    745                                 break;
    746                             }
    747                         }
    748                         for (i = index_min; i <= index_max; i++) {
    749                             if (sb_test_write_entry(unit, cmc,
    750                                                     sb_test_mem[n].mem,
    751                                                     sb_test_mem[n].copyno, i,
    752                                                     entbuf) < 0) {
    753                                 test_error(unit, "SCHAN Write Error: Memory %s.%d\n",
    754                                            sb_test_mem[n].mem_str,
    755                                            sb_test_mem[n].copyno);
    756                             }
    757                             entbuf += sb_test_mem[n].entwords;
    758                         }
    759                         avail_bm |= 1 << (cmc * NUM_SBUSDMA_CH_PER_CMC);
    760                     }
    761                     if ((avail_bm == 0) || (frag == sb_test_mem[n].frag_count-1)) {
    762                         /* kick start descriptor mode sbusdma */
    763                         if (sb_test_data.dma_wr_en && sb_test_data.desc_mode > 0) {
    764                             soc_timeout_t to;
    765                             soc_timeout_init(&to, 2 * dma_timeout, 0);
    766                             do {
    767                                 ret = soc_sbusdma_desc_run(unit,
    768                                           sbusdma_desc_handle[cmc * NUM_SBUSDMA_CH_PER_CMC + ch]);
    769                                 if ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) {
    770                                     if (ret == SOC_E_INIT) {
    771                                         break;
    772                                     }
    773                                     if (soc_timeout_check(&to)) {
    774                                         LOG_WARN(BSL_LS_APPL_TESTS,
    775                                                  (BSL_META_U(unit,
    776                                                              " sbusdma desc run operation timeout\n")));
    777                                         break;
    778                                     }
    779                                     sal_usleep(10);
    780                                 }
    781                             } while ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT));
    782                             sb_test_data.run[n] = FALSE;
    783                             /* poll until descriptor mode sbusdma finishes */
    784                             do {
    785                                  sal_usleep(10);
    786                             } while (sbusdma_desc_handle[cmc * NUM_SBUSDMA_CH_PER_CMC + ch] != 0);
    787                         }
    788                         if (sb_test_data.dma_wr_en) {
    789                             avail_bm = sb_test_mem[n].mem_cmc_ch_bm;
    790                         }
    791                     }
    792                 }
    793                 loop_cnt++;
    794             }
    795         }
    796         etime = sal_time_usecs();
    797         td = SAL_USECS_SUB(etime, stime);
    798         if (sb_test_data.dma_wr_en && sb_test_data.desc_mode > 0) {
    799             loop_cnt = sb_test_data.desc_mode;
    800         }
    801         entry_per_sec = _shr_div_exp10(sb_test_mem[n].count, td, 6) * loop_cnt;
    802         mb_per_sec = _shr_div_exp10(WORDS2BYTES(sb_test_mem[n].bufwords) /
    803                                     0x400, td, 10) / 1024 * loop_cnt;
    804         LOG_INFO(BSL_LS_APPL_TESTS,
    805                      (BSL_META_U(unit,
    806                                  "%s write loop_cnt %0d, entry %0d, time %0d\n"),
    807                                  sb_test_mem[n].mem_str, loop_cnt,
    808                                  sb_test_mem[n].count, td));
    809         if (sb_test_data.verbose)
    810             cli_out("%s wrote %s.%s: %3d dw by %5d entry %9d entry/s %4d.%04d MB/s\n",
    811                     access_type, sb_test_mem[n].mem_str,
    812                     SOC_BLOCK_NAME(unit, sb_test_mem[n].copyno),
    813                     sb_test_mem[n].entwords, sb_test_mem[n].count,
    814                     entry_per_sec, INT_FRAC_4PT(mb_per_sec));
    815         else
    816             cli_out("%s wrote %s: %9d entry/s %4d.%04d MB/s\n",
    817                     access_type, sb_test_mem[n].mem_str, entry_per_sec,
    818                     INT_FRAC_4PT(mb_per_sec));
    819     } else {
    820         cli_out("Note:  memory %s is read only, so verifying a few\n",
    821                 sb_test_mem[n].mem_str);
    822         cli_out("entries directly.\n");
    823     }
    824 
    825     if (sb_test_data.verbose || sb_test_data.debug) {
    826         cli_out("Done writing mem[%0d]\n", n);
    827     }
    828     sb_test_data.mem_done[n] = TRUE;
    829     sal_free(access_type);
    830     sal_thread_exit(0);
    831 }
    832 
    833 
    834 static void
    835 sbusdma_read(void* up)
    836 {
    837     int         unit = PTR_TO_INT(up) & 0xff;
    838     int         i, j, loop_cnt;
    839     uint32      *entbuf;
    840     int         frag;
    841     int         index_min, index_max;
    842     sal_usecs_t stime, etime, td;
    843     int         entry_per_sec, mb_per_sec;
    844     char        *access_type;
    845 
    846     uint32      avail_bm;
    847     int         cmc, ch, n;
    848     sal_usecs_t dma_timeout = 1000000;
    849     int         ret;
    850 
    851     if (sb_test_data.dma_rd_en) {
    852         access_type = sal_strdup("SBUS DMA");
    853     } else {
    854         access_type = sal_strdup("SBUS    ");
    855     }
    856     loop_cnt = 0;
    857     cmc = 0;
    858     ch = 0;
    859 
    860     n = PTR_TO_INT(up) >> 8;
    861     avail_bm = sb_test_mem[n].mem_cmc_ch_bm;
    862     for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC; i++) {
    863         if (avail_bm & (0x1 << i)) {
    864             LOG_INFO(BSL_LS_APPL_TESTS,
    865                      (BSL_META_U(unit,
    866                                  "reading mem[%0d] with vchan %0d\n"), n, i));
    867             if (sb_test_data.ch_mem_map[i] != n) {;
    868                 test_error(unit, "sbusdma_read called with more than one memory\n");
    869             }
    870         }
    871     }
    872 
    873     while (sb_test_data.run[n] == FALSE) {
    874         sal_usleep(10);
    875     }
    876     stime = sal_time_usecs();
    877     while (sb_test_data.run[n]) {
    878         for (frag = 0; frag < sb_test_mem[n].frag_count; frag++) {
    879             index_min = sb_test_mem[n].frag_index_min[frag];
    880             index_max = sb_test_mem[n].frag_index_max[frag];
    881             entbuf = sb_test_mem[n].dma_ed +
    882                      (sb_test_mem[n].frag_index_min[frag] -
    883                       sb_test_mem[n].index_min) * sb_test_mem[n].entwords;
    884             if (sb_test_data.verbose || sb_test_data.debug) {
    885                 cli_out("%s reading from %s[%0d..%0d] to address 0x%08x\n",
    886                         access_type, sb_test_mem[n].mem_str, index_max,
    887                         index_min, PTR_TO_INT(entbuf));
    888             }
    889             if (sb_test_data.dma_rd_en) {
    890                 for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC; i++) {
    891                     if (avail_bm & (0x1 << i)) {
    892                         cmc = i / NUM_SBUSDMA_CH_PER_CMC;
    893                         ch  = i % NUM_SBUSDMA_CH_PER_CMC;
    894                         sb_test_sbusdma_setup(unit, cmc, ch, entbuf, index_min,
    895                                               index_max, frag, 0);
    896                         avail_bm &= ~(1 << i);
    897                         break;
    898                     }
    899                 }
    900             } else {
    901                 for (cmc = 0; cmc < SOC_CMCS_NUM_MAX + 1; cmc++) {
    902                     i = cmc * NUM_SBUSDMA_CH_PER_CMC;
    903                     if ((avail_bm & (0x1 << i)) &&
    904                         (SCHAN_CH_MASK & (0x1 << cmc))) {
    905                         avail_bm &= ~(1 << i);
    906                         break;
    907                     }
    908                 }
    909                 for (i = index_min; i <= index_max; i++) {
    910                     if (sb_test_read_entry(unit, cmc, sb_test_mem[n].mem,
    911                                            sb_test_mem[n].copyno, i, entbuf) < 0) {
    912                         test_error(unit, "SCHAN Read Error: Memory %s.%d\n",
    913                                    sb_test_mem[n].mem_str, sb_test_mem[n].copyno);
    914                     }
    915                     entbuf += sb_test_mem[n].entwords;
    916                 }
    917                 avail_bm |= 1 << (cmc * NUM_SBUSDMA_CH_PER_CMC);
    918             }
    919             if (sb_test_data.debug) {
    920                 entbuf = sb_test_mem[n].dma_ed +
    921                          sb_test_mem[n].frag_index_min[frag] *
    922                          sb_test_mem[n].entwords;
    923                 for (i = index_min; i <= index_max; i++) {
    924                     cli_out("DEBUG: %s[%0d]:", sb_test_mem[n].mem_str, i);
    925                     for (j = 0; j < sb_test_mem[n].entwords; j++) {
    926                         cli_out(" 0x%08x", *(entbuf+i*sb_test_mem[n].entwords+j));
    927                     }
    928                     cli_out("\n");
    929                 }
    930             }
    931             if ((avail_bm == 0) || (frag == sb_test_mem[n].frag_count-1)) {
    932                 if (sb_test_data.dma_rd_en && sb_test_data.desc_mode > 0) {
    933                     soc_timeout_t to;
    934                     soc_timeout_init(&to, 2 * dma_timeout, 0);
    935                     do {
    936                         ret = soc_sbusdma_desc_run(unit,
    937                                   sbusdma_desc_handle[cmc * NUM_SBUSDMA_CH_PER_CMC + ch]);
    938                         if ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) {
    939                             if (ret == SOC_E_INIT) {
    940                                 break;
    941                             }
    942                             if (soc_timeout_check(&to)) {
    943                                 LOG_WARN(BSL_LS_APPL_TESTS,
    944                                          (BSL_META_U(unit,
    945                                                      " sbusdma desc run operation timeout\n")));
    946                                 break;
    947                             }
    948                             sal_usleep(10);
    949                         }
    950                     } while ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT));
    951                     sb_test_data.run[n] = FALSE;
    952                     /* poll until descriptor mode sbusdma finishes */
    953                     do {
    954                          sal_usleep(10);
    955                     } while (sbusdma_desc_handle[cmc * NUM_SBUSDMA_CH_PER_CMC + ch] != 0);
    956                 }
    957                 if (sb_test_data.dma_rd_en) {
    958                     avail_bm = sb_test_mem[n].mem_cmc_ch_bm;
    959                 }
    960             }
    961         }
    962         loop_cnt++;
    963     }
    964     etime = sal_time_usecs();
    965     td = SAL_USECS_SUB(etime, stime);
    966     if (sb_test_data.dma_rd_en && sb_test_data.desc_mode > 0) {
    967         loop_cnt = sb_test_data.desc_mode;
    968     }
    969     entry_per_sec = _shr_div_exp10(sb_test_mem[n].count, td, 6) * loop_cnt;
    970     mb_per_sec = _shr_div_exp10(WORDS2BYTES(sb_test_mem[n].bufwords) / 0x400,
    971                                 td, 10) / 1024 * loop_cnt;
    972     LOG_INFO(BSL_LS_APPL_TESTS,
    973                  (BSL_META_U(unit,
    974                              "%s read loop_cnt %0d, entry %0d, time %0d\n"),
    975                              sb_test_mem[n].mem_str, loop_cnt,
    976                              sb_test_mem[n].count, td));
    977     if (sb_test_data.verbose)
    978         cli_out("%s read  %s.%s: %3d dw by %5d entry %9d entry/s %4d.%04d MB/s\n",
    979                 access_type, sb_test_mem[n].mem_str,
    980                 SOC_BLOCK_NAME(unit, sb_test_mem[n].copyno),
    981                 sb_test_mem[n].entwords, sb_test_mem[n].count,
    982                 entry_per_sec, INT_FRAC_4PT(mb_per_sec));
    983     else
    984         cli_out("%s read  %s: %9d entry/s %4d.%04d MB/s\n",
    985                 access_type, sb_test_mem[n].mem_str, entry_per_sec,
    986                 INT_FRAC_4PT(mb_per_sec));
    987 
    988     if (sb_test_data.verbose || sb_test_data.debug) {
    989         cli_out("Done reading mem[%0d]\n", n);
    990     }
    991     sb_test_data.mem_done[n] = TRUE;
    992     sal_free(access_type);
    993     sal_thread_exit(0);
    994 }
    995 
    996 
    997 static void
    998 reserve_all_schan_channels(int unit)
    999 {
   1000     int cmc;
   1001     int rv = SOC_E_NONE;
   1002 
   1003     for (cmc = 0; cmc < SOC_CMCS_NUM_MAX + 1; cmc++) {
   1004         if (SCHAN_CH_MASK & (0x01 << cmc)) {
   1005             rv = cmicm_schan_ch_try_get(unit, cmc);
   1006             if (rv != SOC_E_NONE) {
   1007                 test_error(unit, "Failed to reserved schan from cmc %0d\n", cmc);
   1008             }
   1009         }
   1010     }
   1011     if (rv == SOC_E_NONE) {
   1012         cli_out("Reserved all SCHANs successfully\n");
   1013     }
   1014 }
   1015 
   1016 
   1017 static void
   1018 release_all_schan_channels(int unit)
   1019 {
   1020     int cmc;
   1021 
   1022     for (cmc = 0; cmc < SOC_CMCS_NUM_MAX + 1; cmc++) {
   1023         if (SCHAN_CH_MASK & (0x01 << cmc)) {
   1024             cmicm_schan_ch_put(unit, cmc);
   1025         }
   1026     }
   1027 }
   1028 
   1029 
   1030 static void
   1031 reserve_all_sbusdma_channels(int unit)
   1032 {
   1033     int cmc, ch;
   1034     int rv = SOC_E_NONE;
   1035 
   1036     for (cmc = 0; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   1037         for (ch = 0; ch < NUM_SBUSDMA_CH_PER_CMC; ch++) {
   1038             rv = soc_sbusdma_ch_try_get(unit, cmc, ch);
   1039             if (rv != SOC_E_NONE) {
   1040                 test_error(unit, "Failed to reserved sbusdma from cmc %0d ch %0d\n",
   1041                            cmc, ch);
   1042             }
   1043         }
   1044     }
   1045     if (rv == SOC_E_NONE) {
   1046         cli_out("Reserved all SBUSDMA channels successfully\n");
   1047     }
   1048 }
   1049 
   1050 
   1051 static void
   1052 release_all_sbusdma_channels(int unit)
   1053 {
   1054     int cmc, ch;
   1055 
   1056     for (cmc = 0; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   1057         for (ch = 0; ch < NUM_SBUSDMA_CH_PER_CMC; ch++) {
   1058             soc_sbusdma_ch_put(unit, cmc, ch);
   1059         }
   1060     }
   1061 }
   1062 
   1063 
   1064 void
   1065 sb_test_write(int unit)
   1066 {
   1067     soc_control_t *soc = SOC_CONTROL(unit);
   1068     int n, done = FALSE;
   1069     char str[80];
   1070     /* sal_thread_t pid_sbusdma[SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC]; */
   1071     int ch_max;
   1072     sal_thread_t *pid_sbusdma;
   1073 
   1074     ch_max = SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC;
   1075     pid_sbusdma = sal_alloc(sizeof(sal_thread_t) * ch_max, "pid_sbusdma");
   1076     sal_memset(pid_sbusdma, 0, sizeof(sal_thread_t) * ch_max);
   1077 
   1078     /* sbus dma write */
   1079     if (!soc_feature(unit, soc_feature_cmicm_multi_dma_cmc) &&
   1080         sb_test_data.desc_mode == 0) {
   1081         sb_test_data.cmc_ch_bm = 0x1 << soc->tslam_ch;
   1082     }
   1083     for (n = 0; n < sb_test_data.num_mem && n < ch_max; n++) {
   1084         sal_sprintf(str, "SBUSDMA_MEM_%0d", n);
   1085         sb_test_data.mem_done[n] = FALSE;
   1086         pid_sbusdma[n] = sal_thread_create(str, 32 * 1024 * 1024, 200,
   1087                                            sbusdma_write,
   1088                                            INT_TO_PTR(n << 8 | unit));
   1089         if (sb_test_data.verbose || sb_test_data.debug) {
   1090             cli_out("\npid_sbusdma[%0d] = %p", n, pid_sbusdma[n]);
   1091         }
   1092         sal_usleep(10);
   1093     }
   1094     for (n = 0; n < sb_test_data.num_mem; n++) {
   1095         sb_test_data.run[n] = TRUE;
   1096     }
   1097     if (sb_test_data.desc_mode == 0) {
   1098         sal_sleep(sb_test_data.rate_calc_int);
   1099         for (n = 0; n < sb_test_data.num_mem; n++) {
   1100             sb_test_data.run[n] = FALSE;
   1101         }
   1102     }
   1103     do {
   1104         sal_usleep(100000);
   1105         for (n = 0; n < sb_test_data.num_mem; n++) {
   1106             if (n == 0) {
   1107                 done = sb_test_data.mem_done[n];
   1108             } else {
   1109                 done &= sb_test_data.mem_done[n];
   1110             }
   1111         }
   1112     } while (done == FALSE);
   1113     if (sb_test_data.verbose || sb_test_data.debug) {
   1114         cli_out("Finished waiting for sbusdma_write done\n");
   1115     }
   1116 }
   1117 
   1118 
   1119 int
   1120 sb_test_read(int unit)
   1121 {
   1122     soc_control_t *soc = SOC_CONTROL(unit);
   1123     int n, done = FALSE;
   1124     int rv = SOC_E_NONE;
   1125     char str[80];
   1126     /* sal_thread_t pid_sbusdma[SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC]; */
   1127     int ch_max;
   1128     sal_thread_t *pid_sbusdma;
   1129 
   1130     ch_max = SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC;
   1131     pid_sbusdma = sal_alloc(sizeof(sal_thread_t) * ch_max, "pid_sbusdma");
   1132     sal_memset(pid_sbusdma, 0, sizeof(sal_thread_t) * ch_max);
   1133 
   1134     /* sbus dma read */
   1135     if (!soc_feature(unit, soc_feature_cmicm_multi_dma_cmc) &&
   1136         sb_test_data.desc_mode == 0) {
   1137         sb_test_data.cmc_ch_bm = 0x1 << soc->tdma_ch;
   1138     }
   1139     for (n = 0; n < sb_test_data.num_mem && n < ch_max; n++) {
   1140         sal_sprintf(str, "SBUSDMA_MEM_%0d", n);
   1141         sb_test_data.mem_done[n] = FALSE;
   1142         pid_sbusdma[n] = sal_thread_create(str, 32 * 1024 * 1024, 200,
   1143                                            sbusdma_read,
   1144                                            INT_TO_PTR(n << 8 | unit));
   1145         if (sb_test_data.verbose || sb_test_data.debug) {
   1146             cli_out("\npid_sbusdma[%0d] = %p", n, pid_sbusdma[n]);
   1147         }
   1148         sal_usleep(10);
   1149     }
   1150     for (n = 0; n < sb_test_data.num_mem; n++) {
   1151         sb_test_data.run[n] = TRUE;
   1152     }
   1153     if (sb_test_data.desc_mode == 0) {
   1154         sal_sleep(sb_test_data.rate_calc_int);
   1155         for (n = 0; n < sb_test_data.num_mem; n++) {
   1156             sb_test_data.run[n] = FALSE;
   1157         }
   1158     }
   1159     do {
   1160         sal_usleep(100000);
   1161         for (n = 0; n < sb_test_data.num_mem; n++) {
   1162             if (n == 0) {
   1163                 done = sb_test_data.mem_done[n];
   1164             } else {
   1165                 done &= sb_test_data.mem_done[n];
   1166             }
   1167         }
   1168     } while (done == FALSE);
   1169     if (sb_test_data.verbose || sb_test_data.debug) {
   1170         cli_out("Finished waiting for sbusdma_read done\n");
   1171     }
   1172 
   1173     if (sb_test_data.dma_wr_en || sb_test_data.dma_rd_en) {
   1174         release_all_sbusdma_channels(unit);
   1175     }
   1176     if (!sb_test_data.dma_wr_en || !sb_test_data.dma_rd_en) {
   1177         if (soc_feature(unit, soc_feature_cmicm)) {
   1178             release_all_schan_channels(unit);
   1179         }
   1180     }
   1181 
   1182     /* verify data integity */
   1183     if (sb_test_data.check_data == TRUE) {
   1184         for (n = 0; n < sb_test_data.num_mem; n++) {
   1185             if ((rv = sb_test_verify(unit, n)) < 0) {
   1186                 test_error(unit, "SBUS DMA failed: inconsistency observed\n");
   1187                 if (!sb_test_data.debug) {
   1188                     sb_test_dump_data(unit, n, TD_DEFAULT_DUMP_ENTRY_COUNT);
   1189                 }
   1190             }
   1191         }
   1192     }
   1193 
   1194     return rv;
   1195 }
   1196 
   1197 
   1198 int
   1199 sb_test_main(int unit, args_t *a, void *pa)
   1200 {
   1201     int rv = SOC_E_NONE;
   1202 
   1203     if (sb_test_data.dma_wr_en || sb_test_data.dma_rd_en) {
   1204         reserve_all_sbusdma_channels(unit);
   1205     }
   1206     if (!sb_test_data.dma_wr_en || !sb_test_data.dma_rd_en) {
   1207         if (soc_feature(unit, soc_feature_cmicm)) {
   1208             reserve_all_schan_channels(unit);
   1209         }
   1210     }
   1211 
   1212     if (sb_test_data.test_mode & 0x1) {
   1213         sb_test_write(unit);
   1214     }
   1215     if (sb_test_data.test_mode & 0x2) {
   1216         rv = sb_test_read(unit);
   1217     }
   1218 
   1219     return rv;
   1220 }
   1221 
   1222 
   1223 char sb_test_usage[] =
   1224     "SBUS DMA test usage:\n"
   1225     " \n"
   1226     "NumMem=<int>        -  number of table to be tested; default is 1\n"
   1227     "Mem=<name>          -  name of the first table to be tested; default is L2X\n"
   1228     "Mem<int>=<name>     -  name of tables to be tested\n"
   1229 #ifdef COMPILER_STRING_CONST_LIMIT
   1230     "\nFull documentation cannot be displayed with -pedantic compiler\n";
   1231 #else
   1232     "Start=<int>         -  first entry to be tested; default is 0\n"
   1233     "Count=<int>         -  number of entries to be tested; default is the table size\n"
   1234     "Frag=<1..32768>     -  split the table SBUS DMA in fragment; default is 1\n"
   1235     "                       CmcChanBitmap has priority over frag\n"
   1236     "RateCalcInt=<int>   -  Interval in seconds over which rate is to be calculated.\n"
   1237     "Seed=<int>          -  random seed for the random write values\n"
   1238     "EccAsData=<1/0>     -  do not mask off the ECC field for testing; default is 0\n"
   1239     "Desc=<int>          -  descriptor mode chain length; default is register mode\n"
   1240     "CmcChanBitmap=<hex> -  specify which of the 9 available CMC/channels to use\n"
   1241     "                       default is 2 for descriptor based write/read, 1 for\n"
   1242     "                       register based write, and 0 for register based read\n"
   1243     "                       CmcChanBitmap has priority over frag\n"
   1244     "DmaWrEn=<1/0>       -  enable SBUS DMA write. Otherwise SCHAN; default is 1\n"
   1245     "DmaRdEn=<1/0>       -  enable SBUS DMA write. Otherwise SCHAN; default is 1\n"
   1246     "TestMode=<1/2/3>    -  1: write only; 2: read only; default is 3 write and read\n"
   1247     "Verbose=<1/0>       -  print more debug information; default is 0\n"
   1248     ;
   1249 #endif
   1250 
   1251 
   1252 int
   1253 sb_test_init(int unit, args_t *a, void **pa)
   1254 {
   1255     soc_control_t *soc = SOC_CONTROL(unit);
   1256     parse_table_t pt;
   1257     int i, n, cmc;
   1258     int index_min, index_max;
   1259     int count_arg;
   1260     int frag, delta;
   1261     int big_packet;
   1262     uint32 addr_remap;
   1263 
   1264     if (sb_test_data_init(unit, 0) < 0) {
   1265         return BCM_E_FAIL;
   1266     }
   1267 
   1268     SOC_IF_ERROR_RETURN(soc_counter_stop(unit));
   1269     if (soc_feature(unit, soc_feature_arl_hashed)) {
   1270         SOC_IF_ERROR_RETURN(soc_l2x_stop(unit));
   1271     }
   1272 
   1273     parse_table_init(unit, &pt);
   1274     sb_test_data.cmc_ch_bm = 0;
   1275     sb_test_mem[0].frag_count = 0;
   1276 
   1277     parse_table_add(&pt, "NumMem", PQ_INT|PQ_DFL, 0,
   1278                     &sb_test_data.num_mem, NULL);
   1279     parse_table_add(&pt, "Mem", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1280                     &sb_test_mem[0].mem_str, NULL);
   1281     parse_table_add(&pt, "Mem0", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1282                     &sb_test_mem[0].mem_str, NULL);
   1283     parse_table_add(&pt, "Mem1", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1284                     &sb_test_mem[1].mem_str, NULL);
   1285     parse_table_add(&pt, "Mem2", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1286                     &sb_test_mem[2].mem_str, NULL);
   1287     parse_table_add(&pt, "Mem3", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1288                     &sb_test_mem[3].mem_str, NULL);
   1289     parse_table_add(&pt, "Mem4", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1290                     &sb_test_mem[4].mem_str, NULL);
   1291     parse_table_add(&pt, "Mem5", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1292                     &sb_test_mem[5].mem_str, NULL);
   1293     parse_table_add(&pt, "Mem6", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1294                     &sb_test_mem[6].mem_str, NULL);
   1295     parse_table_add(&pt, "Mem7", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1296                     &sb_test_mem[7].mem_str, NULL);
   1297     parse_table_add(&pt, "Mem8", PQ_DFL|PQ_STRING|PQ_STATIC, 0,
   1298                     &sb_test_mem[8].mem_str, NULL);
   1299     parse_table_add(&pt, "Start", PQ_DFL|PQ_INT, 0,
   1300                     &sb_test_mem[0].index_min, NULL);
   1301     parse_table_add(&pt, "Count", PQ_DFL|PQ_INT, (void *)(-1),
   1302                     &count_arg, NULL);
   1303     parse_table_add(&pt, "Frag", PQ_DFL|PQ_INT, (void *)(-1),
   1304                     &sb_test_mem[0].frag_count, NULL);
   1305     parse_table_add(&pt, "RateCalcInt", PQ_INT|PQ_DFL, 0,
   1306                     &sb_test_data.rate_calc_int, NULL);
   1307     parse_table_add(&pt, "Seed", PQ_INT|PQ_DFL, 0,
   1308                     &sb_test_data.rnum, NULL);
   1309     parse_table_add(&pt, "EccAsData", PQ_BOOL|PQ_DFL, (void *)1,
   1310                     &sb_test_data.ecc_as_data, NULL);
   1311     parse_table_add(&pt, "Desc", PQ_INT|PQ_DFL, 0,
   1312                     &sb_test_data.desc_mode, NULL);
   1313     parse_table_add(&pt, "CmcChanBitmap", PQ_HEX|PQ_DFL, 0,
   1314                     &sb_test_data.cmc_ch_bm, NULL);
   1315     parse_table_add(&pt, "DmaWrEn", PQ_BOOL|PQ_DFL, 0,
   1316                     &sb_test_data.dma_wr_en, NULL);
   1317     parse_table_add(&pt, "DmaRdEn", PQ_BOOL|PQ_DFL, 0,
   1318                     &sb_test_data.dma_rd_en, NULL);
   1319     parse_table_add(&pt, "TestMode", PQ_INT|PQ_DFL, 0,
   1320                     &sb_test_data.test_mode, NULL);
   1321     parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0,
   1322                     &sb_test_data.verbose, NULL);
   1323     parse_table_add(&pt, "debug", PQ_BOOL|PQ_DFL, 0,
   1324                     &sb_test_data.debug, NULL);
   1325     parse_table_add(&pt, "SlamEnable", PQ_BOOL|PQ_DFL, 0,
   1326                     &sb_test_data.slam_en, NULL);
   1327     parse_table_add(&pt, "SlamLowToHigh", PQ_BOOL|PQ_DFL, 0,
   1328                     &sb_test_data.slam_dir, NULL);
   1329     parse_table_add(&pt, "CheckData",   PQ_BOOL|PQ_DFL, 0,
   1330                     &sb_test_data.check_data, NULL);
   1331 
   1332     if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) {
   1333         test_msg("%s", sb_test_usage);
   1334         test_error(unit,
   1335                    "%s: Invalid option: %s\n", ARG_CMD(a),
   1336                    ARG_CUR(a) ? ARG_CUR(a) : "*");
   1337         parse_arg_eq_done(&pt);
   1338         return BCM_E_FAIL;
   1339     }
   1340 
   1341     if (soc_feature(unit, soc_feature_cmicm) &&
   1342         !soc_feature(unit, soc_feature_cmicm_multi_dma_cmc)) {
   1343         if ((sb_test_data.num_mem > 1)) {
   1344             test_error(unit, "Cannot test %0d memories in parallel since cmicm_multi_dma_cmc is disabled.\n",
   1345                        sb_test_data.num_mem);
   1346             parse_arg_eq_done(&pt);
   1347             return BCM_E_FAIL;
   1348         }
   1349     } else {
   1350         if ((sb_test_data.num_mem < 1) ||
   1351             (sb_test_data.num_mem > SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC)) {
   1352             test_error(unit, "NumMem \"%d\" is invalid\n",
   1353                        sb_test_data.num_mem);
   1354             parse_arg_eq_done(&pt);
   1355             return BCM_E_FAIL;
   1356         }
   1357     }
   1358 
   1359     for (n = 0; n < sb_test_data.num_mem; n++) {
   1360         if (parse_memory_name(unit, &sb_test_mem[n].mem, sb_test_mem[n].mem_str,
   1361                               &sb_test_mem[n].copyno, 0) < 0) {
   1362             test_error(unit, "Memory \"%s\" is invalid\n",
   1363                        sb_test_mem[n].mem_str);
   1364             parse_arg_eq_done(&pt);
   1365             return BCM_E_FAIL;
   1366         }
   1367 
   1368         if (count_arg > -1) {
   1369             sb_test_mem[n].count = count_arg;
   1370         }
   1371 
   1372         if (sb_test_mem[n].copyno == COPYNO_ALL) {
   1373             sb_test_mem[n].copyno = SOC_MEM_BLOCK_ANY(unit, sb_test_mem[n].mem);
   1374         }
   1375         if (!SOC_MEM_BLOCK_VALID(unit, sb_test_mem[n].mem, sb_test_mem[n].copyno)) {
   1376             test_error(unit,
   1377                        "Invalid copyno %d specified in %s\n",
   1378                        sb_test_mem[n].copyno, sb_test_mem[n].mem_str);
   1379             parse_arg_eq_done(&pt);
   1380             return BCM_E_FAIL;
   1381         }
   1382 
   1383         index_min = soc_mem_index_min(unit, sb_test_mem[n].mem);
   1384         index_max = soc_mem_index_max(unit, sb_test_mem[n].mem);
   1385 
   1386         if (sb_test_mem[n].index_min <= index_min) {
   1387             sb_test_mem[n].index_min = index_min;
   1388         }
   1389         if (sb_test_mem[n].index_min > index_max) {
   1390             cli_out("Min index out of range: %d\n",  sb_test_mem[n].index_min);
   1391             sb_test_mem[n].index_min = index_min;
   1392             cli_out("Changed to %d\n", sb_test_mem[n].index_min);
   1393         }
   1394 
   1395         if (sb_test_mem[n].count <= 0) {
   1396             /*
   1397              * do not use soc_mem_index_count, index_max may have been,
   1398              * index_max may have been modified above
   1399              */
   1400             sb_test_mem[n].count = index_max - index_min + 1;
   1401         }
   1402 
   1403         if (sb_test_mem[n].index_min + sb_test_mem[n].count - 1 > index_max) {
   1404             sb_test_mem[n].count = index_max - sb_test_mem[n].index_min + 1;
   1405             if (sb_test_data.verbose || sb_test_data.debug) {
   1406                 cli_out("Reduced the count to %d\n", sb_test_mem[n].count);
   1407             }
   1408         }
   1409 
   1410         if (sb_test_mem[n].count == 0) {
   1411             if (soc_feature(unit, soc_feature_esm_support)) {
   1412                 if ((sb_test_mem[n].mem == L3_DEFIPm && SOC_MEM_IS_ENABLED(unit, L3_DEFIPm)) ||
   1413                     (sb_test_mem[n].mem == L3_DEFIP_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_ONLYm)) ||
   1414                     (sb_test_mem[n].mem == L3_DEFIP_DATA_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_DATA_ONLYm)) ||
   1415                     (sb_test_mem[n].mem == L3_DEFIP_HIT_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_DATA_ONLYm)) ||
   1416                     (sb_test_mem[n].mem == L3_DEFIP_PAIR_128_DATA_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_PAIR_128_DATA_ONLYm)) ||
   1417                     (sb_test_mem[n].mem == L3_DEFIP_PAIR_128_HIT_ONLYm && SOC_MEM_IS_ENABLED(unit, L3_DEFIP_PAIR_128_HIT_ONLYm))) {
   1418                     /* The above internal memories will not be supported if External TCAM is present.
   1419                     These internal memories are set to 0 and hence can not run the test on these memories.*/
   1420                     return BCM_E_UNAVAIL;
   1421                 } else {
   1422                     test_error(unit,
   1423                                "Cannot test memory %s:  No entries.\n",
   1424                                SOC_MEM_UFNAME(unit, sb_test_mem[n].mem));
   1425                     parse_arg_eq_done(&pt);
   1426                     return BCM_E_FAIL;
   1427                 }
   1428             } else {
   1429                 test_error(unit,
   1430                            "Cannot test memory %s:  No entries.\n",
   1431                            SOC_MEM_UFNAME(unit, sb_test_mem[n].mem));
   1432                 parse_arg_eq_done(&pt);
   1433                 return BCM_E_FAIL;
   1434             }
   1435         }
   1436 
   1437         sb_test_mem[n].index_max = sb_test_mem[n].index_min +
   1438                                  sb_test_mem[n].count - 1;
   1439 
   1440         if (sb_test_mem[n].frag_count <= sb_test_data.num_mem) {
   1441             sb_test_mem[n].frag_count = sb_test_data.num_mem;
   1442             sb_test_mem[n].frag_index_min[0] = sb_test_mem[n].index_min;
   1443             sb_test_mem[n].frag_index_max[0] = sb_test_mem[n].index_max;
   1444         } else {
   1445             if (sb_test_mem[n].frag_count > sb_test_mem[n].count) {
   1446                 sb_test_mem[n].frag_count = sb_test_mem[n].count;
   1447                 cli_out("Reduced the fragment count to %d\n",
   1448                         sb_test_mem[n].frag_count);
   1449             }
   1450             if (sb_test_mem[n].frag_count > 32768) {
   1451                 sb_test_mem[n].frag_count = 32768;
   1452                 cli_out("Reduced the fragment count to %d\n",
   1453                         sb_test_mem[n].frag_count);
   1454             }
   1455             delta = (sb_test_mem[n].index_max - sb_test_mem[n].index_min) /
   1456                     sb_test_mem[n].frag_count;
   1457             for (frag = 0; frag < sb_test_mem[n].frag_count; frag++) {
   1458                 sb_test_mem[n].frag_index_min[frag] = sb_test_mem[n].index_min +
   1459                                                     frag * delta;
   1460                 sb_test_mem[n].frag_index_max[frag] = sb_test_mem[n].index_min +
   1461                                                     (frag + 1) * delta - 1;
   1462             }
   1463             sb_test_mem[n].frag_index_max[sb_test_mem[n].frag_count - 1] =
   1464                 sb_test_mem[n].index_max;
   1465         }
   1466     }
   1467 
   1468     if (soc_feature(unit, soc_feature_cmicm)) {
   1469         if (soc_feature(unit, soc_feature_cmicm_multi_dma_cmc)) {
   1470             if (sb_test_mem[0].frag_count > SOC_PCI_CMCS_NUM(unit) *
   1471                                             NUM_SBUSDMA_CH_PER_CMC) {
   1472                 sb_test_data.cmc_ch_bm = 0x777;
   1473             } else if (sb_test_data.cmc_ch_bm == 0) {
   1474                 switch (sb_test_mem[0].frag_count) {
   1475                     case 1: sb_test_data.cmc_ch_bm =   0x1; break;
   1476                     case 2: sb_test_data.cmc_ch_bm =  0x11; break;
   1477                     case 3: sb_test_data.cmc_ch_bm = 0x111; break;
   1478                     case 4: sb_test_data.cmc_ch_bm = 0x113; break;
   1479                     case 5: sb_test_data.cmc_ch_bm = 0x133; break;
   1480                     case 6: sb_test_data.cmc_ch_bm = 0x333; break;
   1481                     case 7: sb_test_data.cmc_ch_bm = 0x733; break;
   1482                     case 8: sb_test_data.cmc_ch_bm = 0x773; break;
   1483                     case 9: sb_test_data.cmc_ch_bm = 0x777; break;
   1484                 }
   1485             }
   1486         } else {
   1487             if (sb_test_data.desc_mode > 0) {
   1488                 sb_test_data.cmc_ch_bm = 0x1 << soc->desc_ch;
   1489             } else {
   1490                 sb_test_data.cmc_ch_bm = 0x1 << soc->tdma_ch |
   1491                                          0x1 <<soc->tslam_ch;
   1492             }
   1493         }
   1494     } else {
   1495         if (sb_test_mem[0].frag_count > SOC_PCI_CMCS_NUM(unit) *
   1496                                         NUM_SBUSDMA_CH_PER_CMC) {
   1497             sb_test_data.cmc_ch_bm = 0x77;
   1498         } else if (sb_test_data.cmc_ch_bm == 0) {
   1499             switch (sb_test_mem[0].frag_count) {
   1500                 case 1: sb_test_data.cmc_ch_bm =  0x1; break;
   1501                 case 2: sb_test_data.cmc_ch_bm = 0x11; break;
   1502                 case 3: sb_test_data.cmc_ch_bm = 0x13; break;
   1503                 case 4: sb_test_data.cmc_ch_bm = 0x33; break;
   1504                 case 5: sb_test_data.cmc_ch_bm = 0x37; break;
   1505                 case 6: sb_test_data.cmc_ch_bm = 0x77; break;
   1506             }
   1507         }
   1508     }
   1509 
   1510     frag = 0;
   1511     for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC + 1; i++) {
   1512         if (sb_test_data.cmc_ch_bm & (0x1 << i)) {
   1513             LOG_INFO(BSL_LS_APPL_TESTS,
   1514                  (BSL_META_U(unit,
   1515                              "Testing CMC %0d channel %0d\n"), i / NUM_SBUSDMA_CH_PER_CMC,
   1516                              i % NUM_SBUSDMA_CH_PER_CMC));
   1517             frag++;
   1518         }
   1519     }
   1520     if (sb_test_data.num_mem > 1) {
   1521         sb_test_mem[0].frag_count = 1;
   1522     } else if (frag > sb_test_mem[0].frag_count) {
   1523         sb_test_mem[0].frag_count = frag;
   1524     }
   1525 
   1526     if (frag < sb_test_data.num_mem) {
   1527         test_error(unit,"%0d CMC channels insufficient to test %0d memories\n",
   1528                    frag, sb_test_data.num_mem);
   1529         return BCM_E_FAIL;
   1530     }
   1531     for (i = 0; i < sb_test_data.num_mem; i++) {
   1532         sb_test_mem[i].mem_cmc_ch_bm = 0;
   1533     }
   1534     frag = 0;
   1535     for (i = 0; i < SOC_PCI_CMCS_NUM(unit) * NUM_SBUSDMA_CH_PER_CMC + 1; i++) {
   1536         if (sb_test_data.cmc_ch_bm & (0x1 << i)) {
   1537             sb_test_data.ch_mem_map[i] = frag % sb_test_data.num_mem;
   1538             sb_test_mem[sb_test_data.ch_mem_map[i]].mem_cmc_ch_bm |= 0x1 << i;
   1539                 LOG_INFO(BSL_LS_APPL_TESTS,
   1540                      (BSL_META_U(unit,
   1541                                  "sb_test_data.ch_mem_map[%0d] = 0x%x\n"),
   1542                                  i, sb_test_data.ch_mem_map[i]));
   1543                 LOG_INFO(BSL_LS_APPL_TESTS,
   1544                      (BSL_META_U(unit,
   1545                                  "sb_test_mem[%0d].mem_cmc_ch_bm = 0x%x\n"),
   1546                                  sb_test_data.ch_mem_map[i],
   1547                                  sb_test_mem[sb_test_data.ch_mem_map[i]].mem_cmc_ch_bm));
   1548             frag++;
   1549         } else {
   1550             sb_test_data.ch_mem_map[i] = -1;
   1551         }
   1552     }
   1553 
   1554     soc_endian_get(unit, &sb_test_data.big_pio, &big_packet, &sb_test_data.big_endian);
   1555 
   1556     if (soc_feature(unit, soc_feature_cmicm_multi_dma_cmc) &&
   1557         soc_feature(unit, soc_feature_cmicm)) {
   1558         for (cmc = 1; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   1559             if ((sb_test_data.cmc_ch_bm &
   1560                  (CMIC_CMC0_SBUSDMA_CH_MASK << (cmc * NUM_SBUSDMA_CH_PER_CMC))) != 0) {
   1561                 addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(0));
   1562                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc),
   1563                               addr_remap);
   1564                 addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(0));
   1565                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc),
   1566                               addr_remap);
   1567                 addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(0));
   1568                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc),
   1569                               addr_remap);
   1570                 addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(0));
   1571                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc),
   1572                               addr_remap);
   1573             }
   1574         }
   1575     }
   1576 
   1577     parse_arg_eq_done(&pt);
   1578 
   1579     if (!SOC_IS_XGS_SWITCH(unit)) {
   1580         test_error(unit, "Chip type not supported for SBUS DMA test\n");
   1581     }
   1582 
   1583     for (n = 0; n < sb_test_data.num_mem; n++) {
   1584         if (n > 0) {
   1585             sb_test_mem[n].frag_count = 1;
   1586         }
   1587         LOG_INFO(BSL_LS_APPL_TESTS,
   1588                  (BSL_META_U(unit,
   1589                              "SBUS DMA %s: copy %d, from entry %d for %d entries SEED = %d\n"),
   1590                   sb_test_mem[n].mem_str,
   1591                   sb_test_mem[n].copyno,
   1592                   sb_test_mem[n].index_min,
   1593                   sb_test_mem[n].count,
   1594                   sb_test_data.rnum));
   1595         if (!soc_mem_dmaable(unit, sb_test_mem[n].mem, sb_test_mem[n].copyno)) {
   1596             cli_out("WARNING: DMA will not be used for memory %s.%d.\n",
   1597                     sb_test_mem[n].mem_str, sb_test_mem[n].copyno);
   1598         }
   1599     }
   1600 
   1601     /* integrity check: For read-only mem, ignore integrity check.
   1602      *                  Because there is no writing operation on mem.
   1603      */
   1604     if (sb_test_data.test_mode == 2) {
   1605         sb_test_data.check_data = FALSE;
   1606     }
   1607 
   1608     if (sb_test_data_init(unit, 1) < 0) {
   1609         test_error(unit, "Test initialization failed\n");
   1610     }
   1611 
   1612     return SOC_E_NONE;
   1613 }
   1614 
   1615 int
   1616 sb_test_done(int unit, void *pa)
   1617 {
   1618     sb_test_data_clear(unit);
   1619 
   1620     return SOC_E_NONE;
   1621 }
   1622 
   1623 #endif /* BCM_ESW_SUPPORT && BCM_CMICM_SUPPORT BCM_SBUSDMA_SUPPORT */