draco_arltest.c (263468B)
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 * ARL Tests. 8 * 9 * Insert/Lookup/Delete, hashing, bucket overflow tests. 10 */ 11 12 13 #ifdef BCM_ESW_SUPPORT 14 #include <soc/mem.h> 15 #include <soc/hash.h> 16 #include <soc/l2x.h> 17 #include <soc/l3x.h> 18 #include <appl/diag/system.h> 19 #include <appl/test/draco_arltest.h> 20 #include <shared/bsl.h> 21 #include "testlist.h" 22 #include <bcm/init.h> 23 #include <bcm/l2.h> 24 #include <bcm/l3.h> 25 #include <bcm/stack.h> 26 #include <bcm/link.h> 27 #include <bcm_int/esw/firebolt.h> 28 #if defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 29 #include <bcm_int/esw/triumph.h> 30 #endif /* BCM_TRIUMPH_SUPPORT */ 31 #include <appl/diag/progress.h> 32 #if defined(BCM_TRIDENT2_SUPPORT) 33 #include <soc/trident2.h> 34 #endif 35 #if defined(BCM_TRIDENT3_SUPPORT) 36 #include <soc/trident3.h> 37 #endif 38 #if defined(CANCUN_SUPPORT) 39 #include "cancun.h" 40 #endif 41 42 #ifdef BCM_XGS_SWITCH_SUPPORT 43 44 #if defined(BCM_TRIDENT2_SUPPORT) 45 #define SOC_TD2_L2X_BUCKET_SIZE 4 46 #define L2_MAX_BANKS 6 47 #define SOC_TD2_L3X_BUCKET_SIZE 4 48 #define L3_MAX_BANKS 8 49 #endif 50 51 /* 52 * L2 work structure 53 */ 54 55 STATIC draco_l2_test_t dl2_work[SOC_MAX_NUM_DEVICES]; 56 #ifdef INCLUDE_L3 57 STATIC draco_l3_test_t dl3_work[SOC_MAX_NUM_DEVICES]; 58 #endif /* INCLUDE_L3 */ 59 60 sal_mac_addr_t dl_mac_src = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; 61 62 #ifdef BCM_TRIDENT3_SUPPORT 63 STATIC int 64 td3_entry_hash_control_set(int unit, uint32 opt_hash, 65 soc_mem_t mem, uint32 *entry_hash_control) 66 { 67 uint32 tbl_mode = 0; 68 uint32 hash_offset_0 = 0; 69 uint32 hash_offset_1 = 32; 70 71 switch(opt_hash) { 72 case FB_HASH_ZERO: 73 tbl_mode = 1; 74 hash_offset_0 = hash_offset_1 = 48; 75 break; 76 case FB_HASH_CRC32_UPPER: 77 case FB_HASH_CRC32_LOWER: 78 break; 79 case FB_HASH_LSB: 80 tbl_mode = 1; 81 hash_offset_0 = hash_offset_1 = 32; 82 break; 83 case FB_HASH_CRC16_LOWER: 84 case FB_HASH_CRC16_UPPER: 85 break; 86 case FB_HASH_COUNT: 87 default: 88 test_error(unit, "Wrong Hash\n"); 89 return (-1); 90 } 91 soc_mem_field_set(unit, mem, entry_hash_control, 92 HASH_TABLE_TEST_MODEf, &tbl_mode); 93 soc_mem_field_set(unit, mem, entry_hash_control, 94 HASH_OFFSET_DEDICATED_BANK_0f, &hash_offset_0); 95 soc_mem_field_set(unit, mem, entry_hash_control, 96 HASH_OFFSET_DEDICATED_BANK_1f, &hash_offset_1); 97 98 return 0; 99 } 100 #endif 101 102 #ifdef BCM_BRADLEY_SUPPORT 103 STATIC void 104 hbl2_setup(int unit, draco_l2_test_t *dw) 105 { 106 draco_l2_testdata_t *ad; 107 108 109 /* Hash */ 110 ad = &dw->dlp_l2_hash; 111 112 ad->opt_count = soc_mem_index_count(unit, L2Xm); 113 ad->opt_hash = FB_HASH_CRC16_LOWER; 114 ad->hash_count = FB_HASH_COUNT; 115 116 /* Overflow */ 117 ad = &dw->dlp_l2_ov; 118 119 ad->opt_count = 2048; 120 ad->opt_hash = FB_L2_DEFAULT_HASH; 121 ad->hash_count = FB_HASH_COUNT; 122 123 /* Lookup */ 124 ad = &dw->dlp_l2_lu; 125 126 ad->opt_count = soc_mem_index_count(unit, L2Xm); 127 ad->opt_hash = FB_HASH_CRC16_LOWER; 128 ad->hash_count = FB_HASH_COUNT; 129 130 /* Delete by port */ 131 ad = &dw->dlp_l2_dp; 132 133 ad->opt_count = 20; /* 20 GX PORTS */ 134 ad->opt_hash = FB_HASH_CRC16_LOWER; 135 ad->hash_count = FB_HASH_COUNT; 136 137 /* Delete by VLAN */ 138 ad = &dw->dlp_l2_dv; 139 140 ad->opt_count = soc_mem_index_count(unit, VLAN_TABm); 141 ad->opt_hash = FB_HASH_CRC16_LOWER; 142 ad->hash_count = FB_HASH_COUNT; 143 } 144 145 #endif /* BCM_BRADLEY_SUPPORT */ 146 147 #ifdef BCM_FIREBOLT_SUPPORT 148 STATIC void 149 fbl2_setup(int unit, draco_l2_test_t *dw) 150 { 151 draco_l2_testdata_t *ad; 152 153 154 /* Hash */ 155 ad = &dw->dlp_l2_hash; 156 157 ad->opt_count = soc_mem_index_count(unit, L2Xm); 158 ad->opt_hash = FB_HASH_CRC16_LOWER; 159 ad->hash_count = FB_HASH_COUNT; 160 161 /* Overflow */ 162 ad = &dw->dlp_l2_ov; 163 164 ad->opt_count = 2048; 165 ad->opt_hash = FB_L2_DEFAULT_HASH; 166 ad->hash_count = FB_HASH_COUNT; 167 168 /* Lookup */ 169 ad = &dw->dlp_l2_lu; 170 171 ad->opt_count = soc_mem_index_count(unit, L2Xm); 172 ad->opt_hash = FB_HASH_CRC16_LOWER; 173 ad->hash_count = FB_HASH_COUNT; 174 175 /* Delete by port */ 176 ad = &dw->dlp_l2_dp; 177 178 ad->opt_count = 24; /* 24 GE ports + N XE PORTS */ 179 ad->opt_hash = FB_HASH_CRC16_LOWER; 180 ad->hash_count = FB_HASH_COUNT; 181 182 /* Delete by VLAN */ 183 ad = &dw->dlp_l2_dv; 184 185 ad->opt_count = soc_mem_index_count(unit, VLAN_TABm); 186 ad->opt_hash = FB_HASH_CRC16_LOWER; 187 ad->hash_count = FB_HASH_COUNT; 188 } 189 190 #endif /* BCM_FIREBOLT_SUPPORT */ 191 192 #ifdef BCM_TRX_SUPPORT 193 STATIC void 194 trl2_setup(int unit, draco_l2_test_t *dw) 195 { 196 draco_l2_testdata_t *ad; 197 198 /* Hash */ 199 ad = &dw->dlp_l2_hash; 200 201 ad->opt_count = soc_mem_index_count(unit, L2Xm); 202 ad->opt_hash = FB_HASH_CRC16_LOWER; 203 ad->hash_count = FB_HASH_COUNT; 204 205 /* Overflow */ 206 ad = &dw->dlp_l2_ov; 207 208 ad->opt_count = 2048; 209 ad->opt_hash = FB_L2_DEFAULT_HASH; 210 ad->hash_count = FB_HASH_COUNT; 211 212 /* Lookup */ 213 ad = &dw->dlp_l2_lu; 214 215 ad->opt_count = soc_mem_index_count(unit, L2Xm); 216 ad->opt_hash = FB_HASH_CRC16_LOWER; 217 ad->hash_count = FB_HASH_COUNT; 218 219 /* Delete by port */ 220 ad = &dw->dlp_l2_dp; 221 222 ad->opt_count = 49; /* 49 GE ports + N XE PORTS */ 223 ad->opt_hash = FB_HASH_CRC16_LOWER; 224 ad->hash_count = FB_HASH_COUNT; 225 226 /* Delete by VLAN */ 227 ad = &dw->dlp_l2_dv; 228 229 ad->opt_count = soc_mem_index_count(unit, VLAN_TABm); 230 ad->opt_hash = FB_HASH_CRC16_LOWER; 231 ad->hash_count = FB_HASH_COUNT; 232 } 233 234 #endif /* BCM_TRX_SUPPORT */ 235 236 237 STATIC void 238 dl2_setup(int unit, draco_l2_test_t *dw) 239 { 240 draco_l2_testdata_t *ad; 241 242 if (dw->dlw_set_up) { 243 return; 244 } 245 246 dw->dlw_set_up = TRUE; 247 dw->dlw_unit = unit; 248 249 /* Hash */ 250 ad = &dw->dlp_l2_hash; 251 252 ad->unit = unit; 253 ad->opt_count = 8191; 254 ad->opt_verbose = FALSE; 255 ad->opt_reset = TRUE; 256 ad->opt_hash = XGS_HASH_CRC16_LOWER; 257 ad->opt_base_vid = 0; 258 ad->opt_vid_inc = 1; 259 ad->opt_mac_inc = 1; 260 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 261 ad->hash_count = XGS_HASH_COUNT; 262 263 /* Overflow */ 264 ad = &dw->dlp_l2_ov; 265 266 ad->unit = unit; 267 ad->opt_count = 1024; 268 ad->opt_verbose = FALSE; 269 ad->opt_reset = TRUE; 270 ad->opt_hash = DRACO_ARL_DEFAULT_HASH; 271 ad->opt_base_vid = 0; 272 ad->opt_vid_inc = 1; 273 ad->opt_mac_inc = 1; 274 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 275 ad->hash_count = XGS_HASH_COUNT; 276 277 /* Lookup */ 278 ad = &dw->dlp_l2_lu; 279 280 ad->unit = unit; 281 ad->opt_count = 8191; 282 ad->opt_verbose = FALSE; 283 ad->opt_reset = TRUE; 284 ad->opt_hash = XGS_HASH_CRC16_LOWER; 285 ad->opt_base_vid = 0; 286 ad->opt_vid_inc = 1; 287 ad->opt_mac_inc = 1; 288 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 289 ad->hash_count = XGS_HASH_COUNT; 290 291 /* Delete by port */ 292 ad = &dw->dlp_l2_dp; 293 294 ad->unit = unit; 295 ad->opt_count = 12; /* Only 12 relevant ports? */ 296 ad->opt_verbose = FALSE; 297 ad->opt_reset = TRUE; 298 ad->opt_hash = XGS_HASH_CRC16_LOWER; 299 ad->opt_base_vid = 0; 300 ad->opt_vid_inc = 1; 301 ad->opt_mac_inc = 1; 302 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 303 ad->hash_count = XGS_HASH_COUNT; 304 305 /* Delete by VLAN */ 306 ad = &dw->dlp_l2_dv; 307 308 ad->unit = unit; 309 ad->opt_count = 4096; 310 ad->opt_verbose = FALSE; 311 ad->opt_reset = TRUE; 312 ad->opt_hash = XGS_HASH_CRC16_LOWER; 313 ad->opt_base_vid = 0; 314 ad->opt_vid_inc = 1; 315 ad->opt_mac_inc = 1; 316 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 317 ad->hash_count = XGS_HASH_COUNT; 318 319 #ifdef BCM_BRADLEY_SUPPORT 320 /* Bradley adjustments */ 321 if (SOC_IS_HB_GW(unit)) { 322 hbl2_setup(unit, dw); 323 } 324 #endif /* BCM_BRADLEY_SUPPORT */ 325 #ifdef BCM_FIREBOLT_SUPPORT 326 /* Firebolt adjustments */ 327 if (SOC_IS_FB_FX_HX(unit)) { 328 fbl2_setup(unit, dw); 329 } 330 #endif /* BCM_FIREBOLT_SUPPORT */ 331 #ifdef BCM_TRX_SUPPORT 332 /* Triumph adjustments */ 333 if (SOC_IS_TRX(unit)) { 334 trl2_setup(unit, dw); 335 } 336 #endif /* BCM_TRX_SUPPORT */ 337 } 338 339 340 /* 341 * Test initialization routine used for all L2 tests 342 */ 343 344 STATIC int 345 draco_l2_test_init(int unit, draco_l2_testdata_t *ad, args_t *a) 346 { 347 int rv = -1; 348 parse_table_t pt; 349 uint32 hash_read; 350 uint32 l2_aux_hash_control; 351 uint32 l2_table_hash_control; 352 uint32 shared_table_hash_control; 353 #ifdef BCM_TRIDENT3_SUPPORT 354 l2_entry_hash_control_entry_t l2_entry_hash_control; 355 uft_shared_banks_control_entry_t shared_entry_hash_control; 356 #endif 357 358 359 parse_table_init(unit, &pt); 360 361 parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL); 362 parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL); 363 parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL); 364 parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL); 365 parse_table_add(&pt, "BaseVID", PQ_INT|PQ_DFL, 0, &ad->opt_base_vid, NULL); 366 parse_table_add(&pt, "VidIncrement", PQ_INT|PQ_DFL, 0, 367 &ad->opt_vid_inc, NULL); 368 parse_table_add(&pt, "BaseMac", PQ_DFL|PQ_MAC, 0, 369 &ad->opt_base_mac, NULL); 370 parse_table_add(&pt, "MacIncrement", PQ_INT|PQ_DFL, 0, 371 &ad->opt_mac_inc, NULL); 372 373 /* Test the obvious parsings before wasting time with malloc */ 374 if (parse_arg_eq(a, &pt) < 0) { 375 test_error(unit, 376 "%s: Error: Invalid option: %s\n", ARG_CMD(a), 377 ARG_CUR(a) ? ARG_CUR(a) : "*"); 378 goto done; 379 } 380 381 if (ad->opt_count < 1) { 382 test_error(unit, "Illegal count %d\n", ad->opt_count); 383 goto done; 384 } 385 386 if (ad->opt_hash >= ad->hash_count) { 387 test_error(unit, "Illegal hash selection %d\n", ad->opt_hash); 388 goto done; 389 } 390 391 if (ad->opt_base_vid >= (1 << 12)) { 392 test_error(unit, "Out of range VLAN ID selection %d\n", 393 ad->opt_base_vid); 394 goto done; 395 } 396 397 /* 398 * Re-initialize chip to ensure ARL and software ARL table are clear 399 * at start of test. 400 */ 401 402 if (ad->opt_reset) { 403 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0)); 404 if (soc_reset_init(unit) < 0) { 405 test_error(unit, "SOC initialization failed\n"); 406 goto done; 407 } 408 409 #if defined(CANCUN_SUPPORT) 410 if (soc_cancun_pre_misc_init_load(unit) < 0) { 411 test_error(unit, "CMH/CCH/CEH load failed"); 412 goto done; 413 } 414 #endif 415 416 if (soc_misc_init(unit) < 0) { 417 test_error(unit, "ARL initialization failed\n"); 418 goto done; 419 } 420 421 #if defined(CANCUN_SUPPORT) 422 if (soc_cancun_post_misc_init_load(unit) < 0) { 423 test_error(unit, "CIH/CFH load failed"); 424 goto done; 425 } 426 #endif 427 428 if (soc_mmu_init(unit) < 0) { 429 test_error(unit, "MMU initialization failed\n"); 430 goto done; 431 } 432 433 if (SOC_FUNCTIONS(unit)->soc_age_timer_set(unit, 0, 0) < 0) { 434 test_error(unit, "Could not disable age timers\n"); 435 goto done; 436 } 437 438 if (mbcm_init(unit) < 0) { /* Needed for "delete by" tests */ 439 test_error(unit, "mBCM initialization failed\n"); 440 goto done; 441 } 442 443 } 444 445 if (READ_HASH_CONTROLr(unit, &hash_read) < 0) { 446 test_error(unit, "Hash select read failed\n"); 447 goto done; 448 } 449 450 ad->save_hash_control = hash_read; 451 452 hash_read = ad->opt_hash; 453 454 #ifdef BCM_XGS3_SWITCH_SUPPORT 455 if (SOC_IS_XGS3_SWITCH(unit)) { 456 hash_read = ad->save_hash_control; 457 soc_reg_field_set(unit, HASH_CONTROLr, &hash_read, 458 L2_AND_VLAN_MAC_HASH_SELECTf, ad->opt_hash); 459 } 460 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 461 462 if (WRITE_HASH_CONTROLr(unit, hash_read) < 0) { 463 test_error(unit, "Hash select setting failed\n"); 464 goto done; 465 } 466 467 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 468 #ifdef BCM_TRIDENT3_SUPPORT 469 if (soc_mem_is_valid(unit, L2_ENTRY_HASH_CONTROLm)) { 470 if (soc_mem_read(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY, 471 0, (void*)&l2_entry_hash_control) < 0) { 472 test_error(unit, "L2 Entry hash control read failed\n"); 473 goto done; 474 } 475 ad->save_l2_entry_hash_control = l2_entry_hash_control; 476 rv = td3_entry_hash_control_set(unit, ad->opt_hash, 477 L2_ENTRY_HASH_CONTROLm, 478 (uint32 *)&l2_entry_hash_control); 479 if (rv < 0) { 480 test_error(unit, "Hash Control write failed"); 481 goto done; 482 } 483 if (soc_mem_write(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY, 484 0, (void*)&l2_entry_hash_control) < 0) { 485 test_error(unit, "L2 Entry hash control setting failed\n"); 486 goto done; 487 } 488 if (soc_mem_read(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY, 489 0, (void*)&shared_entry_hash_control) < 0) { 490 test_error(unit, "Shared Entry hash control read failed\n"); 491 goto done; 492 } 493 ad->save_shared_entry_hash_control = shared_entry_hash_control; 494 } else 495 #endif /* BCM_TRIDENT3_SUPPORT */ 496 { 497 if (READ_L2_TABLE_HASH_CONTROLr(unit, &l2_table_hash_control) < 0) { 498 test_error(unit, "L2 Table hash control read failed\n"); 499 goto done; 500 } 501 ad->save_l2_table_hash_control = l2_table_hash_control; 502 soc_reg_field_set(unit, L2_TABLE_HASH_CONTROLr, 503 &l2_table_hash_control, HASH_ZERO_OR_LSBf, 1); 504 if (WRITE_L2_TABLE_HASH_CONTROLr(unit, l2_table_hash_control) < 0) { 505 test_error(unit, "L2 Table hash control setting failed\n"); 506 goto done; 507 } 508 if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) 509 { 510 if (READ_SHARED_TABLE_HASH_CONTROLr(unit, &shared_table_hash_control) < 0) { 511 test_error(unit, "Shared Table hash control read failed\n"); 512 goto done; 513 } 514 ad->save_shared_table_hash_control = shared_table_hash_control; 515 } 516 } 517 } else { 518 if (soc_feature(unit, soc_feature_dual_hash)) { 519 if (READ_L2_AUX_HASH_CONTROLr(unit, &l2_aux_hash_control) < 0) { 520 test_error(unit, "L2 AUX hash control read failed\n"); 521 goto done; 522 } 523 524 ad->save_l2_aux_hash_control = l2_aux_hash_control; 525 526 soc_reg_field_set(unit, L2_AUX_HASH_CONTROLr, 527 &l2_aux_hash_control, HASH_SELECTf, FB_HASH_LSB); 528 529 if ((SAL_BOOT_SIMULATION) && (!SAL_BOOT_QUICKTURN)) { 530 soc_reg_field_set(unit, L2_AUX_HASH_CONTROLr, 531 &l2_aux_hash_control, ENABLEf, 0); 532 } 533 534 if (WRITE_L2_AUX_HASH_CONTROLr(unit, l2_aux_hash_control) < 0) { 535 test_error(unit, "L2 AUX hash control setting failed\n"); 536 goto done; 537 } 538 } 539 } 540 541 rv = 0; 542 543 done: 544 545 parse_arg_eq_done(&pt); 546 return rv; 547 } 548 549 /* Individual test init wrappers */ 550 int 551 draco_l2_hash_test_init(int unit, args_t *a, void **p) 552 { 553 draco_l2_test_t *dw = &dl2_work[unit]; 554 draco_l2_testdata_t *dp = &dw->dlp_l2_hash; 555 int rv; 556 557 dl2_setup(unit, dw); 558 559 /* Set working data to hash */ 560 dw->dlp_l2_cur = dp; 561 562 if ((rv = draco_l2_test_init(unit, dp, a)) < 0) { 563 return rv; 564 } else { 565 *p = dp; 566 } 567 568 return 0; 569 } 570 571 int 572 draco_l2_ov_test_init(int unit, args_t *a, void **p) 573 { 574 draco_l2_test_t *dw = &dl2_work[unit]; 575 draco_l2_testdata_t *dp = &dw->dlp_l2_ov; 576 int rv; 577 578 dl2_setup(unit, dw); 579 580 /* Set working data to overflow */ 581 dw->dlp_l2_cur = dp; 582 583 if ((rv = draco_l2_test_init(unit, dp, a)) < 0) { 584 return rv; 585 } else { 586 *p = dp; 587 } 588 589 return 0; 590 } 591 592 int 593 draco_l2_lu_test_init(int unit, args_t *a, void **p) 594 { 595 draco_l2_test_t *dw = &dl2_work[unit]; 596 draco_l2_testdata_t *dp = &dw->dlp_l2_lu; 597 int rv; 598 599 dl2_setup(unit, dw); 600 601 /* Set working data to lookup */ 602 dw->dlp_l2_cur = dp; 603 604 if ((rv = draco_l2_test_init(unit, dp, a)) < 0) { 605 return rv; 606 } else { 607 *p = dp; 608 } 609 610 return 0; 611 } 612 613 int 614 draco_l2_dp_test_init(int unit, args_t *a, void **p) 615 { 616 draco_l2_test_t *dw = &dl2_work[unit]; 617 draco_l2_testdata_t *dp = &dw->dlp_l2_dp; 618 int rv; 619 620 dl2_setup(unit, dw); 621 622 /* Set working data to delete by port */ 623 dw->dlp_l2_cur = dp; 624 625 if ((rv = draco_l2_test_init(unit, dp, a)) < 0) { 626 return rv; 627 } else { 628 *p = dp; 629 } 630 631 return 0; 632 } 633 634 int 635 draco_l2_dv_test_init(int unit, args_t *a, void **p) 636 { 637 draco_l2_test_t *dw = &dl2_work[unit]; 638 draco_l2_testdata_t *dp = &dw->dlp_l2_dv; 639 int rv; 640 641 dl2_setup(unit, dw); 642 643 /* Set working data to delete by VLAN */ 644 dw->dlp_l2_cur = dp; 645 646 if ((rv = draco_l2_test_init(unit, dp, a)) < 0) { 647 return rv; 648 } else { 649 *p = dp; 650 } 651 652 return 0; 653 } 654 655 /* 656 * Utility routines for ARL testing 657 */ 658 659 void 660 draco_l2_time_start(draco_l2_testdata_t *ad) 661 { 662 ad->tm = SAL_TIME_DOUBLE(); 663 } 664 665 void 666 draco_l2_time_end(draco_l2_testdata_t *ad) 667 { 668 ad->tm = SAL_TIME_DOUBLE() - ad->tm; 669 if (ad->opt_verbose) { 670 cli_out(" time: %"COMPILER_DOUBLE_FORMAT" msec\n", ad->tm * 1000); 671 } 672 } 673 674 675 #if defined(BCM_FIREBOLT_SUPPORT) 676 static int 677 draco_l2_bucket_search(int unit, draco_l2_testdata_t *ad, int bucket, 678 l2x_entry_t *expect) 679 { 680 l2x_entry_t chip_entry; 681 int ix, mem_table_index; 682 int rv = -1; /* Assume failed unless we find it */ 683 int validf; 684 int bucket_size = SOC_L2X_BUCKET_SIZE; 685 validf = VALIDf; 686 687 if (soc_mem_field_valid(unit, L2Xm, BASE_VALIDf)) { 688 validf = BASE_VALIDf; 689 } 690 691 /* Use soc_*_hash_bank_info_get() to make the test generic */ 692 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 693 bucket_size = 4; 694 } 695 /* 696 #if defined(BCM_MONTEREY_SUPPORT) 697 if (SOC_IS_MONTEREY(unit)) { 698 bucket_size = 2; 699 } 700 #endif 701 */ 702 for (ix = 0; ix < bucket_size; ix++) { 703 mem_table_index = (bucket * bucket_size) + ix; 704 705 if (soc_mem_read(unit, L2Xm, MEM_BLOCK_ANY, 706 mem_table_index, &chip_entry) < 0) { 707 test_error(unit, 708 "Read ARL failed at bucket %d, offset %d\n", 709 bucket, ix); 710 break; 711 } 712 713 if (!soc_L2Xm_field32_get(unit, &chip_entry, validf)) { 714 /* Valid bit unset, entry blank */ 715 continue; 716 } 717 718 if (soc_mem_compare_key(unit, L2Xm, expect, &chip_entry) == 0) { 719 /* Found the matching entry */ 720 rv = 0; 721 break; 722 } 723 } 724 725 return rv; 726 } 727 728 /* 729 * Test of L2X hashing 730 * 731 * This test tries a number of keys against one of the hashing functions, 732 * checking a software hash against the hardware hash, then searching the 733 * bucket to find the entry after inserting. 734 */ 735 int 736 fb_l2_test_hash(int unit, args_t *a, void *p) 737 { 738 draco_l2_testdata_t *ad = p; 739 l2x_entry_t entry; 740 int r, rv = 0; 741 int soft_bucket; 742 int ix; 743 int hash = ad->opt_hash; 744 uint8 key[XGS_HASH_KEY_SIZE]; 745 int iterations; 746 bcm_l2_addr_t addr; 747 int vid_inc = ad->opt_vid_inc; 748 int mac_inc = ad->opt_mac_inc; 749 #ifdef BCM_TRIUMPH_SUPPORT 750 int ext_index_max = -1; 751 #endif /* BCM_TRIUMPH_SUPPORT */ 752 753 COMPILER_REFERENCE(a); 754 755 #ifdef BCM_TRIUMPH_SUPPORT 756 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 757 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 758 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 759 } 760 #endif /* BCM_TRIUMPH_SUPPORT */ 761 762 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 763 764 if (ad->opt_verbose) { 765 cli_out("Starting ARL hash test\n"); 766 } 767 768 iterations = ad->opt_count; 769 770 for (ix = 0; ix < iterations; ix++) { 771 #ifdef BCM_TRX_SUPPORT 772 if (SOC_IS_TRX(unit)) { 773 int num_bits; 774 775 _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE); 776 num_bits = soc_tr_l2x_base_entry_to_key(unit, &entry, key); 777 soft_bucket = soc_tr_l2x_hash(unit, hash, num_bits, &entry, key); 778 } else 779 #endif /* BCM_TRX_SUPPORT */ 780 { 781 _bcm_fb_l2_to_l2x(unit, &entry, &addr); 782 soc_draco_l2x_base_entry_to_key(unit, &entry, key); 783 soft_bucket = soc_fb_l2_hash(unit, hash, key); 784 } 785 786 if (ad->opt_verbose) { 787 cli_out("Inserting "); 788 soc_mem_entry_dump(unit, L2Xm, &entry, BSL_LSS_CLI); 789 cli_out("\n"); 790 cli_out("into bucket 0x%x\n", soft_bucket); 791 } 792 793 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 794 if (r == SOC_E_FULL) { 795 /* Bucket overflow, just pass on */ 796 goto incr; 797 } else { 798 test_error(unit, 799 "ARL insert failed at bucket %d\n", soft_bucket); 800 rv = -1; 801 goto done; 802 } 803 } 804 805 /* Now we search for the entry */ 806 807 /* Only do a quick check vs. expected bucket here */ 808 if (draco_l2_bucket_search(unit, ad, soft_bucket, &entry) < 0) { 809 test_error(unit, 810 "ARL entry with key " 811 "0x%02x%02x%02x%02x%02x%02x%02x%01x " 812 "not found in predicted bucket %d\n", 813 key[7], key[6], key[5], key[4], 814 key[3], key[2], key[1], (key[0] >> 4) & 0xf, 815 soft_bucket); 816 } 817 818 if (bcm_l2_addr_delete(unit, addr.mac, addr.vid) < 0) { 819 test_error(unit, "ARL delete failed at bucket %d\n", 820 soft_bucket); 821 rv = -1; 822 goto done; 823 } 824 825 incr: 826 addr.vid += vid_inc; 827 if (addr.vid > FB_L2_VID_MAX) { 828 addr.vid = 1; 829 } 830 increment_macaddr(addr.mac, mac_inc); 831 } 832 833 done: 834 #ifdef BCM_TRIUMPH_SUPPORT 835 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 836 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 837 } 838 #endif /* BCM_TRIUMPH_SUPPORT */ 839 return rv; 840 } 841 842 /* 843 * Test of ARL overflow behavior 844 * 845 * This test fills each bucket of the ARL, then inserts another entry to see 846 * that the last entry fails to insert. 847 */ 848 849 int 850 fb_l2_test_ov(int unit, args_t *a, void *p) 851 { 852 draco_l2_testdata_t *ad = p; 853 l2x_entry_t entry, result, entry_tmp[SOC_L2X_BUCKET_SIZE]; 854 int ix, jx, r, idx, rv = 0; 855 int bucket = 0; 856 uint32 hash = ad->opt_hash; 857 bcm_l2_addr_t addr, addr_tmp; 858 int vid_inc = ad->opt_vid_inc; 859 int iter = ad->opt_count; 860 uint8 key[XGS_HASH_KEY_SIZE]; 861 #ifdef BCM_TRIUMPH_SUPPORT 862 int ext_index_max = -1; 863 #endif /* BCM_TRIUMPH_SUPPORT */ 864 865 COMPILER_REFERENCE(a); 866 867 #ifdef BCM_TRIUMPH_SUPPORT 868 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 869 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 870 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 871 } 872 #endif /* BCM_TRIUMPH_SUPPORT */ 873 874 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 875 876 if (hash != FB_HASH_LSB) { 877 if (ad->opt_verbose) { 878 cli_out("Resetting hash selection to LSB\n"); 879 } 880 881 hash = ad->save_hash_control; 882 soc_reg_field_set(unit, HASH_CONTROLr, &hash, 883 L2_AND_VLAN_MAC_HASH_SELECTf, FB_HASH_LSB); 884 885 if (WRITE_HASH_CONTROLr(unit, hash) < 0) { 886 test_error(unit, "Hash select setting failed\n"); 887 goto done; 888 } 889 890 ad->opt_hash = hash = FB_HASH_LSB; 891 } 892 893 if (iter > soc_mem_index_count(unit, L2Xm)) { 894 iter = soc_mem_index_count(unit, L2Xm); 895 } 896 897 while (iter--) { 898 for (ix = 0; ix < SOC_L2X_BUCKET_SIZE; ix++) { 899 #ifdef BCM_TRX_SUPPORT 900 if (SOC_IS_TRX(unit)) { 901 _bcm_tr_l2_to_l2x(unit, &(entry_tmp[ix]), &addr, TRUE); 902 903 if (ix == 0) { 904 int num_bits; 905 906 num_bits = soc_tr_l2x_base_entry_to_key 907 (unit, &(entry_tmp[ix]), key); 908 bucket = soc_tr_l2x_hash(unit, hash, num_bits, 909 &(entry_tmp[ix]), key); 910 911 if (ad->opt_verbose) { 912 cli_out("Filling bucket %d\n", bucket); 913 } 914 } 915 } else 916 #endif /* BCM_TRX_SUPPORT */ 917 { 918 _bcm_fb_l2_to_l2x(unit, &(entry_tmp[ix]), &addr); 919 920 if (ix == 0) { 921 soc_draco_l2x_base_entry_to_key(unit, &(entry_tmp[ix]), key); 922 bucket = soc_fb_l2_hash(unit, hash, key); 923 924 if (ad->opt_verbose) { 925 cli_out("Filling bucket %d\n", bucket); 926 } 927 } 928 } 929 930 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 931 if (r == SOC_E_FULL) { 932 /* Already full, stop wasting time */ 933 break; 934 } else { 935 test_error(unit, 936 "ARL insert failed at bucket %d\n", bucket); 937 rv = -1; 938 goto done; 939 } 940 } 941 942 /* key for LSB is the MAC address, so we must keep it constant */ 943 addr.vid += vid_inc; 944 if (addr.vid > DRACO_L2_VID_MAX) { 945 addr.vid = 1; 946 } 947 } 948 949 if (ad->opt_verbose) { 950 cli_out("Inserting %dth entry in bucket %d, should fail\n", 951 (SOC_L2X_BUCKET_SIZE + 1), bucket); 952 } 953 954 #ifdef BCM_TRX_SUPPORT 955 if (SOC_IS_TRX(unit)) { 956 _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE); 957 } else 958 #endif /* BCM_TRX_SUPPORT */ 959 { 960 _bcm_fb_l2_to_l2x(unit, &entry, &addr); 961 } 962 963 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 964 if (r != SOC_E_FULL) { 965 test_error(unit, 966 "ARL insert failed\n"); 967 rv = -1; 968 goto done; 969 } 970 } else { 971 test_error(unit, "ARL insert to full bucket succeeded\n"); 972 rv = -1; 973 goto done; 974 } 975 976 if (ad->opt_verbose) { 977 cli_out("Verifying entries present\n"); 978 } 979 980 /* Verify bucket contains our added entries */ 981 for (jx = 0; jx < ix; jx++) { 982 if (draco_l2_bucket_search(unit, ad, bucket, 983 &(entry_tmp[jx])) < 0) { 984 test_error(unit, "ARL entry missing at bucket %d\n", bucket); 985 rv = -1; 986 goto done; 987 } 988 if (soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &idx, 989 &entry_tmp[jx], &result, 0) < 0) { 990 test_error(unit, "ARL entry missing at bucket %d\n", bucket); 991 rv = -1; 992 goto done; 993 } 994 if (bucket != (idx / SOC_L2X_BUCKET_SIZE)) { 995 test_error(unit, "ARL entry inserted into wrong bucket" 996 " Expected %d Actual %d\n", bucket, idx); 997 rv = -1; 998 goto done; 999 } 1000 } 1001 1002 if (ad->opt_verbose) { 1003 cli_out("Cleaning bucket %d\n", bucket); 1004 } 1005 1006 /* Remove the entries that we added */ 1007 for (jx = 0; jx < ix; jx++) { 1008 #ifdef BCM_TRX_SUPPORT 1009 if (SOC_IS_TRX(unit)) { 1010 _bcm_tr_l2_from_l2x(unit, &addr_tmp, &(entry_tmp[jx])); 1011 } else 1012 #endif /* BCM_TRX_SUPPORT */ 1013 { 1014 _bcm_fb_l2_from_l2x(unit, &addr_tmp, &(entry_tmp[jx])); 1015 } 1016 if (bcm_l2_addr_delete(unit, addr_tmp.mac, addr_tmp.vid) < 0) { 1017 test_error(unit, "ARL delete failed at bucket %d\n", bucket); 1018 rv = -1; 1019 goto done; 1020 } 1021 } 1022 1023 /* We want the increment to change buckets by one */ 1024 increment_macaddr(addr.mac, 1); 1025 } 1026 1027 done: 1028 #ifdef BCM_TRIUMPH_SUPPORT 1029 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1030 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 1031 } 1032 #endif /* BCM_TRIUMPH_SUPPORT */ 1033 return rv; 1034 } 1035 1036 /* 1037 * Test of ARL lookup 1038 * 1039 * This test loops a given number of times. It inserts a single ARL 1040 * entry, looks up the ARL entry, and deletes the ARL entry. 1041 * It is possible to run this test while heavy switching is going on. 1042 */ 1043 1044 int 1045 fb_l2_test_lu(int unit, args_t *a, void *p) 1046 { 1047 draco_l2_testdata_t *ad = p; 1048 l2x_entry_t entry, entry_tmp; 1049 int i, r, rv = -1; 1050 int found_times, bucket_full_times; 1051 int index; 1052 bcm_l2_addr_t addr; 1053 int vid_inc = ad->opt_vid_inc; 1054 int mac_inc = ad->opt_mac_inc; 1055 #ifdef BCM_TRIUMPH_SUPPORT 1056 int ext_index_max = -1; 1057 #endif /* BCM_TRIUMPH_SUPPORT */ 1058 1059 COMPILER_REFERENCE(a); 1060 1061 if (! soc_feature(unit, soc_feature_l2_lookup_cmd)) { 1062 test_error(unit, "L2 lookup not supported by chip (unit %d)\n", unit); 1063 return -1; 1064 } 1065 1066 #ifdef BCM_TRIUMPH_SUPPORT 1067 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1068 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 1069 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 1070 } 1071 #endif /* BCM_TRIUMPH_SUPPORT */ 1072 1073 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 1074 1075 draco_l2_time_start(ad); 1076 1077 found_times = 0; 1078 bucket_full_times = 0; 1079 1080 for (i = 1; i <= ad->opt_count; i++) { 1081 1082 #ifdef BCM_TRX_SUPPORT 1083 if (SOC_IS_TRX(unit)) { 1084 _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE); 1085 } else 1086 #endif /* BCM_TRX_SUPPORT */ 1087 { 1088 _bcm_fb_l2_to_l2x(unit, &entry, &addr); 1089 } 1090 1091 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 1092 if (r == SOC_E_FULL) { 1093 /* Bucket overflow, just pass on */ 1094 bucket_full_times++; 1095 goto inc; 1096 } else { 1097 test_error(unit, 1098 "ARL insert failed on loop %d: %s\n", 1099 i, soc_errmsg(r)); 1100 break; 1101 } 1102 } 1103 1104 if ((r = soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &index, 1105 &entry, &entry_tmp, 0)) < 0) { 1106 test_error(unit, 1107 "ARL lookup failure on loop %d: %s\n", 1108 i, soc_errmsg(r)); 1109 break; 1110 } else { 1111 found_times++; 1112 } 1113 1114 if ((r = bcm_l2_addr_delete(unit, addr.mac, addr.vid)) < 0) { 1115 test_error(unit, 1116 "ARL delete failed on loop %d: %s\n", 1117 i, soc_errmsg(r)); 1118 break; 1119 } 1120 1121 if ((r = soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &index, 1122 &entry, &entry_tmp, 0)) < 0) { 1123 if (r != SOC_E_NOT_FOUND) { 1124 test_error(unit, 1125 "ARL lookup failure on loop %d: %s\n", 1126 i, soc_errmsg(r)); 1127 break; 1128 } 1129 /* else, OK */ 1130 } else { 1131 test_error(unit, 1132 "ARL lookup succeeded after delete on loop %d\n", i); 1133 break; 1134 } 1135 1136 inc: 1137 addr.vid += vid_inc; 1138 if (addr.vid > DRACO_L2_VID_MAX) { 1139 addr.vid = 1; 1140 } 1141 increment_macaddr(addr.mac, mac_inc); 1142 } 1143 1144 draco_l2_time_end(ad); 1145 1146 if (i > ad->opt_count) { /* All iterations passed */ 1147 if ((bucket_full_times + found_times) != ad->opt_count) { 1148 test_error(unit, 1149 "Lookup succeeded only %d times out of %d\n", 1150 found_times, ad->opt_count); 1151 } else { 1152 rv = 0; /* Test passed */ 1153 1154 if (ad->opt_verbose) { 1155 cli_out("Passed: %d lookups, %d bucket overflows\n", 1156 found_times, bucket_full_times); 1157 } 1158 } 1159 } 1160 1161 #ifdef BCM_TRIUMPH_SUPPORT 1162 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1163 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 1164 } 1165 #endif /* BCM_TRIUMPH_SUPPORT */ 1166 1167 return rv; 1168 } 1169 1170 /* 1171 * Test of ARL delete by port 1172 * 1173 * This test will insert a collection of entries with different ports, 1174 * then try to delete them by port reference. 1175 */ 1176 1177 int 1178 fb_l2_test_dp(int unit, args_t *a, void *p) 1179 { 1180 draco_l2_testdata_t *ad = p; 1181 l2x_entry_t *entries = NULL; 1182 int i, r, rv = 0; 1183 int bucket_full_times; 1184 int *bucket_full = NULL; 1185 bcm_l2_addr_t addr; 1186 int vid_inc = ad->opt_vid_inc; 1187 int mac_inc = ad->opt_mac_inc; 1188 int modid, modid_hi; 1189 uint8 key[XGS_HASH_KEY_SIZE]; 1190 #ifdef BCM_TRIUMPH_SUPPORT 1191 int ext_index_max = -1; 1192 #endif /* BCM_TRIUMPH_SUPPORT */ 1193 1194 COMPILER_REFERENCE(a); 1195 1196 #ifdef BCM_TRIUMPH_SUPPORT 1197 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1198 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 1199 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 1200 } 1201 #endif /* BCM_TRIUMPH_SUPPORT */ 1202 1203 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 1204 if ((r = bcm_stk_my_modid_get(unit, &modid)) < 0) { 1205 test_error(unit, 1206 "Modid retrieval failed: %s\n", 1207 soc_errmsg(r)); 1208 rv = -1; 1209 goto done; 1210 } 1211 modid_hi = modid + 1; 1212 1213 entries = 1214 sal_alloc(sizeof(l2x_entry_t) * SOC_MAX_NUM_PORTS, "L2 entries"); 1215 if (!entries) { 1216 test_error(unit, 1217 "Memory allocation failure\n"); 1218 rv = -1; 1219 goto done; 1220 } 1221 sal_memset(entries, 0, sizeof(l2x_entry_t) * SOC_MAX_NUM_PORTS); 1222 1223 bucket_full = sal_alloc(sizeof(int) * SOC_MAX_NUM_PORTS, 1224 "L2 full buckets"); 1225 if (!bucket_full) { 1226 test_error(unit, 1227 "Memory allocation failure\n"); 1228 rv = -1; 1229 goto done; 1230 } 1231 sal_memset(bucket_full, 0, sizeof(int) * SOC_MAX_NUM_PORTS); 1232 1233 bucket_full_times = 0; 1234 1235 if (ad->opt_verbose) { 1236 cli_out("Inserting port entries\n"); 1237 } 1238 1239 draco_l2_time_start(ad); 1240 1241 PBMP_E_ITER(unit, i) { 1242 if (SOC_PORT_MOD1(unit, i)) { 1243 addr.modid = modid_hi; 1244 } else { 1245 addr.modid = modid; 1246 } 1247 addr.port = i & 0x1f; 1248 #ifdef BCM_TRX_SUPPORT 1249 if (SOC_IS_TRX(unit)) { 1250 _bcm_tr_l2_to_l2x(unit, &(entries[i]), &addr, FALSE); 1251 } else 1252 #endif /* BCM_TRX_SUPPORT */ 1253 { 1254 _bcm_fb_l2_to_l2x(unit, &(entries[i]), &addr); 1255 } 1256 1257 if (ad->opt_verbose) { 1258 cli_out("Inserting port %d entry\n", i); 1259 } 1260 1261 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 1262 if (r == SOC_E_FULL) { 1263 bucket_full_times++; 1264 bucket_full[i] = 1; 1265 continue; 1266 } else { 1267 test_error(unit, 1268 "ARL insert failed on port entry %d: %s\n", 1269 i, soc_errmsg(r)); 1270 rv = -1; 1271 goto done; 1272 } 1273 } else { 1274 bucket_full[i] = 0; 1275 } 1276 1277 addr.vid += vid_inc; 1278 if (addr.vid > DRACO_L2_VID_MAX) { 1279 addr.vid = 1; 1280 } 1281 increment_macaddr(addr.mac, mac_inc); 1282 } 1283 1284 PBMP_E_ITER(unit, i) { 1285 l2x_entry_t *cur_entry = &(entries[i]); 1286 int local_modid; 1287 int port; 1288 1289 port = i & 0x1f; 1290 1291 if (SOC_PORT_MOD1(unit, i)) { 1292 local_modid = modid_hi; 1293 } else { 1294 local_modid = modid; 1295 } 1296 if (!bucket_full[i]) { 1297 if (ad->opt_verbose) { 1298 cli_out("Attempting to delete by port %d\n", i); 1299 } 1300 1301 r = bcm_l2_addr_delete_by_port(unit, local_modid, port, 1302 BCM_L2_DELETE_STATIC); 1303 if (r < 0) { 1304 test_error(unit, 1305 "ARL delete by port unsuccessful on modid %d, port %d\n", 1306 local_modid, port); 1307 rv = -1; 1308 goto done; 1309 } else { 1310 /* Delete claims to be successful, check */ 1311 int soft_bucket; 1312 1313 #ifdef BCM_TRX_SUPPORT 1314 if (SOC_IS_TRX(unit)) { 1315 int num_bits; 1316 num_bits = soc_tr_l2x_base_entry_to_key(unit, cur_entry, 1317 key); 1318 soft_bucket = soc_tr_l2x_hash(unit, ad->opt_hash, num_bits, 1319 cur_entry, key); 1320 } else 1321 #endif 1322 { 1323 soc_draco_l2x_base_entry_to_key(unit, cur_entry, key); 1324 soft_bucket = soc_fb_l2_hash(unit, ad->opt_hash, key); 1325 } 1326 1327 /* We should not find the entry when searching its bucket */ 1328 if (draco_l2_bucket_search(unit, ad, 1329 soft_bucket, cur_entry) == 0) { 1330 test_error(unit, 1331 "ARL delete by port failed on port %d\n", i); 1332 rv = -1; 1333 goto done; 1334 } 1335 } 1336 } 1337 } 1338 1339 draco_l2_time_end(ad); 1340 1341 done: 1342 if (bucket_full) { 1343 sal_free(bucket_full); 1344 } 1345 if (entries) { 1346 sal_free(entries); 1347 } 1348 #ifdef BCM_TRIUMPH_SUPPORT 1349 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1350 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 1351 } 1352 #endif /* BCM_TRIUMPH_SUPPORT */ 1353 1354 return rv; 1355 } 1356 1357 /* 1358 * Test of ARL delete by VLAN 1359 * 1360 * This test will insert a collection of entries with different VLAN ids, 1361 * then try to delete them by VLAN. 1362 */ 1363 1364 int 1365 fb_l2_test_dv(int unit, args_t *a, void *p) 1366 { 1367 draco_l2_testdata_t *ad = p; 1368 int count = ad->opt_count; 1369 l2x_entry_t *entries = NULL; 1370 int i, vid, r = 0, rv = 0; 1371 int bucket_full_times; 1372 int *bucket_full = NULL; 1373 bcm_l2_addr_t addr; 1374 int mac_inc = ad->opt_mac_inc; 1375 int vid_inc = ad->opt_vid_inc; 1376 uint8 key[XGS_HASH_KEY_SIZE]; 1377 #ifdef BCM_TRIUMPH_SUPPORT 1378 int ext_index_max = -1; 1379 #endif /* BCM_TRIUMPH_SUPPORT */ 1380 1381 COMPILER_REFERENCE(a); 1382 1383 entries = sal_alloc(sizeof(l2x_entry_t) * count, "L2 entries"); 1384 if (!entries) { 1385 test_error(unit, 1386 "Memory allocation failure\n"); 1387 rv = -1; 1388 goto done; 1389 } 1390 sal_memset(entries, 0, sizeof(l2x_entry_t) * count); 1391 1392 bucket_full = sal_alloc(sizeof(int) * count, "L2 full buckets"); 1393 if (!bucket_full) { 1394 test_error(unit, 1395 "Memory allocation failure\n"); 1396 rv = -1; 1397 goto done; 1398 } 1399 sal_memset(bucket_full, 0, sizeof(int) * count); 1400 1401 #ifdef BCM_TRIUMPH_SUPPORT 1402 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1403 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 1404 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 1405 } 1406 #endif /* BCM_TRIUMPH_SUPPORT */ 1407 1408 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 1409 1410 draco_l2_time_start(ad); 1411 1412 bucket_full_times = 0; 1413 1414 if (ad->opt_verbose) { 1415 cli_out("Inserting VLAN entries\n"); 1416 } 1417 1418 for (i = 0; i < count; i++) { 1419 #ifdef BCM_TRX_SUPPORT 1420 if (SOC_IS_TRX(unit)) { 1421 _bcm_tr_l2_to_l2x(unit, &(entries[i]), &addr, TRUE); 1422 } else 1423 #endif /* BCM_TRX_SUPPORT */ 1424 { 1425 _bcm_fb_l2_to_l2x(unit, &(entries[i]), &addr); 1426 } 1427 1428 if (ad->opt_verbose) { 1429 cli_out("Inserting VLAN %d entry\n", addr.vid); 1430 } 1431 1432 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 1433 if (r == SOC_E_FULL) { 1434 bucket_full_times++; 1435 bucket_full[i] = 1; 1436 continue; 1437 } else { 1438 test_error(unit, 1439 "ARL insert failed on VLAN entry %d: %s\n", 1440 i, soc_errmsg(r)); 1441 rv = -1; 1442 goto done; 1443 } 1444 } else { 1445 bucket_full[i] = 0; 1446 } 1447 1448 addr.vid += vid_inc; 1449 if (addr.vid > DRACO_L2_VID_MAX) { 1450 addr.vid = 1; 1451 } 1452 increment_macaddr(addr.mac, mac_inc); 1453 } 1454 1455 vid = ad->opt_base_vid; 1456 1457 for (i = 0; i < count; i++) { 1458 l2x_entry_t *cur_entry = &(entries[i]); 1459 if (!bucket_full[i]) { 1460 if (ad->opt_verbose) { 1461 cli_out("Attempting to delete by VLAN %d\n", vid); 1462 } 1463 1464 r = bcm_l2_addr_delete_by_vlan(unit, vid, BCM_L2_DELETE_STATIC); 1465 if (r < 0) { 1466 test_error(unit, 1467 "ARL delete by VLAN unsuccessful on VLAN %d\n", vid); 1468 rv = -1; 1469 goto done; 1470 } else { 1471 /* Delete claims to be successful, check */ 1472 int soft_bucket; 1473 1474 #ifdef BCM_TRX_SUPPORT 1475 if (SOC_IS_TRX(unit)) { 1476 int num_bits; 1477 1478 num_bits = soc_tr_l2x_base_entry_to_key(unit, cur_entry, 1479 key); 1480 soft_bucket = soc_tr_l2x_hash(unit, ad->opt_hash, num_bits, 1481 cur_entry, key); 1482 } else 1483 #endif 1484 { 1485 soc_draco_l2x_base_entry_to_key(unit, cur_entry, key); 1486 soft_bucket = soc_fb_l2_hash(unit, ad->opt_hash, key); 1487 } 1488 /* We should not find the entry when searching its bucket */ 1489 if (draco_l2_bucket_search(unit, ad, 1490 soft_bucket, cur_entry) == 0) { 1491 test_error(unit, 1492 "ARL delete by VLAN failed on VLAN %d\n", 1493 vid); 1494 rv = -1; 1495 goto done; 1496 } 1497 } 1498 } 1499 1500 vid += vid_inc; 1501 if (vid > DRACO_L2_VID_MAX) { 1502 vid = 1; 1503 } 1504 } 1505 1506 draco_l2_time_end(ad); 1507 1508 done: 1509 if (bucket_full) { 1510 sal_free(bucket_full); 1511 } 1512 if (entries) { 1513 sal_free(entries); 1514 } 1515 1516 #ifdef BCM_TRIUMPH_SUPPORT 1517 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1518 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 1519 } 1520 #endif /* BCM_TRIUMPH_SUPPORT */ 1521 1522 return rv; 1523 } 1524 1525 /* 1526 * Test clean-up routine used for all ARL tests 1527 */ 1528 1529 int 1530 fb_l2_test_done(int unit, void *p) 1531 { 1532 draco_l2_testdata_t *ad = p; 1533 1534 if (ad == NULL) { 1535 return 0; 1536 } 1537 1538 /* Check if empty at the end of the test */ 1539 if (ad->opt_reset) { 1540 int rv, ix; 1541 int index_min = soc_mem_index_min(unit, L2Xm); 1542 int index_max = soc_mem_index_max(unit, L2Xm); 1543 uint32 *buf = 0; 1544 uint32 *ent; 1545 uint32 count; 1546 1547 buf = soc_cm_salloc(unit, 1548 SOC_MEM_TABLE_BYTES(unit, L2Xm), 1549 "l2x_test"); 1550 if (!buf) { 1551 test_error(unit, "Memory allocation failed\n"); 1552 return (-1); 1553 } 1554 1555 if ((rv = soc_mem_read_range(unit, L2Xm, MEM_BLOCK_ANY, 1556 index_min, index_max, buf)) < 0) { 1557 test_error(unit, "Memory DMA of L2X entries failed\n"); 1558 return (-1); 1559 } 1560 1561 count = soc_mem_index_count(unit, L2Xm); 1562 for (ix = 0; ix < count; ix++) { 1563 int vld_fld = VALIDf; 1564 1565 if (soc_mem_field_valid(unit, L2Xm, BASE_VALIDf)) { 1566 vld_fld = BASE_VALIDf; 1567 } 1568 1569 ent = soc_mem_table_idx_to_pointer(unit, L2Xm, 1570 uint32 *, buf, ix); 1571 if (soc_L2Xm_field32_get(unit, ent, vld_fld)) { 1572 test_error(unit, "L2 table not empty after test entry = %d\n", 1573 ix); 1574 soc_mem_entry_dump(unit, L2Xm, ent, BSL_LSS_CLI); 1575 return (-1); 1576 } 1577 } 1578 1579 soc_cm_sfree(unit, buf); 1580 } 1581 1582 if (WRITE_HASH_CONTROLr(unit, ad->save_hash_control) < 0) { 1583 test_error(unit, "Hash select restore failed\n"); 1584 } 1585 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 1586 #ifdef BCM_TRIDENT3_SUPPORT 1587 if (soc_mem_is_valid(unit, L2_ENTRY_HASH_CONTROLm)) { 1588 if (soc_mem_write(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY, 1589 0, (void*)&ad->save_l2_entry_hash_control) < 0) { 1590 test_error(unit, "L2 Entry hash control setting failed\n"); 1591 } 1592 if (soc_mem_write(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY, 1593 0, (void*)&ad->save_shared_entry_hash_control) < 0) { 1594 test_error(unit, "Shared Entry hash control setting failed\n"); 1595 } 1596 } else 1597 #endif /* BCM_TRIDENT3_SUPPORT */ 1598 { 1599 if (WRITE_L2_TABLE_HASH_CONTROLr(unit, 1600 ad->save_l2_table_hash_control) < 0) { 1601 test_error(unit, "L2 Table hash control setting failed\n"); 1602 } 1603 if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) 1604 { 1605 if (WRITE_SHARED_TABLE_HASH_CONTROLr(unit, ad->save_shared_table_hash_control) < 0) { 1606 test_error(unit, "Shared Table hash control setting failed\n"); 1607 } 1608 } 1609 } 1610 } else { 1611 if (soc_feature(unit, soc_feature_dual_hash)) { 1612 if (WRITE_L2_AUX_HASH_CONTROLr(unit, ad->save_l2_aux_hash_control) < 0) { 1613 test_error(unit, "L2 AUX hash control restore failed\n"); 1614 } 1615 } 1616 } 1617 1618 return 0; 1619 } 1620 #endif /* BCM_FIREBOLT_SUPPORT */ 1621 1622 #if defined(BCM_TRIDENT2_SUPPORT) 1623 static int 1624 td2_l2_bucket_search(int unit, draco_l2_testdata_t *ad, int bank, int *index_array, 1625 l2x_entry_t *expect) 1626 { 1627 l2x_entry_t chip_entry; 1628 int ix, mem_table_index; 1629 int rv = -1; /* Assume failed unless we find it */ 1630 int validf; 1631 int bucket_size = SOC_TD2_L2X_BUCKET_SIZE; 1632 validf = VALIDf; 1633 1634 if (soc_feature(unit, soc_feature_base_valid)) { 1635 validf = BASE_VALIDf; 1636 } 1637 1638 for (ix = 0; ix < bucket_size; ix++) { 1639 mem_table_index = index_array[bank] + ix; 1640 1641 if (soc_mem_read(unit, L2Xm, MEM_BLOCK_ANY, 1642 mem_table_index, &chip_entry) < 0) { 1643 test_error(unit, 1644 "Read ARL failed at band %d, index %d, offset %d\n", 1645 bank, index_array[bank], ix); 1646 break; 1647 } 1648 1649 if (!soc_L2Xm_field32_get(unit, &chip_entry, validf)) { 1650 /* Valid bit unset, entry blank */ 1651 continue; 1652 } 1653 1654 if (soc_mem_compare_key(unit, L2Xm, expect, &chip_entry) == 0) { 1655 /* Found the matching entry */ 1656 rv = 0; 1657 break; 1658 } 1659 } 1660 1661 return rv; 1662 } 1663 /* 1664 * Test of L2X hashing 1665 * 1666 * This test tries a number of keys against one of the hashing functions, 1667 * checking a software hash against the hardware hash, then searching the 1668 * bucket to find the entry after inserting. 1669 */ 1670 int 1671 td2_l2_test_hash(int unit, args_t *a, void *p) 1672 { 1673 draco_l2_testdata_t *ad = p; 1674 l2x_entry_t entry; 1675 int r, rv = 0; 1676 int ix; 1677 uint8 key[XGS_HASH_KEY_SIZE]; 1678 int iterations; 1679 int num_l2_banks = 0; 1680 int bank = 0; 1681 int found; 1682 int l2_index_array[L2_MAX_BANKS] = {0}; 1683 int l2_bucket_array[L2_MAX_BANKS] = {0}; 1684 bcm_l2_addr_t addr; 1685 int vid_inc = ad->opt_vid_inc; 1686 int mac_inc = ad->opt_mac_inc; 1687 1688 COMPILER_REFERENCE(a); 1689 1690 #ifdef BCM_TRIDENT3_SUPPORT 1691 if (soc_mem_is_valid(unit, L2_ENTRY_KEY_ATTRIBUTESm)) { 1692 l2_entry_key_attributes_entry_t l2_key_attr; 1693 1694 /* Set L2 Entry Key Attributes */ 1695 sal_memset(&l2_key_attr, 0, sizeof(l2_key_attr)); 1696 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1697 BUCKET_MODEf, 0); 1698 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1699 KEY_BASE_WIDTHf, 0); 1700 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1701 KEY_WIDTHf, 16); 1702 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1703 DATA_BASE_WIDTHf, 0); 1704 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1705 HASH_LSB_OFFSETf, 19); 1706 if (soc_mem_write(unit, L2_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 1707 TD3_L2_HASH_KEY_TYPE_BRIDGE, 1708 (uint32*)&l2_key_attr) < 0) { 1709 test_error(unit, "L2 Entry Key Attr setting failed\n"); 1710 goto done; 1711 } 1712 } 1713 #endif 1714 1715 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 1716 1717 if (ad->opt_verbose) { 1718 cli_out("Starting ARL hash test\n"); 1719 } 1720 1721 iterations = ad->opt_count; 1722 1723 for (ix = 0; ix < iterations; ix++) { 1724 _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE); 1725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 1726 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 1727 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 1728 (SOC_IS_TRIDENT3X(unit))) { 1729 if ((rv = soc_td2x_th_l2x_hash(unit, (uint32 *)&entry, 1730 &num_l2_banks, l2_bucket_array, 1731 l2_index_array, key)) < 0) { 1732 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 1733 goto done; 1734 } 1735 1736 if (num_l2_banks > L2_MAX_BANKS) { 1737 cli_out("%s ERROR: the number of banks overflow\n", 1738 ARG_CMD(a)); 1739 rv = -1; 1740 goto done; 1741 } 1742 } else 1743 #endif 1744 { 1745 rv = -1; 1746 goto done; 1747 } 1748 1749 if (ad->opt_verbose) { 1750 cli_out("Inserting "); 1751 soc_mem_entry_dump(unit, L2Xm, &entry, BSL_LSS_CLI); 1752 cli_out("\n"); 1753 for (bank = 0; bank < num_l2_banks; bank++) { 1754 cli_out("bank%d bucket 0x%06x (%06d) index 0x%06x (%06d)\n", 1755 bank, l2_bucket_array[bank], l2_bucket_array[bank], 1756 l2_index_array[bank], l2_index_array[bank]); 1757 } 1758 } 1759 1760 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 1761 if (r == SOC_E_FULL) { 1762 /* Bucket overflow, just pass on */ 1763 goto incr; 1764 } else { 1765 test_error(unit, 1766 "ARL insert failed\n"); 1767 rv = -1; 1768 goto done; 1769 } 1770 } 1771 1772 /* Now we search for the entry */ 1773 1774 found = FALSE; 1775 for (bank = 0; bank < num_l2_banks; bank++) { 1776 /* Only do a quick check vs. expected bucket here */ 1777 if (td2_l2_bucket_search(unit, ad, bank, 1778 l2_index_array, &entry) == 0) { 1779 found = TRUE; 1780 break; 1781 } 1782 } 1783 if (!found) { 1784 test_error(unit, 1785 "ARL entry with key " 1786 "0x%02x%02x%02x%02x%02x%02x%02x%01x " 1787 "not found in predicted buckets\n", 1788 key[7], key[6], key[5], key[4], 1789 key[3], key[2], key[1], (key[0] >> 4) & 0xf); 1790 } 1791 if (bcm_l2_addr_delete(unit, addr.mac, addr.vid) < 0) { 1792 test_error(unit, "ARL delete failed!\n"); 1793 rv = -1; 1794 goto done; 1795 } 1796 1797 incr: 1798 addr.vid += vid_inc; 1799 if (addr.vid > FB_L2_VID_MAX) { 1800 addr.vid = 1; 1801 } 1802 increment_macaddr(addr.mac, mac_inc); 1803 } 1804 1805 done: 1806 return rv; 1807 } 1808 1809 /* 1810 * Test of ARL overflow behavior 1811 * 1812 * This test fills each bucket of the ARL, then inserts another entry to see 1813 * that the last entry fails to insert. 1814 */ 1815 1816 int 1817 td2_l2_test_ov(int unit, args_t *a, void *p) 1818 { 1819 draco_l2_testdata_t *ad = p; 1820 l2x_entry_t entry, result, *entry_array = NULL; 1821 int ix, jx, r, idx, rv = 0, alloc_sz; 1822 int bucket_size = SOC_TD2_L2X_BUCKET_SIZE; 1823 int bank; 1824 int found; 1825 uint32 bank_count; 1826 uint32 hash = ad->opt_hash; 1827 bcm_l2_addr_t addr, addr_tmp; 1828 int vid_inc = ad->opt_vid_inc; 1829 int iter = ad->opt_count; 1830 uint8 key[XGS_HASH_KEY_SIZE]; 1831 int num_l2_banks = 0; 1832 int l2_index_array[L2_MAX_BANKS] = {0}; 1833 int l2_bucket_array[L2_MAX_BANKS] = {0}; 1834 1835 COMPILER_REFERENCE(a); 1836 1837 bcm_l2_addr_t_init(&addr, ad->opt_base_mac, ad->opt_base_vid); 1838 1839 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL2, 1840 &bank_count)) < 0) { 1841 test_error(unit, "Getting bank count for L2 table failed\n"); 1842 rv = -1; 1843 goto done; 1844 } 1845 alloc_sz = sizeof(l2x_entry_t) * bucket_size * bank_count; 1846 entry_array = sal_alloc(alloc_sz, "l2_entry_array"); 1847 if (entry_array == NULL) { 1848 rv = -1; 1849 goto done; 1850 } 1851 for (bank = 0; bank < bank_count; bank++) { 1852 if (ad->opt_verbose) { 1853 cli_out("Resetting hash bank %d selection to LSB\n", bank); 1854 } 1855 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL2, bank, 1856 BCM_HASH_LSB, 48)) < 0) { 1857 test_error(unit, "Hash bank setting failed\n"); 1858 rv = -1; 1859 goto done; 1860 } 1861 } 1862 1863 if (hash != FB_HASH_LSB) { 1864 ad->opt_hash = hash = FB_HASH_LSB; 1865 } 1866 1867 if (iter > soc_mem_index_count(unit, L2Xm)) { 1868 iter = soc_mem_index_count(unit, L2Xm); 1869 } 1870 #ifdef BCM_TRIDENT3_SUPPORT 1871 if (soc_mem_is_valid(unit, L2_ENTRY_KEY_ATTRIBUTESm)) { 1872 l2_entry_key_attributes_entry_t l2_key_attr; 1873 1874 /* Set L2 Entry Key Attributes */ 1875 sal_memset(&l2_key_attr, 0, sizeof(l2_key_attr)); 1876 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1877 BUCKET_MODEf, 0); 1878 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1879 KEY_BASE_WIDTHf, 0); 1880 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1881 KEY_WIDTHf, 16); 1882 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1883 DATA_BASE_WIDTHf, 0); 1884 soc_mem_field32_set(unit, L2_ENTRY_KEY_ATTRIBUTESm, &l2_key_attr, 1885 HASH_LSB_OFFSETf, 19); 1886 if (soc_mem_write(unit, L2_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 1887 TD3_L2_HASH_KEY_TYPE_BRIDGE, 1888 (uint32*)&l2_key_attr) < 0) { 1889 test_error(unit, "L2 Entry Key Attr setting failed\n"); 1890 goto done; 1891 } 1892 } 1893 #endif 1894 1895 while (iter--) { 1896 sal_memset(entry_array, 0, alloc_sz); 1897 for (ix = 0; ix < bucket_size * bank_count; ix++) { 1898 _bcm_tr_l2_to_l2x(unit, &(entry_array[ix]), &addr, TRUE); 1899 1900 if (ix == 0) { 1901 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 1902 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 1903 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 1904 (SOC_IS_TRIDENT3X(unit))) { 1905 if ((rv = soc_td2x_th_l2x_hash(unit, (uint32 *)&(entry_array[ix]), 1906 &num_l2_banks, l2_bucket_array, 1907 l2_index_array, key)) < 0) { 1908 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 1909 goto done; 1910 } 1911 1912 if (num_l2_banks > L2_MAX_BANKS) { 1913 cli_out("%s ERROR: the number of banks overflow\n", 1914 ARG_CMD(a)); 1915 rv = -1; 1916 goto done; 1917 } 1918 } else 1919 #endif 1920 { 1921 rv = -1; 1922 goto done; 1923 } 1924 1925 if (ad->opt_verbose) { 1926 for (bank = 0; bank < bank_count; bank++) { 1927 cli_out("bank%d bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 1928 bank, l2_bucket_array[bank], l2_bucket_array[bank], 1929 l2_index_array[bank], l2_index_array[bank]); 1930 } 1931 } 1932 } 1933 1934 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 1935 if (r == SOC_E_FULL) { 1936 /* Already full, stop wasting time */ 1937 break; 1938 } else { 1939 test_error(unit, 1940 "ARL ix %d insert failed!\n", ix); 1941 rv = -1; 1942 goto done; 1943 } 1944 } 1945 1946 /* key for LSB is the MAC address, so we must keep it constant */ 1947 addr.vid += vid_inc; 1948 if (addr.vid > DRACO_L2_VID_MAX) { 1949 addr.vid = 1; 1950 } 1951 } 1952 1953 if (ad->opt_verbose) { 1954 cli_out("Inserting %dth entry in banks should fail\n", 1955 (bucket_size * bank_count + 1)); 1956 } 1957 1958 _bcm_tr_l2_to_l2x(unit, &entry, &addr, TRUE); 1959 1960 if ((r = bcm_l2_addr_add(unit, &addr)) < 0) { 1961 if (r != SOC_E_FULL) { 1962 test_error(unit, 1963 "ARL insert failed\n"); 1964 rv = -1; 1965 goto done; 1966 } 1967 } else { 1968 test_error(unit, "ARL insert to full bucket succeeded\n"); 1969 rv = -1; 1970 goto done; 1971 } 1972 1973 if (ad->opt_verbose) { 1974 cli_out("Verifying entries present\n"); 1975 } 1976 1977 /* Verify bucket contains our added entries */ 1978 for (jx = 0; jx < bucket_size * bank_count; jx++) { 1979 found = 0; 1980 for (bank = 0; bank < bank_count; bank++) { 1981 if (td2_l2_bucket_search(unit, ad, bank, l2_index_array, 1982 &(entry_array[jx])) == 0) { 1983 found = 1; 1984 break; 1985 } 1986 } 1987 if (!found) { 1988 test_error(unit, 1989 "ARL entry jx %d missing on all banks\n", jx); 1990 rv = -1; 1991 goto done; 1992 } 1993 if (soc_mem_search(unit, L2Xm, MEM_BLOCK_ANY, &idx, 1994 &entry_array[jx], &result, 0) < 0) { 1995 test_error(unit, 1996 "ARL entry missing at bucket %d index %d on bank %d\n", 1997 l2_bucket_array[bank], l2_index_array[bank], bank); 1998 rv = -1; 1999 goto done; 2000 } 2001 if (idx < (l2_index_array[bank]) || 2002 idx >= (l2_index_array[bank] + bucket_size)) { 2003 test_error(unit, "ARL entry inserted into wrong index" 2004 " Expected [%d-%d] Actual %d\n", 2005 l2_index_array[bank], 2006 l2_index_array[bank] + bucket_size, 2007 idx); 2008 rv = -1; 2009 goto done; 2010 } 2011 } 2012 2013 if (ad->opt_verbose) { 2014 cli_out("Cleaning each entry on all banks...\n"); 2015 } 2016 /* Remove the entries that we added */ 2017 for (jx = 0; jx < bucket_size * bank_count; jx++) { 2018 _bcm_tr_l2_from_l2x(unit, &addr_tmp, &(entry_array[jx])); 2019 if (bcm_l2_addr_delete(unit, addr_tmp.mac, addr_tmp.vid) < 0) { 2020 test_error(unit, 2021 "ARL delete jx %d failed on all bank\n", jx); 2022 rv = -1; 2023 goto done; 2024 } 2025 } 2026 2027 /* We want the increment to change buckets by one */ 2028 increment_macaddr(addr.mac, 1); 2029 } 2030 2031 done: 2032 if (entry_array) { 2033 sal_free(entry_array); 2034 entry_array = NULL; 2035 } 2036 return rv; 2037 } 2038 2039 #endif /* BCM_TRIDENT2_SUPPORT */ 2040 2041 /* 2042 * Test of ARL hashing 2043 * 2044 * This test tries a number of keys against one of the hashing functions, 2045 * checking a software hash against the hardware hash, then searching the 2046 * bucket to find the entry after inserting. 2047 */ 2048 int 2049 draco_l2_test_hash(int unit, args_t *a, void *p) 2050 { 2051 int rv = 0; 2052 2053 COMPILER_REFERENCE(a); 2054 2055 #if defined(BCM_TRIDENT2_SUPPORT) 2056 if (SOC_IS_TD2_TT2(unit)) { 2057 return td2_l2_test_hash(unit, a, p); 2058 } 2059 #endif /* BCM_TRIDENT2_SUPPORT */ 2060 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT) 2061 if (SOC_IS_FBX(unit)) { 2062 return fb_l2_test_hash(unit, a, p); 2063 } 2064 #endif /* BCM_FIREBOLT_SUPPORT || BCM_BRADLEY_SUPPORT */ 2065 2066 return rv; 2067 } 2068 2069 2070 /* 2071 * Test of ARL overflow behavior 2072 * 2073 * This test fills each bucket of the ARL, then inserts another entry to see 2074 * that the last entry fails to insert. 2075 */ 2076 2077 int 2078 draco_l2_test_ov(int unit, args_t *a, void *p) 2079 { 2080 int rv = 0; 2081 2082 COMPILER_REFERENCE(a); 2083 2084 #if defined(BCM_TRIDENT2_SUPPORT) 2085 if (SOC_IS_TD2_TT2(unit)) { 2086 return td2_l2_test_ov(unit, a, p); 2087 } 2088 #endif /* BCM_TRIDENT2_SUPPORT */ 2089 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT) 2090 if (SOC_IS_FBX(unit)) { 2091 return fb_l2_test_ov(unit, a, p); 2092 } 2093 #endif /* BCM_FIREBOLT_SUPPORT || BCM_BRADLEY_SUPPORT */ 2094 2095 return rv; 2096 } 2097 2098 /* 2099 * Test of ARL lookup 2100 * 2101 * This test loops a given number of times. It inserts a single ARL 2102 * entry, looks up the ARL entry, and deletes the ARL entry. 2103 * It is possible to run this test while heavy switching is going on. 2104 */ 2105 2106 int 2107 draco_l2_test_lu(int unit, args_t *a, void *p) 2108 { 2109 int rv = -1; 2110 2111 COMPILER_REFERENCE(a); 2112 2113 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT) 2114 if (SOC_IS_FBX(unit)) { 2115 return fb_l2_test_lu(unit, a, p); 2116 } 2117 #endif /* BCM_FIREBOLT_SUPPORT */ 2118 if (! soc_feature(unit, soc_feature_arl_lookup_cmd)) { 2119 test_error(unit, "ARL lookup not supported by chip (unit %d)\n", unit); 2120 return -1; 2121 } 2122 2123 return rv; 2124 } 2125 2126 /* 2127 * Test of ARL delete by port 2128 * 2129 * This test will insert a collection of entries with different ports, 2130 * then try to delete them by port reference. 2131 */ 2132 2133 int 2134 draco_l2_test_dp(int unit, args_t *a, void *p) 2135 { 2136 int rv = 0; 2137 2138 COMPILER_REFERENCE(a); 2139 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT) 2140 if (SOC_IS_FBX(unit)) { 2141 return fb_l2_test_dp(unit, a, p); 2142 } 2143 #endif /* BCM_FIREBOLT_SUPPORT */ 2144 2145 return rv; 2146 } 2147 2148 /* 2149 * Test of ARL delete by VLAN 2150 * 2151 * This test will insert a collection of entries with different VLAN ids, 2152 * then try to delete them by VLAN. 2153 */ 2154 2155 int 2156 draco_l2_test_dv(int unit, args_t *a, void *p) 2157 { 2158 int rv = 0; 2159 2160 COMPILER_REFERENCE(a); 2161 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT) 2162 if (SOC_IS_FBX(unit)) { 2163 return fb_l2_test_dv(unit, a, p); 2164 } 2165 #endif /* BCM_FIREBOLT_SUPPORT */ 2166 2167 return rv; 2168 } 2169 2170 /* 2171 * Test clean-up routine used for all ARL tests 2172 */ 2173 2174 int 2175 draco_l2_test_done(int unit, void *p) 2176 { 2177 draco_l2_testdata_t *ad = p; 2178 2179 if (ad == NULL) { 2180 return 0; 2181 } 2182 2183 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT) 2184 if (SOC_IS_FBX(unit)) { 2185 return fb_l2_test_done(unit, p); 2186 } 2187 #endif /* BCM_FIREBOLT_SUPPORT */ 2188 2189 return 0; 2190 } 2191 2192 #ifdef INCLUDE_L3 2193 #ifdef BCM_FIREBOLT_SUPPORT 2194 STATIC void 2195 fbl3_setup(int unit, draco_l3_test_t *dw) 2196 { 2197 draco_l3_testdata_t *ad; 2198 int mem = L3_ENTRY_IPV6_MULTICASTm; 2199 2200 #ifdef BCM_TRIDENT3_SUPPORT 2201 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 2202 mem = L3_ENTRY_QUADm; 2203 } 2204 #endif 2205 /* Hash */ 2206 ad = &dw->dlp_l3_hash; 2207 2208 ad->opt_count = soc_mem_index_count(unit, mem); 2209 ad->opt_hash = FB_HASH_CRC16_LOWER; 2210 ad->opt_dual_hash = -1; 2211 ad->hash_count = FB_HASH_COUNT; 2212 sal_memset (ad->opt_src_ip6, 0, sizeof(ad->opt_src_ip6)); 2213 sal_memset (ad->opt_base_ip6, 0, sizeof(ad->opt_base_ip6)); 2214 ad->opt_base_ip6[15] = 1; 2215 ad->opt_src_ip6[15] = 1; 2216 ad->opt_ip6_inc = 1; 2217 ad->opt_src_ip6_inc = 1; 2218 ad->opt_base_vrf_id = 0; 2219 ad->opt_vrf_id_inc = 1; 2220 2221 /* Overflow */ 2222 ad = &dw->dlp_l3_ov; 2223 2224 ad->opt_count = soc_mem_index_count(unit, mem); 2225 ad->opt_hash = FB_L3_DEFAULT_HASH; 2226 ad->opt_dual_hash = -1; 2227 ad->hash_count = FB_HASH_COUNT; 2228 sal_memset (ad->opt_src_ip6, 0, sizeof(ad->opt_src_ip6)); 2229 sal_memset (ad->opt_base_ip6, 0, sizeof(ad->opt_base_ip6)); 2230 ad->opt_base_ip6[15] = 1; 2231 ad->opt_src_ip6[15] = 1; 2232 ad->opt_ip6_inc = 1; 2233 ad->opt_src_ip6_inc = 1; 2234 ad->opt_base_vrf_id = 0; 2235 ad->opt_vrf_id_inc = 1; 2236 } 2237 2238 #endif /* BCM_FIREBOLT_SUPPORT */ 2239 2240 STATIC void 2241 dl3_setup(int unit, draco_l3_test_t *dw) 2242 { 2243 draco_l3_testdata_t *ad; 2244 soc_mem_t l3xm = INVALIDm; 2245 soc_mem_t l3x_validm = INVALIDm; 2246 int mem = L3_ENTRY_IPV6_MULTICASTm; 2247 2248 #ifdef BCM_TRIDENT3_SUPPORT 2249 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 2250 mem = L3_ENTRY_QUADm; 2251 } 2252 #endif 2253 2254 if (dw->dlw_set_up) { 2255 return; 2256 } 2257 #ifdef BCM_FIREBOLT_SUPPORT 2258 /* Firebolt adjustments */ 2259 if (SOC_IS_FBX(unit)) { 2260 l3xm = mem; 2261 l3x_validm = mem; 2262 } 2263 #endif /* BCM_FIREBOLT_SUPPORT */ 2264 2265 dw->dlw_set_up = TRUE; 2266 dw->dlw_unit = unit; 2267 2268 /* Hash */ 2269 ad = &dw->dlp_l3_hash; 2270 2271 ad->unit = unit; 2272 ad->opt_count = SOC_MEM_IS_VALID(unit, l3xm) ? 2273 soc_mem_index_count(unit, l3xm) : 0; 2274 ad->opt_verbose = FALSE; 2275 ad->opt_reset = TRUE; 2276 ad->opt_hash = XGS_HASH_CRC16_LOWER; 2277 ad->opt_ipmc_enable = TRUE; 2278 ad->opt_key_src_ip = 1; 2279 ad->opt_base_ip = 0; 2280 ad->opt_ip_inc = 1; 2281 ad->opt_src_ip = 0; 2282 ad->opt_src_ip_inc = 1; 2283 ad->opt_base_vid = 0; 2284 ad->opt_vid_inc = 1; 2285 ad->opt_mac_inc = 1; 2286 ad->ipv6 = 0; 2287 ad->hash_count = XGS_HASH_COUNT; 2288 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 2289 2290 /* Overflow */ 2291 ad = &dw->dlp_l3_ov; 2292 2293 ad->unit = unit; 2294 ad->opt_count = SOC_MEM_IS_VALID(unit, l3x_validm) ? 2295 soc_mem_index_count(unit, l3x_validm) : 0; 2296 ad->opt_verbose = FALSE; 2297 ad->opt_reset = TRUE; 2298 ad->opt_hash = DRACO_ARL_DEFAULT_HASH; 2299 ad->opt_ipmc_enable = TRUE; 2300 ad->opt_key_src_ip = 1; 2301 ad->opt_base_ip = 0; 2302 ad->opt_ip_inc = 1; 2303 ad->opt_src_ip = 0; 2304 ad->opt_src_ip_inc = 1; 2305 ad->opt_base_vid = 0; 2306 ad->opt_vid_inc = 1; 2307 ad->opt_mac_inc = 1; 2308 ad->ipv6 = 0; 2309 ad->hash_count = XGS_HASH_COUNT; 2310 ENET_SET_MACADDR(ad->opt_base_mac, dl_mac_src); 2311 2312 #ifdef BCM_FIREBOLT_SUPPORT 2313 /* Firebolt adjustments */ 2314 if (SOC_IS_FBX(unit)) { 2315 fbl3_setup(unit, dw); 2316 } 2317 #endif /* BCM_FIREBOLT_SUPPORT */ 2318 } 2319 2320 STATIC int 2321 _xgs_l3_hash_save(int unit, draco_l3_testdata_t *ad) 2322 { 2323 SOC_IF_ERROR_RETURN(_soc_mem_cmp_l3x_sync(unit)); 2324 ad->save_ipmc_config = SOC_CONTROL(unit)->hash_key_config; 2325 return SOC_E_NONE; 2326 } 2327 2328 STATIC int 2329 _xgs_l3_hash_set(int unit, draco_l3_testdata_t *ad) 2330 { 2331 ad->set_ipmc_config = ad->save_ipmc_config; 2332 if (ad->opt_ipmc_enable) { 2333 ad->set_ipmc_config |= L3X_IPMC_ENABLE; 2334 } else { 2335 ad->set_ipmc_config &= ~L3X_IPMC_ENABLE; 2336 } 2337 /* Turn off PIM_DM_SM mode */ 2338 ad->set_ipmc_config &= ~L3X_IPMC_SIP; 2339 if (ad->opt_key_src_ip) { 2340 ad->set_ipmc_config &= ~L3X_IPMC_SIP0; 2341 } else { 2342 ad->set_ipmc_config |= L3X_IPMC_SIP0; 2343 } 2344 2345 2346 if (ad->set_ipmc_config != ad->save_ipmc_config) { 2347 SOC_IF_ERROR_RETURN(_soc_mem_cmp_l3x_set(unit, ad->set_ipmc_config)); 2348 } 2349 return SOC_E_NONE; 2350 } 2351 2352 /* 2353 * Test initialization routine used for all L3 tests 2354 */ 2355 2356 STATIC int 2357 draco_l3_test_init(int unit, draco_l3_testdata_t *ad, args_t *a) 2358 { 2359 int rv = -1, dual = 0; 2360 parse_table_t pt; 2361 uint32 hash_read = 0; 2362 uint32 dual_hash_read = 0; 2363 uint32 l3_table_hash_control = 0; 2364 uint32 shared_table_hash_control = 0; 2365 #ifdef BCM_TRIDENT3_SUPPORT 2366 l3_entry_hash_control_entry_t l3_entry_hash_control; 2367 uft_shared_banks_control_entry_t shared_entry_hash_control; 2368 2369 sal_memset(&l3_entry_hash_control, 0, sizeof(l3_entry_hash_control)); 2370 sal_memset(&shared_entry_hash_control, 0, sizeof(shared_entry_hash_control)); 2371 #endif 2372 2373 parse_table_init(unit, &pt); 2374 2375 parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &ad->opt_count, NULL); 2376 parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &ad->opt_verbose, NULL); 2377 parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &ad->opt_reset, NULL); 2378 parse_table_add(&pt, "Hash", PQ_INT|PQ_DFL, 0, &ad->opt_hash, NULL); 2379 if (soc_feature(unit, soc_feature_dual_hash)) { 2380 parse_table_add(&pt, "DualHash", PQ_INT|PQ_DFL, 0, &ad->opt_dual_hash, NULL); 2381 parse_table_add(&pt, "DualEnable", PQ_INT|PQ_DFL, 0, &dual, NULL); 2382 } 2383 parse_table_add(&pt, "IPMCEnable", PQ_BOOL|PQ_DFL, 0, 2384 &ad->opt_ipmc_enable, NULL); 2385 parse_table_add(&pt, "SrcIPKey", PQ_BOOL|PQ_DFL, 0, 2386 &ad->opt_key_src_ip, NULL); 2387 if (ad->ipv6) { 2388 parse_table_add(&pt, "BaseIP", PQ_IP6|PQ_DFL, 0, &ad->opt_base_ip6, NULL); 2389 parse_table_add(&pt, "BIPIncrement", PQ_INT|PQ_DFL, 0, 2390 &ad->opt_ip6_inc, NULL); 2391 parse_table_add(&pt, "SourceIP", PQ_IP6|PQ_DFL, 0, 2392 &ad->opt_src_ip6, NULL); 2393 parse_table_add(&pt, "SrcIPIncrement", PQ_INT|PQ_DFL, 0, 2394 &ad->opt_src_ip6_inc, NULL); 2395 } else { 2396 parse_table_add(&pt, "BaseIP", PQ_IP|PQ_DFL, 0, &ad->opt_base_ip, NULL); 2397 parse_table_add(&pt, "BIPIncrement", PQ_INT|PQ_DFL, 0, 2398 &ad->opt_ip_inc, NULL); 2399 parse_table_add(&pt, "SourceIP", PQ_IP|PQ_DFL, 0, &ad->opt_src_ip, NULL); 2400 parse_table_add(&pt, "SrcIPIncrement", PQ_INT|PQ_DFL, 0, 2401 &ad->opt_src_ip_inc, NULL); 2402 } 2403 parse_table_add(&pt, "BaseVID", PQ_HEX|PQ_DFL, 0, &ad->opt_base_vid, NULL); 2404 parse_table_add(&pt, "VIDIncrement", PQ_INT|PQ_DFL, 0, 2405 &ad->opt_vid_inc, NULL); 2406 parse_table_add(&pt, "BaseMac", PQ_DFL|PQ_MAC, 0, &ad->opt_base_mac, NULL); 2407 parse_table_add(&pt, "MacIncrement", PQ_INT|PQ_DFL, 0, 2408 &ad->opt_mac_inc, NULL); 2409 2410 parse_table_add(&pt, "BaseVRFID", PQ_INT|PQ_DFL, 0, 2411 &ad->opt_base_vrf_id, NULL); 2412 parse_table_add(&pt, "VRFIDIncrement", PQ_INT|PQ_DFL, 0, 2413 &ad->opt_vrf_id_inc, NULL); 2414 2415 /* Test the obvious parsings before wasting time with malloc */ 2416 if (parse_arg_eq(a, &pt) < 0) { 2417 test_error(unit, 2418 "%s: Error: Invalid option: %s\n", ARG_CMD(a), 2419 ARG_CUR(a) ? ARG_CUR(a) : "*"); 2420 goto done; 2421 } 2422 2423 if (ad->opt_count < 1) { 2424 test_error(unit, "Illegal count %d\n", ad->opt_count); 2425 goto done; 2426 } 2427 2428 if (ad->opt_hash >= ad->hash_count) { 2429 test_error(unit, "Illegal hash selection %d\n", ad->opt_hash); 2430 goto done; 2431 } 2432 2433 if (dual == 1) { 2434 if (ad->opt_dual_hash >= ad->hash_count) { 2435 test_error(unit, "Illegal dual hash selection %d\n", ad->opt_dual_hash); 2436 goto done; 2437 } 2438 } else { 2439 ad->opt_dual_hash = -1; 2440 } 2441 2442 /* 2443 * Re-initialize chip to ensure ARL and software ARL table are clear 2444 * at start of test. 2445 */ 2446 2447 if (ad->opt_reset) { 2448 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0)); 2449 if (soc_reset_init(unit) < 0) { 2450 test_error(unit, "SOC initialization failed\n"); 2451 goto done; 2452 } 2453 2454 #if defined(CANCUN_SUPPORT) 2455 if (soc_cancun_pre_misc_init_load(unit) < 0) { 2456 test_error(unit, "CMH/CCH/CEH load failed"); 2457 goto done; 2458 } 2459 #endif 2460 2461 if (soc_misc_init(unit) < 0) { 2462 test_error(unit, "ARL initialization failed\n"); 2463 goto done; 2464 } 2465 2466 #if defined(CANCUN_SUPPORT) 2467 if (soc_cancun_post_misc_init_load(unit) < 0) { 2468 test_error(unit, "CIH/CFH load failed"); 2469 goto done; 2470 } 2471 #endif 2472 2473 if (soc_mmu_init(unit) < 0) { 2474 test_error(unit, "MMU initialization failed\n"); 2475 goto done; 2476 } 2477 2478 /* Must initialize mbcm for L3 functions below */ 2479 if (bcm_init(unit) < 0) { 2480 test_error(unit, "BCM layer initialization failed\n"); 2481 goto done; 2482 } 2483 2484 if (bcm_l3_init(unit) < 0) { 2485 test_error(unit, "L3 initialization failed\n"); 2486 goto done; 2487 } 2488 2489 if (SOC_FUNCTIONS(unit)->soc_age_timer_set(unit, 0, 0) < 0) { 2490 test_error(unit, "Could not disable age timers\n"); 2491 goto done; 2492 } 2493 } 2494 2495 if (READ_HASH_CONTROLr(unit, &hash_read) < 0) { 2496 test_error(unit, "Hash select read failed\n"); 2497 goto done; 2498 } 2499 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 2500 #ifdef BCM_TRIDENT3_SUPPORT 2501 if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) { 2502 if (soc_mem_read(unit, L3_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY, 2503 0, (void*)&l3_entry_hash_control) < 0) { 2504 test_error(unit, "L3 Table hash control read failed\n"); 2505 goto done; 2506 } 2507 if (soc_mem_read(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY, 2508 0, (void*)&shared_entry_hash_control) < 0) { 2509 test_error(unit, "Shared Entry hash control read failed\n"); 2510 goto done; 2511 } 2512 } else 2513 #endif /* BCM_TRIDENT3_SUPPORT */ 2514 { 2515 if (READ_L3_TABLE_HASH_CONTROLr(unit, 2516 &l3_table_hash_control) < 0) { 2517 test_error(unit, "L3 Table hash control read failed\n"); 2518 goto done; 2519 } 2520 if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) 2521 { 2522 if (READ_SHARED_TABLE_HASH_CONTROLr(unit, 2523 &shared_table_hash_control) < 0) { 2524 test_error(unit, "Shared Table hash control read failed\n"); 2525 goto done; 2526 } 2527 } 2528 } 2529 } else { 2530 if (soc_feature(unit, soc_feature_dual_hash)) { 2531 if (READ_L3_AUX_HASH_CONTROLr(unit, &dual_hash_read) < 0) { 2532 test_error(unit, "Dual Hash select read failed\n"); 2533 goto done; 2534 } 2535 } 2536 } 2537 2538 2539 ad->save_hash_control = hash_read; 2540 ad->save_dual_hash_control = dual_hash_read; 2541 ad->save_l3_table_hash_control = l3_table_hash_control; 2542 ad->save_shared_table_hash_control = shared_table_hash_control; 2543 #ifdef BCM_TRIDENT3_SUPPORT 2544 ad->save_l3_entry_hash_control = l3_entry_hash_control; 2545 ad->save_shared_entry_hash_control = shared_entry_hash_control; 2546 #endif /* BCM_TRIDENT3_SUPPORT */ 2547 hash_read = ad->opt_hash; 2548 dual_hash_read = ad->opt_dual_hash; 2549 #ifdef BCM_XGS3_SWITCH_SUPPORT 2550 if (SOC_IS_XGS3_SWITCH(unit)) { 2551 hash_read = ad->save_hash_control; 2552 soc_reg_field_set(unit, HASH_CONTROLr, &hash_read, 2553 L3_HASH_SELECTf, ad->opt_hash); 2554 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 2555 #ifdef BCM_TRIDENT3_SUPPORT 2556 if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) { 2557 rv = td3_entry_hash_control_set(unit, ad->opt_hash, 2558 L3_ENTRY_HASH_CONTROLm, 2559 (uint32 *)&l3_entry_hash_control); 2560 if (rv < 0) { 2561 test_error(unit, "Hash Control write failed"); 2562 goto done; 2563 } 2564 } else 2565 #endif /* BCM_TRIDENT3_SUPPORT */ 2566 { 2567 soc_reg_field_set(unit, L3_TABLE_HASH_CONTROLr, 2568 &l3_table_hash_control, 2569 HASH_ZERO_OR_LSBf, 1); 2570 } 2571 } else { 2572 if (soc_feature(unit, soc_feature_dual_hash)) { 2573 dual_hash_read = ad->save_dual_hash_control; 2574 if (ad->opt_dual_hash != -1) { 2575 soc_reg_field_set(unit, L3_AUX_HASH_CONTROLr, &dual_hash_read, 2576 HASH_SELECTf, ad->opt_dual_hash); 2577 soc_reg_field_set(unit, L3_AUX_HASH_CONTROLr, &dual_hash_read, 2578 ENABLEf, 1); 2579 } else { 2580 soc_reg_field_set(unit, L3_AUX_HASH_CONTROLr, &dual_hash_read, 2581 ENABLEf, 0); 2582 } 2583 } 2584 } 2585 } 2586 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 2587 2588 if (WRITE_HASH_CONTROLr(unit, hash_read) < 0) { 2589 test_error(unit, "Hash select set failed\n"); 2590 goto done; 2591 } 2592 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 2593 #ifdef BCM_TRIDENT3_SUPPORT 2594 if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) { 2595 if (soc_mem_write(unit, L3_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY, 2596 0, (uint32*)&l3_entry_hash_control) < 0) { 2597 test_error(unit, "L3 Entry hash control setting failed\n"); 2598 goto done; 2599 } 2600 } else 2601 #endif /* BCM_TRIDENT3_SUPPORT */ 2602 { 2603 if (WRITE_L3_TABLE_HASH_CONTROLr(unit, l3_table_hash_control) < 0) { 2604 test_error(unit, "L3 Table hash control setting failed\n"); 2605 goto done; 2606 } 2607 } 2608 } else { 2609 if (soc_feature(unit, soc_feature_dual_hash)) { 2610 if (WRITE_L3_AUX_HASH_CONTROLr(unit, dual_hash_read) < 0) { 2611 test_error(unit, "Dual Hash select set failed\n"); 2612 goto done; 2613 } 2614 } 2615 } 2616 2617 if (!SOC_IS_FBX(unit)) { 2618 if (_xgs_l3_hash_save(unit, ad) < 0) { 2619 test_error(unit, "hash state save failed"); 2620 goto done; 2621 } 2622 if (_xgs_l3_hash_set(unit, ad) < 0) { 2623 test_error(unit, "hash state set failed"); 2624 goto done; 2625 } 2626 2627 if (_soc_mem_cmp_l3x_sync(unit) < 0) { 2628 test_error(unit, "Unable to sync L3 config\n"); 2629 goto done; 2630 } 2631 } 2632 2633 rv = 0; 2634 2635 done: 2636 2637 parse_arg_eq_done(&pt); 2638 return rv; 2639 } 2640 2641 /* Individual test init wrappers */ 2642 int 2643 draco_l3_hash_test_init(int unit, args_t *a, void **p) 2644 { 2645 draco_l3_test_t *dw = &dl3_work[unit]; 2646 draco_l3_testdata_t *dp = &dw->dlp_l3_hash; 2647 int rv; 2648 2649 dl3_setup(unit, dw); 2650 2651 /* Set working data to hash */ 2652 dw->dlp_l3_cur = dp; 2653 2654 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2655 return rv; 2656 } else { 2657 *p = dp; 2658 } 2659 2660 return 0; 2661 } 2662 2663 int 2664 draco_l3_ov_test_init(int unit, args_t *a, void **p) 2665 { 2666 draco_l3_test_t *dw = &dl3_work[unit]; 2667 draco_l3_testdata_t *dp = &dw->dlp_l3_ov; 2668 int rv; 2669 2670 dl3_setup(unit, dw); 2671 2672 /* Set working data to overflow */ 2673 dw->dlp_l3_cur = dp; 2674 2675 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2676 return rv; 2677 } else { 2678 *p = dp; 2679 } 2680 2681 return 0; 2682 } 2683 2684 #ifdef BCM_XGS3_SWITCH_SUPPORT 2685 /* Individual test init wrappers */ 2686 int 2687 fb_l3_hash_test_init(int unit, args_t *a, void **p) 2688 { 2689 draco_l3_test_t *dw = &dl3_work[unit]; 2690 draco_l3_testdata_t *dp = &dw->dlp_l3_hash; 2691 int rv; 2692 2693 dl3_setup(unit, dw); 2694 dp->ipv6 = 0; 2695 2696 /* Set working data to hash */ 2697 dw->dlp_l3_cur = dp; 2698 2699 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2700 return rv; 2701 } else { 2702 *p = dp; 2703 } 2704 2705 return 0; 2706 } 2707 2708 int 2709 fb_l3_ov_test_init(int unit, args_t *a, void **p) 2710 { 2711 draco_l3_test_t *dw = &dl3_work[unit]; 2712 draco_l3_testdata_t *dp = &dw->dlp_l3_ov; 2713 int rv; 2714 2715 dl3_setup(unit, dw); 2716 dp->ipv6 = 0; 2717 2718 /* Set working data to overflow */ 2719 dw->dlp_l3_cur = dp; 2720 2721 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2722 return rv; 2723 } else { 2724 *p = dp; 2725 } 2726 2727 return 0; 2728 } 2729 2730 int 2731 fb_l3ip6_hash_test_init(int unit, args_t *a, void **p) 2732 { 2733 draco_l3_test_t *dw = &dl3_work[unit]; 2734 draco_l3_testdata_t *dp = &dw->dlp_l3_hash; 2735 int rv; 2736 2737 dl3_setup(unit, dw); 2738 dp->ipv6 = 1; 2739 2740 /* Set working data to hash */ 2741 dw->dlp_l3_cur = dp; 2742 2743 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2744 return rv; 2745 } else { 2746 *p = dp; 2747 } 2748 2749 return 0; 2750 } 2751 2752 int 2753 fb_l3ip6_ov_test_init(int unit, args_t *a, void **p) 2754 { 2755 draco_l3_test_t *dw = &dl3_work[unit]; 2756 draco_l3_testdata_t *dp = &dw->dlp_l3_ov; 2757 int rv; 2758 2759 dl3_setup(unit, dw); 2760 dp->ipv6 = 1; 2761 2762 /* Set working data to overflow */ 2763 dw->dlp_l3_cur = dp; 2764 2765 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2766 return rv; 2767 } else { 2768 *p = dp; 2769 } 2770 2771 return 0; 2772 } 2773 2774 int 2775 fb_l3_ipv6_hash_test_init(int unit, args_t *a, void **p) 2776 { 2777 draco_l3_test_t *dw = &dl3_work[unit]; 2778 draco_l3_testdata_t *dp = &dw->dlp_l3_hash; 2779 int rv; 2780 2781 dl3_setup(unit, dw); 2782 dp->ipv6 = 1; 2783 2784 /* Set working data to hash */ 2785 dw->dlp_l3_cur = dp; 2786 2787 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2788 return rv; 2789 } else { 2790 *p = dp; 2791 } 2792 2793 return 0; 2794 } 2795 2796 int 2797 fb_l3_ipv6_ov_test_init(int unit, args_t *a, void **p) 2798 { 2799 draco_l3_test_t *dw = &dl3_work[unit]; 2800 draco_l3_testdata_t *dp = &dw->dlp_l3_ov; 2801 int rv; 2802 2803 dl3_setup(unit, dw); 2804 dp->ipv6 = 1; 2805 2806 /* Set working data to overflow */ 2807 dw->dlp_l3_cur = dp; 2808 2809 if ((rv = draco_l3_test_init(unit, dp, a)) < 0) { 2810 return rv; 2811 } else { 2812 *p = dp; 2813 } 2814 2815 return 0; 2816 } 2817 2818 #ifdef BCM_FIREBOLT_SUPPORT 2819 static int 2820 fb_l3_bucket_search(int unit, draco_l3_testdata_t *ad, 2821 int bucket, uint32 *expect, int dual, int bank) 2822 { 2823 uint32 entry[SOC_MAX_MEM_WORDS]; 2824 int i, ix, mem_table_index; 2825 int num_vbits; 2826 int num_ent_per_bucket, iter_count; 2827 soc_mem_t mem; 2828 int valid_ix; 2829 soc_field_t valid_f[] = {VALIDf, VALID_0f, VALID_1f, VALID_2f, VALID_3f}; 2830 int rv = -1; /* Assume failed unless we find it */ 2831 2832 #ifdef BCM_TRIUMPH_SUPPORT 2833 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 2834 int key_type; 2835 2836 key_type = soc_mem_field32_get(unit, L3_ENTRY_ONLYm, 2837 expect, KEY_TYPEf); 2838 switch (key_type) { 2839 case TR_L3_HASH_KEY_TYPE_V4UC: 2840 valid_ix = 0; 2841 num_vbits = 1; 2842 mem = L3_ENTRY_IPV4_UNICASTm; 2843 break; 2844 case TR_L3_HASH_KEY_TYPE_V4MC: 2845 valid_ix = 1; 2846 num_vbits = 2; 2847 mem = L3_ENTRY_IPV4_MULTICASTm; 2848 break; 2849 case TR_L3_HASH_KEY_TYPE_V6UC: 2850 valid_ix = 1; 2851 num_vbits = 2; 2852 mem = L3_ENTRY_IPV6_UNICASTm; 2853 break; 2854 case TR_L3_HASH_KEY_TYPE_V6MC: 2855 valid_ix = 1; 2856 num_vbits = 4; 2857 mem = L3_ENTRY_IPV6_MULTICASTm; 2858 break; 2859 default: 2860 return -1; 2861 } 2862 } else 2863 #endif /* BCM_TRIUMPH_SUPPORT */ 2864 if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, expect, V6f)) { 2865 valid_ix = 1; 2866 if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, expect, IPMCf)) { 2867 mem = L3_ENTRY_IPV6_MULTICASTm; 2868 num_vbits = 4; 2869 } else { 2870 mem = L3_ENTRY_IPV6_UNICASTm; 2871 num_vbits = 2; 2872 } 2873 } else { 2874 num_vbits = 1; 2875 valid_ix = 0; 2876 if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, expect, IPMCf)) { 2877 mem = L3_ENTRY_IPV4_MULTICASTm; 2878 } else { 2879 mem = L3_ENTRY_IPV4_UNICASTm; 2880 } 2881 } 2882 2883 num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits; 2884 if (dual == TRUE) { 2885 iter_count = num_ent_per_bucket / 2; 2886 } else { 2887 iter_count = num_ent_per_bucket; 2888 } 2889 2890 for (ix = 0; ix < iter_count; ix++) { 2891 mem_table_index = (bucket * num_ent_per_bucket) + ix; 2892 if (bank) { 2893 mem_table_index += (num_ent_per_bucket / 2); 2894 } 2895 2896 if (soc_mem_read(unit, mem, MEM_BLOCK_ANY, 2897 mem_table_index, entry) < 0) { 2898 test_error(unit, 2899 "Read ARL failed at bucket %d, offset %d\n", 2900 bucket, ix); 2901 break; 2902 } 2903 2904 for(i = 0; i < num_vbits; i++) { 2905 if (!soc_mem_field32_get(unit, mem, entry, valid_f[valid_ix + i])) { 2906 break; 2907 } 2908 } 2909 if (i != num_vbits) { 2910 /* Valid bit not set, blank entry */ 2911 continue; 2912 } 2913 2914 if (soc_mem_compare_key(unit, mem, expect, entry) == 0) { 2915 /* Found the matching entry */ 2916 rv = 0; 2917 break; 2918 } 2919 } 2920 2921 return rv; 2922 } 2923 2924 int 2925 _fb_l3ip4ucast_test_hash(int unit, args_t *a, void *p) 2926 { 2927 draco_l3_testdata_t *ad = p; 2928 uint32 entry[SOC_MAX_MEM_WORDS]; 2929 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 2930 soc_mem_t mem = L3_ENTRY_IPV4_UNICASTm; 2931 ip_addr_t dst_ip; 2932 ip_addr_t dst_ip_inc; 2933 bcm_vlan_t vid; 2934 int vid_inc; 2935 int r, rv = 0; 2936 int soft_bucket; 2937 int hard_index; 2938 int hard_bucket; 2939 int ix; 2940 int iterations; 2941 int vrf_id; 2942 int vrf_id_inc; 2943 int vrf_id_max = 0; 2944 int dual = FALSE; 2945 int bank, banks, bank_count = 1; 2946 2947 COMPILER_REFERENCE(a); 2948 vrf_id_max = SOC_VRF_MAX(unit); 2949 2950 dst_ip = ad->opt_base_ip; 2951 dst_ip_inc = ad->opt_ip_inc; 2952 vid = ad->opt_base_vid; 2953 vid_inc = ad->opt_vid_inc; 2954 2955 vrf_id = ad->opt_base_vrf_id; 2956 vrf_id_inc = ad->opt_vrf_id_inc; 2957 2958 if (ad->opt_verbose) { 2959 cli_out("Starting L3 hash test\n"); 2960 } 2961 2962 iterations = ad->opt_count; 2963 if (soc_feature(unit, soc_feature_dual_hash)) { 2964 if (ad->opt_dual_hash != -1) { 2965 dual = TRUE; 2966 bank_count = 2; 2967 } 2968 } 2969 2970 sal_memset (entry, 0, sizeof(entry)); 2971 #ifdef BCM_TRIUMPH_SUPPORT 2972 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 2973 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 2974 TR_L3_HASH_KEY_TYPE_V4UC); 2975 } else 2976 #endif /* BCM_TRIUMPH_SUPPORT */ 2977 { 2978 soc_mem_field32_set(unit, mem, entry, V6f, 0); 2979 soc_mem_field32_set(unit, mem, entry, IPMCf, 0); 2980 } 2981 soc_mem_field32_set(unit, mem, entry, VALIDf, 1); 2982 if (vrf_id_max) { 2983 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 2984 } 2985 2986 for (ix = 0; ix < iterations; ix++) { 2987 for (bank = 0; bank < bank_count; bank++) { 2988 soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip); 2989 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) { 2990 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 2991 } 2992 if (vrf_id_max) { 2993 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 2994 } 2995 soft_bucket = soc_fb_l3x2_entry_hash(unit, entry); 2996 banks = 0x3; 2997 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 2998 defined(BCM_TRX_SUPPORT) 2999 if (dual == TRUE) { 3000 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry); 3001 banks = (bank == 0) ? 2 : 1; 3002 } 3003 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3004 3005 if (ad->opt_verbose) { 3006 cli_out("Inserting "); 3007 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 3008 cli_out("\n"); 3009 if (dual) { 3010 cli_out("into bucket 0x%x (bank %d)\n", 3011 soft_bucket, bank); 3012 } else { 3013 cli_out("into bucket 0x%x\n", soft_bucket); 3014 } 3015 } 3016 3017 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3018 defined(BCM_TRX_SUPPORT) 3019 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 3020 #else /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3021 r = soc_mem_insert(unit, mem, COPYNO_ALL, entry); 3022 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3023 if (SOC_FAILURE(r)) { 3024 if (r == SOC_E_FULL) { 3025 /* Bucket overflow, just pass on */ 3026 continue; 3027 } else { 3028 test_error(unit, "L3 insert failed at bucket %d\n", soft_bucket); 3029 rv = -1; 3030 goto done; 3031 } 3032 } 3033 3034 /* Now we search for the entry */ 3035 hard_index = 0; 3036 if (soc_mem_search(unit, mem, COPYNO_ALL, 3037 &hard_index, entry, entry_lkup, 0) < 0) { 3038 test_error(unit, "Entry lookup failed\n"); 3039 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3040 goto done; 3041 } 3042 3043 hard_bucket = (hard_index >> (SOC_L3X_BUCKET_SIZE(unit) == 16 ? 4 : 3)); 3044 /* entries per bucket */ 3045 if (soft_bucket != hard_bucket) { 3046 test_error(unit, 3047 "Software Hash %d disagrees with Hardware Hash %d\n", 3048 soft_bucket, hard_bucket); 3049 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3050 goto done; 3051 } 3052 3053 /* Only do a quick check vs. expected bucket here */ 3054 if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) { 3055 test_error(unit, "Entry not found in bucket %d\n", soft_bucket); 3056 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3057 rv = -1; 3058 goto done; 3059 } 3060 3061 /* Clean up afterward */ 3062 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 3063 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket); 3064 rv = -1; 3065 goto done; 3066 } 3067 3068 } 3069 dst_ip += dst_ip_inc; 3070 vid += vid_inc; 3071 if (vid > DRACO_L3_VID_MAX) { 3072 vid = 1; 3073 } 3074 if (vrf_id_max) { 3075 vrf_id += vrf_id_inc; 3076 if (vrf_id > vrf_id_max) { 3077 vrf_id = 0; 3078 } 3079 } 3080 } 3081 3082 done: 3083 return rv; 3084 } 3085 3086 int 3087 _fb_l3ip4mcast_test_hash(int unit, args_t *a, void *p) 3088 { 3089 draco_l3_testdata_t *ad = p; 3090 uint32 entry[SOC_MAX_MEM_WORDS]; 3091 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 3092 soc_mem_t mem = L3_ENTRY_IPV4_MULTICASTm; 3093 ip_addr_t src_ip; 3094 ip_addr_t dst_ip; 3095 ip_addr_t src_ip_inc; 3096 ip_addr_t dst_ip_inc; 3097 bcm_vlan_t vid; 3098 int vid_inc; 3099 int r, rv = 0; 3100 int soft_bucket; 3101 int hard_index; 3102 int hard_bucket; 3103 int ix; 3104 int iterations; 3105 int vrf_id; 3106 int vrf_id_inc; 3107 int vrf_id_max = 0; 3108 int ent_per_bucket; 3109 int dual = FALSE; 3110 int bank, banks, bank_count = 1; 3111 3112 COMPILER_REFERENCE(a); 3113 #ifdef BCM_TRIDENT3_SUPPORT 3114 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 3115 mem = L3_ENTRY_DOUBLEm; 3116 } 3117 #endif /* BCM_TRIDENT3_SUPPORT */ 3118 3119 vrf_id_max = SOC_VRF_MAX(unit); 3120 3121 if (ad->opt_key_src_ip) { 3122 src_ip_inc = ad->opt_src_ip_inc; 3123 src_ip = ad->opt_src_ip; 3124 } else { 3125 src_ip_inc = 0; 3126 src_ip = 0; 3127 } 3128 dst_ip = ad->opt_base_ip; 3129 dst_ip_inc = ad->opt_ip_inc; 3130 vid = ad->opt_base_vid; 3131 vid_inc = ad->opt_vid_inc; 3132 3133 vrf_id = ad->opt_base_vrf_id; 3134 vrf_id_inc = ad->opt_vrf_id_inc; 3135 3136 /* Invalid IPMC/Unicast address checks required */ 3137 3138 if (ad->opt_verbose) { 3139 cli_out("Starting L3 hash test\n"); 3140 } 3141 3142 iterations = ad->opt_count; 3143 if (soc_feature(unit, soc_feature_dual_hash)) { 3144 if (ad->opt_dual_hash != -1) { 3145 dual = TRUE; 3146 bank_count = 2; 3147 } 3148 } 3149 3150 sal_memset (entry, 0, sizeof(entry)); 3151 #ifdef BCM_TRIDENT3_SUPPORT 3152 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 3153 l3_entry_key_attributes_entry_t l3_key_attr; 3154 3155 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 3156 TD3_L3_HASH_KEY_TYPE_V4MC); 3157 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 3158 TD3_L3_HASH_DATA_TYPE_V4MC); 3159 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3); 3160 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7); 3161 if (vrf_id_max) { 3162 soc_mem_field32_set(unit, mem, entry, IPV4MC__VRF_IDf, 1); 3163 } 3164 3165 /* Set L3 Entry Key Attributes */ 3166 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 3167 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 3168 BUCKET_MODEf, 1); 3169 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 3170 KEY_BASE_WIDTHf, 0); 3171 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 3172 KEY_WIDTHf, 23); 3173 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 3174 DATA_BASE_WIDTHf, 1); 3175 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 3176 HASH_LSB_OFFSETf, 5); 3177 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 3178 TD3_L3_HASH_KEY_TYPE_V4MC, 3179 (uint32*)&l3_key_attr) < 0) { 3180 test_error(unit, "L3 Entry Key Attr setting failed\n"); 3181 goto done; 3182 } 3183 } else 3184 #endif 3185 { 3186 #ifdef BCM_TRIUMPH_SUPPORT 3187 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3188 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 3189 TR_L3_HASH_KEY_TYPE_V4MC); 3190 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 3191 TR_L3_HASH_KEY_TYPE_V4MC); 3192 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 3193 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 3194 } else 3195 #endif 3196 { 3197 soc_mem_field32_set(unit, mem, entry, V6f, 0); 3198 soc_mem_field32_set(unit, mem, entry, IPMCf, 1); 3199 soc_mem_field32_set(unit, mem, entry, VALIDf, 1); 3200 } 3201 } 3202 if (vrf_id_max) { 3203 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 3204 } 3205 for (ix = 0; ix < iterations; ix++) { 3206 for (bank = 0; bank < bank_count; bank++) { 3207 soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip); 3208 soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip); 3209 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 3210 if (vrf_id_max) { 3211 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 3212 } 3213 3214 soft_bucket = soc_fb_l3x2_entry_hash(unit, entry); 3215 banks = 0x3; 3216 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3217 defined(BCM_TRX_SUPPORT) 3218 if (dual == TRUE) { 3219 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry); 3220 banks = (bank == 0) ? 2 : 1; 3221 } 3222 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3223 3224 if (ad->opt_verbose) { 3225 cli_out("Inserting "); 3226 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 3227 if (dual) { 3228 cli_out("into bucket 0x%x (bank %d)", 3229 soft_bucket, bank); 3230 } else { 3231 cli_out("into bucket 0x%x", soft_bucket); 3232 } 3233 } 3234 3235 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3236 defined(BCM_TRX_SUPPORT) 3237 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 3238 #else /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3239 r = soc_mem_insert(unit, mem, COPYNO_ALL, entry); 3240 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3241 if (SOC_FAILURE(r)) { 3242 if (r == SOC_E_FULL) { 3243 /* Bucket overflow, just pass on */ 3244 continue; 3245 } else { 3246 test_error(unit, 3247 "L3 insert failed at bucket %d\n", soft_bucket); 3248 rv = -1; 3249 goto done; 3250 } 3251 } 3252 3253 /* Now we search for the entry */ 3254 hard_index = 0; 3255 if (soc_mem_search(unit, mem, COPYNO_ALL, 3256 &hard_index, entry, entry_lkup, 0) < 0) { 3257 test_error(unit, "Entry lookup failed\n"); 3258 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3259 goto done; 3260 } 3261 3262 #ifdef BCM_TRIUMPH_SUPPORT 3263 if (SOC_IS_TR_VL(unit)) { 3264 ent_per_bucket = 8; 3265 } else 3266 #endif 3267 if (SOC_L3X_BUCKET_SIZE(unit) == 16) { 3268 ent_per_bucket = 16; 3269 } else { 3270 ent_per_bucket = 8; 3271 } 3272 hard_bucket = (hard_index / ent_per_bucket); /* entries per bucket */ 3273 if (soft_bucket != hard_bucket) { 3274 test_error(unit, 3275 "Software Hash %d disagrees with Hardware Hash %d\n", 3276 soft_bucket, hard_bucket); 3277 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3278 goto done; 3279 } 3280 3281 /* Only do a quick check vs. expected bucket here */ 3282 if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) { 3283 test_error(unit, "Entry not found in bucket %d\n", soft_bucket); 3284 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3285 rv = -1; 3286 goto done; 3287 } 3288 3289 /* Clean up afterward */ 3290 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 3291 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket); 3292 rv = -1; 3293 goto done; 3294 } 3295 3296 src_ip += src_ip_inc; 3297 dst_ip += dst_ip_inc; 3298 vid += vid_inc; 3299 if (vid > DRACO_L3_VID_MAX) { 3300 vid = 1; 3301 } 3302 if (vrf_id_max) { 3303 vrf_id += vrf_id_inc; 3304 if (vrf_id > vrf_id_max) { 3305 vrf_id = 0; 3306 } 3307 } 3308 } 3309 } 3310 3311 done: 3312 return rv; 3313 } 3314 3315 int 3316 _fb_l3ip6ucast_test_hash(int unit, args_t *a, void *p) 3317 { 3318 draco_l3_testdata_t *ad = p; 3319 uint32 entry[SOC_MAX_MEM_WORDS]; 3320 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 3321 soc_mem_t mem = L3_ENTRY_IPV6_UNICASTm; 3322 ip6_addr_t dst_ip; 3323 uint32 ip_tmp[2]; 3324 int dst_ip_inc; 3325 int r, rv = 0; 3326 int soft_bucket; 3327 int hard_index; 3328 int hard_bucket; 3329 int ix; 3330 int iterations; 3331 int vrf_id; 3332 int vrf_id_inc; 3333 int vrf_id_max = 0; 3334 int dual = FALSE; 3335 int bank, banks, bank_count = 1; 3336 3337 COMPILER_REFERENCE(a); 3338 3339 vrf_id_max = SOC_VRF_MAX(unit); 3340 3341 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 3342 dst_ip_inc = ad->opt_ip6_inc; 3343 vrf_id = ad->opt_base_vrf_id; 3344 vrf_id_inc = ad->opt_vrf_id_inc; 3345 3346 if (ad->opt_verbose) { 3347 cli_out("Starting L3 hash test\n"); 3348 } 3349 3350 iterations = ad->opt_count; 3351 if (soc_feature(unit, soc_feature_dual_hash)) { 3352 if (ad->opt_dual_hash != -1) { 3353 dual = TRUE; 3354 bank_count = 2; 3355 } 3356 } 3357 3358 sal_memset (entry, 0, sizeof(entry)); 3359 #ifdef BCM_TRIUMPH_SUPPORT 3360 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3361 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 3362 TR_L3_HASH_KEY_TYPE_V6UC); 3363 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 3364 TR_L3_HASH_KEY_TYPE_V6UC); 3365 if (vrf_id_max) { 3366 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 3367 } 3368 } else 3369 #endif /* BCM_TRIUMPH_SUPPORT */ 3370 { 3371 soc_mem_field32_set(unit, mem, entry, V6_0f, 1); 3372 soc_mem_field32_set(unit, mem, entry, V6_1f, 1); 3373 soc_mem_field32_set(unit, mem, entry, IPMC_0f, 0); 3374 soc_mem_field32_set(unit, mem, entry, IPMC_1f, 0); 3375 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3376 defined(BCM_SCORPION_SUPPORT) 3377 if (vrf_id_max) { 3378 soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1); 3379 soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1); 3380 } 3381 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 3382 } 3383 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 3384 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 3385 for (ix = 0; ix < iterations; ix++) { 3386 for (bank = 0; bank < bank_count; bank++) { 3387 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 3388 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 3389 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 3390 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 3391 soc_mem_field_set(unit, mem, entry, 3392 IP_ADDR_LWR_64f, ip_tmp); 3393 3394 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 3395 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 3396 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 3397 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 3398 soc_mem_field_set(unit, mem, entry, 3399 IP_ADDR_UPR_64f, ip_tmp); 3400 3401 #ifdef BCM_TRIUMPH_SUPPORT 3402 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3403 if (vrf_id_max) { 3404 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 3405 } 3406 } else 3407 #endif /* BCM_TRIUMPH_SUPPORT */ 3408 { 3409 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3410 defined(BCM_SCORPION_SUPPORT) 3411 if (vrf_id_max) { 3412 soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, vrf_id); 3413 soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, vrf_id); 3414 } 3415 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 3416 } 3417 soft_bucket = soc_fb_l3x2_entry_hash(unit, entry); 3418 banks = 0x3; 3419 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3420 defined(BCM_TRX_SUPPORT) 3421 if (dual == TRUE) { 3422 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry); 3423 banks = (bank == 0) ? 2 : 1; 3424 } 3425 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3426 3427 if (ad->opt_verbose) { 3428 cli_out("Inserting "); 3429 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 3430 if (dual) { 3431 cli_out("into bucket 0x%x (bank %d)", soft_bucket, bank); 3432 } else { 3433 cli_out("into bucket 0x%x", soft_bucket); 3434 } 3435 } 3436 3437 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3438 defined(BCM_TRX_SUPPORT) 3439 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 3440 #else /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3441 r = soc_mem_insert(unit, mem, COPYNO_ALL, entry); 3442 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3443 if (SOC_FAILURE(r)) { 3444 if (r == SOC_E_FULL) { 3445 /* Bucket overflow, just pass on */ 3446 continue; 3447 } else { 3448 test_error(unit, "L3 insert failed at bucket %d\n", soft_bucket); 3449 rv = -1; 3450 goto done; 3451 } 3452 } 3453 3454 /* Now we search for the entry */ 3455 hard_index = 0; 3456 if (soc_mem_search(unit, mem, COPYNO_ALL, 3457 &hard_index, entry, entry_lkup, 0) < 0) { 3458 test_error(unit, "Entry lookup failed\n"); 3459 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3460 goto done; 3461 } 3462 3463 hard_bucket = (hard_index >> (SOC_L3X_BUCKET_SIZE(unit) == 16 ? 3 : 2)); 3464 /* entries per bucket */ 3465 if (soft_bucket != hard_bucket) { 3466 test_error(unit, 3467 "Software Hash %d disagrees with Hardware Hash %d\n", 3468 soft_bucket, hard_bucket); 3469 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3470 goto done; 3471 } 3472 3473 /* Only do a quick check vs. expected bucket here */ 3474 if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) { 3475 test_error(unit, "Entry not found in bucket %d\n", soft_bucket); 3476 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3477 rv = -1; 3478 goto done; 3479 } 3480 3481 /* Clean up afterward */ 3482 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 3483 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket); 3484 rv = -1; 3485 goto done; 3486 } 3487 increment_ip6addr(dst_ip, 15, dst_ip_inc); 3488 if (vrf_id_max) { 3489 vrf_id += vrf_id_inc; 3490 if (vrf_id > vrf_id_max) { 3491 vrf_id = 0; 3492 } 3493 } 3494 } 3495 } 3496 3497 done: 3498 return rv; 3499 } 3500 3501 int 3502 _fb_l3ip6mcast_test_hash(int unit, args_t *a, void *p) 3503 { 3504 draco_l3_testdata_t *ad = p; 3505 uint32 entry[SOC_MAX_MEM_WORDS]; 3506 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 3507 soc_mem_t mem = L3_ENTRY_IPV6_MULTICASTm; 3508 ip6_addr_t src_ip; 3509 ip6_addr_t dst_ip; 3510 uint32 ip_tmp[2]; 3511 int src_ip_inc; 3512 int dst_ip_inc; 3513 bcm_vlan_t vid; 3514 int vid_inc; 3515 int r, rv = 0; 3516 int soft_bucket; 3517 int hard_index; 3518 int hard_bucket; 3519 int ix; 3520 int iterations; 3521 int vrf_id; 3522 int vrf_id_inc; 3523 int vrf_id_max = 0; 3524 int dual = FALSE; 3525 int bank, banks, bank_count = 1; 3526 3527 COMPILER_REFERENCE(a); 3528 vrf_id_max = SOC_VRF_MAX(unit); 3529 3530 #ifdef BCM_TRIDENT3_SUPPORT 3531 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 3532 mem = L3_ENTRY_QUADm; 3533 } 3534 #endif 3535 if (ad->opt_key_src_ip) { 3536 memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t)); 3537 src_ip_inc = ad->opt_src_ip6_inc; 3538 } else { 3539 sal_memset (src_ip, 0, sizeof(src_ip)); 3540 src_ip_inc = 0; 3541 } 3542 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 3543 dst_ip_inc = ad->opt_ip6_inc; 3544 vid = ad->opt_base_vid; 3545 vid_inc = ad->opt_vid_inc; 3546 vrf_id = ad->opt_base_vrf_id; 3547 vrf_id_inc = ad->opt_vrf_id_inc; 3548 3549 /* Invalid IPMC/Unicast address checks required */ 3550 3551 if (ad->opt_verbose) { 3552 cli_out("Starting L3 hash test\n"); 3553 } 3554 3555 iterations = ad->opt_count; 3556 if (soc_feature(unit, soc_feature_dual_hash)) { 3557 if (ad->opt_dual_hash != -1) { 3558 dual = TRUE; 3559 bank_count = 2; 3560 } 3561 } 3562 3563 sal_memset (entry, 0, sizeof(entry)); 3564 #ifdef BCM_TRIUMPH_SUPPORT 3565 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3566 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 3567 TR_L3_HASH_KEY_TYPE_V6MC); 3568 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 3569 TR_L3_HASH_KEY_TYPE_V6MC); 3570 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f, 3571 TR_L3_HASH_KEY_TYPE_V6MC); 3572 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f, 3573 TR_L3_HASH_KEY_TYPE_V6MC); 3574 if (vrf_id_max) { 3575 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 3576 } 3577 } else 3578 #endif /* BCM_TRIUMPH_SUPPORT */ 3579 { 3580 soc_mem_field32_set(unit, mem, entry, V6_0f, 1); 3581 soc_mem_field32_set(unit, mem, entry, V6_1f, 1); 3582 soc_mem_field32_set(unit, mem, entry, V6_2f, 1); 3583 soc_mem_field32_set(unit, mem, entry, V6_3f, 1); 3584 soc_mem_field32_set(unit, mem, entry, IPMC_0f, 1); 3585 soc_mem_field32_set(unit, mem, entry, IPMC_1f, 1); 3586 soc_mem_field32_set(unit, mem, entry, IPMC_2f, 1); 3587 soc_mem_field32_set(unit, mem, entry, IPMC_3f, 1); 3588 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||\ 3589 defined(BCM_SCORPION_SUPPORT) 3590 if (vrf_id_max) { 3591 soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1); 3592 soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1); 3593 soc_mem_field32_set(unit, mem, entry, VRF_ID_2f, 1); 3594 soc_mem_field32_set(unit, mem, entry, VRF_ID_3f, 1); 3595 } 3596 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 3597 } 3598 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 3599 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 3600 soc_mem_field32_set(unit, mem, entry, VALID_2f, 1); 3601 soc_mem_field32_set(unit, mem, entry, VALID_3f, 1); 3602 for (ix = 0; ix < iterations; ix++) { 3603 for (bank = 0; bank < bank_count; bank++) { 3604 dst_ip[0] = 0; 3605 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 3606 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 3607 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 3608 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 3609 soc_mem_field_set(unit, mem, entry, 3610 GROUP_IP_ADDR_LWR_64f, ip_tmp); 3611 3612 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 3613 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 3614 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 3615 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 3616 soc_mem_field_set(unit, mem, entry, 3617 GROUP_IP_ADDR_UPR_56f, ip_tmp); 3618 3619 ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) | 3620 (src_ip[10] << 8) | (src_ip[11] << 0)); 3621 ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) | 3622 (src_ip[14] << 8) | (src_ip[15] << 0)); 3623 soc_mem_field_set(unit, mem, entry, 3624 SOURCE_IP_ADDR_LWR_64f, ip_tmp); 3625 3626 ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) | 3627 (src_ip[2] << 8) | (src_ip[3] << 0)); 3628 ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) | 3629 (src_ip[6] << 8) | (src_ip[7] << 0)); 3630 soc_mem_field_set(unit, mem, entry, 3631 SOURCE_IP_ADDR_UPR_64f, ip_tmp); 3632 3633 3634 #ifdef BCM_TRIUMPH_SUPPORT 3635 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3636 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 3637 if (vrf_id_max) { 3638 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 3639 } 3640 } else 3641 #endif /* BCM_TRIUMPH_SUPPORT */ 3642 { 3643 soc_mem_field32_set(unit, mem, entry, VLAN_ID_0f, vid); 3644 soc_mem_field32_set(unit, mem, entry, VLAN_ID_1f, vid); 3645 soc_mem_field32_set(unit, mem, entry, VLAN_ID_2f, vid); 3646 soc_mem_field32_set(unit, mem, entry, VLAN_ID_3f, vid); 3647 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3648 defined(BCM_SCORPION_SUPPORT) 3649 if (vrf_id_max) { 3650 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id); 3651 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id); 3652 soc_mem_field32_set(unit, mem,entry, VRF_ID_2f, vrf_id); 3653 soc_mem_field32_set(unit, mem,entry, VRF_ID_3f, vrf_id); 3654 } 3655 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 3656 } 3657 soft_bucket = soc_fb_l3x2_entry_hash(unit, entry); 3658 banks = 0x3; 3659 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3660 defined(BCM_TRX_SUPPORT) 3661 if (dual == TRUE) { 3662 soft_bucket = soc_fb_l3x_bank_entry_hash(unit, bank, entry); 3663 banks = (bank == 0) ? 2 : 1; 3664 } 3665 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3666 3667 if (ad->opt_verbose) { 3668 cli_out("Inserting "); 3669 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 3670 if (dual) { 3671 cli_out("into bucket 0x%x (bank %d)", soft_bucket, bank); 3672 } else { 3673 cli_out("into bucket 0x%x", soft_bucket); 3674 } 3675 } 3676 3677 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 3678 defined(BCM_TRX_SUPPORT) 3679 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 3680 #else /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3681 r = soc_mem_insert(unit, mem, COPYNO_ALL, entry); 3682 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 3683 if (SOC_FAILURE(r)) { 3684 if (r == SOC_E_FULL) { 3685 /* Bucket overflow, just pass on */ 3686 continue; 3687 } else { 3688 test_error(unit, 3689 "L3 insert failed at bucket %d\n", soft_bucket); 3690 rv = -1; 3691 goto done; 3692 } 3693 } 3694 3695 /* Now we search for the entry */ 3696 hard_index = 0; 3697 if (soc_mem_search(unit, mem, COPYNO_ALL, 3698 &hard_index, entry, entry_lkup, 0) < 0) { 3699 test_error(unit, "Entry lookup failed\n"); 3700 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3701 goto done; 3702 } 3703 3704 hard_bucket = (hard_index >> (SOC_L3X_BUCKET_SIZE(unit) == 16 ? 2 : 1)); 3705 /* entries per bucket */ 3706 if (soft_bucket != hard_bucket) { 3707 test_error(unit, 3708 "Software Hash %d disagrees with Hardware Hash %d\n", 3709 soft_bucket, hard_bucket); 3710 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3711 goto done; 3712 } 3713 3714 /* Only do a quick check vs. expected bucket here */ 3715 if (fb_l3_bucket_search(unit, ad, soft_bucket, entry, dual, bank) < 0) { 3716 test_error(unit, "Entry not found in bucket %d\n", soft_bucket); 3717 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 3718 rv = -1; 3719 goto done; 3720 } 3721 3722 /* Clean up afterward */ 3723 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 3724 test_error(unit, "L3 delete failed at bucket %d\n", soft_bucket); 3725 rv = -1; 3726 goto done; 3727 } 3728 3729 increment_ip6addr(src_ip, 15, src_ip_inc); 3730 increment_ip6addr(dst_ip, 15, dst_ip_inc); 3731 vid += vid_inc; 3732 if (vid > DRACO_L3_VID_MAX) { 3733 vid = 1; 3734 } 3735 if (vrf_id_max) { 3736 vrf_id += vrf_id_inc; 3737 if (vrf_id > vrf_id_max) { 3738 vrf_id = 0; 3739 } 3740 } 3741 } 3742 } 3743 3744 done: 3745 return rv; 3746 } 3747 3748 STATIC uint32 entry_tmp[SOC_L3X_MAX_BUCKET_SIZE][SOC_MAX_MEM_WORDS]; 3749 int 3750 _fb_l3ip4ucast_test_ov(int unit, args_t *a, void *p) 3751 { 3752 uint32 entry[SOC_MAX_MEM_WORDS]; 3753 soc_mem_t mem = L3_ENTRY_IPV4_UNICASTm; 3754 int num_ent_per_bucket; 3755 int num_vbits; 3756 int num_buckets; 3757 ip_addr_t dst_ip; 3758 bcm_vlan_t vid; 3759 int vid_inc; 3760 int r, rv = 0; 3761 int bucket; 3762 int i, j; 3763 int iterations; 3764 draco_l3_testdata_t *ad = p; 3765 int vrf_id; 3766 int vrf_id_inc; 3767 int vrf_id_max = 0; 3768 3769 3770 COMPILER_REFERENCE(a); 3771 vrf_id_max = SOC_VRF_MAX(unit); 3772 3773 num_vbits = 1; 3774 num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits; 3775 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 3776 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 3777 3778 dst_ip = ad->opt_base_ip; 3779 vid = ad->opt_base_vid; 3780 vid_inc = ad->opt_vid_inc; 3781 vrf_id = ad->opt_base_vrf_id; 3782 vrf_id_inc = ad->opt_vrf_id_inc; 3783 3784 sal_memset (entry, 0, sizeof(entry)); 3785 #ifdef BCM_TRIUMPH_SUPPORT 3786 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3787 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 3788 TR_L3_HASH_KEY_TYPE_V4UC); 3789 } else 3790 #endif /* BCM_TRIUMPH_SUPPORT */ 3791 { 3792 soc_mem_field32_set(unit, mem, entry, V6f, 0); 3793 soc_mem_field32_set(unit, mem, entry, IPMCf, 0); 3794 } 3795 soc_mem_field32_set(unit, mem, entry, VALIDf, 1); 3796 if (vrf_id_max) { 3797 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 3798 } 3799 3800 while (iterations--) { 3801 soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip); 3802 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) { 3803 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 3804 } 3805 if (vrf_id_max) { 3806 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 3807 } 3808 3809 bucket = soc_fb_l3x2_entry_hash(unit, entry); 3810 3811 for (i = 0; i < num_ent_per_bucket; i++) { 3812 memcpy(entry_tmp[i], entry, sizeof(entry)); 3813 if (ad->opt_verbose) { 3814 cli_out("Inserting "); 3815 soc_mem_entry_dump(unit, mem, entry_tmp[i], BSL_LSS_CLI); 3816 cli_out("into bucket 0x%x\n", bucket); 3817 } 3818 3819 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) { 3820 if (r == SOC_E_FULL) { 3821 /* Already full, stop wasting time */ 3822 break; 3823 } else { 3824 test_error(unit, "L3 insert failed at bucket %d\n", bucket); 3825 rv = -1; 3826 goto done; 3827 } 3828 } 3829 3830 /* Increment key by number of buckets in the table */ 3831 dst_ip += num_buckets; 3832 vid += vid_inc; 3833 if (vid > DRACO_L3_VID_MAX) { 3834 vid = 1; 3835 } 3836 if (vrf_id_max) { 3837 vrf_id += vrf_id_inc; 3838 if (vrf_id > vrf_id_max) { 3839 vrf_id = 0; 3840 } 3841 } 3842 soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip); 3843 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) { 3844 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 3845 } 3846 if (vrf_id_max) { 3847 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 3848 } 3849 } 3850 3851 if (ad->opt_verbose) { 3852 cli_out("Inserting %d entry in bucket %d, should fail\n", 3853 num_ent_per_bucket, bucket); 3854 } 3855 3856 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 3857 if (r != SOC_E_FULL) { 3858 test_error(unit, "L3 insert failed\n"); 3859 rv = -1; 3860 goto done; 3861 } 3862 } else { 3863 test_error(unit, "L3 insert to full bucket succeeded\n"); 3864 rv = -1; 3865 goto done; 3866 } 3867 3868 if (ad->opt_verbose) { 3869 cli_out("Verifying installed entries\n"); 3870 } 3871 3872 /* Verify bucket contains added entries */ 3873 for (j = 0; j < i; j++) { 3874 if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) { 3875 test_error(unit, "L3 entry missing at bucket %d\n", bucket); 3876 rv = -1; 3877 goto done; 3878 } 3879 } 3880 3881 if (ad->opt_verbose) { 3882 cli_out("Cleaning bucket %d\n", bucket); 3883 } 3884 3885 /* Remove the entries that we added */ 3886 for (j = 0; j < i; j++) { 3887 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) { 3888 test_error(unit, "L3 delete failed at bucket %d\n", bucket); 3889 rv = -1; 3890 goto done; 3891 } 3892 } 3893 3894 /* Do Next bucket */ 3895 dst_ip += 1; 3896 vid += vid_inc; 3897 if (vid > DRACO_L3_VID_MAX) { 3898 vid = 1; 3899 } 3900 if (vrf_id_max) { 3901 vrf_id += vrf_id_inc; 3902 if (vrf_id > vrf_id_max) { 3903 vrf_id = 0; 3904 } 3905 } 3906 } 3907 3908 done: 3909 3910 return rv; 3911 } 3912 3913 int 3914 _fb_l3ip4mcast_test_ov(int unit, args_t *a, void *p) 3915 { 3916 uint32 entry[SOC_MAX_MEM_WORDS]; 3917 soc_mem_t mem = L3_ENTRY_IPV4_MULTICASTm; 3918 int num_ent_per_bucket; 3919 int num_vbits; 3920 int num_buckets; 3921 ip_addr_t src_ip; 3922 ip_addr_t dst_ip; 3923 int src_ip_inc; 3924 bcm_vlan_t vid; 3925 int vid_inc; 3926 int r, rv = 0; 3927 int bucket; 3928 int i, j; 3929 int iterations; 3930 draco_l3_testdata_t *ad = p; 3931 int vrf_id; 3932 int vrf_id_inc; 3933 int vrf_id_max = 0; 3934 uint32 hash_read; 3935 3936 3937 COMPILER_REFERENCE(a); 3938 num_vbits = 1; 3939 3940 vrf_id_max = SOC_VRF_MAX(unit); 3941 #ifdef BCM_TRIUMPH_SUPPORT 3942 if (SOC_IS_TR_VL(unit)) { 3943 num_vbits = 2; 3944 } 3945 #endif 3946 3947 num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits; 3948 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 3949 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 3950 3951 if (ad->opt_key_src_ip) { 3952 src_ip_inc = ad->opt_src_ip_inc; 3953 src_ip = ad->opt_src_ip; 3954 } else { 3955 src_ip_inc = 0; 3956 src_ip = 0; 3957 } 3958 dst_ip = ad->opt_base_ip; 3959 vid = ad->opt_base_vid; 3960 vid_inc = ad->opt_vid_inc; 3961 vrf_id = ad->opt_base_vrf_id; 3962 vrf_id_inc = ad->opt_vrf_id_inc; 3963 3964 3965 sal_memset (entry, 0, sizeof(entry)); 3966 #ifdef BCM_TRIUMPH_SUPPORT 3967 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 3968 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 3969 TR_L3_HASH_KEY_TYPE_V4MC); 3970 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 3971 TR_L3_HASH_KEY_TYPE_V4MC); 3972 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 3973 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 3974 } else 3975 #endif /* BCM_TRIUMPH_SUPPORT */ 3976 { 3977 soc_mem_field32_set(unit, mem, entry, V6f, 0); 3978 soc_mem_field32_set(unit, mem, entry, IPMCf, 1); 3979 soc_mem_field32_set(unit, mem, entry, VALIDf, 1); 3980 } 3981 if (vrf_id_max) { 3982 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 3983 } 3984 while (iterations--) { 3985 soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip); 3986 soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip); 3987 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 3988 if (vrf_id_max) { 3989 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 3990 } 3991 3992 bucket = soc_fb_l3x2_entry_hash(unit, entry); 3993 3994 for (i = 0; i < num_ent_per_bucket; i++) { 3995 memcpy(entry_tmp[i], entry, sizeof(entry)); 3996 if (ad->opt_verbose) { 3997 cli_out("Inserting "); 3998 soc_mem_entry_dump(unit, mem, entry_tmp[i], BSL_LSS_CLI); 3999 cli_out("into bucket 0x%x\n", bucket); 4000 } 4001 4002 if (READ_HASH_CONTROLr(unit, &hash_read) < 0) { 4003 test_error(unit, "Hash select read failed\n"); 4004 goto done; 4005 } 4006 4007 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) { 4008 if (r == SOC_E_FULL) { 4009 /* Already full, stop wasting time */ 4010 break; 4011 } else { 4012 test_error(unit, "L3 insert failed at bucket %d\n", bucket); 4013 rv = -1; 4014 goto done; 4015 } 4016 } 4017 4018 if (READ_HASH_CONTROLr(unit, &hash_read) < 0) { 4019 test_error(unit, "Hash select read failed\n"); 4020 goto done; 4021 } 4022 4023 /* Increment key by number of buckets in the table */ 4024 dst_ip += num_buckets; 4025 src_ip += src_ip_inc; 4026 vid += vid_inc; 4027 if (vid > DRACO_L3_VID_MAX) { 4028 vid = 1; 4029 } 4030 if (vrf_id_max) { 4031 vrf_id += vrf_id_inc; 4032 if (vrf_id > vrf_id_max) { 4033 vrf_id = 0; 4034 } 4035 } 4036 soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip); 4037 soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip); 4038 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 4039 if (vrf_id_max) { 4040 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 4041 } 4042 } 4043 4044 if (ad->opt_verbose) { 4045 cli_out("Inserting %d entry in bucket %d, should fail\n", 4046 num_ent_per_bucket, bucket); 4047 } 4048 4049 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 4050 if (r != SOC_E_FULL) { 4051 test_error(unit, "L3 insert failed\n"); 4052 rv = -1; 4053 goto done; 4054 } 4055 } else { 4056 test_error(unit, "L3 insert to full bucket succeeded\n"); 4057 rv = -1; 4058 goto done; 4059 } 4060 4061 if (ad->opt_verbose) { 4062 cli_out("Verifying installed entries\n"); 4063 } 4064 4065 /* Verify bucket contains added entries */ 4066 for (j = 0; j < i; j++) { 4067 if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) { 4068 test_error(unit, "L3 entry missing at bucket %d\n", bucket); 4069 rv = -1; 4070 goto done; 4071 } 4072 } 4073 4074 if (ad->opt_verbose) { 4075 cli_out("Cleaning bucket %d\n", bucket); 4076 } 4077 4078 /* Remove the entries that we added */ 4079 for (j = 0; j < i; j++) { 4080 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) { 4081 test_error(unit, "L3 delete failed at bucket %d\n", bucket); 4082 rv = -1; 4083 goto done; 4084 } 4085 } 4086 4087 /* Do Next bucket */ 4088 dst_ip += 1; 4089 src_ip += src_ip_inc; 4090 vid += vid_inc; 4091 if (vid > DRACO_L3_VID_MAX) { 4092 vid = 1; 4093 } 4094 if (vrf_id_max) { 4095 vrf_id += vrf_id_inc; 4096 if (vrf_id > vrf_id_max) { 4097 vrf_id = 0; 4098 } 4099 } 4100 } 4101 4102 done: 4103 4104 return rv; 4105 } 4106 4107 int 4108 _fb_l3ip6ucast_test_ov(int unit, args_t *a, void *p) 4109 { 4110 uint32 entry[SOC_MAX_MEM_WORDS]; 4111 soc_mem_t mem = L3_ENTRY_IPV6_UNICASTm; 4112 int num_ent_per_bucket; 4113 int num_vbits; 4114 int num_buckets; 4115 ip6_addr_t dst_ip; 4116 uint32 ip_tmp[2]; 4117 bcm_vlan_t vid; 4118 int vid_inc; 4119 int r, rv = 0; 4120 int bucket; 4121 int i, j; 4122 int iterations; 4123 draco_l3_testdata_t *ad = p; 4124 int vrf_id; 4125 int vrf_id_inc; 4126 int vrf_id_max = 0; 4127 4128 COMPILER_REFERENCE(a); 4129 vrf_id_max = SOC_VRF_MAX(unit); 4130 4131 num_vbits = 2; 4132 num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits; 4133 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 4134 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 4135 4136 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 4137 vid = ad->opt_base_vid; 4138 vid_inc = ad->opt_vid_inc; 4139 vrf_id = ad->opt_base_vrf_id; 4140 vrf_id_inc = ad->opt_vrf_id_inc; 4141 sal_memset (entry, 0, sizeof(entry)); 4142 #ifdef BCM_TRIUMPH_SUPPORT 4143 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 4144 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 4145 TR_L3_HASH_KEY_TYPE_V6UC); 4146 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 4147 TR_L3_HASH_KEY_TYPE_V6UC); 4148 if (vrf_id_max) { 4149 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 4150 } 4151 } else 4152 #endif /* BCM_TRIUMPH_SUPPORT */ 4153 { 4154 soc_mem_field32_set(unit, mem, entry, V6_0f, 1); 4155 soc_mem_field32_set(unit, mem, entry, V6_1f, 1); 4156 soc_mem_field32_set(unit, mem, entry, IPMC_0f, 0); 4157 soc_mem_field32_set(unit, mem, entry, IPMC_1f, 0); 4158 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 4159 defined(BCM_SCORPION_SUPPORT) 4160 if (vrf_id_max) { 4161 soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1); 4162 soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1); 4163 } 4164 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 4165 } 4166 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 4167 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 4168 while (iterations--) { 4169 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 4170 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 4171 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 4172 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 4173 soc_mem_field_set(unit, mem, entry, 4174 IP_ADDR_LWR_64f, ip_tmp); 4175 4176 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 4177 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 4178 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 4179 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 4180 soc_mem_field_set(unit, mem, entry, 4181 IP_ADDR_UPR_64f, ip_tmp); 4182 #ifdef BCM_TRIUMPH_SUPPORT 4183 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 4184 if (vrf_id_max) { 4185 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 4186 } 4187 } else 4188 #endif /* BCM_TRIUMPH_SUPPORT */ 4189 { 4190 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) ||\ 4191 defined(BCM_SCORPION_SUPPORT) 4192 if (vrf_id_max) { 4193 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id); 4194 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id); 4195 } 4196 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 4197 } 4198 bucket = soc_fb_l3x2_entry_hash(unit, entry); 4199 4200 for (i = 0; i < num_ent_per_bucket; i++) { 4201 if (ad->opt_verbose) { 4202 cli_out("Inserting "); 4203 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 4204 cli_out("into bucket 0x%x\n", bucket); 4205 } 4206 4207 memcpy(entry_tmp[i], entry, sizeof(entry)); 4208 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) { 4209 if (r == SOC_E_FULL) { 4210 /* Already full, stop wasting time */ 4211 break; 4212 } else { 4213 test_error(unit, "L3 insert failed at bucket %d\n", bucket); 4214 rv = -1; 4215 goto done; 4216 } 4217 } 4218 4219 /* Increment key by number of buckets in the table */ 4220 increment_ip6addr(dst_ip, 15, num_buckets); 4221 vid += vid_inc; 4222 if (vid > DRACO_L3_VID_MAX) { 4223 vid = 1; 4224 } 4225 if (vrf_id_max) { 4226 vrf_id += vrf_id_inc; 4227 if (vrf_id > vrf_id_max) { 4228 vrf_id = 0; 4229 } 4230 } 4231 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 4232 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 4233 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 4234 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 4235 soc_mem_field_set(unit, mem, entry, 4236 IP_ADDR_LWR_64f, ip_tmp); 4237 4238 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 4239 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 4240 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 4241 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 4242 soc_mem_field_set(unit, mem, entry, 4243 IP_ADDR_UPR_64f, ip_tmp); 4244 4245 if (vrf_id_max) { 4246 #ifdef BCM_TRIUMPH_SUPPORT 4247 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 4248 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 4249 } else 4250 #endif /* BCM_TRIUMPH_SUPPORT */ 4251 { 4252 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 4253 defined(BCM_SCORPION_SUPPORT) 4254 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id); 4255 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id); 4256 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 4257 } 4258 } 4259 } 4260 4261 if (ad->opt_verbose) { 4262 cli_out("Inserting %d entry in bucket %d, should fail\n", 4263 num_ent_per_bucket, bucket); 4264 } 4265 4266 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 4267 if (r != SOC_E_FULL) { 4268 test_error(unit, "L3 insert failed\n"); 4269 rv = -1; 4270 goto done; 4271 } 4272 } else { 4273 test_error(unit, "L3 insert to full bucket succeeded\n"); 4274 rv = -1; 4275 goto done; 4276 } 4277 4278 if (ad->opt_verbose) { 4279 cli_out("Verifying installed entries\n"); 4280 } 4281 4282 /* Verify bucket contains added entries */ 4283 for (j = 0; j < i; j++) { 4284 if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) { 4285 test_error(unit, "L3 entry missing at bucket %d\n", bucket); 4286 rv = -1; 4287 goto done; 4288 } 4289 } 4290 4291 if (ad->opt_verbose) { 4292 cli_out("Cleaning bucket %d\n", bucket); 4293 } 4294 4295 /* Remove the entries that we added */ 4296 for (j = 0; j < i; j++) { 4297 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) { 4298 test_error(unit, "L3 delete failed at bucket %d\n", bucket); 4299 rv = -1; 4300 goto done; 4301 } 4302 } 4303 4304 /* Do Next bucket */ 4305 increment_ip6addr(dst_ip, 15, 1); 4306 vid += vid_inc; 4307 if (vid > DRACO_L3_VID_MAX) { 4308 vid = 1; 4309 } 4310 if (vrf_id_max) { 4311 vrf_id += vrf_id_inc; 4312 if (vrf_id > vrf_id_max) { 4313 vrf_id = 0; 4314 } 4315 } 4316 } 4317 4318 done: 4319 4320 return rv; 4321 } 4322 4323 int 4324 _fb_l3ip6mcast_test_ov(int unit, args_t *a, void *p) 4325 { 4326 uint32 entry[SOC_MAX_MEM_WORDS]; 4327 soc_mem_t mem = L3_ENTRY_IPV6_MULTICASTm; 4328 int num_ent_per_bucket; 4329 int num_vbits; 4330 int num_buckets; 4331 ip6_addr_t src_ip; 4332 ip6_addr_t dst_ip; 4333 uint32 ip_tmp[2]; 4334 int src_ip_inc; 4335 bcm_vlan_t vid; 4336 int vid_inc; 4337 int r, rv = 0; 4338 int bucket; 4339 int i, j; 4340 int iterations; 4341 draco_l3_testdata_t *ad = p; 4342 int vrf_id; 4343 int vrf_id_inc; 4344 int vrf_id_max = 0; 4345 4346 COMPILER_REFERENCE(a); 4347 vrf_id_max = SOC_VRF_MAX(unit); 4348 4349 #ifdef BCM_TRIDENT3_SUPPORT 4350 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 4351 mem = L3_ENTRY_QUADm; 4352 } 4353 #endif 4354 num_vbits = 4; 4355 num_ent_per_bucket = SOC_L3X_BUCKET_SIZE(unit) / num_vbits; 4356 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 4357 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 4358 4359 if (ad->opt_key_src_ip) { 4360 memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t)); 4361 src_ip_inc = ad->opt_src_ip6_inc; 4362 } else { 4363 sal_memset (src_ip, 0, sizeof(src_ip)); 4364 src_ip_inc = 0; 4365 } 4366 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 4367 vid = ad->opt_base_vid; 4368 vid_inc = ad->opt_vid_inc; 4369 vrf_id = ad->opt_base_vrf_id; 4370 vrf_id_inc = ad->opt_vrf_id_inc; 4371 4372 sal_memset (entry, 0, sizeof(entry)); 4373 #ifdef BCM_TRIUMPH_SUPPORT 4374 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 4375 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 4376 TR_L3_HASH_KEY_TYPE_V6MC); 4377 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 4378 TR_L3_HASH_KEY_TYPE_V6MC); 4379 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f, 4380 TR_L3_HASH_KEY_TYPE_V6MC); 4381 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f, 4382 TR_L3_HASH_KEY_TYPE_V6MC); 4383 if (vrf_id_max) { 4384 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 4385 } 4386 } else 4387 #endif /* BCM_TRIUMPH_SUPPORT */ 4388 { 4389 soc_mem_field32_set(unit, mem, entry, V6_0f, 1); 4390 soc_mem_field32_set(unit, mem, entry, V6_1f, 1); 4391 soc_mem_field32_set(unit, mem, entry, V6_2f, 1); 4392 soc_mem_field32_set(unit, mem, entry, V6_3f, 1); 4393 soc_mem_field32_set(unit, mem, entry, IPMC_0f, 1); 4394 soc_mem_field32_set(unit, mem, entry, IPMC_1f, 1); 4395 soc_mem_field32_set(unit, mem, entry, IPMC_2f, 1); 4396 soc_mem_field32_set(unit, mem, entry, IPMC_3f, 1); 4397 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 4398 defined(BCM_SCORPION_SUPPORT) 4399 if (vrf_id_max) { 4400 soc_mem_field32_set(unit, mem, entry, VRF_ID_0f, 1); 4401 soc_mem_field32_set(unit, mem, entry, VRF_ID_1f, 1); 4402 soc_mem_field32_set(unit, mem, entry, VRF_ID_2f, 1); 4403 soc_mem_field32_set(unit, mem, entry, VRF_ID_3f, 1); 4404 } 4405 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 4406 } 4407 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 4408 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 4409 soc_mem_field32_set(unit, mem, entry, VALID_2f, 1); 4410 soc_mem_field32_set(unit, mem, entry, VALID_3f, 1); 4411 while (iterations--) { 4412 dst_ip[0] = 0; 4413 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 4414 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 4415 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 4416 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 4417 soc_mem_field_set(unit, mem, entry, 4418 GROUP_IP_ADDR_LWR_64f, ip_tmp); 4419 4420 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 4421 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 4422 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 4423 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 4424 soc_mem_field_set(unit, mem, entry, 4425 GROUP_IP_ADDR_UPR_56f, ip_tmp); 4426 4427 ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) | 4428 (src_ip[10] << 8) | (src_ip[11] << 0)); 4429 ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) | 4430 (src_ip[14] << 8) | (src_ip[15] << 0)); 4431 soc_mem_field_set(unit, mem, entry, 4432 SOURCE_IP_ADDR_LWR_64f, ip_tmp); 4433 4434 ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) | 4435 (src_ip[2] << 8) | (src_ip[3] << 0)); 4436 ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) | 4437 (src_ip[6] << 8) | (src_ip[7] << 0)); 4438 soc_mem_field_set(unit, mem, entry, 4439 SOURCE_IP_ADDR_UPR_64f, ip_tmp); 4440 4441 #ifdef BCM_TRIUMPH_SUPPORT 4442 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 4443 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 4444 if (vrf_id_max) { 4445 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 4446 } 4447 } else 4448 #endif /* BCM_TRIUMPH_SUPPORT */ 4449 { 4450 soc_mem_field32_set(unit, mem, entry, VLAN_ID_0f, vid); 4451 soc_mem_field32_set(unit, mem, entry, VLAN_ID_1f, vid); 4452 soc_mem_field32_set(unit, mem, entry, VLAN_ID_2f, vid); 4453 soc_mem_field32_set(unit, mem, entry, VLAN_ID_3f, vid); 4454 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 4455 defined(BCM_SCORPION_SUPPORT) 4456 if (vrf_id_max) { 4457 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id); 4458 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id); 4459 soc_mem_field32_set(unit, mem,entry, VRF_ID_2f, vrf_id); 4460 soc_mem_field32_set(unit, mem,entry, VRF_ID_3f, vrf_id); 4461 } 4462 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 4463 } 4464 bucket = soc_fb_l3x2_entry_hash(unit, entry); 4465 4466 for (i = 0; i < num_ent_per_bucket; i++) { 4467 if (ad->opt_verbose) { 4468 cli_out("Inserting "); 4469 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 4470 cli_out("into bucket 0x%x\n", bucket); 4471 } 4472 4473 memcpy(entry_tmp[i], entry, sizeof(entry)); 4474 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry_tmp[i])) < 0) { 4475 if (r == SOC_E_FULL) { 4476 /* Already full, stop wasting time */ 4477 break; 4478 } else { 4479 test_error(unit, "L3 insert failed at bucket %d\n", bucket); 4480 rv = -1; 4481 goto done; 4482 } 4483 } 4484 4485 /* Increment key by number of buckets in the table */ 4486 increment_ip6addr(dst_ip, 15, num_buckets); 4487 increment_ip6addr(src_ip, 15, src_ip_inc); 4488 vid += vid_inc; 4489 if (vid > DRACO_L3_VID_MAX) { 4490 vid = 1; 4491 } 4492 if (vrf_id_max) { 4493 vrf_id += vrf_id_inc; 4494 if (vrf_id > vrf_id_max) { 4495 vrf_id = 0; 4496 } 4497 } 4498 dst_ip[0] = 0; 4499 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 4500 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 4501 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 4502 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 4503 soc_mem_field_set(unit, mem, entry, 4504 GROUP_IP_ADDR_LWR_64f, ip_tmp); 4505 4506 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 4507 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 4508 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 4509 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 4510 soc_mem_field_set(unit, mem, entry, 4511 GROUP_IP_ADDR_UPR_56f, ip_tmp); 4512 4513 ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) | 4514 (src_ip[10] << 8) | (src_ip[11] << 0)); 4515 ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) | 4516 (src_ip[14] << 8) | (src_ip[15] << 0)); 4517 soc_mem_field_set(unit, mem, entry, 4518 SOURCE_IP_ADDR_LWR_64f, ip_tmp); 4519 4520 ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) | 4521 (src_ip[2] << 8) | (src_ip[3] << 0)); 4522 ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) | 4523 (src_ip[6] << 8) | (src_ip[7] << 0)); 4524 soc_mem_field_set(unit, mem, entry, 4525 SOURCE_IP_ADDR_UPR_64f, ip_tmp); 4526 #ifdef BCM_TRIUMPH_SUPPORT 4527 if (soc_feature(unit, soc_feature_l3_entry_key_type)) { 4528 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 4529 if (vrf_id_max) { 4530 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 4531 } 4532 } else 4533 #endif /* BCM_TRIUMPH_SUPPORT */ 4534 { 4535 soc_mem_field32_set(unit, mem, entry, VLAN_ID_0f, vid); 4536 soc_mem_field32_set(unit, mem, entry, VLAN_ID_1f, vid); 4537 soc_mem_field32_set(unit, mem, entry, VLAN_ID_2f, vid); 4538 soc_mem_field32_set(unit, mem, entry, VLAN_ID_3f, vid); 4539 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 4540 defined(BCM_SCORPION_SUPPORT) 4541 if (vrf_id_max) { 4542 soc_mem_field32_set(unit, mem,entry, VRF_ID_0f, vrf_id); 4543 soc_mem_field32_set(unit, mem,entry, VRF_ID_1f, vrf_id); 4544 soc_mem_field32_set(unit, mem,entry, VRF_ID_2f, vrf_id); 4545 soc_mem_field32_set(unit, mem,entry, VRF_ID_3f, vrf_id); 4546 } 4547 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 4548 } 4549 } 4550 4551 if (ad->opt_verbose) { 4552 cli_out("Inserting %d entry in bucket %d, should fail\n", 4553 num_ent_per_bucket, bucket); 4554 } 4555 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 4556 if (r != SOC_E_FULL) { 4557 test_error(unit, "L3 insert failed\n"); 4558 rv = -1; 4559 goto done; 4560 } 4561 } else { 4562 test_error(unit, "L3 insert to full bucket succeeded\n"); 4563 rv = -1; 4564 goto done; 4565 } 4566 4567 if (ad->opt_verbose) { 4568 cli_out("Verifying installed entries\n"); 4569 } 4570 4571 /* Verify bucket contains added entries */ 4572 for (j = 0; j < i; j++) { 4573 if (fb_l3_bucket_search(unit, ad, bucket, entry_tmp[j], FALSE, 0) < 0) { 4574 test_error(unit, "L3 entry missing at bucket %d\n", bucket); 4575 rv = -1; 4576 goto done; 4577 } 4578 } 4579 4580 if (ad->opt_verbose) { 4581 cli_out("Cleaning bucket %d\n", bucket); 4582 } 4583 4584 /* Remove the entries that we added */ 4585 for (j = 0; j < i; j++) { 4586 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry_tmp[j]) < 0) { 4587 test_error(unit, "L3 delete failed at bucket %d\n", bucket); 4588 rv = -1; 4589 goto done; 4590 } 4591 } 4592 4593 /* Do Next bucket */ 4594 increment_ip6addr(dst_ip, 15, 1); 4595 increment_ip6addr(src_ip, 15, src_ip_inc); 4596 vid += vid_inc; 4597 if (vid > DRACO_L3_VID_MAX) { 4598 vid = 1; 4599 } 4600 if (vrf_id_max) { 4601 vrf_id += vrf_id_inc; 4602 if (vrf_id > vrf_id_max) { 4603 vrf_id = 0; 4604 } 4605 } 4606 } 4607 4608 done: 4609 4610 return rv; 4611 } 4612 4613 #if defined(BCM_TRIDENT2_SUPPORT) 4614 static int 4615 td2_l3_bucket_search(int unit, draco_l3_testdata_t *ad, soc_mem_t mem, int bank, 4616 int *index_array, uint32 *expect) 4617 { 4618 uint32 entry[SOC_MAX_MEM_WORDS]; 4619 int i, ix, mem_table_index; 4620 int bucket_size = SOC_TD2_L3X_BUCKET_SIZE; 4621 int num_vbits; 4622 int num_ent_per_bucket; 4623 int valid_ix; 4624 soc_field_t valid_f[] = {VALIDf, VALID_0f, VALID_1f, VALID_2f, VALID_3f}; 4625 int rv = -1; /* Assume failed unless we find it */ 4626 int key_type; 4627 4628 #ifdef BCM_TRIDENT3_SUPPORT 4629 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 4630 key_type = soc_mem_field32_get(unit, mem, expect, KEY_TYPEf); 4631 } else 4632 #endif /* BCM_TRIDENT3_SUPPORT */ 4633 { 4634 key_type = soc_mem_field32_get(unit, L3_ENTRY_ONLYm, 4635 expect, KEY_TYPEf); 4636 } 4637 4638 switch (key_type) { 4639 case TD2_L3_HASH_KEY_TYPE_V4UC: 4640 #ifdef BCM_TRIDENT3_SUPPORT 4641 if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) { 4642 if (mem == L3_ENTRY_DOUBLEm) { 4643 valid_f[0] = BASE_VALID_0f; 4644 valid_f[1] = BASE_VALID_1f; 4645 } else if (mem == L3_ENTRY_SINGLEm) { 4646 valid_f[0] = BASE_VALIDf; 4647 } else { 4648 return rv; 4649 } 4650 valid_ix = 0; 4651 num_vbits = 1; 4652 } else 4653 #endif /* BCM_TRIDENT3_SUPPORT */ 4654 { 4655 valid_ix = 0; 4656 num_vbits = 1; 4657 mem = L3_ENTRY_IPV4_UNICASTm; 4658 } 4659 break; 4660 case TD2_L3_HASH_KEY_TYPE_V4MC: 4661 #ifdef BCM_TRIDENT3_SUPPORT 4662 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 4663 valid_f[0] = BASE_VALID_0f; 4664 valid_f[1] = BASE_VALID_1f; 4665 valid_ix = 0; 4666 num_vbits = 1; 4667 } else 4668 #endif /* BCM_TRIDENT3_SUPPORT */ 4669 { 4670 valid_ix = 1; 4671 num_vbits = 2; 4672 mem = L3_ENTRY_IPV4_MULTICASTm; 4673 } 4674 break; 4675 case TD2_L3_HASH_KEY_TYPE_V6UC: 4676 #ifdef BCM_TRIDENT3_SUPPORT 4677 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 4678 if (mem == L3_ENTRY_QUADm) { 4679 valid_f[0] = BASE_VALID_0f; 4680 valid_f[1] = BASE_VALID_1f; 4681 valid_f[2] = BASE_VALID_2f; 4682 valid_f[3] = BASE_VALID_3f; 4683 valid_ix = 0; 4684 num_vbits = 1; 4685 } else if (mem == L3_ENTRY_DOUBLEm) { 4686 valid_f[0] = BASE_VALID_0f; 4687 valid_f[1] = BASE_VALID_1f; 4688 valid_ix = 0; 4689 num_vbits = 1; 4690 } else { 4691 return rv; 4692 } 4693 } else 4694 #endif 4695 { 4696 valid_ix = 1; 4697 num_vbits = 2; 4698 mem = L3_ENTRY_IPV6_UNICASTm; 4699 } 4700 break; 4701 case TD2_L3_HASH_KEY_TYPE_V6MC: 4702 #ifdef BCM_TRIDENT3_SUPPORT 4703 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 4704 valid_f[0] = BASE_VALID_0f; 4705 valid_f[1] = BASE_VALID_1f; 4706 valid_f[2] = BASE_VALID_2f; 4707 valid_f[3] = BASE_VALID_3f; 4708 valid_ix = 0; 4709 num_vbits = 1; 4710 mem = L3_ENTRY_QUADm; 4711 } else 4712 #endif /* BCM_TRIDENT3_SUPPORT */ 4713 { 4714 valid_ix = 1; 4715 num_vbits = 4; 4716 mem = L3_ENTRY_IPV6_MULTICASTm; 4717 } 4718 break; 4719 default: 4720 return -1; 4721 } 4722 4723 num_ent_per_bucket = bucket_size / num_vbits; 4724 4725 for (ix = 0; ix < num_ent_per_bucket; ix++) { 4726 mem_table_index = index_array[bank] + ix; 4727 4728 if (soc_mem_read(unit, mem, MEM_BLOCK_ANY, 4729 mem_table_index, entry) < 0) { 4730 test_error(unit, 4731 "Read %s failed at band %d, index %d, offset %d\n", 4732 SOC_MEM_NAME(unit, mem), bank, index_array[bank], ix); 4733 break; 4734 } 4735 4736 for(i = 0; i < num_vbits; i++) { 4737 if (!soc_mem_field32_get(unit, mem, entry, valid_f[valid_ix + i])) { 4738 break; 4739 } 4740 } 4741 if (i != num_vbits) { 4742 /* Valid bit not set, blank entry */ 4743 continue; 4744 } 4745 4746 if (soc_mem_compare_key(unit, mem, expect, entry) == 0) { 4747 /* Found the matching entry */ 4748 rv = 0; 4749 break; 4750 } 4751 } 4752 4753 return rv; 4754 } 4755 4756 int 4757 _td2_l3ip4ucast_test_hash(int unit, args_t *a, void *p) 4758 { 4759 draco_l3_testdata_t *ad = p; 4760 uint32 entry[SOC_MAX_MEM_WORDS]; 4761 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 4762 soc_mem_t mem = L3_ENTRY_IPV4_UNICASTm; 4763 ip_addr_t dst_ip; 4764 ip_addr_t dst_ip_inc; 4765 bcm_vlan_t vid; 4766 int vid_inc; 4767 int r, rv = 0; 4768 int hard_index; 4769 int bucket_size, bucket_offset; 4770 int ix; 4771 int iterations; 4772 int vrf_id; 4773 int vrf_id_inc; 4774 int vrf_id_max = 0; 4775 int bank, banks, bi; 4776 uint32 bank_count; 4777 int num_l3_banks = 0; 4778 int l3_index_array[L3_MAX_BANKS] = {0}; 4779 int l3_bucket_array[L3_MAX_BANKS] = {0}; 4780 int phy_bank_array[L3_MAX_BANKS] = {0}; 4781 4782 COMPILER_REFERENCE(a); 4783 vrf_id_max = SOC_VRF_MAX(unit); 4784 bucket_size = 4; 4785 4786 #ifdef BCM_TRIDENT3_SUPPORT 4787 if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) { 4788 mem = L3_ENTRY_SINGLEm; 4789 } 4790 #endif /* BCM_TRIDENT3_SUPPORT */ 4791 4792 dst_ip = ad->opt_base_ip; 4793 dst_ip_inc = ad->opt_ip_inc; 4794 vid = ad->opt_base_vid; 4795 vid_inc = ad->opt_vid_inc; 4796 4797 vrf_id = ad->opt_base_vrf_id; 4798 vrf_id_inc = ad->opt_vrf_id_inc; 4799 4800 if (ad->opt_verbose) { 4801 cli_out("Starting L3 hash test\n"); 4802 } 4803 4804 iterations = ad->opt_count; 4805 4806 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 4807 &bank_count)) < 0) { 4808 test_error(unit, "Getting bank count for L3 table failed\n"); 4809 rv = -1; 4810 goto done; 4811 } 4812 4813 sal_memset(entry, 0, sizeof(entry)); 4814 #ifdef BCM_TRIDENT3_SUPPORT 4815 if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) { 4816 l3_entry_key_attributes_entry_t l3_key_attr; 4817 4818 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 4819 TD3_L3_HASH_KEY_TYPE_V4UC); 4820 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 4821 TD3_L3_HASH_DATA_TYPE_V4UC); 4822 soc_mem_field32_set(unit, mem, entry, BASE_VALIDf, 1); 4823 if (vrf_id_max) { 4824 soc_mem_field32_set(unit, mem, entry, IPV4UC__VRF_IDf, 1); 4825 } 4826 4827 /* Set L3 Entry Key Attributes */ 4828 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 4829 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 4830 BUCKET_MODEf, 0); 4831 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 4832 KEY_BASE_WIDTHf, 0); 4833 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 4834 KEY_WIDTHf, 12); 4835 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 4836 DATA_BASE_WIDTHf, 1); 4837 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 4838 HASH_LSB_OFFSETf, 5); 4839 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 4840 TD3_L3_HASH_KEY_TYPE_V4UC, 4841 (uint32*)&l3_key_attr) < 0) { 4842 test_error(unit, "L3 Entry Key Attr setting failed\n"); 4843 goto done; 4844 } 4845 } else 4846 #endif 4847 { 4848 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 4849 TD2_L3_HASH_KEY_TYPE_V4UC); 4850 soc_mem_field32_set(unit, mem, entry, VALIDf, 1); 4851 if (vrf_id_max) { 4852 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 4853 } 4854 } 4855 4856 for (ix = 0; ix < iterations; ix++) { 4857 for (bank = 0; bank < bank_count; bank++) { 4858 soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip); 4859 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) { 4860 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 4861 } 4862 if (vrf_id_max) { 4863 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 4864 } 4865 4866 if (bank == 0) { 4867 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 4868 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 4869 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) 4870 || SOC_IS_TRIDENT3X(unit)) { 4871 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 4872 &num_l3_banks, l3_bucket_array, 4873 l3_index_array, phy_bank_array, 4874 NULL)) < 0) { 4875 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 4876 goto done; 4877 } 4878 4879 if (num_l3_banks > L3_MAX_BANKS) { 4880 cli_out("%s ERROR: the number of banks overflow\n", 4881 ARG_CMD(a)); 4882 rv = -1; 4883 goto done; 4884 } 4885 } else 4886 #endif 4887 { 4888 rv = -1; 4889 goto done; 4890 } 4891 4892 if (ad->opt_verbose) { 4893 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 4894 for (bi = 0; bi < bank_count; bi++) { 4895 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 4896 bi, phy_bank_array[bi], 4897 l3_bucket_array[bi], l3_bucket_array[bi], 4898 l3_index_array[bi], l3_index_array[bi]); 4899 } 4900 } 4901 } 4902 4903 if (ad->opt_verbose) { 4904 cli_out("Inserting "); 4905 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 4906 cli_out("\n"); 4907 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank); 4908 } 4909 4910 banks = 1 << phy_bank_array[bank]; 4911 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 4912 if (SOC_FAILURE(r)) { 4913 if (r == SOC_E_FULL) { 4914 /* Bucket overflow, just pass on */ 4915 continue; 4916 } else { 4917 test_error(unit, "L3 insert failed at bucket %d bank %d\n", 4918 l3_bucket_array[bank], bank); 4919 rv = -1; 4920 goto done; 4921 } 4922 } 4923 4924 /* Now we search for the entry */ 4925 hard_index = 0; 4926 if (soc_mem_search(unit, mem, COPYNO_ALL, 4927 &hard_index, entry, entry_lkup, 0) < 0) { 4928 test_error(unit, "Entry lookup failed\n"); 4929 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 4930 goto done; 4931 } 4932 4933 /* entries per bucket */ 4934 bucket_offset = hard_index - l3_index_array[bank]; 4935 if (bucket_offset < 0 || bucket_offset >= bucket_size) { 4936 test_error(unit, 4937 "Hardware Hash %d out range of Software Hash base %d (%d)\n", 4938 hard_index, l3_index_array[bank], bucket_offset); 4939 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 4940 goto done; 4941 } 4942 4943 /* Only do a quick check vs. expected bucket here */ 4944 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) { 4945 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 4946 bank, l3_index_array[bank]); 4947 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 4948 rv = -1; 4949 goto done; 4950 } 4951 4952 /* Clean up afterward */ 4953 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 4954 test_error(unit, "L3 delete failed at bucket %d bank %d\n", 4955 l3_bucket_array[bank], bank); 4956 rv = -1; 4957 goto done; 4958 } 4959 } 4960 4961 dst_ip += dst_ip_inc; 4962 vid += vid_inc; 4963 if (vid > DRACO_L3_VID_MAX) { 4964 vid = 1; 4965 } 4966 if (vrf_id_max) { 4967 vrf_id += vrf_id_inc; 4968 if (vrf_id > vrf_id_max) { 4969 vrf_id = 0; 4970 } 4971 } 4972 } 4973 4974 done: 4975 return rv; 4976 } 4977 4978 int 4979 _td2_l3ip4mcast_test_hash(int unit, args_t *a, void *p) 4980 { 4981 draco_l3_testdata_t *ad = p; 4982 uint32 entry[SOC_MAX_MEM_WORDS]; 4983 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 4984 soc_mem_t mem = L3_ENTRY_IPV4_MULTICASTm; 4985 ip_addr_t src_ip; 4986 ip_addr_t dst_ip; 4987 ip_addr_t src_ip_inc; 4988 ip_addr_t dst_ip_inc; 4989 bcm_vlan_t vid; 4990 int vid_inc; 4991 int r, rv = 0; 4992 int hard_index; 4993 int bucket_size, bucket_offset; 4994 int ix; 4995 int iterations; 4996 int vrf_id; 4997 int vrf_id_inc; 4998 int vrf_id_max = 0; 4999 int bank, banks, bi; 5000 uint32 bank_count; 5001 int num_l3_banks = 0; 5002 int l3_index_array[L3_MAX_BANKS] = {0}; 5003 int l3_bucket_array[L3_MAX_BANKS] = {0}; 5004 int phy_bank_array[L3_MAX_BANKS] = {0}; 5005 5006 COMPILER_REFERENCE(a); 5007 bucket_size = 2; 5008 5009 #ifdef BCM_TRIDENT3_SUPPORT 5010 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5011 mem = L3_ENTRY_DOUBLEm; 5012 bucket_size = 4; 5013 } 5014 #endif /* BCM_TRIDENT3_SUPPORT */ 5015 5016 vrf_id_max = SOC_VRF_MAX(unit); 5017 if (ad->opt_key_src_ip) { 5018 src_ip_inc = ad->opt_src_ip_inc; 5019 src_ip = ad->opt_src_ip; 5020 } else { 5021 src_ip_inc = 0; 5022 src_ip = 0; 5023 } 5024 dst_ip = ad->opt_base_ip; 5025 dst_ip_inc = ad->opt_ip_inc; 5026 vid = ad->opt_base_vid; 5027 vid_inc = ad->opt_vid_inc; 5028 5029 vrf_id = ad->opt_base_vrf_id; 5030 vrf_id_inc = ad->opt_vrf_id_inc; 5031 5032 /* Invalid IPMC/Unicast address checks required */ 5033 5034 if (ad->opt_verbose) { 5035 cli_out("Starting L3 hash test\n"); 5036 } 5037 5038 iterations = ad->opt_count; 5039 5040 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 5041 &bank_count)) < 0) { 5042 test_error(unit, "Getting bank count for L3 table failed\n"); 5043 rv = -1; 5044 goto done; 5045 } 5046 5047 sal_memset(entry, 0, sizeof(entry)); 5048 #ifdef BCM_TRIDENT3_SUPPORT 5049 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5050 l3_entry_key_attributes_entry_t l3_key_attr; 5051 5052 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 5053 TD3_L3_HASH_KEY_TYPE_V4MC); 5054 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 5055 TD3_L3_HASH_DATA_TYPE_V4MC); 5056 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3); 5057 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7); 5058 if (vrf_id_max) { 5059 soc_mem_field32_set(unit, mem, entry, IPV4MC__VRF_IDf, 1); 5060 } 5061 /* Set L3 Entry Key Attributes */ 5062 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 5063 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5064 BUCKET_MODEf, 1); 5065 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5066 KEY_BASE_WIDTHf, 0); 5067 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5068 KEY_WIDTHf, 23); 5069 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5070 DATA_BASE_WIDTHf, 1); 5071 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5072 HASH_LSB_OFFSETf, 5); 5073 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 5074 TD3_L3_HASH_KEY_TYPE_V4MC, 5075 (uint32*)&l3_key_attr) < 0) { 5076 test_error(unit, "L3 Entry Key Attr setting failed\n"); 5077 goto done; 5078 } 5079 } else 5080 #endif 5081 { 5082 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 5083 TD2_L3_HASH_KEY_TYPE_V4MC); 5084 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 5085 TD2_L3_HASH_KEY_TYPE_V4MC); 5086 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 5087 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 5088 if (vrf_id_max) { 5089 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 5090 } 5091 } 5092 5093 for (ix = 0; ix < iterations; ix++) { 5094 for (bank = 0; bank < bank_count; bank++) { 5095 #ifdef BCM_TRIDENT3_SUPPORT 5096 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5097 soc_mem_field_set(unit, mem, entry, 5098 IPV4MC__GROUP_IP_ADDRf, &dst_ip); 5099 soc_mem_field_set(unit, mem, entry, 5100 IPV4MC__SOURCE_IP_ADDRf, &src_ip); 5101 soc_mem_field32_set(unit, mem, entry, 5102 IPV4MC__VLAN_IDf, vid); 5103 if (vrf_id_max) { 5104 soc_mem_field32_set(unit, mem,entry, 5105 IPV4MC__VRF_IDf, vrf_id); 5106 } 5107 } else 5108 #endif 5109 { 5110 soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip); 5111 soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip); 5112 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 5113 if (vrf_id_max) { 5114 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 5115 } 5116 } 5117 5118 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 5119 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 5120 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 5121 SOC_IS_TRIDENT3X(unit)) { 5122 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 5123 &num_l3_banks, l3_bucket_array, 5124 l3_index_array, phy_bank_array, 5125 NULL)) < 0) { 5126 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 5127 goto done; 5128 } 5129 5130 if (num_l3_banks > L3_MAX_BANKS) { 5131 cli_out("%s ERROR: the number of banks overflow\n", 5132 ARG_CMD(a)); 5133 rv = -1; 5134 goto done; 5135 } 5136 } else 5137 #endif 5138 { 5139 rv = -1; 5140 goto done; 5141 } 5142 5143 if (ad->opt_verbose) { 5144 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 5145 for (bi = 0; bi < bank_count; bi++) { 5146 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 5147 bi, phy_bank_array[bi], 5148 l3_bucket_array[bi], l3_bucket_array[bi], 5149 l3_index_array[bi], l3_index_array[bi]); 5150 } 5151 } 5152 5153 if (ad->opt_verbose) { 5154 cli_out("Inserting "); 5155 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 5156 cli_out("\n"); 5157 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank); 5158 } 5159 5160 banks = 1 << phy_bank_array[bank]; 5161 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 5162 if (SOC_FAILURE(r)) { 5163 if (r == SOC_E_FULL) { 5164 /* Bucket overflow, just pass on */ 5165 continue; 5166 } else { 5167 test_error(unit, "L3 insert failed at bucket %d bank %d\n", 5168 l3_bucket_array[bank], bank); 5169 rv = -1; 5170 goto done; 5171 } 5172 } 5173 5174 /* Now we search for the entry */ 5175 hard_index = 0; 5176 if (soc_mem_search(unit, mem, COPYNO_ALL, 5177 &hard_index, entry, entry_lkup, 0) < 0) { 5178 test_error(unit, "Entry lookup failed\n"); 5179 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5180 goto done; 5181 } 5182 5183 /* entries per bucket */ 5184 bucket_offset = hard_index - l3_index_array[bank]; 5185 if (bucket_offset < 0 || bucket_offset >= bucket_size) { 5186 test_error(unit, 5187 "Hardware Hash %d out range of Software Hash base %d (%d)\n", 5188 hard_index, l3_index_array[bank], bucket_offset); 5189 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5190 goto done; 5191 } 5192 5193 /* Only do a quick check vs. expected bucket here */ 5194 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) { 5195 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 5196 bank, l3_index_array[bank]); 5197 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5198 rv = -1; 5199 goto done; 5200 } 5201 5202 /* Clean up afterward */ 5203 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 5204 test_error(unit, "L3 delete failed at bucket %d bank %d\n", 5205 l3_bucket_array[bank], bank); 5206 rv = -1; 5207 goto done; 5208 } 5209 5210 src_ip += src_ip_inc; 5211 dst_ip += dst_ip_inc; 5212 vid += vid_inc; 5213 if (vid > DRACO_L3_VID_MAX) { 5214 vid = 1; 5215 } 5216 if (vrf_id_max) { 5217 vrf_id += vrf_id_inc; 5218 if (vrf_id > vrf_id_max) { 5219 vrf_id = 0; 5220 } 5221 } 5222 } 5223 } 5224 5225 done: 5226 return rv; 5227 } 5228 5229 int 5230 _td2_l3ip6ucast_test_hash(int unit, args_t *a, void *p) 5231 { 5232 draco_l3_testdata_t *ad = p; 5233 uint32 entry[SOC_MAX_MEM_WORDS]; 5234 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 5235 soc_mem_t mem = L3_ENTRY_IPV6_UNICASTm; 5236 ip6_addr_t dst_ip; 5237 uint32 ip_tmp[2]; 5238 int dst_ip_inc; 5239 int r, rv = 0; 5240 int hard_index; 5241 int bucket_size, bucket_offset; 5242 int ix; 5243 int iterations; 5244 int vrf_id; 5245 int vrf_id_inc; 5246 int vrf_id_max = 0; 5247 int bank, banks, bi; 5248 uint32 bank_count; 5249 int num_l3_banks = 0; 5250 int l3_index_array[L3_MAX_BANKS] = {0}; 5251 int l3_bucket_array[L3_MAX_BANKS] = {0}; 5252 int phy_bank_array[L3_MAX_BANKS] = {0}; 5253 5254 COMPILER_REFERENCE(a); 5255 vrf_id_max = SOC_VRF_MAX(unit); 5256 bucket_size = 2; 5257 5258 #ifdef BCM_TRIDENT3_SUPPORT 5259 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5260 mem = L3_ENTRY_DOUBLEm; 5261 bucket_size = 4; 5262 } 5263 #endif 5264 5265 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 5266 dst_ip_inc = ad->opt_ip6_inc; 5267 vrf_id = ad->opt_base_vrf_id; 5268 vrf_id_inc = ad->opt_vrf_id_inc; 5269 5270 if (ad->opt_verbose) { 5271 cli_out("Starting L3 hash test\n"); 5272 } 5273 5274 iterations = ad->opt_count; 5275 5276 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 5277 &bank_count)) < 0) { 5278 test_error(unit, "Getting bank count for L3 table failed\n"); 5279 rv = -1; 5280 goto done; 5281 } 5282 5283 sal_memset(entry, 0, sizeof(entry)); 5284 #ifdef BCM_TRIDENT3_SUPPORT 5285 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5286 l3_entry_key_attributes_entry_t l3_key_attr; 5287 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 5288 TD3_L3_HASH_KEY_TYPE_V6UC); 5289 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 5290 TD3_L3_HASH_DATA_TYPE_V6UC); 5291 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3); 5292 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 4); 5293 if (vrf_id_max) { 5294 soc_mem_field32_set(unit, mem, entry, IPV6UC__VRF_IDf, 1); 5295 } 5296 5297 /* Set L3 Entry Key Attributes */ 5298 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 5299 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5300 BUCKET_MODEf, 1); 5301 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5302 KEY_BASE_WIDTHf, 1); 5303 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5304 KEY_WIDTHf, 15); 5305 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5306 DATA_BASE_WIDTHf, 2); 5307 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5308 HASH_LSB_OFFSETf, 5); 5309 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 5310 TD3_L3_HASH_KEY_TYPE_V6UC, 5311 (uint32*)&l3_key_attr) < 0) { 5312 test_error(unit, "L3 Entry Key Attr setting failed\n"); 5313 goto done; 5314 } 5315 } else 5316 #endif 5317 { 5318 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 5319 TD2_L3_HASH_KEY_TYPE_V6UC); 5320 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 5321 TD2_L3_HASH_KEY_TYPE_V6UC); 5322 if (vrf_id_max) { 5323 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 5324 } 5325 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 5326 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 5327 } 5328 for (ix = 0; ix < iterations; ix++) { 5329 for (bank = 0; bank < bank_count; bank++) { 5330 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 5331 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 5332 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 5333 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 5334 #ifdef BCM_TRIDENT3_SUPPORT 5335 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5336 soc_mem_field_set(unit, mem, entry, 5337 IPV6UC__IP_ADDR_LWR_64f, ip_tmp); 5338 } else 5339 #endif 5340 { 5341 soc_mem_field_set(unit, mem, entry, 5342 IP_ADDR_LWR_64f, ip_tmp); 5343 } 5344 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 5345 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 5346 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 5347 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 5348 #ifdef BCM_TRIDENT3_SUPPORT 5349 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 5350 soc_mem_field_set(unit, mem, entry, 5351 IPV6UC__IP_ADDR_UPR_64f, ip_tmp); 5352 } else 5353 #endif 5354 { 5355 soc_mem_field_set(unit, mem, entry, 5356 IP_ADDR_UPR_64f, ip_tmp); 5357 } 5358 if (vrf_id_max) { 5359 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 5360 } 5361 5362 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 5363 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 5364 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 5365 (SOC_IS_TRIDENT3X(unit))) { 5366 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 5367 &num_l3_banks, l3_bucket_array, 5368 l3_index_array, phy_bank_array, 5369 NULL)) < 0) { 5370 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 5371 goto done; 5372 } 5373 5374 if (num_l3_banks > L3_MAX_BANKS) { 5375 cli_out("%s ERROR: the number of banks overflow\n", 5376 ARG_CMD(a)); 5377 rv = -1; 5378 goto done; 5379 } 5380 } else 5381 #endif 5382 { 5383 rv = -1; 5384 goto done; 5385 } 5386 5387 if (ad->opt_verbose) { 5388 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 5389 for (bi = 0; bi < bank_count; bi++) { 5390 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 5391 bi, phy_bank_array[bi], 5392 l3_bucket_array[bi], l3_bucket_array[bi], 5393 l3_index_array[bi], l3_index_array[bi]); 5394 } 5395 } 5396 5397 if (ad->opt_verbose) { 5398 cli_out("Inserting "); 5399 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 5400 cli_out("\n"); 5401 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank); 5402 } 5403 5404 banks = 1 << phy_bank_array[bank]; 5405 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 5406 if (SOC_FAILURE(r)) { 5407 if (r == SOC_E_FULL) { 5408 /* Bucket overflow, just pass on */ 5409 continue; 5410 } else { 5411 test_error(unit, "L3 insert failed at bucket %d bank %d\n", 5412 l3_bucket_array[bank], bank); 5413 rv = -1; 5414 goto done; 5415 } 5416 } 5417 5418 /* Now we search for the entry */ 5419 hard_index = 0; 5420 if (soc_mem_search(unit, mem, COPYNO_ALL, 5421 &hard_index, entry, entry_lkup, 0) < 0) { 5422 test_error(unit, "Entry lookup failed\n"); 5423 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5424 goto done; 5425 } 5426 5427 /* entries per bucket */ 5428 bucket_offset = hard_index - l3_index_array[bank]; 5429 if (bucket_offset < 0 || bucket_offset >= bucket_size) { 5430 test_error(unit, 5431 "Hardware Hash %d out range of Software Hash base %d (%d)\n", 5432 hard_index, l3_index_array[bank], bucket_offset); 5433 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5434 goto done; 5435 } 5436 5437 /* Only do a quick check vs. expected bucket here */ 5438 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) { 5439 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 5440 bank, l3_index_array[bank]); 5441 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5442 rv = -1; 5443 goto done; 5444 } 5445 5446 /* Clean up afterward */ 5447 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 5448 test_error(unit, "L3 delete failed at bucket %d bank %d\n", 5449 l3_bucket_array[bank], bank); 5450 rv = -1; 5451 goto done; 5452 } 5453 increment_ip6addr(dst_ip, 15, dst_ip_inc); 5454 if (vrf_id_max) { 5455 vrf_id += vrf_id_inc; 5456 if (vrf_id > vrf_id_max) { 5457 vrf_id = 0; 5458 } 5459 } 5460 } 5461 } 5462 5463 done: 5464 return rv; 5465 } 5466 5467 int 5468 _td2_l3ip6mcast_test_hash(int unit, args_t *a, void *p) 5469 { 5470 draco_l3_testdata_t *ad = p; 5471 uint32 entry[SOC_MAX_MEM_WORDS]; 5472 uint32 entry_lkup[SOC_MAX_MEM_WORDS]; 5473 soc_mem_t mem = L3_ENTRY_IPV6_MULTICASTm; 5474 ip6_addr_t src_ip; 5475 ip6_addr_t dst_ip; 5476 uint32 ip_tmp[2]; 5477 int src_ip_inc; 5478 int dst_ip_inc; 5479 bcm_vlan_t vid; 5480 int vid_inc; 5481 int r, rv = 0; 5482 int hard_index; 5483 int bucket_size, bucket_offset; 5484 int ix; 5485 int iterations; 5486 int vrf_id; 5487 int vrf_id_inc; 5488 int vrf_id_max = 0; 5489 int bank, banks, bi; 5490 uint32 bank_count; 5491 int num_l3_banks = 0; 5492 int l3_index_array[L3_MAX_BANKS] = {0}; 5493 int l3_bucket_array[L3_MAX_BANKS] = {0}; 5494 int phy_bank_array[L3_MAX_BANKS] = {0}; 5495 5496 COMPILER_REFERENCE(a); 5497 vrf_id_max = SOC_VRF_MAX(unit); 5498 bucket_size = 1; 5499 5500 #ifdef BCM_TRIDENT3_SUPPORT 5501 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 5502 mem = L3_ENTRY_QUADm; 5503 bucket_size = 4; 5504 } 5505 #endif 5506 5507 if (ad->opt_key_src_ip) { 5508 memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t)); 5509 src_ip_inc = ad->opt_src_ip6_inc; 5510 } else { 5511 sal_memset (src_ip, 0, sizeof(src_ip)); 5512 src_ip_inc = 0; 5513 } 5514 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 5515 dst_ip_inc = ad->opt_ip6_inc; 5516 vid = ad->opt_base_vid; 5517 vid_inc = ad->opt_vid_inc; 5518 vrf_id = ad->opt_base_vrf_id; 5519 vrf_id_inc = ad->opt_vrf_id_inc; 5520 5521 /* Invalid IPMC/Unicast address checks required */ 5522 5523 if (ad->opt_verbose) { 5524 cli_out("Starting L3 hash test\n"); 5525 } 5526 5527 iterations = ad->opt_count; 5528 5529 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 5530 &bank_count)) < 0) { 5531 test_error(unit, "Getting bank count for L3 table failed\n"); 5532 rv = -1; 5533 goto done; 5534 } 5535 5536 sal_memset(entry, 0, sizeof(entry)); 5537 #ifdef BCM_TRIDENT3_SUPPORT 5538 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 5539 l3_entry_key_attributes_entry_t l3_key_attr; 5540 5541 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 5542 TD3_L3_HASH_KEY_TYPE_V6MC); 5543 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 5544 TD3_L3_HASH_DATA_TYPE_V6MC); 5545 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 5); 5546 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 6); 5547 soc_mem_field32_set(unit, mem, entry, BASE_VALID_2f, 6); 5548 soc_mem_field32_set(unit, mem, entry, BASE_VALID_3f, 7); 5549 if (vrf_id_max) { 5550 soc_mem_field32_set(unit, mem, entry, IPV6MC__VRF_IDf, 1); 5551 } 5552 5553 /* Set L3 Entry Key Attributes */ 5554 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 5555 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5556 BUCKET_MODEf, 2); 5557 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5558 KEY_BASE_WIDTHf, 2); 5559 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5560 KEY_WIDTHf, 23); 5561 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5562 DATA_BASE_WIDTHf, 1); 5563 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5564 HASH_LSB_OFFSETf, 5); 5565 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 5566 TD3_L3_HASH_KEY_TYPE_V6MC, 5567 (uint32*)&l3_key_attr) < 0) { 5568 test_error(unit, "L3 Entry Key Attr setting failed\n"); 5569 goto done; 5570 } 5571 } else 5572 #endif /* BCM_TRIDENT3_SUPPORT */ 5573 { 5574 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 5575 TD2_L3_HASH_KEY_TYPE_V6MC); 5576 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 5577 TD2_L3_HASH_KEY_TYPE_V6MC); 5578 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f, 5579 TD2_L3_HASH_KEY_TYPE_V6MC); 5580 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f, 5581 TD2_L3_HASH_KEY_TYPE_V6MC); 5582 if (vrf_id_max) { 5583 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 5584 } 5585 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 5586 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 5587 soc_mem_field32_set(unit, mem, entry, VALID_2f, 1); 5588 soc_mem_field32_set(unit, mem, entry, VALID_3f, 1); 5589 } 5590 for (ix = 0; ix < iterations; ix++) { 5591 for (bank = 0; bank < bank_count; bank++) { 5592 soc_field_t fld_arr1[] = { GROUP_IP_ADDR_LWR_64f, 5593 GROUP_IP_ADDR_UPR_56f, 5594 SOURCE_IP_ADDR_LWR_64f, 5595 SOURCE_IP_ADDR_UPR_64f, 5596 VLAN_IDf, VRF_IDf}; 5597 soc_field_t *p_fld_arr = fld_arr1; 5598 #ifdef BCM_TRIDENT3_SUPPORT 5599 soc_field_t fld_arr2[] = { IPV6MC__GROUP_IP_ADDR_LWR_64f, 5600 IPV6MC__GROUP_IP_ADDR_UPR_56f, 5601 IPV6MC__SOURCE_IP_ADDR_BITS_31_0f, 5602 IPV6MC__SOURCE_IP_ADDR_UPR_64f, 5603 IPV6MC__VLAN_IDf, IPV6MC__VRF_IDf, 5604 IPV6MC__SOURCE_IP_ADDR_BITS_63_32f}; 5605 5606 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 5607 p_fld_arr = fld_arr2; 5608 } 5609 #endif /* BCM_TRIDENT3_SUPPORT */ 5610 5611 dst_ip[0] = 0; 5612 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 5613 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 5614 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 5615 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 5616 soc_mem_field_set(unit, mem, entry, p_fld_arr[0], ip_tmp); 5617 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 5618 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 5619 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 5620 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 5621 soc_mem_field_set(unit, mem, entry, p_fld_arr[1], ip_tmp); 5622 ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) | 5623 (src_ip[10] << 8) | (src_ip[11] << 0)); 5624 ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) | 5625 (src_ip[14] << 8) | (src_ip[15] << 0)); 5626 #ifdef BCM_TRIDENT3_SUPPORT 5627 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 5628 soc_mem_field_set(unit, mem, entry, p_fld_arr[2], &ip_tmp[0]); 5629 soc_mem_field_set(unit, mem, entry, p_fld_arr[6], &ip_tmp[1]); 5630 } else 5631 #endif /* BCM_TRIDENT3_SUPPORT */ 5632 { 5633 soc_mem_field_set(unit, mem, entry, p_fld_arr[2], ip_tmp); 5634 } 5635 ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) | 5636 (src_ip[2] << 8) | (src_ip[3] << 0)); 5637 ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) | 5638 (src_ip[6] << 8) | (src_ip[7] << 0)); 5639 soc_mem_field_set(unit, mem, entry, p_fld_arr[3], ip_tmp); 5640 soc_mem_field32_set(unit, mem, entry, p_fld_arr[4], vid); 5641 if (vrf_id_max) { 5642 soc_mem_field32_set(unit, mem,entry, p_fld_arr[5], vrf_id); 5643 } 5644 5645 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 5646 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 5647 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 5648 (SOC_IS_TRIDENT3X(unit))) { 5649 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 5650 &num_l3_banks, l3_bucket_array, 5651 l3_index_array, phy_bank_array, 5652 NULL)) < 0) { 5653 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 5654 goto done; 5655 } 5656 5657 if (num_l3_banks > L3_MAX_BANKS) { 5658 cli_out("%s ERROR: the number of banks overflow\n", 5659 ARG_CMD(a)); 5660 rv = -1; 5661 goto done; 5662 } 5663 } else 5664 #endif 5665 { 5666 rv = -1; 5667 goto done; 5668 } 5669 5670 if (ad->opt_verbose) { 5671 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 5672 for (bi = 0; bi < bank_count; bi++) { 5673 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 5674 bi, phy_bank_array[bi], 5675 l3_bucket_array[bi], l3_bucket_array[bi], 5676 l3_index_array[bi], l3_index_array[bi]); 5677 } 5678 } 5679 5680 if (ad->opt_verbose) { 5681 cli_out("Inserting "); 5682 soc_mem_entry_dump(unit, mem, &entry, BSL_LSS_CLI); 5683 cli_out("\n"); 5684 cli_out("into bucket 0x%x (bank %d)\n", l3_bucket_array[bank], bank); 5685 } 5686 5687 banks = 1 << phy_bank_array[bank]; 5688 r = soc_mem_bank_insert(unit, mem, banks, COPYNO_ALL, entry, NULL); 5689 if (SOC_FAILURE(r)) { 5690 if (r == SOC_E_FULL) { 5691 /* Bucket overflow, just pass on */ 5692 continue; 5693 } else { 5694 test_error(unit, "L3 insert failed at bucket %d bank %d\n", 5695 l3_bucket_array[bank], bank); 5696 rv = -1; 5697 goto done; 5698 } 5699 } 5700 5701 /* Now we search for the entry */ 5702 hard_index = 0; 5703 if (soc_mem_search(unit, mem, COPYNO_ALL, 5704 &hard_index, entry, entry_lkup, 0) < 0) { 5705 test_error(unit, "Entry lookup failed\n"); 5706 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5707 goto done; 5708 } 5709 5710 /* entries per bucket */ 5711 bucket_offset = hard_index - l3_index_array[bank]; 5712 if (bucket_offset < 0 || bucket_offset >= bucket_size) { 5713 test_error(unit, 5714 "Hardware Hash %d out range of Software Hash base %d (%d)\n", 5715 hard_index, l3_index_array[bank], bucket_offset); 5716 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5717 goto done; 5718 } 5719 5720 /* Only do a quick check vs. expected bucket here */ 5721 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, entry) < 0) { 5722 test_error(unit, "Entry not found in bank%d baseIndex %d\n", 5723 bank, l3_index_array[bank]); 5724 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 5725 rv = -1; 5726 goto done; 5727 } 5728 5729 /* Clean up afterward */ 5730 if (soc_mem_delete(unit, mem, COPYNO_ALL, entry) < 0) { 5731 test_error(unit, "L3 delete failed at bucket %d bank %d\n", 5732 l3_bucket_array[bank], bank); 5733 rv = -1; 5734 goto done; 5735 } 5736 5737 increment_ip6addr(src_ip, 15, src_ip_inc); 5738 increment_ip6addr(dst_ip, 15, dst_ip_inc); 5739 vid += vid_inc; 5740 if (vid > DRACO_L3_VID_MAX) { 5741 vid = 1; 5742 } 5743 if (vrf_id_max) { 5744 vrf_id += vrf_id_inc; 5745 if (vrf_id > vrf_id_max) { 5746 vrf_id = 0; 5747 } 5748 } 5749 } 5750 } 5751 5752 done: 5753 return rv; 5754 } 5755 5756 int 5757 _td2_l3ip4ucast_test_ov(int unit, args_t *a, void *p) 5758 { 5759 uint32 *entry_array = NULL; 5760 uint32 entry[SOC_MAX_MEM_WORDS]; 5761 uint32 result[SOC_MAX_MEM_WORDS]; 5762 soc_mem_t mem = L3_ENTRY_IPV4_UNICASTm; 5763 int bank; 5764 uint32 bank_count; 5765 int bucket_size = SOC_TD2_L3X_BUCKET_SIZE; 5766 int num_ent_per_bucket; 5767 int num_bucket_per_bank; 5768 int num_vbits; 5769 int num_buckets; 5770 ip_addr_t dst_ip; 5771 int dst_ip_inc; 5772 bcm_vlan_t vid; 5773 int vid_inc; 5774 int r, rv = 0; 5775 int ix, offset, j, idx; 5776 int iterations; 5777 draco_l3_testdata_t *ad = p; 5778 int hash = ad->opt_hash; 5779 int vrf_id; 5780 int vrf_id_inc; 5781 int vrf_id_max = 0; 5782 int alloc_sz; 5783 int found; 5784 int num_l3_banks = 0; 5785 int l3_index_array[L3_MAX_BANKS] = {0}; 5786 int l3_bucket_array[L3_MAX_BANKS] = {0}; 5787 int phy_bank_array[L3_MAX_BANKS] = {0}; 5788 int entry_num_array[L3_MAX_BANKS] = {0}; 5789 5790 5791 COMPILER_REFERENCE(a); 5792 vrf_id_max = SOC_VRF_MAX(unit); 5793 num_vbits = 1; 5794 5795 #ifdef BCM_TRIDENT3_SUPPORT 5796 if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) { 5797 mem = L3_ENTRY_SINGLEm; 5798 } 5799 #endif /* BCM_TRIDENT3_SUPPORT */ 5800 5801 num_ent_per_bucket = bucket_size / num_vbits; 5802 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 5803 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 5804 5805 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 5806 &bank_count)) < 0) { 5807 test_error(unit, "Getting bank count for L3 table failed\n"); 5808 rv = -1; 5809 goto done; 5810 } 5811 alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count; 5812 entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array"); 5813 if (entry_array == NULL) { 5814 rv = -1; 5815 goto done; 5816 } 5817 for (bank = 0; bank < bank_count; bank++) { 5818 if (ad->opt_verbose) { 5819 cli_out("Resetting hash bank %d selection to LSB\n", bank); 5820 } 5821 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank, 5822 BCM_HASH_LSB, 48)) < 0) { 5823 test_error(unit, "Hash bank setting failed: unit %d, bank %d\n", 5824 unit, bank); 5825 rv = -1; 5826 goto done; 5827 } 5828 } 5829 5830 if (hash != FB_HASH_LSB) { 5831 ad->opt_hash = hash = FB_HASH_LSB; 5832 } 5833 5834 dst_ip = ad->opt_base_ip; 5835 dst_ip_inc = ad->opt_ip_inc; 5836 vid = ad->opt_base_vid; 5837 vid_inc = ad->opt_vid_inc; 5838 vrf_id = ad->opt_base_vrf_id; 5839 vrf_id_inc = ad->opt_vrf_id_inc; 5840 5841 sal_memset(entry, 0, sizeof(entry)); 5842 #ifdef BCM_TRIDENT3_SUPPORT 5843 if (soc_mem_is_valid(unit, L3_ENTRY_SINGLEm)) { 5844 l3_entry_key_attributes_entry_t l3_key_attr; 5845 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 5846 TD2_L3_HASH_KEY_TYPE_V4UC); 5847 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 5848 TD2_L3_HASH_KEY_TYPE_V4UC); 5849 soc_mem_field32_set(unit, mem, entry, BASE_VALIDf, 1); 5850 if (vrf_id_max) { 5851 soc_mem_field32_set(unit, mem, entry, IPV4UC__VRF_IDf, 1); 5852 } 5853 5854 /* Set L3 Entry Key Attributes */ 5855 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 5856 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5857 BUCKET_MODEf, 0); 5858 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5859 KEY_BASE_WIDTHf, 0); 5860 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5861 KEY_WIDTHf, 12); 5862 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5863 DATA_BASE_WIDTHf, 1); 5864 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 5865 HASH_LSB_OFFSETf, 5); 5866 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 5867 TD3_L3_HASH_KEY_TYPE_V4UC, 5868 (uint32*)&l3_key_attr) < 0) { 5869 test_error(unit, "L3 Entry Key Attr setting failed\n"); 5870 goto done; 5871 } 5872 } else 5873 #endif 5874 { 5875 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 5876 TD2_L3_HASH_KEY_TYPE_V4UC); 5877 soc_mem_field32_set(unit, mem, entry, VALIDf, 1); 5878 if (vrf_id_max) { 5879 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 5880 } 5881 } 5882 5883 while (iterations--) { 5884 sal_memset(entry_array, 0, alloc_sz); 5885 for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) { 5886 soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip); 5887 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) { 5888 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 5889 } 5890 if (vrf_id_max) { 5891 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 5892 } 5893 5894 if (ix == 0) { 5895 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 5896 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 5897 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 5898 (SOC_IS_TRIDENT3X(unit))) { 5899 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 5900 &num_l3_banks, l3_bucket_array, 5901 l3_index_array, phy_bank_array, 5902 entry_num_array)) < 0) { 5903 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 5904 goto done; 5905 } 5906 5907 if (num_l3_banks > L3_MAX_BANKS) { 5908 cli_out("%s ERROR: the number of banks overflow\n", 5909 ARG_CMD(a)); 5910 rv = -1; 5911 goto done; 5912 } 5913 for (bank = 0; bank < bank_count; bank++) { 5914 num_bucket_per_bank = entry_num_array[bank] / 5915 num_ent_per_bucket; 5916 dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 5917 dst_ip_inc : num_bucket_per_bank; 5918 } 5919 } else 5920 #endif 5921 { 5922 rv = -1; 5923 goto done; 5924 } 5925 5926 if (ad->opt_verbose) { 5927 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 5928 for (bank = 0; bank < bank_count; bank++) { 5929 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 5930 bank, phy_bank_array[bank], 5931 l3_bucket_array[bank], l3_bucket_array[bank], 5932 l3_index_array[bank], l3_index_array[bank]); 5933 } 5934 } 5935 } 5936 5937 offset = ix * SOC_MAX_MEM_WORDS; 5938 memcpy(&entry_array[offset], entry, sizeof(entry)); 5939 if (ad->opt_verbose) { 5940 cli_out("Inserting "); 5941 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI); 5942 } 5943 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, 5944 &entry_array[offset])) < 0) { 5945 if (r == SOC_E_FULL) { 5946 /* Already full, stop wasting time */ 5947 break; 5948 } else { 5949 test_error(unit, "L3 insert failed!\n"); 5950 rv = -1; 5951 goto done; 5952 } 5953 } 5954 5955 /* Increment key by number of buckets in the table */ 5956 dst_ip += dst_ip_inc; 5957 vid += vid_inc; 5958 if (vid > DRACO_L3_VID_MAX) { 5959 vid = 1; 5960 } 5961 if (vrf_id_max) { 5962 vrf_id += vrf_id_inc; 5963 if (vrf_id > vrf_id_max) { 5964 vrf_id = 0; 5965 } 5966 } 5967 } 5968 5969 if (ad->opt_verbose) { 5970 cli_out("Inserting %dth entry in banks should fail\n", 5971 (num_ent_per_bucket * bank_count + 1)); 5972 } 5973 5974 soc_mem_field_set(unit, mem, entry, IP_ADDRf, &dst_ip); 5975 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_IDf)) { 5976 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 5977 } 5978 if (vrf_id_max) { 5979 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 5980 } 5981 5982 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 5983 if (r != SOC_E_FULL) { 5984 test_error(unit, "L3 insert failed\n"); 5985 rv = -1; 5986 goto done; 5987 } 5988 } else { 5989 test_error(unit, "L3 insert to full bucket succeeded\n"); 5990 rv = -1; 5991 goto done; 5992 } 5993 5994 if (ad->opt_verbose) { 5995 cli_out("Verifying installed entries\n"); 5996 } 5997 5998 /* Verify bucket contains our added entries */ 5999 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 6000 found = 0; 6001 offset = j * SOC_MAX_MEM_WORDS; 6002 for (bank = 0; bank < bank_count; bank++) { 6003 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, 6004 &(entry_array[offset])) == 0) { 6005 found = 1; 6006 break; 6007 } 6008 } 6009 if (!found) { 6010 test_error(unit, 6011 "%s entry j %d missing on all banks\n", 6012 SOC_MEM_NAME(unit, mem), j); 6013 rv = -1; 6014 goto done; 6015 } 6016 if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 6017 &entry_array[offset], &result, 0) < 0) { 6018 test_error(unit, 6019 "%s entry missing at bucket %d index %d on bank %d\n", 6020 SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 6021 l3_index_array[bank], bank); 6022 rv = -1; 6023 goto done; 6024 } 6025 if (idx < (l3_index_array[bank]) || 6026 idx >= (l3_index_array[bank] + num_ent_per_bucket)) { 6027 test_error(unit, "%s entry inserted into wrong index" 6028 " Expected [%d-%d] Actual %d\n", 6029 SOC_MEM_NAME(unit, mem), 6030 l3_index_array[bank], 6031 l3_index_array[bank] + num_ent_per_bucket, 6032 idx); 6033 rv = -1; 6034 goto done; 6035 } 6036 } 6037 6038 if (ad->opt_verbose) { 6039 cli_out("Cleaning each entry on all banks...\n"); 6040 } 6041 6042 /* Remove the entries that we added */ 6043 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 6044 offset = j * SOC_MAX_MEM_WORDS; 6045 if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) { 6046 test_error(unit, "L3 delete j %d failed on all banks\n", j); 6047 rv = -1; 6048 goto done; 6049 } 6050 } 6051 6052 /* Do Next bucket */ 6053 dst_ip += 1; 6054 vid += vid_inc; 6055 if (vid > DRACO_L3_VID_MAX) { 6056 vid = 1; 6057 } 6058 if (vrf_id_max) { 6059 vrf_id += vrf_id_inc; 6060 if (vrf_id > vrf_id_max) { 6061 vrf_id = 0; 6062 } 6063 } 6064 } 6065 6066 done: 6067 if (entry_array) { 6068 sal_free(entry_array); 6069 entry_array = NULL; 6070 } 6071 return rv; 6072 } 6073 6074 int 6075 _td2_l3ip4mcast_test_ov(int unit, args_t *a, void *p) 6076 { 6077 uint32 *entry_array = NULL; 6078 uint32 entry[SOC_MAX_MEM_WORDS]; 6079 uint32 result[SOC_MAX_MEM_WORDS]; 6080 soc_mem_t mem = L3_ENTRY_IPV4_MULTICASTm; 6081 int bank; 6082 uint32 bank_count; 6083 int bucket_size = SOC_TD2_L3X_BUCKET_SIZE; 6084 int num_ent_per_bucket; 6085 int num_bucket_per_bank; 6086 int num_vbits; 6087 int num_buckets; 6088 ip_addr_t src_ip; 6089 ip_addr_t dst_ip; 6090 int src_ip_inc; 6091 int dst_ip_inc; 6092 bcm_vlan_t vid; 6093 int vid_inc; 6094 int r, rv = 0; 6095 int ix, offset, j, idx; 6096 int iterations; 6097 draco_l3_testdata_t *ad = p; 6098 int hash = ad->opt_hash; 6099 int vrf_id; 6100 int vrf_id_inc; 6101 int vrf_id_max = 0; 6102 uint32 hash_read; 6103 int alloc_sz; 6104 int found; 6105 int num_l3_banks = 0; 6106 int l3_index_array[L3_MAX_BANKS] = {0}; 6107 int l3_bucket_array[L3_MAX_BANKS] = {0}; 6108 int phy_bank_array[L3_MAX_BANKS] = {0}; 6109 int entry_num_array[L3_MAX_BANKS] = {0}; 6110 6111 6112 COMPILER_REFERENCE(a); 6113 6114 num_vbits = 2; 6115 #ifdef BCM_TRIDENT3_SUPPORT 6116 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6117 mem = L3_ENTRY_DOUBLEm; 6118 num_vbits = 1; 6119 } 6120 #endif /* BCM_TRIDENT3_SUPPORT */ 6121 6122 vrf_id_max = SOC_VRF_MAX(unit); 6123 6124 num_ent_per_bucket = bucket_size / num_vbits; 6125 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 6126 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 6127 6128 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 6129 &bank_count)) < 0) { 6130 test_error(unit, "Getting bank count for L3 table failed\n"); 6131 rv = -1; 6132 goto done; 6133 } 6134 alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count; 6135 entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array"); 6136 if (entry_array == NULL) { 6137 rv = -1; 6138 goto done; 6139 } 6140 for (bank = 0; bank < bank_count; bank++) { 6141 if (ad->opt_verbose) { 6142 cli_out("Resetting hash bank %d selection to LSB\n", bank); 6143 } 6144 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank, 6145 BCM_HASH_LSB, 48)) < 0) { 6146 test_error(unit, "Hash bank setting failed: unit %d, bank %d\n", 6147 unit, bank); 6148 rv = -1; 6149 goto done; 6150 } 6151 } 6152 6153 if (hash != FB_HASH_LSB) { 6154 ad->opt_hash = hash = FB_HASH_LSB; 6155 } 6156 6157 if (ad->opt_key_src_ip) { 6158 src_ip_inc = ad->opt_src_ip_inc; 6159 src_ip = ad->opt_src_ip; 6160 } else { 6161 src_ip_inc = 0; 6162 src_ip = 0; 6163 } 6164 dst_ip = ad->opt_base_ip; 6165 dst_ip_inc = ad->opt_ip_inc; 6166 vid = ad->opt_base_vid; 6167 vid_inc = ad->opt_vid_inc; 6168 vrf_id = ad->opt_base_vrf_id; 6169 vrf_id_inc = ad->opt_vrf_id_inc; 6170 6171 sal_memset (entry, 0, sizeof(entry)); 6172 #ifdef BCM_TRIDENT3_SUPPORT 6173 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6174 l3_entry_key_attributes_entry_t l3_key_attr; 6175 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 6176 TD3_L3_HASH_KEY_TYPE_V4MC); 6177 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 6178 TD3_L3_HASH_DATA_TYPE_V4MC); 6179 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3); 6180 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7); 6181 if (vrf_id_max) { 6182 soc_mem_field32_set(unit, mem, entry, IPV4MC__VRF_IDf, 1); 6183 } 6184 6185 /* Set L3 Entry Key Attributes */ 6186 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 6187 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6188 BUCKET_MODEf, 1); 6189 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6190 KEY_BASE_WIDTHf, 0); 6191 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6192 KEY_WIDTHf, 23); 6193 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6194 DATA_BASE_WIDTHf, 1); 6195 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6196 HASH_LSB_OFFSETf, 5); 6197 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 6198 TD3_L3_HASH_KEY_TYPE_V4MC, 6199 (uint32*)&l3_key_attr) < 0) { 6200 test_error(unit, "L3 Entry Key Attr setting failed\n"); 6201 goto done; 6202 } 6203 } else 6204 #endif 6205 { 6206 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 6207 TD2_L3_HASH_KEY_TYPE_V4MC); 6208 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 6209 TD2_L3_HASH_KEY_TYPE_V4MC); 6210 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 6211 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 6212 if (vrf_id_max) { 6213 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 6214 } 6215 } 6216 while (iterations--) { 6217 sal_memset(entry_array, 0, alloc_sz); 6218 for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) { 6219 #ifdef BCM_TRIDENT3_SUPPORT 6220 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6221 soc_mem_field_set(unit, mem, entry, 6222 IPV4MC__GROUP_IP_ADDRf, &dst_ip); 6223 soc_mem_field_set(unit, mem, entry, 6224 IPV4MC__SOURCE_IP_ADDRf, &src_ip); 6225 soc_mem_field32_set(unit, mem, entry, 6226 IPV4MC__VLAN_IDf, vid); 6227 if (vrf_id_max) { 6228 soc_mem_field32_set(unit, mem,entry, 6229 IPV4MC__VRF_IDf, vrf_id); 6230 } 6231 } else 6232 #endif 6233 { 6234 soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip); 6235 soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip); 6236 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 6237 if (vrf_id_max) { 6238 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 6239 } 6240 } 6241 6242 if (ix == 0) { 6243 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 6244 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 6245 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 6246 SOC_IS_TRIDENT3X(unit)) { 6247 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 6248 &num_l3_banks, l3_bucket_array, 6249 l3_index_array, phy_bank_array, 6250 entry_num_array)) < 0) { 6251 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 6252 goto done; 6253 } 6254 6255 if (num_l3_banks > L3_MAX_BANKS) { 6256 cli_out("%s ERROR: the number of banks overflow\n", 6257 ARG_CMD(a)); 6258 rv = -1; 6259 goto done; 6260 } 6261 for (bank = 0; bank < bank_count; bank++) { 6262 num_bucket_per_bank = entry_num_array[bank] / 6263 num_ent_per_bucket; 6264 dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 6265 dst_ip_inc : num_bucket_per_bank; 6266 } 6267 } else 6268 #endif 6269 { 6270 rv = -1; 6271 goto done; 6272 } 6273 6274 if (ad->opt_verbose) { 6275 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 6276 for (bank = 0; bank < bank_count; bank++) { 6277 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 6278 bank, phy_bank_array[bank], 6279 l3_bucket_array[bank], l3_bucket_array[bank], 6280 l3_index_array[bank], l3_index_array[bank]); 6281 } 6282 } 6283 } 6284 6285 offset = ix * SOC_MAX_MEM_WORDS; 6286 memcpy(&entry_array[offset], entry, sizeof(entry)); 6287 if (ad->opt_verbose) { 6288 cli_out("Inserting "); 6289 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI); 6290 } 6291 if (READ_HASH_CONTROLr(unit, &hash_read) < 0) { 6292 test_error(unit, "Hash select read failed\n"); 6293 goto done; 6294 } 6295 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, &entry_array[offset])) < 0) { 6296 if (r == SOC_E_FULL) { 6297 /* Already full, stop wasting time */ 6298 break; 6299 } else { 6300 test_error(unit, "L3 insert failed!\n"); 6301 rv = -1; 6302 goto done; 6303 } 6304 } 6305 if (READ_HASH_CONTROLr(unit, &hash_read) < 0) { 6306 test_error(unit, "Hash select read failed\n"); 6307 goto done; 6308 } 6309 6310 /* Increment key by number of buckets in the table */ 6311 dst_ip += dst_ip_inc; 6312 src_ip += src_ip_inc; 6313 vid += vid_inc; 6314 if (vid > DRACO_L3_VID_MAX) { 6315 vid = 1; 6316 } 6317 if (vrf_id_max) { 6318 vrf_id += vrf_id_inc; 6319 if (vrf_id > vrf_id_max) { 6320 vrf_id = 0; 6321 } 6322 } 6323 } 6324 6325 if (ad->opt_verbose) { 6326 cli_out("Inserting %dth entry in banks should fail\n", 6327 (num_ent_per_bucket * bank_count + 1)); 6328 } 6329 6330 #ifdef BCM_TRIDENT3_SUPPORT 6331 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6332 soc_mem_field_set(unit, mem, entry, 6333 IPV4MC__GROUP_IP_ADDRf, &dst_ip); 6334 soc_mem_field_set(unit, mem, entry, 6335 IPV4MC__SOURCE_IP_ADDRf, &src_ip); 6336 soc_mem_field32_set(unit, mem, entry, 6337 IPV4MC__VLAN_IDf, vid); 6338 if (vrf_id_max) { 6339 soc_mem_field32_set(unit, mem,entry, 6340 IPV4MC__VRF_IDf, vrf_id); 6341 } 6342 } else 6343 #endif 6344 { 6345 soc_mem_field_set(unit, mem, entry, GROUP_IP_ADDRf, &dst_ip); 6346 soc_mem_field_set(unit, mem, entry, SOURCE_IP_ADDRf, &src_ip); 6347 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 6348 if (vrf_id_max) { 6349 soc_mem_field32_set(unit, mem, entry, VRF_IDf, vrf_id); 6350 } 6351 } 6352 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 6353 if (r != SOC_E_FULL) { 6354 test_error(unit, "L3 insert failed\n"); 6355 rv = -1; 6356 goto done; 6357 } 6358 } else { 6359 test_error(unit, "L3 insert to full bucket succeeded\n"); 6360 rv = -1; 6361 goto done; 6362 } 6363 6364 if (ad->opt_verbose) { 6365 cli_out("Verifying installed entries\n"); 6366 } 6367 6368 /* Verify bucket contains our added entries */ 6369 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 6370 found = 0; 6371 offset = j * SOC_MAX_MEM_WORDS; 6372 for (bank = 0; bank < bank_count; bank++) { 6373 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, 6374 &(entry_array[offset])) == 0) { 6375 found = 1; 6376 break; 6377 } 6378 } 6379 if (!found) { 6380 test_error(unit, 6381 "%s entry j %d missing on all banks\n", 6382 SOC_MEM_NAME(unit, mem), j); 6383 rv = -1; 6384 goto done; 6385 } 6386 if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 6387 &entry_array[offset], &result, 0) < 0) { 6388 test_error(unit, 6389 "%s entry missing at bucket %d index %d on bank %d\n", 6390 SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 6391 l3_index_array[bank], bank); 6392 rv = -1; 6393 goto done; 6394 } 6395 if (idx < (l3_index_array[bank]) || 6396 idx >= (l3_index_array[bank] + num_ent_per_bucket)) { 6397 test_error(unit, "%s entry inserted into wrong index" 6398 " Expected [%d-%d] Actual %d\n", 6399 SOC_MEM_NAME(unit, mem), 6400 l3_index_array[bank], 6401 l3_index_array[bank] + num_ent_per_bucket, 6402 idx); 6403 rv = -1; 6404 goto done; 6405 } 6406 } 6407 6408 if (ad->opt_verbose) { 6409 cli_out("Cleaning each entry on all banks...\n"); 6410 } 6411 6412 /* Remove the entries that we added */ 6413 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 6414 offset = j * SOC_MAX_MEM_WORDS; 6415 if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) { 6416 test_error(unit, "L3 delete j %d failed on all banks\n", j); 6417 rv = -1; 6418 goto done; 6419 } 6420 } 6421 6422 /* Do Next bucket */ 6423 dst_ip += 1; 6424 src_ip += src_ip_inc; 6425 vid += vid_inc; 6426 if (vid > DRACO_L3_VID_MAX) { 6427 vid = 1; 6428 } 6429 if (vrf_id_max) { 6430 vrf_id += vrf_id_inc; 6431 if (vrf_id > vrf_id_max) { 6432 vrf_id = 0; 6433 } 6434 } 6435 } 6436 6437 done: 6438 if (entry_array) { 6439 sal_free(entry_array); 6440 entry_array = NULL; 6441 } 6442 return rv; 6443 } 6444 6445 int 6446 _td2_l3ip6ucast_test_ov(int unit, args_t *a, void *p) 6447 { 6448 uint32 *entry_array = NULL; 6449 uint32 entry[SOC_MAX_MEM_WORDS]; 6450 uint32 result[SOC_MAX_MEM_WORDS]; 6451 soc_mem_t mem = L3_ENTRY_IPV6_UNICASTm; 6452 int bank; 6453 uint32 bank_count; 6454 int bucket_size = SOC_TD2_L3X_BUCKET_SIZE; 6455 int num_ent_per_bucket; 6456 int num_bucket_per_bank; 6457 int num_vbits; 6458 int num_buckets; 6459 ip6_addr_t dst_ip; 6460 int dst_ip_inc; 6461 uint32 ip_tmp[2]; 6462 bcm_vlan_t vid; 6463 int vid_inc; 6464 int r, rv = 0; 6465 int ix, offset, j, idx; 6466 int iterations; 6467 draco_l3_testdata_t *ad = p; 6468 int hash = ad->opt_hash; 6469 int vrf_id; 6470 int vrf_id_inc; 6471 int vrf_id_max = 0; 6472 int alloc_sz; 6473 int found; 6474 int num_l3_banks = 0; 6475 int l3_index_array[L3_MAX_BANKS] = {0}; 6476 int l3_bucket_array[L3_MAX_BANKS] = {0}; 6477 int phy_bank_array[L3_MAX_BANKS] = {0}; 6478 int entry_num_array[L3_MAX_BANKS] = {0}; 6479 6480 COMPILER_REFERENCE(a); 6481 vrf_id_max = SOC_VRF_MAX(unit); 6482 num_vbits = 2; 6483 6484 #ifdef BCM_TRIDENT3_SUPPORT 6485 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6486 mem = L3_ENTRY_DOUBLEm; 6487 num_vbits = 1; 6488 } 6489 #endif 6490 6491 num_ent_per_bucket = bucket_size / num_vbits; 6492 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 6493 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 6494 6495 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 6496 &bank_count)) < 0) { 6497 test_error(unit, "Getting bank count for L3 table failed\n"); 6498 rv = -1; 6499 goto done; 6500 } 6501 alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count; 6502 entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array"); 6503 if (entry_array == NULL) { 6504 rv = -1; 6505 goto done; 6506 } 6507 for (bank = 0; bank < bank_count; bank++) { 6508 if (ad->opt_verbose) { 6509 cli_out("Resetting hash bank %d selection to LSB\n", bank); 6510 } 6511 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank, 6512 BCM_HASH_LSB, 48)) < 0) { 6513 test_error(unit, "Hash bank setting failed: unit %d, bank %d\n", 6514 unit, bank); 6515 rv = -1; 6516 goto done; 6517 } 6518 } 6519 6520 if (hash != FB_HASH_LSB) { 6521 ad->opt_hash = hash = FB_HASH_LSB; 6522 } 6523 6524 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 6525 dst_ip_inc = ad->opt_ip_inc; 6526 vid = ad->opt_base_vid; 6527 vid_inc = ad->opt_vid_inc; 6528 vrf_id = ad->opt_base_vrf_id; 6529 vrf_id_inc = ad->opt_vrf_id_inc; 6530 sal_memset (entry, 0, sizeof(entry)); 6531 #ifdef BCM_TRIDENT3_SUPPORT 6532 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6533 l3_entry_key_attributes_entry_t l3_key_attr; 6534 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 6535 TD3_L3_HASH_KEY_TYPE_V6UC); 6536 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 6537 TD3_L3_HASH_DATA_TYPE_V6UC); 6538 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3); 6539 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 4); 6540 if (vrf_id_max) { 6541 soc_mem_field32_set(unit, mem, entry, IPV6UC__VRF_IDf, 1); 6542 } 6543 6544 /* Set L3 Entry Key Attributes */ 6545 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 6546 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6547 BUCKET_MODEf, 1); 6548 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6549 KEY_BASE_WIDTHf, 1); 6550 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6551 KEY_WIDTHf, 15); 6552 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6553 DATA_BASE_WIDTHf, 2); 6554 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6555 HASH_LSB_OFFSETf, 5); 6556 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 6557 TD3_L3_HASH_KEY_TYPE_V6UC, 6558 (uint32*)&l3_key_attr) < 0) { 6559 test_error(unit, "L3 Entry Key Attr setting failed\n"); 6560 goto done; 6561 } 6562 } else 6563 #endif 6564 { 6565 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 6566 TD2_L3_HASH_KEY_TYPE_V6UC); 6567 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 6568 TD2_L3_HASH_KEY_TYPE_V6UC); 6569 if (vrf_id_max) { 6570 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 6571 } 6572 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 6573 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 6574 } 6575 while (iterations--) { 6576 sal_memset(entry_array, 0, alloc_sz); 6577 for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) { 6578 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 6579 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 6580 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 6581 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 6582 #ifdef BCM_TRIDENT3_SUPPORT 6583 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6584 soc_mem_field_set(unit, mem, entry, 6585 IPV6UC__IP_ADDR_LWR_64f, ip_tmp); 6586 } else 6587 #endif 6588 { 6589 6590 soc_mem_field_set(unit, mem, entry, 6591 IP_ADDR_LWR_64f, ip_tmp); 6592 } 6593 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 6594 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 6595 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 6596 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 6597 #ifdef BCM_TRIDENT3_SUPPORT 6598 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6599 soc_mem_field_set(unit, mem, entry, 6600 IPV6UC__IP_ADDR_UPR_64f, ip_tmp); 6601 } else 6602 #endif 6603 { 6604 soc_mem_field_set(unit, mem, entry, 6605 IP_ADDR_UPR_64f, ip_tmp); 6606 } 6607 if (vrf_id_max) { 6608 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 6609 } 6610 6611 if (ix == 0) { 6612 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 6613 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 6614 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 6615 SOC_IS_TRIDENT3X(unit)) { 6616 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 6617 &num_l3_banks, l3_bucket_array, 6618 l3_index_array, phy_bank_array, 6619 entry_num_array)) < 0) { 6620 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 6621 goto done; 6622 } 6623 6624 if (num_l3_banks > L3_MAX_BANKS) { 6625 cli_out("%s ERROR: the number of banks overflow\n", 6626 ARG_CMD(a)); 6627 rv = -1; 6628 goto done; 6629 } 6630 for (bank = 0; bank < bank_count; bank++) { 6631 num_bucket_per_bank = entry_num_array[bank] / 6632 num_ent_per_bucket; 6633 dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 6634 dst_ip_inc : num_bucket_per_bank; 6635 } 6636 } else 6637 #endif 6638 { 6639 rv = -1; 6640 goto done; 6641 } 6642 6643 if (ad->opt_verbose) { 6644 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 6645 for (bank = 0; bank < bank_count; bank++) { 6646 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 6647 bank, phy_bank_array[bank], 6648 l3_bucket_array[bank], l3_bucket_array[bank], 6649 l3_index_array[bank], l3_index_array[bank]); 6650 } 6651 } 6652 } 6653 6654 offset = ix * SOC_MAX_MEM_WORDS; 6655 memcpy(&entry_array[offset], entry, sizeof(entry)); 6656 if (ad->opt_verbose) { 6657 cli_out("Inserting "); 6658 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI); 6659 } 6660 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, &entry_array[offset])) < 0) { 6661 if (r == SOC_E_FULL) { 6662 /* Already full, stop wasting time */ 6663 break; 6664 } else { 6665 test_error(unit, "L3 insert failed!\n"); 6666 rv = -1; 6667 goto done; 6668 } 6669 } 6670 6671 /* Increment key by number of buckets in the table */ 6672 increment_ip6addr(dst_ip, 15, dst_ip_inc); 6673 vid += vid_inc; 6674 if (vid > DRACO_L3_VID_MAX) { 6675 vid = 1; 6676 } 6677 if (vrf_id_max) { 6678 vrf_id += vrf_id_inc; 6679 if (vrf_id > vrf_id_max) { 6680 vrf_id = 0; 6681 } 6682 } 6683 } 6684 6685 if (ad->opt_verbose) { 6686 cli_out("Inserting %dth entry in banks should fail\n", 6687 (num_ent_per_bucket * bank_count + 1)); 6688 } 6689 6690 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 6691 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 6692 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 6693 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 6694 #ifdef BCM_TRIDENT3_SUPPORT 6695 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6696 soc_mem_field_set(unit, mem, entry, 6697 IPV6UC__IP_ADDR_LWR_64f, ip_tmp); 6698 } else 6699 #endif 6700 { 6701 soc_mem_field_set(unit, mem, entry, 6702 IP_ADDR_LWR_64f, ip_tmp); 6703 } 6704 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 6705 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 6706 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 6707 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 6708 #ifdef BCM_TRIDENT3_SUPPORT 6709 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 6710 soc_mem_field_set(unit, mem, entry, 6711 IPV6UC__IP_ADDR_UPR_64f, ip_tmp); 6712 } else 6713 #endif 6714 { 6715 soc_mem_field_set(unit, mem, entry, 6716 IP_ADDR_UPR_64f, ip_tmp); 6717 } 6718 if (vrf_id_max) { 6719 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 6720 } 6721 6722 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 6723 if (r != SOC_E_FULL) { 6724 test_error(unit, "L3 insert failed\n"); 6725 rv = -1; 6726 goto done; 6727 } 6728 } else { 6729 test_error(unit, "L3 insert to full bucket succeeded\n"); 6730 rv = -1; 6731 goto done; 6732 } 6733 6734 if (ad->opt_verbose) { 6735 cli_out("Verifying installed entries\n"); 6736 } 6737 6738 /* Verify bucket contains added entries */ 6739 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 6740 found = 0; 6741 offset = j * SOC_MAX_MEM_WORDS; 6742 for (bank = 0; bank < bank_count; bank++) { 6743 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, 6744 &(entry_array[offset])) == 0) { 6745 found = 1; 6746 break; 6747 } 6748 } 6749 if (!found) { 6750 test_error(unit, 6751 "%s entry j %d missing on all banks\n", 6752 SOC_MEM_NAME(unit, mem), j); 6753 rv = -1; 6754 goto done; 6755 } 6756 if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 6757 &entry_array[offset], &result, 0) < 0) { 6758 test_error(unit, 6759 "%s entry missing at bucket %d index %d on bank %d\n", 6760 SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 6761 l3_index_array[bank], bank); 6762 rv = -1; 6763 goto done; 6764 } 6765 if (idx < (l3_index_array[bank]) || 6766 idx >= (l3_index_array[bank] + num_ent_per_bucket)) { 6767 test_error(unit, "%s entry inserted into wrong index" 6768 " Expected [%d-%d] Actual %d\n", 6769 SOC_MEM_NAME(unit, mem), 6770 l3_index_array[bank], 6771 l3_index_array[bank] + num_ent_per_bucket, 6772 idx); 6773 rv = -1; 6774 goto done; 6775 } 6776 } 6777 6778 if (ad->opt_verbose) { 6779 cli_out("Cleaning each entry on all banks...\n"); 6780 } 6781 6782 /* Remove the entries that we added */ 6783 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 6784 offset = j * SOC_MAX_MEM_WORDS; 6785 if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) { 6786 test_error(unit, "L3 delete j %d failed on all banks\n", j); 6787 rv = -1; 6788 goto done; 6789 } 6790 } 6791 6792 /* Do Next bucket */ 6793 increment_ip6addr(dst_ip, 15, 1); 6794 vid += vid_inc; 6795 if (vid > DRACO_L3_VID_MAX) { 6796 vid = 1; 6797 } 6798 if (vrf_id_max) { 6799 vrf_id += vrf_id_inc; 6800 if (vrf_id > vrf_id_max) { 6801 vrf_id = 0; 6802 } 6803 } 6804 } 6805 6806 done: 6807 if (entry_array) { 6808 sal_free(entry_array); 6809 entry_array = NULL; 6810 } 6811 return rv; 6812 } 6813 6814 int 6815 _td2_l3ip6mcast_test_ov(int unit, args_t *a, void *p) 6816 { 6817 uint32 *entry_array = NULL; 6818 uint32 entry[SOC_MAX_MEM_WORDS]; 6819 uint32 result[SOC_MAX_MEM_WORDS]; 6820 soc_mem_t mem = L3_ENTRY_IPV6_MULTICASTm; 6821 int bank; 6822 uint32 bank_count; 6823 int bucket_size = SOC_TD2_L3X_BUCKET_SIZE; 6824 int num_ent_per_bucket; 6825 int num_bucket_per_bank; 6826 int num_vbits; 6827 int num_buckets; 6828 ip6_addr_t src_ip; 6829 ip6_addr_t dst_ip; 6830 uint32 ip_tmp[2]; 6831 int src_ip_inc; 6832 int dst_ip_inc; 6833 bcm_vlan_t vid; 6834 int vid_inc; 6835 int r, rv = 0; 6836 int ix, offset, j, idx; 6837 int iterations; 6838 draco_l3_testdata_t *ad = p; 6839 int hash = ad->opt_hash; 6840 int vrf_id; 6841 int vrf_id_inc; 6842 int vrf_id_max = 0; 6843 int alloc_sz; 6844 int found; 6845 int num_l3_banks = 0; 6846 int l3_index_array[L3_MAX_BANKS] = {0}; 6847 int l3_bucket_array[L3_MAX_BANKS] = {0}; 6848 int phy_bank_array[L3_MAX_BANKS] = {0}; 6849 int entry_num_array[L3_MAX_BANKS] = {0}; 6850 6851 COMPILER_REFERENCE(a); 6852 vrf_id_max = SOC_VRF_MAX(unit); 6853 num_vbits = 4; 6854 6855 #ifdef BCM_TRIDENT3_SUPPORT 6856 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 6857 mem = L3_ENTRY_QUADm; 6858 num_vbits = 1; 6859 } 6860 #endif 6861 num_ent_per_bucket = bucket_size / num_vbits; 6862 num_buckets = soc_mem_index_count(unit, mem) / num_ent_per_bucket; 6863 iterations = (ad->opt_count > num_buckets) ? num_buckets : ad->opt_count; 6864 6865 if ((r = bcm_switch_hash_banks_max_get(unit, bcmHashTableL3, 6866 &bank_count)) < 0) { 6867 test_error(unit, "Getting bank count for L3 table failed\n"); 6868 rv = -1; 6869 goto done; 6870 } 6871 alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_ent_per_bucket * bank_count; 6872 entry_array = sal_alloc(alloc_sz, "L3_ENTRY_IPV4_UNICASTm entry_array"); 6873 if (entry_array == NULL) { 6874 rv = -1; 6875 goto done; 6876 } 6877 for (bank = 0; bank < bank_count; bank++) { 6878 if (ad->opt_verbose) { 6879 cli_out("Resetting hash bank %d selection to LSB\n", bank); 6880 } 6881 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank, 6882 BCM_HASH_LSB, 48)) < 0) { 6883 test_error(unit, "Hash bank setting failed: unit %d, bank %d\n", 6884 unit, bank); 6885 rv = -1; 6886 goto done; 6887 } 6888 } 6889 6890 if (hash != FB_HASH_LSB) { 6891 ad->opt_hash = hash = FB_HASH_LSB; 6892 } 6893 6894 if (ad->opt_key_src_ip) { 6895 memcpy(src_ip, ad->opt_src_ip6, sizeof(ip6_addr_t)); 6896 src_ip_inc = ad->opt_src_ip6_inc; 6897 } else { 6898 sal_memset (src_ip, 0, sizeof(src_ip)); 6899 src_ip_inc = 0; 6900 } 6901 memcpy(dst_ip, ad->opt_base_ip6, sizeof(ip6_addr_t)); 6902 dst_ip_inc = ad->opt_ip_inc; 6903 vid = ad->opt_base_vid; 6904 vid_inc = ad->opt_vid_inc; 6905 vrf_id = ad->opt_base_vrf_id; 6906 vrf_id_inc = ad->opt_vrf_id_inc; 6907 6908 sal_memset (entry, 0, sizeof(entry)); 6909 #ifdef BCM_TRIDENT3_SUPPORT 6910 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 6911 l3_entry_key_attributes_entry_t l3_key_attr; 6912 soc_mem_field32_set(unit, mem, entry, KEY_TYPEf, 6913 TD3_L3_HASH_KEY_TYPE_V6MC); 6914 soc_mem_field32_set(unit, mem, entry, DATA_TYPEf, 6915 TD3_L3_HASH_DATA_TYPE_V6MC); 6916 soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 5); 6917 soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 6); 6918 soc_mem_field32_set(unit, mem, entry, BASE_VALID_2f, 6); 6919 soc_mem_field32_set(unit, mem, entry, BASE_VALID_3f, 7); 6920 if (vrf_id_max) { 6921 soc_mem_field32_set(unit, mem, entry, IPV6MC__VRF_IDf, 1); 6922 } 6923 6924 /* Set L3 Entry Key Attributes */ 6925 sal_memset(&l3_key_attr, 0, sizeof(l3_key_attr)); 6926 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6927 BUCKET_MODEf, 2); 6928 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6929 KEY_BASE_WIDTHf, 2); 6930 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6931 KEY_WIDTHf, 23); 6932 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6933 DATA_BASE_WIDTHf, 1); 6934 soc_mem_field32_set(unit, L3_ENTRY_KEY_ATTRIBUTESm, &l3_key_attr, 6935 HASH_LSB_OFFSETf, 5); 6936 if (soc_mem_write(unit, L3_ENTRY_KEY_ATTRIBUTESm, MEM_BLOCK_ANY, 6937 TD3_L3_HASH_KEY_TYPE_V6MC, 6938 (uint32*)&l3_key_attr) < 0) { 6939 test_error(unit, "L3 Entry Key Attr setting failed\n"); 6940 goto done; 6941 } 6942 } else 6943 #endif 6944 { 6945 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_0f, 6946 TD2_L3_HASH_KEY_TYPE_V6MC); 6947 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_1f, 6948 TD2_L3_HASH_KEY_TYPE_V6MC); 6949 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_2f, 6950 TD2_L3_HASH_KEY_TYPE_V6MC); 6951 soc_mem_field32_set(unit, mem, entry, KEY_TYPE_3f, 6952 TD2_L3_HASH_KEY_TYPE_V6MC); 6953 if (vrf_id_max) { 6954 soc_mem_field32_set(unit, mem, entry, VRF_IDf, 1); 6955 } 6956 soc_mem_field32_set(unit, mem, entry, VALID_0f, 1); 6957 soc_mem_field32_set(unit, mem, entry, VALID_1f, 1); 6958 soc_mem_field32_set(unit, mem, entry, VALID_2f, 1); 6959 soc_mem_field32_set(unit, mem, entry, VALID_3f, 1); 6960 } 6961 while (iterations--) { 6962 sal_memset(entry_array, 0, alloc_sz); 6963 for (ix = 0; ix < num_ent_per_bucket * bank_count; ix++) { 6964 dst_ip[0] = 0; 6965 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 6966 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 6967 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 6968 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 6969 #ifdef BCM_TRIDENT3_SUPPORT 6970 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 6971 soc_mem_field_set(unit, mem, entry, 6972 IPV6MC__GROUP_IP_ADDR_LWR_64f, ip_tmp); 6973 } else 6974 #endif 6975 { 6976 soc_mem_field_set(unit, mem, entry, 6977 GROUP_IP_ADDR_LWR_64f, ip_tmp); 6978 } 6979 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 6980 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 6981 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 6982 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 6983 #ifdef BCM_TRIDENT3_SUPPORT 6984 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 6985 soc_mem_field_set(unit, mem, entry, 6986 IPV6MC__GROUP_IP_ADDR_UPR_56f, ip_tmp); 6987 } else 6988 #endif 6989 { 6990 soc_mem_field_set(unit, mem, entry, 6991 GROUP_IP_ADDR_UPR_56f, ip_tmp); 6992 } 6993 ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) | 6994 (src_ip[10] << 8) | (src_ip[11] << 0)); 6995 ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) | 6996 (src_ip[14] << 8) | (src_ip[15] << 0)); 6997 #ifdef BCM_TRIDENT3_SUPPORT 6998 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 6999 soc_mem_field_set(unit, mem, entry, 7000 IPV6MC__SOURCE_IP_ADDR_BITS_63_32f, &ip_tmp[1]); 7001 soc_mem_field_set(unit, mem, entry, 7002 IPV6MC__SOURCE_IP_ADDR_BITS_31_0f, &ip_tmp[0]); 7003 } else 7004 #endif 7005 { 7006 soc_mem_field_set(unit, mem, entry, 7007 SOURCE_IP_ADDR_LWR_64f, ip_tmp); 7008 } 7009 ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) | 7010 (src_ip[2] << 8) | (src_ip[3] << 0)); 7011 ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) | 7012 (src_ip[6] << 8) | (src_ip[7] << 0)); 7013 #ifdef BCM_TRIDENT3_SUPPORT 7014 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 7015 soc_mem_field_set(unit, mem, entry, 7016 IPV6MC__SOURCE_IP_ADDR_UPR_64f, ip_tmp); 7017 soc_mem_field32_set(unit, mem, entry, IPV6MC__VLAN_IDf, vid); 7018 if (vrf_id_max) { 7019 soc_mem_field32_set(unit, mem,entry, IPV6MC__VRF_IDf, vrf_id); 7020 } 7021 } else 7022 #endif 7023 { 7024 soc_mem_field_set(unit, mem, entry, 7025 SOURCE_IP_ADDR_UPR_64f, ip_tmp); 7026 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 7027 if (vrf_id_max) { 7028 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 7029 } 7030 } 7031 7032 if (ix == 0) { 7033 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 7034 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 7035 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 7036 SOC_IS_TRIDENT3X(unit)) { 7037 if ((rv = soc_td2x_th_l3x_hash(unit, mem, entry, 7038 &num_l3_banks, l3_bucket_array, 7039 l3_index_array, phy_bank_array, 7040 entry_num_array)) < 0) { 7041 cli_out("%s ERROR: %s\n", ARG_CMD(a), soc_errmsg(rv)); 7042 goto done; 7043 } 7044 7045 if (num_l3_banks > L3_MAX_BANKS) { 7046 cli_out("%s ERROR: the number of banks overflow\n", 7047 ARG_CMD(a)); 7048 rv = -1; 7049 goto done; 7050 } 7051 for (bank = 0; bank < bank_count; bank++) { 7052 num_bucket_per_bank = entry_num_array[bank] / 7053 num_ent_per_bucket; 7054 dst_ip_inc = dst_ip_inc > num_bucket_per_bank ? 7055 dst_ip_inc : num_bucket_per_bank; 7056 } 7057 } else 7058 #endif 7059 { 7060 rv = -1; 7061 goto done; 7062 } 7063 7064 if (ad->opt_verbose) { 7065 cli_out("%s mem: %s\n", ARG_CMD(a), SOC_MEM_NAME(unit, mem)); 7066 for (bank = 0; bank < bank_count; bank++) { 7067 cli_out("bank%d(%d) bucket 0x%06x (%06d) base_index 0x%06x (%06d)\n", 7068 bank, phy_bank_array[bank], 7069 l3_bucket_array[bank], l3_bucket_array[bank], 7070 l3_index_array[bank], l3_index_array[bank]); 7071 } 7072 } 7073 } 7074 7075 offset = ix * SOC_MAX_MEM_WORDS; 7076 memcpy(&entry_array[offset], entry, sizeof(entry)); 7077 if (ad->opt_verbose) { 7078 cli_out("Inserting "); 7079 soc_mem_entry_dump(unit, mem, &entry_array[offset], BSL_LSS_CLI); 7080 } 7081 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, &entry_array[offset])) < 0) { 7082 if (r == SOC_E_FULL) { 7083 /* Already full, stop wasting time */ 7084 break; 7085 } else { 7086 test_error(unit, "L3 insert failed!\n"); 7087 rv = -1; 7088 goto done; 7089 } 7090 } 7091 7092 /* Increment key by number of buckets in the table */ 7093 increment_ip6addr(dst_ip, 15, dst_ip_inc); 7094 increment_ip6addr(src_ip, 15, src_ip_inc); 7095 vid += vid_inc; 7096 if (vid > DRACO_L3_VID_MAX) { 7097 vid = 1; 7098 } 7099 if (vrf_id_max) { 7100 vrf_id += vrf_id_inc; 7101 if (vrf_id > vrf_id_max) { 7102 vrf_id = 0; 7103 } 7104 } 7105 } 7106 7107 if (ad->opt_verbose) { 7108 cli_out("Inserting %dth entry in banks should fail\n", 7109 (num_ent_per_bucket * bank_count + 1)); 7110 } 7111 7112 dst_ip[0] = 0; 7113 ip_tmp[1] = ((dst_ip[8] << 24) | (dst_ip[9] << 16) | 7114 (dst_ip[10] << 8) | (dst_ip[11] << 0)); 7115 ip_tmp[0] = ((dst_ip[12] << 24) | (dst_ip[13] << 16) | 7116 (dst_ip[14] << 8) | (dst_ip[15] << 0)); 7117 #ifdef BCM_TRIDENT3_SUPPORT 7118 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 7119 soc_mem_field_set(unit, mem, entry, 7120 IPV6MC__GROUP_IP_ADDR_LWR_64f, ip_tmp); 7121 } else 7122 #endif 7123 { 7124 soc_mem_field_set(unit, mem, entry, 7125 GROUP_IP_ADDR_LWR_64f, ip_tmp); 7126 } 7127 ip_tmp[1] = ((dst_ip[0] << 24) | (dst_ip[1] << 16) | 7128 (dst_ip[2] << 8) | (dst_ip[3] << 0)); 7129 ip_tmp[0] = ((dst_ip[4] << 24) | (dst_ip[5] << 16) | 7130 (dst_ip[6] << 8) | (dst_ip[7] << 0)); 7131 #ifdef BCM_TRIDENT3_SUPPORT 7132 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 7133 soc_mem_field_set(unit, mem, entry, 7134 IPV6MC__GROUP_IP_ADDR_UPR_56f, ip_tmp); 7135 } else 7136 #endif 7137 { 7138 soc_mem_field_set(unit, mem, entry, 7139 GROUP_IP_ADDR_UPR_56f, ip_tmp); 7140 } 7141 ip_tmp[1] = ((src_ip[8] << 24) | (src_ip[9] << 16) | 7142 (src_ip[10] << 8) | (src_ip[11] << 0)); 7143 ip_tmp[0] = ((src_ip[12] << 24) | (src_ip[13] << 16) | 7144 (src_ip[14] << 8) | (src_ip[15] << 0)); 7145 #ifdef BCM_TRIDENT3_SUPPORT 7146 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 7147 soc_mem_field_set(unit, mem, entry, 7148 IPV6MC__SOURCE_IP_ADDR_BITS_63_32f, &ip_tmp[1]); 7149 soc_mem_field_set(unit, mem, entry, 7150 IPV6MC__SOURCE_IP_ADDR_BITS_31_0f, &ip_tmp[0]); 7151 } else 7152 #endif 7153 { 7154 soc_mem_field_set(unit, mem, entry, 7155 SOURCE_IP_ADDR_LWR_64f, ip_tmp); 7156 } 7157 ip_tmp[1] = ((src_ip[0] << 24) | (src_ip[1] << 16) | 7158 (src_ip[2] << 8) | (src_ip[3] << 0)); 7159 ip_tmp[0] = ((src_ip[4] << 24) | (src_ip[5] << 16) | 7160 (src_ip[6] << 8) | (src_ip[7] << 0)); 7161 #ifdef BCM_TRIDENT3_SUPPORT 7162 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 7163 soc_mem_field_set(unit, mem, entry, 7164 IPV6MC__SOURCE_IP_ADDR_UPR_64f, ip_tmp); 7165 } else 7166 #endif 7167 { 7168 soc_mem_field_set(unit, mem, entry, 7169 SOURCE_IP_ADDR_UPR_64f, ip_tmp); 7170 } 7171 #ifdef BCM_TRIDENT3_SUPPORT 7172 if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 7173 soc_mem_field32_set(unit, mem, entry, IPV6MC__VLAN_IDf, vid); 7174 if (vrf_id_max) { 7175 soc_mem_field32_set(unit, mem,entry, IPV6MC__VRF_IDf, vrf_id); 7176 } 7177 } else 7178 #endif 7179 { 7180 soc_mem_field32_set(unit, mem, entry, VLAN_IDf, vid); 7181 if (vrf_id_max) { 7182 soc_mem_field32_set(unit, mem,entry, VRF_IDf, vrf_id); 7183 } 7184 } 7185 7186 if ((r = soc_mem_insert(unit, mem, COPYNO_ALL, entry)) < 0) { 7187 if (r != SOC_E_FULL) { 7188 test_error(unit, "L3 insert failed\n"); 7189 rv = -1; 7190 goto done; 7191 } 7192 } else { 7193 test_error(unit, "L3 insert to full bucket succeeded\n"); 7194 rv = -1; 7195 goto done; 7196 } 7197 7198 if (ad->opt_verbose) { 7199 cli_out("Verifying installed entries\n"); 7200 } 7201 7202 /* Verify bucket contains added entries */ 7203 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 7204 found = 0; 7205 offset = j * SOC_MAX_MEM_WORDS; 7206 for (bank = 0; bank < bank_count; bank++) { 7207 if (td2_l3_bucket_search(unit, ad, mem, bank, l3_index_array, 7208 &(entry_array[offset])) == 0) { 7209 found = 1; 7210 break; 7211 } 7212 } 7213 if (!found) { 7214 test_error(unit, 7215 "%s entry j %d missing on all banks\n", 7216 SOC_MEM_NAME(unit, mem), j); 7217 rv = -1; 7218 goto done; 7219 } 7220 if (soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, 7221 &entry_array[offset], &result, 0) < 0) { 7222 test_error(unit, 7223 "%s entry missing at bucket %d index %d on bank %d\n", 7224 SOC_MEM_NAME(unit, mem), l3_bucket_array[bank], 7225 l3_index_array[bank], bank); 7226 rv = -1; 7227 goto done; 7228 } 7229 if (idx < (l3_index_array[bank]) || 7230 idx >= (l3_index_array[bank] + num_ent_per_bucket)) { 7231 test_error(unit, "%s entry inserted into wrong index" 7232 " Expected [%d-%d] Actual %d\n", 7233 SOC_MEM_NAME(unit, mem), 7234 l3_index_array[bank], 7235 l3_index_array[bank] + num_ent_per_bucket, 7236 idx); 7237 rv = -1; 7238 goto done; 7239 } 7240 } 7241 7242 if (ad->opt_verbose) { 7243 cli_out("Cleaning each entry on all banks...\n"); 7244 } 7245 7246 /* Remove the entries that we added */ 7247 for (j = 0; j < num_ent_per_bucket * bank_count; j++) { 7248 offset = j * SOC_MAX_MEM_WORDS; 7249 if (soc_mem_delete(unit, mem, COPYNO_ALL, &entry_array[offset]) < 0) { 7250 test_error(unit, "L3 delete j %d failed on all banks\n", j); 7251 rv = -1; 7252 goto done; 7253 } 7254 } 7255 7256 /* Do Next bucket */ 7257 increment_ip6addr(dst_ip, 15, 1); 7258 increment_ip6addr(src_ip, 15, src_ip_inc); 7259 vid += vid_inc; 7260 if (vid > DRACO_L3_VID_MAX) { 7261 vid = 1; 7262 } 7263 if (vrf_id_max) { 7264 vrf_id += vrf_id_inc; 7265 if (vrf_id > vrf_id_max) { 7266 vrf_id = 0; 7267 } 7268 } 7269 } 7270 7271 done: 7272 if (entry_array) { 7273 sal_free(entry_array); 7274 entry_array = NULL; 7275 } 7276 return rv; 7277 } 7278 7279 int 7280 td2_l3_test_hash(int unit, args_t *a, void *p) 7281 { 7282 draco_l3_testdata_t *ad = p; 7283 int ipv6_enable = ad->ipv6; 7284 int ipmc_enable = ad->opt_ipmc_enable; 7285 7286 if (ipv6_enable) { 7287 if (ipmc_enable) { 7288 return (_td2_l3ip6mcast_test_hash(unit, a, p)); 7289 } else { 7290 return (_td2_l3ip6ucast_test_hash(unit, a, p)); 7291 } 7292 } else { 7293 if (ipmc_enable) { 7294 return (_td2_l3ip4mcast_test_hash(unit, a, p)); 7295 } else { 7296 return (_td2_l3ip4ucast_test_hash(unit, a, p)); 7297 } 7298 } 7299 } 7300 7301 int 7302 td2_l3_test_ov(int unit, args_t *a, void *p) 7303 { 7304 draco_l3_testdata_t *ad = p; 7305 int ipv6_enable = ad->ipv6; 7306 int ipmc_enable = ad->opt_ipmc_enable; 7307 7308 if (ipv6_enable) { 7309 if (ipmc_enable) { 7310 return (_td2_l3ip6mcast_test_ov(unit, a, p)); 7311 } else { 7312 return (_td2_l3ip6ucast_test_ov(unit, a, p)); 7313 } 7314 } else { 7315 if (ipmc_enable) { 7316 return (_td2_l3ip4mcast_test_ov(unit, a, p)); 7317 } else { 7318 return (_td2_l3ip4ucast_test_ov(unit, a, p)); 7319 } 7320 } 7321 } 7322 #endif /* BCM_TRIDENT2_SUPPORT */ 7323 #endif /* BCM_FIREBOLT_SUPPORT */ 7324 7325 7326 /* 7327 * Test of L3 hashing 7328 * 7329 * This test tries a number of keys against one of the hashing functions, 7330 * checking a software hash against the hardware hash, then searching the 7331 * bucket to find the entry after inserting. 7332 */ 7333 int 7334 fb_l3_test_hash(int unit, args_t *a, void *p) 7335 { 7336 draco_l3_testdata_t *ad = p; 7337 int ipv6_enable = ad->ipv6; 7338 #ifdef BCM_FIREBOLT_SUPPORT 7339 int ipmc_enable = ad->opt_ipmc_enable; 7340 #endif /* BCM_FIREBOLT_SUPPORT */ 7341 7342 #ifdef BCM_FIREBOLT_SUPPORT 7343 #if defined(BCM_TRIDENT2_SUPPORT) 7344 if (SOC_IS_TD2_TT2(unit)) { 7345 return td2_l3_test_hash(unit, a, p); 7346 } 7347 #endif /* BCM_TRIDENT2_SUPPORT */ 7348 7349 if (ipv6_enable) { 7350 if (ipmc_enable) { 7351 return (_fb_l3ip6mcast_test_hash(unit, a, p)); 7352 } else { 7353 return (_fb_l3ip6ucast_test_hash(unit, a, p)); 7354 } 7355 } else { 7356 if (ipmc_enable) { 7357 return (_fb_l3ip4mcast_test_hash(unit, a, p)); 7358 } else { 7359 return (_fb_l3ip4ucast_test_hash(unit, a, p)); 7360 } 7361 } 7362 #endif /* BCM_FIREBOLT_SUPPORT */ 7363 return SOC_E_NONE; 7364 } 7365 7366 /* 7367 * Test of L3 overflow behavior 7368 * 7369 * This test fills each bucket of the L3, then inserts another entry to see 7370 * that the last entry fails to insert. 7371 */ 7372 7373 int 7374 fb_l3_test_ov(int unit, args_t *a, void *p) 7375 { 7376 draco_l3_testdata_t *ad = p; 7377 int ipv6_enable = ad->ipv6; 7378 uint32 hash = ad->opt_hash; 7379 #ifdef BCM_FIREBOLT_SUPPORT 7380 int ipmc_enable = ad->opt_ipmc_enable; 7381 #endif /* BCM_FIREBOLT_SUPPORT */ 7382 7383 if (hash != FB_HASH_LSB) { 7384 if (ad->opt_verbose) { 7385 cli_out("Resetting hash selection to LSB\n"); 7386 } 7387 7388 hash = ad->save_hash_control; 7389 soc_reg_field_set(unit, HASH_CONTROLr, &hash, 7390 L3_HASH_SELECTf, FB_HASH_LSB); 7391 7392 if (WRITE_HASH_CONTROLr(unit, hash) < 0) { 7393 test_error(unit, "Hash select setting failed\n"); 7394 return(-1); 7395 } 7396 7397 #ifdef BCM_TRIDENT3_SUPPORT 7398 if (soc_mem_is_valid(unit, L3_ENTRY_HASH_CONTROLm)) { 7399 int rv = 0; 7400 rv = td3_entry_hash_control_set(unit, FB_HASH_LSB, 7401 L3_ENTRY_HASH_CONTROLm, 7402 (uint32 *)&ad->save_l3_entry_hash_control); 7403 if (rv < 0) { 7404 test_error(unit, "Hash Control write failed"); 7405 return rv; 7406 } 7407 } 7408 #endif 7409 7410 ad->opt_hash = hash = FB_HASH_LSB; 7411 } 7412 7413 #ifdef BCM_FIREBOLT_SUPPORT 7414 #if defined(BCM_TRIDENT2_SUPPORT) 7415 if (SOC_IS_TD2_TT2(unit)) { 7416 return td2_l3_test_ov(unit, a, p); 7417 } 7418 #endif /* BCM_TRIDENT2_SUPPORT */ 7419 7420 if (ipv6_enable) { 7421 if (ipmc_enable) { 7422 return (_fb_l3ip6mcast_test_ov(unit, a, p)); 7423 } else { 7424 return (_fb_l3ip6ucast_test_ov(unit, a, p)); 7425 } 7426 } else { 7427 if (ipmc_enable) { 7428 return (_fb_l3ip4mcast_test_ov(unit, a, p)); 7429 } else { 7430 return (_fb_l3ip4ucast_test_ov(unit, a, p)); 7431 } 7432 } 7433 #endif /* BCM_FIREBOLT_SUPPORT */ 7434 return SOC_E_NONE; 7435 } 7436 7437 int 7438 fb_l3_test_done(int unit, void *p) 7439 { 7440 draco_l3_testdata_t *ad = p; 7441 soc_mem_t tmem = INVALIDm; 7442 soc_field_t vldf = VALIDf; 7443 7444 if (ad == NULL) { 7445 return 0; 7446 } 7447 7448 if (SOC_IS_FBX(unit)) { 7449 tmem = L3_ENTRY_IPV4_UNICASTm; 7450 if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 7451 tmem = L3_ENTRY_DOUBLEm; 7452 vldf = BASE_VALID_0f; 7453 } 7454 } else { 7455 return (-1); 7456 } 7457 7458 /* Check if empty at the end of the test */ 7459 if (ad->opt_reset) { 7460 int rv, ix; 7461 int index_min = soc_mem_index_min(unit, tmem); 7462 int index_max = soc_mem_index_max(unit, tmem); 7463 uint32 *buf = 0; 7464 uint32 *ent = 0; 7465 uint32 count; 7466 7467 buf = soc_cm_salloc(unit, 7468 SOC_MEM_TABLE_BYTES(unit, tmem), 7469 "fb_l3_test"); 7470 if (!buf) { 7471 test_error(unit, "Memory allocation failed\n"); 7472 return (-1); 7473 } 7474 7475 if ((rv = soc_mem_read_range(unit, tmem, 7476 MEM_BLOCK_ANY, index_min, index_max, buf)) < 0) { 7477 test_error(unit, "Memory DMA of L3 Entry failed\n"); 7478 return (-1); 7479 } 7480 7481 count = soc_mem_index_count(unit, tmem); 7482 for (ix = 0; ix < count; ix++) { 7483 ent = soc_mem_table_idx_to_pointer(unit, tmem, uint32 *, buf, ix); 7484 if (soc_mem_field32_get(unit, tmem, ent, vldf)) { 7485 test_error(unit, "L3 table not empty after test ent = %d\n", 7486 ix); 7487 soc_mem_entry_dump(unit, tmem, ent, BSL_LSS_CLI); 7488 return (-1); 7489 } 7490 } 7491 7492 soc_cm_sfree(unit, buf); 7493 } 7494 7495 if (WRITE_HASH_CONTROLr(unit, ad->save_hash_control) < 0) { 7496 test_error(unit, "Hash select restore failed\n"); 7497 } 7498 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 7499 #ifdef BCM_TRIDENT3_SUPPORT 7500 if (soc_mem_is_valid(unit, L2_ENTRY_HASH_CONTROLm)) { 7501 if (soc_mem_write(unit, L2_ENTRY_HASH_CONTROLm, MEM_BLOCK_ANY, 7502 0, &ad->save_l3_entry_hash_control) < 0) { 7503 test_error(unit, "L2 Entry hash control setting failed\n"); 7504 } 7505 if (soc_mem_write(unit, UFT_SHARED_BANKS_CONTROLm, MEM_BLOCK_ANY, 7506 0, &ad->save_shared_entry_hash_control) < 0) { 7507 test_error(unit, "Shared Table hash control setting failed\n"); 7508 } 7509 } else 7510 #endif /* BCM_TRIDENT3_SUPPORT */ 7511 { 7512 if (WRITE_L2_TABLE_HASH_CONTROLr(unit, 7513 ad->save_l3_table_hash_control) < 0) { 7514 test_error(unit, "L2 Table hash control setting failed\n"); 7515 } 7516 if (SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) 7517 { 7518 if (WRITE_SHARED_TABLE_HASH_CONTROLr(unit, ad->save_shared_table_hash_control) < 0) { 7519 test_error(unit, "Shared Table hash control setting failed\n"); 7520 } 7521 } 7522 } 7523 } else { 7524 if (soc_feature(unit, soc_feature_dual_hash)) { 7525 if (ad->save_dual_hash_control != ad->opt_dual_hash) { 7526 if (WRITE_L3_AUX_HASH_CONTROLr(unit, 7527 ad->save_dual_hash_control) < 0) { 7528 test_error(unit, "Dual Hash select restore failed\n"); 7529 } 7530 } 7531 } 7532 } 7533 7534 return 0; 7535 } 7536 #endif 7537 7538 #endif /* INCLUDE_L3 */ 7539 7540 #endif /* BCM_XGS_SWITCH_SUPPORT */ 7541 #else 7542 /*ISO C forbids an empty source file */ 7543 #include <bcm/types.h> 7544 #endif /* BCM_ESW_SUPPORT */ 7545