vlan.c (271662B)
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 XGS3 VLAN resources 9 */ 10 11 #include <sal/core/boot.h> 12 #include <shared/bsl.h> 13 #include <soc/drv.h> 14 #include <soc/mem.h> 15 16 #include <bcm/error.h> 17 #include <bcm/vlan.h> 18 19 #include <bcm_int/esw/mbcm.h> 20 #include <bcm_int/esw/field.h> 21 #include <bcm_int/esw/firebolt.h> 22 #include <bcm_int/esw/trx.h> 23 /* #include <bcm_int/esw/firebolt.h> */ 24 #if defined(BCM_TRIUMPH_SUPPORT) 25 #include <bcm_int/esw/triumph.h> 26 #endif /* BCM_TRIUMPH_SUPPORT */ 27 #if defined(BCM_TRIUMPH2_SUPPORT) 28 #include <bcm_int/esw/triumph2.h> 29 #include <bcm_int/common/multicast.h> 30 #endif /* BCM_TRIUMPH2_SUPPORT */ 31 #if defined(BCM_TRIDENT_SUPPORT) 32 #include <bcm_int/esw/trident.h> 33 #include <bcm_int/common/multicast.h> 34 #endif /* BCM_TRIUMPH2_SUPPORT */ 35 #include <bcm_int/esw/port.h> 36 #include <bcm_int/esw/vlan.h> 37 #include <bcm_int/esw/multicast.h> 38 #include <bcm_int/esw/xgs3.h> 39 #include <bcm_int/esw/vpn.h> 40 #include <bcm_int/esw/trill.h> 41 42 #include <bcm_int/esw_dispatch.h> 43 #if defined(BCM_TRIDENT2_SUPPORT) 44 #include <bcm_int/esw/trident2.h> 45 #endif 46 #if defined(BCM_KATANA2_SUPPORT) 47 #include <bcm_int/esw/katana2.h> 48 #endif 49 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50 #include <bcm_int/esw/trident2plus.h> 51 #include <bcm_int/esw/virtual.h> 52 #endif 53 54 #if defined(BCM_TRIDENT3_SUPPORT) 55 #include <bcm_int/esw/trident3.h> 56 #endif 57 #if defined(BCM_GREYHOUND2_SUPPORT) 58 #include <bcm_int/esw/greyhound2.h> 59 #endif 60 61 #if defined(BCM_TOMAHAWK3_SUPPORT) 62 #include <bcm_int/esw/tomahawk3.h> 63 #endif 64 65 #define TABLE_HAS_UT_BITMAP(unit, table) \ 66 ((SOC_IS_FBX(unit) && \ 67 (!soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) && \ 68 (table) == EGR_VLANm) || \ 69 (SOC_IS_KATANA2 (unit) && (table) == VLAN_TABm)) 70 71 #define TABLE_HAS_T_BITMAP(unit, table) \ 72 (((table) == VLAN_TABLE(unit)) || \ 73 (soc_feature(unit, soc_feature_egr_vlan_check) && (table) == EGR_VLANm)) 74 75 #define TABLE_HAS_PFM(unit, table) \ 76 (((table) == VLAN_TABm) || \ 77 (soc_feature(unit, soc_feature_egr_vlan_pfm) && (table) == EGR_VLANm)) 78 79 #ifdef BCM_KATANA_SUPPORT 80 #define _BCM_QOS_MAP_TYPE_MASK 0x3ff 81 #define _BCM_QOS_MAP_SHIFT 10 82 #define _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE 5 83 #define _BCM_QOS_MAP_ING_QUEUE_OFFSET_MAX 7 84 #endif 85 86 #define BCM_PROTO_PKT_CONTROL_MAX 64 87 /* 88 * Function : 89 * _bcm_vlan_mcast_flood_mode_to_pfm 90 * 91 * Purpose : 92 * Encode vlan flood mode to pfm value. 93 * 94 * Parameters : 95 * unit - (IN) BCM device number. 96 * mode - (IN) Vlan flood mode. 97 * pfm - (OUT) PFM value. 98 * 99 * Return : 100 * BCM_E_XXX 101 */ 102 int 103 _bcm_vlan_mcast_flood_mode_to_pfm(int unit, int mode, int *pfm) 104 { 105 COMPILER_REFERENCE(unit); 106 107 if (NULL == pfm) { 108 return (BCM_E_PARAM); 109 } 110 111 switch (mode) { 112 case BCM_VLAN_MCAST_FLOOD_ALL: 113 *pfm = 0; 114 break; 115 case BCM_VLAN_MCAST_FLOOD_NONE: 116 *pfm = 2; 117 break; 118 default: 119 *pfm = 1; 120 } 121 return (BCM_E_NONE); 122 } 123 124 /* 125 * Function : 126 * _bcm_vlan_mcast_pfm_to_flood_mode 127 * 128 * Purpose : 129 * Decode pfm value to vlan flood mode enumerator. 130 * 131 * Parameters : 132 * unit - (IN) BCM device number. 133 * pfm - (IN) PFM value. 134 * mode - (OUT) Vlan flood mode. 135 * 136 * Return : 137 * BCM_E_XXX 138 */ 139 int 140 _bcm_vlan_mcast_pfm_to_flood_mode(int unit, int pfm, 141 bcm_vlan_mcast_flood_t *mode) 142 { 143 COMPILER_REFERENCE(unit); 144 145 if (NULL == mode) { 146 return (BCM_E_PARAM); 147 } 148 149 switch (pfm) { 150 case 0: 151 *mode = BCM_VLAN_MCAST_FLOOD_ALL; 152 break; 153 case 1: 154 *mode = BCM_VLAN_MCAST_FLOOD_UNKNOWN; 155 break; 156 case 2: 157 *mode = BCM_VLAN_MCAST_FLOOD_NONE; 158 break; 159 default: 160 return (BCM_E_PARAM); 161 } 162 return (BCM_E_NONE); 163 } 164 165 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 166 || defined(BCM_RAVEN_SUPPORT) 167 typedef struct _vlan_outer_tpid_s { 168 uint16 tpid; 169 int ref_count; 170 } _vlan_outer_tpid_t; 171 172 #define BCM_MAX_TPID_ENTRIES 4 173 174 STATIC _vlan_outer_tpid_t 175 (*_vlan_outer_tpid_tab[BCM_MAX_NUM_UNITS])[BCM_MAX_TPID_ENTRIES]; 176 STATIC sal_mutex_t _fb2_outer_tpid_lock[BCM_MAX_NUM_UNITS]; 177 178 #define OUTER_TPID_TAB(unit) _vlan_outer_tpid_tab[unit] 179 180 #define OUTER_TPID_ENTRY(unit, index) \ 181 ((*_vlan_outer_tpid_tab[unit])[index].tpid) 182 183 #define OUTER_TPID_REF_COUNT(unit, index) \ 184 ((*_vlan_outer_tpid_tab[unit])[index].ref_count) 185 186 #define OUTER_TPID_TAB_INIT_CHECK(unit) \ 187 if (OUTER_TPID_TAB(unit) == NULL) { return BCM_E_INIT; } 188 189 #define BCM_FB2_TPID_MUTEX(_u_) _fb2_outer_tpid_lock[_u_] 190 191 #define BCM_FB2_TPID_LOCK(_u_) \ 192 ((_fb2_outer_tpid_lock[_u_]) ? \ 193 sal_mutex_take(_fb2_outer_tpid_lock[_u_], sal_mutex_FOREVER) : \ 194 (BCM_E_INTERNAL)) 195 196 #define BCM_FB2_TPID_UNLOCK(_u_) \ 197 ((_fb2_outer_tpid_lock[_u_]) ? \ 198 sal_mutex_give(_fb2_outer_tpid_lock[_u_]) : \ 199 (BCM_E_INTERNAL)) 200 201 202 /* 203 * Function: 204 * _bcm_fb2_outer_tpid_detach 205 * Purpose: 206 * De-allocate and initialize memory to cache tpid entries. 207 * Initialize lock for cached tpid entries. 208 * Parameters: 209 * unit - (IN)SOC unit number. 210 * Returns: 211 * BCM_E_XXX 212 * Notes: 213 */ 214 int 215 _bcm_fb2_outer_tpid_detach(int unit) 216 { 217 sal_free (OUTER_TPID_TAB(unit)); 218 OUTER_TPID_TAB(unit) = NULL; 219 220 if (NULL != BCM_FB2_TPID_MUTEX(unit)) { 221 sal_mutex_destroy(BCM_FB2_TPID_MUTEX(unit)); 222 BCM_FB2_TPID_MUTEX(unit) = NULL; 223 } 224 return (BCM_E_NONE); 225 } 226 227 /* 228 * Function: 229 * _bcm_fb2_outer_tpid_init 230 * Purpose: 231 * Allocate and initialize memory to cache tpid entries. 232 * Initialize lock for cached tpid entries. 233 * Parameters: 234 * unit - (IN)SOC unit number. 235 * Returns: 236 * BCM_E_XXX 237 * Notes: 238 */ 239 int 240 _bcm_fb2_outer_tpid_init(int unit) { 241 int index; 242 int alloc_size; 243 bcm_port_t port; 244 uint32 reg32; 245 int enabled; 246 uint32 value; 247 bcm_pbmp_t all_pbmp; 248 249 /* Allocate memory to cache ING_OUTER_TPID entries. 250 * ING_OUTER_TPID entries are always the same as 251 * EGR_OUTER_TPID entries. 252 */ 253 alloc_size = sizeof(_vlan_outer_tpid_t) * BCM_MAX_TPID_ENTRIES; 254 if (OUTER_TPID_TAB(unit) == NULL) { 255 OUTER_TPID_TAB(unit) = sal_alloc(alloc_size, 256 "Cached ingress outer TPIDs"); 257 if (OUTER_TPID_TAB(unit) == NULL) { 258 return BCM_E_MEMORY; 259 } 260 } 261 sal_memset(OUTER_TPID_TAB(unit), 0, alloc_size); 262 263 /* Cache ingress outer TPID table */ 264 for (index = 0; index < BCM_MAX_TPID_ENTRIES; index++) { 265 uint32 outer_tpid = 0; 266 267 if (SOC_IS_TRIDENT3X(unit)) { 268 soc_reg_t ing_outer_tpid_reg[] = { 269 ING_OUTER_TPID_0r, 270 ING_OUTER_TPID_1r, 271 ING_OUTER_TPID_2r, 272 ING_OUTER_TPID_3r 273 }; 274 if (SOC_WARM_BOOT(unit)) { 275 BCM_IF_ERROR_RETURN 276 (soc_reg32_get(unit, ing_outer_tpid_reg[index], REG_PORT_ANY, 277 0, &outer_tpid)); 278 OUTER_TPID_ENTRY(unit, index) = 279 soc_reg_field_get(unit, ing_outer_tpid_reg[index], outer_tpid, TPIDf); 280 } else { 281 uint32 ing_outer_tpid_init_val[] = { 282 0x8100, 283 0x9100, 284 0x88a8, 285 0xaa8a 286 }; 287 soc_reg_field_set(unit, ing_outer_tpid_reg[index], 288 &outer_tpid, TPIDf, 289 ing_outer_tpid_init_val[index]); 290 BCM_IF_ERROR_RETURN 291 (soc_reg32_set(unit, ing_outer_tpid_reg[index], REG_PORT_ANY, 292 0, outer_tpid)); 293 294 OUTER_TPID_ENTRY(unit, index) = ing_outer_tpid_init_val[index]; 295 } 296 } else { 297 BCM_IF_ERROR_RETURN 298 (READ_ING_OUTER_TPIDr(unit, index, &outer_tpid)); 299 OUTER_TPID_ENTRY(unit, index) = 300 soc_reg_field_get(unit, ING_OUTER_TPIDr, outer_tpid, TPIDf); 301 } 302 } 303 304 /* All port has a reference to TPID */ 305 BCM_PBMP_CLEAR(all_pbmp); 306 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 307 308 #ifdef BCM_KATANA2_SUPPORT 309 if (soc_feature(unit, soc_feature_linkphy_coe) || 310 soc_feature(unit, soc_feature_subtag_coe)) { 311 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 312 } 313 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 314 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 315 } 316 #endif 317 318 PBMP_ITER(all_pbmp, port) { 319 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 320 if (soc_feature(unit, soc_feature_egr_all_profile)) { 321 BCM_IF_ERROR_RETURN( 322 bcm_esw_port_egr_lport_field_get(unit, port, 323 EGR_VLAN_CONTROL_1m, OUTER_TPID_INDEXf, (void *)&index)); 324 } else { 325 BCM_IF_ERROR_RETURN( 326 READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &value)); 327 index = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_1m, &value, 328 OUTER_TPID_INDEXf); 329 } 330 } else { 331 BCM_IF_ERROR_RETURN 332 (READ_EGR_VLAN_CONTROL_1r(unit, port, ®32)); 333 index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 334 reg32, OUTER_TPID_INDEXf); 335 } 336 337 if (index < BCM_MAX_TPID_ENTRIES) { 338 OUTER_TPID_REF_COUNT(unit, index)++; 339 } 340 341 enabled = 0; 342 BCM_IF_ERROR_RETURN 343 (_bcm_esw_port_config_get(unit, port, 344 _bcmPortOuterTpidEnables, &enabled)); 345 index = 0; 346 while(enabled) { 347 if (enabled & 1) { 348 OUTER_TPID_REF_COUNT(unit, index)++; 349 } 350 enabled = enabled >> 1; 351 index++; 352 } 353 } 354 355 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLEm) && 356 !SOC_WARM_BOOT(unit)) { 357 int i, rv; 358 int i_min; 359 int i_max; 360 void *buf = NULL; 361 soc_mem_t mem = SYSTEM_CONFIG_TABLEm; 362 system_config_table_entry_t *entry; 363 364 buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), "syscfg_tbl"); 365 if (buf == NULL) { 366 return BCM_E_MEMORY; 367 } 368 369 i_min = soc_mem_index_min(unit, mem); 370 i_max = soc_mem_index_max(unit, mem); 371 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, i_min, i_max, buf); 372 if (BCM_FAILURE(rv)) { 373 soc_cm_sfree(unit, buf); 374 return rv; 375 } 376 377 for (i = i_min; i <= i_max; i++) { 378 entry = soc_mem_table_idx_to_pointer(unit, mem, 379 system_config_table_entry_t *, buf, i); 380 enabled = soc_mem_field32_get(unit, mem, entry, 381 OUTER_TPID_ENABLEf); 382 index = 0; 383 while (enabled) { 384 if (enabled & 1) { 385 OUTER_TPID_REF_COUNT(unit, index)++; 386 } 387 enabled = enabled >> 1; 388 index++; 389 } 390 } 391 soc_cm_sfree(unit, buf); 392 } 393 394 if (NULL == BCM_FB2_TPID_MUTEX(unit)) { 395 /* Create protection mutex. */ 396 BCM_FB2_TPID_MUTEX(unit) = sal_mutex_create("outer_tpid_lock"); 397 398 if (NULL == BCM_FB2_TPID_MUTEX(unit)) { 399 return (BCM_E_MEMORY); 400 } 401 } 402 return (BCM_E_NONE); 403 } 404 405 /* 406 * Function: 407 * _bcm_fb2_priority_map_init 408 * Purpose: 409 * Initialize the priority map table so that the incomming 410 * and outgoing priority are the same if the switch logic doesn't 411 * change it. 412 * Parameters: 413 * unit - (IN)SOC unit number. 414 * Returns: 415 * BCM_E_XXX 416 * Notes: 417 */ 418 int 419 _bcm_fb2_priority_map_init(int unit) 420 { 421 int priority; 422 int cfi; 423 bcm_color_t color; 424 bcm_port_t port; 425 bcm_color_t color_array[] = {bcmColorGreen, bcmColorYellow, bcmColorRed}; 426 int index; 427 bcm_pbmp_t all_pbmp; 428 429 #ifdef BCM_WARM_BOOT_SUPPORT 430 if (SOC_WARM_BOOT(unit)) { 431 return (BCM_E_NONE); 432 } 433 #endif /* BCM_WARM_BOOT_SUPPORT */ 434 435 BCM_PBMP_CLEAR(all_pbmp); 436 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 437 438 #ifdef BCM_KATANA2_SUPPORT 439 if (soc_feature(unit, soc_feature_linkphy_coe) || 440 soc_feature(unit, soc_feature_subtag_coe)) { 441 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 442 } 443 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 444 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 445 } 446 #endif 447 448 if (SOC_IS_TRIUMPH(unit) || SOC_IS_VALKYRIE(unit) 449 || !soc_feature(unit, soc_feature_qos_profile)) { 450 PBMP_ITER(all_pbmp, port) { 451 for (cfi = 0; cfi <= 1; cfi++) { 452 for (priority = 0; priority <= 7; priority++){ 453 color = _BCM_COLOR_DECODING(unit, cfi); 454 BCM_IF_ERROR_RETURN 455 (bcm_esw_port_vlan_priority_map_set 456 (unit, port, priority, cfi, priority, color)); 457 } 458 } 459 } 460 } 461 462 PBMP_ITER(all_pbmp, port) { 463 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 464 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 465 BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port, 466 EGR_QOS_PROFILE_INDEXf,0)); 467 } else if (SOC_IS_TRIDENT3X(unit)) { 468 BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port, 469 EGR_QOS_PROFILE_INDEXf,0)); 470 } else 471 #endif 472 { 473 for (index = 0; index < 3; index++) { 474 color = color_array[index]; 475 for (priority = 0; priority <= 7; priority++) { 476 cfi = (color == bcmColorRed) ? 1 : 0; 477 BCM_IF_ERROR_RETURN 478 (bcm_esw_port_vlan_priority_unmap_set(unit, port, priority, 479 color, priority, cfi)); 480 } 481 } 482 } 483 } 484 return (BCM_E_NONE); 485 } 486 487 /* 488 * Function : 489 * _bcm_fb2_outer_tpid_entry_get 490 * 491 * Purpose : 492 * Get tpid value for tpid entry index . 493 * 494 * Parameters : 495 * unit - (IN) BCM device number. 496 * tpid - (OUT) TPID value. 497 * index - (IN) Entry index. 498 * 499 * Return : 500 * BCM_E_XXX 501 */ 502 int 503 _bcm_fb2_outer_tpid_entry_get(int unit, uint16 *tpid, int index) 504 { 505 if ((index < 0) || (index >= BCM_MAX_TPID_ENTRIES) || 506 (OUTER_TPID_REF_COUNT(unit, index) <= 0)) { 507 return (BCM_E_PARAM); 508 } 509 510 *tpid = OUTER_TPID_ENTRY(unit, index); 511 return (BCM_E_NONE); 512 } 513 514 /* 515 * Function : 516 * _bcm_fb2_outer_tpid_entry_delete 517 * 518 * Purpose : 519 * Delete tpid entry by index. 520 * 521 * Parameters : 522 * unit - (IN) BCM device number. 523 * index - (IN) Entry index. 524 * 525 * Return : 526 * BCM_E_XXX 527 */ 528 int 529 _bcm_fb2_outer_tpid_entry_delete(int unit, int index) 530 { 531 int rv = BCM_E_NONE; 532 533 _bcm_fb2_outer_tpid_tab_lock(unit); 534 535 if ((index < 0) || (index >= BCM_MAX_TPID_ENTRIES) || 536 (OUTER_TPID_REF_COUNT(unit, index) <= 0)) { 537 rv = BCM_E_PARAM; 538 goto _cleanup_bcm_fb2_outer_tpid_entry_delete; 539 } 540 541 OUTER_TPID_REF_COUNT(unit, index)--; 542 543 #if defined(BCM_TRX_SUPPORT) 544 if ((0 == OUTER_TPID_REF_COUNT(unit, index)) && (SOC_IS_SC_CQ(unit)) && 545 (0 == SOC_IS_SHADOW(unit))) { 546 rv = _bcm_trx_egr_src_port_outer_tpid_set(unit, index, FALSE); 547 if (BCM_FAILURE(rv)) { 548 goto _cleanup_bcm_fb2_outer_tpid_entry_delete; 549 } 550 } 551 #endif /* BCM_TRX_SUPPORT */ 552 553 _cleanup_bcm_fb2_outer_tpid_entry_delete: 554 _bcm_fb2_outer_tpid_tab_unlock(unit); 555 return (rv); 556 } 557 558 /* 559 * Function : 560 * _bcm_fb2_outer_tpid_default_get 561 * 562 * Purpose : 563 * Get system default tpid value. 564 * 565 * Parameters : 566 * unit - (IN) BCM device number. 567 * 568 * Return : 569 * BCM_E_XXX 570 */ 571 uint16 572 _bcm_fb2_outer_tpid_default_get(int unit) 573 { 574 COMPILER_REFERENCE(unit); 575 return 0x8100; 576 } 577 578 /* 579 * Function : 580 * _bcm_fb2_outer_tpid_lkup 581 * 582 * Purpose : 583 * Get tpid entry index for specific tpid value. 584 * 585 * Parameters : 586 * unit - (IN) BCM device number. 587 * tpid - (IN) TPID value. 588 * index - (OUT) Entry index. 589 * 590 * Return : 591 * BCM_E_XXX 592 */ 593 int 594 _bcm_fb2_outer_tpid_lkup(int unit, uint16 tpid, int *index) 595 { 596 int i; 597 598 for (i = 0; i < BCM_MAX_TPID_ENTRIES; i++) { 599 if (OUTER_TPID_ENTRY(unit, i) == tpid) { 600 *index = i; 601 return BCM_E_NONE; 602 } 603 } 604 605 return BCM_E_NOT_FOUND; 606 } 607 608 /* 609 * Function: 610 * _bcm_fb2_outer_tpid_entry_add 611 * Purpose: 612 * Add a new TPID entry. 613 * Allocate and initialize memory to cache tpid entries. 614 * Initialize lock for cached tpid entries. 615 * Parameters: 616 * unit - (IN) SOC unit number. 617 * tpid - (IN) TPID to be added. 618 * index - (OUT) Index where the the new TPID is added. 619 * Returns: 620 * BCM_E_XXX 621 * Notes: 622 * If the same TPID already exists, simple increase the 623 * reference count of the cached entry. Otherwise, add the entry 624 * to the cached table and write the new entry to hardware. 625 * Only four distinct TPID values are currently supported. 626 */ 627 int 628 _bcm_fb2_outer_tpid_entry_add(int unit, uint16 tpid, int *index) 629 { 630 int i, free_index; 631 uint32 tpid_reg = 0; 632 int rv = BCM_E_NONE; 633 soc_reg_t ing_outer_tpid_reg[] = { 634 ING_OUTER_TPID_0r, 635 ING_OUTER_TPID_1r, 636 ING_OUTER_TPID_2r, 637 ING_OUTER_TPID_3r 638 }; 639 640 _bcm_fb2_outer_tpid_tab_lock(unit); 641 /* 642 * Search for an existing entry. 643 */ 644 free_index = -1; 645 for (i = 0; i < BCM_MAX_TPID_ENTRIES; i++) { 646 if (OUTER_TPID_ENTRY(unit, i) == tpid) { 647 OUTER_TPID_REF_COUNT(unit, i)++; 648 *index = i; 649 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 650 } 651 if (OUTER_TPID_REF_COUNT(unit, i) == 0) { 652 free_index = i; 653 } 654 } 655 656 if (free_index < 0) { 657 rv = BCM_E_RESOURCE; 658 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 659 } 660 661 /* 662 * Insert the new configuration into tpid table if a free 663 * entry is available. 664 */ 665 if (SOC_IS_TRIDENT3X(unit)) { 666 soc_reg_field_set(unit, ing_outer_tpid_reg[free_index], &tpid_reg, TPIDf, tpid); 667 rv = soc_reg32_set(unit, ing_outer_tpid_reg[free_index], REG_PORT_ANY, 0, tpid_reg); 668 } else { 669 soc_reg_field_set(unit, ING_OUTER_TPIDr, &tpid_reg, TPIDf, tpid); 670 rv = WRITE_ING_OUTER_TPIDr(unit, free_index, tpid_reg); 671 } 672 if (BCM_FAILURE(rv)) { 673 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 674 } 675 #if defined(BCM_TOMAHAWK_SUPPORT) 676 /* Skip EGR_OUTER_TPID for low latency mode, will be set via EGR_VLAN_TAG_ACTION_FOR_BYPASSr */ 677 if (!(soc_feature(unit, soc_feature_fast_egr_vlan_action))) { 678 rv = WRITE_EGR_OUTER_TPIDr(unit, free_index, tpid_reg); 679 } 680 #else 681 rv = WRITE_EGR_OUTER_TPIDr(unit, free_index, tpid_reg); 682 #endif 683 if (BCM_FAILURE(rv)) { 684 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 685 } 686 #if defined(BCM_TRIDENT3_SUPPORT) 687 if (SOC_REG_IS_VALID(unit, EGR_PARSER_OUTER_TPIDr)) { 688 rv = WRITE_EGR_PARSER_OUTER_TPIDr(unit, free_index, tpid_reg); 689 } 690 if (BCM_FAILURE(rv)) { 691 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 692 } 693 #endif 694 #ifdef BCM_TRIUMPH_SUPPORT 695 if (SOC_REG_IS_VALID(unit, ING_MPLS_TPID_0r)) { 696 rv = WRITE_ING_MPLS_TPIDr(unit, free_index, tpid_reg); 697 if (BCM_FAILURE(rv)) { 698 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 699 } 700 } 701 #endif /* BCM_TRIUMPH_SUPPORT */ 702 #if defined(BCM_TRX_SUPPORT) 703 if (SOC_IS_SC_CQ(unit)) { 704 rv = _bcm_trx_egr_src_port_outer_tpid_set(unit, free_index, TRUE); 705 if (BCM_FAILURE(rv)) { 706 goto _cleanup_bcm_fb2_outer_tpid_entry_add; 707 } 708 } 709 #endif /* BCM_TRX_SUPPORT */ 710 OUTER_TPID_ENTRY(unit, free_index) = tpid; 711 OUTER_TPID_REF_COUNT(unit, free_index)++; 712 *index = free_index; 713 714 _cleanup_bcm_fb2_outer_tpid_entry_add: 715 _bcm_fb2_outer_tpid_tab_unlock(unit); 716 return rv; 717 } 718 719 /* 720 * Function : 721 * _bcm_fb2_outer_tpid_tab_lock 722 * 723 * Purpose : 724 * Lock TPID values table. 725 * 726 * Parameters : 727 * unit - (IN) BCM device number. 728 * 729 * Return : 730 * BCM_E_XXX 731 */ 732 int 733 _bcm_fb2_outer_tpid_tab_lock(int unit) 734 { 735 return BCM_FB2_TPID_LOCK(unit); 736 } 737 738 /* 739 * Function : 740 * _bcm_fb2_outer_tpid_tab_unlock 741 * 742 * Purpose : 743 * Unlock TPID values table. 744 * 745 * Parameters : 746 * unit - (IN) BCM device number. 747 * 748 * Return : 749 * BCM_E_XXX 750 */ 751 int 752 _bcm_fb2_outer_tpid_tab_unlock(int unit) 753 { 754 return BCM_FB2_TPID_UNLOCK(unit); 755 } 756 757 /* 758 * Function : 759 * _bcm_fb2_outer_tpid_tab_ref_count_add 760 * 761 * Purpose : 762 * update tpid value reference count. 763 * 764 * Parameters : 765 * unit - (IN) BCM device number. 766 * index - (IN) Table entry index. 767 * count - (IN) Reference counter update diff. 768 * 769 * Return : 770 * BCM_E_XXX 771 */ 772 int 773 _bcm_fb2_outer_tpid_tab_ref_count_add(int unit, int index, int count) 774 { 775 if (index >= BCM_MAX_TPID_ENTRIES) { 776 return BCM_E_PARAM; 777 } 778 if ((OUTER_TPID_REF_COUNT(unit, index) + count) < 0) { 779 return BCM_E_PARAM; 780 } 781 _bcm_fb2_outer_tpid_tab_lock(unit); 782 783 OUTER_TPID_REF_COUNT(unit, index) += count; 784 785 _bcm_fb2_outer_tpid_tab_unlock(unit); 786 787 return BCM_E_NONE; 788 } 789 790 /* Flags for _vlan_profile_t.profile_flags. */ 791 #define _BCM_VLAN_PROFILE_PHB2_ENABLE 0x00000001 792 #define _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG 0x00000002 793 #define _BCM_VLAN_PROFILE_TRUST_DOT1P 0x00000004 794 795 /* 796 * Vlan profile structure. 797 * 798 * Purpose : Track per vlan configuration. 799 */ 800 typedef struct _vlan_profile_s { 801 uint16 outer_tpid; 802 uint32 flags; 803 bcm_vlan_mcast_flood_t ip6_mcast_flood_mode; 804 bcm_vlan_mcast_flood_t ip4_mcast_flood_mode; 805 bcm_vlan_mcast_flood_t l2_mcast_flood_mode; 806 #if defined (BCM_TRX_SUPPORT) 807 _trx_vlan_block_t block; 808 #endif /* BCM_TRX_SUPPORT */ 809 int qm_ptr; 810 int trust_dot1p_ptr; 811 uint32 profile_flags; /* _BCM_VLAN_PROFILE_XXX */ 812 int ref_count; 813 #if defined (BCM_TRX_SUPPORT) 814 bcm_vlan_protocol_packet_ctrl_t protocol_pkt; 815 #endif /* BCM_TRX_SUPPORT */ 816 #if defined (BCM_HURRICANE3_SUPPORT) 817 uint32 learn_flags; /* VLAN-based Learn control flags */ 818 #endif /* BCM_HURRICANE3_SUPPORT */ 819 } _vlan_profile_t; 820 821 static _vlan_profile_t (*_vlan_profile[BCM_MAX_NUM_UNITS])[]; 822 823 #define VLAN_PROFILE(_unit_) _vlan_profile[_unit_] 824 825 #define VLAN_PROFILE_ENTRY(_unit_, _idx_) (*VLAN_PROFILE(_unit_))[(_idx_)] 826 827 #define VLAN_PROFILE_REF_COUNT(_unit_, _idx_) \ 828 VLAN_PROFILE_ENTRY(_unit_, _idx_).ref_count 829 830 #if defined(BCM_EASY_RELOAD_SUPPORT) 831 typedef struct _vlan_profile_er_s { 832 uint8 profile_num; 833 } _vlan_profile_er_t; 834 835 static _vlan_profile_er_t (*_vlan_profile_er[BCM_MAX_NUM_UNITS])[]; 836 837 #define VLAN_PROFILE_ER(_unit_) (_vlan_profile_er[_unit_]) 838 #define VLAN_PROFILE_PTR_ER(unit, vlan) \ 839 ((*_vlan_profile_er[unit])[vlan].profile_num) 840 #endif 841 842 /* 843 * Function : 844 * _vlan_profile_idx_get 845 * 846 * Purpose : 847 * Get programmed vlan profile index. 848 * 849 * Parameters : 850 * unit - (IN) BCM device number. 851 * mem - (IN) Memory name. 852 * field - (IN) VLAN profile index field. 853 * buf - (IN) HW entry buffer. 854 * vlan - (IN) Vlan id profile attached. 855 * profile_idx - (OUT) Profile index. 856 * 857 * Return : 858 * BCM_E_XXX 859 */ 860 STATIC int 861 _vlan_profile_idx_get(int unit, soc_mem_t mem, soc_field_t field, 862 uint32 *buf, bcm_vlan_t vlan, int *profile_index) 863 { 864 uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS]; 865 uint32 *hw_buf_ptr; 866 int rv; 867 868 /* Input parameters check. */ 869 if (NULL == profile_index) { 870 return (BCM_E_PARAM); 871 } 872 873 #if defined(BCM_EASY_RELOAD_SUPPORT) 874 if (SOC_IS_RELOADING(unit)) { 875 /* 876 * Use VLAN_PROFILE_ER() as a write-through cache 877 * for VLAN profile pointers during easy reload 878 */ 879 *profile_index = VLAN_PROFILE_PTR_ER(unit, vlan); 880 } else 881 #endif 882 { 883 if (NULL == buf) { 884 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, vlan, hw_buf); 885 BCM_IF_ERROR_RETURN(rv); 886 hw_buf_ptr = hw_buf; 887 } else { 888 hw_buf_ptr = buf; 889 } 890 if (0 == soc_mem_field32_get(unit, mem, hw_buf_ptr, VALIDf)) { 891 return BCM_E_NOT_FOUND; 892 } 893 *profile_index = soc_mem_field32_get(unit, mem, hw_buf_ptr, field); 894 } 895 return (BCM_E_NONE); 896 } 897 898 /* 899 * Function : 900 * _vlan_profile_idx_set 901 * 902 * Purpose : 903 * Set vlan profile index in vlan table. 904 * 905 * Parameters : 906 * unit - (IN) BCM device number. 907 * mem - (IN) Memory name. 908 * field - (IN) VLAN profile index field. 909 * buf - (IN) HW entry buffer. 910 * vlan - (IN) Vlan id profile attached. 911 * profile_idx - (IN) Profile index. 912 * 913 * Return : 914 * BCM_E_XXX 915 */ 916 STATIC int 917 _vlan_profile_idx_set(int unit, soc_mem_t mem, soc_field_t field, 918 uint32 *buf, bcm_vlan_t vlan, int profile_index) 919 { 920 /* Input parameters check. */ 921 if (NULL == buf) { 922 return (BCM_E_PARAM); 923 } 924 925 #if defined(BCM_EASY_RELOAD_SUPPORT) 926 if (SOC_IS_RELOADING(unit)) { 927 /* 928 * Use VLAN_PROFILE_ER() as a write-through cache 929 * for VLAN profile pointers during easy reload 930 */ 931 VLAN_PROFILE_PTR_ER(unit, vlan) = (uint8) profile_index; 932 } else 933 #endif 934 { 935 soc_mem_field32_set(unit, mem, buf, field, profile_index); 936 } 937 return (BCM_E_NONE); 938 } 939 940 /* 941 * Function: 942 * _bcm_xgs3_protocol_pkt_ctrl_get 943 * Purpose: 944 * function to get protocol packet action for given protocol 945 * control register table index. 946 * Parameters: 947 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 948 * proto_index - (IN) index in PROTOCOL_PKT_CONTROLr and 949 * IGMP_MLD_PKT_CONTROLr 950 * protocol_pkt- (OUT) protocol packet actions configured 951 * Returns: 952 * BCM_E_NONE - protocol packet action get is successful. 953 * BCM_E_XXX - Other error 954 * Notes: 955 * None. 956 */ 957 int 958 _bcm_xgs3_protocol_pkt_ctrl_get(int unit, int proto_index, 959 bcm_vlan_protocol_packet_ctrl_t *protocol_pkt) 960 { 961 #if defined (BCM_TRX_SUPPORT) 962 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 963 soc_reg_t reg; 964 uint64 regval; 965 uint32 value = 0; 966 int pkt_action = 0; 967 968 COMPILER_64_ZERO(regval); 969 970 reg = PROTOCOL_PKT_CONTROLr; 971 BCM_IF_ERROR_RETURN 972 (soc_reg_get(unit, reg, REG_PORT_ANY, proto_index, ®val)); 973 974 pkt_action = 0; 975 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_TO_CPUf)) { 976 value = soc_reg64_field32_get(unit, reg, regval, ARP_REPLY_TO_CPUf); 977 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 978 } 979 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_DROPf)) { 980 value = soc_reg64_field32_get(unit, reg, regval, ARP_REPLY_DROPf); 981 pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0; 982 } 983 protocol_pkt->arp_reply_action = pkt_action; 984 985 pkt_action = 0; 986 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_TO_CPUf)) { 987 value = soc_reg64_field32_get(unit, reg, regval, 988 ARP_REQUEST_TO_CPUf); 989 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 990 } 991 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_DROPf)) { 992 value = soc_reg64_field32_get(unit, reg, regval, ARP_REQUEST_DROPf); 993 pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0; 994 } 995 protocol_pkt->arp_request_action = pkt_action; 996 997 pkt_action = 0; 998 if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_TO_CPUf)) { 999 value = soc_reg64_field32_get(unit, reg, regval, ND_PKT_TO_CPUf); 1000 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1001 } 1002 if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_DROPf)) { 1003 value = soc_reg64_field32_get(unit, reg, regval, ND_PKT_DROPf); 1004 pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0; 1005 } 1006 protocol_pkt->nd_action = pkt_action; 1007 1008 pkt_action = 0; 1009 if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_TO_CPUf)) { 1010 value = soc_reg64_field32_get(unit, reg, regval, DHCP_PKT_TO_CPUf); 1011 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1012 } 1013 if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_DROPf)) { 1014 value = soc_reg64_field32_get(unit, reg, regval, DHCP_PKT_DROPf); 1015 pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0; 1016 } 1017 protocol_pkt->dhcp_action = pkt_action; 1018 1019 pkt_action = 0; 1020 if (SOC_REG_FIELD_VALID(unit, reg, MMRP_PKT_TO_CPUf)) { 1021 value = soc_reg64_field32_get(unit, reg, regval, MMRP_PKT_TO_CPUf); 1022 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1023 } 1024 if (SOC_REG_FIELD_VALID(unit, reg, MMRP_FWD_ACTIONf)) { 1025 value = soc_reg64_field32_get(unit, reg, regval, MMRP_FWD_ACTIONf); 1026 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1027 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1028 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1029 } 1030 protocol_pkt->mmrp_action = pkt_action; 1031 1032 pkt_action = 0; 1033 if (SOC_REG_FIELD_VALID(unit, reg, SRP_PKT_TO_CPUf)) { 1034 value = soc_reg64_field32_get(unit, reg, regval, SRP_PKT_TO_CPUf); 1035 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1036 } 1037 if (SOC_REG_FIELD_VALID(unit, reg, SRP_FWD_ACTIONf)) { 1038 value = soc_reg64_field32_get(unit, reg, regval, SRP_FWD_ACTIONf); 1039 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1040 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1041 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1042 } 1043 protocol_pkt->srp_action = pkt_action; 1044 1045 reg = IGMP_MLD_PKT_CONTROLr; 1046 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, proto_index, 1047 ®val)); 1048 1049 pkt_action = 0; 1050 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_TO_CPUf)) { 1051 value = soc_reg64_field32_get(unit, reg, regval, 1052 IGMP_REP_LEAVE_TO_CPUf); 1053 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1054 } 1055 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_FWD_ACTIONf)) { 1056 value = soc_reg64_field32_get(unit, reg, regval, 1057 IGMP_REP_LEAVE_FWD_ACTIONf); 1058 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1059 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1060 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1061 } 1062 protocol_pkt->igmp_report_leave_action = pkt_action; 1063 1064 pkt_action = 0; 1065 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_TO_CPUf)) { 1066 value = soc_reg64_field32_get(unit, reg, regval, 1067 IGMP_QUERY_TO_CPUf); 1068 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1069 } 1070 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_FWD_ACTIONf)) { 1071 value = soc_reg64_field32_get(unit, reg, regval, 1072 IGMP_QUERY_FWD_ACTIONf); 1073 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1074 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1075 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1076 } 1077 protocol_pkt->igmp_query_action = pkt_action; 1078 pkt_action = 0; 1079 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_TO_CPUf)) { 1080 value = soc_reg64_field32_get(unit, reg, regval, 1081 IGMP_UNKNOWN_MSG_TO_CPUf); 1082 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1083 } 1084 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_FWD_ACTIONf)) { 1085 value = soc_reg64_field32_get(unit, reg, regval, 1086 IGMP_UNKNOWN_MSG_FWD_ACTIONf); 1087 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1088 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1089 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1090 } 1091 protocol_pkt->igmp_unknown_msg_action = pkt_action; 1092 pkt_action = 0; 1093 if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_TO_CPUf)) { 1094 value = soc_reg64_field32_get(unit, reg, regval, 1095 MLD_REP_DONE_TO_CPUf); 1096 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1097 } 1098 if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_FWD_ACTIONf)) { 1099 value = soc_reg64_field32_get(unit, reg, regval, 1100 MLD_REP_DONE_FWD_ACTIONf); 1101 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1102 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1103 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1104 } 1105 protocol_pkt->mld_report_done_action = pkt_action; 1106 pkt_action = 0; 1107 if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_TO_CPUf)) { 1108 value = soc_reg64_field32_get(unit, reg, regval, MLD_QUERY_TO_CPUf); 1109 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1110 } 1111 if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_FWD_ACTIONf)) { 1112 value = soc_reg64_field32_get(unit, reg, regval, 1113 MLD_QUERY_FWD_ACTIONf); 1114 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1115 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1116 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1117 } 1118 protocol_pkt->mld_query_action = pkt_action; 1119 pkt_action = 0; 1120 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_TO_CPUf)) { 1121 value = soc_reg64_field32_get(unit, reg, regval, 1122 IPV4_RESVD_MC_PKT_TO_CPUf); 1123 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1124 } 1125 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_FWD_ACTIONf)) { 1126 value = soc_reg64_field32_get(unit, reg, regval, 1127 IPV4_RESVD_MC_PKT_FWD_ACTIONf); 1128 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1129 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1130 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1131 } 1132 protocol_pkt->ip4_rsvd_mc_action = pkt_action; 1133 pkt_action = 0; 1134 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_TO_CPUf)) { 1135 value = soc_reg64_field32_get(unit, reg, regval, 1136 IPV6_RESVD_MC_PKT_TO_CPUf); 1137 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1138 } 1139 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_FWD_ACTIONf)) { 1140 value = soc_reg64_field32_get(unit, reg, regval, 1141 IPV6_RESVD_MC_PKT_FWD_ACTIONf); 1142 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1143 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1144 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1145 } 1146 protocol_pkt->ip6_rsvd_mc_action = pkt_action; 1147 pkt_action = 0; 1148 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_MC_ROUTER_ADV_PKT_TO_CPUf)) { 1149 value = soc_reg64_field32_get(unit, reg, regval, 1150 IPV4_MC_ROUTER_ADV_PKT_TO_CPUf); 1151 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1152 } 1153 if (SOC_REG_FIELD_VALID(unit, reg,IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) { 1154 value = soc_reg64_field32_get(unit, reg, regval, 1155 IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf); 1156 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1157 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1158 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1159 } 1160 protocol_pkt->ip4_mc_router_adv_action = pkt_action; 1161 pkt_action = 0; 1162 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_MC_ROUTER_ADV_PKT_TO_CPUf)) { 1163 value = soc_reg64_field32_get(unit, reg, regval, 1164 IPV6_MC_ROUTER_ADV_PKT_TO_CPUf); 1165 pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0; 1166 } 1167 if (SOC_REG_FIELD_VALID(unit, reg,IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) { 1168 value = soc_reg64_field32_get(unit, reg, regval, 1169 IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf); 1170 pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE : 1171 (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 1172 BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 1173 } 1174 protocol_pkt->ip6_mc_router_adv_action = pkt_action; 1175 1176 value = 0; 1177 if (SOC_REG_FIELD_VALID(unit, reg, PFM_RULE_APPLYf)) { 1178 value = soc_reg64_field32_get(unit, reg, regval, 1179 PFM_RULE_APPLYf); 1180 } 1181 protocol_pkt->flood_action_according_to_pfm = value ? TRUE : FALSE; 1182 1183 return BCM_E_NONE; 1184 } 1185 #endif /* BCM_TRX_SUPPORT */ 1186 return BCM_E_UNAVAIL; 1187 } 1188 1189 /* 1190 * Function: 1191 * _bcm_xgs3_protocol_pkt_ctrl_set 1192 * Purpose: 1193 * function to set protocol packet action for given protocol 1194 * control register table index. 1195 * 1196 * Parameters: 1197 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1198 * vlan_profile_index - (IN) index in vlan_profile table 1199 * protocol_pkt- protocol packet actions to be configured 1200 * protocol_pkt_index (OUT) - the index in PROTOCOL_PKT_CONTROLr 1201 * and IGPM_PLD_PKT_CONTROLr 1202 * Returns: 1203 * BCM_E_NONE - protocol packet action configuration is successful. 1204 * BCM_E_XXX - Other error 1205 * Notes: 1206 * None. 1207 */ 1208 int 1209 _bcm_xgs3_protocol_pkt_ctrl_set(int unit, int old_protocol_pkt_index, 1210 bcm_vlan_protocol_packet_ctrl_t *protocol_pkt, 1211 int *protocol_pkt_index) 1212 { 1213 #if defined (BCM_TRX_SUPPORT) 1214 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 1215 uint32 value; 1216 uint32 prot_pkt_ctrl = 0, igmp_mld_pkt_ctrl = 0; 1217 int pkt_action; 1218 1219 uint32 index; 1220 soc_reg_t reg; 1221 int ref_count = 0; 1222 1223 if (NULL == protocol_pkt) { 1224 return BCM_E_PARAM; 1225 } 1226 1227 reg = PROTOCOL_PKT_CONTROLr; 1228 pkt_action = protocol_pkt->arp_reply_action; 1229 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_TO_CPUf)) { 1230 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1231 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ARP_REPLY_TO_CPUf, 1232 value); 1233 } 1234 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_DROPf)) { 1235 value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0; 1236 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ARP_REPLY_DROPf, 1237 value); 1238 } 1239 pkt_action = protocol_pkt->arp_request_action; 1240 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_TO_CPUf)) { 1241 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1242 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, 1243 ARP_REQUEST_TO_CPUf, value); 1244 } 1245 if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_DROPf)) { 1246 value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0; 1247 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ARP_REQUEST_DROPf, 1248 value); 1249 } 1250 pkt_action = protocol_pkt->nd_action; 1251 if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_TO_CPUf)) { 1252 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1253 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ND_PKT_TO_CPUf, value); 1254 } 1255 if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_DROPf)) { 1256 value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0; 1257 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ND_PKT_DROPf, value); 1258 } 1259 pkt_action = protocol_pkt->dhcp_action; 1260 if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_TO_CPUf)) { 1261 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1262 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, DHCP_PKT_TO_CPUf, 1263 value); 1264 } 1265 if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_DROPf)) { 1266 value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0; 1267 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, DHCP_PKT_DROPf, value); 1268 } 1269 pkt_action = protocol_pkt->mmrp_action; 1270 if (SOC_REG_FIELD_VALID(unit, reg, MMRP_PKT_TO_CPUf)) { 1271 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1272 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, MMRP_PKT_TO_CPUf, 1273 value); 1274 } 1275 if (SOC_REG_FIELD_VALID(unit, reg, MMRP_FWD_ACTIONf)) { 1276 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1277 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1278 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, MMRP_FWD_ACTIONf, 1279 value); 1280 } 1281 pkt_action = protocol_pkt->srp_action; 1282 if (SOC_REG_FIELD_VALID(unit, reg, SRP_PKT_TO_CPUf)) { 1283 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1284 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, SRP_PKT_TO_CPUf, 1285 value); 1286 } 1287 if (SOC_REG_FIELD_VALID(unit, reg, SRP_FWD_ACTIONf)) { 1288 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1289 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1290 soc_reg_field_set(unit, reg, &prot_pkt_ctrl, SRP_FWD_ACTIONf, 1291 value); 1292 } 1293 1294 reg = IGMP_MLD_PKT_CONTROLr; 1295 pkt_action = protocol_pkt->igmp_report_leave_action; 1296 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_TO_CPUf)) { 1297 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1298 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1299 IGMP_REP_LEAVE_TO_CPUf, value); 1300 } 1301 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_FWD_ACTIONf)) { 1302 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1303 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1304 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1305 IGMP_REP_LEAVE_FWD_ACTIONf, value); 1306 } 1307 1308 pkt_action = protocol_pkt->igmp_query_action; 1309 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_TO_CPUf)) { 1310 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1311 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1312 IGMP_QUERY_TO_CPUf, value); 1313 } 1314 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_FWD_ACTIONf)) { 1315 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1316 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1317 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1318 IGMP_QUERY_FWD_ACTIONf, value); 1319 } 1320 1321 pkt_action = protocol_pkt->igmp_unknown_msg_action; 1322 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_TO_CPUf)) { 1323 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1324 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1325 IGMP_UNKNOWN_MSG_TO_CPUf, value); 1326 } 1327 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_FWD_ACTIONf)) { 1328 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1329 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1330 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1331 IGMP_UNKNOWN_MSG_FWD_ACTIONf, value); 1332 } 1333 1334 pkt_action = protocol_pkt->mld_report_done_action; 1335 if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_TO_CPUf)) { 1336 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1337 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1338 MLD_REP_DONE_TO_CPUf, value); 1339 } 1340 if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_FWD_ACTIONf)) { 1341 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1342 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1343 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1344 MLD_REP_DONE_FWD_ACTIONf, value); 1345 } 1346 1347 pkt_action = protocol_pkt->mld_query_action; 1348 if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_TO_CPUf)) { 1349 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1350 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1351 MLD_QUERY_TO_CPUf, value); 1352 } 1353 if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_FWD_ACTIONf)) { 1354 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1355 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1356 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1357 MLD_QUERY_FWD_ACTIONf, value); 1358 } 1359 1360 pkt_action = protocol_pkt->ip4_rsvd_mc_action; 1361 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_TO_CPUf)) { 1362 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1363 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1364 IPV4_RESVD_MC_PKT_TO_CPUf, value); 1365 } 1366 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_FWD_ACTIONf)) { 1367 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1368 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1369 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1370 IPV4_RESVD_MC_PKT_FWD_ACTIONf, value); 1371 } 1372 1373 pkt_action = protocol_pkt->ip6_rsvd_mc_action; 1374 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_TO_CPUf)) { 1375 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1376 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1377 IPV6_RESVD_MC_PKT_TO_CPUf, value); 1378 } 1379 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_FWD_ACTIONf)) { 1380 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1381 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1382 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1383 IPV6_RESVD_MC_PKT_FWD_ACTIONf, value); 1384 } 1385 1386 pkt_action = protocol_pkt->ip4_mc_router_adv_action; 1387 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_MC_ROUTER_ADV_PKT_TO_CPUf)) { 1388 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1389 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1390 IPV4_MC_ROUTER_ADV_PKT_TO_CPUf, value); 1391 } 1392 if (SOC_REG_FIELD_VALID(unit, reg, 1393 IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) { 1394 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1395 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1396 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1397 IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf, value); 1398 } 1399 1400 pkt_action = protocol_pkt->ip6_mc_router_adv_action; 1401 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_MC_ROUTER_ADV_PKT_TO_CPUf)) { 1402 value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0; 1403 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1404 IPV6_MC_ROUTER_ADV_PKT_TO_CPUf, value); 1405 } 1406 if (SOC_REG_FIELD_VALID(unit, reg, 1407 IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) { 1408 value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 : 1409 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0); 1410 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1411 IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf, value); 1412 } 1413 1414 if (SOC_REG_FIELD_VALID(unit, reg, PFM_RULE_APPLYf)) { 1415 value = protocol_pkt->flood_action_according_to_pfm ? 1 : 0; 1416 soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 1417 PFM_RULE_APPLYf, value); 1418 } 1419 BCM_IF_ERROR_RETURN( 1420 _bcm_prot_pkt_ctrl_add(unit, prot_pkt_ctrl, igmp_mld_pkt_ctrl, 1421 &index)); 1422 if (old_protocol_pkt_index >= 0) { 1423 BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_ref_count_get( 1424 unit, old_protocol_pkt_index, &ref_count)); 1425 if (ref_count > 0) { 1426 BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_delete(unit, 1427 old_protocol_pkt_index)); 1428 } 1429 } 1430 *protocol_pkt_index = index; 1431 return BCM_E_NONE; 1432 } 1433 #endif /* BCM_TRX_SUPPORT */ 1434 return BCM_E_UNAVAIL; 1435 } 1436 1437 /* 1438 * Function: 1439 * _vlan_profile_read 1440 * 1441 * Purpose: 1442 * Read a vlan profile entry from vlan profile table. 1443 * 1444 * Parameters: 1445 * unit - (IN) BCM device number. 1446 * index - (IN) Entry index. 1447 * entry - (IN) Vlan profile entry. 1448 * 1449 * Return: 1450 * BCM_E_XXX 1451 * 1452 * Notes: 1453 * Only used as part of reload. 1454 */ 1455 STATIC int 1456 _vlan_profile_read(int unit, int index, _vlan_profile_t *entry) 1457 { 1458 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 1459 uint32 value; /* Field specific value.*/ 1460 soc_mem_t mem; /* Vlan profile table memory. */ 1461 #if defined (BCM_TRX_SUPPORT) 1462 _trx_vlan_block_t *block; /* Vlan block profile pointer. */ 1463 uint32 proto_index; 1464 #endif /* BCM_TRX_SUPPORT */ 1465 int rv = BCM_E_NONE; 1466 1467 /* Input parameters check. */ 1468 if ((NULL == entry) || (index < 0) || 1469 (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) { 1470 return (BCM_E_PARAM) ; 1471 } 1472 1473 /* Reset output buffer. */ 1474 sal_memset(entry, 0, sizeof(_vlan_profile_t)); 1475 1476 /* Reset hw buffer. */ 1477 sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 1478 mem = VLAN_PROFILE_TABm; 1479 1480 /* READ vlan profile table. */ 1481 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf); 1482 if (BCM_FAILURE(rv)) { 1483 return (rv); 1484 } 1485 1486 /* Enable/Disable MIM termination on a vlan. */ 1487 if (soc_mem_field_valid(unit, mem, MIM_TERM_ENABLEf)) { 1488 if (0 == soc_mem_field32_get(unit, mem, buf, MIM_TERM_ENABLEf)) { 1489 entry->flags |= BCM_VLAN_MIM_TERM_DISABLE; 1490 } 1491 } 1492 1493 /* Enable/Disable MPLS forwarding on a vlan. */ 1494 if (soc_mem_field_valid(unit, mem, MPLS_ENABLEf)) { 1495 if (0 == soc_mem_field32_get(unit, mem, buf, MPLS_ENABLEf)) { 1496 entry->flags |= BCM_VLAN_MPLS_DISABLE; 1497 } 1498 } 1499 1500 /* Drop non-unicast, broadcast or multicast packets that miss L2 lookup. */ 1501 if (SOC_MEM_FIELD_VALID(unit, mem, L2_NON_UCAST_DROPf)) { 1502 if (soc_mem_field32_get(unit, mem, buf, L2_NON_UCAST_DROPf)) { 1503 entry->flags |= BCM_VLAN_NON_UCAST_DROP; 1504 } 1505 } 1506 1507 /* Copy to cpu non-unicast, broadcast or multicast packets 1508 * that miss L2 lookup. 1509 */ 1510 if (SOC_MEM_FIELD_VALID(unit, mem, BCM_VLAN_NON_UCAST_TOCPU)) { 1511 if (soc_mem_field32_get(unit, mem, buf, L2_NON_UCAST_TOCPUf)) { 1512 entry->flags |= BCM_VLAN_NON_UCAST_TOCPU; 1513 } 1514 } 1515 1516 /* Drop packets that miss L2 lookup. */ 1517 if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_DROPf)) { 1518 if (soc_mem_field32_get(unit, mem, buf, L2_MISS_DROPf)) { 1519 entry->flags |= BCM_VLAN_UNKNOWN_UCAST_DROP; 1520 } 1521 } 1522 1523 /* Copy to cpu packets that miss L2 lookup. */ 1524 if (SOC_REG_FIELD_VALID(unit, VLAN_PROFILE_TABr, L2_MISS_TOCPUf)) { 1525 uint32 rval; 1526 BCM_IF_ERROR_RETURN( 1527 soc_reg32_get(unit, VLAN_PROFILE_TABr, REG_PORT_ANY, 0, &rval)); 1528 if (soc_reg_field_get(unit, VLAN_PROFILE_TABr, rval, L2_MISS_TOCPUf)) { 1529 entry->flags |= BCM_VLAN_UNKNOWN_UCAST_TOCPU; 1530 } 1531 } else if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_TOCPUf)) { 1532 if (soc_mem_field32_get(unit, mem, buf, L2_MISS_TOCPUf)) { 1533 entry->flags |= BCM_VLAN_UNKNOWN_UCAST_TOCPU; 1534 } 1535 } 1536 1537 /* L3 Enable for IPv4 packets on the VLAN. */ 1538 if (SOC_MEM_FIELD_VALID(unit, mem, IPV4L3_ENABLEf)) { 1539 if (0 == soc_mem_field32_get(unit, mem, buf, IPV4L3_ENABLEf)) { 1540 entry->flags |= BCM_VLAN_IP4_DISABLE; 1541 } 1542 } 1543 1544 /* L3 Enable for IPv6 packets on the VLAN. */ 1545 if (SOC_MEM_FIELD_VALID(unit, mem, IPV6L3_ENABLEf)) { 1546 if (0 == soc_mem_field32_get(unit, mem, buf, IPV6L3_ENABLEf)) { 1547 entry->flags |= BCM_VLAN_IP6_DISABLE; 1548 } 1549 } 1550 1551 /* Enable L2-only forwarding of IPMCv4 packets on this VLAN. */ 1552 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_L2_ENABLEf)) { 1553 if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV4_L2_ENABLEf)) { 1554 entry->flags |= BCM_VLAN_IP4_MCAST_L2_DISABLE; 1555 } 1556 } 1557 1558 /* Enable L2-only forwarding of IPMCv6 packets on this VLAN. */ 1559 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_L2_ENABLEf)) { 1560 if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV6_L2_ENABLEf)) { 1561 entry->flags |= BCM_VLAN_IP6_MCAST_L2_DISABLE; 1562 } 1563 } 1564 1565 /* IPMC Enable IPv4 packets on this VLAN. */ 1566 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_ENABLEf)) { 1567 if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV4_ENABLEf)) { 1568 entry->flags |= BCM_VLAN_IP4_MCAST_DISABLE; 1569 } 1570 } 1571 1572 /* IPMC Enable IPv6 packets on this VLAN. */ 1573 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_ENABLEf)) { 1574 if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV6_ENABLEf)) { 1575 entry->flags |= BCM_VLAN_IP6_MCAST_DISABLE; 1576 } 1577 } 1578 1579 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 1580 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_UNICAST_MACDA_ENABLEf)) { 1581 if (0 != soc_mem_field32_get(unit, mem, buf, 1582 IPMCV4_UNICAST_MACDA_ENABLEf)) { 1583 entry->flags |= BCM_VLAN_IPMC4_UCAST_ENABLE; 1584 } 1585 } 1586 1587 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_UNICAST_MACDA_ENABLEf)) { 1588 if (0 != soc_mem_field32_get(unit, mem, buf, 1589 IPMCV6_UNICAST_MACDA_ENABLEf)) { 1590 entry->flags |= BCM_VLAN_IPMC6_UCAST_ENABLE; 1591 } 1592 } 1593 } 1594 1595 /* Enables copy to cpu when ICMP redirect packet is needed. */ 1596 if (SOC_MEM_FIELD_VALID(unit, mem, ICMP_REDIRECT_TOCPUf)) { 1597 if (soc_mem_field32_get(unit, mem, buf, ICMP_REDIRECT_TOCPUf)) { 1598 entry->flags |= BCM_VLAN_ICMP_REDIRECT_TOCPU; 1599 } 1600 } 1601 1602 /* Unknown IPMC (IPMC miss) for IPv6 packets sent to CPU enable. */ 1603 if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV6_MC_TOCPUf)) { 1604 if (soc_mem_field32_get(unit, mem, buf, UNKNOWN_IPV6_MC_TOCPUf)) { 1605 entry->flags |= BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU; 1606 } 1607 } 1608 1609 /* Unknown IPMC (IPMC miss) for IPv4 packets sent to CPU enable. */ 1610 if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV4_MC_TOCPUf)) { 1611 if (soc_mem_field32_get(unit, mem, buf, UNKNOWN_IPV4_MC_TOCPUf)) { 1612 entry->flags |= BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU; 1613 } 1614 } 1615 1616 /* Outer tpid index Used when PORT_TABLE.OUTER_TPID_VERIFY, 1617 * is enabled and indicates which of the ING_OUTER_TPID[xx] 1618 * register is expected to match for this VLAN 1619 */ 1620 if (SOC_MEM_FIELD_VALID(unit, mem, OUTER_TPID_INDEX_MASKf)) { 1621 int i, field_len; 1622 value = soc_mem_field32_get(unit, mem, buf, OUTER_TPID_INDEX_MASKf); 1623 field_len = soc_mem_field_length(unit, mem, OUTER_TPID_INDEX_MASKf); 1624 for (i = 0; i < field_len; i++) { 1625 if (1 << i == value) { 1626 value = i; 1627 break; 1628 } 1629 } 1630 if (i == field_len) { 1631 value = 0; 1632 } 1633 } else { 1634 value = soc_mem_field32_get(unit, mem, buf, OUTER_TPID_INDEXf); 1635 } 1636 entry->outer_tpid= OUTER_TPID_ENTRY(unit, value); 1637 1638 /* Disable learning on this vlan. */ 1639 if (soc_mem_field32_get(unit, mem, buf, LEARN_DISABLEf)) { 1640 entry->flags |= BCM_VLAN_LEARN_DISABLE; 1641 } 1642 1643 /* PFM value for IPv6 multicast lookups */ 1644 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV6_PFMf)) { 1645 value = soc_mem_field32_get(unit, mem, buf, L3_IPV6_PFMf); 1646 rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, (int)value, 1647 &entry->ip6_mcast_flood_mode); 1648 BCM_IF_ERROR_RETURN(rv); 1649 } 1650 1651 /* PFM value for IPv4 multicast lookups */ 1652 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV4_PFMf)) { 1653 value = soc_mem_field32_get(unit, mem, buf, L3_IPV4_PFMf); 1654 rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, (int)value, 1655 &entry->ip4_mcast_flood_mode); 1656 BCM_IF_ERROR_RETURN(rv); 1657 } 1658 1659 /* PFM value for L2 multicast lookups */ 1660 value = soc_mem_field32_get(unit, mem, buf, L2_PFMf); 1661 rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, (int)value, 1662 &entry->l2_mcast_flood_mode); 1663 BCM_IF_ERROR_RETURN(rv); 1664 1665 #if defined (BCM_HURRICANE3_SUPPORT) 1666 if (SOC_MEM_FIELD_VALID(unit, mem, USE_VLAN_CMLf)) { 1667 if (0 != soc_mem_field32_get(unit, mem, buf, USE_VLAN_CMLf)) { 1668 entry->learn_flags = BCM_VLAN_LEARN_CONTROL_ENABLE; 1669 value = soc_mem_field32_get(unit, mem, buf, CML_FLAGS_NEWf); 1670 if (!(value & (1 << 0))) { 1671 entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_FWD; 1672 } 1673 if (value & (1 << 1)) { 1674 entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_CPU; 1675 } 1676 if (value & (1 << 2)) { 1677 entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_PENDING; 1678 } 1679 if (value & (1 << 3)) { 1680 entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_ARL; 1681 } 1682 } else { 1683 entry->learn_flags = 0x0; 1684 } 1685 } 1686 #endif /* BCM_HURRICANE3_SUPPORT */ 1687 1688 #if defined (BCM_TRIUMPH2_SUPPORT) 1689 if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1Pf)) { 1690 if (soc_mem_field32_get(unit, mem, buf, TRUST_DOT1Pf)) { 1691 entry->profile_flags |= _BCM_VLAN_PROFILE_TRUST_DOT1P; 1692 } 1693 } 1694 1695 if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1P_PTRf)) { 1696 entry->trust_dot1p_ptr = 1697 soc_mem_field32_get(unit, mem, buf, TRUST_DOT1P_PTRf); 1698 } 1699 #endif /* BCM_TRIUMPH2_SUPPORT */ 1700 1701 #if defined (BCM_TRX_SUPPORT) 1702 if (SOC_MEM_FIELD_VALID (unit,mem, PROTOCOL_PKT_INDEXf)) { 1703 proto_index = soc_mem_field32_get (unit, mem, buf, PROTOCOL_PKT_INDEXf); 1704 rv = _bcm_xgs3_protocol_pkt_ctrl_get(unit, 1705 proto_index, &entry->protocol_pkt); 1706 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 1707 return (rv); 1708 } 1709 } 1710 1711 if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) { 1712 /* READ VLAN_PROFILE_2 portion. */ 1713 sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 1714 mem = VLAN_PROFILE_2m; 1715 block = &entry->block; 1716 1717 /* READ vlan profile 2 table. */ 1718 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf); 1719 if (BCM_FAILURE(rv)) { 1720 return (rv); 1721 } 1722 1723 /* Bitmap A */ 1724 soc_mem_pbmp_field_get(unit, mem, buf, BLOCK_MASK_Af, 1725 &block->first_mask); 1726 1727 /* Bitmap B */ 1728 soc_mem_pbmp_field_get(unit, mem, buf, BLOCK_MASK_Bf, 1729 &block->second_mask); 1730 1731 /* Broadcast mask select. */ 1732 block->broadcast_mask_sel = soc_mem_field32_get(unit, mem, buf, BCAST_MASK_SELf); 1733 1734 /* Unknown unicast mask select. */ 1735 block->unknown_unicast_mask_sel = 1736 soc_mem_field32_get(unit, mem, buf, UNKNOWN_UCAST_MASK_SELf); 1737 1738 /* Unknown multicast mask select. */ 1739 block->unknown_mulitcast_mask_sel = 1740 soc_mem_field32_get(unit, mem, buf, UNKNOWN_MCAST_MASK_SELf); 1741 1742 /* Unknown multicast mask select. */ 1743 block->known_mulitcast_mask_sel = 1744 soc_mem_field32_get(unit, mem, buf, KNOWN_MCAST_MASK_SELf); 1745 } 1746 #endif /* BCM_TRX_SUPPORT */ 1747 return (BCM_E_NONE); 1748 } 1749 1750 /* 1751 * Function : _vlan_profile_detach 1752 * 1753 * Purpose : to de-initialize hardware VLAN_PROFILE_TAB and free memory 1754 * used to cache hardware table in RAM. 1755 */ 1756 int 1757 _bcm_xgs3_vlan_profile_detach(int unit) 1758 { 1759 sal_free(VLAN_PROFILE(unit)); 1760 VLAN_PROFILE(unit) = NULL; 1761 1762 return BCM_E_NONE; 1763 } 1764 1765 /* 1766 * Function : _vlan_profile_init 1767 * 1768 * Purpose : to initialize hardware VLAN_PROFILE_TAB and allocate memory 1769 * to cache hardware table in RAM. 1770 * 1771 * Note: 1772 * Allocate memory to cache the profile table and initialize it. 1773 * If memory to cache the profile table is already allocated, just 1774 * initialize the table. 1775 */ 1776 STATIC int 1777 _vlan_profile_init(int unit) 1778 { 1779 int alloc_size; /* Memory allocation size. */ 1780 int rv; /* Operation return status. */ 1781 1782 if ((0 == SOC_WARM_BOOT(unit)) && (0 == SOC_IS_RCPU_ONLY(unit))) { 1783 /* Clear the hardware table */ 1784 rv = soc_mem_clear(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ALL, TRUE); 1785 BCM_IF_ERROR_RETURN(rv); 1786 } 1787 1788 alloc_size = sizeof(_vlan_profile_t) * 1789 soc_mem_index_count(unit, VLAN_PROFILE_TABm); 1790 if (VLAN_PROFILE(unit) == NULL) { 1791 /* Allocate memory to cache VLAN Profile table */ 1792 VLAN_PROFILE(unit) = sal_alloc(alloc_size, "Cached VLAN Profile Table"); 1793 if (NULL == VLAN_PROFILE(unit)) { 1794 return BCM_E_MEMORY; 1795 } 1796 } 1797 sal_memset(VLAN_PROFILE(unit), 0, alloc_size); 1798 1799 if (SOC_WARM_BOOT(unit)) { 1800 int index; 1801 int index_max = soc_mem_index_max(unit, VLAN_PROFILE_TABm); 1802 for (index = 0; index <= index_max; index++) { 1803 rv = _vlan_profile_read(unit, index, 1804 &VLAN_PROFILE_ENTRY(unit, index)); 1805 BCM_IF_ERROR_RETURN(rv); 1806 } 1807 } 1808 1809 #if defined(BCM_EASY_RELOAD_SUPPORT) 1810 if (SOC_IS_RELOADING(unit)) { 1811 if (NULL == VLAN_PROFILE_ER(unit)) { 1812 alloc_size = sizeof(_vlan_profile_er_t) * BCM_VLAN_COUNT; 1813 1814 VLAN_PROFILE_ER(unit) = 1815 sal_alloc(alloc_size, "Cached VLAN Profile Pointers"); 1816 1817 if (NULL == VLAN_PROFILE_ER(unit)) { 1818 sal_free(VLAN_PROFILE(unit)); 1819 return BCM_E_MEMORY; 1820 } 1821 } 1822 sal_memset(VLAN_PROFILE_ER(unit), 0, alloc_size); 1823 } 1824 #endif 1825 return BCM_E_NONE; 1826 } 1827 1828 /* 1829 * Function : 1830 * _vlan_profile_compare 1831 * 1832 * Purpose : 1833 * Compare two vlan profiles. 1834 * 1835 * Parameters : 1836 * unit - (IN) BCM device number. 1837 * first - (IN) First vlan profile entry. 1838 * second - (IN) Second vlan profile entry. 1839 * equal - (OUT) Profile is identical flag. 1840 * 1841 * Return : 1842 * BCM_E_XXX 1843 */ 1844 STATIC int 1845 _vlan_profile_compare(int unit, _vlan_profile_t *first, 1846 _vlan_profile_t *second, uint8 *equal) 1847 { 1848 /* Input parameters check. */ 1849 if ((NULL == first) || (NULL == second) || (NULL == equal)) { 1850 return (BCM_E_PARAM); 1851 } 1852 1853 #if defined (BCM_TRX_SUPPORT) 1854 if (0 != sal_memcmp(&first->block, &second->block, 1855 sizeof (_trx_vlan_block_t))) { 1856 *equal = FALSE; 1857 } else 1858 #endif /* BCM_TRX_SUPPORT */ 1859 1860 if ((first->outer_tpid != second->outer_tpid) || 1861 (first->flags != second->flags) || 1862 (first->ip6_mcast_flood_mode != second->ip6_mcast_flood_mode) || 1863 (first->ip4_mcast_flood_mode != second->ip4_mcast_flood_mode) || 1864 (first->l2_mcast_flood_mode != second->l2_mcast_flood_mode) || 1865 (first->qm_ptr != second->qm_ptr) || 1866 (first->trust_dot1p_ptr != second->trust_dot1p_ptr) || 1867 (first->profile_flags != second->profile_flags)) { 1868 *equal = FALSE; 1869 } else { 1870 *equal = TRUE; 1871 } 1872 1873 #if defined (BCM_TRX_SUPPORT) 1874 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl) 1875 && (*equal == TRUE)) { 1876 if (0 != sal_memcmp(&first->protocol_pkt, &second->protocol_pkt, 1877 sizeof (bcm_vlan_protocol_packet_ctrl_t))) { 1878 *equal = FALSE; 1879 } 1880 } 1881 #endif /* BCM_TRX_SUPPORT */ 1882 1883 #if defined (BCM_HURRICANE3_SUPPORT) 1884 if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf) 1885 && (*equal == TRUE)) { 1886 if (0 != sal_memcmp(&first->learn_flags, &second->learn_flags, 1887 sizeof (uint32))) { 1888 *equal = FALSE; 1889 } 1890 } 1891 #endif /* BCM_HURRICANE3_SUPPORT */ 1892 1893 return (BCM_E_NONE); 1894 } 1895 1896 /* 1897 * Function : 1898 * _vlan_profile_entry_init 1899 * 1900 * Purpose : 1901 * Initialize sw vlan profile entry. 1902 * 1903 * Parameters : 1904 * unit - (IN) BCM device number. 1905 * index - (IN) Inserted entry index. 1906 * entry - (IN) Inserted entry data. 1907 * 1908 * Return : 1909 * BCM_E_XXX 1910 */ 1911 STATIC int 1912 _vlan_profile_entry_init(int unit, int index, _vlan_profile_t *entry) 1913 { 1914 _vlan_profile_t *vte; 1915 1916 /* Input parameters check. */ 1917 if (NULL == entry) { 1918 return (BCM_E_PARAM); 1919 } 1920 if ((index < 0) || 1921 (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) { 1922 return (BCM_E_PARAM); 1923 } 1924 1925 vte = &VLAN_PROFILE_ENTRY(unit, index); 1926 /* Vlan control vlan portion. */ 1927 vte->outer_tpid = entry->outer_tpid; 1928 vte->flags = entry->flags; 1929 vte->profile_flags = entry->profile_flags; 1930 vte->ip6_mcast_flood_mode = entry->ip6_mcast_flood_mode; 1931 vte->ip4_mcast_flood_mode = entry->ip4_mcast_flood_mode; 1932 vte->l2_mcast_flood_mode = entry->l2_mcast_flood_mode; 1933 vte->qm_ptr = entry->qm_ptr; 1934 vte->trust_dot1p_ptr = entry->trust_dot1p_ptr; 1935 #if defined (BCM_TRX_SUPPORT) 1936 /* Vlan block portion. */ 1937 sal_memcpy(&VLAN_PROFILE_ENTRY(unit, index).block, 1938 &entry->block, sizeof (_trx_vlan_block_t)); 1939 1940 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 1941 sal_memcpy(&VLAN_PROFILE_ENTRY(unit, index).protocol_pkt, 1942 &entry->protocol_pkt, sizeof (bcm_vlan_protocol_packet_ctrl_t)); 1943 } 1944 #endif /* BCM_TRX_SUPPORT */ 1945 1946 #if defined (BCM_HURRICANE3_SUPPORT) 1947 if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)) { 1948 sal_memcpy(&VLAN_PROFILE_ENTRY(unit, index).learn_flags, 1949 &entry->learn_flags, sizeof (uint32)); 1950 } 1951 #endif /* BCM_HURRICANE3_SUPPORT */ 1952 1953 VLAN_PROFILE_REF_COUNT(unit, index) = 1; 1954 1955 return (BCM_E_NONE); 1956 } 1957 1958 /* 1959 * Function: 1960 * _vlan_profile_write 1961 * 1962 * Purpose: 1963 * Write a vlan profile entry to vlan profile table. 1964 * 1965 * Parameters: 1966 * unit - (IN) BCM device number. 1967 * index - (IN) Entry index. 1968 * entry - (IN) Vlan profile entry. 1969 * 1970 * Return: 1971 * BCM_E_XXX 1972 */ 1973 STATIC int 1974 _vlan_profile_write(int unit, int index, _vlan_profile_t *entry) 1975 { 1976 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 1977 uint32 value; /* Field specific value.*/ 1978 soc_mem_t mem; /* Vlan profile table memory. */ 1979 int tpid_index; /* Outer tpid index. */ 1980 int rv; /* Operation return status. */ 1981 #if defined (BCM_TRX_SUPPORT) 1982 _trx_vlan_block_t *block; /* Vlan block profile pointer. */ 1983 int protocol_pkt_index; 1984 #endif /* BCM_TRX_SUPPORT */ 1985 1986 /* Input parameters check. */ 1987 if ((NULL == entry) || (index < 0) || 1988 (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) { 1989 return (BCM_E_PARAM); 1990 } 1991 1992 1993 /* Reset hw buffer. */ 1994 sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 1995 mem = VLAN_PROFILE_TABm; 1996 1997 /* Enable/Disable MIM termination on a vlan. */ 1998 if (soc_mem_field_valid(unit, mem, MIM_TERM_ENABLEf)) { 1999 value = (entry->flags & BCM_VLAN_MIM_TERM_DISABLE) ? 0 : 1; 2000 soc_mem_field32_set(unit, mem, buf, MIM_TERM_ENABLEf, value); 2001 } 2002 2003 /* Enable/Disable MPLS forwarding on a vlan. */ 2004 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ENABLEf)) { 2005 value = (entry->flags & BCM_VLAN_MPLS_DISABLE) ? 0 : 1; 2006 soc_mem_field32_set(unit, mem, buf, MPLS_ENABLEf, value); 2007 } 2008 2009 if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_ENABLEf)) { 2010 value = entry->profile_flags & _BCM_VLAN_PROFILE_PHB2_ENABLE ? 1 : 0; 2011 soc_mem_field32_set(unit, mem, buf, PHB2_ENABLEf, value); 2012 } 2013 2014 if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_USE_INNER_DOT1Pf)) { 2015 value = entry->profile_flags & _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG ? 2016 1 : 0; 2017 soc_mem_field32_set(unit, mem, buf, PHB2_USE_INNER_DOT1Pf, value); 2018 } 2019 2020 if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_ENABLEf)) { 2021 value = entry->profile_flags & _BCM_VLAN_PROFILE_PHB2_ENABLE ? 1 : 0; 2022 soc_mem_field32_set(unit, mem, buf, PHB2_ENABLEf, value); 2023 } 2024 2025 if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_DOT1P_MAPPING_PTRf)) { 2026 soc_mem_field32_set(unit, mem, buf, PHB2_DOT1P_MAPPING_PTRf, 2027 entry->qm_ptr); 2028 } 2029 2030 /* Drop non-unicast, broadcast or multicast packets that miss L2 lookup. */ 2031 if (SOC_MEM_FIELD_VALID(unit, mem, L2_NON_UCAST_DROPf)) { 2032 value = (entry->flags & BCM_VLAN_NON_UCAST_DROP) ? 1 : 0; 2033 soc_mem_field32_set(unit, mem, buf, L2_NON_UCAST_DROPf, value); 2034 } 2035 2036 /* Copy to cpu non-unicast, broadcast or multicast packets 2037 * that miss L2 lookup. 2038 */ 2039 if (SOC_MEM_FIELD_VALID(unit, mem, L2_NON_UCAST_TOCPUf)) { 2040 value = (entry->flags & BCM_VLAN_NON_UCAST_TOCPU) ? 1 : 0; 2041 soc_mem_field32_set(unit, mem, buf, L2_NON_UCAST_TOCPUf, value); 2042 } 2043 2044 /* Drop packets that miss L2 lookup. */ 2045 if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_DROPf)) { 2046 value = (entry->flags & BCM_VLAN_UNKNOWN_UCAST_DROP) ? 1 : 0; 2047 soc_mem_field32_set(unit, mem, buf, L2_MISS_DROPf, value); 2048 } 2049 2050 /* Copy to cpu packets that miss L2 lookup. */ 2051 if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_TOCPUf)) { 2052 value = (entry->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) ? 1 : 0; 2053 soc_mem_field32_set(unit, mem, buf, L2_MISS_TOCPUf, value); 2054 } 2055 2056 /* L3 Enable for IPv4 packets on the VLAN. */ 2057 if (SOC_MEM_FIELD_VALID(unit, mem, IPV4L3_ENABLEf)) { 2058 value = (entry->flags & BCM_VLAN_IP4_DISABLE) ? 0 : 1; 2059 soc_mem_field32_set(unit, mem, buf, IPV4L3_ENABLEf, value); 2060 } 2061 2062 /* L3 Enable for IPv6 packets on the VLAN. */ 2063 if (SOC_MEM_FIELD_VALID(unit, mem, IPV6L3_ENABLEf)) { 2064 value = (entry->flags & BCM_VLAN_IP6_DISABLE) ? 0 : 1; 2065 soc_mem_field32_set(unit, mem, buf, IPV6L3_ENABLEf, value); 2066 } 2067 2068 /* Enable L2-only forwarding of IPMCv4 packets on this VLAN. */ 2069 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_L2_ENABLEf)) { 2070 value = (entry->flags & BCM_VLAN_IP4_MCAST_L2_DISABLE) ? 0 : 1; 2071 soc_mem_field32_set(unit, mem, buf, IPMCV4_L2_ENABLEf, value); 2072 } 2073 2074 /* Enable L2-only forwarding of IPMCv6 packets on this VLAN. */ 2075 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_L2_ENABLEf)) { 2076 value = (entry->flags & BCM_VLAN_IP6_MCAST_L2_DISABLE) ? 0 : 1; 2077 soc_mem_field32_set(unit, mem, buf, IPMCV6_L2_ENABLEf, value); 2078 } 2079 2080 2081 /* IPMC Enable IPv4 packets on this VLAN. */ 2082 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_ENABLEf)) { 2083 value = (entry->flags & BCM_VLAN_IP4_MCAST_DISABLE) ? 0 : 1; 2084 soc_mem_field32_set(unit, mem, buf, IPMCV4_ENABLEf, value); 2085 } 2086 2087 /* IPMC Enable IPv6 packets on this VLAN. */ 2088 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_ENABLEf)) { 2089 value = (entry->flags & BCM_VLAN_IP6_MCAST_DISABLE) ? 0 : 1; 2090 soc_mem_field32_set(unit, mem, buf, IPMCV6_ENABLEf, value); 2091 } 2092 2093 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 2094 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_UNICAST_MACDA_ENABLEf)) { 2095 value = (entry->flags & BCM_VLAN_IPMC4_UCAST_ENABLE) ? 1 : 0; 2096 soc_mem_field32_set(unit, mem, buf, 2097 IPMCV4_UNICAST_MACDA_ENABLEf, value); 2098 } 2099 2100 if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_UNICAST_MACDA_ENABLEf)) { 2101 value = (entry->flags & BCM_VLAN_IPMC6_UCAST_ENABLE) ? 1 : 0; 2102 soc_mem_field32_set(unit, mem, buf, 2103 IPMCV6_UNICAST_MACDA_ENABLEf, value); 2104 } 2105 } 2106 2107 /* Enable copy to cpu when ICMP redirect packet is needed. */ 2108 if (SOC_MEM_FIELD_VALID(unit, mem, ICMP_REDIRECT_TOCPUf)) { 2109 value = (entry->flags & BCM_VLAN_ICMP_REDIRECT_TOCPU) ? 1 : 0; 2110 soc_mem_field32_set(unit, mem, buf, ICMP_REDIRECT_TOCPUf, value); 2111 } 2112 2113 /* Unknown IPMC (IPMC miss) for IPv6 packets sent to CPU enable. */ 2114 if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV6_MC_TOCPUf)) { 2115 value = (entry->flags & BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU)? 1 : 0; 2116 soc_mem_field32_set(unit, mem, buf, UNKNOWN_IPV6_MC_TOCPUf, value); 2117 } 2118 2119 /* Unknown IPMC (IPMC miss) for IPv4 packets sent to CPU enable. */ 2120 if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV4_MC_TOCPUf)) { 2121 value = (entry->flags & BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU)? 1 : 0; 2122 soc_mem_field32_set(unit, mem, buf, UNKNOWN_IPV4_MC_TOCPUf, value); 2123 } 2124 2125 /* Outer tpid index Used when PORT_TABLE.OUTER_TPID_VERIFY, 2126 * is enabled and indicates which of the ING_OUTER_TPID[xx] 2127 * register is expected to match for this VLAN 2128 */ 2129 2130 if(!SOC_IS_SHADOW(unit)) { 2131 rv = _bcm_fb2_outer_tpid_lkup(unit, entry->outer_tpid, &tpid_index); 2132 BCM_IF_ERROR_RETURN(rv); 2133 value = (uint32) tpid_index; 2134 if (SOC_MEM_FIELD_VALID(unit, mem, OUTER_TPID_INDEX_MASKf)) { 2135 soc_mem_field32_set(unit, mem, buf, OUTER_TPID_INDEX_MASKf, 2136 1 << value); 2137 } else { 2138 soc_mem_field32_set(unit, mem, buf, OUTER_TPID_INDEXf, value); 2139 } 2140 } 2141 2142 /* Disable learning on this vlan. */ 2143 if (SOC_MEM_FIELD_VALID(unit, mem, LEARN_DISABLEf)) { 2144 value = (entry->flags & BCM_VLAN_LEARN_DISABLE) ? 1 : 0; 2145 soc_mem_field32_set(unit, mem, buf, LEARN_DISABLEf, value); 2146 } 2147 2148 /* PFM value for IPv6 multicast lookups */ 2149 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV6_PFMf)) { 2150 rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, entry->ip6_mcast_flood_mode, 2151 (int *)&value); 2152 BCM_IF_ERROR_RETURN(rv); 2153 soc_mem_field32_set(unit, mem, buf, L3_IPV6_PFMf, value); 2154 } 2155 2156 /* PFM value for IPv4 multicast lookups */ 2157 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV4_PFMf)) { 2158 rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, entry->ip4_mcast_flood_mode, 2159 (int *)&value); 2160 BCM_IF_ERROR_RETURN(rv); 2161 soc_mem_field32_set(unit, mem, buf, L3_IPV4_PFMf, value); 2162 } 2163 2164 /* PFM value for L2 multicast lookups */ 2165 rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, entry->l2_mcast_flood_mode, 2166 (int *)&value); 2167 BCM_IF_ERROR_RETURN(rv); 2168 soc_mem_field32_set(unit, mem, buf, L2_PFMf, value); 2169 2170 #if defined (BCM_TRX_SUPPORT) 2171 /*Get the protocol_pkt_control register index and program 2172 in PROTOCOL_PKT_INDEX field*/ 2173 if (SOC_MEM_FIELD_VALID (unit,mem, PROTOCOL_PKT_INDEXf)) { 2174 rv = _bcm_xgs3_protocol_pkt_ctrl_set(unit, -1, 2175 &entry->protocol_pkt, &protocol_pkt_index); 2176 if (BCM_SUCCESS(rv)) { 2177 value = (uint32)protocol_pkt_index; 2178 soc_mem_field32_set(unit, mem, buf, PROTOCOL_PKT_INDEXf, value); 2179 } else if (rv != BCM_E_UNAVAIL) { 2180 return rv; 2181 } 2182 } 2183 #endif /* BCM_TRX_SUPPORT */ 2184 2185 #if defined (BCM_TRIUMPH2_SUPPORT) 2186 if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1Pf)) { 2187 value = entry->profile_flags & _BCM_VLAN_PROFILE_TRUST_DOT1P ? 1 : 0; 2188 soc_mem_field32_set(unit, mem, buf, TRUST_DOT1Pf, value); 2189 } 2190 2191 if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1P_PTRf)) { 2192 soc_mem_field32_set(unit, mem, buf, TRUST_DOT1P_PTRf, 2193 entry->trust_dot1p_ptr); 2194 } 2195 #endif /* BCM_TRIUMPH2_SUPPORT */ 2196 2197 #if defined (BCM_HURRICANE3_SUPPORT) 2198 if (SOC_MEM_FIELD_VALID(unit, mem, USE_VLAN_CMLf)) { 2199 value = entry->learn_flags & BCM_VLAN_LEARN_CONTROL_ENABLE ? 1 : 0; 2200 soc_mem_field32_set(unit, mem, buf, USE_VLAN_CMLf, value); 2201 2202 if (value) { 2203 value = 0; 2204 if (!(entry->learn_flags & BCM_VLAN_LEARN_CONTROL_FWD)) { 2205 value |= (1 << 0); 2206 } 2207 if (entry->learn_flags & BCM_VLAN_LEARN_CONTROL_CPU) { 2208 value |= (1 << 1); 2209 } 2210 if (entry->learn_flags & BCM_VLAN_LEARN_CONTROL_PENDING) { 2211 value |= (1 << 2); 2212 } 2213 if (entry->learn_flags & BCM_VLAN_LEARN_CONTROL_ARL) { 2214 value |= (1 << 3); 2215 } 2216 soc_mem_field32_set(unit, mem, buf, CML_FLAGS_MOVEf, value); 2217 soc_mem_field32_set(unit, mem, buf, CML_FLAGS_NEWf, value); 2218 } 2219 } 2220 #endif /* BCM_HURRICANE3_SUPPORT */ 2221 2222 /* Write vlan profile table entry. */ 2223 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, buf); 2224 BCM_IF_ERROR_RETURN(rv); 2225 2226 /* Copy to cpu packets that miss L2 lookup. */ 2227 if (SOC_REG_FIELD_VALID(unit, VLAN_PROFILE_TABr, L2_MISS_TOCPUf)) { 2228 value = (entry->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) ? 1 : 0; 2229 soc_reg_field32_modify(unit, VLAN_PROFILE_TABr, REG_PORT_ANY, 2230 L2_MISS_TOCPUf, value); 2231 } 2232 2233 #if defined (BCM_TRX_SUPPORT) 2234 /* WRITE VLAN_PROFILE_2 portion. */ 2235 if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) { 2236 sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2237 mem = VLAN_PROFILE_2m; 2238 block = &entry->block; 2239 2240 /* Bitmap A */ 2241 soc_mem_pbmp_field_set(unit, mem, buf, BLOCK_MASK_Af, 2242 &block->first_mask); 2243 2244 /* Bitmap B */ 2245 soc_mem_pbmp_field_set(unit, mem, buf, BLOCK_MASK_Bf, 2246 &block->second_mask); 2247 2248 /* Broadcast mask select. */ 2249 soc_mem_field32_set(unit, mem, buf, BCAST_MASK_SELf, 2250 block->broadcast_mask_sel); 2251 2252 /* Unknown unicast mask select. */ 2253 if (soc_mem_field_valid(unit, VLAN_PROFILE_2m, 2254 UNKNOWN_UCAST_MASK_SELf)) { 2255 soc_mem_field32_set(unit, mem, buf, UNKNOWN_UCAST_MASK_SELf, 2256 block->unknown_unicast_mask_sel); 2257 } 2258 2259 /* Unknown multicast mask select. */ 2260 if (soc_mem_field_valid(unit, VLAN_PROFILE_2m, 2261 UNKNOWN_MCAST_MASK_SELf)) { 2262 soc_mem_field32_set(unit, mem, buf, UNKNOWN_MCAST_MASK_SELf, 2263 block->unknown_mulitcast_mask_sel); 2264 } 2265 2266 /* Unknown multicast mask select. */ 2267 if (soc_mem_field_valid(unit, VLAN_PROFILE_2m, KNOWN_MCAST_MASK_SELf)) { 2268 soc_mem_field32_set(unit, mem, buf, KNOWN_MCAST_MASK_SELf, 2269 block->known_mulitcast_mask_sel); 2270 } 2271 2272 /* Write vlan profile 2 entry. */ 2273 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, buf); 2274 BCM_IF_ERROR_RETURN(rv); 2275 } 2276 #endif /* BCM_TRX_SUPPORT */ 2277 2278 return (BCM_E_NONE); 2279 } 2280 /* 2281 * Function: 2282 * _bcm_vlan_profile_add 2283 * 2284 * Purpose: 2285 * Add a new entry to vlan profile table 2286 * 2287 * Parameters: 2288 * unit - (IN) BCM device number. 2289 * entry - (IN) Vlan profile entry. 2290 * index - (OUT) Allocated/existing entry index. 2291 * 2292 * Return: 2293 * BCM_E_XXX 2294 */ 2295 STATIC int 2296 _vlan_profile_add(int unit, _vlan_profile_t *entry, int *index) 2297 { 2298 int free_index = -1; /* Unused proile index. */ 2299 int idx; /* Vlan profiles iterator. */ 2300 int idx_max; /* Profile entry count. */ 2301 uint8 equal; /* Prifiles are equal flag.*/ 2302 int rv; /* Operation return status.*/ 2303 2304 /* Input parameters check. */ 2305 if (NULL == entry) { 2306 return (BCM_E_PARAM); 2307 } 2308 2309 idx_max = soc_mem_index_max(unit, VLAN_PROFILE_TABm); 2310 /* Search for an existing entry that has the same configuration. */ 2311 for (idx = 0; idx <= idx_max; idx++) { 2312 /* Compare profiles. */ 2313 rv = _vlan_profile_compare(unit, &VLAN_PROFILE_ENTRY(unit, idx), 2314 entry, &equal); 2315 BCM_IF_ERROR_RETURN(rv); 2316 if (equal) { 2317 VLAN_PROFILE_REF_COUNT(unit, idx)++; 2318 #if defined (BCM_TRX_SUPPORT) 2319 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 2320 int pkt_idx; 2321 2322 /* should only increase reference counter when called 2323 * on the existing entry 2324 */ 2325 rv = _bcm_xgs3_protocol_pkt_ctrl_set(unit, -1, 2326 &entry->protocol_pkt, 2327 &pkt_idx); 2328 BCM_IF_ERROR_RETURN(rv); 2329 } 2330 #endif /* BCM_TRX_SUPPORT */ 2331 *index = idx; 2332 return (BCM_E_NONE); 2333 } 2334 2335 if ((-1 == free_index) && (0 == VLAN_PROFILE_REF_COUNT(unit, idx))) { 2336 free_index = idx; 2337 } 2338 } 2339 2340 /* Entry not found & no free indexes. */ 2341 if (-1 == free_index) { 2342 return BCM_E_RESOURCE; 2343 } 2344 2345 /* 2346 * Insert the new configuration into profile table 2347 */ 2348 rv = _vlan_profile_write(unit, free_index, entry); 2349 BCM_IF_ERROR_RETURN(rv); 2350 2351 rv = _vlan_profile_entry_init(unit, free_index, entry); 2352 BCM_IF_ERROR_RETURN(rv); 2353 2354 *index = free_index; 2355 return BCM_E_NONE; 2356 } 2357 2358 /* 2359 * Function : 2360 * _vlan_profile_delete 2361 * 2362 * Parameters : 2363 * unit - (IN) BCM device number. 2364 * index - (IN) Existing entry index. 2365 * 2366 * Purpose : 2367 * Remove an entry from vlan profile table. 2368 * 2369 * Return : 2370 * BCM_E_XXX 2371 */ 2372 STATIC int 2373 _vlan_profile_delete(int unit, int index) 2374 { 2375 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 2376 int rv; /* Operation return status. */ 2377 #if defined (BCM_TRX_SUPPORT) 2378 vlan_profile_tab_entry_t entry; 2379 uint32 prot_pkt_index; 2380 int ref_count; 2381 #endif /* BCM_TRX_SUPPORT */ 2382 2383 /* Input parameters check. */ 2384 if ((index < 0) || (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) { 2385 return (BCM_E_PARAM); 2386 } 2387 2388 /* Decrement profile reference counter. */ 2389 if (VLAN_PROFILE_REF_COUNT(unit, index) > 0) { 2390 VLAN_PROFILE_REF_COUNT(unit, index)--; 2391 } 2392 2393 #if defined (BCM_TRX_SUPPORT) 2394 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl) 2395 && SOC_MEM_FIELD_VALID (unit,VLAN_PROFILE_TABm, PROTOCOL_PKT_INDEXf)) { 2396 BCM_IF_ERROR_RETURN 2397 (soc_mem_read(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ANY, index, &entry)); 2398 prot_pkt_index = soc_mem_field32_get(unit, VLAN_PROFILE_TABm, &entry, 2399 PROTOCOL_PKT_INDEXf); 2400 BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_ref_count_get (unit, 2401 prot_pkt_index, &ref_count)); 2402 if (ref_count > 0) { 2403 BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_delete(unit,prot_pkt_index)); 2404 } 2405 } 2406 #endif /* BCM_TRX_SUPPORT */ 2407 if (0 == VLAN_PROFILE_REF_COUNT(unit, index)) { 2408 /* Reset hw table entries. */ 2409 sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2410 #if defined (BCM_TRX_SUPPORT) 2411 if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) { 2412 rv = soc_mem_write(unit, VLAN_PROFILE_2m, MEM_BLOCK_ALL, index, buf); 2413 BCM_IF_ERROR_RETURN(rv); 2414 } 2415 2416 #endif /* BCM_TRX_SUPPORT */ 2417 2418 rv = soc_mem_write(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ALL, index, buf); 2419 BCM_IF_ERROR_RETURN(rv); 2420 2421 /* Reset sw vlan profile entry. */ 2422 sal_memset(&VLAN_PROFILE_ENTRY(unit, index), 0, sizeof(_vlan_profile_t)); 2423 } 2424 return (BCM_E_NONE); 2425 } 2426 2427 #if defined (BCM_TRX_SUPPORT) 2428 /* 2429 * Function: 2430 * _vlan_protocol_pkt_ctrl_default_add 2431 * 2432 * Purpose: 2433 * Add default vlan protocol packet control value 2434 * 2435 * Parameters: 2436 * unit - (IN) BCM device number. 2437 * protocol_pkt - (OUT) protocol packet actions to be configured. 2438 * Return: 2439 * BCM_E_XXX 2440 */ 2441 STATIC int 2442 _vlan_protocol_pkt_ctrl_default_add(int unit, bcm_vlan_protocol_packet_ctrl_t *protocol_pkt) 2443 { 2444 soc_reg_t reg = PROTOCOL_PKT_CONTROLr; 2445 2446 if (!soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 2447 return BCM_E_UNAVAIL; 2448 } 2449 2450 if (SOC_REG_FIELD_VALID(unit, reg, MMRP_FWD_ACTIONf)) { 2451 protocol_pkt->mmrp_action = BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2452 } 2453 if (SOC_REG_FIELD_VALID(unit, reg, SRP_FWD_ACTIONf)) { 2454 protocol_pkt->srp_action = BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2455 } 2456 2457 reg = IGMP_MLD_PKT_CONTROLr; 2458 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_FWD_ACTIONf)) { 2459 protocol_pkt->igmp_report_leave_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2460 } 2461 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_FWD_ACTIONf)) { 2462 protocol_pkt->igmp_query_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2463 } 2464 if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_FWD_ACTIONf)) { 2465 protocol_pkt->igmp_unknown_msg_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2466 } 2467 if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_FWD_ACTIONf)) { 2468 protocol_pkt->mld_report_done_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2469 } 2470 if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_FWD_ACTIONf)) { 2471 protocol_pkt->mld_query_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2472 } 2473 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) { 2474 protocol_pkt->ip4_mc_router_adv_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2475 } 2476 if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_FWD_ACTIONf)) { 2477 protocol_pkt->ip4_rsvd_mc_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2478 } 2479 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_FWD_ACTIONf)) { 2480 protocol_pkt->ip6_rsvd_mc_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2481 } 2482 if (SOC_REG_FIELD_VALID(unit, reg, IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) { 2483 protocol_pkt->ip6_mc_router_adv_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE; 2484 } 2485 2486 return BCM_E_NONE; 2487 2488 } 2489 #endif /*BCM_TRX_SUPPORT*/ 2490 2491 /* 2492 * Function: 2493 * _vlan_profile_default_add 2494 * 2495 * Purpose: 2496 * Add a default entry to vlan profile table 2497 * 2498 * Parameters: 2499 * unit - (IN) BCM device number. 2500 * index - (OUT) Profile index. 2501 * Return: 2502 * BCM_E_XXX 2503 */ 2504 STATIC int 2505 _vlan_profile_default_add(int unit, int *index) 2506 { 2507 int rv; /* Operation return status. */ 2508 _vlan_profile_t entry; /* Vlan profile_entry. */ 2509 bcm_vlan_mcast_flood_t mode; /* Mcast flood mode. */ 2510 2511 /* Input parameters check. */ 2512 if (NULL == index) { 2513 return (BCM_E_PARAM); 2514 } 2515 2516 /* Reset entry structure. */ 2517 sal_memset (&entry, 0, sizeof(_vlan_profile_t)); 2518 2519 /* Multicast flood mode. */ 2520 rv = _bcm_esw_vlan_flood_default_get(unit, &mode); 2521 BCM_IF_ERROR_RETURN(rv); 2522 2523 entry.ip6_mcast_flood_mode = mode; 2524 entry.ip4_mcast_flood_mode = mode; 2525 entry.l2_mcast_flood_mode = mode; 2526 2527 /* Default outer tpid value. */ 2528 entry.outer_tpid = _bcm_fb2_outer_tpid_default_get(unit); 2529 2530 /* Default VLAN Protocol Packet control */ 2531 #if defined (BCM_TRX_SUPPORT) 2532 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 2533 BCM_IF_ERROR_RETURN 2534 (_vlan_protocol_pkt_ctrl_default_add(unit, &entry.protocol_pkt)); 2535 } 2536 #endif 2537 2538 return _vlan_profile_add (unit, &entry, index); 2539 } 2540 2541 /* 2542 * Function: 2543 * _vlan_profile_update 2544 * 2545 * Purpose: 2546 * Update existing vlan "profile" 2547 * 2548 * Parameters: 2549 * unit - (IN) BCM device number. 2550 * vlan - (IN) VLAN id. 2551 * buf - (IN) Vlan table entry. 2552 * profile - (IN) Updated profile 2553 * Return: 2554 * BCM_E_XXX 2555 */ 2556 STATIC int 2557 _vlan_profile_update(int unit, bcm_vlan_t vlan, _vlan_profile_t *profile) 2558 { 2559 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 2560 int rv; /* Operation return status. */ 2561 int idx; /* Vlan profile index. */ 2562 int oidx; /* Original vlan profile index. */ 2563 uint8 equal; /* Profiles are equal flag. */ 2564 2565 2566 /* Input parameters check. */ 2567 if (NULL == profile) { 2568 return (BCM_E_PARAM); 2569 } 2570 2571 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int) vlan, buf); 2572 BCM_IF_ERROR_RETURN(rv); 2573 2574 BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, VLAN_TABm, 2575 (vlan_tab_entry_t *)buf, vlan)); 2576 2577 /* Get original vlan profile. */ 2578 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 2579 buf, vlan, &oidx); 2580 BCM_IF_ERROR_RETURN(rv); 2581 2582 /* Compare original profile with new one. */ 2583 rv = _vlan_profile_compare(unit, &VLAN_PROFILE_ENTRY(unit, oidx), 2584 profile, &equal); 2585 BCM_IF_ERROR_RETURN(rv); 2586 2587 if (TRUE == equal) { 2588 return (BCM_E_NONE); 2589 } 2590 2591 /* Add new profile. */ 2592 rv = _vlan_profile_add(unit, profile, &idx); 2593 if (BCM_SUCCESS(rv)) { 2594 } 2595 if (BCM_E_RESOURCE == rv) { 2596 /* Check if we can update an existing profile. */ 2597 if (1 == VLAN_PROFILE_REF_COUNT(unit, oidx)) { 2598 rv = _vlan_profile_write(unit, oidx, profile); 2599 BCM_IF_ERROR_RETURN(rv); 2600 2601 VLAN_PROFILE_ENTRY(unit, oidx) = *profile; 2602 VLAN_PROFILE_REF_COUNT(unit, oidx) = 1; 2603 idx = oidx; 2604 } 2605 } 2606 BCM_IF_ERROR_RETURN(rv); 2607 2608 /* Set new vlan profile index. */ 2609 rv = _vlan_profile_idx_set(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 2610 buf, vlan, idx); 2611 BCM_IF_ERROR_RETURN(rv); 2612 2613 /* Write back vlan table entry. */ 2614 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int) vlan, buf); 2615 BCM_IF_ERROR_RETURN(rv); 2616 2617 /* Delete original vlan profile if new one was allocated. */ 2618 if (oidx != idx) { 2619 rv = _vlan_profile_delete(unit, oidx); 2620 BCM_IF_ERROR_RETURN(rv); 2621 } 2622 return (BCM_E_NONE); 2623 } 2624 2625 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 2626 2627 #ifdef BCM_TRIUMPH2_SUPPORT 2628 /* 2629 * Function: 2630 * bcm_xgs3_vlan_mpls_table_init 2631 * 2632 * Purpose: 2633 * Initialize the VLAN_MPLS table with the default entry in it. 2634 * 2635 * Parameters: 2636 * unit - (IN) BCM device number. 2637 * vd - (IN) VLAN data. 2638 * 2639 * Return: 2640 * BCM_E_XXX 2641 */ 2642 STATIC int 2643 _bcm_xgs3_vlan_mpls_table_init(int unit, bcm_vlan_data_t *vd) 2644 { 2645 vlan_mpls_entry_t vlan_mpls; 2646 2647 if ((SAL_BOOT_QUICKTURN || SAL_BOOT_PLISIM) && (!SAL_BOOT_BCMSIM) && 2648 !SOC_IS_HAWKEYE(unit) && !SOC_IS_KATANA2(unit)) { 2649 LOG_CLI((BSL_META_U(unit, 2650 "SIMULATION: skipped VLAN_MPLS table clear " 2651 "(assuming hardware did it)\n"))); 2652 } else if (!SOC_IS_RCPU_ONLY(unit)) { 2653 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, VLAN_MPLSm, MEM_BLOCK_ALL, TRUE)); 2654 } 2655 2656 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t)); 2657 BCM_IF_ERROR_RETURN 2658 (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vd->vlan_tag, 2659 &vlan_mpls)); 2660 2661 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, L3_IIFf, vd->vlan_tag); 2662 2663 if (soc_feature(unit, soc_feature_mpls)) { 2664 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, MPLS_ENABLEf, 0x1); 2665 } 2666 if (soc_feature(unit, soc_feature_mim)) { 2667 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, MIM_TERM_ENABLEf, 2668 0x1); 2669 } 2670 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2671 if (soc_feature(unit, soc_feature_vlan_filter)) { 2672 2673 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, EN_IFILTERf, 2674 0x1); 2675 } 2676 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 2677 BCM_IF_ERROR_RETURN 2678 (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vd->vlan_tag, 2679 &vlan_mpls)); 2680 2681 return BCM_E_NONE; 2682 } 2683 #endif 2684 2685 /* 2686 * Function: 2687 * bcm_xgs3_vlan_init 2688 * 2689 * Purpose: 2690 * Initialize the VLAN tables with the default entry in it. 2691 * 2692 * Parameters: 2693 * unit - (IN) BCM device number. 2694 * 2695 * Return: 2696 * BCM_E_XXX 2697 */ 2698 static int 2699 _bcm_xgs3_vlan_table_init(int unit, bcm_vlan_data_t *vd, soc_mem_t table) 2700 { 2701 vlan_tab_entry_t ve; 2702 bcm_pbmp_t pbm; 2703 int rv; 2704 2705 #ifdef BCM_SHADOW_SUPPORT 2706 /* No EGR_VLAN support for shadow */ 2707 if(SOC_IS_SHADOW(unit)) { 2708 return BCM_E_NONE; 2709 } 2710 #endif 2711 2712 assert(sizeof(vlan_tab_entry_t) >= sizeof(egr_vlan_entry_t)); 2713 assert(sizeof(vlan_tab_entry_t) >= sizeof(vlan_2_tab_entry_t)); 2714 2715 if ((SAL_BOOT_QUICKTURN || SAL_BOOT_PLISIM) && (!SAL_BOOT_BCMSIM) && 2716 !soc_mem_field32_get(unit, table, 2717 soc_mem_entry_null(unit, table), VALIDf) && 2718 !SOC_IS_HAWKEYE(unit) && !SOC_IS_KATANA2(unit)) { 2719 LOG_CLI((BSL_META_U(unit, 2720 "SIMULATION: skipped VLAN table clear " 2721 "(assuming hardware did it)\n"))); 2722 } else if (!SOC_IS_RCPU_ONLY(unit)) { 2723 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, table, MEM_BLOCK_ALL, TRUE)); 2724 } 2725 2726 sal_memcpy(&ve, soc_mem_entry_null(unit, table), 2727 soc_mem_entry_words(unit, table) * 4); 2728 2729 BCM_PBMP_ASSIGN(pbm, vd->ut_port_bitmap); 2730 #ifdef BCM_KATANA2_SUPPORT 2731 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 2732 bcm_pbmp_t temp_pbm; 2733 2734 BCM_PBMP_ASSIGN(temp_pbm, PBMP_E_ALL(unit)); 2735 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbm)); 2736 2737 #ifndef BCM_VLAN_NO_DEFAULT_ETHER 2738 BCM_PBMP_OR(pbm, temp_pbm); 2739 #endif /* BCM_VLAN_NO_DEFAULT_ETHER */ 2740 } else 2741 #endif /* BCM_KATANA2_SUPPORT */ 2742 { 2743 #ifndef BCM_VLAN_NO_DEFAULT_ETHER 2744 BCM_PBMP_OR(pbm, PBMP_E_ALL(unit)); 2745 #endif /* BCM_VLAN_NO_DEFAULT_ETHER */ 2746 } 2747 2748 if (TABLE_HAS_T_BITMAP(unit, table)) { 2749 #if defined(BCM_TOMAHAWK3_SUPPORT) 2750 if ((table == VLAN_TABLE(unit)) && 2751 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 2752 2753 /* Use profile based approach to the port bitmap */ 2754 uint32 profile_idx; 2755 2756 /* Initialize the port bitmap profile table */ 2757 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_pbmp_profile_init(unit)); 2758 2759 /* Insert the port bitmap into the profile table */ 2760 BCM_IF_ERROR_RETURN( 2761 _bcm_th3_vlan_pbmp_profile_entry_add( 2762 unit, vd->port_bitmap, &profile_idx)); 2763 2764 /* Set the corressponding profile index into the VLAN table */ 2765 soc_mem_field32_set( 2766 unit, table, &ve, PORT_BITMAP_PROFILE_PTRf, profile_idx); 2767 } else 2768 #endif /* BCM_TOMAHAWK3_SUPPORT */ 2769 { 2770 soc_mem_pbmp_field_set( 2771 unit, table, &ve, PORT_BITMAPf, &vd->port_bitmap); 2772 } 2773 2774 if ((table == VLAN_TABLE(unit)) && 2775 SOC_MEM_FIELD_VALID(unit, table, ING_PORT_BITMAPf)) { 2776 soc_mem_pbmp_field_set(unit, table, &ve, ING_PORT_BITMAPf, 2777 &vd->port_bitmap); 2778 } 2779 } 2780 /* This function will be called with VLAN_TABm, EGR_VLANm, and VLAN_2_TABm 2781 * for TH2 and TH3. In TH2/TH3, VLAN_2_TABm has STGf while VLAN_TABm does 2782 * not. The check is to prevent STGf being set wrongly. 2783 */ 2784 if (SOC_MEM_FIELD_VALID(unit, table, STGf)) { 2785 soc_mem_field32_set(unit, table, &ve, STGf, BCM_STG_DEFAULT); 2786 } 2787 soc_mem_field32_set(unit, table, &ve, VALIDf, 1); 2788 2789 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 2790 if (SOC_MEM_FIELD_VALID(unit, table, L3_IIFf)) { 2791 uint32 l3_iif_value; 2792 2793 if (soc_feature(unit, soc_feature_l3_iif_under_4k)) { 2794 l3_iif_value = 0; 2795 } else { 2796 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 2797 l3_iif_value = vd->vlan_tag; 2798 } else { 2799 /* L3_IIFf value should be 0 once device can't support L3 2800 * ingress interface 2801 */ 2802 l3_iif_value = 0; 2803 } 2804 } 2805 soc_mem_field32_set(unit, table, &ve, L3_IIFf, l3_iif_value); 2806 } 2807 #endif 2808 #if defined(BCM_EASY_RELOAD_SUPPORT) 2809 if (SOC_IS_RELOADING(unit)) { 2810 _bcm_vlan_valid_set(unit, table, vd->vlan_tag, 1); 2811 } 2812 #endif 2813 2814 if (TABLE_HAS_UT_BITMAP(unit, table)) { 2815 soc_mem_pbmp_field_set(unit, table, &ve, UT_BITMAPf, &pbm); 2816 } 2817 2818 #if defined(BCM_TRIDENT3_SUPPORT) 2819 if (soc_feature(unit, soc_feature_vlan_filter)) { 2820 if (table == VLAN_TABm && SOC_IS_TRIDENT3X(unit)) { 2821 soc_mem_field32_set(unit, table, &ve, EN_IFILTERf, 0x1); 2822 } 2823 } 2824 #endif /* BCM_TRIDENT3_SUPPORT */ 2825 2826 if ((table == EGR_VLANm && SOC_IS_FBX(unit)) || 2827 (table == VLAN_TABm && SOC_IS_KATANA2(unit))) { 2828 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 2829 || defined(BCM_RAVEN_SUPPORT) 2830 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 2831 uint16 tpid; 2832 int tpid_index; 2833 2834 tpid = _bcm_fb2_outer_tpid_default_get(unit); 2835 2836 /* Add the default outer TPID entry twice during init so that 2837 * the default entry does not get removed even when no table 2838 * entry is referencing to the default TPID entry. 2839 */ 2840 BCM_IF_ERROR_RETURN 2841 (_bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index)); 2842 BCM_IF_ERROR_RETURN 2843 (_bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index)); 2844 soc_mem_field32_set(unit, table, &ve, OUTER_TPID_INDEXf, 2845 tpid_index); 2846 } 2847 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2848 2849 if (soc_feature(unit, soc_feature_vlan_filter)) { 2850 2851 soc_mem_field32_set(unit, table, &ve, EN_EFILTERf, 0x1); 2852 } 2853 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 2854 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 2855 } 2856 2857 if (TABLE_HAS_PFM(unit, table)) { 2858 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 2859 || defined(BCM_RAVEN_SUPPORT) 2860 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 2861 int profile_index; 2862 2863 BCM_IF_ERROR_RETURN (_vlan_profile_init(unit)); 2864 rv = _vlan_profile_default_add(unit, &profile_index); 2865 BCM_IF_ERROR_RETURN(rv); 2866 2867 rv = _vlan_profile_idx_set(unit, table, VLAN_PROFILE_PTRf, 2868 (uint32 *)&ve, vd->vlan_tag, 2869 profile_index); 2870 BCM_IF_ERROR_RETURN(rv); 2871 } else 2872 #endif 2873 { 2874 bcm_vlan_mcast_flood_t mode; 2875 int pfm; 2876 2877 rv = _bcm_esw_vlan_flood_default_get(unit, &mode); 2878 BCM_IF_ERROR_RETURN(rv); 2879 2880 rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, mode, &pfm); 2881 BCM_IF_ERROR_RETURN(rv); 2882 if (SOC_MEM_FIELD_VALID(unit, table, PFMf)) { 2883 soc_mem_field32_set(unit, table, &ve, PFMf, pfm); 2884 } 2885 } 2886 } 2887 2888 #if defined(BCM_TRIDENT3_SUPPORT) 2889 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 2890 vlan_attrs_1_entry_t vlan_attrs; 2891 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t)); 2892 BCM_IF_ERROR_RETURN 2893 (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vd->vlan_tag, 2894 &vlan_attrs)); 2895 2896 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, STGf, 2897 BCM_STG_DEFAULT); 2898 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, VALIDf, 1); 2899 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, FID_IDf, 0); 2900 2901 if (soc_feature(unit, soc_feature_mpls)) { 2902 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MPLS_ENABLEf, 0x1); 2903 } 2904 if (soc_feature(unit, soc_feature_mim)) { 2905 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MIM_TERM_ENABLEf, 0x1); 2906 } 2907 if (soc_feature(unit, soc_feature_vlan_filter)) { 2908 2909 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, EN_IFILTERf, 2910 0x1); 2911 } 2912 BCM_IF_ERROR_RETURN 2913 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vd->vlan_tag, 2914 &vlan_attrs)); 2915 } 2916 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf)) { 2917 vlan_tab_entry_t vlan_tab; 2918 sal_memset(&vlan_tab, 0, sizeof(vlan_tab_entry_t)); 2919 BCM_IF_ERROR_RETURN 2920 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vd->vlan_tag, 2921 &vlan_tab)); 2922 2923 soc_mem_field32_set(unit, VLAN_TABm, &vlan_tab, L3_IIFf, 2924 vd->vlan_tag); 2925 BCM_IF_ERROR_RETURN 2926 (soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, vd->vlan_tag, 2927 &vlan_tab)); 2928 } 2929 #endif 2930 2931 BCM_IF_ERROR_RETURN 2932 (soc_mem_write(unit, table, MEM_BLOCK_ALL, vd->vlan_tag, &ve)); 2933 2934 #if defined(BCM_TRIDENT3_SUPPORT) 2935 if (table == EGR_VLANm && 2936 soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) { 2937 BCM_IF_ERROR_RETURN 2938 (bcm_td3_vlan_vfi_untag_init(unit, vd->vlan_tag, 2939 vd->ut_port_bitmap)); 2940 } 2941 #endif 2942 2943 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 2944 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 2945 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set( 2946 unit, vd->vlan_tag, (table == EGR_VLANm), TRUE, vd->port_bitmap)); 2947 } 2948 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 2949 2950 return BCM_E_NONE; 2951 } 2952 2953 /* 2954 * Function: 2955 * bcm_xgs3_vlan_create 2956 * Purpose: 2957 * Create a VLAN entry in VLAN_TAB 2958 */ 2959 2960 static int 2961 _bcm_xgs3_vlan_table_create(int unit, bcm_vlan_t vid, int table) 2962 { 2963 vlan_tab_entry_t vt; 2964 int rv; 2965 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 2966 int ingress_map_mode=0; 2967 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 2968 int use_default = TRUE; /* use default value for VLAN_TABm */ 2969 2970 assert(sizeof(vlan_tab_entry_t) >= sizeof(egr_vlan_entry_t)); 2971 assert(sizeof(vlan_tab_entry_t) >= sizeof(vlan_2_tab_entry_t)); 2972 2973 /* Upper layer already checks that vid is valid */ 2974 2975 soc_mem_lock(unit, table); 2976 2977 if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) { 2978 soc_mem_unlock(unit, table); 2979 return rv; 2980 } 2981 2982 if (!SOC_IS_RELOADING(unit)) { 2983 if (soc_mem_field32_get(unit, table, &vt, VALIDf) != 2984 soc_mem_field32_get(unit, table, 2985 soc_mem_entry_null(unit, table), VALIDf)) { 2986 if (!SOC_IS_KATANA2(unit)) { 2987 soc_mem_unlock(unit, table); 2988 return BCM_E_EXISTS; 2989 } 2990 } 2991 } 2992 2993 /* don't use default value if already pre-configured*/ 2994 if (SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) { 2995 use_default = FALSE; 2996 } 2997 /* This function will be called with VLAN_TABm, EGR_VLANm, and VLAN_2_TABm 2998 * in TH2/TH3. In TH2/TH3, VLAN_2_TABm has STGf while VLAN_TABm does not. 2999 * The check is to prevent STGf being set wrongly. The STG value doesn't 3000 * matter much; it will get changed immediately after this routine completes 3001 */ 3002 if (SOC_MEM_FIELD_VALID(unit, table, STGf)) { 3003 soc_mem_field32_set(unit, table, &vt, STGf, 0); 3004 } 3005 soc_mem_field32_set(unit, table, &vt, VALIDf, 1); 3006 3007 #if defined(BCM_EASY_RELOAD_SUPPORT) 3008 if (SOC_IS_RELOADING(unit)) { 3009 _bcm_vlan_valid_set(unit, table, vid, 1); 3010 } 3011 #endif 3012 3013 #if defined(BCM_TOMAHAWK3_SUPPORT) 3014 if ((table == VLAN_TABLE(unit)) && 3015 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 3016 pbmp_t pbmp; 3017 uint32 profile_idx; 3018 3019 /* Insert a profile entry with empty port bitmap */ 3020 SOC_PBMP_CLEAR(pbmp); 3021 rv = _bcm_th3_vlan_pbmp_profile_entry_add(unit, pbmp, &profile_idx); 3022 if (BCM_FAILURE(rv)) { 3023 soc_mem_unlock(unit, table); 3024 return rv; 3025 } 3026 3027 /* Set the corressponding profile index into the VLAN table entry */ 3028 soc_mem_field32_set( 3029 unit, table, &vt, PORT_BITMAP_PROFILE_PTRf, profile_idx); 3030 } 3031 #endif /* BCM_TOMAHAWK3_SUPPORT */ 3032 3033 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 3034 /* Set default vrf id if supported. */ 3035 if (use_default && SOC_MEM_FIELD_VALID(unit, table, VRF_IDf)) { 3036 soc_mem_field32_set(unit, table, &vt, VRF_IDf, 0); 3037 } 3038 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_SCORPION_SUPPORT */ 3039 3040 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 3041 /* Set L3_IIF, using vid as index into L3_IIF table */ 3042 if (SOC_MEM_FIELD_VALID(unit, table, L3_IIFf)) { 3043 uint32 ingress_intf = 0; 3044 3045 /* Check L3 Ingress Interface Map mode. */ 3046 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 3047 BCM_IF_ERROR_RETURN( 3048 bcm_xgs3_l3_ingress_intf_map_get(unit, &ingress_map_mode)); 3049 3050 if (ingress_map_mode) { 3051 if (soc_feature(unit, soc_feature_l3_iif_under_4k)) { 3052 ingress_intf = 0; 3053 } else { 3054 if (use_default) { 3055 ingress_intf = BCM_L3_INGRESS_INTERFACE_INVALID; 3056 } 3057 } 3058 } else { 3059 ingress_intf = vid; 3060 } 3061 } else { 3062 /* L3_IIFf for those device can't support L3 ingress interface 3063 * should be never referenced. Remaining the value at 0. 3064 */ 3065 ingress_intf = 0; 3066 } 3067 3068 soc_mem_field32_set(unit, table, &vt, L3_IIFf, ingress_intf); 3069 } 3070 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 3071 3072 if (TABLE_HAS_UT_BITMAP(unit, table)) { 3073 pbmp_t pbmp; 3074 SOC_PBMP_CLEAR(pbmp); 3075 soc_mem_pbmp_field_set(unit, table, &vt, UT_BITMAPf, &pbmp); 3076 } 3077 3078 if ((table == EGR_VLANm && SOC_IS_FBX(unit)) || 3079 (table == VLAN_TABm && SOC_IS_KATANA2(unit))) { 3080 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 3081 || defined(BCM_RAVEN_SUPPORT) 3082 if (use_default && soc_feature(unit, soc_feature_vlan_ctrl)) { 3083 uint16 tpid; 3084 int tpid_index; 3085 3086 tpid = _bcm_fb2_outer_tpid_default_get(unit); 3087 3088 _bcm_fb2_outer_tpid_tab_lock(unit); 3089 rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index); 3090 _bcm_fb2_outer_tpid_tab_unlock(unit); 3091 3092 if (BCM_SUCCESS(rv)) { 3093 soc_mem_field32_set(unit, table, &vt, OUTER_TPID_INDEXf, 3094 tpid_index); 3095 } 3096 } 3097 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3098 if (soc_feature(unit, soc_feature_vlan_filter)) { 3099 3100 soc_mem_field32_set(unit, table, &vt, EN_EFILTERf, 0x1); 3101 } 3102 #endif 3103 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 3104 } 3105 3106 #if defined(BCM_TRIDENT3_SUPPORT) 3107 if (soc_feature(unit, soc_feature_vlan_filter)) { 3108 if (table == VLAN_TABm && SOC_IS_TRIDENT3X(unit)) { 3109 soc_mem_field32_set(unit, table, &vt, EN_IFILTERf, 0x1); 3110 } 3111 } 3112 #endif /* BCM_TRIDENT3_SUPPORT */ 3113 3114 #if defined(BCM_TRIDENT3_SUPPORT) 3115 if (table == EGR_VLANm && 3116 soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) { 3117 pbmp_t pbmp; 3118 SOC_PBMP_CLEAR(pbmp); 3119 BCM_IF_ERROR_RETURN 3120 (bcm_td3_vlan_vfi_untag_add(unit, vid, pbmp, pbmp)); 3121 } 3122 #endif /* BCM_TRIDENT3_SUPPORT */ 3123 3124 /* 3125 * Multicast flood setting 3126 */ 3127 if (TABLE_HAS_PFM(unit, table)) { 3128 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 3129 || defined(BCM_RAVEN_SUPPORT) 3130 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 3131 3132 if (use_default) { 3133 int profile_index, rv; 3134 3135 rv = _vlan_profile_default_add(unit, &profile_index); 3136 if (BCM_FAILURE(rv)) { 3137 soc_mem_unlock(unit, table); 3138 return rv; 3139 } 3140 3141 rv = _vlan_profile_idx_set(unit, table, VLAN_PROFILE_PTRf, 3142 (uint32 *)&vt, vid, profile_index); 3143 if (BCM_FAILURE(rv)) { 3144 soc_mem_unlock(unit, table); 3145 return rv; 3146 } 3147 3148 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt); 3149 if (BCM_FAILURE(rv)) { 3150 _vlan_profile_delete(unit, profile_index); 3151 } 3152 soc_mem_unlock(unit, table); 3153 return rv; 3154 } 3155 } else 3156 #endif 3157 { 3158 bcm_vlan_mcast_flood_t mode; 3159 int pfm; 3160 3161 rv =_bcm_esw_vlan_flood_default_get(unit, &mode); 3162 if (BCM_FAILURE(rv)) { 3163 soc_mem_unlock(unit, table); 3164 return rv; 3165 } 3166 rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, mode, &pfm); 3167 if (BCM_FAILURE(rv)) { 3168 soc_mem_unlock(unit, table); 3169 return rv; 3170 } 3171 3172 if (SOC_MEM_FIELD_VALID(unit, table, PFMf)) { 3173 soc_mem_field32_set(unit, table, &vt, PFMf, pfm); 3174 } 3175 } 3176 } 3177 3178 if (BCM_SUCCESS(rv)) { 3179 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt); 3180 } 3181 3182 soc_mem_unlock(unit, table); 3183 3184 return rv; 3185 } 3186 3187 /* 3188 * Function: 3189 * bcm_xgs3_vlan_destroy 3190 * Purpose: 3191 * Clear a VLAN entry in VLAN_TAB 3192 */ 3193 3194 static int 3195 _bcm_xgs3_vlan_table_destroy(int unit, bcm_vlan_t vid, int table) 3196 { 3197 vlan_tab_entry_t vt; 3198 int rv; 3199 3200 /* Upper layer already checks that vid is valid */ 3201 3202 soc_mem_lock(unit, table); 3203 3204 if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) { 3205 soc_mem_unlock(unit, table); 3206 return rv; 3207 } 3208 3209 if (_bcm_vlan_valid_check(unit, table, &vt, vid) == BCM_E_NOT_FOUND) { 3210 soc_mem_unlock(unit, table); 3211 return BCM_E_NOT_FOUND; 3212 } 3213 3214 #if defined(BCM_EASY_RELOAD_SUPPORT) 3215 if (SOC_IS_RELOADING(unit)) { 3216 _bcm_vlan_valid_set(unit, table, vid, 0); 3217 } 3218 #endif 3219 3220 #if defined(BCM_TOMAHAWK3_SUPPORT) 3221 if ((VLAN_TABLE(unit) == table) && 3222 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 3223 int profile_ptr = 3224 soc_mem_field32_get(unit, table, &vt, PORT_BITMAP_PROFILE_PTRf); 3225 rv = _bcm_th3_vlan_pbmp_profile_entry_delete(unit, profile_ptr); 3226 3227 if (BCM_FAILURE(rv)) { 3228 soc_mem_unlock(unit, table); 3229 return rv; 3230 } 3231 } 3232 #endif /* BCM_TOMAHAWK3_SUPPORT */ 3233 3234 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, 3235 soc_mem_entry_null(unit, table)); 3236 if (BCM_FAILURE(rv)) { 3237 soc_mem_unlock(unit, table); 3238 return rv; 3239 } 3240 3241 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 3242 || defined(BCM_RAVEN_SUPPORT) 3243 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 3244 if (table == VLAN_TABm) { 3245 int profile_ptr, tpid_ptr; 3246 3247 _bcm_fb2_outer_tpid_tab_lock(unit); 3248 3249 rv = _vlan_profile_idx_get(unit, table, VLAN_PROFILE_PTRf, 3250 (uint32 *)&vt, vid, &profile_ptr); 3251 if (BCM_FAILURE(rv)) { 3252 _bcm_fb2_outer_tpid_tab_unlock(unit); 3253 soc_mem_unlock(unit, table); 3254 return rv; 3255 } 3256 3257 rv = _bcm_fb2_outer_tpid_lkup(unit, 3258 VLAN_PROFILE_ENTRY(unit, profile_ptr).outer_tpid, 3259 &tpid_ptr); 3260 if (BCM_FAILURE(rv)) { 3261 _bcm_fb2_outer_tpid_tab_unlock(unit); 3262 soc_mem_unlock(unit, table); 3263 return rv; 3264 } 3265 3266 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_ptr); 3267 if (BCM_FAILURE(rv)) { 3268 _bcm_fb2_outer_tpid_tab_unlock(unit); 3269 soc_mem_unlock(unit, table); 3270 return rv; 3271 } 3272 3273 rv = _vlan_profile_delete(unit, profile_ptr); 3274 _bcm_fb2_outer_tpid_tab_unlock(unit); 3275 } 3276 } 3277 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 3278 3279 #if defined(BCM_TRIUMPH2_SUPPORT) 3280 if (soc_feature(unit, soc_feature_gport_service_counters)) { 3281 /* Release Service counter, if any */ 3282 _bcm_esw_flex_stat_handle_free(unit, _bcmFlexStatTypeService, vid); 3283 } 3284 #endif 3285 3286 soc_mem_unlock(unit, table); 3287 return rv; 3288 } 3289 3290 /* 3291 * Function: 3292 * _bcm_xgs3_vlan_table_port_add 3293 * Purpose: 3294 * Add ports to the VLAN bitmap in a VLAN_TAB entry. 3295 */ 3296 int 3297 _bcm_xgs3_vlan_table_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, 3298 pbmp_t ubmp, pbmp_t ing_pbmp, int table) 3299 { 3300 vlan_tab_entry_t vt; 3301 int rv; 3302 bcm_pbmp_t cur_pbmp; 3303 3304 /* Only allow untagged ports on the vlan. */ 3305 SOC_PBMP_AND(ubmp, pbmp); 3306 3307 /* Draco does not have room for CMIC/IPIC in ubmp */ 3308 SOC_PBMP_REMOVE(ubmp, PBMP_CMIC(unit)); 3309 SOC_PBMP_REMOVE(ubmp, PBMP_ST_ALL(unit)); 3310 3311 /* Upper layer already checks that vid is valid */ 3312 3313 soc_mem_lock(unit, table); 3314 3315 if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) { 3316 soc_mem_unlock(unit, table); 3317 return rv; 3318 } 3319 3320 if ((rv = _bcm_vlan_valid_check(unit, table, &vt, vid)) == BCM_E_NOT_FOUND) { 3321 soc_mem_unlock(unit, table); 3322 return rv; 3323 } 3324 3325 /* 3326 * Update the entry for this VLAN. 3327 */ 3328 if (TABLE_HAS_T_BITMAP(unit, table)) { 3329 #if defined(BCM_TOMAHAWK3_SUPPORT) 3330 if ((table == VLAN_TABLE(unit)) && 3331 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 3332 rv = _bcm_th3_vlan_pbmp_port_add(unit, &vt, &pbmp); 3333 if (BCM_FAILURE(rv)) { 3334 soc_mem_unlock(unit, table); 3335 return rv; 3336 } 3337 } else 3338 #endif /* BCM_TOMAHAWK3_SUPPORT */ 3339 { 3340 soc_mem_pbmp_field_get(unit, table, &vt, PORT_BITMAPf, &cur_pbmp); 3341 BCM_PBMP_OR(cur_pbmp, pbmp); 3342 soc_mem_pbmp_field_set(unit, table, &vt, PORT_BITMAPf, &cur_pbmp); 3343 } 3344 } 3345 3346 if (TABLE_HAS_UT_BITMAP(unit, table)) { 3347 soc_mem_pbmp_field_get(unit, table, &vt, UT_BITMAPf, &cur_pbmp); 3348 BCM_PBMP_REMOVE(cur_pbmp, pbmp); 3349 BCM_PBMP_OR(cur_pbmp, ubmp); 3350 soc_mem_pbmp_field_set(unit, table, &vt, UT_BITMAPf, &cur_pbmp); 3351 } 3352 3353 if (soc_mem_field_valid(unit, table, ING_PORT_BITMAPf)) { 3354 soc_mem_pbmp_field_get(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp); 3355 BCM_PBMP_OR(cur_pbmp, ing_pbmp); 3356 soc_mem_pbmp_field_set(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp); 3357 } 3358 3359 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt); 3360 3361 soc_mem_unlock(unit, table); 3362 3363 return rv; 3364 } 3365 3366 /* 3367 * Function: 3368 * bcm_xgs3_vlan_port_remove 3369 * Purpose: 3370 * Remove ports from the VLAN bitmap in a VLAN_TAB entry. 3371 */ 3372 3373 int 3374 _bcm_xgs3_vlan_table_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp, 3375 pbmp_t ubmp, pbmp_t ing_pbmp, int table) 3376 { 3377 vlan_tab_entry_t vt; 3378 int rv; 3379 bcm_pbmp_t cur_pbmp; 3380 3381 /* Upper layer already checks that vid is valid */ 3382 3383 soc_mem_lock(unit, table); 3384 3385 if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) { 3386 soc_mem_unlock(unit, table); 3387 return rv; 3388 } 3389 3390 if ((rv = _bcm_vlan_valid_check(unit, table, &vt, vid)) == BCM_E_NOT_FOUND) { 3391 soc_mem_unlock(unit, table); 3392 return rv; 3393 } 3394 3395 if (TABLE_HAS_T_BITMAP(unit, table)) { 3396 #if defined(BCM_TOMAHAWK3_SUPPORT) 3397 if ((table == VLAN_TABLE(unit)) && 3398 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 3399 rv = _bcm_th3_vlan_pbmp_port_remove(unit, &vt, &pbmp); 3400 if (BCM_FAILURE(rv)) { 3401 soc_mem_unlock(unit, table); 3402 return rv; 3403 } 3404 } else 3405 #endif /* BCM_TOMAHAWK3_SUPPORT */ 3406 { 3407 soc_mem_pbmp_field_get(unit, table, &vt, PORT_BITMAPf, &cur_pbmp); 3408 BCM_PBMP_REMOVE(cur_pbmp, pbmp); 3409 soc_mem_pbmp_field_set(unit, table, &vt, PORT_BITMAPf, &cur_pbmp); 3410 } 3411 } 3412 3413 if (TABLE_HAS_UT_BITMAP(unit, table)) { 3414 soc_mem_pbmp_field_get(unit, table, &vt, UT_BITMAPf, &cur_pbmp); 3415 BCM_PBMP_REMOVE(cur_pbmp, ubmp); 3416 soc_mem_pbmp_field_set(unit, table, &vt, UT_BITMAPf, &cur_pbmp); 3417 } 3418 3419 if (soc_mem_field_valid(unit, table, ING_PORT_BITMAPf)) { 3420 soc_mem_pbmp_field_get(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp); 3421 BCM_PBMP_REMOVE(cur_pbmp, ing_pbmp); 3422 soc_mem_pbmp_field_set(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp); 3423 } 3424 3425 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt); 3426 3427 soc_mem_unlock(unit, table); 3428 3429 return rv; 3430 } 3431 3432 /* 3433 * Function: 3434 * bcm_xgs3_vlan_table_port_get 3435 * Purpose: 3436 * Read the port bitmap from a vlan entry. Both VLAN_TAB and EGR_VLAN 3437 * shall be identical, except for the untagged bitmap, which is only 3438 * available via EGR_VLAN. 3439 */ 3440 3441 int 3442 _bcm_xgs3_vlan_table_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, 3443 pbmp_t *ubmp, pbmp_t *ing_pbmp, uint32 table) 3444 { 3445 vlan_tab_entry_t vt; 3446 3447 /* Upper layer already checks that vid is valid */ 3448 3449 SOC_IF_ERROR_RETURN 3450 (soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)); 3451 3452 BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, table, &vt, vid)); 3453 3454 if (TABLE_HAS_T_BITMAP(unit, table)) { 3455 if (pbmp != NULL) { 3456 #if defined(BCM_TOMAHAWK3_SUPPORT) 3457 if ((table == VLAN_TABLE(unit)) && 3458 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 3459 3460 int rv; 3461 uint32 profile_idx; 3462 3463 /* Retrieve the profile index from the VLAN table entry */ 3464 profile_idx = soc_mem_field32_get( 3465 unit, VLAN_2_TABm, &vt, PORT_BITMAP_PROFILE_PTRf); 3466 3467 /* Based on the index retrieve the pbmp from the profile mem */ 3468 rv = _bcm_th3_vlan_pbmp_profile_entry_get( unit, 3469 profile_idx, 3470 pbmp); 3471 if (BCM_FAILURE(rv)) { 3472 return rv; 3473 } 3474 } else 3475 #endif /* BCM_TOMAHAWK3_SUPPORT */ 3476 { 3477 soc_mem_pbmp_field_get(unit, table, &vt, PORT_BITMAPf, pbmp); 3478 } 3479 } 3480 } 3481 3482 if (soc_mem_field_valid(unit, table, UT_BITMAPf)) { 3483 if (ubmp != NULL) { 3484 soc_mem_pbmp_field_get(unit, table, &vt, UT_BITMAPf, ubmp); 3485 } 3486 } 3487 3488 if (soc_mem_field_valid(unit, table, ING_PORT_BITMAPf)) { 3489 if (ing_pbmp != NULL) { 3490 soc_mem_pbmp_field_get(unit, table, &vt, ING_PORT_BITMAPf, 3491 ing_pbmp); 3492 } 3493 } 3494 3495 return BCM_E_NONE; 3496 } 3497 3498 /* 3499 * Function: 3500 * bcm_xgs3_vlan_stg_get 3501 * Purpose: 3502 * Read the STG number from a vlan entry. 3503 */ 3504 3505 int 3506 bcm_xgs3_vlan_stg_get(int unit, bcm_vlan_t vid, bcm_stg_t *stg_ptr) 3507 { 3508 vlan_tab_entry_t vt; 3509 3510 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 3511 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 3512 return bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vid, FALSE, stg_ptr); 3513 } 3514 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 3515 3516 SOC_IF_ERROR_RETURN 3517 (soc_mem_read(unit, VLAN_TABLE(unit), MEM_BLOCK_ANY, (int) vid, &vt)); 3518 3519 BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, VLAN_TABLE(unit), &vt, vid)); 3520 3521 *stg_ptr = soc_mem_field32_get(unit, VLAN_TABLE(unit), &vt, STGf); 3522 3523 return BCM_E_NONE; 3524 } 3525 3526 /* 3527 * Function: 3528 * bcm_xgs3_vlan_stg_set 3529 * Purpose: 3530 * Update the STG number for a VLAN_TAB entry. 3531 */ 3532 3533 static int 3534 _bcm_xgs3_vlan_table_stg_set(int unit, bcm_vlan_t vid, 3535 bcm_stg_t stg, int table) 3536 { 3537 vlan_tab_entry_t vt; 3538 int rv; 3539 3540 /* Upper layer already checks that vid is valid */ 3541 3542 soc_mem_lock(unit, table); 3543 3544 rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt); 3545 3546 if (BCM_SUCCESS(rv)) { 3547 rv = _bcm_vlan_valid_check(unit, table, &vt, vid); 3548 } 3549 3550 if (BCM_SUCCESS(rv)) { 3551 soc_mem_field32_set(unit, table, &vt, STGf, stg); 3552 3553 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt); 3554 } 3555 3556 if (BCM_SUCCESS(rv) && 3557 SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 3558 rv = soc_mem_field32_modify(unit, VLAN_ATTRS_1m, (int)vid, STGf, stg); 3559 } 3560 3561 soc_mem_unlock(unit, table); 3562 3563 return rv; 3564 } 3565 3566 #ifdef BCM_KATANA_SUPPORT 3567 /* 3568 * Function : 3569 * _vlan_kt_cosq_map_set 3570 * 3571 * Purpose : 3572 * Set per vlan cosq number. 3573 * 3574 * Parameters: 3575 * unit - (IN) BCM device number. 3576 * vid - (IN) Vlan table entry buffer. 3577 * control - (IN) vlan control structure 3578 * Return : 3579 * BCM_E_XXX 3580 */ 3581 STATIC int 3582 _vlan_kt_cosq_map_set(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control) 3583 { 3584 vlan_cos_map_entry_t vcm; 3585 int rv; 3586 3587 rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm); 3588 BCM_IF_ERROR_RETURN(rv); 3589 3590 soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VALIDf, 3591 ((control->flags & BCM_VLAN_COSQ_ENABLE) ? 1 : 0)); 3592 3593 if (control->flags & BCM_VLAN_COSQ_ENABLE) { 3594 3595 if ((control->cosq < 0) || (control->cosq > 63)) { 3596 return BCM_E_PARAM; 3597 } 3598 soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf, control->cosq); 3599 if ((((control->qos_map_id >> _BCM_QOS_MAP_SHIFT) != 3600 _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE)) || 3601 ((control->qos_map_id & _BCM_QOS_MAP_TYPE_MASK) > 3602 _BCM_QOS_MAP_ING_QUEUE_OFFSET_MAX)) { 3603 /* value of 0 is not a error case. It should set 3604 the QUEUE_OFFSET_PROFILE_INDEXf to 0 */ 3605 if (control->qos_map_id != 0) { 3606 return (BCM_E_PARAM); 3607 } 3608 } 3609 soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, 3610 QUEUE_OFFSET_PROFILE_INDEXf, 3611 (control->qos_map_id & _BCM_QOS_MAP_TYPE_MASK)); 3612 } 3613 3614 /* Write back updated buffer. */ 3615 rv = soc_mem_write(unit, VLAN_COS_MAPm, MEM_BLOCK_ALL, (int)vid, &vcm); 3616 return (rv); 3617 } 3618 3619 /* 3620 * Function : 3621 * _vlan_kt_cosq_map_get 3622 * 3623 * Purpose : 3624 * Get per vlan cosq number. 3625 * 3626 * Parameters: 3627 * unit - (IN) BCM device number. 3628 * vid - (IN) Vlan table entry buffer. 3629 * control- (OUT) vlan control structure. 3630 * Return : 3631 * BCM_E_XXX 3632 */ 3633 STATIC int 3634 _vlan_kt_cosq_map_get(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control) 3635 { 3636 vlan_cos_map_entry_t vcm; 3637 int rv; 3638 3639 rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm); 3640 if (BCM_FAILURE(rv)) { 3641 return rv; 3642 } 3643 3644 if (0 == soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VALIDf)) { 3645 return (BCM_E_NONE); 3646 } 3647 3648 control->flags |= BCM_VLAN_COSQ_ENABLE; 3649 control->cosq = soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf); 3650 control->qos_map_id = _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE << 3651 _BCM_QOS_MAP_SHIFT; 3652 control->qos_map_id |= soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, 3653 QUEUE_OFFSET_PROFILE_INDEXf); 3654 return (BCM_E_NONE); 3655 } 3656 #endif /* BCM_KATANA_SUPPORT */ 3657 3658 /* 3659 * Function: 3660 * _bcm_xgs3_vlan_reload 3661 * Purpose: 3662 * VLAN reload 3663 */ 3664 3665 static int 3666 _bcm_xgs3_vlan_table_reload(int unit, vbmp_t *bmp, int *count, int table) 3667 { 3668 vlan_tab_entry_t *vlan_entry, *vlan_tbl; 3669 int index, total, vlan_tbl_size; 3670 bcm_pbmp_t cur_pbmp; 3671 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 3672 || defined(BCM_RAVEN_SUPPORT) 3673 int profile_ptr; 3674 int outer_tpid, i; 3675 #endif 3676 #if defined(BCM_TRX_SUPPORT) 3677 int rv; /* Operation return status.*/ 3678 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 3679 uint32 value; 3680 #endif 3681 3682 vlan_tbl_size = sizeof(vlan_tab_entry_t) * \ 3683 soc_mem_index_count(unit, table); 3684 vlan_tbl = soc_cm_salloc(unit, vlan_tbl_size, "vlan tbl dma"); 3685 if (vlan_tbl == NULL) { 3686 return BCM_E_MEMORY; 3687 } 3688 3689 sal_memset((void *)vlan_tbl, 0, vlan_tbl_size); 3690 if (soc_mem_read_range(unit, table, MEM_BLOCK_ANY, 3691 soc_mem_index_min(unit, table), 3692 soc_mem_index_max(unit, table), vlan_tbl) < 0) { 3693 soc_cm_sfree(unit, vlan_tbl); 3694 return BCM_E_INTERNAL; 3695 } 3696 3697 soc_mem_lock(unit, table); 3698 3699 total = *count; 3700 3701 for (index = soc_mem_index_min(unit, table); 3702 index <= soc_mem_index_max(unit, table); index++) { 3703 vlan_entry = soc_mem_table_idx_to_pointer(unit, table, 3704 vlan_tab_entry_t *, 3705 vlan_tbl, index); 3706 3707 if (soc_mem_field32_get(unit, table, vlan_entry, VALIDf)) { 3708 if (TABLE_HAS_T_BITMAP(unit, table)) { 3709 #if defined(BCM_TRX_SUPPORT) && defined(BCM_TOMAHAWK3_SUPPORT) 3710 if ((table == VLAN_TABLE(unit)) && 3711 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 3712 BCM_PBMP_CLEAR(cur_pbmp); 3713 profile_ptr = 3714 soc_mem_field32_get( 3715 unit, table, vlan_entry, PORT_BITMAP_PROFILE_PTRf); 3716 rv = _bcm_th3_vlan_pbmp_profile_entry_get( 3717 unit, profile_ptr, &cur_pbmp); 3718 if (BCM_FAILURE(rv)) { 3719 soc_mem_unlock(unit, table); 3720 soc_cm_sfree(unit, vlan_tbl); 3721 return rv; 3722 } 3723 } else 3724 #endif /* BCM_TRX_SUPPORT && BCM_TOMAHAWK3_SUPPORT */ 3725 { 3726 soc_mem_pbmp_field_get( 3727 unit, table, vlan_entry, PORT_BITMAPf, &cur_pbmp); 3728 } 3729 if (BCM_PBMP_IS_NULL(cur_pbmp)) { 3730 if ((EGR_VLANm != table) && !SHR_BITGET(bmp->w, index)) { 3731 3732 continue; 3733 } 3734 } 3735 } 3736 if (!SHR_BITGET(bmp->w, index)) { 3737 SHR_BITSET(bmp->w, index); 3738 total++; 3739 } 3740 3741 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 3742 || defined(BCM_RAVEN_SUPPORT) 3743 profile_ptr = -1; 3744 if (soc_mem_field_valid(unit, table, VLAN_PROFILE_PTRf)) { 3745 profile_ptr = soc_mem_field32_get(unit, table, vlan_entry, 3746 VLAN_PROFILE_PTRf); 3747 } 3748 3749 if (profile_ptr >= 0) { 3750 VLAN_PROFILE_REF_COUNT(unit, profile_ptr)++; 3751 3752 outer_tpid = VLAN_PROFILE_ENTRY(unit, profile_ptr).outer_tpid; 3753 for (i = 0; i < BCM_MAX_TPID_ENTRIES; i++) { 3754 if (OUTER_TPID_ENTRY(unit, i) == outer_tpid) { 3755 OUTER_TPID_REF_COUNT(unit, i)++; 3756 break; 3757 } 3758 } 3759 #if defined(BCM_TRX_SUPPORT) 3760 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl) && 3761 SOC_MEM_FIELD_VALID (unit,VLAN_PROFILE_TABm, PROTOCOL_PKT_INDEXf)) { 3762 3763 rv = soc_mem_read(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ANY, profile_ptr, buf); 3764 BCM_IF_ERROR_RETURN(rv); 3765 3766 value = soc_mem_field32_get(unit, VLAN_PROFILE_TABm, buf, PROTOCOL_PKT_INDEXf); 3767 3768 _bcm_prot_pkt_ctrl_reference(unit, value); 3769 } 3770 #endif /* BCM_TRX_SUPPORT */ 3771 } 3772 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 3773 3774 #if defined(BCM_TRIUMPH2_SUPPORT) 3775 if (soc_feature(unit, soc_feature_gport_service_counters)) { 3776 if (soc_mem_field_valid(unit, table, SERVICE_CTR_IDXf)) { 3777 int fs_idx; 3778 fs_idx = 3779 soc_mem_field32_get(unit, table, vlan_entry, 3780 SERVICE_CTR_IDXf); 3781 if (fs_idx) { 3782 _bcm_esw_flex_stat_reinit_add(unit, 3783 _bcmFlexStatTypeService, fs_idx, index); 3784 } 3785 } 3786 } 3787 #endif 3788 } 3789 } 3790 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 3791 if ((VLAN_TABm == table) && 3792 soc_mem_field_valid(unit, VLAN_TABm, VLAN_PROFILE_PTRf)) { 3793 /* Create a dummy reference to default outer TPID entry so 3794 * that the default entry never gets removed. */ 3795 OUTER_TPID_REF_COUNT(unit, 0)++; 3796 } 3797 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 3798 soc_mem_unlock(unit, table); 3799 soc_cm_sfree(unit, vlan_tbl); 3800 *count = total; 3801 3802 return BCM_E_NONE; 3803 } 3804 3805 int 3806 bcm_xgs3_vlan_init(int unit, bcm_vlan_data_t *vd) 3807 { 3808 if (SOC_IS_HAWKEYE(unit)) { 3809 uint32 rval; 3810 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval)); 3811 soc_reg_field_set(unit, VLAN_CTRLr, &rval, USE_LEARN_VIDf, 0); 3812 soc_reg_field_set(unit, VLAN_CTRLr, &rval, LEARN_VIDf, 0); 3813 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, rval)); 3814 3815 SOC_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, &rval)); 3816 soc_reg_field_set(unit, EGR_CONFIGr, &rval, USE_LEARN_VIDf, 0); 3817 soc_reg_field_set(unit, EGR_CONFIGr, &rval, LEARN_VIDf, 0); 3818 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIGr(unit, rval)); 3819 } 3820 3821 #ifdef BCM_TRIUMPH2_SUPPORT 3822 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 3823 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_mpls_table_init(unit, vd)); 3824 } 3825 #endif 3826 3827 /* Must call on EGR_VLANm before VLAN_TABm */ 3828 if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm)) { 3829 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_init(unit, vd, EGR_VLANm)); 3830 } 3831 3832 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_init(unit, vd, VLAN_TABm)); 3833 if (SOC_MEM_IS_VALID(unit,VLAN_2_TABm)) { 3834 BCM_IF_ERROR_RETURN 3835 (_bcm_xgs3_vlan_table_init(unit, vd, VLAN_2_TABm)); 3836 } 3837 return BCM_E_NONE; 3838 } 3839 3840 int 3841 bcm_xgs3_vlan_create(int unit, bcm_vlan_t vid) 3842 { 3843 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 3844 int l3IntfMapMode=0; 3845 soc_mem_t vlan_mem = VLAN_MPLSm; 3846 uint32 entry[SOC_MAX_MEM_FIELD_WORDS]; 3847 3848 #if defined(BCM_TRIDENT3_SUPPORT) 3849 if (SOC_IS_TRIDENT3X(unit)) { 3850 vlan_mem = VLAN_TABm; 3851 } 3852 #endif 3853 if (SOC_MEM_IS_VALID(unit, vlan_mem)) { 3854 sal_memset (entry, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 3855 BCM_IF_ERROR_RETURN 3856 (soc_mem_read(unit, vlan_mem, MEM_BLOCK_ANY, vid, entry)); 3857 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 3858 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_ingress_intf_map_get(unit, &l3IntfMapMode)); 3859 } 3860 if (l3IntfMapMode) { 3861 /* don't use default if pre-configuration exists */ 3862 if (!SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) { 3863 /* Disable 1:1 mapping */ 3864 if (soc_feature(unit, soc_feature_l3_iif_under_4k)) { 3865 /* use zero as invalid in case of IIF entries less than 4k */ 3866 soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, 0); 3867 } else { 3868 soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, 3869 BCM_L3_INGRESS_INTERFACE_INVALID); 3870 } 3871 } 3872 } else { 3873 if ((soc_feature(unit, soc_feature_l3_iif_under_4k)) && 3874 (soc_mem_field32_fit(unit, vlan_mem, L3_IIFf, vid) != SOC_E_NONE)) { 3875 /* use zero in case of IIF entries less than 4k and does not fit */ 3876 soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, 0); 3877 }else { 3878 soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, vid); 3879 } 3880 } 3881 3882 if (SOC_MEM_FIELD_VALID(unit, vlan_mem, MPLS_ENABLEf) && 3883 soc_feature(unit, soc_feature_mpls)) { 3884 soc_mem_field32_set(unit, vlan_mem, entry, MPLS_ENABLEf, 0x1); 3885 } 3886 3887 if (SOC_MEM_FIELD_VALID(unit, vlan_mem, MIM_TERM_ENABLEf) && 3888 soc_feature(unit, soc_feature_mim)) { 3889 soc_mem_field32_set(unit, vlan_mem, entry, MIM_TERM_ENABLEf, 0x1); 3890 } 3891 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3892 if (soc_feature(unit, soc_feature_vlan_filter)) { 3893 3894 soc_mem_field32_set(unit, vlan_mem, entry, EN_IFILTERf, 3895 0x1); 3896 } 3897 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 3898 BCM_IF_ERROR_RETURN 3899 (soc_mem_write(unit, vlan_mem, MEM_BLOCK_ALL, vid, entry)); 3900 } 3901 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 3902 3903 #if defined(BCM_TRIDENT3_SUPPORT) 3904 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 3905 vlan_attrs_1_entry_t vlan_attrs; 3906 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t)); 3907 BCM_IF_ERROR_RETURN 3908 (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid, &vlan_attrs)); 3909 3910 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, VALIDf, 0x1); 3911 3912 if (soc_feature(unit, soc_feature_mpls)) { 3913 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MPLS_ENABLEf, 0x1); 3914 } 3915 if (soc_feature(unit, soc_feature_mim)) { 3916 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MIM_TERM_ENABLEf, 0x1); 3917 } 3918 if (soc_feature(unit, soc_feature_vlan_filter)) { 3919 3920 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, EN_IFILTERf, 0x1); 3921 } 3922 BCM_IF_ERROR_RETURN 3923 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid, &vlan_attrs)); 3924 } 3925 #endif 3926 3927 /* Must call on EGR_VLANm before VLAN_TABm on Firebolt 2 */ 3928 if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm)) { 3929 BCM_IF_ERROR_RETURN 3930 (_bcm_xgs3_vlan_table_create(unit, vid, EGR_VLANm)); 3931 } 3932 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_create(unit, vid, VLAN_TABm)); 3933 if (SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) { 3934 BCM_IF_ERROR_RETURN 3935 (_bcm_xgs3_vlan_table_create(unit, vid, VLAN_2_TABm)); 3936 } 3937 return BCM_E_NONE; 3938 } 3939 3940 int 3941 bcm_xgs3_vlan_destroy(int unit, bcm_vlan_t vid) 3942 { 3943 #ifdef BCM_TRIDENT3_SUPPORT 3944 if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) { 3945 BCM_IF_ERROR_RETURN 3946 (bcm_td3_vlan_vfi_untag_destroy(unit, vid)); 3947 } 3948 #endif 3949 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 3950 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 3951 BCM_IF_ERROR_RETURN 3952 (bcm_td2p_vlan_vpn_membership_delete(unit, vid)); 3953 } 3954 #endif 3955 3956 #ifdef BCM_TRIUMPH2_SUPPORT 3957 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 3958 vlan_mpls_entry_t vlan_mpls; 3959 3960 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t)); 3961 BCM_IF_ERROR_RETURN 3962 (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid, &vlan_mpls)); 3963 } 3964 #endif 3965 #ifdef BCM_TRIDENT3_SUPPORT 3966 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 3967 vlan_attrs_1_entry_t vlan_attrs; 3968 3969 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t)); 3970 BCM_IF_ERROR_RETURN 3971 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid, &vlan_attrs)); 3972 } 3973 #endif 3974 /* Must call on EGR_VLANm before VLAN_TABm on Firebolt 2 */ 3975 if (((SOC_IS_FBX(unit) && !SOC_IS_KATANA2(unit)) || (SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) 3976 && (SOC_MEM_IS_VALID(unit, EGR_VLANm))) { 3977 /* VLAN table in IP and EGR_VLAN table in EP are overlay memories and share the same physical memory. 3978 In BCMSIM overlay of memories is not possible, so need to explicity delete*/ 3979 BCM_IF_ERROR_RETURN 3980 (_bcm_xgs3_vlan_table_destroy(unit, vid, EGR_VLANm)); 3981 } 3982 if (SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) { 3983 BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_destroy(unit, vid, VLAN_2_TABm)); 3984 } 3985 return _bcm_xgs3_vlan_table_destroy(unit, vid, VLAN_TABm); 3986 } 3987 3988 int 3989 bcm_xgs3_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 3990 pbmp_t ing_pbmp) 3991 { 3992 if (SOC_IS_FBX(unit)) { 3993 /* Check for the presence of 'ING_PORT_BITMAPf', this could either 3994 reside in VLAN_TABm or in the 'ING_VLAN_VFI_MEMBERSHIPm' if 3995 'soc_feature_vlan_vfi_membership' is true */ 3996 if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) && 3997 !(soc_feature(unit, soc_feature_vlan_vfi_membership))) { 3998 BCM_PBMP_OR(pbmp, ing_pbmp); 3999 } 4000 if (SOC_MEM_IS_VALID(unit, EGR_VLANm) && BCM_VLAN_VALID(vid)) { 4001 BCM_IF_ERROR_RETURN 4002 (_bcm_xgs3_vlan_table_port_add(unit, vid, pbmp, ubmp, ing_pbmp, 4003 EGR_VLANm)); 4004 } 4005 } else { 4006 SOC_PBMP_OR(pbmp, ing_pbmp); 4007 } 4008 4009 if (BCM_VLAN_VALID(vid)) { 4010 BCM_IF_ERROR_RETURN 4011 (_bcm_xgs3_vlan_table_port_add(unit, vid, pbmp, ubmp, 4012 ing_pbmp, VLAN_TABLE(unit))); 4013 } 4014 #if defined(BCM_TRIDENT3_SUPPORT) 4015 if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) { 4016 BCM_IF_ERROR_RETURN 4017 (bcm_td3_vlan_vfi_untag_add(unit, vid, pbmp, ubmp)); 4018 } 4019 #endif /* BCM_TRIDENT3_SUPPORT */ 4020 4021 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 4022 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 4023 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set( 4024 unit, vid, TRUE, TRUE, pbmp)); 4025 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set( 4026 unit, vid, FALSE, TRUE, ing_pbmp)); 4027 } 4028 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4029 return BCM_E_NONE; 4030 } 4031 4032 int 4033 bcm_xgs3_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 4034 pbmp_t ing_pbmp) 4035 { 4036 if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm) && 4037 BCM_VLAN_VALID(vid)) { 4038 BCM_IF_ERROR_RETURN 4039 (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp, 4040 ing_pbmp, EGR_VLANm)); 4041 } 4042 4043 if (BCM_VLAN_VALID(vid)) { 4044 BCM_IF_ERROR_RETURN 4045 (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp, 4046 ing_pbmp, VLAN_TABLE(unit))); 4047 } 4048 4049 #if defined(BCM_TRIDENT3_SUPPORT) 4050 if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) { 4051 BCM_IF_ERROR_RETURN 4052 (bcm_td3_vlan_vfi_untag_delete(unit, vid, ubmp)); 4053 } 4054 #endif /* BCM_TRIDENT3_SUPPORT */ 4055 4056 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 4057 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 4058 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set( 4059 unit, vid, TRUE, FALSE, pbmp)); 4060 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set( 4061 unit, vid, FALSE, FALSE, ing_pbmp)); 4062 } 4063 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4064 return BCM_E_NONE; 4065 } 4066 4067 int 4068 bcm_xgs3_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp, 4069 pbmp_t *ing_pbmp) 4070 { 4071 pbmp_t local_pbmp, local_ing_pbmp; 4072 BCM_PBMP_CLEAR(local_pbmp); 4073 BCM_PBMP_CLEAR(local_ing_pbmp); 4074 if (SOC_IS_FBX(unit)) { 4075 if (BCM_VLAN_VALID(vid)) { 4076 if (SOC_MEM_IS_VALID(unit, EGR_VLANm)) { 4077 BCM_IF_ERROR_RETURN 4078 (_bcm_xgs3_vlan_table_port_get(unit, vid, &local_pbmp, ubmp, NULL, 4079 EGR_VLANm)); 4080 } 4081 /* coverity[result_independent_of_operands] */ 4082 if (!TABLE_HAS_T_BITMAP(unit, EGR_VLANm)) { 4083 BCM_IF_ERROR_RETURN 4084 (_bcm_xgs3_vlan_table_port_get(unit, vid, &local_pbmp, NULL, 4085 NULL, VLAN_TABLE(unit))); 4086 } 4087 4088 if (soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf)) { 4089 BCM_IF_ERROR_RETURN 4090 (_bcm_xgs3_vlan_table_port_get(unit, vid, NULL, NULL, 4091 &local_ing_pbmp, VLAN_TABLE(unit))); 4092 } else { 4093 BCM_PBMP_ASSIGN(local_ing_pbmp, local_pbmp); 4094 } 4095 } 4096 } else { 4097 if (BCM_VLAN_VALID(vid)) { 4098 BCM_IF_ERROR_RETURN 4099 (_bcm_xgs3_vlan_table_port_get(unit, vid, &local_pbmp, ubmp, NULL, 4100 VLAN_TABLE(unit))); 4101 BCM_PBMP_ASSIGN(local_ing_pbmp, local_pbmp); 4102 } 4103 } 4104 4105 #if defined(BCM_TRIDENT3_SUPPORT) 4106 if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) { 4107 BCM_IF_ERROR_RETURN 4108 (bcm_td3_vlan_table_ut_port_get(unit, vid, ubmp)); 4109 } 4110 #endif 4111 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 4112 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 4113 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_get( 4114 unit, vid, TRUE, &local_pbmp)); 4115 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_get( 4116 unit, vid, FALSE, &local_ing_pbmp)); 4117 } 4118 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4119 4120 if (pbmp != NULL) { 4121 BCM_PBMP_ASSIGN(*pbmp, local_pbmp); 4122 } 4123 if (ing_pbmp != NULL) { 4124 BCM_PBMP_ASSIGN(*ing_pbmp, local_ing_pbmp); 4125 } 4126 4127 return BCM_E_NONE; 4128 } 4129 4130 int 4131 bcm_xgs3_vlan_stg_set(int unit, bcm_vlan_t vid, bcm_stg_t stg) 4132 { 4133 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 4134 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 4135 BCM_IF_ERROR_RETURN( 4136 bcm_td2p_vp_group_vlan_vpn_stg_set(unit, vid, TRUE, stg)); 4137 4138 return bcm_td2p_vp_group_vlan_vpn_stg_set(unit, vid, FALSE, stg); 4139 } 4140 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4141 4142 if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm)) { 4143 BCM_IF_ERROR_RETURN 4144 (_bcm_xgs3_vlan_table_stg_set(unit, vid, stg, EGR_VLANm)); 4145 } 4146 4147 return _bcm_xgs3_vlan_table_stg_set(unit, vid, stg, VLAN_TABLE(unit)); 4148 } 4149 4150 int 4151 bcm_xgs3_vlan_reload(int unit, vbmp_t *bmp, int *count) 4152 { 4153 int rv = BCM_E_NONE; 4154 4155 if (SOC_IS_FBX(unit)) { 4156 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 4157 || defined(BCM_RAVEN_SUPPORT) 4158 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 4159 BCM_IF_ERROR_RETURN(_vlan_profile_init(unit)); 4160 } 4161 #endif 4162 #if defined(BCM_TOMAHAWK3_SUPPORT) 4163 if (soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) { 4164 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_pbmp_profile_init(unit)); 4165 } 4166 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4167 4168 if (SOC_MEM_IS_VALID(unit, EGR_VLANm)) { 4169 rv = _bcm_xgs3_vlan_table_reload(unit, bmp, count, EGR_VLANm); 4170 } 4171 } 4172 4173 if (BCM_SUCCESS(rv)) { 4174 rv = _bcm_xgs3_vlan_table_reload(unit, bmp, count, VLAN_TABm); 4175 } 4176 if (BCM_SUCCESS(rv) && SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) { 4177 rv = _bcm_xgs3_vlan_table_reload(unit, bmp, count, VLAN_2_TABm); 4178 } 4179 4180 return rv; 4181 } 4182 4183 /* 4184 * Function : 4185 * _bcm_xgs3_vlan_mcast_flood_set 4186 * 4187 * Purpose : 4188 * Set multicast flood mode. 4189 * 4190 * Parameters: 4191 * unit - (IN) BCM device number. 4192 * vlan - (IN) Vlan id. 4193 * mode - (IN) Vlan flood mode. 4194 * 4195 * Return : 4196 * BCM_E_XXX 4197 */ 4198 int _bcm_xgs3_vlan_mcast_flood_set(int unit, 4199 bcm_vlan_t vlan, 4200 bcm_vlan_mcast_flood_t mode) 4201 { 4202 4203 vlan_tab_entry_t vt; 4204 int rv; 4205 int pfm; 4206 4207 /* Upper layer already checks that vid is valid */ 4208 4209 soc_mem_lock(unit, VLAN_TABm); 4210 4211 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int) vlan, &vt); 4212 if (BCM_FAILURE(rv)) { 4213 soc_mem_unlock(unit, VLAN_TABm); 4214 return rv; 4215 } 4216 4217 if ((rv =_bcm_vlan_valid_check(unit, VLAN_TABm, &vt, vlan)) 4218 == BCM_E_NOT_FOUND) { 4219 soc_mem_unlock(unit, VLAN_TABm); 4220 return rv; 4221 } 4222 4223 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 4224 || defined(BCM_RAVEN_SUPPORT) 4225 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 4226 int profile_ptr; 4227 _vlan_profile_t vpe; 4228 4229 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 4230 (uint32 *)&vt, vlan, &profile_ptr); 4231 if (BCM_FAILURE(rv)) { 4232 soc_mem_unlock(unit, VLAN_TABm); 4233 return rv; 4234 } 4235 4236 sal_memcpy(&vpe, &VLAN_PROFILE_ENTRY(unit, profile_ptr), 4237 sizeof(_vlan_profile_t)); 4238 vpe.ip6_mcast_flood_mode = mode; 4239 vpe.ip4_mcast_flood_mode = mode; 4240 vpe.l2_mcast_flood_mode = mode; 4241 4242 rv = _vlan_profile_update(unit, vlan, &vpe); 4243 if (BCM_FAILURE(rv)) { 4244 soc_mem_unlock(unit, VLAN_TABm); 4245 return rv; 4246 } 4247 } else 4248 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 4249 { 4250 /* 4251 * Update the multicast flood setting for this VLAN. 4252 */ 4253 rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, mode, &pfm); 4254 if (BCM_FAILURE(rv)) { 4255 soc_mem_unlock(unit, VLAN_TABm); 4256 return BCM_E_NOT_FOUND; 4257 } 4258 soc_mem_field32_set(unit, VLAN_TABm, &vt, PFMf, pfm); 4259 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int) vlan, &vt); 4260 } 4261 4262 soc_mem_unlock(unit, VLAN_TABm); 4263 4264 if (TABLE_HAS_PFM(unit, EGR_VLANm)) { 4265 soc_mem_lock(unit, EGR_VLANm); 4266 if ((rv = soc_mem_read(unit, EGR_VLANm, 4267 MEM_BLOCK_ANY, (int) vlan, &vt)) < 0) { 4268 soc_mem_unlock(unit, EGR_VLANm); 4269 return rv; 4270 } 4271 soc_mem_field32_set(unit, EGR_VLANm, &vt, PFMf, mode); 4272 rv = soc_mem_write(unit, EGR_VLANm, MEM_BLOCK_ALL, (int) vlan, &vt); 4273 soc_mem_unlock(unit, EGR_VLANm); 4274 } 4275 4276 return rv; 4277 } 4278 4279 /* 4280 * Function : 4281 * _bcm_xgs3_vlan_mcast_flood_get 4282 * 4283 * Purpose : 4284 * Get multicast flood mode. 4285 * 4286 * Parameters: 4287 * unit - (IN) BCM device number. 4288 * vlan - (IN) Vlan id. 4289 * mode - (OUT) Vlan flood mode. 4290 * 4291 * Return : 4292 * BCM_E_XXX 4293 */ 4294 int _bcm_xgs3_vlan_mcast_flood_get(int unit, 4295 bcm_vlan_t vlan, 4296 bcm_vlan_mcast_flood_t *mode) 4297 { 4298 vlan_tab_entry_t vt; 4299 int rv; 4300 4301 /* Upper layer already checks that vid is valid */ 4302 4303 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int) vlan, &vt); 4304 if (BCM_FAILURE(rv)) { 4305 return rv; 4306 } 4307 4308 BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, VLAN_TABm, &vt, vlan)); 4309 4310 /* 4311 * Get the multicast flood setting for this VLAN. 4312 */ 4313 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 4314 || defined(BCM_RAVEN_SUPPORT) 4315 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 4316 int index; 4317 _vlan_profile_t *vpe; 4318 4319 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 4320 (uint32 *)&vt, vlan, &index); 4321 BCM_IF_ERROR_RETURN(rv); 4322 4323 vpe = &VLAN_PROFILE_ENTRY(unit, index); 4324 *mode = vpe->l2_mcast_flood_mode; 4325 } else 4326 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 4327 { 4328 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, PFMf)) { 4329 *mode = soc_mem_field32_get(unit, VLAN_TABm, &vt, PFMf); 4330 } else { 4331 *mode = 0; 4332 } 4333 } 4334 rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, *mode, mode); 4335 return rv; 4336 } 4337 #if defined (BCM_TRX_SUPPORT) 4338 /* 4339 * Function : 4340 * _vlan_control_trx_forwarding_mode_set 4341 * 4342 * Purpose : 4343 * Set cross - connect entry type. 4344 * 4345 * Parameters: 4346 * unit - (IN) BCM device number. 4347 * buf - (IN) Vlan table entry buffer. 4348 * type - (IN) Entry type. 4349 * Return : 4350 * BCM_E_XXX 4351 */ 4352 STATIC int 4353 _vlan_control_trx_forwarding_mode_set(int unit, uint32 *buf, 4354 bcm_vlan_forward_t type) 4355 { 4356 uint32 value; 4357 4358 /* Input parameters check. */ 4359 if (NULL == buf) { 4360 return (BCM_E_PARAM); 4361 } 4362 4363 switch (type) { 4364 case bcmVlanForwardBridging: 4365 value = 0; 4366 break; 4367 case bcmVlanForwardSingleCrossConnect: 4368 value = 1; 4369 break; 4370 case bcmVlanForwardDoubleCrossConnect: 4371 value = 2; 4372 break; 4373 default: 4374 return (BCM_E_PARAM); 4375 } 4376 soc_mem_field32_set(unit, VLAN_TABm, buf, L2_ENTRY_KEY_TYPEf, value); 4377 return (BCM_E_NONE); 4378 } 4379 4380 /* 4381 * Function : 4382 * _vlan_control_trx_forwarding_mode_get 4383 * 4384 * Purpose : 4385 * Get cross - connect entry type. 4386 * 4387 * Parameters: 4388 * unit - (IN) BCM device number. 4389 * buf - (IN) Vlan table entry buffer. 4390 * type - (OUT) Entry type. 4391 * Return : 4392 * BCM_E_XXX 4393 */ 4394 STATIC int 4395 _vlan_control_trx_forwarding_mode_get(int unit, uint32 *buf, 4396 bcm_vlan_forward_t *type) 4397 { 4398 uint32 value; 4399 4400 /* Input parameters check. */ 4401 if ((NULL == buf) || (NULL == type)) { 4402 return (BCM_E_PARAM); 4403 } 4404 value = soc_mem_field32_get(unit, VLAN_TABm, buf, L2_ENTRY_KEY_TYPEf); 4405 switch (value) { 4406 case 0x2: 4407 *type = bcmVlanForwardDoubleCrossConnect; 4408 break; 4409 case 0x1: 4410 *type = bcmVlanForwardSingleCrossConnect; 4411 break; 4412 default: 4413 *type = bcmVlanForwardBridging; 4414 break; 4415 } 4416 return (BCM_E_NONE); 4417 } 4418 #endif /* BCM_TRX_SUPPORT */ 4419 4420 #ifdef BCM_TRIUMPH_SUPPORT 4421 /* 4422 * Function : 4423 * _vlan_cosq_map_set 4424 * 4425 * Purpose : 4426 * Set per vlan cosq number. 4427 * 4428 * Parameters: 4429 * unit - (IN) BCM device number. 4430 * vid - (IN) Vlan table entry buffer. 4431 * cosq - (IN) VLAN control structure. 4432 * Return : 4433 * BCM_E_XXX 4434 */ 4435 STATIC int 4436 _vlan_cosq_map_set(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control) 4437 { 4438 vlan_cos_map_entry_t vcm; 4439 int rv; 4440 bcm_cos_queue_t cosq = 0; 4441 rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm); 4442 BCM_IF_ERROR_RETURN(rv); 4443 4444 soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VALIDf, 4445 ((control->flags & BCM_VLAN_COSQ_ENABLE) ? 1 : 0)); 4446 4447 if (control->flags & BCM_VLAN_COSQ_ENABLE) { 4448 4449 /* Add 8 since VLAN COS queues are from 8..23 */ 4450 cosq = control->cosq + 8; 4451 if ((cosq < 8) || (cosq > 23)) { 4452 return BCM_E_PARAM; 4453 } 4454 soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf, cosq); 4455 } 4456 4457 /* Write back updated buffer. */ 4458 rv = soc_mem_write(unit, VLAN_COS_MAPm, MEM_BLOCK_ALL, (int)vid, &vcm); 4459 return (rv); 4460 } 4461 4462 /* 4463 * Function : 4464 * _vlan_cosq_map_get 4465 * 4466 * Purpose : 4467 * Get per vlan cosq number. 4468 * 4469 * Parameters: 4470 * unit - (IN) BCM device number. 4471 * vid - (IN) Vlan table entry buffer. 4472 * control- (OUT) vlan control structure. 4473 * Return : 4474 * BCM_E_XXX 4475 */ 4476 STATIC int 4477 _vlan_cosq_map_get(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control) 4478 { 4479 vlan_cos_map_entry_t vcm; 4480 int rv; 4481 4482 rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm); 4483 if (BCM_FAILURE(rv)) { 4484 return rv; 4485 } 4486 4487 if (0 == soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VALIDf)) { 4488 return (BCM_E_NONE); 4489 } 4490 4491 control->flags |= BCM_VLAN_COSQ_ENABLE; 4492 /* Subtract 8 since VLAN COS queues are from 8..23 */ 4493 control->cosq = soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf) - 8; 4494 return (BCM_E_NONE); 4495 } 4496 #endif /* BCM_TRIUMPH_SUPPORT */ 4497 4498 #if defined(INCLUDE_L3) 4499 /* 4500 * Function : 4501 * _bcm_xgs3_vlan_control_vpn_get 4502 * 4503 * Purpose : 4504 * Reads VFI table and fills vlan_control 4505 * 4506 * Parameters: 4507 * unit - (IN) BCM device number. 4508 * vid - (IN) Vlan id. 4509 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4510 * control - (OUT) Configuration structure. 4511 * 4512 * Return : 4513 * BCM_E_XXX 4514 */ 4515 int 4516 _bcm_xgs3_vlan_control_vpn_get(int unit, bcm_vlan_t vid, uint32 valid_fields, 4517 bcm_vlan_control_vlan_t *control) 4518 { 4519 int rv; 4520 int vfi; 4521 int value; 4522 vfi_entry_t vfi_entry; 4523 soc_mem_t mem = VFIm; 4524 4525 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 4526 4527 /* Read the VFI memory */ 4528 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 4529 if (!SOC_SUCCESS(rv)) { 4530 return rv; 4531 } 4532 4533 /* Get the CLASS_ID */ 4534 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) { 4535 if (soc_mem_field_valid(unit, mem, CLASS_IDf)) { 4536 value = soc_mem_field32_get(unit, mem, &vfi_entry, CLASS_IDf); 4537 control->if_class = value; 4538 control->flags |= (control->if_class) ? BCM_VLAN_L2_CLASS_ID_ONLY : 0; 4539 } 4540 } 4541 4542 return BCM_E_NONE; 4543 } 4544 #endif /* INCLUDE_L3 */ 4545 4546 uint32 4547 _bcm_xgs3_vlan_mcast_idx_get(int unit, const void *entbuf, soc_field_t field) 4548 { 4549 uint32 fval = 0; 4550 uint32 dest_type = 0; 4551 soc_mem_t vtab = VLAN_TABm; 4552 int fidx = 0; 4553 soc_field_t idxfld; 4554 4555 soc_field_t idx_f[3] = { 4556 BC_IDXf, 4557 UMC_IDXf, 4558 UUC_IDXf 4559 }; 4560 soc_field_t dst_idx_f[3] = { 4561 BC_DESTINATIONf, 4562 UMC_DESTINATIONf, 4563 UUC_DESTINATIONf 4564 }; 4565 4566 switch (field) { 4567 case BC_IDXf: 4568 fidx = 0; 4569 break; 4570 case UMC_IDXf: 4571 fidx = 1; 4572 break; 4573 case UUC_IDXf: 4574 fidx = 2; 4575 break; 4576 default: 4577 return fval; 4578 break; 4579 } 4580 if (soc_feature(unit, soc_feature_generic_dest)) { 4581 idxfld = dst_idx_f[fidx]; 4582 } else { 4583 idxfld = idx_f[fidx]; 4584 } 4585 4586 if (SOC_MEM_FIELD_VALID(unit, vtab, idxfld)) { 4587 if (soc_feature(unit, soc_feature_generic_dest)) { 4588 fval = soc_mem_field32_dest_get(unit, vtab, entbuf, idxfld, 4589 &dest_type); 4590 if (dest_type != SOC_MEM_FIF_DEST_IPMC) { 4591 fval = 0; 4592 } 4593 } else { 4594 fval = soc_mem_field32_get(unit, vtab, entbuf, idxfld); 4595 } 4596 } 4597 4598 return fval; 4599 } 4600 4601 void 4602 _bcm_xgs3_vlan_mcast_idx_set(int unit, void *entbuf, soc_field_t field, 4603 uint32 fval) 4604 { 4605 soc_mem_t vtab = VLAN_TABm; 4606 int fidx = 0; 4607 soc_field_t idxfld; 4608 4609 soc_field_t idx_f[3] = { 4610 BC_IDXf, 4611 UMC_IDXf, 4612 UUC_IDXf 4613 }; 4614 soc_field_t dst_idx_f[3] = { 4615 BC_DESTINATIONf, 4616 UMC_DESTINATIONf, 4617 UUC_DESTINATIONf 4618 }; 4619 4620 switch (field) { 4621 case BC_IDXf: 4622 fidx = 0; 4623 break; 4624 case UMC_IDXf: 4625 fidx = 1; 4626 break; 4627 case UUC_IDXf: 4628 fidx = 2; 4629 break; 4630 default: 4631 break; 4632 } 4633 if (soc_feature(unit, soc_feature_generic_dest)) { 4634 idxfld = dst_idx_f[fidx]; 4635 } else { 4636 idxfld = idx_f[fidx]; 4637 } 4638 4639 if (SOC_MEM_FIELD_VALID(unit, vtab, idxfld)) { 4640 if (soc_feature(unit, soc_feature_generic_dest)) { 4641 soc_mem_field32_dest_set(unit, vtab, entbuf, idxfld, 4642 SOC_MEM_FIF_DEST_IPMC, fval); 4643 } else { 4644 soc_mem_field32_set(unit, vtab, entbuf, idxfld, fval); 4645 } 4646 } 4647 4648 return ; 4649 } 4650 4651 /* 4652 * Function : 4653 * _bcm_xgs3_vlan_control_vlan_get 4654 * 4655 * Purpose : 4656 * Get vlan specific traffic forwarding parameters 4657 * 4658 * Parameters: 4659 * unit - (IN) BCM device number. 4660 * vid - (IN) Vlan id. 4661 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4662 * control - (IN) Configuration. 4663 * 4664 * Return : 4665 * BCM_E_XXX 4666 */ 4667 int 4668 _bcm_xgs3_vlan_control_vlan_get(int unit, bcm_vlan_t vid, 4669 uint32 valid_fields, bcm_vlan_control_vlan_t *control) 4670 { 4671 int rv = BCM_E_UNAVAIL; 4672 4673 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 4674 || defined(BCM_RAVEN_SUPPORT) 4675 int profile_index; 4676 vlan_tab_entry_t vt; 4677 _vlan_profile_t *vpt; 4678 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 4679 int enable; 4680 int ingress_map_mode=0; 4681 _bcm_l3_ingress_intf_t iif; 4682 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 4683 int pre_cfg = FALSE; 4684 4685 if (!soc_feature(unit, soc_feature_vlan_ctrl)) { 4686 return BCM_E_UNAVAIL; 4687 } 4688 4689 sal_memset(control, 0, sizeof(bcm_vlan_control_vlan_t)); 4690 4691 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 4692 defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3) 4693 if (_BCM_VPN_VFI_IS_SET(vid)) { 4694 if (soc_feature(unit, soc_feature_vfi_profile)) { 4695 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4696 return bcmi_td2p_vlan_control_vpn_get( 4697 unit, vid, valid_fields, control); 4698 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4699 } else { 4700 #ifdef BCM_GREYHOUND2_SUPPORT 4701 if (soc_feature(unit, soc_feature_vxlan_lite_riot)) { 4702 return bcmi_gh2_vlan_control_vpn_get(unit, vid, valid_fields, 4703 control); 4704 } else 4705 #endif /* BCM_GREYHOUND2_SUPPORT */ 4706 { 4707 return _bcm_xgs3_vlan_control_vpn_get(unit, vid, valid_fields, 4708 control); 4709 } 4710 } 4711 } 4712 #endif /* (TRIDENT2PLUS || TOMAHAWK || GREYHOUND2) && INCLUDE_L3 */ 4713 4714 /* check if pre-configuration exists before vlan is created*/ 4715 if (!SHR_BITGET(vlan_info[unit].bmp.w, vid)) { 4716 if (!SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) { 4717 return BCM_E_PARAM; 4718 } else { 4719 pre_cfg = TRUE; 4720 } 4721 } 4722 4723 soc_mem_lock(unit, VLAN_TABm); 4724 /* Don't need to lock the cached outer TPID table. 4725 * because the TPID entries referenced by the VLAN_TAB cannot 4726 * be removed if the VLAN_TAB is lock. 4727 */ 4728 4729 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt); 4730 if (BCM_FAILURE(rv)) { 4731 soc_mem_unlock(unit, VLAN_TABm); 4732 return rv; 4733 } 4734 4735 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 4736 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 4737 rv = bcm_xgs3_l3_ingress_intf_map_get(unit, &ingress_map_mode); 4738 if (BCM_FAILURE(rv)) { 4739 soc_mem_unlock(unit, VLAN_TABm); 4740 return rv; 4741 } 4742 } 4743 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 4744 4745 /* Get VRF */ 4746 if (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) { 4747 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VRF_IDf)) { 4748 control->vrf = soc_mem_field32_get(unit, VLAN_TABm, &vt, VRF_IDf); 4749 } 4750 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 4751 else if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_l3) && 4752 soc_feature(unit, soc_feature_l3_ingress_interface) && 4753 SOC_MEM_IS_VALID(unit,L3_IIFm)) { 4754 if (soc_feature(unit, soc_feature_no_vlan_vrf)) { 4755 /* 4756 * Return E_UNAVAIL for those device can't support VID 1:1 4757 * mapping to L3_IIFm to set VLAN based VRF_ID 4758 */ 4759 #if defined(BCM_GREYHOUND2_SUPPORT) 4760 if (SOC_IS_GREYHOUND2(unit)) { 4761 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf)) { 4762 if (soc_mem_field32_get(unit, VLAN_TABm, &vt, L3_IIFf) 4763 && (ingress_map_mode)) { 4764 iif.intf_id = soc_mem_field32_get(unit, VLAN_TABm, 4765 &vt, L3_IIFf); 4766 rv = _bcm_tr_l3_ingress_interface_get(unit, NULL, 4767 &iif); 4768 if (BCM_FAILURE(rv)) { 4769 soc_mem_unlock(unit, VLAN_TABm); 4770 return rv; 4771 } 4772 control->vrf = iif.vrf; 4773 } 4774 } 4775 } else 4776 #endif /* BCM_GREYHOUND2_SUPPORT */ 4777 { 4778 soc_mem_unlock(unit, VLAN_TABm); 4779 return BCM_E_UNAVAIL; 4780 } 4781 } else if (!ingress_map_mode) { 4782 rv = _bcm_tr_l3_intf_vrf_get(unit, vid, &control->vrf); 4783 if (BCM_FAILURE(rv)) { 4784 soc_mem_unlock(unit, VLAN_TABm); 4785 return rv; 4786 } 4787 } 4788 } 4789 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 4790 } 4791 4792 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 4793 if (soc_feature(unit, soc_feature_l3) && 4794 soc_feature(unit, soc_feature_l3_ingress_interface) && 4795 (!ingress_map_mode)) { 4796 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, ALLOW_GLOBAL_ROUTEf) || 4797 SOC_IS_TD2_TT2(unit)) { 4798 rv = _bcm_tr_l3_intf_global_route_enable_get(unit, vid, &enable); 4799 if (BCM_FAILURE(rv)) { 4800 soc_mem_unlock(unit, VLAN_TABm); 4801 return rv; 4802 } 4803 if (0 == enable) { 4804 control->flags |= BCM_VLAN_L3_VRF_GLOBAL_DISABLE; 4805 } 4806 } 4807 } 4808 if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) { 4809 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf) && 4810 soc_feature(unit, soc_feature_l3_ingress_interface) && 4811 soc_feature(unit, soc_feature_l3)) { 4812 4813 /* Get Vlan mapping */ 4814 control->ingress_if = soc_mem_field32_get(unit, 4815 VLAN_TABm, &vt, L3_IIFf); 4816 } 4817 } 4818 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 4819 #if defined(BCM_TRIUMPH2_SUPPORT) && defined (INCLUDE_L3) 4820 if (soc_feature(unit, soc_feature_l3) 4821 && soc_feature(unit, soc_feature_l3_ingress_interface) 4822 && (!ingress_map_mode)) { 4823 if (valid_fields & BCM_VLAN_CONTROL_VLAN_URPF_MODE_MASK) { 4824 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_MODEf) || 4825 soc_feature(unit, soc_feature_l3_iif_profile)) { 4826 rv = _bcm_tr2_l3_intf_urpf_mode_get(unit, vid, &control->urpf_mode); 4827 if (BCM_FAILURE(rv)) { 4828 soc_mem_unlock(unit, VLAN_TABm); 4829 return rv; 4830 } 4831 } 4832 } 4833 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_DEFAULTROUTECHECKf) || 4834 soc_feature(unit, soc_feature_l3_iif_profile)) { 4835 rv = _bcm_tr2_l3_intf_urpf_default_route_get(unit, vid, &enable); 4836 if (BCM_FAILURE(rv)) { 4837 soc_mem_unlock(unit, VLAN_TABm); 4838 return rv; 4839 } 4840 if (0 == enable) { 4841 control->flags |= BCM_VLAN_L3_URPF_DEFAULT_ROUTE_CHECK_DISABLE; 4842 } 4843 } 4844 } 4845 if (soc_feature(unit, soc_feature_mpls)) { 4846 int mpls_enable = 0; 4847 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 4848 vlan_mpls_entry_t vlan_mpls_entry; 4849 sal_memset(&vlan_mpls_entry, 0, sizeof(vlan_mpls_entry_t)); 4850 rv = soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid, 4851 &vlan_mpls_entry); 4852 if (BCM_FAILURE(rv)) { 4853 soc_mem_unlock(unit, VLAN_TABm); 4854 return rv; 4855 } 4856 mpls_enable = soc_mem_field32_get(unit, VLAN_MPLSm, 4857 &vlan_mpls_entry, MPLS_ENABLEf); 4858 if (0 == mpls_enable) { 4859 control->flags |= BCM_VLAN_MPLS_DISABLE; 4860 } 4861 } 4862 #if defined(BCM_TRIDENT3_SUPPORT) 4863 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 4864 vlan_attrs_1_entry_t vlan_attrs; 4865 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t)); 4866 rv = soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid, 4867 &vlan_attrs); 4868 if (BCM_FAILURE(rv)) { 4869 soc_mem_unlock(unit, VLAN_TABm); 4870 return rv; 4871 } 4872 mpls_enable = soc_mem_field32_get(unit, VLAN_ATTRS_1m, 4873 &vlan_attrs, MPLS_ENABLEf); 4874 if (0 == mpls_enable) { 4875 control->flags |= BCM_VLAN_MPLS_DISABLE; 4876 } 4877 } 4878 #endif 4879 } 4880 4881 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4882 if (soc_feature(unit, soc_feature_vlan_filter)) { 4883 vlan_tab_entry_t vlan_tab; 4884 sal_memset(&vlan_tab, 0, sizeof(vlan_tab)); 4885 rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, 4886 vid, &vlan_tab); 4887 if (BCM_FAILURE(rv)) { 4888 soc_mem_unlock(unit, VLAN_TABm); 4889 return rv; 4890 } 4891 4892 if (soc_mem_field32_get(unit, EGR_VLANm, 4893 &vlan_tab, EN_EFILTERf) == 0) { 4894 control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE; 4895 } 4896 4897 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 4898 vlan_attrs_1_entry_t vlan_attrs; 4899 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs)); 4900 rv = soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, 4901 vid, &vlan_attrs); 4902 if (BCM_FAILURE(rv)) { 4903 soc_mem_unlock(unit, VLAN_TABm); 4904 return rv; 4905 } 4906 4907 if (soc_mem_field32_get(unit, VLAN_ATTRS_1m, 4908 &vlan_attrs, EN_IFILTERf) == 0) { 4909 control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE; 4910 } 4911 } else if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 4912 vlan_mpls_entry_t vlan_mpls; 4913 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls)); 4914 rv = soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, 4915 vid, &vlan_mpls); 4916 if (BCM_FAILURE(rv)) { 4917 soc_mem_unlock(unit, VLAN_TABm); 4918 return rv; 4919 } 4920 4921 if (soc_mem_field32_get(unit, VLAN_MPLSm, 4922 &vlan_mpls, EN_IFILTERf) == 0) { 4923 control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE; 4924 } 4925 } 4926 } 4927 #endif 4928 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 4929 #if defined(BCM_TRIDENT2_SUPPORT) && defined (INCLUDE_L3) 4930 if (soc_feature(unit, soc_feature_l3_iif_profile) && (!ingress_map_mode)) { 4931 rv = _bcm_td2_l3_intf_iif_profile_get(unit, vid, control); 4932 if (BCM_FAILURE(rv)) { 4933 soc_mem_unlock(unit, VLAN_TABm); 4934 return rv; 4935 } 4936 } 4937 4938 #endif /* BCM_TRIDENT2_SUPPORT */ 4939 #if defined(BCM_TRX_SUPPORT) 4940 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) { 4941 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VLAN_CLASS_IDf)) { 4942 control->if_class = 4943 soc_mem_field32_get(unit, VLAN_TABm, &vt, VLAN_CLASS_IDf); 4944 control->flags |= BCM_VLAN_L2_CLASS_ID_ONLY; 4945 } 4946 } 4947 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 4948 if (valid_fields & BCM_VLAN_CONTROL_VLAN_L3_IF_CLASS_MASK) { 4949 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 4950 if (!ingress_map_mode) { 4951 iif.intf_id = vid; 4952 rv = _bcm_tr_l3_ingress_interface_get(unit, NULL, &iif); 4953 if (BCM_FAILURE(rv)) { 4954 soc_mem_unlock(unit, VLAN_TABm); 4955 return rv; 4956 } 4957 control->l3_if_class = iif.if_class; 4958 control->flags |= BCM_VLAN_L3_CLASS_ID; 4959 } 4960 } 4961 } 4962 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 4963 if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK) { 4964 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L2_ENTRY_KEY_TYPEf)) { 4965 rv = _vlan_control_trx_forwarding_mode_get(unit, (uint32 *)&vt, 4966 &control->forwarding_mode); 4967 if (BCM_FAILURE(rv)) { 4968 soc_mem_unlock(unit, VLAN_TABm); 4969 return rv; 4970 } 4971 } 4972 } 4973 #endif /* BCM_TRX_SUPPORT */ 4974 4975 #if defined(BCM_HELIX5_SUPPORT) 4976 if (soc_feature(unit, soc_feature_vlan_wirelss_traffic_select)) { 4977 rv = soc_mem_field32_get(unit, VLAN_TABm, &vt, WIRED_WIRELESSf); 4978 if(rv == 0x1) { 4979 control->flags2 |= BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT; 4980 } 4981 if(rv == 0x2) { 4982 control->flags2 |= BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT; 4983 } 4984 } 4985 #endif 4986 #if defined(BCM_TRX_SUPPORT) 4987 if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK) { 4988 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, FID_IDf)) { 4989 control->forwarding_vlan = soc_mem_field32_get(unit, VLAN_TABm, 4990 &vt, FID_IDf); 4991 } 4992 } 4993 #endif /* BCM_TRX_SUPPORT */ 4994 4995 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 4996 if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) { 4997 if(soc_feature(unit, soc_feature_l3)) { 4998 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 4999 vlan_mpls_entry_t vlan_mpls; 5000 5001 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t)); 5002 rv = soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid, 5003 &vlan_mpls); 5004 if (BCM_FAILURE(rv)) { 5005 soc_mem_unlock(unit, VLAN_TABm); 5006 return rv; 5007 } 5008 /* Get Vlan mapping */ 5009 control->ingress_if = soc_mem_field32_get(unit, VLAN_MPLSm, 5010 &vlan_mpls, L3_IIFf); 5011 5012 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_METROLITE_SUPPORT) 5013 if ((SOC_IS_MONTEREY(unit) || SOC_IS_METROLITE(unit)) && 5014 soc_feature(unit, soc_feature_l3_ingress_interface) && 5015 !soc_feature(unit, soc_feature_no_vlan_vrf) && 5016 (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) && 5017 (ingress_map_mode)) { 5018 5019 iif.intf_id = control->ingress_if; 5020 5021 rv = _bcm_tr_l3_ingress_interface_get(unit, NULL, &iif); 5022 if (BCM_FAILURE(rv)) { 5023 soc_mem_unlock(unit, VLAN_TABm); 5024 return rv; 5025 } 5026 5027 control->vrf = iif.vrf; 5028 } 5029 #endif 5030 #if defined(BCM_MONTEREY_SUPPORT) 5031 if ((SOC_IS_MONTEREY(unit) && 5032 (ingress_map_mode) && 5033 (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK))) { 5034 BCM_IF_ERROR_RETURN( 5035 _bcm_td2_l3_intf_iif_profile_get(unit, control->ingress_if, control)); 5036 } 5037 #endif /* BCM_MONTEREY_SUPPORT */ 5038 } 5039 } 5040 } 5041 5042 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 5043 int idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, BC_IDXf); 5044 if (idx) { 5045 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, idx, 5046 &control->broadcast_group); 5047 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 5048 soc_mem_unlock(unit, VLAN_TABm); 5049 return rv; 5050 } 5051 } 5052 } 5053 5054 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 5055 int idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, UMC_IDXf); 5056 if (idx) { 5057 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, idx, 5058 &control->unknown_multicast_group); 5059 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 5060 soc_mem_unlock(unit, VLAN_TABm); 5061 return rv; 5062 } 5063 } 5064 } 5065 5066 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 5067 int idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, UUC_IDXf); 5068 if (idx) { 5069 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, idx, 5070 &control->unknown_unicast_group); 5071 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 5072 soc_mem_unlock(unit, VLAN_TABm); 5073 return rv; 5074 } 5075 } 5076 } 5077 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 5078 5079 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 5080 if (soc_feature(unit, soc_feature_trill)) { 5081 if (valid_fields & BCM_VLAN_CONTROL_VLAN_TRILL_NONUNICAST_GROUP_MASK) { 5082 if (soc_mem_field32_get(unit, VLAN_TABm, 5083 &vt, TRILL_DOMAIN_NONUC_REPL_INDEXf)) { 5084 _BCM_MULTICAST_GROUP_SET(control->trill_nonunicast_group, 5085 _BCM_MULTICAST_TYPE_TRILL, 5086 soc_mem_field32_get(unit, VLAN_TABm, 5087 &vt, TRILL_DOMAIN_NONUC_REPL_INDEXf)); 5088 } 5089 } 5090 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 5091 TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf)) { 5092 if ( !soc_mem_field32_get(unit, VLAN_TABm, &vt, 5093 TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf )) { 5094 control->flags |= BCM_VLAN_TRILL_IGMP_SNOOP_DISABLE; 5095 } 5096 } 5097 /* Get per-Vlan trill_name */ 5098 if (valid_fields & BCM_VLAN_CONTROL_VLAN_SOURCE_TRILL_NAME_MASK) { 5099 if (soc_mem_field_valid (unit, VLAN_TABm, TRILL_RBRIDGE_NICKNAME_INDEXf)) { 5100 rv = bcm_td_trill_source_trill_idx_name_get(unit, 5101 soc_mem_field32_get(unit, VLAN_TABm, 5102 &vt, TRILL_RBRIDGE_NICKNAME_INDEXf), 5103 &control->source_trill_name); 5104 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 5105 soc_mem_unlock(unit, VLAN_TABm); 5106 return rv; 5107 } 5108 } 5109 } 5110 } 5111 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 5112 5113 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 5114 if (valid_fields & BCM_VLAN_CONTROL_VLAN_VP_MCAST_MASK) { 5115 if (SHR_BITGET(vlan_info[unit].vp_mode, vid)) { 5116 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) && 5117 soc_mem_field32_get(unit, VLAN_TABm, &vt, VIRTUAL_PORT_ENf)) { 5118 control->vp_mc_ctrl = bcmVlanVPMcControlEnable; 5119 } else { 5120 control->vp_mc_ctrl = bcmVlanVPMcControlDisable; 5121 } 5122 } else { 5123 control->vp_mc_ctrl = bcmVlanVPMcControlAuto; 5124 } 5125 } 5126 #endif 5127 5128 if (pre_cfg == FALSE) { 5129 /* after vlan is created */ 5130 5131 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 5132 (uint32 *)&vt, vid, &profile_index); 5133 if (BCM_FAILURE(rv)) { 5134 soc_mem_unlock(unit, VLAN_TABm); 5135 return (rv); 5136 } 5137 } else { 5138 #if defined(BCM_EASY_RELOAD_SUPPORT) 5139 if (SOC_IS_RELOADING(unit)) { 5140 /* 5141 * Use VLAN_PROFILE_ER() as a write-through cache 5142 * for VLAN profile pointers during easy reload 5143 */ 5144 profile_index = VLAN_PROFILE_PTR_ER(unit, vid); 5145 } else 5146 #endif 5147 { 5148 profile_index = soc_mem_field32_get(unit, VLAN_TABm, &vt, 5149 VLAN_PROFILE_PTRf); 5150 } 5151 } 5152 5153 vpt = &VLAN_PROFILE_ENTRY(unit, profile_index); 5154 control->flags |= vpt->flags; 5155 if (valid_fields & BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK) { 5156 control->outer_tpid = vpt->outer_tpid; 5157 } 5158 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP6_MCAST_FLOOD_MODE_MASK) { 5159 control->ip6_mcast_flood_mode = vpt->ip6_mcast_flood_mode; 5160 } 5161 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP4_MCAST_FLOOD_MODE_MASK) { 5162 control->ip4_mcast_flood_mode = vpt->ip4_mcast_flood_mode; 5163 } 5164 if (valid_fields & BCM_VLAN_CONTROL_VLAN_L2_MCAST_FLOOD_MODE_MASK) { 5165 control->l2_mcast_flood_mode = vpt->l2_mcast_flood_mode; 5166 } 5167 #if defined(BCM_TRX_SUPPORT) 5168 if (valid_fields & BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK) { 5169 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl) 5170 && SOC_MEM_FIELD_VALID (unit, VLAN_PROFILE_TABm, 5171 PROTOCOL_PKT_INDEXf)) { 5172 sal_memcpy(&control->protocol_pkt, 5173 &vpt->protocol_pkt, sizeof(bcm_vlan_protocol_packet_ctrl_t)); 5174 } 5175 } 5176 #endif /* BCM_TRX_SUPPORT */ 5177 5178 #if defined(BCM_HURRICANE3_SUPPORT) 5179 if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)) { 5180 if (vpt->learn_flags & BCM_VLAN_LEARN_CONTROL_ENABLE) { 5181 control->learn_flags = vpt->learn_flags; 5182 } else { 5183 control->learn_flags = 0x0; 5184 } 5185 } 5186 #endif /* BCM_HURRICANE3_SUPPORT */ 5187 5188 #ifdef BCM_TRIUMPH_SUPPORT 5189 if (valid_fields & BCM_VLAN_CONTROL_VLAN_COSQ_MASK) { 5190 if (SOC_MEM_IS_VALID(unit, VLAN_COS_MAPm)) { 5191 #if defined(BCM_KATANA_SUPPORT) 5192 if (SOC_IS_KATANAX(unit)) { 5193 rv = _vlan_kt_cosq_map_get(unit, vid, control); 5194 } else 5195 #endif 5196 { 5197 rv = _vlan_cosq_map_get(unit, vid, control); 5198 } 5199 if (BCM_FAILURE(rv)) { 5200 soc_mem_unlock(unit, VLAN_TABm); 5201 return (rv); 5202 } 5203 } 5204 } 5205 #endif 5206 5207 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 5208 ENABLE_IGMP_MLD_SNOOPINGf)) { 5209 if (0 == soc_mem_field32_get(unit, VLAN_TABm, &vt, 5210 ENABLE_IGMP_MLD_SNOOPINGf)) { 5211 control->flags |= BCM_VLAN_IGMP_SNOOP_DISABLE; 5212 } 5213 } 5214 5215 #if defined(INCLUDE_L3) && defined(BCM_TRIDENT2_SUPPORT) 5216 if (valid_fields & BCM_VLAN_CONTROL_VLAN_NAT_REALM_ID_MASK) { 5217 if (soc_feature(unit, soc_feature_nat) && 5218 SOC_MEM_IS_VALID(unit, L3_IIFm) && 5219 SOC_MEM_FIELD_VALID(unit, L3_IIFm, SRC_REALM_IDf) && 5220 (!ingress_map_mode)) { 5221 rv = _bcm_tr_l3_intf_nat_realm_id_get(unit, 5222 ingress_map_mode ? control->ingress_if : vid, 5223 &control->nat_realm_id); 5224 if (BCM_FAILURE(rv)) { 5225 soc_mem_unlock(unit, VLAN_TABm); 5226 return (rv); 5227 } 5228 } 5229 } 5230 #endif /* INCLUDE_L3 && BCM_TRIDENT2_SUPPORT */ 5231 5232 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5233 if (soc_feature(unit, soc_feature_vfi_from_vlan_tables)) { 5234 int vfi_index = -1; 5235 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm) && 5236 SOC_MEM_FIELD_VALID(unit, VLAN_MPLSm, VFIf)) { 5237 vlan_mpls_entry_t vlan_mpls; 5238 5239 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t)); 5240 soc_mem_lock(unit, VLAN_MPLSm); 5241 rv = READ_VLAN_MPLSm(unit, MEM_BLOCK_ANY, vid, &vlan_mpls); 5242 soc_mem_unlock(unit, VLAN_MPLSm); 5243 if (BCM_FAILURE(rv)) { 5244 soc_mem_unlock(unit, VLAN_TABm); 5245 return rv; 5246 } 5247 vfi_index = soc_mem_field32_get(unit, VLAN_MPLSm, 5248 &vlan_mpls, VFIf); 5249 } 5250 #if defined(BCM_TRIDENT3_SUPPORT) 5251 else if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VFIf)) { 5252 vfi_index = soc_mem_field32_get(unit, VLAN_TABm, 5253 &vt, VFIf); 5254 } 5255 #endif/* BCM_TRIDENT3_SUPPORT && INCLUDE_L3 */ 5256 _BCM_VPN_SET(control->vpn, _BCM_VPN_TYPE_VFI, vfi_index); 5257 } 5258 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3*/ 5259 5260 #if defined(BCM_TSN_SR_SUPPORT) 5261 if (soc_feature(unit, soc_feature_tsn_sr)) { 5262 if (valid_fields & BCM_VLAN_CONTROL_VLAN_SR_FLAGS_MASK) { 5263 if (soc_mem_field32_get(unit, VLAN_TABm, &vt, SR_ENABLEf)){ 5264 control->sr_flags |= BCM_VLAN_CONTROL_SR_FLAG_ENABLE; 5265 if (soc_mem_field32_get(unit, VLAN_TABm, &vt, SR_LAN_IDf)){ 5266 control->sr_flags |= BCM_VLAN_CONTROL_SR_FLAG_LAN_ID; 5267 } 5268 } 5269 } 5270 } 5271 #endif /* BCM_TSN_SR_SUPPORT*/ 5272 5273 soc_mem_unlock(unit, VLAN_TABm); 5274 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 5275 return rv; 5276 } 5277 5278 #if defined (BCM_TRX_SUPPORT) 5279 STATIC int _vlan_protocol_pkt_action_validate(int pkt_action) 5280 { 5281 if ((pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE) && 5282 (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE)) { 5283 return BCM_E_PARAM; 5284 } 5285 return BCM_E_NONE; 5286 } 5287 #endif 5288 5289 /* 5290 * Function : 5291 * _bcm_xgs3_protocol_packet_actions_validate 5292 * 5293 * Purpose : 5294 * Validate the protocol packet control actions 5295 * 5296 * Parameters: 5297 * unit - (IN) BCM device number. 5298 * pkt - (IN) protocol packet control actions. 5299 * 5300 * Return : 5301 * BCM_E_XXX 5302 */ 5303 int _bcm_xgs3_protocol_packet_actions_validate(int unit, 5304 bcm_vlan_protocol_packet_ctrl_t *pkt) 5305 { 5306 #if defined (BCM_TRX_SUPPORT) 5307 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) { 5308 int pkt_action; 5309 5310 pkt_action = pkt->mmrp_action; 5311 if (pkt_action) { 5312 if (_vlan_protocol_pkt_action_validate(pkt_action) 5313 ==BCM_E_PARAM) { 5314 return BCM_E_PARAM; 5315 } 5316 } 5317 pkt_action = pkt->srp_action; 5318 if (pkt_action) { 5319 if (_vlan_protocol_pkt_action_validate(pkt_action) 5320 == BCM_E_PARAM) { 5321 return BCM_E_PARAM; 5322 } 5323 } 5324 pkt_action = pkt->arp_reply_action; 5325 if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) || 5326 (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) { 5327 return BCM_E_PARAM; 5328 } 5329 pkt_action = pkt->arp_request_action; 5330 if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) || 5331 (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) { 5332 return BCM_E_PARAM; 5333 } 5334 pkt_action = pkt->nd_action; 5335 if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) || 5336 (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) { 5337 return BCM_E_PARAM; 5338 } 5339 pkt_action = pkt->dhcp_action; 5340 if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) || 5341 (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) { 5342 return BCM_E_PARAM; 5343 } 5344 5345 pkt_action = pkt->igmp_report_leave_action; 5346 if (pkt_action) { 5347 if (_vlan_protocol_pkt_action_validate(pkt_action) 5348 == BCM_E_PARAM) { 5349 return BCM_E_PARAM; 5350 } 5351 } 5352 pkt_action = pkt->igmp_query_action; 5353 if (pkt_action) { 5354 if (_vlan_protocol_pkt_action_validate(pkt_action) 5355 == BCM_E_PARAM) { 5356 return BCM_E_PARAM; 5357 } 5358 } 5359 pkt_action = pkt->igmp_unknown_msg_action; 5360 if (pkt_action) { 5361 if (_vlan_protocol_pkt_action_validate(pkt_action) 5362 == BCM_E_PARAM) { 5363 return BCM_E_PARAM; 5364 } 5365 } 5366 pkt_action = pkt->mld_report_done_action; 5367 if (pkt_action) { 5368 if (_vlan_protocol_pkt_action_validate(pkt_action) 5369 == BCM_E_PARAM) { 5370 return BCM_E_PARAM; 5371 } 5372 } 5373 pkt_action = pkt->mld_query_action; 5374 if (pkt_action) { 5375 if (_vlan_protocol_pkt_action_validate(pkt_action) 5376 == BCM_E_PARAM) { 5377 return BCM_E_PARAM; 5378 } 5379 } 5380 pkt_action = pkt->ip4_rsvd_mc_action; 5381 if (pkt_action) { 5382 if (_vlan_protocol_pkt_action_validate(pkt_action) 5383 == BCM_E_PARAM) { 5384 return BCM_E_PARAM; 5385 } 5386 } 5387 pkt_action = pkt->ip6_rsvd_mc_action; 5388 if (pkt_action) { 5389 if (_vlan_protocol_pkt_action_validate(pkt_action) 5390 == BCM_E_PARAM) { 5391 return BCM_E_PARAM; 5392 } 5393 } 5394 pkt_action = pkt->ip4_mc_router_adv_action; 5395 if (pkt_action) { 5396 if (_vlan_protocol_pkt_action_validate(pkt_action) 5397 == BCM_E_PARAM) { 5398 return BCM_E_PARAM; 5399 } 5400 } 5401 pkt_action = pkt->ip6_mc_router_adv_action; 5402 if (pkt_action) { 5403 if (_vlan_protocol_pkt_action_validate(pkt_action) 5404 == BCM_E_PARAM) { 5405 return BCM_E_PARAM; 5406 } 5407 } 5408 return BCM_E_NONE; 5409 } 5410 #endif 5411 return BCM_E_UNAVAIL; 5412 } 5413 5414 #if defined(INCLUDE_L3) 5415 5416 /* 5417 * Function : 5418 * _bcm_xgs3_vlan_control_vpn_set 5419 * 5420 * Purpose : 5421 * Configures various controls on the VFI. 5422 * 5423 * Parameters: 5424 * unit - (IN) BCM device number. 5425 * vid - (IN) Vlan id. 5426 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 5427 * control - (IN) Configuration structure. 5428 * 5429 * Return : 5430 * BCM_E_XXX 5431 */ 5432 5433 int 5434 _bcm_xgs3_vlan_control_vpn_set(int unit, bcm_vlan_t vid, uint32 valid_fields, 5435 bcm_vlan_control_vlan_t *control) 5436 { 5437 int rv; 5438 int vfi; 5439 int value; 5440 vfi_entry_t vfi_entry; 5441 soc_mem_t mem = VFIm; 5442 5443 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 5444 5445 /* Read the VFI memory */ 5446 MEM_LOCK(unit, mem); 5447 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 5448 if (!SOC_SUCCESS(rv)) { 5449 MEM_UNLOCK(unit, mem); 5450 return rv; 5451 } 5452 5453 /* Program the VFI table */ 5454 if (control->flags & BCM_VLAN_L2_CLASS_ID_ONLY) { 5455 if (soc_mem_field_valid(unit, mem, CLASS_IDf)) { 5456 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) { 5457 if ((control->if_class < 0) || 5458 (control->if_class > SOC_INTF_CLASS_MAX(unit))) { 5459 rv = BCM_E_PARAM; 5460 } else { 5461 value = control->if_class; 5462 soc_mem_field32_set(unit, mem, &vfi_entry, CLASS_IDf, value); 5463 } 5464 } else { 5465 rv = BCM_E_PARAM; 5466 } 5467 } 5468 } 5469 5470 if (!SOC_SUCCESS(rv)) { 5471 MEM_UNLOCK(unit, mem); 5472 return rv; 5473 } 5474 5475 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vfi, &vfi_entry); 5476 5477 MEM_UNLOCK(unit, mem); 5478 return rv; 5479 } 5480 #endif /* INCLUDE_L3 */ 5481 5482 /* 5483 * Function : 5484 * _bcm_xgs3_vlan_control_vlan_set 5485 * 5486 * Purpose : 5487 * Get vlan specific traffic forwarding parameters 5488 * 5489 * Parameters: 5490 * unit - (IN) BCM device number. 5491 * vid - (IN) Vlan id. 5492 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 5493 * control - (OUT) Configuration. 5494 * 5495 * Return : 5496 * BCM_E_XXX 5497 */ 5498 int 5499 _bcm_xgs3_vlan_control_vlan_set(int unit, bcm_vlan_t vid, 5500 uint32 valid_fields, bcm_vlan_control_vlan_t *control) 5501 { 5502 int rv = BCM_E_UNAVAIL; 5503 5504 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 5505 || defined(BCM_RAVEN_SUPPORT) 5506 uint16 old_outer_tpid; 5507 int tpid_index = -1; /* used also as check flag for cleanup */ 5508 int profile_index; 5509 _vlan_profile_t *old_vpt, vpt; 5510 vlan_tab_entry_t vt; 5511 egr_vlan_entry_t evt; 5512 int disable_mask; 5513 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 5514 int ingress_map_mode=0; 5515 int if_class; 5516 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 5517 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 5518 int trill_name_index=-1; 5519 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 5520 int iif_profile_valid; 5521 int pre_cfg = FALSE; /* pre-configuration flag */ 5522 5523 if (!soc_feature(unit, soc_feature_vlan_ctrl)) { 5524 return (BCM_E_UNAVAIL); 5525 } 5526 5527 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 5528 defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3) 5529 if (_BCM_VPN_VFI_IS_SET(vid)) { 5530 if (soc_feature(unit, soc_feature_vfi_profile)) { 5531 #ifdef BCM_TRIDENT2PLUS_SUPPORT 5532 return bcmi_td2p_vlan_control_vpn_set( 5533 unit, vid, valid_fields, control); 5534 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5535 } else { 5536 #ifdef BCM_GREYHOUND2_SUPPORT 5537 if (soc_feature(unit, soc_feature_vxlan_lite_riot)) { 5538 return bcmi_gh2_vlan_control_vpn_set(unit, vid, valid_fields, 5539 control); 5540 } else 5541 #endif /* BCM_GREYHOUND2_SUPPORT */ 5542 { 5543 return _bcm_xgs3_vlan_control_vpn_set(unit, vid, valid_fields, 5544 control); 5545 } 5546 } 5547 } 5548 #endif /* (TRIDENT2PLUS || TOMAHAWK || GREYHOUND2) && INCLUDE_L3*/ 5549 5550 /* check if perform pre-configuration before vlan is created */ 5551 if (!SHR_BITGET(vlan_info[unit].bmp.w, vid)) { 5552 pre_cfg = TRUE; 5553 } 5554 5555 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 5556 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 5557 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_ingress_intf_map_get(unit, &ingress_map_mode)); 5558 } 5559 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 5560 5561 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit) || 5562 SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 5563 SOC_IS_GREYHOUND2(unit)) { 5564 if(control->flags & ( BCM_VLAN_MPLS_DISABLE | 5565 BCM_VLAN_COSQ_ENABLE | 5566 BCM_VLAN_IGMP_SNOOP_DISABLE | 5567 BCM_VLAN_PIM_SNOOP_DISABLE | 5568 BCM_VLAN_USE_FABRIC_DISTRIBUTION | 5569 BCM_VLAN_TRILL_IGMP_SNOOP_DISABLE | 5570 BCM_VLAN_MIM_TERM_DISABLE)) { 5571 return BCM_E_PARAM; 5572 } 5573 } 5574 5575 if (!soc_feature(unit, soc_feature_l3_ingress_interface)) { 5576 if(control->flags & BCM_VLAN_L3_CLASS_ID) { 5577 return BCM_E_PARAM; 5578 } 5579 } else { 5580 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 5581 /* to check the ingress interface id */ 5582 if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) { 5583 /* VLAN_TABm.L3_IIFm can be assigned for ingress_map_mode=1 */ 5584 if (ingress_map_mode) { 5585 if (control->ingress_if > soc_mem_index_max(unit, L3_IIFm) || 5586 control->ingress_if < soc_mem_index_min(unit, L3_IIFm) ) { 5587 return BCM_E_PARAM; 5588 } 5589 } 5590 /* cannot set l3 class id of vlan if ingress_map_mode=1 */ 5591 if(control->flags & BCM_VLAN_L3_CLASS_ID) { 5592 if (ingress_map_mode) { 5593 return BCM_E_PARAM; 5594 } 5595 if (!SOC_MEM_FIELD_VALID(unit, L3_IIFm, CLASS_IDf)) { 5596 return BCM_E_PARAM; 5597 } 5598 } 5599 } 5600 #endif 5601 } 5602 5603 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 5604 /* TIME-BEING ::: as soc_feature_service_queuing is FALSE for KATANA2 */ 5605 if (soc_feature(unit, soc_feature_service_queuing) || (SOC_IS_KATANA2(unit))) { 5606 /* vlan cosq supported thru bcm_cosq_classifier_xxx() APIs */ 5607 if (control->flags & BCM_VLAN_COSQ_ENABLE) { 5608 return BCM_E_UNAVAIL; 5609 } 5610 } 5611 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT */ 5612 5613 5614 disable_mask = (BCM_VLAN_IP4_DISABLE | 5615 BCM_VLAN_IP6_DISABLE | 5616 BCM_VLAN_IP4_MCAST_DISABLE | 5617 BCM_VLAN_IP6_MCAST_DISABLE | 5618 BCM_VLAN_IP4_MCAST_L2_DISABLE | 5619 BCM_VLAN_IP6_MCAST_L2_DISABLE); 5620 5621 iif_profile_valid = FALSE; 5622 #if defined(BCM_TRIDENT2_SUPPORT) && defined (INCLUDE_L3) 5623 if (soc_feature(unit, soc_feature_l3_iif_profile)) { 5624 iif_profile_valid = TRUE; 5625 if (!ingress_map_mode) { 5626 BCM_IF_ERROR_RETURN( 5627 _bcm_td2_l3_intf_iif_profile_update(unit, vid, control)); 5628 } 5629 #ifdef BCM_MONTEREY_SUPPORT 5630 else if (SOC_IS_MONTEREY(unit) && 5631 (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK)) { 5632 BCM_IF_ERROR_RETURN( 5633 _bcm_td2_l3_intf_iif_profile_update(unit, control->ingress_if, control)); 5634 } 5635 #endif 5636 } 5637 #endif /* BCM_TRIDENT2_SUPPORT */ 5638 5639 if (control->flags & disable_mask) { 5640 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 5641 if (0 == SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, IPV4L3_ENABLEf) && 5642 !iif_profile_valid) { 5643 /* This device does not have per-vlan enable controls */ 5644 return BCM_E_PARAM; 5645 } 5646 #else /* BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 5647 return BCM_E_PARAM; 5648 #endif /* BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 5649 } 5650 5651 if ((control->flags & BCM_VLAN_IGMP_SNOOP_DISABLE) 5652 && !SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 5653 ENABLE_IGMP_MLD_SNOOPINGf)) { 5654 return BCM_E_PARAM; 5655 } 5656 5657 5658 if (control->flags & (BCM_VLAN_PIM_SNOOP_DISABLE | 5659 BCM_VLAN_USE_FABRIC_DISTRIBUTION)) { 5660 return BCM_E_PARAM; 5661 } 5662 5663 if ((control->flags & 5664 (BCM_VLAN_MPLS_DISABLE | BCM_VLAN_COSQ_ENABLE)) && 5665 !SOC_IS_TR_VL(unit)) { 5666 return BCM_E_PARAM; 5667 } 5668 5669 if ((control->flags & BCM_VLAN_MIM_TERM_DISABLE) && !SOC_IS_ENDURO(unit)) { 5670 return BCM_E_PARAM; 5671 } 5672 5673 if (control->forwarding_vlan > BCM_VLAN_MAX) { 5674 return BCM_E_PARAM; 5675 } 5676 5677 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 5678 if ((control->forwarding_mode == bcmVlanForwardSingleCrossConnect) || 5679 (control->forwarding_mode == bcmVlanForwardDoubleCrossConnect)) { 5680 /* No L2 learning for cross-connect */ 5681 if (0 == (control->flags & BCM_VLAN_LEARN_DISABLE)) { 5682 return (BCM_E_PARAM); 5683 } 5684 } 5685 #endif /* BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 5686 5687 #if defined(BCM_TRX_SUPPORT) 5688 if ((0 == SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, ICMP_REDIRECT_TOCPUf)) && 5689 (!iif_profile_valid) && 5690 (control->flags & BCM_VLAN_ICMP_REDIRECT_TOCPU)) { 5691 return (BCM_E_PARAM); 5692 } 5693 if ((control->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) && 5694 !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, L2_MISS_TOCPUf)) { 5695 return BCM_E_PARAM; 5696 } 5697 if ((control->flags & BCM_VLAN_UNKNOWN_UCAST_DROP) && 5698 !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, L2_MISS_DROPf)) { 5699 return BCM_E_PARAM; 5700 } 5701 if ((control->flags & BCM_VLAN_NON_UCAST_TOCPU) && 5702 !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, 5703 L2_NON_UCAST_TOCPUf)) { 5704 return BCM_E_PARAM; 5705 } 5706 if ((control->flags & BCM_VLAN_NON_UCAST_DROP) && 5707 !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, 5708 L2_NON_UCAST_DROPf)) { 5709 return BCM_E_PARAM; 5710 } 5711 if (control->if_class < 0 || control->if_class > SOC_INTF_CLASS_MAX(unit)){ 5712 return BCM_E_PARAM; 5713 } 5714 if (control->l3_if_class < 0 || 5715 control->l3_if_class > SOC_INTF_CLASS_MAX(unit)){ 5716 return BCM_E_PARAM; 5717 } 5718 #endif /* BCM_TRX_SUPPORT */ 5719 5720 /* validate parameter protocol_pkt */ 5721 if (valid_fields & BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK) { 5722 if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, PROTOCOL_PKT_INDEXf)) { 5723 #if defined(BCM_TRIDENT_SUPPORT) 5724 bcm_vlan_protocol_packet_ctrl_t zero_protocol_pkt; 5725 bcm_vlan_control_vlan_t dft_control; 5726 sal_memset(&zero_protocol_pkt, 0, 5727 sizeof(bcm_vlan_protocol_packet_ctrl_t)); 5728 bcm_vlan_control_vlan_t_init(&dft_control); 5729 #if defined(BCM_TRX_SUPPORT) 5730 BCM_IF_ERROR_RETURN(_vlan_protocol_pkt_ctrl_default_add 5731 (unit, &dft_control.protocol_pkt)); 5732 #endif /*BCM_TRX_SUPPORT*/ 5733 if (sal_memcmp(&zero_protocol_pkt, &control->protocol_pkt, 5734 sizeof(bcm_vlan_protocol_packet_ctrl_t)) && 5735 sal_memcmp(&dft_control.protocol_pkt, &control->protocol_pkt, 5736 sizeof(bcm_vlan_protocol_packet_ctrl_t))) { 5737 if (SOC_IS_TRIDENT(unit) && 5738 !SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 5739 ENABLE_IGMP_MLD_SNOOPINGf)) { 5740 return BCM_E_UNAVAIL; 5741 } 5742 } 5743 #endif /* BCM_TRIDENT_SUPPORT */ 5744 rv = _bcm_xgs3_protocol_packet_actions_validate(unit, 5745 &control->protocol_pkt); 5746 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 5747 return rv; 5748 } 5749 } 5750 #if defined(BCM_TRX_SUPPORT) 5751 else { 5752 bcm_vlan_protocol_packet_ctrl_t tmp_protocol_pkt; 5753 sal_memset(&tmp_protocol_pkt, 0, sizeof(bcm_vlan_protocol_packet_ctrl_t)); 5754 if (sal_memcmp(&tmp_protocol_pkt, &control->protocol_pkt, 5755 sizeof(bcm_vlan_protocol_packet_ctrl_t))) { 5756 return BCM_E_UNAVAIL; 5757 } 5758 } 5759 #endif /* BCM_TRX_SUPPORT */ 5760 } 5761 5762 #if defined(BCM_TRIUMPH_SUPPORT) 5763 if (valid_fields & BCM_VLAN_CONTROL_VLAN_COSQ_MASK) { 5764 if (SOC_MEM_IS_VALID(unit, VLAN_COS_MAPm)) { 5765 #if defined(BCM_KATANA_SUPPORT) 5766 if (SOC_IS_KATANAX(unit)) { 5767 rv = _vlan_kt_cosq_map_set(unit, vid, control); 5768 } else 5769 #endif 5770 { 5771 rv = _vlan_cosq_map_set(unit, vid, control); 5772 } 5773 BCM_IF_ERROR_RETURN(rv); 5774 } 5775 } 5776 #if defined(INCLUDE_L3) 5777 /* Check L3 Ingress Interface Map mode. */ 5778 if (soc_feature(unit, soc_feature_l3) && 5779 soc_feature(unit, soc_feature_l3_ingress_interface) && 5780 (!ingress_map_mode)) { 5781 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) { 5782 if (!(control->flags & BCM_VLAN_L2_CLASS_ID_ONLY ) || 5783 (control->flags & BCM_VLAN_L3_CLASS_ID)) { 5784 if_class = control->if_class; 5785 if (valid_fields & BCM_VLAN_CONTROL_VLAN_L3_IF_CLASS_MASK) { 5786 if (control->flags & BCM_VLAN_L3_CLASS_ID) { 5787 if_class = control->l3_if_class; 5788 } 5789 } 5790 if ((SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf) || 5791 SOC_MEM_FIELD_VALID(unit, VLAN_MPLSm, L3_IIFf)) && 5792 SOC_MEM_IS_VALID(unit, L3_IIFm)) { 5793 rv = _bcm_tr_l3_intf_class_set(unit, vid, if_class); 5794 BCM_IF_ERROR_RETURN(rv); 5795 } 5796 } 5797 } 5798 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, ALLOW_GLOBAL_ROUTEf)) { 5799 rv = _bcm_tr_l3_intf_global_route_enable_set(unit, vid, 5800 (0 == (control->flags & BCM_VLAN_L3_VRF_GLOBAL_DISABLE))); 5801 BCM_IF_ERROR_RETURN(rv); 5802 } 5803 } 5804 5805 if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) { 5806 if ((soc_feature(unit, soc_feature_l3) && (ingress_map_mode) && 5807 soc_feature(unit, soc_feature_l3_ingress_interface)) || 5808 (BCM_VLAN_VALID(control->forwarding_vlan ) && 5809 (control->ingress_if <= soc_mem_index_max(unit, L3_IIFm))) ) { 5810 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 5811 vlan_mpls_entry_t vlan_mpls; 5812 5813 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t)); 5814 BCM_IF_ERROR_RETURN 5815 (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid, 5816 &vlan_mpls)); 5817 /* Configure Vlan mapping */ 5818 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, 5819 L3_IIFf, control->ingress_if); 5820 5821 BCM_IF_ERROR_RETURN 5822 (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid, 5823 &vlan_mpls)); 5824 } 5825 } 5826 } 5827 #if defined(BCM_TRIDENT2_SUPPORT) 5828 if (valid_fields & BCM_VLAN_CONTROL_VLAN_NAT_REALM_ID_MASK) { 5829 /* set the src realm id in L3_IIF table */ 5830 if (soc_feature(unit, soc_feature_nat) && (SOC_MEM_IS_VALID(unit, L3_IIFm)) 5831 && (SOC_MEM_FIELD_VALID(unit, L3_IIFm, SRC_REALM_IDf)) && 5832 (!ingress_map_mode)) { 5833 /* validate realm id param */ 5834 if ((control->nat_realm_id < 0) || (control->nat_realm_id > 3)) { 5835 return BCM_E_PARAM; 5836 } 5837 BCM_IF_ERROR_RETURN(_bcm_tr_l3_intf_nat_realm_id_set(unit, vid, 5838 control->nat_realm_id)); 5839 if(control->flags & BCM_VLAN_SRC_DST_NAT_REALM_ID) { 5840 BCM_IF_ERROR_RETURN( 5841 _bcm_td2_nh_nat_id_update_by_vlan( 5842 unit, vid, control->nat_realm_id)); 5843 } 5844 } 5845 } 5846 #endif /* BCM_TRIDENT2_SUPPORT */ 5847 #endif /* INCLUDE_L3 */ 5848 #endif /* BCM_TRIUMPH_SUPPORT */ 5849 5850 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 5851 if (soc_feature(unit, soc_feature_l3) && 5852 soc_feature(unit, soc_feature_l3_ingress_interface) && 5853 (!ingress_map_mode)) { 5854 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_DEFAULTROUTECHECKf) || 5855 soc_feature(unit, soc_feature_l3_iif_profile)) { 5856 rv = _bcm_tr2_l3_intf_urpf_default_route_set(unit, vid, 5857 (0 == (control->flags & BCM_VLAN_L3_URPF_DEFAULT_ROUTE_CHECK_DISABLE))); 5858 BCM_IF_ERROR_RETURN(rv); 5859 if (valid_fields & BCM_VLAN_CONTROL_VLAN_URPF_MODE_MASK) { 5860 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_MODEf) || 5861 soc_feature(unit, soc_feature_l3_iif_profile)) { 5862 rv = _bcm_tr2_l3_intf_urpf_mode_set(unit, vid, 5863 control->urpf_mode); 5864 BCM_IF_ERROR_RETURN(rv); 5865 } 5866 } 5867 } 5868 } 5869 if (soc_feature(unit, soc_feature_mpls)) { 5870 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 5871 vlan_mpls_entry_t vlan_mpls_entry; 5872 sal_memset(&vlan_mpls_entry, 0, sizeof(vlan_mpls_entry_t)); 5873 BCM_IF_ERROR_RETURN 5874 (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid, 5875 &vlan_mpls_entry)); 5876 soc_mem_field32_set(unit, VLAN_MPLSm, 5877 &vlan_mpls_entry, MPLS_ENABLEf, 5878 (control->flags & BCM_VLAN_MPLS_DISABLE) ? 0x0 : 0x1); 5879 BCM_IF_ERROR_RETURN 5880 (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid, 5881 &vlan_mpls_entry)); 5882 } 5883 #if defined(BCM_TRIDENT3_SUPPORT) 5884 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 5885 vlan_attrs_1_entry_t vlan_attrs; 5886 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs)); 5887 BCM_IF_ERROR_RETURN 5888 (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid, 5889 &vlan_attrs)); 5890 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MPLS_ENABLEf, 5891 (control->flags & BCM_VLAN_MPLS_DISABLE) ? 0x0 : 0x1); 5892 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, FID_IDf, 5893 control->forwarding_vlan); 5894 BCM_IF_ERROR_RETURN 5895 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid, 5896 &vlan_attrs)); 5897 } 5898 #endif 5899 } 5900 5901 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5902 if (soc_feature(unit, soc_feature_vlan_filter)) { 5903 vlan_tab_entry_t vlan_tab; 5904 sal_memset(&vlan_tab, 0, sizeof(vlan_tab)); 5905 BCM_IF_ERROR_RETURN 5906 (soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, vid, 5907 &vlan_tab)); 5908 soc_mem_field32_set(unit, EGR_VLANm, &vlan_tab, EN_EFILTERf, 5909 (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE) ? 0x0 : 0x1); 5910 BCM_IF_ERROR_RETURN 5911 (soc_mem_write(unit, EGR_VLANm, MEM_BLOCK_ALL, vid, 5912 &vlan_tab)); 5913 5914 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 5915 vlan_attrs_1_entry_t vlan_attrs; 5916 sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs)); 5917 BCM_IF_ERROR_RETURN 5918 (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid, 5919 &vlan_attrs)); 5920 soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, EN_IFILTERf, 5921 (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE) ? 0x0 : 0x1); 5922 BCM_IF_ERROR_RETURN 5923 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid, 5924 &vlan_attrs)); 5925 } else if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) { 5926 vlan_mpls_entry_t vlan_mpls; 5927 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t)); 5928 BCM_IF_ERROR_RETURN 5929 (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid, 5930 &vlan_mpls)); 5931 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, EN_IFILTERf, 5932 (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE) ? 0x0 : 0x1); 5933 BCM_IF_ERROR_RETURN 5934 (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid, 5935 &vlan_mpls)); 5936 } 5937 } 5938 #endif 5939 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 5940 5941 soc_mem_lock(unit, VLAN_TABm); 5942 _bcm_fb2_outer_tpid_tab_lock(unit); 5943 5944 if (pre_cfg == FALSE) { 5945 /* after vlan is created */ 5946 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 5947 NULL, vid, &profile_index); 5948 if (BCM_FAILURE(rv)) { 5949 _bcm_fb2_outer_tpid_tab_unlock(unit); 5950 soc_mem_unlock(unit, VLAN_TABm); 5951 return (rv); 5952 } 5953 old_vpt = &VLAN_PROFILE_ENTRY(unit, profile_index); 5954 vpt = *old_vpt; 5955 old_outer_tpid = old_vpt->outer_tpid; 5956 5957 } else { /* before vlan is created */ 5958 uint16 dft_tpid; 5959 5960 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt); 5961 if (BCM_FAILURE(rv)) { 5962 _bcm_fb2_outer_tpid_tab_unlock(unit); 5963 soc_mem_unlock(unit, VLAN_TABm); 5964 return (rv); 5965 } 5966 5967 #if defined(BCM_EASY_RELOAD_SUPPORT) 5968 if (SOC_IS_RELOADING(unit)) { 5969 /* 5970 * Use VLAN_PROFILE_ER() as a write-through cache 5971 * for VLAN profile pointers during easy reload 5972 */ 5973 profile_index = VLAN_PROFILE_PTR_ER(unit, vid); 5974 } else 5975 #endif 5976 { 5977 profile_index = soc_mem_field32_get(unit, VLAN_TABm, &vt, 5978 VLAN_PROFILE_PTRf); 5979 } 5980 old_vpt = &VLAN_PROFILE_ENTRY(unit, profile_index); 5981 vpt = *old_vpt; 5982 old_outer_tpid = old_vpt->outer_tpid; 5983 5984 /* check if first time doing pre-configuration */ 5985 if (!SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) { 5986 /* no profile added, hence no valid tpid */ 5987 dft_tpid = _bcm_fb2_outer_tpid_default_get(unit); 5988 rv = _bcm_fb2_outer_tpid_entry_add(unit, dft_tpid, 5989 &tpid_index); 5990 if (BCM_FAILURE(rv)) { 5991 _bcm_fb2_outer_tpid_tab_unlock(unit); 5992 soc_mem_unlock(unit, VLAN_TABm); 5993 return (rv); 5994 } 5995 old_outer_tpid = dft_tpid; 5996 } 5997 } 5998 5999 if (valid_fields & BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK) { 6000 /* If old TPID and new TPID are different, deletes the old entry 6001 * and adds the new entry. 6002 */ 6003 if (old_outer_tpid != control->outer_tpid) { 6004 if (!SOC_MEM_IS_VALID(unit, EGR_VLANm)) { 6005 _bcm_fb2_outer_tpid_tab_unlock(unit); 6006 soc_mem_unlock(unit, VLAN_TABm); 6007 return BCM_E_UNAVAIL; 6008 } 6009 6010 rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, (int)vid, &evt); 6011 if (BCM_FAILURE(rv)) { 6012 _bcm_fb2_outer_tpid_tab_unlock(unit); 6013 soc_mem_unlock(unit, VLAN_TABm); 6014 return (rv); 6015 } 6016 6017 rv = _bcm_fb2_outer_tpid_lkup(unit, old_outer_tpid, &tpid_index); 6018 if (BCM_FAILURE(rv)) { 6019 _bcm_fb2_outer_tpid_tab_unlock(unit); 6020 soc_mem_unlock(unit, VLAN_TABm); 6021 return (rv); 6022 } 6023 6024 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 6025 if (BCM_FAILURE(rv)) { 6026 _bcm_fb2_outer_tpid_tab_unlock(unit); 6027 soc_mem_unlock(unit, VLAN_TABm); 6028 return (rv); 6029 } 6030 6031 rv = _bcm_fb2_outer_tpid_entry_add(unit, control->outer_tpid, 6032 &tpid_index); 6033 if (BCM_FAILURE(rv)) { 6034 (void)_bcm_fb2_outer_tpid_entry_add(unit, old_outer_tpid, 6035 &tpid_index); 6036 _bcm_fb2_outer_tpid_tab_unlock(unit); 6037 soc_mem_unlock(unit, VLAN_TABm); 6038 return (rv); 6039 } 6040 6041 soc_mem_field32_set(unit, EGR_VLANm, &evt, OUTER_TPID_INDEXf, tpid_index); 6042 rv = WRITE_EGR_VLANm(unit, MEM_BLOCK_ALL, (int)vid, &evt); 6043 if (BCM_FAILURE(rv)) { 6044 _bcm_fb2_outer_tpid_tab_unlock(unit); 6045 soc_mem_unlock(unit, VLAN_TABm); 6046 return (rv); 6047 } 6048 } 6049 } 6050 vpt.flags = control->flags; 6051 if (valid_fields & BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK) { 6052 vpt.outer_tpid = control->outer_tpid; 6053 } else { 6054 vpt.outer_tpid = old_outer_tpid; 6055 } 6056 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP6_MCAST_FLOOD_MODE_MASK) { 6057 vpt.ip6_mcast_flood_mode = control->ip6_mcast_flood_mode; 6058 } 6059 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP4_MCAST_FLOOD_MODE_MASK) { 6060 vpt.ip4_mcast_flood_mode = control->ip4_mcast_flood_mode; 6061 } 6062 if (valid_fields & BCM_VLAN_CONTROL_VLAN_L2_MCAST_FLOOD_MODE_MASK) { 6063 vpt.l2_mcast_flood_mode = control->l2_mcast_flood_mode; 6064 } 6065 #if defined(BCM_TRX_SUPPORT) 6066 if (valid_fields & BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK) { 6067 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl) 6068 && SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, 6069 PROTOCOL_PKT_INDEXf)) { 6070 sal_memcpy(&vpt.protocol_pkt, &control->protocol_pkt, 6071 sizeof(bcm_vlan_protocol_packet_ctrl_t)); 6072 } 6073 } 6074 #endif /* BCM_TRX_SUPPORT */ 6075 6076 if (!SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf) && 6077 (control->learn_flags != 0)) { 6078 _bcm_fb2_outer_tpid_tab_unlock(unit); 6079 soc_mem_unlock(unit, VLAN_TABm); 6080 return BCM_E_UNAVAIL; 6081 } 6082 #if defined(BCM_HURRICANE3_SUPPORT) 6083 else if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)) { 6084 if (control->learn_flags & 6085 ~(BCM_VLAN_LEARN_CONTROL_ENABLE | 6086 BCM_VLAN_LEARN_CONTROL_ARL | 6087 BCM_VLAN_LEARN_CONTROL_CPU | 6088 BCM_VLAN_LEARN_CONTROL_FWD | 6089 BCM_VLAN_LEARN_CONTROL_PENDING)) { 6090 _bcm_fb2_outer_tpid_tab_unlock(unit); 6091 soc_mem_unlock(unit, VLAN_TABm); 6092 return BCM_E_PARAM; 6093 } 6094 vpt.learn_flags= control->learn_flags; 6095 } 6096 #endif /* BCM_HURRICANE3_SUPPORT */ 6097 6098 /* Update the vlan profile table only if the old and new entries are 6099 * different. 6100 */ 6101 if (pre_cfg == FALSE) { 6102 /* after vlan is created */ 6103 rv = _vlan_profile_update(unit, vid, &vpt); 6104 6105 } else { /* before vlan is created */ 6106 uint8 equal; 6107 int idx; 6108 6109 /* Compare original profile with new one. */ 6110 rv = _vlan_profile_compare(unit, &VLAN_PROFILE_ENTRY(unit, profile_index), 6111 &vpt, &equal); 6112 if (rv == BCM_E_NONE && (equal != TRUE)) { 6113 /* Add new profile. */ 6114 rv = _vlan_profile_add(unit, &vpt, &idx); 6115 6116 if (BCM_SUCCESS(rv)) { 6117 /* Set new vlan profile index. */ 6118 soc_mem_field32_set(unit, VLAN_TABm, &vt, VLAN_PROFILE_PTRf, idx); 6119 6120 /* Write back vlan table entry. */ 6121 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int)vid, &vt); 6122 if (BCM_SUCCESS(rv)) { 6123 /* Delete original vlan profile if new one was allocated and 6124 the original one is valid. */ 6125 if (SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid) && 6126 (profile_index != idx)) { 6127 rv = _vlan_profile_delete(unit, profile_index); 6128 } 6129 } 6130 } 6131 } 6132 } 6133 if (BCM_FAILURE(rv)) { 6134 if (-1 != tpid_index) { 6135 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 6136 } 6137 (void)_bcm_fb2_outer_tpid_entry_add(unit, old_outer_tpid, &tpid_index); 6138 _bcm_fb2_outer_tpid_tab_unlock(unit); 6139 soc_mem_unlock(unit, VLAN_TABm); 6140 return (rv); 6141 } 6142 6143 _bcm_fb2_outer_tpid_tab_unlock(unit); 6144 6145 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt); 6146 if (BCM_FAILURE(rv)) { 6147 soc_mem_unlock(unit, VLAN_TABm); 6148 return (rv); 6149 } 6150 6151 if (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) { 6152 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VRF_IDf)) { 6153 soc_mem_field32_set(unit, VLAN_TABm, &vt, VRF_IDf, control->vrf); 6154 } 6155 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 6156 else if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_l3) && 6157 soc_feature(unit, soc_feature_l3_ingress_interface) && 6158 SOC_MEM_IS_VALID(unit,L3_IIFm)) { 6159 if (soc_feature(unit, soc_feature_no_vlan_vrf)) { 6160 /* 6161 * Return E_UNAVAIL for those device can't support VID 1:1 6162 * mapping to L3_IIFm to set VLAN based VRF_ID 6163 */ 6164 soc_mem_unlock(unit, VLAN_TABm); 6165 return BCM_E_UNAVAIL; 6166 } else if (!ingress_map_mode) { 6167 rv = _bcm_tr_l3_intf_vrf_bind(unit, vid, control->vrf); 6168 if (BCM_FAILURE(rv)) { 6169 soc_mem_unlock(unit, VLAN_TABm); 6170 return rv; 6171 } 6172 } 6173 } 6174 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 6175 } 6176 6177 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 6178 if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) { 6179 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf) && 6180 soc_feature(unit, soc_feature_l3_ingress_interface) && 6181 soc_feature(unit, soc_feature_l3)) { 6182 if (ingress_map_mode) { 6183 /* Configure Vlan mapping */ 6184 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6185 L3_IIFf, control->ingress_if); 6186 } 6187 } 6188 } 6189 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 6190 6191 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 6192 if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK) { 6193 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, FID_IDf)) { 6194 soc_mem_field32_set(unit, VLAN_TABm, &vt, FID_IDf, 6195 control->forwarding_vlan); 6196 } else { 6197 /* For Raven and Hawkeye devices FID_ID is not valid.*/ 6198 soc_mem_unlock(unit, VLAN_TABm); 6199 return BCM_E_UNAVAIL; 6200 } 6201 } 6202 #endif /* BCM_TRX_SUPPORT */ 6203 #if defined(BCM_TRX_SUPPORT) 6204 /* if_class is set for any of below conditions: 6205 * BCM_VLAN_L2_CLASS_ID_ONLY and BCM_VLAN_L3_CLASS_ID are not set 6206 * Only BCM_VLAN_L2_CLASS_ID_ONLY is set 6207 * When both BCM_VLAN_L2_CLASS_ID_ONLY and BCM_VLAN_L3_CLASS_ID are set */ 6208 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) { 6209 if (!((!(control->flags & BCM_VLAN_L2_CLASS_ID_ONLY)) && 6210 (control->flags & BCM_VLAN_L3_CLASS_ID))) { 6211 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VLAN_CLASS_IDf)) { 6212 soc_mem_field32_set(unit, VLAN_TABm, &vt, VLAN_CLASS_IDf, 6213 control->if_class); 6214 } 6215 } 6216 } 6217 #endif /* BCM_TRX_SUPPORT */ 6218 #if defined(BCM_TRX_SUPPORT) 6219 if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK) { 6220 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L2_ENTRY_KEY_TYPEf)) { 6221 rv = _vlan_control_trx_forwarding_mode_set(unit, (uint32 *)&vt, 6222 control->forwarding_mode); 6223 if (BCM_FAILURE(rv)) { 6224 soc_mem_unlock(unit, VLAN_TABm); 6225 return rv; 6226 } 6227 } 6228 } 6229 #endif /* BCM_TRX_SUPPORT */ 6230 6231 #if defined(BCM_HELIX5_SUPPORT) 6232 if (soc_feature(unit, soc_feature_vlan_wirelss_traffic_select)) { 6233 6234 if (control->flags2 & BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT && 6235 control->flags2 & BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT) { 6236 return BCM_E_PARAM; 6237 } 6238 if (control->flags2 & BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT) { 6239 soc_mem_field32_set(unit, VLAN_TABm, &vt, WIRED_WIRELESSf, 0x1); 6240 } 6241 6242 if (control->flags2 & BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT) { 6243 soc_mem_field32_set(unit, VLAN_TABm, &vt, WIRED_WIRELESSf, 0x2); 6244 } 6245 } 6246 #endif 6247 6248 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 6249 6250 if (valid_fields & BCM_VLAN_CONTROL_VLAN_VP_MCAST_MASK) { 6251 /* Should update manual_vpctrl before trill setting */ 6252 if (control->vp_mc_ctrl != bcmVlanVPMcControlAuto) { 6253 SHR_BITSET(vlan_info[unit].vp_mode, vid); 6254 } else { 6255 SHR_BITCLR(vlan_info[unit].vp_mode, vid); 6256 } 6257 } 6258 6259 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6260 if (0 == control->broadcast_group) { 6261 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 0); 6262 } 6263 } 6264 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6265 if (0 == control->unknown_multicast_group) { 6266 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 0); 6267 } 6268 } 6269 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6270 if (0 == control->unknown_unicast_group) { 6271 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 0); 6272 } 6273 } 6274 6275 if (soc_feature(unit, soc_feature_wlan)) { 6276 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6277 if (_BCM_MULTICAST_IS_WLAN(control->broadcast_group)) { 6278 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 6279 _BCM_MULTICAST_ID_GET(control->broadcast_group)); 6280 } 6281 } 6282 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6283 if (_BCM_MULTICAST_IS_WLAN(control->unknown_multicast_group)) { 6284 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 6285 _BCM_MULTICAST_ID_GET(control->unknown_multicast_group)); 6286 } 6287 } 6288 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6289 if (_BCM_MULTICAST_IS_WLAN(control->unknown_unicast_group)) { 6290 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 6291 _BCM_MULTICAST_ID_GET(control->unknown_unicast_group)); 6292 } 6293 } 6294 } 6295 6296 if (soc_feature(unit, soc_feature_vlan_vp)) { 6297 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6298 if (_BCM_MULTICAST_IS_VLAN(control->broadcast_group)) { 6299 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 6300 _BCM_MULTICAST_ID_GET(control->broadcast_group)); 6301 } 6302 } 6303 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6304 if (_BCM_MULTICAST_IS_VLAN(control->unknown_multicast_group)) { 6305 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 6306 _BCM_MULTICAST_ID_GET(control->unknown_multicast_group)); 6307 } 6308 } 6309 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6310 if (_BCM_MULTICAST_IS_VLAN(control->unknown_unicast_group)) { 6311 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 6312 _BCM_MULTICAST_ID_GET(control->unknown_unicast_group)); 6313 } 6314 } 6315 } 6316 #endif /* (BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 6317 6318 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 6319 if (soc_feature(unit, soc_feature_trill)) { 6320 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6321 TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf)) { 6322 if (control->flags & BCM_VLAN_TRILL_IGMP_SNOOP_DISABLE) { 6323 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6324 TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf, 0x0); 6325 } else { 6326 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6327 TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf, 0x1); 6328 } 6329 } 6330 6331 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6332 if (_BCM_MULTICAST_IS_VLAN(control->broadcast_group)) { 6333 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 6334 _BCM_MULTICAST_ID_GET(control->broadcast_group)); 6335 } 6336 } 6337 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6338 if (_BCM_MULTICAST_IS_VLAN(control->unknown_multicast_group)) { 6339 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 6340 _BCM_MULTICAST_ID_GET(control->unknown_multicast_group)); 6341 } 6342 } 6343 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6344 if (_BCM_MULTICAST_IS_VLAN(control->unknown_unicast_group)) { 6345 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 6346 _BCM_MULTICAST_ID_GET(control->unknown_unicast_group)); 6347 } 6348 } 6349 6350 if (valid_fields & BCM_VLAN_CONTROL_VLAN_TRILL_NONUNICAST_GROUP_MASK) { 6351 if (BCM_SUCCESS(bcm_td_trill_multicast_check(unit, 6352 control->trill_nonunicast_group))) { 6353 /* Obtain matching l3mc for given l2mc */ 6354 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6355 TRILL_DOMAIN_NONUC_REPL_INDEXf)) { 6356 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6357 TRILL_DOMAIN_NONUC_REPL_INDEXf, 6358 _BCM_MULTICAST_ID_GET(control->trill_nonunicast_group)); 6359 } 6360 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6361 BC_TRILL_NETWORK_RECEIVERS_PRESENTf)) { 6362 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6363 BC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0x1); 6364 } 6365 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6366 UMC_TRILL_NETWORK_RECEIVERS_PRESENTf)) { 6367 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6368 UMC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0x1); 6369 } 6370 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6371 UUC_TRILL_NETWORK_RECEIVERS_PRESENTf)) { 6372 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6373 UUC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0x1); 6374 } 6375 rv = bcm_td_trill_vlan_multicast_group_add(unit, vid, &vt); 6376 } else { 6377 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6378 TRILL_DOMAIN_NONUC_REPL_INDEXf)) { 6379 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6380 TRILL_DOMAIN_NONUC_REPL_INDEXf, 0); 6381 } 6382 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6383 BC_TRILL_NETWORK_RECEIVERS_PRESENTf)) { 6384 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6385 BC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0); 6386 } 6387 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6388 UMC_TRILL_NETWORK_RECEIVERS_PRESENTf)) { 6389 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6390 UMC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0); 6391 } 6392 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, 6393 UUC_TRILL_NETWORK_RECEIVERS_PRESENTf)) { 6394 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6395 UUC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0); 6396 } 6397 rv = bcm_td_trill_vlan_multicast_group_delete(unit, vid, &vt); 6398 } 6399 6400 /* Specify per-Vlan trill_name */ 6401 if (BCM_SUCCESS(rv)) { 6402 if (valid_fields & BCM_VLAN_CONTROL_VLAN_SOURCE_TRILL_NAME_MASK) { 6403 if (control->source_trill_name && 6404 soc_mem_field_valid (unit, VLAN_TABm, TRILL_RBRIDGE_NICKNAME_INDEXf)) { 6405 rv = bcm_td_trill_source_trill_name_idx_get(unit, 6406 control->source_trill_name, &trill_name_index); 6407 if (BCM_SUCCESS(rv)) { 6408 soc_mem_field32_set(unit, VLAN_TABm, &vt, 6409 TRILL_RBRIDGE_NICKNAME_INDEXf, 6410 trill_name_index); 6411 } 6412 } 6413 } 6414 } else { 6415 soc_mem_unlock(unit, VLAN_TABm); 6416 return (rv); 6417 } 6418 } 6419 } 6420 6421 if (soc_feature(unit, soc_feature_niv)) { 6422 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6423 if (_BCM_MULTICAST_IS_NIV(control->broadcast_group)) { 6424 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 6425 _BCM_MULTICAST_ID_GET(control->broadcast_group)); 6426 } 6427 } 6428 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6429 if (_BCM_MULTICAST_IS_NIV(control->unknown_multicast_group)) { 6430 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 6431 _BCM_MULTICAST_ID_GET(control->unknown_multicast_group)); 6432 } 6433 } 6434 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6435 if (_BCM_MULTICAST_IS_NIV(control->unknown_unicast_group)) { 6436 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 6437 _BCM_MULTICAST_ID_GET(control->unknown_unicast_group)); 6438 } 6439 } 6440 } 6441 6442 if (soc_feature(unit, soc_feature_l3) && soc_property_get(unit, spn_L3_ENABLE, 1)) { 6443 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6444 if (_BCM_MULTICAST_IS_L3(control->broadcast_group)) { 6445 soc_mem_field32_set(unit, VLAN_TABm, &vt, BC_IDXf, 6446 _BCM_MULTICAST_ID_GET 6447 (control->broadcast_group)); 6448 } 6449 } 6450 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6451 if (_BCM_MULTICAST_IS_L3(control->unknown_multicast_group)) { 6452 soc_mem_field32_set(unit, VLAN_TABm, &vt, UMC_IDXf, 6453 _BCM_MULTICAST_ID_GET 6454 (control->unknown_multicast_group)); 6455 } 6456 } 6457 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6458 if (_BCM_MULTICAST_IS_L3(control->unknown_unicast_group)) { 6459 soc_mem_field32_set(unit, VLAN_TABm, &vt, UUC_IDXf, 6460 _BCM_MULTICAST_ID_GET 6461 (control->unknown_unicast_group)); 6462 } 6463 } 6464 } 6465 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 6466 6467 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 6468 if (soc_feature(unit, soc_feature_port_extension)) { 6469 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6470 if (_BCM_MULTICAST_IS_EXTENDER(control->broadcast_group)) { 6471 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 6472 _BCM_MULTICAST_ID_GET(control->broadcast_group)); 6473 } 6474 } 6475 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6476 if (_BCM_MULTICAST_IS_EXTENDER(control->unknown_multicast_group)) { 6477 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 6478 _BCM_MULTICAST_ID_GET(control->unknown_multicast_group)); 6479 } 6480 } 6481 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6482 if (_BCM_MULTICAST_IS_EXTENDER(control->unknown_unicast_group)) { 6483 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 6484 _BCM_MULTICAST_ID_GET(control->unknown_unicast_group)); 6485 } 6486 } 6487 } 6488 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 6489 6490 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6491 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 6492 if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) { 6493 if (_BCM_MULTICAST_IS_SUBPORT(control->broadcast_group)) { 6494 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 6495 _BCM_MULTICAST_ID_GET(control->broadcast_group)); 6496 } 6497 } 6498 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) { 6499 if (_BCM_MULTICAST_IS_SUBPORT(control->unknown_multicast_group)) { 6500 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 6501 _BCM_MULTICAST_ID_GET(control->unknown_multicast_group)); 6502 } 6503 } 6504 if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) { 6505 if (_BCM_MULTICAST_IS_SUBPORT(control->unknown_unicast_group)) { 6506 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 6507 _BCM_MULTICAST_ID_GET(control->unknown_unicast_group)); 6508 } 6509 } 6510 } 6511 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) */ 6512 6513 6514 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 6515 if (valid_fields & BCM_VLAN_CONTROL_VLAN_VP_MCAST_MASK) { 6516 if (control->vp_mc_ctrl == bcmVlanVPMcControlEnable) { 6517 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 6518 int i, mc_idx; 6519 bcm_pbmp_t vlan_pbmp, vlan_ubmp, pbmp, l3_pbmp; 6520 soc_field_t group_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf}; 6521 #if defined(BCM_HGPROXY_COE_SUPPORT) 6522 bcm_port_t port_iter; 6523 int port_type; 6524 #endif 6525 /* Also need to copy the physical port members to the L2_BITMAP of 6526 * the IPMC entry for each group once we've gone virtual */ 6527 rv = mbcm_driver[unit]->mbcm_vlan_port_get 6528 (unit, vid, &vlan_pbmp, &vlan_ubmp, NULL); 6529 6530 if (rv < 0) { 6531 soc_mem_unlock(unit, VLAN_TABm); 6532 return rv; 6533 } 6534 #if defined(BCM_HGPROXY_COE_SUPPORT) 6535 /* Coe cascaded port should be removed from l2bmap of L3_IPMC. */ 6536 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, PORT_TYPEf)) { 6537 BCM_PBMP_ITER(vlan_pbmp, port_iter) { 6538 rv = _bcm_esw_port_tab_get(unit, port_iter, 6539 PORT_TYPEf, &port_type); 6540 if (rv < 0) { 6541 soc_mem_unlock(unit, VLAN_TABm); 6542 return rv; 6543 } 6544 if (port_type == _BCM_COE_PORT_TYPE_CASCADED) { 6545 BCM_PBMP_PORT_REMOVE(vlan_pbmp, port_iter); 6546 } 6547 } 6548 } 6549 #endif 6550 /* Deal with each group */ 6551 for (i = 0; i < 3; i++) { 6552 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, 6553 group_type[i]); 6554 rv = _bcm_esw_multicast_ipmc_read(unit, mc_idx, &pbmp, 6555 &l3_pbmp); 6556 if (rv < 0) { 6557 soc_mem_unlock(unit, VLAN_TABm); 6558 return rv; 6559 } 6560 6561 if (BCM_PBMP_IS_NULL(pbmp)) { 6562 rv = _bcm_esw_multicast_ipmc_write(unit, mc_idx, vlan_pbmp, 6563 l3_pbmp, TRUE); 6564 if (rv < 0) { 6565 soc_mem_unlock(unit, VLAN_TABm); 6566 return rv; 6567 } 6568 } 6569 } 6570 soc_mem_field32_set(unit, VLAN_TABm, &vt, VIRTUAL_PORT_ENf, 1); 6571 } 6572 } else if (control->vp_mc_ctrl == bcmVlanVPMcControlDisable) { 6573 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 6574 soc_mem_field32_set(unit, VLAN_TABm, &vt, VIRTUAL_PORT_ENf, 0); 6575 } 6576 } 6577 } 6578 6579 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */ 6580 6581 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6582 if (soc_feature(unit, soc_feature_vfi_from_vlan_tables)) { 6583 if (_BCM_VPN_VFI_IS_SET (control->vpn)) { 6584 int vfi_index = -1, num_vfi = -1; 6585 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, control->vpn); 6586 num_vfi = soc_mem_index_count(unit, VFIm); 6587 if (vfi_index > (num_vfi-1)) { 6588 soc_mem_unlock(unit, VLAN_TABm); 6589 return BCM_E_PARAM; 6590 } 6591 if (vfi_index && 6592 (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeAny))) { 6593 soc_mem_unlock(unit, VLAN_TABm); 6594 return BCM_E_NOT_FOUND; 6595 } 6596 if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm) && 6597 SOC_MEM_FIELD_VALID(unit, VLAN_MPLSm, VFIf)) { 6598 rv = soc_mem_field32_modify(unit, VLAN_MPLSm, vid, VFIf, vfi_index); 6599 if (BCM_FAILURE(rv)) { 6600 soc_mem_unlock(unit, VLAN_TABm); 6601 return rv; 6602 } 6603 } 6604 #if defined(BCM_TRIDENT3_SUPPORT) 6605 else if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VFIf)) { 6606 soc_mem_field32_set(unit, VLAN_TABm, &vt, VFIf, vfi_index); 6607 } 6608 #endif/* BCM_TRIDENT3_SUPPORT */ 6609 } else if (control->vpn) { 6610 soc_mem_unlock(unit, VLAN_TABm); 6611 return (BCM_E_PARAM); 6612 } 6613 } 6614 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6615 6616 #if defined(BCM_TSN_SR_SUPPORT) 6617 if (soc_feature(unit, soc_feature_tsn_sr)) { 6618 if (valid_fields & BCM_VLAN_CONTROL_VLAN_SR_FLAGS_MASK) { 6619 int i; 6620 void *entbuf; 6621 soc_mem_t mem[2] = {VLAN_TABm, EGR_VLANm}; 6622 6623 if ((!(control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_ENABLE)) && 6624 (control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_LAN_ID)) { 6625 soc_mem_unlock(unit, VLAN_TABm); 6626 return BCM_E_PARAM; 6627 } 6628 6629 for (i = 0; i < 2; i++){ 6630 if (1 == i) { 6631 /* handle egress vlan table, skip it if there is no such table */ 6632 entbuf = &evt; 6633 if(SOC_MEM_IS_VALID(unit, mem[i])){ 6634 rv = soc_mem_read(unit, mem[i], MEM_BLOCK_ANY, 6635 (int)vid, &evt); 6636 if (BCM_FAILURE(rv)) { 6637 soc_mem_unlock(unit, VLAN_TABm); 6638 return (rv); 6639 } 6640 } else { 6641 break; 6642 } 6643 } else { 6644 entbuf = &vt; 6645 } 6646 if (control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_ENABLE) { 6647 soc_mem_field32_set(unit, mem[i], entbuf, SR_ENABLEf, 1); 6648 soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_ID_VALIDf, 1); 6649 if (control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_LAN_ID) { 6650 soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_IDf, 1); 6651 } else { 6652 soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_IDf, 0); 6653 } 6654 } else { 6655 soc_mem_field32_set(unit, mem[i], entbuf, SR_ENABLEf, 0); 6656 soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_ID_VALIDf, 0); 6657 } 6658 if (1 == i) { 6659 /* handle egress vlan table */ 6660 rv = soc_mem_write(unit, mem[i], MEM_BLOCK_ANY, 6661 (int)vid, entbuf); 6662 if (BCM_FAILURE(rv)) { 6663 soc_mem_unlock(unit, VLAN_TABm); 6664 return (rv); 6665 } 6666 } 6667 } 6668 } 6669 } 6670 #endif /* BCM_TSN_SR_SUPPORT*/ 6671 6672 6673 6674 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, ENABLE_IGMP_MLD_SNOOPINGf)) { 6675 soc_mem_field32_set(unit, VLAN_TABm, &vt, ENABLE_IGMP_MLD_SNOOPINGf, 6676 (0 == (control->flags & BCM_VLAN_IGMP_SNOOP_DISABLE))); 6677 } 6678 6679 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt); 6680 soc_mem_unlock(unit, VLAN_TABm); 6681 if (BCM_SUCCESS(rv) && (pre_cfg == TRUE)) { 6682 SHR_BITSET(vlan_info[unit].pre_cfg_bmp.w,vid); 6683 } 6684 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAPTOR_SUPPORT */ 6685 return (rv); 6686 } 6687 6688 #if defined (BCM_TRX_SUPPORT) 6689 /* 6690 * Function : 6691 * _vlan_block_mask_create 6692 * 6693 * Purpose : 6694 * Compose block mask based 6695 * 6696 * Parameters: 6697 * unit - (IN) BCM device number. 6698 * first_mask - (IN) First mask. 6699 * second_mask - (IN) Second mask. 6700 * select - (IN) Mask select. 6701 * result_mask - (OUT) Output mask. 6702 * Return : 6703 * BCM_E_XXX 6704 */ 6705 int 6706 _vlan_block_mask_create(int unit, bcm_pbmp_t first_mask, 6707 bcm_pbmp_t second_mask, 6708 uint8 select, bcm_pbmp_t *result_mask) 6709 { 6710 /* Input parameters check */ 6711 if (NULL == result_mask) { 6712 return (BCM_E_PARAM); 6713 } 6714 6715 switch (select) { 6716 case 0: 6717 BCM_PBMP_CLEAR(*result_mask); 6718 break; 6719 case 1: 6720 BCM_PBMP_ASSIGN(*result_mask, first_mask); 6721 break; 6722 case 2: 6723 BCM_PBMP_ASSIGN(*result_mask, second_mask); 6724 break; 6725 case 3: 6726 BCM_PBMP_ASSIGN(*result_mask, first_mask); 6727 BCM_PBMP_OR(*result_mask, second_mask); 6728 break; 6729 default: 6730 return (BCM_E_PARAM); 6731 } 6732 return (BCM_E_NONE); 6733 } 6734 6735 /* 6736 * Function : 6737 * _bcm_trx_vlan_block_get 6738 * 6739 * Purpose : 6740 * Get vlan specific traffic blocking parameters 6741 * 6742 * Parameters: 6743 * unit - (IN) BCM device number. 6744 * vid - (IN) Vlan id. 6745 * block - (IN) Block configuration. 6746 * 6747 * Return : 6748 * BCM_E_XXX 6749 */ 6750 int 6751 _bcm_trx_vlan_block_get (int unit, bcm_vlan_t vid, bcm_vlan_block_t *block) 6752 { 6753 _trx_vlan_block_t *hw_block; /* Vlan block profile. */ 6754 int rv; /* Operation return status. */ 6755 int idx; /* Vlan profile index. */ 6756 6757 /* Input parameters check. */ 6758 if (NULL == block) { 6759 return (BCM_E_PARAM); 6760 } 6761 6762 /* Get original vlan profile. */ 6763 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 6764 NULL, vid, &idx); 6765 BCM_IF_ERROR_RETURN(rv); 6766 6767 hw_block = &VLAN_PROFILE_ENTRY(unit, idx).block; 6768 6769 rv = _vlan_block_mask_create (unit, hw_block->first_mask, 6770 hw_block->second_mask, 6771 hw_block->broadcast_mask_sel, 6772 &block->broadcast); 6773 BCM_IF_ERROR_RETURN(rv); 6774 6775 rv = _vlan_block_mask_create (unit, hw_block->first_mask, 6776 hw_block->second_mask, 6777 hw_block->unknown_unicast_mask_sel, 6778 &block->unknown_unicast); 6779 BCM_IF_ERROR_RETURN(rv); 6780 6781 rv = _vlan_block_mask_create (unit, 6782 hw_block->first_mask, 6783 hw_block->second_mask, 6784 hw_block->unknown_mulitcast_mask_sel, 6785 &block->unknown_multicast); 6786 BCM_IF_ERROR_RETURN(rv); 6787 6788 rv = _vlan_block_mask_create (unit, 6789 hw_block->first_mask, 6790 hw_block->second_mask, 6791 hw_block->known_mulitcast_mask_sel, 6792 &block->known_multicast); 6793 BCM_IF_ERROR_RETURN(rv); 6794 6795 return (BCM_E_NONE); 6796 } 6797 6798 /* Number of lookup types in bcm_vlan_block_t structure. */ 6799 #define _BCM_VLAN_BLOCK_LOOKUP_TYPES (4) 6800 6801 /* 6802 * Function : 6803 * _vlan_block_bitmap_min 6804 * 6805 * Purpose : 6806 * Find shortest bitmap. 6807 * 6808 * Parameters: 6809 * unit - (IN) BCM device number. 6810 * array - (IN) Bitmaps array. 6811 * arr_sz - (IN) Array size. 6812 * min_pbm - (OUT) Shortest bitmap. 6813 * 6814 * Return : 6815 * BCM_E_XXX 6816 */ 6817 int 6818 _vlan_block_bitmap_min(int unit, bcm_pbmp_t *array, 6819 int arr_size, bcm_pbmp_t *min_pbm) 6820 { 6821 int idx; /* Bitmaps array iteration index. */ 6822 int min; /* Mask length minimum. */ 6823 int mask_len; /* Bitmap length. */ 6824 6825 if (NULL == array) { 6826 return (BCM_E_PARAM); 6827 } 6828 BCM_PBMP_CLEAR(*min_pbm); 6829 min = 0; 6830 for (idx = 0; idx < arr_size; idx++) { 6831 6832 BCM_PBMP_COUNT(array[idx], mask_len); 6833 if (0 == mask_len) { 6834 continue; 6835 } else { 6836 if ((0 == min) || ((0 != min) && (mask_len < min))) { 6837 min = mask_len; 6838 BCM_PBMP_ASSIGN(*min_pbm, array[idx]); 6839 } 6840 } 6841 } 6842 return (BCM_E_NONE); 6843 } 6844 6845 /* 6846 * Function : 6847 * _vlan_block_bitmap_clear 6848 * 6849 * Purpose : 6850 * Clear those masks in the array that exactly match the given mask. 6851 * 6852 * Parameters: 6853 * unit - (IN) BCM device number. 6854 * array - (IN/OUT) Bitmaps array 6855 * arr_sz - (IN) Array size. 6856 * mask - (IN) Mask. 6857 * 6858 * Return : 6859 * BCM_E_XXX 6860 */ 6861 int 6862 _vlan_block_bitmap_clear(int unit, bcm_pbmp_t *array, 6863 int arr_size, bcm_pbmp_t mask) 6864 { 6865 int idx; /* Bitmaps array iteration index. */ 6866 6867 if (NULL == array) { 6868 return (BCM_E_PARAM); 6869 } 6870 6871 for (idx = 0; idx < arr_size; idx++) { 6872 if (BCM_PBMP_EQ(array[idx], mask)) { 6873 BCM_PBMP_CLEAR(array[idx]); 6874 } 6875 } 6876 return (BCM_E_NONE); 6877 } 6878 6879 /* 6880 * Function : 6881 * _vlan_block_select_get 6882 * 6883 * Purpose : 6884 * Identify block mask combination which will produce 6885 * requested block mask 6886 * Parameters: 6887 * unit - (IN) BCM device number. 6888 * req - (IN) Requested mask. 6889 * first - (IN) Bitmaps array. 6890 * second - (IN) Bitmaps array. 6891 * select - (OUT)Block mask. 6892 * Return : 6893 * BCM_E_XXX 6894 */ 6895 int 6896 _vlan_block_select_get(int unit, bcm_pbmp_t request, 6897 bcm_pbmp_t first, 6898 bcm_pbmp_t second, 6899 uint8 *sel) 6900 { 6901 bcm_pbmp_t or_mask; 6902 6903 /* Input parameters check. */ 6904 if (NULL == sel) { 6905 return (BCM_E_PARAM); 6906 } 6907 6908 if (BCM_PBMP_IS_NULL(request)) { 6909 *sel = 0; 6910 } else if (BCM_PBMP_EQ(first, request)) { 6911 *sel = 0x1; 6912 } else if (BCM_PBMP_EQ(second, request)) { 6913 *sel = 0x2; 6914 } else { 6915 BCM_PBMP_ASSIGN(or_mask, first); 6916 BCM_PBMP_OR(or_mask, second); 6917 if (BCM_PBMP_EQ(or_mask, request)) { 6918 *sel = 0x3; 6919 } else { 6920 return (BCM_E_RESOURCE); 6921 } 6922 } 6923 return (BCM_E_NONE); 6924 } 6925 6926 /* 6927 * Function : 6928 * _bcm_trx_vlan_block_set 6929 * 6930 * Purpose : 6931 * sjt vlan specific traffic blocking parameters 6932 * 6933 * Parameters: 6934 * unit - (IN) BCM device number. 6935 * vid - (IN) Vlan id. 6936 * block - (IN) Block configuration. 6937 * 6938 * Return : 6939 * BCM_E_XXX 6940 */ 6941 int 6942 _bcm_trx_vlan_block_set (int unit, bcm_vlan_t vid, bcm_vlan_block_t *block) 6943 { 6944 bcm_pbmp_t array[_BCM_VLAN_BLOCK_LOOKUP_TYPES]; 6945 _trx_vlan_block_t hw_block; /* HW block structure. */ 6946 _vlan_profile_t profile; /* Original vlan profile. */ 6947 int profile_idx; /* Profile index. */ 6948 int rv; /* Operation return status. */ 6949 6950 /* Input parameters check. */ 6951 if (NULL == block) { 6952 return (BCM_E_PARAM); 6953 } 6954 6955 /* Store block mask in a array. */ 6956 BCM_PBMP_ASSIGN(array[0], block->broadcast); 6957 BCM_PBMP_ASSIGN(array[1], block->unknown_unicast); 6958 BCM_PBMP_ASSIGN(array[2], block->unknown_multicast); 6959 BCM_PBMP_ASSIGN(array[3], block->known_multicast); 6960 6961 /* Select first shortest mask. */ 6962 6963 /* Coverity 6964 * The index coverity thinks outside of boundary is actually for 6965 * the field pbits of the pbmp structure. 6966 */ 6967 /* coverity[overrun-buffer-val: FALSE] */ 6968 rv = _vlan_block_bitmap_min(unit, array, 6969 _BCM_VLAN_BLOCK_LOOKUP_TYPES, 6970 &hw_block.first_mask); 6971 BCM_IF_ERROR_RETURN(rv); 6972 6973 /* Clear those masks in the array that exactly match the shortest mask. */ 6974 /* coverity[overrun-buffer-val: FALSE] */ 6975 rv = _vlan_block_bitmap_clear(unit, array, 6976 _BCM_VLAN_BLOCK_LOOKUP_TYPES, 6977 hw_block.first_mask); 6978 BCM_IF_ERROR_RETURN(rv); 6979 6980 /* Select second shortest mask. */ 6981 /* coverity[overrun-buffer-val: FALSE] */ 6982 rv = _vlan_block_bitmap_min(unit, array, 6983 _BCM_VLAN_BLOCK_LOOKUP_TYPES, 6984 &hw_block.second_mask); 6985 BCM_IF_ERROR_RETURN(rv); 6986 6987 6988 /* Get mask selector for each lookup type. */ 6989 rv = _vlan_block_select_get(unit, block->broadcast, hw_block.first_mask, 6990 hw_block.second_mask, &hw_block.broadcast_mask_sel); 6991 BCM_IF_ERROR_RETURN(rv); 6992 6993 rv = _vlan_block_select_get(unit, block->unknown_unicast, hw_block.first_mask, 6994 hw_block.second_mask, &hw_block.unknown_unicast_mask_sel); 6995 BCM_IF_ERROR_RETURN(rv); 6996 6997 rv = _vlan_block_select_get(unit, block->unknown_multicast, hw_block.first_mask, 6998 hw_block.second_mask, &hw_block.unknown_mulitcast_mask_sel); 6999 BCM_IF_ERROR_RETURN(rv); 7000 7001 rv = _vlan_block_select_get(unit, block->known_multicast, hw_block.first_mask, 7002 hw_block.second_mask, &hw_block.known_mulitcast_mask_sel); 7003 BCM_IF_ERROR_RETURN(rv); 7004 7005 /* Get original vlan profile. */ 7006 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, 7007 NULL, vid, &profile_idx); 7008 BCM_IF_ERROR_RETURN(rv); 7009 7010 profile = VLAN_PROFILE_ENTRY(unit, profile_idx); 7011 profile.block = hw_block; 7012 7013 /* Update vlan profile. */ 7014 rv = _vlan_profile_update(unit, vid, &profile); 7015 BCM_IF_ERROR_RETURN(rv); 7016 7017 return (BCM_E_NONE); 7018 } 7019 7020 #endif /* BCM_TRX_SUPPORT */ 7021 7022 #ifdef BCM_TRIUMPH2_SUPPORT 7023 /* 7024 * Function: 7025 * _bcm_tr2_vlan_qmid_set 7026 * Purpose: 7027 * Set vlan queue mapping pointer in vlan profile table 7028 * Parameters: 7029 * unit device number 7030 * vlan vlan idenetifier 7031 * qm_ptr queue mapping identifier (use -1 to disable) 7032 * use_inner_tag use priority from inner tag 7033 * Return: 7034 * BCM_E_XXX 7035 */ 7036 int 7037 _bcm_tr2_vlan_qmid_set(int unit, bcm_vlan_t vlan, int qmid, 7038 int use_inner_tag) 7039 { 7040 _vlan_profile_t profile; 7041 int profile_idx; 7042 uint32 profile_flags; 7043 7044 BCM_IF_ERROR_RETURN 7045 (_vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL, 7046 vlan, &profile_idx)); 7047 7048 profile = VLAN_PROFILE_ENTRY(unit, profile_idx); 7049 profile_flags = profile.profile_flags; 7050 profile_flags &= ~(_BCM_VLAN_PROFILE_PHB2_ENABLE | 7051 _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG); 7052 if (qmid >= 0) { 7053 profile_flags |= _BCM_VLAN_PROFILE_PHB2_ENABLE; 7054 } else { 7055 qmid = 0; 7056 } 7057 if (use_inner_tag) { 7058 profile_flags |= _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG; 7059 } 7060 7061 if (profile.qm_ptr == qmid && profile.profile_flags == profile_flags) { 7062 return BCM_E_NONE; 7063 } 7064 7065 profile.profile_flags = profile_flags; 7066 profile.qm_ptr = qmid; 7067 BCM_IF_ERROR_RETURN(_vlan_profile_update(unit, vlan, &profile)); 7068 7069 return BCM_E_NONE; 7070 } 7071 7072 /* 7073 * Function: 7074 * _bcm_tr2_vlan_qmid_get 7075 * Purpose: 7076 * get vlan queue mapping pointer in vlan profile table 7077 * Parameters: 7078 * unit device number 7079 * vlan vlan idenetifier 7080 * qm_ptr (OUT) queue mapping identifier (use -1 to disable) 7081 * use_inner_tag (OUT) use priority from inner tag 7082 * Return: 7083 * BCM_E_XXX 7084 */ 7085 int 7086 _bcm_tr2_vlan_qmid_get(int unit, bcm_vlan_t vlan, int *qmid, 7087 int *use_inner_tag) 7088 { 7089 _vlan_profile_t profile; 7090 int profile_idx; 7091 7092 if (qmid == NULL || use_inner_tag == NULL) { 7093 return BCM_E_PARAM; 7094 } 7095 7096 BCM_IF_ERROR_RETURN 7097 (_vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL, 7098 vlan, &profile_idx)); 7099 7100 profile = VLAN_PROFILE_ENTRY(unit, profile_idx); 7101 if (profile.profile_flags & _BCM_VLAN_PROFILE_PHB2_ENABLE) { 7102 *qmid = profile.qm_ptr; 7103 } else { 7104 *qmid = -1; 7105 return BCM_E_NOT_FOUND; 7106 } 7107 if (profile.profile_flags & _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG) { 7108 *use_inner_tag = 1; 7109 } else { 7110 *use_inner_tag = 0; 7111 } 7112 7113 return BCM_E_NONE; 7114 } 7115 7116 /* 7117 * Function: 7118 * _bcm_tr2_qos_pvmid_set 7119 * Purpose: 7120 * Set vlan port vlan mapping pointer in vlan profile table 7121 * Parameters: 7122 * unit device number 7123 * vlan vlan idenetifier 7124 * pvm_ptr port vlan mapping identifier (use -1 to disable) 7125 * Return: 7126 * BCM_E_XXX 7127 */ 7128 int 7129 _bcm_tr2_qos_pvmid_set(int unit, bcm_vlan_t vlan, int pvmid) 7130 { 7131 int rv; 7132 _vlan_profile_t profile; 7133 int profile_idx; 7134 uint32 profile_flags; 7135 7136 soc_mem_lock(unit, VLAN_TABm); 7137 7138 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL, 7139 vlan, &profile_idx); 7140 if (BCM_FAILURE(rv)) { 7141 soc_mem_unlock(unit, VLAN_TABm); 7142 return rv; 7143 } 7144 7145 profile = VLAN_PROFILE_ENTRY(unit, profile_idx); 7146 profile_flags = profile.profile_flags; 7147 profile_flags &= ~_BCM_VLAN_PROFILE_TRUST_DOT1P; 7148 if (pvmid >= 0) { 7149 profile_flags |= _BCM_VLAN_PROFILE_TRUST_DOT1P; 7150 } else { 7151 pvmid = 0; 7152 } 7153 7154 if (profile.trust_dot1p_ptr == pvmid && 7155 profile.profile_flags == profile_flags) { 7156 soc_mem_unlock(unit, VLAN_TABm); 7157 return BCM_E_NONE; 7158 } 7159 7160 profile.profile_flags = profile_flags; 7161 profile.trust_dot1p_ptr = pvmid; 7162 7163 rv = _vlan_profile_update(unit, vlan, &profile); 7164 7165 soc_mem_unlock(unit, VLAN_TABm); 7166 7167 return rv; 7168 } 7169 7170 /* 7171 * Function: 7172 * _bcm_tr2_qos_pvmid_get 7173 * Purpose: 7174 * get vlan port vlan mapping pointer in vlan profile table 7175 * Parameters: 7176 * unit device number 7177 * vlan vlan idenetifier 7178 * pvm_ptr (OUT) port vlan mapping identifier (use -1 to disable) 7179 * Return: 7180 * BCM_E_XXX 7181 */ 7182 int 7183 _bcm_tr2_qos_pvmid_get(int unit, bcm_vlan_t vlan, int *pvmid) 7184 { 7185 int rv; 7186 _vlan_profile_t profile; 7187 int profile_idx; 7188 7189 if (pvmid == NULL) { 7190 return BCM_E_PARAM; 7191 } 7192 7193 soc_mem_lock(unit, VLAN_TABm); 7194 7195 rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL, 7196 vlan, &profile_idx); 7197 if (BCM_FAILURE(rv)) { 7198 soc_mem_unlock(unit, VLAN_TABm); 7199 return rv; 7200 } 7201 7202 profile = VLAN_PROFILE_ENTRY(unit, profile_idx); 7203 if (profile.profile_flags & _BCM_VLAN_PROFILE_TRUST_DOT1P) { 7204 *pvmid = profile.trust_dot1p_ptr; 7205 } else { 7206 *pvmid = -1; 7207 } 7208 7209 soc_mem_unlock(unit, VLAN_TABm); 7210 7211 return BCM_E_NONE; 7212 } 7213 #endif /* BCM_TRIUMPH2_SUPPORT */ 7214 7215 /* 7216 * Function: 7217 * _bcm_fb_vlan_translate_add 7218 * Purpose: 7219 * Helper function to bcm_esw_vlan_translate_add to add vlan translation 7220 * for Firebolt 7221 * Parameters: 7222 * unit - StrataSwitch PCI device unit number (driver internal). 7223 * port - port numebr 7224 * old_vid - Old VLAN ID to has translation for 7225 * new_vid - New VLAN ID that packet will get 7226 * prio - Priority 7227 * xtable - Memory to use for Firebolt 7228 * Returns: 7229 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 7230 * BCM_E_NOT_FOUND - Translation does not exist 7231 * BCM_E_XXX - Other error 7232 * Notes: 7233 * None. 7234 */ 7235 int 7236 _bcm_fb_vlan_translate_add(int unit, int port, bcm_vlan_t old_vid, 7237 bcm_vlan_t new_vid, int prio, 7238 int xtable) 7239 { 7240 vlan_xlate_entry_t vtent; 7241 int index_min, index_max; 7242 soc_mem_t mem; 7243 int addvid; 7244 uint32 *vtcachep, vtcache; 7245 uint32 ve_valid, ve_port, ve_vid, ve_add; 7246 int empty, match, slot, i, rv; 7247 7248 if (!soc_feature(unit, soc_feature_vlan_translation)) { 7249 return BCM_E_UNAVAIL; 7250 } 7251 7252 switch (xtable) { 7253 case BCM_VLAN_XLATE_ING: 7254 mem = VLAN_XLATEm; 7255 addvid = 0; 7256 break; 7257 case BCM_VLAN_XLATE_EGR: 7258 mem = EGR_VLAN_XLATEm; 7259 addvid = -1; 7260 break; 7261 case BCM_VLAN_XLATE_DTAG: 7262 mem = VLAN_XLATEm; 7263 addvid = 1; 7264 break; 7265 default: 7266 return BCM_E_INTERNAL; 7267 } 7268 7269 if (((port < 0) || (old_vid == BCM_VLAN_NONE)) && port != -1) { 7270 return BCM_E_PARAM; 7271 } 7272 7273 #ifdef BCM_KATANA2_SUPPORT 7274 if ((port != -1) && ((soc_feature(unit, soc_feature_linkphy_coe) && 7275 BCM_PBMP_MEMBER (SOC_INFO(unit).linkphy_pp_port_pbm, port)) || 7276 (soc_feature(unit, soc_feature_subtag_coe) && 7277 BCM_PBMP_MEMBER (SOC_INFO(unit).subtag_pp_port_pbm, port)))) { 7278 } else 7279 #endif 7280 if (port >= 0 && !SOC_PORT_VALID(unit, port)) { 7281 return BCM_E_PORT; 7282 } 7283 7284 if ((prio != -1) && ((prio & ~BCM_PRIO_MASK) != 0)) { 7285 return BCM_E_PARAM; 7286 } 7287 7288 index_min = soc_mem_index_min(unit, mem); 7289 index_max = soc_mem_index_max(unit, mem); 7290 7291 soc_mem_lock(unit, mem); 7292 7293 /* get vt cache, allocate if necessary */ 7294 if (mem == EGR_VLAN_XLATEm) { 7295 vtcachep = vlan_info[unit].egr_trans; 7296 } else { 7297 vtcachep = vlan_info[unit].ing_trans; 7298 } 7299 if (vtcachep == NULL) { 7300 vtcachep = sal_alloc(sizeof(*vtcachep) * (index_max+1), 7301 "vlan trans cache"); 7302 if (vtcachep == NULL) { 7303 soc_mem_unlock(unit, mem); 7304 return BCM_E_MEMORY; 7305 } 7306 sal_memset(vtcachep, 0, sizeof(*vtcachep) * (index_max+1)); 7307 if (mem == EGR_VLAN_XLATEm) { 7308 vlan_info[unit].egr_trans = vtcachep; 7309 } else { 7310 vlan_info[unit].ing_trans = vtcachep; 7311 } 7312 } 7313 7314 /* search vt cache for match */ 7315 match = empty = -1; 7316 for (i = index_min; i <= index_max; i++) { 7317 vtcache = vtcachep[i]; 7318 ve_valid = BCM_VTCACHE_VALID_GET(vtcache); 7319 if (empty < 0 && !ve_valid) { 7320 empty = i; 7321 } 7322 ve_port = BCM_VTCACHE_PORT_GET(vtcache); 7323 if ((int)ve_port != port) { 7324 continue; 7325 } 7326 ve_vid = BCM_VTCACHE_VID_GET(vtcache); 7327 if (ve_vid != old_vid) { 7328 continue; 7329 } 7330 if (addvid >= 0) { 7331 ve_add = BCM_VTCACHE_ADD_GET(vtcache); 7332 if ((int)ve_add != addvid) { 7333 soc_mem_unlock(unit, mem); 7334 return BCM_E_EXISTS; 7335 } 7336 } 7337 match = i; 7338 break; 7339 } 7340 7341 if (match != -1) { 7342 slot = match; 7343 } else if (empty != -1) { 7344 slot = empty; 7345 } else { 7346 soc_mem_unlock(unit, mem); 7347 return BCM_E_FULL; 7348 } 7349 7350 sal_memset(&vtent, 0, sizeof(vtent)); 7351 7352 soc_mem_field32_set(unit, mem, &vtent, VALIDf, 1); 7353 if (port == -1) { 7354 soc_mem_field32_set(unit, mem, &vtent, PORTf, 0); 7355 } else { 7356 soc_mem_field32_set(unit, mem, &vtent, PORTf, port); 7357 } 7358 soc_mem_field32_set(unit, mem, &vtent, OLD_VLAN_IDf, old_vid); 7359 soc_mem_field32_set(unit, mem, &vtent, NEW_VLAN_IDf, new_vid); 7360 if (soc_mem_field_valid(unit, mem, MASKf)) { 7361 if (port == -1) { 7362 if (mem == VLAN_XLATEm) { 7363 soc_mem_field32_set(unit, mem, &vtent, MASKf, 0x1ffe0); 7364 } else { /* mem == EGR_VLAN_XLATEm */ 7365 soc_mem_field32_set(unit, mem, &vtent, MASKf, 0xfff); 7366 } 7367 } else { 7368 soc_mem_field32_set(unit, mem, &vtent, MASKf, 7369 (1 << soc_mem_field_length(unit, mem, MASKf)) - 1); 7370 } 7371 } 7372 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 7373 if (soc_mem_field_valid(unit, mem, RESERVED_MASKf)) { 7374 soc_mem_field32_set(unit, mem, &vtent, RESERVED_MASKf, 0); 7375 } 7376 if (soc_mem_field_valid(unit, mem, RESERVED_DATAf)) { 7377 soc_mem_field32_set(unit, mem, &vtent, RESERVED_DATAf, 0); 7378 } 7379 if (soc_mem_field_valid(unit, mem, RESERVED_KEYf)) { 7380 soc_mem_field32_set(unit, mem, &vtent, RESERVED_KEYf, 0); 7381 } 7382 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 7383 7384 if (prio >= 0) { 7385 soc_mem_field32_set(unit, mem, &vtent, RPEf, 1); 7386 soc_mem_field32_set(unit, mem, &vtent, PRIf, prio); 7387 } 7388 if (addvid >= 0) { 7389 soc_mem_field32_set(unit, mem, &vtent, ADD_VIDf, addvid); 7390 } 7391 7392 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, &vtent); 7393 if (rv >= 0) { 7394 vtcache = 0; 7395 BCM_VTCACHE_VALID_SET(vtcache, 1); 7396 BCM_VTCACHE_PORT_SET(vtcache, port); 7397 BCM_VTCACHE_VID_SET(vtcache, old_vid); 7398 if (addvid >= 0) { 7399 BCM_VTCACHE_ADD_SET(vtcache, addvid); 7400 } 7401 vtcachep[slot] = vtcache; 7402 } 7403 soc_mem_unlock(unit, mem); 7404 return rv; 7405 } 7406 7407 /* 7408 * Function: 7409 * _bcm_fb_vlan_translate_delete 7410 * Purpose: 7411 * Helper function to bcm_esw_vlan_translate_delete to delete vlan 7412 * translation for Firebolt family 7413 * Parameters: 7414 * unit - StrataSwitch PCI device unit number (driver internal). 7415 * port - port numebr can be wildcarded (port = -1) 7416 * old_vid - Old VLAN ID to delete translation for can be wildcarded (old_vid = BCM_VLAN_NONE) 7417 * xtable - Memory table 7418 * Returns: 7419 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 7420 * BCM_E_NOT_FOUND - Translation does not exist 7421 * BCM_E_XXX - Other error 7422 * Notes: 7423 * None. 7424 */ 7425 int 7426 _bcm_fb_vlan_translate_delete(int unit, int port, bcm_vlan_t old_vid, 7427 int xtable) 7428 { 7429 soc_mem_t mem; 7430 int addvid, index_min, index_max, rv; 7431 int nmatch, nwrongadd, i; 7432 vlan_xlate_entry_t vtempty; 7433 uint32 *vtcachep, vtcache; 7434 uint32 ve_valid, ve_port, ve_vid, ve_add; 7435 7436 if (!soc_feature(unit, soc_feature_vlan_translation)) { 7437 return BCM_E_UNAVAIL; 7438 } 7439 7440 switch (xtable) { 7441 case BCM_VLAN_XLATE_ING: 7442 mem = VLAN_XLATEm; 7443 addvid = 0; 7444 break; 7445 case BCM_VLAN_XLATE_EGR: 7446 mem = EGR_VLAN_XLATEm; 7447 addvid = -1; 7448 break; 7449 case BCM_VLAN_XLATE_DTAG: 7450 mem = VLAN_XLATEm; 7451 addvid = 1; 7452 break; 7453 default: 7454 return BCM_E_INTERNAL; 7455 } 7456 7457 #ifdef BCM_KATANA2_SUPPORT 7458 if ((soc_feature(unit, soc_feature_linkphy_coe) && 7459 BCM_PBMP_MEMBER (SOC_INFO(unit).linkphy_pp_port_pbm, port)) || 7460 (soc_feature(unit, soc_feature_subtag_coe) && 7461 BCM_PBMP_MEMBER (SOC_INFO(unit).subtag_pp_port_pbm, port))) { 7462 } else 7463 #endif 7464 if (port >= 0 && !SOC_PORT_VALID(unit, port)) { 7465 return BCM_E_PORT; 7466 } 7467 7468 soc_mem_lock(unit, mem); 7469 7470 /* get vt cache */ 7471 if (mem == EGR_VLAN_XLATEm) { 7472 vtcachep = vlan_info[unit].egr_trans; 7473 } else { 7474 vtcachep = vlan_info[unit].ing_trans; 7475 } 7476 if (vtcachep == NULL) { /* vt cache empty */ 7477 soc_mem_unlock(unit, mem); 7478 return BCM_E_NOT_FOUND; 7479 } 7480 7481 index_min = soc_mem_index_min(unit, mem); 7482 index_max = soc_mem_index_max(unit, mem); 7483 rv = BCM_E_NOT_FOUND; 7484 sal_memset(&vtempty, 0, sizeof(vtempty)); 7485 7486 /* search vt cache for matches */ 7487 nmatch = nwrongadd = 0; 7488 for (i = index_min; i <= index_max; i++) { 7489 vtcache = vtcachep[i]; 7490 ve_valid = BCM_VTCACHE_VALID_GET(vtcache); 7491 if (!ve_valid) { 7492 continue; 7493 } 7494 if (port >= 0) { 7495 ve_port = BCM_VTCACHE_PORT_GET(vtcache); 7496 if ((int)ve_port != port) { 7497 continue; 7498 } 7499 } 7500 if (old_vid != BCM_VLAN_NONE) { 7501 ve_vid = BCM_VTCACHE_VID_GET(vtcache); 7502 if (ve_vid != old_vid) { 7503 continue; 7504 } 7505 } 7506 if (addvid >= 0) { 7507 ve_add = BCM_VTCACHE_ADD_GET(vtcache); 7508 if ((int)ve_add != addvid) { 7509 nwrongadd += 1; 7510 continue; 7511 } 7512 } 7513 7514 /* matched entry, delete it */ 7515 nmatch += 1; 7516 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, i, &vtempty); 7517 if (rv < 0) { 7518 break; 7519 } 7520 vtcachep[i] = 0; 7521 } 7522 7523 soc_mem_unlock(unit, mem); 7524 if (nmatch == 0 && nwrongadd == 1 && 7525 port >= 0 && old_vid != BCM_VLAN_NONE) { 7526 rv = BCM_E_EXISTS; /* specific delete that only missed addvid */ 7527 } 7528 return rv; 7529 } 7530 7531 /* 7532 * Function: 7533 * _bcm_fb_vlan_translate_delete 7534 * Purpose: 7535 * Helper function to bcm_esw_vlan_translate_delete to delete vlan 7536 * translation for Firebolt family 7537 * Parameters: 7538 * unit - StrataSwitch PCI device unit number (driver internal). 7539 * port - port numebr can be wildcarded (port = -1) 7540 * old_vid - Old VLAN ID to delete translation for can be wildcarded (old_vid = BCM_VLAN_NONE) 7541 * xtable - Memory table 7542 * Returns: 7543 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 7544 * BCM_E_NOT_FOUND - Translation does not exist 7545 * BCM_E_XXX - Other error 7546 * Notes: 7547 * None. 7548 */ 7549 STATIC int 7550 _bcm_fb_vlan_translate_get_cb(int unit, void *trvs_info, int *stop) 7551 { 7552 7553 _bcm_vlan_translate_data_t *get_info; 7554 _bcm_vlan_translate_traverse_t *trvs_str; 7555 bcm_vlan_t old_vlan, new_vlan; 7556 bcm_port_t port; 7557 bcm_module_t modid; 7558 bcm_trunk_t trunk; 7559 int id; 7560 7561 if ((NULL == trvs_info) || (NULL == stop)){ 7562 return BCM_E_PARAM; 7563 } 7564 trvs_str = (_bcm_vlan_translate_traverse_t *)trvs_info; 7565 if (BCM_VLAN_INVALID != trvs_str->outer_vlan) { 7566 old_vlan = trvs_str->outer_vlan; 7567 } else { 7568 old_vlan = trvs_str->inner_vlan; 7569 } 7570 7571 if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) { 7572 new_vlan = trvs_str->action->new_outer_vlan; 7573 } else { 7574 new_vlan = trvs_str->action->new_inner_vlan; 7575 } 7576 7577 get_info = (_bcm_vlan_translate_data_t *)trvs_str->user_data; 7578 7579 BCM_IF_ERROR_RETURN( 7580 _bcm_esw_gport_resolve(unit, trvs_str->gport, &modid, &port, 7581 &trunk, &id)); 7582 7583 if ((port == get_info->port) && (old_vlan == get_info->old_vlan)) { 7584 *(get_info->new_vlan) = new_vlan; 7585 *(get_info->prio) = trvs_str->action->priority; 7586 *stop = TRUE; 7587 } else { 7588 *stop = FALSE; 7589 } 7590 return (BCM_E_NONE); 7591 } 7592 7593 /* 7594 * Function: 7595 * _bcm_fb_vlan_translate_delete 7596 * Purpose: 7597 * Helper function to bcm_esw_vlan_translate_delete to delete vlan 7598 * translation for Firebolt family 7599 * Parameters: 7600 * unit - StrataSwitch PCI device unit number (driver internal). 7601 * port - port numebr can be wildcarded (port = -1) 7602 * old_vid - Old VLAN ID to delete translation for can be wildcarded (old_vid = BCM_VLAN_NONE) 7603 * xtable - Memory table 7604 * Returns: 7605 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 7606 * BCM_E_NOT_FOUND - Translation does not exist 7607 * BCM_E_XXX - Other error 7608 * Notes: 7609 * None. 7610 */ 7611 int 7612 _bcm_fb_vlan_translate_get(int unit, int port, bcm_vlan_t old_vid, 7613 bcm_vlan_t *new_vid, int *prio, int xtable) 7614 { 7615 _bcm_vlan_translate_data_t get_info; 7616 _bcm_vlan_translate_traverse_t trvs_st; 7617 bcm_vlan_action_set_t action; 7618 soc_mem_t mem; 7619 bcm_vlan_t new_vlan; 7620 int priority; 7621 7622 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 7623 return BCM_E_PORT; 7624 } 7625 if (!soc_feature(unit, soc_feature_vlan_translation)) { 7626 return BCM_E_UNAVAIL; 7627 } 7628 7629 if ((NULL == new_vid) || (NULL == prio)){ 7630 return BCM_E_PARAM; 7631 } 7632 7633 sal_memset(&get_info, 0, sizeof(_bcm_vlan_translate_data_t)); 7634 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 7635 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 7636 7637 new_vlan = BCM_VLAN_INVALID; 7638 priority = -1; 7639 get_info.old_vlan = old_vid; 7640 get_info.port = port; 7641 get_info.new_vlan = &new_vlan; 7642 get_info.prio = &priority; 7643 7644 trvs_st.user_data = (void *)&get_info; 7645 trvs_st.action = &action; 7646 trvs_st.user_cb_st = NULL; 7647 trvs_st.int_cb = _bcm_fb_vlan_translate_get_cb; 7648 7649 switch (xtable) { 7650 case BCM_VLAN_XLATE_ING: 7651 mem = VLAN_XLATEm; 7652 break; 7653 case BCM_VLAN_XLATE_EGR: 7654 mem = EGR_VLAN_XLATEm; 7655 break; 7656 case BCM_VLAN_XLATE_DTAG: 7657 mem = VLAN_XLATEm; 7658 break; 7659 default: 7660 return BCM_E_INTERNAL; 7661 } 7662 7663 BCM_IF_ERROR_RETURN( 7664 _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st)); 7665 if ((BCM_VLAN_INVALID != new_vlan) && (-1 != priority) ){ 7666 *new_vid = new_vlan; 7667 *prio = priority; 7668 return BCM_E_NONE; 7669 } 7670 7671 return BCM_E_NOT_FOUND; 7672 } 7673 7674 7675 /* 7676 * Function : 7677 * _bcm_fb_vlan_translate_parse 7678 * Description : 7679 * Helper function for an API to parse a vlan translate 7680 * entry for Firebolt and call given call back. 7681 * Parameters : 7682 * unit (IN) BCM unit number 7683 * trvs_info (IN/OUT) Traverse structure that contain all relevant info 7684 */ 7685 int 7686 _bcm_fb_vlan_translate_parse(int unit, soc_mem_t mem, uint32* vent, 7687 _bcm_vlan_translate_traverse_t *trvs_info) 7688 { 7689 bcm_port_t port; 7690 int rv = BCM_E_UNAVAIL; 7691 7692 if (!soc_feature(unit, soc_feature_vlan_translation)) { 7693 return rv; 7694 } 7695 7696 port = soc_mem_field32_get(unit, mem , vent, PORTf); 7697 rv = bcm_esw_port_gport_get(unit, port, &(trvs_info->gport)); 7698 BCM_IF_ERROR_RETURN(rv); 7699 7700 trvs_info->outer_vlan = soc_mem_field32_get(unit, mem, vent, OLD_VLAN_IDf); 7701 trvs_info->action->new_outer_vlan = soc_mem_field32_get(unit, mem, vent, 7702 NEW_VLAN_IDf); 7703 trvs_info->action->priority = soc_mem_field32_get(unit, mem, vent, PRIf); 7704 return (rv); 7705 } 7706 7707 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 7708 || defined(BCM_RAPTOR_SUPPORT) 7709 #ifndef BCM_SW_STATE_DUMP_DISABLE 7710 void _bcm_fb2_vlan_profile_sw_dump(int unit) 7711 { 7712 int index; 7713 int index_max; 7714 int outer_tpid, flags; 7715 int ip4_mcast_mode, ip6_mcast_mode, l2_mcast_mode, ref_count; 7716 int outer_tpid_entry, outer_tpid_ref_count; 7717 7718 LOG_CLI((BSL_META_U(unit, 7719 "\nSW Information VLAN Profile - Unit %d\n"), unit)); 7720 7721 index_max = soc_mem_index_max(unit, VLAN_PROFILE_TABm); 7722 for (index = 0; index <= index_max; index++) { 7723 outer_tpid = VLAN_PROFILE_ENTRY(unit, index).outer_tpid; 7724 flags = VLAN_PROFILE_ENTRY(unit, index).flags; 7725 ip6_mcast_mode = VLAN_PROFILE_ENTRY(unit, index).ip6_mcast_flood_mode; 7726 ip4_mcast_mode = VLAN_PROFILE_ENTRY(unit, index).ip4_mcast_flood_mode; 7727 l2_mcast_mode = VLAN_PROFILE_ENTRY(unit, index).l2_mcast_flood_mode; 7728 ref_count = VLAN_PROFILE_REF_COUNT (unit, index); 7729 7730 if (outer_tpid == 0 && flags == 0 && 7731 ip6_mcast_mode == 0 && ip4_mcast_mode == 0 && 7732 l2_mcast_mode == 0 && ref_count == 0) { 7733 continue; 7734 } 7735 LOG_CLI((BSL_META_U(unit, " Index = 0x%x, "), index)); 7736 LOG_CLI((BSL_META_U(unit, " TPID = 0x%x, "), outer_tpid)); 7737 LOG_CLI((BSL_META_U(unit, " Flags = 0x%x, "), flags)); 7738 LOG_CLI((BSL_META_U(unit, " IP6 PFM = 0x%x, "), ip6_mcast_mode)); 7739 LOG_CLI((BSL_META_U(unit, " IP4 PFM = 0x%x, "), ip4_mcast_mode)); 7740 LOG_CLI((BSL_META_U(unit, " L2 PFM = 0x%x, "), l2_mcast_mode)); 7741 LOG_CLI((BSL_META_U(unit, " Ref count = %d\n"), ref_count)); 7742 } 7743 7744 LOG_CLI((BSL_META_U(unit, 7745 "\nSW Information outer TPIDs - Unit %d\n"), unit)); 7746 7747 for (index = 0; index < BCM_MAX_TPID_ENTRIES; index++) { 7748 outer_tpid_entry = OUTER_TPID_ENTRY(unit, index); 7749 outer_tpid_ref_count = OUTER_TPID_REF_COUNT(unit, index); 7750 7751 if (outer_tpid_entry == 0 && 7752 outer_tpid_ref_count == 0) { 7753 continue; 7754 } 7755 7756 LOG_CLI((BSL_META_U(unit, " Index = 0x%x, "), index)); 7757 LOG_CLI((BSL_META_U(unit, " TPID = 0x%x, "), outer_tpid_entry)); 7758 LOG_CLI((BSL_META_U(unit, " Ref count = %d\n"), outer_tpid_ref_count)); 7759 } 7760 } 7761 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 7762 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \ 7763 || BCM_RAPTOR_SUPPORT */