switch_match.c (35204B)
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 8 #include <shared/bsl.h> 9 #include <soc/debug.h> 10 #include <soc/drv.h> 11 #include <soc/scache.h> 12 #include <soc/mem.h> 13 #include <bcm/switch.h> 14 #include <bcm/error.h> 15 #include <bcm_int/esw/trx.h> 16 #include <bcm_int/esw/switch.h> 17 #include <bcm_int/esw/switch_match.h> 18 #include <bcm_int/esw/hurricane3.h> 19 #include <bcm_int/esw/xgs3.h> 20 #if defined(BCM_HURRICANE3_SUPPORT) 21 #if defined(BCM_SWITCH_MATCH_SUPPORT) 22 23 /* Parameter NULL error handling */ 24 #define HR3_MATCH_CHECK_NULL_PARAMETER(_u_, _parameter_) \ 25 do { \ 26 if (NULL == (_parameter_)) { \ 27 LOG_ERROR(BSL_LS_BCM_SWITCH, \ 28 (BSL_META_U((_u_), \ 29 "Error: NULL parameter\n"))); \ 30 return BCM_E_PARAM; \ 31 } \ 32 } while (0) 33 34 /* Function Enter/Leave Tracing */ 35 #define HR3_MATCH_FUNCTION_TRACE(_u_, _str_) \ 36 do { \ 37 LOG_VERBOSE(BSL_LS_BCM_SWITCH, \ 38 (BSL_META_U((_u_), \ 39 "%s: " _str_ "\n"), __FUNCTION__)); \ 40 } while (0) 41 42 /* Switch Match Miml table size */ 43 #define HR3_SWITCH_MATCH_TABLE_SIZE_MIML (1) 44 45 /* Check if the value exceed the field max acceptable value */ 46 STATIC int 47 bcmi_hr3_swtich_match_valid_field_value( 48 int unit, 49 soc_mem_t mem, 50 soc_field_t field, 51 uint32 value) 52 { 53 uint32 max_value; 54 55 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 56 57 /* Check that memory is a valid one for this unit. */ 58 if (!SOC_MEM_IS_VALID(unit, mem)) { 59 return (BCM_E_INTERNAL); 60 } 61 62 /* Check that field is a valid one for the memory. */ 63 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 64 return (BCM_E_INTERNAL); 65 } 66 67 max_value = (uint32)(1 << soc_mem_field_length(unit, mem, field)) - 1; 68 69 if (!(value <= max_value)) { 70 LOG_ERROR(BSL_LS_BCM_SWITCH, 71 (BSL_META_U(unit, 72 "value(%d) doesn't fit to %s of %s.\n"), 73 value, 74 SOC_FIELD_NAME(unit, field), 75 SOC_MEM_NAME(unit, mem))); 76 return BCM_E_PARAM; 77 } 78 79 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 80 return BCM_E_NONE; 81 } 82 83 /* 84 * Function: 85 * bcmi_hr3_miml_table_size_get 86 * Purpose: 87 * Get the table size for MIML 88 * Parameters: 89 * unit - (IN) Unit number 90 * table_size - (OUT) table size 91 * Returns: 92 * BCM_E_xxx 93 */ 94 STATIC int 95 bcmi_hr3_miml_match_table_size_get( 96 int unit, 97 uint32 *table_size) 98 { 99 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 100 /* Parameter NULL error handling */ 101 HR3_MATCH_CHECK_NULL_PARAMETER(unit, table_size); 102 103 #if defined(BCM_HURRICANE3_SUPPORT) 104 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 105 *table_size = HR3_SWITCH_MATCH_TABLE_SIZE_MIML; 106 } 107 #endif /* BCM_HURRICANE3_SUPPORT */ 108 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 109 return BCM_E_NONE; 110 } 111 112 /* 113 * Function: 114 * bcmi_hr3_miml_match_hw_idx_get 115 * Purpose: 116 * Get HW memory index 117 * Parameters: 118 * unit - (IN) Unit number 119 * sw_idx - (IN) SW memory index 120 * hw_idx - (OUT) HW memory index 121 * Returns: 122 * BCM_E_xxx 123 */ 124 STATIC int 125 bcmi_hr3_miml_match_hw_idx_get( 126 int unit, 127 uint32 sw_idx, 128 uint32 *hw_idx) 129 { 130 uint32 table_size; 131 132 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 133 /* Parameter NULL error handling */ 134 HR3_MATCH_CHECK_NULL_PARAMETER(unit, hw_idx); 135 136 /* Parameter validation */ 137 BCM_IF_ERROR_RETURN 138 (bcmi_hr3_miml_match_table_size_get(unit, &table_size)); 139 140 if (sw_idx >= table_size) { 141 LOG_ERROR(BSL_LS_BCM_SWITCH, 142 (BSL_META_U(unit, 143 "Invalid sw_idx.\n"))); 144 return BCM_E_RESOURCE; 145 } 146 /* For Miml case, the hardware index and sw_idx are always 0 */ 147 *hw_idx = sw_idx; 148 149 LOG_DEBUG(BSL_LS_BCM_SWITCH, 150 (BSL_META_U(unit, 151 "hw_idx %u\n"), *hw_idx)); 152 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 153 return BCM_E_NONE; 154 } 155 156 /* 157 * Function: 158 * bcmi_hr3_miml_match_match_sw_idx_get 159 * Purpose: 160 * Get SW memory index 161 * Parameters: 162 * unit - (IN) Unit number 163 * hw_idx - (IN) HW memory index 164 * sw_idx - (OUT) SW memory index 165 * Returns: 166 * BCM_E_xxx 167 */ 168 STATIC int 169 bcmi_hr3_miml_match_sw_idx_get( 170 int unit, 171 uint32 hw_idx, 172 uint32 *sw_idx) 173 { 174 uint32 table_size; 175 176 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 177 178 /* Parameter NULL error handling */ 179 HR3_MATCH_CHECK_NULL_PARAMETER(unit, sw_idx); 180 181 /* Parameter validation */ 182 BCM_IF_ERROR_RETURN 183 (bcmi_hr3_miml_match_table_size_get(unit, &table_size)); 184 185 if (hw_idx >= table_size) { 186 LOG_ERROR(BSL_LS_BCM_SWITCH, 187 (BSL_META_U(unit, 188 "Invalid sw_idx.\n"))); 189 return BCM_E_RESOURCE; 190 } 191 192 /* For Miml case, the hardware index and sw_idx are always 0 */ 193 *sw_idx = hw_idx; 194 195 LOG_DEBUG(BSL_LS_BCM_SWITCH, 196 (BSL_META_U(unit, 197 "sw_idx %u\n"), *sw_idx)); 198 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 199 return BCM_E_NONE; 200 } 201 202 /* 203 * Function: 204 * bcmi_hr3_custom_hdr_table_size_get 205 * Purpose: 206 * Get the table size for Custom Header 207 * Parameters: 208 * unit - (IN) Unit number 209 * table_size - (OUT) table size 210 * Returns: 211 * BCM_E_xxx 212 */ 213 STATIC int 214 bcmi_hr3_custom_hdr_match_table_size_get( 215 int unit, 216 uint32 *table_size) 217 { 218 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 219 220 /* Parameter NULL error handling */ 221 HR3_MATCH_CHECK_NULL_PARAMETER(unit, table_size); 222 223 *table_size = soc_mem_index_count(unit, CUSTOM_HEADER_MATCHm); 224 LOG_DEBUG(BSL_LS_BCM_SWITCH, 225 (BSL_META_U(unit, 226 "table_size %u\n"), *table_size)); 227 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 228 return BCM_E_NONE; 229 } 230 231 /* 232 * Function: 233 * bcmi_hr3_custom_hdr_match_hw_idx_get 234 * Purpose: 235 * Get HW memory index 236 * Parameters: 237 * unit - (IN) Unit number 238 * sw_idx - (IN) SW memory index 239 * hw_idx - (OUT) HW memory index 240 * Returns: 241 * BCM_E_xxx 242 */ 243 STATIC int 244 bcmi_hr3_custom_hdr_match_hw_idx_get( 245 int unit, 246 uint32 sw_idx, 247 uint32 *hw_idx) 248 { 249 uint32 table_size; 250 251 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 252 253 /* Parameter NULL error handling */ 254 HR3_MATCH_CHECK_NULL_PARAMETER(unit, hw_idx); 255 256 /* Parameter validation */ 257 BCM_IF_ERROR_RETURN 258 (bcmi_hr3_custom_hdr_match_table_size_get(unit, &table_size)); 259 260 if (sw_idx >= table_size) { 261 LOG_ERROR(BSL_LS_BCM_SWITCH, 262 (BSL_META_U(unit, 263 "Invalid sw_idx.\n"))); 264 return BCM_E_RESOURCE; 265 } 266 /* For Customer Header, sw_idx = hw_idx */ 267 *hw_idx = sw_idx; 268 269 LOG_DEBUG(BSL_LS_BCM_SWITCH, 270 (BSL_META_U(unit, 271 "hw_idx %u\n"), *hw_idx)); 272 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 273 return BCM_E_NONE; 274 } 275 276 /* 277 * Function: 278 * bcmi_hr3_custom_hdr_match_sw_idx_get 279 * Purpose: 280 * Get SW memory index 281 * Parameters: 282 * unit - (IN) Unit number 283 * hw_idx - (IN) HW memory index 284 * sw_idx - (OUT) SW memory index 285 * Returns: 286 * BCM_E_xxx 287 */ 288 STATIC int 289 bcmi_hr3_custom_hdr_match_sw_idx_get( 290 int unit, 291 uint32 hw_idx, 292 uint32 *sw_idx) 293 { 294 uint32 table_size; 295 296 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 297 298 /* Parameter NULL error handling */ 299 HR3_MATCH_CHECK_NULL_PARAMETER(unit, sw_idx); 300 301 /* Parameter validation */ 302 BCM_IF_ERROR_RETURN 303 (bcmi_hr3_custom_hdr_match_table_size_get(unit, &table_size)); 304 305 if (hw_idx >= table_size) { 306 LOG_ERROR(BSL_LS_BCM_SWITCH, 307 (BSL_META_U(unit, 308 "Invalid sw_idx.\n"))); 309 return BCM_E_RESOURCE; 310 } 311 312 /* For Customer Header, sw_idx = hw_idx */ 313 *sw_idx = hw_idx; 314 315 LOG_DEBUG(BSL_LS_BCM_SWITCH, 316 (BSL_META_U(unit, 317 "sw_idx %u\n"), *sw_idx)); 318 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 319 return BCM_E_NONE; 320 } 321 322 /* 323 * Function: 324 * bcmi_hr3_miml_match_config_write 325 * Purpose: 326 * Write the match configuration to hardware 327 * Parameters: 328 * unit - (IN) Unit number 329 * config_info - (IN) Match configuration 330 * Returns: 331 * BCM_E_xxx 332 */ 333 STATIC int 334 bcmi_hr3_miml_match_config_write( 335 int unit, 336 bcm_switch_match_config_info_t *config_info) 337 { 338 uint32 rval = 0; 339 340 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 341 /* Parameter NULL error handling */ 342 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 343 344 if (config_info->outer_ethtype == 0 || 345 config_info->inner_ethtype == 0) { 346 return BCM_E_PARAM; 347 } 348 349 BCM_IF_ERROR_RETURN(READ_MIML_TPIDr(unit, &rval)); 350 soc_reg_field_set(unit, MIML_TPIDr, &rval, TPIDf, 351 config_info->outer_ethtype); 352 BCM_IF_ERROR_RETURN(WRITE_MIML_TPIDr(unit, rval)); 353 354 BCM_IF_ERROR_RETURN(READ_MIML_ETYPEr(unit, &rval)); 355 soc_reg_field_set(unit, MIML_ETYPEr, &rval, ETYPEf, 356 config_info->inner_ethtype); 357 BCM_IF_ERROR_RETURN(WRITE_MIML_ETYPEr(unit, rval)); 358 359 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 360 return BCM_E_NONE; 361 } 362 363 /* 364 * Function: 365 * bcmi_hr3_miml_match_config_add 366 * Purpose: 367 * Add a match config, return match_id after matched 368 * config created. 369 * Parameters: 370 * unit - (IN) Unit number 371 * config_info - (IN) Match configuration 372 * sw_idx - (OUT) SW memory index 373 * Returns: 374 * BCM_E_xxx 375 */ 376 STATIC int 377 bcmi_hr3_miml_match_config_add( 378 int unit, 379 bcm_switch_match_config_info_t *config_info, 380 uint32 *sw_idx) 381 { 382 int rv = BCM_E_NONE; 383 uint32 rval = 0; 384 uint16 outer_ethtype, inner_ethtype; 385 /* For Miml case, the hardware index (hw_idx) is always 0 */ 386 uint32 hw_idx = 0; 387 388 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 389 /* Parameter NULL error handling */ 390 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 391 HR3_MATCH_CHECK_NULL_PARAMETER(unit, sw_idx); 392 393 if (config_info->outer_ethtype == 0 || 394 config_info->inner_ethtype == 0) { 395 return BCM_E_PARAM; 396 } 397 /* Check if the config is the same or HW has been used */ 398 BCM_IF_ERROR_RETURN(READ_MIML_TPIDr(unit, &rval)); 399 outer_ethtype = (uint16)soc_reg_field_get(unit, MIML_TPIDr, rval, TPIDf); 400 401 BCM_IF_ERROR_RETURN(READ_MIML_ETYPEr(unit, &rval)); 402 inner_ethtype = (uint16)soc_reg_field_get(unit, MIML_ETYPEr, rval, ETYPEf); 403 404 if (outer_ethtype == config_info->outer_ethtype && 405 inner_ethtype == config_info->inner_ethtype) { 406 /* the config is the same */ 407 return BCM_E_EXISTS; 408 } else if (outer_ethtype != 0 && inner_ethtype != 0) { 409 /* the only HW entry has been used */ 410 return BCM_E_RESOURCE; 411 } 412 413 /* No sw_idx paramter since there is only one entry in HR3 miml */ 414 BCM_IF_ERROR_RETURN 415 (bcmi_hr3_miml_match_config_write(unit, 416 config_info)); 417 *sw_idx = hw_idx; 418 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 419 return rv; 420 } 421 422 /* 423 * Function: 424 * bcmi_hr3_custom_hdr_match_config_add 425 * Purpose: 426 * Add a match config, return match_id after matched 427 * config created. 428 * Parameters: 429 * unit - (IN) Unit number 430 * config_info - (IN) Match configuration 431 * sw_idx - (OUT) SW memory index 432 * Returns: 433 * BCM_E_xxx 434 */ 435 STATIC int 436 bcmi_hr3_custom_hdr_match_config_add( 437 int unit, 438 bcm_switch_match_config_info_t *config_info, 439 uint32 *sw_idx) 440 { 441 int rv = BCM_E_NONE; 442 uint32 hw_idx; 443 int ref_count = 0; 444 custom_header_match_entry_t custom_hdr_entry; 445 custom_header_policy_table_entry_t policy_entry; 446 void *entries[1]; 447 448 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 449 450 /* Parameter NULL error handling */ 451 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 452 HR3_MATCH_CHECK_NULL_PARAMETER(unit, sw_idx); 453 454 sal_memset(&custom_hdr_entry, 0, sizeof(custom_header_match_entry_t)); 455 sal_memset(&policy_entry, 0, sizeof(custom_header_policy_table_entry_t)); 456 457 /* Add one entry in CUSTOM_HEADER_MATCHm */ 458 soc_mem_field32_set(unit, CUSTOM_HEADER_MATCHm, &custom_hdr_entry, 459 CUSTOM_HEADERf, config_info->value32); 460 soc_mem_field32_set(unit, CUSTOM_HEADER_MATCHm, &custom_hdr_entry, 461 VALIDf, 1); 462 entries[0] = &custom_hdr_entry; 463 464 BCM_IF_ERROR_RETURN 465 (_bcm_custom_header_match_entry_add(unit, entries, 1, &hw_idx)); 466 467 if (hw_idx >= soc_mem_index_count(unit, CUSTOM_HEADER_MATCHm)) { 468 return BCM_E_INTERNAL; 469 } 470 471 /* Check if the entry is existed */ 472 BCM_IF_ERROR_RETURN 473 (_bcm_custom_header_match_entry_ref_count_get(unit, hw_idx, 474 &ref_count)); 475 476 /* Decrease the reference count if existed, and return BCM_E_EXISTS */ 477 if (ref_count > 1) { 478 _bcm_common_profile_mem_ref_cnt_update(unit, CUSTOM_HEADER_MATCHm, 479 hw_idx, -1); 480 *sw_idx = hw_idx; 481 return BCM_E_EXISTS; 482 } 483 /* Check if the value fit the target field range */ 484 BCM_IF_ERROR_RETURN 485 (bcmi_hr3_swtich_match_valid_field_value( 486 unit, CUSTOM_HEADER_POLICY_TABLEm, INT_PRIf, 487 config_info->int_pri)); 488 489 BCM_IF_ERROR_RETURN 490 (bcmi_hr3_swtich_match_valid_field_value( 491 unit, CUSTOM_HEADER_POLICY_TABLEm, CNGf, 492 config_info->color)); 493 494 /* Write PRI/CNG to CUSTOM_HEADER_POLICY_TABLEm */ 495 BCM_IF_ERROR_RETURN 496 (soc_mem_read(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ANY, 497 hw_idx, &policy_entry)); 498 soc_mem_field32_set(unit, CUSTOM_HEADER_POLICY_TABLEm, &policy_entry, 499 INT_PRIf, config_info->int_pri); 500 soc_mem_field32_set(unit, CUSTOM_HEADER_POLICY_TABLEm, &policy_entry, 501 CNGf, _BCM_COLOR_ENCODING(unit, config_info->color)); 502 BCM_IF_ERROR_RETURN 503 (soc_mem_write(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ALL, 504 hw_idx, &policy_entry)); 505 506 *sw_idx = hw_idx; 507 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 508 return rv; 509 } 510 511 /* 512 * Function: 513 * bcmi_hr3_miml_match_config_delete 514 * Purpose: 515 * Destroy a match ID by removing it from hardware. 516 * Parameters: 517 * unit - (IN) Unit number 518 * sw_idx - (IN) SW memory index 519 * Returns: 520 * BCM_E_XXX 521 */ 522 STATIC int 523 bcmi_hr3_miml_match_config_delete( 524 int unit, 525 uint32 sw_idx) 526 { 527 uint32 table_size; 528 529 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 530 BCM_IF_ERROR_RETURN 531 (bcmi_hr3_miml_match_table_size_get(unit, &table_size)); 532 533 if (sw_idx >= table_size) { 534 LOG_ERROR(BSL_LS_BCM_SWITCH, 535 (BSL_META_U(unit, 536 "Invalid sw_idx.\n"))); 537 return BCM_E_RESOURCE; 538 } 539 BCM_IF_ERROR_RETURN(WRITE_MIML_TPIDr(unit, 0)); 540 BCM_IF_ERROR_RETURN(WRITE_MIML_ETYPEr(unit, 0)); 541 542 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 543 return BCM_E_NONE; 544 } 545 546 /* 547 * Function: 548 * bcmi_hr3_custom_hdr_match_config_delete 549 * Purpose: 550 * Destroy a match ID by removing it from hardware. 551 * Parameters: 552 * unit - (IN) Unit number 553 * sw_idx - (IN) SW memory index 554 * Returns: 555 * BCM_E_XXX 556 */ 557 STATIC int 558 bcmi_hr3_custom_hdr_match_config_delete( 559 int unit, 560 uint32 sw_idx) 561 { 562 int rv = BCM_E_UNAVAIL; 563 custom_header_policy_table_entry_t policy_entry; 564 uint32 hw_idx = sw_idx; 565 uint32 table_size; 566 567 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 568 BCM_IF_ERROR_RETURN 569 (bcmi_hr3_custom_hdr_match_table_size_get(unit, &table_size)); 570 571 if (sw_idx >= table_size) { 572 LOG_ERROR(BSL_LS_BCM_SWITCH, 573 (BSL_META_U(unit, 574 "Invalid sw_idx.\n"))); 575 return BCM_E_RESOURCE; 576 } 577 /* Delete the entry from CUSTOM_HEADER_MATCHm */ 578 rv = _bcm_custom_header_match_entry_delete(unit, hw_idx); 579 /* For cold boot case, delete return BCM_E_NOT_FOUND should be okay */ 580 if (rv == BCM_E_NOT_FOUND) { 581 return BCM_E_NONE; 582 } 583 BCM_IF_ERROR_RETURN(rv); 584 585 /* Clear the entry from CUSTOM_HEADER_POLICY_TABLEm */ 586 BCM_IF_ERROR_RETURN 587 (soc_mem_read(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ANY, 588 hw_idx, &policy_entry)); 589 soc_mem_field32_set(unit, CUSTOM_HEADER_POLICY_TABLEm, 590 &policy_entry, INT_PRIf, 0); 591 soc_mem_field32_set(unit, CUSTOM_HEADER_POLICY_TABLEm, 592 &policy_entry, CNGf, 0); 593 BCM_IF_ERROR_RETURN 594 (soc_mem_write(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ALL, 595 hw_idx, &policy_entry)); 596 597 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 598 return BCM_E_NONE; 599 } 600 601 /* 602 * Function: 603 * bcmi_hr3_miml_match_config_get 604 * Purpose: 605 * Get the match configuration from hardware 606 * Parameters: 607 * unit - (IN) Unit number 608 * sw_idx - (IN) SW memory index 609 * config_info - (OUT) Match configuration 610 * Returns: 611 * BCM_E_xxx 612 */ 613 STATIC int 614 bcmi_hr3_miml_match_config_get( 615 int unit, 616 uint32 sw_idx, 617 bcm_switch_match_config_info_t *config_info) 618 { 619 uint32 rval = 0; 620 uint32 table_size; 621 622 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 623 /* Parameter NULL error handling */ 624 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 625 626 BCM_IF_ERROR_RETURN 627 (bcmi_hr3_miml_match_table_size_get(unit, &table_size)); 628 629 if (sw_idx >= table_size) { 630 LOG_ERROR(BSL_LS_BCM_SWITCH, 631 (BSL_META_U(unit, 632 "Invalid sw_idx.\n"))); 633 return BCM_E_RESOURCE; 634 } 635 636 BCM_IF_ERROR_RETURN(READ_MIML_TPIDr(unit, &rval)); 637 config_info->outer_ethtype = 638 soc_reg_field_get(unit, MIML_TPIDr, rval, TPIDf); 639 640 BCM_IF_ERROR_RETURN(READ_MIML_ETYPEr(unit, &rval)); 641 config_info->inner_ethtype = 642 soc_reg_field_get(unit, MIML_ETYPEr, rval, ETYPEf); 643 644 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 645 return BCM_E_NONE; 646 } 647 648 /* 649 * Function: 650 * bcmi_hr3_custom_hdr_match_config_get 651 * Purpose: 652 * Get the match configuration from hardware 653 * Parameters: 654 * unit - (IN) Unit number 655 * sw_idx - (IN) SW memory index 656 * config_info - (OUT) Match configuration 657 * Returns: 658 * BCM_E_xxx 659 */ 660 STATIC int 661 bcmi_hr3_custom_hdr_match_config_get( 662 int unit, 663 uint32 sw_idx, 664 bcm_switch_match_config_info_t *config_info) 665 { 666 uint32 hw_idx = sw_idx; 667 custom_header_match_entry_t custom_hdr_entry; 668 custom_header_policy_table_entry_t policy_entry; 669 void *entries[1]; 670 uint32 hw_color; 671 uint32 table_size; 672 673 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 674 /* Parameter NULL error handling */ 675 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 676 677 BCM_IF_ERROR_RETURN 678 (bcmi_hr3_custom_hdr_match_table_size_get(unit, &table_size)); 679 680 if (sw_idx >= table_size) { 681 LOG_ERROR(BSL_LS_BCM_SWITCH, 682 (BSL_META_U(unit, 683 "Invalid sw_idx.\n"))); 684 return BCM_E_RESOURCE; 685 } 686 687 sal_memset(&custom_hdr_entry, 0, sizeof(custom_header_match_entry_t)); 688 sal_memset(&policy_entry, 0, sizeof(custom_header_policy_table_entry_t)); 689 690 /* Get the entry from CUSTOM_HEADER_MATCHm */ 691 entries[0] = &custom_hdr_entry; 692 BCM_IF_ERROR_RETURN 693 (_bcm_custom_header_match_entry_get(unit, hw_idx, 1, entries)); 694 695 config_info->value32 = soc_mem_field32_get(unit, 696 CUSTOM_HEADER_MATCHm, 697 &custom_hdr_entry, 698 CUSTOM_HEADERf); 699 700 /* Get PRI/CNG from CUSTOM_HEADER_POLICY_TABLEm */ 701 BCM_IF_ERROR_RETURN 702 (soc_mem_read(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ANY, 703 hw_idx, &policy_entry)); 704 config_info->int_pri = soc_mem_field32_get(unit, 705 CUSTOM_HEADER_POLICY_TABLEm, 706 &policy_entry, INT_PRIf); 707 hw_color = soc_mem_field32_get(unit, 708 CUSTOM_HEADER_POLICY_TABLEm, 709 &policy_entry, CNGf); 710 config_info->color = _BCM_COLOR_DECODING(unit, hw_color); 711 712 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 713 return BCM_E_NONE; 714 } 715 716 /* 717 * Function: 718 * bcmi_hr3_miml_match_config_set 719 * Purpose: 720 * Set the match configuration from hardware 721 * Parameters: 722 * unit - (IN) Unit number 723 * sw_idx - (IN) SW memory index 724 * config_info - (IN) Match configuration 725 * Returns: 726 * BCM_E_xxx 727 */ 728 STATIC int 729 bcmi_hr3_miml_match_config_set( 730 int unit, 731 uint32 sw_idx, 732 bcm_switch_match_config_info_t *config_info) 733 { 734 uint32 table_size; 735 736 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 737 /* Parameter NULL error handling */ 738 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 739 740 BCM_IF_ERROR_RETURN 741 (bcmi_hr3_miml_match_table_size_get(unit, &table_size)); 742 743 if (sw_idx >= table_size) { 744 LOG_ERROR(BSL_LS_BCM_SWITCH, 745 (BSL_META_U(unit, 746 "Invalid sw_idx.\n"))); 747 return BCM_E_RESOURCE; 748 } 749 750 if (config_info->outer_ethtype == 0 || 751 config_info->inner_ethtype == 0) { 752 return BCM_E_PARAM; 753 } 754 755 /* No sw_idx paramter since there is only one entry in HR3 miml */ 756 BCM_IF_ERROR_RETURN 757 (bcmi_hr3_miml_match_config_write(unit, 758 config_info)); 759 760 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 761 return BCM_E_NONE; 762 } 763 764 /* 765 * Function: 766 * bcmi_hr3_custom_hdr_match_config_set 767 * Purpose: 768 * Set the match configuration from hardware 769 * Parameters: 770 * unit - (IN) Unit number 771 * sw_idx - (IN) SW memory index 772 * config_info - (IN) Match configuration 773 * Returns: 774 * BCM_E_xxx 775 */ 776 STATIC int 777 bcmi_hr3_custom_hdr_match_config_set( 778 int unit, 779 uint32 sw_idx, 780 bcm_switch_match_config_info_t *config_info) 781 { 782 uint32 hw_idx = sw_idx; 783 custom_header_match_entry_t custom_hdr_entry; 784 custom_header_policy_table_entry_t policy_entry; 785 void *entries[1]; 786 uint32 table_size; 787 788 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 789 790 /* Parameter NULL error handling */ 791 HR3_MATCH_CHECK_NULL_PARAMETER(unit, config_info); 792 793 BCM_IF_ERROR_RETURN 794 (bcmi_hr3_custom_hdr_match_table_size_get(unit, &table_size)); 795 796 if (sw_idx >= table_size) { 797 LOG_ERROR(BSL_LS_BCM_SWITCH, 798 (BSL_META_U(unit, 799 "Invalid sw_idx.\n"))); 800 return BCM_E_RESOURCE; 801 } 802 803 sal_memset(&custom_hdr_entry, 0, sizeof(custom_header_match_entry_t)); 804 sal_memset(&policy_entry, 0, sizeof(custom_header_policy_table_entry_t)); 805 806 /* Set the entry to CUSTOM_HEADER_MATCHm */ 807 soc_mem_field32_set(unit, CUSTOM_HEADER_MATCHm, &custom_hdr_entry, 808 CUSTOM_HEADERf, config_info->value32); 809 soc_mem_field32_set(unit, CUSTOM_HEADER_MATCHm, &custom_hdr_entry, 810 VALIDf, 1); 811 entries[0] = &custom_hdr_entry; 812 BCM_IF_ERROR_RETURN 813 (_bcm_custom_header_match_entry_update(unit, entries, hw_idx)); 814 815 /* Set PRI/CNG to CUSTOM_HEADER_POLICY_TABLEm */ 816 BCM_IF_ERROR_RETURN 817 (soc_mem_read(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ANY, 818 hw_idx, &policy_entry)); 819 soc_mem_field32_set(unit, CUSTOM_HEADER_POLICY_TABLEm, 820 &policy_entry, INT_PRIf, config_info->int_pri); 821 soc_mem_field32_set(unit, CUSTOM_HEADER_POLICY_TABLEm, 822 &policy_entry, CNGf, 823 _BCM_COLOR_ENCODING(unit, config_info->color)); 824 BCM_IF_ERROR_RETURN 825 (soc_mem_write(unit, CUSTOM_HEADER_POLICY_TABLEm, MEM_BLOCK_ALL, 826 hw_idx, &policy_entry)); 827 828 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 829 return BCM_E_NONE; 830 } 831 832 833 /* 834 * Function: 835 * bcmi_hr3_miml_match_control_get 836 * Purpose: 837 * Get the match related control information with given control type. 838 * Parameters: 839 * unit - (IN) Unit number 840 * control_type - (IN) Match control type 841 * gport - (IN) gport number for port basis control. 842 * Otherwise, BCM_GPORT_INVALID. 843 * control_info - (OUT) Match control information 844 * Returns: 845 * BCM_E_xxx 846 */ 847 STATIC int 848 bcmi_hr3_miml_match_control_get( 849 int unit, 850 bcm_switch_match_control_type_t control_type, 851 bcm_gport_t gport, 852 bcm_switch_match_control_info_t *control_info) 853 { 854 int rv = BCM_E_UNAVAIL; 855 int val; 856 857 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 858 /* Parameter NULL error handling */ 859 HR3_MATCH_CHECK_NULL_PARAMETER(unit, control_info); 860 861 if (control_type == bcmSwitchMatchControlPortEnable) { 862 rv = _bcm_esw_port_tab_get(unit, gport, MIML_ENABLEf, &val); 863 864 if (BCM_SUCCESS(rv)) { 865 control_info->port_enable = val ? 1 : 0; 866 } 867 } 868 869 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 870 return rv; 871 } 872 873 /* 874 * Function: 875 * bcmi_hr3_custom_hdr_match_control_get 876 * Purpose: 877 * Get the match related control information with given control type. 878 * Parameters: 879 * unit - (IN) Unit number 880 * control_type - (IN) Match control type 881 * gport - (IN) gport number for port basis control. 882 * Otherwise, BCM_GPORT_INVALID. 883 * control_info - (OUT) Match control information 884 * Returns: 885 * BCM_E_xxx 886 */ 887 STATIC int 888 bcmi_hr3_custom_hdr_match_control_get( 889 int unit, 890 bcm_switch_match_control_type_t control_type, 891 bcm_gport_t gport, 892 bcm_switch_match_control_info_t *control_info) 893 { 894 int rv = BCM_E_UNAVAIL; 895 int fval = 0; 896 uint32 rval = 0; 897 898 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 899 900 /* Parameter NULL error handling */ 901 HR3_MATCH_CHECK_NULL_PARAMETER(unit, control_info); 902 903 if (control_type == bcmSwitchMatchControlPortEnable) { 904 rv = _bcm_esw_port_tab_get(unit, gport, CUSTOM_HEADER_ENABLEf, &fval); 905 906 if (BCM_SUCCESS(rv)) { 907 control_info->port_enable = fval ? 1 : 0; 908 } 909 } else if (control_type == bcmSwitchMatchControlMatchMask) { 910 rv = READ_CUSTOM_HEADER_MASKr(unit, &rval); 911 if (BCM_SUCCESS(rv)) { 912 control_info->mask32 = soc_reg_field_get(unit, CUSTOM_HEADER_MASKr, 913 rval, MASKf); 914 } 915 } 916 917 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 918 return rv; 919 } 920 921 /* 922 * Function: 923 * bcmi_hr3_miml_match_control_set 924 * Purpose: 925 * Set the match related control information with given control type. 926 * Parameters: 927 * unit - (IN) Unit number 928 * control_type - (IN) Match control type 929 * gport - (IN) gport number for port basis control. 930 * Otherwise, BCM_GPORT_INVALID. 931 * control_info - (IN) Match control information 932 * Returns: 933 * BCM_E_xxx 934 */ 935 STATIC int 936 bcmi_hr3_miml_match_control_set( 937 int unit, 938 bcm_switch_match_control_type_t control_type, 939 bcm_gport_t gport, 940 bcm_switch_match_control_info_t *control_info) 941 { 942 int rv = BCM_E_UNAVAIL; 943 944 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 945 /* Parameter NULL error handling */ 946 HR3_MATCH_CHECK_NULL_PARAMETER(unit, control_info); 947 948 if (control_type == bcmSwitchMatchControlPortEnable) { 949 rv = _bcm_esw_port_tab_set(unit, gport, 950 _BCM_CPU_TABS_ETHER, MIML_ENABLEf, 951 (control_info->port_enable) ? 1 : 0); 952 } 953 954 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 955 return rv; 956 } 957 958 /* 959 * Function: 960 * bcmi_hr3_custom_hdr_match_control_set 961 * Purpose: 962 * Set the match related control information with given control type. 963 * Parameters: 964 * unit - (IN) Unit number 965 * control_type - (IN) Match control type 966 * gport - (IN) gport number for port basis control. 967 * Otherwise, BCM_GPORT_INVALID. 968 * control_info - (IN) Match control information 969 * Returns: 970 * BCM_E_xxx 971 */ 972 int 973 bcmi_hr3_custom_hdr_match_control_set( 974 int unit, 975 bcm_switch_match_control_type_t control_type, 976 bcm_gport_t gport, 977 bcm_switch_match_control_info_t *control_info) 978 { 979 int rv = BCM_E_UNAVAIL; 980 uint32 rval = 0; 981 982 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 983 984 /* Parameter NULL error handling */ 985 HR3_MATCH_CHECK_NULL_PARAMETER(unit, control_info); 986 987 if (control_type == bcmSwitchMatchControlPortEnable) { 988 rv = _bcm_esw_port_tab_set(unit, gport, 989 _BCM_CPU_TABS_ETHER, CUSTOM_HEADER_ENABLEf, 990 (control_info->port_enable) ? 1 : 0); 991 } else if (control_type == bcmSwitchMatchControlMatchMask) { 992 BCM_IF_ERROR_RETURN(READ_CUSTOM_HEADER_MASKr(unit, &rval)); 993 soc_reg_field_set(unit, CUSTOM_HEADER_MASKr, &rval, 994 MASKf, control_info->mask32); 995 rv = WRITE_CUSTOM_HEADER_MASKr(unit, rval); 996 } 997 998 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 999 return rv; 1000 } 1001 1002 /* 1003 * Function: 1004 * bcmi_hr3_miml_match_wb_hw_existed 1005 * Purpose: 1006 * check if the HW existed value or not 1007 * Parameters: 1008 * unit - (IN) Unit being initialized 1009 * sw_idx - (IN) SW bookeeping memory index 1010 * Returns: 1011 * BCM_E_NOT_FOUND means HW doesn't exist 1012 * BCM_E_NONE means HW existed 1013 */ 1014 STATIC int 1015 bcmi_hr3_miml_match_wb_hw_existed( 1016 int unit, 1017 uint32 sw_idx) 1018 { 1019 #if defined(BCM_WARM_BOOT_SUPPORT) 1020 uint32 rval = 0; 1021 int outer_ethtype = 0, inner_ethtype = 0; 1022 uint32 table_size; 1023 #endif /* BCM_WARM_BOOT_SUPPORT */ 1024 1025 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 1026 #if defined(BCM_WARM_BOOT_SUPPORT) 1027 BCM_IF_ERROR_RETURN 1028 (bcmi_hr3_miml_match_table_size_get(unit, &table_size)); 1029 1030 if (sw_idx >= table_size) { 1031 LOG_ERROR(BSL_LS_BCM_SWITCH, 1032 (BSL_META_U(unit, 1033 "Invalid sw_idx.\n"))); 1034 return BCM_E_RESOURCE; 1035 } 1036 BCM_IF_ERROR_RETURN(READ_MIML_TPIDr(unit, &rval)); 1037 outer_ethtype = soc_reg_field_get(unit, MIML_TPIDr, rval, TPIDf); 1038 1039 BCM_IF_ERROR_RETURN(READ_MIML_ETYPEr(unit, &rval)); 1040 inner_ethtype = soc_reg_field_get(unit, MIML_ETYPEr, rval, ETYPEf); 1041 1042 if (outer_ethtype && inner_ethtype) { 1043 /* BCM_E_NONE means HW existed */ 1044 return BCM_E_NONE; 1045 } 1046 1047 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 1048 /* Return BCM_E_NOT_FOUND means HW doesn't exist */ 1049 return BCM_E_NOT_FOUND; 1050 #else /* BCM_WARM_BOOT_SUPPORT */ 1051 1052 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 1053 return BCM_E_UNAVAIL; 1054 #endif /* BCM_WARM_BOOT_SUPPORT */ 1055 } 1056 1057 /* 1058 * Function: 1059 * bcmi_hr3_custom_hdr_match_wb_hw_existed 1060 * Purpose: 1061 * check if the HW existed value or not 1062 * Parameters: 1063 * unit - (IN) Unit being initialized 1064 * sw_idx - (IN) SW memory index 1065 * Returns: 1066 * BCM_E_NOT_FOUND means HW doesn't exist 1067 * BCM_E_NONE means HW existed 1068 */ 1069 STATIC int 1070 bcmi_hr3_custom_hdr_match_wb_hw_existed( 1071 int unit, 1072 uint32 sw_idx) 1073 { 1074 #if defined(BCM_WARM_BOOT_SUPPORT) 1075 int is_valid = 0; 1076 custom_header_match_entry_t custom_hdr_entry; 1077 uint32 hw_idx = sw_idx; 1078 #endif /* BCM_WARM_BOOT_SUPPORT */ 1079 1080 HR3_MATCH_FUNCTION_TRACE(unit, "IN"); 1081 #if defined(BCM_WARM_BOOT_SUPPORT) 1082 sal_memset(&custom_hdr_entry, 0, sizeof(custom_header_match_entry_t)); 1083 1084 BCM_IF_ERROR_RETURN 1085 (soc_mem_read(unit, CUSTOM_HEADER_MATCHm, MEM_BLOCK_ANY, 1086 hw_idx, &custom_hdr_entry)); 1087 1088 is_valid = soc_mem_field32_get(unit, CUSTOM_HEADER_MATCHm, 1089 &custom_hdr_entry, VALIDf); 1090 if (is_valid) { 1091 _bcm_common_profile_mem_ref_cnt_update(unit, CUSTOM_HEADER_MATCHm, 1092 hw_idx, 1); 1093 /* BCM_E_NONE means HW existed */ 1094 return BCM_E_NONE; 1095 } 1096 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 1097 /* Return BCM_E_NOT_FOUND means HW doesn't exist */ 1098 return BCM_E_NOT_FOUND; 1099 #else /* BCM_WARM_BOOT_SUPPORT */ 1100 1101 HR3_MATCH_FUNCTION_TRACE(unit, "OUT"); 1102 return BCM_E_UNAVAIL; 1103 #endif /* BCM_WARM_BOOT_SUPPORT */ 1104 } 1105 1106 const bcmi_switch_match_service_info_t bcmi_hr3_miml_match_info = { 1107 "hr3_miml_match", /* table_name */ 1108 bcmi_hr3_miml_match_table_size_get, /* switch_match_table_size_get */ 1109 bcmi_hr3_miml_match_hw_idx_get, /* switch_match_hw_id_get */ 1110 bcmi_hr3_miml_match_sw_idx_get, /* switch_match_sw_idx_get */ 1111 bcmi_hr3_miml_match_wb_hw_existed, /* switch_match_wb_hw_existed */ 1112 bcmi_hr3_miml_match_config_add, /* switch_match_config_add */ 1113 bcmi_hr3_miml_match_config_delete, /* switch_match_config_delete */ 1114 bcmi_hr3_miml_match_config_get, /* switch_match_config_get */ 1115 bcmi_hr3_miml_match_config_set, /* switch_match_config_set */ 1116 bcmi_hr3_miml_match_control_get, /* switch_match_control_get */ 1117 bcmi_hr3_miml_match_control_set /* switch_match_control_set */ 1118 }; 1119 1120 const bcmi_switch_match_service_info_t bcmi_hr3_custom_hdr_match_info = { 1121 "hr3_custom_hdr_match", /* table_name */ 1122 bcmi_hr3_custom_hdr_match_table_size_get, /* switch_match_table_size_get */ 1123 bcmi_hr3_custom_hdr_match_hw_idx_get, /* switch_match_hw_id_get */ 1124 bcmi_hr3_custom_hdr_match_sw_idx_get, /* switch_match_sw_idx_get */ 1125 bcmi_hr3_custom_hdr_match_wb_hw_existed, /* switch_match_wb_hw_existed */ 1126 bcmi_hr3_custom_hdr_match_config_add, /* switch_match_config_add */ 1127 bcmi_hr3_custom_hdr_match_config_delete, /* switch_match_config_delete */ 1128 bcmi_hr3_custom_hdr_match_config_get, /* switch_match_config_get */ 1129 bcmi_hr3_custom_hdr_match_config_set, /* switch_match_config_set */ 1130 bcmi_hr3_custom_hdr_match_control_get, /* switch_match_control_get */ 1131 bcmi_hr3_custom_hdr_match_control_set /* switch_match_control_set */ 1132 }; 1133 1134 STATIC const bcmi_switch_match_dev_info_t bcmi_hr3_match_dev_info = { 1135 { /* service_info[bcmSwitchMatchService__Count] */ 1136 &bcmi_hr3_miml_match_info, /* Miml */ 1137 &bcmi_hr3_custom_hdr_match_info, /* Custom Header */ 1138 NULL, /* GTP */ 1139 NULL, /* HsrPrp */ 1140 NULL, /* Dot1cb */ 1141 NULL /* LinkLocal */ 1142 } 1143 }; 1144 1145 /* 1146 * Function: 1147 * bcmi_hr3_switch_match_info_init 1148 * Purpose: 1149 * Setup the chip specific info. 1150 * Parameters: 1151 * unit - (IN) Unit being initialized 1152 * devinfo - (OUT) device info structure. 1153 * Returns: 1154 * none 1155 */ 1156 int 1157 bcmi_hr3_switch_match_dev_info_init( 1158 int unit, 1159 const bcmi_switch_match_dev_info_t **dev_info) 1160 { 1161 if (dev_info == NULL) { 1162 return BCM_E_PARAM; 1163 } 1164 1165 /* Return the chip info structure */ 1166 *dev_info = &bcmi_hr3_match_dev_info; 1167 return BCM_E_NONE; 1168 } 1169 #endif /* BCM_HURRICANE3_SUPPORT */ 1170 #endif /* BCM_SWITCH_MATCH_SUPPORT */