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

ccmdma_test.c (26847B)


      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  * CCM DMA Test
      8  *
      9  * The CCM DMA test transfers a source memory to a destination memory with one
     10  * or more CMC in parallel. The memories can be internal or external. First, the
     11  * test initializes the source memory with random values. Then, it kicks off one
     12  * or more CCM DMA transfer from the source memory to the destination memory.
     13  * Data integrity check is done by comparing the source and destination
     14  * memories. The CCM DMA performance in calculated by dividing the number of CCM
     15  * DMA performed x the CCM DMA transfer size by the duration of the performance
     16  * test.
     17  */
     18 
     19 #include <shared/bsl.h>
     20 #include <sal/appl/sal.h>
     21 #include <sal/core/time.h>
     22 #include <appl/diag/system.h>
     23 #include <appl/diag/parse.h>
     24 #include <soc/debug.h>
     25 #include <soc/dma.h>
     26 #include <soc/l2x.h>
     27 #include <soc/uc.h>
     28 #include "testlist.h"
     29 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT)
     30 #include <soc/cmicm.h>
     31 #endif
     32 #include <soc/ccmdma.h>
     33 #define EXT_TO_EXT 0
     34 #define EXT_TO_INT 1
     35 #define INT_TO_EXT 2
     36 #define INT_TO_INT 3
     37 #define MIXED_MODE 4
     38 #define FEATURE_TEST 0
     39 #define PERFORMANCE_TEST 1
     40 
     41 #define CMC_BITMAP_PARAM  0x1
     42 #define CHAN_BITMAP_PARAM 0x1
     43 #define XFER_TYPE_PARAM   0
     44 #define ENTRY_COUNT_PARAM 1024
     45 #define TEST_TYPE_PARAM 1
     46 #define CCMDMA_RATE_CALC_INTERVAL_PARAM 10
     47 
     48 #if defined(BCM_ESW_SUPPORT) && defined(BCM_CCMDMA_SUPPORT)
     49 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
     50 
     51 sal_thread_t pid_ccmdma[SOC_CMCS_NUM_MAX];
     52 
     53 typedef struct cdt_data_s {
     54     unsigned int cmc_bitmap;
     55     unsigned int chan_bitmap;
     56     unsigned int xfer_type;
     57     unsigned int entry_count;
     58     unsigned int test_type;
     59     unsigned int rate_calc_interval;
     60     unsigned int use_api;
     61     unsigned int sram_base;
     62     unsigned int sram_size;
     63     unsigned int* host0_base[SOC_CMCS_NUM_MAX];
     64     unsigned int* host1_base[SOC_CMCS_NUM_MAX];
     65     volatile unsigned int transfer_count[SOC_CMCS_NUM_MAX];
     66     unsigned int do_ccmdma_wrapper_cmc;
     67     unsigned int do_ccmdma_wrapper_chan;
     68     unsigned int max_cmc;
     69     unsigned int max_chan;
     70     unsigned int stream;
     71 } cd_test_data_t;
     72 
     73 static cd_test_data_t cd_test_data;
     74 
     75 char cd_test_usage[] =
     76     "CCM DMA test usage:\n"
     77     " \n"
     78 #ifdef COMPILER_STRING_CONST_LIMIT
     79     "\nFull documentation cannot be displayed with -pedantic compiler\n";
     80 #else
     81     "CmcBitmap=<hex>  -  Specify which of the 3 available CMCs to use; default is 0x1\n"
     82     "ChanBitmap=<hex> -  Specify which of the chan to use; default is 0x1\n"
     83     "XferType=<0..4>  -  Data transfer scenarios, 0: external->external;\n"
     84     "                    1: external->internal; 2: internal->external;\n"
     85     "                    3: internal->internal; 4: mixed XferType 0, 2, and 3\n"
     86     "TestType=<1/0>   -  0: feature test; 1: performance test; default is 1\n"
     87     "EntryCount=<int> -  Number of entries per CCM DMA; default is 1024 DWords\n"
     88     "RateCalcInt=<int>-  Duration for rate calculation; default is 10 s\n"
     89     "UseAPI=<1/0>     -  Switch between SOC APIs and manual coding; default is 1\n"
     90     "SramBase=<hex>   -  SRAM base address; default is 0x1b000000 for Tomahawk and\n"
     91     "                    0x400000 for Trident2+\n"
     92     "SramSize=<hex>   -  SRAM Size\n"
     93     ;
     94 #endif
     95 
     96 
     97 static void
     98 parse_ccmdma_test_params(int unit, args_t* a)
     99 {
    100     parse_table_t parse_table_ccmdma_test;
    101 
    102     parse_table_init(unit, &parse_table_ccmdma_test);
    103     parse_table_add(&parse_table_ccmdma_test, "CmcBitmap",    PQ_HEX|PQ_DFL, 0,
    104                     &(cd_test_data.cmc_bitmap),               NULL);
    105     parse_table_add(&parse_table_ccmdma_test, "ChanBitmap",   PQ_HEX|PQ_DFL, 0,
    106                     &(cd_test_data.chan_bitmap),              NULL);
    107     parse_table_add(&parse_table_ccmdma_test, "XferType",     PQ_INT|PQ_DFL, 0,
    108                     &(cd_test_data.xfer_type),                NULL);
    109     parse_table_add(&parse_table_ccmdma_test, "EntryCount",   PQ_INT|PQ_DFL, 0,
    110                     &(cd_test_data.entry_count),              NULL);
    111     parse_table_add(&parse_table_ccmdma_test, "TestType",     PQ_INT|PQ_DFL, 0,
    112                     &(cd_test_data.test_type),                NULL);
    113     parse_table_add(&parse_table_ccmdma_test, "RateCalcInt",  PQ_INT|PQ_DFL, 0,
    114                     &(cd_test_data.rate_calc_interval), NULL);
    115     parse_table_add(&parse_table_ccmdma_test, "UseAPI",       PQ_BOOL|PQ_DFL, 0,
    116                     &(cd_test_data.use_api),                  NULL);
    117     parse_table_add(&parse_table_ccmdma_test, "SramBase",     PQ_HEX|PQ_DFL, 0,
    118                     &(cd_test_data.sram_base),                NULL);
    119     parse_table_add(&parse_table_ccmdma_test, "SramSize",     PQ_HEX|PQ_DFL, 0,
    120                     &(cd_test_data.sram_size),                NULL);
    121     if (parse_arg_eq(a, &parse_table_ccmdma_test) < 0 || ARG_CNT(a) != 0) {
    122         test_error(unit,
    123                    "%s: Invalid option: %s\n", ARG_CMD(a),
    124                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    125         test_msg(cd_test_usage);
    126         parse_arg_eq_done(&parse_table_ccmdma_test);
    127     }
    128 
    129     if ((cd_test_data.xfer_type != EXT_TO_EXT) &&
    130         (SOC_PCI_CMCS_NUM(unit) < SOC_CMCS_NUM(unit))) {
    131             test_error(unit,
    132                    "Embedded processor enabled, unable to test internal SRAM\n");
    133     }
    134 
    135     if (cd_test_data.xfer_type == MIXED_MODE) {
    136         /* mixed mode runs all three CMCs in different transfer types */
    137         cd_test_data.cmc_bitmap = 7;
    138     }
    139 
    140     cli_out("\n ------------- PRINTING TEST PARAMS ------------------");
    141     cli_out("\nCmcBitmap   = 0x%0x",  cd_test_data.cmc_bitmap);
    142     cli_out("\nChanBitmap  = 0x%0x",  cd_test_data.chan_bitmap);
    143     cli_out("\nXferType    = %0d",    cd_test_data.xfer_type);
    144     cli_out("\nEntryCount  = %0d",    cd_test_data.entry_count);
    145     cli_out("\nTestType    = %0d",    cd_test_data.test_type);
    146     cli_out("\nRateCalcInt = %0d",    cd_test_data.rate_calc_interval);
    147     cli_out("\nUseAPI      = %0d",    cd_test_data.use_api);
    148     cli_out("\nSramBase    = 0x%0x",  cd_test_data.sram_base);
    149     cli_out("\nSramSize    = 0x%0x",  cd_test_data.sram_size);
    150     cli_out("\n -----------------------------------------------------");
    151 }
    152 
    153 
    154 static unsigned int
    155 ccmdma_soc_read(int unit, unsigned int addr)
    156 {
    157 #ifdef BCM_CMICX_SUPPORT
    158     if (soc_feature(unit, soc_feature_cmicx)) {
    159         return (soc_cm_iproc_read(unit, addr));
    160     } else
    161 #endif /* BCM_CMICX_SUPPORT */
    162     if (soc_feature(unit, soc_feature_cmicm)) {
    163         return (soc_pci_mcs_read(unit, addr));
    164     }
    165 
    166     return 0;
    167 }
    168 
    169 
    170 static void
    171 ccmdma_soc_write(int unit, unsigned int addr, unsigned int data)
    172 {
    173 #ifdef BCM_CMICX_SUPPORT
    174     if (soc_feature(unit, soc_feature_cmicx)) {
    175         soc_cm_iproc_write(unit, addr, data);
    176     } else
    177 #endif /* BCM_CMICX_SUPPORT */
    178     if (soc_feature(unit, soc_feature_cmicm)) {
    179         soc_pci_mcs_write(unit, addr, data);
    180     }
    181 }
    182 
    183 static void
    184 clear_ext_memory(unsigned char* start_addr, unsigned int num_bytes)
    185 {
    186     unsigned int i;
    187 
    188     for (i = 0; i < num_bytes; i++) {
    189         start_addr[i] = 0x0;
    190     }
    191 }
    192 
    193 
    194 static void
    195 clear_internal_memory(int unit, unsigned int start_addr, unsigned int num_words)
    196 {
    197     unsigned int i;
    198 
    199     for (i = 0; i < num_words; i++)  {
    200         ccmdma_soc_write(unit, (start_addr + sizeof(unsigned int) * i), 0x0);
    201     }
    202 }
    203 
    204 
    205 static void
    206 ccmdma_test_clean(int unit)
    207 {
    208     soc_ccmdma_clean(unit, cd_test_data.max_cmc);
    209 }
    210 
    211 
    212 static unsigned int
    213 xfer_type_per_cmc(int unit, unsigned int xfer_type, unsigned int cmc)
    214 {
    215     if (xfer_type == MIXED_MODE) {
    216         /* If xfer_type is mixed mode, make CMC 0  EXT_to_EXT, CMC 1 INT_TO_EXT,
    217            and CMC 2 INT_TO_INT */
    218         switch (cmc) {
    219             case 0: return(EXT_TO_EXT); break;
    220             case 1: return(INT_TO_EXT); break;
    221             case 2: return(INT_TO_INT); break;
    222         }
    223     }
    224     return xfer_type;
    225 }
    226 
    227 static void
    228 do_ccmdma_th(int unit, unsigned int cmc, unsigned int* host0_mem_start_addr,
    229           unsigned int* host1_mem_start_addr, unsigned int entry_count,
    230           unsigned int host0_is_internal, unsigned int host1_is_internal,
    231           volatile unsigned int* transfer_count)
    232 {
    233     int rv;
    234 
    235     do {
    236             rv = soc_ccmdma_copy(unit, (sal_paddr_t*)host0_mem_start_addr,
    237                                        (sal_paddr_t*)host1_mem_start_addr,
    238                                        host0_is_internal, host1_is_internal,
    239                                        entry_count, 0, cmc);
    240             if(rv != SOC_E_NONE) {
    241                 cli_out("\nWARNING: soc_ccmdma_copy returned with error %x\n", rv);
    242                 return;
    243             }
    244             cd_test_data.transfer_count[cmc]++;
    245     } while (cd_test_data.stream != 0);
    246 }
    247 
    248 
    249 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
    250 static void
    251 do_ccmdma_cmicx(int unit, unsigned int cmc, unsigned int* host0_mem_start_addr,
    252           unsigned int* host1_mem_start_addr, unsigned int entry_count,
    253           unsigned int host0_is_internal, unsigned int host1_is_internal,
    254           volatile unsigned int* transfer_count)
    255 {
    256     int rv;
    257     unsigned int bitmap, chan, vchan = 0;
    258 
    259     bitmap = cd_test_data.chan_bitmap;
    260 
    261     do {
    262         for (chan = 0; chan < cd_test_data.max_chan; chan++) {
    263             if (bitmap & (0x1 << chan)) {
    264                 vchan = (cd_test_data.max_chan * cmc) + chan;
    265                 rv = soc_ccmdma_copy(unit, (sal_paddr_t*)host0_mem_start_addr,
    266                                            (sal_paddr_t*)host1_mem_start_addr,
    267                                  host0_is_internal, host1_is_internal,
    268                                  entry_count, 0, vchan);
    269                 if(rv != SOC_E_NONE) {
    270                     cli_out("\nWARNING: soc_ccmdma_copy returned with error %x\n", rv);
    271                     return;
    272                 }
    273                 cd_test_data.transfer_count[cmc]++;
    274             }
    275         }
    276     } while (cd_test_data.stream != 0);
    277 }
    278 #endif
    279 
    280 
    281 static void
    282 do_ccmdma(int unit, unsigned int cmc, unsigned int* host0_mem_start_addr,
    283           unsigned int* host1_mem_start_addr, unsigned int entry_count,
    284           unsigned int host0_is_internal, unsigned int host1_is_internal,
    285           volatile unsigned int* transfer_count)
    286 {
    287 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
    288     if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
    289         do_ccmdma_cmicx(unit, cmc, host0_mem_start_addr, host1_mem_start_addr,
    290                   entry_count, host0_is_internal, host1_is_internal,
    291                   transfer_count);
    292     } else
    293 #endif
    294     if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT2PLUS(unit)) {
    295         do_ccmdma_th(unit, cmc, host0_mem_start_addr, host1_mem_start_addr,
    296                   entry_count, host0_is_internal, host1_is_internal,
    297                   transfer_count);
    298     }
    299 }
    300 
    301 
    302 static void
    303 initialize_memory(int unit, unsigned int cmc_bitmap, unsigned int entry_count)
    304 {
    305     unsigned int cmc;
    306     unsigned int i;
    307     unsigned int xfer_type;
    308 #ifdef PTRS_ARE_64BITS
    309     unsigned int* int_mem_base = (unsigned int*)((uint64)cd_test_data.sram_base);
    310 #else
    311     unsigned int* int_mem_base = (unsigned int*)(cd_test_data.sram_base);
    312 #endif
    313 
    314     if ((cd_test_data.sram_base == 0) && (cd_test_data.xfer_type != EXT_TO_EXT)) {
    315         test_error(unit, "\nSramBase Unspecified");
    316     }
    317 
    318     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    319         xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type, cmc);
    320         if ((cmc_bitmap >> cmc) % 2 != 0) {
    321             if ((xfer_type == EXT_TO_EXT) || (xfer_type == EXT_TO_INT)) {
    322                 cd_test_data.host0_base[cmc] =
    323                                   sal_dma_alloc(cd_test_data.entry_count *
    324                          sizeof(unsigned int), "HOST0_BASE");
    325                 clear_ext_memory((unsigned char*) cd_test_data.host0_base[cmc],
    326                                  (entry_count * sizeof(unsigned int)));
    327             } else {
    328                 cd_test_data.host0_base[cmc] = int_mem_base;
    329                 int_mem_base += entry_count;
    330 #ifdef PTRS_ARE_64BITS
    331                 clear_internal_memory(unit, (uint64)cd_test_data.host0_base[cmc],
    332                                       entry_count);
    333 #else
    334                 clear_internal_memory(unit, (uint32)cd_test_data.host0_base[cmc],
    335                                       entry_count);
    336 #endif
    337             }
    338 
    339             if ((xfer_type == EXT_TO_EXT) || (xfer_type == INT_TO_EXT)) {
    340                 cd_test_data.host1_base[cmc] =
    341                                   sal_dma_alloc(cd_test_data.entry_count *
    342                         sizeof(unsigned int), "HOST0_BASE");
    343                 clear_ext_memory((unsigned char*) cd_test_data.host1_base[cmc],
    344                                  (entry_count * sizeof(unsigned int)));
    345             } else {
    346                 cd_test_data.host1_base[cmc] = int_mem_base;
    347                 int_mem_base += entry_count;
    348 #ifdef PTRS_ARE_64BITS
    349                 clear_internal_memory(unit, (uint64)cd_test_data.host1_base[cmc],
    350                                       entry_count);
    351 #else
    352                 clear_internal_memory(unit, (uint32)cd_test_data.host1_base[cmc],
    353                                       entry_count);
    354 #endif
    355             }
    356 
    357             for (i = 0; i < entry_count; i++)  {
    358                 if ((xfer_type == EXT_TO_EXT) || (xfer_type == EXT_TO_INT)) {
    359                     cd_test_data.host0_base[cmc][i] = sal_rand();
    360                 }  else  {
    361 #ifdef PTRS_ARE_64BITS
    362                     ccmdma_soc_write(unit, (uint64)cd_test_data.host0_base[cmc] +
    363                                       sizeof(unsigned int) * i, sal_rand());
    364 #else
    365                     ccmdma_soc_write(unit, (uint32)cd_test_data.host0_base[cmc] +
    366                                       sizeof(unsigned int) * i, sal_rand());
    367 #endif
    368                 }
    369             }
    370         }
    371     }
    372 
    373     cli_out("\n----------------MEMORY INITIALIZED-------------------");
    374     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++)  {
    375         cli_out("\nFor CMC %0d, host0_base = %p, host1_base = %p",
    376                 cmc, cd_test_data.host0_base[cmc], cd_test_data.host1_base[cmc]);
    377     }
    378     cli_out("\n-----------------------------------------------------");
    379 }
    380 
    381 #define BSAND_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0x00ff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24)))
    382 
    383 static unsigned int
    384 check_data_integrity(int unit, unsigned int cmc_bitmap, unsigned int num_entries)
    385 {
    386     unsigned int cmc;
    387     unsigned int i;
    388     unsigned int xfer_type;
    389     unsigned int src_word;
    390     unsigned int dest_word;
    391     unsigned int match = 1;
    392     int big_pio, big_packet, big_other;
    393 
    394     soc_endian_get(unit, &big_pio, &big_packet, &big_other);
    395 
    396     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++)  {
    397         xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type, cmc);
    398         if (((cmc_bitmap >> cmc) % 2) != 0)  {
    399             for (i = 0; i < num_entries; i++)  {
    400                 if ((xfer_type == EXT_TO_EXT) || (xfer_type == EXT_TO_INT)) {
    401                     src_word = cd_test_data.host0_base[cmc][i];
    402                 }  else  {
    403 #ifdef PTRS_ARE_64BITS
    404                     src_word = ccmdma_soc_read(unit,
    405                                    (uint64)cd_test_data.host0_base[cmc] +
    406                                                 (sizeof(unsigned int) * i));
    407 #else
    408                     src_word = ccmdma_soc_read(unit,
    409                                    (uint32)cd_test_data.host0_base[cmc] +
    410                                                 (sizeof(unsigned int) * i));
    411 #endif
    412                     if (big_other) {
    413                         src_word = BSAND_BYTE_SWAP(src_word);
    414                     }
    415                 }
    416 
    417                 if ((xfer_type == EXT_TO_EXT) || (xfer_type == INT_TO_EXT)) {
    418                     dest_word = cd_test_data.host1_base[cmc][i];
    419                 }  else  {
    420 #ifdef PTRS_ARE_64BITS
    421                     dest_word = ccmdma_soc_read(unit,
    422                                    (uint64)cd_test_data.host1_base[cmc] +
    423                                                  (sizeof(unsigned int) * i));
    424 #else
    425                     dest_word = ccmdma_soc_read(unit,
    426                                    (uint32)cd_test_data.host1_base[cmc] +
    427                                                  (sizeof(unsigned int) * i));
    428 #endif
    429                     if (big_other) {
    430                         dest_word = BSAND_BYTE_SWAP(dest_word);
    431                     }
    432                 }
    433 
    434                 if (src_word != dest_word) {
    435                     match = 0;
    436                     test_error(unit, "\nMismatch: CMC=%0d | host0_addr=%p, Src_word=0x%08x | host1_addr=%p, Dest_word=0x%08x",
    437                                cmc, (cd_test_data.host0_base[cmc] + i), src_word,
    438                                (cd_test_data.host1_base[cmc] + i), dest_word);
    439                     break;
    440                 }
    441             }
    442         }
    443     }
    444     return(match);
    445 }
    446 
    447 
    448 static void
    449 ccmdma_feature_test(int unit)
    450 {
    451     unsigned int cmc, match;
    452     unsigned int xfer_type;
    453     unsigned int src_type;
    454     unsigned int dst_type;
    455 
    456     initialize_memory(unit, cd_test_data.cmc_bitmap, cd_test_data.entry_count);
    457 
    458     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++)  {
    459         xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type, cmc);
    460         if((xfer_type == INT_TO_EXT) || (xfer_type == INT_TO_INT)) {
    461             src_type = 1;
    462         }
    463         else {
    464             src_type = 0;
    465         }
    466 
    467         if((xfer_type == EXT_TO_INT) || (xfer_type == INT_TO_INT)) {
    468             dst_type = 1;
    469         }
    470         else {
    471             dst_type = 0;
    472         }
    473 
    474         if ((cd_test_data.cmc_bitmap >> cmc) % 2 != 0)  {
    475             do_ccmdma(unit, cmc, cd_test_data.host0_base[cmc],
    476                       cd_test_data.host1_base[cmc],
    477                       cd_test_data.entry_count,
    478                       src_type,
    479                       dst_type,
    480                       &cd_test_data.transfer_count[cmc]);
    481         }
    482     }
    483     match = check_data_integrity(unit, cd_test_data.cmc_bitmap,
    484                                  cd_test_data.entry_count);
    485 
    486     if (match == 1)  {
    487         cli_out("\n************* DATA INTEGRITY CHECK PASSED **************");
    488     }  else  {
    489         test_error(unit, "\n************* DATA INTEGRITY CHECK FAILED **************");
    490     }
    491 }
    492 
    493 
    494 static void
    495 do_ccmdma_wrapper(void* up)
    496 {
    497     int unit = PTR_TO_INT(up);
    498     unsigned int xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type,
    499                                                cd_test_data.do_ccmdma_wrapper_cmc);
    500 
    501     do_ccmdma(unit, cd_test_data.do_ccmdma_wrapper_cmc,
    502               cd_test_data.host0_base[cd_test_data.do_ccmdma_wrapper_cmc],
    503               cd_test_data.host1_base[cd_test_data.do_ccmdma_wrapper_cmc],
    504               cd_test_data.entry_count,
    505               (unsigned int)((xfer_type == INT_TO_EXT) ||
    506                              (xfer_type == INT_TO_INT)),
    507               (unsigned int)((xfer_type == EXT_TO_INT) ||
    508                              (xfer_type == INT_TO_INT)),
    509               (&cd_test_data.transfer_count[cd_test_data.do_ccmdma_wrapper_cmc]));
    510 
    511     while (cd_test_data.stream != 0) {
    512         sal_usleep(100000);
    513     }
    514 
    515     sal_thread_exit(0);
    516 }
    517 
    518 
    519 static void
    520 ccmdma_measure_rate(int unit, unsigned int entry_count,
    521                     unsigned int interval_in_seconds)
    522 {
    523     unsigned int cmc;
    524     unsigned int transfer_count_start[SOC_CMCS_NUM_MAX];
    525     unsigned int transfer_count_end[SOC_CMCS_NUM_MAX];
    526     unsigned long byte_transferred;
    527 
    528     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    529         transfer_count_start[cmc] = cd_test_data.transfer_count[cmc];
    530         cli_out("\ntransfer_count_start[%0d] = %u",
    531                 cmc, transfer_count_start[cmc]);
    532     }
    533 
    534     cli_out("\nMeasuring data transfer rate over an interval of %0d seconds",
    535             interval_in_seconds);
    536     sal_sleep(interval_in_seconds);
    537 
    538     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    539         transfer_count_end[cmc] = cd_test_data.transfer_count[cmc];
    540         cli_out("\ntransfer_count_end[%0d] = %u",
    541                 cmc, transfer_count_end[cmc]);
    542     }
    543 
    544     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    545         byte_transferred = (transfer_count_end[cmc] - transfer_count_start[cmc]) *
    546                             entry_count * 4;
    547         cli_out("\n***CCM DMA transfer rate on CMC %0d = %lu byte/s",
    548                 cmc, (byte_transferred/interval_in_seconds));
    549     }
    550 }
    551 
    552 static void
    553 ccmdma_performance_test(int unit)
    554 {
    555     unsigned int cmc;
    556     char str[80];
    557 
    558     initialize_memory(unit, cd_test_data.cmc_bitmap, cd_test_data.entry_count);
    559 
    560     cd_test_data.stream = 1;
    561 
    562     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    563         if ((cd_test_data.cmc_bitmap >> cmc) % 2 != 0) {
    564             sal_sprintf(str, "CCMDMA_CMC%0d", cmc);
    565             cd_test_data.do_ccmdma_wrapper_cmc = cmc;
    566 
    567             pid_ccmdma[cmc] = sal_thread_create(str, 32 * 1024 * 1024, 200,
    568                                                 do_ccmdma_wrapper,
    569                                                 INT_TO_PTR(unit));
    570 
    571             sal_usleep(100000);
    572             cli_out("\npid_ccmdma[%0d] = %p", cmc, pid_ccmdma[cmc]);
    573         }
    574     }
    575 
    576     sal_usleep(100000);
    577 
    578     ccmdma_measure_rate(unit, cd_test_data.entry_count,
    579                         cd_test_data.rate_calc_interval);
    580 
    581     cd_test_data.stream = 0;
    582     sal_usleep(100000);
    583 }
    584 
    585 
    586 int ccmdma_test_init(int unit, args_t *a, void **pa)
    587 {
    588     unsigned int cmc;
    589     unsigned int xfer_type;
    590     uint32 addr_remap;
    591 
    592     cli_out("\nCalling ccmdma_test_init\n");
    593 
    594 #ifdef BCM_CMICX_SUPPORT
    595     if (soc_feature(unit, soc_feature_cmicx)) {
    596         cli_out("\nSOC feature is CMICX\n");
    597     } else
    598 #endif /* BCM_CMICX_SUPPORT */
    599     if (soc_feature(unit, soc_feature_cmicm)) {
    600         cli_out("\nSOC feature is CMICM\n");
    601     } else {
    602         cli_out("\n*WARN SOC feature is unknown\n");
    603     }
    604 
    605     if (soc_property_get(unit, spn_CCM_DMA_ENABLE, 0) == 0) {
    606         test_error(unit, "CCM DMA is disabled. Please add ccm_dma_enable=1 to config.bcm\n");
    607     }
    608 
    609     cd_test_data.cmc_bitmap         = CMC_BITMAP_PARAM;
    610     cd_test_data.chan_bitmap        = CHAN_BITMAP_PARAM;
    611     cd_test_data.xfer_type          = XFER_TYPE_PARAM;
    612     cd_test_data.entry_count        = ENTRY_COUNT_PARAM;
    613     cd_test_data.test_type          = TEST_TYPE_PARAM;
    614     cd_test_data.rate_calc_interval = CCMDMA_RATE_CALC_INTERVAL_PARAM;
    615     cd_test_data.use_api            = 1;
    616 
    617     (void) soc_uc_sram_extents(unit, &cd_test_data.sram_base, &cd_test_data.sram_size);
    618 
    619     cd_test_data.do_ccmdma_wrapper_cmc = 0;
    620 #ifdef BCM_CMICX_SUPPORT
    621     if (soc_feature(unit, soc_feature_cmicx)) {
    622         cd_test_data.max_cmc = SOC_PCI_CMCS_NUM(unit);
    623         cd_test_data.max_chan = 2;
    624     } else
    625 #endif /* BCM_CMICX_SUPPORT */
    626     if (soc_feature(unit, soc_feature_cmicm_multi_dma_cmc)) {
    627         cd_test_data.max_cmc = SOC_PCI_CMCS_NUM(unit);
    628         cd_test_data.max_chan = 1;
    629     } else {
    630         cd_test_data.max_cmc = 1;
    631         cd_test_data.max_chan = 1;
    632     }
    633 
    634     cd_test_data.stream = 0;
    635     parse_ccmdma_test_params(unit, a);
    636     ccmdma_test_clean(unit);
    637 
    638     if (soc_feature(unit, soc_feature_cmicm)
    639             || soc_feature(unit, soc_feature_cmicd_v2)
    640             || soc_feature(unit, soc_feature_cmicd_v3)) {
    641         for (cmc = 1; cmc < cd_test_data.max_cmc; cmc++) {
    642             addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(0));
    643             soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc), addr_remap);
    644             addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(0));
    645             soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc), addr_remap);
    646             addr_remap = soc_pci_read(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(0));
    647             soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc), addr_remap);
    648         }
    649         for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    650             xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type, cmc);
    651             cd_test_data.transfer_count[cmc] = 0;
    652             if (SOC_REG_IS_VALID(unit, CMIC_CMC0_HOSTMEM_ADDR_REMAP_3r)) {
    653                 if (xfer_type != EXT_TO_EXT) {
    654                     /* Set hostmem_addr_remap for internal SRAM */
    655                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc),
    656                               0x1);
    657                 } else {
    658                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc),
    659                               0x1f);
    660                 }
    661             } else {
    662                 if (xfer_type != EXT_TO_EXT) {
    663                     /* Set hostmem_addr_remap for internal SRAM */
    664                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc),
    665                               0x7bbc);
    666                 } else {
    667                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc),
    668                               0xffbbc);
    669                 }
    670             }
    671         }
    672     } else {
    673         for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    674             xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type, cmc);
    675             cd_test_data.transfer_count[cmc] = 0;
    676         }
    677     }
    678 
    679     return 0;
    680 }
    681 
    682 int ccmdma_test_cleanup(int unit, void *pa)
    683 {
    684     unsigned int cmc;
    685     unsigned int xfer_type;
    686 
    687     cli_out("\nCalling ccmdma_test_cleanup");
    688     ccmdma_test_clean(unit);
    689     for (cmc = 0; cmc < cd_test_data.max_cmc; cmc++) {
    690         if (soc_feature(unit, soc_feature_cmicm)
    691             || soc_feature(unit, soc_feature_cmicd_v2)
    692             || soc_feature(unit, soc_feature_cmicd_v3)) {
    693             /* Restore hostmem_addr_remap to default value */
    694             if (SOC_REG_IS_VALID(unit, CMIC_CMC0_HOSTMEM_ADDR_REMAP_3r)) {
    695                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc),
    696                               0x1f);
    697             } else {
    698                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc),
    699                               0xffbbc);
    700             }
    701         }
    702         xfer_type = xfer_type_per_cmc(unit, cd_test_data.xfer_type, cmc);
    703         if ((xfer_type == EXT_TO_EXT) ||
    704             (xfer_type == EXT_TO_INT)) {
    705             sal_dma_free(cd_test_data.host0_base[cmc]);
    706         }
    707         if ((xfer_type == EXT_TO_EXT) ||
    708             (xfer_type == INT_TO_EXT)) {
    709             sal_dma_free(cd_test_data.host1_base[cmc]);
    710         }
    711         cd_test_data.host0_base[cmc] = 0;
    712         cd_test_data.host1_base[cmc] = 0;
    713     }
    714 
    715     cli_out("\n");
    716     return 0;
    717 }
    718 
    719 
    720 int ccmdma_test(int unit, args_t *a, void *pa)
    721 {
    722     if (cd_test_data.test_type == PERFORMANCE_TEST) {
    723         ccmdma_performance_test(unit);
    724     } else {
    725         ccmdma_feature_test(unit);
    726     }
    727     return 0;
    728 }
    729 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */
    730 #endif /* BCM_ESW_SUPPORT && BCM_CCMDMA_SUPPORT */