vlan.c (61086B)
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 * File: vlan.c 8 * Purpose: Provide low-level access to Tomahawk3 VLAN resources 9 */ 10 #if defined(BCM_TOMAHAWK3_SUPPORT) 11 #include <soc/drv.h> 12 #include <soc/mem.h> 13 #include <soc/profile_mem.h> 14 #include <bcm/error.h> 15 16 #include <bcm_int/esw/mbcm.h> 17 #include <bcm_int/esw/vlan.h> 18 #include <bcm_int/esw/port.h> 19 #include <bcm_int/esw/trx.h> 20 #ifdef BCM_TRX_SUPPORT 21 #include <bcm_int/esw/triumph.h> 22 #endif 23 #include <bcm_int/esw/tomahawk3.h> 24 #include <bcm_int/esw/firebolt.h> 25 26 /* VLAN Cross Connect DB declaraions/definitions */ 27 typedef struct _bcm_th3_vlan_xconnect_db_s { 28 SHR_BITDCL valid[_SHR_BITDCLSIZE(BCM_VLAN_COUNT)]; /* Valid bitmap */ 29 SHR_BITDCL dest_type[_SHR_BITDCLSIZE(BCM_VLAN_COUNT*2)]; /* TGID/Port */ 30 uint8 destination[BCM_VLAN_COUNT*2]; /* Trunk/Port ID */ 31 } _bcm_th3_vlan_xconnect_db_t; 32 33 static 34 _bcm_th3_vlan_xconnect_db_t *_bcm_th3_xconnect_db[BCM_MAX_NUM_UNITS]= {0}; 35 36 #define BCM_TH3_VLAN_XC_DB_DESTTYPE_OFFSET(_ovid_) ((_ovid_) * 2) 37 #define BCM_TH3_VLAN_XC_DB_DESTTYPE1_OFFSET(_ovid_) (((_ovid_) * 2) + 1) 38 39 /* VLAN Cross Connect Mutex defintion/macros */ 40 sal_mutex_t _bcm_th3_xconnect_mtx[BCM_MAX_NUM_UNITS] = {0}; 41 42 #define BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(_unit_) \ 43 sal_mutex_take(_bcm_th3_xconnect_mtx[(_unit_)], sal_mutex_FOREVER); 44 45 #define BCM_TH3_VLAN_XCONNECT_MUTEX_REL(_unit_) \ 46 sal_mutex_give(_bcm_th3_xconnect_mtx[(_unit_)]); 47 48 #define ING_ACTION_PROFILE_DEFAULT 0 49 /* Cache of Ingress Vlan Translate Action Profile Table */ 50 static soc_profile_mem_t *ing_action_profile[BCM_MAX_NUM_UNITS] = {NULL}; 51 52 /* Cache of Egress Vlan Translate Action Profile Table */ 53 static soc_profile_mem_t *egr_action_profile[BCM_MAX_NUM_UNITS] = {NULL}; 54 55 /* Cache of VLAN Port Bitmap Profile Table */ 56 static soc_profile_mem_t *vlan_pbmp_profile[BCM_MAX_NUM_UNITS] = {NULL}; 57 58 /* 59 * Function: 60 * _bcm_th3_vlan_pbmp_profile_init 61 * 62 * Purpose: 63 * to initialize hardware PORT_BITMAP_PROFILE table 64 * and allocate memory to cache hardware tables in RAM. 65 * 66 * Parameters: 67 * unit - (IN) Device Number 68 * 69 * Returns: 70 * BCM_E_XXX 71 * 72 * Notes: 73 * Allocate memory to cache the profile tables and initialize. 74 * If memory to cache the profile table is already allocated, 75 * just initialize the table. 76 */ 77 int 78 _bcm_th3_vlan_pbmp_profile_init(int unit) { 79 80 uint32 profile_idx; 81 soc_mem_t mem; 82 int entry_dwords; 83 bcm_pbmp_t pbmp; 84 #if defined(BCM_WARM_BOOT_SUPPORT) 85 int mem_idx; 86 vlan_2_tab_entry_t vlan_2_entry; 87 const int mem_entry_cnt = soc_mem_index_count(unit, VLAN_2_TABm); 88 #endif /* BCM_WARM_BOOT_SUPPORT */ 89 90 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 91 return BCM_E_UNAVAIL; 92 } 93 94 /* Initialize the PORT_BITMAP_PROFILE table */ 95 if (NULL == vlan_pbmp_profile[unit]) { 96 vlan_pbmp_profile[unit] = 97 sal_alloc(sizeof(soc_profile_mem_t), "VLAN PBMP Profile"); 98 if (NULL == vlan_pbmp_profile[unit]) { 99 return BCM_E_MEMORY; 100 } 101 soc_profile_mem_t_init(vlan_pbmp_profile[unit]); 102 } 103 104 /* Create profile table cache( or re-init if it already exists */ 105 mem = PORT_BITMAP_PROFILEm; 106 entry_dwords = sizeof(port_bitmap_profile_entry_t) / sizeof(uint32); 107 108 SOC_IF_ERROR_RETURN( 109 soc_profile_mem_create( 110 unit, &mem, &entry_dwords, 1, vlan_pbmp_profile[unit])); 111 112 /* Create a default entry with empty port bitmap */ 113 SOC_PBMP_CLEAR(pbmp); 114 _bcm_th3_vlan_pbmp_profile_entry_add(unit, pbmp, &profile_idx); 115 116 #if defined(BCM_WARM_BOOT_SUPPORT) 117 if (SOC_WARM_BOOT(unit)) { 118 /* Sync the SW profile data structure with actual indexes is use */ 119 for (mem_idx = 0 ; mem_idx < mem_entry_cnt ; mem_idx++) { 120 121 SOC_IF_ERROR_RETURN( 122 READ_VLAN_2_TABm(unit, MEM_BLOCK_ANY, mem_idx, &vlan_2_entry)); 123 124 if (soc_mem_field32_get(unit, VLAN_2_TABm, &vlan_2_entry, VALIDf)) { 125 profile_idx = soc_mem_field32_get( 126 unit, VLAN_2_TABm, &vlan_2_entry, PORT_BITMAP_PROFILE_PTRf); 127 SOC_PROFILE_MEM_REFERENCE( 128 unit, vlan_pbmp_profile[unit], profile_idx, 1); 129 SOC_PROFILE_MEM_ENTRIES_PER_SET( 130 unit, vlan_pbmp_profile[unit], profile_idx, 1); 131 } 132 } 133 } 134 #endif /* BCM_WARM_BOOT_SUPPORT */ 135 return BCM_E_NONE; 136 } 137 138 /* 139 * Function: 140 * _bcm_th3_vlan_pbmp_profile_destroy 141 * 142 * Purpose: 143 * to deinitialize hardware PORT_BITMAP_PROFILE and 144 * deallocate cached RAM memory for the hardware table. 145 * 146 * Parameters: 147 * unit - (IN) Device Number 148 * 149 * Returns: 150 * BCM_E_FAIL 151 * BCM_E_NONE 152 * 153 * Notes: 154 */ 155 int 156 _bcm_th3_vlan_pbmp_profile_destroy(int unit) { 157 int rv; 158 159 if (vlan_pbmp_profile[unit]) { 160 rv = soc_profile_mem_destroy(unit, vlan_pbmp_profile[unit]); 161 if (BCM_FAILURE(rv)) { 162 return BCM_E_FAIL; 163 } 164 165 sal_free(vlan_pbmp_profile[unit]); 166 vlan_pbmp_profile[unit] = NULL; 167 } 168 169 return BCM_E_NONE; 170 } 171 172 /* 173 * Function: 174 * _bcm_th3_vlan_pbmp_profile_entry_add 175 * 176 * Purpose: 177 * add a new entry to PORT_BITMAP_PROFILE table 178 * 179 * Parameters: 180 * unit - (IN) Device Number 181 * port_bitmap - (IN) Bitmap entry to be added into the memory 182 * index - (OUT) Index into the profile table. 183 * Only valid if the function returns BCM_E_NONE 184 * 185 * Returns: 186 * BCM_E_PARAM 187 * BCM_E_UNAVAIL 188 * BCM_E_FULL 189 * BCM_E_FAIL 190 * BCM_E_NONE 191 * 192 * Notes: 193 */ 194 int 195 _bcm_th3_vlan_pbmp_profile_entry_add( 196 int unit, bcm_pbmp_t port_bitmap, uint32 *index) { 197 198 int profile_idx; 199 soc_error_t rv; 200 port_bitmap_profile_entry_t vlan_pbmp_entry; 201 202 /* Perform sanity checks */ 203 if (NULL == index) { 204 return BCM_E_PARAM; 205 } 206 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 207 return BCM_E_UNAVAIL; 208 } 209 210 /* Create an entry from the given port bitmap */ 211 sal_memset(&vlan_pbmp_entry, 0, sizeof(port_bitmap_profile_entry_t)); 212 soc_mem_pbmp_field_set( 213 unit, PORT_BITMAP_PROFILEm, &vlan_pbmp_entry, BITMAPf, &port_bitmap); 214 215 /* Insert the entry into the profile memory */ 216 rv = soc_profile_mem_single_table_add( 217 unit, vlan_pbmp_profile[unit], &vlan_pbmp_entry, 1, &profile_idx); 218 219 /* Convert the SOC return value to BCM return code */ 220 if (SOC_FAILURE(rv)) { 221 return (((SOC_E_FULL == rv) || (SOC_E_RESOURCE == rv)) ? 222 BCM_E_FULL : BCM_E_FAIL); 223 } else { 224 /* Populate the given index buffer if the entry add succeeded */ 225 *index = profile_idx; 226 return BCM_E_NONE; 227 } 228 } 229 230 /* 231 * Function: 232 * _bcm_th3_vlan_pbmp_profile_entry_delete 233 * 234 * Purpose: 235 * delete an entry from PORT_BITMAP_PROFILE table 236 * 237 * Parameters: 238 * unit - (IN) Device Number 239 * index - (IN) Index into the profile table. 240 * 241 * Returns: 242 * BCM_E_PARAM 243 * BCM_E_UNAVAIL 244 * BCM_E_NOT_FOUND 245 * BCM_E_FAIL 246 * BCM_E_NONE 247 * 248 * Notes: 249 */ 250 int 251 _bcm_th3_vlan_pbmp_profile_entry_delete(int unit, uint32 index) { 252 253 soc_error_t rv; 254 255 /* Perform sanity checks */ 256 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 257 return BCM_E_UNAVAIL; 258 } 259 260 /* Call soc interface to delete an entry */ 261 rv = soc_profile_mem_delete(unit, vlan_pbmp_profile[unit], index); 262 263 if (SOC_FAILURE(rv)) { 264 return ((SOC_E_PARAM!=rv && SOC_E_NOT_FOUND!=rv) ? BCM_E_FAIL : rv); 265 } else { 266 return BCM_E_NONE; 267 } 268 } 269 270 /* 271 * Function: 272 * _bcm_th3_vlan_pbmp_port_entry_get 273 * 274 * Purpose: 275 * Retrieve the port bitmap for a given index. 276 * 277 * Parameters: 278 * unit - (IN) Device Number 279 * index - (IN) Index into the profile table. 280 * pbmp - (OUT) Bitmap entry to be retrieved from the memory 281 * 282 * Returns: 283 * BCM_E_PARAM 284 * BCM_E_UNAVAIL 285 * BCM_E_NOT_FOUND 286 * BCM_E_FAIL 287 * BCM_E_NONE 288 * 289 * Notes: 290 */ 291 int _bcm_th3_vlan_pbmp_profile_entry_get( 292 int unit, uint32 index, bcm_pbmp_t *pbmp) { 293 294 soc_error_t rv; 295 port_bitmap_profile_entry_t vlan_pbmp_entry; 296 297 /* Perform sanity checks */ 298 if (NULL == pbmp) { 299 return BCM_E_PARAM; 300 } 301 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 302 return BCM_E_UNAVAIL; 303 } 304 305 /* Retrieve an entry from the profile memory */ 306 sal_memset(&vlan_pbmp_entry, 0, sizeof(port_bitmap_profile_entry_t)); 307 rv = soc_profile_mem_single_table_get( 308 unit, vlan_pbmp_profile[unit], (int) index, 1, &vlan_pbmp_entry); 309 310 /* Convert the SOC return value to BCM return code */ 311 if (SOC_FAILURE(rv)) { 312 return ((SOC_E_PARAM != rv && SOC_E_NOT_FOUND != rv) ? BCM_E_FAIL : rv); 313 } else { 314 /* Extract the port bitmap from the table entry */ 315 soc_mem_pbmp_field_get( 316 unit, PORT_BITMAP_PROFILEm, &vlan_pbmp_entry, BITMAPf, pbmp); 317 return BCM_E_NONE; 318 } 319 } 320 321 /* 322 * Function: 323 * _bcm_th3_vlan_pbmp_index_get 324 * 325 * Purpose: 326 * Retrieve the portbitmap profile memory 327 * index from corresponding VLAN memory 328 * 329 * Parameters: 330 * unit - (IN) Device Number 331 * vlan_id - (IN) VLAN Identifier 332 * index - (OUT) Index into the profile table. 333 * 334 * Returns: 335 * BCM_E_PARAM 336 * BCM_E_UNAVAIL 337 * BCM_E_NOT_FOUND 338 * BCM_E_FAIL 339 * BCM_E_NONE 340 * 341 * Notes: 342 * The function assumes that the VLAN_2 memory is already locked 343 * and hence no locks are explicitly acquired or released 344 */ 345 int _bcm_th3_vlan_pbmp_index_get(int unit, bcm_vlan_t vlan_id, uint32 *index) { 346 347 soc_error_t rv; 348 vlan_2_tab_entry_t vlan_2_entry; 349 const soc_mem_t mem = VLAN_2_TABm; 350 351 /* Perform sanity checks */ 352 if (NULL == index || !BCM_VLAN_VALID(vlan_id)) { 353 return BCM_E_PARAM; 354 } 355 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 356 return BCM_E_UNAVAIL; 357 } 358 359 /* Read the corresponding VLAN table entry */ 360 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vlan_id, &vlan_2_entry); 361 if (SOC_FAILURE(rv)) { 362 return BCM_E_FAIL; 363 } 364 365 /* Check if the given VLAN is an existing one */ 366 if (!soc_mem_field32_get(unit, mem, &vlan_2_entry, VALIDf)) { 367 return BCM_E_NOT_FOUND; 368 } 369 370 /* Populate the given buffer with the correct index value */ 371 *index = 372 soc_mem_field32_get(unit, mem, &vlan_2_entry, PORT_BITMAP_PROFILE_PTRf); 373 374 return BCM_E_NONE; 375 } 376 377 /* 378 * Function: 379 * _bcm_th3_vlan_pbmp_index_set 380 * 381 * Purpose: 382 * Insert the portbitmap profile memory 383 * index to corresponding VLAN memory entry 384 * 385 * Parameters: 386 * unit - (IN) Device Number 387 * vlan_id - (IN) VLAN Identifier 388 * index - (IN) Index into the profile table. 389 * 390 * Returns: 391 * BCM_E_PARAM 392 * BCM_E_UNAVAIL 393 * BCM_E_NOT_FOUND 394 * BCM_E_FAIL 395 * BCM_E_NONE 396 * 397 * Notes: 398 * The function assumes that the VLAN_2 memory is already locked 399 * and hence no locks are explicitly acquired or released 400 */ 401 int _bcm_th3_vlan_pbmp_index_set(int unit, bcm_vlan_t vlan_id, uint32 index) 402 { 403 404 soc_error_t rv; 405 vlan_2_tab_entry_t vlan_2_entry; 406 const soc_mem_t mem = VLAN_2_TABm; 407 408 /* Perform sanity checks */ 409 if (!BCM_VLAN_VALID(vlan_id)) { 410 return BCM_E_PARAM; 411 } 412 413 414 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 415 return BCM_E_UNAVAIL; 416 } 417 418 /* Read the corresponding VLAN table entry */ 419 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vlan_id, &vlan_2_entry); 420 if (SOC_FAILURE(rv)) { 421 return BCM_E_FAIL; 422 } 423 424 /* Check if the given VLAN is an existing one */ 425 if (!soc_mem_field32_get(unit, mem, &vlan_2_entry, VALIDf)) { 426 return BCM_E_NOT_FOUND; 427 } 428 429 /* Populate the given buffer with the correct index value */ 430 soc_mem_field32_set( 431 unit, mem, &vlan_2_entry, PORT_BITMAP_PROFILE_PTRf, index); 432 433 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, (int) vlan_id, &vlan_2_entry); 434 435 return (SOC_FAILURE(rv) ? BCM_E_FAIL : BCM_E_NONE); 436 } 437 438 /* 439 * Function: 440 * _bcm_th3_vlan_pbmp_port_update 441 * 442 * Purpose: 443 * Add/Remove the ports in the given bitmap for a VLAN 444 * The table entry for the VLAN is provided as input 445 * Hence the profile index is set to the same entry 446 * 447 * Parameters: 448 * unit - (IN) Device Number 449 * vt - (IN/OUT) VLAN table entry. 450 * pbmp - (IN) Bitmap of ports to be added/removed from the VLAN. 451 * operation - (IN) 0 for Add, 1 for Remove 452 * 453 * Returns: 454 * BCM_E_PARAM 455 * BCM_E_UNAVAIL 456 * BCM_E_NOT_FOUND 457 * BCM_E_FAIL 458 * BCM_E_NONE 459 * 460 * Notes: 461 */ 462 STATIC int 463 _bcm_th3_vlan_pbmp_port_update( 464 int unit, vlan_2_tab_entry_t *vt, bcm_pbmp_t *pbmp, uint8 operation) 465 { 466 int rv = BCM_E_NONE; 467 uint32 old_profile_idx; 468 uint32 new_profile_idx; 469 bcm_pbmp_t cur_pbmp, org_pbmp; 470 471 if (0 != operation && 1 != operation) { 472 return BCM_E_UNAVAIL; 473 } 474 475 BCM_PBMP_CLEAR(cur_pbmp); 476 477 /* Retrieve the profile index from the VLAN table entry */ 478 old_profile_idx = 479 soc_mem_field32_get(unit, VLAN_2_TABm, vt, PORT_BITMAP_PROFILE_PTRf); 480 481 /* Retrieve the port bmp from the profile table given the index */ 482 BCM_IF_ERROR_RETURN( 483 _bcm_th3_vlan_pbmp_profile_entry_get( 484 unit, old_profile_idx, &cur_pbmp)); 485 486 /* Cache the retrieved port bitmap for later use */ 487 BCM_PBMP_ASSIGN(org_pbmp, cur_pbmp); 488 489 /* Perform read-modify-write operation on bitmap */ 490 if (operation) { 491 BCM_PBMP_REMOVE(cur_pbmp, *pbmp); 492 } else { 493 BCM_PBMP_OR(cur_pbmp, *pbmp); 494 } 495 496 /* Only perform the profile modification if the pbmp has changed */ 497 if (BCM_PBMP_NEQ(cur_pbmp, org_pbmp)) { 498 499 /* First delete the old profile entry from the profile table */ 500 rv = _bcm_th3_vlan_pbmp_profile_entry_delete(unit, old_profile_idx); 501 502 if (BCM_SUCCESS(rv)) { 503 /* Insert the modified port bitmap into the profile table */ 504 rv = _bcm_th3_vlan_pbmp_profile_entry_add(unit, 505 cur_pbmp, 506 &new_profile_idx); 507 508 /* If new entry add failed then add back the old pbmp */ 509 if (BCM_FAILURE(rv)) { 510 if (BCM_SUCCESS( 511 _bcm_th3_vlan_pbmp_profile_entry_add(unit, 512 org_pbmp, 513 &old_profile_idx))) { 514 /* Set the old index into the given VLAN table entry */ 515 soc_mem_field32_set(unit, VLAN_2_TABm, 516 vt, PORT_BITMAP_PROFILE_PTRf, old_profile_idx); 517 } 518 } else { 519 /* Set the new profile index into the given VLAN table entry */ 520 soc_mem_field32_set(unit, 521 VLAN_2_TABm, vt, PORT_BITMAP_PROFILE_PTRf, new_profile_idx); 522 } 523 } 524 } 525 return rv; 526 } 527 528 /* 529 * Function: 530 * _bcm_th3_vlan_pbmp_port_add 531 * 532 * Purpose: 533 * Add the ports in the given bitmap for a VLAN 534 * The table entry for the VLAN is provided as input 535 * Hence the profile index is set to the same entry 536 * 537 * Parameters: 538 * unit - (IN) Device Number 539 * entry - (IN/OUT) VLAN table entry. 540 * pbmp - (IN) Bitmap of ports to be added from the VLAN. 541 * 542 * Returns: 543 * BCM_E_PARAM 544 * BCM_E_UNAVAIL 545 * BCM_E_NOT_FOUND 546 * BCM_E_FAIL 547 * BCM_E_NONE 548 * 549 * Notes: 550 * It is assumed that the given vlan entry is genuine and has 551 * all the relevant parameters in correct state. Also the VLAN 552 * valid bit is assumed to be set to begin with. 553 */ 554 int _bcm_th3_vlan_pbmp_port_add(int unit, void *entry, bcm_pbmp_t *pbmp) 555 { 556 /* Perform sanity checks */ 557 if (NULL == entry || NULL == pbmp) { 558 return BCM_E_PARAM; 559 } 560 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 561 return BCM_E_UNAVAIL; 562 } 563 564 return(_bcm_th3_vlan_pbmp_port_update(unit, entry, pbmp, 0)); 565 } 566 567 /* 568 * Function: 569 * _bcm_th3_vlan_pbmp_port_remove 570 * 571 * Purpose: 572 * Remove the ports in the given bitmap for a VLAN 573 * The table entry for the VLAN is provided as input 574 * Hence the profile index is set to the same entry 575 * 576 * Parameters: 577 * unit - (IN) Device Number 578 * entry - (IN/OUT) VLAN table entry. 579 * pbmp - (IN) Bitmap of ports to be removed from the VLAN. 580 * 581 * Returns: 582 * BCM_E_PARAM 583 * BCM_E_UNAVAIL 584 * BCM_E_NOT_FOUND 585 * BCM_E_FAIL 586 * BCM_E_NONE 587 * 588 * Notes: 589 * It is assumed that the given vlan entry is genuine and has 590 * all the relevant parameters in correct state. Also the VLAN 591 * valid bit is assumed to be set to begin with. 592 */ 593 int _bcm_th3_vlan_pbmp_port_remove(int unit, void *entry, bcm_pbmp_t *pbmp) 594 { 595 /* Perform sanity checks */ 596 if (NULL == entry || NULL == pbmp) { 597 return BCM_E_PARAM; 598 } 599 if (!soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 600 return BCM_E_UNAVAIL; 601 } 602 603 return(_bcm_th3_vlan_pbmp_port_update(unit, entry, pbmp, 1)); 604 } 605 606 /* 607 * Function: 608 * _bcm_th3_vlan_action_profile_init 609 * 610 * Purpose : to initialize hardware ING_VLAN_TAG_ACTION_PROFILE and 611 * EGR_VLAN_TAG_ACTION_PROFILE tables and allocate memory 612 * to cache hardware tables in RAM. 613 * 614 * Parameters: 615 * unit - (IN) Device Number 616 * 617 * Returns: 618 * BCM_E_XXX 619 * 620 * Notes: 621 * Allocate memory to cache the profile tables and initialize. 622 * If memory to cache the profile table is already allocated, just 623 * initialize the table. 624 */ 625 int 626 _bcm_th3_vlan_action_profile_init(int unit) 627 { 628 int i, idx, num_ports; 629 ing_vlan_tag_action_profile_entry_t ing_profile_entry; 630 egr_vlan_tag_action_profile_entry_t egr_profile_entry; 631 uint32 rval; 632 soc_mem_t mem; 633 int temp_index; 634 int entry_idxmax; 635 int entry_words; 636 int entry_idxmin = 0; 637 const uint32 ing_ent_sz = sizeof(ing_vlan_tag_action_profile_entry_t); 638 639 /* Initialize the ING_VLAN_TAG_ACTION_PROFILE table */ 640 if (ing_action_profile[unit] == NULL) { 641 ing_action_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t), 642 "Ing Action Profile Mem"); 643 if (ing_action_profile[unit] == NULL) { 644 return BCM_E_MEMORY; 645 } 646 soc_profile_mem_t_init(ing_action_profile[unit]); 647 } 648 649 mem = ING_VLAN_TAG_ACTION_PROFILEm; 650 entry_idxmax = soc_mem_index_max(unit, mem); 651 entry_words = ing_ent_sz / sizeof(uint32); 652 if (SOC_FAILURE( 653 soc_profile_mem_index_create(unit, &mem, &entry_words, 654 &entry_idxmin, &entry_idxmax, 655 NULL, 1, ing_action_profile[unit]))) { 656 sal_free(ing_action_profile[unit]); 657 ing_action_profile[unit] = NULL; 658 return BCM_E_FAIL; 659 } 660 661 if (SOC_WARM_BOOT(unit)) { 662 soc_mem_t port_mem = PORT_TABm; 663 664 /* Increment the ref count for all ports */ 665 for (i = 0; i < soc_mem_index_count(unit, port_mem); i++) { 666 SOC_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, i, 667 TAG_ACTION_PROFILE_PTRf, &idx)); 668 SOC_IF_ERROR_RETURN( 669 soc_profile_mem_reference(unit, ing_action_profile[unit], 670 idx - entry_idxmin, 1)); 671 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit], 672 idx - entry_idxmin, 1); 673 } 674 675 /* One extra incr to preserve location ING_ACTION_PROFILE_DEFAULT */ 676 SOC_IF_ERROR_RETURN( 677 soc_profile_mem_reference(unit, ing_action_profile[unit], 678 ING_ACTION_PROFILE_DEFAULT, 1)); 679 } else { 680 /* Initialize the ING_ACTION_PROFILE_DEFAULT. For untagged and 681 * inner-tagged packets, always add an outer tag. 682 */ 683 soc_mem_t port_mem = PORT_TABm; 684 sal_memset(&ing_profile_entry, 0, ing_ent_sz); 685 soc_mem_field32_set(unit, mem, &ing_profile_entry, UT_OTAG_ACTIONf, 686 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionAdd)); 687 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 688 soc_mem_field32_set(unit, mem, &ing_profile_entry, UT_OPRI_ACTIONf, 689 _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd)); 690 soc_mem_field32_set(unit, mem, &ing_profile_entry, UT_OCFI_ACTIONf, 691 _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd)); 692 } 693 soc_mem_field32_set(unit, mem, &ing_profile_entry, SOT_POTAG_ACTIONf, 694 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionReplace)); 695 SOC_IF_ERROR_RETURN 696 (soc_profile_mem_single_table_add(unit, 697 ing_action_profile[unit], &ing_profile_entry, 1, &temp_index)); 698 699 for (i = 0; i < soc_mem_index_count(unit, port_mem); i++) { 700 SOC_IF_ERROR_RETURN( 701 soc_profile_mem_reference(unit, ing_action_profile[unit], 702 ING_ACTION_PROFILE_DEFAULT, 1)); 703 } 704 } 705 706 /* Initialize the EGR_VLAN_TAG_ACTION_PROFILE table */ 707 if (egr_action_profile[unit] == NULL) { 708 egr_action_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t), 709 "Egr Action Profile Mem"); 710 if (egr_action_profile[unit] == NULL) { 711 return BCM_E_MEMORY; 712 } 713 soc_profile_mem_t_init(egr_action_profile[unit]); 714 } 715 716 /* Create profile table cache (or re-init if it already exists) */ 717 mem = EGR_VLAN_TAG_ACTION_PROFILEm; 718 entry_words = sizeof(egr_vlan_tag_action_profile_entry_t) / sizeof(uint32); 719 SOC_IF_ERROR_RETURN(soc_profile_mem_create(unit, &mem, &entry_words, 1, 720 egr_action_profile[unit])); 721 722 SOC_PBMP_COUNT(PBMP_ALL(unit), num_ports); 723 if (SOC_WARM_BOOT(unit)) { 724 /* Increment the ref count for all ports */ 725 PBMP_ALL_ITER(unit, i) { 726 SOC_IF_ERROR_RETURN 727 (READ_EGR_VLAN_CONTROL_3r(unit, i, &rval)); 728 idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 729 rval, TAG_ACTION_PROFILE_PTRf); 730 SOC_PROFILE_MEM_REFERENCE(unit, egr_action_profile[unit], idx, 1); 731 SOC_PROFILE_MEM_ENTRIES_PER_SET( 732 unit, egr_action_profile[unit], idx, 1); 733 } 734 735 /* 1 extra increment to preserve location EGR_ACTION_PROFILE_DEFAULT */ 736 SOC_PROFILE_MEM_REFERENCE(unit, egr_action_profile[unit], 737 BCM_TH3_EGR_ACTION_PROFILE_DEFAULT, 1); 738 } else { 739 /* Initialize the BCM_TH3_EGR_ACTION_PROFILE_DEFAULT to have all 740 * actions as NOP (0). 741 */ 742 sal_memset(&egr_profile_entry, 0, 743 sizeof(egr_vlan_tag_action_profile_entry_t)); 744 SOC_IF_ERROR_RETURN 745 (soc_profile_mem_single_table_add(unit, 746 egr_action_profile[unit], &egr_profile_entry, 1, &temp_index)); 747 748 /* Increment the ref count for all ports */ 749 SOC_PROFILE_MEM_REFERENCE(unit, egr_action_profile[unit], 750 BCM_TH3_EGR_ACTION_PROFILE_DEFAULT, num_ports); 751 } 752 753 return BCM_E_NONE; 754 } 755 756 /* 757 * Function: 758 * _bcm_th3_vlan_action_profile_detach 759 * 760 * Purpose : to deallocate resources for hardware 761 * ING_VLAN_TAG_ACTION_PROFILE and 762 * EGR_VLAN_TAG_ACTION_PROFILE tables and 763 * their caches correspondingly in RAM. 764 * 765 * Parameters: 766 * unit - (IN) Device Number 767 * 768 * Returns: 769 * BCM_E_XXX 770 * 771 * Notes: 772 */ 773 int 774 _bcm_th3_vlan_action_profile_detach(int unit) 775 { 776 int rv; 777 778 /* De-initialize the ING_VLAN_TAG_ACTION_PROFILE table */ 779 if (ing_action_profile[unit]) { 780 rv = soc_profile_mem_destroy(unit, ing_action_profile[unit]); 781 BCM_IF_ERROR_RETURN(rv); 782 783 sal_free(ing_action_profile[unit]); 784 ing_action_profile[unit] = NULL; 785 } 786 787 /* De-initialize the EGR_VLAN_TAG_ACTION_PROFILE table */ 788 if (egr_action_profile[unit]) { 789 rv = soc_profile_mem_destroy(unit, egr_action_profile[unit]); 790 BCM_IF_ERROR_RETURN(rv); 791 792 sal_free(egr_action_profile[unit]); 793 egr_action_profile[unit] = NULL; 794 } 795 796 return BCM_E_NONE; 797 } 798 799 /* 800 * Function: 801 * _bcm_th3_vlan_action_verify 802 * 803 * Purpose : to validate all members of action structure 804 * 805 * Parameters: 806 * unit - (IN) Device Number 807 * action - (IN) tag actions to be verified 808 * 809 * Returns: 810 * BCM_E_NONE 811 * BCM_E_PARAM 812 * 813 * Notes: 814 */ 815 STATIC int 816 _bcm_th3_vlan_action_verify(int unit, bcm_vlan_action_set_t *action) 817 { 818 if (NULL == action) { 819 return BCM_E_PARAM; 820 } 821 VLAN_CHK_ID(unit, action->new_outer_vlan); 822 823 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 824 if (action->priority < -1 || 825 action->priority > 7 || action->new_outer_cfi > 1) { 826 return BCM_E_PARAM; 827 } 828 } 829 830 /* Double Tag operations not supported */ 831 if ((bcmVlanActionNone != action->dt_outer) || 832 (bcmVlanActionNone != action->dt_outer_prio) || 833 (bcmVlanActionNone != action->dt_outer_pkt_prio) || 834 (bcmVlanActionNone != action->dt_outer_cfi) || 835 (bcmVlanActionNone != action->dt_inner) || 836 (bcmVlanActionNone != action->dt_inner_prio) || 837 (bcmVlanActionNone != action->dt_inner_pkt_prio) || 838 (bcmVlanActionNone != action->dt_inner_cfi)) { 839 return BCM_E_UNAVAIL; 840 } 841 842 /* Two tags not supported */ 843 if ((bcmVlanActionNone != action->ot_inner) || 844 (bcmVlanActionNone != action->ot_inner_pkt_prio) || 845 (bcmVlanActionNone != action->ot_inner_cfi) || 846 (bcmVlanActionNone != action->it_outer) || 847 (bcmVlanActionNone != action->it_outer_pkt_prio) || 848 (bcmVlanActionNone != action->it_outer_cfi)) { 849 return BCM_E_UNAVAIL; 850 } 851 852 /* No Inner tag operations supported */ 853 if ((bcmVlanActionNone != action->it_inner) || 854 (bcmVlanActionNone != action->it_inner_prio) || 855 (bcmVlanActionNone != action->it_inner_pkt_prio) || 856 (bcmVlanActionNone != action->it_inner_cfi) || 857 (bcmVlanActionNone != action->ut_inner) || 858 (bcmVlanActionNone != action->ut_inner_pkt_prio) || 859 (bcmVlanActionNone != action->ut_inner_cfi)) { 860 return BCM_E_UNAVAIL; 861 } 862 863 switch (action->ot_outer) { 864 case bcmVlanActionNone: 865 case bcmVlanActionReplace: 866 case bcmVlanActionDelete: 867 break; 868 default: 869 return BCM_E_PARAM; 870 } 871 872 switch (action->ot_outer_prio) { 873 case bcmVlanActionNone: 874 case bcmVlanActionReplace: 875 case bcmVlanActionDelete: 876 break; 877 default: 878 return BCM_E_PARAM; 879 } 880 881 switch (action->ot_outer_pkt_prio) { 882 case bcmVlanActionNone: 883 break; 884 case bcmVlanActionReplace: 885 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 886 return BCM_E_UNAVAIL; 887 } 888 break; 889 default: 890 return BCM_E_PARAM; 891 } 892 893 switch (action->ot_outer_cfi) { 894 case bcmVlanActionNone: 895 break; 896 case bcmVlanActionReplace: 897 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 898 return BCM_E_UNAVAIL; 899 } 900 break; 901 default: 902 return BCM_E_PARAM; 903 } 904 905 switch (action->ut_outer) { 906 case bcmVlanActionNone: 907 case bcmVlanActionAdd: 908 break; 909 default: 910 return BCM_E_PARAM; 911 } 912 913 switch (action->ut_outer_pkt_prio) { 914 case bcmVlanActionNone: 915 break; 916 case bcmVlanActionAdd: 917 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 918 return BCM_E_UNAVAIL; 919 } 920 break; 921 default: 922 return BCM_E_PARAM; 923 } 924 925 switch (action->ut_outer_cfi) { 926 case bcmVlanActionNone: 927 break; 928 case bcmVlanActionAdd: 929 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 930 return BCM_E_UNAVAIL; 931 } 932 break; 933 default: 934 return BCM_E_PARAM; 935 } 936 937 return BCM_E_NONE; 938 } 939 940 /* 941 * Function: 942 * _bcm_th3_vlan_action_profile_entry_add 943 * 944 * Purpose : add a new entry to the given vlan 945 * action profile table at given index 946 * 947 * Parameters: 948 * unit - (IN) Device Number 949 * vtap_mem - (IN) VLAN Tag Action Profile Memory 950 * action - (IN) tag actions to be added 951 * index - (IN) Index of profile memory where to add the entry 952 * 953 * Returns: 954 * BCM_E_XXX 955 * 956 * Notes: 957 */ 958 STATIC int 959 _bcm_th3_vlan_action_profile_entry_add(int unit, 960 soc_mem_t vtap_mem, 961 bcm_vlan_action_set_t *action, 962 int *index) 963 { 964 soc_profile_mem_t *profile = NULL; 965 egr_vlan_tag_action_profile_entry_t egr_vtap_entry; 966 ing_vlan_tag_action_profile_entry_t ing_vtap_entry; 967 void *vtap_entry = NULL; 968 969 if (ING_VLAN_TAG_ACTION_PROFILEm == vtap_mem) { 970 profile = ing_action_profile[unit]; 971 vtap_entry = (void *)&ing_vtap_entry; 972 sal_memset(vtap_entry, 0, sizeof(ing_vlan_tag_action_profile_entry_t)); 973 } else if (EGR_VLAN_TAG_ACTION_PROFILEm == vtap_mem) { 974 profile = egr_action_profile[unit]; 975 vtap_entry = (void *)&egr_vtap_entry; 976 sal_memset(vtap_entry, 0, sizeof(egr_vlan_tag_action_profile_entry_t)); 977 } else { 978 return BCM_E_PARAM; 979 } 980 981 soc_mem_field32_set(unit, vtap_mem, vtap_entry, SOT_OTAG_ACTIONf, 982 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer)); 983 soc_mem_field32_set(unit, vtap_mem, vtap_entry, SOT_POTAG_ACTIONf, 984 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer_prio)); 985 soc_mem_field32_set(unit, vtap_mem, vtap_entry, UT_OTAG_ACTIONf, 986 _BCM_TRX_TAG_ACTION_ENCODE(action->ut_outer)); 987 988 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 989 soc_mem_field32_set 990 (unit, vtap_mem, vtap_entry, SOT_OPRI_ACTIONf, 991 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_pkt_prio)); 992 soc_mem_field32_set 993 (unit, vtap_mem, vtap_entry, SOT_OCFI_ACTIONf, 994 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_cfi)); 995 soc_mem_field32_set 996 (unit, vtap_mem, vtap_entry, UT_OPRI_ACTIONf, 997 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_pkt_prio)); 998 soc_mem_field32_set 999 (unit, vtap_mem, vtap_entry, UT_OCFI_ACTIONf, 1000 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_cfi)); 1001 } 1002 1003 return 1004 (soc_profile_mem_single_table_add(unit, profile, vtap_entry, 1, index)); 1005 } 1006 1007 /* 1008 * Function: 1009 * _bcm_th3_ing_vlan_action_profile_entry_add 1010 * 1011 * Purpose : add a new entry to the ING_VLAN_TAG_ACTION_PROFILE 1012 * memory at given index 1013 * 1014 * Parameters: 1015 * unit - (IN) Device Number 1016 * action - (IN) tag actions to be added 1017 * index - (IN) Index of profile memory where to add the entry 1018 * 1019 * Returns: 1020 * BCM_E_XXX 1021 * 1022 * Notes: 1023 * It is assumed that the action data structure is thorougly scrutinized 1024 * before the function is called. Hence no additional checks are performed 1025 */ 1026 int 1027 _bcm_th3_ing_vlan_action_profile_entry_add(int unit, 1028 bcm_vlan_action_set_t *action, 1029 int *index) 1030 { 1031 return(_bcm_th3_vlan_action_profile_entry_add(unit, 1032 ING_VLAN_TAG_ACTION_PROFILEm, 1033 action, 1034 index)); 1035 } 1036 1037 /* 1038 * Function: 1039 * _bcm_th3_egr_vlan_action_profile_entry_add 1040 * 1041 * Purpose : add a new entry to the EGR_VLAN_TAG_ACTION_PROFILE 1042 * memory at given index 1043 * 1044 * Parameters: 1045 * unit - (IN) Device Number 1046 * action - (IN) tag actions to be added 1047 * index - (IN) Index of profile memory where to add the entry 1048 * 1049 * Returns: 1050 * BCM_E_XXX 1051 * 1052 * Notes: 1053 * It is assumed that the action data structure is thorougly scrutinized 1054 * before the function is called. Hence no additional checks are performed 1055 */ 1056 int 1057 _bcm_th3_egr_vlan_action_profile_entry_add(int unit, 1058 bcm_vlan_action_set_t *action, 1059 int *index) 1060 { 1061 return(_bcm_th3_vlan_action_profile_entry_add(unit, 1062 EGR_VLAN_TAG_ACTION_PROFILEm, 1063 action, 1064 index)); 1065 } 1066 1067 /* 1068 * Function: 1069 * _bcm_th3_vlan_action_profile_entry_decode 1070 * 1071 * Purpose : Decode and save the tag actions from the given 1072 * memory entry for the given TAG Action memory 1073 * 1074 * Parameters: 1075 * unit - (IN) Device Number 1076 * mem - (IN) VLAN Tag Action memory 1077 * vtap_entry - (IN) Retrieved entry from the memory 'mem' 1078 * action - (OUT) save the decoded tag actions here 1079 * 1080 * Returns: 1081 * 1082 * Notes: 1083 */ 1084 STATIC void 1085 _bcm_th3_vlan_action_profile_entry_decode(int unit, 1086 soc_mem_t mem, 1087 void *vtap_entry, 1088 bcm_vlan_action_set_t *action) 1089 { 1090 uint32 val; 1091 1092 val = soc_mem_field32_get(unit, mem, vtap_entry, SOT_OTAG_ACTIONf); 1093 action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 1094 1095 val = soc_mem_field32_get(unit, mem, vtap_entry, SOT_POTAG_ACTIONf); 1096 action->ot_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 1097 1098 val = soc_mem_field32_get(unit, mem, vtap_entry, UT_OTAG_ACTIONf); 1099 action->ut_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 1100 1101 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1102 val = soc_mem_field32_get(unit, mem, vtap_entry, SOT_OPRI_ACTIONf); 1103 action->ot_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 1104 1105 val = soc_mem_field32_get(unit, mem, vtap_entry, SOT_OCFI_ACTIONf); 1106 action->ot_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 1107 1108 val = soc_mem_field32_get(unit, mem, vtap_entry, UT_OPRI_ACTIONf); 1109 action->ut_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 1110 1111 val = soc_mem_field32_get(unit, mem, vtap_entry, UT_OCFI_ACTIONf); 1112 action->ut_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 1113 } else { 1114 action->ot_outer_pkt_prio = bcmVlanActionNone; 1115 action->ot_outer_cfi = bcmVlanActionNone; 1116 action->ut_outer_pkt_prio = bcmVlanActionNone; 1117 action->ut_outer_cfi = bcmVlanActionNone; 1118 } 1119 1120 action->dt_outer = 1121 action->dt_outer_prio = 1122 action->dt_outer_pkt_prio = 1123 action->dt_outer_cfi = 1124 action->dt_inner = 1125 action->dt_inner_prio = 1126 action->dt_inner_pkt_prio = 1127 action->dt_inner_cfi = 1128 action->ot_inner = 1129 action->ot_inner_pkt_prio = 1130 action->ot_inner_cfi = 1131 action->it_outer_pkt_prio = 1132 action->it_outer_cfi = 1133 action->it_outer = 1134 action->it_inner_pkt_prio = 1135 action->it_inner_cfi = 1136 action->it_inner = 1137 action->it_inner_prio = 1138 action->ut_inner = 1139 action->ut_inner_cfi = 1140 action->ut_inner_pkt_prio = bcmVlanActionNone; 1141 } 1142 1143 /* 1144 * Function: 1145 * _bcm_th3_ing_vlan_action_profile_entry_get 1146 * 1147 * Purpose : get tag actions for given index to the Ingress VLAN Tag action 1148 * 1149 * Parameters: 1150 * unit - (IN) Device Number 1151 * action - (OUT) save the decoded tag actions here 1152 * index - (IN) index to the ING_VLAN_TAG_ACTION_PROFILE 1153 * 1154 * Returns: 1155 * 1156 * Notes: 1157 */ 1158 void 1159 _bcm_th3_ing_vlan_action_profile_entry_get(int unit, 1160 bcm_vlan_action_set_t *action, 1161 int index) 1162 { 1163 ing_vlan_tag_action_profile_entry_t ing_vtap_entry; 1164 1165 sal_memset(&ing_vtap_entry, 0, sizeof(ing_vlan_tag_action_profile_entry_t)); 1166 1167 /* Retrieve an entry from the profile memory */ 1168 (void) soc_profile_mem_single_table_get( 1169 unit, ing_action_profile[unit], index, 1, &ing_vtap_entry); 1170 1171 _bcm_th3_vlan_action_profile_entry_decode(unit, 1172 ING_VLAN_TAG_ACTION_PROFILEm, &ing_vtap_entry, action); 1173 } 1174 1175 /* 1176 * Function: 1177 * _bcm_th3_egr_vlan_action_profile_entry_get 1178 * 1179 * Purpose : get a copy of cached vlan action profile table 1180 * 1181 * Parameters: 1182 * unit - (IN) Device Number 1183 * action - (OUT) save the decoded tag actions here 1184 * index - (IN) index to the ING_VLAN_TAG_ACTION_PROFILE 1185 * 1186 * Returns: 1187 * 1188 * Notes: 1189 */ 1190 void 1191 _bcm_th3_egr_vlan_action_profile_entry_get(int unit, 1192 bcm_vlan_action_set_t *action, 1193 uint32 index) 1194 { 1195 egr_vlan_tag_action_profile_entry_t *vtap_entry; 1196 1197 vtap_entry = SOC_PROFILE_MEM_ENTRY(unit, egr_action_profile[unit], 1198 egr_vlan_tag_action_profile_entry_t *, 1199 index); 1200 _bcm_th3_vlan_action_profile_entry_decode(unit, 1201 EGR_VLAN_TAG_ACTION_PROFILEm, vtap_entry, action); 1202 } 1203 1204 /* 1205 * Function: 1206 * _bcm_th3_ing_vlan_action_profile_entry_delete 1207 * 1208 * Purpose : remove an entry from Ingress vlan action profile table 1209 * 1210 * Parameters: 1211 * unit - (IN) Device Number 1212 * index - (IN) index of the entry to be deleted 1213 * 1214 * Returns: 1215 * BCM_E_XXX 1216 * 1217 * Notes: 1218 */ 1219 int 1220 _bcm_th3_ing_vlan_action_profile_entry_delete(int unit, uint32 index) 1221 { 1222 return soc_profile_mem_delete(unit, ing_action_profile[unit], index); 1223 } 1224 1225 /* 1226 * Function: 1227 * _bcm_th3_egr_vlan_action_profile_entry_delete 1228 * 1229 * Purpose : remove an entry from Egress vlan action profile table 1230 * 1231 * Parameters: 1232 * unit - (IN) Device Number 1233 * index - (IN) index of the entry to be deleted 1234 * 1235 * Returns: 1236 * BCM_E_XXX 1237 * 1238 * Notes: 1239 */ 1240 int 1241 _bcm_th3_egr_vlan_action_profile_entry_delete(int unit, uint32 index) 1242 { 1243 return soc_profile_mem_delete(unit, egr_action_profile[unit], index); 1244 } 1245 1246 /* 1247 * Function: 1248 * _bcm_th3_egr_vlan_action_profile_entry_increment 1249 * 1250 * Purpose : increment the refcount for default egr vlan action profile table 1251 * entry 1252 * 1253 * Parameters: 1254 * unit - (IN) BCM unit. 1255 * index - (IN) Profile table entry index 1256 * 1257 * Returns: 1258 * 1259 * Notes: 1260 */ 1261 void 1262 _bcm_th3_egr_vlan_action_profile_entry_increment(int unit, uint32 index) 1263 { 1264 soc_profile_mem_reference(unit, egr_action_profile[unit], index, 1); 1265 } 1266 1267 /* 1268 * Function: 1269 * _bcm_th3_vlan_port_egress_default_action_set 1270 * 1271 * Purpose: 1272 * Set the egress port's default vlan tag actions 1273 * 1274 * Parameters: 1275 * unit - (IN) BCM unit. 1276 * port - (IN) Port number. 1277 * action - (IN) Vlan tag actions 1278 * 1279 * Returns: 1280 * BCM_E_XXX 1281 * 1282 * Notes: 1283 */ 1284 int 1285 _bcm_th3_vlan_port_egress_default_action_set(int unit, bcm_port_t port, 1286 bcm_vlan_action_set_t *action) 1287 { 1288 int rv; 1289 uint32 rval; 1290 int profile_idx, old_profile_idx; 1291 1292 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_action_verify(unit, action)); 1293 BCM_IF_ERROR_RETURN( 1294 _bcm_th3_egr_vlan_action_profile_entry_add(unit, action, &profile_idx)); 1295 1296 rv = READ_EGR_VLAN_CONTROL_2r(unit, port, &rval); 1297 if (rv < 0) { 1298 goto error; 1299 } 1300 1301 if (-1 == action->priority) { 1302 /* point to default map profile(0) for default priority action */ 1303 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRI_CFI_SELf, 1); 1304 } else { 1305 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRI_CFI_SELf, 0); 1306 soc_reg_field_set( 1307 unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf, action->priority); 1308 soc_reg_field_set( 1309 unit, EGR_VLAN_CONTROL_2r, &rval, OCFIf, action->new_outer_cfi); 1310 } 1311 soc_reg_field_set( 1312 unit, EGR_VLAN_CONTROL_2r, &rval, OVIDf, action->new_outer_vlan); 1313 1314 rv = WRITE_EGR_VLAN_CONTROL_2r(unit, port, rval); 1315 if (rv < 0) { 1316 goto error; 1317 } 1318 1319 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval); 1320 if (rv < 0) { 1321 goto error; 1322 } 1323 old_profile_idx = soc_reg_field_get( 1324 unit, EGR_VLAN_CONTROL_3r, rval, TAG_ACTION_PROFILE_PTRf); 1325 soc_reg_field_set( 1326 unit, EGR_VLAN_CONTROL_3r, &rval, TAG_ACTION_PROFILE_PTRf, profile_idx); 1327 1328 rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval); 1329 if (rv < 0) { 1330 goto error; 1331 } 1332 1333 /* Delete the old profile entry even if it is same as the new one as 1334 * reference count has to adjust back to old value since it must have been 1335 * bumped up by one when the profile entry was added in the very beginning 1336 * of this function. 1337 */ 1338 BCM_IF_ERROR_RETURN 1339 (_bcm_th3_egr_vlan_action_profile_entry_delete(unit, old_profile_idx)); 1340 1341 return BCM_E_NONE; 1342 error: 1343 /* Undo action profile entry addition */ 1344 BCM_IF_ERROR_RETURN 1345 (_bcm_th3_egr_vlan_action_profile_entry_delete(unit, profile_idx)); 1346 return rv; 1347 } 1348 1349 /* 1350 * Function: 1351 * _bcm_th3_vlan_port_egress_default_action_get 1352 * 1353 * Purpose: 1354 * Get the egress port's default vlan tag actions 1355 * 1356 * Parameters: 1357 * unit - (IN) BCM unit. 1358 * port - (IN) Port number. 1359 * action - (OUT) Vlan tag actions 1360 * 1361 * Returns: 1362 * BCM_E_XXX 1363 * 1364 * Notes: 1365 */ 1366 int 1367 _bcm_th3_vlan_port_egress_default_action_get(int unit, bcm_port_t port, 1368 bcm_vlan_action_set_t *action) 1369 { 1370 uint32 profile_idx, rval; 1371 1372 if (NULL == action) { 1373 return BCM_E_PARAM; 1374 } 1375 1376 bcm_vlan_action_set_t_init(action); 1377 1378 BCM_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_3r(unit, port, &rval)); 1379 profile_idx = 1380 soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 1381 rval, TAG_ACTION_PROFILE_PTRf); 1382 _bcm_th3_egr_vlan_action_profile_entry_get(unit, action, profile_idx); 1383 1384 BCM_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_2r(unit, port, &rval)); 1385 action->new_outer_vlan = 1386 soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OVIDf); 1387 1388 if (!soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OPRI_CFI_SELf)) { 1389 action->priority = 1390 soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OPRIf); 1391 action->new_outer_cfi = 1392 soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OCFIf); 1393 } 1394 return BCM_E_NONE; 1395 } 1396 1397 /* 1398 * Function: 1399 * _bcm_th3_vlan_port_egress_default_action_delete 1400 * 1401 * Purpose: 1402 * Deletes the egress port's default vlan tag actions 1403 * 1404 * Parameters: 1405 * unit - (IN) BCM unit. 1406 * port - (IN) Port number. 1407 * 1408 * Returns: 1409 * BCM_E_XXX 1410 * 1411 * Notes: 1412 */ 1413 int 1414 _bcm_th3_vlan_port_egress_default_action_delete(int unit, bcm_port_t port) 1415 { 1416 uint32 profile_idx, rval; 1417 1418 BCM_IF_ERROR_RETURN( 1419 READ_EGR_VLAN_CONTROL_3r(unit, port, &rval)); 1420 profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 1421 rval, TAG_ACTION_PROFILE_PTRf); 1422 1423 BCM_IF_ERROR_RETURN( 1424 _bcm_th3_egr_vlan_action_profile_entry_delete(unit, profile_idx)); 1425 1426 sal_memset(&rval, 0, sizeof(uint32)); 1427 BCM_IF_ERROR_RETURN( 1428 WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval)); 1429 BCM_IF_ERROR_RETURN( 1430 WRITE_EGR_VLAN_CONTROL_2r(unit, port, rval)); 1431 return BCM_E_NONE; 1432 } 1433 1434 /* 1435 * Function: 1436 * _bcm_th3_vlan_port_default_action_set 1437 * 1438 * Purpose: 1439 * Set the port's default vlan tag actions 1440 * 1441 * Parameters: 1442 * unit - (IN) BCM unit. 1443 * port - (IN) Port number. 1444 * action - (IN) Vlan tag actions 1445 * 1446 * Returns: 1447 * BCM_E_XXX 1448 * 1449 * Notes: 1450 */ 1451 int 1452 _bcm_th3_vlan_port_default_action_set(int unit, bcm_port_t port, 1453 bcm_vlan_action_set_t *action) 1454 { 1455 int profile_idx; 1456 uint32 old_profile_idx; 1457 bcm_port_cfg_t pcfg; 1458 1459 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_action_verify(unit, action)); 1460 BCM_IF_ERROR_RETURN( 1461 _bcm_th3_ing_vlan_action_profile_entry_add(unit, action, &profile_idx)); 1462 1463 BCM_IF_ERROR_RETURN( 1464 mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 1465 old_profile_idx = pcfg.pc_vlan_action; 1466 1467 pcfg.pc_vlan = action->new_outer_vlan; 1468 pcfg.pc_vlan_action = profile_idx; 1469 if (action->priority >= BCM_PRIO_MIN && action->priority <= BCM_PRIO_MAX) { 1470 pcfg.pc_new_opri = action->priority; 1471 } 1472 pcfg.pc_new_ocfi = action->new_outer_cfi; 1473 BCM_IF_ERROR_RETURN( 1474 mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 1475 1476 SOC_IF_ERROR_RETURN( 1477 _bcm_th3_ing_vlan_action_profile_entry_delete(unit, old_profile_idx)); 1478 return BCM_E_NONE; 1479 } 1480 1481 /* 1482 * Function: 1483 * _bcm_th3_vlan_port_default_action_get 1484 * 1485 * Purpose: 1486 * Get the port's default vlan tag actions 1487 * 1488 * Parameters: 1489 * unit - (IN) BCM unit. 1490 * port - (IN) Port number. 1491 * action - (OUT) Vlan tag actions 1492 * 1493 * Returns: 1494 * BCM_E_XXX 1495 * 1496 * Notes: 1497 */ 1498 int 1499 _bcm_th3_vlan_port_default_action_get(int unit, bcm_port_t port, 1500 bcm_vlan_action_set_t *action) 1501 { 1502 bcm_port_cfg_t pcfg; 1503 1504 if (NULL == action) { 1505 return BCM_E_PARAM; 1506 } 1507 1508 bcm_vlan_action_set_t_init(action); 1509 1510 BCM_IF_ERROR_RETURN 1511 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 1512 1513 _bcm_th3_ing_vlan_action_profile_entry_get( unit, 1514 action, 1515 pcfg.pc_vlan_action); 1516 action->new_outer_vlan = pcfg.pc_vlan; 1517 action->priority = pcfg.pc_new_opri; 1518 action->new_outer_cfi = pcfg.pc_new_ocfi; 1519 return BCM_E_NONE; 1520 } 1521 1522 /* 1523 * Function: 1524 * _bcm_th3_vlan_action_profile_entry_increment 1525 * 1526 * Purpose : increment the refcount for a vlan action profile table entry 1527 * 1528 * Parameters: 1529 * unit - (IN) BCM unit. 1530 * index - (IN) 1531 * 1532 * Returns: 1533 * 1534 * Notes: 1535 */ 1536 STATIC void 1537 _bcm_th3_vlan_action_profile_entry_increment(int unit, uint32 index) 1538 { 1539 SOC_PROFILE_MEM_REFERENCE(unit, ing_action_profile[unit], index, 1); 1540 } 1541 1542 /* 1543 * Function: 1544 * _bcm_th3_vlan_port_default_action_delete 1545 * 1546 * Purpose: 1547 * Deletes the port's default vlan tag actions 1548 * 1549 * Parameters: 1550 * unit - (IN) BCM unit. 1551 * port - (IN) Port number. 1552 * 1553 * Returns: 1554 * BCM_E_XXX 1555 * 1556 * Notes: 1557 */ 1558 int 1559 _bcm_th3_vlan_port_default_action_delete(int unit, bcm_port_t port) 1560 { 1561 uint32 old_profile_idx; 1562 bcm_port_cfg_t pcfg; 1563 1564 BCM_IF_ERROR_RETURN 1565 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 1566 old_profile_idx = pcfg.pc_vlan_action; 1567 1568 pcfg.pc_vlan = BCM_VLAN_DEFAULT; 1569 pcfg.pc_vlan_action = ING_ACTION_PROFILE_DEFAULT; 1570 BCM_IF_ERROR_RETURN 1571 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 1572 1573 _bcm_th3_vlan_action_profile_entry_increment( 1574 unit, ING_ACTION_PROFILE_DEFAULT); 1575 BCM_IF_ERROR_RETURN 1576 (_bcm_th3_ing_vlan_action_profile_entry_delete(unit, old_profile_idx)); 1577 1578 return (BCM_E_NONE); 1579 } 1580 1581 #if defined(BCM_WARM_BOOT_SUPPORT) 1582 /* 1583 * Function: 1584 * _bcm_th3_vlan_xconnect_db_reinit 1585 * 1586 * Purpose: 1587 * In Warmboot, fill in the Cross Connect SW cached from the L2 HW table 1588 * 1589 * Parameters: 1590 * unit - (IN) BCM unit. 1591 * 1592 * Returns: 1593 * BCM_E_XXX 1594 * 1595 * Notes: 1596 */ 1597 int _bcm_th3_vlan_xconnect_db_reinit(int unit) { 1598 int rv = BCM_E_NONE; 1599 1600 /* Allocate memory for the database */ 1601 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_xconnect_db_init(unit)); 1602 1603 /* Acquire the Mutex */ 1604 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1605 1606 /* Invoke appr. function to parse through L2Xm */ 1607 rv = _bcm_th3_l2_cross_connect_entry_add_all(unit); 1608 1609 /* Release the Mutex */ 1610 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1611 1612 return rv; 1613 } 1614 #endif /* BCM_WARM_BOOT_SUPPORT */ 1615 1616 /* 1617 * Function: 1618 * _bcm_th3_vlan_xconnect_db_init 1619 * 1620 * Purpose: 1621 * Initialize/Allocate the Cross Connect SW cache 1622 * 1623 * Parameters: 1624 * unit - (IN) BCM unit. 1625 * 1626 * Returns: 1627 * BCM_E_NONE 1628 * BCM_E_MEMORY 1629 * 1630 * Notes: 1631 * If the memory is already available then only task 1632 * done is to invalidate all entries in SW cache. 1633 */ 1634 int _bcm_th3_vlan_xconnect_db_init(int unit) { 1635 1636 /* Allocate the mutex, if not allocated yet */ 1637 if (NULL == _bcm_th3_xconnect_mtx[unit]) { 1638 _bcm_th3_xconnect_mtx[unit] = sal_mutex_create("VlanXConnect"); 1639 if (NULL == _bcm_th3_xconnect_mtx[unit]) { 1640 return BCM_E_MEMORY; 1641 } 1642 } 1643 1644 /* Acquire the Mutex */ 1645 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1646 1647 /* Allocate the database, if not yet allocated */ 1648 if (NULL == _bcm_th3_xconnect_db[unit]) { 1649 _bcm_th3_xconnect_db[unit] = 1650 sal_alloc(sizeof(_bcm_th3_vlan_xconnect_db_t), "XConnectDB"); 1651 1652 if (NULL == _bcm_th3_xconnect_db[unit]) { 1653 sal_free(_bcm_th3_xconnect_mtx[unit]); 1654 _bcm_th3_xconnect_mtx[unit] = NULL; 1655 return BCM_E_MEMORY; 1656 } 1657 } 1658 1659 /* Clear the state to begin-with */ 1660 SHR_BITCLR_RANGE(_bcm_th3_xconnect_db[unit]->valid, 0, BCM_VLAN_COUNT); 1661 1662 /* Release the Mutex */ 1663 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1664 1665 return BCM_E_NONE; 1666 } 1667 1668 /* 1669 * Function: 1670 * _bcm_th3_vlan_xconnect_db_destroy 1671 * 1672 * Purpose: 1673 * Deallocate the Cross Connect SW cache 1674 * 1675 * Parameters: 1676 * unit - (IN) BCM unit. 1677 * 1678 * Returns: 1679 * BCM_E_NONE 1680 * 1681 * Notes: 1682 * The Mutex is not destroyed 1683 */ 1684 int _bcm_th3_vlan_xconnect_db_destroy(int unit) { 1685 1686 /* Acquire the Mutex */ 1687 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1688 1689 /* Deallocate memory */ 1690 if (NULL != _bcm_th3_xconnect_db[unit]) { 1691 sal_free(_bcm_th3_xconnect_db[unit]); 1692 _bcm_th3_xconnect_db[unit] = NULL; 1693 } 1694 1695 /* Release the Mutex */ 1696 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1697 1698 return BCM_E_NONE; 1699 } 1700 1701 /* 1702 * Function: 1703 * _bcm_th3_vlan_xconnect_db_entry_add 1704 * 1705 * Purpose: 1706 * Add cross connect entry to HW and SW database 1707 * 1708 * Parameters: 1709 * unit - (IN) BCM unit. 1710 * ovlan - (IN) Outer VLAN ID. 1711 * destt - (IN) array of 2, specifies the corresponding dst is TGID or Port 1712 * destv - (IN) array of 2, TGID or Port corresponding to two gports 1713 * 1714 * Returns: 1715 * BCM_E_XXX 1716 * 1717 * Notes: 1718 * 1) All incoming paramaters are assumed to be valid and hence no further 1719 * checks are performed on them 1720 * 2) Cross Connect Mutex is acquired in the very beginning as updating the 1721 * HW table and SW cache has to be atomic with respect to VLAN module 1722 */ 1723 int _bcm_th3_vlan_xconnect_db_entry_add( 1724 int unit, bcm_vlan_t ovlan, uint8 *destt, int *destv) { 1725 1726 int rv = BCM_E_NONE; 1727 1728 /* Acquire the Mutex */ 1729 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1730 1731 /* Add the entry to L2 table at first */ 1732 rv = _bcm_th3_l2_cross_connect_add(unit, ovlan, destt, destv); 1733 1734 /* Only when the entry is successfully added to HW table add it to cache */ 1735 if ( BCM_SUCCESS(rv) ) { 1736 1737 /* Add the destination value */ 1738 _bcm_th3_xconnect_db[unit]->destination[ 1739 BCM_TH3_VLAN_XC_DB_DESTTYPE_OFFSET(ovlan)] = (uint8) destv[0]; 1740 _bcm_th3_xconnect_db[unit]->destination[ 1741 BCM_TH3_VLAN_XC_DB_DESTTYPE1_OFFSET(ovlan)] = (uint8) destv[1]; 1742 1743 /* Add the distinguishing parameter - Trunk or Port */ 1744 SHR_BITWRITE(_bcm_th3_xconnect_db[unit]->dest_type, 1745 BCM_TH3_VLAN_XC_DB_DESTTYPE_OFFSET(ovlan), !!destt[0]); 1746 SHR_BITWRITE(_bcm_th3_xconnect_db[unit]->dest_type, 1747 BCM_TH3_VLAN_XC_DB_DESTTYPE1_OFFSET(ovlan), !!destt[1]); 1748 1749 /* Mark the entry valid */ 1750 SHR_BITSET(_bcm_th3_xconnect_db[unit]->valid, ovlan); 1751 } 1752 1753 /* Release the Mutex */ 1754 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1755 1756 return rv; 1757 } 1758 1759 /* 1760 * Function: 1761 * _bcm_th3_vlan_xconnect_db_entry_delete 1762 * 1763 * Purpose: 1764 * Delete cross connect entry from HW and SW database 1765 * 1766 * Parameters: 1767 * unit - (IN) BCM unit. 1768 * ovlan - (IN) Outer VLAN ID. 1769 * 1770 * Returns: 1771 * BCM_E_XXX 1772 * 1773 * Notes: 1774 * Cross Connect Mutex is acquired in the very beginning as updating 1775 * the HW table and SW cache has to be atomic with respect to VLAN module 1776 */ 1777 int _bcm_th3_vlan_xconnect_db_entry_delete(int unit, bcm_vlan_t ovlan) { 1778 1779 int rv = BCM_E_NONE; 1780 1781 #ifdef BCM_TRX_SUPPORT 1782 /* Acquire the Mutex */ 1783 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1784 1785 /* Delete the entry in L2 HW Table at first */ 1786 rv = bcm_tr_l2_cross_connect_delete(unit, ovlan, BCM_VLAN_INVALID); 1787 1788 /* Invalidate the entry in SW cache, only when HW table entry is deleted */ 1789 if( BCM_SUCCESS(rv) ) { 1790 SHR_BITCLR(_bcm_th3_xconnect_db[unit]->valid, ovlan); 1791 } 1792 1793 /* Release the Mutex */ 1794 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1795 #else 1796 rv = BCM_E_UNAVAIL; 1797 #endif 1798 1799 return rv; 1800 } 1801 1802 /* 1803 * Function: 1804 * _bcm_th3_vlan_xconnect_db_entry_delete_all 1805 * 1806 * Purpose: 1807 * Delete all cross connect entries from HW and SW database 1808 * 1809 * Parameters: 1810 * unit - (IN) BCM unit. 1811 * 1812 * Returns: 1813 * BCM_E_XXX 1814 * 1815 * Notes: 1816 * Cross Connect Mutex is acquired in the very beginning as updating 1817 * the HW table and SW cache has to be atomic with respect to VLAN module 1818 */ 1819 int _bcm_th3_vlan_xconnect_db_entry_delete_all(int unit) { 1820 1821 int rv = BCM_E_NONE; 1822 1823 #ifdef BCM_TRX_SUPPORT 1824 /* Acquire the Mutex */ 1825 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1826 1827 /* Update L2 HW Table at first */ 1828 rv = bcm_tr_l2_cross_connect_delete_all(unit); 1829 1830 /* Invalidate all entries in SW cache, only when HW is updated accord. */ 1831 if( BCM_SUCCESS(rv) ) { 1832 SHR_BITCLR_RANGE(_bcm_th3_xconnect_db[unit]->valid, 0, BCM_VLAN_COUNT); 1833 } 1834 1835 /* Release the Mutex */ 1836 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1837 #else 1838 rv = BCM_E_UNAVAIL; 1839 #endif 1840 1841 return rv; 1842 } 1843 1844 /* 1845 * Function: 1846 * _bcm_th3_vlan_xconnect_traverse 1847 * 1848 * Purpose: 1849 * Walks through the valid cross connect entries and 1850 * calls the user supplied callback function for each entry. 1851 * 1852 * Parameters: 1853 * unit - (IN) BCM unit. 1854 * cb - (IN) Callback function. 1855 * user_data - (IN) User data to be passed to callback function. 1856 * 1857 * Returns: 1858 * BCM_E_XXX 1859 * 1860 * Notes: 1861 */ 1862 int 1863 _bcm_th3_vlan_xconnect_traverse(int unit, 1864 bcm_vlan_cross_connect_traverse_cb cb, 1865 void *user_data) 1866 { 1867 int rv = BCM_E_NONE; 1868 uint32 destv; 1869 bcm_vlan_t ovlan; 1870 bcm_gport_t gport_1; 1871 bcm_gport_t gport_2; 1872 bcm_module_t local_modid; 1873 1874 /* Get hold of chip local MODID */ 1875 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &local_modid)); 1876 1877 /* Acquire the Mutex */ 1878 BCM_TH3_VLAN_XCONNECT_MUTEX_ACQ(unit); 1879 1880 /* Iterate through all valid cross connect entries */ 1881 SHR_BIT_ITER(_bcm_th3_xconnect_db[unit]->valid, BCM_VLAN_COUNT, ovlan) { 1882 1883 /* Deduce the first gport */ 1884 destv = _bcm_th3_xconnect_db[unit]-> 1885 destination[BCM_TH3_VLAN_XC_DB_DESTTYPE_OFFSET(ovlan)]; 1886 if (SHR_BITGET(_bcm_th3_xconnect_db[unit]->dest_type, 1887 BCM_TH3_VLAN_XC_DB_DESTTYPE_OFFSET(ovlan))) { 1888 BCM_GPORT_TRUNK_SET(gport_1, destv); 1889 } else { 1890 BCM_GPORT_MODPORT_SET(gport_1, local_modid, destv); 1891 } 1892 1893 /* Deduce the second gport */ 1894 destv = _bcm_th3_xconnect_db[unit]-> 1895 destination[BCM_TH3_VLAN_XC_DB_DESTTYPE1_OFFSET(ovlan)]; 1896 if (SHR_BITGET(_bcm_th3_xconnect_db[unit]-> 1897 dest_type, BCM_TH3_VLAN_XC_DB_DESTTYPE1_OFFSET(ovlan))) { 1898 BCM_GPORT_TRUNK_SET(gport_2, destv); 1899 } else { 1900 BCM_GPORT_MODPORT_SET(gport_2, local_modid, destv); 1901 } 1902 1903 /* Call application call-back */ 1904 rv = cb(unit, ovlan, BCM_VLAN_INVALID, gport_1, gport_2, user_data); 1905 #ifdef BCM_CB_ABORT_ON_ERR 1906 if (BCM_FAILURE(rv) && SOC_CB_ABORT_ON_ERR(unit)) { 1907 break; 1908 } 1909 #endif 1910 } 1911 1912 /* Release the Mutex */ 1913 BCM_TH3_VLAN_XCONNECT_MUTEX_REL(unit); 1914 1915 return rv; 1916 } 1917 1918 /* 1919 * Function: 1920 * bcm_th3_vlan_port_add 1921 * 1922 * Purpose: 1923 * Invokes low level functions to program the port membership bitmaps 1924 * in tables VLAN_2 and EGR_VLAN. 1925 * 1926 * Parameters: 1927 * unit - (IN) BCM unit. 1928 * vid - (IN) VLAN Identifier. 1929 * pbmp - (IN) Egress Tagged Port Bitmap to be added to the VLAN. 1930 * upbmp - (IN) Egress Untagged Port Bitmap to be added to the VLAN. 1931 * ing_pbmp - (IN) Ingress Port Bitmap to be added to the VLAN. 1932 * 1933 * Returns: 1934 * BCM_E_NONE 1935 * BCM_E_PARAM 1936 * BCM_E_NOT_FOUND 1937 * BCM_E_FAIL 1938 * BCM_E_FULL 1939 * 1940 * Notes: 1941 */ 1942 int 1943 bcm_th3_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 1944 pbmp_t ing_pbmp) 1945 { 1946 if (BCM_VLAN_VALID(vid)) { 1947 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_port_add( 1948 unit, vid, pbmp, ubmp, ing_pbmp, VLAN_2_TABm)); 1949 1950 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_port_add( 1951 unit, vid, pbmp, ubmp, ing_pbmp, EGR_VLANm)); 1952 } 1953 1954 return BCM_E_NONE; 1955 } 1956 1957 /* 1958 * Function: 1959 * bcm_th3_vlan_port_remove 1960 * 1961 * Purpose: 1962 * Invokes low level functions to remove the ports in the given bitmaps 1963 * from tables VLAN_2 and EGR_VLAN. 1964 * 1965 * Parameters: 1966 * unit - (IN) BCM unit. 1967 * vid - (IN) VLAN Identifier. 1968 * pbmp - (IN) Egress Tagged Port Bitmap to be removed from the VLAN. 1969 * upbmp - (IN) Egress Untagged Port Bitmap to be removed from the VLAN. 1970 * ing_pbmp - (IN) Ingress Port Bitmap to be removed from the VLAN. 1971 * 1972 * Returns: 1973 * BCM_E_NONE 1974 * BCM_E_PARAM 1975 * BCM_E_NOT_FOUND 1976 * BCM_E_FAIL 1977 * BCM_E_FULL 1978 * 1979 * Notes: 1980 */ 1981 int 1982 bcm_th3_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 1983 pbmp_t ing_pbmp) 1984 { 1985 if (BCM_VLAN_VALID(vid)) { 1986 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_port_remove( 1987 unit, vid, pbmp, ubmp, ing_pbmp, VLAN_2_TABm)); 1988 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_port_remove( 1989 unit, vid, pbmp, ubmp, ing_pbmp, EGR_VLANm)); 1990 } 1991 return BCM_E_NONE; 1992 } 1993 1994 #ifndef BCM_SW_STATE_DUMP_DISABLE 1995 /* 1996 * Function: 1997 * _bcm_th3_vlan_sw_tag_action_profile_dump 1998 * 1999 * Purpose: 2000 * Displays VLAN Tag action information maintained by software. 2001 * 2002 * Parameters: 2003 * unit - (IN) BCM unit. 2004 * 2005 * Returns: 2006 * 2007 * Notes: 2008 */ 2009 void 2010 _bcm_th3_vlan_sw_tag_action_profile_dump(int unit) 2011 { 2012 int num_entries; 2013 int ref_count; 2014 int entries_per_set; 2015 int index, idx; 2016 void *entry; 2017 soc_mem_t mem; 2018 soc_profile_mem_t *profile[2]; 2019 2020 profile[0] = ing_action_profile[unit]; 2021 profile[1] = egr_action_profile[unit]; 2022 2023 for (idx = 0 ; idx < 2 ; idx++) { 2024 if (NULL != profile[idx]) { 2025 LOG_CLI((BSL_META_U(unit, 2026 "\nSW Information %sgress VLAN Action Profile - Unit %d\n") 2027 , (ing_action_profile[unit] == profile[idx])?"In":"E", unit)); 2028 2029 mem = profile[idx]->tables[0].mem; 2030 num_entries = soc_mem_index_count(unit, mem); 2031 LOG_CLI((BSL_META_U(unit, " Number of entries: %d\n\n"), num_entries)); 2032 for (index = 0; index < num_entries; index ++) { 2033 if (SOC_FAILURE( 2034 soc_profile_mem_ref_count_get( 2035 unit, profile[idx], index, &ref_count))) { 2036 break; 2037 } 2038 2039 /* Display entries with reference count > 0 */ 2040 if (ref_count <= 0) { 2041 continue; 2042 } 2043 2044 entries_per_set = 2045 profile[idx]->tables[0].entries[index].entries_per_set; 2046 entry = SOC_PROFILE_MEM_ENTRY(unit, profile[idx], void *, index); 2047 2048 LOG_CLI((BSL_META_U(unit, " Index = 0x%x\n"), index)); 2049 LOG_CLI((BSL_META_U(unit, " Reference count = %d\n"), ref_count)); 2050 LOG_CLI((BSL_META_U(unit, " Entries per set = %d\n") 2051 , entries_per_set)); 2052 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 2053 LOG_CLI((BSL_META_U(unit, "\n\n"))); 2054 } 2055 } 2056 } 2057 2058 return; 2059 } 2060 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 2061 #else /* BCM_TOMAHAWK3_SUPPORT */ 2062 int _tomahawk3_vlan_not_empty; 2063 #endif /* BCM_TOMAHAWK3_SUPPORT */