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