hash_mem_test.c (48621B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * Generic memory table Tests. 9 * 10 * Insert/Lookup/Delete, hashing, bucket overflow tests. 11 */ 12 13 #include <soc/mem.h> 14 #include <appl/diag/system.h> 15 #include "testlist.h" 16 #include <bcm/init.h> 17 #include <bcm/l2.h> 18 #include <bcm/l3.h> 19 #include <bcm/link.h> 20 #include <soc/l2x.h> 21 #include <soc/ism.h> 22 #include <appl/diag/mem_table_test.h> 23 #include <shared/bsl.h> 24 #ifdef BCM_XGS_SWITCH_SUPPORT 25 #include <bcm_int/esw/triumph.h> 26 #ifdef BCM_MONTEREY_SUPPORT 27 #include <soc/monterey.h> 28 #endif 29 #ifdef BCM_TOMAHAWK_SUPPORT 30 #include <soc/tomahawk.h> 31 #endif 32 #ifdef BCM_APACHE_SUPPORT 33 #include <soc/apache.h> 34 #endif 35 #ifdef BCM_TRIDENT2_SUPPORT 36 #include <soc/trident2.h> 37 #endif 38 #ifdef BCM_TRIDENT3_SUPPORT 39 #include <soc/trident3.h> 40 #endif 41 #ifdef BCM_HELIX5_SUPPORT 42 #include <soc/helix5.h> 43 #endif 44 45 STATIC test_generic_hash_test_t hash_test[SOC_MAX_NUM_DEVICES]; 46 47 STATIC void 48 _test_generic_hash_setup(int unit, test_generic_hash_test_t *ht) 49 { 50 test_generic_hash_testdata_t *htd; 51 soc_mem_t tmem = L2_ENTRY_1m; 52 53 if (ht->setup_done) { 54 return; 55 } 56 ht->setup_done = TRUE; 57 ht->unit = unit; 58 59 htd = &ht->testdata; 60 htd->mem = tmem; 61 htd->mem_str = sal_strdup("l2_entry_1"); 62 htd->opt_count = 100; /*soc_mem_index_count(unit, tmem);*/ 63 htd->opt_verbose = FALSE; 64 htd->opt_reset = FALSE; 65 htd->opt_key_base = sal_strdup("0"); 66 htd->opt_key_incr = 1; 67 htd->opt_banks = -1; /* All applicable banks by default */ 68 htd->opt_hash_offsets = sal_strdup(""); 69 } 70 71 STATIC int 72 _test_generic_hash_init(int unit, test_generic_hash_testdata_t *htd, 73 args_t *a) 74 { 75 int rv = -1, val; 76 parse_table_t pt; 77 char *offset, *buf = NULL; 78 char *tokstr; 79 80 parse_table_init(unit, &pt); 81 82 parse_table_add(&pt, "Mem", PQ_DFL|PQ_STRING|PQ_STATIC, 0, &htd->mem_str, NULL); 83 parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, &htd->opt_count, NULL); 84 parse_table_add(&pt, "Verbose", PQ_BOOL|PQ_DFL, 0, &htd->opt_verbose, NULL); 85 parse_table_add(&pt, "Reset", PQ_BOOL|PQ_DFL, 0, &htd->opt_reset, NULL); 86 parse_table_add(&pt, "Key base", PQ_DFL|PQ_STRING|PQ_STATIC, 0, &htd->opt_key_base, NULL); 87 parse_table_add(&pt, "Key incr", PQ_INT|PQ_DFL, 0, &htd->opt_key_incr, NULL); 88 parse_table_add(&pt, "Banks", PQ_HEX|PQ_DFL, 0, &htd->opt_banks, NULL); 89 parse_table_add(&pt, "Bank offsets", PQ_DFL|PQ_STRING|PQ_STATIC, 0, &htd->opt_hash_offsets, NULL); 90 91 if (htd->opt_count < 1) { 92 test_error(unit, "Illegal count %d\n", htd->opt_count); 93 goto done; 94 } 95 96 if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) { 97 test_error(unit, 98 "%s: Invalid option: %s\n", ARG_CMD(a), 99 ARG_CUR(a) ? ARG_CUR(a) : "*"); 100 parse_arg_eq_done(&pt); 101 return -1; 102 } 103 104 if (parse_memory_name(unit, &htd->mem, htd->mem_str, 105 &htd->copyno, 0) < 0) { 106 test_error(unit, "Memory \"%s\" is invalid\n", 107 htd->mem_str); 108 parse_arg_eq_done(&pt); 109 return -1; 110 } 111 112 if (!isint(htd->opt_key_base)) { 113 test_error(unit, "Key val is not valid\n"); 114 parse_arg_eq_done(&pt); 115 return -1; 116 } 117 118 htd->offset_count = 0; 119 120 if ((buf = sal_alloc(ARGS_BUFFER, "bank_offsets")) == NULL) { 121 test_error(unit, "Unable to allocate memory for bank offsets\n"); 122 return -1; 123 } 124 125 strncpy(buf, htd->opt_hash_offsets, ARGS_BUFFER);/* Don't destroy input string */ 126 buf[ARGS_BUFFER - 1] = 0; 127 128 offset = sal_strtok_r(buf, ",", &tokstr); 129 while (offset != 0) { 130 val = parse_integer(offset); 131 if (val > 64) { 132 val = 64; 133 } 134 htd->offsets[htd->offset_count] = (uint8)val; 135 htd->offset_count++; 136 offset = sal_strtok_r(NULL, ",", &tokstr); 137 } 138 139 /* 140 * Re-initialize chip to ensure tables are clear 141 * at start of test. 142 */ 143 144 if (htd->opt_reset) { 145 rv = bcm_linkscan_enable_set(unit, 0); 146 if (rv && rv != BCM_E_UNIT) { 147 test_error(unit, "Linkscan disabling failed\n"); 148 goto done; 149 } 150 if (soc_reset_init(unit) < 0) { 151 test_error(unit, "SOC initialization failed\n"); 152 goto done; 153 } 154 155 if (soc_misc_init(unit) < 0) { 156 test_error(unit, "MISC initialization failed\n"); 157 goto done; 158 } 159 160 if (soc_mmu_init(unit) < 0) { 161 test_error(unit, "MMU initialization failed\n"); 162 goto done; 163 } 164 165 if (mbcm_init(unit) < 0) { 166 test_error(unit, "BCM initialization failed\n"); 167 goto done; 168 } 169 } 170 171 rv = 0; 172 173 done: 174 if (buf) { 175 sal_free(buf); 176 } 177 parse_arg_eq_done(&pt); 178 return rv; 179 } 180 181 /* Generic hash test init */ 182 int 183 test_generic_hash_init(int unit, args_t *a, void **p) 184 { 185 test_generic_hash_test_t *ht = &hash_test[unit]; 186 test_generic_hash_testdata_t *htd = &ht->testdata; 187 int rv; 188 189 _test_generic_hash_setup(unit, ht); 190 191 ht->ctp = htd; 192 193 if ((rv = _test_generic_hash_init(unit, htd, a)) < 0) { 194 return rv; 195 } else { 196 *p = htd; 197 } 198 return 0; 199 } 200 201 #if defined(BCM_TRIDENT2_SUPPORT) 202 /* 203 * Test of hash memory 204 * 205 * This test tries a number of keys against one of the hashing functions, 206 * checking a software hash against the hardware hash, then searching the 207 * bucket to find the entry after inserting. 208 */ 209 int 210 test_td2_generic_hash(int unit, args_t *a, void *p) 211 { 212 test_generic_hash_testdata_t *htd = p; 213 uint32 entry[SOC_MAX_MEM_WORDS] = {0}, soft_bucket; 214 int ix, r, rv = 0; 215 int iterations; 216 int index, key_type = 0; 217 int bank, bank_count; 218 219 #ifdef BCM_TOMAHAWK_SUPPORT 220 if (SOC_IS_TOMAHAWKX(unit)) { 221 r = soc_tomahawk_hash_bank_count_get(unit, htd->mem, &bank_count); 222 } else 223 #endif 224 #ifdef BCM_APACHE_SUPPORT 225 if (SOC_IS_APACHE(unit)) { 226 r = soc_apache_hash_bank_count_get(unit, htd->mem, &bank_count); 227 } else 228 #endif 229 #ifdef BCM_HELIX5_SUPPORT 230 if (SOC_IS_HELIX5(unit)) { 231 r = soc_helix5_hash_bank_count_get(unit, htd->mem, &bank_count); 232 } else 233 #endif /* BCM_HELIX5_SUPPORT */ 234 #ifdef BCM_TRIDENT3_SUPPORT 235 if (SOC_IS_TRIDENT3X(unit)) { 236 r = soc_trident3_hash_bank_count_get(unit, htd->mem, &bank_count); 237 } else 238 #endif /* BCM_TRIDENT3_SUPPORT */ 239 { 240 r = soc_trident2_hash_bank_count_get(unit, htd->mem, &bank_count); 241 } 242 if (r) { 243 test_error(unit, "Could not get bank count\n"); 244 rv = -1; 245 goto done; 246 } 247 iterations = htd->opt_count; 248 249 if (htd->opt_verbose) { 250 cli_out("Starting Generic Memory hashing test. Iterations: %d\n",iterations); 251 } 252 253 for( ix=0; ix < iterations; ix++) { 254 for (bank = 0; bank < bank_count; bank++) { 255 256 /* Prepare the entry */ 257 if (SOC_MEM_FIELD_VALID(unit, htd->mem, VALIDf)) { 258 soc_mem_field32_set(unit, htd->mem, entry, VALIDf, 1); 259 } else { 260 soc_mem_field32_set(unit, htd->mem, entry, VALID_0f, 1); 261 soc_mem_field32_set(unit, htd->mem, entry, VALID_1f, 1); 262 if (SOC_MEM_FIELD_VALID(unit, htd->mem, VALID_2f)) { 263 soc_mem_field32_set(unit, htd->mem, entry, VALID_2f, 1); 264 soc_mem_field32_set(unit, htd->mem, entry, VALID_3f, 1); 265 } 266 } 267 switch (htd->mem) { 268 case L3_ENTRY_IPV4_UNICASTm: 269 key_type = TD2_L3_HASH_KEY_TYPE_V4UC; 270 break; 271 case L3_ENTRY_IPV4_MULTICASTm: 272 key_type = TD2_L3_HASH_KEY_TYPE_V4MC; 273 break; 274 case L3_ENTRY_IPV6_UNICASTm: 275 key_type = TD2_L3_HASH_KEY_TYPE_V6UC; 276 break; 277 case L3_ENTRY_IPV6_MULTICASTm: 278 key_type = TD2_L3_HASH_KEY_TYPE_V6MC; 279 } 280 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPEf)) { 281 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPEf, key_type); 282 } else { 283 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_0f)) { 284 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_0f, key_type); 285 } 286 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_1f)) { 287 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_1f, key_type); 288 } 289 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_2f)) { 290 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_2f, key_type); 291 } 292 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_3f)) { 293 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_3f, key_type); 294 } 295 } 296 297 #ifdef BCM_TOMAHAWK_SUPPORT 298 if (SOC_IS_TOMAHAWKX(unit)) { 299 r = soc_th_hash_bucket_get(unit, htd->mem, bank, entry, &soft_bucket); 300 } else 301 #endif 302 #ifdef BCM_APACHE_SUPPORT 303 if (SOC_IS_APACHE(unit)) { 304 r = soc_ap_hash_bucket_get(unit, htd->mem, bank, entry, &soft_bucket); 305 } else 306 #endif 307 #ifdef BCM_HELIX5_SUPPORT 308 if (SOC_IS_HELIX5(unit)) { 309 r = soc_hx5_hash_bucket_get(unit, htd->mem, bank, entry, &soft_bucket); 310 } else 311 #endif /* BCM_HELIX5_SUPPORT */ 312 #ifdef BCM_TRIDENT3_SUPPORT 313 if (SOC_IS_TRIDENT3X(unit)) { 314 r = soc_td3_hash_bucket_get(unit, htd->mem, bank, entry, &soft_bucket); 315 } else 316 #endif /* BCM_TRIDENT3_SUPPORT */ 317 { 318 r = soc_hash_bucket_get(unit, htd->mem, bank, entry, &soft_bucket); 319 } 320 321 if (r) { 322 test_error(unit, "Could not get bucket\n"); 323 rv = -1; 324 goto done; 325 } 326 327 #ifdef BCM_TOMAHAWK_SUPPORT 328 if (SOC_IS_TOMAHAWKX(unit)) { 329 index = soc_th_hash_index_get(unit, htd->mem, bank, soft_bucket); 330 } else 331 #endif 332 #ifdef BCM_APACHE_SUPPORT 333 if (SOC_IS_APACHE(unit)) { 334 index = soc_ap_hash_index_get(unit, htd->mem, bank, soft_bucket); 335 } else 336 #endif 337 #ifdef BCM_HELIX5_SUPPORT 338 if (SOC_IS_HELIX5(unit)) { 339 index = soc_hx5_hash_index_get(unit, htd->mem, bank, soft_bucket); 340 } else 341 #endif /* BCM_HELIX5_SUPPORT */ 342 #ifdef BCM_TRIDENT3_SUPPORT 343 if (SOC_IS_TRIDENT3X(unit)) { 344 index = soc_td3_hash_index_get(unit, htd->mem, bank, soft_bucket); 345 } else 346 #endif /* BCM_TRIDENT3_SUPPORT */ 347 { 348 index = soc_hash_index_get(unit, htd->mem, bank, soft_bucket); 349 } 350 351 if (htd->opt_verbose) { 352 cli_out("Inserting "); 353 soc_mem_entry_dump(unit, htd->mem, entry, BSL_LSS_CLI); 354 cli_out("\n"); 355 } 356 if ((r = soc_mem_generic_insert(unit, htd->mem, MEM_BLOCK_ALL, bank, 357 entry, NULL, &index)) < 0) { 358 if (r == SOC_E_FULL) { 359 /* Bucket overflow, just pass on */ 360 break; 361 } else { 362 test_error(unit, "Insert failed at bucket %d\n", soft_bucket); 363 rv = -1; 364 goto done; 365 } 366 } 367 368 /* Search for the entry, should be found */ 369 if (soc_mem_search(unit, htd->mem, MEM_BLOCK_ANY, &index, 370 entry, entry, 0) < 0) { 371 test_error(unit, "Search failed in bucket %d\n", soft_bucket); 372 rv = -1; 373 return rv; 374 } 375 376 /* Delete the entry */ 377 if (soc_mem_delete(unit, htd->mem, MEM_BLOCK_ALL, entry) < 0) { 378 test_error(unit, "Delete failed at bucket %d\n", soft_bucket); 379 rv = -1; 380 goto done; 381 } 382 } 383 } 384 done: 385 return rv; 386 } 387 #endif /* BCM_TRIDENT2_SUPPORT */ 388 389 #ifdef BCM_ISM_SUPPORT 390 /* 391 * Test of hash memory 392 * 393 * This test tries a number of keys against one of the hashing functions, 394 * checking a software hash against the hardware hash, then searching the 395 * bucket to find the entry after inserting. 396 */ 397 int 398 test_tr3_generic_hash(int unit, args_t *a, void *p) 399 { 400 int ix, index, rc = 0; 401 int incr, iter, hw_index; 402 uint8 *is = NULL, *isptr, inc_mode_hw = 0; 403 uint8 tmp, inc_mode = 0, num_flds, key[64] = {0}; 404 uint8 banks[_SOC_ISM_MAX_BANKS], req_bcount = 0, bcount; 405 uint32 opres, full = 0; 406 uint32 entry[SOC_MAX_MEM_WORDS] = {0}; 407 uint32 rentry[SOC_MAX_MEM_WORDS] = {0}; 408 uint32 ifail = 0, sfail = 0, dfail = 0; 409 uint32 fvalue[SOC_MAX_MEM_WORDS] = {0}; 410 uint32 *buff = NULL, *bptr, sskip = 0; 411 uint32 bmask = -1, sizes[_SOC_ISM_MAX_BANKS] = {0}; 412 soc_field_t lsbf, keyf[4] = {0}; 413 test_generic_hash_testdata_t *htd = p; 414 415 COMPILER_REFERENCE(a); 416 417 if (htd->opt_count > soc_mem_index_count(unit, htd->mem)) { 418 htd->opt_count = soc_mem_index_count(unit, htd->mem); 419 } 420 iter = htd->opt_count; 421 incr = htd->opt_key_incr; 422 if (!incr) { 423 iter = 1; 424 } 425 if (incr > 10) { 426 /* Artificially limiting the increment value to max 100 */ 427 incr = htd->opt_key_incr = 10; 428 } 429 if (htd->opt_verbose) { 430 cli_out("Starting generic hash test: iter: %d, inc: %d\n", 431 iter, incr); 432 } 433 parse_long_integer((uint32*)key, sizeof(key)/sizeof(uint32), htd->opt_key_base); 434 /* prepare entry and get s/w insert index */ 435 rc = soc_gen_entry_from_key(unit, htd->mem, key, entry); 436 if (rc) { 437 test_error(unit, "Could not generate entry from key: Test aborted.\n"); 438 return 0; 439 } 440 /* Fix the key_types to be the same */ 441 if (soc_mem_field_valid(unit, htd->mem, KEY_TYPE_0f)) { 442 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_1f, 443 soc_mem_field32_get(unit, htd->mem, entry, KEY_TYPE_0f)); 444 if (soc_mem_field_valid(unit, htd->mem, KEY_TYPE_2f)) { 445 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_2f, 446 soc_mem_field32_get(unit, htd->mem, entry, KEY_TYPE_0f)); 447 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_3f, 448 soc_mem_field32_get(unit, htd->mem, entry, KEY_TYPE_0f)); 449 } 450 } 451 rc = soc_generic_get_hash_key(unit, htd->mem, entry, keyf, &lsbf, &num_flds); 452 if (rc) { 453 test_error(unit, "Could not retreive key fields from entry: Test aborted.\n"); 454 return 0; 455 } 456 457 rc = soc_ism_get_banks_for_mem(unit, htd->mem, banks, sizes, &bcount); 458 if (rc || !bcount) { 459 test_error(unit, "No banks configured for this memory: Test aborted.\n"); 460 return 0; 461 } 462 if (htd->opt_verbose) { 463 cli_out("Num of configured banks: %d\n", bcount); 464 } 465 if (htd->opt_banks != -1) { 466 bmask = 0; 467 for (ix = 0; ix < bcount; ix++) { 468 bmask |= 1 << banks[ix]; 469 } 470 if (htd->opt_verbose) { 471 cli_out("Supported banks mask: 0x%x\n", bmask); 472 } 473 if (!(htd->opt_banks & bmask)) { 474 test_error(unit, "Invalid input banks mask: 0x%4x\n", htd->opt_banks); 475 return 0; 476 } 477 if ((htd->opt_banks | bmask) != bmask) { 478 test_error(unit, "Invalid input banks mask: 0x%4x\n", htd->opt_banks); 479 return 0; 480 } 481 cli_out("Num of requested banks: %d\n", req_bcount); 482 } 483 htd->restore = 0; 484 if (htd->offset_count) { 485 if (htd->opt_verbose) { 486 cli_out("Requested offsets: %d\n", htd->offset_count); 487 } 488 if (htd->offset_count > bcount) { 489 test_error(unit, "Offsets count(%d) does not match banks count(%d).\n", 490 htd->offset_count, bcount); 491 htd->offset_count = bcount; 492 } 493 for (ix = 0; ix < htd->offset_count; ix++) { 494 if (htd->offsets[ix] >= 48) { 495 inc_mode++; /* lsb mode */ 496 } 497 } 498 /* retreive, set and save offsets */ 499 for (ix = 0; ix < htd->offset_count; ix++) { 500 rc = soc_ism_hash_offset_config_get(unit, banks[ix], &htd->cur_offset[ix]); 501 if (rc) { 502 test_error(unit, "Error retreiving offset for %s: bank: %d\n", 503 htd->mem_str, banks[ix]); 504 return 0; 505 } 506 if (inc_mode && (htd->offsets[ix] < 48)) { 507 /* Artificially bump the offset to lsb */ 508 if (htd->opt_verbose) { 509 cli_out("Updating offset for bank %d from %d to 48\n", 510 banks[ix], htd->offsets[ix]); 511 } 512 htd->offsets[ix] = 48; 513 } 514 if (htd->offsets[ix] == htd->cur_offset[ix]) { 515 continue; 516 } 517 rc = soc_ism_hash_offset_config(unit, banks[ix], htd->offsets[ix]); 518 if (rc) { 519 test_error(unit, "Error setting offset for %s: bank: %d\n", 520 htd->mem_str, banks[ix]); 521 return 0; 522 } 523 htd->restore |= 1 << banks[ix]; 524 htd->config_banks[ix] = banks[ix]; 525 if (htd->opt_verbose) { 526 cli_out("Set offset %d in place of %d for bank %d\n", 527 htd->offsets[ix], htd->cur_offset[ix], banks[ix]); 528 } 529 } 530 } 531 532 /* determine inc_mode again from h/w config as something already with lsb 533 offset might not have been modified above */ 534 if (htd->opt_banks != -1) { 535 for (ix = 0; ix < _SOC_ISM_MAX_BANKS; ix++) { 536 if (htd->opt_banks & (1 << ix)) { 537 rc = soc_ism_hash_offset_config_get(unit, ix, &tmp); 538 if (rc) { 539 test_error(unit, "Error retreiving offset for %s: bank: %d\n", 540 htd->mem_str, ix); 541 return 0; 542 } 543 if (tmp >= 48) { 544 inc_mode_hw++; 545 } 546 req_bcount++; 547 } 548 } 549 } else { 550 for (ix = 0; ix < bcount; ix++) { 551 rc = soc_ism_hash_offset_config_get(unit, banks[ix], &tmp); 552 if (rc) { 553 test_error(unit, "Error retreiving offset for %s: bank: %d\n", 554 htd->mem_str, banks[ix]); 555 return 0; 556 } 557 if (tmp >= 48) { 558 inc_mode_hw++; 559 } 560 } 561 } 562 if ((inc_mode && (inc_mode != inc_mode_hw)) || 563 (inc_mode_hw && (inc_mode_hw != req_bcount && inc_mode_hw != bcount))) { 564 test_error(unit, "Conflicting or unsupported offset config detected: Test aborted.\n"); 565 return 0; 566 } 567 if (!inc_mode && inc_mode_hw) { 568 inc_mode = inc_mode_hw; 569 } 570 571 if (!inc_mode) { 572 soc_mem_field_get(unit, htd->mem, entry, keyf[0], fvalue); 573 } else { 574 soc_mem_field_get(unit, htd->mem, entry, lsbf, fvalue); 575 } 576 577 if ((buff = sal_alloc(iter * SOC_MAX_MEM_WORDS * sizeof(uint32), 578 "hash_test_buff")) == NULL) { 579 test_error(unit, "Buffer allocation failure: Test aborted.\n"); 580 return 0; 581 } 582 bptr = buff; 583 if ((is = sal_alloc(iter * sizeof(uint8), "hash_test_stat")) == NULL) { 584 test_error(unit, "Status buffer allocation failure: Test aborted.\n"); 585 rc = 0; 586 goto done; 587 } 588 isptr = is; 589 for (ix = 0; ix < iter; ix++) { 590 rc = soc_generic_hash(unit, htd->mem, entry, htd->opt_banks, TABLE_INSERT_CMD_MSG, 591 &index, &opres, NULL, NULL); 592 if (rc) { 593 test_error(unit, "Error calculating hash: Test aborted.\n"); 594 goto done; 595 } 596 /* Insert in h/w */ 597 rc = soc_mem_generic_insert(unit, htd->mem, MEM_BLOCK_ANY, htd->opt_banks, 598 entry, NULL, &hw_index); 599 if (rc && ((rc != SOC_E_FULL) && (rc != SOC_E_EXISTS))) { 600 test_error(unit, "Error in h/w insert: Test aborted.\n"); 601 goto done; 602 } else { 603 isptr[ix] = 1; 604 rc = 0; 605 } 606 if ((opres == SCHAN_GEN_RESP_TYPE_FULL) && (hw_index == -1)) { 607 cli_out("Bucket full for iter: %d\n", ix); 608 isptr[ix] = 0; 609 full++; 610 bptr += (sizeof(entry) / sizeof(uint32)); 611 continue; 612 } 613 /* Compare indexes */ 614 if (index == hw_index) { 615 if (htd->opt_verbose) { 616 cli_out("Matching s/w and h/w insert(%d) index: %d\n", 617 ix, index); 618 } 619 /* Search for the entry, should be found */ 620 if (soc_mem_search(unit, htd->mem, MEM_BLOCK_ALL, &hw_index, 621 entry, rentry, 0) < 0) { 622 test_error(unit, "Search failed at index %d\n", index); 623 rc = -1; 624 break; 625 } 626 if (index != hw_index) { 627 test_error(unit, "Mismatch in s/w and h/w search index: %d vs %d\n", index, hw_index); 628 sfail++; 629 } else { 630 if (htd->opt_verbose) { 631 cli_out("Matching s/w and h/w search(%d) index: %d\n", 632 ix, index); 633 } 634 } 635 } else { 636 cli_out("Mismatch in s/w and h/w insert index: %d vs %d\n", 637 index, hw_index); 638 ifail++; 639 sskip++; 640 } 641 sal_memcpy(bptr, entry, sizeof(entry)); 642 bptr += ((sizeof(entry) / sizeof(uint32))); 643 644 if (!inc_mode) { 645 if (soc_mem_field_valid(unit, htd->mem, KEY_TYPEf)) { 646 fvalue[0] += incr << soc_mem_field_length(unit, htd->mem, KEY_TYPEf); 647 soc_mem_field_set(unit, htd->mem, entry, keyf[0], fvalue); 648 } else { 649 fvalue[0] += incr << soc_mem_field_length(unit, htd->mem, KEY_TYPE_0f); 650 soc_mem_field_set(unit, htd->mem, entry, keyf[0], fvalue); 651 } 652 } else { 653 fvalue[0] += incr; 654 fvalue[0] &= ((1 << soc_mem_field_length(unit, htd->mem, lsbf)) - 1); 655 soc_mem_field_set(unit, htd->mem, entry, lsbf, fvalue); 656 } 657 } 658 /* Delete entries */ 659 bptr = buff; 660 isptr = is; 661 for (ix = 0; ix < iter; ix++) { 662 if (!isptr[ix]) { 663 bptr += ((sizeof(entry) / sizeof(uint32))); 664 continue; 665 } 666 if (soc_mem_delete(unit, htd->mem, MEM_BLOCK_ALL, bptr) < 0) { 667 test_error(unit, "Delete failed for entry %d\n", ix); 668 dfail++; 669 } 670 bptr += ((sizeof(entry) / sizeof(uint32))); 671 } 672 cli_out("Insert result: %d iter(s) passed out of %d iter(s), " 673 "%d iter(s) skipped.\n", 674 iter-ifail-full, iter, full); 675 cli_out("Search result: %d iter(s) passed out of %d iter(s), " 676 "%d iter(s) skipped.\n", 677 iter-sfail-full-sskip, iter, full+sskip); 678 cli_out("Delete result: %d entr(y/ies) deleted.\n", 679 iter-dfail-full); 680 done: 681 if (buff) { 682 sal_free(buff); 683 } 684 if (is) { 685 sal_free(is); 686 } 687 return rc; 688 } 689 690 int 691 test_generic_hash(int unit, args_t *a, void *p) 692 { 693 int rv = -1; 694 695 if (soc_feature(unit, soc_feature_ism_memory)) { 696 #ifdef BCM_ISM_SUPPORT 697 rv = test_tr3_generic_hash(unit, a, p); 698 #endif /* BCM_ISM_SUPPORT */ 699 } else { 700 #ifdef BCM_TRIDENT2_SUPPORT 701 rv = test_td2_generic_hash(unit, a, p); 702 #endif /* BCM_TRIDENT2_SUPPORT */ 703 } 704 705 return rv; 706 } 707 708 int 709 test_generic_hash_ov_init(int unit, args_t *a, void **p) 710 { 711 test_generic_hash_test_t *ht = &hash_test[unit]; 712 test_generic_hash_testdata_t *htd = &ht->testdata; 713 int rv; 714 715 _test_generic_hash_setup(unit, ht); 716 717 ht->ctp = htd; 718 719 if ((rv = _test_generic_hash_init(unit, htd, a)) < 0) { 720 return rv; 721 } else { 722 *p = htd; 723 } 724 return 0; 725 } 726 727 #ifdef BCM_TRIDENT2_SUPPORT 728 /* 729 * Test of hash memory overflow behavior 730 * 731 * This test fills each bucket, then inserts another entry to see 732 * that the last entry fails to insert. 733 */ 734 int 735 test_td2_generic_hash_ov(int unit, args_t *a, void *p) 736 { 737 test_generic_hash_testdata_t *htd = p; 738 uint32 *entry_tmp = NULL, entry[SOC_MAX_MEM_WORDS] = {0}; 739 uint32 bucket = 0, result[SOC_MAX_MEM_WORDS] = {0}, hash; 740 int ix, jx, r, idx, rv = 0; 741 int ivid = 0, port = 0, key_type = 0, vrf_id = 0, vfi = 0, vp = 0; 742 int iter = htd->opt_count; 743 int bucket_size, num_entries; 744 int bank_count, bank_num = 0, bank; 745 int alloc_sz, offset; 746 747 COMPILER_REFERENCE(a); 748 749 if (htd->opt_verbose) { 750 cli_out("Resetting hash selection to LSB\n"); 751 } 752 #ifdef BCM_TOMAHAWK_SUPPORT 753 if (SOC_IS_TOMAHAWKX(unit)) { 754 r = soc_tomahawk_hash_bank_count_get(unit, htd->mem, &bank_count); 755 if (r) { 756 test_error(unit, "Could not get bank count\n"); 757 rv = -1; 758 goto done; 759 } 760 r = soc_tomahawk_hash_bank_number_get(unit, htd->mem, 0, &bank_num); 761 if (r) { 762 test_error(unit, "Could not get bank number\n"); 763 rv = -1; 764 goto done; 765 } 766 r = soc_tomahawk_hash_bank_info_get(unit, htd->mem, bank_num, NULL, NULL, 767 &bucket_size, NULL, NULL); 768 if (r) { 769 test_error(unit, "Could not get bucket size\n"); 770 rv = -1; 771 goto done; 772 } 773 } else 774 #endif 775 #ifdef BCM_APACHE_SUPPORT 776 if (SOC_IS_APACHE(unit)) { 777 r = soc_apache_hash_bank_count_get(unit, htd->mem, &bank_count); 778 if (r) { 779 test_error(unit, "Could not get bank count\n"); 780 rv = -1; 781 goto done; 782 } 783 r = soc_apache_hash_bank_number_get(unit, htd->mem, 0, &bank_num); 784 if (r) { 785 test_error(unit, "Could not get bank number\n"); 786 rv = -1; 787 goto done; 788 } 789 r = soc_apache_hash_bank_info_get(unit, htd->mem, bank_num, NULL, NULL, 790 &bucket_size, NULL, NULL); 791 if (r) { 792 test_error(unit, "Could not get bucket size\n"); 793 rv = -1; 794 goto done; 795 } 796 } else 797 #endif 798 #ifdef BCM_HELIX5_SUPPORT 799 if (SOC_IS_HELIX5(unit)) { 800 r = soc_helix5_hash_bank_count_get(unit, htd->mem, &bank_count); 801 if (r) { 802 test_error(unit, "Could not get bank count\n"); 803 rv = -1; 804 goto done; 805 } 806 r = soc_hx5_hash_bank_number_get(unit, htd->mem, 0, &bank_num); 807 if (r) { 808 test_error(unit, "Could not get bank number\n"); 809 rv = -1; 810 goto done; 811 } 812 r = soc_hx5_hash_bank_info_get(unit, htd->mem, bank_num, NULL, NULL, 813 &bucket_size, NULL, NULL); 814 if (r) { 815 test_error(unit, "Could not get bucket size\n"); 816 rv = -1; 817 goto done; 818 } 819 } else 820 #endif 821 #ifdef BCM_TRIDENT3_SUPPORT 822 if (SOC_IS_TRIDENT3X(unit)) { 823 r = soc_trident3_hash_bank_count_get(unit, htd->mem, &bank_count); 824 if (r) { 825 test_error(unit, "Could not get bank count\n"); 826 rv = -1; 827 goto done; 828 } 829 r = soc_td3_hash_bank_number_get(unit, htd->mem, 0, &bank_num); 830 if (r) { 831 test_error(unit, "Could not get bank number\n"); 832 rv = -1; 833 goto done; 834 } 835 r = soc_td3_hash_bank_info_get(unit, htd->mem, bank_num, NULL, NULL, 836 &bucket_size, NULL, NULL); 837 if (r) { 838 test_error(unit, "Could not get bucket size\n"); 839 rv = -1; 840 goto done; 841 } 842 } else 843 #endif 844 { 845 r = soc_trident2_hash_bank_count_get(unit, htd->mem, &bank_count); 846 if (r) { 847 test_error(unit, "Could not get bank count\n"); 848 rv = -1; 849 goto done; 850 } 851 r = soc_trident2_hash_bank_number_get(unit, htd->mem, 0, &bank_num); 852 if (r) { 853 test_error(unit, "Could not get bank number\n"); 854 rv = -1; 855 goto done; 856 } 857 r = soc_trident2_hash_bank_info_get(unit, htd->mem, bank_num, NULL, NULL, 858 &bucket_size, NULL, NULL); 859 if (r) { 860 test_error(unit, "Could not get bucket size\n"); 861 rv = -1; 862 goto done; 863 } 864 } 865 866 num_entries = (bucket_size * bank_count); 867 868 alloc_sz = sizeof(uint32) * SOC_MAX_MEM_WORDS * num_entries; 869 entry_tmp = sal_alloc(alloc_sz, "entry_tmp"); 870 if (entry_tmp == NULL) { 871 rv = -1; 872 goto done; 873 } 874 875 /* Program the respective registers */ 876 switch (htd->mem) { 877 case L2Xm: 878 for (bank = 0; bank < bank_count; bank++) { 879 if (htd->opt_verbose) { 880 cli_out("Resetting hash bank %d selection to LSB\n", bank); 881 } 882 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL2, bank, 883 BCM_HASH_LSB, 48)) < 0) { 884 test_error(unit, "Hash bank setting failed\n"); 885 rv = -1; 886 goto done; 887 } 888 } 889 break; 890 case L3_ENTRY_IPV4_UNICASTm: 891 case L3_ENTRY_IPV4_MULTICASTm: 892 case L3_ENTRY_IPV6_UNICASTm: 893 case L3_ENTRY_IPV6_MULTICASTm: 894 for (bank = 0; bank < bank_count; bank++) { 895 if (htd->opt_verbose) { 896 cli_out("Resetting hash bank %d selection to LSB\n", bank); 897 } 898 if ((r = bcm_switch_hash_banks_config_set(unit, bcmHashTableL3, bank, 899 BCM_HASH_LSB, 48)) < 0) { 900 test_error(unit, "Hash bank setting failed\n"); 901 rv = -1; 902 goto done; 903 } 904 } 905 break; 906 case ING_VP_VLAN_MEMBERSHIPm: 907 if (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &hash) < 0) { 908 test_error(unit, "Hash select read failed\n"); 909 goto done; 910 } 911 soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, &hash, 912 HASH_SELECT_Af, FB_HASH_LSB); 913 soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, &hash, 914 HASH_SELECT_Bf, FB_HASH_LSB); 915 if (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, hash) < 0) { 916 test_error(unit, "Hash select setting failed\n"); 917 rv = -1; 918 goto done; 919 } 920 break; 921 case EGR_VP_VLAN_MEMBERSHIPm: 922 if (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &hash) < 0) { 923 test_error(unit, "Hash select read failed\n"); 924 goto done; 925 } 926 soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, &hash, 927 HASH_SELECT_Af, FB_HASH_LSB); 928 soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, &hash, 929 HASH_SELECT_Bf, FB_HASH_LSB); 930 if (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, hash) < 0) { 931 test_error(unit, "Hash select setting failed\n"); 932 rv = -1; 933 goto done; 934 } 935 break; 936 case ING_DNAT_ADDRESS_TYPEm: 937 if (READ_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLr(unit, &hash) < 0) { 938 test_error(unit, "Hash select read failed\n"); 939 goto done; 940 } 941 soc_reg_field_set(unit, ING_DNAT_ADDRESS_TYPE_HASH_CONTROLr, &hash, 942 HASH_SELECT_Af, FB_HASH_LSB); 943 soc_reg_field_set(unit, ING_DNAT_ADDRESS_TYPE_HASH_CONTROLr, &hash, 944 HASH_SELECT_Bf, FB_HASH_LSB); 945 if (WRITE_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLr(unit, hash) < 0) { 946 test_error(unit, "Hash select setting failed\n"); 947 rv = -1; 948 goto done; 949 } 950 break; 951 case L2_ENDPOINT_IDm: 952 if (READ_L2_ENDPOINT_ID_HASH_CONTROLr(unit, &hash) < 0) { 953 test_error(unit, "Hash select read failed\n"); 954 goto done; 955 } 956 soc_reg_field_set(unit, L2_ENDPOINT_ID_HASH_CONTROLr, &hash, 957 HASH_SELECT_Af, FB_HASH_LSB); 958 soc_reg_field_set(unit, L2_ENDPOINT_ID_HASH_CONTROLr, &hash, 959 HASH_SELECT_Bf, FB_HASH_LSB); 960 if (WRITE_L2_ENDPOINT_ID_HASH_CONTROLr(unit, hash) < 0) { 961 test_error(unit, "Hash select setting failed\n"); 962 rv = -1; 963 goto done; 964 } 965 break; 966 case ENDPOINT_QUEUE_MAPm: 967 if (READ_ENDPOINT_QUEUE_MAP_HASH_CONTROLr(unit, &hash) < 0) { 968 test_error(unit, "Hash select read failed\n"); 969 goto done; 970 } 971 soc_reg_field_set(unit, ENDPOINT_QUEUE_MAP_HASH_CONTROLr, &hash, 972 HASH_SELECT_Af, FB_HASH_LSB); 973 soc_reg_field_set(unit, ENDPOINT_QUEUE_MAP_HASH_CONTROLr, &hash, 974 HASH_SELECT_Bf, FB_HASH_LSB); 975 if (WRITE_ENDPOINT_QUEUE_MAP_HASH_CONTROLr(unit, hash) < 0) { 976 test_error(unit, "Hash select setting failed\n"); 977 rv = -1; 978 goto done; 979 } 980 break; 981 case VLAN_XLATEm: 982 if (READ_VLAN_XLATE_HASH_CONTROLr(unit, &hash) < 0) { 983 test_error(unit, "Hash select read failed\n"); 984 goto done; 985 } 986 soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash, 987 HASH_SELECT_Af, FB_HASH_LSB); 988 soc_reg_field_set(unit, VLAN_XLATE_HASH_CONTROLr, &hash, 989 HASH_SELECT_Bf, FB_HASH_LSB); 990 if (WRITE_VLAN_XLATE_HASH_CONTROLr(unit, hash) < 0) { 991 test_error(unit, "Hash select setting failed\n"); 992 rv = -1; 993 goto done; 994 } 995 break; 996 case EGR_VLAN_XLATEm: 997 if (READ_EGR_VLAN_XLATE_HASH_CONTROLr(unit, &hash) < 0) { 998 test_error(unit, "Hash select read failed\n"); 999 goto done; 1000 } 1001 soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash, 1002 HASH_SELECT_Af, FB_HASH_LSB); 1003 soc_reg_field_set(unit, EGR_VLAN_XLATE_HASH_CONTROLr, &hash, 1004 HASH_SELECT_Bf, FB_HASH_LSB); 1005 if (WRITE_EGR_VLAN_XLATE_HASH_CONTROLr(unit, hash) < 0) { 1006 test_error(unit, "Hash select setting failed\n"); 1007 rv = -1; 1008 goto done; 1009 } 1010 break; 1011 case MPLS_ENTRYm: 1012 if (READ_MPLS_ENTRY_HASH_CONTROLr(unit, &hash) < 0) { 1013 test_error(unit, "Hash select read failed\n"); 1014 goto done; 1015 } 1016 soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash, 1017 HASH_SELECT_Af, FB_HASH_LSB); 1018 soc_reg_field_set(unit, MPLS_ENTRY_HASH_CONTROLr, &hash, 1019 HASH_SELECT_Bf, FB_HASH_LSB); 1020 if (WRITE_MPLS_ENTRY_HASH_CONTROLr(unit, hash) < 0) { 1021 test_error(unit, "Hash select setting failed\n"); 1022 rv = -1; 1023 goto done; 1024 } 1025 } 1026 1027 while (iter--) { 1028 for (ix = 0; ix < num_entries; ix++) { 1029 1030 offset = ix * SOC_MAX_MEM_WORDS; 1031 /* Prepare the entry */ 1032 sal_memset (&(entry_tmp[offset]), 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1033 if (SOC_MEM_FIELD_VALID(unit, htd->mem, VALIDf)) { 1034 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VALIDf, 1); 1035 } else { 1036 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VALID_0f, 1); 1037 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VALID_1f, 1); 1038 if (SOC_MEM_FIELD_VALID(unit, htd->mem, VALID_2f)) { 1039 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VALID_2f, 1); 1040 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VALID_3f, 1); 1041 } 1042 } 1043 switch (htd->mem) { 1044 case L2Xm: 1045 key_type = TD2_L2_HASH_KEY_TYPE_VFI; 1046 break; 1047 case L3_ENTRY_IPV4_UNICASTm: 1048 key_type = TD2_L3_HASH_KEY_TYPE_V4UC; 1049 break; 1050 case L3_ENTRY_IPV4_MULTICASTm: 1051 key_type = TD2_L3_HASH_KEY_TYPE_V4MC; 1052 break; 1053 case L3_ENTRY_IPV6_UNICASTm: 1054 key_type = TD2_L3_HASH_KEY_TYPE_V6UC; 1055 break; 1056 case L3_ENTRY_IPV6_MULTICASTm: 1057 key_type = TD2_L3_HASH_KEY_TYPE_V6MC; 1058 } 1059 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPEf)) { 1060 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), KEY_TYPEf, key_type); 1061 } else { 1062 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_0f)) { 1063 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), KEY_TYPE_0f, key_type); 1064 } 1065 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_1f)) { 1066 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), KEY_TYPE_1f, key_type); 1067 } 1068 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_2f)) { 1069 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), KEY_TYPE_2f, key_type); 1070 } 1071 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_3f)) { 1072 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), KEY_TYPE_3f, key_type); 1073 } 1074 } 1075 switch (htd->mem) { 1076 case L2Xm: 1077 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VFIf, vfi); 1078 break; 1079 case L3_ENTRY_IPV4_UNICASTm: 1080 case L3_ENTRY_IPV4_MULTICASTm: 1081 case L3_ENTRY_IPV6_UNICASTm: 1082 case L3_ENTRY_IPV6_MULTICASTm: 1083 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VRF_IDf, vrf_id); 1084 break; 1085 case ING_VP_VLAN_MEMBERSHIPm: 1086 case EGR_VP_VLAN_MEMBERSHIPm: 1087 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VPf, vp); 1088 break; 1089 case ING_DNAT_ADDRESS_TYPEm: 1090 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VRFf, vrf_id); 1091 break; 1092 case L2_ENDPOINT_IDm: 1093 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), VFIf, vfi); 1094 break; 1095 case ENDPOINT_QUEUE_MAPm: 1096 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), DEST_PORTf, port); 1097 break; 1098 case VLAN_XLATEm: 1099 case EGR_VLAN_XLATEm: 1100 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), IVIDf, ivid); 1101 break; 1102 case MPLS_ENTRYm: 1103 soc_mem_field32_set(unit, htd->mem, &(entry_tmp[offset]), PORT_NUMf, port); 1104 } 1105 1106 if (ix == 0) { 1107 #ifdef BCM_TOMAHAWK_SUPPORT 1108 if (SOC_IS_TOMAHAWKX(unit)) { 1109 soc_th_hash_bucket_get(unit, htd->mem, 0, &(entry_tmp[offset]), &bucket); 1110 idx = soc_th_hash_index_get(unit, htd->mem, 0, bucket); 1111 } else 1112 #endif 1113 #ifdef BCM_APACHE_SUPPORT 1114 if (SOC_IS_APACHE(unit)) { 1115 soc_ap_hash_bucket_get(unit, htd->mem, 0, &(entry_tmp[offset]), &bucket); 1116 idx = soc_ap_hash_index_get(unit, htd->mem, 0, bucket); 1117 } else 1118 #endif 1119 #ifdef BCM_HELIX5_SUPPORT 1120 if (SOC_IS_HELIX5(unit)) { 1121 soc_hx5_hash_bucket_get(unit, htd->mem, 0, &(entry_tmp[offset]), &bucket); 1122 idx = soc_hx5_hash_index_get(unit, htd->mem, 0, bucket); 1123 } else 1124 #endif 1125 #ifdef BCM_TRIDENT3_SUPPORT 1126 if (SOC_IS_TRIDENT3X(unit)) { 1127 soc_td3_hash_bucket_get(unit, htd->mem, 0, &(entry_tmp[offset]), &bucket); 1128 idx = soc_td3_hash_index_get(unit, htd->mem, 0, bucket); 1129 } else 1130 #endif 1131 { 1132 soc_hash_bucket_get(unit, htd->mem, 0, &(entry_tmp[offset]), &bucket); 1133 idx = soc_hash_index_get(unit, htd->mem, 0, bucket); 1134 } 1135 if (htd->opt_verbose) { 1136 cli_out("Filling bucket %d\n", bucket); 1137 } 1138 } 1139 if (htd->opt_verbose) { 1140 cli_out("Inserting entry at bucket %d\n", bucket); 1141 soc_mem_entry_dump(unit, htd->mem, &(entry_tmp[ix]), BSL_LSS_CLI); 1142 cli_out("\n"); 1143 } 1144 1145 if ((r = soc_mem_insert(unit, htd->mem, MEM_BLOCK_ALL, &(entry_tmp[offset]))) < 0) { 1146 if (r == SOC_E_FULL) { 1147 /* Already full, stop wasting time */ 1148 break; 1149 } else { 1150 test_error(unit, "Insert failed at bucket %d return:%d\n", bucket, r); 1151 rv = -1; 1152 goto done; 1153 } 1154 } 1155 1156 ivid = (ivid > 0xfff) ? 1 : ivid + 1; 1157 port = (port > 0x3f) ? 1 : port + 1; 1158 vrf_id = (vrf_id >= SOC_VRF_MAX(unit)) ? 1 : vrf_id + 1; 1159 vp = (vp > 0xfff) ? 1 : vp + 1; 1160 vfi = (vfi > 0xfff) ? 1 : vfi + 1; 1161 } 1162 1163 /* Prepare the entry which should overflow */ 1164 sal_memset (entry, 0, sizeof(entry)); 1165 if (SOC_MEM_FIELD_VALID(unit, htd->mem, VALIDf)) { 1166 soc_mem_field32_set(unit, htd->mem, entry, VALIDf, 1); 1167 } else { 1168 soc_mem_field32_set(unit, htd->mem, entry, VALID_0f, 1); 1169 soc_mem_field32_set(unit, htd->mem, entry, VALID_1f, 1); 1170 if (SOC_MEM_FIELD_VALID(unit, htd->mem, VALID_2f)) { 1171 soc_mem_field32_set(unit, htd->mem, entry, VALID_2f, 1); 1172 soc_mem_field32_set(unit, htd->mem, entry, VALID_3f, 1); 1173 } 1174 } 1175 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPEf)) { 1176 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPEf, key_type); 1177 } else { 1178 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_0f)) { 1179 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_0f, key_type); 1180 } 1181 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_1f)) { 1182 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_1f, key_type); 1183 } 1184 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_2f)) { 1185 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_2f, key_type); 1186 } 1187 if (SOC_MEM_FIELD_VALID(unit, htd->mem, KEY_TYPE_3f)) { 1188 soc_mem_field32_set(unit, htd->mem, entry, KEY_TYPE_3f, key_type); 1189 } 1190 } 1191 1192 switch (htd->mem) { 1193 case L2Xm: 1194 soc_mem_field32_set(unit, htd->mem, entry, VFIf, vfi); 1195 break; 1196 case L3_ENTRY_IPV4_UNICASTm: 1197 case L3_ENTRY_IPV4_MULTICASTm: 1198 case L3_ENTRY_IPV6_UNICASTm: 1199 case L3_ENTRY_IPV6_MULTICASTm: 1200 soc_mem_field32_set(unit, htd->mem, entry, VRF_IDf, vrf_id); 1201 break; 1202 case ING_VP_VLAN_MEMBERSHIPm: 1203 case EGR_VP_VLAN_MEMBERSHIPm: 1204 soc_mem_field32_set(unit, htd->mem, entry, VPf, vp); 1205 break; 1206 case ING_DNAT_ADDRESS_TYPEm: 1207 soc_mem_field32_set(unit, htd->mem, entry, VRFf, vrf_id); 1208 break; 1209 case L2_ENDPOINT_IDm: 1210 soc_mem_field32_set(unit, htd->mem, entry, VFIf, vfi); 1211 break; 1212 case ENDPOINT_QUEUE_MAPm: 1213 soc_mem_field32_set(unit, htd->mem, entry, DEST_PORTf, port); 1214 break; 1215 case VLAN_XLATEm: 1216 case EGR_VLAN_XLATEm: 1217 soc_mem_field32_set(unit, htd->mem, entry, IVIDf, ivid); 1218 break; 1219 case MPLS_ENTRYm: 1220 soc_mem_field32_set(unit, htd->mem, entry, PORT_NUMf, port); 1221 } 1222 1223 if (htd->opt_verbose) { 1224 cli_out("Inserting the extra entry in bucket %d, should fail\n", bucket); 1225 soc_mem_entry_dump(unit, htd->mem, entry, BSL_LSS_CLI); 1226 cli_out("\n"); 1227 } 1228 /* Insert the extra entry, should overflow */ 1229 if ((r = soc_mem_insert(unit, htd->mem, MEM_BLOCK_ALL, (entry))) < 0) { 1230 if (r != SOC_E_FULL) { 1231 test_error(unit, "Insert failed.\n"); 1232 rv = -1; 1233 goto done; 1234 } 1235 } else { 1236 test_error(unit, "Insert to full bucket succeeded \n"); 1237 rv = -1; 1238 goto done; 1239 } 1240 1241 if (htd->opt_verbose) { 1242 cli_out("Verifying entries present\n"); 1243 } 1244 1245 /* Verify bucket contains our added entries */ 1246 for (jx = 0; jx < ix; jx++) { 1247 offset = jx * SOC_MAX_MEM_WORDS; 1248 if (soc_mem_search(unit, htd->mem, MEM_BLOCK_ANY, &idx, 1249 &(entry_tmp[offset]), result, 0) < 0) { 1250 test_error(unit, "Entry missing at bucket %d\n", bucket); 1251 rv = -1; 1252 goto done; 1253 } 1254 } 1255 1256 if (htd->opt_verbose) { 1257 cli_out("Cleaning bucket %d\n", bucket); 1258 } 1259 1260 /* Remove the entries that we added */ 1261 for (jx = 0; jx < ix; jx++) { 1262 offset = jx * SOC_MAX_MEM_WORDS; 1263 if (soc_mem_delete(unit, htd->mem, MEM_BLOCK_ALL, &(entry_tmp[offset])) < 0) { 1264 test_error(unit, "Delete failed at bucket %d\n", bucket); 1265 rv = -1; 1266 goto done; 1267 } 1268 } 1269 } 1270 1271 done: 1272 if (entry_tmp) { 1273 sal_free(entry_tmp); 1274 entry_tmp = NULL; 1275 } 1276 return rv; 1277 } 1278 #endif /* BCM_TRIDENT2_SUPPORT */ 1279 1280 /* 1281 * Test of hash memory overflow behavior 1282 * 1283 * This test fills each bucket, then inserts another entry to see 1284 * that the last entry fails to insert. 1285 */ 1286 int 1287 test_generic_hash_ov(int unit, args_t *a, void *p) 1288 { 1289 test_generic_hash_testdata_t *htd = p; 1290 int rv = -1; 1291 1292 COMPILER_REFERENCE(a); 1293 if (htd->opt_verbose) { 1294 cli_out("Starting generic hash overflow test\n"); 1295 } 1296 if (soc_feature(unit, soc_feature_ism_memory)) { 1297 rv = 0; 1298 #ifdef BCM_TRIDENT2_SUPPORT 1299 } else { 1300 rv = test_td2_generic_hash_ov(unit, a, p); 1301 #endif /* BCM_TRIDENT2_SUPPORT */ 1302 } 1303 1304 return rv; 1305 } 1306 1307 /* 1308 * Test clean-up routine used for generic hash tests 1309 */ 1310 1311 int 1312 test_generic_hash_done(int unit, void *p) 1313 { 1314 uint8 ix; 1315 int rc = 0; 1316 test_generic_hash_testdata_t *htd = p; 1317 1318 if (htd->restore) { 1319 for (ix = 0; ix < htd->offset_count; ix++) { 1320 if (htd->restore & (1 << htd->config_banks[ix])) { 1321 rc = soc_ism_hash_offset_config(unit, htd->config_banks[ix], 1322 htd->cur_offset[ix]); 1323 if (rc) { 1324 test_error(unit, "Error setting offset for %s: bank: %d\n", 1325 htd->mem_str, htd->config_banks[ix]); 1326 } 1327 if (htd->opt_verbose) { 1328 cli_out("Restore offset %d for bank %d\n", 1329 htd->cur_offset[ix], htd->config_banks[ix]); 1330 } 1331 } 1332 } 1333 } 1334 return rc; 1335 } 1336 1337 #endif /* BCM_ISM_SUPPORT */ 1338 #endif /* BCM_XGS_SWITCH_SUPPORT */ 1339