vlan.c (187173B)
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: Handle trident2plus specific vlan features: 9 * Manages VFI VLAN membership tables. 10 */ 11 12 #include <soc/defs.h> 13 #include <soc/field.h> 14 #include <sal/core/libc.h> 15 #include <shared/bsl.h> 16 17 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 18 19 #include <soc/mem.h> 20 #include <soc/hash.h> 21 #include <soc/ptable.h> 22 #include <soc/drv.h> 23 #include <soc/td2_td2p.h> 24 #include <soc/mcm/memacc.h> 25 #include <bcm/error.h> 26 #include <bcm/port.h> 27 28 #include <bcm_int/api_xlate_port.h> 29 #include <bcm_int/esw/trident2plus.h> 30 #include <bcm_int/esw/trident.h> 31 #include <bcm_int/esw/trx.h> 32 #include <bcm_int/esw/triumph3.h> 33 #include <bcm_int/esw/triumph2.h> 34 #include <bcm_int/common/multicast.h> 35 #include <bcm_int/esw/trunk.h> 36 #include <bcm_int/esw/port.h> 37 #include <bcm_int/esw/ipmc.h> 38 #include <bcm_int/esw/virtual.h> 39 #if defined(BCM_TRIDENT3_SUPPORT) 40 #include <bcm_int/esw/trident3.h> 41 #endif 42 43 #define BCMI_MAX_COE_MODULE_ID 255 44 #define BCMI_NUM_PORTS_PER_COE_MODULE 128 45 46 #define BCMI_VP_GROUP_VP_OFFSET ((BCMI_MAX_COE_MODULE_ID * \ 47 BCMI_NUM_PORTS_PER_COE_MODULE) - 1) 48 49 #define BCMI_VP_GROUP_GLP_COUNT ((BCMI_MAX_COE_MODULE_ID * \ 50 BCMI_NUM_PORTS_PER_COE_MODULE)) 51 52 #define BCMI_VP_GROUP_GLP_MODID_SHIFT 7 53 #define BCMI_VP_GROUP_GLP_MODID_MASK 0xff 54 #define BCMI_VP_GROUP_GLP_PORT_SHIFT 0 55 #define BCMI_VP_GROUP_GLP_PORT_MASK 0x7f 56 57 #define BCMI_VP_GROUP_SUBPORT_MODID_GET(_gport) \ 58 (((_gport) >> BCMI_VP_GROUP_GLP_MODID_SHIFT) & \ 59 BCMI_VP_GROUP_GLP_MODID_MASK) 60 61 #define BCMI_VP_GROUP_SUBPORT_PORT_GET(_gport) \ 62 (((_gport) >> BCMI_VP_GROUP_GLP_PORT_SHIFT) & \ 63 BCMI_VP_GROUP_GLP_PORT_MASK) 64 65 #define VP_FILTER_DISABLE 0 66 #define VP_FILTER_VP_GRP_BMAP 1 67 #define VP_FILTER_HASH 2 68 #define VP_DO_NOT_CHECK 3 69 70 #define GPP_FILTER_DISABLE 0 71 #define GPP_FILTER_ING_PORT 1 72 #define GPP_FILTER_HASH 2 73 #define GPP_FILTER_VP_GRP_BMAP 3 74 75 #define _BCM_DEFAULT_STP_STATE 0 /* Disabled */ 76 #define _BCM_DEFAULT_UNTAGGED_STATE 0 77 78 #define _BCM_INVALID_STG -1 79 #define _BCM_INVALID_VP_GROUP -1 80 #define _BCM_INVALID_VFI_PROFILE -1 81 82 #define BCM_MN_VPN_MAX 2047 83 #define BCM_MN_VPN_COUNT (BCM_MN_VPN_MAX - BCM_VPN_MIN + 1) 84 85 STATIC soc_field_t _bcm_vp_group_stp_field[64] = { 86 SP_TREE_VP_GRP0f, 87 SP_TREE_VP_GRP1f, 88 SP_TREE_VP_GRP2f, 89 SP_TREE_VP_GRP3f, 90 SP_TREE_VP_GRP4f, 91 SP_TREE_VP_GRP5f, 92 SP_TREE_VP_GRP6f, 93 SP_TREE_VP_GRP7f, 94 SP_TREE_VP_GRP8f, 95 SP_TREE_VP_GRP9f, 96 SP_TREE_VP_GRP10f, 97 SP_TREE_VP_GRP11f, 98 SP_TREE_VP_GRP12f, 99 SP_TREE_VP_GRP13f, 100 SP_TREE_VP_GRP14f, 101 SP_TREE_VP_GRP15f, 102 SP_TREE_VP_GRP16f, 103 SP_TREE_VP_GRP17f, 104 SP_TREE_VP_GRP18f, 105 SP_TREE_VP_GRP19f, 106 SP_TREE_VP_GRP20f, 107 SP_TREE_VP_GRP21f, 108 SP_TREE_VP_GRP22f, 109 SP_TREE_VP_GRP23f, 110 SP_TREE_VP_GRP24f, 111 SP_TREE_VP_GRP25f, 112 SP_TREE_VP_GRP26f, 113 SP_TREE_VP_GRP27f, 114 SP_TREE_VP_GRP28f, 115 SP_TREE_VP_GRP29f, 116 SP_TREE_VP_GRP30f, 117 SP_TREE_VP_GRP31f, 118 SP_TREE_VP_GRP32f, 119 SP_TREE_VP_GRP33f, 120 SP_TREE_VP_GRP34f, 121 SP_TREE_VP_GRP35f, 122 SP_TREE_VP_GRP36f, 123 SP_TREE_VP_GRP37f, 124 SP_TREE_VP_GRP38f, 125 SP_TREE_VP_GRP39f, 126 SP_TREE_VP_GRP40f, 127 SP_TREE_VP_GRP41f, 128 SP_TREE_VP_GRP42f, 129 SP_TREE_VP_GRP43f, 130 SP_TREE_VP_GRP44f, 131 SP_TREE_VP_GRP45f, 132 SP_TREE_VP_GRP46f, 133 SP_TREE_VP_GRP47f, 134 SP_TREE_VP_GRP48f, 135 SP_TREE_VP_GRP49f, 136 SP_TREE_VP_GRP50f, 137 SP_TREE_VP_GRP51f, 138 SP_TREE_VP_GRP52f, 139 SP_TREE_VP_GRP53f, 140 SP_TREE_VP_GRP54f, 141 SP_TREE_VP_GRP55f, 142 SP_TREE_VP_GRP56f, 143 SP_TREE_VP_GRP57f, 144 SP_TREE_VP_GRP58f, 145 SP_TREE_VP_GRP59f, 146 SP_TREE_VP_GRP60f, 147 SP_TREE_VP_GRP61f, 148 SP_TREE_VP_GRP62f, 149 SP_TREE_VP_GRP63f 150 }; 151 152 /* Internal functions */ 153 STATIC int _bcm_td2p_vlan_vfi_mbrship_profile_entry_set(int unit, 154 bcm_vlan_t vlan_vpn, 155 int egress, 156 void *entry_data); 157 STATIC int _bcm_td2p_vlan_vpn_mbrship_profile_get(int unit, 158 bcm_vlan_t vlan_vpn, 159 int egress, 160 uint32 *prof_index); 161 STATIC int _bcm_td2p_vlan_vpn_mbrship_profile_set(int unit, 162 bcm_vlan_t vlan_vpn, 163 int egress, 164 int prof_index); 165 166 STATIC int bcm_td2p_vp_group_port_filter_get(int unit, int port, 167 int egress, int *vp_group, int *filter); 168 STATIC int _bcm_td2p_gpp_hw_index_get(int unit, int port, int *hw_index); 169 STATIC int _bcm_td2p_vp_group_resolve_port_num(int unit, int port, int *port_offset); 170 171 172 /* -------------------------------------------------------- 173 * Software book keeping for virtual port group information 174 * -------------------------------------------------------- 175 */ 176 177 typedef struct _bcm_td2p_vp_group_s { 178 int gpp_vp_count; /* Number of VPs and GPPs that belong to this VP group */ 179 int stp_state; 180 int ut_state; 181 182 SHR_BITDCL *gpp_vp_bitmap; /* Bitmap of VPs and GPPs that belong to this VP group */ 183 SHR_BITDCL *vlan_vfi_bitmap; /* VLANs and VFIs this VP group belongs to */ 184 } _bcm_td2p_vp_group_t; 185 186 187 typedef struct _bcm_td2p_vp_group_bk_s { 188 int vp_group_initialized; /* Flag to check initialized status */ 189 int num_ing_vp_group; /* Number of ingress VP groups */ 190 _bcm_td2p_vp_group_t *ing_vp_group_array; /* Ingress VP group array */ 191 int num_eg_vp_group; /* Number of egress VP groups */ 192 _bcm_td2p_vp_group_t *eg_vp_group_array; /* Egress VP group array */ 193 } _bcm_td2p_vp_group_bk_t; 194 195 typedef struct { 196 int ingress; 197 int egress; 198 } _bcm_td2p_vp_group_unmanaged_t; 199 200 STATIC _bcm_td2p_vp_group_bk_t _bcm_td2p_vp_group_bk[BCM_MAX_NUM_UNITS]; 201 202 STATIC _bcm_td2p_vp_group_unmanaged_t 203 _bcm_td2p_vp_group_unmanaged[BCM_MAX_NUM_UNITS]; 204 205 STATIC sal_mutex_t _bcm_vp_group_ing_mutex[BCM_MAX_NUM_UNITS] = {NULL}; 206 STATIC sal_mutex_t _bcm_vp_group_egr_mutex[BCM_MAX_NUM_UNITS] = {NULL}; 207 208 209 /* 210 * VP Group resource lock 211 */ 212 #define VP_GROUP_ING_LOCK(unit) \ 213 sal_mutex_take(_bcm_vp_group_ing_mutex[unit], sal_mutex_FOREVER); 214 215 #define VP_GROUP_EGR_LOCK(unit) \ 216 sal_mutex_take(_bcm_vp_group_egr_mutex[unit], sal_mutex_FOREVER); 217 218 #define VP_GROUP_ING_UNLOCK(unit) \ 219 sal_mutex_give(_bcm_vp_group_ing_mutex[unit]); 220 221 #define VP_GROUP_EGR_UNLOCK(unit) \ 222 sal_mutex_give(_bcm_vp_group_egr_mutex[unit]); 223 224 #define VP_GROUP_LOCK_MEMS(unit, egress) \ 225 if(!egress) { \ 226 VP_GROUP_ING_LOCK(unit); \ 227 } else { \ 228 VP_GROUP_EGR_LOCK(unit); \ 229 } 230 231 #define VP_GROUP_UNLOCK_MEMS(unit, egress) \ 232 if(!egress) { \ 233 VP_GROUP_ING_UNLOCK(unit); \ 234 } else { \ 235 VP_GROUP_EGR_UNLOCK(unit); \ 236 } 237 238 const char * _bcm_vp_group_access_type_strs[] = { 239 "GLP", 240 "VP", 241 "STG" 242 }; 243 244 const char * _bcm_vp_group_port_type_strs[] = { 245 "Front-Panel", 246 "GLP", 247 "VP" 248 }; 249 250 #define VP_GROUP_BK(unit) (&_bcm_td2p_vp_group_bk[unit]) 251 252 #define VP_GROUP_INIT(unit) \ 253 do { \ 254 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { \ 255 return BCM_E_UNIT; \ 256 } \ 257 if (!VP_GROUP_BK(unit)->vp_group_initialized) { \ 258 return BCM_E_INIT; \ 259 } \ 260 } while (0) 261 262 #define ING_VP_GROUP(unit, vp_group) \ 263 (&VP_GROUP_BK(unit)->ing_vp_group_array[vp_group]) 264 265 #define EG_VP_GROUP(unit, vp_group) \ 266 (&VP_GROUP_BK(unit)->eg_vp_group_array[vp_group]) 267 268 #define ING_STG_GROUP_DATA(unit, stg) \ 269 (&VP_GROUP_BK(unit)->ing_vp_group_array[vp_group]) 270 271 #define TD2P_EGR_DVP_ATTRIBUTE_FIELD(_type,_sf) \ 272 (_type) == 1 ? TRILL__##_sf: \ 273 (_type) == 2 ? VXLAN__##_sf: \ 274 (_type) == 3 ? L2GRE__##_sf: \ 275 COMMON__##_sf; 276 277 #define VP_GROUP_SP_TREE_FIELD(_vp_group) \ 278 SP_TREE_VP_GRP##_vp_group##f 279 280 #define VP_GROUP_CLEANUP(op) \ 281 do { int __rv__; if ((__rv__ = (op)) < 0) { goto cleanup; } } while(0) 282 283 /* 284 * Function: 285 * _bcm_td2p_vp_group_free_resources 286 * Purpose: 287 * Free VP group data structures. 288 * Parameters: 289 * unit - SOC unit number 290 * Returns: 291 * Nothing 292 */ 293 STATIC void 294 _bcm_td2p_vp_group_free_resources(int unit) 295 { 296 int num_vp_groups, i; 297 298 if (VP_GROUP_BK(unit)->ing_vp_group_array) { 299 num_vp_groups = soc_mem_field_length(unit, ING_VLAN_VFI_MEMBERSHIPm, 300 VP_GROUP_BITMAPf); 301 for (i = 0; i < num_vp_groups; i++) { 302 if (ING_VP_GROUP(unit, i)->gpp_vp_bitmap) { 303 sal_free(ING_VP_GROUP(unit, i)->gpp_vp_bitmap); 304 ING_VP_GROUP(unit, i)->gpp_vp_bitmap = NULL; 305 } 306 if (ING_VP_GROUP(unit, i)->vlan_vfi_bitmap) { 307 sal_free(ING_VP_GROUP(unit, i)->vlan_vfi_bitmap); 308 ING_VP_GROUP(unit, i)->vlan_vfi_bitmap = NULL; 309 } 310 } 311 sal_free(VP_GROUP_BK(unit)->ing_vp_group_array); 312 VP_GROUP_BK(unit)->ing_vp_group_array = NULL; 313 } 314 315 if (_bcm_vp_group_ing_mutex[unit]) { 316 sal_mutex_destroy(_bcm_vp_group_ing_mutex[unit]); 317 _bcm_vp_group_ing_mutex[unit] = NULL; 318 } 319 320 if (VP_GROUP_BK(unit)->eg_vp_group_array) { 321 num_vp_groups = soc_mem_field_length(unit, EGR_VLAN_VFI_MEMBERSHIPm, 322 VP_GROUP_BITMAPf); 323 for (i = 0; i < num_vp_groups; i++) { 324 if (EG_VP_GROUP(unit, i)->gpp_vp_bitmap) { 325 sal_free(EG_VP_GROUP(unit, i)->gpp_vp_bitmap); 326 EG_VP_GROUP(unit, i)->gpp_vp_bitmap = NULL; 327 } 328 if (EG_VP_GROUP(unit, i)->vlan_vfi_bitmap) { 329 sal_free(EG_VP_GROUP(unit, i)->vlan_vfi_bitmap); 330 EG_VP_GROUP(unit, i)->vlan_vfi_bitmap = NULL; 331 } 332 } 333 sal_free(VP_GROUP_BK(unit)->eg_vp_group_array); 334 VP_GROUP_BK(unit)->eg_vp_group_array = NULL; 335 } 336 337 if (_bcm_vp_group_egr_mutex[unit]) { 338 sal_mutex_destroy(_bcm_vp_group_egr_mutex[unit]); 339 _bcm_vp_group_egr_mutex[unit] = NULL; 340 } 341 342 return; 343 } 344 345 /* 346 * Function: 347 * _td2p_egr_dvp_attribute_field_name_get 348 * Purpose: 349 * Retrieve the proper field name based the device and vp type. 350 * Parameters: 351 * unit - SOC unit number. 352 * Returns: 353 * BCM_E_XXX 354 */ 355 STATIC int 356 _td2p_egr_dvp_attribute_field_name_get(int unit, 357 void *dvp_entry, 358 soc_field_t legacy_name, 359 soc_field_t *result_name) 360 { 361 int vp_type; 362 soc_field_t vpt_fld = DATA_TYPEf; 363 364 if (soc_mem_field_valid(unit, EGR_DVP_ATTRIBUTEm, VP_TYPEf)) { 365 vpt_fld = VP_TYPEf; 366 } 367 368 vp_type = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, 369 (egr_dvp_attribute_entry_t *)dvp_entry, vpt_fld); 370 switch (legacy_name) { 371 case EN_EFILTERf: 372 *result_name = TD2P_EGR_DVP_ATTRIBUTE_FIELD(vp_type, EN_EFILTERf); 373 break; 374 case VLAN_MEMBERSHIP_PROFILEf: 375 *result_name = TD2P_EGR_DVP_ATTRIBUTE_FIELD(vp_type, 376 VLAN_MEMBERSHIP_PROFILEf); 377 break; 378 default: 379 return BCM_E_NOT_FOUND; 380 break; 381 } 382 return BCM_E_NONE; 383 } 384 385 #ifdef BCM_WARM_BOOT_SUPPORT 386 /* 387 * Function: 388 * _bcm_td2p_vp_group_reinit 389 * Purpose: 390 * Recover the virtual port group data structures. 391 * Parameters: 392 * unit - SOC unit number. 393 * Returns: 394 * BCM_E_XXX 395 */ 396 STATIC int 397 _bcm_td2p_vp_group_reinit(int unit) 398 { 399 400 401 int rv = BCM_E_NONE; 402 uint8 *source_vp_buf = NULL; 403 uint8 *vlan_buf = NULL; 404 uint8 *egr_dvp_buf = NULL; 405 uint8 *vlan_vfi_mbrship_buf = NULL; 406 uint8 *vlan_mpls_buf = NULL; 407 int profile_ptr = 0; 408 uint8 *egr_vlan_buf = NULL; 409 int index_min, index_max; 410 int i, k; 411 source_vp_entry_t *svp_entry; 412 int vp_group; 413 vlan_tab_entry_t *vlan_entry = NULL; 414 vlan_mpls_entry_t *vlan_mpls_entry; 415 #if defined(BCM_TRIDENT3_SUPPORT) 416 vlan_attrs_1_entry_t *vlan_attrs_entry; 417 #endif 418 soc_mem_t vlan_mpls_mem = VLAN_MPLSm; 419 uint32 fldbuf[2]; 420 egr_dvp_attribute_entry_t *egr_dvp_entry = NULL; 421 egr_vlan_entry_t *egr_vlan_entry = NULL; 422 ing_vlan_vfi_membership_entry_t *ing_vlan_vfi_mbrship = NULL; 423 egr_vlan_vfi_membership_entry_t *egr_vlan_vfi_mbrship = NULL; 424 soc_field_t en_efilter_f; 425 soc_field_t vm_prof_f; 426 uint8 *vfi_buf = NULL; 427 vfi_entry_t *vfi_entry = NULL; 428 egr_vfi_entry_t *egr_vfi_entry = NULL; 429 uint8 *stg_buf = NULL; 430 stg_tab_entry_t *stg_entry = NULL; 431 egr_vlan_stg_entry_t *egr_stg_entry = NULL; 432 int stg = BCM_STG_DEFAULT; 433 uint32 ut_grp_bmap[SOC_PBMP_WORD_MAX] = {0}; 434 435 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 436 437 if(!bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 438 /* Recover ingress VP group's virtual ports from SOURCE_VP table */ 439 440 source_vp_buf = soc_cm_salloc(unit, 441 SOC_MEM_TABLE_BYTES(unit, SOURCE_VPm), "SOURCE_VP buffer"); 442 if (NULL == source_vp_buf) { 443 rv = BCM_E_MEMORY; 444 goto cleanup; 445 } 446 447 index_min = soc_mem_index_min(unit, SOURCE_VPm); 448 index_max = soc_mem_index_max(unit, SOURCE_VPm); 449 rv = soc_mem_read_range(unit, SOURCE_VPm, MEM_BLOCK_ANY, 450 index_min, index_max, source_vp_buf); 451 if (SOC_FAILURE(rv)) { 452 goto cleanup; 453 } 454 455 for (i = index_min; i <= index_max; i++) { 456 svp_entry = soc_mem_table_idx_to_pointer 457 (unit, SOURCE_VPm, source_vp_entry_t *, source_vp_buf, i); 458 459 if (soc_SOURCE_VPm_field32_get(unit, svp_entry, 460 ENABLE_IFILTERf) != 1) { 461 continue; 462 } 463 464 vp_group = soc_SOURCE_VPm_field32_get(unit, svp_entry, 465 VLAN_MEMBERSHIP_PROFILEf); 466 SHR_BITSET(ING_VP_GROUP(unit, vp_group)->gpp_vp_bitmap, 467 BCMI_VP_GROUP_VP_OFFSET + i); 468 ING_VP_GROUP(unit, vp_group)->gpp_vp_count++; 469 } 470 471 soc_cm_sfree(unit, source_vp_buf); 472 source_vp_buf = NULL; 473 } 474 /* Recover ingress VP group's vlans from VLAN table */ 475 #if defined(BCM_TRIDENT3_SUPPORT) 476 if (SOC_IS_TRIDENT3X(unit)) { 477 vlan_mpls_mem = VLAN_ATTRS_1m; 478 } 479 #endif 480 vlan_mpls_buf = soc_cm_salloc(unit, 481 SOC_MEM_TABLE_BYTES(unit, vlan_mpls_mem), "VLAN_MPLS buffer"); 482 if (NULL == vlan_mpls_buf) { 483 rv = BCM_E_MEMORY; 484 goto cleanup; 485 } 486 index_min = soc_mem_index_min(unit, vlan_mpls_mem); 487 index_max = soc_mem_index_max(unit, vlan_mpls_mem); 488 rv = soc_mem_read_range(unit, vlan_mpls_mem, MEM_BLOCK_ANY, 489 index_min, index_max, vlan_mpls_buf); 490 if (SOC_FAILURE(rv)) { 491 goto cleanup; 492 } 493 494 vlan_vfi_mbrship_buf = soc_cm_salloc(unit, 495 SOC_MEM_TABLE_BYTES(unit, ING_VLAN_VFI_MEMBERSHIPm), 496 "ING_VLAN_VFI buffer"); 497 if (NULL == vlan_vfi_mbrship_buf) { 498 rv = BCM_E_MEMORY; 499 goto cleanup; 500 } 501 index_min = soc_mem_index_min(unit, ING_VLAN_VFI_MEMBERSHIPm); 502 index_max = soc_mem_index_max(unit, ING_VLAN_VFI_MEMBERSHIPm); 503 rv = soc_mem_read_range(unit, ING_VLAN_VFI_MEMBERSHIPm, 504 MEM_BLOCK_ANY, index_min, index_max, vlan_vfi_mbrship_buf); 505 if (SOC_FAILURE(rv)) { 506 goto cleanup; 507 } 508 509 stg_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, STG_TABm), 510 "STG_TAB buffer"); 511 if (NULL == stg_buf) { 512 rv = BCM_E_MEMORY; 513 goto cleanup; 514 } 515 index_min = soc_mem_index_min(unit, STG_TABm); 516 index_max = soc_mem_index_max(unit, STG_TABm); 517 rv = soc_mem_read_range(unit, STG_TABm, MEM_BLOCK_ANY, 518 index_min, index_max, stg_buf); 519 if (SOC_FAILURE(rv)) { 520 goto cleanup; 521 } 522 523 vlan_buf = soc_cm_salloc(unit, 524 SOC_MEM_TABLE_BYTES(unit, VLAN_TABm), 525 "VLAN_TAB buffer"); 526 if (NULL == vlan_buf) { 527 rv = BCM_E_MEMORY; 528 goto cleanup; 529 } 530 index_min = soc_mem_index_min(unit, VLAN_TABm); 531 index_max = soc_mem_index_max(unit, VLAN_TABm); 532 rv = soc_mem_read_range(unit, VLAN_TABm, MEM_BLOCK_ANY, 533 index_min, index_max, vlan_buf); 534 if (SOC_FAILURE(rv)) { 535 goto cleanup; 536 } 537 538 for (i = index_min; i <= index_max; i++) { 539 vlan_entry = soc_mem_table_idx_to_pointer 540 (unit, VLAN_TABm, vlan_tab_entry_t *, vlan_buf, i); 541 542 if (soc_VLAN_TABm_field32_get(unit, vlan_entry, VALIDf) == 0) { 543 continue; 544 } 545 546 if (soc_mem_is_valid(unit, VLAN_MPLSm)) { 547 vlan_mpls_entry = soc_mem_table_idx_to_pointer 548 (unit, vlan_mpls_mem, vlan_mpls_entry_t *, vlan_mpls_buf, i); 549 profile_ptr = soc_mem_field32_get(unit, vlan_mpls_mem, vlan_mpls_entry, 550 MEMBERSHIP_PROFILE_PTRf); 551 } 552 #if defined(BCM_TRIDENT3_SUPPORT) 553 else if (soc_mem_is_valid(unit, VLAN_ATTRS_1m)) { 554 vlan_attrs_entry = soc_mem_table_idx_to_pointer 555 (unit, vlan_mpls_mem, vlan_attrs_1_entry_t *, vlan_mpls_buf, i); 556 profile_ptr = soc_mem_field32_get(unit, vlan_mpls_mem, vlan_attrs_entry, 557 MEMBERSHIP_PROFILE_PTRf); 558 } 559 #endif 560 561 rv = _bcm_vlan_vfi_membership_profile_mem_reference( 562 unit, profile_ptr, 1, 0); 563 if (SOC_FAILURE(rv)) { 564 goto cleanup; 565 } 566 567 if (bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 568 continue; 569 } 570 571 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 572 if (soc_VLAN_TABm_field32_get(unit, vlan_entry, 573 VIRTUAL_PORT_ENf) == 0) { 574 continue; 575 } 576 } 577 578 stg = soc_VLAN_TABm_field32_get(unit, vlan_entry, STGf); 579 580 ing_vlan_vfi_mbrship = soc_mem_table_idx_to_pointer(unit, 581 ING_VLAN_VFI_MEMBERSHIPm, 582 ing_vlan_vfi_membership_entry_t *, 583 vlan_vfi_mbrship_buf, profile_ptr); 584 soc_ING_VLAN_VFI_MEMBERSHIPm_field_get(unit, ing_vlan_vfi_mbrship, 585 VP_GROUP_BITMAPf, fldbuf); 586 587 for (k = 0; k < VP_GROUP_BK(unit)->num_ing_vp_group; k++) { 588 if (fldbuf[k / 32] & (1 << (k % 32))) { 589 /* The bit in VP_GROUP_BITMAP that corresponds to 590 * VP group k is set. 591 */ 592 SHR_BITSET(ING_VP_GROUP(unit, k)->vlan_vfi_bitmap, i); 593 594 if (stg != BCM_STG_DEFAULT) { 595 stg_entry = 596 soc_mem_table_idx_to_pointer(unit, STG_TABm, 597 stg_tab_entry_t *, 598 stg_buf, stg); 599 ING_VP_GROUP(unit, k)->stp_state = 600 soc_STG_TABm_field32_get(unit, stg_entry, 601 _bcm_vp_group_stp_field[k]); 602 } 603 } 604 } 605 } 606 607 soc_cm_sfree(unit, vlan_buf); 608 soc_cm_sfree(unit, vlan_mpls_buf); 609 vlan_buf = NULL; 610 vlan_mpls_buf = NULL; 611 612 vfi_buf = 613 soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, VFIm), "VFI buffer"); 614 if (NULL == vfi_buf) { 615 rv = BCM_E_MEMORY; 616 goto cleanup; 617 } 618 619 index_min = soc_mem_index_min(unit, VFIm); 620 index_max = soc_mem_index_max(unit, VFIm); 621 rv = soc_mem_read_range(unit, VFIm, MEM_BLOCK_ANY, 622 index_min, index_max, vfi_buf); 623 if (SOC_FAILURE(rv)) { 624 goto cleanup; 625 } 626 627 for (i = index_min; i <= index_max; i++) { 628 vfi_entry = 629 soc_mem_table_idx_to_pointer(unit, VFIm, vfi_entry_t *, 630 vfi_buf, i); 631 profile_ptr = 632 soc_VFIm_field32_get(unit, vfi_entry, 633 MEMBERSHIP_PROFILE_PTRf); 634 rv = _bcm_vlan_vfi_membership_profile_mem_reference( 635 unit, profile_ptr, 1, 0); 636 if (SOC_FAILURE(rv)) { 637 goto cleanup; 638 } 639 640 if (bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 641 continue; 642 } 643 644 stg = soc_VFIm_field32_get(unit, vfi_entry, STGf); 645 646 ing_vlan_vfi_mbrship = 647 soc_mem_table_idx_to_pointer(unit, 648 ING_VLAN_VFI_MEMBERSHIPm, 649 ing_vlan_vfi_membership_entry_t *, 650 vlan_vfi_mbrship_buf, profile_ptr); 651 652 soc_ING_VLAN_VFI_MEMBERSHIPm_field_get(unit, ing_vlan_vfi_mbrship, 653 VP_GROUP_BITMAPf, fldbuf); 654 for (k = 0; k < VP_GROUP_BK(unit)->num_ing_vp_group; k++) { 655 if (fldbuf[k / 32] & (1 << (k % 32))) { 656 /* The bit in VP_GROUP_BITMAP that corresponds to 657 * VP group k is set. 658 */ 659 SHR_BITSET(ING_VP_GROUP(unit, k)->vlan_vfi_bitmap, 660 BCM_VLAN_COUNT + i); 661 662 if (stg != BCM_STG_DEFAULT) { 663 stg_entry = 664 soc_mem_table_idx_to_pointer(unit, STG_TABm, 665 stg_tab_entry_t *, 666 stg_buf, stg); 667 ING_VP_GROUP(unit, k)->stp_state = 668 soc_STG_TABm_field32_get(unit, stg_entry, 669 _bcm_vp_group_stp_field[k]); 670 } 671 } 672 } 673 } 674 675 soc_cm_sfree(unit, vfi_buf); 676 soc_cm_sfree(unit, vlan_vfi_mbrship_buf); 677 soc_cm_sfree(unit, stg_buf); 678 vlan_vfi_mbrship_buf = NULL; 679 vfi_buf = NULL; 680 stg_buf = NULL; 681 } 682 683 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 684 if (!bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 685 /* Recover egress VP group's virtual ports from 686 * EGR_DVP_ATTRIBUTE table 687 */ 688 689 egr_dvp_buf = soc_cm_salloc(unit, 690 SOC_MEM_TABLE_BYTES(unit, EGR_DVP_ATTRIBUTEm), 691 "EGR_DVP buffer"); 692 if (NULL == egr_dvp_buf) { 693 rv = BCM_E_MEMORY; 694 goto cleanup; 695 } 696 697 index_min = soc_mem_index_min(unit, EGR_DVP_ATTRIBUTEm); 698 index_max = soc_mem_index_max(unit, EGR_DVP_ATTRIBUTEm); 699 rv = soc_mem_read_range(unit, EGR_DVP_ATTRIBUTEm, MEM_BLOCK_ANY, 700 index_min, index_max, egr_dvp_buf); 701 if (SOC_FAILURE(rv)) { 702 goto cleanup; 703 } 704 705 for (i = index_min; i <= index_max; i++) { 706 egr_dvp_entry = soc_mem_table_idx_to_pointer 707 (unit, EGR_DVP_ATTRIBUTEm, egr_dvp_attribute_entry_t *, 708 egr_dvp_buf, i); 709 710 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get(unit, 711 egr_dvp_entry, EN_EFILTERf, &en_efilter_f)); 712 713 if (soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, egr_dvp_entry, 714 en_efilter_f) != 1) { 715 continue; 716 } 717 718 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get(unit, 719 egr_dvp_entry, VLAN_MEMBERSHIP_PROFILEf, 720 &vm_prof_f)); 721 722 vp_group = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, egr_dvp_entry, 723 vm_prof_f); 724 SHR_BITSET(EG_VP_GROUP(unit, vp_group)->gpp_vp_bitmap, 725 BCMI_VP_GROUP_VP_OFFSET + i); 726 EG_VP_GROUP(unit, vp_group)->gpp_vp_count++; 727 } 728 729 soc_cm_sfree(unit, egr_dvp_buf); 730 egr_dvp_buf = NULL; 731 } 732 /* Recover egress VP group's vlans from EGR_VLAN table */ 733 734 vlan_vfi_mbrship_buf = soc_cm_salloc(unit, 735 SOC_MEM_TABLE_BYTES(unit, EGR_VLAN_VFI_MEMBERSHIPm), 736 "EGR_VLAN_VFI buffer"); 737 if (NULL == vlan_vfi_mbrship_buf) { 738 rv = BCM_E_MEMORY; 739 goto cleanup; 740 } 741 742 index_min = soc_mem_index_min(unit, EGR_VLAN_VFI_MEMBERSHIPm); 743 index_max = soc_mem_index_max(unit, EGR_VLAN_VFI_MEMBERSHIPm); 744 rv = soc_mem_read_range(unit, EGR_VLAN_VFI_MEMBERSHIPm, 745 MEM_BLOCK_ANY, index_min, index_max, vlan_vfi_mbrship_buf); 746 if (SOC_FAILURE(rv)) { 747 goto cleanup; 748 } 749 750 stg_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, EGR_VLAN_STGm), 751 "EGR_VLAN_STG buffer"); 752 if (NULL == stg_buf) { 753 rv = BCM_E_MEMORY; 754 goto cleanup; 755 } 756 index_min = soc_mem_index_min(unit, EGR_VLAN_STGm); 757 index_max = soc_mem_index_max(unit, EGR_VLAN_STGm); 758 rv = soc_mem_read_range(unit, EGR_VLAN_STGm, MEM_BLOCK_ANY, 759 index_min, index_max, stg_buf); 760 if (SOC_FAILURE(rv)) { 761 goto cleanup; 762 } 763 egr_vlan_buf = soc_cm_salloc(unit, 764 SOC_MEM_TABLE_BYTES(unit, EGR_VLANm), 765 "EGR_VLAN buffer"); 766 if (NULL == egr_vlan_buf) { 767 rv = BCM_E_MEMORY; 768 goto cleanup; 769 } 770 771 index_min = soc_mem_index_min(unit, EGR_VLANm); 772 index_max = soc_mem_index_max(unit, EGR_VLANm); 773 rv = soc_mem_read_range(unit, EGR_VLANm, MEM_BLOCK_ANY, 774 index_min, index_max, egr_vlan_buf); 775 if (SOC_FAILURE(rv)) { 776 goto cleanup; 777 } 778 779 for (i = index_min; i <= index_max; i++) { 780 egr_vlan_entry = soc_mem_table_idx_to_pointer 781 (unit, EGR_VLANm, egr_vlan_entry_t *, egr_vlan_buf, i); 782 783 if (soc_EGR_VLANm_field32_get(unit, egr_vlan_entry, VALIDf) == 0) { 784 continue; 785 } 786 787 profile_ptr = soc_EGR_VLANm_field32_get(unit, egr_vlan_entry, 788 MEMBERSHIP_PROFILE_PTRf); 789 rv =_bcm_vlan_vfi_membership_profile_mem_reference 790 (unit, profile_ptr, 1, 1); 791 if (SOC_FAILURE(rv)) { 792 goto cleanup; 793 } 794 795 if (bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 796 continue; 797 } 798 799 stg = soc_EGR_VLANm_field32_get(unit, egr_vlan_entry, STGf); 800 #if defined(BCM_TRIDENT3_SUPPORT) 801 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 802 uint32 prof_index; 803 egr_vlan_vfi_untag_entry_t egr_vlan_vfi; 804 prof_index = soc_mem_field32_get(unit, EGR_VLANm, 805 egr_vlan_entry, UNTAG_PROFILE_PTRf); 806 rv = READ_EGR_VLAN_VFI_UNTAGm(unit, MEM_BLOCK_ANY, prof_index, 807 &egr_vlan_vfi); 808 if (SOC_FAILURE(rv)) { 809 goto cleanup; 810 } 811 soc_mem_pbmp_field_get(unit, EGR_VLAN_VFI_UNTAGm, &egr_vlan_vfi, 812 UT_VP_GRP_BITMAPf, (void *)ut_grp_bmap); 813 rv = _bcm_vlan_vfi_untag_profile_mem_reference(unit, 814 prof_index, 1); 815 if (SOC_FAILURE(rv)) { 816 goto cleanup; 817 } 818 } else 819 #endif 820 { 821 soc_EGR_VLANm_field_get(unit, egr_vlan_entry, 822 UT_VP_GRP_BITMAPf, ut_grp_bmap); 823 } 824 825 egr_vlan_vfi_mbrship = soc_mem_table_idx_to_pointer(unit, 826 EGR_VLAN_VFI_MEMBERSHIPm, 827 egr_vlan_vfi_membership_entry_t *, 828 vlan_vfi_mbrship_buf, profile_ptr); 829 soc_EGR_VLAN_VFI_MEMBERSHIPm_field_get(unit, egr_vlan_vfi_mbrship, 830 VP_GROUP_BITMAPf, fldbuf); 831 832 for (k = 0; k < VP_GROUP_BK(unit)->num_eg_vp_group; k++) { 833 if (fldbuf[k / 32] & (1 << (k % 32))) { 834 /* The bit in VP_GROUP_BITMAP that corresponds to 835 * VP group k is set. 836 */ 837 SHR_BITSET(EG_VP_GROUP(unit, k)->vlan_vfi_bitmap, i); 838 839 if (stg != BCM_STG_DEFAULT) { 840 egr_stg_entry = 841 soc_mem_table_idx_to_pointer(unit, EGR_VLAN_STGm, 842 egr_vlan_stg_entry_t *, 843 stg_buf, stg); 844 EG_VP_GROUP(unit, k)->stp_state = 845 soc_EGR_VLAN_STGm_field32_get(unit, egr_stg_entry, 846 _bcm_vp_group_stp_field[k]); 847 } 848 849 EG_VP_GROUP(unit, k)->ut_state = 850 (ut_grp_bmap[k / 32] & (1 << (k % 32))); 851 852 } 853 } 854 } 855 856 soc_cm_sfree(unit, egr_vlan_buf); 857 egr_vlan_buf = NULL; 858 859 vfi_buf = 860 soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, EGR_VFIm), 861 "EGR_VFI buffer"); 862 if (NULL == vfi_buf) { 863 rv = BCM_E_MEMORY; 864 goto cleanup; 865 } 866 867 index_min = soc_mem_index_min(unit, EGR_VFIm); 868 index_max = soc_mem_index_max(unit, EGR_VFIm); 869 rv = soc_mem_read_range(unit, EGR_VFIm, MEM_BLOCK_ANY, 870 index_min, index_max, vfi_buf); 871 if (SOC_FAILURE(rv)) { 872 goto cleanup; 873 } 874 875 for (i = index_min; i <= index_max; i++) { 876 egr_vfi_entry = 877 soc_mem_table_idx_to_pointer(unit, EGR_VFIm, egr_vfi_entry_t *, 878 vfi_buf, i); 879 profile_ptr = 880 soc_EGR_VFIm_field32_get(unit, egr_vfi_entry, 881 MEMBERSHIP_PROFILE_PTRf); 882 rv = _bcm_vlan_vfi_membership_profile_mem_reference( 883 unit, profile_ptr, 1, 1); 884 if (SOC_FAILURE(rv)) { 885 goto cleanup; 886 } 887 888 if (bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 889 continue; 890 } 891 892 stg = soc_EGR_VFIm_field32_get(unit, egr_vfi_entry, STGf); 893 #if defined(BCM_TRIDENT3_SUPPORT) 894 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 895 uint32 prof_index; 896 egr_vlan_vfi_untag_entry_t egr_vlan_vfi; 897 prof_index = soc_mem_field32_get(unit, EGR_VFIm, 898 egr_vfi_entry, UNTAG_PROFILE_PTRf); 899 rv = READ_EGR_VLAN_VFI_UNTAGm(unit, MEM_BLOCK_ANY, prof_index, 900 &egr_vlan_vfi); 901 if (SOC_FAILURE(rv)) { 902 goto cleanup; 903 } 904 soc_mem_pbmp_field_get(unit, EGR_VLAN_VFI_UNTAGm, &egr_vlan_vfi, 905 UT_VP_GRP_BITMAPf, (void *)ut_grp_bmap); 906 rv = _bcm_vlan_vfi_untag_profile_mem_reference(unit, 907 prof_index, 1); 908 if (SOC_FAILURE(rv)) { 909 goto cleanup; 910 } 911 } 912 #endif 913 egr_vlan_vfi_mbrship = 914 soc_mem_table_idx_to_pointer(unit, 915 EGR_VLAN_VFI_MEMBERSHIPm, 916 egr_vlan_vfi_membership_entry_t *, 917 vlan_vfi_mbrship_buf, profile_ptr); 918 soc_EGR_VLAN_VFI_MEMBERSHIPm_field_get(unit, egr_vlan_vfi_mbrship, 919 VP_GROUP_BITMAPf, fldbuf); 920 921 for (k = 0; k < VP_GROUP_BK(unit)->num_eg_vp_group; k++) { 922 if (fldbuf[k / 32] & (1 << (k % 32))) { 923 /* The bit in VP_GROUP_BITMAP that corresponds to 924 * VP group k is set. 925 */ 926 SHR_BITSET(EG_VP_GROUP(unit, k)->vlan_vfi_bitmap, 927 BCM_VLAN_COUNT + i); 928 929 if (stg != BCM_STG_DEFAULT) { 930 egr_stg_entry = 931 soc_mem_table_idx_to_pointer(unit, EGR_VLAN_STGm, 932 egr_vlan_stg_entry_t *, 933 stg_buf, stg); 934 EG_VP_GROUP(unit, k)->stp_state = 935 soc_EGR_VLAN_STGm_field32_get(unit, egr_stg_entry, 936 _bcm_vp_group_stp_field[k]); 937 } 938 #if defined(BCM_TRIDENT3_SUPPORT) 939 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 940 EG_VP_GROUP(unit, k)->ut_state = 941 (ut_grp_bmap[k / 32] & (1 << (k % 32))); 942 } 943 #endif 944 } 945 } 946 } 947 948 soc_cm_sfree(unit, vfi_buf); 949 soc_cm_sfree(unit, vlan_vfi_mbrship_buf); 950 soc_cm_sfree(unit, stg_buf); 951 vlan_vfi_mbrship_buf = NULL; 952 vfi_buf = NULL; 953 stg_buf = NULL; 954 } 955 956 cleanup: 957 if (source_vp_buf) { 958 soc_cm_sfree(unit, source_vp_buf); 959 } 960 if (vlan_buf) { 961 soc_cm_sfree(unit, vlan_buf); 962 } 963 if (vlan_mpls_buf) { 964 soc_cm_sfree(unit, vlan_mpls_buf); 965 } 966 if (egr_dvp_buf) { 967 soc_cm_sfree(unit, egr_dvp_buf); 968 } 969 if (egr_vlan_buf) { 970 soc_cm_sfree(unit, egr_vlan_buf); 971 } 972 if (vlan_vfi_mbrship_buf) { 973 soc_cm_sfree(unit, vlan_vfi_mbrship_buf); 974 } 975 if (vfi_buf) { 976 soc_cm_sfree(unit, vfi_buf); 977 } 978 if (stg_buf) { 979 soc_cm_sfree(unit, stg_buf); 980 } 981 982 return rv; 983 } 984 #endif /* BCM_WARM_BOOT_SUPPORT */ 985 986 #ifndef BCM_SW_STATE_DUMP_DISABLE 987 /* 988 * Function: 989 * bcm_td2p_vp_group_sw_dump 990 * Purpose: 991 * Displays VP group information maintained by software. 992 * Parameters: 993 * unit - Device unit number 994 * Returns: 995 * None 996 */ 997 void 998 bcm_td2p_vp_group_sw_dump(int unit) 999 { 1000 int i, k; 1001 int vlan_vfi_count; 1002 int gpp_vp_bit_size, num_gpp; 1003 int gpp_vp_count, stp_state, ut_state; 1004 1005 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 1006 num_gpp = BCMI_MAX_COE_MODULE_ID * BCMI_NUM_PORTS_PER_COE_MODULE; 1007 gpp_vp_bit_size = soc_mem_index_count(unit, SOURCE_VPm) + num_gpp; 1008 1009 cli_out("\nSW Information Ingress VP Group - Unit %d\n", unit); 1010 for (i = 0; i < VP_GROUP_BK(unit)->num_ing_vp_group; i++) { 1011 gpp_vp_count = ING_VP_GROUP(unit, i)->gpp_vp_count; 1012 stp_state = ING_VP_GROUP(unit, i)->stp_state; 1013 ut_state = ING_VP_GROUP(unit, i)->ut_state; 1014 1015 if (gpp_vp_count == 0 && stp_state == 0 && 1016 ut_state == 0) { 1017 continue; 1018 } 1019 cli_out("\n Ingress Group = %d, ", i); 1020 cli_out("GPP_VP Count = %d, ", gpp_vp_count); 1021 cli_out("STP State = %d, ", stp_state); 1022 cli_out("Untag State = %d\n", ut_state); 1023 1024 cli_out(" GPP_VP List ="); 1025 for (k = 0; k < gpp_vp_bit_size; k++) { 1026 if (SHR_BITGET(ING_VP_GROUP(unit, i)->gpp_vp_bitmap, k)) { 1027 1028 if(k < num_gpp) { 1029 cli_out(" GPP (mod,port) (%d,%d)", (k % BCMI_MAX_COE_MODULE_ID), 1030 (k - (k % BCMI_MAX_COE_MODULE_ID))); 1031 } else { 1032 cli_out(" VP %d", k); 1033 } 1034 } 1035 } 1036 cli_out("\n"); 1037 1038 cli_out(" VLAN/VFI List ="); 1039 for (k = 0; k < vlan_vfi_count; k++) { 1040 if (SHR_BITGET(ING_VP_GROUP(unit, i)->vlan_vfi_bitmap, k)) { 1041 if(k <= BCM_VLAN_MAX) { 1042 cli_out(" vlan %d", k); 1043 } else { 1044 cli_out(" vfi %d", k); 1045 } 1046 } 1047 } 1048 cli_out("\n"); 1049 } 1050 1051 cli_out("\nSW Information Egress VP Group - Unit %d\n", unit); 1052 for (i = 0; i < VP_GROUP_BK(unit)->num_eg_vp_group; i++) { 1053 gpp_vp_count = EG_VP_GROUP(unit, i)->gpp_vp_count; 1054 stp_state = EG_VP_GROUP(unit, i)->stp_state; 1055 ut_state = EG_VP_GROUP(unit, i)->ut_state; 1056 1057 if (gpp_vp_count == 0 && stp_state == 0 && 1058 ut_state == 0) { 1059 continue; 1060 } 1061 cli_out("\n Egress VP Group = %d, ", i); 1062 cli_out("GPP_VP Count = %d, ", gpp_vp_count); 1063 cli_out("STP State = %d, ", stp_state); 1064 cli_out("Untag State = %d\n", ut_state); 1065 1066 cli_out(" GPP/VP List ="); 1067 for (k = 0; k < gpp_vp_bit_size; k++) { 1068 if (SHR_BITGET(EG_VP_GROUP(unit, i)->gpp_vp_bitmap, k)) { 1069 1070 if(k < num_gpp) { 1071 cli_out(" GPP (mod,port) (%d,%d)", (k % BCMI_MAX_COE_MODULE_ID), 1072 (k - (k % BCMI_MAX_COE_MODULE_ID))); 1073 } else { 1074 cli_out(" VP %d", k); 1075 } 1076 } 1077 } 1078 cli_out("\n"); 1079 1080 cli_out(" VLAN List ="); 1081 for (k = 0; k < vlan_vfi_count; k++) { 1082 if (SHR_BITGET(EG_VP_GROUP(unit, i)->vlan_vfi_bitmap, k)) { 1083 if(k <= BCM_VLAN_MAX) { 1084 cli_out(" vlan %d", k); 1085 } else { 1086 cli_out(" vfi %d", k); 1087 } 1088 } 1089 } 1090 cli_out("\n"); 1091 } 1092 1093 return; 1094 } 1095 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 1096 1097 /* 1098 * Function: 1099 * bcm_td2p_vp_group_init 1100 * Purpose: 1101 * Initialize the virtual port group data structures. 1102 * Parameters: 1103 * unit - SOC unit number. 1104 * Returns: 1105 * BCM_E_XXX 1106 */ 1107 int 1108 bcm_td2p_vp_group_init(int unit) 1109 { 1110 int vlan_vfi_count; 1111 int num_vp_groups = 0, num_vp = 0; 1112 int num_gpp = 0, i = 0; 1113 int rv = BCM_E_NONE; 1114 uint32 reg_value = 0; 1115 1116 _bcm_td2p_vp_group_free_resources(unit); 1117 1118 #ifdef BCM_WARM_BOOT_SUPPORT 1119 if (SOC_WARM_BOOT(unit)) { 1120 } else 1121 #endif 1122 { 1123 _bcm_td2p_vp_group_unmanaged[unit].ingress = FALSE; 1124 _bcm_td2p_vp_group_unmanaged[unit].egress = FALSE; 1125 } 1126 sal_memset(VP_GROUP_BK(unit), 0, sizeof(_bcm_td2p_vp_group_bk_t)); 1127 1128 num_vp_groups = soc_mem_field_length(unit, ING_VLAN_VFI_MEMBERSHIPm, 1129 VP_GROUP_BITMAPf); 1130 VP_GROUP_BK(unit)->num_ing_vp_group = num_vp_groups; 1131 1132 if (NULL == VP_GROUP_BK(unit)->ing_vp_group_array) { 1133 VP_GROUP_BK(unit)->ing_vp_group_array = 1134 sal_alloc(sizeof(_bcm_td2p_vp_group_t) * num_vp_groups, 1135 "ingress vp group array"); 1136 if (NULL == VP_GROUP_BK(unit)->ing_vp_group_array) { 1137 _bcm_td2p_vp_group_free_resources(unit); 1138 return BCM_E_MEMORY; 1139 } 1140 } 1141 sal_memset(VP_GROUP_BK(unit)->ing_vp_group_array, 0, 1142 sizeof(_bcm_td2p_vp_group_t) * num_vp_groups); 1143 1144 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 1145 num_gpp = BCMI_MAX_COE_MODULE_ID * BCMI_NUM_PORTS_PER_COE_MODULE; 1146 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 1147 1148 for (i = 0; i < num_vp_groups; i++) { 1149 if (NULL == ING_VP_GROUP(unit, i)->gpp_vp_bitmap) { 1150 ING_VP_GROUP(unit, i)->gpp_vp_bitmap = sal_alloc 1151 (SHR_BITALLOCSIZE(num_gpp + num_vp), 1152 "ingress vp group vp gpp bitmap"); 1153 if (NULL == ING_VP_GROUP(unit, i)->gpp_vp_bitmap) { 1154 _bcm_td2p_vp_group_free_resources(unit); 1155 return BCM_E_MEMORY; 1156 } 1157 } 1158 sal_memset(ING_VP_GROUP(unit, i)->gpp_vp_bitmap, 0, 1159 (SHR_BITALLOCSIZE(num_gpp + num_vp))); 1160 1161 if (NULL == ING_VP_GROUP(unit, i)->vlan_vfi_bitmap) { 1162 ING_VP_GROUP(unit, i)->vlan_vfi_bitmap = sal_alloc 1163 (SHR_BITALLOCSIZE(vlan_vfi_count), 1164 "ingress vp group vlan vfi bitmap"); 1165 if (NULL == ING_VP_GROUP(unit, i)->vlan_vfi_bitmap) { 1166 _bcm_td2p_vp_group_free_resources(unit); 1167 return BCM_E_MEMORY; 1168 } 1169 } 1170 1171 sal_memset(ING_VP_GROUP(unit, i)->vlan_vfi_bitmap, 0, 1172 SHR_BITALLOCSIZE(vlan_vfi_count)); 1173 } 1174 1175 /* Enable the STG checks on Ingress VP Groups */ 1176 soc_reg_field_set(unit, VP_GROUP_CHECK_ENABLEr, ®_value, 1177 STG_ENABLEf, 1); 1178 BCM_IF_ERROR_RETURN(WRITE_VP_GROUP_CHECK_ENABLEr(unit, reg_value)); 1179 1180 if (NULL == _bcm_vp_group_ing_mutex[unit]) { 1181 _bcm_vp_group_ing_mutex[unit] = sal_mutex_create("vp group ing mutex"); 1182 if (_bcm_vp_group_ing_mutex[unit] == NULL) { 1183 _bcm_td2p_vp_group_free_resources(unit); 1184 return BCM_E_MEMORY; 1185 } 1186 } 1187 1188 num_vp_groups = soc_mem_field_length(unit, EGR_VLAN_VFI_MEMBERSHIPm, 1189 VP_GROUP_BITMAPf); 1190 VP_GROUP_BK(unit)->num_eg_vp_group = num_vp_groups; 1191 1192 if (NULL == VP_GROUP_BK(unit)->eg_vp_group_array) { 1193 VP_GROUP_BK(unit)->eg_vp_group_array = 1194 sal_alloc(sizeof(_bcm_td2p_vp_group_t) * num_vp_groups, 1195 "egress vp group array"); 1196 if (NULL == VP_GROUP_BK(unit)->eg_vp_group_array) { 1197 _bcm_td2p_vp_group_free_resources(unit); 1198 return BCM_E_MEMORY; 1199 } 1200 } 1201 1202 sal_memset(VP_GROUP_BK(unit)->eg_vp_group_array, 0, 1203 sizeof(_bcm_td2p_vp_group_t) * num_vp_groups); 1204 1205 num_vp = soc_mem_index_count(unit, EGR_DVP_ATTRIBUTEm); 1206 1207 for (i = 0; i < num_vp_groups; i++) { 1208 if (NULL == EG_VP_GROUP(unit, i)->gpp_vp_bitmap) { 1209 EG_VP_GROUP(unit, i)->gpp_vp_bitmap = sal_alloc 1210 (SHR_BITALLOCSIZE(num_gpp + num_vp), 1211 "egress vp group vp gpp bitmap"); 1212 if (NULL == EG_VP_GROUP(unit, i)->gpp_vp_bitmap) { 1213 _bcm_td2p_vp_group_free_resources(unit); 1214 return BCM_E_MEMORY; 1215 } 1216 } 1217 1218 sal_memset(EG_VP_GROUP(unit, i)->gpp_vp_bitmap, 0, 1219 (SHR_BITALLOCSIZE(num_gpp + num_vp))); 1220 1221 if (NULL == EG_VP_GROUP(unit, i)->vlan_vfi_bitmap) { 1222 EG_VP_GROUP(unit, i)->vlan_vfi_bitmap = sal_alloc 1223 (SHR_BITALLOCSIZE(vlan_vfi_count), 1224 "egress vp group vlan vfi bitmap"); 1225 if (NULL == EG_VP_GROUP(unit, i)->vlan_vfi_bitmap) { 1226 _bcm_td2p_vp_group_free_resources(unit); 1227 return BCM_E_MEMORY; 1228 } 1229 } 1230 1231 sal_memset(EG_VP_GROUP(unit, i)->vlan_vfi_bitmap, 0, 1232 SHR_BITALLOCSIZE(vlan_vfi_count)); 1233 } 1234 1235 /* Enables the STG checks and UT deletion on Egress VP Groups */ 1236 reg_value = 0; 1237 soc_reg_field_set(unit, EGR_VP_GROUP_CHECK_ENABLEr, ®_value, 1238 STG_ENABLEf, 1); 1239 soc_reg_field_set(unit, EGR_VP_GROUP_CHECK_ENABLEr, ®_value, 1240 UNTAG_ENABLEf, 1); 1241 BCM_IF_ERROR_RETURN(WRITE_EGR_VP_GROUP_CHECK_ENABLEr(unit, reg_value)); 1242 1243 if (NULL == _bcm_vp_group_egr_mutex[unit]) { 1244 _bcm_vp_group_egr_mutex[unit] = sal_mutex_create("vp group egr mutex"); 1245 if (_bcm_vp_group_egr_mutex[unit] == NULL) { 1246 _bcm_td2p_vp_group_free_resources(unit); 1247 return BCM_E_MEMORY; 1248 } 1249 } 1250 1251 VP_GROUP_BK(unit)->vp_group_initialized = 1; 1252 1253 #ifdef BCM_WARM_BOOT_SUPPORT 1254 if (SOC_WARM_BOOT(unit)) { 1255 rv = _bcm_td2p_vp_group_reinit(unit); 1256 if (BCM_FAILURE(rv)) { 1257 _bcm_td2p_vp_group_free_resources(unit); 1258 } 1259 } 1260 #endif /* BCM_WARM_BOOT_SUPPORT */ 1261 1262 return rv; 1263 } 1264 1265 /* 1266 * Function: 1267 * bcm_td2p_vp_group_detach 1268 * Purpose: 1269 * De-initialize the virtual port group data structures. 1270 * Parameters: 1271 * unit - SOC unit number. 1272 * Returns: 1273 * BCM_E_XXX 1274 */ 1275 int 1276 bcm_td2p_vp_group_detach(int unit) 1277 { 1278 _bcm_td2p_vp_group_free_resources(unit); 1279 1280 VP_GROUP_BK(unit)->vp_group_initialized = 0; 1281 1282 return BCM_E_NONE; 1283 } 1284 1285 /* 1286 * Function: 1287 * bcm_td2p_vlan_vp_group_set 1288 * Purpose: 1289 * set/clear the specified VP group in the vlan's vp group bitmap. 1290 * Parameters: 1291 * unit - (IN) Device Number 1292 * vlan_vpn - (IN) vlan/vpn ID 1293 * egress - (IN) TURE for egress, FALSE for ingress 1294 * vp_group - (IN) the specified VP group 1295 * enable - (IN) TRUE to set, FALSE to clear 1296 * Returns: 1297 * BCM_E_XXX 1298 * Notes: 1299 * If vp_group == -1 and enable == false, clear the vp_group bitmap 1300 */ 1301 1302 int 1303 bcm_td2p_vlan_vp_group_set(int unit, int vlan_vpn, int egress, int vp_group, int enable) 1304 { 1305 int rv = BCM_E_NONE; 1306 int field_len; 1307 int bit_exist; 1308 uint32 profile_idx; 1309 uint32 vp_group_bitmap[2]; 1310 soc_mem_t mbrship_mem; 1311 uint32 mbrship_entry[SOC_MAX_MEM_WORDS]; 1312 1313 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 1314 unit, vlan_vpn, egress, &profile_idx)); 1315 1316 if (egress) { 1317 mbrship_mem = EGR_VLAN_VFI_MEMBERSHIPm; 1318 } else { 1319 mbrship_mem = ING_VLAN_VFI_MEMBERSHIPm; 1320 } 1321 1322 /* safety check */ 1323 field_len = soc_mem_field_length(unit, mbrship_mem, VP_GROUP_BITMAPf); 1324 if (vp_group >= 0) { 1325 if (vp_group >= field_len) { 1326 return BCM_E_PARAM; 1327 } 1328 } else if (enable) { 1329 return BCM_E_PARAM; 1330 } 1331 1332 if (field_len > sizeof(vp_group_bitmap) * 8) { 1333 return BCM_E_INTERNAL; 1334 } 1335 1336 soc_mem_lock(unit, mbrship_mem); 1337 if ((rv = soc_mem_read(unit, mbrship_mem, MEM_BLOCK_ANY, profile_idx, 1338 mbrship_entry)) != BCM_E_NONE) { 1339 soc_mem_unlock(unit, mbrship_mem); 1340 return rv; 1341 } 1342 1343 if (vp_group >= 0) { 1344 soc_mem_field_get(unit, mbrship_mem, mbrship_entry, 1345 VP_GROUP_BITMAPf, vp_group_bitmap); 1346 bit_exist = vp_group_bitmap[vp_group/32] & (1 << (vp_group % 32)); 1347 1348 if (enable) { 1349 if (bit_exist) { 1350 soc_mem_unlock(unit, mbrship_mem); 1351 return BCM_E_NONE; 1352 } 1353 1354 vp_group_bitmap[vp_group/32] |= 1 << (vp_group%32); 1355 } else { 1356 if (!bit_exist) { 1357 soc_mem_unlock(unit, mbrship_mem); 1358 return BCM_E_NONE; 1359 } 1360 1361 /* clear the vp_group */ 1362 vp_group_bitmap[vp_group/32] &= ~(1 << (vp_group%32)); 1363 } 1364 } else { 1365 /* clear the VP group bitmap for this vlan */ 1366 sal_memset(vp_group_bitmap, 0, sizeof(vp_group_bitmap)); 1367 } 1368 1369 soc_mem_field_set(unit, mbrship_mem, mbrship_entry, 1370 VP_GROUP_BITMAPf, vp_group_bitmap); 1371 1372 rv = _bcm_td2p_vlan_vfi_mbrship_profile_entry_set(unit, 1373 vlan_vpn, egress, mbrship_entry); 1374 1375 soc_mem_unlock(unit, mbrship_mem); 1376 1377 return rv; 1378 } 1379 1380 /* 1381 * Function: 1382 * bcm_td2p_vlan_vp_group_get 1383 * Purpose: 1384 * get the flags indicating the given vp group is set for 1385 * ingress or/and egress. 1386 * Parameters: 1387 * unit - (IN) Device Number 1388 * vlan_vpn - (IN) vlan/vpn ID 1389 * egress - (IN) TURE for egress, FALSE for ingress 1390 * vp_group - (IN) the specified VP group 1391 * enable - (OUT) usage flag 1392 * Returns: 1393 * BCM_E_XXX 1394 */ 1395 1396 int 1397 bcm_td2p_vlan_vp_group_get(int unit, int vlan_vpn, int egress, int vp_group, int *enable) 1398 { 1399 uint32 profile_idx; 1400 uint32 vp_group_bitmap[2]; 1401 int field_len; 1402 soc_mem_t mbrship_mem; 1403 uint32 mbrship_entry[SOC_MAX_MEM_WORDS]; 1404 1405 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 1406 unit, vlan_vpn, egress, &profile_idx)); 1407 1408 if (egress) { 1409 mbrship_mem = EGR_VLAN_VFI_MEMBERSHIPm; 1410 } else { 1411 mbrship_mem = ING_VLAN_VFI_MEMBERSHIPm; 1412 } 1413 1414 /* safety check */ 1415 field_len = soc_mem_field_length(unit, mbrship_mem, VP_GROUP_BITMAPf); 1416 if (vp_group >= field_len) { 1417 return BCM_E_PARAM; 1418 } 1419 if (field_len > sizeof(vp_group_bitmap) * 8) { 1420 return BCM_E_INTERNAL; 1421 } 1422 1423 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 1424 mbrship_mem, MEM_BLOCK_ANY, profile_idx, mbrship_entry)); 1425 soc_mem_field_get(unit, mbrship_mem, 1426 (uint32 *)mbrship_entry, VP_GROUP_BITMAPf, vp_group_bitmap); 1427 1428 *enable = 0; 1429 if (vp_group_bitmap[vp_group/32] & (1 << (vp_group % 32))) { 1430 *enable = TRUE; 1431 } 1432 1433 return BCM_E_NONE; 1434 } 1435 1436 /* 1437 * Function: 1438 * _bcm_td2p_vp_local_ports_get 1439 * Purpose: 1440 * Get the local ports on which the given VP resides. 1441 * Parameters: 1442 * unit - (IN) Device Number 1443 * vp - (IN) Virtual port number 1444 * local_port_max - (OUT) Size of local_port_array 1445 * local_port_array - (OUT) Array of local ports 1446 * local_port_count - (OUT) Number of local ports 1447 * Returns: 1448 * BCM_E_XXX 1449 * Notes: 1450 * If local_port_max = 0 and local_port_array == NULL, 1451 * the number of local ports will still be returned in 1452 * local_port_count. 1453 */ 1454 1455 STATIC int 1456 _bcm_td2p_vp_local_ports_get(int unit, int vp, int local_port_max, 1457 bcm_port_t *local_port_array, int *local_port_count) 1458 { 1459 ing_dvp_table_entry_t dvp_entry; 1460 ing_l3_next_hop_entry_t ing_nh; 1461 uint32 nh_index; 1462 bcm_trunk_t trunk_id = -1; 1463 bcm_module_t modid = 0; 1464 bcm_port_t port = 0; 1465 int modid_local; 1466 1467 if (local_port_max < 0) { 1468 return BCM_E_PARAM; 1469 } 1470 1471 if ((local_port_max == 0) && (NULL != local_port_array)) { 1472 return BCM_E_PARAM; 1473 } 1474 1475 if ((local_port_max > 0) && (NULL == local_port_array)) { 1476 return BCM_E_PARAM; 1477 } 1478 1479 if (NULL == local_port_count) { 1480 return BCM_E_PARAM; 1481 } 1482 1483 *local_port_count = 0; 1484 1485 BCM_IF_ERROR_RETURN 1486 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 1487 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 1488 NEXT_HOP_INDEXf); 1489 BCM_IF_ERROR_RETURN (soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, 1490 nh_index, &ing_nh)); 1491 1492 if (soc_feature(unit, soc_feature_generic_dest)) { 1493 uint32 dest_type = SOC_MEM_FIF_DEST_INVALID, dest = 0; 1494 dest = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, &ing_nh, 1495 DESTINATIONf, &dest_type); 1496 if (dest_type == SOC_MEM_FIF_DEST_LAG) { 1497 trunk_id = (dest & SOC_MEM_FIF_DGPP_TGID_MASK); 1498 } else if (dest_type == SOC_MEM_FIF_DEST_DGPP) { 1499 modid = (dest & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 1500 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 1501 port = dest & SOC_MEM_FIF_DGPP_PORT_MASK; 1502 } 1503 } else { 1504 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 1505 trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 1506 } else { 1507 modid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 1508 port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 1509 } 1510 } 1511 1512 if (trunk_id != -1) { 1513 BCM_IF_ERROR_RETURN 1514 (_bcm_esw_trunk_local_members_get(unit, 1515 trunk_id, 1516 local_port_max, 1517 local_port_array, 1518 local_port_count)); 1519 } else { 1520 BCM_IF_ERROR_RETURN 1521 (_bcm_esw_modid_is_local(unit, modid, &modid_local)); 1522 if (TRUE != modid_local) { 1523 *local_port_count = 0; 1524 return BCM_E_NONE; 1525 } 1526 1527 *local_port_count = 1; 1528 if (NULL != local_port_array) { 1529 local_port_array[0] = port; 1530 } 1531 } 1532 1533 return BCM_E_NONE; 1534 } 1535 1536 /* 1537 * Function: 1538 * bcm_td2p_vlan_vp_group_get_all 1539 * Purpose: 1540 * get the array of gports and flags related to the gport. 1541 * Parameters: 1542 * unit - (IN) Device Number 1543 * vlan - (IN) vlan mem entry index 1544 * array_max - (IN) max size of the array 1545 * bcm_gport_t *gport_array - (IN) gport array 1546 * flags_array -(IN) flags array related to gports 1547 * port_cnt - (IN/OUT) point to the first available array entry 1548 * Returns: 1549 * BCM_E_XXX 1550 */ 1551 1552 int 1553 bcm_td2p_vlan_vp_group_get_all( 1554 int unit, /* unit number */ 1555 int vlan, /* index to the vlan memory table */ 1556 int array_max, /* max size of the array */ 1557 bcm_gport_t *gport_array, /* gport array */ 1558 int *flags_array, /* flags array related to gports */ 1559 int *port_cnt) /* point to the first available array entry */ 1560 { 1561 int num_vp_groups; 1562 int vpg; 1563 int ing_enable; 1564 int egr_enable; 1565 int rv = BCM_E_NONE; 1566 1567 num_vp_groups = soc_mem_field_length(unit, ING_VLAN_VFI_MEMBERSHIPm, 1568 VP_GROUP_BITMAPf); 1569 1570 for (vpg = 0; vpg < num_vp_groups; vpg++) { 1571 ing_enable = 0; 1572 egr_enable = 0; 1573 if ((*port_cnt == array_max) && (gport_array || flags_array)) { 1574 break; 1575 } 1576 if (flags_array) { 1577 flags_array[*port_cnt] = 0; 1578 } 1579 if (soc_feature(unit, 1580 soc_feature_vp_group_ingress_vlan_membership) && 1581 bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 1582 rv = bcm_td2p_vlan_vp_group_get(unit,vlan, FALSE, vpg, &ing_enable); 1583 BCM_IF_ERROR_RETURN(rv); 1584 if (ing_enable) { 1585 if (gport_array) { 1586 BCM_GPORT_VP_GROUP_SET(gport_array[*port_cnt],vpg); 1587 } 1588 if (flags_array) { 1589 flags_array[*port_cnt] = BCM_VLAN_PORT_INGRESS_ONLY; 1590 } 1591 } 1592 } 1593 if (soc_feature(unit, 1594 soc_feature_vp_group_egress_vlan_membership) && 1595 bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 1596 rv = bcm_td2p_vlan_vp_group_get(unit,vlan, TRUE, vpg, &egr_enable); 1597 BCM_IF_ERROR_RETURN(rv); 1598 if (egr_enable) { 1599 if (gport_array) { 1600 BCM_GPORT_VP_GROUP_SET(gport_array[*port_cnt],vpg); 1601 } 1602 if (flags_array) { 1603 flags_array[*port_cnt] |= BCM_VLAN_PORT_EGRESS_ONLY; 1604 } 1605 } 1606 } 1607 if (ing_enable || egr_enable) { 1608 (*port_cnt)++; 1609 } 1610 } 1611 return BCM_E_NONE; 1612 } 1613 1614 /* 1615 * Function: 1616 * _bcm_td2p_vp_vlan_vfi_bitmap_get 1617 * Purpose: 1618 * Get a bitmap of all the VLANs the given VP belongs to. 1619 * Parameters: 1620 * unit - (IN) BCM device number 1621 * vp_gport - (IN) VP gport ID 1622 * vlan_vfi_bitmap - (OUT) Bitmap of VLANs 1623 * Returns: 1624 * BCM_E_XXX 1625 */ 1626 STATIC int 1627 _bcm_td2p_vp_vlan_vfi_bitmap_get(int unit, bcm_gport_t vp_gport, SHR_BITDCL *vlan_vfi_bitmap) 1628 { 1629 int rv; 1630 int vp; 1631 int mc_type; 1632 source_vp_entry_t svp_entry; 1633 int vp_group; 1634 egr_dvp_attribute_entry_t egr_dvp_entry; 1635 bcm_port_t local_port; 1636 int local_port_count; 1637 int vlan_vfi_count; 1638 uint8 *vlan_tab_buf = NULL; 1639 uint8 *vfi_tab_buf = NULL; 1640 int if_max, if_count = 0; 1641 bcm_if_t *if_array = NULL; 1642 int i, j, k; 1643 vlan_tab_entry_t *vlan_tab_entry = NULL; 1644 vfi_entry_t *vfi_entry = NULL; 1645 int mc_index_array[3]; 1646 int match_prev_mc_index = FALSE; 1647 bcm_multicast_t group; 1648 bcm_gport_t local_gport; 1649 bcm_if_t encap_id; 1650 int match = FALSE; 1651 bcm_trunk_member_t *member_array = NULL; 1652 int member_count, member_max; 1653 bcm_trunk_chip_info_t trunk_chip_info; 1654 SHR_BITDCL *vlan_vfi_bitmap_tmp = NULL; 1655 1656 if(vlan_vfi_bitmap == NULL) { 1657 return BCM_E_PARAM; 1658 } 1659 1660 if (BCM_GPORT_IS_VLAN_PORT(vp_gport)) { 1661 vp = BCM_GPORT_VLAN_PORT_ID_GET(vp_gport); 1662 mc_type = _BCM_MULTICAST_TYPE_VLAN; 1663 } else if (BCM_GPORT_IS_NIV_PORT(vp_gport)) { 1664 vp = BCM_GPORT_NIV_PORT_ID_GET(vp_gport); 1665 mc_type = _BCM_MULTICAST_TYPE_NIV; 1666 } else if (BCM_GPORT_IS_EXTENDER_PORT(vp_gport)) { 1667 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(vp_gport); 1668 mc_type = _BCM_MULTICAST_TYPE_EXTENDER; 1669 } else if (BCM_GPORT_IS_VXLAN_PORT(vp_gport)) { 1670 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vp_gport); 1671 mc_type = _BCM_MULTICAST_TYPE_VXLAN; 1672 } else if (BCM_GPORT_IS_FLOW_PORT(vp_gport)) { 1673 vp = BCM_GPORT_FLOW_PORT_ID_GET(vp_gport); 1674 mc_type = _BCM_MULTICAST_TYPE_FLOW; 1675 } else if (BCM_GPORT_IS_L2GRE_PORT(vp_gport)) { 1676 vp = BCM_GPORT_L2GRE_PORT_ID_GET(vp_gport); 1677 mc_type = _BCM_MULTICAST_TYPE_L2GRE; 1678 } else if (BCM_GPORT_IS_MIM_PORT(vp_gport)) { 1679 vp = BCM_GPORT_MIM_PORT_ID_GET(vp_gport); 1680 mc_type = _BCM_MULTICAST_TYPE_MIM; 1681 } else if (BCM_GPORT_IS_MPLS_PORT(vp_gport)) { 1682 vp = BCM_GPORT_MPLS_PORT_ID_GET(vp_gport); 1683 mc_type = _BCM_MULTICAST_TYPE_VPLS; 1684 } else if (BCM_GPORT_IS_TRUNK(vp_gport)) { 1685 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_tid_to_vp_lag_vp( 1686 unit, BCM_GPORT_TRUNK_GET(vp_gport), &vp)); 1687 /* there is no need to set mc_type for vplag */ 1688 mc_type = 0; 1689 } else { 1690 return BCM_E_PARAM; 1691 } 1692 1693 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 1694 1695 /* Check if VP already belongs to a VP group. 1696 * If so, just return the VP group's VLAN bitmap. 1697 */ 1698 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 1699 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 1700 if (VP_FILTER_VP_GRP_BMAP == 1701 soc_SOURCE_VPm_field32_get(unit, &svp_entry, ENABLE_IFILTERf)) { 1702 vp_group = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 1703 VLAN_MEMBERSHIP_PROFILEf); 1704 sal_memcpy(vlan_vfi_bitmap, 1705 ING_VP_GROUP(unit, vp_group)->vlan_vfi_bitmap, 1706 SHR_BITALLOCSIZE(vlan_vfi_count)); 1707 return BCM_E_NONE; 1708 } 1709 } 1710 1711 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 1712 soc_field_t en_efilter_f; 1713 soc_field_t vm_prof_f; 1714 BCM_IF_ERROR_RETURN 1715 (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, &egr_dvp_entry)); 1716 1717 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get(unit, 1718 &egr_dvp_entry, EN_EFILTERf, &en_efilter_f)); 1719 1720 if (VP_FILTER_VP_GRP_BMAP == 1721 soc_EGR_DVP_ATTRIBUTEm_field32_get( 1722 unit, &egr_dvp_entry, en_efilter_f)) { 1723 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get(unit, 1724 &egr_dvp_entry, VLAN_MEMBERSHIP_PROFILEf, &vm_prof_f)); 1725 vp_group = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, &egr_dvp_entry, 1726 vm_prof_f); 1727 sal_memcpy(vlan_vfi_bitmap, EG_VP_GROUP(unit, vp_group)->vlan_vfi_bitmap, 1728 SHR_BITALLOCSIZE(vlan_vfi_count)); 1729 return BCM_E_NONE; 1730 } 1731 } 1732 1733 /* need a special process for vp-lag */ 1734 if (BCM_GPORT_IS_TRUNK(vp_gport)) { 1735 /* 1 get vp-lag member count max */ 1736 rv = bcm_esw_trunk_chip_info_get(unit, &trunk_chip_info); 1737 VP_GROUP_CLEANUP(rv); 1738 1739 /* 2 alloc member array according to the member count */ 1740 member_max = trunk_chip_info.vp_ports_max; 1741 member_array = sal_alloc(member_max * sizeof(bcm_trunk_member_t), 1742 "member array"); 1743 if (NULL == member_array) { 1744 rv = BCM_E_MEMORY; 1745 goto cleanup; 1746 } 1747 /* 3 get member array */ 1748 rv = bcm_esw_trunk_get(unit, BCM_GPORT_TRUNK_GET(vp_gport), NULL, 1749 member_max, member_array, &member_count); 1750 VP_GROUP_CLEANUP(rv); 1751 1752 /* 4 alloc vlan bitmap tmp */ 1753 vlan_vfi_bitmap_tmp = sal_alloc(SHR_BITALLOCSIZE(vlan_vfi_count), 1754 "vlan bitmap tmp"); 1755 if (NULL == vlan_vfi_bitmap_tmp) { 1756 rv = BCM_E_MEMORY; 1757 goto cleanup; 1758 } 1759 1760 /* 5 get each member vlan bitmap, then or them together */ 1761 for (i = 0; i < member_count; i++) { 1762 sal_memset(vlan_vfi_bitmap_tmp, 0, SHR_BITALLOCSIZE(vlan_vfi_count)); 1763 rv = _bcm_td2p_vp_vlan_vfi_bitmap_get( 1764 unit, member_array[i].gport, vlan_vfi_bitmap_tmp); 1765 VP_GROUP_CLEANUP(rv); 1766 1767 SHR_BITOR_RANGE(vlan_vfi_bitmap_tmp, 1768 vlan_vfi_bitmap, 0, vlan_vfi_count, vlan_vfi_bitmap); 1769 } 1770 1771 return BCM_E_NONE; 1772 } 1773 1774 /* VP does not belong to any VP group. Need to derive VLAN bitmap by 1775 * searching through each VLAN table entry's BC_IDX/UMC_IDX/UUC_IDX 1776 * multicast groups to see if VP belongs to their VP replication lists. 1777 */ 1778 1779 /* Get one local port on which the VP resides. 1780 * Even if the VP resides on a trunk group, only one trunk 1781 * member is needed since all members of a trunk group 1782 * have the same VP replication list. 1783 */ 1784 BCM_IF_ERROR_RETURN(_bcm_td2p_vp_local_ports_get(unit, 1785 vp, 1, &local_port, &local_port_count)); 1786 if (local_port_count == 0) { 1787 return BCM_E_PORT; 1788 } 1789 1790 vlan_tab_buf = soc_cm_salloc(unit, 1791 SOC_MEM_TABLE_BYTES(unit, VLAN_TABm), "VLAN_TAB buffer"); 1792 if (NULL == vlan_tab_buf) { 1793 rv = BCM_E_MEMORY; 1794 goto cleanup; 1795 } 1796 1797 rv = soc_mem_read_range(unit, VLAN_TABm, MEM_BLOCK_ANY, 1798 0, BCM_VLAN_MAX, vlan_tab_buf); 1799 VP_GROUP_CLEANUP(rv); 1800 1801 vfi_tab_buf = soc_cm_salloc(unit, 1802 SOC_MEM_TABLE_BYTES(unit, VFIm), "VFI buffer"); 1803 if (NULL == vfi_tab_buf) { 1804 rv = BCM_E_MEMORY; 1805 goto cleanup; 1806 } 1807 1808 1809 if (SOC_IS_MONTEREY(unit)) { 1810 rv = soc_mem_read_range(unit, VFIm, MEM_BLOCK_ANY, 1811 0, BCM_MN_VPN_MAX, vfi_tab_buf); 1812 } else { 1813 rv = soc_mem_read_range(unit, VFIm, MEM_BLOCK_ANY, 1814 0, BCM_VPN_MAX, vfi_tab_buf); 1815 } 1816 VP_GROUP_CLEANUP(rv); 1817 1818 if_max = soc_mem_index_count(unit, ING_L3_NEXT_HOPm); 1819 if_array = sal_alloc(sizeof(bcm_if_t) * if_max, "if_array"); 1820 if (NULL == if_array) { 1821 rv = BCM_E_MEMORY; 1822 goto cleanup; 1823 } 1824 sal_memset(if_array, 0, sizeof(bcm_if_t) * if_max); 1825 1826 SHR_BITCLR_RANGE(vlan_vfi_bitmap, 0, vlan_vfi_count); 1827 1828 for (i = 0; i < vlan_vfi_count; i++) { 1829 if (i < BCM_VLAN_COUNT) { 1830 vlan_tab_entry = soc_mem_table_idx_to_pointer 1831 (unit, VLAN_TABm, vlan_tab_entry_t *, vlan_tab_buf, i); 1832 1833 if (0 == soc_VLAN_TABm_field32_get(unit, vlan_tab_entry, 1834 VALIDf)) { 1835 continue; 1836 } 1837 1838 if (0 == soc_VLAN_TABm_field32_get(unit, vlan_tab_entry, 1839 VIRTUAL_PORT_ENf)) { 1840 continue; 1841 } 1842 1843 mc_index_array[0] = _bcm_xgs3_vlan_mcast_idx_get( 1844 unit, vlan_tab_entry, BC_IDXf); 1845 mc_index_array[1] = _bcm_xgs3_vlan_mcast_idx_get( 1846 unit, vlan_tab_entry, UMC_IDXf); 1847 mc_index_array[2] = _bcm_xgs3_vlan_mcast_idx_get( 1848 unit, vlan_tab_entry, UUC_IDXf); 1849 } else { 1850 if (!_bcm_vfi_used_get(unit, (i-BCM_VLAN_COUNT), _bcmVfiTypeAny)) { 1851 continue; 1852 } 1853 1854 vfi_entry = soc_mem_table_idx_to_pointer 1855 (unit, VFIm, vfi_entry_t *, vfi_tab_buf, (i-BCM_VLAN_COUNT)); 1856 1857 if (soc_VFIm_field32_get(unit, vfi_entry, PT2PT_ENf)){ 1858 continue; 1859 } 1860 #if defined(BCM_TRIDENT3_SUPPORT) 1861 if (soc_feature(unit, soc_feature_generic_dest)) { 1862 uint32 dt; 1863 1864 mc_index_array[0] = soc_mem_field32_dest_get(unit, VFIm, 1865 vfi_entry, BC_DESTINATIONf, &dt); 1866 if (dt != SOC_MEM_FIF_DEST_IPMC) { 1867 rv = BCM_E_INTERNAL; 1868 } 1869 mc_index_array[1] = soc_mem_field32_dest_get(unit, VFIm, 1870 vfi_entry, UMC_DESTINATIONf, &dt); 1871 if (dt != SOC_MEM_FIF_DEST_IPMC) { 1872 rv = BCM_E_INTERNAL; 1873 } 1874 mc_index_array[2] = soc_mem_field32_dest_get(unit, VFIm, 1875 vfi_entry, UUC_DESTINATIONf, &dt); 1876 if (dt != SOC_MEM_FIF_DEST_IPMC) { 1877 rv = BCM_E_INTERNAL; 1878 } 1879 1880 VP_GROUP_CLEANUP(rv); 1881 } else 1882 #endif 1883 { 1884 mc_index_array[0] = soc_VFIm_field32_get(unit, vfi_entry, BC_INDEXf); 1885 mc_index_array[1] = soc_VFIm_field32_get(unit, vfi_entry, UMC_INDEXf); 1886 mc_index_array[2] = soc_VFIm_field32_get(unit, vfi_entry, UUC_INDEXf); 1887 } 1888 } 1889 1890 for (j = 0; j < 3; j++) { 1891 1892 /* Check if the same mc_index was already searched */ 1893 match_prev_mc_index = FALSE; 1894 for (k = j - 1; k >= 0; k--) { 1895 if (mc_index_array[j] == mc_index_array[k]) { 1896 match_prev_mc_index = TRUE; 1897 break; 1898 } 1899 } 1900 if (match_prev_mc_index) { 1901 /* continue to next mc_index */ 1902 continue; 1903 } 1904 1905 /* Get VP replication list for (mc_index, local_port) */ 1906 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_index_array[j], 1907 local_port, if_max, if_array, &if_count); 1908 VP_GROUP_CLEANUP(rv); 1909 1910 /* Get VP's encap_id */ 1911 _BCM_MULTICAST_GROUP_SET(group, mc_type, mc_index_array[j]); 1912 rv = bcm_esw_port_gport_get(unit, local_port, &local_gport); 1913 VP_GROUP_CLEANUP(rv); 1914 1915 if (BCM_GPORT_IS_VLAN_PORT(vp_gport)) { 1916 rv = bcm_esw_multicast_vlan_encap_get(unit, group, 1917 local_gport, vp_gport, &encap_id); 1918 } else if (BCM_GPORT_IS_NIV_PORT(vp_gport)) { 1919 rv = bcm_esw_multicast_niv_encap_get(unit, group, 1920 local_gport, vp_gport, &encap_id); 1921 } else if (BCM_GPORT_IS_EXTENDER_PORT(vp_gport)) { 1922 rv = bcm_esw_multicast_extender_encap_get(unit, group, 1923 local_gport, vp_gport, &encap_id); 1924 } else if (BCM_GPORT_IS_VXLAN_PORT(vp_gport)) { 1925 rv = bcm_esw_multicast_vxlan_encap_get(unit, group, 1926 local_gport, vp_gport, &encap_id); 1927 } 1928 #if 0 1929 else if (BCM_GPORT_IS_FLOW_PORT(vp_gport)) { 1930 rv = bcm_esw_multicast_flow_encap_get(unit, group, 1931 local_gport, vp_gport, &encap_id); 1932 } 1933 #endif 1934 else if (BCM_GPORT_IS_MIM_PORT(vp_gport)) { 1935 rv = bcm_esw_multicast_mim_encap_get(unit, group, 1936 local_gport, vp_gport, &encap_id); 1937 } 1938 VP_GROUP_CLEANUP(rv); 1939 1940 /* Search for VP's encap_id in if_array */ 1941 match = FALSE; 1942 for (k = 0; k < if_count; k++) { 1943 if (encap_id == if_array[k]) { 1944 match = TRUE; 1945 break; 1946 } 1947 } 1948 if (match) { 1949 break; 1950 } 1951 } 1952 1953 if (match) { 1954 /* VP belongs to this VLAN */ 1955 SHR_BITSET(vlan_vfi_bitmap, i); 1956 } 1957 } 1958 1959 cleanup: 1960 if (vlan_tab_buf) { 1961 soc_cm_sfree(unit, vlan_tab_buf); 1962 } 1963 if (vfi_tab_buf) { 1964 soc_cm_sfree(unit, vfi_tab_buf); 1965 } 1966 if (if_array) { 1967 sal_free(if_array); 1968 } 1969 if (vlan_vfi_bitmap_tmp) { 1970 sal_free(vlan_vfi_bitmap_tmp); 1971 } 1972 if (member_array) { 1973 sal_free(member_array); 1974 } 1975 return rv; 1976 } 1977 1978 /* 1979 * Function: 1980 * _bcm_td2p_vlan_vfi_mbrship_profile_entry_set 1981 * Purpose: 1982 * Given a VLAN/VFI value and a direction (Igr/Egr), set the 1983 * data associated with a profile entry and update the VLAN/VFI 1984 * with a new profile index 1985 * Parameters: 1986 * unit - (IN) BCM device number 1987 * vlan_vpn - (IN) VLAN/VPN ID 1988 * egress - (IN) If TRUE, VP handling is for egress, else ingress. 1989 * entry_data - (IN) Entry to write 1990 * Returns: 1991 * BCM_E_XXX 1992 */ 1993 1994 STATIC int 1995 _bcm_td2p_vlan_vfi_mbrship_profile_entry_set(int unit, 1996 bcm_vlan_t vlan_vpn, 1997 int egress, 1998 void *entry_data) 1999 { 2000 uint32 cur_prof_index = 0, new_prof_index = 0; 2001 2002 /* Get the profile_idx associated with the VLAN/VFI */ 2003 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 2004 unit, vlan_vpn, egress, &cur_prof_index)); 2005 2006 BCM_IF_ERROR_RETURN(_bcm_vlan_vfi_membership_profile_entry_op( 2007 unit, &entry_data, 1, TRUE, egress, &new_prof_index)); 2008 /* Write the new index into the VALN/VFI tables */ 2009 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_set( 2010 unit, vlan_vpn, egress, new_prof_index)); 2011 2012 /* 2013 * If the old-profile-index entry is not default, delete it, note that if the 2014 * same index is reallocated, the profile-mgmt would have incremented the 2015 * ref-count anyway. 2016 */ 2017 if(cur_prof_index != 0 && cur_prof_index != 1) { 2018 BCM_IF_ERROR_RETURN(_bcm_vlan_vfi_membership_profile_entry_op( 2019 unit, NULL, 1, FALSE, egress, &cur_prof_index)); 2020 2021 } 2022 2023 return BCM_E_NONE; 2024 } 2025 2026 /* 2027 * Function: 2028 * _bcm_td2p_vlan_vpn_mbrship_profile_get 2029 * Purpose: 2030 * Per direction get membership profile of the given vlan/vpn. 2031 * Parameters: 2032 * unit - (IN) BCM device number 2033 * vlan_vpn - (IN) VLAN/VPN ID 2034 * egress - (IN) If TRUE, VP handling is for egress, else ingress. 2035 * prof_index - (OUT) The associated profile index if all goes well 2036 * Returns: 2037 * BCM_E_XXX 2038 */ 2039 2040 STATIC int 2041 _bcm_td2p_vlan_vpn_mbrship_profile_get(int unit, 2042 bcm_vlan_t vlan_vpn, 2043 int egress, 2044 uint32 *prof_index) 2045 { 2046 int index; 2047 soc_mem_t mem; 2048 uint32 vlan_vfi_entry[SOC_MAX_MEM_WORDS]; 2049 2050 if(prof_index == NULL) { 2051 return BCM_E_PARAM; 2052 } 2053 2054 if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 2055 if (egress) { 2056 mem = EGR_VFIm; 2057 } else { 2058 mem = VFIm; 2059 } 2060 2061 _BCM_VPN_GET(index, _BCM_VPN_TYPE_VFI, vlan_vpn); 2062 2063 } else { 2064 if (egress) { 2065 mem = EGR_VLANm; 2066 } else if (SOC_MEM_FIELD_VALID(unit, VLAN_ATTRS_1m, 2067 MEMBERSHIP_PROFILE_PTRf)) { 2068 mem = VLAN_ATTRS_1m; 2069 } else { 2070 mem = VLAN_MPLSm; 2071 } 2072 2073 index = vlan_vpn; 2074 } 2075 2076 /* Read the memory and extract the field in question */ 2077 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 2078 MEM_BLOCK_ANY, index, vlan_vfi_entry)); 2079 2080 /* Assign the profile index */ 2081 *prof_index = soc_mem_field32_get(unit, mem, vlan_vfi_entry, 2082 MEMBERSHIP_PROFILE_PTRf); 2083 2084 return BCM_E_NONE; 2085 } 2086 2087 /* 2088 * Function: 2089 * _bcm_td2p_vlan_vpn_mbrship_profile_set 2090 * Purpose: 2091 * Per direction set membership profile of the given vlan/vpn. 2092 * Parameters: 2093 * unit - (IN) BCM device number 2094 * vlan_vpn - (IN) VLAN/VPN ID 2095 * egress - (IN) If TRUE, VP handling is for egress, else ingress. 2096 * prof_index - (OUT) The associated profile index if all goes well 2097 * Returns: 2098 * BCM_E_XXX 2099 */ 2100 2101 STATIC int 2102 _bcm_td2p_vlan_vpn_mbrship_profile_set(int unit, 2103 bcm_vlan_t vlan_vpn, 2104 int egress, 2105 int prof_index) 2106 { 2107 int index = -1; 2108 soc_mem_t mem; 2109 2110 /* Depending on VLAN/VFI, write to relevant memories */ 2111 if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 2112 if (egress) { 2113 mem = EGR_VFIm; 2114 } else { 2115 mem = VFIm; 2116 } 2117 2118 /* Index in case of a VFI is the encoded value */ 2119 _BCM_VPN_GET(index, _BCM_VPN_TYPE_VFI, vlan_vpn); 2120 2121 } else { 2122 if (egress) { 2123 mem = EGR_VLANm; 2124 } else if (SOC_MEM_FIELD_VALID(unit, VLAN_ATTRS_1m, 2125 MEMBERSHIP_PROFILE_PTRf)) { 2126 mem = VLAN_ATTRS_1m; 2127 } else { 2128 mem = VLAN_MPLSm; 2129 } 2130 2131 index = vlan_vpn; 2132 } 2133 2134 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2135 mem, index, MEMBERSHIP_PROFILE_PTRf, prof_index)); 2136 2137 if (mem == VLAN_ATTRS_1m && 2138 soc_mem_field_valid(unit, VLAN_TABm, MEMBERSHIP_PROFILE_PTRf)) { 2139 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2140 VLAN_TABm, index, MEMBERSHIP_PROFILE_PTRf, prof_index)); 2141 } 2142 2143 return BCM_E_NONE; 2144 } 2145 2146 /* 2147 * Function: 2148 * _bcm_td2p_vp_group_id_set 2149 * Purpose: 2150 * For a given port, update its vp_group id into relevant memory 2151 * Parameters: 2152 * unit - (IN) BCM device number 2153 * port - (IN) Port in question 2154 * vp_group - (IN) vp_group to update with 2155 * egress - (IN) True if we are dealing with egress 2156 * Returns: 2157 * BCM_E_XXX 2158 */ 2159 STATIC int 2160 _bcm_td2p_vp_group_id_set(int unit, int port, int vp_group, int egress) 2161 { 2162 soc_mem_t port_mem; 2163 soc_field_t mbrship_field; 2164 int index; 2165 egr_dvp_attribute_entry_t egr_dvp_entry; 2166 2167 if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 2168 if (egress) { 2169 port_mem = EGR_GPP_ATTRIBUTESm; 2170 } else { 2171 port_mem = SOURCE_TRUNK_MAP_TABLEm; 2172 } 2173 mbrship_field = VLAN_MEMBERSHIP_PROFILEf; 2174 2175 BCM_IF_ERROR_RETURN(_bcm_td2p_gpp_hw_index_get(unit, port, &index)); 2176 } else { 2177 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &index)); 2178 2179 if (egress) { 2180 port_mem = EGR_DVP_ATTRIBUTEm; 2181 2182 BCM_IF_ERROR_RETURN(READ_EGR_DVP_ATTRIBUTEm( 2183 unit, MEM_BLOCK_ANY, index, &egr_dvp_entry)); 2184 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get(unit, 2185 &egr_dvp_entry, VLAN_MEMBERSHIP_PROFILEf, &mbrship_field)); 2186 } else { 2187 port_mem = SOURCE_VPm; 2188 mbrship_field = VLAN_MEMBERSHIP_PROFILEf; 2189 } 2190 } 2191 2192 /* Modify the group into relevant memory */ 2193 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 2194 unit, port_mem, index, mbrship_field, vp_group)); 2195 2196 return BCM_E_NONE; 2197 } 2198 2199 /* 2200 * Function: 2201 * _bcm_td2p_vp_group_join 2202 * Purpose: 2203 * Given a port and a vlan_vfi bmap, either join and existing 2204 * vp group or create a new group. 2205 * Parameters: 2206 * unit - (IN) BCM device number 2207 * port - (IN) Port number passed in 2208 * vlan_vfi_bmap - (IN) The VLAN/VFI bmap 2209 * stp_state - (IN) STP status 2210 * ut_state - (IN) Vlan untag status 2211 * egress - (IN) Direction, TRUE is egress 2212 * vp_group - (OUT) The alloted vp_group num, if all goes well 2213 * Returns: 2214 * BCM_E_XXX 2215 */ 2216 2217 int 2218 _bcm_td2p_vp_group_join(int unit, int port, SHR_BITDCL *vlan_vfi_bmap, 2219 int stp_state, int ut_state, int egress, int *vp_group) 2220 { 2221 int rv = BCM_E_NONE; 2222 int i; 2223 int vpg; 2224 int gport; 2225 int port_offset = 0; 2226 int vlan_vfi_count; 2227 int num_grps = 0, vlan_count = 0; 2228 int stg, vlan_vfi, vlan_vpn; 2229 _bcm_td2p_vp_group_t *vp_grp_array = NULL; 2230 2231 if (vlan_vfi_bmap == NULL) 2232 { 2233 return BCM_E_PARAM; 2234 } 2235 2236 VP_GROUP_LOCK_MEMS(unit, egress); 2237 /* Get the data pertaining to Ingress/Egress */ 2238 if(egress) { 2239 num_grps = VP_GROUP_BK(unit)->num_eg_vp_group; 2240 vp_grp_array = EG_VP_GROUP(unit, 0); 2241 } else { 2242 num_grps = VP_GROUP_BK(unit)->num_ing_vp_group; 2243 vp_grp_array = ING_VP_GROUP(unit, 0); 2244 } 2245 2246 /* Set the vp_group_num to invalid to start with */ 2247 vpg = _BCM_INVALID_VP_GROUP; 2248 SHR_BITCOUNT_RANGE(vlan_vfi_bmap, vlan_count, 0, BCM_VLAN_COUNT); 2249 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 2250 #if defined(BCM_TRIDENT3_SUPPORT) 2251 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 2252 SHR_BITCOUNT_RANGE(vlan_vfi_bmap, vlan_count, 0, vlan_vfi_count); 2253 } 2254 #endif 2255 /* Run through all vp groups to get a matched/new one */ 2256 for (i = 0; i < num_grps; i++) { 2257 if (vp_grp_array[i].gpp_vp_count > 0 && 2258 SHR_BITEQ_RANGE(vlan_vfi_bmap, 2259 vp_grp_array[i].vlan_vfi_bitmap, 0, vlan_vfi_count)) { 2260 2261 if (vp_grp_array[i].stp_state != stp_state) { 2262 continue; 2263 } 2264 if (egress && vlan_count) { 2265 if (vp_grp_array[i].ut_state != ut_state) { 2266 continue; 2267 } 2268 } 2269 vpg = i; 2270 break; 2271 } else { 2272 if (vp_grp_array[i].gpp_vp_count == 0 && 2273 vpg == _BCM_INVALID_VP_GROUP) { 2274 2275 vpg = i; 2276 } 2277 } 2278 } 2279 2280 *vp_group = vpg; 2281 2282 if (vpg == _BCM_INVALID_VP_GROUP) { 2283 VP_GROUP_UNLOCK_MEMS(unit, egress); 2284 return BCM_E_RESOURCE; 2285 } 2286 2287 if (vp_grp_array[vpg].gpp_vp_count == 0) { 2288 vp_grp_array[vpg].stp_state = stp_state; 2289 vp_grp_array[vpg].ut_state = ut_state; 2290 sal_memcpy(vp_grp_array[vpg].vlan_vfi_bitmap, 2291 vlan_vfi_bmap, SHR_BITALLOCSIZE(vlan_vfi_count)); 2292 2293 /* Update EGR_VLAN table's VP_GROUP_BITMAP field */ 2294 SHR_BIT_ITER(vlan_vfi_bmap, vlan_vfi_count, vlan_vfi) { 2295 if(vlan_vfi < BCM_VLAN_COUNT) { 2296 vlan_vpn = vlan_vfi; 2297 2298 if (egress && ut_state) { 2299 rv = bcm_td2p_vp_group_ut_state_set(unit, vlan_vpn, vpg, 2300 ut_state); 2301 if (BCM_FAILURE(rv)) { 2302 VP_GROUP_UNLOCK_MEMS(unit, egress); 2303 return rv; 2304 } 2305 } 2306 } else { 2307 _BCM_VPN_SET(vlan_vpn, _BCM_VPN_TYPE_VFI, 2308 (vlan_vfi - BCM_VLAN_COUNT)); 2309 #if defined(BCM_TRIDENT3_SUPPORT) 2310 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm) && 2311 egress && ut_state) { 2312 rv = bcm_td2p_vp_group_ut_state_set(unit, vlan_vpn, vpg, 2313 ut_state); 2314 if (BCM_FAILURE(rv)) { 2315 VP_GROUP_UNLOCK_MEMS(unit, egress); 2316 return rv; 2317 } 2318 } 2319 #endif 2320 } 2321 2322 rv = bcm_td2p_vlan_vp_group_set(unit, vlan_vpn, egress, vpg, TRUE); 2323 if (BCM_FAILURE(rv)) { 2324 VP_GROUP_UNLOCK_MEMS(unit, egress); 2325 return rv; 2326 } 2327 2328 rv = bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan_vpn, egress, 2329 &stg); 2330 if (BCM_FAILURE(rv)) { 2331 VP_GROUP_UNLOCK_MEMS(unit, egress); 2332 return rv; 2333 } 2334 2335 if(stg != BCM_STG_DEFAULT) { 2336 BCM_GPORT_VP_GROUP_SET(gport, vpg); 2337 rv = bcm_td2p_vp_group_stp_state_set(unit, stg, gport, egress, 2338 stp_state); 2339 if (BCM_FAILURE(rv)) { 2340 VP_GROUP_UNLOCK_MEMS(unit, egress); 2341 return rv; 2342 } 2343 } 2344 } 2345 } 2346 2347 rv = _bcm_td2p_vp_group_resolve_port_num(unit, port, &port_offset); 2348 if (BCM_FAILURE(rv)) { 2349 VP_GROUP_UNLOCK_MEMS(unit, egress); 2350 return rv; 2351 } 2352 2353 if (!SHR_BITGET(vp_grp_array[vpg].gpp_vp_bitmap, port_offset)) { 2354 SHR_BITSET(vp_grp_array[vpg].gpp_vp_bitmap, port_offset); 2355 vp_grp_array[vpg].gpp_vp_count++; 2356 } 2357 2358 rv = _bcm_td2p_vp_group_id_set(unit, port, vpg, egress); 2359 if (BCM_FAILURE(rv)) { 2360 VP_GROUP_UNLOCK_MEMS(unit, egress); 2361 return rv; 2362 } 2363 2364 VP_GROUP_UNLOCK_MEMS(unit, egress); 2365 2366 return BCM_E_NONE; 2367 } 2368 2369 /* 2370 * Function: 2371 * _bcm_td2p_vp_group_leave 2372 * Purpose: 2373 * Leave a given VP group 2374 * Parameters: 2375 * unit - (IN) BCM device number 2376 * port - (IN) Front-panel/Gpp/VP port value 2377 * vp_group - (IN) VP Group in question 2378 * egress - (IN) If TRUE, VP handling is for egress, else ingress 2379 * Returns: 2380 * BCM_E_XXX 2381 */ 2382 STATIC int 2383 _bcm_td2p_vp_group_leave(int unit, int port, int vp_group, int egress) 2384 { 2385 int gport; 2386 int vlan_vfi_count; 2387 int stg = 0, port_offset = 0; 2388 int vlan_vfi = 0, vlan_vpn = 0; 2389 _bcm_td2p_vp_group_t *vp_grp = NULL; 2390 2391 /* Get the data pertaining to Ingress/Egress */ 2392 if(egress) { 2393 vp_grp = EG_VP_GROUP(unit, vp_group); 2394 } else { 2395 vp_grp = ING_VP_GROUP(unit, vp_group); 2396 } 2397 2398 if (vp_grp->gpp_vp_count == 0) { 2399 return BCM_E_NONE; 2400 } 2401 2402 BCM_IF_ERROR_RETURN( 2403 _bcm_td2p_vp_group_resolve_port_num(unit, port, &port_offset)); 2404 2405 vp_grp->gpp_vp_count--; 2406 SHR_BITCLR(vp_grp->gpp_vp_bitmap, port_offset); 2407 2408 /* no port use this group, release it */ 2409 if(0 == vp_grp->gpp_vp_count) { 2410 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 2411 2412 /* Run through all VLAN/VFI's and unset this vp_group bit */ 2413 SHR_BIT_ITER(vp_grp->vlan_vfi_bitmap, vlan_vfi_count, vlan_vfi) { 2414 if(vlan_vfi <= BCM_VLAN_MAX) { 2415 vlan_vpn = vlan_vfi; 2416 if (egress) { 2417 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_set(unit, 2418 vlan_vpn, vp_group, _BCM_DEFAULT_UNTAGGED_STATE)); 2419 } 2420 } else { 2421 _BCM_VPN_SET(vlan_vpn, _BCM_VPN_TYPE_VFI, 2422 (vlan_vfi - (BCM_VLAN_MAX+1))); 2423 #if defined(BCM_TRIDENT3_SUPPORT) 2424 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm) && egress) { 2425 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_set(unit, 2426 vlan_vpn, vp_group, _BCM_DEFAULT_UNTAGGED_STATE)); 2427 } 2428 #endif 2429 } 2430 2431 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vp_group_set( 2432 unit, vlan_vpn, egress, vp_group, FALSE)); 2433 2434 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_vlan_vpn_stg_get( 2435 unit, vlan_vpn, egress, &stg)); 2436 2437 if(stg != BCM_STG_DEFAULT) { 2438 BCM_GPORT_VP_GROUP_SET(gport, vp_group); 2439 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_set( 2440 unit, stg, gport, egress, _BCM_DEFAULT_STP_STATE)); 2441 } 2442 } 2443 2444 /* Clear out the vlan_vfi array */ 2445 SHR_BITCLR_RANGE(vp_grp->vlan_vfi_bitmap, 0, vlan_vfi_count); 2446 } 2447 2448 return BCM_E_NONE; 2449 } 2450 2451 /* 2452 * Function: 2453 * bcm_td2p_vp_group_port_move 2454 * Purpose: 2455 * Move GPP/VP from one VP group to another due to add/remove 2456 * of the GPP/VP to/from VLAN. 2457 * Parameters: 2458 * unit - (IN) BCM device number 2459 * gport - (IN) Gpp/VP port value 2460 * vlan_vpn - (IN) vlan/vpn ID 2461 * add - (IN) If TRUE, VP is added to VLAN, else removed from VLAN. 2462 * egress - (IN) If TRUE, VP handling is for egress, else ingress. 2463 * flags - (IN) Flags value 2464 * Returns: 2465 * BCM_E_XXX 2466 */ 2467 int 2468 bcm_td2p_vp_group_port_move(int unit, int gport, bcm_vlan_t vlan_vpn, 2469 int add, int egress, int flags) 2470 { 2471 int rv = BCM_E_NONE; 2472 int index = 0, vlan_vfi_bit = 0; 2473 int old_vp_group = 0, new_vp_group = 0; 2474 int vlan_count, vlan_vfi_count; 2475 int ut_state = 0, filter = 0; 2476 SHR_BITDCL *vlan_vfi_bitmap = NULL; 2477 _bcm_td2p_vp_group_t *cur_vp_grp = NULL; 2478 2479 VP_GROUP_LOCK_MEMS(unit, egress); 2480 2481 /* Get the current vp group associated with this port */ 2482 rv = bcm_td2p_vp_group_port_filter_get( 2483 unit, gport, egress, &old_vp_group, &filter); 2484 if (BCM_FAILURE(rv)) { 2485 goto cleanup; 2486 } 2487 2488 if(BCM_GPORT_IS_SUBPORT_PORT(gport)) { 2489 if (GPP_FILTER_VP_GRP_BMAP != filter) { 2490 rv = BCM_E_DISABLED; 2491 goto cleanup; 2492 } 2493 } else { 2494 if (VP_FILTER_VP_GRP_BMAP != filter) { 2495 rv = BCM_E_DISABLED; 2496 goto cleanup; 2497 } 2498 } 2499 2500 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 2501 vlan_vfi_bitmap = sal_alloc(SHR_BITALLOCSIZE(vlan_vfi_count), "vlan bitmap"); 2502 if (NULL == vlan_vfi_bitmap) { 2503 rv = BCM_E_MEMORY; 2504 goto cleanup; 2505 } 2506 sal_memset(vlan_vfi_bitmap, 0, SHR_BITALLOCSIZE(vlan_vfi_count)); 2507 2508 /* Get the current vlan_vfi bitmap associated with this old_group */ 2509 if (egress) { 2510 cur_vp_grp = EG_VP_GROUP(unit, old_vp_group); 2511 } else { 2512 cur_vp_grp = ING_VP_GROUP(unit, old_vp_group); 2513 } 2514 sal_memcpy(vlan_vfi_bitmap, cur_vp_grp->vlan_vfi_bitmap, 2515 SHR_BITALLOCSIZE(vlan_vfi_count)); 2516 2517 if(_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 2518 #if defined(BCM_TRIDENT3_SUPPORT) 2519 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 2520 if ((flags & BCM_VLAN_GPORT_ADD_UNTAGGED) && egress) { 2521 ut_state = 1; 2522 } else { 2523 ut_state = _BCM_DEFAULT_UNTAGGED_STATE; 2524 } 2525 } 2526 #endif 2527 _BCM_VPN_GET(index, _BCM_VPN_TYPE_VFI, vlan_vpn); 2528 index += BCM_VLAN_COUNT; 2529 } else { 2530 if ((flags & BCM_VLAN_GPORT_ADD_UNTAGGED) && egress) { 2531 ut_state = 1; 2532 } else { 2533 ut_state = _BCM_DEFAULT_UNTAGGED_STATE; 2534 } 2535 2536 index = vlan_vpn; 2537 } 2538 2539 /* Get changing status of the relevant bit*/ 2540 vlan_vfi_bit = SHR_BITGET(vlan_vfi_bitmap, index); 2541 if(!vlan_vfi_bit && !add) { /* VP does not exist in vlan/vfi */ 2542 rv = BCM_E_NOT_FOUND; 2543 goto cleanup; 2544 } 2545 2546 SHR_BITCOUNT_RANGE(vlan_vfi_bitmap, vlan_count, 0, BCM_VLAN_COUNT); 2547 #if defined(BCM_TRIDENT3_SUPPORT) 2548 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 2549 SHR_BITCOUNT_RANGE(vlan_vfi_bitmap, vlan_count, 0, vlan_vfi_count); 2550 } 2551 #endif 2552 if (vlan_vfi_bit && add) { /* vp already exist in vlan/vfi */ 2553 if (egress && vlan_count) { /* check ut status for egress vlan */ 2554 if (ut_state == cur_vp_grp->ut_state) { 2555 goto cleanup; 2556 } 2557 } else { 2558 goto cleanup; 2559 } 2560 } 2561 2562 /* Set or clear the VLAN/VFI */ 2563 if (add) { 2564 SHR_BITSET(vlan_vfi_bitmap, index); 2565 } else { 2566 SHR_BITCLR(vlan_vfi_bitmap, index); 2567 } 2568 2569 rv = _bcm_td2p_vp_group_join(unit, gport, vlan_vfi_bitmap, 2570 cur_vp_grp->stp_state, ut_state, egress, &new_vp_group); 2571 VP_GROUP_CLEANUP(rv); 2572 2573 /* Now leave the previous group, if different from the old one */ 2574 if (old_vp_group != new_vp_group) { 2575 rv = _bcm_td2p_vp_group_leave(unit, gport, old_vp_group, egress); 2576 } 2577 2578 cleanup: 2579 if (vlan_vfi_bitmap) { 2580 sal_free(vlan_vfi_bitmap); 2581 vlan_vfi_bitmap = NULL; 2582 } 2583 2584 VP_GROUP_UNLOCK_MEMS(unit, egress); 2585 2586 return rv; 2587 } 2588 2589 /* 2590 * Function: 2591 * _bcm_td2p_gpp_hw_index_get 2592 * Purpose: 2593 * Given a port and port_type, pass back the absolute value to 2594 * be used within a vp_group in addition to the offset. 2595 * bmap from the group this port is a member of. 2596 * Parameters: 2597 * unit - (IN) BCM device number 2598 * port - (IN) Port number 2599 * egress - (IN) True for egress 2600 * hw_index - (OUT) The hardware index 2601 * Returns: 2602 * BCM_E_XXX 2603 */ 2604 2605 STATIC int 2606 _bcm_td2p_gpp_hw_index_get(int unit, int port, int *hw_index) 2607 { 2608 bcm_trunk_t trunk_id; 2609 bcm_module_t mod_out; 2610 bcm_port_t port_out; 2611 int id; 2612 2613 /* Resolve the port */ 2614 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve( 2615 unit, port, &mod_out, &port_out, &trunk_id, &id)); 2616 2617 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get( 2618 unit, mod_out, port_out, hw_index)); 2619 2620 return BCM_E_NONE; 2621 } 2622 2623 /* 2624 * Function: 2625 * _bcm_td2p_vp_group_resolve_port_num 2626 * Purpose: 2627 * Get absolute offset of port for gpp_vp_bitmap updatation 2628 * Parameters: 2629 * unit - (IN) BCM device number 2630 * port - (IN) Port number passed in . 2631 * port_offset - (OUT) The offset to be used for VP group bmap 2632 * Returns: 2633 * BCM_E_XXX 2634 */ 2635 2636 STATIC int 2637 _bcm_td2p_vp_group_resolve_port_num(int unit, int port, int *port_offset) 2638 { 2639 int vp; 2640 2641 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 2642 BCM_IF_ERROR_RETURN(_bcm_td2p_gpp_hw_index_get(unit, port, port_offset)); 2643 } else { 2644 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &vp)); 2645 2646 /* VP's follow the GPP's, add the offset */ 2647 *port_offset = BCMI_VP_GROUP_VP_OFFSET + vp; 2648 } 2649 2650 return BCM_E_NONE; 2651 } 2652 2653 /* 2654 * Function: 2655 * bcm_td2p_vp_group_port_filter_get 2656 * Purpose: 2657 * Given a access_type and the port value, 2658 * return the current vp_group the entity belongs to. 2659 * Parameters: 2660 * unit - (IN) BCM device number 2661 * port - (IN) Gpp/VP port value 2662 * egress - (IN) If TRUE, VP handling is for egress, else ingress 2663 * vp_group - (OUT) The vp_group associated with the entity 2664 * ifilter - (OUT) The ifilter value 2665 * 2666 * Returns: 2667 * BCM_E_XXX 2668 */ 2669 STATIC int 2670 bcm_td2p_vp_group_port_filter_get(int unit, int port, int egress, int *vp_group, int *filter) 2671 { 2672 int port_index; 2673 soc_mem_t port_mem; 2674 soc_field_t mbrship_field; 2675 soc_field_t filter_field; 2676 uint32 entry[SOC_MAX_MEM_WORDS]; 2677 2678 if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 2679 if (egress) { 2680 port_mem = EGR_GPP_ATTRIBUTESm; 2681 filter_field = EN_EFILTERf; 2682 mbrship_field = VLAN_MEMBERSHIP_PROFILEf; 2683 } else { 2684 port_mem = SOURCE_TRUNK_MAP_TABLEm; 2685 filter_field = EN_IFILTERf; 2686 mbrship_field = VLAN_MEMBERSHIP_PROFILEf; 2687 } 2688 2689 BCM_IF_ERROR_RETURN(_bcm_td2p_gpp_hw_index_get(unit, port, &port_index)); 2690 BCM_IF_ERROR_RETURN( 2691 soc_mem_read(unit, port_mem, MEM_BLOCK_ANY, port_index, &entry)); 2692 2693 *vp_group = soc_mem_field32_get(unit, port_mem, &entry, mbrship_field); 2694 2695 if(egress) { 2696 /* Currently '_bcm_esw_egr_port_tab_set' is defined only for KT2, 2697 when the port handling gets cleaned up, we need to make it 2698 generic and call this LPORT config from there. 2699 */ 2700 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get( 2701 unit, port, EGR_LPORT_PROFILEm, 2702 filter_field, (uint32*)filter)); 2703 } else { 2704 BCM_IF_ERROR_RETURN( 2705 _bcm_esw_port_tab_get(unit, port, filter_field, filter)); 2706 } 2707 } else { 2708 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &port_index)); 2709 2710 if (egress) { 2711 port_mem = EGR_DVP_ATTRIBUTEm; 2712 2713 BCM_IF_ERROR_RETURN(soc_mem_read( 2714 unit, port_mem, MEM_BLOCK_ANY, port_index, &entry)); 2715 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get( 2716 unit, &entry, EN_EFILTERf, &filter_field)); 2717 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get( 2718 unit, &entry, VLAN_MEMBERSHIP_PROFILEf, &mbrship_field)); 2719 } else { 2720 port_mem = SOURCE_VPm; 2721 filter_field = ENABLE_IFILTERf; 2722 mbrship_field = VLAN_MEMBERSHIP_PROFILEf; 2723 2724 BCM_IF_ERROR_RETURN(soc_mem_read( 2725 unit, port_mem, MEM_BLOCK_ANY, port_index, &entry)); 2726 } 2727 2728 *vp_group = soc_mem_field32_get(unit, port_mem, &entry, mbrship_field); 2729 *filter = soc_mem_field32_get(unit, port_mem, &entry, filter_field); 2730 } 2731 2732 return BCM_E_NONE; 2733 } 2734 2735 /* 2736 * Function: 2737 * bcm_td2p_vp_group_port_filter_set 2738 * Purpose: 2739 * Given a access_type and the port value, 2740 * return the current vp_group the entity belongs to. 2741 * Parameters: 2742 * unit - (IN) BCM device number 2743 * access_type - (IN) The data_type which can be FP, GPP/VP or STG 2744 * port - (IN) Gpp/VP port value 2745 * egress - (IN) If TRUE, VP handling is for egress, else ingress 2746 * ifilter - (IN) The ifilter value to set 2747 * 2748 * Returns: 2749 * BCM_E_XXX 2750 */ 2751 STATIC int 2752 bcm_td2p_vp_group_port_filter_set(int unit, int port, int egress, int filter) 2753 { 2754 int port_index; 2755 soc_mem_t port_mem; 2756 soc_field_t filter_field; 2757 uint32 entry[SOC_MAX_MEM_WORDS]; 2758 2759 if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 2760 if (egress) { 2761 filter_field = EN_EFILTERf; 2762 } else { 2763 filter_field = EN_IFILTERf; 2764 } 2765 2766 if (egress) { 2767 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, port, 2768 EGR_LPORT_PROFILEm, filter_field, filter)); 2769 } else { 2770 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, 2771 _BCM_CPU_TABS_NONE, filter_field, filter)); 2772 } 2773 } else { 2774 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &port_index)); 2775 2776 if (egress) { 2777 port_mem = EGR_DVP_ATTRIBUTEm; 2778 2779 BCM_IF_ERROR_RETURN(soc_mem_read( 2780 unit, port_mem, MEM_BLOCK_ANY, port_index, &entry)); 2781 BCM_IF_ERROR_RETURN(_td2p_egr_dvp_attribute_field_name_get( 2782 unit, &entry, EN_EFILTERf, &filter_field)); 2783 } else { 2784 port_mem = SOURCE_VPm; 2785 filter_field = ENABLE_IFILTERf; 2786 2787 BCM_IF_ERROR_RETURN(soc_mem_read( 2788 unit, port_mem, MEM_BLOCK_ANY, port_index, &entry)); 2789 } 2790 2791 soc_mem_field32_set(unit, port_mem, &entry, filter_field, filter); 2792 BCM_IF_ERROR_RETURN( 2793 soc_mem_write(unit, port_mem, MEM_BLOCK_ALL, port_index, &entry)); 2794 } 2795 2796 return BCM_E_NONE; 2797 } 2798 2799 /* 2800 * Function: 2801 * bcm_td2p_vp_group_ut_state_set 2802 * Purpose: 2803 * Given an "EGR-VLAN" and a group, set the UT state. 2804 * 2805 * Parameters: 2806 * unit - (IN) BCM device number 2807 * egr_vlan - (IN) Egress VLAN 2808 * vp_group - (IN) - STP state that the value needs to be set to 2809 * ut_state - (IN) The UT state for the given group on this egr_vlan 2810 * Returns: 2811 * BCM_E_XXX 2812 */ 2813 int 2814 bcm_td2p_vp_group_ut_state_set(int unit, int egr_vlan, int vp_group, int ut_state) 2815 { 2816 uint32 ut_grp_bmap[2]; 2817 egr_vlan_entry_t egr_vlan_entry; 2818 #if defined(BCM_TRIDENT3_SUPPORT) 2819 egr_vlan_vfi_untag_entry_t egr_vlan_vfi; 2820 #endif 2821 int rv = BCM_E_NONE; 2822 2823 #if defined(BCM_TRIDENT3_SUPPORT) 2824 sal_memset(&egr_vlan_vfi, 0, sizeof(egr_vlan_vfi)); 2825 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 2826 BCM_IF_ERROR_RETURN(_bcm_td3_vlan_vfi_profile_entry_get(unit, 2827 egr_vlan, &egr_vlan_vfi)); 2828 soc_mem_field_get(unit, EGR_VLAN_VFI_UNTAGm, (uint32*)&egr_vlan_vfi, 2829 UT_VP_GRP_BITMAPf, ut_grp_bmap); 2830 } else 2831 #endif 2832 { 2833 BCM_IF_ERROR_RETURN(READ_EGR_VLANm(unit, MEM_BLOCK_ANY, 2834 egr_vlan, &egr_vlan_entry)); 2835 soc_EGR_VLANm_field_get(unit, &egr_vlan_entry, 2836 UT_VP_GRP_BITMAPf, ut_grp_bmap); 2837 } 2838 2839 /* Set or clear the relevant group */ 2840 if(ut_state) { 2841 ut_grp_bmap[vp_group / 32] |= (1 << (vp_group % 32)); 2842 } else { 2843 ut_grp_bmap[vp_group / 32] &= ~(1 << (vp_group % 32)); 2844 } 2845 2846 #if defined(BCM_TRIDENT3_SUPPORT) 2847 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 2848 soc_mem_field_set(unit, EGR_VLAN_VFI_UNTAGm, (uint32*)&egr_vlan_vfi, 2849 UT_VP_GRP_BITMAPf, ut_grp_bmap); 2850 _bcm_td3_vlan_vfi_profile_entry_set(unit, egr_vlan, &egr_vlan_vfi); 2851 } else 2852 #endif 2853 { 2854 soc_EGR_VLANm_field_set(unit, &egr_vlan_entry, 2855 UT_VP_GRP_BITMAPf, ut_grp_bmap); 2856 BCM_IF_ERROR_RETURN 2857 (WRITE_EGR_VLANm(unit, MEM_BLOCK_ALL, egr_vlan, &egr_vlan_entry)); 2858 } 2859 2860 return rv; 2861 } 2862 2863 /* 2864 * Function: 2865 * bcm_td2p_vp_group_ut_state_get 2866 * Purpose: 2867 * Given an "VLAN" and a subport, get the port's states. 2868 * 2869 * Parameters: 2870 * unit - (IN) BCM device number 2871 * gport - (IN) Subport port 2872 * vlan - (IN) - vlan 2873 * flags - (OUT) Subport state 2874 * Returns: 2875 * BCM_E_XXX 2876 */ 2877 int 2878 bcm_td2p_vp_group_ut_state_get(int unit, bcm_port_t gport, bcm_vlan_t vlan, int *ut_state) 2879 { 2880 int vp_group = 0, filter = 0; 2881 uint32 ut_grp_bmap[2]; 2882 egr_vlan_entry_t egr_vlan_entry; 2883 egr_vlan_vfi_untag_entry_t egr_vlan_vfi; 2884 uint32 prof_index = 0; 2885 2886 if ((vlan > BCM_VLAN_MAX) && (!SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm))) { 2887 return BCM_E_PARAM; 2888 } 2889 2890 if(BCM_GPORT_IS_VP_GROUP(gport)) { 2891 vp_group = BCM_GPORT_VP_GROUP_GET(gport); 2892 } else { 2893 /* Get vp_group associated with this port */ 2894 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 2895 unit, gport, TRUE, &vp_group, &filter)); 2896 2897 /* Make sure the filter values are set to vp_group */ 2898 if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 2899 if (filter != GPP_FILTER_VP_GRP_BMAP) { 2900 return BCM_E_PARAM; 2901 } 2902 } else { 2903 if (filter != VP_FILTER_VP_GRP_BMAP) { 2904 return BCM_E_PARAM; 2905 } 2906 } 2907 } 2908 2909 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 2910 /* Get the profile_idx associated with the VLAN/VFI */ 2911 #if defined(BCM_TRIDENT3_SUPPORT) 2912 if (SOC_IS_TRIDENT3X(unit)) { 2913 BCM_IF_ERROR_RETURN(_bcm_td3_vlan_vfi_profile_entry_get(unit, 2914 vlan, &egr_vlan_vfi)); 2915 } else 2916 #endif 2917 { 2918 BCM_IF_ERROR_RETURN(READ_EGR_VLANm(unit, MEM_BLOCK_ANY, vlan, &egr_vlan_entry)); 2919 prof_index = soc_mem_field32_get(unit, EGR_VLANm, 2920 &egr_vlan_entry, UNTAG_PROFILE_PTRf); 2921 BCM_IF_ERROR_RETURN 2922 (READ_EGR_VLAN_VFI_UNTAGm(unit, MEM_BLOCK_ANY, prof_index, &egr_vlan_vfi)); 2923 } 2924 soc_EGR_VLAN_VFI_UNTAGm_field_get(unit, &egr_vlan_vfi, UT_VP_GRP_BITMAPf, ut_grp_bmap); 2925 } else { 2926 BCM_IF_ERROR_RETURN(READ_EGR_VLANm(unit, MEM_BLOCK_ANY, vlan, &egr_vlan_entry)); 2927 soc_EGR_VLANm_field_get(unit, &egr_vlan_entry, UT_VP_GRP_BITMAPf, ut_grp_bmap); 2928 } 2929 2930 *ut_state = (ut_grp_bmap[vp_group / 32] & (1 << (vp_group % 32))); 2931 2932 return BCM_E_NONE; 2933 } 2934 2935 /* 2936 * Function: 2937 * bcm_td2p_vp_group_vlan_vpn_stg_set 2938 * Purpose: 2939 * Attach a STG group to vlan/vpn. 2940 * Parameters: 2941 * unit - (IN) BCM device number 2942 * vlan_vpn - (IN) vlan/vpn ID 2943 * egress - (IN) If TRUE, VP handling is for egress, else ingress 2944 * stg - (OUT) The STG for the VLAN 2945 * 2946 * Returns: 2947 * BCM_E_XXX 2948 */ 2949 int 2950 bcm_td2p_vp_group_vlan_vpn_stg_set(int unit, int vlan_vpn, int egress, int stg) 2951 { 2952 int rv = 0; 2953 soc_mem_t mem; 2954 uint32 index = 0; 2955 bcm_vlan_info_t *vi = &vlan_info[unit]; 2956 _bcm_virtual_bookkeeping_t *virtual_info = &_bcm_virtual_bk_info[unit]; 2957 2958 /* Depending on VLAN/VFI and direction, note the memory to use */ 2959 if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 2960 _BCM_VPN_GET(index, _BCM_VPN_TYPE_VFI, vlan_vpn); 2961 if (virtual_info->vfi_bitmap != NULL && 2962 !_bcm_vfi_used_get(unit, index, _bcmVfiTypeAny)) { 2963 return BCM_E_NOT_FOUND; 2964 } 2965 2966 if (!egress) { 2967 mem = VFIm; 2968 } else { 2969 mem = EGR_VFIm; 2970 } 2971 } else { 2972 index = vlan_vpn; 2973 if (vi->init && !SHR_BITGET(vi->bmp.w, vlan_vpn)) { 2974 return BCM_E_NOT_FOUND; 2975 } 2976 2977 if (!egress) { 2978 mem = VLAN_TABm; 2979 } else { 2980 mem = EGR_VLANm; 2981 } 2982 } 2983 2984 rv = soc_mem_field32_modify(unit, mem, index, STGf, stg); 2985 if (BCM_SUCCESS(rv) && 2986 !egress && mem == VLAN_TABm && 2987 SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 2988 rv = soc_mem_field32_modify(unit, VLAN_ATTRS_1m, index, STGf, stg); 2989 } 2990 2991 return rv; 2992 } 2993 2994 /* 2995 * Function: 2996 * bcm_td2p_vp_group_vlan_vpn_stg_get 2997 * Purpose: 2998 * Get stg group id of given vlan/vpn per direction. 2999 * Parameters: 3000 * unit - (IN) BCM device number 3001 * vlan_vpn - (IN) vlan/vpn ID 3002 * egress - (IN) If TRUE, VP handling is for egress, else ingress 3003 * stg - (OUT) The STG for the VLAN 3004 * 3005 * Returns: 3006 * BCM_E_XXX 3007 */ 3008 int 3009 bcm_td2p_vp_group_vlan_vpn_stg_get(int unit, int vlan_vpn, int egress, int *stg) 3010 { 3011 soc_mem_t mem; 3012 uint32 index = 0; 3013 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to read memory entry. */ 3014 bcm_vlan_info_t *vi = &vlan_info[unit]; 3015 _bcm_virtual_bookkeeping_t *virtual_info = &_bcm_virtual_bk_info[unit]; 3016 3017 /* Depending on VLAN/VFI and direction, note the memory to use */ 3018 if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 3019 _BCM_VPN_GET(index, _BCM_VPN_TYPE_VFI, vlan_vpn); 3020 if (virtual_info->vfi_bitmap != NULL && 3021 !_bcm_vfi_used_get(unit, index, _bcmVfiTypeAny)) { 3022 return BCM_E_NOT_FOUND; 3023 } 3024 3025 if (egress) { 3026 mem = EGR_VFIm; 3027 } else { 3028 mem = VFIm; 3029 } 3030 } else { 3031 index = vlan_vpn; 3032 if (vi->init && !SHR_BITGET(vi->bmp.w, vlan_vpn)) { 3033 return BCM_E_NOT_FOUND; 3034 } 3035 3036 if (egress) { 3037 mem = EGR_VLANm; 3038 } else { 3039 mem = VLAN_TABm; 3040 } 3041 } 3042 3043 /* Read the memory location */ 3044 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf)); 3045 /* Assign the stp_state */ 3046 *stg = soc_mem_field32_get(unit, mem, buf, STGf); 3047 3048 return BCM_E_NONE; 3049 } 3050 3051 /* 3052 * Function: 3053 * bcm_td2p_vp_group_stg_move 3054 * Purpose: 3055 * Move FP/GPP/VP from one VP group to another due to add/remove 3056 * Parameters: 3057 * unit - (IN) BCM device number 3058 * port - (IN) Gpp/VP port value 3059 * stg - (IN) STG associated with the call, if the access_type is STG 3060 * stp_state - (IN) - STP state that the value needs to be set to 3061 * egress - (IN) If TRUE, VP handling is for egress, else ingress 3062 * Returns: 3063 * BCM_E_XXX 3064 */ 3065 int 3066 bcm_td2p_vp_group_stg_move(int unit, int stg, int gport, int stp_state, int egress) 3067 { 3068 int rv; 3069 int filter = 0; 3070 int vlan_vfi_count; 3071 int old_vp_group = 0, new_vp_grp = 0; 3072 _bcm_td2p_vp_group_t *cur_vp_grp = NULL; 3073 SHR_BITDCL *vlan_vfi_bmap = NULL; 3074 3075 VP_GROUP_LOCK_MEMS(unit, egress); 3076 3077 /* Get the current vp group associated with this STG group */ 3078 rv = bcm_td2p_vp_group_port_filter_get( 3079 unit, gport, egress, &old_vp_group, &filter); 3080 if (BCM_FAILURE(rv)) { 3081 goto cleanup; 3082 } 3083 3084 if(BCM_GPORT_IS_SUBPORT_PORT(gport)) { 3085 if (GPP_FILTER_VP_GRP_BMAP != filter) { 3086 rv = BCM_E_DISABLED; 3087 goto cleanup; 3088 } 3089 } else { 3090 if (VP_FILTER_VP_GRP_BMAP != filter) { 3091 rv = BCM_E_DISABLED; 3092 goto cleanup; 3093 } 3094 } 3095 3096 if (egress) { 3097 cur_vp_grp = EG_VP_GROUP(unit, old_vp_group); 3098 } else { 3099 cur_vp_grp = ING_VP_GROUP(unit, old_vp_group); 3100 } 3101 3102 if(stp_state == cur_vp_grp->stp_state) { 3103 rv = BCM_E_NONE; 3104 goto cleanup; 3105 } 3106 3107 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 3108 vlan_vfi_bmap = sal_alloc(SHR_BITALLOCSIZE(vlan_vfi_count), "vlan bitmap"); 3109 if (NULL == vlan_vfi_bmap) { 3110 rv = BCM_E_MEMORY; 3111 goto cleanup; 3112 } 3113 sal_memset(vlan_vfi_bmap, 0, SHR_BITALLOCSIZE(vlan_vfi_count)); 3114 3115 if (SHR_BITEQ_RANGE(vlan_vfi_bmap, 3116 cur_vp_grp->vlan_vfi_bitmap, 0, vlan_vfi_count)) { 3117 rv = BCM_E_PARAM; 3118 goto cleanup; 3119 } else { 3120 sal_memcpy(vlan_vfi_bmap, cur_vp_grp->vlan_vfi_bitmap, 3121 SHR_BITALLOCSIZE(vlan_vfi_count)); 3122 } 3123 3124 /* Try and find a group we can re-use */ 3125 rv = _bcm_td2p_vp_group_join(unit, gport, vlan_vfi_bmap, 3126 stp_state, cur_vp_grp->ut_state, egress, &new_vp_grp); 3127 VP_GROUP_CLEANUP(rv); 3128 3129 /* Now leave the previous group, if different from new group */ 3130 if (old_vp_group != new_vp_grp){ 3131 rv = _bcm_td2p_vp_group_leave(unit, gport, old_vp_group, egress); 3132 } 3133 3134 cleanup: 3135 if(vlan_vfi_bmap) { 3136 sal_free(vlan_vfi_bmap); 3137 vlan_vfi_bmap = NULL; 3138 } 3139 VP_GROUP_UNLOCK_MEMS(unit, egress); 3140 3141 return rv; 3142 } 3143 3144 /* 3145 * Function: 3146 * bcm_td2p_vp_group_stp_init 3147 * Purpose: 3148 * Init all vp group stp state for the given stg group. 3149 * Parameters: 3150 * unit - (IN) BCM device number 3151 * stg - (IN) STG associated with the call, if the access_type is STG 3152 * egress - (IN) If TRUE, VP handling is for egress, else ingress 3153 * stp_state - (IN) - STP state the stg-port belongs to 3154 * Returns: 3155 * BCM_E_XXX 3156 */ 3157 int 3158 bcm_td2p_vp_group_stp_init(int unit, int stg, int egress, int stp_state) 3159 { 3160 int rv = BCM_E_NONE; 3161 int vp_group = 0; 3162 int num_grps = 0; 3163 soc_mem_t mem; 3164 uint32 stg_entry[SOC_MAX_MEM_WORDS]; 3165 3166 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)){ 3167 return BCM_E_UNAVAIL; 3168 } 3169 3170 if (egress) { 3171 mem = EGR_VLAN_STGm; 3172 num_grps = soc_mem_field_length(unit, 3173 EGR_VLAN_VFI_MEMBERSHIPm, VP_GROUP_BITMAPf); 3174 } else { 3175 mem = STG_TABm; 3176 num_grps = soc_mem_field_length(unit, 3177 ING_VLAN_VFI_MEMBERSHIPm, VP_GROUP_BITMAPf); 3178 } 3179 3180 soc_mem_lock(unit, mem); 3181 3182 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stg, &stg_entry); 3183 VP_GROUP_CLEANUP(rv); 3184 3185 for (vp_group = 0; vp_group < num_grps; vp_group++) { 3186 soc_mem_field32_set(unit, mem, &stg_entry, 3187 _bcm_vp_group_stp_field[vp_group], stp_state); 3188 } 3189 3190 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, stg, &stg_entry); 3191 3192 cleanup: 3193 soc_mem_unlock(unit, mem); 3194 3195 return rv; 3196 } 3197 3198 /* 3199 * Function: 3200 * bcm_td2p_vp_group_stp_state_set 3201 * Purpose: 3202 * Given a port and a stg, sets it state 3203 * Parameters: 3204 * unit - (IN) BCM device number 3205 * stg - (IN) STG associated with the call, if the access_type is STG 3206 * port - (IN) Port number 3207 * egress - (IN) If TRUE, VP handling is for egress, else ingress 3208 * stp_state - (IN) - STP state the stg-port belongs to 3209 * Returns: 3210 * BCM_E_XXX 3211 */ 3212 int 3213 bcm_td2p_vp_group_stp_state_set(int unit, int stg, int gport, int egress, int stp_state) 3214 { 3215 int rv = BCM_E_NONE; 3216 int vp_group = 0, filter = 0; 3217 soc_mem_t mem; 3218 3219 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)){ 3220 return BCM_E_UNAVAIL; 3221 } 3222 3223 if (egress) { 3224 mem = EGR_VLAN_STGm; 3225 } else { 3226 mem = STG_TABm; 3227 } 3228 3229 if(BCM_GPORT_IS_VP_GROUP(gport)) { 3230 vp_group = BCM_GPORT_VP_GROUP_GET(gport); 3231 } else { 3232 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 3233 unit, gport, egress, &vp_group, &filter)); 3234 } 3235 3236 soc_mem_lock(unit, mem); 3237 3238 rv = soc_mem_field32_modify(unit, mem, stg, 3239 _bcm_vp_group_stp_field[vp_group], stp_state); 3240 3241 soc_mem_unlock(unit, mem); 3242 3243 return rv; 3244 } 3245 3246 /* 3247 * Function: 3248 * bcm_td2p_vp_group_stp_state_get 3249 * Purpose: 3250 * Given a port and a stg, gets its state 3251 * Parameters: 3252 * unit - (IN) BCM device number 3253 * stg - (IN) STG associated with the call, if the access_type is STG 3254 * port - (IN) Port number 3255 * egress - (IN) If TRUE, VP handling is for egress, else ingress 3256 * stp_state - (OUT) - STP state the stg-port belongs to 3257 * Returns: 3258 * BCM_E_XXX 3259 */ 3260 int 3261 bcm_td2p_vp_group_stp_state_get(int unit, int stg, int gport, int egress, int *stp_state) 3262 { 3263 int rv = BCM_E_NONE; 3264 int vp_group = 0, filter = 0; 3265 soc_mem_t mem; 3266 uint32 stg_entry[SOC_MAX_MEM_WORDS]; 3267 3268 if(BCM_GPORT_IS_VP_GROUP(gport)) { 3269 vp_group = BCM_GPORT_VP_GROUP_GET(gport); 3270 } else { 3271 /* Get vp_group associated with this port */ 3272 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 3273 unit, gport, egress, &vp_group, &filter)); 3274 } 3275 3276 if (egress) { 3277 mem = EGR_VLAN_STGm; 3278 } else { 3279 mem = STG_TABm; 3280 } 3281 3282 soc_mem_lock(unit, STG_TABm); 3283 /* Read the relevant entry */ 3284 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stg, &stg_entry); 3285 soc_mem_unlock(unit, STG_TABm); 3286 BCM_IF_ERROR_RETURN(rv); 3287 3288 /* Get the STP state */ 3289 *stp_state = soc_mem_field32_get(unit, mem,&stg_entry, 3290 _bcm_vp_group_stp_field[vp_group]); 3291 3292 return BCM_E_NONE; 3293 } 3294 3295 /* 3296 * Function: 3297 * bcm_td2p_ing_vp_group_vlan_get_all 3298 * Purpose: 3299 * Get all VPs from the VP groups belonging to the given VLAN. 3300 * Parameters: 3301 * unit - (IN) BCM device number 3302 * vlan - (IN) VLAN ID 3303 * gpp_vp_bitmap - (OUT) Bitmap of VPs. 3304 * Returns: 3305 * BCM_E_XXX 3306 */ 3307 int 3308 bcm_td2p_ing_vp_group_vlan_get_all(int unit, bcm_vlan_t vlan, 3309 SHR_BITDCL *gpp_vp_bitmap) 3310 { 3311 vlan_mpls_entry_t vlan_mpls_entry; 3312 ing_vlan_vfi_membership_entry_t vlan_vfi_entry; 3313 uint32 fldbuf[2]; 3314 int i; 3315 uint32 profile_idx; 3316 3317 #if defined(BCM_TRIDENT3_SUPPORT) 3318 if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) { 3319 vlan_attrs_1_entry_t vlan_tab; 3320 SOC_IF_ERROR_RETURN( 3321 READ_VLAN_ATTRS_1m(unit, MEM_BLOCK_ANY, vlan, &vlan_tab)); 3322 profile_idx = soc_VLAN_ATTRS_1m_field32_get(unit, &vlan_tab, 3323 MEMBERSHIP_PROFILE_PTRf); 3324 } else 3325 #endif 3326 { 3327 SOC_IF_ERROR_RETURN 3328 (READ_VLAN_MPLSm(unit, MEM_BLOCK_ANY, vlan, &vlan_mpls_entry)); 3329 soc_VLAN_MPLSm_field_get(unit, &vlan_mpls_entry, MEMBERSHIP_PROFILE_PTRf, 3330 &profile_idx); 3331 } 3332 3333 BCM_IF_ERROR_RETURN 3334 (READ_ING_VLAN_VFI_MEMBERSHIPm(unit, MEM_BLOCK_ANY, profile_idx, 3335 &vlan_vfi_entry)); 3336 soc_ING_VLAN_VFI_MEMBERSHIPm_field_get(unit, &vlan_vfi_entry, 3337 VP_GROUP_BITMAPf, fldbuf); 3338 for (i = 0; i < VP_GROUP_BK(unit)->num_ing_vp_group; i++) { 3339 if (fldbuf[i / 32] & (1 << (i % 32))) { 3340 /* The bit in VP_GROUP_BITMAP that corresponds to 3341 * VP group i is set. Get all VPs in VP group i. 3342 */ 3343 SHR_BITOR_RANGE(gpp_vp_bitmap, ING_VP_GROUP(unit, i)->gpp_vp_bitmap, 3344 0, (BCMI_VP_GROUP_GLP_COUNT + 3345 soc_mem_index_count(unit, SOURCE_VPm)), 3346 gpp_vp_bitmap); 3347 } 3348 } 3349 3350 return BCM_E_NONE; 3351 } 3352 3353 /* 3354 * Function: 3355 * bcm_td2p_eg_vp_group_vlan_get_all 3356 * Purpose: 3357 * Get all VPs from the VP groups belonging to the given VLAN. 3358 * Parameters: 3359 * unit - (IN) BCM device number 3360 * vlan - (IN) VLAN ID 3361 * gpp_vp_bitmap - (OUT) Bitmap of VPs. 3362 * Returns: 3363 * BCM_E_XXX 3364 */ 3365 int 3366 bcm_td2p_eg_vp_group_vlan_get_all(int unit, bcm_vlan_t vlan, 3367 SHR_BITDCL *gpp_vp_bitmap) 3368 { 3369 egr_vlan_entry_t egr_vlan_entry; 3370 egr_vlan_vfi_membership_entry_t vlan_vfi_entry; 3371 uint32 fldbuf[2]; 3372 int i; 3373 uint32 profile_idx; 3374 3375 BCM_IF_ERROR_RETURN 3376 (READ_EGR_VLANm(unit, MEM_BLOCK_ANY, vlan, &egr_vlan_entry)); 3377 soc_EGR_VLANm_field_get(unit, &egr_vlan_entry, MEMBERSHIP_PROFILE_PTRf, 3378 &profile_idx); 3379 3380 BCM_IF_ERROR_RETURN 3381 (READ_EGR_VLAN_VFI_MEMBERSHIPm(unit, MEM_BLOCK_ANY, profile_idx, 3382 &vlan_vfi_entry)); 3383 soc_EGR_VLAN_VFI_MEMBERSHIPm_field_get(unit, &vlan_vfi_entry, 3384 VP_GROUP_BITMAPf, fldbuf); 3385 3386 for (i = 0; i < VP_GROUP_BK(unit)->num_eg_vp_group; i++) { 3387 if (fldbuf[i / 32] & (1 << (i % 32))) { 3388 /* The bit in VP_GROUP_BITMAP that corresponds to 3389 * VP group i is set. Get all VPs in VP group i. 3390 */ 3391 SHR_BITOR_RANGE(gpp_vp_bitmap, EG_VP_GROUP(unit, i)->gpp_vp_bitmap, 3392 0, (BCMI_VP_GROUP_GLP_COUNT + 3393 soc_mem_index_count(unit, SOURCE_VPm)), 3394 gpp_vp_bitmap); 3395 } 3396 } 3397 3398 return BCM_E_NONE; 3399 } 3400 3401 #if defined(BCM_TRX_SUPPORT) 3402 3403 /* 3404 * Function: 3405 * bcm_td2p_vp_group_delete_all 3406 * Purpose: 3407 * Delete all VP groups from the given VLAN. 3408 * Parameters: 3409 * unit - (IN) BCM device number 3410 * vlan - (IN) VLAN ID 3411 * egress - (IN) TRUE for egress, FALSE for ingress 3412 * Returns: 3413 * BCM_E_XXX 3414 */ 3415 int 3416 bcm_td2p_vp_group_delete_all(int unit, bcm_vlan_t vlan_vpn, int egress) 3417 { 3418 uint32 profile_idx; 3419 uint32 fldbuf[2]; 3420 int mod, port, gport; 3421 int grp; 3422 int grp_num; 3423 int gpp_vp; 3424 int gpp_vp_num; 3425 soc_mem_t mbrship_mem; 3426 uint32 mbrship_entry[SOC_MAX_MEM_WORDS]; 3427 _bcm_td2p_vp_group_t *vp_grp = NULL; 3428 3429 if (egress) { 3430 mbrship_mem = EGR_VLAN_VFI_MEMBERSHIPm; 3431 grp_num = VP_GROUP_BK(unit)->num_eg_vp_group; 3432 } else { 3433 mbrship_mem = ING_VLAN_VFI_MEMBERSHIPm; 3434 grp_num = VP_GROUP_BK(unit)->num_ing_vp_group; 3435 } 3436 3437 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 3438 unit, vlan_vpn, egress, &profile_idx)); 3439 3440 if (profile_idx == 0 || profile_idx == 1) { 3441 return BCM_E_NONE; 3442 } 3443 3444 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mbrship_mem, 3445 MEM_BLOCK_ANY, profile_idx, mbrship_entry)); 3446 soc_mem_field_get(unit, mbrship_mem, mbrship_entry, VP_GROUP_BITMAPf, fldbuf); 3447 3448 gpp_vp_num = BCMI_VP_GROUP_GLP_COUNT + soc_mem_index_count(unit, SOURCE_VPm); 3449 3450 SHR_BIT_ITER(fldbuf, grp_num, grp) { /* find vp group used by this VLAN_VFI */ 3451 if (egress) { 3452 vp_grp = EG_VP_GROUP(unit, grp); 3453 } else { 3454 vp_grp = ING_VP_GROUP(unit, grp); 3455 } 3456 3457 /* find GPP/VP used by this vp group */ 3458 SHR_BIT_ITER(vp_grp->gpp_vp_bitmap, gpp_vp_num, gpp_vp) { 3459 if(gpp_vp < BCMI_VP_GROUP_GLP_COUNT) { 3460 /* Compute the (mod, port) for this GPP, 3461 based on the location */ 3462 mod = gpp_vp % 255; 3463 port = gpp_vp - mod; 3464 BCM_GPORT_SUBPORT_PORT_SET(gport, 3465 (((mod & 0xFF) << 0x7) | port )); 3466 } else { 3467 if(_bcm_vp_encode_gport(unit, (gpp_vp-BCMI_VP_GROUP_VP_OFFSET), 3468 &gport) != BCM_E_NONE) { 3469 return BCM_E_INTERNAL; 3470 } 3471 } 3472 3473 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_move(unit, 3474 gport, vlan_vpn, FALSE, egress, 0)); 3475 } 3476 } 3477 3478 return BCM_E_NONE; 3479 } 3480 3481 /* 3482 * Function: 3483 * bcm_td2p_vp_vlan_member_set 3484 * Purpose: 3485 * Set virtual port ingress and egress filter modes. 3486 * Parameters: 3487 * unit - (IN) BCM device number 3488 * gport - (IN) VP gport ID 3489 * flags - (IN) Ingress and egress filter modes. 3490 * Returns: 3491 * BCM_E_XXX 3492 */ 3493 int 3494 bcm_td2p_vp_vlan_member_set(int unit, bcm_gport_t gport, uint32 flags) 3495 { 3496 int rv = BCM_E_NONE; 3497 int vp = -1; 3498 int vlan_vfi_count; 3499 int ing_vpg_managed, egr_vpg_managed; 3500 int old_ifilter = 0, old_efilter = 0; 3501 SHR_BITDCL *vlan_vfi_bitmap = NULL; 3502 int old_ing_vpg = 0, old_egr_vpg = 0, vp_group = 0; 3503 int filter_disable, filter_hash_table, filter_vp_grp; 3504 int filter_vp_not_check = -1; 3505 3506 if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 3507 filter_disable = GPP_FILTER_DISABLE; 3508 filter_hash_table = GPP_FILTER_HASH; 3509 filter_vp_grp = GPP_FILTER_VP_GRP_BMAP; 3510 } else { 3511 filter_disable = VP_FILTER_DISABLE; 3512 filter_hash_table = VP_FILTER_HASH; 3513 filter_vp_grp = VP_FILTER_VP_GRP_BMAP; 3514 filter_vp_not_check = VP_DO_NOT_CHECK; 3515 3516 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &vp)); 3517 3518 if (!BCM_GPORT_IS_TRUNK(gport)) { 3519 int local_port_num; 3520 3521 BCM_IF_ERROR_RETURN(_bcm_td2p_vp_local_ports_get( 3522 unit, vp, 0, NULL, &local_port_num)); 3523 if ((local_port_num == 0) && 3524 (flags & (BCM_PORT_VLAN_MEMBER_INGRESS | BCM_PORT_VLAN_MEMBER_EGRESS))) { 3525 return BCM_E_PORT; 3526 } 3527 } 3528 } 3529 3530 /* Get current filter mode */ 3531 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 3532 unit, gport, FALSE, &old_ing_vpg, &old_ifilter)); 3533 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 3534 unit, gport, TRUE, &old_egr_vpg, &old_efilter)); 3535 3536 if (flags & BCM_PORT_VLAN_MEMBER_VP_DO_NOT_CHECK) { 3537 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) { 3538 if (old_ifilter != filter_vp_not_check) { 3539 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3540 unit, gport, FALSE, filter_vp_not_check)); 3541 } 3542 } else { 3543 if (old_ifilter != filter_disable) { 3544 /* Disable checks */ 3545 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3546 unit, gport, FALSE, filter_disable)); 3547 } 3548 } 3549 3550 if(flags & BCM_PORT_VLAN_MEMBER_EGRESS) { 3551 if (old_efilter != filter_vp_not_check) { 3552 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3553 unit, gport, TRUE, filter_vp_not_check)); 3554 } 3555 } else { 3556 if (old_efilter != filter_disable) { 3557 /* Disable checks */ 3558 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3559 unit, gport, TRUE, filter_disable)); 3560 } 3561 } 3562 } else if (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) { /* hash table */ 3563 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) { 3564 if (old_ifilter != filter_hash_table) { 3565 /* enable hash table */ 3566 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3567 unit, gport, FALSE, filter_hash_table)); 3568 } 3569 } else { 3570 if (old_ifilter != filter_disable) { 3571 /* Disable checks */ 3572 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3573 unit, gport, FALSE, filter_disable)); 3574 } 3575 } 3576 3577 if (flags & BCM_PORT_VLAN_MEMBER_EGRESS) { 3578 if (old_efilter != filter_hash_table) { 3579 /* enable hash table */ 3580 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3581 unit, gport, TRUE, filter_hash_table)); 3582 } 3583 } else { 3584 if (old_efilter != filter_disable) { 3585 /* Disable checks */ 3586 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_set( 3587 unit, gport, TRUE, filter_disable)); 3588 } 3589 } 3590 } else { /* vp group */ 3591 ing_vpg_managed = !bcm_td2p_ing_vp_group_unmanaged_get(unit); 3592 egr_vpg_managed = !bcm_td2p_egr_vp_group_unmanaged_get(unit); 3593 3594 if (((flags & BCM_PORT_VLAN_MEMBER_INGRESS) && 3595 ing_vpg_managed && (old_ifilter != filter_vp_grp)) || 3596 ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 3597 egr_vpg_managed && (old_efilter != filter_vp_grp))) { 3598 vlan_vfi_count = BCM_VLAN_COUNT + soc_mem_index_count(unit, VFIm); 3599 3600 vlan_vfi_bitmap = sal_alloc( 3601 SHR_BITALLOCSIZE(vlan_vfi_count), "vlan bitmap"); 3602 if (NULL == vlan_vfi_bitmap) { 3603 return BCM_E_MEMORY; 3604 } 3605 sal_memset(vlan_vfi_bitmap, 0, 3606 SHR_BITALLOCSIZE(vlan_vfi_count)); 3607 3608 if(!BCM_GPORT_IS_SUBPORT_PORT(gport)) { 3609 rv = _bcm_td2p_vp_vlan_vfi_bitmap_get( 3610 unit, gport, vlan_vfi_bitmap); 3611 VP_GROUP_CLEANUP(rv); 3612 } 3613 } 3614 3615 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) { 3616 if (old_ifilter != filter_vp_grp) { 3617 if (ing_vpg_managed) { 3618 rv = _bcm_td2p_vp_group_join(unit, gport, vlan_vfi_bitmap, 3619 _BCM_DEFAULT_STP_STATE, _BCM_DEFAULT_UNTAGGED_STATE, 3620 FALSE, &vp_group); 3621 VP_GROUP_CLEANUP(rv); 3622 } 3623 3624 /* Enable ingress VP group filtering */ 3625 rv = bcm_td2p_vp_group_port_filter_set( 3626 unit, gport, FALSE, filter_vp_grp); 3627 VP_GROUP_CLEANUP(rv); 3628 } 3629 } else { 3630 if (old_ifilter != filter_disable) { 3631 /* Disable ingress filtering */ 3632 rv = bcm_td2p_vp_group_port_filter_set( 3633 unit, gport, FALSE, filter_disable); 3634 VP_GROUP_CLEANUP(rv); 3635 } 3636 3637 if (filter_vp_grp == old_ifilter) { 3638 if (!bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 3639 /* Remove VP from VP group */ 3640 rv = _bcm_td2p_vp_group_leave(unit, gport, old_ing_vpg, FALSE); 3641 VP_GROUP_CLEANUP(rv); 3642 3643 rv = _bcm_td2p_vp_group_id_set(unit, gport, 0, FALSE); 3644 VP_GROUP_CLEANUP(rv); 3645 } 3646 } 3647 } 3648 3649 if (flags & BCM_PORT_VLAN_MEMBER_EGRESS) { 3650 if (old_efilter != filter_vp_grp) { 3651 if (egr_vpg_managed) { 3652 rv = _bcm_td2p_vp_group_join(unit, gport, vlan_vfi_bitmap, 3653 _BCM_DEFAULT_STP_STATE, _BCM_DEFAULT_UNTAGGED_STATE, 3654 TRUE, &vp_group); 3655 VP_GROUP_CLEANUP(rv); 3656 } 3657 3658 /* Enable ingress VP group filtering */ 3659 rv = bcm_td2p_vp_group_port_filter_set( 3660 unit, gport, TRUE, filter_vp_grp); 3661 VP_GROUP_CLEANUP(rv); 3662 } 3663 } else { 3664 if (old_efilter != filter_disable) { 3665 /* Disable ingress filtering */ 3666 rv = bcm_td2p_vp_group_port_filter_set( 3667 unit, gport, TRUE, filter_disable); 3668 VP_GROUP_CLEANUP(rv); 3669 } 3670 3671 if (filter_vp_grp == old_efilter) { 3672 if (!bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 3673 /* Remove VP from VP group */ 3674 rv = _bcm_td2p_vp_group_leave(unit, gport, old_egr_vpg, TRUE); 3675 VP_GROUP_CLEANUP(rv); 3676 3677 rv = _bcm_td2p_vp_group_id_set(unit, gport, 0, TRUE); 3678 VP_GROUP_CLEANUP(rv); 3679 } 3680 } 3681 } 3682 } 3683 3684 cleanup: 3685 if (vlan_vfi_bitmap) { 3686 sal_free(vlan_vfi_bitmap); 3687 } 3688 3689 return rv; 3690 } 3691 3692 #endif 3693 3694 /* 3695 * Function: 3696 * bcm_td2p_vp_vlan_member_get 3697 * Purpose: 3698 * Get virtual port ingress and egress filter modes. 3699 * Parameters: 3700 * unit - (IN) BCM device number 3701 * gport - (IN) VP gport id 3702 * flags - (OUT) Ingress and egress filter modes. 3703 * Returns: 3704 * BCM_E_XXX 3705 */ 3706 int 3707 bcm_td2p_vp_vlan_member_get(int unit, bcm_gport_t gport, uint32 *flags) 3708 { 3709 int cur_vp_group = 0; 3710 int filter = 0, filter_hash_table, filter_vp_grp, filter_vp_do_not_check=-1; 3711 3712 if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 3713 filter_hash_table = GPP_FILTER_HASH; 3714 filter_vp_grp = GPP_FILTER_VP_GRP_BMAP; 3715 } else { 3716 filter_hash_table = VP_FILTER_HASH; 3717 filter_vp_grp = VP_FILTER_VP_GRP_BMAP; 3718 filter_vp_do_not_check = VP_DO_NOT_CHECK; 3719 } 3720 3721 *flags = 0; 3722 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 3723 unit, gport, FALSE, &cur_vp_group, &filter)); 3724 if (filter == filter_vp_grp) { 3725 *flags = BCM_PORT_VLAN_MEMBER_INGRESS; 3726 } else if (filter == filter_hash_table) { 3727 *flags = BCM_PORT_VLAN_MEMBER_INGRESS | 3728 BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 3729 } else if (filter == filter_vp_do_not_check) { 3730 *flags = BCM_PORT_VLAN_MEMBER_INGRESS | 3731 BCM_PORT_VLAN_MEMBER_VP_DO_NOT_CHECK; 3732 } 3733 3734 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_filter_get( 3735 unit, gport, TRUE, &cur_vp_group, &filter)); 3736 if (filter == filter_vp_grp) { 3737 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 3738 } else if (filter == filter_hash_table) { 3739 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS | 3740 BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 3741 } else if (filter == filter_vp_do_not_check) { 3742 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS | 3743 BCM_PORT_VLAN_MEMBER_VP_DO_NOT_CHECK; 3744 } 3745 3746 return BCM_E_NONE; 3747 } 3748 3749 /* 3750 * Function: 3751 * bcm_td2p_ing_vp_group_unmanaged_get 3752 * Purpose: 3753 * Check if VP group resource is managed by user. If so, user will be 3754 * resposible to assign a VP group to a VP and add the VP group to the 3755 * vlan's VP group bitmap in order to establish the vlan membership. 3756 * Parameters: 3757 * unit - (IN) BCM device number 3758 * Returns: 3759 * TRUE/FALSE 3760 */ 3761 int 3762 bcm_td2p_ing_vp_group_unmanaged_get(int unit) 3763 { 3764 return _bcm_td2p_vp_group_unmanaged[unit].ingress; 3765 } 3766 3767 int 3768 bcm_td2p_egr_vp_group_unmanaged_get(int unit) 3769 { 3770 return _bcm_td2p_vp_group_unmanaged[unit].egress; 3771 } 3772 3773 /* 3774 * Function: 3775 * bcm_td2p_ing_vp_group_unmanaged_set 3776 * Purpose: 3777 * Set whether the VP group resource is managed by user. 3778 * Parameters: 3779 * unit - (IN) BCM device number 3780 unmanaged - (IN) TRUE/FALSE 3781 * Returns: BCM_E_XXX 3782 */ 3783 int 3784 bcm_td2p_ing_vp_group_unmanaged_set(int unit, int flag) 3785 { 3786 int i; 3787 int gpp_vp_count = 0; 3788 3789 /* check if to set the same value */ 3790 if (_bcm_td2p_vp_group_unmanaged[unit].ingress == flag) { 3791 return BCM_E_NONE; 3792 } 3793 3794 /* make sure auto method hasn't kicked in yet */ 3795 if (VP_GROUP_BK(unit)->vp_group_initialized) { 3796 for (i = 0; i < VP_GROUP_BK(unit)->num_ing_vp_group; i++) { 3797 if (0 == ING_VP_GROUP(unit, i)->gpp_vp_count){ 3798 gpp_vp_count++; 3799 } 3800 } 3801 3802 if (gpp_vp_count != VP_GROUP_BK(unit)->num_ing_vp_group) { 3803 LOG_INFO(BSL_LS_BCM_VLAN, 3804 (BSL_META_U(unit, "Unmanaged mode set fails:" 3805 "VP group auto method already started\n"))); 3806 return BCM_E_EXISTS; 3807 } 3808 } 3809 _bcm_td2p_vp_group_unmanaged[unit].ingress = flag; 3810 return BCM_E_NONE; 3811 } 3812 3813 int 3814 bcm_td2p_egr_vp_group_unmanaged_set(int unit, int flag) 3815 { 3816 int i; 3817 int gpp_vp_count = 0; 3818 3819 /* check if to set the same value */ 3820 if (_bcm_td2p_vp_group_unmanaged[unit].egress == flag) { 3821 return BCM_E_NONE; 3822 } 3823 3824 /* make sure auto method hasn't kicked in yet */ 3825 if (VP_GROUP_BK(unit)->vp_group_initialized) { 3826 for (i = 0; i < VP_GROUP_BK(unit)->num_eg_vp_group; i++) { 3827 if (0 == EG_VP_GROUP(unit, i)->gpp_vp_count) { 3828 gpp_vp_count++; 3829 } 3830 } 3831 3832 if (gpp_vp_count != VP_GROUP_BK(unit)->num_eg_vp_group) { 3833 LOG_INFO(BSL_LS_BCM_VLAN, 3834 (BSL_META_U(unit, "Unmanaged mode set fails:" 3835 "VP group auto method already started\n"))); 3836 3837 return BCM_E_EXISTS; 3838 } 3839 } 3840 _bcm_td2p_vp_group_unmanaged[unit].egress = flag; 3841 return BCM_E_NONE; 3842 } 3843 3844 /* 3845 * Function: 3846 * bcm_td2p_dvp_group_validate 3847 * Purpose: 3848 * Check dvp group id valid or not 3849 */ 3850 int 3851 bcm_td2p_dvp_group_validate(int unit, int dvp_group_id) 3852 { 3853 int max_group_id; 3854 3855 max_group_id = (1 << soc_mem_field_length(unit, EGR_DVP_ATTRIBUTEm, 3856 VT_DVP_GROUP_IDf)) - 1; 3857 #ifdef BCM_TRIDENT3_SUPPORT 3858 if (SOC_IS_TRIDENT3X(unit)) { 3859 if (SOC_MEM_FIELD_VALID(unit,EGR_DVP_ATTRIBUTEm,COMMON__VT_DVP_GROUP_IDf)) { 3860 max_group_id = (1 << soc_mem_field_length(unit, EGR_DVP_ATTRIBUTEm, 3861 COMMON__VT_DVP_GROUP_IDf)) - 1; 3862 } else { 3863 return BCM_E_UNAVAIL; 3864 } 3865 } 3866 #endif 3867 if ((dvp_group_id < 0) || (dvp_group_id > max_group_id)) { 3868 return BCM_E_PARAM; 3869 } 3870 3871 return BCM_E_NONE; 3872 } 3873 3874 /* 3875 * Function: 3876 * bcm_td2p_vlan_vfi_mbrship_port_get 3877 * Purpose: 3878 * Read the ING_PORT_BITMAP from a vlan entry. 3879 */ 3880 int 3881 bcm_td2p_vlan_vfi_mbrship_port_get(int unit, 3882 bcm_vlan_t vlan_vpn, int egress, pbmp_t *pbmp) 3883 { 3884 uint32 profile_idx; 3885 soc_mem_t mbrship_mem; 3886 soc_field_t port_field; 3887 uint32 mbrship_entry[SOC_MAX_MEM_WORDS]; 3888 3889 if (egress) { 3890 mbrship_mem = EGR_VLAN_VFI_MEMBERSHIPm; 3891 port_field = PORT_BITMAPf; 3892 } else { 3893 mbrship_mem = ING_VLAN_VFI_MEMBERSHIPm; 3894 port_field = ING_PORT_BITMAPf; 3895 } 3896 3897 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 3898 unit, vlan_vpn, egress, &profile_idx)); 3899 3900 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mbrship_mem, 3901 MEM_BLOCK_ANY, profile_idx, &mbrship_entry)); 3902 3903 soc_mem_pbmp_field_get(unit, mbrship_mem, &mbrship_entry, port_field, pbmp); 3904 3905 return BCM_E_NONE; 3906 } 3907 3908 /* 3909 * Function: 3910 * bcm_td2p_vlan_vpn_membership_delete 3911 * Purpose: 3912 * Delete the VLAN Vfi membership entry. 3913 * Parameters: 3914 * unit - (IN) SOC unit number. 3915 * vlan_vpn - (IN) VLAN/VPN ID. 3916 * Returns: 3917 * BCM_E_XXX 3918 */ 3919 int 3920 bcm_td2p_vlan_vpn_membership_delete(int unit, bcm_vlan_t vlan_vpn) 3921 { 3922 uint32 profile_ptr = 0; 3923 3924 /* Delete ingress vlan_vfi_membership profile */ 3925 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 3926 unit, vlan_vpn, FALSE, &profile_ptr)); 3927 3928 if(profile_ptr != 0 && profile_ptr != 1) { 3929 BCM_IF_ERROR_RETURN(_bcm_vlan_vfi_membership_profile_entry_op( 3930 unit, NULL, 1, FALSE, FALSE, &profile_ptr)); 3931 } 3932 3933 /* Delete egress vlan_vfi_membership profile */ 3934 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 3935 unit, vlan_vpn, TRUE, &profile_ptr)); 3936 3937 if(profile_ptr != 0 && profile_ptr != 1) { 3938 BCM_IF_ERROR_RETURN(_bcm_vlan_vfi_membership_profile_entry_op( 3939 unit, NULL, 1, FALSE, TRUE, &profile_ptr)); 3940 } 3941 3942 return BCM_E_NONE; 3943 } 3944 3945 /* 3946 * Function: 3947 * bcm_td2p_vlan_vfi_mbrship_port_set 3948 * Purpose: 3949 * Program membership port bitmap in vlan vfi membership tables 3950 */ 3951 int 3952 bcm_td2p_vlan_vfi_mbrship_port_set(int unit, bcm_vlan_t vlan_vpn, 3953 int egress, int add, pbmp_t pbmp) 3954 { 3955 uint32 profile_idx; 3956 pbmp_t cur_pbmp; 3957 pbmp_t tmp_pbmp; 3958 soc_mem_t mbrship_mem; 3959 soc_field_t port_field; 3960 uint32 mbrship_entry[SOC_MAX_MEM_WORDS]; 3961 3962 if (egress) { 3963 mbrship_mem = EGR_VLAN_VFI_MEMBERSHIPm; 3964 port_field = PORT_BITMAPf; 3965 } else { 3966 mbrship_mem = ING_VLAN_VFI_MEMBERSHIPm; 3967 port_field = ING_PORT_BITMAPf; 3968 } 3969 3970 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vpn_mbrship_profile_get( 3971 unit, vlan_vpn, egress, &profile_idx)); 3972 3973 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mbrship_mem, 3974 MEM_BLOCK_ANY, profile_idx, &mbrship_entry)); 3975 3976 soc_mem_pbmp_field_get(unit, mbrship_mem, &mbrship_entry, port_field, &cur_pbmp); 3977 BCM_PBMP_ASSIGN(tmp_pbmp, cur_pbmp); 3978 3979 if (add) { 3980 BCM_PBMP_OR(cur_pbmp, pbmp); 3981 } else { 3982 BCM_PBMP_REMOVE(cur_pbmp, pbmp); 3983 } 3984 3985 if (BCM_PBMP_NEQ(tmp_pbmp, cur_pbmp)) { 3986 soc_mem_pbmp_field_set(unit, mbrship_mem, 3987 &mbrship_entry, port_field, &cur_pbmp); 3988 BCM_IF_ERROR_RETURN(_bcm_td2p_vlan_vfi_mbrship_profile_entry_set( 3989 unit, vlan_vpn, egress, &mbrship_entry)); 3990 } 3991 3992 return BCM_E_NONE; 3993 } 3994 3995 /* 3996 * Function: 3997 * bcmi_td2p_vfi_control_params_check 3998 * 3999 * Purpose: 4000 * Verifies if input parameters are valid for the operation on the device 4001 * 4002 * Parameters: 4003 * unit - (IN) BCM device number. 4004 * vid - (IN) Vlan id. 4005 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4006 * control - (IN) Configuration. 4007 * 4008 * Returns: 4009 * BCM_E_PARAM for errorneous inputs 4010 * BCM_E_NONE if all memebers in the structure are legal 4011 */ 4012 STATIC int 4013 bcmi_td2p_vfi_control_params_check(int unit, bcm_vlan_t vid, 4014 uint32 valid_fields, 4015 bcm_vlan_control_vlan_t *control) 4016 { 4017 uint32 supported_flags = 0; 4018 uint32 supported_flags2 = 0; 4019 uint32 supported_fields = 0; 4020 4021 /* 4022 * VFI_PROFILE table in TD2Plus supports only the following fields: 4023 * 4024 * - IPMCV4_L2_ENABLE : Enable IGMP-based L2 lookups for IPMCv4 packets 4025 * - IPMCV6_L2_ENABLE : Enable IGMP-based L2 lookups for IPMCv6 packets 4026 * - L2_NON_UCAST_DROP : Drop all broadcast and multicast packets 4027 * - L2_NON_UCAST_TOCPU: Copy all broadcast and multicast packets to CPU 4028 * - L2_MISS_DROP : Drop unknown unicast traffic, Do not flood. 4029 * - L2_MISS_TOCPU : Copy unknown unicast traffic to the CPU 4030 * - LEARN_DISABLE : Disable learning. 4031 * - EN_IFILTER : Enable membership checks. 4032 */ 4033 4034 /* 4035 * VFI table can be programmed with the following fields: 4036 * 4037 * - VRF : Virtual Routing and Forwarding Instance 4038 * - VFI_CLASS_ID : VFI Class ID for IFP lookup key 4039 * - L3_IIF : Layer3 Incoming Interface to be assigned to the packet 4040 * - UUC_INDEX : Default unknown unicast group for this VFI 4041 * - UMC_INDEX : Default unknown multicast group for this VFI 4042 * - BC_INDEX : Default Multicast group for broadcasting to this VFI 4043 */ 4044 supported_fields = (BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK | 4045 BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK | 4046 BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK | 4047 BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK | 4048 BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK | 4049 BCM_VLAN_CONTROL_VLAN_VRF_MASK); 4050 #if defined(BCM_TRIDENT3_SUPPORT) 4051 if (soc_feature(unit, soc_feature_pvlan_on_vfi)) { 4052 supported_fields |= BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK; 4053 } 4054 #endif 4055 supported_flags = (BCM_VLAN_IP4_MCAST_L2_DISABLE | 4056 BCM_VLAN_IP6_MCAST_L2_DISABLE | 4057 BCM_VLAN_UNKNOWN_UCAST_TOCPU | 4058 BCM_VLAN_UNKNOWN_UCAST_DROP | 4059 BCM_VLAN_NON_UCAST_TOCPU | 4060 BCM_VLAN_NON_UCAST_DROP | 4061 BCM_VLAN_LEARN_DISABLE | 4062 BCM_VLAN_L2_CLASS_ID_ONLY 4063 ); 4064 4065 supported_flags2 = (BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE | 4066 BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE 4067 ); 4068 4069 #if defined(BCM_HELIX5_SUPPORT) 4070 supported_flags2 |= (BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT | 4071 BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT 4072 ); 4073 #endif 4074 4075 if (valid_fields != BCM_VLAN_CONTROL_VLAN_ALL_MASK) { 4076 if ((~supported_fields) & valid_fields) { 4077 return BCM_E_PARAM; 4078 } 4079 } 4080 4081 if ((~supported_flags) & control->flags) { 4082 return BCM_E_PARAM; 4083 } 4084 4085 if ((~supported_flags2) & control->flags2) { 4086 return BCM_E_PARAM; 4087 } 4088 4089 if (control->flags & BCM_VLAN_L2_CLASS_ID_ONLY) { 4090 if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) { 4091 if ((control->if_class < 0) || 4092 (control->if_class > SOC_INTF_CLASS_MAX(unit))) { 4093 return BCM_E_PARAM; 4094 } 4095 } else { 4096 return BCM_E_PARAM; 4097 } 4098 } 4099 4100 if (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) { 4101 if ((control->vrf < 0) || 4102 (control->vrf > SOC_VRF_MAX(unit))) { 4103 return BCM_E_PARAM; 4104 } 4105 } 4106 4107 #if defined(BCM_TRIDENT3_SUPPORT) 4108 if (soc_feature(unit, soc_feature_egr_intf_vlan_vfi_deoverlay)) { 4109 if (control->egress_vlan != BCM_VLAN_NONE) { 4110 return BCM_E_PARAM; 4111 } 4112 } 4113 #endif 4114 4115 VLAN_CHK_ID(unit, control->egress_vlan); 4116 4117 4118 /* 4119 * There is no provision to implicitly map L3 IIFs to VFIs. 4120 * Hence, assigning L3 IIF class id through this API is not allowed. 4121 * Users should use bcm_l3_ingress_create() to create L3 ingress interfaces 4122 * and assign class ids through the same API. 4123 */ 4124 4125 if (!soc_feature(unit, soc_feature_vp_sharing)) { 4126 if (control->egress_vlan != BCM_VLAN_NONE) { 4127 return BCM_E_PARAM; 4128 } 4129 } 4130 4131 #if defined(BCM_TRIDENT3_SUPPORT) 4132 if (soc_feature(unit, soc_feature_pvlan_on_vfi)) { 4133 VLAN_CHK_ID(unit, control->forwarding_vlan); 4134 } 4135 #endif 4136 4137 return BCM_E_NONE; 4138 } 4139 4140 /* 4141 * Function: 4142 * bcmi_td2p_vfi_profile_add 4143 * 4144 * Purpose: 4145 * Programs VFI_PROFILE table based on input bcm_vlan_control_vlan_t 4146 * 4147 * Parameters: 4148 * unit - (IN) BCM device number. 4149 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4150 * vfi_control - (IN) Configuration. 4151 * profile_index - (OUT) Profile index allocated by soc_mem_profile_add 4152 * 4153 * Returns: 4154 * BCM_E_XXXs 4155 */ 4156 STATIC int 4157 bcmi_td2p_vfi_profile_add(int unit, uint32 valid_fields, 4158 bcm_vlan_control_vlan_t *vfi_control, 4159 int old_profile_index, int *profile_index) 4160 { 4161 int i; 4162 soc_field_t field; 4163 int field_num = 0; 4164 uint32 index; 4165 int value; 4166 vfi_profile_entry_t vfi_profile_entry; 4167 vfi_profile_2_entry_t vfi_profile_2_entry; 4168 soc_mem_t vfi_profile_mem = VFI_PROFILEm; 4169 void *entries[3]; 4170 int vfi_profile_flags_map[][4] = { 4171 /* field, flag, bool_invert, 0: flags; 1: flags2 */ 4172 {L2_NON_UCAST_DROPf, BCM_VLAN_NON_UCAST_DROP, 0, 0}, 4173 {L2_NON_UCAST_TOCPUf, BCM_VLAN_NON_UCAST_TOCPU, 0, 0}, 4174 {L2_MISS_DROPf, BCM_VLAN_UNKNOWN_UCAST_DROP, 0, 0}, 4175 {L2_MISS_TOCPUf, BCM_VLAN_UNKNOWN_UCAST_TOCPU, 0, 0}, 4176 {IPMCV4_L2_ENABLEf, BCM_VLAN_IP4_MCAST_L2_DISABLE, 1, 0}, 4177 {IPMCV6_L2_ENABLEf, BCM_VLAN_IP6_MCAST_L2_DISABLE, 1, 0}, 4178 {LEARN_DISABLEf, BCM_VLAN_LEARN_DISABLE, 0, 0}, 4179 {EN_IFILTERf, BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE, 1, 1}, 4180 {INVALIDf, 0, 0} 4181 }; 4182 4183 entries[0] = &vfi_profile_entry; 4184 if (soc_feature(unit, soc_feature_vfi_combo_profile)) { 4185 entries[1] = &vfi_profile_2_entry; 4186 } 4187 if (_BCM_INVALID_VFI_PROFILE != old_profile_index) { 4188 BCM_IF_ERROR_RETURN( 4189 _bcm_vfi_profile_entry_get(unit, old_profile_index, 1, entries)); 4190 } else { 4191 sal_memset(&vfi_profile_entry, 0, sizeof(vfi_profile_entry_t)); 4192 sal_memset(&vfi_profile_2_entry, 0, sizeof(vfi_profile_2_entry_t)); 4193 } 4194 4195 field_num = COUNTOF(vfi_profile_flags_map); 4196 for (i = 0; i < field_num; i++) { 4197 field = vfi_profile_flags_map[i][0]; 4198 if (field == INVALIDf) { 4199 continue; 4200 } 4201 4202 if (vfi_profile_flags_map[i][3] == 0) { 4203 value = ((vfi_profile_flags_map[i][2]) ? 4204 (!(vfi_control->flags & vfi_profile_flags_map[i][1])): 4205 ((vfi_control->flags & vfi_profile_flags_map[i][1]))); 4206 } else { 4207 /* flags2 */ 4208 value = ((vfi_profile_flags_map[i][2]) ? 4209 (!(vfi_control->flags2 & vfi_profile_flags_map[i][1])): 4210 ((vfi_control->flags2 & vfi_profile_flags_map[i][1]))); 4211 } 4212 4213 value = !!value; 4214 soc_mem_field32_set(unit, vfi_profile_mem, &vfi_profile_entry, field, value); 4215 } 4216 4217 BCM_IF_ERROR_RETURN(_bcm_vfi_profile_entry_add(unit, entries, 1, &index)); 4218 4219 *profile_index = index; 4220 return BCM_E_NONE; 4221 } 4222 4223 /* 4224 * Function: 4225 * bcmi_td2p_vfi_profile_get 4226 * 4227 * Purpose: 4228 * Reads VFI_PROFILE table and fills vfi_control 4229 * 4230 * Parameters: 4231 * unit - (IN) BCM device number. 4232 * profile_index - (IN) Profile index. 4233 * vfi_control - (IN) Configuration. 4234 * 4235 * Returns: 4236 * BCM_E_XXXs 4237 */ 4238 STATIC int 4239 bcmi_td2p_vfi_profile_get(int unit, uint8 profile_index, bcm_vlan_control_vlan_t *vfi_control) 4240 { 4241 int rv; 4242 int i; 4243 soc_field_t field; 4244 int field_num = 0; 4245 int value; 4246 vfi_profile_entry_t vfi_profile_entry; 4247 vfi_profile_2_entry_t vfi_profile_2_entry; 4248 soc_mem_t vfi_profile_mem = VFI_PROFILEm; 4249 void *entries[2]; 4250 int vfi_profile_flags_map[][4] = { 4251 /* field, flag, bool_invert, 0: flags; 1: flags2 */ 4252 {L2_NON_UCAST_DROPf, BCM_VLAN_NON_UCAST_DROP, 0, 0}, 4253 {L2_NON_UCAST_TOCPUf, BCM_VLAN_NON_UCAST_TOCPU, 0, 0}, 4254 {L2_MISS_DROPf, BCM_VLAN_UNKNOWN_UCAST_DROP, 0, 0}, 4255 {L2_MISS_TOCPUf, BCM_VLAN_UNKNOWN_UCAST_TOCPU, 0, 0}, 4256 {IPMCV4_L2_ENABLEf, BCM_VLAN_IP4_MCAST_L2_DISABLE, 1, 0}, 4257 {IPMCV6_L2_ENABLEf, BCM_VLAN_IP6_MCAST_L2_DISABLE, 1, 0}, 4258 {LEARN_DISABLEf, BCM_VLAN_LEARN_DISABLE, 0, 0}, 4259 {EN_IFILTERf, BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE, 1, 1}, 4260 {INVALIDf, 0, 0} 4261 }; 4262 4263 entries[0] = &vfi_profile_entry; 4264 if (soc_feature(unit, soc_feature_vfi_combo_profile)) { 4265 entries[1] = &vfi_profile_2_entry; 4266 } 4267 4268 rv = _bcm_vfi_profile_entry_get(unit, profile_index, 1, entries); 4269 BCM_IF_ERROR_RETURN(rv); 4270 4271 field_num = COUNTOF(vfi_profile_flags_map); 4272 for (i = 0; i < field_num; i++) { 4273 field = vfi_profile_flags_map[i][0]; 4274 if (field == INVALIDf) { 4275 continue; 4276 } 4277 value = soc_mem_field32_get(unit, vfi_profile_mem, &vfi_profile_entry, field); 4278 if (vfi_profile_flags_map[i][3] == 0) { 4279 vfi_control->flags |= ((vfi_profile_flags_map[i][2]) ? 4280 ((!value) ? vfi_profile_flags_map[i][1] : 0) : 4281 ((value) ? vfi_profile_flags_map[i][1] : 0)); 4282 } else { 4283 /* flags2 */ 4284 vfi_control->flags2 |= ((vfi_profile_flags_map[i][2]) ? 4285 ((!value) ? vfi_profile_flags_map[i][1] : 0) : 4286 ((value) ? vfi_profile_flags_map[i][1] : 0)); 4287 } 4288 } 4289 4290 return BCM_E_NONE; 4291 } 4292 4293 4294 /* 4295 * Function: 4296 * bcmi_td2p_vfi_control_ingress_set 4297 * 4298 * Purpose: 4299 * Programs VFI table according to vfi_control 4300 * 4301 * Parameters: 4302 * unit - (IN) BCM device number. 4303 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4304 * vfi_control - (IN) Configuration. 4305 * 4306 * Returns: 4307 * BCM_E_XXXs 4308 */ 4309 STATIC int 4310 bcmi_td2p_vfi_control_ingress_set(int unit, int vfi, uint32 valid_fields, bcm_vlan_control_vlan_t *control) 4311 { 4312 int rv; 4313 int i; 4314 soc_field_t field; 4315 int field_num = 0; 4316 int value; 4317 int profile_index; 4318 int old_profile_index; 4319 vfi_entry_t vfi_entry; 4320 soc_mem_t mem = VFIm; 4321 struct vfi_fields_s { 4322 soc_field_t field; 4323 uint32 valid_field; 4324 int *vlan_control_obj; 4325 } vfi_field_values[] = { 4326 {VFI_CLASS_IDf, BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK}, 4327 {L3_IIFf, BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK}, 4328 {UUC_INDEXf, BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK}, 4329 {UMC_INDEXf, BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK}, 4330 {BC_INDEXf, BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK}, 4331 {VRFf, BCM_VLAN_CONTROL_VLAN_VRF_MASK}, 4332 #if defined(BCM_TRIDENT3_SUPPORT) 4333 {FID_IDf, BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK}, /*td3 only*/ 4334 #endif 4335 {INVALIDf, 0, 0} 4336 }; 4337 4338 vfi_field_values[0].vlan_control_obj = &(control->if_class); 4339 vfi_field_values[1].vlan_control_obj = &(control->ingress_if); 4340 vfi_field_values[2].vlan_control_obj = &(control->unknown_unicast_group); 4341 vfi_field_values[3].vlan_control_obj = &(control->unknown_multicast_group); 4342 vfi_field_values[4].vlan_control_obj = &(control->broadcast_group); 4343 vfi_field_values[5].vlan_control_obj = &(control->vrf); 4344 #if defined(BCM_TRIDENT3_SUPPORT) 4345 vfi_field_values[6].vlan_control_obj = (int*)&(control->forwarding_vlan); 4346 4347 if (!soc_feature(unit, soc_feature_pvlan_on_vfi)) { 4348 valid_fields &= ~BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK; 4349 } 4350 4351 if (soc_feature(unit, soc_feature_generic_dest)) { 4352 vfi_field_values[2].field = UUC_DESTINATIONf; 4353 vfi_field_values[3].field = UMC_DESTINATIONf; 4354 vfi_field_values[4].field = BC_DESTINATIONf; 4355 } 4356 #endif 4357 4358 #if defined(BCM_TRIDENT3_SUPPORT) 4359 if (soc_feature(unit, soc_feature_generic_dest)) { 4360 vfi_field_values[2].field = UUC_DESTINATIONf; 4361 vfi_field_values[3].field = UMC_DESTINATIONf; 4362 vfi_field_values[4].field = BC_DESTINATIONf; 4363 } 4364 #endif 4365 4366 /* 4367 * VFI table can be programmed with the following fields: 4368 * 4369 * - VRF : Virtual Routing and Forwarding Instance 4370 * - VFI_CLASS_ID : VFI Class ID for IFP lookup key 4371 * - L3_IIF : Layer3 Incoming Interface to be assigned to the packet 4372 * - UUC_INDEX : Default unknown unicast group for this VFI 4373 * - UMC_INDEX : Default unknown multicast group for this VFI 4374 * - BC_INDEX : Default Multicast group for broadcasting to this VFI 4375 */ 4376 4377 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 4378 BCM_IF_ERROR_RETURN(rv); 4379 4380 old_profile_index = soc_mem_field32_get(unit, mem, 4381 &vfi_entry, VFI_PROFILE_PTRf); 4382 4383 field_num = COUNTOF(vfi_field_values); 4384 for (i = 0; i < field_num; i++) { 4385 field = vfi_field_values[i].field; 4386 if (!(valid_fields & vfi_field_values[i].valid_field) || (field == INVALIDf)) { 4387 continue; 4388 } 4389 value = *(vfi_field_values[i].vlan_control_obj); 4390 #if defined(BCM_TRIDENT3_SUPPORT) 4391 if (field == FID_IDf) { 4392 value = *((uint16 *)vfi_field_values[i].vlan_control_obj); 4393 } 4394 4395 if (soc_feature(unit, soc_feature_generic_dest) && 4396 ((field == UUC_DESTINATIONf) || (field == UMC_DESTINATIONf) || 4397 (field == BC_DESTINATIONf))) { 4398 soc_mem_field32_dest_set(unit, mem, &vfi_entry, field, 4399 SOC_MEM_FIF_DEST_IPMC,value); 4400 } else 4401 #endif 4402 { 4403 soc_mem_field32_set(unit, mem, &vfi_entry, field, value); 4404 } 4405 } 4406 4407 if (control->vrf == 0) { 4408 soc_mem_field32_set(unit, mem, &vfi_entry, VRF_VALIDf, 0); 4409 } else { 4410 soc_mem_field32_set(unit, mem, &vfi_entry, VRF_VALIDf, 1); 4411 } 4412 4413 #if defined(BCM_HELIX5_SUPPORT) 4414 if (soc_feature(unit, soc_feature_vlan_wirelss_traffic_select)) { 4415 if (control->flags2 & BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT && 4416 control->flags2 & BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT) { 4417 return BCM_E_PARAM; 4418 } 4419 4420 if (control->flags2 & BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT) { 4421 soc_mem_field32_set(unit, mem, &vfi_entry, WIRED_WIRELESSf, 0x1); 4422 } 4423 4424 if (control->flags2 & BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT) { 4425 soc_mem_field32_set(unit, mem, &vfi_entry, WIRED_WIRELESSf, 0x2); 4426 } 4427 } 4428 #endif 4429 4430 4431 /* Add profile object */ 4432 rv = bcmi_td2p_vfi_profile_add(unit, valid_fields, 4433 control, old_profile_index, &profile_index); 4434 BCM_IF_ERROR_RETURN(rv); 4435 4436 /* Overwrite the the profile pointer in VFI with the new profile index */ 4437 soc_mem_field32_set(unit, mem, &vfi_entry, VFI_PROFILE_PTRf, profile_index); 4438 4439 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vfi, &vfi_entry); 4440 BCM_IF_ERROR_RETURN(rv); 4441 4442 /* Delete the old profile object */ 4443 if (old_profile_index > 0) { 4444 rv = _bcm_vfi_profile_entry_delete(unit, old_profile_index); 4445 BCM_IF_ERROR_RETURN(rv); 4446 } 4447 4448 return BCM_E_NONE; 4449 } 4450 4451 /* 4452 * Function: 4453 * bcmi_td2p_vfi_control_egress_set 4454 * 4455 * Purpose: 4456 * Programs EGR_VFI table according to vfi_control 4457 * 4458 * Parameters: 4459 * unit - (IN) BCM device number. 4460 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4461 * vfi_control - (IN) Configuration. 4462 * 4463 * Returns: 4464 * BCM_E_XXXs 4465 */ 4466 STATIC int 4467 bcmi_td2p_vfi_control_egress_set(int unit, int vfi, uint32 valid_fields, bcm_vlan_control_vlan_t *control) 4468 { 4469 4470 int rv; 4471 int i; 4472 soc_field_t field; 4473 int field_num = 0; 4474 int value; 4475 egr_vfi_entry_t vfi_entry; 4476 soc_mem_t mem = EGR_VFIm; 4477 struct vfi_fields_s { 4478 soc_field_t field; 4479 uint32 valid_field; 4480 uint16 *vlan_control_obj; 4481 } vfi_field_values[] = { 4482 {OVIDf, BCM_VLAN_CONTROL_VLAN_ALL_MASK}, 4483 {INVALIDf, 0, NULL} 4484 }; 4485 4486 vfi_field_values[0].vlan_control_obj = (uint16 *)&(control->egress_vlan); 4487 4488 /* Read the memory */ 4489 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 4490 BCM_IF_ERROR_RETURN(rv); 4491 4492 field_num = COUNTOF(vfi_field_values); 4493 for (i = 0; i < field_num; i++) { 4494 field = vfi_field_values[i].field; 4495 if (!(valid_fields & vfi_field_values[i].valid_field) || (field == INVALIDf) || 4496 (soc_feature(unit, soc_feature_egr_intf_vlan_vfi_deoverlay) && (field == OVIDf))) { 4497 continue; 4498 } 4499 value = *(vfi_field_values[i].vlan_control_obj); 4500 /* update each field */ 4501 if (soc_mem_field_valid(unit, mem, field)) { 4502 soc_mem_field32_set(unit, mem, &vfi_entry, field, value); 4503 } 4504 } 4505 4506 if (soc_mem_field_valid(unit, mem, EN_EFILTERf)) { 4507 /* EN_EFILTERf is enabled by default during the VPN creation */ 4508 if (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE) { 4509 soc_mem_field32_set(unit, mem, &vfi_entry, EN_EFILTERf, 0); 4510 } else { 4511 soc_mem_field32_set(unit, mem, &vfi_entry, EN_EFILTERf, 1); 4512 } 4513 } 4514 4515 /* Write the memory back */ 4516 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vfi, &vfi_entry); 4517 BCM_IF_ERROR_RETURN(rv); 4518 4519 return BCM_E_NONE; 4520 } 4521 4522 /* 4523 * Function: 4524 * bcmi_td2p_vfi_control_ingress_get 4525 * 4526 * Purpose: 4527 * Reads VFI table and fills vfi_control 4528 * 4529 * Parameters: 4530 * unit - (IN) BCM device number. 4531 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4532 * vfi_control - (OUT) Configuration. 4533 * 4534 * Returns: 4535 * BCM_E_XXXs 4536 */ 4537 STATIC int 4538 bcmi_td2p_vfi_control_ingress_get(int unit, int vfi, uint32 valid_fields, bcm_vlan_control_vlan_t *control) 4539 { 4540 int rv; 4541 int i; 4542 soc_field_t field; 4543 int field_num = 0; 4544 int value; 4545 uint8 profile_index; 4546 vfi_entry_t vfi_entry; 4547 soc_mem_t mem = VFIm; 4548 struct vfi_fields_s { 4549 soc_field_t field; 4550 uint32 valid_field; 4551 int *vlan_control_obj; 4552 } vfi_field_values[] = { 4553 {VFI_CLASS_IDf, BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK}, 4554 {L3_IIFf, BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK}, 4555 {UUC_INDEXf, BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK}, 4556 {UMC_INDEXf, BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK}, 4557 {BC_INDEXf, BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK}, 4558 {VRFf, BCM_VLAN_CONTROL_VLAN_VRF_MASK}, 4559 #if defined(BCM_TRIDENT3_SUPPORT) 4560 {FID_IDf, BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK}, 4561 #endif 4562 {INVALIDf, 0, 0} 4563 }; 4564 4565 vfi_field_values[0].vlan_control_obj = &(control->if_class); 4566 vfi_field_values[1].vlan_control_obj = &(control->ingress_if); 4567 vfi_field_values[2].vlan_control_obj = &(control->unknown_unicast_group); 4568 vfi_field_values[3].vlan_control_obj = &(control->unknown_multicast_group); 4569 vfi_field_values[4].vlan_control_obj = &(control->broadcast_group); 4570 vfi_field_values[5].vlan_control_obj = &(control->vrf); 4571 #if defined(BCM_TRIDENT3_SUPPORT) 4572 if (!soc_feature(unit, soc_feature_pvlan_on_vfi)) { 4573 valid_fields &= ~BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK; 4574 } 4575 4576 if (soc_feature(unit, soc_feature_generic_dest)) { 4577 vfi_field_values[2].field = UUC_DESTINATIONf; 4578 vfi_field_values[3].field = UMC_DESTINATIONf; 4579 vfi_field_values[4].field = BC_DESTINATIONf; 4580 } 4581 #endif 4582 4583 /* Read the memory */ 4584 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 4585 BCM_IF_ERROR_RETURN(rv); 4586 4587 field_num = COUNTOF(vfi_field_values); 4588 for (i = 0; i < field_num; i++) { 4589 field = vfi_field_values[i].field; 4590 if (!(valid_fields & vfi_field_values[i].valid_field) || (field == INVALIDf)) { 4591 continue; 4592 } 4593 /* read each field */ 4594 #if defined(BCM_TRIDENT3_SUPPORT) 4595 if (soc_feature(unit, soc_feature_generic_dest) && 4596 ((field == UUC_DESTINATIONf) || (field == UMC_DESTINATIONf) || 4597 (field == BC_DESTINATIONf))) { 4598 uint32 dest_type = 0; 4599 value = soc_mem_field32_dest_get(unit, mem, &vfi_entry, field, 4600 &dest_type); 4601 } else 4602 #endif 4603 { 4604 value = soc_mem_field32_get(unit, mem, &vfi_entry, field); 4605 } 4606 #if defined(BCM_TRIDENT3_SUPPORT) 4607 if (field == FID_IDf) { 4608 control->forwarding_vlan = value & 0xffff; 4609 } else 4610 #endif 4611 { 4612 *(vfi_field_values[i].vlan_control_obj) = value; 4613 } 4614 } 4615 4616 control->flags |= (control->if_class) ? BCM_VLAN_L2_CLASS_ID_ONLY : 0; 4617 4618 #if defined(BCM_HELIX5_SUPPORT) 4619 if (soc_feature(unit, soc_feature_vlan_wirelss_traffic_select)) { 4620 value = soc_mem_field32_get(unit, mem, &vfi_entry, WIRED_WIRELESSf); 4621 if (value == 0x1) { 4622 control->flags2 |= BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT; 4623 } 4624 if (value == 0x2) { 4625 control->flags2 |= BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT; 4626 } 4627 } 4628 #endif 4629 4630 profile_index = soc_mem_field32_get(unit, mem, &vfi_entry, VFI_PROFILE_PTRf); 4631 BCM_IF_ERROR_RETURN(bcmi_td2p_vfi_profile_get(unit, profile_index, control)); 4632 4633 return BCM_E_NONE; 4634 } 4635 4636 /* 4637 * Function: 4638 * bcmi_td2p_vfi_control_egress_get 4639 * 4640 * Purpose: 4641 * Reads EGR_VFI table and fills vfi_control 4642 * 4643 * Parameters: 4644 * unit - (IN) BCM device number. 4645 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4646 * vfi_control - (OUT) Configuration. 4647 * 4648 * Returns: 4649 * BCM_E_XXXs 4650 */ 4651 STATIC int 4652 bcmi_td2p_vfi_control_egress_get(int unit, int vfi, uint32 valid_fields, bcm_vlan_control_vlan_t *control) 4653 { 4654 4655 int rv; 4656 int i; 4657 int value; 4658 soc_field_t field; 4659 int field_num = 0; 4660 egr_vfi_entry_t vfi_entry; 4661 soc_mem_t mem = EGR_VFIm; 4662 4663 struct vfi_fields_s { 4664 soc_field_t field; 4665 uint32 valid_field; 4666 uint16 *vlan_control_obj; 4667 } vfi_field_values[] = { 4668 {OVIDf, BCM_VLAN_CONTROL_VLAN_ALL_MASK}, 4669 {INVALIDf, 0, NULL} 4670 }; 4671 4672 vfi_field_values[0].vlan_control_obj = (uint16 *)&(control->egress_vlan); 4673 4674 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 4675 BCM_IF_ERROR_RETURN(rv); 4676 4677 field_num = COUNTOF(vfi_field_values); 4678 for (i = 0; i < field_num; i++) { 4679 field = vfi_field_values[i].field; 4680 if (!(valid_fields & vfi_field_values[i].valid_field) || (field == INVALIDf) || 4681 (soc_feature(unit, soc_feature_egr_intf_vlan_vfi_deoverlay) && (field == OVIDf))) { 4682 continue; 4683 } 4684 if (soc_mem_field_valid(unit, mem, field)) { 4685 value = soc_mem_field32_get(unit, mem, &vfi_entry, field); 4686 *(vfi_field_values[i].vlan_control_obj) = value; 4687 } 4688 } 4689 4690 if (soc_mem_field_valid(unit, mem, EN_EFILTERf)) { 4691 if (soc_mem_field32_get(unit, mem, &vfi_entry, EN_EFILTERf) == 0) { 4692 control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE; 4693 } else { 4694 control->flags2 &= ~BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE; 4695 } 4696 } 4697 4698 BCM_IF_ERROR_RETURN(rv); 4699 4700 return BCM_E_NONE; 4701 } 4702 4703 4704 /* 4705 * Function : 4706 * bcmi_td2p_vlan_control_vpn_set 4707 * 4708 * Purpose : 4709 * Configures various controls on the VFI. 4710 * 4711 * Parameters: 4712 * unit - (IN) BCM device number. 4713 * vid - (IN) Vlan id. 4714 * valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 4715 * control - (IN) Configuration structure. 4716 * 4717 * Return : 4718 * BCM_E_XXX 4719 */ 4720 int 4721 bcmi_td2p_vlan_control_vpn_set(int unit, bcm_vlan_t vid, uint32 valid_fields, 4722 bcm_vlan_control_vlan_t *control) 4723 { 4724 4725 int rv; 4726 int vfi; 4727 4728 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 4729 4730 rv = bcmi_td2p_vfi_control_params_check(unit, vid, valid_fields, control); 4731 BCM_IF_ERROR_RETURN(rv); 4732 4733 /* Update VFI & VI_PROFILE tables per vlan_control INPUT */ 4734 rv = bcmi_td2p_vfi_control_ingress_set(unit, vfi, valid_fields, control); 4735 BCM_IF_ERROR_RETURN(rv); 4736 4737 /* Update EGR_VFI table */ 4738 rv = bcmi_td2p_vfi_control_egress_set(unit, vfi, valid_fields, control); 4739 BCM_IF_ERROR_RETURN(rv); 4740 4741 return BCM_E_NONE; 4742 } 4743 4744 /* 4745 * Function : 4746 * bcmi_td2p_vlan_control_vpn_get 4747 * 4748 * Purpose : 4749 * 4750 * Parameters: 4751 * unit - (IN) BCM device number. 4752 * vid - (IN) Vlan id. 4753 * control - (OUT) Configuration structure. 4754 * 4755 * Return : 4756 * BCM_E_XXX 4757 */ 4758 int 4759 bcmi_td2p_vlan_control_vpn_get(int unit, bcm_vlan_t vid, uint32 valid_fields, 4760 bcm_vlan_control_vlan_t *control) 4761 { 4762 int rv; 4763 int vfi; 4764 4765 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 4766 4767 rv = bcmi_td2p_vfi_control_ingress_get(unit, vfi, valid_fields, control); 4768 BCM_IF_ERROR_RETURN(rv); 4769 4770 rv = bcmi_td2p_vfi_control_egress_get(unit, vfi, valid_fields, control); 4771 BCM_IF_ERROR_RETURN(rv); 4772 4773 return BCM_E_NONE; 4774 } 4775 4776 /* 4777 * Function: 4778 * bcm_td2p_dvp_vlan_xlate_key_set 4779 * Description: 4780 * Set egress vlan translation key per VXLAN gport 4781 * 4782 * Parameters: 4783 * unit - (IN) unit number 4784 * port_id - (IN) vxlan gport 4785 * key_type - (IN) Hardware egress vlan translation key type. 4786 * 4787 * Return Value: 4788 * BCM_E_XXX 4789 */ 4790 int 4791 bcm_td2p_dvp_vlan_xlate_key_set(int unit, bcm_gport_t port_id, int key_type) 4792 { 4793 int vp = -1, egr_key_type = 0, rv = BCM_E_UNAVAIL; 4794 soc_mem_t mem = EGR_DVP_ATTRIBUTEm; 4795 int network_port = 0; 4796 source_vp_entry_t svp; 4797 egr_dvp_attribute_entry_t egr_dvp_attribute; 4798 _bcm_vp_info_t vp_info; 4799 4800 if (BCM_GPORT_IS_VXLAN_PORT(port_id)) { 4801 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port_id); 4802 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 4803 return BCM_E_NOT_FOUND; 4804 } 4805 } else if (BCM_GPORT_IS_MIM_PORT(port_id)) { 4806 vp = BCM_GPORT_MIM_PORT_ID_GET(port_id); 4807 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 4808 return BCM_E_NOT_FOUND; 4809 } 4810 } else if (BCM_GPORT_IS_MPLS_PORT(port_id)) { 4811 vp = BCM_GPORT_MPLS_PORT_ID_GET(port_id); 4812 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 4813 return BCM_E_NOT_FOUND; 4814 } 4815 } else if (BCM_GPORT_IS_L2GRE_PORT(port_id)) { 4816 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port_id); 4817 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 4818 return BCM_E_NOT_FOUND; 4819 } 4820 } 4821 4822 /* Check for Network-Port */ 4823 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 4824 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 4825 if (BCM_FAILURE(rv)) { 4826 return rv; 4827 } 4828 4829 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 4830 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 4831 network_port = TRUE; 4832 } else { 4833 network_port = FALSE; 4834 } 4835 4836 /* bcmVlanTranslateEgressKeyVpn only for network port*/ 4837 if ((!network_port) && (key_type == TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_VFI)) { 4838 return BCM_E_UNAVAIL; 4839 } 4840 4841 sal_memset(&egr_dvp_attribute, 0, 4842 sizeof(egr_dvp_attribute_entry_t)); 4843 /* coverity[negative_returns] */ 4844 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 4845 if (BCM_FAILURE(rv)) { 4846 return rv; 4847 } 4848 if ((network_port) && (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 4849 egr_key_type = soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 4850 VXLAN__EVXLT_KEY_SELf); 4851 } else if ((network_port) && (_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 4852 egr_key_type = soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 4853 L2GRE__EVXLT_KEY_SELf); 4854 } else { 4855 egr_key_type = soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 4856 COMMON__EVXLT_KEY_SELf); 4857 } 4858 if (egr_key_type != key_type) { 4859 if ((network_port) && (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 4860 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4861 VXLAN__EVXLT_KEY_SELf, key_type); 4862 } else if ((network_port) && (_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 4863 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4864 L2GRE__EVXLT_KEY_SELf, key_type); 4865 } else { 4866 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4867 COMMON__EVXLT_KEY_SELf, key_type); 4868 } 4869 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, 4870 vp, &egr_dvp_attribute); 4871 if (BCM_FAILURE(rv)) { 4872 return rv; 4873 } 4874 } 4875 4876 return rv; 4877 } 4878 4879 /* 4880 * Function: 4881 * bcm_td2p_dvp_vlan_xlate_key_get 4882 * Description: 4883 * Get egress vlan translation key per gport 4884 * 4885 * Parameters: 4886 * unit - (IN) unit number 4887 * port_id - (IN) vxlan gport 4888 * key_type - (IN) Hardware egress vlan translation key type. 4889 * 4890 * Return Value: 4891 * BCM_E_XXX 4892 */ 4893 int 4894 bcm_td2p_dvp_vlan_xlate_key_get(int unit, bcm_gport_t port_id, int *key_type) 4895 { 4896 int vp = -1, rv = BCM_E_UNAVAIL; 4897 soc_mem_t mem = EGR_DVP_ATTRIBUTEm; 4898 int network_port = 0; 4899 source_vp_entry_t svp; 4900 egr_dvp_attribute_entry_t egr_dvp_attribute; 4901 _bcm_vp_info_t vp_info; 4902 4903 if (key_type == NULL) { 4904 return BCM_E_PARAM; 4905 } 4906 4907 if (BCM_GPORT_IS_VXLAN_PORT(port_id)) { 4908 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port_id); 4909 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 4910 return BCM_E_NOT_FOUND; 4911 } 4912 } else if (BCM_GPORT_IS_MIM_PORT(port_id)) { 4913 vp = BCM_GPORT_MIM_PORT_ID_GET(port_id); 4914 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 4915 return BCM_E_NOT_FOUND; 4916 } 4917 } else if (BCM_GPORT_IS_MPLS_PORT(port_id)) { 4918 vp = BCM_GPORT_MPLS_PORT_ID_GET(port_id); 4919 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 4920 return BCM_E_NOT_FOUND; 4921 } 4922 } else if (BCM_GPORT_IS_L2GRE_PORT(port_id)) { 4923 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port_id); 4924 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 4925 return BCM_E_NOT_FOUND; 4926 } 4927 } 4928 4929 /* Check for Network-Port */ 4930 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 4931 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 4932 if (BCM_FAILURE(rv)) { 4933 return rv; 4934 } 4935 4936 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 4937 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 4938 network_port = TRUE; 4939 } else { 4940 network_port = FALSE; 4941 } 4942 4943 sal_memset(&egr_dvp_attribute, 0, 4944 sizeof(egr_dvp_attribute_entry_t)); 4945 /* coverity[negative_returns] */ 4946 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 4947 if (BCM_FAILURE(rv)) { 4948 return rv; 4949 } 4950 if ((network_port) && (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 4951 *key_type = soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 4952 VXLAN__EVXLT_KEY_SELf); 4953 } else if ((network_port) && (_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 4954 *key_type = soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 4955 L2GRE__EVXLT_KEY_SELf); 4956 } else { 4957 *key_type = soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 4958 COMMON__EVXLT_KEY_SELf); 4959 } 4960 4961 return rv; 4962 } 4963 4964 int 4965 bcm_td2p_ing_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, 4966 SHR_BITDCL *vp_bitmap, int arr_size, int *flags_arr) 4967 { 4968 int rv = BCM_E_NONE; 4969 soc_mem_t mem; 4970 int chunk_size, num_chunks, chunk_index; 4971 int alloc_size; 4972 uint8 *buf = NULL; 4973 int i, entry_index_min, entry_index_max; 4974 uint32 *buf_entry; 4975 int vp; 4976 int sp_state; 4977 int vfi = -1; 4978 _bcm_vp_vlan_mbrship_key_type_e key_type; 4979 soc_field_t vld_fld = VALIDf; 4980 4981 if (_BCM_VPN_VFI_IS_SET(vlan)) { 4982 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan); 4983 } 4984 4985 if (NULL == vp_bitmap) { 4986 return BCM_E_PARAM; 4987 } 4988 if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) { 4989 return BCM_E_PARAM; 4990 } 4991 if (NULL == flags_arr) { 4992 return BCM_E_PARAM; 4993 } 4994 4995 mem = ING_VP_VLAN_MEMBERSHIPm; 4996 4997 chunk_size = 1024; 4998 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 4999 if (soc_mem_index_count(unit, mem) % chunk_size) { 5000 num_chunks++; 5001 } 5002 5003 alloc_size = sizeof(ing_vp_vlan_membership_entry_t) * chunk_size; 5004 buf = soc_cm_salloc(unit, alloc_size, "ING_VP_VLAN_MEMBERSHIP buffer"); 5005 if (NULL == buf) { 5006 rv = BCM_E_MEMORY; 5007 goto cleanup; 5008 } 5009 5010 if (soc_feature(unit, soc_feature_base_valid)) { 5011 vld_fld = BASE_VALIDf; 5012 } 5013 5014 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 5015 5016 /* Get a chunk of entries */ 5017 entry_index_min = chunk_index * chunk_size; 5018 entry_index_max = entry_index_min + chunk_size - 1; 5019 if (entry_index_max > soc_mem_index_max(unit, mem)) { 5020 entry_index_max = soc_mem_index_max(unit, mem); 5021 } 5022 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 5023 entry_index_min, entry_index_max, buf); 5024 if (SOC_FAILURE(rv)) { 5025 goto cleanup; 5026 } 5027 5028 /* Read each entry of the chunk to extract VP and flags */ 5029 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 5030 buf_entry = soc_mem_table_idx_to_pointer(unit, 5031 mem, uint32 *, buf, i); 5032 5033 key_type = soc_mem_field32_get(unit, mem, buf_entry, KEY_TYPEf); 5034 5035 if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) { 5036 continue; 5037 } 5038 5039 if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 5040 if (soc_mem_field32_get(unit, mem, buf_entry, VFIf) != vfi) { 5041 continue; 5042 } 5043 } else { 5044 if (soc_mem_field32_get(unit, mem, buf_entry, VLANf) != vlan) { 5045 continue; 5046 } 5047 } 5048 5049 vp = soc_mem_field32_get(unit, mem, buf_entry, VPf); 5050 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan) && 5051 !_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) && 5052 !_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender) && 5053 !_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan) && 5054 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 5055 continue; 5056 } 5057 SHR_BITSET(vp_bitmap, vp); 5058 5059 sp_state = soc_mem_field32_get(unit, mem, buf_entry, SP_TREEf); 5060 if (sp_state == PVP_STP_DISABLED) { 5061 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_DISABLE; 5062 } else if (sp_state == PVP_STP_LEARNING) { 5063 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_LEARN; 5064 } else if (sp_state == PVP_STP_BLOCKING) { 5065 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_BLOCK; 5066 } else { 5067 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_FORWARD; 5068 } 5069 } 5070 } 5071 5072 cleanup: 5073 if (buf) { 5074 soc_cm_sfree(unit, buf); 5075 } 5076 5077 return rv; 5078 } 5079 5080 int 5081 bcm_td2p_egr_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, 5082 SHR_BITDCL *vp_bitmap, int arr_size, int *flags_arr) 5083 { 5084 int rv = BCM_E_NONE; 5085 soc_mem_t mem; 5086 int chunk_size, num_chunks, chunk_index; 5087 int alloc_size; 5088 uint8 *buf = NULL; 5089 int i, entry_index_min, entry_index_max; 5090 uint32 *buf_entry; 5091 int vp; 5092 int sp_state; 5093 int untag; 5094 int vfi = -1; 5095 _bcm_vp_vlan_mbrship_key_type_e key_type; 5096 soc_field_t vld_fld = VALIDf; 5097 5098 if (_BCM_VPN_VFI_IS_SET(vlan)) { 5099 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan); 5100 } 5101 5102 if (NULL == vp_bitmap) { 5103 return BCM_E_PARAM; 5104 } 5105 if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) { 5106 return BCM_E_PARAM; 5107 } 5108 if (NULL == flags_arr) { 5109 return BCM_E_PARAM; 5110 } 5111 5112 mem = EGR_VP_VLAN_MEMBERSHIPm; 5113 if (soc_feature(unit, soc_feature_base_valid)) { 5114 vld_fld = BASE_VALIDf; 5115 } 5116 5117 chunk_size = 1024; 5118 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 5119 if (soc_mem_index_count(unit, mem) % chunk_size) { 5120 num_chunks++; 5121 } 5122 5123 alloc_size = sizeof(egr_vp_vlan_membership_entry_t) * chunk_size; 5124 buf = soc_cm_salloc(unit, alloc_size, "EGR_VP_VLAN_MEMBERSHIP buffer"); 5125 if (NULL == buf) { 5126 rv = BCM_E_MEMORY; 5127 goto cleanup; 5128 } 5129 5130 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 5131 5132 /* Get a chunk of entries */ 5133 entry_index_min = chunk_index * chunk_size; 5134 entry_index_max = entry_index_min + chunk_size - 1; 5135 if (entry_index_max > soc_mem_index_max(unit, mem)) { 5136 entry_index_max = soc_mem_index_max(unit, mem); 5137 } 5138 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 5139 entry_index_min, entry_index_max, buf); 5140 if (SOC_FAILURE(rv)) { 5141 goto cleanup; 5142 } 5143 5144 /* Read each entry of the chunk to extract VP and flags */ 5145 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 5146 buf_entry = soc_mem_table_idx_to_pointer(unit, 5147 mem, uint32 *, buf, i); 5148 5149 key_type = soc_mem_field32_get(unit, mem, buf_entry, KEY_TYPEf); 5150 5151 if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) { 5152 continue; 5153 } 5154 5155 if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 5156 if (soc_mem_field32_get(unit, mem, buf_entry, VFIf) != vfi) { 5157 continue; 5158 } 5159 } else { 5160 if (soc_mem_field32_get(unit, mem, buf_entry, VLANf) != vlan) { 5161 continue; 5162 } 5163 } 5164 5165 vp = soc_mem_field32_get(unit, mem, buf_entry, VPf); 5166 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan) && 5167 !_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) && 5168 !_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender) && 5169 !_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan) && 5170 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 5171 continue; 5172 } 5173 SHR_BITSET(vp_bitmap, vp); 5174 5175 sp_state = soc_mem_field32_get(unit, mem, buf_entry, SP_TREEf); 5176 if (sp_state == PVP_STP_DISABLED) { 5177 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_DISABLE; 5178 } else if (sp_state == PVP_STP_LEARNING) { 5179 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_LEARN; 5180 } else if (sp_state == PVP_STP_BLOCKING) { 5181 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_BLOCK; 5182 } else { 5183 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_FORWARD; 5184 } 5185 5186 untag = soc_mem_field32_get(unit, mem, buf_entry, UNTAGf); 5187 if (untag) { 5188 flags_arr[vp] |= BCM_VLAN_PORT_UNTAGGED; 5189 } 5190 } 5191 } 5192 5193 cleanup: 5194 if (buf) { 5195 soc_cm_sfree(unit, buf); 5196 } 5197 5198 return rv; 5199 } 5200 5201 int 5202 bcm_td2p_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, int array_max, 5203 bcm_gport_t *gport_array, int *flags_array, 5204 int *array_size) 5205 { 5206 int i = 0; 5207 int rv = 0; 5208 int num_vp = 0; 5209 SHR_BITDCL *ing_vp_bitmap = NULL; 5210 int *ing_flags_arr = NULL; 5211 SHR_BITDCL *egr_vp_bitmap = NULL; 5212 int *egr_flags_arr = NULL; 5213 int flags = 0; 5214 5215 if ((array_max > 0) && (NULL == gport_array)) { 5216 return BCM_E_PARAM; 5217 } 5218 5219 if ((array_max > 0) && (*array_size >= array_max)) { 5220 return BCM_E_NONE; 5221 } 5222 5223 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 5224 5225 ing_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "ing_vp_bitmap"); 5226 if (NULL == ing_vp_bitmap) { 5227 rv = BCM_E_MEMORY; 5228 goto cleanup; 5229 } 5230 sal_memset(ing_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5231 5232 ing_flags_arr = sal_alloc(num_vp * sizeof(int), "ing_flags_arr"); 5233 if (NULL == ing_flags_arr) { 5234 rv = BCM_E_MEMORY; 5235 goto cleanup; 5236 } 5237 sal_memset(ing_flags_arr, 0, num_vp * sizeof(int)); 5238 5239 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 5240 rv = bcm_td2p_ing_vp_vlan_membership_get_all(unit, vlan, ing_vp_bitmap, 5241 num_vp, ing_flags_arr); 5242 if (BCM_FAILURE(rv)) { 5243 goto cleanup; 5244 } 5245 } 5246 5247 egr_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "egr_vp_bitmap"); 5248 if (NULL == egr_vp_bitmap) { 5249 rv = BCM_E_MEMORY; 5250 goto cleanup; 5251 } 5252 sal_memset(egr_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5253 5254 egr_flags_arr = sal_alloc(num_vp * sizeof(int), "egr_flags_arr"); 5255 if (NULL == egr_flags_arr) { 5256 rv = BCM_E_MEMORY; 5257 goto cleanup; 5258 } 5259 sal_memset(egr_flags_arr, 0, num_vp * sizeof(int)); 5260 5261 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 5262 rv = bcm_td2p_egr_vp_vlan_membership_get_all(unit, vlan, egr_vp_bitmap, 5263 num_vp, egr_flags_arr); 5264 if (BCM_FAILURE(rv)) { 5265 goto cleanup; 5266 } 5267 } 5268 5269 for (i = 0; i < num_vp; i++) { 5270 if (!SHR_BITGET(ing_vp_bitmap, i) && 5271 !SHR_BITGET(egr_vp_bitmap, i)) { 5272 continue; 5273 } 5274 5275 if (0 == array_max) { 5276 (*array_size)++; 5277 } else { 5278 if (_bcm_vp_used_get(unit, i, _bcmVpTypeVlan)) { 5279 BCM_GPORT_VLAN_PORT_ID_SET(gport_array[*array_size], i); 5280 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeNiv)) { 5281 BCM_GPORT_NIV_PORT_ID_SET(gport_array[*array_size], i); 5282 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeExtender)) { 5283 BCM_GPORT_EXTENDER_PORT_ID_SET(gport_array[*array_size], i); 5284 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeVxlan)) { 5285 BCM_GPORT_VXLAN_PORT_ID_SET(gport_array[*array_size], i); 5286 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeMpls)) { 5287 BCM_GPORT_MPLS_PORT_ID_SET(gport_array[*array_size], i); 5288 } else { 5289 rv = BCM_E_INTERNAL; 5290 goto cleanup; 5291 } 5292 5293 if (NULL != flags_array) { 5294 flags_array[*array_size] = ing_flags_arr[i] | 5295 egr_flags_arr[i] | 5296 BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 5297 5298 if (SHR_BITGET(ing_vp_bitmap, i) && !SHR_BITGET(egr_vp_bitmap, i)) { 5299 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_INGRESS_ONLY; 5300 } 5301 5302 if (!SHR_BITGET(ing_vp_bitmap, i) && SHR_BITGET(egr_vp_bitmap, i)) { 5303 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_EGRESS_ONLY; 5304 } 5305 5306 rv = bcm_tr2_vlan_gport_get(unit, vlan, gport_array[*array_size], &flags); 5307 if (BCM_FAILURE(rv)) { 5308 goto cleanup; 5309 } 5310 flags_array[*array_size] |= flags; 5311 5312 } 5313 5314 (*array_size)++; 5315 if (*array_size == array_max) { 5316 break; 5317 } 5318 } 5319 } 5320 5321 cleanup: 5322 if (NULL != ing_vp_bitmap) { 5323 sal_free(ing_vp_bitmap); 5324 } 5325 if (NULL != ing_flags_arr) { 5326 sal_free(ing_flags_arr); 5327 } 5328 if (NULL != egr_vp_bitmap) { 5329 sal_free(egr_vp_bitmap); 5330 } 5331 if (NULL != egr_flags_arr) { 5332 sal_free(egr_flags_arr); 5333 } 5334 5335 return rv; 5336 5337 } 5338 5339 /* 5340 * Function : 5341 * bcmi_td2p_vfi_block_update 5342 * 5343 * Purpose : 5344 * Update blocking profile on VFI. 5345 * 5346 * Parameters: 5347 * unit - (IN) BCM device number. 5348 * block - (IN) Block configuration. 5349 * 5350 * Return : 5351 * BCM_E_XXX 5352 */ 5353 int 5354 bcmi_td2p_vfi_block_update(int unit, int vfi, _trx_vlan_block_t *block) 5355 { 5356 int rv; /* Operation return status. */ 5357 soc_mem_t mem; /* Vlan profile table memory. */ 5358 int old_profile_idx; /* Profile index. */ 5359 void *entries[3], *entry; 5360 vfi_profile_entry_t vfi_profile_entry; 5361 vfi_profile_2_entry_t vfi_profile_2_entry; 5362 uint32 profile_index; 5363 vfi_entry_t vfi_entry; 5364 5365 /* Input parameters check. */ 5366 if (NULL == block) { 5367 return (BCM_E_PARAM); 5368 } 5369 5370 /* Get original vlan profile. */ 5371 rv = soc_mem_read(unit, VFIm, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 5372 BCM_IF_ERROR_RETURN(rv); 5373 5374 old_profile_idx = soc_mem_field32_get(unit, VFIm, 5375 &vfi_entry, VFI_PROFILE_PTRf); 5376 5377 mem = VFI_PROFILE_2m; 5378 entries[0] = &vfi_profile_entry; 5379 entries[1] = &vfi_profile_2_entry; 5380 BCM_IF_ERROR_RETURN( 5381 _bcm_vfi_profile_entry_get(unit, old_profile_idx, 1, entries)); 5382 5383 entry = &vfi_profile_2_entry; 5384 /* Bitmap A */ 5385 soc_mem_pbmp_field_set(unit, mem, entry, BLOCK_MASK_Af, 5386 &block->first_mask); 5387 5388 /* Bitmap B */ 5389 soc_mem_pbmp_field_set(unit, mem, entry, BLOCK_MASK_Bf, 5390 &block->second_mask); 5391 5392 /* Broadcast mask select. */ 5393 soc_mem_field32_set(unit, mem, entry, BCAST_MASK_SELf, 5394 block->broadcast_mask_sel); 5395 5396 /* Unknown unicast mask select. */ 5397 if (soc_mem_field_valid(unit, mem, 5398 UNKNOWN_UCAST_MASK_SELf)) { 5399 soc_mem_field32_set(unit, mem, entry, UNKNOWN_UCAST_MASK_SELf, 5400 block->unknown_unicast_mask_sel); 5401 } 5402 5403 /* Unknown multicast mask select. */ 5404 if (soc_mem_field_valid(unit, mem, 5405 UNKNOWN_MCAST_MASK_SELf)) { 5406 soc_mem_field32_set(unit, mem, entry, UNKNOWN_MCAST_MASK_SELf, 5407 block->unknown_mulitcast_mask_sel); 5408 } 5409 5410 /* Unknown multicast mask select. */ 5411 if (soc_mem_field_valid(unit, mem, KNOWN_MCAST_MASK_SELf)) { 5412 soc_mem_field32_set(unit, mem, entry, KNOWN_MCAST_MASK_SELf, 5413 block->known_mulitcast_mask_sel); 5414 } 5415 5416 BCM_IF_ERROR_RETURN( 5417 _bcm_vfi_profile_entry_add(unit, entries, 1, &profile_index)); 5418 5419 /* Overwrite the the profile pointer in VFI with the new profile index */ 5420 soc_mem_field32_set(unit, VFIm, &vfi_entry, VFI_PROFILE_PTRf, 5421 profile_index); 5422 5423 BCM_IF_ERROR_RETURN( 5424 soc_mem_write(unit, VFIm, MEM_BLOCK_ALL, vfi, &vfi_entry)); 5425 5426 /* Delete the old profile object */ 5427 if (old_profile_idx > 0) { 5428 BCM_IF_ERROR_RETURN( 5429 _bcm_vfi_profile_entry_delete(unit, old_profile_idx)); 5430 } 5431 5432 return (BCM_E_NONE); 5433 } 5434 5435 /* 5436 * Function : 5437 * bcmi_td2p_vlan_block_set 5438 * 5439 * Purpose : 5440 * Configures VFI specific traffic blocking parameters. 5441 * 5442 * Parameters: 5443 * unit - (IN) BCM device number. 5444 * vid - (IN) Vlan id. 5445 * block - (IN) Block configuration. 5446 * 5447 * Return : 5448 * BCM_E_XXX 5449 */ 5450 int 5451 bcmi_td2p_vlan_block_set(int unit, bcm_vlan_t vid, bcm_vlan_block_t *block) 5452 { 5453 bcm_pbmp_t array[_BCM_VLAN_BLOCK_LOOKUP_TYPES]; 5454 _trx_vlan_block_t hw_block; /* HW block structure. */ 5455 int rv; /* Operation return status. */ 5456 int vfi; 5457 5458 /* Input parameters check. */ 5459 if (NULL == block) { 5460 return (BCM_E_PARAM); 5461 } 5462 5463 /* Store block mask in a array. */ 5464 BCM_PBMP_ASSIGN(array[0], block->broadcast); 5465 BCM_PBMP_ASSIGN(array[1], block->unknown_unicast); 5466 BCM_PBMP_ASSIGN(array[2], block->unknown_multicast); 5467 BCM_PBMP_ASSIGN(array[3], block->known_multicast); 5468 5469 /* Select first shortest mask. */ 5470 5471 /* Coverity 5472 * The index coverity thinks outside of boundary is actually for 5473 * the field pbits of the pbmp structure. 5474 */ 5475 /* coverity[overrun-buffer-val: FALSE] */ 5476 rv = _vlan_block_bitmap_min(unit, array, 5477 _BCM_VLAN_BLOCK_LOOKUP_TYPES, 5478 &hw_block.first_mask); 5479 BCM_IF_ERROR_RETURN(rv); 5480 5481 /* Clear those masks in the array that exactly match the shortest mask. */ 5482 /* coverity[overrun-buffer-val: FALSE] */ 5483 rv = _vlan_block_bitmap_clear(unit, array, 5484 _BCM_VLAN_BLOCK_LOOKUP_TYPES, 5485 hw_block.first_mask); 5486 BCM_IF_ERROR_RETURN(rv); 5487 5488 /* Select second shortest mask. */ 5489 /* coverity[overrun-buffer-val: FALSE] */ 5490 rv = _vlan_block_bitmap_min(unit, array, 5491 _BCM_VLAN_BLOCK_LOOKUP_TYPES, 5492 &hw_block.second_mask); 5493 BCM_IF_ERROR_RETURN(rv); 5494 5495 5496 /* Get mask selector for each lookup type. */ 5497 rv = _vlan_block_select_get(unit, block->broadcast, hw_block.first_mask, 5498 hw_block.second_mask, 5499 &hw_block.broadcast_mask_sel); 5500 BCM_IF_ERROR_RETURN(rv); 5501 5502 rv = _vlan_block_select_get(unit, block->unknown_unicast, 5503 hw_block.first_mask, hw_block.second_mask, 5504 &hw_block.unknown_unicast_mask_sel); 5505 BCM_IF_ERROR_RETURN(rv); 5506 5507 rv = _vlan_block_select_get(unit, block->unknown_multicast, 5508 hw_block.first_mask, hw_block.second_mask, 5509 &hw_block.unknown_mulitcast_mask_sel); 5510 BCM_IF_ERROR_RETURN(rv); 5511 5512 rv = _vlan_block_select_get(unit, block->known_multicast, 5513 hw_block.first_mask, hw_block.second_mask, 5514 &hw_block.known_mulitcast_mask_sel); 5515 BCM_IF_ERROR_RETURN(rv); 5516 5517 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 5518 5519 BCM_IF_ERROR_RETURN( 5520 bcmi_td2p_vfi_block_update(unit, vfi, &hw_block)); 5521 5522 return (BCM_E_NONE); 5523 } 5524 5525 /* 5526 * Function : 5527 * bcmi_td2p_vlan_block_get 5528 * 5529 * Purpose : 5530 * Get VFI specific traffic blocking parameters 5531 * 5532 * Parameters: 5533 * unit - (IN) BCM device number. 5534 * vid - (IN) Vlan id. 5535 * block - (IN) Block configuration. 5536 * 5537 * Return : 5538 * BCM_E_XXX 5539 */ 5540 int 5541 bcmi_td2p_vlan_block_get (int unit, bcm_vlan_t vid, bcm_vlan_block_t *block) 5542 { 5543 _trx_vlan_block_t hw_block; /* Vlan block profile. */ 5544 int rv; /* Operation return status. */ 5545 soc_mem_t mem; 5546 int profile_index; 5547 vfi_entry_t vfi_entry; 5548 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 5549 int vfi; 5550 5551 /* Input parameters check. */ 5552 if (NULL == block) { 5553 return (BCM_E_PARAM); 5554 } 5555 5556 /* Get original vlan profile. */ 5557 mem = VFIm; 5558 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 5559 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry); 5560 BCM_IF_ERROR_RETURN(rv); 5561 5562 profile_index = soc_mem_field32_get(unit, mem, 5563 &vfi_entry, VFI_PROFILE_PTRf); 5564 5565 /* READ VFI_PROFILE_2 portion. */ 5566 sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 5567 mem = VFI_PROFILE_2m; 5568 5569 /* READ vfi profile 2 table. */ 5570 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, profile_index, buf); 5571 if (BCM_FAILURE(rv)) { 5572 return (rv); 5573 } 5574 5575 /* Bitmap A */ 5576 soc_mem_pbmp_field_get(unit, mem, buf, BLOCK_MASK_Af, 5577 &hw_block.first_mask); 5578 5579 /* Bitmap B */ 5580 soc_mem_pbmp_field_get(unit, mem, buf, BLOCK_MASK_Bf, 5581 &hw_block.second_mask); 5582 5583 /* Broadcast mask select. */ 5584 hw_block.broadcast_mask_sel = 5585 soc_mem_field32_get(unit, mem, buf, BCAST_MASK_SELf); 5586 5587 /* Unknown unicast mask select. */ 5588 hw_block.unknown_unicast_mask_sel = 5589 soc_mem_field32_get(unit, mem, buf, UNKNOWN_UCAST_MASK_SELf); 5590 5591 /* Unknown multicast mask select. */ 5592 hw_block.unknown_mulitcast_mask_sel = 5593 soc_mem_field32_get(unit, mem, buf, UNKNOWN_MCAST_MASK_SELf); 5594 5595 /* Unknown multicast mask select. */ 5596 hw_block.known_mulitcast_mask_sel = 5597 soc_mem_field32_get(unit, mem, buf, KNOWN_MCAST_MASK_SELf); 5598 5599 rv = _vlan_block_mask_create (unit, hw_block.first_mask, 5600 hw_block.second_mask, 5601 hw_block.broadcast_mask_sel, 5602 &block->broadcast); 5603 BCM_IF_ERROR_RETURN(rv); 5604 5605 rv = _vlan_block_mask_create (unit, hw_block.first_mask, 5606 hw_block.second_mask, 5607 hw_block.unknown_unicast_mask_sel, 5608 &block->unknown_unicast); 5609 BCM_IF_ERROR_RETURN(rv); 5610 5611 rv = _vlan_block_mask_create (unit, 5612 hw_block.first_mask, 5613 hw_block.second_mask, 5614 hw_block.unknown_mulitcast_mask_sel, 5615 &block->unknown_multicast); 5616 BCM_IF_ERROR_RETURN(rv); 5617 5618 rv = _vlan_block_mask_create (unit, 5619 hw_block.first_mask, 5620 hw_block.second_mask, 5621 hw_block.known_mulitcast_mask_sel, 5622 &block->known_multicast); 5623 BCM_IF_ERROR_RETURN(rv); 5624 5625 return (BCM_E_NONE); 5626 } 5627 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 5628