switch_match.c (46774B)
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/greyhound2.h> 20 21 #if defined(BCM_SWITCH_MATCH_SUPPORT) 22 23 /* 24 * Switch Match id encoding: 25 * 4-bit bcm_switch_match_service_t (+encoding base) + 12-bit (reserved) 26 * + 16-bit sw_idx 27 */ 28 #define BCMI_MATCH_TYPE_ENCODING_BASE (1) 29 #define BCMI_MATCH_TYPE_SHIFT (28) 30 #define BCMI_MATCH_TYPE_MASK (0xF) 31 #define BCMI_MATCH_SW_IDX_MASK (0xFFFF) 32 33 /* 34 * Translate between Match_ID and sw_idx & Switch Match Type 35 * It represents the entry is used or not in intf_bitmap[match_service] 36 * with the MARCO MATCH_INTF_GET/SET/CLR 37 * Note: 38 * The sw_idx is not the hardware index of register/memory. 39 * There is a hw_idx which is mapping in the chip specific layer 40 * which is a real HW index 41 */ 42 #define MATCH_ID_TO_SW_IDX(_match_id_) \ 43 ((_match_id_) & BCMI_MATCH_SW_IDX_MASK) 44 45 #define SW_IDX_TO_MATCH_ID(_sw_idx_, _service_type_) \ 46 ((_sw_idx_) | \ 47 (_service_type_ + BCMI_MATCH_TYPE_ENCODING_BASE) << BCMI_MATCH_TYPE_SHIFT) 48 49 #define MATCH_TYPE_GET(_id_) \ 50 ((((_id_) >> BCMI_MATCH_TYPE_SHIFT) & BCMI_MATCH_TYPE_MASK) \ 51 - BCMI_MATCH_TYPE_ENCODING_BASE) 52 53 #define MATCH_ID_IS_TYPE(_id_, _service_type_) \ 54 (MATCH_TYPE_GET(_id_) == (_service_type_)) 55 56 /* 57 * Software book keeping for Switch Match related information 58 */ 59 typedef struct bcmi_match_bk_s { 60 SHR_BITDCL *intf_bitmap[bcmSwitchMatchService__Count]; 61 sal_mutex_t match_mutex; 62 int initialized; 63 /* Switch match service platform-specific information */ 64 const bcmi_switch_match_dev_info_t *dev_info; 65 } bcmi_match_bk_t; 66 67 STATIC bcmi_match_bk_t bcmi_match_bk_info[BCM_MAX_NUM_UNITS]; 68 69 /* Flag to check first initialized status */ 70 STATIC uint8 bcmi_match_initialized_bool = FALSE; 71 72 /* Switch match SW book keeping instance fetch/lock/unlock */ 73 #define MATCH_BK_INFO(_u_) (&bcmi_match_bk_info[(_u_)]) 74 75 #define MATCH_LOCK(_u_) \ 76 sal_mutex_take(MATCH_BK_INFO(_u_)->match_mutex, sal_mutex_FOREVER) 77 78 #define MATCH_UNLOCK(_u_) \ 79 sal_mutex_give(MATCH_BK_INFO(_u_)->match_mutex) 80 81 /* 82 * Switch match usage bitmap operations 83 */ 84 #define MATCH_INTF_GET(_u_, _intf_, _service_) \ 85 (SHR_BITGET(MATCH_BK_INFO(_u_)->intf_bitmap[(_service_)], (_intf_))) 86 #define MATCH_INTF_SET(_u_, _intf_, _service_) \ 87 (SHR_BITSET(MATCH_BK_INFO(_u_)->intf_bitmap[(_service_)], (_intf_))) 88 #define MATCH_INTF_CLR(_u_, _intf_, _service_) \ 89 (SHR_BITCLR(MATCH_BK_INFO(_u_)->intf_bitmap[(_service_)], (_intf_))) 90 91 #define MATCH_DEVICE_INFO(_u_, _service_) \ 92 bcmi_match_bk_info[(_u_)].dev_info->service_info[(_service_)] 93 94 #define MATCH_CHECK_INIT(_u_, _service_) \ 95 do { \ 96 if (((_u_) < 0) || ((_u_) >= BCM_MAX_NUM_UNITS)) { \ 97 return BCM_E_UNIT; \ 98 } \ 99 if (!soc_feature(unit, soc_feature_switch_match)) { \ 100 return BCM_E_UNAVAIL; \ 101 } \ 102 if (!bcmi_match_bk_info[(_u_)].initialized) { \ 103 LOG_ERROR(BSL_LS_BCM_SWITCH, \ 104 (BSL_META_U(unit, \ 105 "Switch Match Error:" \ 106 " not initialized\n"))); \ 107 return BCM_E_INIT; \ 108 } \ 109 if (!bcmi_match_bk_info[(_u_)].dev_info || \ 110 !bcmi_match_bk_info[(_u_)].dev_info->service_info[(_service_)]) { \ 111 LOG_ERROR(BSL_LS_BCM_SWITCH, \ 112 (BSL_META_U(unit, \ 113 "Switch Match Error:" \ 114 " not supported\n"))); \ 115 return BCM_E_UNAVAIL; \ 116 } \ 117 } while (0) 118 119 /* Parameter NULL error handling */ 120 #define MATCH_CHECK_NULL_PARAMETER(_u_, _parameter_) \ 121 do { \ 122 if (NULL == (_parameter_)) { \ 123 LOG_ERROR(BSL_LS_BCM_SWITCH, \ 124 (BSL_META_U((_u_), \ 125 "Error: NULL parameter\n"))); \ 126 return BCM_E_PARAM; \ 127 } \ 128 } while (0) 129 130 /* Device Information NULL error handling */ 131 #define MATCH_CHECK_NULL_DEV_INSTANCE(_u_, _instance_) \ 132 do { \ 133 if (NULL == (_instance_)) { \ 134 LOG_ERROR(BSL_LS_BCM_SWITCH, \ 135 (BSL_META_U((_u_), \ 136 "Error: NULL chip specific function \n"))); \ 137 return BCM_E_UNAVAIL; \ 138 } \ 139 } while (0) 140 141 /* Function Enter/Leave Tracing */ 142 #define MATCH_FUNCTION_TRACE(_u_, _str_) \ 143 do { \ 144 LOG_VERBOSE(BSL_LS_BCM_SWITCH, \ 145 (BSL_META_U((_u_), \ 146 "%s: " _str_ "\n"), __FUNCTION__)); \ 147 } while (0) 148 149 /* 150 * Function: 151 * bcmi_switch_match_dev_info_init 152 * Purpose: 153 * register switch match chip specific information 154 * Parameters: 155 * unit - (IN) Unit being initialized 156 * Returns: 157 * BCM_E_xxx 158 */ 159 STATIC int 160 bcmi_switch_match_dev_info_init(int unit) 161 { 162 bcm_error_t rv = BCM_E_UNAVAIL; 163 bcm_switch_match_service_t match_service; 164 165 MATCH_FUNCTION_TRACE(unit, "IN"); 166 167 /* Chip specific initialization */ 168 #if defined(BCM_HURRICANE3_SUPPORT) 169 if (SOC_IS_HURRICANE3(unit)) { 170 rv = bcmi_hr3_switch_match_dev_info_init(unit, 171 &(bcmi_match_bk_info[unit].dev_info)); 172 } else 173 #endif /* BCM_HURRICANE3_SUPPORT */ 174 #if defined(BCM_GREYHOUND2_SUPPORT) 175 if (SOC_IS_GREYHOUND2(unit)) { 176 rv = bcmi_gh2_switch_match_dev_info_init(unit, 177 &(bcmi_match_bk_info[unit].dev_info)); 178 } else 179 #endif /* BCM_GREYHOUND2_SUPPORT */ 180 { 181 return BCM_E_UNAVAIL; 182 } 183 184 if (BCM_FAILURE(rv) || NULL == bcmi_match_bk_info[unit].dev_info) { 185 /* No chip specific information initialized */ 186 LOG_WARN(BSL_LS_BCM_SWITCH, 187 (BSL_META_U(unit, 188 "Switch Match not supported:\n" 189 "dev_info_init failed.\n"))); 190 if (BCM_SUCCESS(rv)) { 191 return BCM_E_UNAVAIL; 192 } 193 return rv; 194 } 195 196 /* Check if MATCH_DEVICE_INFO(unit, match_service) are all NULL */ 197 for (match_service = bcmSwitchMatchServiceMiml; 198 match_service < bcmSwitchMatchService__Count; 199 match_service++) { 200 if (NULL != MATCH_DEVICE_INFO(unit, match_service)) { 201 /* Found instance */ 202 return BCM_E_NONE; 203 } 204 } 205 206 /* All MATCH_DEVICE_INFO(unit, match_service) are NULL */ 207 LOG_WARN(BSL_LS_BCM_SWITCH, 208 (BSL_META_U(unit, 209 "Switch Match not supported:\n" 210 "platform initialized, but none " 211 "Switch Match services are available.\n"))); 212 213 MATCH_FUNCTION_TRACE(unit, "OUT"); 214 return BCM_E_UNAVAIL; 215 } 216 217 /* 218 * Function: 219 * bcmi_switch_match_service_check 220 * Purpose: 221 * Check the supported match service. 222 * Parameters: 223 * unit - (IN) Unit number 224 * match_service - (IN) Match service type 225 * Returns: 226 * BCM_E_xxx 227 */ 228 STATIC int 229 bcmi_switch_match_service_check( 230 int unit, 231 bcm_switch_match_service_t match_service) 232 { 233 MATCH_FUNCTION_TRACE(unit, "IN"); 234 235 if (!((match_service >= bcmSwitchMatchServiceMiml) && 236 (match_service < bcmSwitchMatchService__Count))) { 237 LOG_WARN(BSL_LS_BCM_SWITCH, 238 (BSL_META_U(unit, 239 "Wrong Switch Match Service (%d)\n"), 240 match_service)); 241 return BCM_E_PARAM; 242 } 243 244 if ((match_service == bcmSwitchMatchServiceMiml) && 245 (soc_feature(unit, soc_feature_miml))) { 246 return BCM_E_NONE; 247 } 248 249 if ((match_service == bcmSwitchMatchServiceCustomHeader) && 250 (soc_feature(unit, soc_feature_custom_header))) { 251 return BCM_E_NONE; 252 } 253 254 if ((match_service == bcmSwitchMatchServicePrpHsrSupervision) && 255 ((soc_feature(unit, soc_feature_tsn_sr_hsr)) || 256 (soc_feature(unit, soc_feature_tsn_sr_prp)))) { 257 return BCM_E_NONE; 258 } 259 260 if ((match_service == bcmSwitchMatchServiceDot1cbSupervision) && 261 (soc_feature(unit, soc_feature_tsn_sr_802_1cb))) { 262 return BCM_E_NONE; 263 } 264 265 if ((match_service == bcmSwitchMatchServiceLinkLocal) && 266 (soc_feature(unit, soc_feature_tsn_sr))) { 267 return BCM_E_NONE; 268 } 269 270 LOG_WARN(BSL_LS_BCM_SWITCH, 271 (BSL_META_U(unit, 272 "Switch Match Service (%d) not supported\n"), 273 match_service)); 274 275 MATCH_FUNCTION_TRACE(unit, "OUT"); 276 return BCM_E_UNAVAIL; 277 } 278 279 /* 280 * Function: 281 * bcmi_switch_match_control_check 282 * Purpose: 283 * Check the supported match control type according to the match service. 284 * Parameters: 285 * unit - (IN) Unit number 286 * match_service - (IN) Match service type 287 * control_type - (IN) Match control type 288 * Returns: 289 * BCM_E_xxx 290 */ 291 STATIC int 292 bcmi_switch_match_control_check( 293 int unit, 294 bcm_switch_match_service_t match_service, 295 bcm_switch_match_control_type_t control_type) 296 { 297 MATCH_FUNCTION_TRACE(unit, "IN"); 298 299 /* Parameter validation check */ 300 BCM_IF_ERROR_RETURN 301 (bcmi_switch_match_service_check(unit, match_service)); 302 303 if (!((control_type >= bcmSwitchMatchControlPortEnable) && 304 (control_type < bcmSwitchMatchControl__Count))) { 305 LOG_WARN(BSL_LS_BCM_SWITCH, 306 (BSL_META_U(unit, 307 "Wrong Switch Match Service Control Type (%d)\n"), 308 control_type)); 309 return BCM_E_PARAM; 310 } 311 312 if (match_service == bcmSwitchMatchServiceMiml) { 313 if (control_type == bcmSwitchMatchControlPortEnable) { 314 return BCM_E_NONE; 315 } 316 } 317 318 if (match_service == bcmSwitchMatchServiceCustomHeader) { 319 if (control_type == bcmSwitchMatchControlPortEnable || 320 control_type == bcmSwitchMatchControlMatchMask) { 321 return BCM_E_NONE; 322 } 323 } 324 LOG_WARN(BSL_LS_BCM_SWITCH, 325 (BSL_META_U(unit, 326 "Wrong Switch Match Control\n"))); 327 328 MATCH_FUNCTION_TRACE(unit, "OUT"); 329 return BCM_E_UNAVAIL; 330 } 331 332 /* 333 * Function: 334 * bcmi_switch_match_id_check 335 * Purpose: 336 * Check match_id is valid 337 * Parameters: 338 * unit - (IN) Unit number 339 * match_service - (IN) Match service type 340 * match_id - (IN) Match ID 341 * Returns: 342 * BCM_E_xxx 343 */ 344 STATIC int 345 bcmi_switch_match_id_check( 346 int unit, 347 bcm_switch_match_service_t match_service, 348 int match_id) 349 { 350 bcm_error_t rv = BCM_E_NONE; 351 bcmi_match_bk_t *match_bk_info = NULL; 352 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 353 uint32 sw_idx = MATCH_ID_TO_SW_IDX(match_id); 354 uint32 table_size; 355 356 MATCH_FUNCTION_TRACE(unit, "IN"); 357 358 /* Parameter validation check */ 359 BCM_IF_ERROR_RETURN 360 (bcmi_switch_match_service_check(unit, match_service)); 361 362 /* Initialization check */ 363 MATCH_CHECK_INIT(unit, match_service); 364 365 if (!MATCH_ID_IS_TYPE(match_id, match_service)) { 366 LOG_ERROR(BSL_LS_BCM_SWITCH, 367 (BSL_META_U(unit, 368 "match_id(0x%x) doesn't match " 369 "SwitchMatchService(%d)\n"), 370 match_id, 371 match_service)); 372 return BCM_E_PARAM; 373 } 374 375 /* Get chip specific assignment & bookkeeping structure */ 376 match_bk_info = MATCH_BK_INFO(unit); 377 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 378 379 /* Check if the chip specific function existed */ 380 MATCH_CHECK_NULL_DEV_INSTANCE( 381 unit, sm_dev_info->switch_match_table_size_get); 382 383 rv = sm_dev_info->switch_match_table_size_get(unit, &table_size); 384 if (BCM_FAILURE(rv)) { 385 LOG_ERROR(BSL_LS_BCM_SWITCH, 386 (BSL_META_U(unit, 387 "Get table size failed(rv = %d)\n"), 388 rv)); 389 return rv; 390 } 391 392 /* Check if sw_idx excess the table size or not */ 393 if (sw_idx >= table_size) { 394 return BCM_E_PARAM; 395 } 396 397 /* Check if the valid bitmap is NULL or not */ 398 if (NULL == match_bk_info->intf_bitmap[match_service]) { 399 return BCM_E_UNAVAIL; 400 } 401 402 /* Check if the sw_idx is valid or not */ 403 if (!MATCH_INTF_GET(unit, sw_idx, match_service)) { 404 LOG_ERROR(BSL_LS_BCM_SWITCH, 405 (BSL_META_U(unit, 406 "HW resource (sw_idx:%d) doesn't exist.\n"), 407 sw_idx)); 408 return BCM_E_NOT_FOUND; 409 } 410 MATCH_FUNCTION_TRACE(unit, "OUT"); 411 return BCM_E_NONE; 412 } 413 414 /* 415 * Function: 416 * bcmi_switch_match_hw_id_get 417 * Purpose: 418 * Get HW memory index with given map_id 419 * Parameters: 420 * unit - (IN) Unit number 421 * match_id - (IN) Match ID 422 * match_service - (OUT) Match service type 423 * hw_id - (OUT) Priority Map Type 424 * Returns: 425 * BCM_E_xxx 426 */ 427 int 428 bcmi_switch_match_hw_id_get( 429 int unit, 430 int match_id, 431 bcm_switch_match_service_t *match_service, 432 uint32 *hw_id) 433 { 434 bcm_error_t rv = BCM_E_UNAVAIL; 435 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 436 uint32 sw_idx; 437 438 MATCH_FUNCTION_TRACE(unit, "IN"); 439 440 /* Parameter NULL error handling */ 441 MATCH_CHECK_NULL_PARAMETER(unit, match_service); 442 MATCH_CHECK_NULL_PARAMETER(unit, hw_id); 443 444 *match_service = MATCH_TYPE_GET(match_id); 445 446 /* Parameter validation check */ 447 BCM_IF_ERROR_RETURN 448 (bcmi_switch_match_service_check(unit, *match_service)); 449 450 /* Initialization check */ 451 MATCH_CHECK_INIT(unit, *match_service); 452 453 BCM_IF_ERROR_RETURN 454 (bcmi_switch_match_id_check(unit, *match_service, match_id)); 455 456 sw_idx = MATCH_ID_TO_SW_IDX(match_id); 457 458 sm_dev_info = MATCH_DEVICE_INFO(unit, *match_service); 459 460 /* Check if the chip specific function existed */ 461 MATCH_CHECK_NULL_DEV_INSTANCE( 462 unit, sm_dev_info->switch_match_hw_id_get); 463 464 rv = sm_dev_info->switch_match_hw_id_get(unit, sw_idx, hw_id); 465 if (BCM_FAILURE(rv)) { 466 LOG_ERROR(BSL_LS_BCM_TSN, 467 (BSL_META_U(unit, 468 "HW operation failed(rv = %d)\n"), 469 rv)); 470 return rv; 471 } 472 MATCH_FUNCTION_TRACE(unit, "OUT"); 473 return BCM_E_NONE; 474 } 475 476 /* 477 * Function: 478 * bcmi_switch_match_match_id_get 479 * Purpose: 480 * Get map_id with given HW memory index 481 * Parameters: 482 * unit - (IN) Unit number 483 * match_service - (IN) Priority Map Type 484 * hw_id - (IN) HW memory index 485 * match_id - (OUT) Match ID 486 * Returns: 487 * BCM_E_xxx 488 */ 489 int 490 bcmi_switch_match_match_id_get( 491 int unit, 492 bcm_switch_match_service_t match_service, 493 uint32 hw_id, 494 int *match_id) 495 { 496 bcm_error_t rv = BCM_E_UNAVAIL; 497 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 498 uint32 sw_idx; 499 500 MATCH_FUNCTION_TRACE(unit, "IN"); 501 502 /* Parameter NULL error handling */ 503 MATCH_CHECK_NULL_PARAMETER(unit, match_id); 504 505 /* Parameter validation check */ 506 BCM_IF_ERROR_RETURN 507 (bcmi_switch_match_service_check(unit, match_service)); 508 509 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 510 511 /* Check if the chip specific function existed */ 512 MATCH_CHECK_NULL_DEV_INSTANCE( 513 unit, sm_dev_info->switch_match_sw_idx_get); 514 515 rv = sm_dev_info->switch_match_sw_idx_get(unit, hw_id, &sw_idx); 516 if (BCM_FAILURE(rv)) { 517 LOG_ERROR(BSL_LS_BCM_TSN, 518 (BSL_META_U(unit, 519 "HW operation failed(rv = %d)\n"), 520 rv)); 521 return rv; 522 } 523 *match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service); 524 525 BCM_IF_ERROR_RETURN 526 (bcmi_switch_match_id_check(unit, match_service, *match_id)); 527 528 MATCH_FUNCTION_TRACE(unit, "OUT"); 529 return BCM_E_NONE; 530 } 531 532 /* 533 * Function: 534 * bcmi_switch_match_free_resources 535 * Purpose: 536 * Free match bookkeeping resources associated with a given unit. This 537 * happens either during an error initializing or during a detach operation. 538 * Parameters: 539 * unit - (IN) Unit number 540 * Returns: 541 * none 542 */ 543 STATIC void 544 bcmi_switch_match_free_resources(int unit) 545 { 546 bcmi_match_bk_t *match_bk_info = MATCH_BK_INFO(unit); 547 bcm_switch_match_service_t match_service; 548 549 MATCH_FUNCTION_TRACE(unit, "IN"); 550 for (match_service = bcmSwitchMatchServiceMiml; 551 match_service < bcmSwitchMatchService__Count; 552 match_service++) { 553 if (match_bk_info->intf_bitmap[match_service]) { 554 sal_free(match_bk_info->intf_bitmap[match_service]); 555 match_bk_info->intf_bitmap[match_service] = NULL; 556 } 557 } 558 559 if (match_bk_info->match_mutex) { 560 sal_mutex_destroy(match_bk_info->match_mutex); 561 match_bk_info->match_mutex = NULL; 562 } 563 MATCH_FUNCTION_TRACE(unit, "OUT"); 564 } 565 566 #ifdef BCM_WARM_BOOT_SUPPORT 567 568 /* 569 * Function: 570 * bcmi_switch_match_reinit 571 * Purpose: 572 * Re-initialize the resource. Restore bookkeeping information. 573 * Parameters: 574 * unit - (IN) Unit being initialized 575 * Returns: 576 * BCM_E_XXX 577 */ 578 STATIC int 579 bcmi_switch_match_reinit(int unit) 580 { 581 int rv = BCM_E_UNAVAIL; 582 uint32 table_size; 583 uint32 sw_idx; 584 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 585 bcm_switch_match_service_t match_service; 586 587 MATCH_FUNCTION_TRACE(unit, "IN"); 588 589 for (match_service = bcmSwitchMatchServiceMiml; 590 match_service < bcmSwitchMatchService__Count; 591 match_service++) { 592 593 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 594 595 if (NULL == sm_dev_info) { 596 /* Need to check all match_service */ 597 continue; 598 } 599 600 /* Check if the chip specific function existed */ 601 MATCH_CHECK_NULL_DEV_INSTANCE( 602 unit, sm_dev_info->switch_match_table_size_get); 603 MATCH_CHECK_NULL_DEV_INSTANCE( 604 unit, sm_dev_info->switch_match_wb_hw_existed); 605 606 rv = sm_dev_info->switch_match_table_size_get(unit, &table_size); 607 if (BCM_FAILURE(rv)) { 608 LOG_ERROR(BSL_LS_BCM_SWITCH, 609 (BSL_META_U(unit, 610 "Get table size failed(rv = %d)\n"), 611 rv)); 612 return rv; 613 } 614 615 /* Scan all sw_idx (0 ~ table_size) to check existed HW */ 616 for (sw_idx = 0; sw_idx < table_size; sw_idx++) { 617 MATCH_INTF_CLR(unit, sw_idx, match_service); 618 619 /* BCM_SUCCESS means HW(sw_idx) existed */ 620 rv = sm_dev_info->switch_match_wb_hw_existed(unit, sw_idx); 621 if (BCM_SUCCESS(rv)) { 622 MATCH_INTF_SET(unit, sw_idx, match_service); 623 } 624 } 625 } 626 MATCH_FUNCTION_TRACE(unit, "OUT"); 627 /* Return BCM_E_NONE means that WB successfully */ 628 return BCM_E_NONE; 629 } 630 #endif /* BCM_WARM_BOOT_SUPPORT */ 631 632 /* 633 * Function: 634 * bcmi_switch_match_coldboot_init 635 * Purpose: 636 * Reset the HW to default status 637 * Parameters: 638 * unit - (IN) unit number 639 * Returns: 640 * BCM_E_XXX 641 */ 642 STATIC int 643 bcmi_switch_match_coldboot_init(int unit) 644 { 645 bcm_error_t rv = BCM_E_UNAVAIL; 646 const bcmi_switch_match_service_info_t *sm_dev_info; 647 bcm_switch_match_service_t match_service; 648 uint32 table_size; 649 uint32 sw_idx; 650 651 #if defined(BCM_WARM_BOOT_SUPPORT) 652 /* Warm boot should be false in cold boot case */ 653 if (SOC_WARM_BOOT(unit)) { 654 return BCM_E_UNAVAIL; 655 } 656 #endif /* BCM_WARM_BOOT_SUPPORT */ 657 658 /* Reset all type to default value */ 659 for (match_service = bcmSwitchMatchServiceMiml; 660 match_service < bcmSwitchMatchService__Count; 661 match_service++) { 662 663 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 664 665 /* Check if the chip specific function existed */ 666 if (NULL == sm_dev_info) { 667 /* Maybe some chips only have some services */ 668 continue; 669 } 670 /* Check if the chip specific function existed */ 671 MATCH_CHECK_NULL_DEV_INSTANCE( 672 unit, sm_dev_info->switch_match_table_size_get); 673 MATCH_CHECK_NULL_DEV_INSTANCE( 674 unit, sm_dev_info->switch_match_config_delete); 675 676 rv = sm_dev_info->switch_match_table_size_get(unit, &table_size); 677 678 for (sw_idx = 0; 679 sw_idx < table_size; 680 sw_idx++) { 681 /* Use delete for reset HW to default value */ 682 rv = sm_dev_info->switch_match_config_delete(unit, sw_idx); 683 if (BCM_FAILURE(rv)) { 684 LOG_ERROR(BSL_LS_BCM_SWITCH, 685 (BSL_META_U(unit, 686 "coldboot fail(rv=%d) on " 687 "Switch Match Service(%d)\n"), 688 rv, 689 match_service)); 690 return rv; 691 } 692 } 693 } 694 695 return BCM_E_NONE; 696 } 697 698 /* 699 * Function: 700 * bcmi_switch_match_detach 701 * Purpose: 702 * Detach resource. Called when the module should de-initialize. 703 * Parameters: 704 * unit - (IN) Unit being detached. 705 * Returns: 706 * BCM_E_XXX 707 */ 708 int 709 bcmi_switch_match_detach(int unit) 710 { 711 MATCH_FUNCTION_TRACE(unit, "IN"); 712 if (bcmi_match_bk_info[unit].initialized) { 713 bcmi_switch_match_free_resources(unit); 714 bcmi_match_bk_info[unit].initialized = FALSE; 715 bcmi_match_bk_info[unit].dev_info = NULL; 716 } 717 MATCH_FUNCTION_TRACE(unit, "OUT"); 718 return BCM_E_NONE; 719 } 720 721 /* 722 * Function: 723 * bcmi_switch_match_init 724 * Purpose: 725 * Initialize the resource. Allocate bookkeeping information. 726 * Parameters: 727 * unit - (IN) Unit being initialized 728 * Returns: 729 * BCM_E_XXX 730 */ 731 int 732 bcmi_switch_match_init(int unit) 733 { 734 bcm_error_t rv = BCM_E_NONE; 735 bcmi_match_bk_t *match_bk_info = NULL; 736 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 737 int i; 738 uint32 table_size, shr_bitdcl_size; 739 bcm_switch_match_service_t match_service; 740 741 MATCH_FUNCTION_TRACE(unit, "IN"); 742 743 if (!soc_feature(unit, soc_feature_switch_match)) { 744 return BCM_E_UNAVAIL; 745 } 746 747 /* Check if leading bits is enough for identifying different types*/ 748 assert((1 << (32 - BCMI_MATCH_TYPE_SHIFT - 1)) >= bcmSwitchMatchService__Count); 749 750 /* Initial all unit with default value FALSE. */ 751 if (FALSE == bcmi_match_initialized_bool) { 752 for (i = 0; i < BCM_MAX_NUM_UNITS; i++) { 753 bcmi_match_bk_info[unit].initialized = FALSE; 754 bcmi_match_bk_info[unit].dev_info = NULL; 755 } 756 bcmi_match_initialized_bool = TRUE; 757 } 758 759 /* 760 * Check whether the unit is initialized or not 761 * if it's initialized, and then free resource for later initialization. 762 */ 763 BCM_IF_ERROR_RETURN 764 (bcmi_switch_match_detach(unit)); 765 766 /* Initialize platform-specific functions related information */ 767 BCM_IF_ERROR_RETURN 768 (bcmi_switch_match_dev_info_init(unit)); 769 770 /* Check if chip specific information is NULL or not */ 771 if (NULL == bcmi_match_bk_info[unit].dev_info) { 772 return BCM_E_UNAVAIL; 773 } 774 775 /* Get chip specific assignment & bookkeeping structure */ 776 match_bk_info = MATCH_BK_INFO(unit); 777 778 /* Create all match_id list */ 779 for (match_service = bcmSwitchMatchServiceMiml; 780 match_service < bcmSwitchMatchService__Count; 781 match_service++) { 782 783 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 784 785 /* Check if the chip specific function existed */ 786 if (NULL == sm_dev_info) { 787 /* Maybe some chips only have some services */ 788 continue; 789 } 790 791 /* Check if the chip specific function existed */ 792 MATCH_CHECK_NULL_DEV_INSTANCE( 793 unit, sm_dev_info->switch_match_table_size_get); 794 795 rv = sm_dev_info->switch_match_table_size_get(unit, &table_size); 796 if (BCM_FAILURE(rv) || !(table_size > 0)) { 797 LOG_ERROR(BSL_LS_BCM_SWITCH, 798 (BSL_META_U(unit, 799 "Get table size failed(rv = %d)\n"), 800 rv)); 801 /* Table size should > 0 */ 802 assert(table_size > 0); 803 return rv; 804 } 805 806 /* Allocate usage bitmap */ 807 shr_bitdcl_size = SHR_BITALLOCSIZE(table_size); 808 match_bk_info->intf_bitmap[match_service] = 809 sal_alloc(shr_bitdcl_size, "Switch Map Valid intf_bitmap"); 810 if (match_bk_info->intf_bitmap[match_service] == NULL) { 811 bcmi_switch_match_free_resources(unit); 812 return BCM_E_MEMORY; 813 } 814 sal_memset(match_bk_info->intf_bitmap[match_service], 815 0, shr_bitdcl_size); 816 } 817 818 /* Create mutex */ 819 match_bk_info->match_mutex = sal_mutex_create("switch_match.lock"); 820 if (match_bk_info->match_mutex == NULL) { 821 bcmi_switch_match_free_resources(unit); 822 return BCM_E_MEMORY; 823 } 824 825 #ifdef BCM_WARM_BOOT_SUPPORT 826 if (SOC_WARM_BOOT(unit)) { 827 /* Warm Boot recovery */ 828 rv = bcmi_switch_match_reinit(unit); 829 if (BCM_FAILURE(rv)) { 830 BCM_IF_ERROR_RETURN 831 (bcmi_switch_match_detach(unit)); 832 return rv; 833 } 834 } else 835 #endif /* BCM_WARM_BOOT_SUPPORT */ 836 { 837 /* Cold Boot */ 838 rv = bcmi_switch_match_coldboot_init(unit); 839 if (BCM_FAILURE(rv)) { 840 bcmi_switch_match_detach(unit); 841 LOG_ERROR(BSL_LS_BCM_SWITCH, 842 (BSL_META_U(unit, 843 "Cold boot failed" 844 "(rv = %d)\n"), 845 rv)); 846 return rv; 847 } 848 } 849 bcmi_match_bk_info[unit].initialized = TRUE; 850 851 MATCH_FUNCTION_TRACE(unit, "OUT"); 852 return BCM_E_NONE; 853 } 854 855 /* 856 * Function: 857 * bcmi_switch_match_config_add 858 * Purpose: 859 * Add a match config to hardware. 860 * Parameters: 861 * unit - (IN) Unit number 862 * match_service - (IN) Match service type 863 * config_info - (IN) Match configuration 864 * match_id - (OUT) Match ID 865 * Returns: 866 * BCM_E_xxx 867 */ 868 int 869 bcmi_switch_match_config_add( 870 int unit, 871 bcm_switch_match_service_t match_service, 872 bcm_switch_match_config_info_t *config_info, 873 int *match_id) 874 { 875 bcm_error_t rv = BCM_E_NONE; 876 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 877 uint32 sw_idx; 878 879 MATCH_FUNCTION_TRACE(unit, "IN"); 880 881 /* Parameter NULL error handling */ 882 MATCH_CHECK_NULL_PARAMETER(unit, config_info); 883 MATCH_CHECK_NULL_PARAMETER(unit, match_id); 884 885 /* Parameter validation check */ 886 BCM_IF_ERROR_RETURN 887 (bcmi_switch_match_service_check(unit, match_service)); 888 889 /* Initialization check */ 890 MATCH_CHECK_INIT(unit, match_service); 891 892 /* Get chip specific assignment & bookkeeping structure */ 893 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 894 895 /* Check if the chip specific function existed */ 896 MATCH_CHECK_NULL_DEV_INSTANCE( 897 unit, sm_dev_info->switch_match_table_size_get); 898 MATCH_CHECK_NULL_DEV_INSTANCE( 899 unit, sm_dev_info->switch_match_config_add); 900 901 MATCH_LOCK(unit); 902 903 /* Check if there is any empty sw_idx */ 904 rv = sm_dev_info->switch_match_config_add(unit, 905 config_info, 906 &sw_idx); 907 if (BCM_FAILURE(rv)) { 908 MATCH_UNLOCK(unit); 909 if (BCM_E_EXISTS == rv) { 910 *match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service); 911 return BCM_E_EXISTS; 912 } 913 LOG_ERROR(BSL_LS_BCM_SWITCH, 914 (BSL_META_U(unit, 915 "add to HW failed(rv = %d)\n"), 916 rv)); 917 return rv; 918 } 919 920 *match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service); 921 /* Set current sw_idx to valid */ 922 MATCH_INTF_SET(unit, sw_idx, match_service); 923 924 MATCH_UNLOCK(unit); 925 926 MATCH_FUNCTION_TRACE(unit, "OUT"); 927 return BCM_E_NONE; 928 } 929 930 /* 931 * Function: 932 * bcmi_switch_match_config_delete 933 * Purpose: 934 * Delete a match config with the given match_id by removing it from 935 * hardware and deleting the associated software state info. 936 * Parameters: 937 * unit - (IN) Unit number 938 * match_service - (IN) Match service type 939 * match_id - (IN) Match ID 940 * Returns: 941 * BCM_E_xxx 942 */ 943 int 944 bcmi_switch_match_config_delete( 945 int unit, 946 bcm_switch_match_service_t match_service, 947 int match_id) 948 { 949 int rv; 950 uint32 sw_idx = MATCH_ID_TO_SW_IDX(match_id); 951 const bcmi_switch_match_service_info_t *sm_dev_info; 952 953 MATCH_FUNCTION_TRACE(unit, "IN"); 954 955 /* Parameter validation check */ 956 BCM_IF_ERROR_RETURN 957 (bcmi_switch_match_service_check(unit, match_service)); 958 959 /* Initialization check */ 960 MATCH_CHECK_INIT(unit, match_service); 961 962 BCM_IF_ERROR_RETURN 963 (bcmi_switch_match_id_check(unit, match_service, match_id)); 964 965 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 966 967 /* Check if the chip specific function existed */ 968 MATCH_CHECK_NULL_DEV_INSTANCE( 969 unit, sm_dev_info->switch_match_config_delete); 970 971 MATCH_LOCK(unit); 972 rv = sm_dev_info->switch_match_config_delete(unit, 973 sw_idx); 974 if (BCM_FAILURE(rv)) { 975 MATCH_UNLOCK(unit); 976 LOG_ERROR(BSL_LS_BCM_SWITCH, 977 (BSL_META_U(unit, 978 "delete HW failed(rv = %d)\n"), 979 rv)); 980 return rv; 981 } 982 983 /* Clear the ID in software table */ 984 MATCH_INTF_CLR(unit, sw_idx, match_service); 985 986 MATCH_UNLOCK(unit); 987 MATCH_FUNCTION_TRACE(unit, "OUT"); 988 return BCM_E_NONE; 989 } 990 991 /* 992 * Function: 993 * bcmi_switch_match_config_delete_all 994 * Purpose: 995 * Delete all match config with the given match_service. 996 * Parameters: 997 * unit - (IN) Unit number 998 * match_service - (IN) Match service type 999 * Returns: 1000 * BCM_E_xxx 1001 */ 1002 int 1003 bcmi_switch_match_config_delete_all( 1004 int unit, 1005 bcm_switch_match_service_t match_service) 1006 { 1007 bcm_error_t rv = BCM_E_NONE; 1008 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 1009 uint32 table_size, sw_idx; 1010 1011 MATCH_FUNCTION_TRACE(unit, "IN"); 1012 1013 /* Parameter validation check */ 1014 BCM_IF_ERROR_RETURN 1015 (bcmi_switch_match_service_check(unit, match_service)); 1016 1017 /* Initialization check */ 1018 MATCH_CHECK_INIT(unit, match_service); 1019 1020 /* Get chip specific assignment & bookkeeping structure */ 1021 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 1022 1023 /* Check if the chip specific function existed */ 1024 MATCH_CHECK_NULL_DEV_INSTANCE( 1025 unit, sm_dev_info->switch_match_table_size_get); 1026 MATCH_CHECK_NULL_DEV_INSTANCE( 1027 unit, sm_dev_info->switch_match_config_delete); 1028 1029 rv = sm_dev_info->switch_match_table_size_get(unit, &table_size); 1030 if (BCM_FAILURE(rv)) { 1031 LOG_ERROR(BSL_LS_BCM_SWITCH, 1032 (BSL_META_U(unit, 1033 "Get table size failed(rv = %d)\n"), 1034 rv)); 1035 return rv; 1036 } 1037 1038 MATCH_LOCK(unit); 1039 1040 for (sw_idx = 0; sw_idx < table_size; sw_idx++) { 1041 if (MATCH_INTF_GET(unit, sw_idx, match_service)) { 1042 1043 rv = sm_dev_info->switch_match_config_delete(unit, 1044 sw_idx); 1045 if (BCM_FAILURE(rv)) { 1046 MATCH_UNLOCK(unit); 1047 LOG_ERROR(BSL_LS_BCM_SWITCH, 1048 (BSL_META_U(unit, 1049 "Delete HW failed(rv = %d)\n"), 1050 rv)); 1051 return rv; 1052 } 1053 1054 /* Clear the ID in software table */ 1055 MATCH_INTF_CLR(unit, sw_idx, match_service); 1056 } 1057 } 1058 1059 MATCH_UNLOCK(unit); 1060 MATCH_FUNCTION_TRACE(unit, "OUT"); 1061 return BCM_E_NONE; 1062 } 1063 1064 /* 1065 * Function: 1066 * bcmi_switch_match_config_get 1067 * Purpose: 1068 * Get the configuration of the match with the given match_id. 1069 * Parameters: 1070 * unit - (IN) Unit number 1071 * match_service - (IN) Match service type 1072 * match_id - (IN) Match ID 1073 * config_info - (OUT) Match configuration 1074 * Returns: 1075 * BCM_E_xxx 1076 */ 1077 int 1078 bcmi_switch_match_config_get( 1079 int unit, 1080 bcm_switch_match_service_t match_service, 1081 int match_id, 1082 bcm_switch_match_config_info_t *config_info) 1083 { 1084 int rv; 1085 const bcmi_switch_match_service_info_t *sm_dev_info; 1086 uint32 sw_idx; 1087 1088 MATCH_FUNCTION_TRACE(unit, "IN"); 1089 1090 /* Parameter NULL error handling */ 1091 MATCH_CHECK_NULL_PARAMETER(unit, config_info); 1092 1093 /* Parameter validation check */ 1094 BCM_IF_ERROR_RETURN 1095 (bcmi_switch_match_service_check(unit, match_service)); 1096 1097 /* Initialization check */ 1098 MATCH_CHECK_INIT(unit, match_service); 1099 1100 BCM_IF_ERROR_RETURN 1101 (bcmi_switch_match_id_check(unit, match_service, match_id)); 1102 1103 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 1104 1105 /* Check if the chip specific function existed */ 1106 MATCH_CHECK_NULL_DEV_INSTANCE( 1107 unit, sm_dev_info->switch_match_config_get); 1108 1109 sw_idx = MATCH_ID_TO_SW_IDX(match_id); 1110 1111 bcm_switch_match_config_info_t_init(config_info); 1112 1113 MATCH_LOCK(unit); 1114 rv = sm_dev_info->switch_match_config_get(unit, 1115 sw_idx, 1116 config_info); 1117 if (BCM_FAILURE(rv)) { 1118 MATCH_UNLOCK(unit); 1119 LOG_ERROR(BSL_LS_BCM_SWITCH, 1120 (BSL_META_U(unit, 1121 "Read from HW failed(rv = %d)\n"), 1122 rv)); 1123 return rv; 1124 } 1125 1126 MATCH_UNLOCK(unit); 1127 MATCH_FUNCTION_TRACE(unit, "OUT"); 1128 return BCM_E_NONE; 1129 } 1130 1131 /* 1132 * Function: 1133 * bcmi_switch_match_config_set 1134 * Purpose: 1135 * Set the configuration of the match with the given match_id. 1136 * Parameters: 1137 * unit - (IN) Unit number 1138 * match_service - (IN) Match service type 1139 * match_id - (IN) Match ID 1140 * config_info - (IN) Match configuration 1141 * Returns: 1142 * BCM_E_xxx 1143 */ 1144 int 1145 bcmi_switch_match_config_set( 1146 int unit, 1147 bcm_switch_match_service_t match_service, 1148 int match_id, 1149 bcm_switch_match_config_info_t *config_info) 1150 { 1151 int rv; 1152 const bcmi_switch_match_service_info_t *sm_dev_info; 1153 uint32 sw_idx; 1154 1155 MATCH_FUNCTION_TRACE(unit, "IN"); 1156 1157 /* Parameter NULL error handling */ 1158 MATCH_CHECK_NULL_PARAMETER(unit, config_info); 1159 1160 /* Parameter validation check */ 1161 BCM_IF_ERROR_RETURN 1162 (bcmi_switch_match_service_check(unit, match_service)); 1163 1164 /* Initialization check */ 1165 MATCH_CHECK_INIT(unit, match_service); 1166 1167 BCM_IF_ERROR_RETURN 1168 (bcmi_switch_match_id_check(unit, match_service, match_id)); 1169 1170 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 1171 1172 /* Check if the chip specific function existed */ 1173 MATCH_CHECK_NULL_DEV_INSTANCE( 1174 unit, sm_dev_info->switch_match_config_set); 1175 1176 sw_idx = MATCH_ID_TO_SW_IDX(match_id); 1177 1178 MATCH_LOCK(unit); 1179 rv = sm_dev_info->switch_match_config_set(unit, 1180 sw_idx, 1181 config_info); 1182 if (BCM_FAILURE(rv)) { 1183 MATCH_UNLOCK(unit); 1184 LOG_ERROR(BSL_LS_BCM_SWITCH, 1185 (BSL_META_U(unit, 1186 "Write to HW failed(rv = %d)\n"), 1187 rv)); 1188 return rv; 1189 } 1190 1191 MATCH_UNLOCK(unit); 1192 MATCH_FUNCTION_TRACE(unit, "OUT"); 1193 return BCM_E_NONE; 1194 } 1195 1196 1197 /* 1198 * Function: 1199 * bcmi_switch_match_config_traverse 1200 * Purpose: 1201 * Traverse the created match config. 1202 * Parameters: 1203 * unit - (IN) Unit number 1204 * match_service - (IN) Match service type 1205 * cb_fn - (IN) Traverse call back function 1206 * user_data - (IN) User data 1207 * Returns: 1208 * BCM_E_xxx 1209 */ 1210 int 1211 bcmi_switch_match_config_traverse( 1212 int unit, 1213 bcm_switch_match_service_t match_service, 1214 bcm_switch_match_config_traverse_cb cb_fn, 1215 void *user_data) 1216 { 1217 bcm_error_t rv = BCM_E_NONE; 1218 const bcmi_switch_match_service_info_t *sm_dev_info = NULL; 1219 int sw_idx = 0; 1220 int match_id; 1221 uint32 table_size; 1222 bcm_switch_match_config_info_t match_config; 1223 1224 MATCH_FUNCTION_TRACE(unit, "IN"); 1225 1226 /* Parameter NULL error handling */ 1227 MATCH_CHECK_NULL_PARAMETER(unit, cb_fn); 1228 1229 /* Parameter validation check */ 1230 BCM_IF_ERROR_RETURN 1231 (bcmi_switch_match_service_check(unit, match_service)); 1232 1233 /* Initialization check */ 1234 MATCH_CHECK_INIT(unit, match_service); 1235 1236 /* Get chip specific assignment & bookkeeping structure */ 1237 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 1238 1239 1240 /* Check if the chip specific function existed */ 1241 MATCH_CHECK_NULL_DEV_INSTANCE( 1242 unit, sm_dev_info->switch_match_table_size_get); 1243 1244 rv = sm_dev_info->switch_match_table_size_get(unit, &table_size); 1245 if (BCM_FAILURE(rv)) { 1246 LOG_ERROR(BSL_LS_BCM_SWITCH, 1247 (BSL_META_U(unit, 1248 "Get table size failed(rv = %d)\n"), 1249 rv)); 1250 return rv; 1251 } 1252 1253 MATCH_LOCK(unit); 1254 1255 for (sw_idx = 0; sw_idx < table_size; sw_idx++) { 1256 if (MATCH_INTF_GET(unit, sw_idx, match_service)) { 1257 match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service); 1258 /* Reset the config */ 1259 bcm_switch_match_config_info_t_init(&match_config); 1260 1261 /* Get the config */ 1262 rv = bcmi_switch_match_config_get(unit, 1263 match_service, 1264 match_id, 1265 &match_config); 1266 1267 /* Doing the user cb function with config */ 1268 if (BCM_SUCCESS(rv)) { 1269 rv = cb_fn(unit, match_id, &match_config, user_data); 1270 if (BCM_FAILURE(rv)) { 1271 MATCH_UNLOCK(unit); 1272 return rv; 1273 } 1274 } 1275 } 1276 } 1277 MATCH_UNLOCK(unit); 1278 MATCH_FUNCTION_TRACE(unit, "OUT"); 1279 return BCM_E_NONE; 1280 } 1281 1282 /* 1283 * Function: 1284 * bcmi_switch_match_control_get 1285 * Purpose: 1286 * Get the match related control information with given control service 1287 * and type. 1288 * Parameters: 1289 * unit - (IN) Unit number 1290 * match_service - (IN) Match service type 1291 * control_type - (IN) Match control type 1292 * gport - (IN) gport number for port basis control. 1293 * Otherwise, BCM_GPORT_INVALID. 1294 * control_info - (OUT) Match control information 1295 * Returns: 1296 * BCM_E_xxx 1297 */ 1298 int 1299 bcmi_switch_match_control_get( 1300 int unit, 1301 bcm_switch_match_service_t match_service, 1302 bcm_switch_match_control_type_t control_type, 1303 bcm_gport_t gport, 1304 bcm_switch_match_control_info_t *control_info) 1305 { 1306 int rv; 1307 const bcmi_switch_match_service_info_t *sm_dev_info; 1308 1309 MATCH_FUNCTION_TRACE(unit, "IN"); 1310 1311 /* Parameter NULL error handling */ 1312 MATCH_CHECK_NULL_PARAMETER(unit, control_info); 1313 1314 /* Parameter validation check */ 1315 BCM_IF_ERROR_RETURN 1316 (bcmi_switch_match_control_check(unit, match_service, control_type)); 1317 1318 /* Initialization check */ 1319 MATCH_CHECK_INIT(unit, match_service); 1320 1321 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 1322 1323 1324 /* Check if the chip specific function existed */ 1325 MATCH_CHECK_NULL_DEV_INSTANCE( 1326 unit, sm_dev_info->switch_match_control_get); 1327 1328 MATCH_LOCK(unit); 1329 bcm_switch_match_control_info_t_init(control_info); 1330 rv = sm_dev_info->switch_match_control_get(unit, 1331 control_type, 1332 gport, 1333 control_info); 1334 if (BCM_FAILURE(rv)) { 1335 MATCH_UNLOCK(unit); 1336 LOG_ERROR(BSL_LS_BCM_SWITCH, 1337 (BSL_META_U(unit, 1338 "Read from HW failed(rv = %d)\n"), 1339 rv)); 1340 return rv; 1341 } 1342 MATCH_UNLOCK(unit); 1343 MATCH_FUNCTION_TRACE(unit, "OUT"); 1344 return BCM_E_NONE; 1345 } 1346 1347 /* 1348 * Function: 1349 * bcmi_switch_match_control_set 1350 * Purpose: 1351 * Set the match related control information with given control type. 1352 * Parameters: 1353 * unit - (IN) Unit number 1354 * match_service - (IN) Match service type 1355 * control_type - (IN) Match control type 1356 * gport - (IN) gport number for port basis control. 1357 * Otherwise, BCM_GPORT_INVALID. 1358 * control_info - (IN) Match control information 1359 * Returns: 1360 * BCM_E_xxx 1361 */ 1362 int 1363 bcmi_switch_match_control_set( 1364 int unit, 1365 bcm_switch_match_service_t match_service, 1366 bcm_switch_match_control_type_t control_type, 1367 bcm_gport_t gport, 1368 bcm_switch_match_control_info_t *control_info) 1369 { 1370 int rv; 1371 const bcmi_switch_match_service_info_t *sm_dev_info; 1372 1373 MATCH_FUNCTION_TRACE(unit, "IN"); 1374 1375 /* Parameter NULL error handling */ 1376 MATCH_CHECK_NULL_PARAMETER(unit, control_info); 1377 1378 /* Parameter validation check */ 1379 BCM_IF_ERROR_RETURN 1380 (bcmi_switch_match_control_check(unit, match_service, control_type)); 1381 1382 /* Initialization check */ 1383 MATCH_CHECK_INIT(unit, match_service); 1384 1385 sm_dev_info = MATCH_DEVICE_INFO(unit, match_service); 1386 1387 /* Check if the chip specific function existed */ 1388 MATCH_CHECK_NULL_DEV_INSTANCE( 1389 unit, sm_dev_info->switch_match_control_set); 1390 1391 MATCH_LOCK(unit); 1392 rv = sm_dev_info->switch_match_control_set(unit, 1393 control_type, 1394 gport, 1395 control_info); 1396 if (BCM_FAILURE(rv)) { 1397 MATCH_UNLOCK(unit); 1398 LOG_ERROR(BSL_LS_BCM_SWITCH, 1399 (BSL_META_U(unit, 1400 "Write to HW failed(rv = %d)\n"), 1401 rv)); 1402 return rv; 1403 } 1404 MATCH_UNLOCK(unit); 1405 MATCH_FUNCTION_TRACE(unit, "OUT"); 1406 return BCM_E_NONE; 1407 } 1408 1409 /* 1410 * Function: 1411 * bcmi_switch_match_control_traverse 1412 * Purpose: 1413 * Traverse the match control information. 1414 * Parameters: 1415 * unit - (IN) Unit number 1416 * match_service - (IN) Match service type 1417 * cb_fn - (IN) Traverse call back function 1418 * user_data - (IN) User data 1419 * Returns: 1420 * BCM_E_xxx 1421 */ 1422 int 1423 bcmi_switch_match_control_traverse( 1424 int unit, 1425 bcm_switch_match_service_t match_service, 1426 bcm_switch_match_control_traverse_cb cb_fn, 1427 void *user_data) 1428 { 1429 bcm_error_t rv = BCM_E_NONE; 1430 bcm_port_t port; 1431 bcm_switch_match_control_info_t match_ctrl; 1432 1433 MATCH_FUNCTION_TRACE(unit, "IN"); 1434 1435 /* Parameter NULL error handling */ 1436 MATCH_CHECK_NULL_PARAMETER(unit, cb_fn); 1437 1438 /* Parameter validation check */ 1439 BCM_IF_ERROR_RETURN 1440 (bcmi_switch_match_service_check(unit, match_service)); 1441 1442 /* Initialization check */ 1443 MATCH_CHECK_INIT(unit, match_service); 1444 1445 MATCH_LOCK(unit); 1446 1447 if (match_service == bcmSwitchMatchServiceMiml || 1448 match_service == bcmSwitchMatchServiceCustomHeader) { 1449 /* Traverse all logical port with bcmSwitchMatchControlPortEnable */ 1450 PBMP_ALL_ITER(unit, port) { 1451 bcm_switch_match_control_info_t_init(&match_ctrl); 1452 1453 rv = bcmi_switch_match_control_get(unit, 1454 match_service, 1455 bcmSwitchMatchControlPortEnable, 1456 port, 1457 &match_ctrl); 1458 if (BCM_SUCCESS(rv)) { 1459 rv = cb_fn(unit, 1460 bcmSwitchMatchControlPortEnable, 1461 port, 1462 &match_ctrl, user_data); 1463 if (BCM_FAILURE(rv)) { 1464 MATCH_UNLOCK(unit); 1465 return rv; 1466 } 1467 } 1468 } 1469 } 1470 1471 if (match_service == bcmSwitchMatchServiceCustomHeader) { 1472 1473 /* Traverse bcmSwitchMatchControlMatchMask */ 1474 bcm_switch_match_control_info_t_init(&match_ctrl); 1475 rv = bcmi_switch_match_control_get(unit, 1476 match_service, 1477 bcmSwitchMatchControlMatchMask, 1478 BCM_GPORT_INVALID, 1479 &match_ctrl); 1480 if (BCM_SUCCESS(rv)) { 1481 rv = cb_fn(unit, 1482 bcmSwitchMatchControlMatchMask, 1483 BCM_GPORT_INVALID, 1484 &match_ctrl, 1485 user_data); 1486 if (BCM_FAILURE(rv)) { 1487 MATCH_UNLOCK(unit); 1488 return rv; 1489 } 1490 } 1491 } 1492 MATCH_UNLOCK(unit); 1493 MATCH_FUNCTION_TRACE(unit, "OUT"); 1494 return BCM_E_NONE; 1495 } 1496 #endif /* BCM_SWITCH_MATCH_SUPPORT */ 1497