fifodma_test.c (19461B)
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 * FIFO DMA Test 8 * 9 * The FIFO DMA test fills up the L2_MOD_FIFO with random values through SCHAN. 10 * Then, it reads the L2_MOD_FIFO through FIFO DMA to an external memory. Data 11 * integrity check is done by comparing the source and destination memories. 12 * FIFO DMA read performance in bps is calculated. 13 */ 14 15 #include <shared/bsl.h> 16 #include <sal/appl/sal.h> 17 #include <sal/core/time.h> 18 #include <appl/diag/system.h> 19 #include <appl/diag/parse.h> 20 #include <soc/debug.h> 21 #include <soc/dma.h> 22 #include <soc/cmic.h> 23 #include <soc/l2x.h> 24 #include "testlist.h" 25 26 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT) || \ 27 defined(BCM_CMICX_SUPPORT) 28 #include <soc/cmicm.h> 29 #endif 30 31 #define FIFODMA_PARAM_TEST_TYPE_DEFAULT 1 32 #define FIFODMA_PARAM_RATE_CALC_INT_DEFAULT 10 33 #define FIFODMA_PARAM_VCHAN_DEFAULT 0 34 #define FIFODMA_PARAM_DEBUG_DEFAULT 0 35 36 #define FIFODMA_TIMEOUT_DEFAULT 10 37 38 #if defined(BCM_ESW_SUPPORT) && defined(BCM_CMICM_SUPPORT) 39 40 typedef struct fifodma_data_s { 41 unsigned int param_test_type; 42 unsigned int param_rate_calc_interval; 43 unsigned int param_vchan; 44 unsigned int param_debug; 45 unsigned int fifo_depth; 46 unsigned int fifo_width; 47 unsigned int stop_perf_test; 48 volatile sal_usecs_t td_acc; 49 unsigned int* host_base; 50 volatile int total_fifo_drains; 51 uint32 cmc; 52 uint32 ch; 53 uint32 test_fail; 54 uint32 bad_input; 55 } fifodma_data_t; 56 57 static fifodma_data_t fifodma_data; 58 59 const char fd_test_usage[] = 60 "FIFO DMA test usage: [L2_MOD_FIFO]\n" 61 " \n" 62 #ifdef COMPILER_STRING_CONST_LIMIT 63 "\nFull documentation cannot be displayed with -pedantic compiler\n"; 64 #else 65 "VChan=<int> - Virtual CMC Channel; default 0\n" 66 " TD3: Only 0 is valid for L2_MOD_FIFO\n" 67 " TH : Only 0, 4 and 8 are valid for L2_MOD_FIFO\n" 68 "RateCalcIn=<int> - Duration for rate calculation; default is 10 s\n" 69 "TestType=<1/0> - 0: feature test; 1: performance test (default)\n" 70 "Debug=<1/0> - Debug mode with verbose info\n" 71 ; 72 #endif 73 74 75 static void 76 fifodma_soc_chk_fifodma_status(int unit, uint32 vchan, uint32 cmc, uint32 ch) 77 { 78 uint32 rval; 79 80 #ifdef BCM_CMICX_SUPPORT 81 if (soc_feature(unit, soc_feature_cmicx)) { 82 { 83 uint32 rval, hostmem_timeout, hostmem_overflow, done, error; 84 85 soc_fifodma_masks_get(unit, &hostmem_timeout, &hostmem_overflow, 86 &error, &done); 87 soc_fifodma_status_get(unit, ch, &rval); 88 if (rval & done) { 89 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 90 "FIFO DMA engine terminated for cmc[%d]:ch[%d]\n"), 91 cmc, ch)); 92 if (rval & error) { 93 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 94 "FIFO DMA engine encountered error: [0x%x]\n"), rval)); 95 } 96 } 97 } 98 } 99 #endif 100 if (soc_feature(unit, soc_feature_cmicm)) { 101 rval = soc_pci_read(unit, CMIC_CMCx_FIFO_CHy_RD_DMA_STAT_OFFSET(cmc, ch)); 102 if (soc_reg_field_get(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STATr, rval, 103 DONEf)) { 104 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 105 "FIFO DMA engine terminated for cmc[%d]:ch[%d]\n"), cmc, ch)); 106 if (soc_reg_field_get(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STATr, rval, 107 ERRORf)) { 108 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 109 "FIFO DMA engine encountered error: [0x%x]\n"), rval)); 110 } 111 } 112 } 113 } 114 115 static void 116 fifodma_soc_set_cmc_ch(int unit, uint32 vchan) 117 { 118 #ifdef BCM_CMICX_SUPPORT 119 if (soc_feature(unit, soc_feature_cmicx)) { 120 fifodma_data.cmc = vchan / CMICX_N_DMA_CHAN; 121 fifodma_data.ch = vchan % CMICX_N_DMA_CHAN; 122 } 123 #endif 124 if (soc_feature(unit, soc_feature_cmicm)) { 125 fifodma_data.cmc = vchan / N_DMA_CHAN; 126 fifodma_data.ch = vchan % N_DMA_CHAN; 127 } 128 } 129 130 static void 131 fifodma_soc_remap_addr(int unit, uint32 cmc) 132 { 133 uint32 addr_remap; 134 135 if (soc_feature(unit, soc_feature_cmicm) && cmc != 0) { 136 addr_remap = soc_pci_read(unit, 137 CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(0)); 138 (void) soc_pci_write(unit, 139 CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc), addr_remap); 140 addr_remap = soc_pci_read(unit, 141 CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(0)); 142 (void) soc_pci_write(unit, 143 CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc), addr_remap); 144 addr_remap = soc_pci_read(unit, 145 CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(0)); 146 (void) soc_pci_write(unit, 147 CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc), addr_remap); 148 if (SOC_REG_IS_VALID(unit, CMIC_CMC0_HOSTMEM_ADDR_REMAP_3r)) { 149 addr_remap = soc_pci_read(unit, 150 CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(0)); 151 (void) soc_pci_write(unit, 152 CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc), addr_remap); 153 } 154 } 155 } 156 157 static void 158 fifodma_parse_test_params(int unit, args_t* a) 159 { 160 parse_table_t parse_table_fifodma_test; 161 162 parse_table_init(unit, &parse_table_fifodma_test); 163 parse_table_add(&parse_table_fifodma_test, "VChan", PQ_INT|PQ_DFL, 0, 164 &(fifodma_data.param_vchan), NULL); 165 parse_table_add(&parse_table_fifodma_test, "RateCalcInt", PQ_INT|PQ_DFL, 0, 166 &(fifodma_data.param_rate_calc_interval), NULL); 167 parse_table_add(&parse_table_fifodma_test, "TestType", PQ_INT|PQ_DFL, 0, 168 &(fifodma_data.param_test_type), NULL); 169 parse_table_add(&parse_table_fifodma_test, "Debug", PQ_INT|PQ_DFL, 0, 170 &(fifodma_data.param_debug), NULL); 171 172 if (parse_arg_eq(a, &parse_table_fifodma_test) < 0 || ARG_CNT(a) != 0) { 173 test_error(unit, "%s: Invalid option: %s\n", 174 ARG_CMD(a), ARG_CUR(a) ? ARG_CUR(a) : "*"); 175 fifodma_data.test_fail = 1; 176 fifodma_data.bad_input = 1; 177 test_msg("%s", fd_test_usage); 178 parse_arg_eq_done(&parse_table_fifodma_test); 179 return; 180 } 181 182 /* Note: 183 * The channel number for L2_MOD_FIFO is hard coded in Hardware 184 * -- TD3: Only 0 is valid for L2_MOD_FIFO 185 * -- TH : Only 0, 4 and 8 are valid for L2_MOD_FIFO 186 */ 187 if (fifodma_data.param_vchan >= SOC_DCHAN_NUM(unit)) { 188 fifodma_data.param_vchan = FIFODMA_PARAM_VCHAN_DEFAULT; 189 } 190 191 cli_out("\n ------------- PRINTING TEST PARAMS ------------------"); 192 cli_out("\nVChan = %0d", fifodma_data.param_vchan); 193 cli_out("\nRateCalcInt = %0d", fifodma_data.param_rate_calc_interval); 194 cli_out("\nTestType = %0d", fifodma_data.param_test_type); 195 cli_out("\nDebug = %0d", fifodma_data.param_debug); 196 cli_out("\n -----------------------------------------------------"); 197 } 198 199 static void 200 fifodma_debug_print_fifo_info(int unit, char *msg) 201 { 202 uint64 wr_ptr, rd_ptr; 203 int num_entries; 204 uint32 vchan = fifodma_data.param_vchan; 205 206 if (fifodma_data.param_debug) { 207 (void) soc_mem_fifo_dma_get_num_entries(unit, vchan, &num_entries); 208 (void) soc_reg_get(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, (&wr_ptr)); 209 (void) soc_reg_get(unit, L2_MOD_FIFO_RD_PTRr, 0, 0, (&rd_ptr)); 210 cli_out("\n[%s] valid_entries %0d", msg, num_entries); 211 cli_out("\n[%s] wr_ptr %0d", msg, (uint32) COMPILER_64_LO(wr_ptr)); 212 cli_out("\n[%s] wr_ptr %0d", msg, (uint32) COMPILER_64_LO(rd_ptr)); 213 } 214 } 215 216 static void 217 fifodma_fill_l2_mod_fifo(int unit, unsigned int num_entries) 218 { 219 uint64 wr_ptr, rd_ptr; 220 unsigned int i, j; 221 unsigned int *wr_data = NULL; 222 uint64 zero_64; 223 wr_data = (unsigned int *) soc_cm_salloc(unit, 224 fifodma_data.fifo_width, "wr_data"); 225 if(!wr_data) { 226 cli_out("\nError in allocating memory for wr_data"); 227 return; 228 } 229 230 COMPILER_64_ZERO(zero_64); 231 (void) soc_reg_set(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, zero_64); 232 (void) soc_reg_set(unit, L2_MOD_FIFO_RD_PTRr, 0, 0, zero_64); 233 sal_sleep(2); 234 (void) soc_reg_get(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, (&wr_ptr)); 235 (void) soc_reg_get(unit, L2_MOD_FIFO_RD_PTRr, 0, 0, (&rd_ptr)); 236 fifodma_debug_print_fifo_info(unit, "before filling"); 237 238 for (i = 0; i < num_entries; i++) { 239 for (j = 0; j < fifodma_data.fifo_width; j++) { 240 /* coverity[dont_call : FALSE] */ 241 wr_data[j] = sal_rand(); 242 } 243 (void) soc_mem_write(unit, L2_MOD_FIFOm, COPYNO_ALL, i, wr_data); 244 COMPILER_64_ADD_32(wr_ptr, 0x1); 245 } 246 (void) soc_reg_set(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, wr_ptr); 247 fifodma_debug_print_fifo_info(unit, "after filling"); 248 249 soc_cm_sfree(unit, (void *)wr_data); 250 } 251 252 #define BSAND_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0x00ff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24))) 253 254 static unsigned int 255 fifodma_chk_data_integrity(int unit, unsigned int* base_addr, 256 unsigned int start_index, unsigned int num_entries) 257 { 258 unsigned int i, j, match = 1; 259 unsigned int fifo_width = fifodma_data.fifo_width; 260 unsigned int *rd_data; 261 volatile unsigned int* exp_data; 262 263 exp_data = base_addr; 264 rd_data = (unsigned int *) soc_cm_salloc(unit, fifo_width, "rd_data"); 265 if(!rd_data) { 266 cli_out("\nError in allocating memory for rd_data"); 267 return 0; 268 } 269 270 for (i = 0; i < num_entries; i++) { 271 (void) soc_mem_read(unit, L2_MOD_FIFOm, COPYNO_ALL, start_index + i, 272 rd_data); 273 for (j = 0; j < fifo_width; j++) { 274 #if 0 275 /* convert LE to BE */ 276 rd_data[j] = BSAND_BYTE_SWAP(rd_data[j]); 277 #endif 278 if (exp_data[fifo_width * i + j] != rd_data[j]) { 279 cli_out("\nIndex %0d mismatched: Exp: 0x%x, Act: 0x%x", 280 start_index + i, 281 exp_data[fifo_width * i + j], 282 rd_data[j]); 283 match = 0; 284 } 285 } 286 } 287 soc_cm_sfree(unit, rd_data); 288 289 return(match); 290 } 291 292 static void 293 fifodma_test_feature(int unit) 294 { 295 int match = 0; 296 unsigned int fifo_depth = fifodma_data.fifo_depth; 297 uint32 vchan = fifodma_data.param_vchan; 298 uint32 cmc = fifodma_data.cmc; 299 uint32 ch = fifodma_data.ch; 300 unsigned int* host_base = fifodma_data.host_base; 301 302 cli_out("\nFill up L2_MOD_FIFO through SBUS"); 303 soc_mem_fifo_dma_stop(unit, vchan); 304 fifodma_fill_l2_mod_fifo(unit, fifo_depth); 305 fifodma_debug_print_fifo_info(unit, "1"); 306 307 /* start fifo dma */ 308 cli_out("\nfifo_dma_start"); 309 (void) soc_mem_fifo_dma_start(unit, vchan, L2_MOD_FIFOm, COPYNO_ALL, 310 fifo_depth, host_base); 311 fifodma_debug_print_fifo_info(unit, "2"); 312 cli_out("\nSleep 1 second "); 313 sal_sleep(1); 314 fifodma_debug_print_fifo_info(unit, "3"); 315 316 cli_out("\nSet RD_DMA_NUM_OF_ENTRIES_READ_FRM_HOSTMEM"); 317 (void) soc_mem_fifo_dma_set_entries_read(unit, vchan, fifo_depth); 318 fifodma_debug_print_fifo_info(unit, "4"); 319 320 /* check data integrity */ 321 cli_out("\n\nCheck l2_mod_fifo data, addr_base %p, entry_num %d", 322 host_base, fifo_depth); 323 match = fifodma_chk_data_integrity(unit, host_base, 0x0, fifo_depth); 324 325 /* check and clear error */ 326 fifodma_soc_chk_fifodma_status(unit, vchan, cmc, ch); 327 328 /* stop fifo dma */ 329 cli_out("\nfifo_dma_stop"); 330 soc_mem_fifo_dma_stop(unit, vchan); 331 332 if (match == 1) { 333 cli_out("\n\n********** DATA INTEGRITY CHECK PASSED **********\n"); 334 } else { 335 fifodma_data.test_fail = 1; 336 test_error(unit, "\n*ERROR: **** DATA INTEGRITY CHECK FAILED ****\n"); 337 } 338 } 339 340 static void 341 fifodma_test_performance(void* up) 342 { 343 /* int num_valid_entries = 0; */ 344 uint64 wr_ptr, rd_ptr; 345 sal_usecs_t time0, time1; 346 uint32 timeout; 347 int unit = PTR_TO_INT(up); 348 unsigned int fifo_depth = fifodma_data.fifo_depth; 349 uint32 vchan = fifodma_data.param_vchan; 350 uint32 cmc = fifodma_data.cmc; 351 uint32 ch = fifodma_data.ch; 352 unsigned int* host_base = fifodma_data.host_base; 353 354 cli_out("\nFill up L2_MOD_FIFO through SBUS"); 355 soc_mem_fifo_dma_stop(unit, vchan); 356 fifodma_fill_l2_mod_fifo(unit, fifo_depth); 357 fifodma_debug_print_fifo_info(unit, "0"); 358 359 do { 360 fifodma_debug_print_fifo_info(unit, "while_loop_1 a"); 361 362 /* kick off fifo dma */ 363 time0 = sal_time_usecs(); 364 (void) soc_mem_fifo_dma_start(unit, vchan, L2_MOD_FIFOm, COPYNO_ALL, 365 fifo_depth, host_base); 366 367 (void) soc_reg_get(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, (&wr_ptr)); 368 (void) soc_reg_get(unit, L2_MOD_FIFO_RD_PTRr, 0, 0, (&rd_ptr)); 369 time1 = sal_time_usecs(); 370 fifodma_debug_print_fifo_info(unit, "while_loop_1 b"); 371 372 /* check if fifo dma is done */ 373 timeout = FIFODMA_TIMEOUT_DEFAULT; 374 /* while ((num_valid_entries != fifo_depth || 375 wr_ptr != rd_ptr) && 376 (timeout-- > 0)) { */ 377 while ((COMPILER_64_LO(wr_ptr) != COMPILER_64_LO(rd_ptr)) && 378 (timeout-- > 0)) { 379 (void) soc_reg_get(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, (&wr_ptr)); 380 (void) soc_reg_get(unit, L2_MOD_FIFO_RD_PTRr, 0, 0, (&rd_ptr)); 381 time1 = sal_time_usecs(); 382 if (timeout % 2 == 0) { 383 fifodma_debug_print_fifo_info(unit, "while_loop_2"); 384 } 385 sal_usleep(1000); 386 } 387 388 fifodma_debug_print_fifo_info(unit, "while_loop_1 c"); 389 if (fifodma_data.param_debug) { 390 cli_out("\n------------------------------\n"); 391 } 392 393 /* record transfered fifo_drans */ 394 fifodma_data.total_fifo_drains++; 395 fifodma_data.td_acc = SAL_USECS_ADD(fifodma_data.td_acc, 396 SAL_USECS_SUB(time1, time0)); 397 398 /* set RD_DMA_NUM_OF_ENTRIES_READ_FRM_HOSTMEM */ 399 (void) soc_mem_fifo_dma_set_entries_read(unit, vchan, fifo_depth); 400 401 /* check and clear error */ 402 fifodma_soc_chk_fifodma_status(unit, vchan, cmc, ch); 403 404 /* stop fifo dma */ 405 soc_mem_fifo_dma_stop(unit, vchan); 406 407 /* update wr_ptr for next iteration */ 408 (void) soc_reg_get(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, &wr_ptr); 409 COMPILER_64_ADD_32(wr_ptr, fifo_depth); 410 (void) soc_reg_set(unit, L2_MOD_FIFO_WR_PTRr, 0, 0, wr_ptr); 411 } while (fifodma_data.stop_perf_test == 0); 412 413 sal_thread_exit(0); 414 } 415 416 static void 417 fifodma_measure_rate(unsigned int interval_in_seconds) 418 { 419 uint64 drains_cnt_start, drains_cnt_end, byte_transferred; 420 sal_usecs_t td_acc_start, td_acc_end, actual_drain_time; 421 char byte_transferred_str[32]; 422 uint32 byte_per_usec, div1, div2; 423 unsigned int fifo_depth = fifodma_data.fifo_depth; 424 unsigned int fifo_width = fifodma_data.fifo_width; 425 426 cli_out("\nMeasuring data transfer rate over an interval of %0d seconds", 427 interval_in_seconds); 428 429 /* actual transfer time */ 430 COMPILER_64_SET(drains_cnt_start, 0, fifodma_data.total_fifo_drains); 431 td_acc_start = fifodma_data.td_acc; 432 sal_sleep(interval_in_seconds); 433 COMPILER_64_SET(drains_cnt_end, 0, fifodma_data.total_fifo_drains); 434 td_acc_end = fifodma_data.td_acc; 435 actual_drain_time = SAL_USECS_SUB(td_acc_end, td_acc_start); 436 437 /* byte transfered */ 438 COMPILER_64_DELTA(byte_transferred, drains_cnt_start, 439 drains_cnt_end); 440 COMPILER_64_UMUL_32(byte_transferred, fifo_depth); 441 COMPILER_64_UMUL_32(byte_transferred, fifo_width); 442 format_uint64_decimal(byte_transferred_str, byte_transferred, 0); 443 444 /* transfer rate, with accuracy .xxxx */ 445 div1 = (uint32) COMPILER_64_LO(byte_transferred); 446 div2 = (uint32) actual_drain_time; 447 byte_per_usec = _shr_div_exp10(div1, div2, 4); 448 449 cli_out("\n*** Actual draining time = %d us", actual_drain_time); 450 cli_out("\n*** Total bytes transferred = %s Byte", byte_transferred_str); 451 cli_out("\n*** Transfer rate = %0d.%04d Byte/us", 452 byte_per_usec/10000, byte_per_usec%10000); 453 } 454 455 int fifodma_test_init(int unit, args_t *a, void **pa) 456 { 457 int i; 458 459 cli_out("\nCalling fifodma_test_init\n"); 460 if (soc_feature(unit, soc_feature_arl_hashed)) { 461 SOC_IF_ERROR_RETURN(soc_l2x_stop(unit)); 462 } 463 464 /* initialize parameter/variable with default value */ 465 fifodma_data.param_test_type = FIFODMA_PARAM_TEST_TYPE_DEFAULT; 466 fifodma_data.param_rate_calc_interval = FIFODMA_PARAM_RATE_CALC_INT_DEFAULT; 467 fifodma_data.param_vchan = FIFODMA_PARAM_VCHAN_DEFAULT; 468 fifodma_data.param_debug = FIFODMA_PARAM_DEBUG_DEFAULT; 469 470 fifodma_data.fifo_depth = soc_mem_index_count(unit, L2_MOD_FIFOm); 471 fifodma_data.fifo_width = soc_mem_entry_words(unit, L2_MOD_FIFOm); 472 fifodma_data.test_fail = 0; 473 fifodma_data.bad_input = 0; 474 fifodma_data.stop_perf_test = 0; 475 fifodma_data.total_fifo_drains = 0; 476 fifodma_data.cmc = 0; 477 fifodma_data.ch = 0; 478 479 /* parse parameters from cli */ 480 fifodma_parse_test_params(unit, a); 481 if (fifodma_data.bad_input) { 482 goto test_done; 483 } 484 485 /* initialize host memory */ 486 fifodma_data.host_base = (unsigned int*)sal_dma_alloc( 487 fifodma_data.fifo_depth * fifodma_data.fifo_width * 488 sizeof(unsigned int), "HOST_BASE"); 489 for (i = 0; i < (fifodma_data.fifo_depth * fifodma_data.fifo_width); i++) { 490 fifodma_data.host_base[i] = 0x0; 491 } 492 493 /* initialize internal variables */ 494 fifodma_soc_set_cmc_ch(unit, fifodma_data.param_vchan); 495 496 /* address remap for CMICM */ 497 fifodma_soc_remap_addr(unit, fifodma_data.cmc); 498 499 cli_out("\n\nTEST FIFO INFO"); 500 cli_out("\nFIFO name : L2_MOD_FIFOm"); 501 cli_out("\nFIFO depth: %0d", fifodma_data.fifo_depth); 502 cli_out("\nFIFO width: %0d", fifodma_data.fifo_width); 503 cli_out("\n"); 504 505 test_done: 506 return 0; 507 } 508 509 int fifodma_test_cleanup(int unit, void *pa) 510 { 511 if (fifodma_data.bad_input) { 512 goto test_done; 513 } 514 cli_out("\nCalling fifodma_fifoma_test_cleanup\n"); 515 516 test_done: 517 sal_dma_free(fifodma_data.host_base); 518 cli_out("\n"); 519 return 0; 520 } 521 522 int fifodma_test(int unit, args_t *a, void *pa) 523 { 524 sal_thread_t pid_fifodma; 525 int rv = 0; 526 527 if (fifodma_data.bad_input) { 528 goto test_done; 529 } 530 531 if (fifodma_data.param_test_type == FIFODMA_PARAM_TEST_TYPE_DEFAULT) { 532 cli_out("\nDoing FIFO DMA performance test"); 533 pid_fifodma = sal_thread_create("FIFO DMA", 32 * 1024 * 1024, 200, 534 fifodma_test_performance, 535 INT_TO_PTR(unit)); 536 537 sal_usleep(1000000); 538 fifodma_measure_rate(fifodma_data.param_rate_calc_interval); 539 cli_out("\npid_fifodma = %p", pid_fifodma); 540 fifodma_data.stop_perf_test = 1; 541 sal_usleep(100000); 542 } else { 543 cli_out("\nDoing FIFO DMA feature test"); 544 fifodma_test_feature(unit); 545 } 546 547 rv = (fifodma_data.test_fail == 1)? BCM_E_FAIL : BCM_E_NONE; 548 549 test_done: 550 return rv; 551 } 552 553 #endif /* BCM_ESW_SUPPORT && BCM_CMICM_SUPPORT */