vlan.c (237621B)
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: Manages VLAN virtual port creation and deletion. 9 * Also manages addition and removal of virtual 10 * ports from VLAN. The types of virtual ports that 11 * can be added to or removed from VLAN can be VLAN 12 * VPs, NIV VPs, or Extender VPs. 13 */ 14 15 #include <shared/bsl.h> 16 17 #include <soc/defs.h> 18 #include <sal/core/libc.h> 19 20 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 21 22 #include <soc/drv.h> 23 #include <soc/scache.h> 24 #include <soc/hash.h> 25 26 #include <bcm/error.h> 27 28 #include <bcm_int/esw_dispatch.h> 29 #include <bcm_int/api_xlate_port.h> 30 31 #include <bcm_int/common/multicast.h> 32 #include <bcm_int/esw/multicast.h> 33 #include <bcm_int/esw/virtual.h> 34 #include <bcm_int/esw/vlan.h> 35 #include <bcm_int/esw/firebolt.h> 36 #include <bcm_int/esw/trx.h> 37 #include <bcm_int/esw/triumph2.h> 38 #include <bcm_int/esw/trident.h> 39 #include <bcm_int/esw/stack.h> 40 #include <bcm_int/esw/trunk.h> 41 #include <bcm_int/esw/ipmc.h> 42 #if defined(BCM_TRIUMPH3_SUPPORT) 43 #include <bcm_int/esw/triumph3.h> 44 #endif /* BCM_TRIUMPH3_SUPPORT*/ 45 46 #if defined(BCM_TRIDENT2_SUPPORT) 47 #include <bcm_int/esw/trident2.h> 48 #endif /* BCM_TRIDENT2_SUPPORT*/ 49 50 #if defined(BCM_KATANA2_SUPPORT) 51 #include <bcm_int/esw/katana2.h> 52 #endif /*BCM_KATANA2_SUPPORT*/ 53 #if defined(BCM_KATANA_SUPPORT) 54 #include <bcm_int/esw/katana.h> 55 #endif /*BCM_KATANA_SUPPORT*/ 56 57 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58 #include <bcm_int/esw/trident2plus.h> 59 #include <bcm_int/esw/xgs5.h> 60 #include <bcm_int/esw/vlan.h> 61 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 62 63 #include <bcm_int/esw/policer.h> 64 65 66 /* ------------------------------------------------------- 67 * Software book keeping for VLAN virtual port information 68 * ------------------------------------------------------- 69 */ 70 71 typedef struct _bcm_tr2_vlan_vp_info_s { 72 bcm_vlan_port_match_t criteria; 73 uint32 flags; 74 int match_count; 75 bcm_vlan_t match_vlan; 76 bcm_vlan_t match_inner_vlan; 77 bcm_vlan_t match_tunnel_value; 78 bcm_gport_t port; 79 } _bcm_tr2_vlan_vp_info_t; 80 81 typedef struct _bcm_tr2_vlan_virtual_bookkeeping_s { 82 int vlan_virtual_initialized; /* Flag to check initialized status */ 83 sal_mutex_t vlan_virtual_mutex; /* VLAN virtual module lock */ 84 _bcm_tr2_vlan_vp_info_t *port_info; /* VP state */ 85 } _bcm_tr2_vlan_virtual_bookkeeping_t; 86 87 STATIC _bcm_tr2_vlan_virtual_bookkeeping_t _bcm_tr2_vlan_virtual_bk_info[BCM_MAX_NUM_UNITS]; 88 89 #define VLAN_VIRTUAL_INFO(unit) (&_bcm_tr2_vlan_virtual_bk_info[unit]) 90 91 #define VLAN_VIRTUAL_INIT(unit) \ 92 do { \ 93 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { \ 94 return BCM_E_UNIT; \ 95 } \ 96 if (!VLAN_VIRTUAL_INFO(unit)->vlan_virtual_initialized) { \ 97 return BCM_E_INIT; \ 98 } \ 99 } while (0) 100 101 #define VLAN_VIRTUAL_LOCK(unit) \ 102 sal_mutex_take(VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex, sal_mutex_FOREVER); 103 104 #define VLAN_VIRTUAL_UNLOCK(unit) \ 105 sal_mutex_give(VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex); 106 107 #define VLAN_VP_INFO(unit, vp) (&VLAN_VIRTUAL_INFO(unit)->port_info[vp]) 108 109 #ifdef BCM_TRIUMPH3_SUPPORT 110 #define _BCM_VLAN_VPN_INVALID 0xFFFF /* Invalid VLAN VPN */ 111 #define _BCM_VLAN_VFI_INVALID 0 /* Invalid VFI INDEX */ 112 #define VIRTUAL_INFO(unit) (&_bcm_virtual_bk_info[unit]) 113 #endif 114 115 /* ---------------------------------------------------------------------------- 116 * 117 * Routines for creation and deletion of VLAN virtual ports 118 * 119 * ---------------------------------------------------------------------------- 120 */ 121 122 /* 123 * Function: 124 * _bcm_tr2_vlan_vp_port_cnt_update 125 * Purpose: 126 * Update port's VP count. 127 * Parameters: 128 * unit - (IN) SOC unit number. 129 * gport - (IN) GPORT ID. 130 * vp - (IN) Virtual port number. 131 * incr - (IN) If TRUE, increment VP count, else decrease VP count. 132 * Returns: 133 * BCM_X_XXX 134 */ 135 STATIC int 136 _bcm_tr2_vlan_vp_port_cnt_update(int unit, bcm_gport_t gport, 137 int vp, int incr) 138 { 139 int mod_out, port_out, tgid_out, id_out; 140 int idx; 141 int mod_local = FALSE; 142 _bcm_port_info_t *port_info; 143 int local_member_count; 144 int soc_max_num_ports = SOC_MAX_NUM_PORTS; 145 uint32 port_flags; 146 #if (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 147 bcm_port_t local_member_array[SOC_MAX_NUM_PP_PORTS]; 148 #else 149 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 150 #endif 151 152 if (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) { 153 soc_max_num_ports = SOC_MAX_NUM_PP_PORTS; 154 } 155 156 BCM_IF_ERROR_RETURN 157 (_bcm_esw_gport_resolve(unit, gport, &mod_out, 158 &port_out, &tgid_out, &id_out)); 159 if (-1 != id_out) { 160 return BCM_E_PARAM; 161 } 162 163 /* In case of extended queuing on KTX, tgid_out gets updated with 164 * extended queue value. So set it to invalid value. 165 */ 166 #ifdef BCM_KATANA_SUPPORT 167 if (soc_feature(unit, soc_feature_extended_queueing)) { 168 if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) || 169 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) || 170 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport))) { 171 tgid_out = BCM_TRUNK_INVALID; 172 } 173 } 174 #endif 175 /* Update the physical port's SW state. If associated with a trunk, 176 * update each local physical port's SW state. 177 */ 178 179 if (BCM_TRUNK_INVALID != tgid_out) { 180 181 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid_out, 182 soc_max_num_ports, local_member_array, &local_member_count)); 183 184 for (idx = 0; idx < local_member_count; idx++) { 185 _bcm_port_info_access(unit, local_member_array[idx], &port_info); 186 if (incr) { 187 port_info->vp_count++; 188 } else { 189 port_info->vp_count--; 190 } 191 BCM_IF_ERROR_RETURN( 192 bcm_esw_port_vlan_member_get( 193 unit, local_member_array[idx], &port_flags)); 194 BCM_IF_ERROR_RETURN( 195 bcm_esw_port_vlan_member_set( 196 unit, local_member_array[idx], port_flags)); 197 } 198 } else { 199 200 201 #if defined(BCM_HGPROXY_COE_SUPPORT) 202 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 203 BCM_GPORT_IS_SET(gport) && 204 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 205 if(_bcm_xgs5_subport_coe_gport_local(unit, gport)) { 206 207 BCM_IF_ERROR_RETURN( 208 _bcmi_coe_subport_physical_port_get(unit, 209 gport, 210 &port_out)); 211 212 _bcm_port_info_access(unit, port_out, &port_info); 213 if (incr) { 214 port_info->vp_count++; 215 } else { 216 port_info->vp_count--; 217 } 218 BCM_IF_ERROR_RETURN( 219 bcm_esw_port_vlan_member_get( 220 unit, port_out, &port_flags)); 221 BCM_IF_ERROR_RETURN( 222 bcm_esw_port_vlan_member_set( 223 unit, port_out, port_flags)); 224 } 225 } else 226 #endif 227 228 #if defined(BCM_KATANA2_SUPPORT) 229 if (BCM_GPORT_IS_SET(gport) && 230 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) { 231 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_is_local_coe_subport(unit, 232 mod_out, port_out, &mod_local)); 233 if (mod_local) { 234 port_out = BCM_GPORT_SUBPORT_PORT_GET(gport); 235 _bcm_port_info_access(unit, port_out, &port_info); 236 if (incr) { 237 port_info->vp_count++; 238 } else { 239 port_info->vp_count--; 240 } 241 BCM_IF_ERROR_RETURN( 242 bcm_esw_port_vlan_member_get( 243 unit, port_out, &port_flags)); 244 BCM_IF_ERROR_RETURN( 245 bcm_esw_port_vlan_member_set( 246 unit, port_out, port_flags)); 247 } 248 } 249 #endif 250 BCM_IF_ERROR_RETURN 251 (_bcm_esw_modid_is_local(unit, mod_out, &mod_local)); 252 if (mod_local) { 253 if (soc_feature(unit, soc_feature_sysport_remap)) { 254 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 255 } 256 _bcm_port_info_access(unit, port_out, &port_info); 257 if (incr) { 258 port_info->vp_count++; 259 } else { 260 port_info->vp_count--; 261 } 262 BCM_IF_ERROR_RETURN( 263 bcm_esw_port_vlan_member_get( 264 unit, port_out, &port_flags)); 265 BCM_IF_ERROR_RETURN( 266 bcm_esw_port_vlan_member_set( 267 unit, port_out, port_flags)); 268 } 269 } 270 271 return BCM_E_NONE; 272 } 273 274 /* 275 * Function: 276 * _bcm_tr2_vlan_virtual_free_resources 277 * Purpose: 278 * Free all allocated tables and memory 279 * Parameters: 280 * unit - SOC unit number 281 * Returns: 282 * Nothing 283 */ 284 STATIC void 285 _bcm_tr2_vlan_virtual_free_resources(int unit) 286 { 287 if (VLAN_VIRTUAL_INFO(unit)->port_info) { 288 sal_free(VLAN_VIRTUAL_INFO(unit)->port_info); 289 VLAN_VIRTUAL_INFO(unit)->port_info = NULL; 290 } 291 if (VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex) { 292 sal_mutex_destroy(VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex); 293 VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex = NULL; 294 } 295 } 296 297 /* 298 * Function: 299 * bcm_tr2_vlan_virtual_init 300 * Purpose: 301 * Initialize the VLAN virtual port module. 302 * Parameters: 303 * unit - SOC unit number. 304 * Returns: 305 * BCM_E_XXX 306 */ 307 int 308 bcm_tr2_vlan_virtual_init(int unit) 309 { 310 int num_vp; 311 int rv = BCM_E_NONE; 312 313 if (VLAN_VIRTUAL_INFO(unit)->vlan_virtual_initialized) { 314 bcm_tr2_vlan_virtual_detach(unit); 315 } 316 317 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 318 if (NULL == VLAN_VIRTUAL_INFO(unit)->port_info) { 319 VLAN_VIRTUAL_INFO(unit)->port_info = 320 sal_alloc(sizeof(_bcm_tr2_vlan_vp_info_t) * num_vp, "vlan_vp_info"); 321 if (NULL == VLAN_VIRTUAL_INFO(unit)->port_info) { 322 _bcm_tr2_vlan_virtual_free_resources(unit); 323 return BCM_E_MEMORY; 324 } 325 } 326 sal_memset(VLAN_VIRTUAL_INFO(unit)->port_info, 0, 327 sizeof(_bcm_tr2_vlan_vp_info_t) * num_vp); 328 329 if (NULL == VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex) { 330 VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex = 331 sal_mutex_create("vlan virtual mutex"); 332 if (NULL == VLAN_VIRTUAL_INFO(unit)->vlan_virtual_mutex) { 333 _bcm_tr2_vlan_virtual_free_resources(unit); 334 return BCM_E_MEMORY; 335 } 336 } 337 338 VLAN_VIRTUAL_INFO(unit)->vlan_virtual_initialized = 1; 339 340 /* Warm boot recovery of VLAN_VP_INFO depends on the completion 341 * of _bcm_virtual_init, but _bcm_virtual_init is after the 342 * VLAN module in the init sequence. Hence, warm boot recovery 343 * of VLAN_VP_INFO is moved to end of _bcm_virtual_init. 344 */ 345 346 return rv; 347 } 348 349 /* 350 * Function: 351 * bcm_tr2_vlan_virtual_detach 352 * Purpose: 353 * Detach the VLAN virtual port module. 354 * Parameters: 355 * unit - SOC unit number. 356 * Returns: 357 * BCM_E_XXX 358 */ 359 int 360 bcm_tr2_vlan_virtual_detach(int unit) 361 { 362 _bcm_tr2_vlan_virtual_free_resources(unit); 363 364 VLAN_VIRTUAL_INFO(unit)->vlan_virtual_initialized = 0; 365 366 return BCM_E_NONE; 367 } 368 369 #ifdef BCM_TRIUMPH3_SUPPORT 370 /* 371 * Function: 372 * _bcm_tr3_vlan_nh_sd_tag_set 373 * Purpose: 374 * Set SD TAG INFORMATION 375 * Parameters: 376 * unit - (IN) Device Number 377 * egr_nh - (IN) Egress next hop information 378 * vlan_vp - (IN) VLAN port information 379 * drop - (IN) Drop flag 380 * Returns: 381 * BCM_E_XXX 382 */ 383 STATIC int 384 _bcm_tr3_vlan_nh_sd_tag_set(int unit, egr_l3_next_hop_entry_t *egr_nh, 385 bcm_vlan_port_t *vlan_vp, int drop) 386 { 387 int sd_tag_pri = -1; 388 int sd_tag_cfi = -1; 389 int sd_tag_vlan = -1; 390 int sd_tag_action_present = -1; 391 int sd_tag_action_not_present = -1; 392 int tpid_index = -1; 393 394 /* Check that unsupported flags are not set */ 395 if (!(vlan_vp->flags & (BCM_VLAN_PORT_SERVICE_VLAN_ADD | 396 BCM_VLAN_PORT_SERVICE_VLAN_REPLACE | 397 BCM_VLAN_PORT_SERVICE_VLAN_DELETE | 398 BCM_VLAN_PORT_SERVICE_VLAN_TPID_REPLACE | 399 BCM_VLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE | 400 BCM_VLAN_PORT_SERVICE_VLAN_PRI_REPLACE | 401 BCM_VLAN_PORT_SERVICE_PRI_REPLACE | 402 BCM_VLAN_PORT_SERVICE_TPID_REPLACE))) { 403 return BCM_E_NONE; 404 } 405 406 if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_ADD) { 407 if (vlan_vp->egress_vlan >= BCM_VLAN_INVALID) { 408 return BCM_E_PARAM; 409 } 410 if (vlan_vp->pkt_pri > BCM_PRIO_MAX) { 411 return BCM_E_PARAM; 412 } 413 if (vlan_vp->pkt_cfi > 1) { 414 return BCM_E_PARAM; 415 } 416 417 sd_tag_vlan = vlan_vp->egress_vlan; 418 sd_tag_pri = vlan_vp->pkt_pri; 419 sd_tag_cfi = vlan_vp->pkt_cfi; 420 sd_tag_action_not_present = 0x1; /* ADD */ 421 } 422 423 if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_TPID_REPLACE) { 424 if (vlan_vp->egress_vlan >= BCM_VLAN_INVALID) { 425 return BCM_E_PARAM; 426 } 427 428 /* REPLACE_VID_TPID */ 429 sd_tag_vlan = vlan_vp->egress_vlan; 430 sd_tag_action_present = 0x1; 431 } else if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_REPLACE) { 432 if (vlan_vp->egress_vlan >= BCM_VLAN_INVALID) { 433 return BCM_E_PARAM; 434 } 435 /* REPLACE_VID_ONLY */ 436 sd_tag_vlan = vlan_vp->egress_vlan; 437 sd_tag_action_present = 0x2; 438 } else if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_DELETE) { 439 sd_tag_action_present = 0x3; 440 sd_tag_action_not_present = 0; 441 } else if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE) { 442 if (vlan_vp->egress_vlan >= BCM_VLAN_INVALID) { 443 return BCM_E_PARAM; 444 } 445 if (vlan_vp->pkt_pri > BCM_PRIO_MAX) { 446 return BCM_E_PARAM; 447 } 448 if (vlan_vp->pkt_cfi > 1) { 449 return BCM_E_PARAM; 450 } 451 452 /* REPLACE_VID_PRI_TPID */ 453 sd_tag_vlan = vlan_vp->egress_vlan; 454 sd_tag_pri = vlan_vp->pkt_pri; 455 sd_tag_cfi = vlan_vp->pkt_cfi; 456 sd_tag_action_present = 0x4; 457 } else if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_PRI_REPLACE) { 458 if (vlan_vp->egress_vlan >= BCM_VLAN_INVALID) { 459 return BCM_E_PARAM; 460 } 461 if (vlan_vp->pkt_pri > BCM_PRIO_MAX) { 462 return BCM_E_PARAM; 463 } 464 if (vlan_vp->pkt_cfi > 1) { 465 return BCM_E_PARAM; 466 } 467 468 /* REPLACE_VID_PRI_ONLY */ 469 sd_tag_vlan = vlan_vp->egress_vlan; 470 sd_tag_pri = vlan_vp->pkt_pri; 471 sd_tag_cfi = vlan_vp->pkt_cfi; 472 sd_tag_action_present = 0x5; 473 } else if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_PRI_REPLACE) { 474 if (vlan_vp->pkt_pri > BCM_PRIO_MAX) { 475 return BCM_E_PARAM; 476 } 477 if (vlan_vp->pkt_cfi > 1) { 478 return BCM_E_PARAM; 479 } 480 481 /* REPLACE_PRI_ONLY */ 482 sd_tag_pri = vlan_vp->pkt_pri; 483 sd_tag_cfi = vlan_vp->pkt_cfi; 484 sd_tag_action_present = 0x6; 485 } else if (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_TPID_REPLACE) { 486 /* REPLACE_TPID_ONLY */ 487 sd_tag_action_present = 0x7; 488 } 489 490 if ((vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_ADD) || 491 (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 492 (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_TPID_REPLACE) || 493 (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 494 /* TPID value is used */ 495 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_add(unit, vlan_vp->egress_service_tpid, &tpid_index)); 496 } 497 498 if (sd_tag_vlan != -1) { 499 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 500 egr_nh, SD_TAG__SD_TAG_VIDf, sd_tag_vlan); 501 } 502 503 if (sd_tag_action_present != -1) { 504 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 505 SD_TAG__SD_TAG_ACTION_IF_PRESENTf, 506 sd_tag_action_present); 507 } 508 509 if (sd_tag_action_not_present != -1) { 510 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 511 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf, 512 sd_tag_action_not_present); 513 } 514 515 if (sd_tag_pri != -1) { 516 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_PRIf)) { 517 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 518 SD_TAG__NEW_PRIf, sd_tag_pri); 519 } 520 } 521 522 if (sd_tag_cfi != -1) { 523 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_CFIf)) { 524 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 525 SD_TAG__NEW_CFIf, sd_tag_cfi); 526 } 527 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_REMARK_CFIf)) { 528 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 529 SD_TAG__SD_TAG_REMARK_CFIf, 0x1); 530 } 531 } 532 533 if (tpid_index != -1) { 534 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 535 egr_nh, SD_TAG__SD_TAG_TPID_INDEXf, tpid_index); 536 } 537 538 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 539 SD_TAG__BC_DROPf, drop ? 1 : 0); 540 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 541 SD_TAG__UUC_DROPf, drop ? 1 : 0); 542 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 543 SD_TAG__UMC_DROPf, drop ? 1 : 0); 544 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 545 egr_nh, SD_TAG__DVP_IS_NETWORK_PORTf, 546 0); 547 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 548 SD_TAG__HG_LEARN_OVERRIDEf, 0); 549 /* HG_MODIFY_ENABLE must be 0x0 for Ingress and Egress Chip */ 550 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 551 SD_TAG__HG_MODIFY_ENABLEf, 0x0); 552 553 return BCM_E_NONE; 554 } 555 #endif /* BCM_TRIUMPH3_SUPPORT */ 556 557 /* 558 * Function: 559 * _bcm_tr2_vlan_vp_nh_info_set 560 * Purpose: 561 * Get a next hop index and configure next hop tables. 562 * Parameters: 563 * unit - (IN) SOC unit number. 564 * vlan_vp - (IN) Pointer to VLAN virtual port structure. 565 * vp - (IN) Virtual port number. 566 * drop - (IN) Drop indication. 567 * nh_index - (IN/OUT) Next hop index. 568 * Returns: 569 * BCM_X_XXX 570 */ 571 STATIC int 572 _bcm_tr2_vlan_vp_nh_info_set(int unit, bcm_vlan_port_t *vlan_vp, int vp, 573 int drop, int *nh_index) 574 { 575 int rv; 576 uint32 nh_flags; 577 bcm_l3_egress_t nh_info; 578 egr_l3_next_hop_entry_t egr_nh; 579 uint8 egr_nh_entry_type; 580 bcm_module_t mod_out; 581 bcm_port_t port_out; 582 bcm_trunk_t trunk_id; 583 int id; 584 int ing_nh_port; 585 int ing_nh_module; 586 int ing_nh_trunk; 587 ing_l3_next_hop_entry_t ing_nh; 588 initial_ing_l3_next_hop_entry_t initial_ing_nh; 589 soc_field_t ent_tpf = ENTRY_TYPEf; 590 int bit_num; 591 int network_group; 592 #ifdef BCM_KATANA_SUPPORT 593 int extended_queue, index; 594 #endif 595 596 #ifdef BCM_TRIUMPH3_SUPPORT 597 uint32 mtu_profile_index = 0; 598 #endif /* BCM_TRIUMPH3_SUPPORT */ 599 600 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 601 ent_tpf = DATA_TYPEf; 602 } 603 604 /* Get a next hop index */ 605 606 if (vlan_vp->flags & BCM_VLAN_PORT_REPLACE) { 607 if ((*nh_index > soc_mem_index_max(unit, EGR_L3_NEXT_HOPm)) || 608 (*nh_index < soc_mem_index_min(unit, EGR_L3_NEXT_HOPm))) { 609 return BCM_E_PARAM; 610 } 611 } else { 612 /* 613 * Allocate a next-hop entry. By calling bcm_xgs3_nh_add() 614 * with _BCM_L3_SHR_WRITE_DISABLE flag, a next-hop index is 615 * allocated but nothing is written to hardware. The "nh_info" 616 * in this case is not used, so just set to all zeros. 617 */ 618 bcm_l3_egress_t_init(&nh_info); 619 620 nh_flags = _BCM_L3_SHR_MATCH_DISABLE | _BCM_L3_SHR_WRITE_DISABLE; 621 rv = bcm_xgs3_nh_add(unit, nh_flags, &nh_info, nh_index); 622 BCM_IF_ERROR_RETURN(rv); 623 } 624 625 /* Write EGR_L3_NEXT_HOP entry */ 626 627 if (vlan_vp->flags & BCM_VLAN_PORT_REPLACE) { 628 /* Read the existing egress next_hop entry */ 629 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 630 *nh_index, &egr_nh); 631 BCM_IF_ERROR_RETURN(rv); 632 633 /* Be sure that the existing entry is programmed to SD-tag */ 634 egr_nh_entry_type = 635 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, ent_tpf); 636 if (egr_nh_entry_type != 0x2) { /* != SD-tag */ 637 return BCM_E_PARAM; 638 } 639 } else { 640 egr_nh_entry_type = 0x2; /* SD-tag */ 641 } 642 643 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 644 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 645 ent_tpf, egr_nh_entry_type); 646 647 if ((vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL) || 648 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN) || 649 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) ) { 650 /* Add the LLTAG for outgoing packets */ 651 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 652 SD_TAG__LLTAG_VIDf, vlan_vp->match_tunnel_value); 653 /* Set the LLTAG ACTION as ADDLLTAG if flag was not set */ 654 if (vlan_vp->flags & BCM_VLAN_PORT_EGRESS_PON_TUNNEL_NONE) { 655 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 656 SD_TAG__LLTAG_ACTIONSf, 0x0); 657 } else { 658 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 659 SD_TAG__LLTAG_ACTIONSf, 0x04); 660 } 661 } 662 663 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 664 SD_TAG__DVPf, vp); 665 666 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 667 SD_TAG__HG_HDR_SELf, 1); 668 669 /* Set Egress Class */ 670 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__CLASS_IDf)) { 671 bit_num = soc_mem_field_length(unit, EGR_L3_NEXT_HOPm, 672 SD_TAG__CLASS_IDf); 673 if ( vlan_vp->if_class > ((1 << bit_num) - 1)) { 674 return BCM_E_PARAM; 675 } else { 676 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 677 SD_TAG__CLASS_IDf, vlan_vp->if_class); 678 } 679 } 680 681 /* Handle Split Horizon */ 682 683 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 684 network_group = vlan_vp->egress_network_group_id; 685 rv = _bcm_validate_splithorizon_network_group(unit, 686 vlan_vp->flags & BCM_VLAN_PORT_NETWORK, &network_group); 687 if (rv < 0) { 688 goto cleanup; 689 } 690 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 691 SD_TAG__DVP_NETWORK_GROUPf)) { 692 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 693 SD_TAG__DVP_NETWORK_GROUPf, 694 network_group); 695 } 696 } 697 #ifdef BCM_TRIUMPH3_SUPPORT 698 if (soc_feature(unit, soc_feature_vlan_vfi)) { 699 rv = _bcm_tr3_vlan_nh_sd_tag_set(unit, &egr_nh, vlan_vp, drop); 700 if (rv < 0) { 701 goto cleanup; 702 } 703 } 704 #endif /* BCM_TRIUMPH3_SUPPORT */ 705 706 rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, 707 MEM_BLOCK_ALL, *nh_index, &egr_nh); 708 if (rv < 0) { 709 goto cleanup; 710 } 711 712 /* Resolve gport */ 713 714 rv = _bcm_esw_gport_resolve(unit, vlan_vp->port, &mod_out, 715 &port_out, &trunk_id, &id); 716 if (rv < 0) { 717 goto cleanup; 718 } 719 720 ing_nh_port = -1; 721 ing_nh_module = -1; 722 ing_nh_trunk = -1; 723 724 if (BCM_GPORT_IS_TRUNK(vlan_vp->port)) { 725 ing_nh_module = -1; 726 ing_nh_port = -1; 727 ing_nh_trunk = trunk_id; 728 } else { 729 ing_nh_module = mod_out; 730 ing_nh_port = port_out; 731 ing_nh_trunk = -1; 732 } 733 734 /* Write ING_L3_NEXT_HOP entry */ 735 736 sal_memset(&ing_nh, 0, sizeof(ing_l3_next_hop_entry_t)); 737 738 if (soc_feature(unit, soc_feature_generic_dest)) { 739 if (ing_nh_trunk == -1) { 740 soc_mem_field32_dest_set(unit, ING_L3_NEXT_HOPm, &ing_nh, 741 DESTINATIONf, SOC_MEM_FIF_DEST_DGPP, 742 (ing_nh_module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | 743 ing_nh_port)); 744 } else { 745 soc_mem_field32_dest_set(unit, ING_L3_NEXT_HOPm, &ing_nh, 746 DESTINATIONf, SOC_MEM_FIF_DEST_LAG, ing_nh_trunk); 747 } 748 } else { 749 if (ing_nh_trunk == -1) { 750 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 751 &ing_nh, PORT_NUMf, ing_nh_port); 752 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 753 &ing_nh, MODULE_IDf, ing_nh_module); 754 } else { 755 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 756 &ing_nh, Tf, 1); 757 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 758 &ing_nh, TGIDf, ing_nh_trunk); 759 } 760 } 761 762 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, &ing_nh, DROPf, drop); 763 764 if ((vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL) || 765 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN) || 766 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) ) { 767 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 768 &ing_nh, ENTRY_TYPEf, 0x03); /* XPON DVP */ 769 } else { 770 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 771 &ing_nh, ENTRY_TYPEf, 0x02); /* L2 DVP */ 772 773 /* Configuration of Mtu Size is valid only for L2 DVP Entry type */ 774 if (SOC_MEM_FIELD_VALID(unit, ING_L3_NEXT_HOPm, MTU_SIZEf)) { 775 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 776 &ing_nh, MTU_SIZEf, 0x3fff); 777 } 778 #ifdef BCM_TRIUMPH3_SUPPORT 779 else if (SOC_MEM_FIELD_VALID(unit, ING_L3_NEXT_HOPm, 780 DVP_ATTRIBUTE_1_INDEXf)) { 781 BCM_IF_ERROR_RETURN( 782 _bcm_tr3_mtu_profile_index_get(unit, 0x3fff, &mtu_profile_index)); 783 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, &ing_nh, 784 DVP_ATTRIBUTE_1_INDEXf, mtu_profile_index); 785 } 786 #endif /*BCM_TRIUMPH3_SUPPORT */ 787 } 788 rv = soc_mem_write (unit, ING_L3_NEXT_HOPm, 789 MEM_BLOCK_ALL, *nh_index, &ing_nh); 790 if (rv < 0) { 791 goto cleanup; 792 } 793 794 /* Write INITIAL_ING_L3_NEXT_HOP entry */ 795 796 sal_memset(&initial_ing_nh, 0, sizeof(initial_ing_l3_next_hop_entry_t)); 797 798 if (soc_feature(unit, soc_feature_generic_dest)) { 799 if (ing_nh_trunk == -1) { 800 soc_mem_field32_dest_set(unit, INITIAL_ING_L3_NEXT_HOPm, 801 &initial_ing_nh, DESTINATIONf, SOC_MEM_FIF_DEST_DGPP, 802 (ing_nh_module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | 803 ing_nh_port)); 804 } else { 805 soc_mem_field32_dest_set(unit, INITIAL_ING_L3_NEXT_HOPm, 806 &initial_ing_nh, DESTINATIONf, SOC_MEM_FIF_DEST_LAG, 807 ing_nh_trunk); 808 } 809 } else { 810 if (ing_nh_trunk == -1) { 811 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 812 &initial_ing_nh, PORT_NUMf, ing_nh_port); 813 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 814 &initial_ing_nh, MODULE_IDf, ing_nh_module); 815 } else { 816 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 817 &initial_ing_nh, Tf, 1); 818 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 819 &initial_ing_nh, TGIDf, ing_nh_trunk); 820 } 821 } 822 rv = soc_mem_write(unit, INITIAL_ING_L3_NEXT_HOPm, 823 MEM_BLOCK_ALL, *nh_index, &initial_ing_nh); 824 if (rv < 0) { 825 goto cleanup; 826 } 827 828 #ifdef BCM_KATANA_SUPPORT 829 if (BCM_SUCCESS(rv)) { 830 if (soc_feature(unit, soc_feature_extended_queueing)) { 831 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, *nh_index)) { 832 index = *nh_index + BCM_XGS3_EGRESS_IDX_MIN(unit); 833 } else { 834 index = *nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 835 } 836 if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(vlan_vp->port)) || 837 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(vlan_vp->port)) || 838 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(vlan_vp->port))) { 839 #ifdef BCM_KATANA2_SUPPORT 840 if (SOC_IS_KATANA2(unit)) { 841 BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_index_resolve(unit, vlan_vp->port, 0, 842 _BCM_KT2_COSQ_INDEX_STYLE_BUCKET, NULL, 843 &extended_queue, NULL)); 844 } else 845 #endif 846 { 847 BCM_IF_ERROR_RETURN(_bcm_kt_cosq_index_resolve(unit, vlan_vp->port, 0, 848 _BCM_KT_COSQ_INDEX_STYLE_BUCKET, NULL, 849 &extended_queue, NULL)); 850 } 851 rv = _bcm_kt_extended_queue_config(unit, vlan_vp->flags, vlan_vp->flags, 852 extended_queue, 853 (vlan_vp->qos_map_id & 0x3 /*_BCM_QOS_MAP_TYPE_MASK*/), &index); 854 } else { 855 /* Reset extended queue configuration, if any */ 856 if (vlan_vp->flags & BCM_L3_REPLACE) { 857 rv = _bcm_kt_extended_queue_config(unit, vlan_vp->flags, vlan_vp->flags, 858 0, 0, &index); 859 } 860 } 861 } 862 if (rv < 0) { 863 goto cleanup; 864 } 865 } 866 #endif 867 return rv; 868 869 cleanup: 870 if (!(vlan_vp->flags & BCM_VLAN_PORT_REPLACE)) { 871 (void) bcm_xgs3_nh_del(unit, _BCM_L3_SHR_WRITE_DISABLE, *nh_index); 872 } 873 return rv; 874 } 875 876 /* 877 * Function: 878 * _bcm_tr2_vlan_vp_nh_info_delete 879 * Purpose: 880 * Free next hop index and clear next hop tables. 881 * Parameters: 882 * unit - (IN) SOC unit number. 883 * nh_index - (IN) Next hop index. 884 * Returns: 885 * BCM_X_XXX 886 */ 887 STATIC int 888 _bcm_tr2_vlan_vp_nh_info_delete(int unit, int nh_index) 889 { 890 egr_l3_next_hop_entry_t egr_nh; 891 ing_l3_next_hop_entry_t ing_nh; 892 initial_ing_l3_next_hop_entry_t initial_ing_nh; 893 894 #ifdef BCM_TRIUMPH3_SUPPORT 895 soc_field_t ent_tpf = ENTRY_TYPEf; 896 897 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 898 ent_tpf = DATA_TYPEf; 899 } 900 if (soc_feature(unit, soc_feature_vlan_vfi)) { 901 int action_present = 0, action_not_present = 0, old_tpid_idx = -1; 902 uint32 entry_type = 0; 903 904 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 905 MEM_BLOCK_ANY, nh_index, &egr_nh)); 906 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, ent_tpf); 907 if (entry_type == 0x2) { 908 action_present = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 909 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 910 action_not_present = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 911 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 912 if ((action_not_present == 0x1) || (action_present == 0x1) || 913 (action_present == 0x4) || (action_present == 0x7)) { 914 old_tpid_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 915 &egr_nh, SD_TAG__SD_TAG_TPID_INDEXf); 916 BCM_IF_ERROR_RETURN( 917 _bcm_fb2_outer_tpid_entry_delete(unit, old_tpid_idx)); 918 } 919 } 920 } 921 #endif /* BCM_TRIUMPH3_SUPPORT */ 922 923 /* Clear EGR_L3_NEXT_HOP entry */ 924 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 925 BCM_IF_ERROR_RETURN(soc_mem_write(unit, EGR_L3_NEXT_HOPm, 926 MEM_BLOCK_ALL, nh_index, &egr_nh)); 927 928 /* Clear ING_L3_NEXT_HOP entry */ 929 sal_memset(&ing_nh, 0, sizeof(ing_l3_next_hop_entry_t)); 930 BCM_IF_ERROR_RETURN(soc_mem_write (unit, ING_L3_NEXT_HOPm, 931 MEM_BLOCK_ALL, nh_index, &ing_nh)); 932 933 /* Clear INITIAL_ING_L3_NEXT_HOP entry */ 934 sal_memset(&initial_ing_nh, 0, sizeof(initial_ing_l3_next_hop_entry_t)); 935 BCM_IF_ERROR_RETURN(soc_mem_write(unit, INITIAL_ING_L3_NEXT_HOPm, 936 MEM_BLOCK_ALL, nh_index, &initial_ing_nh)); 937 938 /* Free the next-hop index. */ 939 BCM_IF_ERROR_RETURN 940 (bcm_xgs3_nh_del(unit, _BCM_L3_SHR_WRITE_DISABLE, nh_index)); 941 942 return BCM_E_NONE; 943 } 944 945 #if defined(BCM_TRIUMPH3_SUPPORT) 946 /* 947 * Function: 948 * _tr3_vlan_vp_match_add 949 * Purpose: 950 * Add match criteria for VLAN VP. 951 * Parameters: 952 * unit - (IN) SOC unit number. 953 * vlan_vp - (IN) Pointer to VLAN virtual port structure. 954 * vp - (IN) Virtual port number. 955 * Returns: 956 * BCM_X_XXX 957 */ 958 STATIC int 959 _tr3_vlan_vp_match_add(int unit, bcm_vlan_port_t *vlan_vp, int vp) 960 { 961 vlan_xlate_entry_t vent; 962 vlan_xlate_extd_entry_t vxent, old_vxent; 963 int key_type = 0; 964 bcm_vlan_action_set_t action; 965 uint32 profile_idx; 966 int rv; 967 968 if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_NONE) { 969 return BCM_E_NONE; 970 } 971 972 if (!((vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN) || 973 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED) || 974 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN16) || 975 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN))) { 976 return BCM_E_PARAM; 977 } 978 979 if ((vlan_vp->egress_vlan > BCM_VLAN_MAX) || 980 (vlan_vp->egress_inner_vlan > BCM_VLAN_MAX)) { 981 return BCM_E_PARAM; 982 } 983 984 sal_memset(&vent, 0, sizeof(vlan_xlate_entry_t)); 985 sal_memset(&vxent, 0, sizeof(vlan_xlate_extd_entry_t)); 986 987 if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN) { 988 key_type = bcmVlanTranslateKeyPortOuter; 989 } else if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED) { 990 key_type = bcmVlanTranslateKeyPortDouble; 991 } else if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN16) { 992 key_type = bcmVlanTranslateKeyPortOuterTag; 993 } else if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN) { 994 key_type = bcmVlanTranslateKeyPortInner; 995 } 996 BCM_IF_ERROR_RETURN 997 (_bcm_trx_vlan_translate_entry_assemble(unit, &vent, 998 vlan_vp->port, 999 key_type, 1000 vlan_vp->match_inner_vlan, 1001 vlan_vp->match_vlan)); 1002 1003 BCM_IF_ERROR_RETURN 1004 (_bcm_tr3_vxlate2vxlate_extd(unit,&vent,&vxent)); 1005 1006 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, VALID_0f, 1); 1007 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, VALID_1f, 1); 1008 1009 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, XLATE__MPLS_ACTIONf, 0x1); /* SVP */ 1010 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, SOURCE_VPf, vp); 1011 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, NEW_OVIDf, 1012 vlan_vp->egress_vlan); 1013 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, NEW_IVIDf, 1014 vlan_vp->egress_inner_vlan); 1015 1016 bcm_vlan_action_set_t_init(&action); 1017 1018 if (vlan_vp->flags & BCM_VLAN_PORT_INNER_VLAN_PRESERVE) { 1019 action.dt_outer = bcmVlanActionReplace; 1020 action.dt_outer_prio = bcmVlanActionReplace; 1021 action.dt_inner = bcmVlanActionNone; 1022 action.dt_inner_prio = bcmVlanActionNone; 1023 } else { 1024 if (soc_feature(unit, soc_feature_vlan_copy_action)) { 1025 action.dt_outer = bcmVlanActionCopy; 1026 action.dt_outer_prio = bcmVlanActionCopy; 1027 } else { 1028 action.dt_outer = bcmVlanActionReplace; 1029 action.dt_outer_prio = bcmVlanActionReplace; 1030 } 1031 action.dt_inner = bcmVlanActionDelete; 1032 action.dt_inner_prio = bcmVlanActionDelete; 1033 } 1034 1035 action.ot_outer = bcmVlanActionReplace; 1036 action.ot_outer_prio = bcmVlanActionReplace; 1037 if (vlan_vp->flags & BCM_VLAN_PORT_INNER_VLAN_ADD) { 1038 action.ot_inner = bcmVlanActionAdd; 1039 } else { 1040 action.ot_inner = bcmVlanActionNone; 1041 } 1042 1043 BCM_IF_ERROR_RETURN 1044 (_bcm_trx_vlan_action_profile_entry_add(unit, &action, &profile_idx)); 1045 1046 soc_VLAN_XLATE_EXTDm_field32_set(unit, &vxent, TAG_ACTION_PROFILE_PTRf, 1047 profile_idx); 1048 1049 rv = soc_mem_insert_return_old(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 1050 &vxent, &old_vxent); 1051 if (rv == SOC_E_EXISTS) { 1052 /* Delete the old vlan translate profile entry */ 1053 profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &old_vxent, 1054 TAG_ACTION_PROFILE_PTRf); 1055 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 1056 } 1057 return rv; 1058 } 1059 1060 /* 1061 * Function: 1062 * _tr3_vlan_vp_match_delete 1063 * Purpose: 1064 * Delete match criteria for VLAN VP. 1065 * Parameters: 1066 * unit - (IN) SOC unit number. 1067 * vp - (IN) Virtual port number. 1068 * Returns: 1069 * BCM_X_XXX 1070 */ 1071 STATIC int 1072 _tr3_vlan_vp_match_delete(int unit, int vp) 1073 { 1074 vlan_xlate_entry_t vent; 1075 vlan_xlate_extd_entry_t vxent, old_vxent; 1076 int key_type = 0; 1077 uint32 profile_idx; 1078 int rv; 1079 1080 if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1081 return BCM_E_NONE; 1082 } 1083 1084 if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN) { 1085 key_type = bcmVlanTranslateKeyPortOuter; 1086 } else if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED) { 1087 key_type = bcmVlanTranslateKeyPortDouble; 1088 } else if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN16) { 1089 key_type = bcmVlanTranslateKeyPortOuterTag; 1090 } else if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN) { 1091 key_type = bcmVlanTranslateKeyPortInner; 1092 } else { 1093 return BCM_E_INTERNAL; 1094 } 1095 1096 sal_memset(&vent, 0, sizeof(vlan_xlate_entry_t)); 1097 sal_memset(&vxent, 0, sizeof(vlan_xlate_extd_entry_t)); 1098 BCM_IF_ERROR_RETURN 1099 (_bcm_trx_vlan_translate_entry_assemble(unit, &vent, 1100 VLAN_VP_INFO(unit, vp)->port, 1101 key_type, 1102 VLAN_VP_INFO(unit, vp)->match_inner_vlan, 1103 VLAN_VP_INFO(unit, vp)->match_vlan)); 1104 BCM_IF_ERROR_RETURN 1105 (_bcm_tr3_vxlate2vxlate_extd(unit,&vent,&vxent)); 1106 1107 rv = soc_mem_delete_return_old(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 1108 &vxent, &old_vxent); 1109 if ((rv == SOC_E_NONE) && 1110 soc_VLAN_XLATE_EXTDm_field32_get(unit, &old_vxent, VALID_0f)) { 1111 profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &old_vxent, 1112 TAG_ACTION_PROFILE_PTRf); 1113 /* Delete the old vlan action profile entry */ 1114 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 1115 } 1116 return rv; 1117 } 1118 1119 /* 1120 * Function: 1121 * _tr3_vlan_vp_match_get 1122 * Purpose: 1123 * Get match criteria for VLAN VP. 1124 * Parameters: 1125 * unit - (IN) SOC unit number. 1126 * vp - (IN) Virtual port number. 1127 * vlan_vp - (OUT) Pointer to VLAN virtual port structure. 1128 * Returns: 1129 * BCM_X_XXX 1130 */ 1131 STATIC int 1132 _tr3_vlan_vp_match_get(int unit, int vp, bcm_vlan_port_t *vlan_vp) 1133 { 1134 vlan_xlate_entry_t vent; 1135 vlan_xlate_extd_entry_t vxent, vxent_out; 1136 int key_type = 0; 1137 int idx; 1138 1139 vlan_vp->criteria = VLAN_VP_INFO(unit, vp)->criteria; 1140 vlan_vp->match_vlan = VLAN_VP_INFO(unit, vp)->match_vlan; 1141 vlan_vp->match_inner_vlan = VLAN_VP_INFO(unit, vp)->match_inner_vlan; 1142 vlan_vp->port = VLAN_VP_INFO(unit, vp)->port; 1143 1144 if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1145 return BCM_E_NONE; 1146 } 1147 1148 if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN) { 1149 key_type = bcmVlanTranslateKeyPortOuter; 1150 } else if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED) { 1151 key_type = bcmVlanTranslateKeyPortDouble; 1152 } else if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN16) { 1153 key_type = bcmVlanTranslateKeyPortOuterTag; 1154 } else if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN) { 1155 key_type = bcmVlanTranslateKeyPortInner; 1156 } else { 1157 return BCM_E_INTERNAL; 1158 } 1159 1160 sal_memset(&vent, 0, sizeof(vlan_xlate_entry_t)); 1161 sal_memset(&vxent, 0, sizeof(vlan_xlate_extd_entry_t)); 1162 1163 BCM_IF_ERROR_RETURN 1164 (_bcm_trx_vlan_translate_entry_assemble(unit, &vent, 1165 VLAN_VP_INFO(unit, vp)->port, 1166 key_type, 1167 VLAN_VP_INFO(unit, vp)->match_inner_vlan, 1168 VLAN_VP_INFO(unit, vp)->match_vlan)); 1169 1170 BCM_IF_ERROR_RETURN 1171 (_bcm_tr3_vxlate2vxlate_extd(unit,&vent,&vxent)); 1172 1173 BCM_IF_ERROR_RETURN 1174 (soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 1175 &idx, &vxent, &vxent_out, 0)); 1176 vlan_vp->egress_vlan = soc_VLAN_XLATE_EXTDm_field32_get(unit, &vxent_out, 1177 NEW_OVIDf); 1178 vlan_vp->egress_inner_vlan = soc_VLAN_XLATE_EXTDm_field32_get(unit, &vxent_out, 1179 NEW_IVIDf); 1180 1181 return BCM_E_NONE; 1182 } 1183 1184 /* 1185 * Function: 1186 * _tr3_vlan_vp_match_cleanup 1187 * Purpose: 1188 * Clean up match criteria for VLAN VP. 1189 * Parameters: 1190 * unit - (IN) SOC unit number. 1191 * vlan_vp - (IN) Pointer to VLAN virtual port structure.. 1192 * Returns: 1193 * BCM_X_XXX 1194 */ 1195 STATIC int 1196 _tr3_vlan_vp_match_cleanup(int unit, bcm_vlan_port_t *vlan_vp) 1197 { 1198 vlan_xlate_entry_t vent; 1199 vlan_xlate_extd_entry_t vxent, old_vxent; 1200 int key_type = 0; 1201 uint32 profile_idx; 1202 int rv; 1203 1204 if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1205 return BCM_E_NONE; 1206 } 1207 1208 if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN) { 1209 key_type = bcmVlanTranslateKeyPortOuter; 1210 } else if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED) { 1211 key_type = bcmVlanTranslateKeyPortDouble; 1212 } else if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_VLAN16) { 1213 key_type = bcmVlanTranslateKeyPortOuterTag; 1214 } else if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN) { 1215 key_type = bcmVlanTranslateKeyPortInner; 1216 } else { 1217 return BCM_E_INTERNAL; 1218 } 1219 1220 sal_memset(&vent, 0, sizeof(vlan_xlate_entry_t)); 1221 sal_memset(&vxent, 0, sizeof(vlan_xlate_extd_entry_t)); 1222 BCM_IF_ERROR_RETURN 1223 (_bcm_trx_vlan_translate_entry_assemble(unit, &vent, 1224 vlan_vp->port, 1225 key_type, 1226 vlan_vp->match_inner_vlan, 1227 vlan_vp->match_vlan)); 1228 BCM_IF_ERROR_RETURN 1229 (_bcm_tr3_vxlate2vxlate_extd(unit,&vent,&vxent)); 1230 1231 rv = soc_mem_delete_return_old(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 1232 &vxent, &old_vxent); 1233 if ((rv == SOC_E_NONE) && 1234 soc_VLAN_XLATE_EXTDm_field32_get(unit, &old_vxent, VALID_0f)) { 1235 profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &old_vxent, 1236 TAG_ACTION_PROFILE_PTRf); 1237 /* Delete the old vlan action profile entry */ 1238 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 1239 } 1240 return rv; 1241 } 1242 #endif /* TRIUMPH3 support */ 1243 1244 #ifdef BCM_TRIDENT2_SUPPORT 1245 1246 /* 1247 * Function: 1248 * _bcm_td2_vlan_match_vp_replace 1249 * Purpose: 1250 * Replace VP value in VLAN VP's match entry. 1251 * Parameters: 1252 * unit - (IN) SOC unit number. 1253 * vp - (IN) VLAN VP whose match entry is being replaced. 1254 * new_vp - (IN) New VP value. 1255 * old_vp - (OUT) Old VP value. 1256 * Returns: 1257 * BCM_X_XXX 1258 */ 1259 STATIC int 1260 _bcm_td2_vlan_match_vp_replace(int unit, int vp, int new_vp, int *old_vp) 1261 { 1262 int rv = BCM_E_NONE; 1263 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 1264 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 1265 soc_mem_t mem = VLAN_XLATEm; 1266 int key_type; 1267 int entry_index; 1268 _bcm_tr2_vlan_vp_info_t *vlan_vp = VLAN_VP_INFO(unit, vp); 1269 1270 switch(vlan_vp->criteria) { 1271 case BCM_VLAN_PORT_MATCH_NONE: 1272 return BCM_E_NONE; 1273 break; 1274 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 1275 key_type = bcmVlanTranslateKeyPortOuter; 1276 break; 1277 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 1278 key_type = bcmVlanTranslateKeyPortDouble; 1279 break; 1280 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 1281 key_type = bcmVlanTranslateKeyPortOuterTag; 1282 break; 1283 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 1284 key_type = bcmVlanTranslateKeyPortInner; 1285 break; 1286 default: 1287 return BCM_E_INTERNAL; 1288 } 1289 1290 sal_memset(vent, 0, sizeof(vent)); 1291 sal_memset(old_vent, 0, sizeof(old_vent)); 1292 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 1293 mem = VLAN_XLATE_1_DOUBLEm; 1294 } 1295 /* Construct lookup key */ 1296 BCM_IF_ERROR_RETURN 1297 (_bcm_trx_vlan_translate_entry_assemble(unit, vent, 1298 vlan_vp->port, key_type, 1299 vlan_vp->match_inner_vlan, 1300 vlan_vp->match_vlan)); 1301 /* Lookup existing entry */ 1302 SOC_IF_ERROR_RETURN( 1303 soc_mem_search(unit, mem, MEM_BLOCK_ALL, 1304 &entry_index, vent, old_vent, 0)); 1305 /* Replace entry's VP value */ 1306 *old_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf); 1307 soc_mem_field32_set(unit, mem, old_vent, SOURCE_VPf, new_vp); 1308 1309 /* Insert new entry */ 1310 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, old_vent); 1311 if (rv == SOC_E_EXISTS) { 1312 rv = BCM_E_NONE; 1313 } else { 1314 return BCM_E_INTERNAL; 1315 } 1316 1317 return rv; 1318 } 1319 1320 /* 1321 * Function: 1322 * bcm_td2_vlan_vp_source_vp_lag_set 1323 * Purpose: 1324 * Set source VP LAG for a VLAN virtual port. 1325 * Parameters: 1326 * unit - (IN) SOC unit number. 1327 * gport - (IN) VLAN virtual port GPORT ID. 1328 * vp_lag_vp - (IN) VP representing VP LAG. 1329 * Returns: 1330 * BCM_X_XXX 1331 */ 1332 int 1333 bcm_td2_vlan_vp_source_vp_lag_set(int unit, bcm_gport_t gport, 1334 int vp_lag_vp) 1335 { 1336 int rv; 1337 int vp, old_vp; 1338 1339 VLAN_VIRTUAL_INIT(unit); 1340 1341 VLAN_VIRTUAL_LOCK(unit); 1342 1343 if (!BCM_GPORT_IS_VLAN_PORT(gport)) { 1344 VLAN_VIRTUAL_UNLOCK(unit); 1345 return BCM_E_PARAM; 1346 } 1347 1348 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 1349 1350 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 1351 VLAN_VIRTUAL_UNLOCK(unit); 1352 return BCM_E_PARAM; 1353 } 1354 1355 /* Set source VP LAG by replacing the SVP field in VLAN VP's 1356 * match entry with the VP value representing the VP LAG. 1357 */ 1358 rv = _bcm_td2_vlan_match_vp_replace(unit, vp, vp_lag_vp, &old_vp); 1359 1360 VLAN_VIRTUAL_UNLOCK(unit); 1361 1362 return rv; 1363 } 1364 1365 /* 1366 * Function: 1367 * bcm_td2_vlan_vp_source_vp_lag_clear 1368 * Purpose: 1369 * Clear source VP LAG for a VLAN virtual port. 1370 * Parameters: 1371 * unit - (IN) SOC unit number. 1372 * gport - (IN) VLAN virtual port GPORT ID. 1373 * vp_lag_vp - (IN) VP representing VP LAG. 1374 * Returns: 1375 * BCM_X_XXX 1376 */ 1377 int 1378 bcm_td2_vlan_vp_source_vp_lag_clear(int unit, bcm_gport_t gport, 1379 int vp_lag_vp) 1380 { 1381 int rv; 1382 int vp, old_vp; 1383 1384 VLAN_VIRTUAL_INIT(unit); 1385 1386 VLAN_VIRTUAL_LOCK(unit); 1387 1388 if (!BCM_GPORT_IS_VLAN_PORT(gport)) { 1389 VLAN_VIRTUAL_UNLOCK(unit); 1390 return BCM_E_PARAM; 1391 } 1392 1393 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 1394 1395 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 1396 VLAN_VIRTUAL_UNLOCK(unit); 1397 return BCM_E_PARAM; 1398 } 1399 1400 /* Clear source VP LAG by replacing the SVP field in VLAN VP's 1401 * match entry with the VP value. 1402 */ 1403 rv = _bcm_td2_vlan_match_vp_replace(unit, vp, vp, &old_vp); 1404 1405 /* Check that the old VP value matches the VP value representing 1406 * the VP LAG or has been restored. 1407 */ 1408 if (BCM_SUCCESS(rv)) { 1409 if ((old_vp != vp_lag_vp) && (old_vp != vp)) { 1410 rv = BCM_E_INTERNAL; 1411 } 1412 } 1413 1414 VLAN_VIRTUAL_UNLOCK(unit); 1415 1416 return rv; 1417 } 1418 1419 /* 1420 * Function: 1421 * bcm_td2_vlan_vp_source_vp_lag_get 1422 * Purpose: 1423 * Get source VP LAG for a VLAN virtual port. 1424 * Parameters: 1425 * unit - (IN) SOC unit number. 1426 * gport - (IN) VLAN virtual port GPORT ID. 1427 * vp_lag_vp - (OUT) VP representing VP LAG. 1428 * Returns: 1429 * BCM_X_XXX 1430 */ 1431 int 1432 bcm_td2_vlan_vp_source_vp_lag_get(int unit, bcm_gport_t gport, 1433 int *vp_lag_vp) 1434 { 1435 int rv; 1436 int vp; 1437 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 1438 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 1439 soc_mem_t mem = VLAN_XLATEm; 1440 int key_type; 1441 int entry_index; 1442 _bcm_tr2_vlan_vp_info_t *vlan_vp = NULL; 1443 1444 VLAN_VIRTUAL_INIT(unit); 1445 1446 VLAN_VIRTUAL_LOCK(unit); 1447 1448 if (!BCM_GPORT_IS_VLAN_PORT(gport)) { 1449 VLAN_VIRTUAL_UNLOCK(unit); 1450 return BCM_E_PARAM; 1451 } 1452 1453 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 1454 1455 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 1456 VLAN_VIRTUAL_UNLOCK(unit); 1457 return BCM_E_PARAM; 1458 } 1459 1460 vlan_vp = VLAN_VP_INFO(unit, vp); 1461 1462 switch(vlan_vp->criteria) { 1463 case BCM_VLAN_PORT_MATCH_NONE: 1464 VLAN_VIRTUAL_UNLOCK(unit); 1465 return BCM_E_NONE; 1466 break; 1467 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 1468 key_type = bcmVlanTranslateKeyPortOuter; 1469 break; 1470 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 1471 key_type = bcmVlanTranslateKeyPortDouble; 1472 break; 1473 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 1474 key_type = bcmVlanTranslateKeyPortOuterTag; 1475 break; 1476 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 1477 key_type = bcmVlanTranslateKeyPortInner; 1478 break; 1479 default: 1480 VLAN_VIRTUAL_UNLOCK(unit); 1481 return BCM_E_INTERNAL; 1482 } 1483 1484 sal_memset(vent, 0, sizeof(vent)); 1485 sal_memset(old_vent, 0, sizeof(old_vent)); 1486 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 1487 mem = VLAN_XLATE_1_DOUBLEm; 1488 } 1489 /* Construct lookup key */ 1490 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, 1491 vlan_vp->port, key_type, 1492 vlan_vp->match_inner_vlan, 1493 vlan_vp->match_vlan); 1494 if (BCM_FAILURE(rv)) { 1495 VLAN_VIRTUAL_UNLOCK(unit); 1496 return rv; 1497 } 1498 1499 /* Lookup existing entry */ 1500 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, 1501 &entry_index, vent, old_vent, 0); 1502 if (SOC_FAILURE(rv)) { 1503 VLAN_VIRTUAL_UNLOCK(unit); 1504 return rv; 1505 } 1506 1507 /* Get VP value representing VP LAG */ 1508 *vp_lag_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf); 1509 if (!_bcm_vp_used_get(unit, *vp_lag_vp, _bcmVpTypeVpLag)) { 1510 VLAN_VIRTUAL_UNLOCK(unit); 1511 return BCM_E_INTERNAL; 1512 } 1513 1514 VLAN_VIRTUAL_UNLOCK(unit); 1515 1516 return rv; 1517 } 1518 1519 #endif /* BCM_TRIDENT2_SUPPORT */ 1520 1521 /* 1522 * Function: 1523 * _tr2_vlan_vp_match_add 1524 * Purpose: 1525 * Add match criteria for VLAN VP. 1526 * Parameters: 1527 * unit - (IN) SOC unit number. 1528 * vlan_vp - (IN) Pointer to VLAN virtual port structure. 1529 * vp - (IN) Virtual port number. 1530 * Returns: 1531 * BCM_X_XXX 1532 */ 1533 STATIC int 1534 _tr2_vlan_vp_match_add(int unit, bcm_vlan_port_t *vlan_vp, int vp) 1535 { 1536 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 1537 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 1538 soc_mem_t mem = VLAN_XLATEm; 1539 int key_type = 0; 1540 bcm_vlan_action_set_t action; 1541 uint32 profile_idx; 1542 int rv; 1543 1544 if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1545 return BCM_E_NONE; 1546 } 1547 1548 switch (vlan_vp->criteria) { 1549 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 1550 key_type = bcmVlanTranslateKeyPortOuter; 1551 break; 1552 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 1553 key_type = bcmVlanTranslateKeyPortDouble; 1554 break; 1555 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 1556 key_type = bcmVlanTranslateKeyPortOuterTag; 1557 break; 1558 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 1559 key_type = bcmVlanTranslateKeyPortInner; 1560 break; 1561 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1562 key_type = bcmVlanTranslateKeyPortPonTunnel; 1563 break; 1564 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1565 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 1566 break; 1567 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1568 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 1569 break; 1570 default: 1571 return BCM_E_PARAM; 1572 } 1573 1574 if ((vlan_vp->egress_vlan > BCM_VLAN_MAX) || 1575 (vlan_vp->egress_inner_vlan > BCM_VLAN_MAX)) { 1576 return BCM_E_PARAM; 1577 } 1578 1579 sal_memset(vent, 0, sizeof(vent)); 1580 sal_memset(old_vent, 0, sizeof(old_vent)); 1581 1582 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 1583 mem = VLAN_XLATE_1_DOUBLEm; 1584 } 1585 1586 if (soc_feature(unit, soc_feature_base_valid)) { 1587 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 1588 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 1589 } else { 1590 soc_mem_field32_set(unit, mem, vent, VALIDf, 1); 1591 } 1592 1593 switch (vlan_vp->criteria) { 1594 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1595 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1596 vlan_vp->port, 1597 key_type, 1598 vlan_vp->match_tunnel_value, 1599 0); 1600 break; 1601 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1602 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1603 vlan_vp->port, 1604 key_type, 1605 vlan_vp->match_tunnel_value, 1606 vlan_vp->match_vlan); 1607 break; 1608 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1609 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1610 vlan_vp->port, 1611 key_type, 1612 vlan_vp->match_tunnel_value, 1613 vlan_vp->match_inner_vlan); 1614 break; 1615 default: 1616 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, 1617 vlan_vp->port, 1618 key_type, 1619 vlan_vp->match_inner_vlan, 1620 vlan_vp->match_vlan); 1621 break; 1622 } 1623 1624 if(BCM_FAILURE(rv)) { 1625 return rv; 1626 } 1627 1628 bcm_vlan_action_set_t_init(&action); 1629 1630 if (vlan_vp->flags & BCM_VLAN_PORT_INNER_VLAN_PRESERVE) { 1631 action.dt_outer = bcmVlanActionReplace; 1632 action.dt_outer_prio = bcmVlanActionReplace; 1633 action.dt_inner = bcmVlanActionNone; 1634 action.dt_inner_prio = bcmVlanActionNone; 1635 } else { 1636 if (soc_feature(unit, soc_feature_vlan_copy_action)) { 1637 action.dt_outer = bcmVlanActionCopy; 1638 action.dt_outer_prio = bcmVlanActionCopy; 1639 } else { 1640 action.dt_outer = bcmVlanActionReplace; 1641 action.dt_outer_prio = bcmVlanActionReplace; 1642 } 1643 action.dt_inner = bcmVlanActionDelete; 1644 action.dt_inner_prio = bcmVlanActionDelete; 1645 } 1646 1647 action.ot_outer = bcmVlanActionReplace; 1648 action.ot_outer_prio = bcmVlanActionReplace; 1649 if (vlan_vp->flags & BCM_VLAN_PORT_INNER_VLAN_ADD) { 1650 action.ot_inner = bcmVlanActionAdd; 1651 } else { 1652 action.ot_inner = bcmVlanActionNone; 1653 } 1654 1655 BCM_IF_ERROR_RETURN 1656 (_bcm_trx_vlan_action_profile_entry_add(unit, &action, &profile_idx)); 1657 1658 if ((vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL) || 1659 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN) || 1660 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN)) { 1661 soc_mem_field32_set(unit, mem, vent, LLTAG__MPLS_ACTIONf, 0x1); /* SVP */ 1662 soc_mem_field32_set(unit, mem, vent, LLTAG__SOURCE_VPf, vp); 1663 soc_mem_field32_set(unit, mem, vent, LLTAG__NEW_OVIDf, 1664 vlan_vp->egress_vlan); 1665 soc_mem_field32_set(unit, mem, vent, LLTAG__NEW_IVIDf, 1666 vlan_vp->egress_inner_vlan); 1667 soc_mem_field32_set(unit, mem, vent, LLTAG__TAG_ACTION_PROFILE_PTRf, 1668 profile_idx); 1669 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 1670 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 1671 } 1672 } else { 1673 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x1); /* SVP */ 1674 soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, vp); 1675 soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, 1676 vlan_vp->egress_vlan); 1677 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, 1678 vlan_vp->egress_inner_vlan); 1679 soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, 1680 profile_idx); 1681 } 1682 1683 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) { 1684 soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1); 1685 } 1686 1687 rv = soc_mem_insert_return_old(unit, mem, MEM_BLOCK_ALL, 1688 vent, old_vent); 1689 if (rv == SOC_E_EXISTS) { 1690 /* Delete the old vlan translate profile entry */ 1691 profile_idx = soc_mem_field32_get(unit, mem, old_vent, 1692 TAG_ACTION_PROFILE_PTRf); 1693 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 1694 } 1695 return rv; 1696 } 1697 1698 /* 1699 * Function: 1700 * _tr2_vlan_vp_match_delete 1701 * Purpose: 1702 * Delete match criteria for VLAN VP. 1703 * Parameters: 1704 * unit - (IN) SOC unit number. 1705 * vp - (IN) Virtual port number. 1706 * old_vp - (OUT) Pointer to the old virtual port number of the entry. 1707 * Returns: 1708 * BCM_X_XXX 1709 */ 1710 STATIC int 1711 _tr2_vlan_vp_match_delete(int unit, int vp, int *old_vp) 1712 { 1713 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 1714 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 1715 soc_mem_t mem = VLAN_XLATEm; 1716 int key_type = 0; 1717 uint32 profile_idx; 1718 int rv; 1719 1720 if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1721 return BCM_E_NONE; 1722 } 1723 1724 switch (VLAN_VP_INFO(unit, vp)->criteria) { 1725 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 1726 key_type = bcmVlanTranslateKeyPortOuter; 1727 break; 1728 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 1729 key_type = bcmVlanTranslateKeyPortDouble; 1730 break; 1731 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 1732 key_type = bcmVlanTranslateKeyPortOuterTag; 1733 break; 1734 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 1735 key_type = bcmVlanTranslateKeyPortInner; 1736 break; 1737 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1738 key_type = bcmVlanTranslateKeyPortPonTunnel; 1739 break; 1740 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1741 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 1742 break; 1743 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1744 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 1745 break; 1746 default: 1747 return BCM_E_INTERNAL; 1748 } 1749 1750 sal_memset(vent, 0, sizeof(vent)); 1751 sal_memset(old_vent, 0, sizeof(old_vent)); 1752 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 1753 mem = VLAN_XLATE_1_DOUBLEm; 1754 } 1755 1756 switch (VLAN_VP_INFO(unit, vp)->criteria) { 1757 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1758 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1759 VLAN_VP_INFO(unit, vp)->port, 1760 key_type, 1761 VLAN_VP_INFO(unit, vp)->match_tunnel_value, 1762 0); 1763 break; 1764 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1765 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1766 VLAN_VP_INFO(unit, vp)->port, 1767 key_type, 1768 VLAN_VP_INFO(unit, vp)->match_tunnel_value, 1769 VLAN_VP_INFO(unit, vp)->match_vlan); 1770 break; 1771 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1772 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1773 VLAN_VP_INFO(unit, vp)->port, 1774 key_type, 1775 VLAN_VP_INFO(unit, vp)->match_tunnel_value, 1776 VLAN_VP_INFO(unit, vp)->match_inner_vlan); 1777 break; 1778 default: 1779 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, 1780 VLAN_VP_INFO(unit, vp)->port, 1781 key_type, 1782 VLAN_VP_INFO(unit, vp)->match_inner_vlan, 1783 VLAN_VP_INFO(unit, vp)->match_vlan); 1784 break; 1785 } 1786 1787 if (BCM_FAILURE(rv)) { 1788 return rv; 1789 } 1790 1791 rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, vent, old_vent); 1792 if (rv == SOC_E_NONE) { 1793 int is_valid = 0; 1794 if (soc_feature(unit, soc_feature_base_valid)) { 1795 is_valid = 1796 soc_mem_field32_get(unit, mem, old_vent, BASE_VALID_0f) == 3 && 1797 soc_mem_field32_get(unit, mem, old_vent, BASE_VALID_1f) == 7; 1798 } else { 1799 is_valid = soc_mem_field32_get(unit, mem, old_vent, VALIDf); 1800 } 1801 if (is_valid) { 1802 if (old_vp != NULL) { 1803 *old_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf); 1804 } 1805 profile_idx = soc_mem_field32_get(unit, mem, old_vent, 1806 TAG_ACTION_PROFILE_PTRf); 1807 /* Delete the old vlan action profile entry */ 1808 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 1809 } 1810 } 1811 1812 /* If the associated the VLAN_XLATE entry was deleted by translation action delete, 1813 * it should return NOT FOUND. 1814 */ 1815 if (rv == BCM_E_NOT_FOUND) { 1816 rv = BCM_E_NONE; 1817 } 1818 return rv; 1819 } 1820 1821 /* 1822 * Function: 1823 * _tr2_vlan_vp_match_get 1824 * Purpose: 1825 * Get match criteria for VLAN VP. 1826 * Parameters: 1827 * unit - (IN) SOC unit number. 1828 * vp - (IN) Virtual port number. 1829 * vlan_vp - (OUT) Pointer to VLAN virtual port structure. 1830 * Returns: 1831 * BCM_X_XXX 1832 */ 1833 STATIC int 1834 _tr2_vlan_vp_match_get(int unit, int vp, bcm_vlan_port_t *vlan_vp) 1835 { 1836 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 1837 uint32 vent_out[SOC_MAX_MEM_FIELD_WORDS]; 1838 soc_mem_t mem = VLAN_XLATEm; 1839 1840 int key_type = 0; 1841 int idx; 1842 int rv; 1843 1844 vlan_vp->criteria = VLAN_VP_INFO(unit, vp)->criteria; 1845 vlan_vp->match_vlan = VLAN_VP_INFO(unit, vp)->match_vlan; 1846 vlan_vp->match_inner_vlan = VLAN_VP_INFO(unit, vp)->match_inner_vlan; 1847 vlan_vp->match_tunnel_value = VLAN_VP_INFO(unit, vp)->match_tunnel_value; 1848 vlan_vp->port = VLAN_VP_INFO(unit, vp)->port; 1849 1850 if (VLAN_VP_INFO(unit, vp)->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1851 return BCM_E_NONE; 1852 } 1853 1854 switch (vlan_vp->criteria) { 1855 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 1856 key_type = bcmVlanTranslateKeyPortOuter; 1857 break; 1858 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 1859 key_type = bcmVlanTranslateKeyPortDouble; 1860 break; 1861 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 1862 key_type = bcmVlanTranslateKeyPortOuterTag; 1863 break; 1864 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 1865 key_type = bcmVlanTranslateKeyPortInner; 1866 break; 1867 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1868 key_type = bcmVlanTranslateKeyPortPonTunnel; 1869 break; 1870 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1871 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 1872 break; 1873 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1874 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 1875 break; 1876 default: 1877 return BCM_E_PARAM; 1878 } 1879 1880 sal_memset(vent, 0, sizeof(vent)); 1881 sal_memset(vent_out, 0, sizeof(vent_out)); 1882 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 1883 mem = VLAN_XLATE_1_DOUBLEm; 1884 } 1885 1886 switch (vlan_vp->criteria) { 1887 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1888 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1889 vlan_vp->port, 1890 key_type, 1891 vlan_vp->match_tunnel_value, 1892 0); 1893 break; 1894 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1895 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1896 vlan_vp->port, 1897 key_type, 1898 vlan_vp->match_tunnel_value, 1899 vlan_vp->match_vlan); 1900 break; 1901 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1902 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1903 vlan_vp->port, 1904 key_type, 1905 vlan_vp->match_tunnel_value, 1906 vlan_vp->match_inner_vlan); 1907 break; 1908 default: 1909 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, 1910 vlan_vp->port, 1911 key_type, 1912 vlan_vp->match_inner_vlan, 1913 vlan_vp->match_vlan); 1914 break; 1915 } 1916 1917 if (BCM_FAILURE(rv)) { 1918 return rv; 1919 } 1920 1921 BCM_IF_ERROR_RETURN 1922 (soc_mem_search(unit, mem, MEM_BLOCK_ALL, 1923 &idx, vent, vent_out, 0)); 1924 vlan_vp->egress_vlan = soc_mem_field32_get(unit, mem, vent_out, NEW_OVIDf); 1925 vlan_vp->egress_inner_vlan = soc_mem_field32_get(unit, mem, vent_out, 1926 NEW_IVIDf); 1927 1928 return BCM_E_NONE; 1929 } 1930 1931 /* 1932 * Function: 1933 * _tr2_vlan_vp_match_cleanup 1934 * Purpose: 1935 * Clean up match criteria for VLAN VP. 1936 * Parameters: 1937 * unit - (IN) SOC unit number. 1938 * vlan_vp - (IN) Pointer to VLAN virtual port structure. 1939 * Returns: 1940 * BCM_X_XXX 1941 */ 1942 STATIC int 1943 _tr2_vlan_vp_match_cleanup(int unit, bcm_vlan_port_t *vlan_vp) 1944 { 1945 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 1946 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 1947 soc_mem_t mem = VLAN_XLATEm; 1948 1949 int key_type = 0; 1950 uint32 profile_idx; 1951 int rv; 1952 1953 if (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_NONE) { 1954 return BCM_E_NONE; 1955 } 1956 1957 switch (vlan_vp->criteria) { 1958 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 1959 key_type = bcmVlanTranslateKeyPortOuter; 1960 break; 1961 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 1962 key_type = bcmVlanTranslateKeyPortDouble; 1963 break; 1964 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 1965 key_type = bcmVlanTranslateKeyPortOuterTag; 1966 break; 1967 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 1968 key_type = bcmVlanTranslateKeyPortInner; 1969 break; 1970 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1971 key_type = bcmVlanTranslateKeyPortPonTunnel; 1972 break; 1973 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1974 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 1975 break; 1976 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 1977 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 1978 break; 1979 default: 1980 return BCM_E_INTERNAL; 1981 } 1982 1983 sal_memset(vent, 0, sizeof(old_vent)); 1984 sal_memset(old_vent, 0, sizeof(old_vent)); 1985 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 1986 mem = VLAN_XLATE_1_DOUBLEm; 1987 } 1988 1989 switch (vlan_vp->criteria) { 1990 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL: 1991 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1992 vlan_vp->port, 1993 key_type, 1994 vlan_vp->match_tunnel_value, 1995 0); 1996 break; 1997 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 1998 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 1999 vlan_vp->port, 2000 key_type, 2001 vlan_vp->match_tunnel_value, 2002 vlan_vp->match_vlan); 2003 break; 2004 case BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 2005 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, 2006 vlan_vp->port, 2007 key_type, 2008 vlan_vp->match_tunnel_value, 2009 vlan_vp->match_inner_vlan); 2010 break; 2011 default: 2012 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, 2013 vlan_vp->port, 2014 key_type, 2015 vlan_vp->match_inner_vlan, 2016 vlan_vp->match_vlan); 2017 break; 2018 } 2019 2020 if (BCM_FAILURE(rv)) { 2021 return rv; 2022 } 2023 2024 rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, 2025 vent, old_vent); 2026 if (rv == SOC_E_NONE) { 2027 int is_valid = 0; 2028 if (soc_feature(unit, soc_feature_base_valid)) { 2029 is_valid = 2030 soc_mem_field32_get(unit, mem, old_vent, BASE_VALID_0f) == 3 && 2031 soc_mem_field32_get(unit, mem, old_vent, BASE_VALID_1f) == 7; 2032 } else { 2033 is_valid = soc_mem_field32_get(unit, mem, old_vent, VALIDf); 2034 } 2035 if (is_valid) { 2036 profile_idx = soc_mem_field32_get(unit, mem, old_vent, 2037 TAG_ACTION_PROFILE_PTRf); 2038 /* Delete the old vlan action profile entry */ 2039 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 2040 } 2041 } 2042 2043 /* If the associated the VLAN_XLATE entry was deleted by translation action delete, 2044 * it should return NOT FOUND. 2045 */ 2046 if (rv == BCM_E_NOT_FOUND) { 2047 rv = BCM_E_NONE; 2048 } 2049 return rv; 2050 } 2051 2052 STATIC int 2053 _bcm_tr2_vlan_vp_match_add(int unit, bcm_vlan_port_t *vlan_vp, int vp) 2054 { 2055 #if defined(BCM_TRIUMPH3_SUPPORT) 2056 if (SOC_IS_TRIUMPH3(unit)) { 2057 return _tr3_vlan_vp_match_add(unit, vlan_vp, vp); 2058 } else 2059 #endif 2060 { 2061 return _tr2_vlan_vp_match_add(unit, vlan_vp, vp); 2062 } 2063 } 2064 2065 STATIC int 2066 _bcm_tr2_vlan_vp_match_delete(int unit, int vp, int *old_vp) 2067 { 2068 #if defined(BCM_TRIUMPH3_SUPPORT) 2069 if (SOC_IS_TRIUMPH3(unit)) { 2070 return _tr3_vlan_vp_match_delete(unit, vp); 2071 } else 2072 #endif 2073 { 2074 return _tr2_vlan_vp_match_delete(unit, vp, old_vp); 2075 } 2076 } 2077 2078 STATIC int 2079 _bcm_tr2_vlan_vp_match_get(int unit, int vp, bcm_vlan_port_t *vlan_vp) 2080 { 2081 #if defined(BCM_TRIUMPH3_SUPPORT) 2082 if (SOC_IS_TRIUMPH3(unit)) { 2083 return _tr3_vlan_vp_match_get(unit, vp, vlan_vp); 2084 } else 2085 #endif 2086 { 2087 return _tr2_vlan_vp_match_get(unit, vp, vlan_vp); 2088 } 2089 } 2090 2091 STATIC int 2092 _bcm_tr2_vlan_vp_match_cleanup(int unit, bcm_vlan_port_t *vlan_vp) 2093 { 2094 #if defined(BCM_TRIUMPH3_SUPPORT) 2095 if (SOC_IS_TRIUMPH3(unit)) { 2096 return _tr3_vlan_vp_match_cleanup(unit, vlan_vp); 2097 } else 2098 #endif 2099 { 2100 return _tr2_vlan_vp_match_cleanup(unit, vlan_vp); 2101 } 2102 } 2103 2104 #ifdef BCM_TRIUMPH3_SUPPORT 2105 2106 /* 2107 * Function: 2108 * _bcm_tr3_vlan_eline_vp_map_set 2109 * Purpose: 2110 * Set VLAN ELINE ports from VPN 2111 * Parameters: 2112 * unit - (IN) Device Number 2113 * vfi_index - (IN) VFI Index 2114 * vp1 - (IN) VP1 2115 * vp1 - (IN) VP2 2116 * Returns: 2117 * BCM_E_XXX 2118 */ 2119 STATIC int 2120 _bcm_tr3_vlan_eline_vp_map_set(int unit, int vfi_index, int vp1, int vp2) 2121 { 2122 vfi_entry_t vfi_entry; 2123 int num_vp=0; 2124 2125 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2126 return BCM_E_NOT_FOUND; 2127 } 2128 2129 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 2130 if ((vp1 < 0) || (vp1 >= num_vp) || 2131 (vp2 < 0) || (vp2 >= num_vp)) { 2132 return BCM_E_PARAM; 2133 } 2134 2135 BCM_IF_ERROR_RETURN 2136 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2137 2138 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 2139 soc_VFIm_field32_set(unit, &vfi_entry, VP_0f, vp1); 2140 soc_VFIm_field32_set(unit, &vfi_entry, VP_1f, vp2); 2141 } else { 2142 /* ELAN */ 2143 return BCM_E_PARAM; 2144 } 2145 2146 return WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 2147 } 2148 2149 /* 2150 * Function: 2151 * _bcm_tr3_vlan_eline_port_add 2152 * Purpose: 2153 * Add VLAN ELINE port to a VPN 2154 * Parameters: 2155 * unit - (IN) Device Number 2156 * vpn - (IN) VPN instance ID 2157 * vlan_port - (IN) VLAN port information 2158 * Returns: 2159 * BCM_E_XXX 2160 */ 2161 STATIC int 2162 _bcm_tr3_vlan_eline_port_add(int unit, bcm_vpn_t vpn, bcm_vlan_port_t *vlan_port) 2163 { 2164 int active_vp = 0; /* default VP */ 2165 source_vp_entry_t svp; 2166 int vfi_index = -1; 2167 2168 if (vpn != _BCM_VLAN_VPN_INVALID) { 2169 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2170 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2171 return BCM_E_NOT_FOUND; 2172 } 2173 } else { 2174 vfi_index = _BCM_VLAN_VFI_INVALID; 2175 } 2176 2177 active_vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_port->vlan_port_id); 2178 if (active_vp == -1) { 2179 return BCM_E_PARAM; 2180 } 2181 2182 if (!_bcm_vp_used_get(unit, active_vp, _bcmVpTypeVlan)) { 2183 return BCM_E_NOT_FOUND; 2184 } 2185 2186 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, active_vp, &svp)); 2187 (void) _bcm_tr3_vlan_eline_vp_map_set(unit, vfi_index, active_vp, 0); 2188 2189 if (vlan_port->flags & BCM_VLAN_PORT_NETWORK) { 2190 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 1); 2191 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, 0x0); 2192 } else { 2193 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 0); 2194 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, 0x2); 2195 } 2196 2197 soc_SOURCE_VPm_field32_set(unit, &svp, DISABLE_VLAN_CHECKSf, 1); 2198 soc_SOURCE_VPm_field32_set(unit, &svp, 2199 ENTRY_TYPEf, 0x1); /* VFI Type */ 2200 soc_SOURCE_VPm_field32_set(unit, &svp, VFIf, vfi_index); 2201 2202 return WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, active_vp, &svp); 2203 } 2204 2205 /* 2206 * Function: 2207 * _bcm_tr3_vlan_elan_port_add 2208 * Purpose: 2209 * Add VLAN ELAN port to a VPN 2210 * Parameters: 2211 * unit - (IN) Device Number 2212 * vpn - (IN) VPN instance ID 2213 * vlan_vp - (IN) vlan port information 2214 * Returns: 2215 * BCM_E_XXX 2216 */ 2217 2218 STATIC int 2219 _bcm_tr3_vlan_elan_port_add(int unit, bcm_vpn_t vpn, bcm_vlan_port_t *vlan_vp) 2220 { 2221 int vp, vfi = 0; 2222 source_vp_entry_t svp; 2223 2224 if (vpn != _BCM_VLAN_VPN_INVALID) { 2225 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 2226 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVlan)) { 2227 return BCM_E_NOT_FOUND; 2228 } 2229 } else { 2230 vfi = _BCM_VLAN_VFI_INVALID; 2231 } 2232 2233 vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_vp->vlan_port_id); 2234 if (vp == -1) { 2235 return BCM_E_PARAM; 2236 } 2237 2238 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 2239 return BCM_E_NOT_FOUND; 2240 } 2241 2242 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 2243 2244 2245 /* ======== Configure SVP/DVP Properties ========== */ 2246 if (vpn == _BCM_VLAN_VPN_INVALID) { 2247 soc_SOURCE_VPm_field32_set(unit, &svp, ENTRY_TYPEf, 0x0); 2248 } else { 2249 /* Initialize VP parameters */ 2250 soc_SOURCE_VPm_field32_set(unit, &svp, ENTRY_TYPEf, 0x1); 2251 } 2252 2253 soc_SOURCE_VPm_field32_set(unit, &svp, VFIf, vfi); 2254 if (vlan_vp->flags & BCM_VLAN_PORT_NETWORK) { 2255 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 1); 2256 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, 0x0); 2257 } else { 2258 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 0); 2259 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, 0x2); 2260 } 2261 2262 if (soc_mem_field_valid(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) { 2263 soc_SOURCE_VPm_field32_set(unit, &svp, DISABLE_VLAN_CHECKSf, 1); 2264 } 2265 2266 return WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 2267 } 2268 2269 /* Function: 2270 * _bcm_tr3_vlan_vpn_is_valid 2271 * Purpose: 2272 * Find if given VLAN VPN is Valid 2273 * Parameters: 2274 * unit - Device Number 2275 * vpn - VLAN VPN 2276 * Returns: 2277 * BCM_E_XXXX 2278 */ 2279 int 2280 _bcm_tr3_vlan_vpn_is_valid( int unit, bcm_vpn_t vpn) 2281 { 2282 bcm_vpn_t vpn_min=0; 2283 int vfi_index=-1, num_vfi=0; 2284 2285 num_vfi = soc_mem_index_count(unit, VFIm); 2286 /* Check for Valid vpn */ 2287 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 2288 if (vpn < vpn_min || vpn > (vpn_min + num_vfi - 1)) { 2289 return BCM_E_PARAM; 2290 } 2291 2292 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2293 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2294 return BCM_E_NOT_FOUND; 2295 } 2296 2297 return BCM_E_NONE; 2298 } 2299 2300 /* Function: 2301 * _bcm_tr3_vlan_vpn_is_eline 2302 * Purpose: 2303 * Find if given VLAN VPN is ELINE 2304 * Parameters: 2305 * unit - Device Number 2306 * vpn - VLAN VPN 2307 * isEline - Flag 2308 * Returns: 2309 * BCM_E_XXXX 2310 * Assumes: 2311 * l2vpn is valid 2312 */ 2313 2314 int 2315 _bcm_tr3_vlan_vpn_is_eline( int unit, bcm_vpn_t vpn, uint8 *isEline) 2316 { 2317 int vfi_index=-1; 2318 vfi_entry_t vfi_entry; 2319 2320 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vpn_is_valid(unit, vpn)); 2321 2322 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2323 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2324 2325 /* Set the returned VPN id */ 2326 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 2327 *isEline = 1; /* ELINE */ 2328 } else { 2329 *isEline = 0; /* ELAN */ 2330 } 2331 2332 return BCM_E_NONE; 2333 } 2334 2335 /* 2336 * Function: 2337 * _bcm_tr3_vlan_port_add 2338 * Purpose: 2339 * Add a VLAN port to the specified VPN. 2340 * Parameters: 2341 * unit - (IN) SOC unit number. 2342 * vlan - (IN) VLAN ID to add virtual port to as a member. 2343 * vlan_vp - (IN) VP port information 2344 * Returns: 2345 * BCM_E_XXX 2346 */ 2347 STATIC int 2348 _bcm_tr3_vlan_port_add(int unit, bcm_vpn_t vpn, 2349 bcm_vlan_port_t *vlan_vp) 2350 { 2351 int mode=0, rv = BCM_E_PARAM; 2352 uint8 isEline=0xFF; 2353 2354 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_egress_mode_get(unit, &mode)); 2355 if (!mode) { 2356 LOG_INFO(BSL_LS_BCM_L3, 2357 (BSL_META_U(unit, 2358 "L3 egress mode must be set first\n"))); 2359 return BCM_E_DISABLED; 2360 } 2361 2362 if ((vpn != _BCM_VLAN_VPN_INVALID) && (isEline != 0x0)) { 2363 BCM_IF_ERROR_RETURN 2364 (_bcm_tr3_vlan_vpn_is_eline(unit, vpn, &isEline)); 2365 } 2366 2367 if (isEline == 0x1) { 2368 rv = _bcm_tr3_vlan_eline_port_add(unit, vpn, vlan_vp); 2369 } else if (isEline == 0x0) { 2370 rv = _bcm_tr3_vlan_elan_port_add(unit, vpn, vlan_vp); 2371 } 2372 2373 return rv; 2374 } 2375 2376 /* 2377 * Function: 2378 * _bcm_tr3_vlan_eline_vp_map_get 2379 * Purpose: 2380 * Get VLAN ELINE ports from VPN 2381 * Parameters: 2382 * unit - (IN) Device Number 2383 * vpn - (IN) VPN instance ID 2384 * Returns: 2385 * BCM_E_XXX 2386 */ 2387 2388 STATIC int 2389 _bcm_tr3_vlan_eline_vp_map_get(int unit, int vfi_index, int *vp1, int *vp2) 2390 { 2391 vfi_entry_t vfi_entry; 2392 2393 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2394 return BCM_E_NOT_FOUND; 2395 } 2396 2397 BCM_IF_ERROR_RETURN 2398 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2399 2400 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 2401 *vp1 = soc_VFIm_field32_get(unit, &vfi_entry, VP_0f); 2402 *vp2 = soc_VFIm_field32_get(unit, &vfi_entry, VP_1f); 2403 return BCM_E_NONE; 2404 } 2405 2406 return BCM_E_PARAM; 2407 } 2408 2409 /* Function: 2410 * _bcm_tr3_vlan_vp_is_eline 2411 * Purpose: 2412 * Find if given VLAN VP is ELINE 2413 * Parameters: 2414 * unit - Device Number 2415 * vp - VLAN VP 2416 * isEline - Flag 2417 * Returns: 2418 * BCM_E_XXXX 2419 * Assumes: 2420 * vp is valid 2421 */ 2422 STATIC int 2423 _bcm_tr3_vlan_vp_is_eline( int unit, int vp, uint8 *isEline) 2424 { 2425 source_vp_entry_t svp; 2426 vfi_entry_t vfi_entry; 2427 int vfi_index; 2428 2429 if (vp == -1) { 2430 return BCM_E_PARAM; 2431 } 2432 2433 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 2434 return BCM_E_NOT_FOUND; 2435 } 2436 2437 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 2438 2439 vfi_index = soc_SOURCE_VPm_field32_get(unit, &svp, VFIf); 2440 BCM_IF_ERROR_RETURN 2441 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2442 2443 /* Set the returned VPN id */ 2444 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 2445 *isEline = 0x1; 2446 } else { 2447 *isEline = 0x0; 2448 } 2449 2450 return BCM_E_NONE; 2451 } 2452 2453 /* 2454 * Function: 2455 * _bcm_tr3_vlan_eline_port_delete 2456 * Purpose: 2457 * Delete VLAN ELINE port from a VPN 2458 * Parameters: 2459 * unit - (IN) Device Number 2460 * vpn - (IN) VPN instance ID 2461 * active_vp - (IN) Active vp 2462 * Returns: 2463 * BCM_E_XXX 2464 */ 2465 2466 STATIC int 2467 _bcm_tr3_vlan_eline_port_delete(int unit, bcm_vpn_t vpn, int active_vp) 2468 { 2469 source_vp_entry_t svp; 2470 int vp1=0, vp2=0, vfi_index= -1; 2471 2472 if (vpn != _BCM_VLAN_VPN_INVALID) { 2473 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2474 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2475 return BCM_E_NOT_FOUND; 2476 } 2477 } else { 2478 vfi_index = _BCM_VLAN_VFI_INVALID; 2479 } 2480 2481 if (!_bcm_vp_used_get(unit, active_vp, _bcmVpTypeVlan)) { 2482 return BCM_E_NOT_FOUND; 2483 } 2484 2485 /* ---- Read in current table values for VP1 and VP2 ----- */ 2486 (void) _bcm_tr3_vlan_eline_vp_map_get(unit, vfi_index, &vp1, &vp2); 2487 2488 /* If the other port is valid, point it to itself */ 2489 if (active_vp == vp1) { 2490 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_eline_vp_map_set(unit, vfi_index, 0, vp2)); 2491 } else if (active_vp == vp2) { 2492 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_eline_vp_map_set(unit, vfi_index, vp1, 0)); 2493 } 2494 2495 /* Check for Network-Port */ 2496 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, active_vp, &svp)); 2497 2498 /* Invalidate the VP being deleted */ 2499 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 2500 return WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, active_vp, &svp); 2501 } 2502 2503 /* 2504 * Function: 2505 * _bcm_tr3_vlan_elan_port_delete 2506 * Purpose: 2507 * Delete VLAN ELAN port from a VPN 2508 * Parameters: 2509 * unit - (IN) Device Number 2510 * vpn - (IN) VPN instance ID 2511 * vp - (IN) vxlan port information 2512 * Returns: 2513 * BCM_E_XXX 2514 */ 2515 2516 STATIC int 2517 _bcm_tr3_vlan_elan_port_delete(int unit, bcm_vpn_t vpn, int vp) 2518 { 2519 source_vp_entry_t svp; 2520 int network_port_flag=0; 2521 int vfi_index= -1; 2522 2523 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 2524 return BCM_E_NOT_FOUND; 2525 } 2526 2527 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 2528 network_port_flag = soc_SOURCE_VPm_field32_get(unit, &svp, NETWORK_PORTf); 2529 if (vpn != _BCM_VLAN_VPN_INVALID) { 2530 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2531 if (!network_port_flag) { 2532 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2533 return BCM_E_NOT_FOUND; 2534 } 2535 } 2536 2537 if (!((soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf) == 0x1) && 2538 (vfi_index == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf)))) { 2539 return BCM_E_PARAM; 2540 } 2541 } 2542 2543 /* Clear the SVP table entries */ 2544 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 2545 return WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 2546 } 2547 2548 /* 2549 * Function: 2550 * _bcm_tr3_vlan_port_delete 2551 * Purpose: 2552 * Delete VLAN port from a VPN 2553 * Parameters: 2554 * unit - (IN) Device Number 2555 * vpn - (IN) VPN instance ID 2556 * vp - (IN) vlan port 2557 * Returns: 2558 * BCM_E_XXX 2559 */ 2560 2561 STATIC int 2562 _bcm_tr3_vlan_port_delete(int unit, bcm_vpn_t vpn, int vp) 2563 { 2564 int rv = BCM_E_UNAVAIL; 2565 uint8 isEline=0; 2566 2567 if (vpn == _BCM_VLAN_VPN_INVALID) { 2568 return BCM_E_PARAM; 2569 } 2570 2571 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vpn_is_valid(unit, vpn)); 2572 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vp_is_eline(unit, vp, &isEline)); 2573 if (isEline == 0x1) { 2574 rv = _bcm_tr3_vlan_eline_port_delete(unit, vpn, vp); 2575 } else if (isEline == 0x0) { 2576 rv = _bcm_tr3_vlan_elan_port_delete(unit, vpn, vp); 2577 } 2578 2579 return rv; 2580 } 2581 2582 /* 2583 * Function: 2584 * _bcm_tr3_vlan_port_delete_all 2585 * Purpose: 2586 * Delete all VLAN ports from a VPN 2587 * Parameters: 2588 * unit - (IN) Device Number 2589 * vpn - (IN) VPN instance ID 2590 * Returns: 2591 * BCM_E_XXX 2592 */ 2593 STATIC int 2594 _bcm_tr3_vlan_port_delete_all(int unit, bcm_vpn_t vpn) 2595 { 2596 int vfi_index=0; 2597 int vp1 = 0, vp2 = 0; 2598 uint8 isEline=0xFF; 2599 uint32 vp=0; 2600 2601 BCM_IF_ERROR_RETURN 2602 (_bcm_tr3_vlan_vpn_is_eline(unit, vpn, &isEline)); 2603 2604 if (isEline == 0x1) { 2605 if (vpn != _BCM_VLAN_VPN_INVALID) { 2606 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2607 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2608 return BCM_E_NOT_FOUND; 2609 } 2610 } else { 2611 vfi_index = _BCM_VLAN_VFI_INVALID; 2612 } 2613 2614 /* ---- Read in current table values for VP1 and VP2 ----- */ 2615 (void) _bcm_tr3_vlan_eline_vp_map_get(unit, vfi_index, &vp1, &vp2); 2616 if (vp1 != 0) { 2617 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_eline_port_delete(unit, vpn, vp1)); 2618 } 2619 if (vp2 != 0) { 2620 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_eline_port_delete(unit, vpn, vp2)); 2621 } 2622 } else if (isEline == 0x0) { 2623 uint32 vfi, num_vp; 2624 source_vp_entry_t svp; 2625 2626 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 2627 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVlan)) { 2628 return BCM_E_NOT_FOUND; 2629 } 2630 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 2631 2632 SHR_BIT_ITER(VIRTUAL_INFO(unit)->vlan_vp_bitmap, num_vp, vp) { 2633 2634 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 2635 if ((soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf) == 0x1) && 2636 (vfi == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf))) { 2637 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_port_delete(unit, vpn, vp)); 2638 } 2639 } 2640 } 2641 2642 return BCM_E_NONE; 2643 } 2644 2645 /* 2646 * Function: 2647 * _bcm_tr3_vlan_port_get_all 2648 * Purpose: 2649 * Get all VLAN ports from a VPN 2650 * Parameters: 2651 * unit - (IN) SOC unit number. 2652 * vlan - (IN) VLAN ID. 2653 * array_max - (IN) Max number of elements in the array. 2654 * gport_array - (OUT) Array of virtual ports in GPORT format. 2655 * flags_array - (OUT) Array of flags. 2656 * array_size - (OUT) Actual number of elements in the array. 2657 */ 2658 STATIC int 2659 _bcm_tr3_vlan_port_get_all(int unit, bcm_vlan_t vpn, int array_max, 2660 bcm_gport_t *gport_array, int *flags_array, int *array_size) 2661 { 2662 int vp; 2663 int vfi_index=-1; 2664 int vp1 = 0, vp2 = 0; 2665 uint8 isEline=0xFF; 2666 2667 if (0 == array_max) { 2668 return BCM_E_NONE; 2669 } 2670 2671 *array_size = 0; 2672 2673 BCM_IF_ERROR_RETURN 2674 (_bcm_tr3_vlan_vpn_is_eline(unit, vpn, &isEline)); 2675 2676 if (isEline == 0x1) { 2677 if (vpn != _BCM_VLAN_VPN_INVALID) { 2678 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2679 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2680 return BCM_E_NOT_FOUND; 2681 } 2682 } else { 2683 vfi_index = _BCM_VLAN_VFI_INVALID; 2684 } 2685 2686 /* ---- Read in current table values for VP1 and VP2 ----- */ 2687 (void) _bcm_tr3_vlan_eline_vp_map_get (unit, vfi_index, &vp1, &vp2); 2688 if (_bcm_vp_used_get(unit, vp1, _bcmVpTypeVlan)) { 2689 BCM_GPORT_VLAN_PORT_ID_SET(gport_array[*array_size], vp1); 2690 flags_array[*array_size] = 0; 2691 (*array_size)++; 2692 } 2693 2694 if (_bcm_vp_used_get(unit, vp2, _bcmVpTypeVlan)) { 2695 if (array_max > *array_size) { 2696 BCM_GPORT_VLAN_PORT_ID_SET(gport_array[*array_size], vp2); 2697 flags_array[*array_size] = 0; 2698 (*array_size)++; 2699 } 2700 } 2701 } else if (isEline == 0x0) { 2702 uint32 vfi, entry_type; 2703 int num_vp; 2704 source_vp_entry_t svp; 2705 2706 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 2707 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVlan)) { 2708 return BCM_E_NOT_FOUND; 2709 } 2710 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 2711 SHR_BIT_ITER(VIRTUAL_INFO(unit)->vlan_vp_bitmap, num_vp, vp) { 2712 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 2713 entry_type = soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf); 2714 2715 if ((vfi == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf)) && 2716 (entry_type == 0x1)) { 2717 if (array_max > *array_size) { 2718 BCM_GPORT_VLAN_PORT_ID_SET(gport_array[*array_size], vp); 2719 flags_array[*array_size] = 0; 2720 (*array_size)++; 2721 } 2722 } 2723 } 2724 } 2725 2726 return BCM_E_NONE; 2727 } 2728 2729 /* 2730 * Function: 2731 * _bcm_tr3_vlan_vp_destroy_all 2732 * Purpose: 2733 * Destroy all virtual port in VPN instance. 2734 * Parameters: 2735 * unit - (IN) SOC unit number. 2736 * vpn - (IN) VPN instance ID. 2737 * Returns: 2738 * BCM_X_XXX 2739 */ 2740 int 2741 _bcm_tr3_vlan_vp_destroy_all(int unit, bcm_vpn_t vpn) 2742 { 2743 int vfi_index=0; 2744 int vp1 = 0, vp2 = 0; 2745 uint8 isEline=0xFF; 2746 uint32 vp=0; 2747 bcm_gport_t vlan_port_id; 2748 2749 BCM_IF_ERROR_RETURN 2750 (_bcm_tr3_vlan_vpn_is_eline(unit, vpn, &isEline)); 2751 2752 if (isEline == 0x1) { 2753 if (vpn != _BCM_VLAN_VPN_INVALID) { 2754 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 2755 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVlan)) { 2756 return BCM_E_NOT_FOUND; 2757 } 2758 } else { 2759 vfi_index = _BCM_VLAN_VFI_INVALID; 2760 } 2761 2762 /* ---- Read in current table values for VP1 and VP2 ----- */ 2763 (void) _bcm_tr3_vlan_eline_vp_map_get(unit, vfi_index, &vp1, &vp2); 2764 if (vp1 != 0) { 2765 BCM_GPORT_VLAN_PORT_ID_SET(vlan_port_id, vp1); 2766 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_vp_destroy(unit, vlan_port_id)); 2767 } 2768 if (vp2 != 0) { 2769 BCM_GPORT_VLAN_PORT_ID_SET(vlan_port_id, vp2); 2770 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_vp_destroy(unit, vlan_port_id)); 2771 } 2772 } else if (isEline == 0x0) { 2773 uint32 vfi, num_vp; 2774 source_vp_entry_t svp; 2775 2776 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 2777 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVlan)) { 2778 return BCM_E_NOT_FOUND; 2779 } 2780 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 2781 2782 SHR_BIT_ITER(VIRTUAL_INFO(unit)->vlan_vp_bitmap, num_vp, vp) { 2783 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 2784 if ((soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf) == 0x1) && 2785 (vfi == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf))) { 2786 BCM_GPORT_VLAN_PORT_ID_SET(vlan_port_id, vp); 2787 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_vp_destroy(unit, vlan_port_id)); 2788 } 2789 } 2790 } 2791 2792 return BCM_E_NONE; 2793 } 2794 2795 #endif /* BCM_TRIUMPH3_SUPPORT */ 2796 2797 /* 2798 * Function: 2799 * _bcm_tr2_vlan_vp_create 2800 * Purpose: 2801 * Create a VLAN virtual port. 2802 * Parameters: 2803 * unit - (IN) SOC unit number. 2804 * vlan_vp - (IN/OUT) Pointer to VLAN virtual port structure. 2805 * Returns: 2806 * BCM_X_XXX 2807 */ 2808 STATIC int 2809 _bcm_tr2_vlan_vp_create(int unit, 2810 bcm_vlan_port_t *vlan_vp) 2811 { 2812 int mode; 2813 int vp, old_vp = 0, matched_vp; 2814 int rv = BCM_E_NONE; 2815 int num_vp; 2816 int nh_index = 0; 2817 ing_dvp_table_entry_t dvp_entry; 2818 source_vp_entry_t svp_entry; 2819 int cml_default_enable=0, cml_default_new=0, cml_default_move=0; 2820 _bcm_vp_info_t vp_info; 2821 int tpid_enable = 0, tpid_index=-1; 2822 int policer_set = 0; 2823 int network_group; 2824 _bcm_vp_info_init(&vp_info); 2825 vp_info.vp_type = _bcmVpTypeVlan; 2826 2827 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_egress_mode_get(unit, &mode)); 2828 if (!mode) { 2829 LOG_INFO(BSL_LS_BCM_L3, 2830 (BSL_META_U(unit, 2831 "L3 egress mode must be set first\n"))); 2832 return BCM_E_DISABLED; 2833 } 2834 2835 if (((vlan_vp->flags & BCM_VLAN_PORT_EGRESS_PON_TUNNEL_NONE) || 2836 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL) || 2837 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN) || 2838 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN)) && 2839 (!soc_feature(unit, soc_feature_lltag))) { 2840 return BCM_E_UNAVAIL; 2841 } else if ((vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL) || 2842 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_VLAN) || 2843 (vlan_vp->criteria == BCM_VLAN_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN)) { 2844 if (vlan_vp->match_tunnel_value >= BCM_VLAN_INVALID) { 2845 return BCM_E_PARAM; 2846 } 2847 } 2848 2849 if (!(vlan_vp->flags & BCM_VLAN_PORT_REPLACE)) { /* Create new VLAN VP */ 2850 2851 if (vlan_vp->flags & BCM_VLAN_PORT_WITH_ID) { 2852 if (!BCM_GPORT_IS_VLAN_PORT(vlan_vp->vlan_port_id)) { 2853 return BCM_E_PARAM; 2854 } 2855 vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_vp->vlan_port_id); 2856 if (vp >= soc_mem_index_count(unit, SOURCE_VPm)) { 2857 return BCM_E_PARAM; 2858 } 2859 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 2860 return BCM_E_EXISTS; 2861 } else { 2862 rv = _bcm_vp_used_set(unit, vp, vp_info); 2863 if (rv < 0) { 2864 return rv; 2865 } 2866 } 2867 } else { 2868 /* allocate a new VP index */ 2869 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 2870 rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, 2871 vp_info, &vp); 2872 if (rv < 0) { 2873 return rv; 2874 } 2875 } 2876 2877 /* Configure next hop tables */ 2878 rv = _bcm_tr2_vlan_vp_nh_info_set(unit, vlan_vp, vp, 0, 2879 &nh_index); 2880 if (rv < 0) { 2881 goto cleanup; 2882 } 2883 2884 /* Configure DVP table */ 2885 sal_memset(&dvp_entry, 0, sizeof(ing_dvp_table_entry_t)); 2886 soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry, NEXT_HOP_INDEXf, 2887 nh_index); 2888 rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp_entry); 2889 if (rv < 0) { 2890 goto cleanup; 2891 } 2892 2893 rv = _bcm_vp_ing_dvp_to_ing_dvp2(unit, &dvp_entry, vp); 2894 if (rv < 0) { 2895 goto cleanup; 2896 } 2897 2898 /* Configure SVP table */ 2899 sal_memset(&svp_entry, 0, sizeof(source_vp_entry_t)); 2900 soc_SOURCE_VPm_field32_set(unit, &svp_entry, ENTRY_TYPEf, 3); 2901 2902 2903 /* Set the CML */ 2904 rv = _bcm_vp_default_cml_mode_get (unit, 2905 &cml_default_enable, &cml_default_new, 2906 &cml_default_move); 2907 if (rv < 0) { 2908 goto cleanup; 2909 } 2910 2911 if (cml_default_enable) { 2912 /* Set the CML to default values */ 2913 soc_SOURCE_VPm_field32_set(unit, &svp_entry, CML_FLAGS_NEWf, cml_default_new); 2914 soc_SOURCE_VPm_field32_set(unit, &svp_entry, CML_FLAGS_MOVEf, cml_default_move); 2915 } else { 2916 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 2917 soc_SOURCE_VPm_field32_set(unit, &svp_entry, CML_FLAGS_NEWf, 0x8); 2918 soc_SOURCE_VPm_field32_set(unit, &svp_entry, CML_FLAGS_MOVEf, 0x8); 2919 } 2920 2921 #if defined(BCM_TRIUMPH3_SUPPORT) 2922 if (soc_feature(unit, soc_feature_vlan_vfi) && (vlan_vp->flags & BCM_VLAN_PORT_SERVICE_TAGGED)) { 2923 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, 2924 vlan_vp->egress_service_tpid, &tpid_index)); 2925 tpid_enable = 1 << tpid_index; 2926 soc_SOURCE_VPm_field32_set(unit, &svp_entry, TPID_ENABLEf, tpid_enable); 2927 soc_SOURCE_VPm_field32_set(unit, &svp_entry, SD_TAG_MODEf, 1); 2928 } 2929 #endif /*BCM_TRIUMPH3_SUPPORT*/ 2930 2931 if (vlan_vp->policer_id != 0) { 2932 if (soc_feature(unit, soc_feature_global_meter)) { 2933 rv = _bcm_esw_add_policer_to_table(unit, vlan_vp->policer_id, 2934 SOURCE_VPm, vp, &svp_entry); 2935 policer_set = 1; 2936 } else { 2937 rv = BCM_E_PARAM; 2938 } 2939 if (rv < 0) { 2940 goto cleanup; 2941 } 2942 } 2943 #if defined(BCM_SABER2_SUPPORT) 2944 if (SOC_IS_SABER2(unit)) { 2945 if (vlan_vp->flags & BCM_VLAN_PORT_USE_SGLP_TPID) { 2946 /* Use TPIDs based on SGLP */ 2947 soc_SOURCE_VPm_field32_set(unit, &svp_entry, TPID_SOURCEf, 2); 2948 } 2949 } 2950 #endif 2951 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry); 2952 if (rv < 0) { 2953 goto cleanup; 2954 } 2955 2956 /* Configure ingress VLAN translation table */ 2957 rv = _bcm_tr2_vlan_vp_match_add(unit, vlan_vp, vp); 2958 if (rv < 0) { 2959 goto cleanup; 2960 } 2961 2962 /* Increment port's VP count */ 2963 rv = _bcm_tr2_vlan_vp_port_cnt_update(unit, vlan_vp->port, vp, TRUE); 2964 if (rv < 0) { 2965 goto cleanup; 2966 } 2967 2968 } else { /* Replace properties of existing VLAN VP */ 2969 2970 if (!(vlan_vp->flags & BCM_VLAN_PORT_WITH_ID)) { 2971 return BCM_E_PARAM; 2972 } 2973 if (!BCM_GPORT_IS_VLAN_PORT(vlan_vp->vlan_port_id)) { 2974 return BCM_E_PARAM; 2975 } 2976 vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_vp->vlan_port_id); 2977 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 2978 return BCM_E_PARAM; 2979 } 2980 2981 if (soc_feature(unit, soc_feature_global_meter)) { 2982 /* read Source_VP mem, add, write back */ 2983 BCM_IF_ERROR_RETURN( 2984 READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 2985 BCM_IF_ERROR_RETURN( 2986 _bcm_esw_add_policer_to_table(unit, vlan_vp->policer_id, 2987 SOURCE_VPm, vp, &svp_entry)); 2988 #if defined(BCM_SABER2_SUPPORT) 2989 if (SOC_IS_SABER2(unit)) { 2990 if (vlan_vp->flags & BCM_VLAN_PORT_USE_SGLP_TPID) { 2991 /* Use TPIDs based on SGLP */ 2992 soc_SOURCE_VPm_field32_set(unit, &svp_entry, TPID_SOURCEf, 2); 2993 } else { 2994 if(soc_SOURCE_VPm_field32_get(unit, &svp_entry, TPID_SOURCEf) == 2) { 2995 soc_SOURCE_VPm_field32_set(unit, &svp_entry, TPID_SOURCEf, 0); 2996 } 2997 } 2998 } 2999 #endif 3000 BCM_IF_ERROR_RETURN( 3001 WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry)); 3002 } else { 3003 if (vlan_vp->policer_id != 0) { 3004 return BCM_E_PARAM; 3005 } 3006 } 3007 3008 /* For existing vlan vp, NH entry already exists */ 3009 BCM_IF_ERROR_RETURN 3010 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 3011 3012 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 3013 NEXT_HOP_INDEXf); 3014 3015 /* Update existing next hop entries */ 3016 BCM_IF_ERROR_RETURN 3017 (_bcm_tr2_vlan_vp_nh_info_set(unit, vlan_vp, vp, 0, 3018 &nh_index)); 3019 3020 /* Delete old ingress VLAN translation entry, 3021 * install new ingress VLAN translation entry 3022 */ 3023 BCM_IF_ERROR_RETURN 3024 (_bcm_tr2_vlan_vp_match_delete(unit, vp, &old_vp)); 3025 #ifdef BCM_TRIDENT2_SUPPORT 3026 /* The vlan port id may be one of members of a vplag. */ 3027 if (_bcm_vp_used_get(unit, old_vp, _bcmVpTypeVpLag)) { 3028 matched_vp = old_vp; 3029 } else 3030 #endif 3031 { 3032 matched_vp = vp; 3033 } 3034 BCM_IF_ERROR_RETURN 3035 (_bcm_tr2_vlan_vp_match_add(unit, vlan_vp, matched_vp)); 3036 3037 /* Decrement old port's VP count, increment new port's VP count */ 3038 BCM_IF_ERROR_RETURN 3039 (_bcm_tr2_vlan_vp_port_cnt_update(unit, 3040 VLAN_VP_INFO(unit, vp)->port, vp, FALSE)); 3041 3042 BCM_IF_ERROR_RETURN 3043 (_bcm_tr2_vlan_vp_port_cnt_update(unit, 3044 vlan_vp->port, vp, TRUE)); 3045 } 3046 /* Handle Split Horizon */ 3047 3048 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 3049 network_group = vlan_vp->ingress_network_group_id; 3050 rv = _bcm_validate_splithorizon_network_group(unit, 3051 vlan_vp->flags & BCM_VLAN_PORT_NETWORK, &network_group); 3052 if (rv < 0) { 3053 goto cleanup; 3054 } 3055 if (soc_mem_field_valid(unit, SOURCE_VPm, NETWORK_GROUPf)) { 3056 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry); 3057 if (rv < 0) { 3058 goto cleanup; 3059 } 3060 soc_SOURCE_VPm_field32_set(unit, &svp_entry, 3061 NETWORK_GROUPf, 3062 network_group); 3063 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry); 3064 if (rv < 0) { 3065 goto cleanup; 3066 } 3067 } 3068 network_group = vlan_vp->egress_network_group_id; 3069 rv = _bcm_validate_splithorizon_network_group(unit, 3070 vlan_vp->flags & BCM_VLAN_PORT_NETWORK, &network_group); 3071 if (rv < 0) { 3072 goto cleanup; 3073 } 3074 if (soc_mem_field_valid(unit, ING_DVP_TABLEm, NETWORK_GROUPf)) { 3075 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry); 3076 if (rv < 0) { 3077 goto cleanup; 3078 } 3079 soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry, 3080 NETWORK_GROUPf, 3081 network_group); 3082 rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp_entry); 3083 if (rv < 0) { 3084 goto cleanup; 3085 } 3086 } 3087 } 3088 3089 3090 /* Set VLAN VP software state */ 3091 VLAN_VP_INFO(unit, vp)->criteria = vlan_vp->criteria; 3092 VLAN_VP_INFO(unit, vp)->flags = vlan_vp->flags; 3093 VLAN_VP_INFO(unit, vp)->match_vlan = vlan_vp->match_vlan; 3094 VLAN_VP_INFO(unit, vp)->match_inner_vlan = vlan_vp->match_inner_vlan; 3095 VLAN_VP_INFO(unit, vp)->port = vlan_vp->port; 3096 VLAN_VP_INFO(unit, vp)->match_tunnel_value = vlan_vp->match_tunnel_value; 3097 3098 BCM_GPORT_VLAN_PORT_ID_SET(vlan_vp->vlan_port_id, vp); 3099 vlan_vp->encap_id = nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 3100 3101 return rv; 3102 3103 cleanup: 3104 if (!(vlan_vp->flags & BCM_VLAN_PORT_REPLACE)) { 3105 (void) _bcm_vp_free(unit, _bcmVpTypeVlan, 1, vp); 3106 _bcm_tr2_vlan_vp_nh_info_delete(unit, nh_index); 3107 3108 (void)_bcm_vp_ing_dvp_config(unit, _bcmVpIngDvpConfigClear, vp, 3109 ING_DVP_CONFIG_INVALID_VP_TYPE, 3110 ING_DVP_CONFIG_INVALID_INTF_ID, 3111 ING_DVP_CONFIG_INVALID_PORT_TYPE); 3112 3113 if (policer_set) { 3114 /* Decrement the reference count for the policer */ 3115 if (soc_feature(unit, soc_feature_global_meter)) { 3116 (void)_bcm_esw_policer_decrement_ref_count(unit, vlan_vp->policer_id); 3117 } 3118 } 3119 sal_memset(&svp_entry, 0, sizeof(source_vp_entry_t)); 3120 (void)WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry); 3121 3122 (void)_bcm_tr2_vlan_vp_match_cleanup(unit, vlan_vp); 3123 } 3124 3125 if (tpid_enable) { 3126 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 3127 } 3128 3129 return rv; 3130 } 3131 3132 /* 3133 * Function: 3134 * bcm_tr2_vlan_vp_create 3135 * Purpose: 3136 * Create a VLAN virtual port. 3137 * Parameters: 3138 * unit - (IN) SOC unit number. 3139 * vlan_vp - (IN/OUT) Pointer to VLAN virtual port structure. 3140 * Returns: 3141 * BCM_X_XXX 3142 */ 3143 int 3144 bcm_tr2_vlan_vp_create(int unit, 3145 bcm_vlan_port_t *vlan_vp) 3146 { 3147 int rv; 3148 3149 VLAN_VIRTUAL_INIT(unit); 3150 3151 VLAN_VIRTUAL_LOCK(unit); 3152 3153 rv = _bcm_tr2_vlan_vp_create(unit, vlan_vp); 3154 3155 VLAN_VIRTUAL_UNLOCK(unit); 3156 3157 return rv; 3158 } 3159 3160 /* 3161 * Function: 3162 * _bcm_tr2_vlan_vp_destroy 3163 * Purpose: 3164 * Destroy a VLAN virtual port. 3165 * Parameters: 3166 * unit - (IN) SOC unit number. 3167 * gport - (IN) VLAN VP GPORT ID. 3168 * Returns: 3169 * BCM_X_XXX 3170 */ 3171 STATIC int 3172 _bcm_tr2_vlan_vp_destroy(int unit, bcm_gport_t gport) 3173 { 3174 int vp; 3175 source_vp_entry_t svp_entry; 3176 int nh_index; 3177 ing_dvp_table_entry_t dvp_entry; 3178 bcm_policer_t policer = 0; 3179 3180 if (!BCM_GPORT_IS_VLAN_PORT(gport)) { 3181 return BCM_E_PARAM; 3182 } 3183 3184 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 3185 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 3186 return BCM_E_NOT_FOUND; 3187 } 3188 3189 #ifdef BCM_TRIDENT_SUPPORT 3190 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3191 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 3192 BCM_IF_ERROR_RETURN 3193 (bcm_td2p_vp_vlan_member_set(unit, gport, 0)); 3194 } else 3195 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 3196 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 3197 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 3198 /* Disable ingress and egress filter modes */ 3199 BCM_IF_ERROR_RETURN 3200 (bcm_td_vp_vlan_member_set(unit, gport, 0)); 3201 } 3202 #endif /* BCM_TRIDENT_SUPPORT */ 3203 3204 /* Delete ingress VLAN translation entry */ 3205 BCM_IF_ERROR_RETURN 3206 (_bcm_tr2_vlan_vp_match_delete(unit, vp, NULL)); 3207 3208 #ifdef BCM_TRIUMPH3_SUPPORT 3209 if (soc_feature(unit, soc_feature_vlan_vfi)) { 3210 bcm_vpn_t vpn; 3211 int vfi_index; 3212 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 3213 vfi_index = soc_SOURCE_VPm_field32_get(unit, &svp_entry, VFIf); 3214 if (vfi_index != _BCM_VLAN_VFI_INVALID) { 3215 _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, vfi_index); 3216 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_port_delete(unit, vpn, vp)); 3217 } 3218 } 3219 #endif /* BCM_TRIUMPH3_SUPPORT */ 3220 3221 if (soc_feature(unit, soc_feature_global_meter)) { 3222 BCM_IF_ERROR_RETURN(_bcm_esw_get_policer_from_table(unit, 3223 SOURCE_VPm, vp, &svp_entry, &policer, 0)); 3224 if (policer != 0) { 3225 /* Decrement reference count */ 3226 BCM_IF_ERROR_RETURN( 3227 _bcm_esw_policer_decrement_ref_count(unit, policer)); 3228 } 3229 } 3230 3231 /* Clear SVP entry */ 3232 sal_memset(&svp_entry, 0, sizeof(source_vp_entry_t)); 3233 BCM_IF_ERROR_RETURN 3234 (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry)); 3235 3236 /* Clear DVP entry */ 3237 BCM_IF_ERROR_RETURN 3238 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 3239 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, NEXT_HOP_INDEXf); 3240 3241 BCM_IF_ERROR_RETURN 3242 (_bcm_vp_ing_dvp_config(unit, _bcmVpIngDvpConfigClear, vp, 3243 ING_DVP_CONFIG_INVALID_VP_TYPE, 3244 ING_DVP_CONFIG_INVALID_INTF_ID, 3245 ING_DVP_CONFIG_INVALID_PORT_TYPE)); 3246 3247 /* Clear next hop entries and free next hop index */ 3248 BCM_IF_ERROR_RETURN 3249 (_bcm_tr2_vlan_vp_nh_info_delete(unit, nh_index)); 3250 3251 /* Decrement port's VP count */ 3252 BCM_IF_ERROR_RETURN 3253 (_bcm_tr2_vlan_vp_port_cnt_update(unit, 3254 VLAN_VP_INFO(unit, vp)->port, 3255 vp, FALSE)); 3256 /* Free VP */ 3257 BCM_IF_ERROR_RETURN 3258 (_bcm_vp_free(unit, _bcmVpTypeVlan, 1, vp)); 3259 3260 /* Clear VLAN VP software state */ 3261 sal_memset(VLAN_VP_INFO(unit, vp), 0, sizeof(_bcm_tr2_vlan_vp_info_t)); 3262 3263 return BCM_E_NONE; 3264 } 3265 3266 /* 3267 * Function: 3268 * bcm_tr2_vlan_vp_destroy 3269 * Purpose: 3270 * Destroy a VLAN virtual port. 3271 * Parameters: 3272 * unit - (IN) SOC unit number. 3273 * gport - (IN) VLAN VP GPORT ID. 3274 * Returns: 3275 * BCM_X_XXX 3276 */ 3277 int 3278 bcm_tr2_vlan_vp_destroy(int unit, bcm_gport_t gport) 3279 { 3280 int rv; 3281 3282 VLAN_VIRTUAL_INIT(unit); 3283 3284 VLAN_VIRTUAL_LOCK(unit); 3285 3286 rv = _bcm_tr2_vlan_vp_destroy(unit, gport); 3287 3288 VLAN_VIRTUAL_UNLOCK(unit); 3289 3290 return rv; 3291 } 3292 #define _BCM_QOS_MAP_SHIFT 10 3293 /* 3294 * Function: 3295 * _bcm_tr2_vlan_vp_find 3296 * Purpose: 3297 * Get VLAN virtual port info. 3298 * Parameters: 3299 * unit - (IN) SOC unit number. 3300 * vlan_vp - (IN/OUT) Pointer to VLAN virtual port structure. 3301 * Returns: 3302 * BCM_X_XXX 3303 */ 3304 STATIC int 3305 _bcm_tr2_vlan_vp_find(int unit, bcm_vlan_port_t *vlan_vp) 3306 { 3307 int vp; 3308 ing_dvp_table_entry_t dvp_entry; 3309 int nh_index; 3310 source_vp_entry_t svp_entry; 3311 egr_l3_next_hop_entry_t egr_nh; 3312 #ifdef BCM_KATANA_SUPPORT 3313 bcm_if_t intf = 0; 3314 int profile_index = -1; 3315 #endif 3316 if (!BCM_GPORT_IS_VLAN_PORT(vlan_vp->vlan_port_id)) { 3317 return BCM_E_PARAM; 3318 } 3319 3320 vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_vp->vlan_port_id); 3321 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 3322 return BCM_E_NOT_FOUND; 3323 } 3324 3325 bcm_vlan_port_t_init(vlan_vp); 3326 3327 BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_vp_match_get(unit, vp, vlan_vp)); 3328 3329 vlan_vp->flags = VLAN_VP_INFO(unit, vp)->flags; 3330 3331 BCM_IF_ERROR_RETURN 3332 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 3333 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, NEXT_HOP_INDEXf); 3334 vlan_vp->encap_id = nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 3335 3336 /* Get Egress Class */ 3337 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__CLASS_IDf)) { 3338 /* Read the existing egress next_hop entry */ 3339 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 3340 nh_index, &egr_nh)); 3341 vlan_vp->if_class = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 3342 &egr_nh, SD_TAG__CLASS_IDf); 3343 } 3344 3345 BCM_GPORT_VLAN_PORT_ID_SET(vlan_vp->vlan_port_id, vp); 3346 3347 if (soc_feature(unit, soc_feature_global_meter)) { 3348 BCM_IF_ERROR_RETURN 3349 (_bcm_esw_get_policer_from_table(unit, SOURCE_VPm, vp, &svp_entry, 3350 &(vlan_vp->policer_id), 0)); 3351 } 3352 3353 #ifdef BCM_KATANA_SUPPORT 3354 if (soc_feature(unit, soc_feature_extended_queueing)) { 3355 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, nh_index)) { 3356 intf = nh_index + BCM_XGS3_EGRESS_IDX_MIN(unit); 3357 } else { 3358 intf = nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 3359 } 3360 if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(vlan_vp->port)) || 3361 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(vlan_vp->port)) || 3362 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(vlan_vp->port))) { 3363 BCM_IF_ERROR_RETURN( 3364 _bcm_kt_extended_queue_qos_profile_get(unit, intf, &profile_index)); 3365 } 3366 if (profile_index != -1) { 3367 profile_index = (profile_index & 0x3) | 3368 (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE << _BCM_QOS_MAP_SHIFT); 3369 } 3370 vlan_vp->qos_map_id = profile_index; 3371 } 3372 #endif 3373 return BCM_E_NONE; 3374 } 3375 3376 /* 3377 * Function: 3378 * bcm_tr2_vlan_vp_find 3379 * Purpose: 3380 * Get VLAN virtual port info. 3381 * Parameters: 3382 * unit - (IN) SOC unit number. 3383 * vlan_vp - (IN/OUT) Pointer to VLAN virtual port structure. 3384 * Returns: 3385 * BCM_X_XXX 3386 */ 3387 int 3388 bcm_tr2_vlan_vp_find(int unit, bcm_vlan_port_t *vlan_vp) 3389 { 3390 VLAN_VIRTUAL_INIT(unit); 3391 return _bcm_tr2_vlan_vp_find(unit, vlan_vp); 3392 } 3393 /* 3394 * Function: 3395 * bcm_tr2_vlan_port_learn_set 3396 * Purpose: 3397 * Modifies learning on a l2 logical port. 3398 * Parameters: 3399 * unit - SOC unit number 3400 * vlan_port_if - l2 logical port ID 3401 * flags - learning control flags 3402 * Returns: 3403 * BCM error code (BCM_E_XXX) 3404 */ 3405 int 3406 bcm_tr2_vlan_port_learn_set(int unit, bcm_gport_t vlan_port_id, uint32 flags) 3407 { 3408 int vp, cml = 0, rv = BCM_E_NONE; 3409 source_vp_entry_t svp; 3410 3411 cml = 0; 3412 if (!(flags & BCM_PORT_LEARN_FWD)) { 3413 cml |= (1 << 0); 3414 } 3415 if (flags & BCM_PORT_LEARN_CPU) { 3416 cml |= (1 << 1); 3417 } 3418 if (flags & BCM_PORT_LEARN_PENDING) { 3419 cml |= (1 << 2); 3420 } 3421 if (flags & BCM_PORT_LEARN_ARL) { 3422 cml |= (1 << 3); 3423 } 3424 3425 /* Get the VP index from the gport */ 3426 vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_port_id); 3427 if (vp == -1) { 3428 return BCM_E_PARAM; 3429 } 3430 3431 /* Be sure the entry is used and is set for VLAN virtual ports */ 3432 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 3433 return BCM_E_NOT_FOUND; 3434 } 3435 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 3436 if (rv < 0) { 3437 return rv; 3438 } 3439 if (soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf) != 3) { /* VLAN PORT (GPON)*/ 3440 return BCM_E_NOT_FOUND; 3441 } 3442 3443 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, cml); 3444 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, cml); 3445 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 3446 3447 return rv; 3448 } 3449 3450 /* 3451 * Function: 3452 * bcm_tr2_vlan_port_phys_gport_get 3453 * Purpose: 3454 * Get the physical gport of a VLAN port. 3455 * Returns: 3456 * BCM_E_XXX 3457 */ 3458 3459 int 3460 bcm_tr2_vlan_port_phys_gport_get(int unit, int vp, bcm_gport_t *gp) 3461 { 3462 int nh_index; 3463 ing_dvp_table_entry_t dvp; 3464 ing_l3_next_hop_entry_t ing_nh; 3465 bcm_module_t mod_out, mod_in; 3466 bcm_port_t port_out, port_in; 3467 bcm_trunk_t trunk_id; 3468 3469 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 3470 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 3471 BCM_IF_ERROR_RETURN(soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, 3472 nh_index, &ing_nh)); 3473 3474 if (soc_feature(unit, soc_feature_generic_dest)) { 3475 uint32 dest_type = SOC_MEM_FIF_DEST_INVALID, dest = 0; 3476 dest = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, &ing_nh, 3477 DESTINATIONf, &dest_type); 3478 if (dest_type == SOC_MEM_FIF_DEST_LAG) { 3479 trunk_id = (dest & SOC_MEM_FIF_DGPP_TGID_MASK); 3480 BCM_GPORT_TRUNK_SET(*gp, trunk_id); 3481 } else if (dest_type == SOC_MEM_FIF_DEST_DGPP) { 3482 mod_in = (dest & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 3483 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 3484 port_in = dest & SOC_MEM_FIF_DGPP_PORT_MASK; 3485 BCM_IF_ERROR_RETURN 3486 (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_in, port_in, 3487 &mod_out, &port_out)); 3488 BCM_GPORT_MODPORT_SET(*gp, mod_out, port_out); 3489 } 3490 } else { 3491 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 3492 trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 3493 BCM_GPORT_TRUNK_SET(*gp, trunk_id); 3494 } else { 3495 mod_in = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 3496 port_in = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 3497 BCM_IF_ERROR_RETURN 3498 (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_in, port_in, 3499 &mod_out, &port_out)); 3500 BCM_GPORT_MODPORT_SET(*gp, mod_out, port_out); 3501 } 3502 } 3503 3504 return BCM_E_NONE; 3505 } 3506 3507 void 3508 bcm_tr2_vlan_port_match_count_adjust(int unit, int vp, int step) 3509 { 3510 VLAN_VP_INFO(unit, vp)->match_count += step; 3511 } 3512 3513 /* 3514 * Function: 3515 * _bcm_tr2_vlan_port_resolve 3516 * Purpose: 3517 * Get the modid, port, trunk values for a VLAN virtual port 3518 * Parameters: 3519 * unit - (IN) BCM device number 3520 * gport - (IN) Global port identifier 3521 * modid - (OUT) Module ID 3522 * port - (OUT) Port number 3523 * trunk_id - (OUT) Trunk ID 3524 * id - (OUT) Virtual port ID 3525 * Returns: 3526 * BCM_E_XXX 3527 */ 3528 int 3529 _bcm_tr2_vlan_port_resolve(int unit, bcm_gport_t vlan_port_id, 3530 bcm_module_t *modid, bcm_port_t *port, 3531 bcm_trunk_t *trunk_id, int *id) 3532 3533 { 3534 int rv = BCM_E_NONE, nh_index, vp; 3535 ing_l3_next_hop_entry_t ing_nh; 3536 ing_dvp_table_entry_t dvp; 3537 3538 VLAN_VIRTUAL_INIT(unit); 3539 3540 if (!BCM_GPORT_IS_VLAN_PORT(vlan_port_id)) { 3541 return (BCM_E_BADID); 3542 } 3543 3544 vp = BCM_GPORT_VLAN_PORT_ID_GET(vlan_port_id); 3545 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 3546 return BCM_E_NOT_FOUND; 3547 } 3548 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 3549 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 3550 NEXT_HOP_INDEXf); 3551 BCM_IF_ERROR_RETURN (soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, 3552 nh_index, &ing_nh)); 3553 3554 if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf) != 0x2) && 3555 (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf) != 0x3)) { 3556 /* Entry type is not L2 DVP and is not GPON DVP*/ 3557 return BCM_E_NOT_FOUND; 3558 } 3559 3560 if (soc_feature(unit, soc_feature_generic_dest)) { 3561 uint32 dest_type = SOC_MEM_FIF_DEST_INVALID, dest = 0; 3562 dest = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, &ing_nh, 3563 DESTINATIONf, &dest_type); 3564 if (dest_type == SOC_MEM_FIF_DEST_LAG) { 3565 *trunk_id = (dest & SOC_MEM_FIF_DGPP_TGID_MASK); 3566 } else if (dest_type == SOC_MEM_FIF_DEST_DGPP) { 3567 *modid = (dest & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 3568 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 3569 *port = dest & SOC_MEM_FIF_DGPP_PORT_MASK; 3570 } 3571 } else { 3572 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 3573 *trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 3574 } else { 3575 /* Only add this to replication set if destination is local */ 3576 *modid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 3577 *port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 3578 } 3579 } 3580 *id = vp; 3581 return rv; 3582 } 3583 3584 /* ---------------------------------------------------------------------------- 3585 * 3586 * Routines for adding/removing virtual ports to/from VLAN 3587 * 3588 * ---------------------------------------------------------------------------- 3589 */ 3590 3591 /* 3592 * Function: 3593 * _bcm_tr2_phy_port_trunk_is_local 3594 * Purpose: 3595 * Determine if the given physical port or trunk is local. 3596 * Parameters: 3597 * unit - (IN) SOC unit number. 3598 * gport - (IN) Physical port or trunk GPORT ID. 3599 * is_local - (OUT) Indicates if gport is local. 3600 * Returns: 3601 * BCM_X_XXX 3602 */ 3603 STATIC int 3604 _bcm_tr2_phy_port_trunk_is_local(int unit, bcm_gport_t gport, int *is_local) 3605 { 3606 bcm_trunk_t trunk_id; 3607 int rv = BCM_E_NONE; 3608 int local_member_count; 3609 bcm_module_t mod_out; 3610 bcm_port_t port_out; 3611 int id; 3612 int modid_local; 3613 3614 *is_local = 0; 3615 3616 if (BCM_GPORT_IS_TRUNK(gport)) { 3617 trunk_id = BCM_GPORT_TRUNK_GET(gport); 3618 rv = _bcm_trunk_id_validate(unit, trunk_id); 3619 if (BCM_FAILURE(rv)) { 3620 return (BCM_E_PORT); 3621 } 3622 rv = _bcm_esw_trunk_local_members_get(unit, trunk_id, 3623 0, NULL, &local_member_count); 3624 if (BCM_FAILURE(rv)) { 3625 return (BCM_E_PORT); 3626 } 3627 if (local_member_count > 0) { 3628 *is_local = 1; 3629 } 3630 } else { 3631 BCM_IF_ERROR_RETURN 3632 (_bcm_esw_gport_resolve(unit, gport, &mod_out, &port_out, 3633 &trunk_id, &id)); 3634 /* In case of extended queuing on KTX, trunk_id gets updated with 3635 * extended queue value. So set it to invalid value. 3636 */ 3637 #ifdef BCM_KATANA_SUPPORT 3638 if (soc_feature(unit, soc_feature_extended_queueing)) { 3639 if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) || 3640 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) || 3641 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport))) { 3642 trunk_id = BCM_TRUNK_INVALID; 3643 } 3644 } 3645 #endif 3646 if ((trunk_id != -1) || (id != -1)) { 3647 return BCM_E_PARAM; 3648 } 3649 3650 BCM_IF_ERROR_RETURN 3651 (_bcm_esw_modid_is_local(unit, mod_out, &modid_local)); 3652 3653 *is_local = modid_local; 3654 } 3655 3656 return BCM_E_NONE; 3657 } 3658 3659 /* 3660 * Function: 3661 * _bcm_tr2_vlan_vp_untagged_add 3662 * Purpose: 3663 * Set VLAN VP tagging/untagging status by adding 3664 * a (VLAN VP, VLAN) egress VLAN translation entry. 3665 * Parameters: 3666 * unit - (IN) SOC unit number. 3667 * vlan - (IN) VLAN ID. 3668 * vp - (IN) Virtual port number. 3669 * flags - (IN) Untagging indication. 3670 * Returns: 3671 * BCM_X_XXX 3672 */ 3673 STATIC int 3674 _bcm_tr2_vlan_vp_untagged_add(int unit, bcm_vlan_t vlan, int vp, int flags) 3675 { 3676 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 3677 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 3678 bcm_vlan_action_set_t action; 3679 uint32 profile_idx; 3680 int rv; 3681 soc_mem_t mem = EGR_VLAN_XLATEm; 3682 3683 if (soc_mem_is_valid(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 3684 mem = EGR_VLAN_XLATE_1_DOUBLEm; 3685 } 3686 3687 sal_memset(vent, 0, sizeof(vent)); 3688 sal_memset(old_vent, 0, sizeof(old_vent)); 3689 3690 if (soc_feature(unit, soc_feature_base_valid)) { 3691 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 3692 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 3693 } else { 3694 soc_mem_field32_set(unit, mem, vent, VALIDf, 1); 3695 } 3696 3697 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 3698 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 1); 3699 } 3700 3701 if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf)) { 3702 soc_mem_field32_set(unit, mem, vent, ENTRY_TYPEf, 1); 3703 } else if (soc_mem_field_valid(unit, mem, KEY_TYPEf)) { 3704 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 1); 3705 } 3706 3707 soc_mem_field32_set(unit, mem, vent, DVPf, vp); 3708 soc_mem_field32_set(unit, mem, vent, OVIDf, vlan); 3709 3710 if (VLAN_VP_INFO(unit, vp)->flags & BCM_VLAN_PORT_EGRESS_VLAN16) { 3711 soc_mem_field32_set(unit, mem, vent, NEW_OTAG_VPTAG_SELf, 1); 3712 soc_mem_field32_set(unit, mem, vent, NEW_OTAG_VPTAGf, 3713 VLAN_VP_INFO(unit, vp)->match_vlan); 3714 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, vlan); 3715 } else { 3716 soc_mem_field32_set(unit, mem, vent, NEW_OTAG_VPTAG_SELf, 0); 3717 /* egress_vlan in vlan_vp structure is used as swithcing vlan */ 3718 soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, 3719 VLAN_VP_INFO(unit, vp)->match_vlan & 0xfff); 3720 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, vlan); 3721 } 3722 3723 bcm_vlan_action_set_t_init(&action); 3724 action.dt_outer = bcmVlanActionReplace; 3725 action.ot_outer = bcmVlanActionReplace; 3726 if (flags & BCM_VLAN_PORT_UNTAGGED) { 3727 action.dt_inner = bcmVlanActionNone; 3728 action.ot_inner = bcmVlanActionNone; 3729 } else { 3730 if (soc_feature(unit, soc_feature_vlan_copy_action)) { 3731 action.dt_inner = bcmVlanActionCopy; 3732 action.ot_inner = bcmVlanActionCopy; 3733 } else { 3734 3735 action.dt_inner = bcmVlanActionReplace; 3736 action.ot_inner = bcmVlanActionAdd; 3737 } 3738 } 3739 BCM_IF_ERROR_RETURN 3740 (_bcm_trx_egr_vlan_action_profile_entry_add(unit, &action, &profile_idx)); 3741 3742 soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, profile_idx); 3743 rv = soc_mem_insert_return_old(unit, mem, MEM_BLOCK_ALL, 3744 vent, old_vent); 3745 if (rv == SOC_E_EXISTS) { 3746 /* Delete the old vlan translate profile entry */ 3747 profile_idx = soc_mem_field32_get(unit, mem, old_vent, 3748 TAG_ACTION_PROFILE_PTRf); 3749 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx); 3750 } 3751 3752 return rv; 3753 } 3754 3755 /* 3756 * Function: 3757 * _bcm_tr2_vlan_vp_untagged_delete 3758 * Purpose: 3759 * Delete (VLAN VP, VLAN) egress VLAN translation entry. 3760 * Parameters: 3761 * unit - (IN) SOC unit number. 3762 * vlan - (IN) VLAN ID. 3763 * vp - (IN) Virtual port number. 3764 * Returns: 3765 * BCM_X_XXX 3766 */ 3767 STATIC int 3768 _bcm_tr2_vlan_vp_untagged_delete(int unit, bcm_vlan_t vlan, int vp) 3769 { 3770 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 3771 uint32 old_vent[SOC_MAX_MEM_FIELD_WORDS]; 3772 uint32 profile_idx; 3773 int rv; 3774 soc_mem_t mem = EGR_VLAN_XLATEm; 3775 3776 if (soc_mem_is_valid(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 3777 mem = EGR_VLAN_XLATE_1_DOUBLEm; 3778 } 3779 3780 sal_memset(vent, 0, sizeof(vent)); 3781 sal_memset(old_vent, 0, sizeof(old_vent)); 3782 3783 if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf)) { 3784 soc_mem_field32_set(unit, mem, vent, ENTRY_TYPEf, 1); 3785 } else if (soc_mem_field_valid(unit, mem, KEY_TYPEf)) { 3786 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 1); 3787 } 3788 3789 soc_mem_field32_set(unit, mem, vent, DVPf, vp); 3790 soc_mem_field32_set(unit, mem, vent, OVIDf, vlan); 3791 3792 rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, 3793 vent, old_vent); 3794 if (rv == SOC_E_NONE) { 3795 int is_valid = 0; 3796 if (soc_feature(unit, soc_feature_base_valid)) { 3797 is_valid = soc_mem_field32_get(unit, mem, old_vent, 3798 BASE_VALID_0f) == 3 && 3799 soc_mem_field32_get(unit, mem, old_vent, 3800 BASE_VALID_1f) == 7; 3801 } else { 3802 is_valid = soc_mem_field32_get(unit, mem, old_vent, VALIDf); 3803 } 3804 if (is_valid) { 3805 /* Delete the old vlan translate profile entry */ 3806 profile_idx = soc_mem_field32_get(unit, mem, old_vent, 3807 TAG_ACTION_PROFILE_PTRf); 3808 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx); 3809 } 3810 } 3811 3812 return rv; 3813 } 3814 3815 /* 3816 * Function: 3817 * _bcm_tr2_vlan_vp_untagged_get 3818 * Purpose: 3819 * Get tagging/untagging status of a VLAN virtual port by 3820 * reading the (VLAN VP, VLAN) egress vlan translation entry. 3821 * Parameters: 3822 * unit - (IN) SOC unit number. 3823 * vlan - (IN) VLAN to remove virtual port from. 3824 * vp - (IN) Virtual port number. 3825 * flags - (OUT) Untagging status of the VLAN virtual port. 3826 * Returns: 3827 * BCM_E_XXX 3828 */ 3829 STATIC int 3830 _bcm_tr2_vlan_vp_untagged_get(int unit, bcm_vlan_t vlan, int vp, 3831 int *flags) 3832 { 3833 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 3834 uint32 res_vent[SOC_MAX_MEM_FIELD_WORDS]; 3835 3836 int rv, idx; 3837 uint32 profile_idx; 3838 bcm_vlan_action_set_t action; 3839 soc_mem_t mem = EGR_VLAN_XLATEm; 3840 3841 if (soc_mem_is_valid(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 3842 mem = EGR_VLAN_XLATE_1_DOUBLEm; 3843 } 3844 3845 *flags = 0; 3846 3847 sal_memset(vent, 0, sizeof(vent)); 3848 sal_memset(res_vent, 0, sizeof(res_vent)); 3849 3850 if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf)) { 3851 soc_mem_field32_set(unit, mem, vent, ENTRY_TYPEf, 1); 3852 } else if (soc_mem_field_valid(unit, mem, KEY_TYPEf)) { 3853 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 1); 3854 } 3855 soc_mem_field32_set(unit, mem, vent, DVPf, vp); 3856 soc_mem_field32_set(unit, mem, vent, OVIDf, vlan); 3857 3858 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, res_vent, 0); 3859 if (rv == SOC_E_NONE) { 3860 int is_valid = 0; 3861 if (soc_feature(unit, soc_feature_base_valid)) { 3862 is_valid = soc_mem_field32_get(unit, mem, res_vent, 3863 BASE_VALID_0f) == 3 && 3864 soc_mem_field32_get(unit, mem, res_vent, 3865 BASE_VALID_1f) == 7; 3866 } else { 3867 is_valid = soc_mem_field32_get(unit, mem, res_vent, VALIDf); 3868 } 3869 3870 if (is_valid) { 3871 profile_idx = soc_mem_field32_get(unit, mem, res_vent, 3872 TAG_ACTION_PROFILE_PTRf); 3873 _bcm_trx_egr_vlan_action_profile_entry_get(unit, &action, profile_idx); 3874 3875 if (bcmVlanActionNone == action.ot_inner) { 3876 *flags = BCM_VLAN_PORT_UNTAGGED; 3877 } 3878 } 3879 } 3880 3881 return rv; 3882 } 3883 3884 /* 3885 * Function: 3886 * bcm_tr2_vlan_gport_add 3887 * Purpose: 3888 * Add a VLAN/NIV/Extender virtual port to the specified vlan. 3889 * Parameters: 3890 * unit - (IN) SOC unit number. 3891 * vlan - (IN) VLAN ID to add virtual port to as a member. 3892 * gport - (IN) VP Gport ID 3893 * flags - (IN) Indicates if packet should egress out of the given 3894 * VLAN virtual port untagged. Not applicable to NIV or 3895 * Extender VPs. 3896 * Returns: 3897 * BCM_E_XXX 3898 */ 3899 int 3900 bcm_tr2_vlan_gport_add(int unit, bcm_vlan_t vlan, bcm_gport_t gport, 3901 int flags) 3902 { 3903 int rv = BCM_E_NONE; 3904 int vp; 3905 bcm_vlan_port_t vlan_vp; 3906 bcm_gport_t phy_port_trunk = BCM_GPORT_INVALID; 3907 int is_local; 3908 vlan_tab_entry_t vtab; 3909 bcm_pbmp_t vlan_pbmp, vlan_ubmp, l2_pbmp, l3_pbmp; 3910 int i, mc_idx; 3911 bcm_if_t encap_id; 3912 bcm_multicast_t group; 3913 int bc_idx, umc_idx, uuc_idx; 3914 int bc_do_not_add = 0, umc_do_not_add = 0, uuc_do_not_add = 0; 3915 soc_field_t group_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf}; 3916 int egr_vt_added = FALSE, is_glp_port = 0; 3917 int ing_vp_vlan_membership_added = FALSE; 3918 int egr_vp_vlan_membership_added = FALSE; 3919 int ing_vp_group_added = FALSE, eg_vp_group_added = FALSE, vlan_vfi, is_vfi; 3920 _bcm_vp_vlan_mbrship_key_type_e key_type; 3921 3922 COMPILER_REFERENCE(vlan_vfi); 3923 COMPILER_REFERENCE(key_type); 3924 3925 /* check for specfic combination */ 3926 if (flags & BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP) { 3927 if ((flags & (BCM_VLAN_GPORT_ADD_INGRESS_ONLY | 3928 BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) == 3929 (BCM_VLAN_GPORT_ADD_INGRESS_ONLY | 3930 BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) { 3931 return BCM_E_PARAM; 3932 } 3933 } 3934 3935 #ifdef BCM_TRIUMPH3_SUPPORT 3936 if (_BCM_VPN_VFI_IS_SET(vlan)) { 3937 is_vfi = 1; 3938 key_type = _bcm_vp_vlan_mbrship_vp_vfi_type; 3939 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan); 3940 } else 3941 #endif /* BCM_TRIUMPH3_SUPPORT */ 3942 { 3943 is_vfi = 0; 3944 key_type = _bcm_vp_vlan_mbrship_vp_vlan_type; 3945 vlan_vfi = vlan; 3946 3947 /* Check that unsupported flags are not set */ 3948 if (flags & ~(BCM_VLAN_PORT_UNTAGGED | 3949 BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP | 3950 BCM_VLAN_GPORT_ADD_INGRESS_ONLY | 3951 BCM_VLAN_GPORT_ADD_EGRESS_ONLY | 3952 BCM_VLAN_GPORT_ADD_STP_MASK | 3953 BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD | 3954 BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD | 3955 BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD)) { 3956 return BCM_E_PARAM; 3957 } 3958 } 3959 3960 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 3961 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 3962 3963 /* Get the physical port or trunk the VP resides on */ 3964 bcm_vlan_port_t_init(&vlan_vp); 3965 vlan_vp.vlan_port_id = gport; 3966 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_vp_find(unit, &vlan_vp)); 3967 if (is_vfi) { 3968 #ifdef BCM_TRIUMPH3_SUPPORT 3969 if (soc_feature(unit, soc_feature_vlan_vfi)) { 3970 return _bcm_tr3_vlan_port_add(unit, vlan, &vlan_vp); 3971 } 3972 #endif /* BCM_TRIUMPH3_SUPPORT */ 3973 } else { 3974 phy_port_trunk = vlan_vp.port; 3975 } 3976 } else 3977 #ifdef BCM_TRIDENT_SUPPORT 3978 if (BCM_GPORT_IS_NIV_PORT(gport)) { 3979 bcm_niv_port_t niv_port; 3980 bcm_niv_egress_t niv_egress; 3981 int count; 3982 3983 vp = BCM_GPORT_NIV_PORT_ID_GET(gport); 3984 3985 /* Get the physical port or trunk the VP resides on */ 3986 bcm_niv_port_t_init(&niv_port); 3987 niv_port.niv_port_id = gport; 3988 BCM_IF_ERROR_RETURN(bcm_trident_niv_port_get(unit, &niv_port)); 3989 if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) { 3990 bcm_niv_egress_t_init(&niv_egress); 3991 rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id, 3992 1, &niv_egress, &count); 3993 if (BCM_SUCCESS(rv)) { 3994 if (!(niv_egress.flags & BCM_NIV_EGRESS_MULTICAST)) { 3995 phy_port_trunk = niv_egress.port; 3996 } 3997 } 3998 } else { 3999 phy_port_trunk = niv_port.port; 4000 } 4001 } else 4002 #endif /* BCM_TRIDENT_SUPPORT */ 4003 #ifdef BCM_TRIUMPH3_SUPPORT 4004 if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4005 bcm_extender_port_t extender_port; 4006 bcm_extender_egress_t extender_egress; 4007 int count; 4008 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport); 4009 4010 /* Get the physical port or trunk the VP resides on */ 4011 bcm_extender_port_t_init(&extender_port); 4012 extender_port.extender_port_id = gport; 4013 BCM_IF_ERROR_RETURN(bcm_tr3_extender_port_get(unit, &extender_port)); 4014 if (extender_port.flags & BCM_EXTENDER_PORT_MATCH_NONE) { 4015 bcm_extender_egress_t_init(&extender_egress); 4016 rv = bcm_tr3_extender_egress_get_all(unit, extender_port.extender_port_id, 4017 1, &extender_egress, &count); 4018 if (count == 0) { 4019 /* No Extender egress object has been added to VP yet. */ 4020 return BCM_E_CONFIG; 4021 } 4022 if (BCM_SUCCESS(rv)) { 4023 if (!(extender_egress.flags & BCM_EXTENDER_EGRESS_MULTICAST)) { 4024 phy_port_trunk = extender_egress.port; 4025 } 4026 } 4027 } else { 4028 phy_port_trunk = extender_port.port; 4029 } 4030 } else 4031 #endif /* BCM_TRIUMPH3_SUPPORT */ 4032 #ifdef BCM_TRIDENT2_SUPPORT 4033 if (BCM_GPORT_IS_TRUNK(gport)) { 4034 BCM_IF_ERROR_RETURN( 4035 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(gport), &vp)); 4036 4037 /* VPLAG special process*/ 4038 flags |= (BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD | 4039 BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD | 4040 BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD); 4041 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 4042 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 4043 } else 4044 #endif 4045 4046 #ifdef BCM_TRIDENT2_SUPPORT 4047 if (BCM_GPORT_IS_VXLAN_PORT(gport) && 4048 soc_feature(unit, soc_feature_vxlan)) { 4049 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 4050 } else 4051 #endif /* BCM_TRIDENT2_SUPPORT */ 4052 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4053 if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 4054 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 4055 }else if (BCM_GPORT_IS_MIM_PORT(gport)) { 4056 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 4057 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 4058 BCM_GPORT_IS_SUBPORT_PORT(gport)) { 4059 bcm_trunk_t trunk_id; 4060 if (BCM_SUCCESS(bcm_esw_trunk_find(unit, 0, gport, &trunk_id))) { 4061 vp = trunk_id | BCM_TGID_TRUNK_INDICATOR(unit); 4062 } else { 4063 /* Put together a VP like value for subport, which will be 4064 used below, this is a (mod,port) value for GPP */ 4065 if (SOC_IS_TRIDENT3X(unit) && _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 4066 vp = _BCM_SUBPORT_COE_PORT_GLP_GET(BCM_GPORT_SUBPORT_PORT_GET(gport)); 4067 } else { 4068 vp = (BCM_GPORT_SUBPORT_PORT_GET(gport) & 0x7FFF); 4069 } 4070 } 4071 is_glp_port = 1; 4072 4073 /* Set the key_type as glp_vlan type */ 4074 key_type = _bcm_vp_vlan_mbrship_glp_vlan_type; 4075 } else 4076 #endif 4077 #ifdef BCM_TRIDENT3_SUPPORT 4078 if (soc_feature(unit, soc_feature_flex_flow) && 4079 BCM_GPORT_IS_FLOW_PORT(gport)) { 4080 vp = BCM_GPORT_FLOW_PORT_ID_GET(gport); 4081 } else 4082 #endif 4083 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4084 if (BCM_GPORT_IS_MODPORT(gport)) { 4085 vp = (BCM_GPORT_MODPORT_MODID_GET(gport) << 8) | BCM_GPORT_MODPORT_PORT_GET(gport); 4086 is_glp_port = 1; 4087 key_type = _bcm_vp_vlan_mbrship_glp_vfi_type; 4088 } else 4089 #endif 4090 { 4091 return BCM_E_PARAM; 4092 } 4093 4094 if (phy_port_trunk != BCM_GPORT_INVALID) { 4095 BCM_IF_ERROR_RETURN 4096 (_bcm_tr2_phy_port_trunk_is_local(unit, phy_port_trunk, &is_local)); 4097 if (!is_local) { 4098 /* VP is added to replication lists only if it resides on a local port */ 4099 return BCM_E_PORT; 4100 } 4101 } 4102 4103 if(!is_vfi && !is_glp_port) { 4104 4105 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 4106 4107 soc_mem_lock(unit, VLAN_TABm); 4108 4109 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vtab); 4110 if (rv < 0) { 4111 soc_mem_unlock(unit, VLAN_TABm); 4112 return rv; 4113 } 4114 4115 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 4116 soc_mem_unlock(unit, VLAN_TABm); 4117 return BCM_E_NOT_FOUND; 4118 } 4119 4120 /* Enable VP switching on the VLAN */ 4121 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan) && 4122 (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) && 4123 (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf))) { 4124 4125 soc_mem_field32_set(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf, 1); 4126 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, vlan, &vtab); 4127 if (rv < 0) { 4128 soc_mem_unlock(unit, VLAN_TABm); 4129 return rv; 4130 } 4131 soc_mem_unlock(unit, VLAN_TABm); 4132 4133 /* Also need to copy the physical port members to the L2_BITMAP of 4134 * the IPMC entry for each group once we've gone virtual */ 4135 rv = mbcm_driver[unit]->mbcm_vlan_port_get 4136 (unit, vlan, &vlan_pbmp, &vlan_ubmp, NULL); 4137 if (rv < 0) { 4138 return rv; 4139 } 4140 4141 /* Deal with each group */ 4142 for (i = 0; i < 3; i++) { 4143 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, group_type[i]); 4144 /* IPMC entry 0 is reserved */ 4145 if (!mc_idx) { 4146 continue; 4147 } 4148 rv = _bcm_esw_multicast_ipmc_read(unit, mc_idx, &l2_pbmp, &l3_pbmp); 4149 if (rv < 0) { 4150 return rv; 4151 } 4152 rv = _bcm_esw_multicast_ipmc_write(unit, mc_idx, vlan_pbmp, 4153 l3_pbmp, TRUE); 4154 if (rv < 0) { 4155 return rv; 4156 } 4157 } 4158 } else { 4159 soc_mem_unlock(unit, VLAN_TABm); 4160 } 4161 4162 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 4163 umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 4164 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 4165 4166 if (flags & BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD) { 4167 bc_do_not_add = 1; 4168 } else { 4169 bc_do_not_add = 0; 4170 } 4171 if (flags & BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD) { 4172 umc_do_not_add = 1; 4173 } else { 4174 umc_do_not_add = 0; 4175 } 4176 if (flags & BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD) { 4177 uuc_do_not_add = 1; 4178 } else { 4179 uuc_do_not_add = 0; 4180 } 4181 4182 if ((bc_idx == umc_idx) && (bc_do_not_add != umc_do_not_add)) { 4183 return BCM_E_PARAM; 4184 } 4185 if ((bc_idx == uuc_idx) && (bc_do_not_add != uuc_do_not_add)) { 4186 return BCM_E_PARAM; 4187 } 4188 if ((umc_idx == uuc_idx) && (umc_do_not_add != uuc_do_not_add)) { 4189 return BCM_E_PARAM; 4190 } 4191 4192 if (phy_port_trunk == BCM_GPORT_INVALID) { 4193 if (!bc_do_not_add || !umc_do_not_add || !uuc_do_not_add) { 4194 /* If VP's physical port is invalid, this VP cannot be added 4195 * to multicast groups. User should set the DO_NOT_ADD flags. 4196 */ 4197 return BCM_E_PARAM; 4198 } 4199 } 4200 if (!bc_do_not_add) { 4201 /* Add the VP to the BC group */ 4202 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx, 4203 &group)); 4204 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4205 BCM_IF_ERROR_RETURN 4206 (bcm_esw_multicast_vlan_encap_get(unit, group, phy_port_trunk, 4207 gport, &encap_id)); 4208 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4209 BCM_IF_ERROR_RETURN 4210 (bcm_esw_multicast_niv_encap_get(unit, group, phy_port_trunk, 4211 gport, &encap_id)); 4212 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4213 BCM_IF_ERROR_RETURN 4214 (bcm_esw_multicast_extender_encap_get(unit, group, phy_port_trunk, 4215 gport, &encap_id)); 4216 } 4217 /* coverity[stack_use_overflow : FALSE] */ 4218 BCM_IF_ERROR_RETURN(bcm_esw_multicast_egress_add(unit, group, 4219 phy_port_trunk, encap_id)); 4220 } 4221 if (!umc_do_not_add) { 4222 /* Add the VP to the UMC group, if UMC group is different from BC group */ 4223 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, umc_idx, 4224 &group)); 4225 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4226 BCM_IF_ERROR_RETURN 4227 (bcm_esw_multicast_vlan_encap_get(unit, group, phy_port_trunk, 4228 gport, &encap_id)); 4229 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4230 BCM_IF_ERROR_RETURN 4231 (bcm_esw_multicast_niv_encap_get(unit, group, phy_port_trunk, 4232 gport, &encap_id)); 4233 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4234 BCM_IF_ERROR_RETURN 4235 (bcm_esw_multicast_extender_encap_get(unit, group, phy_port_trunk, 4236 gport, &encap_id)); 4237 } 4238 if (umc_idx != bc_idx) { 4239 BCM_IF_ERROR_RETURN(bcm_esw_multicast_egress_add(unit, group, 4240 phy_port_trunk, encap_id)); 4241 } 4242 } 4243 if (!uuc_do_not_add) { 4244 /* Add the VP to the UUC group, if UUC group is different from BC/UMC group */ 4245 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx, 4246 &group)); 4247 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4248 BCM_IF_ERROR_RETURN 4249 (bcm_esw_multicast_vlan_encap_get(unit, group, phy_port_trunk, 4250 gport, &encap_id)); 4251 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4252 BCM_IF_ERROR_RETURN 4253 (bcm_esw_multicast_niv_encap_get(unit, group, phy_port_trunk, 4254 gport, &encap_id)); 4255 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4256 BCM_IF_ERROR_RETURN 4257 (bcm_esw_multicast_extender_encap_get(unit, group, phy_port_trunk, 4258 gport, &encap_id)); 4259 } 4260 if ((uuc_idx != bc_idx) && (uuc_idx != umc_idx)) { 4261 BCM_IF_ERROR_RETURN(bcm_esw_multicast_egress_add(unit, group, 4262 phy_port_trunk, encap_id)); 4263 } 4264 } 4265 4266 /* Add (vlan, vp) to egress vlan translation table and 4267 * configure the egress untagging status. 4268 */ 4269 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4270 BCM_IF_ERROR_RETURN 4271 (_bcm_tr2_vlan_vp_untagged_add(unit, vlan, vp, flags)); 4272 egr_vt_added = TRUE; 4273 } 4274 #ifdef BCM_TRIDENT_SUPPORT 4275 else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4276 BCM_IF_ERROR_RETURN 4277 (bcm_trident_niv_untagged_add(unit, vlan, vp, flags, &egr_vt_added)); 4278 } 4279 #endif /* BCM_TRIDENT_SUPPORT */ 4280 #ifdef BCM_TRIUMPH3_SUPPORT 4281 else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4282 BCM_IF_ERROR_RETURN 4283 (bcm_tr3_extender_untagged_add(unit, vlan, vp, flags, &egr_vt_added)); 4284 } 4285 #endif /* BCM_TRIUMPH3_SUPPORT */ 4286 } else { /* !is_vfi && !is_glp_port */ 4287 4288 /* For VFI and GLP types, set the BC/UUC/UMC flags as 1 since they are not 4289 used, these flags will be validated below for config change */ 4290 bc_do_not_add = uuc_do_not_add = umc_do_not_add = 1; 4291 } 4292 4293 /* Configure ingress and egress VLAN membership checks */ 4294 if (flags & BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP) { 4295 4296 #ifdef BCM_TRIDENT2_SUPPORT 4297 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 4298 if (!(flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) { 4299 BCM_IF_ERROR_RETURN(bcm_td2_ing_vp_vlan_membership_add(unit, 4300 vp, vlan_vfi, flags, key_type)); 4301 ing_vp_vlan_membership_added = TRUE; 4302 } 4303 } else 4304 #endif /* BCM_TRIDENT2_SUPPORT */ 4305 { 4306 if (!(flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) { 4307 return BCM_E_UNAVAIL; 4308 } 4309 } 4310 4311 #ifdef BCM_TRIDENT2_SUPPORT 4312 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 4313 if (!(flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY)) { 4314 4315 BCM_IF_ERROR_RETURN(bcm_td2_egr_vp_vlan_membership_add(unit, 4316 vp, vlan_vfi, flags, key_type)); 4317 egr_vp_vlan_membership_added = TRUE; 4318 } 4319 } else 4320 #endif /* BCM_TRIDENT2_SUPPORT */ 4321 { 4322 if (!(flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY)) { 4323 return BCM_E_UNAVAIL; 4324 } 4325 } 4326 } else { 4327 #ifdef BCM_TRIDENT_SUPPORT 4328 /* Due to change in VP's VLAN membership, may need to move VP to 4329 * another VP group. 4330 */ 4331 uint32 filter_flags; 4332 4333 BCM_IF_ERROR_RETURN( 4334 bcm_esw_port_vlan_member_get(unit, gport, &filter_flags)); 4335 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4336 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 4337 if (!bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 4338 if (!(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) 4339 && (filter_flags & BCM_PORT_VLAN_MEMBER_INGRESS)) { 4340 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_move( 4341 unit, gport, vlan, TRUE, FALSE, flags)); 4342 ing_vp_group_added = TRUE; 4343 } 4344 } else { 4345 ing_vp_group_added = FALSE; 4346 } 4347 4348 if (!bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 4349 if (!(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) 4350 && (filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS)) { 4351 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_move(unit, 4352 gport, vlan, TRUE, TRUE, flags)); 4353 eg_vp_group_added = TRUE; 4354 } 4355 } else { 4356 eg_vp_group_added = FALSE; 4357 } 4358 } else 4359 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4360 { 4361 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 4362 if (!bcm_td_ing_vp_group_unmanaged_get(unit)) { 4363 if ((filter_flags & BCM_PORT_VLAN_MEMBER_INGRESS) && 4364 !(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 4365 BCM_IF_ERROR_RETURN 4366 (bcm_td_ing_vp_group_move(unit, vp, vlan, TRUE)); 4367 ing_vp_group_added = TRUE; 4368 } 4369 } else { 4370 ing_vp_group_added = TRUE; 4371 } 4372 } 4373 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 4374 if (!bcm_td_egr_vp_group_unmanaged_get(unit)) { 4375 if ((filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 4376 !(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 4377 BCM_IF_ERROR_RETURN 4378 (bcm_td_eg_vp_group_move(unit, vp, vlan, TRUE)); 4379 eg_vp_group_added = TRUE; 4380 } 4381 } else { 4382 eg_vp_group_added = TRUE; 4383 } 4384 } 4385 } 4386 #endif /* BCM_TRIDENT_SUPPORT */ 4387 } 4388 4389 if (bc_do_not_add && umc_do_not_add && uuc_do_not_add && 4390 !egr_vt_added && !ing_vp_vlan_membership_added && 4391 !egr_vp_vlan_membership_added && !ing_vp_group_added && 4392 !eg_vp_group_added) { 4393 /* The given VP has not been added to VLAN's BC, UMC, and UUC groups. 4394 * It also has not been added to egress VLAN translation table, to 4395 * VP VLAN membership check table, or to a VP group. 4396 * This scenario does not make sense. Moreover, bcm_vlan_gport_get_all 4397 * would not be able to find this VP. 4398 */ 4399 return BCM_E_PARAM; 4400 } 4401 4402 return BCM_E_NONE; 4403 } 4404 4405 /* 4406 * Function: 4407 * bcm_tr2_vlan_gport_delete 4408 * Purpose: 4409 * Remove a VLAN/NIV/Extender virtual port from the specified vlan. 4410 * Parameters: 4411 * unit - (IN) SOC unit number. 4412 * vlan - (IN) VLAN to remove virtual port from. 4413 * gport - (IN) VP Gport ID 4414 * Returns: 4415 * BCM_E_XXX 4416 */ 4417 int 4418 bcm_tr2_vlan_gport_delete(int unit, bcm_vlan_t vlan, bcm_gport_t gport) 4419 { 4420 int rv = BCM_E_NONE; 4421 int vp; 4422 bcm_vlan_port_t vlan_vp; 4423 bcm_gport_t phy_port_trunk = BCM_GPORT_INVALID; 4424 int is_local; 4425 vlan_tab_entry_t vtab; 4426 int bc_idx, umc_idx, uuc_idx; 4427 bcm_multicast_t group; 4428 bcm_if_t encap_id; 4429 int bc_not_found = TRUE; 4430 int umc_not_found = TRUE; 4431 int uuc_not_found = TRUE; 4432 int egr_vt_found = FALSE; 4433 int ing_vp_vlan_membership_found = FALSE; 4434 int egr_vp_vlan_membership_found = FALSE; 4435 int ing_vp_group_found = FALSE, eg_vp_group_found = FALSE; 4436 int is_glp_port = 0, vlan_vfi = vlan, is_vfi = 0; 4437 _bcm_vp_vlan_mbrship_key_type_e key_type; 4438 #ifdef BCM_TRIDENT_SUPPORT 4439 uint32 filter_flags; 4440 #endif 4441 4442 COMPILER_REFERENCE(vlan_vfi); 4443 COMPILER_REFERENCE(key_type); 4444 4445 #ifdef BCM_TRIUMPH3_SUPPORT 4446 if (_BCM_VPN_VFI_IS_SET(vlan)) { 4447 is_vfi = 1; 4448 key_type = _bcm_vp_vlan_mbrship_vp_vfi_type; 4449 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan); 4450 } else 4451 #endif /* BCM_TRIUMPH3_SUPPORT */ 4452 { 4453 is_vfi = 0; 4454 key_type = _bcm_vp_vlan_mbrship_vp_vlan_type; 4455 vlan_vfi = vlan; 4456 } 4457 4458 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4459 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 4460 4461 /* Get the physical port or trunk the VP resides on */ 4462 bcm_vlan_port_t_init(&vlan_vp); 4463 vlan_vp.vlan_port_id = gport; 4464 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_vp_find(unit, &vlan_vp)); 4465 4466 #ifdef BCM_TRIUMPH3_SUPPORT 4467 if (is_vfi) { 4468 if (soc_feature(unit, soc_feature_vlan_vfi)) { 4469 return _bcm_tr3_vlan_port_delete(unit, vlan, vp); 4470 } 4471 } else 4472 #endif /* BCM_TRIUMPH3_SUPPORT */ 4473 { 4474 phy_port_trunk = vlan_vp.port; 4475 } 4476 } else 4477 #ifdef BCM_TRIDENT_SUPPORT 4478 if (BCM_GPORT_IS_NIV_PORT(gport)) { 4479 bcm_niv_port_t niv_port; 4480 bcm_niv_egress_t niv_egress; 4481 int count; 4482 4483 vp = BCM_GPORT_NIV_PORT_ID_GET(gport); 4484 4485 /* Get the physical port or trunk the VP resides on */ 4486 bcm_niv_port_t_init(&niv_port); 4487 niv_port.niv_port_id = gport; 4488 BCM_IF_ERROR_RETURN(bcm_trident_niv_port_get(unit, &niv_port)); 4489 if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) { 4490 phy_port_trunk = BCM_GPORT_INVALID; 4491 bcm_niv_egress_t_init(&niv_egress); 4492 rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id, 4493 1, &niv_egress, &count); 4494 if (BCM_SUCCESS(rv)) { 4495 if (!(niv_egress.flags & BCM_NIV_EGRESS_MULTICAST)) { 4496 phy_port_trunk = niv_egress.port; 4497 } 4498 } 4499 } else { 4500 phy_port_trunk = niv_port.port; 4501 } 4502 } else 4503 #endif /* BCM_TRIDENT_SUPPORT */ 4504 #ifdef BCM_TRIUMPH3_SUPPORT 4505 if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4506 bcm_extender_port_t extender_port; 4507 bcm_extender_egress_t extender_egress; 4508 int count; 4509 4510 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport); 4511 4512 /* Get the physical port or trunk the VP resides on */ 4513 bcm_extender_port_t_init(&extender_port); 4514 extender_port.extender_port_id = gport; 4515 BCM_IF_ERROR_RETURN(bcm_tr3_extender_port_get(unit, &extender_port)); 4516 if (extender_port.flags & BCM_EXTENDER_PORT_MATCH_NONE) { 4517 bcm_extender_egress_t_init(&extender_egress); 4518 rv = bcm_tr3_extender_egress_get_all(unit, 4519 extender_port.extender_port_id, 1, &extender_egress, &count); 4520 if (count == 0) { 4521 /* No Extender egress object has been added to VP yet. */ 4522 return BCM_E_CONFIG; 4523 } 4524 if (BCM_SUCCESS(rv)) { 4525 if (!extender_egress.flags & BCM_EXTENDER_EGRESS_MULTICAST) { 4526 phy_port_trunk = extender_egress.port; 4527 } 4528 } 4529 } else { 4530 phy_port_trunk = extender_port.port; 4531 } 4532 4533 } else 4534 #endif /* BCM_TRIUMPH3_SUPPORT */ 4535 #ifdef BCM_TRIDENT2_SUPPORT 4536 if (BCM_GPORT_IS_TRUNK(gport)) { 4537 BCM_IF_ERROR_RETURN( 4538 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(gport), &vp)); 4539 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 4540 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 4541 } else 4542 #endif 4543 4544 #ifdef BCM_TRIDENT2_SUPPORT 4545 if (BCM_GPORT_IS_VXLAN_PORT(gport) && 4546 soc_feature(unit, soc_feature_vxlan)) { 4547 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 4548 } else 4549 #endif /* BCM_TRIDENT2_SUPPORT */ 4550 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4551 if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 4552 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 4553 } else if (BCM_GPORT_IS_MIM_PORT(gport)) { 4554 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 4555 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 4556 BCM_GPORT_IS_SUBPORT_PORT(gport)) { 4557 bcm_trunk_t trunk_id; 4558 if (BCM_SUCCESS(bcm_esw_trunk_find(unit, 0, gport, &trunk_id))) { 4559 vp = trunk_id | BCM_TGID_TRUNK_INDICATOR(unit); 4560 } else { 4561 /* Put together a VP like value for subport, which will be 4562 used below */ 4563 if (SOC_IS_TRIDENT3X(unit) && _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 4564 vp = _BCM_SUBPORT_COE_PORT_GLP_GET(BCM_GPORT_SUBPORT_PORT_GET(gport)); 4565 } else { 4566 vp = (BCM_GPORT_SUBPORT_PORT_GET(gport) & 0x7FFF); 4567 } 4568 } 4569 4570 /* Make a note that this is a GPP port we are dealing with */ 4571 is_glp_port = 1; 4572 4573 /* Set the key_type as glp_vlan type */ 4574 key_type = _bcm_vp_vlan_mbrship_glp_vlan_type; 4575 } else 4576 #endif 4577 #ifdef BCM_TRIDENT3_SUPPORT 4578 if (soc_feature(unit, soc_feature_flex_flow) && 4579 BCM_GPORT_IS_FLOW_PORT(gport)) { 4580 vp = BCM_GPORT_FLOW_PORT_ID_GET(gport); 4581 } else 4582 #endif 4583 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4584 if (BCM_GPORT_IS_MODPORT(gport)) { 4585 vp = (BCM_GPORT_MODPORT_MODID_GET(gport) << 8) | BCM_GPORT_MODPORT_PORT_GET(gport); 4586 is_glp_port = 1; 4587 key_type = _bcm_vp_vlan_mbrship_glp_vfi_type; 4588 } else 4589 #endif 4590 { 4591 return BCM_E_PARAM; 4592 } 4593 4594 if (phy_port_trunk != BCM_GPORT_INVALID) { 4595 BCM_IF_ERROR_RETURN 4596 (_bcm_tr2_phy_port_trunk_is_local(unit, phy_port_trunk, &is_local)); 4597 if (!is_local) { 4598 /* VP to be deleted must reside on a local port */ 4599 return BCM_E_PORT; 4600 } 4601 } 4602 4603 if(!is_vfi && !is_glp_port) { 4604 4605 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 4606 4607 SOC_IF_ERROR_RETURN 4608 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vtab)); 4609 4610 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 4611 return BCM_E_NOT_FOUND; 4612 } 4613 4614 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan)) { 4615 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 4616 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 4617 /* VP switching is not enabled on the VLAN */ 4618 return BCM_E_PORT; 4619 } 4620 } 4621 } 4622 4623 if (phy_port_trunk != BCM_GPORT_INVALID) { 4624 /* Delete the VP from the BC group */ 4625 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 4626 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx, 4627 &group)); 4628 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4629 BCM_IF_ERROR_RETURN 4630 (bcm_esw_multicast_vlan_encap_get(unit, group, phy_port_trunk, 4631 gport, &encap_id)); 4632 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4633 BCM_IF_ERROR_RETURN 4634 (bcm_esw_multicast_niv_encap_get(unit, group, phy_port_trunk, 4635 gport, &encap_id)); 4636 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4637 BCM_IF_ERROR_RETURN 4638 (bcm_esw_multicast_extender_encap_get(unit, group, phy_port_trunk, 4639 gport, &encap_id)); 4640 } 4641 4642 rv = bcm_esw_multicast_egress_delete(unit, group, phy_port_trunk, encap_id); 4643 /* BCM_E_NOT_FOUND is tolerated since the VP could have been added to the 4644 * VLAN with the BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD flag. 4645 */ 4646 if (BCM_SUCCESS(rv)) { 4647 bc_not_found = FALSE; 4648 } else if (rv == BCM_E_NOT_FOUND) { 4649 bc_not_found = TRUE; 4650 rv = BCM_E_NONE; 4651 } else { 4652 return rv; 4653 } 4654 4655 /* Delete the VP from the UMC group, if UMC group is different 4656 * from BC group. 4657 */ 4658 umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 4659 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, umc_idx, 4660 &group)); 4661 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4662 BCM_IF_ERROR_RETURN 4663 (bcm_esw_multicast_vlan_encap_get(unit, group, phy_port_trunk, 4664 gport, &encap_id)); 4665 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4666 BCM_IF_ERROR_RETURN 4667 (bcm_esw_multicast_niv_encap_get(unit, group, phy_port_trunk, 4668 gport, &encap_id)); 4669 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4670 BCM_IF_ERROR_RETURN 4671 (bcm_esw_multicast_extender_encap_get(unit, group, phy_port_trunk, 4672 gport, &encap_id)); 4673 } 4674 4675 if (umc_idx != bc_idx) { 4676 rv = bcm_esw_multicast_egress_delete(unit, group, phy_port_trunk, encap_id); 4677 /* BCM_E_NOT_FOUND is tolerated since the VP could have been added to 4678 * the VLAN with the BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD flag. 4679 */ 4680 if (BCM_SUCCESS(rv)) { 4681 umc_not_found = FALSE; 4682 } else if (rv == BCM_E_NOT_FOUND) { 4683 umc_not_found = TRUE; 4684 rv = BCM_E_NONE; 4685 } else { 4686 return rv; 4687 } 4688 } else { 4689 umc_not_found = bc_not_found; 4690 } 4691 4692 /* Delete the VP from the UUC group, if UUC group is different 4693 * from BC and UMC groups. 4694 */ 4695 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 4696 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx, 4697 &group)); 4698 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4699 BCM_IF_ERROR_RETURN 4700 (bcm_esw_multicast_vlan_encap_get(unit, group, phy_port_trunk, 4701 gport, &encap_id)); 4702 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4703 BCM_IF_ERROR_RETURN 4704 (bcm_esw_multicast_niv_encap_get(unit, group, phy_port_trunk, 4705 gport, &encap_id)); 4706 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4707 BCM_IF_ERROR_RETURN 4708 (bcm_esw_multicast_extender_encap_get(unit, group, phy_port_trunk, 4709 gport, &encap_id)); 4710 } 4711 4712 if ((uuc_idx != bc_idx) && (uuc_idx != umc_idx)) { 4713 rv = bcm_esw_multicast_egress_delete(unit, group, phy_port_trunk, encap_id); 4714 /* BCM_E_NOT_FOUND is tolerated since the VP could have been added to 4715 * the VLAN with the BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD flag. 4716 */ 4717 if (BCM_SUCCESS(rv)) { 4718 uuc_not_found = FALSE; 4719 } else if (rv == BCM_E_NOT_FOUND) { 4720 uuc_not_found = TRUE; 4721 rv = BCM_E_NONE; 4722 } else { 4723 return rv; 4724 } 4725 } else if (uuc_idx == bc_idx) { 4726 uuc_not_found = bc_not_found; 4727 } else { 4728 uuc_not_found = umc_not_found; 4729 } 4730 } 4731 4732 /* Delete (vlan, vp) from egress vlan translation table */ 4733 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4734 BCM_IF_ERROR_RETURN 4735 (_bcm_tr2_vlan_vp_untagged_delete(unit, vlan, vp)); 4736 egr_vt_found = TRUE; 4737 } 4738 #ifdef BCM_TRIDENT_SUPPORT 4739 else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4740 rv = bcm_trident_niv_untagged_delete(unit, vlan, vp); 4741 if (BCM_SUCCESS(rv)) { 4742 egr_vt_found = TRUE; 4743 } else if (rv == BCM_E_NOT_FOUND) { 4744 egr_vt_found = FALSE; 4745 rv = BCM_E_NONE; 4746 } else { 4747 return rv; 4748 } 4749 } 4750 #endif /* BCM_TRIDENT_SUPPORT */ 4751 #ifdef BCM_TRIUMPH3_SUPPORT 4752 else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4753 rv = bcm_tr3_extender_untagged_delete(unit, vlan, vp); 4754 if (BCM_SUCCESS(rv)) { 4755 egr_vt_found = TRUE; 4756 } else if (rv == BCM_E_NOT_FOUND) { 4757 egr_vt_found = FALSE; 4758 rv = BCM_E_NONE; 4759 } else { 4760 return rv; 4761 } 4762 } 4763 #endif /* BCM_TRIUMPH3_SUPPORT */ 4764 } 4765 4766 #ifdef BCM_TRIDENT2_SUPPORT 4767 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 4768 rv = bcm_td2_ing_vp_vlan_membership_delete(unit, vp, vlan_vfi, 4769 key_type); 4770 if (BCM_SUCCESS(rv)) { 4771 ing_vp_vlan_membership_found = TRUE; 4772 } else if (rv == BCM_E_NOT_FOUND) { 4773 ing_vp_vlan_membership_found = FALSE; 4774 rv = BCM_E_NONE; 4775 } else { 4776 return rv; 4777 } 4778 } 4779 4780 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 4781 rv = bcm_td2_egr_vp_vlan_membership_delete(unit, vp, vlan_vfi, 4782 key_type); 4783 if (BCM_SUCCESS(rv)) { 4784 egr_vp_vlan_membership_found = TRUE; 4785 } else if (rv == BCM_E_NOT_FOUND) { 4786 egr_vp_vlan_membership_found = FALSE; 4787 rv = BCM_E_NONE; 4788 } else { 4789 return rv; 4790 } 4791 } 4792 #endif /* BCM_TRIDENT2_SUPPORT */ 4793 4794 #ifdef BCM_TRIDENT_SUPPORT 4795 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, gport, &filter_flags)); 4796 4797 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4798 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 4799 if (!bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 4800 if (!(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) && 4801 (filter_flags & BCM_PORT_VLAN_MEMBER_INGRESS)) { 4802 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_move(unit, 4803 gport, vlan, FALSE, FALSE, 0)); 4804 ing_vp_group_found = TRUE; 4805 } 4806 } else { 4807 ing_vp_group_found = FALSE; 4808 } 4809 4810 if (!bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 4811 if (!(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) && 4812 (filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS)) { 4813 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_port_move(unit, 4814 gport, vlan, FALSE, TRUE, 0)); 4815 4816 eg_vp_group_found = TRUE; 4817 } 4818 } else { 4819 eg_vp_group_found = FALSE; 4820 } 4821 } else 4822 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4823 { 4824 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 4825 if (!bcm_td_ing_vp_group_unmanaged_get(unit)) { 4826 if ((filter_flags & BCM_PORT_VLAN_MEMBER_INGRESS) && 4827 !(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 4828 BCM_IF_ERROR_RETURN 4829 (bcm_td_ing_vp_group_move(unit, vp, vlan, FALSE)); 4830 ing_vp_group_found = TRUE; 4831 } 4832 } else { 4833 ing_vp_group_found = TRUE; 4834 } 4835 } 4836 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 4837 if (!bcm_td_egr_vp_group_unmanaged_get(unit)) { 4838 if ((filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 4839 !(filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 4840 BCM_IF_ERROR_RETURN 4841 (bcm_td_eg_vp_group_move(unit, vp, vlan, FALSE)); 4842 eg_vp_group_found = TRUE; 4843 } 4844 } else { 4845 eg_vp_group_found = TRUE; 4846 } 4847 } 4848 } 4849 #endif /* BCM_TRIDENT_SUPPORT */ 4850 4851 if (bc_not_found && umc_not_found && uuc_not_found && 4852 !egr_vt_found && !ing_vp_vlan_membership_found && 4853 !egr_vp_vlan_membership_found && !ing_vp_group_found && 4854 !eg_vp_group_found) { 4855 return BCM_E_NOT_FOUND; 4856 } 4857 4858 return BCM_E_NONE; 4859 } 4860 4861 /* 4862 * Function: 4863 * _bcm_tr2_vlan_mc_group_gport_is_member 4864 * Purpose: 4865 * Determine if the given VP is a member of the multicast group. 4866 * Parameters: 4867 * unit - (IN) SOC unit number. 4868 * group - (IN) Multicast group 4869 * gport - (IN) VP Gport ID 4870 * phy_port_trunk - (IN) Gport ID for physical port or trunk on which 4871 * the VP resides 4872 * is_member - (OUT) Indicates if given VP belongs to VLAN. 4873 * Returns: 4874 * BCM_E_XXX 4875 */ 4876 STATIC int 4877 _bcm_tr2_vlan_mc_group_gport_is_member(int unit, bcm_multicast_t group, 4878 bcm_gport_t gport, bcm_gport_t phy_port_trunk, int *is_member) 4879 { 4880 int rv = BCM_E_NONE; 4881 bcm_if_t encap_id; 4882 bcm_trunk_t trunk_id; 4883 int soc_max_num_ports = SOC_MAX_NUM_PORTS; 4884 int trunk_local_ports = 0; 4885 int if_max; 4886 bcm_if_t *if_array; 4887 int if_count, if_cur; 4888 int i, mc_idx; 4889 #if (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 4890 bcm_port_t trunk_member_port[SOC_MAX_NUM_PP_PORTS]; 4891 #else 4892 bcm_port_t trunk_member_port[SOC_MAX_NUM_PORTS]; 4893 #endif 4894 4895 if (NULL == is_member) { 4896 return BCM_E_PARAM; 4897 } 4898 *is_member = FALSE; 4899 4900 if (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) { 4901 soc_max_num_ports = SOC_MAX_NUM_PP_PORTS; 4902 } 4903 4904 /* Get VP's multicast encap id */ 4905 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 4906 BCM_IF_ERROR_RETURN(bcm_esw_multicast_vlan_encap_get(unit, group, 4907 phy_port_trunk, gport, &encap_id)); 4908 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 4909 BCM_IF_ERROR_RETURN(bcm_esw_multicast_niv_encap_get(unit, group, 4910 phy_port_trunk, gport, &encap_id)); 4911 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 4912 BCM_IF_ERROR_RETURN(bcm_esw_multicast_extender_encap_get(unit, group, 4913 phy_port_trunk, gport, &encap_id)); 4914 } else { 4915 return BCM_E_PARAM; 4916 } 4917 4918 /* Get all the local ports of the trunk */ 4919 if (BCM_GPORT_IS_TRUNK(phy_port_trunk)) { 4920 trunk_id = BCM_GPORT_TRUNK_GET(phy_port_trunk); 4921 rv = _bcm_trunk_id_validate(unit, trunk_id); 4922 if (BCM_FAILURE(rv)) { 4923 return BCM_E_PORT; 4924 } 4925 rv = _bcm_esw_trunk_local_members_get(unit, trunk_id, 4926 soc_max_num_ports, trunk_member_port, &trunk_local_ports); 4927 if (BCM_FAILURE(rv)) { 4928 return BCM_E_PORT; 4929 } 4930 } 4931 4932 /* Find out if VP is a member of the multicast group */ 4933 if_max = soc_mem_index_count(unit, EGR_L3_NEXT_HOPm); 4934 if_array = sal_alloc(if_max * sizeof(bcm_if_t), 4935 "temp repl interface array"); 4936 if (if_array == NULL) { 4937 return BCM_E_MEMORY; 4938 } 4939 mc_idx = _BCM_MULTICAST_ID_GET(group); 4940 if (BCM_GPORT_IS_TRUNK(phy_port_trunk)) { 4941 /* Iterate over all local ports in the trunk and search for 4942 * a match on any local port 4943 */ 4944 for (i = 0; i < trunk_local_ports; i++) { 4945 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, 4946 trunk_member_port[i], if_max, if_array, &if_count); 4947 if (BCM_FAILURE(rv)) { 4948 sal_free(if_array); 4949 return rv; 4950 } 4951 for (if_cur = 0; if_cur < if_count; if_cur++) { 4952 if (if_array[if_cur] == encap_id) { 4953 *is_member = TRUE; 4954 sal_free(if_array); 4955 return BCM_E_NONE; 4956 } 4957 } 4958 } 4959 } else { 4960 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, 4961 phy_port_trunk, if_max, if_array, &if_count); 4962 if (BCM_FAILURE(rv)) { 4963 sal_free(if_array); 4964 return rv; 4965 } 4966 for (if_cur = 0; if_cur < if_count; if_cur++) { 4967 if (if_array[if_cur] == encap_id) { 4968 *is_member = TRUE; 4969 sal_free(if_array); 4970 return BCM_E_NONE; 4971 } 4972 } 4973 } 4974 4975 sal_free(if_array); 4976 return BCM_E_NONE; 4977 } 4978 4979 /* 4980 * Function: 4981 * bcm_tr2_vlan_gport_get 4982 * Purpose: 4983 * Get untagging status of a VLAN virtual port. 4984 * Parameters: 4985 * unit - (IN) SOC unit number. 4986 * vlan - (IN) VLAN to remove virtual port from. 4987 * gport - (IN) VLAN VP Gport ID 4988 * flags - (OUT) Untagging status of the VLAN virtual port. 4989 * Returns: 4990 * BCM_E_XXX 4991 */ 4992 int 4993 bcm_tr2_vlan_gport_get(int unit, bcm_vlan_t vlan, bcm_gport_t gport, 4994 int *flags) 4995 { 4996 int rv = BCM_E_NONE; 4997 int vp; 4998 bcm_vlan_port_t vlan_vp; 4999 bcm_gport_t phy_port_trunk = BCM_GPORT_INVALID; 5000 int is_local; 5001 vlan_tab_entry_t vtab; 5002 int bc_idx, umc_idx, uuc_idx; 5003 bcm_multicast_t group; 5004 int is_bc_member = FALSE; 5005 int is_umc_member = FALSE; 5006 int is_uuc_member = FALSE; 5007 int untagged_flag = 0; 5008 int egr_vt_found = FALSE; 5009 int ing_vp_vlan_membership_found = FALSE; 5010 int egr_vp_vlan_membership_found = FALSE; 5011 int ing_vp_group_found = FALSE; 5012 int eg_vp_group_found = FALSE; 5013 int is_glp_port = 0, is_vfi = 0, vlan_vfi = vlan; 5014 _bcm_vp_vlan_mbrship_key_type_e key_type; 5015 5016 COMPILER_REFERENCE(vlan_vfi); 5017 COMPILER_REFERENCE(key_type); 5018 5019 #ifdef BCM_TRIUMPH3_SUPPORT 5020 if (_BCM_VPN_VFI_IS_SET(vlan)) { 5021 is_vfi = 1; 5022 key_type = _bcm_vp_vlan_mbrship_vp_vfi_type; 5023 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan); 5024 } else 5025 #endif /* BCM_TRIUMPH3_SUPPORT */ 5026 { 5027 is_vfi = 0; 5028 key_type = _bcm_vp_vlan_mbrship_vp_vlan_type; 5029 vlan_vfi = vlan; 5030 } 5031 5032 *flags = 0; 5033 5034 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 5035 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 5036 5037 /* Get the physical port or trunk the VP resides on */ 5038 bcm_vlan_port_t_init(&vlan_vp); 5039 vlan_vp.vlan_port_id = gport; 5040 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_vp_find(unit, &vlan_vp)); 5041 5042 #ifdef BCM_TRIUMPH3_SUPPORT 5043 if (is_vfi) { 5044 if (soc_feature(unit, soc_feature_vlan_vfi)) { 5045 source_vp_entry_t svp; 5046 5047 BCM_IF_ERROR_RETURN( 5048 READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 5049 if ((soc_mem_field32_get(unit, SOURCE_VPm, &svp, ENTRY_TYPEf) != 1) || 5050 (soc_mem_field32_get(unit, SOURCE_VPm, &svp, VFIf) != vlan_vfi)) { 5051 return BCM_E_NOT_FOUND; 5052 } 5053 return BCM_E_NONE; 5054 } 5055 } else 5056 #endif /* BCM_TRIUMPH3_SUPPORT */ 5057 { 5058 phy_port_trunk = vlan_vp.port; 5059 } 5060 } else 5061 #ifdef BCM_TRIDENT_SUPPORT 5062 if (BCM_GPORT_IS_NIV_PORT(gport)) { 5063 bcm_niv_port_t niv_port; 5064 bcm_niv_egress_t niv_egress; 5065 int count; 5066 5067 vp = BCM_GPORT_NIV_PORT_ID_GET(gport); 5068 5069 /* Get the physical port or trunk the VP resides on */ 5070 bcm_niv_port_t_init(&niv_port); 5071 niv_port.niv_port_id = gport; 5072 BCM_IF_ERROR_RETURN(bcm_trident_niv_port_get(unit, &niv_port)); 5073 if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) { 5074 phy_port_trunk = BCM_GPORT_INVALID; 5075 bcm_niv_egress_t_init(&niv_egress); 5076 rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id, 5077 1, &niv_egress, &count); 5078 if (BCM_SUCCESS(rv)) { 5079 if (!(niv_egress.flags & BCM_NIV_EGRESS_MULTICAST)) { 5080 phy_port_trunk = niv_egress.port; 5081 } 5082 } 5083 } else { 5084 phy_port_trunk = niv_port.port; 5085 } 5086 } else 5087 #endif /* BCM_TRIDENT_SUPPORT */ 5088 #ifdef BCM_TRIUMPH3_SUPPORT 5089 if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 5090 bcm_extender_port_t extender_port; 5091 bcm_extender_egress_t extender_egress; 5092 int count; 5093 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport); 5094 5095 /* Get the physical port or trunk the VP resides on */ 5096 bcm_extender_port_t_init(&extender_port); 5097 extender_port.extender_port_id = gport; 5098 BCM_IF_ERROR_RETURN(bcm_tr3_extender_port_get(unit, &extender_port)); 5099 if (extender_port.flags & BCM_EXTENDER_PORT_MATCH_NONE) { 5100 bcm_extender_egress_t_init(&extender_egress); 5101 rv = bcm_tr3_extender_egress_get_all(unit, 5102 extender_port.extender_port_id, 1, &extender_egress, &count); 5103 if (count == 0) { 5104 /* No Extender egress object has been added to VP yet. */ 5105 return BCM_E_CONFIG; 5106 } 5107 if (BCM_SUCCESS(rv)) { 5108 if (!extender_egress.flags & BCM_EXTENDER_EGRESS_MULTICAST) { 5109 phy_port_trunk = extender_egress.port; 5110 } 5111 } 5112 } else { 5113 phy_port_trunk = extender_port.port; 5114 } 5115 5116 } else 5117 #endif /* BCM_TRIDENT_SUPPORT */ 5118 #ifdef BCM_TRIDENT2_SUPPORT 5119 if (BCM_GPORT_IS_TRUNK(gport)) { 5120 BCM_IF_ERROR_RETURN( 5121 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(gport), &vp)); 5122 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 5123 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 5124 } else 5125 #endif 5126 5127 #ifdef BCM_TRIDENT2_SUPPORT 5128 if (BCM_GPORT_IS_VXLAN_PORT(gport) && 5129 soc_feature(unit, soc_feature_vxlan)) { 5130 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 5131 } else 5132 #endif /* BCM_TRIDENT2_SUPPORT */ 5133 #ifdef BCM_TRIDENT2PLUS_SUPPORT 5134 if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 5135 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 5136 } else if (BCM_GPORT_IS_MIM_PORT(gport)) { 5137 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 5138 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 5139 BCM_GPORT_IS_SUBPORT_PORT(gport)) { 5140 bcm_trunk_t trunk_id; 5141 if (BCM_SUCCESS(bcm_esw_trunk_find(unit, 0, gport, &trunk_id))) { 5142 vp = trunk_id | BCM_TGID_TRUNK_INDICATOR(unit); 5143 } else { 5144 /* Put together a VP like value for subport, which will be 5145 used below, this is a (mod,port) value for GPP */ 5146 if (SOC_IS_TRIDENT3X(unit) && _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 5147 vp = _BCM_SUBPORT_COE_PORT_GLP_GET(BCM_GPORT_SUBPORT_PORT_GET(gport)); 5148 } else { 5149 vp = (BCM_GPORT_SUBPORT_PORT_GET(gport) & 0x7FFF); 5150 } 5151 } 5152 5153 /* Mark that this is a GLP port */ 5154 is_glp_port = 1; 5155 5156 /* Set the key_type as glp_vlan type */ 5157 key_type = _bcm_vp_vlan_mbrship_glp_vlan_type; 5158 } else 5159 #endif 5160 #ifdef BCM_TRIDENT3_SUPPORT 5161 if (soc_feature(unit, soc_feature_flex_flow) && 5162 BCM_GPORT_IS_FLOW_PORT(gport)) { 5163 vp = BCM_GPORT_FLOW_PORT_ID_GET(gport); 5164 } else 5165 #endif 5166 #ifdef BCM_TRIDENT2PLUS_SUPPORT 5167 if (BCM_GPORT_IS_MODPORT(gport)) { 5168 vp = (BCM_GPORT_MODPORT_MODID_GET(gport) << 8) | BCM_GPORT_MODPORT_PORT_GET(gport); 5169 is_glp_port = 1; 5170 key_type = _bcm_vp_vlan_mbrship_glp_vfi_type; 5171 } else 5172 #endif 5173 { 5174 return BCM_E_PARAM; 5175 } 5176 5177 if (phy_port_trunk != BCM_GPORT_INVALID) { 5178 BCM_IF_ERROR_RETURN 5179 (_bcm_tr2_phy_port_trunk_is_local(unit, phy_port_trunk, &is_local)); 5180 if (!is_local) { 5181 return BCM_E_PORT; 5182 } 5183 } 5184 5185 if(!is_vfi && !is_glp_port) { 5186 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 5187 SOC_IF_ERROR_RETURN 5188 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vtab)); 5189 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 5190 return BCM_E_NOT_FOUND; 5191 } 5192 5193 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan)) { 5194 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 5195 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 5196 /* No virtual port exists for this VLAN */ 5197 return BCM_E_NOT_FOUND; 5198 } 5199 } 5200 } 5201 5202 if (phy_port_trunk != BCM_GPORT_INVALID) { 5203 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 5204 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx, 5205 &group)); 5206 BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_mc_group_gport_is_member(unit, group, 5207 gport, phy_port_trunk, &is_bc_member)); 5208 5209 umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 5210 if (umc_idx != bc_idx) { 5211 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, umc_idx, 5212 &group)); 5213 BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_mc_group_gport_is_member(unit, group, 5214 gport, phy_port_trunk, &is_umc_member)); 5215 } else { 5216 is_umc_member = is_bc_member; 5217 } 5218 5219 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 5220 if (uuc_idx != bc_idx && uuc_idx != umc_idx) { 5221 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx, 5222 &group)); 5223 BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_mc_group_gport_is_member(unit, group, 5224 gport, phy_port_trunk, &is_uuc_member)); 5225 } else if (uuc_idx == bc_idx) { 5226 is_uuc_member = is_bc_member; 5227 } else { 5228 is_uuc_member = is_umc_member; 5229 } 5230 } 5231 5232 if (!is_bc_member) { 5233 *flags |= BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD; 5234 } 5235 if (!is_umc_member) { 5236 *flags |= BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD; 5237 } 5238 if (!is_uuc_member) { 5239 *flags |= BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD; 5240 } 5241 5242 /* Get untagging status */ 5243 if (BCM_GPORT_IS_VLAN_PORT(gport)) { 5244 BCM_IF_ERROR_RETURN 5245 (_bcm_tr2_vlan_vp_untagged_get(unit, vlan, vp, &untagged_flag)); 5246 egr_vt_found = TRUE; 5247 } 5248 #ifdef BCM_TRIDENT_SUPPORT 5249 else if (BCM_GPORT_IS_NIV_PORT(gport)) { 5250 rv = bcm_trident_niv_untagged_get(unit, vlan, vp, &untagged_flag); 5251 if (BCM_SUCCESS(rv)) { 5252 egr_vt_found = TRUE; 5253 } else if (rv == BCM_E_NOT_FOUND) { 5254 egr_vt_found = FALSE; 5255 rv = BCM_E_NONE; 5256 } else { 5257 return rv; 5258 } 5259 } 5260 #endif /* BCM_TRIDENT_SUPPORT */ 5261 #ifdef BCM_TRIUMPH3_SUPPORT 5262 else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 5263 rv = bcm_tr3_extender_untagged_get(unit, vlan, vp, &untagged_flag); 5264 if (BCM_SUCCESS(rv)) { 5265 egr_vt_found = TRUE; 5266 } else if (rv == BCM_E_NOT_FOUND) { 5267 egr_vt_found = FALSE; 5268 rv = BCM_E_NONE; 5269 } else { 5270 return rv; 5271 } 5272 } 5273 #endif /* BCM_TRIUMPH3_SUPPORT */ 5274 5275 *flags |= untagged_flag; 5276 } /* !is_vfi && !is_glp_port */ 5277 5278 #ifdef BCM_TRIDENT2_SUPPORT 5279 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 5280 uint32 ing_flag; 5281 5282 rv = bcm_td2_ing_vp_vlan_membership_get(unit, vp, vlan_vfi, 5283 &ing_flag, key_type); 5284 if (BCM_SUCCESS(rv)) { 5285 ing_vp_vlan_membership_found = TRUE; 5286 *flags |= ing_flag; 5287 *flags |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 5288 } else if (rv == BCM_E_NOT_FOUND) { 5289 ing_vp_vlan_membership_found = FALSE; 5290 rv = BCM_E_NONE; 5291 } else { 5292 return rv; 5293 } 5294 } 5295 5296 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 5297 uint32 egr_flag; 5298 5299 rv = bcm_td2_egr_vp_vlan_membership_get(unit, vp, vlan_vfi, 5300 &egr_flag, key_type); 5301 if (BCM_SUCCESS(rv)) { 5302 egr_vp_vlan_membership_found = TRUE; 5303 *flags |= egr_flag; 5304 *flags |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 5305 } else if (rv == BCM_E_NOT_FOUND) { 5306 egr_vp_vlan_membership_found = FALSE; 5307 rv = BCM_E_NONE; 5308 } else { 5309 return rv; 5310 } 5311 } 5312 5313 if (ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) { 5314 *flags |= BCM_VLAN_GPORT_ADD_INGRESS_ONLY; 5315 } else if (!ing_vp_vlan_membership_found && egr_vp_vlan_membership_found) { 5316 *flags |= BCM_VLAN_GPORT_ADD_EGRESS_ONLY; 5317 } 5318 #endif /* BCM_TRIDENT2_SUPPORT */ 5319 5320 #ifdef BCM_TRIDENT_SUPPORT 5321 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 5322 uint32 ing_filter_flags; 5323 5324 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, gport, 5325 &ing_filter_flags)); 5326 if ((ing_filter_flags & BCM_PORT_VLAN_MEMBER_INGRESS) && 5327 !(ing_filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 5328 ing_vp_group_found = TRUE; 5329 } 5330 } 5331 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 5332 uint32 eg_filter_flags; 5333 5334 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, gport, 5335 &eg_filter_flags)); 5336 if ((eg_filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 5337 !(eg_filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 5338 eg_vp_group_found = TRUE; 5339 } 5340 } 5341 5342 #ifdef BCM_TRIDENT2PLUS_SUPPORT 5343 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 5344 int ut_state = 0; 5345 if (eg_vp_group_found) { 5346 if (!is_vfi) { 5347 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_get( 5348 unit, gport, vlan, &ut_state)); 5349 } 5350 #if defined(BCM_TRIDENT3_SUPPORT) 5351 else if(SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 5352 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_get( 5353 unit, gport, vlan, &ut_state)); 5354 } 5355 #endif 5356 if (ut_state) { 5357 *flags |= BCM_VLAN_GPORT_ADD_UNTAGGED; 5358 } 5359 } 5360 } 5361 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5362 #endif /* BCM_TRIDENT_SUPPORT */ 5363 5364 if (!is_bc_member && !is_umc_member && !is_uuc_member && 5365 !egr_vt_found && !ing_vp_vlan_membership_found && 5366 !egr_vp_vlan_membership_found && !ing_vp_group_found && 5367 !eg_vp_group_found) { 5368 return BCM_E_NOT_FOUND; 5369 } 5370 5371 return rv; 5372 } 5373 5374 /* 5375 * Function: 5376 * _bcm_tr2_mc_group_vp_get_all 5377 * Purpose: 5378 * Get all the virtual ports of the given multicast group. 5379 * Parameters: 5380 * unit - (IN) SOC unit number. 5381 * mc_group - (IN) Multicast group. 5382 * vp_bitmap - (OUT) Bitmap of virtual ports. 5383 * Returns: 5384 * BCM_E_XXX 5385 */ 5386 STATIC int 5387 _bcm_tr2_mc_group_vp_get_all(int unit, bcm_multicast_t mc_group, 5388 SHR_BITDCL *vp_bitmap) 5389 { 5390 int rv = BCM_E_NONE; 5391 int num_encap_id; 5392 bcm_if_t *encap_id_array = NULL; 5393 int i; 5394 int nh_index; 5395 egr_l3_next_hop_entry_t egr_nh; 5396 int vp; 5397 soc_field_t type_field = ENTRY_TYPEf; 5398 5399 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 5400 type_field = DATA_TYPEf; 5401 } 5402 5403 if (NULL == vp_bitmap) { 5404 return BCM_E_PARAM; 5405 } 5406 5407 /* Get the number of encap IDs of the multicast group */ 5408 BCM_IF_ERROR_RETURN 5409 (bcm_esw_multicast_egress_get(unit, mc_group, 0, 5410 NULL, NULL, &num_encap_id)); 5411 /* If no encap IDs in the multicast group, return directly */ 5412 if (num_encap_id == 0) { 5413 return BCM_E_NONE; 5414 } 5415 5416 /* Get all the encap IDs of the multicast group */ 5417 encap_id_array = sal_alloc(sizeof(bcm_if_t) * num_encap_id, 5418 "encap_id_array"); 5419 if (NULL == encap_id_array) { 5420 return BCM_E_MEMORY; 5421 } 5422 sal_memset(encap_id_array, 0, sizeof(bcm_if_t) * num_encap_id); 5423 rv = bcm_esw_multicast_egress_get(unit, mc_group, num_encap_id, 5424 NULL, encap_id_array, &num_encap_id); 5425 if (rv < 0) { 5426 sal_free(encap_id_array); 5427 return rv; 5428 } 5429 5430 /* Convert encap IDs to virtual ports */ 5431 for (i = 0; i < num_encap_id; i++) { 5432 if (BCM_IF_INVALID != encap_id_array[i]) { 5433 nh_index = encap_id_array[i] - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 5434 rv = READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh); 5435 if (BCM_FAILURE(rv)) { 5436 sal_free(encap_id_array); 5437 return rv; 5438 } 5439 if (2 != soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 5440 type_field)) { 5441 sal_free(encap_id_array); 5442 return BCM_E_INTERNAL; 5443 } 5444 vp = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__DVPf); 5445 SHR_BITSET(vp_bitmap, vp); 5446 } 5447 } 5448 5449 sal_free(encap_id_array); 5450 return rv; 5451 } 5452 5453 /* 5454 * Function: 5455 * _bcm_tr2_vp_untagged_get_all 5456 * Purpose: 5457 * Get all the given VLAN's virtual ports and untagged status from egress 5458 * VLAN translation table. 5459 * Parameters: 5460 * unit - (IN) SOC unit number. 5461 * vlan - (IN) VLAN. 5462 * vp_bitmap - (OUT) Bitmap of virtual ports. 5463 * arr_size - (IN) Number of elements in flags_arr. 5464 * flags_arr - (OUT) Array of flags. 5465 * Returns: 5466 * BCM_E_XXX 5467 */ 5468 STATIC int 5469 _bcm_tr2_vp_untagged_get_all(int unit, bcm_vlan_t vlan, SHR_BITDCL *vp_bitmap, 5470 int arr_size, int *flags_arr) 5471 { 5472 int rv = BCM_E_NONE; 5473 int chunk_size, num_chunks, chunk_index; 5474 int alloc_size; 5475 uint8 *egr_vt_buf = NULL; 5476 soc_field_t entry_type_f; 5477 int i, entry_index_min, entry_index_max; 5478 uint32 *ent; 5479 int vp, untagged_flag; 5480 soc_mem_t mem = EGR_VLAN_XLATEm; 5481 5482 if (soc_mem_is_valid(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 5483 mem = EGR_VLAN_XLATE_1_DOUBLEm; 5484 } 5485 5486 if (NULL == vp_bitmap) { 5487 return BCM_E_PARAM; 5488 } 5489 if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) { 5490 return BCM_E_PARAM; 5491 } 5492 if (NULL == flags_arr) { 5493 return BCM_E_PARAM; 5494 } 5495 5496 chunk_size = 1024; 5497 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 5498 if (soc_mem_index_count(unit, mem) % chunk_size) { 5499 num_chunks++; 5500 } 5501 5502 alloc_size = soc_mem_entry_words(unit, mem) * 4 * chunk_size; 5503 egr_vt_buf = soc_cm_salloc(unit, alloc_size, "EGR_VLAN_XLATE buffer"); 5504 if (NULL == egr_vt_buf) { 5505 rv = BCM_E_MEMORY; 5506 goto cleanup; 5507 } 5508 5509 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5510 entry_type_f = DATA_TYPEf; 5511 } else if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf)) { 5512 entry_type_f = ENTRY_TYPEf; 5513 } else { 5514 entry_type_f = KEY_TYPEf; 5515 } 5516 5517 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 5518 5519 /* Get a chunk of entries */ 5520 entry_index_min = chunk_index * chunk_size; 5521 entry_index_max = entry_index_min + chunk_size - 1; 5522 if (entry_index_max > soc_mem_index_max(unit, mem)) { 5523 entry_index_max = soc_mem_index_max(unit, mem); 5524 } 5525 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 5526 entry_index_min, entry_index_max, egr_vt_buf); 5527 if (SOC_FAILURE(rv)) { 5528 goto cleanup; 5529 } 5530 5531 /* Read each entry of the chunk to extract VP and untagged status */ 5532 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 5533 int is_valid = 0; 5534 ent = soc_mem_table_idx_to_pointer(unit, 5535 mem, uint32 *, egr_vt_buf, i); 5536 5537 if (soc_feature(unit, soc_feature_base_valid)) { 5538 is_valid = soc_mem_field32_get(unit, mem, ent, 5539 BASE_VALID_0f) == 3 && 5540 soc_mem_field32_get(unit, mem, ent, 5541 BASE_VALID_1f) == 7; 5542 } else { 5543 is_valid = soc_mem_field32_get(unit, mem, ent, VALIDf); 5544 } 5545 5546 if (!is_valid) { 5547 continue; 5548 } 5549 5550 if (soc_mem_field32_get(unit, mem, ent, entry_type_f) != 1) { 5551 continue; 5552 } 5553 if (soc_mem_field32_get(unit, mem, ent, OVIDf) != vlan) { 5554 continue; 5555 } 5556 5557 vp = soc_mem_field32_get(unit, mem, ent, DVPf); 5558 5559 /* Get untagged status */ 5560 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 5561 rv = _bcm_tr2_vlan_vp_untagged_get(unit, vlan, vp, 5562 &untagged_flag); 5563 } 5564 #ifdef BCM_TRIDENT_SUPPORT 5565 else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 5566 rv = bcm_trident_niv_untagged_get(unit, vlan, vp, 5567 &untagged_flag); 5568 } 5569 #endif /* BCM_TRIDENT_SUPPORT */ 5570 #ifdef BCM_TRIUMPH3_SUPPORT 5571 else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 5572 rv = bcm_tr3_extender_untagged_get(unit, vlan, vp, 5573 &untagged_flag); 5574 } 5575 #endif /* BCM_TRIUMPH3_SUPPORT */ 5576 else { 5577 continue; 5578 } 5579 if (BCM_FAILURE(rv)) { 5580 goto cleanup; 5581 } 5582 5583 SHR_BITSET(vp_bitmap, vp); 5584 flags_arr[vp] = untagged_flag; 5585 } 5586 } 5587 5588 cleanup: 5589 if (egr_vt_buf) { 5590 soc_cm_sfree(unit, egr_vt_buf); 5591 } 5592 5593 return rv; 5594 } 5595 5596 /* 5597 * Function: 5598 * bcm_tr2_vlan_gport_get_all 5599 * Purpose: 5600 * Get all virtual ports of the given VLAN. 5601 * Parameters: 5602 * unit - (IN) SOC unit number. 5603 * vlan - (IN) VLAN ID. 5604 * array_max - (IN) Max number of elements in the array. 5605 * gport_array - (OUT) Array of virtual ports in GPORT format. 5606 * flags_array - (OUT) Array of untagging status. 5607 * array_size - (OUT) Actual number of elements in the array. 5608 * Returns: 5609 * BCM_E_XXX 5610 * Notes: If array_max == 0 and gport_array == NULL, actual number of 5611 * virtual ports in the VLAN will be returned in array_size. 5612 */ 5613 int 5614 bcm_tr2_vlan_gport_get_all(int unit, bcm_vlan_t vlan, int array_max, 5615 bcm_gport_t *gport_array, int *flags_array, int *array_size) 5616 { 5617 int rv = BCM_E_NONE; 5618 vlan_tab_entry_t vtab; 5619 int num_vp; 5620 SHR_BITDCL *bc_vp_bitmap = NULL; 5621 SHR_BITDCL *umc_vp_bitmap = NULL; 5622 SHR_BITDCL *uuc_vp_bitmap = NULL; 5623 int bc_idx, umc_idx, uuc_idx; 5624 bcm_multicast_t mc_group; 5625 SHR_BITDCL *egr_vt_vp_bitmap = NULL; 5626 int *egr_vt_flags_arr = NULL; 5627 SHR_BITDCL *ing_vp_bitmap = NULL; 5628 int *ing_flags_arr = NULL; 5629 SHR_BITDCL *egr_vp_bitmap = NULL; 5630 int *egr_flags_arr = NULL; 5631 SHR_BITDCL *ing_group_vp_bitmap = NULL; 5632 SHR_BITDCL *eg_group_vp_bitmap = NULL; 5633 int i; 5634 5635 if (array_max < 0) { 5636 return BCM_E_PARAM; 5637 } 5638 5639 if ((array_max > 0) && (NULL == gport_array)) { 5640 return BCM_E_PARAM; 5641 } 5642 5643 if (NULL == array_size) { 5644 return BCM_E_PARAM; 5645 } 5646 5647 *array_size = 0; 5648 5649 #ifdef BCM_TRIUMPH3_SUPPORT 5650 if (soc_feature(unit, soc_feature_vlan_vfi)) { 5651 rv = _bcm_tr3_vlan_vpn_is_valid(unit, vlan); 5652 if (rv == BCM_E_NONE) { 5653 return _bcm_tr3_vlan_port_get_all(unit, vlan, array_max, 5654 gport_array, flags_array, array_size); 5655 } 5656 } 5657 #endif /* BCM_TRIUMPH3_SUPPORT */ 5658 5659 BCM_IF_ERROR_RETURN 5660 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, &vtab)); 5661 5662 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 5663 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 5664 /* This vlan has no virtual port members. */ 5665 return BCM_E_NONE; 5666 } 5667 } 5668 5669 /* Get VPs from BC group */ 5670 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 5671 bc_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "bc_vp_bitmap"); 5672 if (NULL == bc_vp_bitmap) { 5673 rv = BCM_E_MEMORY; 5674 goto cleanup; 5675 } 5676 sal_memset(bc_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5677 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 5678 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx, &mc_group); 5679 if (BCM_FAILURE(rv)) { 5680 goto cleanup; 5681 } 5682 rv = _bcm_tr2_mc_group_vp_get_all(unit, mc_group, bc_vp_bitmap); 5683 if (BCM_FAILURE(rv)) { 5684 goto cleanup; 5685 } 5686 5687 /* Get VPs from UMC group, if different from BC group */ 5688 umc_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "umc_vp_bitmap"); 5689 if (NULL == umc_vp_bitmap) { 5690 rv = BCM_E_MEMORY; 5691 goto cleanup; 5692 } 5693 sal_memset(umc_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5694 umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 5695 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, umc_idx, &mc_group); 5696 if (BCM_FAILURE(rv)) { 5697 goto cleanup; 5698 } 5699 if (umc_idx != bc_idx) { 5700 rv = _bcm_tr2_mc_group_vp_get_all(unit, mc_group, umc_vp_bitmap); 5701 if (BCM_FAILURE(rv)) { 5702 goto cleanup; 5703 } 5704 } else { 5705 sal_memcpy(umc_vp_bitmap, bc_vp_bitmap, SHR_BITALLOCSIZE(num_vp)); 5706 } 5707 5708 /* Get VPs from UUC group, if different from BC and UMC group */ 5709 uuc_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "uuc_vp_bitmap"); 5710 if (NULL == uuc_vp_bitmap) { 5711 rv = BCM_E_MEMORY; 5712 goto cleanup; 5713 } 5714 sal_memset(uuc_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5715 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 5716 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx, &mc_group); 5717 if (BCM_FAILURE(rv)) { 5718 goto cleanup; 5719 } 5720 if ((uuc_idx != bc_idx) && (uuc_idx != umc_idx)) { 5721 rv = _bcm_tr2_mc_group_vp_get_all(unit, mc_group, uuc_vp_bitmap); 5722 if (BCM_FAILURE(rv)) { 5723 goto cleanup; 5724 } 5725 } else if (uuc_idx == bc_idx) { 5726 sal_memcpy(uuc_vp_bitmap, bc_vp_bitmap, SHR_BITALLOCSIZE(num_vp)); 5727 } else { 5728 sal_memcpy(uuc_vp_bitmap, umc_vp_bitmap, SHR_BITALLOCSIZE(num_vp)); 5729 } 5730 5731 /* Get VPs and untagged status from egress VLAN translation table */ 5732 egr_vt_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "egr_vt_vp_bitmap"); 5733 if (NULL == egr_vt_vp_bitmap) { 5734 rv = BCM_E_MEMORY; 5735 goto cleanup; 5736 } 5737 sal_memset(egr_vt_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5738 5739 egr_vt_flags_arr = sal_alloc(num_vp * sizeof(int), "egr_vt_flags_arr"); 5740 if (NULL == egr_vt_flags_arr) { 5741 rv = BCM_E_MEMORY; 5742 goto cleanup; 5743 } 5744 sal_memset(egr_vt_flags_arr, 0, num_vp * sizeof(int)); 5745 5746 rv = _bcm_tr2_vp_untagged_get_all(unit, vlan, egr_vt_vp_bitmap, 5747 num_vp, egr_vt_flags_arr); 5748 if (BCM_FAILURE(rv)) { 5749 goto cleanup; 5750 } 5751 5752 /* Get VPs and flags from ingress VP VLAN membership table */ 5753 ing_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "ing_vp_bitmap"); 5754 if (NULL == ing_vp_bitmap) { 5755 rv = BCM_E_MEMORY; 5756 goto cleanup; 5757 } 5758 sal_memset(ing_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5759 5760 ing_flags_arr = sal_alloc(num_vp * sizeof(int), "ing_flags_arr"); 5761 if (NULL == ing_flags_arr) { 5762 rv = BCM_E_MEMORY; 5763 goto cleanup; 5764 } 5765 sal_memset(ing_flags_arr, 0, num_vp * sizeof(int)); 5766 5767 #ifdef BCM_TRIDENT2_SUPPORT 5768 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 5769 rv = bcm_td2_ing_vp_vlan_membership_get_all(unit, vlan, ing_vp_bitmap, 5770 num_vp, ing_flags_arr); 5771 if (BCM_FAILURE(rv)) { 5772 goto cleanup; 5773 } 5774 } 5775 #endif /* BCM_TRIDENT2_SUPPORT */ 5776 5777 /* Get VPs and flags from egress VP VLAN membership table */ 5778 egr_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "egr_vp_bitmap"); 5779 if (NULL == egr_vp_bitmap) { 5780 rv = BCM_E_MEMORY; 5781 goto cleanup; 5782 } 5783 sal_memset(egr_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5784 5785 egr_flags_arr = sal_alloc(num_vp * sizeof(int), "egr_flags_arr"); 5786 if (NULL == egr_flags_arr) { 5787 rv = BCM_E_MEMORY; 5788 goto cleanup; 5789 } 5790 sal_memset(egr_flags_arr, 0, num_vp * sizeof(int)); 5791 5792 #ifdef BCM_TRIDENT2_SUPPORT 5793 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 5794 rv = bcm_td2_egr_vp_vlan_membership_get_all(unit, vlan, egr_vp_bitmap, 5795 num_vp, egr_flags_arr); 5796 if (BCM_FAILURE(rv)) { 5797 goto cleanup; 5798 } 5799 } 5800 #endif /* BCM_TRIDENT2_SUPPORT */ 5801 5802 /* Get VPs from ingress VLAN VP groups */ 5803 ing_group_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), 5804 "ing_group_vp_bitmap"); 5805 if (NULL == ing_group_vp_bitmap) { 5806 rv = BCM_E_MEMORY; 5807 goto cleanup; 5808 } 5809 sal_memset(ing_group_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5810 5811 #ifdef BCM_TRIDENT_SUPPORT 5812 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5813 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 5814 if (!bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 5815 rv = bcm_td2p_ing_vp_group_vlan_get_all(unit, vlan, 5816 ing_group_vp_bitmap); 5817 if (BCM_FAILURE(rv)) { 5818 goto cleanup; 5819 } 5820 } 5821 } else 5822 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5823 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 5824 if (!bcm_td_ing_vp_group_unmanaged_get(unit)) { 5825 rv = bcm_td_ing_vp_group_vlan_get_all(unit, vlan, ing_group_vp_bitmap); 5826 if (BCM_FAILURE(rv)) { 5827 goto cleanup; 5828 } 5829 } 5830 } 5831 #endif /* BCM_TRIDENT_SUPPORT */ 5832 5833 /* Get VPs from egress VLAN VP groups */ 5834 eg_group_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), 5835 "eg_group_vp_bitmap"); 5836 if (NULL == eg_group_vp_bitmap) { 5837 rv = BCM_E_MEMORY; 5838 goto cleanup; 5839 } 5840 sal_memset(eg_group_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 5841 5842 #ifdef BCM_TRIDENT_SUPPORT 5843 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5844 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 5845 if (!bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 5846 rv = bcm_td2p_eg_vp_group_vlan_get_all(unit, vlan, 5847 eg_group_vp_bitmap); 5848 if (BCM_FAILURE(rv)) { 5849 goto cleanup; 5850 } 5851 } 5852 } else 5853 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5854 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 5855 if (!bcm_td_egr_vp_group_unmanaged_get(unit)) { 5856 rv = bcm_td_eg_vp_group_vlan_get_all(unit, vlan, eg_group_vp_bitmap); 5857 if (BCM_FAILURE(rv)) { 5858 goto cleanup; 5859 } 5860 } 5861 } 5862 #endif /* BCM_TRIDENT_SUPPORT */ 5863 5864 /* Combine the VP bitmaps and the flags arrays */ 5865 for (i = 0; i < num_vp; i++) { 5866 if (!SHR_BITGET(bc_vp_bitmap, i) && 5867 !SHR_BITGET(umc_vp_bitmap, i) && 5868 !SHR_BITGET(uuc_vp_bitmap, i) && 5869 !SHR_BITGET(egr_vt_vp_bitmap, i) && 5870 !SHR_BITGET(ing_vp_bitmap, i) && 5871 !SHR_BITGET(egr_vp_bitmap, i) && 5872 !SHR_BITGET(ing_group_vp_bitmap, i) && 5873 !SHR_BITGET(eg_group_vp_bitmap, i)) { 5874 /* VP is not a member of this VLAN */ 5875 continue; 5876 } 5877 5878 if (0 == array_max) { 5879 (*array_size)++; 5880 } else { 5881 if (_bcm_vp_used_get(unit, i, _bcmVpTypeVlan)) { 5882 BCM_GPORT_VLAN_PORT_ID_SET(gport_array[*array_size], i); 5883 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeNiv)) { 5884 BCM_GPORT_NIV_PORT_ID_SET(gport_array[*array_size], i); 5885 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeExtender)) { 5886 BCM_GPORT_EXTENDER_PORT_ID_SET(gport_array[*array_size], i); 5887 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeVpLag)) { 5888 bcm_trunk_t tid; 5889 rv = _bcm_esw_trunk_vp_lag_vp_to_tid(unit, i, &tid); 5890 if (BCM_FAILURE(rv)) { 5891 goto cleanup; 5892 } 5893 BCM_GPORT_TRUNK_SET(gport_array[*array_size], tid); 5894 } else { 5895 /* Unexpected VP type */ 5896 rv = BCM_E_INTERNAL; 5897 goto cleanup; 5898 } 5899 5900 if (NULL != flags_array) { 5901 flags_array[*array_size] = egr_vt_flags_arr[i] | 5902 ing_flags_arr[i] | egr_flags_arr[i]; 5903 if (!SHR_BITGET(bc_vp_bitmap, i)) { 5904 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD; 5905 } 5906 if (!SHR_BITGET(umc_vp_bitmap, i)) { 5907 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD; 5908 } 5909 if (!SHR_BITGET(uuc_vp_bitmap, i)) { 5910 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD; 5911 } 5912 if (SHR_BITGET(ing_vp_bitmap, i)) { 5913 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 5914 } 5915 if (SHR_BITGET(egr_vp_bitmap, i)) { 5916 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 5917 } 5918 } 5919 5920 (*array_size)++; 5921 if (*array_size == array_max) { 5922 break; 5923 } 5924 } 5925 } 5926 5927 cleanup: 5928 if (NULL != bc_vp_bitmap) { 5929 sal_free(bc_vp_bitmap); 5930 } 5931 if (NULL != umc_vp_bitmap) { 5932 sal_free(umc_vp_bitmap); 5933 } 5934 if (NULL != uuc_vp_bitmap) { 5935 sal_free(uuc_vp_bitmap); 5936 } 5937 if (NULL != egr_vt_vp_bitmap) { 5938 sal_free(egr_vt_vp_bitmap); 5939 } 5940 if (NULL != egr_vt_flags_arr) { 5941 sal_free(egr_vt_flags_arr); 5942 } 5943 if (NULL != ing_vp_bitmap) { 5944 sal_free(ing_vp_bitmap); 5945 } 5946 if (NULL != ing_flags_arr) { 5947 sal_free(ing_flags_arr); 5948 } 5949 if (NULL != egr_vp_bitmap) { 5950 sal_free(egr_vp_bitmap); 5951 } 5952 if (NULL != egr_flags_arr) { 5953 sal_free(egr_flags_arr); 5954 } 5955 if (NULL != ing_group_vp_bitmap) { 5956 sal_free(ing_group_vp_bitmap); 5957 } 5958 if (NULL != eg_group_vp_bitmap) { 5959 sal_free(eg_group_vp_bitmap); 5960 } 5961 5962 return rv; 5963 } 5964 5965 /* 5966 * Function: 5967 * _bcm_tr2_vp_untagged_delete_all 5968 * Purpose: 5969 * Delete all the given VLAN's virtual ports from egress 5970 * VLAN translation table. 5971 * Parameters: 5972 * unit - (IN) SOC unit number. 5973 * vlan - (IN) VLAN. 5974 * Returns: 5975 * BCM_E_XXX 5976 */ 5977 STATIC int 5978 _bcm_tr2_vp_untagged_delete_all(int unit, bcm_vlan_t vlan) 5979 { 5980 int rv = BCM_E_NONE; 5981 int chunk_size, num_chunks, chunk_index; 5982 int alloc_size; 5983 uint8 *egr_vt_buf = NULL; 5984 soc_field_t entry_type_f; 5985 int i, entry_index_min, entry_index_max; 5986 uint32 *ent; 5987 int vp; 5988 soc_mem_t mem = EGR_VLAN_XLATEm; 5989 5990 if (soc_mem_is_valid(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 5991 mem = EGR_VLAN_XLATE_1_DOUBLEm; 5992 } 5993 5994 chunk_size = 1024; 5995 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 5996 if (soc_mem_index_count(unit, mem) % chunk_size) { 5997 num_chunks++; 5998 } 5999 6000 alloc_size = soc_mem_entry_words(unit, mem) * 4 * chunk_size; 6001 egr_vt_buf = soc_cm_salloc(unit, alloc_size, "EGR_VLAN_XLATE buffer"); 6002 if (NULL == egr_vt_buf) { 6003 rv = BCM_E_MEMORY; 6004 goto cleanup; 6005 } 6006 6007 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 6008 entry_type_f = DATA_TYPEf; 6009 } else if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf)) { 6010 entry_type_f = ENTRY_TYPEf; 6011 } else { 6012 entry_type_f = KEY_TYPEf; 6013 } 6014 6015 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 6016 /* Get a chunk of entries */ 6017 entry_index_min = chunk_index * chunk_size; 6018 entry_index_max = entry_index_min + chunk_size - 1; 6019 if (entry_index_max > soc_mem_index_max(unit, mem)) { 6020 entry_index_max = soc_mem_index_max(unit, mem); 6021 } 6022 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 6023 entry_index_min, entry_index_max, egr_vt_buf); 6024 if (SOC_FAILURE(rv)) { 6025 goto cleanup; 6026 } 6027 6028 /* Read each entry of the chunk */ 6029 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 6030 int is_valid = 0; 6031 ent = soc_mem_table_idx_to_pointer(unit, 6032 mem, uint32 *, egr_vt_buf, i); 6033 6034 if (soc_feature(unit, soc_feature_base_valid)) { 6035 is_valid = soc_mem_field32_get(unit, mem, ent, 6036 BASE_VALID_0f) == 3 && 6037 soc_mem_field32_get(unit, mem, ent, 6038 BASE_VALID_1f) == 7; 6039 } else { 6040 is_valid = soc_mem_field32_get(unit, mem, ent, VALIDf); 6041 } 6042 6043 if (!is_valid) { 6044 continue; 6045 } 6046 6047 if (soc_mem_field32_get(unit, mem, ent, entry_type_f) != 1) { 6048 continue; 6049 } 6050 if (soc_mem_field32_get(unit, mem, ent, OVIDf) != vlan) { 6051 continue; 6052 } 6053 6054 vp = soc_mem_field32_get(unit, mem, ent, DVPf); 6055 6056 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 6057 rv = _bcm_tr2_vlan_vp_untagged_delete(unit, vlan, vp); 6058 } 6059 #ifdef BCM_TRIDENT_SUPPORT 6060 else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 6061 rv = bcm_trident_niv_untagged_delete(unit, vlan, vp); 6062 } 6063 #endif /* BCM_TRIDENT_SUPPORT */ 6064 #ifdef BCM_TRIUMPH3_SUPPORT 6065 else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 6066 rv = bcm_tr3_extender_untagged_delete(unit, vlan, vp); 6067 } 6068 #endif /* BCM_TRIUMPH3_SUPPORT */ 6069 else { 6070 continue; 6071 } 6072 if (BCM_FAILURE(rv)) { 6073 goto cleanup; 6074 } 6075 } 6076 } 6077 6078 cleanup: 6079 if (egr_vt_buf) { 6080 soc_cm_sfree(unit, egr_vt_buf); 6081 } 6082 6083 return rv; 6084 } 6085 /* 6086 * Function: 6087 * bcm_tr2_vlan_gport_delete_all 6088 * Purpose: 6089 * Remove all VLAN virtual ports from the specified vlan. 6090 * Parameters: 6091 * unit - (IN) SOC unit number. 6092 * vlan - (IN) VLAN to remove virtual ports from. 6093 * Returns: 6094 * BCM_E_XXX 6095 */ 6096 int 6097 bcm_tr2_vlan_gport_delete_all(int unit, bcm_vlan_t vlan) 6098 { 6099 vlan_tab_entry_t vtab; 6100 int bc_idx, umc_idx, uuc_idx; 6101 bcm_multicast_t mc_group; 6102 6103 #ifdef BCM_TRIUMPH3_SUPPORT 6104 if (soc_feature(unit, soc_feature_vlan_vfi)) { 6105 int rv; 6106 rv = _bcm_tr3_vlan_vpn_is_valid(unit, vlan); 6107 if (rv == BCM_E_NONE) { 6108 return _bcm_tr3_vlan_port_delete_all(unit, vlan); 6109 } 6110 } 6111 #endif /* BCM_TRIUMPH3_SUPPORT */ 6112 6113 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 6114 6115 BCM_IF_ERROR_RETURN 6116 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vtab)); 6117 6118 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 6119 return BCM_E_NOT_FOUND; 6120 } 6121 6122 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 6123 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 6124 /* There are no virtual ports to remove. */ 6125 return BCM_E_NONE; 6126 } 6127 } 6128 6129 /* Delete all VPs from the BC group */ 6130 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 6131 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx, 6132 &mc_group)); 6133 BCM_IF_ERROR_RETURN(bcm_esw_multicast_egress_delete_all(unit, mc_group)); 6134 6135 /* Delete all VPs from the UMC group, if UMC group is different 6136 * from BC group. 6137 */ 6138 umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 6139 if (umc_idx != bc_idx) { 6140 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, umc_idx, 6141 &mc_group)); 6142 BCM_IF_ERROR_RETURN(bcm_esw_multicast_egress_delete_all(unit, mc_group)); 6143 } 6144 6145 /* Delete all VPs from the UUC group, if UUC group is different 6146 * from BC and UMC groups. 6147 */ 6148 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 6149 if ((uuc_idx != bc_idx) && (uuc_idx != umc_idx)) { 6150 BCM_IF_ERROR_RETURN(_bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx, 6151 &mc_group)); 6152 BCM_IF_ERROR_RETURN(bcm_esw_multicast_egress_delete_all(unit, mc_group)); 6153 } 6154 6155 /* Clear the VIRTUAL_PORT_EN field since there are no virtual ports in 6156 * this VLAN anymore. 6157 */ 6158 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan) && 6159 SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 6160 soc_mem_field32_set(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf, 0); 6161 } 6162 SOC_IF_ERROR_RETURN(soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, vlan, 6163 &vtab)); 6164 6165 /* Delete given VLAN's (vlan, vp) entries from egress vlan translation table */ 6166 BCM_IF_ERROR_RETURN(_bcm_tr2_vp_untagged_delete_all(unit, vlan)); 6167 6168 #ifdef BCM_TRIDENT2_SUPPORT 6169 /* Delete given VLAN's (vlan, vp) entries from membership tables */ 6170 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 6171 BCM_IF_ERROR_RETURN 6172 (bcm_td2_ing_vp_vlan_membership_delete_all(unit, vlan)); 6173 } 6174 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 6175 BCM_IF_ERROR_RETURN 6176 (bcm_td2_egr_vp_vlan_membership_delete_all(unit, vlan)); 6177 } 6178 #endif /* BCM_TRIDENT2_SUPPORT */ 6179 6180 #ifdef BCM_TRIDENT_SUPPORT 6181 /* Delete VP groups from VLAN */ 6182 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6183 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 6184 if (!bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 6185 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_delete_all(unit, vlan, FALSE)); 6186 } 6187 if (!bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 6188 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_delete_all(unit, vlan, TRUE)); 6189 } 6190 } else 6191 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 6192 { 6193 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 6194 if (!bcm_td_ing_vp_group_unmanaged_get(unit)) { 6195 BCM_IF_ERROR_RETURN(bcm_td_ing_vp_group_vlan_delete_all(unit, vlan)); 6196 } 6197 } 6198 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 6199 if (!bcm_td_egr_vp_group_unmanaged_get(unit)) { 6200 BCM_IF_ERROR_RETURN(bcm_td_eg_vp_group_vlan_delete_all(unit, vlan)); 6201 } 6202 } 6203 } 6204 #endif /* BCM_TRIDENT_SUPPORT */ 6205 6206 return BCM_E_NONE; 6207 } 6208 6209 #ifdef BCM_WARM_BOOT_SUPPORT 6210 #ifdef BCM_TRIUMPH3_SUPPORT 6211 /* 6212 * Function: 6213 * _bcm_tr3_vlan_sd_tag_get 6214 * Purpose: 6215 * Get SD TAG FLAG 6216 * Parameters: 6217 * unit - (IN) Device Number 6218 * nh_index - (IN) Next hop index 6219 * flags - (OUT) SD Tag flag 6220 * Returns: 6221 * BCM_E_XXX 6222 */ 6223 STATIC int 6224 _bcm_tr3_vlan_sd_tag_get(int unit, uint32 nh_index, uint32 *flags) 6225 { 6226 egr_l3_next_hop_entry_t egr_nh; 6227 int action_present = 0, action_not_present = 0; 6228 6229 BCM_IF_ERROR_RETURN(READ_EGR_L3_NEXT_HOPm(unit, 6230 MEM_BLOCK_ANY, nh_index, &egr_nh)); 6231 6232 action_present = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 6233 &egr_nh, SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 6234 action_not_present = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 6235 &egr_nh, SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 6236 6237 if (action_not_present == 1) { 6238 *flags |= BCM_VLAN_PORT_SERVICE_VLAN_ADD; 6239 } 6240 6241 switch (action_present) { 6242 case 1: 6243 *flags |= BCM_VLAN_PORT_SERVICE_VLAN_TPID_REPLACE; 6244 break; 6245 case 2: 6246 *flags |= BCM_VLAN_PORT_SERVICE_VLAN_REPLACE; 6247 break; 6248 case 3: 6249 *flags |= BCM_VLAN_PORT_SERVICE_VLAN_DELETE; 6250 break; 6251 case 4: 6252 *flags |= BCM_VLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE; 6253 break; 6254 case 5: 6255 *flags |= BCM_VLAN_PORT_SERVICE_VLAN_PRI_REPLACE; 6256 break; 6257 case 6: 6258 *flags |= BCM_VLAN_PORT_SERVICE_PRI_REPLACE; 6259 break; 6260 case 7: 6261 *flags |= BCM_VLAN_PORT_SERVICE_TPID_REPLACE; 6262 break; 6263 default: 6264 break; 6265 } 6266 6267 return BCM_E_NONE; 6268 } 6269 #endif /* BCM_TRIUMPH3_SUPPORT */ 6270 6271 #ifdef BCM_TRIDENT2_SUPPORT 6272 int _bcm_td2_vlan_vp_scache_size_get(int unit, int *size) 6273 { 6274 int alloc_sz = 0; 6275 int num_vp = 0; 6276 6277 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 6278 /* Store VLAN_VP_INFO(unit, vp)->criteria */ 6279 alloc_sz += num_vp * sizeof(bcm_vlan_port_match_t); 6280 6281 /* Store VLAN_VP_INFO(unit, vp)->match_vlan */ 6282 alloc_sz += num_vp * sizeof(bcm_vlan_t); 6283 6284 /* Store VLAN_VP_INFO(unit, vp)->match_inner_vlan */ 6285 alloc_sz += num_vp * sizeof(bcm_vlan_t); 6286 6287 /* Store VLAN_VP_INFO(unit, vp)->port */ 6288 alloc_sz += num_vp * sizeof(bcm_gport_t); 6289 6290 /* Store VLAN_VP_INFO(unit, vp)->flags */ 6291 alloc_sz += num_vp * sizeof(uint32); 6292 6293 if (size != NULL) { 6294 *size = alloc_sz; 6295 } 6296 6297 return BCM_E_NONE; 6298 } 6299 6300 int _bcm_td2_vlan_vp_sync(int unit, uint8 **scache_ptr) 6301 { 6302 int num_vp = 0, vp; 6303 _bcm_tr2_vlan_vp_info_t *vlan_vp; 6304 6305 if ((*scache_ptr) == NULL) { 6306 return BCM_E_PARAM; 6307 } 6308 6309 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 6310 6311 for (vp = 0; vp < num_vp; vp++) { 6312 vlan_vp = VLAN_VP_INFO(unit, vp); 6313 /* sync VLAN_VP_INFO(unit, vp)->criteria */ 6314 sal_memcpy((*scache_ptr), 6315 &(vlan_vp->criteria), sizeof(bcm_vlan_port_match_t)); 6316 6317 (*scache_ptr) += sizeof(bcm_vlan_port_match_t); 6318 6319 /* sync VLAN_VP_INFO(unit, vp)->match_vlan */ 6320 sal_memcpy((*scache_ptr), 6321 &(vlan_vp->match_vlan), sizeof(bcm_vlan_t)); 6322 6323 (*scache_ptr) += sizeof(bcm_vlan_t); 6324 6325 /* sync VLAN_VP_INFO(unit, vp)->match_inner_vlan */ 6326 sal_memcpy((*scache_ptr), 6327 &(vlan_vp->match_inner_vlan), sizeof(bcm_vlan_t)); 6328 6329 (*scache_ptr) += sizeof(bcm_vlan_t); 6330 6331 /* sync VLAN_VP_INFO(unit, vp)->port */ 6332 sal_memcpy((*scache_ptr), 6333 &(vlan_vp->port), sizeof(bcm_gport_t)); 6334 6335 (*scache_ptr) += sizeof(bcm_gport_t); 6336 6337 /* sync VLAN_VP_INFO(unit, vp)->flags */ 6338 sal_memcpy((*scache_ptr), 6339 &(vlan_vp->flags), sizeof(uint32)); 6340 6341 (*scache_ptr) += sizeof(uint32); 6342 } 6343 6344 return BCM_E_NONE; 6345 } 6346 6347 int _bcm_td2_vlan_vp_recover(int unit, uint8 **scache_ptr) 6348 { 6349 int num_vp = 0, vp; 6350 _bcm_tr2_vlan_vp_info_t *vlan_vp; 6351 6352 if ((*scache_ptr) == NULL) { 6353 _bcm_tr2_vlan_virtual_free_resources(unit); 6354 return BCM_E_PARAM; 6355 } 6356 6357 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 6358 6359 for (vp = 0; vp < num_vp; vp++) { 6360 vlan_vp = VLAN_VP_INFO(unit, vp); 6361 /* Recover VLAN_VP_INFO(unit, vp)->criteria */ 6362 sal_memcpy(&(vlan_vp->criteria), 6363 (*scache_ptr), sizeof(bcm_vlan_port_match_t)); 6364 6365 (*scache_ptr) += sizeof(bcm_vlan_port_match_t); 6366 6367 /* Recover VLAN_VP_INFO(unit, vp)->match_vlan */ 6368 sal_memcpy(&(vlan_vp->match_vlan), 6369 (*scache_ptr), sizeof(bcm_vlan_t)); 6370 6371 (*scache_ptr) += sizeof(bcm_vlan_t); 6372 6373 /* Recover VLAN_VP_INFO(unit, vp)->match_inner_vlan */ 6374 sal_memcpy(&(vlan_vp->match_inner_vlan), 6375 (*scache_ptr), sizeof(bcm_vlan_t)); 6376 6377 (*scache_ptr) += sizeof(bcm_vlan_t); 6378 6379 /* Recover VLAN_VP_INFO(unit, vp)->port */ 6380 sal_memcpy(&(vlan_vp->port), 6381 (*scache_ptr), sizeof(bcm_gport_t)); 6382 6383 (*scache_ptr) += sizeof(bcm_gport_t); 6384 6385 /* Recover VLAN_VP_INFO(unit, vp)->flags */ 6386 sal_memcpy(&(vlan_vp->flags), 6387 (*scache_ptr), sizeof(uint32)); 6388 6389 (*scache_ptr) += sizeof(uint32); 6390 } 6391 6392 return BCM_E_NONE; 6393 } 6394 #endif 6395 6396 /* 6397 * Function: 6398 * bcm_tr2_vlan_virtual_reinit 6399 * Purpose: 6400 * Warm boot recovery for the VLAN virtual software module 6401 * Parameters: 6402 * unit - Device Number 6403 * Returns: 6404 * BCM_E_XXX 6405 */ 6406 int 6407 bcm_tr2_vlan_virtual_reinit(int unit) 6408 { 6409 int rv = BCM_E_NONE; 6410 int stable_size; 6411 int chunk_size, num_chunks, chunk_index; 6412 uint8 *vt_buf = NULL; 6413 uint32 *vt_entry; 6414 int i, entry_index_min, entry_index_max; 6415 uint32 key_type, vp, nh_index = -1, trunk_bit; 6416 source_vp_entry_t svp_entry; 6417 ing_dvp_table_entry_t dvp_entry; 6418 ing_l3_next_hop_entry_t ing_nh_entry; 6419 wlan_svp_table_entry_t wlan_svp_entry; 6420 bcm_trunk_t tgid; 6421 bcm_module_t modid, mod_out; 6422 bcm_port_t port_num, port_out; 6423 uint32 profile_idx; 6424 ing_vlan_tag_action_profile_entry_t ing_profile_entry; 6425 soc_mem_t vt_mem; 6426 int vt_entry_size; 6427 soc_field_t valid_f; 6428 soc_field_t key_type_f; 6429 int key_type_ovid, key_type_ivid_ovid, key_type_otag, key_type_ivid; 6430 soc_field_t mpls_action_f; 6431 soc_field_t source_vp_f; 6432 soc_field_t ovid_f; 6433 soc_field_t ivid_f; 6434 soc_field_t otag_f; 6435 soc_field_t trunk_f; 6436 soc_field_t tgid_f; 6437 soc_field_t module_id_f; 6438 soc_field_t port_num_f; 6439 soc_field_t tag_action_profile_ptr_f; 6440 _bcm_vp_info_t vp_info; 6441 #ifdef BCM_TRIUMPH3_SUPPORT 6442 int sd_tag = 0; 6443 int network_port = 0; 6444 #endif /* BCM_TRIUMPH3_SUPPORT */ 6445 6446 _bcm_vp_info_init(&vp_info); 6447 vp_info.vp_type = _bcmVpTypeVlan; 6448 6449 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 6450 6451 #ifdef BCM_TRIDENT2PLUS_SUPPORT 6452 if (soc_feature(unit, soc_feature_vfi_profile)) { 6453 soc_mem_t mem; 6454 int buf_size; 6455 uint8 *buf = NULL; 6456 vfi_entry_t *vfi_entry = NULL; 6457 6458 mem = VFIm; 6459 entry_index_min = soc_mem_index_min(unit, mem); 6460 entry_index_max = soc_mem_index_max(unit, mem); 6461 buf_size = SOC_MEM_TABLE_BYTES(unit, mem); 6462 6463 buf = soc_cm_salloc(unit, buf_size, "VFI_Table buffer"); 6464 if (NULL == buf) { 6465 rv = BCM_E_MEMORY; 6466 goto cleanup; 6467 } 6468 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 6469 entry_index_min, entry_index_max, buf); 6470 if (SOC_FAILURE(rv)) { 6471 soc_cm_sfree(unit, buf); 6472 goto cleanup; 6473 } 6474 6475 for (i = entry_index_min; i < entry_index_max; i++) { 6476 vfi_entry = soc_mem_table_idx_to_pointer(unit, mem, 6477 vfi_entry_t *, buf, i); 6478 profile_idx = soc_mem_field32_get(unit, mem, 6479 vfi_entry, VFI_PROFILE_PTRf); 6480 6481 rv = _bcm_vfi_profile_entry_reference(unit, profile_idx, 1); 6482 if (BCM_FAILURE(rv)) { 6483 soc_cm_sfree(unit, buf); 6484 goto cleanup; 6485 } 6486 } 6487 soc_cm_sfree(unit, buf); 6488 } 6489 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 6490 6491 /* 6492 *As to the chips which support vp_lag feature, already recover VLAN_VP_INFO from 6493 *scache in virtual_reinit, so don't need to recover it from VLAN_XLATE table. 6494 */ 6495 #ifdef BCM_TRIDENT2_SUPPORT 6496 if (soc_feature(unit, soc_feature_vp_lag)) { 6497 if (stable_size !=0 && !SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 6498 rv = BCM_E_NONE; 6499 goto cleanup; 6500 } 6501 } 6502 #endif 6503 6504 /* Recover VLAN virtual ports from VLAN_XLATE table */ 6505 6506 #ifdef BCM_TRIUMPH3_SUPPORT 6507 if (SOC_IS_TRIUMPH3(unit)) { 6508 vt_mem = VLAN_XLATE_EXTDm; 6509 vt_entry_size = sizeof(vlan_xlate_extd_entry_t); 6510 valid_f = VALID_0f; 6511 key_type_f = KEY_TYPE_0f; 6512 key_type_ovid = TR3_VLXLT_X_HASH_KEY_TYPE_OVID; 6513 key_type_ivid_ovid = TR3_VLXLT_X_HASH_KEY_TYPE_IVID_OVID; 6514 key_type_otag = TR3_VLXLT_X_HASH_KEY_TYPE_OTAG; 6515 key_type_ivid = TR3_VLXLT_X_HASH_KEY_TYPE_IVID; 6516 mpls_action_f = XLATE__MPLS_ACTIONf; 6517 source_vp_f = XLATE__SOURCE_VPf; 6518 ovid_f = XLATE__OVIDf; 6519 ivid_f = XLATE__IVIDf; 6520 otag_f = XLATE__OTAGf; 6521 trunk_f = XLATE__Tf; 6522 tgid_f = XLATE__TGIDf; 6523 module_id_f = XLATE__MODULE_IDf; 6524 port_num_f = XLATE__PORT_NUMf; 6525 tag_action_profile_ptr_f = XLATE__TAG_ACTION_PROFILE_PTRf; 6526 } else 6527 #endif /* BCM_TRIUMPH3_SUPPORT */ 6528 { 6529 if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) { 6530 vt_mem = VLAN_XLATE_1_DOUBLEm; 6531 vt_entry_size = sizeof(vlan_xlate_1_double_entry_t); 6532 } else { 6533 vt_mem = VLAN_XLATEm; 6534 vt_entry_size = sizeof(vlan_xlate_entry_t); 6535 } 6536 valid_f = VALIDf; 6537 key_type_f = KEY_TYPEf; 6538 /* coverity[mixed_enums] */ 6539 key_type_ovid = TR_VLXLT_HASH_KEY_TYPE_OVID; 6540 /* coverity[mixed_enums] */ 6541 key_type_ivid_ovid = TR_VLXLT_HASH_KEY_TYPE_IVID_OVID; 6542 /* coverity[mixed_enums] */ 6543 key_type_otag = TR_VLXLT_HASH_KEY_TYPE_OTAG; 6544 /* coverity[mixed_enums] */ 6545 key_type_ivid = TR_VLXLT_HASH_KEY_TYPE_IVID; 6546 mpls_action_f = MPLS_ACTIONf; 6547 source_vp_f = SOURCE_VPf; 6548 ovid_f = OVIDf; 6549 ivid_f = IVIDf; 6550 otag_f = OTAGf; 6551 trunk_f = Tf; 6552 tgid_f = TGIDf; 6553 module_id_f = MODULE_IDf; 6554 port_num_f = PORT_NUMf; 6555 tag_action_profile_ptr_f = TAG_ACTION_PROFILE_PTRf; 6556 } 6557 6558 chunk_size = 1024; 6559 num_chunks = soc_mem_index_count(unit, vt_mem) / chunk_size; 6560 if (soc_mem_index_count(unit, vt_mem) % chunk_size) { 6561 num_chunks++; 6562 } 6563 6564 vt_buf = soc_cm_salloc(unit, vt_entry_size * chunk_size, 6565 "VLAN_XLATE buffer"); 6566 if (NULL == vt_buf) { 6567 rv = BCM_E_MEMORY; 6568 goto cleanup; 6569 } 6570 6571 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 6572 6573 /* Get a chunk of entries */ 6574 entry_index_min = chunk_index * chunk_size; 6575 entry_index_max = entry_index_min + chunk_size - 1; 6576 if (entry_index_max > soc_mem_index_max(unit, vt_mem)) { 6577 entry_index_max = soc_mem_index_max(unit, vt_mem); 6578 } 6579 rv = soc_mem_read_range(unit, vt_mem, MEM_BLOCK_ANY, 6580 entry_index_min, entry_index_max, vt_buf); 6581 if (SOC_FAILURE(rv)) { 6582 goto cleanup; 6583 } 6584 6585 /* Read each entry of the chunk */ 6586 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 6587 vt_entry = soc_mem_table_idx_to_pointer(unit, 6588 vt_mem, uint32 *, vt_buf, i); 6589 6590 if (soc_feature(unit, soc_feature_base_valid)) { 6591 if (soc_mem_field32_get(unit, vt_mem, vt_entry, BASE_VALID_0f) != 3 || 6592 soc_mem_field32_get(unit, vt_mem, vt_entry, BASE_VALID_1f) != 7) { 6593 continue; 6594 } 6595 } else { 6596 if (soc_mem_field32_get(unit, vt_mem, vt_entry, valid_f) == 0) { 6597 continue; 6598 } 6599 } 6600 6601 key_type = soc_mem_field32_get(unit, vt_mem, vt_entry, key_type_f); 6602 if ((key_type != key_type_ovid) && 6603 (key_type != key_type_ivid_ovid) && 6604 (key_type != key_type_otag) && 6605 (key_type != key_type_ivid)) { 6606 continue; 6607 } 6608 6609 if (soc_mem_field32_get(unit, vt_mem, vt_entry, mpls_action_f) != 1) { 6610 continue; 6611 } 6612 6613 vp = soc_mem_field32_get(unit, vt_mem, vt_entry, source_vp_f); 6614 if ((stable_size == 0) || SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 6615 /* Determine if VP is a VLAN VP by process of elimination. 6616 * Can rule out NIV and Extender VPs since they have different 6617 * VIF key types in VLAN_XLATEm. 6618 */ 6619 6620 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry); 6621 if (BCM_FAILURE(rv)) { 6622 goto cleanup; 6623 } 6624 6625 #ifdef BCM_TRIUMPH3_SUPPORT 6626 if (soc_feature(unit, soc_feature_vlan_vfi) && 6627 soc_SOURCE_VPm_field32_get(unit, &svp_entry, ENTRY_TYPEf) == 1) { 6628 int vfi_index = soc_SOURCE_VPm_field32_get(unit, &svp_entry, VFIf); 6629 if (vfi_index != _BCM_VLAN_VFI_INVALID) { 6630 rv = _bcm_vfi_alloc_with_id(unit, VFIm, _bcmVfiTypeVlan, vfi_index); 6631 if (BCM_FAILURE(rv)) { 6632 goto cleanup; 6633 } 6634 } 6635 sd_tag = soc_SOURCE_VPm_field32_get(unit, &svp_entry, SD_TAG_MODEf); 6636 network_port = soc_SOURCE_VPm_field32_get(unit, &svp_entry, NETWORK_PORTf); 6637 } else 6638 #endif /* BCM_TRIUMPH3_SUPPORT */ 6639 /* Rule out MPLS and MiM VPs, for which ENTRY_TYPE = 1 */ 6640 if (soc_SOURCE_VPm_field32_get(unit, &svp_entry, ENTRY_TYPEf) != 3) { 6641 continue; 6642 } 6643 6644 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry); 6645 if (BCM_FAILURE(rv)) { 6646 goto cleanup; 6647 } 6648 6649 if (!(soc_mem_field_valid(unit, ING_DVP_TABLEm, VP_TYPEf))) { 6650 continue; 6651 } 6652 6653 /* Rule out Trill VPs, for which VP_TYPE = 1 */ 6654 if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, VP_TYPEf) != 0) { 6655 continue; 6656 } 6657 6658 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 6659 NEXT_HOP_INDEXf); 6660 rv = READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, 6661 &ing_nh_entry); 6662 if (BCM_FAILURE(rv)) { 6663 goto cleanup; 6664 } 6665 /* Rule out Subport VPs, for which ENTRY_TYPE = 3 */ 6666 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, 6667 ENTRY_TYPEf) != 2) { 6668 continue; 6669 } 6670 6671 /* Rule out WLAN vp */ 6672 if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) { 6673 if (vp > soc_mem_index_max(unit, WLAN_SVP_TABLEm)) { 6674 continue; 6675 } 6676 rv = READ_WLAN_SVP_TABLEm(unit, MEM_BLOCK_ANY, vp, 6677 &wlan_svp_entry); 6678 if (BCM_FAILURE(rv)) { 6679 goto cleanup; 6680 } 6681 if (soc_WLAN_SVP_TABLEm_field32_get(unit, &wlan_svp_entry, 6682 VALIDf) == 1) { 6683 continue; 6684 } 6685 } 6686 6687 /* At this point, we are sure VP is a VLAN VP. */ 6688 6689 rv = _bcm_vp_used_set(unit, vp, vp_info); 6690 if (BCM_FAILURE(rv)) { 6691 goto cleanup; 6692 } 6693 } else { 6694 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 6695 /* VP bitmap is recovered by virtual_init */ 6696 continue; 6697 } 6698 } 6699 6700 /* Recover VLAN_VP_INFO(unit, vp)->criteria, match_vlan, and 6701 * match_inner_vlan. 6702 */ 6703 if (key_type == key_type_ovid) { 6704 VLAN_VP_INFO(unit, vp)->criteria = 6705 BCM_VLAN_PORT_MATCH_PORT_VLAN; 6706 VLAN_VP_INFO(unit, vp)->match_vlan = 6707 soc_mem_field32_get(unit, vt_mem, vt_entry, ovid_f); 6708 } else if (key_type == key_type_ivid_ovid) { 6709 VLAN_VP_INFO(unit, vp)->criteria = 6710 BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED; 6711 VLAN_VP_INFO(unit, vp)->match_vlan = 6712 soc_mem_field32_get(unit, vt_mem, vt_entry, ovid_f); 6713 VLAN_VP_INFO(unit, vp)->match_inner_vlan = 6714 soc_mem_field32_get(unit, vt_mem, vt_entry, ivid_f); 6715 } else if (key_type == key_type_otag) { 6716 VLAN_VP_INFO(unit, vp)->criteria = 6717 BCM_VLAN_PORT_MATCH_PORT_VLAN16; 6718 VLAN_VP_INFO(unit, vp)->match_vlan = 6719 soc_mem_field32_get(unit, vt_mem, vt_entry, otag_f); 6720 } else if (key_type == key_type_ivid) { 6721 VLAN_VP_INFO(unit, vp)->criteria = 6722 BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN; 6723 VLAN_VP_INFO(unit, vp)->match_inner_vlan = 6724 soc_mem_field32_get(unit, vt_mem, vt_entry, ivid_f); 6725 } else { 6726 continue; 6727 } 6728 6729 /* Recover VLAN_VP_INFO(unit, vp)->port */ 6730 trunk_bit = soc_mem_field32_get(unit, vt_mem, vt_entry, trunk_f); 6731 if (trunk_bit) { 6732 tgid = soc_mem_field32_get(unit, vt_mem, vt_entry, tgid_f); 6733 BCM_GPORT_TRUNK_SET(VLAN_VP_INFO(unit, vp)->port, tgid); 6734 } else { 6735 modid = soc_mem_field32_get(unit, vt_mem, vt_entry, module_id_f); 6736 port_num = soc_mem_field32_get(unit, vt_mem, vt_entry, port_num_f); 6737 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 6738 modid, port_num, &mod_out, &port_out); 6739 if (BCM_FAILURE(rv)) { 6740 goto cleanup; 6741 } 6742 BCM_GPORT_MODPORT_SET(VLAN_VP_INFO(unit, vp)->port, 6743 mod_out, port_out); 6744 } 6745 6746 /* Recover VLAN_VP_INFO(unit, vp)->flags */ 6747 profile_idx = soc_mem_field32_get(unit, vt_mem, vt_entry, 6748 tag_action_profile_ptr_f); 6749 rv = READ_ING_VLAN_TAG_ACTION_PROFILEm(unit, MEM_BLOCK_ANY, 6750 profile_idx, &ing_profile_entry); 6751 if (BCM_FAILURE(rv)) { 6752 goto cleanup; 6753 } 6754 if ((soc_ING_VLAN_TAG_ACTION_PROFILEm_field32_get(unit, 6755 &ing_profile_entry, DT_OTAG_ACTIONf) == 6756 bcmVlanActionReplace) && 6757 (soc_ING_VLAN_TAG_ACTION_PROFILEm_field32_get(unit, 6758 &ing_profile_entry, DT_ITAG_ACTIONf) == 6759 bcmVlanActionNone)) { 6760 VLAN_VP_INFO(unit, vp)->flags |= BCM_VLAN_PORT_INNER_VLAN_PRESERVE; 6761 } 6762 if ((soc_ING_VLAN_TAG_ACTION_PROFILEm_field32_get(unit, 6763 &ing_profile_entry, SOT_OTAG_ACTIONf) == 6764 bcmVlanActionReplace) && 6765 (soc_ING_VLAN_TAG_ACTION_PROFILEm_field32_get(unit, 6766 &ing_profile_entry, SOT_ITAG_ACTIONf) == 6767 bcmVlanActionAdd)) { 6768 VLAN_VP_INFO(unit, vp)->flags |= BCM_VLAN_PORT_INNER_VLAN_ADD; 6769 } 6770 6771 if (VLAN_VP_INFO(unit, vp)->criteria == 6772 BCM_VLAN_PORT_MATCH_PORT_VLAN16) { 6773 VLAN_VP_INFO(unit, vp)->flags |= BCM_VLAN_PORT_EGRESS_VLAN16; 6774 } 6775 #if defined(BCM_SABER2_SUPPORT) 6776 if (SOC_IS_SABER2(unit)) { 6777 if (soc_SOURCE_VPm_field32_get(unit, &svp_entry, TPID_SOURCEf) == 2) { 6778 VLAN_VP_INFO(unit, vp)->flags |= BCM_VLAN_PORT_USE_SGLP_TPID; 6779 } 6780 } 6781 #endif 6782 #ifdef BCM_TRIUMPH3_SUPPORT 6783 if (soc_feature(unit, soc_feature_vlan_vfi) && (sd_tag == 1)) { 6784 VLAN_VP_INFO(unit, vp)->flags |= BCM_VLAN_PORT_SERVICE_TAGGED; 6785 } 6786 6787 if (soc_feature(unit, soc_feature_vlan_vfi) && (network_port == 1)) { 6788 VLAN_VP_INFO(unit, vp)->flags |= BCM_VLAN_PORT_NETWORK; 6789 } 6790 6791 if (soc_feature(unit, soc_feature_vlan_vfi) && (nh_index != -1)) { 6792 uint32 flags = 0; 6793 rv = _bcm_tr3_vlan_sd_tag_get(unit, nh_index, &flags); 6794 if (BCM_FAILURE(rv)) { 6795 goto cleanup; 6796 } 6797 VLAN_VP_INFO(unit, vp)->flags |= flags; 6798 } 6799 #endif /* BCM_TRIUMPH3_SUPPORT */ 6800 6801 if (stable_size == 0) { 6802 /* In the Port module, a port's VP count is not recovered in 6803 * level 1 Warm Boot. 6804 */ 6805 rv = _bcm_tr2_vlan_vp_port_cnt_update(unit, 6806 VLAN_VP_INFO(unit, vp)->port, vp, TRUE); 6807 if (BCM_FAILURE(rv)) { 6808 goto cleanup; 6809 } 6810 } 6811 } 6812 } 6813 6814 cleanup: 6815 if (vt_buf) { 6816 soc_cm_sfree(unit, vt_buf); 6817 } 6818 6819 if (BCM_FAILURE(rv)) { 6820 _bcm_tr2_vlan_virtual_free_resources(unit); 6821 } 6822 6823 return rv; 6824 } 6825 #endif /* BCM_WARM_BOOT_SUPPORT */ 6826 6827 #ifndef BCM_SW_STATE_DUMP_DISABLE 6828 /* 6829 * Function: 6830 * _bcm_tr2_vlan_vp_sw_dump 6831 * Purpose: 6832 * Displays VLAN VP information maintained by software. 6833 * Parameters: 6834 * unit - Device unit number 6835 * Returns: 6836 * None 6837 */ 6838 void 6839 bcm_tr2_vlan_vp_sw_dump(int unit) 6840 { 6841 int i, num_vp; 6842 6843 LOG_CLI((BSL_META_U(unit, 6844 "\nSW Information VLAN VP - Unit %d\n"), unit)); 6845 6846 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 6847 6848 for (i = 0; i < num_vp; i++) { 6849 if (VLAN_VP_INFO(unit, i)->port == 0) { 6850 continue; 6851 } 6852 LOG_CLI((BSL_META_U(unit, 6853 "\n VLAN vp = %d\n"), i)); 6854 LOG_CLI((BSL_META_U(unit, 6855 " Criteria = 0x%x,"), VLAN_VP_INFO(unit, i)->criteria)); 6856 switch (VLAN_VP_INFO(unit, i)->criteria) { 6857 case BCM_VLAN_PORT_MATCH_PORT_VLAN: 6858 LOG_CLI((BSL_META_U(unit, 6859 " port plus outer VLAN ID\n"))); 6860 break; 6861 case BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED: 6862 LOG_CLI((BSL_META_U(unit, 6863 " port plus outer and inner VLAN IDs\n"))); 6864 break; 6865 case BCM_VLAN_PORT_MATCH_PORT_VLAN16: 6866 LOG_CLI((BSL_META_U(unit, 6867 " port plus outer VLAN tag\n"))); 6868 break; 6869 case BCM_VLAN_PORT_MATCH_PORT_INNER_VLAN: 6870 LOG_CLI((BSL_META_U(unit, 6871 " port plus Inner VLAN ID\n"))); 6872 break; 6873 default: 6874 LOG_CLI((BSL_META_U(unit, 6875 " \n"))); 6876 } 6877 LOG_CLI((BSL_META_U(unit, 6878 " Flags = 0x%x\n"), VLAN_VP_INFO(unit, i)->flags)); 6879 LOG_CLI((BSL_META_U(unit, 6880 " Match VLAN = 0x%x\n"), VLAN_VP_INFO(unit, i)->match_vlan)); 6881 LOG_CLI((BSL_META_U(unit, 6882 " Match Inner VLAN = 0x%x\n"), 6883 VLAN_VP_INFO(unit, i)->match_inner_vlan)); 6884 LOG_CLI((BSL_META_U(unit, 6885 " Port = 0x%x\n"), VLAN_VP_INFO(unit, i)->port)); 6886 } 6887 6888 return; 6889 } 6890 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 6891 6892 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */