mim.c (332395B)
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: mim.c 8 * Purpose: Manages MiM functions 9 */ 10 11 #include <soc/defs.h> 12 #include <sal/core/libc.h> 13 #include <shared/bsl.h> 14 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 15 16 #include <soc/drv.h> 17 #include <soc/scache.h> 18 #include <soc/hash.h> 19 #include <soc/util.h> 20 #include <soc/triumph.h> 21 22 #if defined BCM_METROLITE_SUPPORT 23 #include <soc/katana2.h> 24 #endif 25 26 #include <bcm/error.h> 27 #include <bcm/mim.h> 28 29 #include <bcm_int/esw/mbcm.h> 30 #include <bcm_int/esw/l3.h> 31 #include <bcm_int/esw/firebolt.h> 32 #include <bcm_int/esw/triumph.h> 33 #include <bcm_int/esw/triumph2.h> 34 #include <bcm_int/esw/xgs3.h> 35 #include <bcm_int/esw/mim.h> 36 #include <bcm_int/common/multicast.h> 37 #include <bcm_int/esw/virtual.h> 38 #include <bcm_int/esw/trx.h> 39 #include <bcm_int/esw/stack.h> 40 #include <bcm_int/esw/switch.h> 41 #if defined(BCM_TRIUMPH3_SUPPORT) 42 #include <bcm_int/esw/triumph3.h> 43 #endif /* BCM_TRIUMPH3_SUPPORT*/ 44 45 #include <bcm_int/esw_dispatch.h> 46 #include <bcm_int/api_xlate_port.h> 47 #include <bcm_int/esw/failover.h> 48 49 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 50 #include <bcm_int/esw/policer.h> 51 #endif 52 #if defined(BCM_KATANA2_SUPPORT) 53 #include <bcm_int/esw/katana2.h> 54 #endif 55 #if defined(BCM_TRIDENT2_SUPPORT) 56 #include <bcm_int/esw/trident2.h> 57 #endif /* BCM_TRIDENT2_SUPPORT */ 58 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 59 #include <bcm_int/esw/trident2plus.h> 60 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 61 #if defined(BCM_TRIDENT3_SUPPORT) 62 #include <soc/esw/cancun.h> 63 #include <bcm_int/esw/trident3.h> 64 #endif 65 #if defined(BCM_TOMAHAWK2_SUPPORT) 66 #include <bcm_int/esw/tomahawk2.h> 67 #endif /* BCM_TOMAHAWK2_SUPPORT */ 68 69 _bcm_tr2_mim_bookkeeping_t _bcm_tr2_mim_bk_info[BCM_MAX_NUM_UNITS]; 70 71 /* Flag to check initialized status */ 72 STATIC int mim_initialized[BCM_MAX_NUM_UNITS]; 73 74 STATIC sal_mutex_t _mim_mutex[BCM_MAX_NUM_UNITS] = {NULL}; 75 76 #define L3_INFO(unit) (&_bcm_l3_bk_info[unit]) 77 #define MIM_INFO(_unit_) (&_bcm_tr2_mim_bk_info[_unit_]) 78 #define VPN_ISID(_unit_, _vfi_) \ 79 (_bcm_tr2_mim_bk_info[_unit_].vpn_info[_vfi_].isid) 80 81 #define MIM_INIT(unit) \ 82 do { \ 83 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { \ 84 return BCM_E_UNIT; \ 85 } \ 86 if (!mim_initialized[unit]) { \ 87 return BCM_E_INIT; \ 88 } \ 89 } while (0) 90 91 /* 92 * MIM module lock 93 */ 94 #define MIM_LOCK(unit) \ 95 sal_mutex_take(_mim_mutex[unit], sal_mutex_FOREVER); 96 97 #define MIM_UNLOCK(unit) \ 98 sal_mutex_give(_mim_mutex[unit]); 99 100 /* 101 * L3 interface usage bitmap operations 102 */ 103 #define _BCM_MIM_INTF_USED_GET(_u_, _intf_) \ 104 SHR_BITGET(MIM_INFO(_u_)->intf_bitmap, (_intf_)) 105 #define _BCM_MIM_INTF_USED_SET(_u_, _intf_) \ 106 SHR_BITSET(MIM_INFO((_u_))->intf_bitmap, (_intf_)) 107 #define _BCM_MIM_INTF_USED_CLR(_u_, _intf_) \ 108 SHR_BITCLR(MIM_INFO((_u_))->intf_bitmap, (_intf_)) 109 110 #ifdef BCM_WARM_BOOT_SUPPORT 111 #define MEM_CHUNK_MAX_ENTRY 1024 112 113 #define _BCM_CHUNK_GET_INDEX(unit, mem, mem_index ) \ 114 (mem_index - (mem_index / MEM_CHUNK_MAX_ENTRY) * MEM_CHUNK_MAX_ENTRY) 115 116 #define _BCM_CHUNK_GET_MEM_BUFFER(chunk_buf) \ 117 ((void*)((int32*)chunk_buf + 1)) 118 119 #define _BCM_CHUNK_SET_INDEX_OFFSET(chunk_buf, val) \ 120 (*((int32*)chunk_buf) = val) 121 #define _BCM_CHUNK_GET_INDEX_OFFSET(chunk_buf) \ 122 (*((int32*)(chunk_buf))) 123 124 STATIC int _bcm_chunk_memory_alloc(int unit, soc_mem_t mem, void **mem_buf); 125 STATIC int _bcm_chunk_get_mem_entry(int unit, soc_mem_t mem, int index, 126 void *chunk_buf, void **mem_entry); 127 #endif 128 STATIC int _bcm_tr2_mim_port_delete(int unit, bcm_vpn_t vpn, int vp); 129 STATIC int _bcm_tr2_mim_egr_vxlt_sd_tag_actions_get(int unit, 130 bcm_mim_port_t *mim_port, 131 bcm_mim_vpn_config_t *vpn_info, 132 uint32 *egr_vlan_xlate_entry); 133 134 int _bcm_tr2_mim_egr_vxlt_sd_tag_actions(int unit, bcm_mim_port_t *mim_port, 135 bcm_mim_vpn_config_t *vpn_info, 136 uint32 *evxlt_entry); 137 int _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete(int unit, 138 uint32 *egr_vlan_xlate_entry); 139 typedef uint32 MEM_ENTRY_T[SOC_MAX_MEM_FIELD_WORDS]; 140 141 /* 142 * Function: 143 * bcm_mim_enable 144 * Purpose: 145 * Enable/disable MiM function. 146 * Parameters: 147 * unit - SOC unit number. 148 * enable - TRUE: enable MiM support; FALSE: disable MiM support. 149 * Returns: 150 * BCM_E_XXX. 151 */ 152 STATIC int 153 bcm_tr2_mim_enable(int unit, int enable) 154 { 155 int port; 156 int idx; 157 uint32 ptab[SOC_MAX_MEM_WORDS]; 158 bcm_pbmp_t port_pbmp; 159 soc_mem_t port_mem; 160 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT) 161 uint32 flags; 162 #endif 163 164 #if defined(BCM_TRIDENT3_SUPPORT) 165 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 166 port_mem = ING_DEVICE_PORTm; 167 } else 168 #endif 169 { 170 port_mem = PORT_TABm; 171 } 172 173 174 BCM_PBMP_CLEAR(port_pbmp); 175 BCM_PBMP_ASSIGN(port_pbmp, PBMP_PORT_ALL(unit)); 176 #ifdef BCM_KATANA2_SUPPORT 177 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 178 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &port_pbmp)); 179 } 180 if (soc_feature(unit, soc_feature_linkphy_coe) || 181 soc_feature(unit, soc_feature_subtag_coe)) { 182 _bcm_kt2_subport_pbmp_update(unit, &port_pbmp); 183 } 184 #endif 185 186 PBMP_ITER(port_pbmp, port) { 187 /* No MiM lookup on stacking ports. */ 188 if (IS_ST_PORT(unit, port)) { 189 continue; 190 } 191 /* wait for SDK-95379, modfiy this to unblock others. */ 192 #if defined(BCM_TRIDENT3_SUPPORT) 193 if (!SOC_IS_TRIDENT3X(unit)) 194 #endif 195 { 196 BCM_IF_ERROR_RETURN 197 (bcm_esw_port_control_set(unit, port, bcmPortControlMacInMac, 198 (enable) ? 1 : 0)); 199 } 200 } 201 /* Enable MC_TERM_ENABLE on loopback port */ 202 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT) 203 if (SOC_IS_ENDURO(unit) || SOC_IS_KATANAX(unit)) { 204 PBMP_ALL_ITER(unit, port) { 205 if (IS_LB_PORT(unit, port)) { 206 BCM_IF_ERROR_RETURN 207 (soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab)); 208 soc_PORT_TABm_field32_set(unit, &ptab, 209 MIM_MC_TERM_ENABLEf, (enable) ? 1 : 0); 210 BCM_IF_ERROR_RETURN 211 (soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab)); 212 /* 213 * The loopback port is subjected to ingress/egress vlan + 214 * spanning tree check in Enduro. 215 * - Disable VLAN membership check for loopback port. 216 * - Set STG state to forwarding. 217 */ 218 BCM_IF_ERROR_RETURN 219 (bcm_esw_port_vlan_member_get(unit, port, &flags)); 220 flags &= ~(BCM_PORT_VLAN_MEMBER_EGRESS); 221 BCM_IF_ERROR_RETURN 222 (bcm_esw_port_vlan_member_set(unit, port, flags)); 223 BCM_IF_ERROR_RETURN 224 (bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD)); 225 } 226 } 227 } else 228 #endif /* BCM_ENDURO_SUPPORT */ 229 { 230 if (SOC_IS_TRIUMPH3(unit)) { 231 /* Triumph3 nlf passthru loopback port */ 232 idx = AXP_PORT(unit, SOC_AXP_NLF_PASSTHRU); 233 #if defined(BCM_TRIDENT_SUPPORT) 234 } else if (SOC_IS_TD_TT(unit)) { 235 idx = LB_PORT(unit); 236 #endif /* BCM_TRIDENT_SUPPORT */ 237 } else { 238 idx = 54; 239 } 240 BCM_IF_ERROR_RETURN 241 (soc_mem_read(unit, port_mem, MEM_BLOCK_ANY, idx, ptab)); 242 /* For TD3, it is done by c-code. We don't have to configure anything */ 243 #if defined(BCM_TRIDENT3_SUPPORT) 244 if (!SOC_IS_TRIDENT3X(unit)) 245 #endif 246 { 247 soc_mem_field32_set(unit, port_mem, ptab, 248 MIM_MC_TERM_ENABLEf, (enable) ? 1 : 0); 249 } 250 BCM_IF_ERROR_RETURN 251 (soc_mem_write(unit, port_mem, MEM_BLOCK_ALL, idx, ptab)); 252 } 253 254 return BCM_E_NONE; 255 } 256 257 /* 258 * Function: 259 * _bcm_tr2_mim_free_resources 260 * Purpose: 261 * Free all allocated tables and memory 262 * Parameters: 263 * unit - SOC unit number 264 * Returns: 265 * Nothing 266 */ 267 STATIC void 268 _bcm_tr2_mim_free_resources(int unit) 269 { 270 _bcm_tr2_mim_bookkeeping_t *mim_info = MIM_INFO(unit); 271 272 if (_mim_mutex[unit]) { 273 sal_mutex_destroy(_mim_mutex[unit]); 274 _mim_mutex[unit] = NULL; 275 } 276 if (mim_info->vpn_info) { 277 sal_free(mim_info->vpn_info); 278 mim_info->vpn_info = NULL; 279 } 280 if (mim_info->port_info) { 281 sal_free(mim_info->port_info); 282 mim_info->port_info = NULL; 283 } 284 if (mim_info->intf_bitmap) { 285 sal_free(mim_info->intf_bitmap); 286 mim_info->intf_bitmap = NULL; 287 } 288 } 289 290 /* 291 * Function: 292 * _bcm_tr2_mim_hw_clear 293 * Purpose: 294 * Perform HW tables clean up for MiM module. 295 * Parameters: 296 * unit - Device Number 297 * Returns: 298 * BCM_E_XXX 299 */ 300 STATIC int 301 _bcm_tr2_mim_hw_clear(int unit) 302 { 303 int rv, rv_error = BCM_E_NONE; 304 305 rv = bcm_tr2_mim_enable(unit, FALSE); 306 if (BCM_FAILURE(rv)) { 307 rv_error = rv; 308 } 309 310 /* Destroy all VPNs */ 311 rv = bcm_tr2_mim_vpn_destroy_all(unit); 312 if (BCM_FAILURE(rv) && (BCM_E_NONE == rv_error)) { 313 rv_error = rv; 314 } 315 316 return rv_error; 317 } 318 319 /* 320 * Function: 321 * bcm_mim_detach 322 * Purpose: 323 * Detach the MIM software module 324 * Parameters: 325 * unit - Device Number 326 * Returns: 327 * BCM_E_XXX 328 */ 329 int 330 bcm_tr2_mim_detach(int unit) 331 { 332 int rv = BCM_E_NONE; 333 334 if (mim_initialized[unit] == FALSE) { 335 return BCM_E_NONE; 336 } 337 338 if (0 == SOC_HW_ACCESS_DISABLE(unit)) { 339 rv = _bcm_tr2_mim_hw_clear(unit); 340 } 341 342 _bcm_tr2_mim_free_resources(unit); 343 mim_initialized[unit] = FALSE; 344 return rv; 345 } 346 347 #ifdef BCM_WARM_BOOT_SUPPORT 348 STATIC void 349 _bcm_tr2_mim_port_flex_stat_recover(int unit, source_vp_entry_t *source_vp, 350 int index) 351 { 352 int fs_idx; 353 if (soc_feature(unit, soc_feature_gport_service_counters)) { 354 if (soc_mem_field_valid(unit, SOURCE_VPm, VINTF_CTR_IDXf)) { 355 fs_idx = soc_mem_field32_get(unit, SOURCE_VPm, source_vp, 356 VINTF_CTR_IDXf); 357 if (fs_idx) { 358 BCM_GPORT_MIM_PORT_ID_SET(index, index); 359 _bcm_esw_flex_stat_reinit_add(unit, _bcmFlexStatTypeGport, 360 fs_idx, index); 361 } 362 } 363 } 364 return; 365 } 366 367 STATIC void 368 _bcm_tr2_mim_vpn_flex_stat_recover(int unit, vfi_entry_t *vfi, 369 int index) 370 { 371 int fs_idx; 372 if (soc_feature(unit, soc_feature_gport_service_counters)) { 373 if (soc_mem_field_valid(unit, VFIm, SERVICE_CTR_IDXf)) { 374 fs_idx = soc_mem_field32_get(unit, VFIm, vfi, 375 SERVICE_CTR_IDXf); 376 if (fs_idx) { 377 _BCM_MIM_VPN_SET(index, _BCM_MIM_VPN_TYPE_MIM, index); 378 _bcm_esw_flex_stat_reinit_add(unit, _bcmFlexStatTypeService, 379 fs_idx, index); 380 } 381 } 382 } 383 return; 384 } 385 386 STATIC int 387 _bcm_tr2_mim_source_vp_tpid_recover(int unit, source_vp_entry_t *source_vp, int vp) 388 { 389 int tpid_enable, index, rv = BCM_E_NONE; 390 if (soc_SOURCE_VPm_field32_get(unit, source_vp, SD_TAG_MODEf) == 1) { 391 #if defined(BCM_TRIDENT3_SUPPORT) 392 if (SOC_IS_TRIDENT3X(unit)) { 393 uint32 svp1[SOC_MAX_MEM_WORDS] = {0}; 394 rv = READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1); 395 if (rv < 0) { 396 return rv; 397 } 398 tpid_enable = soc_SVP_ATTRS_1m_field32_get(unit, svp1, TPID_ENABLEf); 399 } else 400 #endif 401 { 402 tpid_enable = soc_SOURCE_VPm_field32_get(unit, source_vp, TPID_ENABLEf); 403 } 404 for (index = 0; index < 4; index++) { 405 if (tpid_enable & (1 << index)) { 406 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1); 407 break; 408 } 409 } 410 } 411 return rv; 412 } 413 414 STATIC int 415 _bcm_tr2_mim_egr_vxlt_tpid_recover(int unit, 416 uint32 *egr_vlan_xlate) 417 { 418 int tpid_enable, index, rv = BCM_E_NONE; 419 soc_mem_t hw_mem; 420 421 #if defined(BCM_TRIDENT3_SUPPORT) 422 if (soc_feature(unit, soc_feature_base_valid)) { 423 hw_mem = EGR_VLAN_XLATE_1_DOUBLEm; 424 } else 425 #endif 426 { 427 hw_mem = EGR_VLAN_XLATEm; 428 } 429 430 if ((soc_mem_field32_get(unit, hw_mem, egr_vlan_xlate, 431 MIM_ISID__SD_TAG_ACTION_IF_NOT_PRESENTf) == 1) || 432 (soc_mem_field32_get(unit, hw_mem, egr_vlan_xlate, 433 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf) == 1) 434 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 435 || (soc_mem_field32_get(unit, hw_mem, egr_vlan_xlate, 436 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf) == 0x7) 437 #endif 438 ) { 439 /* BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE or 440 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD */ 441 tpid_enable = soc_mem_field32_get(unit, hw_mem, egr_vlan_xlate, 442 MIM_ISID__SD_TAG_TPID_INDEXf); 443 if (SOC_IS_TRIDENT3X(unit)) { 444 for (index = 0; index < 4; index++) { 445 if (tpid_enable & (1 << index)) { 446 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1); 447 break; 448 } 449 } 450 } else { 451 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, tpid_enable, 1); 452 } 453 } 454 return rv; 455 } 456 457 STATIC int 458 _bcm_tr2_mim_egr_nh_tpid_recover(int unit, 459 egr_l3_next_hop_entry_t *egr_l3_next_hop) 460 { 461 int index, tpid_idx, rv = BCM_E_NONE; 462 if ((soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_l3_next_hop, 463 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf) == 1) || 464 (soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_l3_next_hop, 465 SD_TAG__SD_TAG_ACTION_IF_PRESENTf) == 1) 466 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 467 ||(soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_l3_next_hop, 468 SD_TAG__SD_TAG_ACTION_IF_PRESENTf) == 0x7) 469 #endif 470 ) { 471 /* BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE or 472 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD */ 473 tpid_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_l3_next_hop, 474 SD_TAG__SD_TAG_TPID_INDEXf); 475 if (SOC_IS_TRIDENT3X(unit)) { 476 for (index = 0; index < 4; index++) { 477 if (tpid_idx & (1 << index)) { 478 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1); 479 break; 480 } 481 } 482 } else { 483 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, tpid_idx, 1); 484 } 485 } 486 return rv; 487 } 488 489 STATIC int 490 _bcm_tr2_mim_port_associated_data_recover(int unit, int vp, int stable_size) 491 { 492 int idx, nh_index, macda_idx, intf_num, rv = BCM_E_NONE; 493 uint32 nh_flags, port_flags; 494 ing_l3_next_hop_entry_t ing_nh_entry; 495 egr_l3_next_hop_entry_t egr_nh_entry; 496 ing_dvp_table_entry_t ing_dvp_entry; 497 bcm_module_t mod_in, mod_out; 498 bcm_port_t port_in, port_out, phys_port; 499 bcm_trunk_t trunk_id; 500 bcm_l3_egress_t nh_info; 501 _bcm_port_info_t *info; 502 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 503 bcm_port_t local_member_array[SOC_MAX_NUM_PP_PORTS]; 504 int max_num_ports = SOC_MAX_NUM_PP_PORTS; 505 #else 506 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 507 int max_num_ports = SOC_MAX_NUM_PORTS; 508 #endif 509 int local_member_count; 510 int entry_type = 0; 511 int is_trunk = 0; 512 513 BCM_IF_ERROR_RETURN(soc_mem_read(unit, ING_DVP_TABLEm, MEM_BLOCK_ANY, 514 vp, &ing_dvp_entry)); 515 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &ing_dvp_entry, 516 NEXT_HOP_INDEXf); 517 BCM_IF_ERROR_RETURN(soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, 518 nh_index, &ing_nh_entry)); 519 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 520 nh_index, &egr_nh_entry)); 521 522 bcm_l3_egress_t_init(&nh_info); 523 524 nh_flags = _BCM_L3_SHR_UPDATE | _BCM_L3_SHR_WRITE_DISABLE | 525 _BCM_L3_SHR_WITH_ID; 526 rv = bcm_xgs3_nh_add(unit, nh_flags, &nh_info, &nh_index); 527 BCM_IF_ERROR_RETURN(rv); 528 529 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, 530 ENTRY_TYPEf) == 0x2) { 531 if (soc_feature(unit, soc_feature_generic_dest)) { 532 uint32 dt, dv; 533 dv = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, 534 &ing_nh_entry, DESTINATIONf, &dt); 535 if (dt == SOC_MEM_FIF_DEST_LAG) { 536 /* Trunk group */ 537 trunk_id = dv & SOC_MEM_FIF_DGPP_TGID_MASK; 538 is_trunk = 1; 539 } else { 540 port_in = dv & SOC_MEM_FIF_DGPP_PORT_MASK; 541 mod_in = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 542 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 543 } 544 } else { 545 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, Tf)) { 546 trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, TGIDf); 547 is_trunk = 1; 548 } else { 549 mod_in = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, MODULE_IDf); 550 port_in = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, PORT_NUMf); 551 } 552 } 553 554 /* Type is SVP */ 555 if (is_trunk) { 556 MIM_INFO(unit)->port_info[vp].modid = -1; 557 MIM_INFO(unit)->port_info[vp].port = -1; 558 MIM_INFO(unit)->port_info[vp].tgid = trunk_id; 559 /* Update each local physical port's SW state */ 560 if (stable_size == 0) { 561 /* When persistent storage is available, this state is recovered 562 in the port module */ 563 rv = _bcm_esw_trunk_local_members_get(unit, trunk_id, 564 max_num_ports, local_member_array, &local_member_count); 565 BCM_IF_ERROR_RETURN(rv); 566 for (idx = 0; idx < local_member_count; idx++) { 567 _bcm_port_info_access(unit, local_member_array[idx], &info); 568 info->vp_count++; 569 BCM_IF_ERROR_RETURN( 570 bcm_esw_port_vlan_member_get( 571 unit, local_member_array[idx], &port_flags)); 572 BCM_IF_ERROR_RETURN( 573 bcm_esw_port_vlan_member_set( 574 unit, local_member_array[idx], port_flags)); 575 } 576 } 577 } else { 578 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 579 mod_in, port_in, &mod_out, &port_out); 580 MIM_INFO(unit)->port_info[vp].modid = mod_out; 581 MIM_INFO(unit)->port_info[vp].port = port_out; 582 MIM_INFO(unit)->port_info[vp].tgid = -1; 583 /* Update the physical port's SW state */ 584 if (stable_size == 0) { 585 /* When persistent storage is available, this state is recovered 586 in the port module */ 587 phys_port = MIM_INFO(unit)->port_info[vp].port; 588 if (soc_feature(unit, soc_feature_sysport_remap)) { 589 BCM_XLATE_SYSPORT_S2P(unit, &phys_port); 590 } 591 _bcm_port_info_access(unit, phys_port, &info); 592 info->vp_count++; 593 BCM_IF_ERROR_RETURN( 594 bcm_esw_port_vlan_member_get(unit, phys_port, &port_flags)); 595 BCM_IF_ERROR_RETURN( 596 bcm_esw_port_vlan_member_set(unit, phys_port, port_flags)); 597 } 598 } 599 } else { 600 return BCM_E_INTERNAL; /* Should never happen */ 601 } 602 603 #if defined(BCM_TRIDENT3_SUPPORT) 604 if (SOC_IS_TRIDENT3X(unit)) { 605 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 606 &egr_nh_entry, DATA_TYPEf); 607 } else 608 #endif /* BCM_TRIDENT3_SUPPORT */ 609 { 610 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 611 &egr_nh_entry, ENTRY_TYPEf); 612 } 613 614 if (entry_type == 2) { 615 /* SD TAG view - recover TPID reference counts */ 616 rv = _bcm_tr2_mim_egr_nh_tpid_recover(unit, &egr_nh_entry); 617 BCM_IF_ERROR_RETURN(rv); 618 } 619 if (entry_type == 3) { 620 /* MIM view - recover MACDA profile and interface reference counts */ 621 macda_idx = soc_EGR_L3_NEXT_HOPm_field32_get 622 (unit, &egr_nh_entry, MIM__MAC_DA_PROFILE_INDEXf); 623 _bcm_common_profile_mem_ref_cnt_update(unit, EGR_MAC_DA_PROFILEm, 624 macda_idx, 1); 625 intf_num = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh_entry, 626 MIM__INTF_NUMf); 627 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, MIM__ISID_LOOKUP_TYPEf)) { 628 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh_entry, 629 MIM__ISID_LOOKUP_TYPEf) == 0) { 630 MIM_INFO(unit)->port_info[vp].flags = _BCM_MIM_PORT_TYPE_NETWORK; 631 } else { 632 MIM_INFO(unit)->port_info[vp].flags = _BCM_MIM_PORT_TYPE_PEER; 633 } 634 } 635 636 _BCM_MIM_INTF_USED_SET(unit, intf_num); 637 BCM_L3_INTF_USED_SET(unit, intf_num); 638 } 639 640 #if defined(BCM_TRIDENT3_SUPPORT) 641 if (SOC_IS_TRIDENT3X(unit)) { 642 soc_mem_t mem = EGR_DVP_ATTRIBUTEm; 643 egr_dvp_attribute_entry_t egr_dvp_attribute; 644 645 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 646 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 647 BCM_IF_ERROR_RETURN(rv); 648 649 if (SOC_MEM_FIELD_VALID(unit, mem, COMMON__EVXLT_KEY_SELf)) { 650 if (soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 651 COMMON__EVXLT_KEY_SELf) == 0x1) { 652 MIM_INFO(unit)->port_info[vp].flags = _BCM_MIM_PORT_TYPE_NETWORK; 653 } else if (soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 654 COMMON__EVXLT_KEY_SELf) == 0x2) { 655 MIM_INFO(unit)->port_info[vp].flags = _BCM_MIM_PORT_TYPE_PEER; 656 } 657 } 658 } 659 #endif 660 return rv; 661 } 662 663 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1, 0) 664 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1, 1) 665 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_1 666 667 /* 668 * Function: 669 * _bcm_tr2_mim_wb_alloc 670 * 671 * Purpose: 672 * Alloc persisitent memory for Level 2 Warm Boot scache. 673 * 674 * Parameters: 675 * unit - (IN) Device Unit Number. 676 * 677 * Returns: 678 * BCM_E_XXX 679 */ 680 STATIC int 681 _bcm_tr2_mim_wb_alloc(int unit) 682 { 683 int alloc_sz = 0, rv = BCM_E_NONE; 684 soc_scache_handle_t scache_handle; 685 int num_vp = 0; 686 687 uint8 *mim_state; 688 int stable_size; 689 690 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 691 692 if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) { 693 return BCM_E_NONE; 694 } 695 696 if (soc_feature(unit, soc_feature_vp_lag)) { 697 /* Size of Initiator of all VP */ 698 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 699 /* 700 * Size of All match_key's flags && index && gport(trunk_id, modid, port) && 701 * match_vlan && match_inner_vlan && match_label && 702 * match_tunnel_srcmac && match_tunnel_vlan. 703 */ 704 alloc_sz += num_vp * (sizeof(uint32) * 2 + sizeof(bcm_gport_t) + 705 sizeof(bcm_vlan_t) * 2 + sizeof(bcm_mpls_label_t) + 706 sizeof(bcm_mac_t) + sizeof(bcm_vlan_t)); 707 } 708 #if defined(BCM_TRIDENT_SUPPORT) 709 else if (soc_feature(unit, soc_feature_mim_peer_sharing)) { 710 /* Size of the flags of all ports */ 711 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 712 alloc_sz += num_vp * sizeof(uint32); 713 } 714 #endif /* BCM_TRIDENT_SUPPORT */ 715 716 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_MIM, 0); 717 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 718 alloc_sz, (uint8**)&mim_state, 719 BCM_WB_DEFAULT_VERSION, NULL); 720 if (BCM_FAILURE(rv)) { 721 return rv; 722 } 723 724 return BCM_E_NONE; 725 } 726 727 /* 728 * Function: 729 * _bcm_tr2_mim_wb_recover 730 * 731 * Purpose: 732 * Recover MIM module info for Level 2 Warm Boot from persisitent memory 733 * 734 * Warm Boot Version Map: 735 * see _bcm_esw_mim_sync definition 736 * 737 * Parameters: 738 * unit - (IN) Device Unit Number. 739 * 740 * Returns: 741 * BCM_E_XXX 742 */ 743 STATIC int 744 _bcm_tr2_mim_wb_recover(int unit) 745 { 746 int i, rv = BCM_E_NONE; 747 int num_vp = 0; 748 int stable_size; 749 uint16 recovered_ver = 0; 750 bcm_gport_t gport; 751 uint8 *mim_state = NULL; 752 soc_scache_handle_t scache_handle; 753 _bcm_tr2_mim_bookkeeping_t *mim_info; 754 #if defined(BCM_TRIDENT_SUPPORT) 755 int additional_scache_size = 0; 756 #endif /* BCM_TRIDENT_SUPPORT */ 757 758 mim_info = MIM_INFO(unit); 759 760 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 761 762 /* Requires extended scache support level-2 warmboot */ 763 if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) { 764 return BCM_E_NONE; 765 } 766 767 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_MIM, 0); 768 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 769 0, &mim_state, 770 BCM_WB_DEFAULT_VERSION, &recovered_ver); 771 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 772 return rv; 773 } else if (rv == BCM_E_NOT_FOUND) { 774 return _bcm_tr2_mim_wb_alloc(unit); 775 } 776 777 if (mim_state == NULL) { 778 return BCM_E_NONE; 779 } 780 781 if (soc_feature(unit, soc_feature_vp_lag)) { 782 /* 783 * Recover the index && gport(trunk_id, modid, port) && match_vlan && 784 * match_inner_vlan of each Match Key. 785 */ 786 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 787 for (i = 0; i < num_vp; i++) { 788 sal_memcpy(&(mim_info->port_info[i].flags), mim_state, 789 sizeof(uint32)); 790 mim_state += sizeof(uint32); 791 sal_memcpy(&(mim_info->port_info[i].index), mim_state, 792 sizeof(uint32)); 793 mim_state += sizeof(uint32); 794 sal_memcpy(&gport, mim_state, sizeof(bcm_gport_t)); 795 if (BCM_GPORT_IS_TRUNK(gport)) { 796 mim_info->port_info[i].tgid = 797 BCM_GPORT_TRUNK_GET(gport); 798 } else if (BCM_GPORT_IS_MODPORT(gport)) { 799 mim_info->port_info[i].modid = 800 BCM_GPORT_MODPORT_MODID_GET(gport); 801 mim_info->port_info[i].port = 802 BCM_GPORT_MODPORT_PORT_GET(gport); 803 } 804 mim_state += sizeof(bcm_gport_t); 805 sal_memcpy(&(mim_info->port_info[i].match_vlan), mim_state, 806 sizeof(bcm_vlan_t)); 807 mim_state += sizeof(bcm_vlan_t); 808 sal_memcpy(&(mim_info->port_info[i].match_inner_vlan), 809 mim_state, sizeof(bcm_vlan_t)); 810 mim_state += sizeof(bcm_vlan_t); 811 sal_memcpy(&(mim_info->port_info[i].match_label), mim_state, 812 sizeof(bcm_mpls_label_t)); 813 mim_state += sizeof(bcm_mpls_label_t); 814 sal_memcpy(&(mim_info->port_info[i].match_tunnel_srcmac), 815 mim_state, sizeof(bcm_mac_t)); 816 mim_state += sizeof(bcm_mac_t); 817 sal_memcpy(&(mim_info->port_info[i].match_tunnel_vlan), 818 mim_state, sizeof(bcm_vlan_t)); 819 mim_state += sizeof(bcm_vlan_t); 820 } 821 } 822 #if defined(BCM_TRIDENT_SUPPORT) 823 else if (soc_feature(unit, soc_feature_mim_peer_sharing)) { 824 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 825 if (recovered_ver >= BCM_WB_VERSION_1_1) { 826 /* Recover the flags of each port */ 827 for (i = 0; i < num_vp; i++) { 828 sal_memcpy(&(mim_info->port_info[i].flags), mim_state, 829 sizeof(uint32)); 830 mim_state += sizeof(uint32); 831 } 832 } else { 833 additional_scache_size += num_vp * sizeof(uint32); 834 } 835 } 836 837 if (additional_scache_size > 0) { 838 rv = soc_scache_realloc(unit, scache_handle, additional_scache_size); 839 if(BCM_FAILURE(rv)) { 840 return rv; 841 } 842 } 843 #endif /* BCM_TRIDENT_SUPPORT */ 844 845 return BCM_E_NONE; 846 } 847 848 /* 849 * Function: 850 * bcm_tr2_mim_sync 851 * 852 * Purpose: 853 * Record MIM module persistent info for Level 2 Warm Boot 854 * 855 * Warm Boot Version Map: 856 * WB_VERSION_1_0 857 * 858 * Parameters: 859 * unit - (IN) Device Unit Number. 860 * 861 * Returns: 862 * BCM_E_XXX 863 */ 864 int 865 bcm_tr2_mim_sync(int unit) 866 { 867 int i, num_vp = 0; 868 int stable_size; 869 bcm_gport_t gport; 870 uint8 *mim_state; 871 soc_scache_handle_t scache_handle; 872 _bcm_tr2_mim_bookkeeping_t *mim_info; 873 874 /* Parameter validation checks */ 875 if (!SOC_UNIT_VALID(unit)) { 876 return BCM_E_UNIT; 877 } 878 879 mim_info = MIM_INFO(unit); 880 881 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 882 883 /* Requires extended scache support level-2 warmboot */ 884 if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) { 885 return BCM_E_NONE; 886 } 887 888 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_MIM, 0); 889 BCM_IF_ERROR_RETURN( 890 _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 891 0, &mim_state, BCM_WB_DEFAULT_VERSION, NULL)); 892 893 if (soc_feature(unit, soc_feature_vp_lag)) { 894 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 895 /* 896 * Since we can't recover index && gport(trunk_id, modid, port) && 897 * match_vlan && match_inner_vlan from HW if we add this mim port to 898 * VPLAG, so we need to store it for warmboot recovery. Total is 34*16K. 899 */ 900 for (i = 0; i < num_vp; i++) { 901 sal_memcpy(mim_state, &(mim_info->port_info[i].flags), sizeof(uint32)); 902 mim_state += sizeof(uint32); 903 sal_memcpy(mim_state, &(mim_info->port_info[i].index), sizeof(uint32)); 904 mim_state += sizeof(uint32); 905 if (mim_info->port_info[i].tgid != -1) { 906 BCM_GPORT_TRUNK_SET(gport, mim_info->port_info[i].tgid); 907 } else if (mim_info->port_info[i].modid != -1) { 908 BCM_GPORT_MODPORT_SET(gport, 909 mim_info->port_info[i].modid, 910 mim_info->port_info[i].port); 911 } else { 912 gport = BCM_GPORT_INVALID; 913 } 914 sal_memcpy(mim_state, &gport, sizeof(bcm_gport_t)); 915 mim_state += sizeof(bcm_gport_t); 916 sal_memcpy(mim_state, &(mim_info->port_info[i].match_vlan), 917 sizeof(bcm_vlan_t)); 918 mim_state += sizeof(bcm_vlan_t); 919 sal_memcpy(mim_state, &(mim_info->port_info[i].match_inner_vlan), 920 sizeof(bcm_vlan_t)); 921 mim_state += sizeof(bcm_vlan_t); 922 sal_memcpy(mim_state, &(mim_info->port_info[i].match_label), 923 sizeof(bcm_mpls_label_t)); 924 mim_state += sizeof(bcm_mpls_label_t); 925 sal_memcpy(mim_state, &(mim_info->port_info[i].match_tunnel_srcmac), 926 sizeof(bcm_mac_t)); 927 mim_state += sizeof(bcm_mac_t); 928 sal_memcpy(mim_state, &(mim_info->port_info[i].match_tunnel_vlan), 929 sizeof(bcm_vlan_t)); 930 mim_state += sizeof(bcm_vlan_t); 931 } 932 } 933 #if defined(BCM_TRIDENT_SUPPORT) 934 else if (soc_feature(unit, soc_feature_mim_peer_sharing)) { 935 /* Store the flags of each port */ 936 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 937 for (i = 0; i < num_vp; i++) { 938 sal_memcpy(mim_state, 939 &(mim_info->port_info[i].flags),sizeof(uint32)); 940 mim_state += sizeof(uint32); 941 } 942 } 943 #endif /* BCM_TRIDENT_SUPPORT */ 944 945 return BCM_E_NONE; 946 } 947 948 /* 949 * Function: 950 * _bcm_tr2_mim_reinit 951 * Purpose: 952 * Warm boot recovery for the MIM software module 953 * Parameters: 954 * unit - Device Number 955 * Returns: 956 * BCM_E_XXX 957 */ 958 STATIC int 959 _bcm_tr2_mim_reinit(int unit) 960 { 961 int rv, i, index_min, index_max, stable_size; 962 uint32 vfi_entry[SOC_MAX_MEM_WORDS] = {0}; 963 uint32 vfi_1_entry[SOC_MAX_MEM_WORDS] = {0}; 964 int vfi, isid, index, tpid_enable, vp = 0; 965 uint32 key_type; 966 uint8 *mpls_entry_buf = NULL; /* MPLS_ENTRY DMA buffer */ 967 MEM_ENTRY_T *mpls_entry; 968 uint8 *vlan_xlate_buf = NULL; /* VLAN_XLATE DMA buffer */ 969 void * vlan_xlate; 970 uint8 *egr_vlan_xlate_buf = NULL; /* EGR_VLAN_XLATE DMA buffer */ 971 void * egr_vlan_xlate; 972 uint8 *source_vp_buf = NULL; /* SOURCE_VP DMA buffer */ 973 source_vp_entry_t *source_vp; 974 uint8 *source_trunk_map_buf = NULL; /* SOURCE_TRUNK_MAP DMA buffer */ 975 source_trunk_map_table_entry_t *source_trunk_map; 976 soc_mem_t mpls_mem = MPLS_ENTRYm; 977 soc_mem_t xlate_mem, egr_xlate_mem = EGR_VLAN_XLATEm; 978 int isid_key_type; 979 void *mem_entry[1], *mem_buf[1]; 980 _bcm_vp_info_t vp_info; 981 soc_mem_t vfi_mem; 982 soc_mem_t vfi_1_mem; 983 984 _bcm_vp_info_init(&vp_info); 985 vp_info.vp_type = _bcmVpTypeMim; 986 987 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 988 989 /* If Level 1 of limited Level 2, proceed only if SOC_WARM_BOOT_MIM 990 * is set */ 991 if ((stable_size == 0) || SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 992 if (!SOC_WARM_BOOT_IS_MIM(unit)) { 993 return BCM_E_NONE; 994 } 995 } 996 997 #if defined(BCM_TRIUMPH3_SUPPORT) 998 if (SOC_IS_TRIUMPH3(unit)) { 999 mpls_mem = MPLS_ENTRY_EXTDm; 1000 xlate_mem = VLAN_XLATE_EXTDm; 1001 isid_key_type = 0x18; 1002 } else 1003 #endif /* BCM_TRIUMPH3_SUPPORT */ 1004 { 1005 #if defined(BCM_TRIDENT3_SUPPORT) 1006 if (soc_feature(unit, soc_feature_base_valid)) { 1007 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 1008 xlate_mem = VLAN_XLATE_1_DOUBLEm; 1009 } else 1010 #endif 1011 { 1012 xlate_mem = VLAN_XLATEm; 1013 } 1014 isid_key_type = 0x2; 1015 } 1016 1017 /* Allocate Chunk Memory buffer for various tables */ 1018 mem_buf[0] = &mpls_entry_buf; 1019 rv = _bcm_chunk_memory_alloc(unit, mpls_mem, mem_buf[0]); 1020 if (BCM_FAILURE(rv) || (NULL == mpls_entry_buf)) { 1021 goto cleanup; 1022 } 1023 1024 mem_buf[0] = &vlan_xlate_buf; 1025 rv = _bcm_chunk_memory_alloc(unit, xlate_mem, mem_buf[0]); 1026 if (BCM_FAILURE(rv) || (NULL == vlan_xlate_buf)) { 1027 goto cleanup; 1028 } 1029 1030 mem_buf[0] = &egr_vlan_xlate_buf; 1031 rv = _bcm_chunk_memory_alloc(unit, egr_xlate_mem, mem_buf[0]); 1032 if (BCM_FAILURE(rv) || (NULL == egr_vlan_xlate_buf)) { 1033 goto cleanup; 1034 } 1035 1036 mem_buf[0] = &source_vp_buf; 1037 rv = _bcm_chunk_memory_alloc(unit, SOURCE_VPm, mem_buf[0]); 1038 if (BCM_FAILURE(rv) || (NULL == source_vp_buf)) { 1039 goto cleanup; 1040 } 1041 1042 mem_buf[0] = &source_trunk_map_buf; 1043 rv = _bcm_chunk_memory_alloc(unit, SOURCE_TRUNK_MAP_TABLEm, mem_buf[0]); 1044 if (BCM_FAILURE(rv) || (NULL == source_trunk_map_buf)) { 1045 goto cleanup; 1046 } 1047 1048 1049 /* Get all valid VFIs (VPNs) */ 1050 index_min = soc_mem_index_min(unit, mpls_mem); 1051 index_max = soc_mem_index_max(unit, mpls_mem); 1052 for (i = index_min; i <= index_max; i++) { 1053 mem_entry[0] = &mpls_entry; 1054 rv = _bcm_chunk_get_mem_entry(unit, mpls_mem, i , 1055 mpls_entry_buf, mem_entry[0]); 1056 if (BCM_FAILURE(rv) || (NULL == mpls_entry)) { 1057 goto cleanup; 1058 } 1059 1060 #if defined(BCM_TRIUMPH3_SUPPORT) 1061 if (SOC_IS_TRIUMPH3(unit)) { 1062 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, VALID_0f) == 0 1063 && soc_mem_field32_get(unit, mpls_mem, mpls_entry, VALID_1f) == 0) { 1064 continue; 1065 } 1066 1067 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, KEY_TYPE_0f) 1068 != isid_key_type) { 1069 /* MIM_ISID */ 1070 continue; 1071 } 1072 } else 1073 #endif /* BCM_TRIUMPH3_SUPPORT */ 1074 { 1075 #if defined(BCM_TRIDENT3_SUPPORT) 1076 if (soc_feature(unit, soc_feature_base_valid)) { 1077 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, BASE_VALID_0f) != 3) { 1078 continue; 1079 } 1080 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, BASE_VALID_1f) != 7) { 1081 continue; 1082 } 1083 } else 1084 #endif 1085 { 1086 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, VALIDf) == 0) { 1087 continue; 1088 } 1089 } 1090 1091 #if defined(BCM_TRIDENT_SUPPORT) 1092 if (soc_feature(unit, soc_feature_mim_peer_sharing) && 1093 (soc_mem_field32_get(unit, mpls_mem, 1094 mpls_entry, KEY_TYPEf) == 0x3)) { 1095 /* MIM_ISID_SVP */ 1096 vp = soc_mem_field32_get(unit, mpls_mem, 1097 mpls_entry, MIM_ISID__SVPf); 1098 MIM_INFO(unit)->port_info[vp].vfi_count++; 1099 continue; 1100 } 1101 #endif /* BCM_TRIDENT_SUPPORT */ 1102 1103 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, KEY_TYPEf) 1104 != isid_key_type) { 1105 /* MIM_ISID */ 1106 continue; 1107 } 1108 } 1109 vfi = soc_mem_field32_get(unit, mpls_mem, mpls_entry, MIM_ISID__VFIf); 1110 isid = soc_mem_field32_get(unit, mpls_mem, mpls_entry, MIM_ISID__ISIDf); 1111 if ((stable_size == 0) || SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 1112 rv = _bcm_vfi_alloc_with_id(unit, VFIm, _bcmVfiTypeMim, vfi); 1113 if (BCM_FAILURE(rv)) { 1114 goto cleanup; 1115 } 1116 } else { 1117 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 1118 /* VFI bitmap is recovered by virtual_init */ 1119 continue; 1120 } 1121 } 1122 VPN_ISID(unit, vfi) = isid; 1123 1124 #if defined(BCM_TRIDENT3_SUPPORT) 1125 if (SOC_MEM_FIELD_VALID(unit, VFIm, SD_TAG_MODEf)) { 1126 vfi_mem = VFIm; 1127 vfi_1_mem = VFI_ATTRS_1m; 1128 } else 1129 #endif 1130 { 1131 vfi_mem = VFI_1m; 1132 vfi_1_mem = VFI_1m; 1133 } 1134 /* Retrieve TPID reference counts if applicable */ 1135 rv = soc_mem_read(unit, vfi_mem, 1136 MEM_BLOCK_ANY, vfi, vfi_entry); 1137 if (BCM_FAILURE(rv)) { 1138 goto cleanup; 1139 } 1140 1141 rv = soc_mem_read(unit, vfi_1_mem, 1142 MEM_BLOCK_ANY, vfi, vfi_1_entry); 1143 if (BCM_FAILURE(rv)) { 1144 goto cleanup; 1145 } 1146 1147 if (soc_mem_field32_get(unit, vfi_mem, vfi_entry, SD_TAG_MODEf) == 1) { 1148 tpid_enable = soc_mem_field32_get(unit, vfi_1_mem, vfi_1_entry, 1149 TPID_ENABLEf); 1150 for (index = 0; index < 4; index++) { 1151 if (tpid_enable & (1 << index)) { 1152 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1); 1153 break; 1154 } 1155 } 1156 } 1157 /* Retrieve flex stats for the VFI */ 1158 rv = READ_VFIm(unit, MEM_BLOCK_ANY, vfi, vfi_entry); 1159 if (BCM_FAILURE(rv)) { 1160 goto cleanup; 1161 } 1162 _bcm_tr2_mim_vpn_flex_stat_recover(unit, (void *)vfi_entry, vfi); 1163 } 1164 1165 /* Get all virtual ports from VLAN_XLATE */ 1166 index_min = soc_mem_index_min(unit, xlate_mem); 1167 index_max = soc_mem_index_max(unit, xlate_mem); 1168 for (i = index_min; i <= index_max; i++) { 1169 mem_entry[0] = &vlan_xlate; 1170 rv = _bcm_chunk_get_mem_entry(unit, xlate_mem, i , 1171 vlan_xlate_buf, mem_entry[0]); 1172 if (BCM_FAILURE(rv) || (NULL == vlan_xlate)) { 1173 goto cleanup; 1174 } 1175 1176 #if defined(BCM_TRIUMPH3_SUPPORT) 1177 if (SOC_IS_TRIUMPH3(unit)) { 1178 if (soc_mem_field32_get(unit, xlate_mem, vlan_xlate, VALID_0f) && 1179 soc_mem_field32_get(unit, xlate_mem, vlan_xlate, VALID_1f) == 0) { 1180 continue; 1181 } 1182 } else 1183 #endif /* BCM_TRIUMPH3_SUPPORT */ 1184 { 1185 #if defined(BCM_TRIDENT3_SUPPORT) 1186 if (soc_feature(unit, soc_feature_base_valid)) { 1187 if (soc_mem_field32_get(unit, xlate_mem, 1188 vlan_xlate, BASE_VALID_0f) != 3) { 1189 continue; 1190 } 1191 if (soc_mem_field32_get(unit, xlate_mem, 1192 vlan_xlate, BASE_VALID_1f) != 7) { 1193 continue; 1194 } 1195 } else 1196 #endif 1197 { 1198 if (soc_mem_field32_get(unit, xlate_mem, 1199 vlan_xlate, VALIDf) == 0) { 1200 continue; 1201 } 1202 } 1203 } 1204 1205 if (soc_mem_field32_get(unit, xlate_mem, vlan_xlate, MPLS_ACTIONf) != 1) { 1206 continue; /* Entry is not for an SVP */ 1207 } 1208 1209 #if defined(BCM_TRIUMPH3_SUPPORT) 1210 if (SOC_IS_TRIUMPH3(unit)) { 1211 key_type = soc_mem_field32_get(unit, xlate_mem, vlan_xlate, 1212 KEY_TYPE_0f); 1213 if ((key_type != TR3_VLXLT_X_HASH_KEY_TYPE_OVID) && 1214 (key_type != TR3_VLXLT_X_HASH_KEY_TYPE_IVID_OVID)) { 1215 continue; 1216 } 1217 } else 1218 #endif /* BCM_TRIUMPH3_SUPPORT */ 1219 { 1220 key_type = soc_mem_field32_get(unit, xlate_mem, vlan_xlate, 1221 KEY_TYPEf); 1222 if ((key_type != TR_VLXLT_HASH_KEY_TYPE_OVID) && 1223 (key_type != TR_VLXLT_HASH_KEY_TYPE_IVID_OVID)) { 1224 continue; 1225 } 1226 } 1227 1228 vp = soc_mem_field32_get(unit, xlate_mem, vlan_xlate, SOURCE_VPf); 1229 if ((stable_size == 0) || SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 1230 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 1231 rv = _bcm_vp_used_set(unit, vp, vp_info); 1232 if (BCM_FAILURE(rv)) { 1233 goto cleanup; 1234 } 1235 } else { 1236 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 1237 /* VFI bitmap is recovered by virtual_init */ 1238 continue; 1239 } 1240 } 1241 switch (key_type) { 1242 case TR_VLXLT_HASH_KEY_TYPE_OVID: 1243 #if defined(BCM_TRIUMPH3_SUPPORT) 1244 case TR3_VLXLT_X_HASH_KEY_TYPE_OVID: 1245 #endif /* BCM_TRIUMPH3_SUPPORT */ 1246 1247 MIM_INFO(unit)->port_info[vp].flags |= 1248 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN; 1249 MIM_INFO(unit)->port_info[vp].match_vlan = 1250 soc_mem_field32_get(unit, xlate_mem, vlan_xlate, OVIDf); 1251 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 1252 break; 1253 case TR_VLXLT_HASH_KEY_TYPE_IVID_OVID: 1254 #if defined(BCM_TRIUMPH3_SUPPORT) 1255 case TR3_VLXLT_X_HASH_KEY_TYPE_IVID_OVID: 1256 #endif /* BCM_TRIUMPH3_SUPPORT */ 1257 1258 MIM_INFO(unit)->port_info[vp].flags |= 1259 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED; 1260 MIM_INFO(unit)->port_info[vp].match_vlan = 1261 soc_mem_field32_get(unit, xlate_mem, vlan_xlate, OVIDf); 1262 MIM_INFO(unit)->port_info[vp].match_inner_vlan = 1263 soc_mem_field32_get(unit, xlate_mem, vlan_xlate, IVIDf); 1264 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 1265 break; 1266 /* coverity[dead_error_begin] */ 1267 default: 1268 break; /* Should never happen */ 1269 } 1270 /* Recover TPID reference counts */ 1271 mem_entry[0] = &source_vp; 1272 rv = _bcm_chunk_get_mem_entry(unit, SOURCE_VPm, vp , 1273 source_vp_buf, mem_entry[0]); 1274 if (BCM_FAILURE(rv) || (NULL == source_vp)) { 1275 goto cleanup; 1276 } 1277 1278 rv = _bcm_tr2_mim_source_vp_tpid_recover(unit, source_vp, vp); 1279 if (BCM_FAILURE(rv)) { 1280 goto cleanup; 1281 } 1282 /* Recover port flex stats */ 1283 _bcm_tr2_mim_port_flex_stat_recover(unit, source_vp, vp); 1284 /* Recover other port data */ 1285 rv = _bcm_tr2_mim_port_associated_data_recover(unit, vp, stable_size); 1286 if (BCM_FAILURE(rv)) { 1287 goto cleanup; 1288 } 1289 } 1290 1291 /* Get all virtual ports from MPLS_ENTRY */ 1292 index_min = soc_mem_index_min(unit, mpls_mem); 1293 index_max = soc_mem_index_max(unit, mpls_mem); 1294 for (i = index_min; i <= index_max; i++) { 1295 mem_entry[0] = &mpls_entry; 1296 rv = _bcm_chunk_get_mem_entry(unit, mpls_mem, i , 1297 mpls_entry_buf, mem_entry[0]); 1298 if (BCM_FAILURE(rv) || (NULL == mpls_entry)) { 1299 goto cleanup; 1300 } 1301 1302 #if defined(BCM_TRIUMPH3_SUPPORT) 1303 if (SOC_IS_TRIUMPH3(unit)) { 1304 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, VALID_0f) == 0 1305 && soc_mem_field32_get(unit, mpls_mem, mpls_entry, VALID_1f) == 0) { 1306 continue; 1307 } 1308 key_type = soc_mem_field32_get(unit, mpls_mem, mpls_entry, 1309 KEY_TYPE_0f); 1310 } else 1311 #endif /* BCM_TRIUMPH3_SUPPORT */ 1312 { 1313 #if defined(BCM_TRIDENT3_SUPPORT) 1314 if (soc_feature(unit, soc_feature_base_valid)) { 1315 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, BASE_VALID_0f) != 3) { 1316 continue; 1317 } 1318 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, BASE_VALID_1f) != 7) { 1319 continue; 1320 } 1321 } else 1322 #endif 1323 { 1324 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, VALIDf) == 0) { 1325 continue; 1326 } 1327 } 1328 key_type = soc_mem_field32_get(unit, mpls_mem, mpls_entry, 1329 KEY_TYPEf); 1330 } 1331 1332 if ((soc_mem_field32_get(unit, mpls_mem, mpls_entry, MPLS_ACTION_IF_BOSf) 1333 != 1) && (key_type == 0)) { 1334 continue; /* Not an SVP */ 1335 } 1336 switch (key_type) { 1337 case 0: /* MPLS Label */ 1338 #if defined(BCM_TRIUMPH3_SUPPORT) 1339 case 17: 1340 case 19: 1341 #endif /* BCM_TRIUMPH3_SUPPORT */ 1342 vp = soc_mem_field32_get(unit, mpls_mem, mpls_entry, SOURCE_VPf); 1343 if ((stable_size == 0) || SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 1344 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 1345 rv = _bcm_vp_used_set(unit, vp, vp_info); 1346 if (BCM_FAILURE(rv)) { 1347 goto cleanup; 1348 } 1349 } else { 1350 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 1351 /* VFI bitmap is recovered by virtual_init */ 1352 continue; 1353 } 1354 } 1355 MIM_INFO(unit)->port_info[vp].flags |= 1356 _BCM_MIM_PORT_TYPE_ACCESS_LABEL; 1357 MIM_INFO(unit)->port_info[vp].match_label = 1358 soc_mem_field32_get(unit, mpls_mem, mpls_entry, MPLS_LABELf); 1359 break; 1360 case 1: /* MIM NVP */ 1361 #if defined(BCM_TRIUMPH3_SUPPORT) 1362 case 23: 1363 #endif /* BCM_TRIUMPH3_SUPPORT */ 1364 vp = soc_mem_field32_get(unit, mpls_mem, mpls_entry, MIM_NVP__SVPf); 1365 if ((stable_size != 0) && !SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 1366 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 1367 /* VFI bitmap is recovered by virtual_init */ 1368 continue; 1369 } 1370 } 1371 soc_mem_mac_addr_get(unit, mpls_mem, mpls_entry, MIM_NVP__BMACSAf, 1372 MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac); 1373 MIM_INFO(unit)->port_info[vp].match_tunnel_vlan = 1374 soc_mem_field32_get(unit, mpls_mem, mpls_entry, MIM_NVP__BVIDf); 1375 1376 if (SOC_MEM_FIELD_VALID(unit, mpls_mem, MIM_NVP__ISID_LOOKUP_TYPEf)) { 1377 if (soc_mem_field32_get(unit, mpls_mem, mpls_entry, 1378 MIM_NVP__ISID_LOOKUP_TYPEf)) { 1379 MIM_INFO(unit)->port_info[vp].flags |= _BCM_MIM_PORT_TYPE_PEER; 1380 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 1381 } else { 1382 MIM_INFO(unit)->port_info[vp].flags |= 1383 _BCM_MIM_PORT_TYPE_NETWORK; 1384 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 1385 } 1386 } 1387 rv = _bcm_vp_used_set(unit, vp, vp_info); 1388 if (BCM_FAILURE(rv)) { 1389 goto cleanup; 1390 } 1391 break; 1392 default: 1393 continue; /* Handled elsewhere */ 1394 } 1395 /* Recover TPID reference counts */ 1396 mem_entry[0] = &source_vp; 1397 rv = _bcm_chunk_get_mem_entry(unit, SOURCE_VPm, vp , 1398 source_vp_buf, mem_entry[0]); 1399 if (BCM_FAILURE(rv) || (NULL == source_vp)) { 1400 goto cleanup; 1401 } 1402 1403 rv = _bcm_tr2_mim_source_vp_tpid_recover(unit, source_vp, vp); 1404 if (BCM_FAILURE(rv)) { 1405 goto cleanup; 1406 } 1407 /* Recover port flex stats */ 1408 _bcm_tr2_mim_port_flex_stat_recover(unit, source_vp, vp); 1409 /* Recover other port data */ 1410 rv = _bcm_tr2_mim_port_associated_data_recover(unit, vp, stable_size); 1411 if (BCM_FAILURE(rv)) { 1412 goto cleanup; 1413 } 1414 } 1415 1416 /* Get all virtual ports from SOURCE_TRUNK_MAP */ 1417 index_min = soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm); 1418 index_max = soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm); 1419 for (i = index_min; i <= index_max; i++) { 1420 bcm_module_t modid; 1421 bcm_port_t port; 1422 bcm_trunk_t tgid; 1423 mem_entry[0] = &source_trunk_map; 1424 rv = _bcm_chunk_get_mem_entry(unit, SOURCE_TRUNK_MAP_TABLEm, i , 1425 source_trunk_map_buf, mem_entry[0]); 1426 if (BCM_FAILURE(rv) || (NULL == source_trunk_map)) { 1427 goto cleanup; 1428 } 1429 1430 vp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, source_trunk_map, 1431 SOURCE_VPf); 1432 if (vp == 0) { 1433 continue; 1434 } 1435 /* If VP has already been discovered, no need to proceed further */ 1436 /* This can happen for the trunk access case */ 1437 if (MIM_INFO(unit)->port_info[vp].flags != 0) { 1438 continue; 1439 } 1440 if ((stable_size == 0) || SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 1441 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 1442 rv = _bcm_vp_used_set(unit, vp, vp_info); 1443 if (BCM_FAILURE(rv)) { 1444 goto cleanup; 1445 } 1446 } else { 1447 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 1448 /* VFI bitmap is recovered by virtual_init */ 1449 continue; 1450 } 1451 } 1452 if (soc_feature(unit, soc_feature_vp_lag)) { 1453 modid = SOC_IS_ENDURO(unit) ? i / 64 : i / SOC_PORT_ADDR_MAX(unit); 1454 port = SOC_IS_ENDURO(unit) ? i % 64 : i % SOC_PORT_ADDR_MAX(unit); 1455 rv = _bcm_esw_trunk_port_property_get(unit, modid, port, &tgid); 1456 if (BCM_FAILURE(rv) && (tgid != -1)) { 1457 goto cleanup; 1458 } 1459 if (tgid == -1) { 1460 MIM_INFO(unit)->port_info[vp].flags |= 1461 _BCM_MIM_PORT_TYPE_ACCESS_PORT; 1462 MIM_INFO(unit)->port_info[vp].index = i; 1463 } else { 1464 MIM_INFO(unit)->port_info[vp].flags |= 1465 _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK; 1466 MIM_INFO(unit)->port_info[vp].index = tgid; 1467 } 1468 /* Recover TPID reference counts */ 1469 mem_entry[0] = &source_vp; 1470 rv = _bcm_chunk_get_mem_entry(unit, SOURCE_VPm, vp , 1471 source_vp_buf, mem_entry[0]); 1472 if (BCM_FAILURE(rv) || (NULL == source_vp)) { 1473 goto cleanup; 1474 } 1475 1476 rv = _bcm_tr2_mim_source_vp_tpid_recover(unit, source_vp, vp); 1477 if (BCM_FAILURE(rv)) { 1478 goto cleanup; 1479 } 1480 } 1481 /* Recover port flex stats */ 1482 _bcm_tr2_mim_port_flex_stat_recover(unit, source_vp, vp); 1483 /* Recover other port data */ 1484 rv = _bcm_tr2_mim_port_associated_data_recover(unit, vp, stable_size); 1485 if (BCM_FAILURE(rv)) { 1486 goto cleanup; 1487 } 1488 } 1489 1490 /* Recover TPID reference counts from EGR_VLAN_XLATE */ 1491 index_min = soc_mem_index_min(unit, egr_xlate_mem); 1492 index_max = soc_mem_index_max(unit, egr_xlate_mem); 1493 for (i = index_min; i <= index_max; i++) { 1494 mem_entry[0] = &egr_vlan_xlate; 1495 rv = _bcm_chunk_get_mem_entry(unit, egr_xlate_mem, i , 1496 egr_vlan_xlate_buf, mem_entry[0]); 1497 if (BCM_FAILURE(rv) || (NULL == egr_vlan_xlate)) { 1498 goto cleanup; 1499 } 1500 #if defined(BCM_TRIDENT3_SUPPORT) 1501 if (soc_feature(unit, soc_feature_base_valid)) { 1502 if (soc_mem_field32_get(unit, egr_xlate_mem, 1503 egr_vlan_xlate, BASE_VALID_0f) != 3) { 1504 continue; 1505 } 1506 if (soc_mem_field32_get(unit, egr_xlate_mem, 1507 egr_vlan_xlate, BASE_VALID_1f) != 7) { 1508 continue; 1509 } 1510 } else 1511 #endif 1512 { 1513 if (soc_mem_field32_get(unit, egr_xlate_mem, 1514 egr_vlan_xlate, VALIDf) == 0) { 1515 continue; 1516 } 1517 } 1518 #if defined(BCM_TRIUMPH3_SUPPORT) 1519 if (SOC_IS_TRIUMPH3(unit)) { 1520 if (soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate, 1521 KEY_TYPEf) != 3) { 1522 continue; /* Not MIM_ISID_DVP */ 1523 } 1524 } else 1525 #endif /* BCM_TRIUMPH3_SUPPORT */ 1526 { 1527 #if defined(BCM_TRIDENT3_SUPPORT) 1528 if (soc_feature(unit, soc_feature_base_valid)) { 1529 if (soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate, 1530 DATA_TYPEf) != 4) { 1531 continue; /* Not ISID_DVP_XLATE */ 1532 } 1533 } else 1534 #endif 1535 { 1536 if (soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate, 1537 ENTRY_TYPEf) != 4) { 1538 continue; /* Not ISID_DVP_XLATE */ 1539 } 1540 } 1541 1542 } 1543 rv = _bcm_tr2_mim_egr_vxlt_tpid_recover(unit, egr_vlan_xlate); 1544 if (BCM_FAILURE(rv)) { 1545 goto cleanup; 1546 } 1547 } 1548 1549 /* Recover L2 scache */ 1550 rv = _bcm_tr2_mim_wb_recover(unit); 1551 1552 cleanup: 1553 if (mpls_entry_buf) { 1554 soc_cm_sfree(unit, mpls_entry_buf); 1555 } 1556 if (vlan_xlate_buf) { 1557 soc_cm_sfree(unit, vlan_xlate_buf); 1558 } 1559 if (egr_vlan_xlate_buf) { 1560 soc_cm_sfree(unit, egr_vlan_xlate_buf); 1561 } 1562 if (source_vp_buf) { 1563 soc_cm_sfree(unit, source_vp_buf); 1564 } 1565 if (source_trunk_map_buf) { 1566 soc_cm_sfree(unit, source_trunk_map_buf); 1567 } 1568 return rv; 1569 } 1570 1571 #endif /* BCM_WARM_BOOT_SUPPORT */ 1572 1573 /* 1574 * Function: 1575 * bcm_mim_init 1576 * Purpose: 1577 * Initialize the MIM software module 1578 * Parameters: 1579 * unit - Device Number 1580 * Returns: 1581 * BCM_E_XXX 1582 */ 1583 int 1584 bcm_tr2_mim_init(int unit) 1585 { 1586 int num_vfi, num_vp, num_intf, rv = BCM_E_NONE; 1587 _bcm_tr2_mim_bookkeeping_t *mim_info = MIM_INFO(unit); 1588 1589 1590 if (!L3_INFO(unit)->l3_initialized) { 1591 LOG_INFO(BSL_LS_BCM_L3, 1592 (BSL_META_U(unit, 1593 "L3 module must be initialized first\n"))); 1594 return BCM_E_NONE; 1595 } 1596 1597 1598 1599 if (mim_initialized[unit]) { 1600 BCM_IF_ERROR_RETURN(bcm_tr2_mim_detach(unit)); 1601 } 1602 num_vfi = soc_mem_index_count(unit, VFIm); 1603 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 1604 num_intf = soc_mem_index_count(unit, EGR_L3_INTFm); 1605 1606 sal_memset(mim_info, 0, sizeof(_bcm_tr2_mim_bookkeeping_t)); 1607 1608 if (mim_info->vpn_info == NULL) { 1609 mim_info->vpn_info = sal_alloc(sizeof(_bcm_tr2_vpn_info_t) 1610 * num_vfi, "mim_vpn_info"); 1611 if (mim_info->vpn_info == NULL) { 1612 _bcm_tr2_mim_free_resources(unit); 1613 return BCM_E_MEMORY; 1614 } 1615 } 1616 sal_memset(mim_info->vpn_info, 0, sizeof(_bcm_tr2_vpn_info_t) * num_vfi); 1617 1618 if (mim_info->port_info == NULL) { 1619 mim_info->port_info = sal_alloc(sizeof(_bcm_tr2_mim_port_info_t) 1620 * num_vp, "mim_port_info"); 1621 if (mim_info->port_info == NULL) { 1622 _bcm_tr2_mim_free_resources(unit); 1623 return BCM_E_MEMORY; 1624 } 1625 } 1626 sal_memset(mim_info->port_info, 0, sizeof(_bcm_tr2_mim_port_info_t) * num_vp); 1627 1628 if (_mim_mutex[unit] == NULL) { 1629 _mim_mutex[unit] = sal_mutex_create("mim mutex"); 1630 if (_mim_mutex[unit] == NULL) { 1631 _bcm_tr2_mim_free_resources(unit); 1632 return BCM_E_MEMORY; 1633 } 1634 } 1635 1636 if (NULL == mim_info->intf_bitmap) { 1637 mim_info->intf_bitmap = 1638 sal_alloc(SHR_BITALLOCSIZE(num_intf), "intf_bitmap"); 1639 if (mim_info->intf_bitmap == NULL) { 1640 _bcm_tr2_mim_free_resources(unit); 1641 return BCM_E_MEMORY; 1642 } 1643 } 1644 sal_memset(mim_info->intf_bitmap, 0, SHR_BITALLOCSIZE(num_intf)); 1645 1646 #ifdef BCM_WARM_BOOT_SUPPORT 1647 if (SOC_WARM_BOOT(unit)) { 1648 /* Warm Boot recovery */ 1649 rv = _bcm_tr2_mim_reinit(unit); 1650 } else { 1651 rv = _bcm_tr2_mim_wb_alloc(unit); 1652 } 1653 1654 if (BCM_FAILURE(rv)) { 1655 _bcm_tr2_mim_free_resources(unit); 1656 return rv; 1657 } 1658 #endif /* BCM_WARM_BOOT_SUPPORT */ 1659 1660 if(!SOC_WARM_BOOT(unit)) { 1661 /* Enable MiM */ 1662 rv = bcm_tr2_mim_enable(unit, TRUE); 1663 if (BCM_FAILURE(rv)) { 1664 _bcm_tr2_mim_free_resources(unit); 1665 return rv; 1666 } 1667 } 1668 1669 mim_initialized[unit] = TRUE; 1670 return rv; 1671 } 1672 1673 /* 1674 * Function: 1675 * bcm_mim_vpn_create 1676 * Purpose: 1677 * Create a VPN instance 1678 * Parameters: 1679 * unit - (IN) Device Number 1680 * info - (IN/OUT) VPN configuration info 1681 * Returns: 1682 * BCM_E_XXX 1683 */ 1684 int 1685 bcm_tr2_mim_vpn_create(int unit, bcm_mim_vpn_config_t *info) 1686 { 1687 int index, rv = BCM_E_PARAM; 1688 vfi_entry_t vfi_entry; 1689 vfi_1_entry_t vfi_1_entry; 1690 uint32 mpls_entry[SOC_MAX_MEM_WORDS] = {0}; 1691 bcm_mim_vpn_config_t old_info; 1692 uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS]; 1693 int vfi, bc_group = 0, umc_group = 0, uuc_group = 0, num_vfi; 1694 int bc_group_type, umc_group_type, uuc_group_type; 1695 soc_mem_t mpls_mem = MPLS_ENTRYm; 1696 bcm_vpn_t mim_vpn_min=0; 1697 int hw_idx; 1698 int proto_pkt_idx; 1699 soc_mem_t egr_xlate_mem; 1700 #if defined(BCM_TRIDENT3_SUPPORT) 1701 uint32 vfi_attrs_1_entry[SOC_MAX_MEM_WORDS] = {0}; 1702 #endif 1703 1704 MIM_INIT(unit); 1705 1706 num_vfi = soc_mem_index_count(unit, VFIm); 1707 1708 bcm_mim_vpn_config_t_init(&old_info); 1709 1710 #if defined(BCM_TRIDENT3_SUPPORT) 1711 if (soc_feature(unit, soc_feature_base_valid)) { 1712 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 1713 } else 1714 #endif 1715 { 1716 egr_xlate_mem = EGR_VLAN_XLATEm; 1717 } 1718 1719 /* For Point-to_point service, multicast groups are not valid */ 1720 if (info->flags & BCM_MIM_VPN_ELINE) { 1721 1722 /* For point-to-point vpn groups are not valid */ 1723 if ((info->broadcast_group != 0) || 1724 (info->unknown_unicast_group != 0) || 1725 (info->unknown_multicast_group != 0)){ 1726 return BCM_E_PARAM; 1727 } 1728 1729 } else { 1730 1731 /* Check that the groups are valid. */ 1732 1733 bc_group_type = _BCM_MULTICAST_TYPE_GET(info->broadcast_group); 1734 bc_group = _BCM_MULTICAST_ID_GET(info->broadcast_group); 1735 umc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_multicast_group); 1736 umc_group = _BCM_MULTICAST_ID_GET(info->unknown_multicast_group); 1737 uuc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_unicast_group); 1738 uuc_group = _BCM_MULTICAST_ID_GET(info->unknown_unicast_group); 1739 1740 if ((bc_group_type != _BCM_MULTICAST_TYPE_MIM) || 1741 (umc_group_type != _BCM_MULTICAST_TYPE_MIM) || 1742 (uuc_group_type != _BCM_MULTICAST_TYPE_MIM) || 1743 (bc_group >= soc_mem_index_count(unit, L3_IPMCm)) || 1744 (umc_group >= soc_mem_index_count(unit, L3_IPMCm)) || 1745 (uuc_group >= soc_mem_index_count(unit, L3_IPMCm))) { 1746 return BCM_E_PARAM; 1747 } 1748 } 1749 /* validate parameter protocol_pkt */ 1750 if (SOC_MEM_FIELD_VALID(unit, VFIm, PROTOCOL_PKT_INDEXf)) { 1751 rv = _bcm_xgs3_protocol_packet_actions_validate(unit, 1752 &info->protocol_pkt); 1753 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 1754 return rv; 1755 } 1756 } 1757 /* Validate lookup id value */ 1758 #if defined(BCM_TRIUMPH3_SUPPORT) 1759 if (SOC_IS_TRIUMPH3(unit)) { 1760 mpls_mem = MPLS_ENTRY_EXTDm; 1761 } else 1762 #endif /* BCM_TRIUMPH3_SUPPORT */ 1763 { 1764 mpls_mem = MPLS_ENTRYm; 1765 } 1766 1767 if ( info->lookup_id >= 0 ) { 1768 /* coverity[large_shift : FALSE] */ 1769 if (!SOC_MEM_FIELD32_VALUE_FIT(unit, mpls_mem, MIM_ISID__ISIDf, 1770 info->lookup_id)) { 1771 LOG_WARN(BSL_LS_BCM_MIM, 1772 (BSL_META_U(unit, 1773 "lookup_id value exceeds 0x%x \n"), 1774 SOC_MEM_FIELD32_VALUE_MAX(unit, mpls_mem, MIM_ISID__ISIDf))); 1775 return BCM_E_PARAM; 1776 } 1777 } 1778 1779 1780 MIM_LOCK(unit); 1781 if (info->flags & BCM_MIM_VPN_WITH_ID) { 1782 _BCM_MIM_VPN_SET(mim_vpn_min, _BCM_MIM_VPN_TYPE_MIM, 0); 1783 if (info->vpn < mim_vpn_min || 1784 info->vpn > (mim_vpn_min + num_vfi - 1) ) { 1785 MIM_UNLOCK(unit); 1786 return BCM_E_PARAM; 1787 } 1788 1789 /* Check if VFI exists and handle the replace case */ 1790 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, info->vpn); 1791 if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 1792 if ((info->flags & BCM_MIM_VPN_REPLACE)) { 1793 1794 /* do not allow P2P -> P2M or P2M -> P2P */ 1795 /* Read the VFI table to check if point-to-point vpn */ 1796 sal_memset(&vfi_entry, 0, sizeof(vfi_entry_t)); 1797 rv = READ_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry); 1798 if (BCM_FAILURE(rv)) { 1799 MIM_UNLOCK(unit); 1800 return rv; 1801 } 1802 1803 /* ELINE */ 1804 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 1805 if (!(info->flags & BCM_MIM_VPN_ELINE)) { 1806 MIM_UNLOCK(unit); 1807 return BCM_E_PARAM; 1808 } 1809 } else { /* ELAN */ 1810 if (!(info->flags & BCM_MIM_VPN_MIM)) { 1811 MIM_UNLOCK(unit); 1812 return BCM_E_PARAM; 1813 } 1814 } 1815 1816 /* Get old ISID lookup id to delete from mpls and xlate table */ 1817 rv = bcm_tr2_mim_vpn_get( unit, info->vpn, &old_info); 1818 if (BCM_FAILURE(rv)) { 1819 MIM_UNLOCK(unit); 1820 return rv; 1821 } 1822 } else { 1823 MIM_UNLOCK(unit); 1824 return BCM_E_EXISTS; 1825 } 1826 } else { 1827 rv = _bcm_vfi_alloc_with_id(unit, VFIm, _bcmVfiTypeMim, vfi); 1828 if (rv < 0) { 1829 MIM_UNLOCK(unit); 1830 return rv; 1831 } 1832 } 1833 } else { 1834 /* Allocate a free VFI entry */ 1835 rv = _bcm_vfi_alloc(unit, VFIm, _bcmVfiTypeMim, &vfi); 1836 if (rv < 0) { 1837 MIM_UNLOCK(unit); 1838 return rv; 1839 } 1840 } 1841 VPN_ISID(unit, vfi) = info->lookup_id; 1842 1843 /* Commit the VFI entry to HW */ 1844 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry)); 1845 if (!(info->flags & BCM_MIM_VPN_ELINE)) { 1846 #if defined(BCM_TRIDENT3_SUPPORT) 1847 if (soc_feature(unit, soc_feature_generic_dest)) { 1848 soc_mem_field32_dest_set(unit, VFIm, &vfi_entry, 1849 UMC_DESTINATIONf, SOC_MEM_FIF_DEST_IPMC, umc_group); 1850 soc_mem_field32_dest_set(unit, VFIm, &vfi_entry, 1851 UUC_DESTINATIONf, SOC_MEM_FIF_DEST_IPMC, uuc_group); 1852 soc_mem_field32_dest_set(unit, VFIm, &vfi_entry, 1853 BC_DESTINATIONf, SOC_MEM_FIF_DEST_IPMC, bc_group); 1854 } else 1855 #endif 1856 { 1857 soc_VFIm_field32_set(unit, &vfi_entry, UMC_INDEXf, umc_group); 1858 soc_VFIm_field32_set(unit, &vfi_entry, UUC_INDEXf, uuc_group); 1859 soc_VFIm_field32_set(unit, &vfi_entry, BC_INDEXf, bc_group); 1860 } 1861 #if defined(BCM_TRIDENT3_SUPPORT) 1862 if (SOC_IS_TRIDENT3X(unit)) { 1863 uint32 profile_idx = 0; 1864 rv = _bcm_td3_def_vfi_profile_add(unit, 1865 info->flags & BCM_MIM_VPN_ELINE, &profile_idx); 1866 if (BCM_E_NONE == rv) { 1867 soc_VFIm_field32_set(unit, &vfi_entry, VFI_PROFILE_PTRf, profile_idx); 1868 } 1869 } 1870 #endif 1871 } 1872 1873 /* If ELINE service set the PT2PT field */ 1874 if (info->flags & BCM_MIM_VPN_ELINE) { 1875 soc_VFIm_field32_set(unit, &vfi_entry, PT2PT_ENf, 0x1); 1876 } 1877 1878 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 1879 defined(BCM_APACHE_SUPPORT) 1880 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_APACHE(unit)) { 1881 rv = _bcm_esw_add_policer_to_table(unit, info->policer_id, VFIm, 0, 1882 &vfi_entry); 1883 if (rv < 0) { 1884 MIM_UNLOCK(unit); 1885 return rv; 1886 } 1887 } 1888 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT or BCM_APACHE_SUPPORT */ 1889 1890 if (info->flags & BCM_MIM_VPN_BVID_DROP_NOMATCH) { 1891 soc_VFIm_field32_set(unit, &vfi_entry, BVIDf, info->tunnel_vlan & 0xfff); 1892 } 1893 1894 if (info->flags & BCM_MIM_VPN_QOS_INGRESS_MAP_INT_PRIORITY) { 1895 rv = _bcm_tr2_qos_id2idx(unit, info->qos_map_id, &hw_idx); 1896 if (BCM_FAILURE(rv)) { 1897 MIM_UNLOCK(unit); 1898 return rv; 1899 } 1900 soc_mem_field32_set(unit, VFIm, &vfi_entry, TRUST_DOT1P_PTRf, hw_idx); 1901 1902 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit) || SOC_IS_TRIDENT2X(unit)) { 1903 soc_mem_field32_set(unit, VFIm, &vfi_entry, 1904 PHB2_USE_INNER_DOT1Pf, info->int_pri & 0x1); 1905 } else { 1906 soc_mem_field32_set(unit, VFIm, &vfi_entry, 1907 USE_INNER_PRIf, info->int_pri & 0x1); 1908 } 1909 } 1910 1911 if (info->flags & BCM_MIM_VPN_QOS_INGRESS_MAP_FIX_INT_PRIORITY) { 1912 /** index 1024 to 1040 are reserved for fixed priority mapping */ 1913 soc_mem_field32_set(unit, VFIm, &vfi_entry, 1914 TRUST_DOT1P_PTRf, info->int_pri + 16); 1915 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit) || SOC_IS_TRIDENT2X(unit)) { 1916 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_USE_INNER_DOT1Pf, 0); 1917 } else { 1918 soc_mem_field32_set(unit, VFIm, &vfi_entry, USE_INNER_PRIf, 0); 1919 } 1920 1921 if (SOC_IS_ENDURO(unit) || SOC_IS_TRIUMPH2(unit)) { 1922 /** set fix priority at location 1024 + fixed priority */ 1923 ing_pri_cng_map_entry_t imap; 1924 rv = READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, 1925 (1024 + info->int_pri), &imap); 1926 if (BCM_FAILURE(rv)) { 1927 MIM_UNLOCK(unit); 1928 return rv; 1929 } 1930 1931 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &imap, PRIf, info->int_pri); 1932 rv = WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, 1933 (1024 + info->int_pri), &imap); 1934 if (BCM_FAILURE(rv)) { 1935 MIM_UNLOCK(unit); 1936 return rv; 1937 } 1938 } 1939 } 1940 if (SOC_MEM_FIELD_VALID (unit,VFIm, PROTOCOL_PKT_INDEXf)) { 1941 if (info->flags & BCM_MIM_VPN_REPLACE) { 1942 proto_pkt_idx = soc_VFIm_field32_get(unit, &vfi_entry, 1943 PROTOCOL_PKT_INDEXf); 1944 } else { 1945 proto_pkt_idx = -1; 1946 } 1947 rv = _bcm_xgs3_protocol_pkt_ctrl_set(unit, proto_pkt_idx, 1948 &info->protocol_pkt, 1949 &proto_pkt_idx); 1950 if (BCM_SUCCESS(rv)) { 1951 soc_VFIm_field32_set(unit, &vfi_entry, PROTOCOL_PKT_INDEXf, 1952 proto_pkt_idx); 1953 } else if (rv != BCM_E_UNAVAIL) { 1954 return rv; 1955 } 1956 } 1957 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry); 1958 1959 if (rv < 0) { 1960 MIM_UNLOCK(unit); 1961 return rv; 1962 } 1963 1964 /* Check for incoming SD-tag match */ 1965 if (info->flags & BCM_MIM_VPN_MATCH_SERVICE_VLAN_TPID) { 1966 sal_memset(&vfi_1_entry, 0, sizeof(vfi_1_entry_t)); 1967 rv = _bcm_fb2_outer_tpid_entry_add(unit, info->match_service_tpid, &index); 1968 if (rv < 0) { 1969 MIM_UNLOCK(unit); 1970 return rv; 1971 } 1972 #if defined(BCM_TRIDENT3_SUPPORT) 1973 if (SOC_MEM_FIELD_VALID(unit, VFIm, SD_TAG_MODEf)) { 1974 rv = READ_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry); 1975 if (rv < 0) { 1976 MIM_UNLOCK(unit); 1977 return rv; 1978 } 1979 soc_VFIm_field32_set(unit, &vfi_entry, SD_TAG_MODEf, 1); 1980 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry); 1981 if (rv < 0) { 1982 MIM_UNLOCK(unit); 1983 return rv; 1984 } 1985 rv = READ_VFI_ATTRS_1m(unit, MEM_BLOCK_ALL, vfi, &vfi_attrs_1_entry); 1986 if (rv < 0) { 1987 MIM_UNLOCK(unit); 1988 return rv; 1989 } 1990 soc_VFI_ATTRS_1m_field32_set(unit, vfi_attrs_1_entry, TPID_ENABLEf, (1 << index)); 1991 rv = WRITE_VFI_ATTRS_1m(unit, MEM_BLOCK_ALL, vfi, &vfi_attrs_1_entry); 1992 if (rv < 0) { 1993 MIM_UNLOCK(unit); 1994 return rv; 1995 } 1996 } else 1997 #endif 1998 { 1999 soc_VFI_1m_field32_set(unit, &vfi_1_entry, SD_TAG_MODEf, 1); 2000 soc_VFI_1m_field32_set(unit, &vfi_1_entry, TPID_ENABLEf, (1 << index)); 2001 rv = WRITE_VFI_1m(unit, MEM_BLOCK_ALL, vfi, &vfi_1_entry); 2002 if (rv < 0) { 2003 MIM_UNLOCK(unit); 2004 return rv; 2005 } 2006 } 2007 } 2008 2009 if ( info->lookup_id >= 0 ) { 2010 /* Program the ISID to VFI mapping */ 2011 sal_memset(&mpls_entry, 0, sizeof(mpls_entry)); 2012 #if defined(BCM_TRIUMPH3_SUPPORT) 2013 if (SOC_IS_TRIUMPH3(unit)) { 2014 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPE_0f, 0x18); 2015 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPE_1f, 0x18); 2016 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALID_0f, 0x1); 2017 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALID_1f, 0x1); 2018 } else 2019 #endif /* BCM_TRIUMPH3_SUPPORT */ 2020 { 2021 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPEf, 0x2); 2022 #if defined(BCM_TRIDENT3_SUPPORT) 2023 if (soc_feature(unit, soc_feature_base_valid)) { 2024 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, BASE_VALID_0f, 3); 2025 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, BASE_VALID_1f, 7); 2026 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, DATA_TYPEf, 0x2); 2027 } else 2028 #endif 2029 { 2030 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALIDf, 0x1); 2031 } 2032 } 2033 /* key */ 2034 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__ISIDf, info->lookup_id); 2035 /* data */ 2036 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__VFIf, vfi); 2037 rv = soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, &index, 2038 &mpls_entry, &mpls_entry, 0); 2039 if (rv == SOC_E_NONE) { 2040 if ( (info->flags & BCM_MIM_VPN_REPLACE) && (info->lookup_id == old_info.lookup_id)) { 2041 /*replace with the same lookup_id*/ 2042 } else { 2043 _bcm_vfi_free(unit, _bcmVfiTypeMim, vfi); 2044 MIM_UNLOCK(unit); 2045 return BCM_E_EXISTS; 2046 } 2047 } else if (rv != SOC_E_NOT_FOUND) { 2048 _bcm_vfi_free(unit, _bcmVfiTypeMim, vfi); 2049 MIM_UNLOCK(unit); 2050 return rv; 2051 } 2052 2053 if ((info->flags & BCM_MIM_VPN_WITH_ID) && 2054 (info->flags & BCM_MIM_VPN_REPLACE) && 2055 (old_info.lookup_id >= 0)) { 2056 /* Delete old lookup ISID from mpls entry table*/ 2057 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__ISIDf, old_info.lookup_id); 2058 rv = soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ALL, &mpls_entry); 2059 if (BCM_FAILURE(rv)) { 2060 MIM_UNLOCK(unit); 2061 return rv; 2062 } 2063 } 2064 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__ISIDf, info->lookup_id); 2065 rv = soc_mem_insert(unit, mpls_mem, MEM_BLOCK_ALL, &mpls_entry); 2066 if (rv < 0) { 2067 if ((info->flags & BCM_MIM_VPN_WITH_ID) && 2068 (info->flags & BCM_MIM_VPN_REPLACE) && 2069 (old_info.lookup_id >= 0)) { 2070 /* Re-insert old lookup ISID into mpls entry table */ 2071 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__ISIDf, old_info.lookup_id); 2072 soc_mem_insert(unit, mpls_mem, MEM_BLOCK_ALL, &mpls_entry); 2073 } 2074 MIM_UNLOCK(unit); 2075 return rv; 2076 } 2077 2078 /* Program the VFI to ISID mapping */ 2079 sal_memset(egr_vlan_xlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2080 #if defined(BCM_TRIUMPH3_SUPPORT) 2081 if (SOC_IS_TRIUMPH3(unit)) { 2082 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2083 KEY_TYPEf, 0x2); /* MIM_ISID */ 2084 } else 2085 #endif /* BCM_TRIUMPH3_SUPPORT */ 2086 { 2087 #if defined(BCM_TRIDENT3_SUPPORT) 2088 if (soc_feature(unit, soc_feature_base_valid)) { 2089 soc_mem_field32_set(unit, egr_xlate_mem, 2090 egr_vlan_xlate_entry, DATA_TYPEf, 0x3); 2091 soc_mem_field32_set(unit, egr_xlate_mem, 2092 egr_vlan_xlate_entry, KEY_TYPEf, 0x3); 2093 } else 2094 #endif 2095 { 2096 soc_mem_field32_set(unit, egr_xlate_mem, 2097 egr_vlan_xlate_entry, ENTRY_TYPEf, 0x3); 2098 } 2099 } 2100 #if defined(BCM_TRIDENT3_SUPPORT) 2101 if (soc_feature(unit, soc_feature_base_valid)) { 2102 soc_mem_field32_set(unit, egr_xlate_mem, 2103 egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 2104 soc_mem_field32_set(unit, egr_xlate_mem, 2105 egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 2106 } else 2107 #endif 2108 { 2109 soc_mem_field32_set(unit, egr_xlate_mem, 2110 egr_vlan_xlate_entry, VALIDf, 0x1); 2111 } 2112 /* MIIM_ISID key */ 2113 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__VFIf, vfi); 2114 /* MIIM_ISID data */ 2115 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__ISIDf, 2116 info->lookup_id); 2117 2118 rv = soc_mem_search(unit, egr_xlate_mem, MEM_BLOCK_ANY, &index, 2119 egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0); 2120 if (rv == SOC_E_NONE) { 2121 if (!((info->flags & BCM_MIM_VPN_WITH_ID) && 2122 (info->flags & BCM_MIM_VPN_REPLACE))) { 2123 _bcm_vfi_free(unit, _bcmVfiTypeMim, vfi); 2124 MIM_UNLOCK(unit); 2125 return BCM_E_EXISTS; 2126 } 2127 } else if (rv != SOC_E_NOT_FOUND) { 2128 _bcm_vfi_free(unit, _bcmVfiTypeMim, vfi); 2129 MIM_UNLOCK(unit); 2130 return rv; 2131 } 2132 2133 if ((info->flags & BCM_MIM_VPN_WITH_ID) && 2134 (info->flags & BCM_MIM_VPN_REPLACE) && 2135 (old_info.lookup_id >= 0)){ 2136 /* Delete old lookup ISID from EGR_VLAN_XLATE entry */ 2137 rv = _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete(unit, egr_vlan_xlate_entry); 2138 if (BCM_FAILURE(rv)) { 2139 MIM_UNLOCK(unit); 2140 return rv; 2141 } 2142 2143 rv = soc_mem_delete(unit, egr_xlate_mem, MEM_BLOCK_ALL, egr_vlan_xlate_entry); 2144 if (BCM_FAILURE(rv)) { 2145 MIM_UNLOCK(unit); 2146 return rv; 2147 } 2148 } 2149 2150 if (info->flags & BCM_MIM_VPN_QOS_SDTAG_NO_ACTION) { 2151 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2152 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf, 0); 2153 } 2154 2155 if (info->flags & BCM_MIM_VPN_QOS_SDTAG_FIX_PRIORITY) { 2156 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2157 MIM_ISID__SD_TAG_DOT1P_PRI_SELECTf, 0); 2158 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2159 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf, 0x5); 2160 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2161 MIM_ISID__NEW_PRIf, info->int_pri & 0x7); 2162 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2163 MIM_ISID__NEW_CFIf, ((info->int_pri >> 0x3) & 0x1)); 2164 } 2165 2166 if (info->flags & BCM_MIM_VPN_QOS_SDTAG_MAP_INT_PRIORITY) { 2167 rv = _bcm_tr2_qos_id2idx(unit, info->qos_map_id, &hw_idx); 2168 if (BCM_FAILURE(rv)) { 2169 MIM_UNLOCK(unit); 2170 return rv; 2171 } 2172 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2173 MIM_ISID__SD_TAG_DOT1P_PRI_SELECTf, 0x1); 2174 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2175 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf, 0x5); 2176 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2177 MIM_ISID__DOT1P_MAPPING_PTRf, hw_idx); 2178 } 2179 2180 if (info->flags & BCM_MIM_VPN_QOS_ITAG_FIX_PRIORITY) { 2181 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2182 MIM_ISID__ISID_DOT1P_PRI_SELECTf, 0); 2183 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2184 MIM_ISID__NEW_PRIf, info->int_pri & 0x7); 2185 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2186 MIM_ISID__NEW_CFIf, ((info->int_pri >> 0x3) & 0x1)); 2187 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2188 MIM_ISID__NEW_CFIf, ((info->int_pri >> 0x3) & 0x1)); 2189 } 2190 2191 if (info->flags & BCM_MIM_VPN_QOS_ITAG_MAP_SDTAG_PRIORITY) { 2192 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2193 MIM_ISID__ISID_DOT1P_PRI_SELECTf, 0x1); 2194 } 2195 2196 if (info->flags & BCM_MIM_VPN_EGRESS_SERVICE_TPID_REPLACE) { 2197 if (soc_feature(unit, soc_feature_evt_replace_tpid_only)) { 2198 rv = _bcm_tr2_mim_egr_vxlt_sd_tag_actions(unit, NULL, 2199 info, 2200 egr_vlan_xlate_entry); 2201 if (BCM_FAILURE(rv)) { 2202 MIM_UNLOCK(unit); 2203 return rv; 2204 } 2205 } else { 2206 MIM_UNLOCK(unit); 2207 return BCM_E_UNAVAIL; 2208 } 2209 } 2210 2211 rv = soc_mem_insert(unit, egr_xlate_mem, MEM_BLOCK_ALL, egr_vlan_xlate_entry); 2212 if (rv < 0) { 2213 MIM_UNLOCK(unit); 2214 return rv; 2215 } 2216 } else if ((info->flags & BCM_MIM_VPN_REPLACE) && 2217 (old_info.lookup_id >= 0)) { 2218 sal_memset(&mpls_entry, 0, sizeof(mpls_entry)); 2219 #if defined(BCM_TRIUMPH3_SUPPORT) 2220 if (SOC_IS_TRIUMPH3(unit)) { 2221 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPE_0f, 0x18); 2222 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPE_1f, 0x18); 2223 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALID_0f, 0x1); 2224 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALID_1f, 0x1); 2225 } else 2226 #endif /* BCM_TRIUMPH3_SUPPORT */ 2227 { 2228 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPEf, 0x2); 2229 #if defined(BCM_TRIDENT3_SUPPORT) 2230 if (soc_feature(unit, soc_feature_base_valid)) { 2231 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, BASE_VALID_0f, 3); 2232 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, BASE_VALID_1f, 7); 2233 } else 2234 #endif 2235 { 2236 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALIDf, 0x1); 2237 } 2238 } 2239 /* key */ 2240 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__ISIDf, old_info.lookup_id); 2241 /* data */ 2242 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__VFIf, vfi); 2243 soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ANY, &mpls_entry); 2244 2245 /* Program the VFI to ISID mapping */ 2246 sal_memset(egr_vlan_xlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2247 #if defined(BCM_TRIUMPH3_SUPPORT) 2248 if (SOC_IS_TRIUMPH3(unit)) { 2249 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2250 KEY_TYPEf, 0x2); /* MIM_ISID */ 2251 } else 2252 #endif /* BCM_TRIUMPH3_SUPPORT */ 2253 { 2254 #if defined(BCM_TRIDENT3_SUPPORT) 2255 if (soc_feature(unit, soc_feature_base_valid)) { 2256 soc_mem_field32_set(unit, egr_xlate_mem, 2257 egr_vlan_xlate_entry, DATA_TYPEf, 0x3); 2258 soc_mem_field32_set(unit, egr_xlate_mem, 2259 egr_vlan_xlate_entry, KEY_TYPEf, 0x3); 2260 } else 2261 #endif 2262 { 2263 soc_mem_field32_set(unit, egr_xlate_mem, 2264 egr_vlan_xlate_entry, ENTRY_TYPEf, 0x3); 2265 } 2266 } 2267 #if defined(BCM_TRIDENT3_SUPPORT) 2268 if (soc_feature(unit, soc_feature_base_valid)) { 2269 soc_mem_field32_set(unit, egr_xlate_mem, 2270 egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 2271 soc_mem_field32_set(unit, egr_xlate_mem, 2272 egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 2273 } else 2274 #endif 2275 { 2276 soc_mem_field32_set(unit, egr_xlate_mem, 2277 egr_vlan_xlate_entry, VALIDf, 0x1); 2278 } 2279 2280 /* MIIM_ISID key */ 2281 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__VFIf, vfi); 2282 /* MIIM_ISID data */ 2283 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__ISIDf, 2284 old_info.lookup_id); 2285 rv = _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete(unit, egr_vlan_xlate_entry); 2286 if (BCM_FAILURE(rv)) { 2287 MIM_UNLOCK(unit); 2288 return rv; 2289 } 2290 soc_mem_delete(unit, egr_xlate_mem, MEM_BLOCK_ALL, egr_vlan_xlate_entry); 2291 } 2292 2293 #ifdef BCM_WARM_BOOT_SUPPORT 2294 SOC_CONTROL_LOCK(unit); 2295 SOC_CONTROL(unit)->scache_dirty = 1; 2296 SOC_CONTROL_UNLOCK(unit); 2297 #endif 2298 2299 MIM_UNLOCK(unit); 2300 2301 _BCM_MIM_VPN_SET(info->vpn, _BCM_MIM_VPN_TYPE_MIM, vfi); 2302 return rv; 2303 } 2304 2305 /* 2306 * Function: 2307 * bcm_mim_vpn_destroy 2308 * Purpose: 2309 * Delete a VPN instance 2310 * Parameters: 2311 * unit - Device Number 2312 * vpn - VPN instance ID 2313 * Returns: 2314 * BCM_E_XXX 2315 */ 2316 int 2317 bcm_tr2_mim_vpn_destroy(int unit, bcm_mim_vpn_t vpn) 2318 { 2319 int vfi, rv, tpid_en, i; 2320 uint32 vfi_1_entry[SOC_MAX_MEM_WORDS] = {0}; 2321 vfi_entry_t vfi_entry; 2322 uint32 mpls_entry[SOC_MAX_MEM_WORDS] = {0}; 2323 uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS]; 2324 soc_mem_t mpls_mem = MPLS_ENTRYm; 2325 int num_vfi; 2326 bcm_vpn_t mim_vpn_min=0; 2327 int ref_count, proto_pkt_idx; 2328 soc_mem_t egr_xlate_mem; 2329 soc_mem_t vfi_mem; 2330 soc_mem_t vfi_1_mem; 2331 uint32 vfi_entry_data[SOC_MAX_MEM_WORDS] = {0}; 2332 int index; 2333 2334 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 2335 int policer=0; 2336 #endif 2337 MIM_INIT(unit); 2338 MIM_LOCK(unit); 2339 2340 #if defined(BCM_TRIDENT3_SUPPORT) 2341 if (soc_feature(unit, soc_feature_base_valid)) { 2342 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 2343 } else 2344 #endif 2345 { 2346 egr_xlate_mem = EGR_VLAN_XLATEm; 2347 } 2348 2349 num_vfi = soc_mem_index_count(unit, VFIm); 2350 _BCM_MIM_VPN_SET(mim_vpn_min, _BCM_MIM_VPN_TYPE_MIM, 0); 2351 if ( vpn < mim_vpn_min || vpn > (mim_vpn_min+num_vfi-1) ) { 2352 MIM_UNLOCK(unit); 2353 return BCM_E_PARAM; 2354 } 2355 2356 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 2357 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 2358 MIM_UNLOCK(unit); 2359 return BCM_E_NOT_FOUND; 2360 } 2361 2362 /* Delete all the MIM ports on this VPN */ 2363 rv = bcm_tr2_mim_port_delete_all(unit, vpn); 2364 if (BCM_FAILURE(rv)) { 2365 MIM_UNLOCK(unit); 2366 return rv; 2367 } 2368 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 2369 if (soc_feature(unit, soc_feature_global_meter)) { 2370 rv = _bcm_esw_get_policer_from_table(unit, 2371 VFIm, vfi, &vfi_entry, &policer, 0); 2372 if(BCM_SUCCESS(rv)) { 2373 _bcm_esw_policer_decrement_ref_count(unit, policer); 2374 } else { 2375 MIM_UNLOCK(unit); 2376 return rv; 2377 } 2378 } 2379 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT */ 2380 if (SOC_MEM_FIELD_VALID(unit, VFIm, PROTOCOL_PKT_INDEXf)) { 2381 rv = READ_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry); 2382 if (BCM_FAILURE(rv)) { 2383 MIM_UNLOCK(unit); 2384 return rv; 2385 } 2386 proto_pkt_idx = soc_VFIm_field32_get(unit, &vfi_entry, 2387 PROTOCOL_PKT_INDEXf); 2388 rv = _bcm_prot_pkt_ctrl_ref_count_get(unit, proto_pkt_idx, 2389 &ref_count); 2390 if (BCM_FAILURE(rv)) { 2391 MIM_UNLOCK(unit); 2392 return rv; 2393 } 2394 if (ref_count > 0) { 2395 rv = _bcm_prot_pkt_ctrl_delete(unit, proto_pkt_idx); 2396 if (BCM_FAILURE(rv)) { 2397 MIM_UNLOCK(unit); 2398 return rv; 2399 } 2400 } 2401 } 2402 2403 if (soc_feature(unit, soc_feature_gport_service_counters)) { 2404 /* Release Service counter, if any */ 2405 _bcm_esw_flex_stat_handle_free(unit, _bcmFlexStatTypeService, 2406 vpn); 2407 } 2408 sal_memset(&mpls_entry, 0, sizeof(mpls_entry)); 2409 #if defined(BCM_TRIUMPH3_SUPPORT) 2410 if (SOC_IS_TRIUMPH3(unit)) { 2411 mpls_mem = MPLS_ENTRY_EXTDm; 2412 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPE_0f, 0x18); 2413 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPE_1f, 0x18); 2414 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALID_0f, 0x1); 2415 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALID_1f, 0x1); 2416 } else 2417 #endif /* BCM_TRIUMPH3_SUPPORT */ 2418 { 2419 mpls_mem = MPLS_ENTRYm; 2420 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, KEY_TYPEf, 0x2); 2421 #if defined(BCM_TRIDENT3_SUPPORT) 2422 if (soc_feature(unit, soc_feature_base_valid)) { 2423 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, BASE_VALID_0f, 3); 2424 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, BASE_VALID_1f, 7); 2425 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, DATA_TYPEf, 0x2); 2426 } else 2427 #endif 2428 { 2429 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, VALIDf, 0x1); 2430 } 2431 2432 } 2433 soc_mem_field32_set(unit, mpls_mem, &mpls_entry, MIM_ISID__ISIDf, VPN_ISID(unit, vfi)); 2434 rv = soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ANY, &mpls_entry); 2435 if (BCM_FAILURE(rv)) { 2436 MIM_UNLOCK(unit); 2437 return rv; 2438 } 2439 2440 sal_memset(egr_vlan_xlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2441 #if defined(BCM_TRIUMPH3_SUPPORT) 2442 if (SOC_IS_TRIUMPH3(unit)) { 2443 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 2444 KEY_TYPEf, 0x2); /* MIM_ISID */ 2445 } else 2446 #endif /* BCM_TRIUMPH3_SUPPORT */ 2447 { 2448 #if defined(BCM_TRIDENT3_SUPPORT) 2449 if (soc_feature(unit, soc_feature_base_valid)) { 2450 soc_mem_field32_set(unit, egr_xlate_mem, 2451 egr_vlan_xlate_entry, DATA_TYPEf, 0x3); 2452 soc_mem_field32_set(unit, egr_xlate_mem, 2453 egr_vlan_xlate_entry, KEY_TYPEf, 0x3); 2454 } else 2455 #endif 2456 { 2457 soc_mem_field32_set(unit, egr_xlate_mem, 2458 egr_vlan_xlate_entry, ENTRY_TYPEf, 0x3); 2459 } 2460 } 2461 #if defined(BCM_TRIDENT3_SUPPORT) 2462 if (soc_feature(unit, soc_feature_base_valid)) { 2463 soc_mem_field32_set(unit, egr_xlate_mem, 2464 egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 2465 soc_mem_field32_set(unit, egr_xlate_mem, 2466 egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 2467 } else 2468 #endif 2469 { 2470 soc_mem_field32_set(unit, egr_xlate_mem, 2471 egr_vlan_xlate_entry, VALIDf, 0x1); 2472 } 2473 2474 /* MIIM_ISID key */ 2475 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__VFIf, vfi); 2476 rv = soc_mem_search(unit, egr_xlate_mem, MEM_BLOCK_ANY, &index, 2477 egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0); 2478 rv = _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete(unit, egr_vlan_xlate_entry); 2479 if (BCM_FAILURE(rv)) { 2480 MIM_UNLOCK(unit); 2481 return rv; 2482 } 2483 rv = soc_mem_delete(unit, egr_xlate_mem, MEM_BLOCK_ANY, egr_vlan_xlate_entry); 2484 if (BCM_FAILURE(rv)) { 2485 MIM_UNLOCK(unit); 2486 return rv; 2487 } 2488 #if defined(BCM_TRIDENT3_SUPPORT) 2489 if (SOC_MEM_FIELD_VALID(unit, VFIm, SD_TAG_MODEf)) { 2490 vfi_mem = VFIm; 2491 vfi_1_mem = VFI_ATTRS_1m; 2492 } else 2493 #endif 2494 { 2495 vfi_mem = VFI_1m; 2496 vfi_1_mem = VFI_1m; 2497 } 2498 rv = soc_mem_read(unit, vfi_mem, MEM_BLOCK_ANY, vfi, vfi_1_entry); 2499 if (BCM_FAILURE(rv)) { 2500 MIM_UNLOCK(unit); 2501 return rv; 2502 } 2503 rv = soc_mem_read(unit, vfi_1_mem, MEM_BLOCK_ANY, vfi, vfi_entry_data); 2504 if (BCM_FAILURE(rv)) { 2505 MIM_UNLOCK(unit); 2506 return rv; 2507 } 2508 2509 /* Delete TPID if applicable */ 2510 if (soc_mem_field32_get(unit, vfi_mem, vfi_1_entry, SD_TAG_MODEf)) { 2511 tpid_en = soc_mem_field32_get(unit, vfi_1_mem, vfi_entry_data, TPID_ENABLEf); 2512 for (i = 0; i < 4; i++) { 2513 if (tpid_en & (1 << i)) { 2514 (void)_bcm_fb2_outer_tpid_entry_delete(unit, i); 2515 break; 2516 } 2517 } 2518 } 2519 sal_memset(vfi_1_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2520 rv = soc_mem_write(unit, vfi_1_mem, MEM_BLOCK_ALL, vfi, vfi_1_entry); 2521 if (BCM_FAILURE(rv)) { 2522 MIM_UNLOCK(unit); 2523 return rv; 2524 } 2525 2526 VPN_ISID(unit, vfi) = 0; 2527 (void) _bcm_vfi_free(unit, _bcmVfiTypeMim, vfi); 2528 2529 #ifdef BCM_WARM_BOOT_SUPPORT 2530 SOC_CONTROL_LOCK(unit); 2531 SOC_CONTROL(unit)->scache_dirty = 1; 2532 SOC_CONTROL_UNLOCK(unit); 2533 #endif 2534 2535 MIM_UNLOCK(unit); 2536 return rv; 2537 } 2538 2539 STATIC int 2540 _bcm_tr2_mim_vpn_np_destroy(int unit) 2541 { 2542 int vp, rv = BCM_E_NONE; 2543 uint32 num_vp; 2544 source_vp_entry_t *psvp; 2545 uint8 *source_vp_buf = NULL; 2546 int network_port = 0; 2547 _bcm_vp_info_t vp_info; 2548 2549 MIM_INIT(unit); 2550 2551 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 2552 source_vp_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, SOURCE_VPm), 2553 "SOURCE_VP buffer"); 2554 if (source_vp_buf == NULL) { 2555 goto done; 2556 } 2557 rv = soc_mem_read_range(unit, SOURCE_VPm, MEM_BLOCK_ANY, 2558 0, num_vp-1, source_vp_buf); 2559 if (rv < 0) { 2560 goto done; 2561 } 2562 2563 for (vp = 0; vp < num_vp; vp++) { 2564 network_port = FALSE; 2565 psvp = soc_mem_table_idx_to_pointer 2566 (unit, SOURCE_VPm, source_vp_entry_t *, source_vp_buf, vp); 2567 if (soc_SOURCE_VPm_field32_get( unit, psvp, ENTRY_TYPEf) != 0) { 2568 if(_bcm_vp_info_get(unit, vp, &vp_info) == BCM_E_NONE) { 2569 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 2570 network_port = TRUE; 2571 } 2572 } 2573 2574 if(network_port) { 2575 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 2576 rv = _bcm_tr2_mim_port_delete(unit, 0, vp); 2577 if (rv < 0) { 2578 goto done; 2579 } 2580 } 2581 } 2582 } 2583 } 2584 done: 2585 if ( source_vp_buf != NULL ){ 2586 soc_cm_sfree( unit, source_vp_buf); 2587 } 2588 return rv; 2589 } 2590 2591 /* 2592 * Function: 2593 * bcm_mim_vpn_destroy_all 2594 * Purpose: 2595 * Delete al VPN instances 2596 * Parameters: 2597 * unit - Device Number 2598 * Returns: 2599 * BCM_E_XXX 2600 */ 2601 int 2602 bcm_tr2_mim_vpn_destroy_all(int unit) 2603 { 2604 int num_vfi, i, rv = BCM_E_NONE; 2605 bcm_vpn_t vpn; 2606 2607 MIM_INIT(unit); 2608 num_vfi = soc_mem_index_count(unit, VFIm); 2609 for (i = 0; i < num_vfi; i++) { 2610 if (_bcm_vfi_used_get(unit, i, _bcmVfiTypeMim)) { 2611 _BCM_MIM_VPN_SET(vpn, _BCM_MIM_VPN_TYPE_MIM, i); 2612 rv = bcm_tr2_mim_vpn_destroy(unit, vpn); 2613 if (rv < 0) { 2614 goto done; 2615 } 2616 } 2617 } 2618 rv = _bcm_tr2_mim_vpn_np_destroy(unit); 2619 done: 2620 return rv; 2621 } 2622 2623 /* 2624 * Function: 2625 * bcm_mim_vpn_get 2626 * Purpose: 2627 * Get information about a VPN instance 2628 * Parameters: 2629 * unit - (IN) Device Number 2630 * vpn - (IN) VPN instance ID 2631 * info - (OUT) VPN configuration info 2632 * Returns: 2633 * BCM_E_XXX 2634 */ 2635 int 2636 bcm_tr2_mim_vpn_get(int unit, bcm_mim_vpn_t vpn, 2637 bcm_mim_vpn_config_t *info) 2638 { 2639 int vfi, tpid_en, i; 2640 vfi_entry_t vfi_entry; 2641 uint32 vfi_entry_data[SOC_MAX_MEM_WORDS] = {0}; 2642 uint32 vfi_1_entry[SOC_MAX_MEM_WORDS] = {0}; 2643 int num_vfi; 2644 bcm_vpn_t mim_vpn_min=0; 2645 int is_eline = 0; 2646 int vpn_type; 2647 int proto_pkt_idx, rv; 2648 int bc_index = 0; 2649 int uuc_index = 0; 2650 int umc_index = 0; 2651 soc_mem_t vfi_mem; 2652 soc_mem_t vfi_1_mem; 2653 soc_mem_t evx_mem = EGR_VLAN_XLATEm; 2654 uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS] = {0}; 2655 int index; 2656 uint8 new_pri = 0; 2657 2658 MIM_INIT(unit); 2659 num_vfi = soc_mem_index_count(unit, VFIm); 2660 2661 _BCM_MIM_VPN_SET(mim_vpn_min, _BCM_MIM_VPN_TYPE_MIM, 0); 2662 if ( vpn < mim_vpn_min || vpn > (mim_vpn_min+num_vfi-1) ) { 2663 return BCM_E_PARAM; 2664 } 2665 2666 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 2667 2668 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 2669 return BCM_E_NOT_FOUND; 2670 } 2671 2672 /* Initialize VPN configuration information */ 2673 bcm_mim_vpn_config_t_init(info); 2674 info->vpn = vpn; 2675 2676 /* check if ELINE vpn service */ 2677 BCM_IF_ERROR_RETURN(soc_mem_read(unit, VFIm, MEM_BLOCK_ANY, vfi, 2678 &vfi_entry)); 2679 2680 is_eline = soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf); 2681 2682 if (is_eline) { 2683 vpn_type = BCM_MIM_VPN_ELINE; 2684 } else { 2685 vpn_type = BCM_MIM_VPN_MIM; 2686 } 2687 2688 info->flags |= vpn_type; 2689 2690 /* if point-to_point vpn BC_INDEX, UUC_INDEX, UMC_INDEX not relevant */ 2691 if (!is_eline) { 2692 #if defined(BCM_TRIDENT3_SUPPORT) 2693 if (soc_feature(unit, soc_feature_generic_dest)) { 2694 uint32 dt; 2695 2696 bc_index = soc_mem_field32_dest_get(unit, VFIm, 2697 &vfi_entry, BC_DESTINATIONf, &dt); 2698 if (dt != SOC_MEM_FIF_DEST_IPMC) { 2699 return BCM_E_INTERNAL; 2700 } 2701 2702 uuc_index = soc_mem_field32_dest_get(unit, VFIm, 2703 &vfi_entry, UUC_DESTINATIONf, &dt); 2704 if (dt != SOC_MEM_FIF_DEST_IPMC) { 2705 return BCM_E_INTERNAL; 2706 } 2707 2708 umc_index = soc_mem_field32_dest_get(unit, VFIm, 2709 &vfi_entry, UMC_DESTINATIONf, &dt); 2710 if (dt != SOC_MEM_FIF_DEST_IPMC) { 2711 return BCM_E_INTERNAL; 2712 } 2713 } else 2714 #endif 2715 { 2716 bc_index = soc_VFIm_field32_get(unit, &vfi_entry, BC_INDEXf); 2717 uuc_index = soc_VFIm_field32_get(unit, &vfi_entry, UUC_INDEXf); 2718 umc_index = soc_VFIm_field32_get(unit, &vfi_entry, UMC_INDEXf); 2719 } 2720 2721 _BCM_MULTICAST_GROUP_SET(info->broadcast_group, 2722 _BCM_MULTICAST_TYPE_MIM, bc_index); 2723 _BCM_MULTICAST_GROUP_SET(info->unknown_unicast_group, 2724 _BCM_MULTICAST_TYPE_MIM, uuc_index); 2725 _BCM_MULTICAST_GROUP_SET(info->unknown_multicast_group, 2726 _BCM_MULTICAST_TYPE_MIM, umc_index); 2727 } 2728 2729 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 2730 if (soc_feature(unit, soc_feature_global_meter)) { 2731 _bcm_esw_get_policer_from_table(unit, VFIm, vfi, &vfi_entry, 2732 &info->policer_id, 1); 2733 } 2734 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT */ 2735 info->lookup_id = VPN_ISID(unit, vfi); 2736 if (SOC_MEM_FIELD_VALID(unit,VFIm, PROTOCOL_PKT_INDEXf)) { 2737 proto_pkt_idx = soc_VFIm_field32_get(unit, &vfi_entry, 2738 PROTOCOL_PKT_INDEXf); 2739 rv = _bcm_xgs3_protocol_pkt_ctrl_get(unit, proto_pkt_idx, 2740 &info->protocol_pkt); 2741 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 2742 return rv; 2743 } 2744 } 2745 #if defined(BCM_TRIDENT3_SUPPORT) 2746 if (SOC_MEM_FIELD_VALID(unit, VFIm, SD_TAG_MODEf)) { 2747 vfi_mem = VFIm; 2748 vfi_1_mem = VFI_ATTRS_1m; 2749 evx_mem = EGR_VLAN_XLATE_1_DOUBLEm; 2750 } else 2751 #endif 2752 { 2753 vfi_mem = VFI_1m; 2754 vfi_1_mem = VFI_1m; 2755 } 2756 2757 BCM_IF_ERROR_RETURN(soc_mem_read(unit, vfi_mem, 2758 MEM_BLOCK_ANY, vfi, vfi_entry_data)); 2759 BCM_IF_ERROR_RETURN(soc_mem_read(unit, vfi_1_mem, 2760 MEM_BLOCK_ANY, vfi, vfi_1_entry)); 2761 if (soc_mem_field32_get(unit, vfi_mem, vfi_entry_data, SD_TAG_MODEf)) { 2762 info->flags |= BCM_MIM_VPN_MATCH_SERVICE_VLAN_TPID; 2763 tpid_en = soc_mem_field32_get(unit, vfi_1_mem, &vfi_1_entry, TPID_ENABLEf); 2764 for (i = 0; i < 4; i++) { 2765 if (tpid_en & (1 << i)) { 2766 _bcm_fb2_outer_tpid_entry_get(unit, 2767 &info->match_service_tpid, i); 2768 break; 2769 } 2770 } 2771 } 2772 2773 sal_memset(egr_vlan_xlate_entry, 0, sizeof(egr_vlan_xlate_entry)); 2774 #if defined(BCM_TRIUMPH3_SUPPORT) 2775 if (SOC_IS_TRIUMPH3(unit)) { 2776 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, 2777 KEY_TYPEf, 0x2); /* MIM_ISID */ 2778 } else 2779 #endif /* BCM_TRIUMPH3_SUPPORT */ 2780 #if defined(BCM_TRIDENT3_SUPPORT) 2781 if (soc_feature(unit, soc_feature_base_valid)) { 2782 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, DATA_TYPEf, 0x3); 2783 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, KEY_TYPEf, 0x3); 2784 } else 2785 #endif 2786 { 2787 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, 2788 ENTRY_TYPEf, 0x3); 2789 } 2790 if (soc_feature(unit, soc_feature_base_valid)) { 2791 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 2792 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 2793 } else { 2794 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, VALIDf, 0x1); 2795 } 2796 /* MIIM_ISID key */ 2797 soc_mem_field32_set(unit, evx_mem, egr_vlan_xlate_entry, MIM_ISID__VFIf, vfi); 2798 rv = soc_mem_search(unit, evx_mem, MEM_BLOCK_ANY, &index, 2799 egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0); 2800 if (rv == SOC_E_NONE) 2801 { 2802 new_pri = 2803 soc_mem_field32_get(unit, evx_mem, &egr_vlan_xlate_entry, 2804 MIM_ISID__NEW_PRIf); 2805 new_pri |= 2806 ((soc_mem_field32_get(unit, evx_mem, &egr_vlan_xlate_entry, 2807 MIM_ISID__NEW_CFIf) & 0x1) << 3); 2808 if (new_pri != 0) { 2809 if (soc_mem_field32_get(unit, evx_mem, &egr_vlan_xlate_entry, 2810 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf) == 0) { 2811 info->flags |= BCM_MIM_VPN_QOS_ITAG_FIX_PRIORITY; 2812 info->int_pri = new_pri; 2813 } 2814 } 2815 2816 rv = _bcm_tr2_mim_egr_vxlt_sd_tag_actions_get(unit, NULL, info, 2817 egr_vlan_xlate_entry); 2818 } 2819 2820 return rv; 2821 } 2822 2823 /* 2824 * Function: 2825 * bcm_mim_vpn_traverse 2826 * Purpose: 2827 * Get information about a VPN instance 2828 * Parameters: 2829 * unit - (IN) Device Number 2830 * cb - (IN) User-provided callback 2831 * info - (IN/OUT) Cookie 2832 * Returns: 2833 * BCM_E_XXX 2834 */ 2835 2836 int bcm_tr2_mim_vpn_traverse(int unit, bcm_mim_vpn_traverse_cb cb, 2837 void *user_data) 2838 { 2839 int i, index_min, index_max, rv = BCM_E_NONE; 2840 int vpn; 2841 bcm_mim_vpn_config_t info; 2842 2843 MIM_INIT(unit); 2844 2845 index_min = soc_mem_index_min(unit, VFIm); 2846 index_max = soc_mem_index_max(unit, VFIm); 2847 2848 MIM_LOCK(unit); 2849 for (i = index_min; i <= index_max; i++) { 2850 if (!_bcm_vfi_used_get(unit, i, _bcmVfiTypeMim)) { 2851 continue; 2852 } 2853 bcm_mim_vpn_config_t_init(&info); 2854 _BCM_MIM_VPN_SET(vpn, _BCM_MIM_VPN_TYPE_MIM, i); 2855 rv = bcm_tr2_mim_vpn_get(unit, vpn, &info); 2856 if (BCM_FAILURE(rv)) { 2857 MIM_UNLOCK(unit); 2858 return rv; 2859 } 2860 rv = cb(unit, &info, user_data); 2861 if (BCM_FAILURE(rv)) { 2862 MIM_UNLOCK(unit); 2863 return rv; 2864 } 2865 } 2866 MIM_UNLOCK(unit); 2867 return rv; 2868 } 2869 2870 STATIC int 2871 _bcm_tr2_mim_l3_intf_add(int unit, _bcm_l3_intf_cfg_t *if_info) 2872 { 2873 int i, num_intf; 2874 egr_l3_intf_entry_t egr_intf; 2875 bcm_mac_t hw_mac; 2876 num_intf = soc_mem_index_count(unit, EGR_L3_INTFm); 2877 for (i = 0; i < num_intf; i++) { 2878 if (_BCM_MIM_INTF_USED_GET(unit, i)) { 2879 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_INTFm, 2880 MEM_BLOCK_ANY, i, &egr_intf)); 2881 soc_mem_mac_addr_get(unit, EGR_L3_INTFm, &egr_intf, 2882 MAC_ADDRESSf, hw_mac); 2883 if (SAL_MAC_ADDR_EQUAL(hw_mac, if_info->l3i_mac_addr)) { 2884 if_info->l3i_index = i; 2885 return BCM_E_NONE; 2886 } 2887 } 2888 } 2889 /* Create an interface */ 2890 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_intf_create(unit, if_info)); 2891 _BCM_MIM_INTF_USED_SET(unit, if_info->l3i_index); 2892 return BCM_E_NONE; 2893 } 2894 2895 typedef struct _bcm_tr2_ing_nh_info_s { 2896 int port; 2897 int module; 2898 int trunk; 2899 uint32 mtu; 2900 } _bcm_tr2_ing_nh_info_t; 2901 2902 typedef struct _bcm_tr2_egr_nh_info_s { 2903 uint8 entry_type; 2904 uint8 dvp_is_network; 2905 uint8 sd_tag_action_present; 2906 uint8 sd_tag_action_not_present; 2907 int dvp; 2908 int intf_num; 2909 int sd_tag_vlan; 2910 int sd_tag_pri; 2911 int sd_tag_cfi; 2912 int macda_index; 2913 int tpid_index; 2914 int vintf_ctr_idx; 2915 } _bcm_tr2_egr_nh_info_t; 2916 2917 STATIC int 2918 _bcm_tr2_mim_egr_sd_tag_actions(int unit, bcm_mim_port_t *mim_port, 2919 _bcm_tr2_egr_nh_info_t *egr_nh_info) 2920 { 2921 int rv = BCM_E_NONE, tpid_index = -1; 2922 if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD) { 2923 if (mim_port->egress_service_vlan >= BCM_VLAN_INVALID) { 2924 if (soc_feature(unit, soc_feature_vp_sharing)) { 2925 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 2926 } else { 2927 return BCM_E_PARAM; 2928 } 2929 } 2930 2931 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 2932 egr_nh_info->sd_tag_vlan = mim_port->egress_service_vlan; 2933 } 2934 egr_nh_info->sd_tag_action_not_present = 0x1; /* ADD */ 2935 } 2936 if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE) { 2937 if (mim_port->egress_service_vlan >= BCM_VLAN_INVALID) { 2938 if (soc_feature(unit, soc_feature_vp_sharing)) { 2939 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 2940 } else { 2941 return BCM_E_PARAM; 2942 } 2943 } 2944 /* REPLACE_VID_TPID */ 2945 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 2946 egr_nh_info->sd_tag_vlan = mim_port->egress_service_vlan; 2947 } 2948 egr_nh_info->sd_tag_action_present = 0x1; 2949 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_REPLACE) { 2950 if (mim_port->egress_service_vlan >= BCM_VLAN_INVALID) { 2951 if (soc_feature(unit, soc_feature_vp_sharing)) { 2952 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 2953 } else { 2954 return BCM_E_PARAM; 2955 } 2956 } 2957 /* REPLACE_VID_ONLY */ 2958 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 2959 egr_nh_info->sd_tag_vlan = mim_port->egress_service_vlan; 2960 } 2961 egr_nh_info->sd_tag_action_present = 0x2; 2962 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_DELETE) { 2963 egr_nh_info->sd_tag_action_present = 0x3; /* DELETE */ 2964 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_PRI_TPID_REPLACE) { 2965 if (mim_port->egress_service_vlan >= BCM_VLAN_INVALID) { 2966 if (soc_feature(unit, soc_feature_vp_sharing)) { 2967 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 2968 } else { 2969 return BCM_E_PARAM; 2970 } 2971 } 2972 /* REPLACE_VID_PRI_TPID */ 2973 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 2974 egr_nh_info->sd_tag_vlan = mim_port->egress_service_vlan; 2975 } 2976 egr_nh_info->sd_tag_pri = mim_port->egress_service_pri; 2977 egr_nh_info->sd_tag_cfi = mim_port->egress_service_cfi; 2978 egr_nh_info->sd_tag_action_present = 0x4; 2979 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_PRI_REPLACE ) { 2980 if (mim_port->egress_service_vlan >= BCM_VLAN_INVALID) { 2981 if (soc_feature(unit, soc_feature_vp_sharing)) { 2982 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 2983 } else { 2984 return BCM_E_PARAM; 2985 } 2986 } 2987 /* REPLACE_VID_PRI ONLY */ 2988 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 2989 egr_nh_info->sd_tag_vlan = mim_port->egress_service_vlan; 2990 } 2991 egr_nh_info->sd_tag_pri = mim_port->egress_service_pri; 2992 egr_nh_info->sd_tag_cfi = mim_port->egress_service_cfi; 2993 egr_nh_info->sd_tag_action_present = 0x5; 2994 } 2995 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 2996 else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_PRI_REPLACE) { 2997 egr_nh_info->sd_tag_pri = mim_port->egress_service_pri; 2998 egr_nh_info->sd_tag_cfi = mim_port->egress_service_cfi; 2999 egr_nh_info->sd_tag_action_present = 0x6; 3000 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_TPID_REPLACE) { 3001 /* TPID value is used */ 3002 rv = _bcm_fb2_outer_tpid_entry_add(unit, mim_port->egress_service_tpid, 3003 &tpid_index); 3004 BCM_IF_ERROR_RETURN(rv); 3005 egr_nh_info->tpid_index = tpid_index; 3006 egr_nh_info->sd_tag_action_present = 0x7; 3007 } 3008 #endif 3009 if ((mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD) 3010 || (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE) 3011 || (mim_port->flags & 3012 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_PRI_TPID_REPLACE)) 3013 { 3014 /* TPID value is used */ 3015 rv = _bcm_fb2_outer_tpid_entry_add(unit, mim_port->egress_service_tpid, 3016 &tpid_index); 3017 BCM_IF_ERROR_RETURN(rv); 3018 egr_nh_info->tpid_index = tpid_index; 3019 } 3020 3021 /* Set fixed priority */ 3022 if (mim_port->flags & BCM_MIM_PORT_FIX_PRIORITY) { 3023 if (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) { 3024 egr_nh_info->sd_tag_pri = mim_port->int_pri & 0x7; 3025 egr_nh_info->sd_tag_cfi = ((mim_port->int_pri >> 0x3) & 0x1); 3026 } 3027 } 3028 3029 return rv; 3030 } 3031 3032 int 3033 _bcm_tr2_mim_egr_vxlt_sd_tag_actions(int unit, bcm_mim_port_t *mim_port, 3034 bcm_mim_vpn_config_t *vpn_info, 3035 uint32 *evxlt_entry) 3036 { 3037 int rv = BCM_E_NONE, tpid_index = -1; 3038 int sd_default_action = 0, sd_tag_action = 0; 3039 soc_mem_t egr_xlate_mem; 3040 3041 #if defined(BCM_TRIDENT3_SUPPORT) 3042 if (soc_feature(unit, soc_feature_base_valid)) { 3043 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 3044 } else 3045 #endif 3046 { 3047 egr_xlate_mem = EGR_VLAN_XLATEm; 3048 } 3049 3050 if (mim_port != NULL) { 3051 if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD) { 3052 if (!BCM_VLAN_VALID(mim_port->egress_service_vlan)) { 3053 return BCM_E_PARAM; 3054 } 3055 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3056 MIM_ISID__SD_TAG_VIDf, 3057 mim_port->egress_service_vlan); 3058 sd_default_action = 0x1; /* ADD */ 3059 } 3060 if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE) { 3061 if (!BCM_VLAN_VALID(mim_port->egress_service_vlan)) { 3062 return BCM_E_PARAM; 3063 } 3064 /* REPLACE_VID_TPID */ 3065 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3066 MIM_ISID__SD_TAG_VIDf, 3067 mim_port->egress_service_vlan); 3068 sd_tag_action = 0x1; /* Replace Vid and TPID */ 3069 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_REPLACE) { 3070 if (!BCM_VLAN_VALID(mim_port->egress_service_vlan)) { 3071 return BCM_E_PARAM; 3072 } 3073 /* REPLACE_VID_ONLY */ 3074 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3075 MIM_ISID__SD_TAG_VIDf, 3076 mim_port->egress_service_vlan); 3077 sd_tag_action = 0x2; /* Replace Vid only */ 3078 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_DELETE) { 3079 sd_tag_action = 0x3; /* DELETE */ 3080 } 3081 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 3082 else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_PRI_REPLACE) { 3083 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3084 MIM_ISID__NEW_PRIf, 3085 mim_port->egress_service_pri); 3086 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3087 MIM_ISID__NEW_CFIf, 3088 mim_port->egress_service_cfi); 3089 sd_tag_action = 0x6; 3090 } else if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_TPID_REPLACE) { 3091 /* TPID value is used */ 3092 rv = _bcm_fb2_outer_tpid_entry_add(unit, mim_port->egress_service_tpid, 3093 &tpid_index); 3094 BCM_IF_ERROR_RETURN(rv); 3095 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3096 MIM_ISID__SD_TAG_TPID_INDEXf, 3097 tpid_index); 3098 sd_tag_action = 0x7; 3099 } 3100 #endif 3101 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3102 MIM_ISID__SD_TAG_ACTION_IF_NOT_PRESENTf, 3103 sd_default_action); 3104 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3105 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf, 3106 sd_tag_action); 3107 3108 if ((mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD) || 3109 (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE)) { 3110 /* TPID value is used */ 3111 rv = _bcm_fb2_outer_tpid_entry_add(unit, mim_port->egress_service_tpid, 3112 &tpid_index); 3113 BCM_IF_ERROR_RETURN(rv); 3114 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3115 MIM_ISID__SD_TAG_TPID_INDEXf, 3116 tpid_index); 3117 } 3118 } else if (vpn_info != NULL) { 3119 if (vpn_info->flags & BCM_MIM_VPN_EGRESS_SERVICE_TPID_REPLACE) { 3120 rv = _bcm_fb2_outer_tpid_entry_add(unit, vpn_info->egress_service_tpid, 3121 &tpid_index); 3122 BCM_IF_ERROR_RETURN(rv); 3123 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3124 MIM_ISID__SD_TAG_TPID_INDEXf, 3125 tpid_index); 3126 3127 /* REPLACE_TPID_ONLY */ 3128 sd_tag_action = 0x7; 3129 soc_mem_field32_set(unit, egr_xlate_mem, evxlt_entry, 3130 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf, 3131 sd_tag_action); 3132 } 3133 } 3134 3135 return rv; 3136 } 3137 3138 int 3139 _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete( 3140 int unit, uint32 *egr_vlan_xlate_entry) 3141 { 3142 int action_present, action_not_present, tpid_idx; 3143 soc_mem_t egr_xlate_mem; 3144 3145 #if defined(BCM_TRIDENT3_SUPPORT) 3146 if (soc_feature(unit, soc_feature_base_valid)) { 3147 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 3148 } else 3149 #endif 3150 { 3151 egr_xlate_mem = EGR_VLAN_XLATEm; 3152 } 3153 3154 /* Populate the API structure */ 3155 action_present = 3156 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 3157 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf); 3158 action_not_present = 3159 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 3160 MIM_ISID__SD_TAG_ACTION_IF_NOT_PRESENTf); 3161 3162 if ((action_not_present == 0x1) || (action_present == 0x1) || 3163 ((action_present == 0x7) && 3164 soc_feature(unit, soc_feature_evt_replace_tpid_only))) { 3165 /* If SD tag action is ADD or REPLACE_VID_TPID, the tpid 3166 * index of the entry is valid. Get the tpid index for later. 3167 */ 3168 tpid_idx = 3169 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 3170 MIM_ISID__SD_TAG_TPID_INDEXf); 3171 /* Delete old TPID */ 3172 if (tpid_idx != -1) { 3173 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 3174 } 3175 } 3176 return BCM_E_NONE; 3177 } 3178 3179 /* 3180 * Function: 3181 * _bcm_tr2_mim_failover_check 3182 * Purpose: 3183 * Check for failover enable - mim port 3184 * Parameters: 3185 * unit : (IN) Device Unit Number 3186 * mim_port : (IN) mim port information 3187 * Returns: 3188 * BCM_E_XXX 3189 */ 3190 STATIC int 3191 _bcm_tr2_mim_failover_check(int unit, bcm_mim_port_t *mim_port) 3192 { 3193 int failover_vp = -1; 3194 int l3mc_index = -1; 3195 int vp_min = -1; 3196 /* Get egress next-hop index from Failover MPLS gport */ 3197 if (_BCM_MULTICAST_IS_SET(mim_port->failover_mc_group)) { 3198 l3mc_index = _BCM_MULTICAST_ID_GET(mim_port->failover_mc_group); 3199 if ((l3mc_index >= 0) && 3200 (l3mc_index < soc_mem_index_count(unit, L3_IPMCm))) { 3201 return BCM_E_NONE; 3202 } else { 3203 return BCM_E_PARAM; 3204 } 3205 } else { 3206 failover_vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port->failover_gport_id); 3207 if (failover_vp == -1) { 3208 return BCM_E_PARAM; 3209 } 3210 if (soc_feature(unit, soc_feature_mim_reserve_default_port) && 3211 soc_property_get(unit, spn_RESERVE_MIM_DEFAULT_SVP, 0)) { 3212 vp_min = 2; 3213 } else { 3214 vp_min = 1; 3215 } 3216 if ((failover_vp >= vp_min) && 3217 (failover_vp < soc_mem_index_count(unit, SOURCE_VPm))) { 3218 return BCM_E_NONE; 3219 } else { 3220 return BCM_E_PARAM; 3221 } 3222 } 3223 return BCM_E_PARAM; 3224 } 3225 3226 STATIC int 3227 _bcm_tr2_mim_l2_nh_info_add(int unit, bcm_mim_port_t *mim_port, int vp, int drop, 3228 int *nh_index, bcm_port_t *local_port, int *is_local) 3229 { 3230 initial_ing_l3_next_hop_entry_t initial_ing_nh; 3231 ing_l3_next_hop_entry_t ing_nh; 3232 egr_l3_next_hop_entry_t egr_nh; 3233 egr_mac_da_profile_entry_t mac_da_ent; 3234 void *macda; 3235 soc_mem_t mem; 3236 _bcm_tr2_ing_nh_info_t ing_nh_info; 3237 _bcm_tr2_egr_nh_info_t egr_nh_info; 3238 bcm_l3_egress_t nh_info; 3239 _bcm_l3_intf_cfg_t if_info; 3240 uint32 nh_flags; 3241 int gport_id, rv; 3242 bcm_module_t mod_out; 3243 bcm_port_t port_out; 3244 bcm_trunk_t trunk_id; 3245 int action_present, action_not_present; 3246 int old_tpid_idx = -1, old_macda_idx = -1; 3247 void *entries[1]; 3248 uint64 temp_mac; 3249 _bcm_port_info_t *info; 3250 int failover_nh_index; 3251 uint32 failover_vp; 3252 ing_dvp_table_entry_t failover_dvp; 3253 uint32 protection_flags=0; 3254 uint32 port_flags; 3255 int network_group=0; 3256 #ifdef BCM_TRIUMPH3_SUPPORT 3257 uint32 mtu_profile_index = 0; 3258 #endif /* BCM_TRIUMPH3_SUPPORT */ 3259 #if defined(BCM_KATANA2_SUPPORT) 3260 int my_modid = 0, is_local_subport = FALSE; 3261 int pp_port; 3262 int min_subport = SOC_INFO(unit).pp_port_index_min; 3263 int max_subport = SOC_INFO(unit).pp_port_index_max; 3264 #endif 3265 3266 /* Initialize values */ 3267 *local_port = 0; 3268 *is_local = 0; 3269 ing_nh_info.mtu = 0x3fff; 3270 ing_nh_info.port = -1; 3271 ing_nh_info.module = -1; 3272 ing_nh_info.trunk = -1; 3273 3274 egr_nh_info.dvp = vp; 3275 if (soc_feature(unit, 3276 soc_feature_multiple_split_horizon_group)) { 3277 network_group = mim_port->network_group_id; 3278 rv = _bcm_validate_splithorizon_network_group(unit, 3279 mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE, 3280 &network_group); 3281 BCM_IF_ERROR_RETURN(rv); 3282 } 3283 egr_nh_info.dvp_is_network = 3284 (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) ? 1 : 0; 3285 3286 egr_nh_info.sd_tag_action_present = 0; 3287 egr_nh_info.sd_tag_action_not_present = 0; 3288 egr_nh_info.intf_num = -1; 3289 egr_nh_info.sd_tag_vlan = -1; 3290 egr_nh_info.sd_tag_pri = -1; 3291 egr_nh_info.sd_tag_cfi = -1; 3292 egr_nh_info.macda_index = -1; 3293 egr_nh_info.tpid_index = -1; 3294 egr_nh_info.vintf_ctr_idx = -1; 3295 3296 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 3297 if ((*nh_index > soc_mem_index_max(unit, EGR_L3_NEXT_HOPm)) || 3298 (*nh_index < soc_mem_index_min(unit, EGR_L3_NEXT_HOPm))) { 3299 return BCM_E_PARAM; 3300 } 3301 /* Read the existing egress next_hop entry */ 3302 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 3303 *nh_index, &egr_nh); 3304 BCM_IF_ERROR_RETURN(rv); 3305 } else { 3306 /* 3307 * Allocate a next-hop entry. By calling bcm_xgs3_nh_add() 3308 * with _BCM_L3_SHR_WRITE_DISABLE flag, a next-hop index is 3309 * allocated but nothing is written to hardware. The "nh_info" 3310 * in this case is not used, so just set to all zeros. 3311 */ 3312 bcm_l3_egress_t_init(&nh_info); 3313 3314 nh_flags = _BCM_L3_SHR_MATCH_DISABLE | _BCM_L3_SHR_WRITE_DISABLE; 3315 rv = bcm_xgs3_nh_add(unit, nh_flags, &nh_info, nh_index); 3316 BCM_IF_ERROR_RETURN(rv); 3317 } 3318 3319 /* Resolve the gport */ 3320 rv = _bcm_esw_gport_resolve(unit, mim_port->port, &mod_out, 3321 &port_out, &trunk_id, &gport_id); 3322 BCM_IF_ERROR_RETURN(rv); 3323 3324 #if defined(BCM_KATANA2_SUPPORT) 3325 if (BCM_GPORT_IS_SET(mim_port->port) && 3326 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 3327 mim_port->port)) { 3328 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 3329 if (_bcm_kt2_mod_is_coe_mod_check(unit, mod_out) == BCM_E_NONE) { 3330 rv = _bcm_kt2_modport_to_pp_port_get( 3331 unit, mod_out, port_out, &pp_port); 3332 BCM_IF_ERROR_RETURN(rv); 3333 #if defined BCM_METROLITE_SUPPORT 3334 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 3335 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 3336 is_local_subport = TRUE; 3337 *is_local = 1; 3338 *local_port = pp_port; 3339 } 3340 } else 3341 #endif 3342 { 3343 if ((pp_port >= min_subport) && 3344 (pp_port <= max_subport)) { 3345 is_local_subport = TRUE; 3346 *is_local = 1; 3347 *local_port = pp_port; 3348 } 3349 } 3350 } 3351 } 3352 3353 #endif 3354 if (BCM_GPORT_IS_TRUNK(mim_port->port)) { 3355 ing_nh_info.module = -1; 3356 ing_nh_info.port = -1; 3357 ing_nh_info.trunk = trunk_id; 3358 MIM_INFO(unit)->port_info[vp].modid = -1; 3359 MIM_INFO(unit)->port_info[vp].port = -1; 3360 MIM_INFO(unit)->port_info[vp].tgid = trunk_id; 3361 } else { 3362 ing_nh_info.module = mod_out; 3363 ing_nh_info.port = port_out; 3364 ing_nh_info.trunk = -1; 3365 BCM_IF_ERROR_RETURN( 3366 _bcm_esw_modid_is_local(unit, mod_out, is_local)); 3367 3368 if (TRUE == *is_local) { 3369 /* Indicated to calling function that this is a local port */ 3370 *is_local = 1; 3371 *local_port = ing_nh_info.port; 3372 } 3373 3374 MIM_INFO(unit)->port_info[vp].modid = mod_out; 3375 MIM_INFO(unit)->port_info[vp].port = port_out; 3376 MIM_INFO(unit)->port_info[vp].tgid = -1; 3377 } 3378 3379 if ((mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) || 3380 (mim_port->flags & BCM_MIM_PORT_TYPE_PEER)) { 3381 /* Deal with backbone/peer ports (ingress and egress) */ 3382 /* Use the MIM view of EGR_L3_NEXT_HOP */ 3383 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 3384 3385 #if defined(BCM_TRIDENT3_SUPPORT) 3386 if (SOC_IS_TRIDENT3X(unit)) { 3387 egr_nh_info.entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 3388 &egr_nh, DATA_TYPEf); 3389 } else 3390 #endif /* BCM_TRIDENT3_SUPPORT */ 3391 { 3392 egr_nh_info.entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 3393 &egr_nh, ENTRY_TYPEf); 3394 } 3395 3396 /* Be sure that the existing entry is programmed to MIM */ 3397 if (egr_nh_info.entry_type != 0x3) { /* != MIM */ 3398 return BCM_E_PARAM; 3399 } 3400 /* Remember old MAC DA profile index */ 3401 old_macda_idx = 3402 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3403 MIM__MAC_DA_PROFILE_INDEXf); 3404 /* Get Flexible Counter index */ 3405 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_VALKYRIE2(unit) 3406 || SOC_IS_TRIDENT(unit)) { 3407 egr_nh_info.vintf_ctr_idx = 3408 soc_EGR_L3_NEXT_HOPm_field32_get 3409 (unit, &egr_nh, VINTF_CTR_IDXf); 3410 } 3411 } 3412 egr_nh_info.entry_type = 0x3; 3413 3414 mem = EGR_MAC_DA_PROFILEm; 3415 macda = (void *)&mac_da_ent; 3416 sal_memset(macda, 0, sizeof(egr_mac_da_profile_entry_t)); 3417 /* Add MAC DA profile */ 3418 soc_mem_mac_addr_set(unit, mem, macda, 3419 MAC_ADDRESSf, mim_port->egress_tunnel_dstmac); 3420 3421 entries[0] = macda; 3422 rv = _bcm_mac_da_profile_entry_add(unit, entries, 1, 3423 (uint32 *) &egr_nh_info.macda_index); 3424 if (BCM_FAILURE(rv)) { 3425 goto cleanup; 3426 } 3427 3428 /* Add MACSA to an L3 interface entry - ref count if exists */ 3429 if (!BCM_VLAN_VALID(mim_port->egress_tunnel_vlan)) { 3430 rv = BCM_E_PARAM; 3431 goto cleanup; 3432 } 3433 sal_memset(&if_info, 0, sizeof(_bcm_l3_intf_cfg_t)); 3434 SAL_MAC_ADDR_TO_UINT64(mim_port->egress_tunnel_srcmac, temp_mac); 3435 SAL_MAC_ADDR_FROM_UINT64(if_info.l3i_mac_addr, temp_mac); 3436 if_info.l3i_vid = mim_port->egress_tunnel_vlan; 3437 rv = _bcm_tr2_mim_l3_intf_add(unit, &if_info); 3438 if (BCM_FAILURE(rv)) { 3439 goto cleanup; 3440 } 3441 3442 /* Populate the fields of MIM::EGR_l3_NEXT_HOP */ 3443 if (!(mim_port->flags & BCM_MIM_PORT_REPLACE)) { 3444 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 3445 } 3446 #if defined(BCM_TRIDENT3_SUPPORT) 3447 if (SOC_IS_TRIDENT3X(unit)) { 3448 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3449 DATA_TYPEf, egr_nh_info.entry_type); 3450 } else 3451 #endif /* BCM_TRIDENT3_SUPPORT */ 3452 { 3453 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3454 ENTRY_TYPEf, egr_nh_info.entry_type); 3455 } 3456 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3457 MIM__DVPf, egr_nh_info.dvp); 3458 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 3459 /* 3460 * Setting DVP_IS_ENNI field for PEER type ports and resetting for 3461 * BACKBONE ports. Resetting is done to support scenarios where 3462 * PEER ports are replaced by BACKBONE ports 3463 */ 3464 if (!SOC_IS_TRIDENT3X(unit)) { 3465 if(mim_port->flags & BCM_MIM_PORT_TYPE_PEER) { 3466 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3467 &egr_nh, MIM__DVP_IS_ENNIf, 1); 3468 } else { 3469 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3470 &egr_nh, MIM__DVP_IS_ENNIf, 0); 3471 } 3472 } 3473 } 3474 3475 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3476 MIM__BVID_VALIDf, 1); 3477 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3478 MIM__INTF_NUMf, if_info.l3i_index); 3479 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3480 MIM__BVIDf, mim_port->egress_tunnel_vlan); 3481 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3482 MIM__HG_HDR_SELf, 1); /* HG 2 */ 3483 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3484 MIM__MAC_DA_PROFILE_INDEXf, egr_nh_info.macda_index); 3485 if (mim_port->flags & BCM_MIM_PORT_TYPE_PEER) { 3486 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, MIM__ISID_LOOKUP_TYPEf)) { 3487 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3488 MIM__ISID_LOOKUP_TYPEf, 1); /* Peer */ 3489 } 3490 #ifdef BCM_TRIDENT2PLUS_SUPPORT 3491 if (soc_feature(unit, soc_feature_mim_bvid_insertion_control)) { 3492 uint32 regval; 3493 BCM_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, ®val)); 3494 if (soc_reg_field_get(unit, EGR_CONFIGr, regval, 3495 HONOR_NEXTHOP_BVID_VALIDf)) { 3496 if (mim_port->flags & BCM_MIM_PORT_PEER_NO_BTAG) { 3497 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3498 MIM__BVID_VALIDf, 0); 3499 } 3500 } 3501 } 3502 #endif 3503 } 3504 if (mim_port->flags & BCM_MIM_PORT_EGRESS_TUNNEL_DEST_MAC_USE_SERVICE) { 3505 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3506 MIM__ADD_ISID_TO_MACDAf, 1); 3507 } 3508 3509 if (mim_port->flags & BCM_MIM_PORT_FIX_PRIORITY) { 3510 BCM_IF_ERROR_RETURN 3511 (_bcm_tr2_mim_egr_sd_tag_actions(unit, mim_port, &egr_nh_info)); 3512 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3513 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf, 0); 3514 if (egr_nh_info.sd_tag_pri != -1) { 3515 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3516 &egr_nh, SD_TAG__NEW_PRIf, 3517 egr_nh_info.sd_tag_pri); 3518 } 3519 if (egr_nh_info.sd_tag_cfi != -1) { 3520 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3521 &egr_nh, SD_TAG__NEW_CFIf, 3522 egr_nh_info.sd_tag_cfi); 3523 } 3524 } 3525 } else if (mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS){ 3526 /* Deal with access ports */ 3527 /* Use the SD_TAG view of EGR_L3_NEXT_HOP */ 3528 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 3529 #if defined(BCM_TRIDENT3_SUPPORT) 3530 if (SOC_IS_TRIDENT3X(unit)) { 3531 egr_nh_info.entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 3532 &egr_nh, DATA_TYPEf); 3533 } else 3534 #endif /* BCM_TRIDENT3_SUPPORT */ 3535 { 3536 egr_nh_info.entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 3537 &egr_nh, ENTRY_TYPEf); 3538 } 3539 /* Be sure that the existing entry is programmed to SD-tag */ 3540 if (egr_nh_info.entry_type != 0x2) { /* != SD-tag */ 3541 return BCM_E_PARAM; 3542 } 3543 action_present = 3544 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3545 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 3546 action_not_present = 3547 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3548 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 3549 if ((action_not_present == 0x1) || (action_present == 0x1)) { 3550 /* If SD tag action is ADD or REPLACE_VID_TPID, the tpid 3551 * index of the entry getting replaced is valid. Save 3552 * the old tpid index to be deleted later. 3553 */ 3554 old_tpid_idx = 3555 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3556 SD_TAG__SD_TAG_TPID_INDEXf); 3557 /* Get Flexible Counter index */ 3558 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_VALKYRIE2(unit) 3559 || SOC_IS_TRIDENT(unit)) { 3560 egr_nh_info.vintf_ctr_idx = 3561 soc_EGR_L3_NEXT_HOPm_field32_get 3562 (unit, &egr_nh, VINTF_CTR_IDXf); 3563 } 3564 } 3565 } 3566 egr_nh_info.entry_type = 0x2; /* SD-tag */ 3567 3568 /* Populate SD_TAG::EGR_L3_NEXT_HOP entry */ 3569 if (!(mim_port->flags & BCM_MIM_PORT_REPLACE)) { 3570 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 3571 } 3572 #if defined(BCM_TRIDENT3_SUPPORT) 3573 if (SOC_IS_TRIDENT3X(unit)) { 3574 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3575 DATA_TYPEf, egr_nh_info.entry_type); 3576 } else 3577 #endif /* BCM_TRIDENT3_SUPPORT */ 3578 { 3579 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3580 ENTRY_TYPEf, egr_nh_info.entry_type); 3581 } 3582 3583 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3584 SD_TAG__DVPf, egr_nh_info.dvp); 3585 /* HG header PPD2 */ 3586 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3587 SD_TAG__HG_HDR_SELf, 1); 3588 3589 if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TAGGED) { 3590 /* Prepare egress SD tag entry (including parameter checks) */ 3591 BCM_IF_ERROR_RETURN 3592 (_bcm_tr2_mim_egr_sd_tag_actions(unit, mim_port, &egr_nh_info)); 3593 3594 /* Populate SD-TAG attributes in HW */ 3595 if (egr_nh_info.sd_tag_vlan != -1) { 3596 if (soc_feature(unit, soc_feature_vp_sharing)) { 3597 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_NOT_VALIDf)) { 3598 if (egr_nh_info.sd_tag_vlan == BCM_VLAN_INVALID) { 3599 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3600 &egr_nh, SD_TAG__SD_TAG_NOT_VALIDf, 1); 3601 } else { 3602 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3603 &egr_nh, SD_TAG__SD_TAG_NOT_VALIDf, 0); 3604 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3605 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info.sd_tag_vlan); 3606 } 3607 } else { 3608 if (egr_nh_info.sd_tag_vlan < BCM_VLAN_INVALID) { 3609 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3610 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info.sd_tag_vlan); 3611 } 3612 } 3613 } else { 3614 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3615 &egr_nh, SD_TAG__SD_TAG_VIDf, 3616 egr_nh_info.sd_tag_vlan); 3617 } 3618 } 3619 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3620 SD_TAG__SD_TAG_ACTION_IF_PRESENTf, 3621 egr_nh_info.sd_tag_action_present); 3622 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3623 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf, 3624 egr_nh_info.sd_tag_action_not_present); 3625 if (egr_nh_info.tpid_index != -1) { 3626 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3627 &egr_nh, SD_TAG__SD_TAG_TPID_INDEXf, 3628 egr_nh_info.tpid_index); 3629 } 3630 3631 3632 if (egr_nh_info.sd_tag_pri != -1) { 3633 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3634 &egr_nh, SD_TAG__NEW_PRIf, 3635 egr_nh_info.sd_tag_pri); 3636 } 3637 3638 if (egr_nh_info.sd_tag_cfi != -1) { 3639 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3640 &egr_nh, SD_TAG__NEW_CFIf, 3641 egr_nh_info.sd_tag_cfi); 3642 3643 } 3644 3645 #if defined(BCM_KATANA2_SUPPORT) 3646 if (is_local_subport) { 3647 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3648 SD_TAG__HG_MODIFY_ENABLEf, 1); 3649 } else 3650 #endif 3651 3652 { 3653 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 3654 SD_TAG__HG_MODIFY_ENABLEf, (*is_local) ? 1 : 0); 3655 } 3656 } 3657 } 3658 3659 /* Network Group ID can be set irrespective of port type */ 3660 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 3661 if (!SOC_IS_TRIDENT3X(unit)) { 3662 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3663 &egr_nh, MIM__DVP_NETWORK_GROUPf, 3664 network_group); 3665 } 3666 } else { 3667 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 3668 &egr_nh, MIM__DVP_IS_NETWORK_PORTf, 3669 egr_nh_info.dvp_is_network); 3670 } 3671 3672 /* Write INITIAL_ING_L3_NEXT_HOP entry */ 3673 sal_memset(&initial_ing_nh, 0, sizeof(initial_ing_l3_next_hop_entry_t)); 3674 if (soc_feature(unit, soc_feature_generic_dest)) { 3675 if (ing_nh_info.trunk == -1) { 3676 soc_mem_field32_dest_set(unit, INITIAL_ING_L3_NEXT_HOPm, &initial_ing_nh, 3677 DESTINATIONf, SOC_MEM_FIF_DEST_DGPP, 3678 ing_nh_info.module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | ing_nh_info.port); 3679 } else { 3680 soc_mem_field32_dest_set(unit, INITIAL_ING_L3_NEXT_HOPm, &initial_ing_nh, 3681 DESTINATIONf, SOC_MEM_FIF_DEST_LAG, ing_nh_info.trunk); 3682 } 3683 } else { 3684 if (ing_nh_info.trunk == -1) { 3685 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 3686 &initial_ing_nh, PORT_NUMf, ing_nh_info.port); 3687 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 3688 &initial_ing_nh, MODULE_IDf, ing_nh_info.module); 3689 } else { 3690 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 3691 &initial_ing_nh, Tf, 1); 3692 soc_mem_field32_set(unit, INITIAL_ING_L3_NEXT_HOPm, 3693 &initial_ing_nh, TGIDf, ing_nh_info.trunk); 3694 BCM_GPORT_TRUNK_SET(*local_port, ing_nh_info.trunk); 3695 } 3696 } 3697 rv = soc_mem_write(unit, INITIAL_ING_L3_NEXT_HOPm, 3698 MEM_BLOCK_ALL, *nh_index, &initial_ing_nh); 3699 if (rv < 0) { 3700 goto cleanup; 3701 } 3702 3703 /* Configure drop bits */ 3704 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, SD_TAG__BC_DROPf, 3705 drop ? 1 : 0); 3706 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, SD_TAG__UUC_DROPf, 3707 drop ? 1 : 0); 3708 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, SD_TAG__UMC_DROPf, 3709 drop ? 1 : 0); 3710 3711 /* Set Flexible Counter index */ 3712 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_VALKYRIE2(unit) 3713 || SOC_IS_TRIDENT(unit)) { 3714 if (egr_nh_info.vintf_ctr_idx != -1) { 3715 soc_EGR_L3_NEXT_HOPm_field32_set 3716 (unit, &egr_nh, VINTF_CTR_IDXf, egr_nh_info.vintf_ctr_idx); 3717 } 3718 } 3719 3720 /* Write EGR_L3_NEXT_HOP entry */ 3721 rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, 3722 MEM_BLOCK_ALL, *nh_index, &egr_nh); 3723 if (rv < 0) { 3724 goto cleanup; 3725 } 3726 3727 /* Write ING_L3_NEXT_HOP entry */ 3728 sal_memset(&ing_nh, 0, sizeof(ing_l3_next_hop_entry_t)); 3729 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, &ing_nh, DROPf, drop); 3730 if (soc_feature(unit, soc_feature_generic_dest)) { 3731 if (ing_nh_info.trunk == -1) { 3732 soc_mem_field32_dest_set(unit, ING_L3_NEXT_HOPm, &ing_nh, 3733 DESTINATIONf, SOC_MEM_FIF_DEST_DGPP, 3734 ing_nh_info.module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | ing_nh_info.port); 3735 } else { 3736 soc_mem_field32_dest_set(unit, ING_L3_NEXT_HOPm, &ing_nh, 3737 DESTINATIONf, SOC_MEM_FIF_DEST_LAG, ing_nh_info.trunk); 3738 } 3739 } else { 3740 if (ing_nh_info.trunk == -1) { 3741 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 3742 &ing_nh, PORT_NUMf, ing_nh_info.port); 3743 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 3744 &ing_nh, MODULE_IDf, ing_nh_info.module); 3745 } else { 3746 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 3747 &ing_nh, Tf, 1); 3748 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 3749 &ing_nh, TGIDf, ing_nh_info.trunk); 3750 } 3751 } 3752 if (drop) { 3753 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, &ing_nh, DROPf, drop); 3754 } 3755 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 3756 &ing_nh, ENTRY_TYPEf, 0x2); /* L2 DVP */ 3757 if (SOC_MEM_FIELD_VALID(unit, ING_L3_NEXT_HOPm, MTU_SIZEf)) { 3758 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 3759 &ing_nh, MTU_SIZEf, 0x3fff); 3760 } 3761 #ifdef BCM_TRIUMPH3_SUPPORT 3762 else if (SOC_MEM_FIELD_VALID(unit, ING_L3_NEXT_HOPm, 3763 DVP_ATTRIBUTE_1_INDEXf)) { 3764 BCM_IF_ERROR_RETURN( 3765 _bcm_tr3_mtu_profile_index_get(unit, 0x3fff, &mtu_profile_index)); 3766 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, &ing_nh, 3767 DVP_ATTRIBUTE_1_INDEXf, mtu_profile_index); 3768 } 3769 #endif /*BCM_TRIUMPH3_SUPPORT */ 3770 rv = soc_mem_write (unit, ING_L3_NEXT_HOPm, 3771 MEM_BLOCK_ALL, *nh_index, &ing_nh); 3772 if (rv < 0) { 3773 goto cleanup; 3774 } 3775 3776 /* Update the physical port's SW state */ 3777 #if defined(BCM_KATANA2_SUPPORT) 3778 if (soc_feature(unit, soc_feature_linkphy_coe) || 3779 soc_feature(unit, soc_feature_subtag_coe)) { 3780 if (is_local_subport) { 3781 _bcm_port_info_access(unit, 3782 MIM_INFO(unit)->port_info[vp].port, &info); 3783 info->vp_count++; 3784 rv = bcm_esw_port_vlan_member_get( 3785 unit, MIM_INFO(unit)->port_info[vp].port, &port_flags); 3786 if (rv < 0) { 3787 goto cleanup; 3788 } 3789 rv = bcm_esw_port_vlan_member_set( 3790 unit, MIM_INFO(unit)->port_info[vp].port, port_flags); 3791 if (rv < 0) { 3792 goto cleanup; 3793 } 3794 } 3795 } 3796 #endif 3797 if (*is_local) { 3798 bcm_port_t phys_port = MIM_INFO(unit)->port_info[vp].port; 3799 if (soc_feature(unit, soc_feature_sysport_remap)) { 3800 BCM_XLATE_SYSPORT_S2P(unit, &phys_port); 3801 } 3802 _bcm_port_info_access(unit, phys_port, &info); 3803 info->vp_count++; 3804 rv = bcm_esw_port_vlan_member_get(unit, phys_port, &port_flags); 3805 if (rv < 0) { 3806 goto cleanup; 3807 } 3808 rv = bcm_esw_port_vlan_member_set(unit, phys_port, port_flags); 3809 if (rv < 0) { 3810 goto cleanup; 3811 } 3812 } 3813 3814 /* If associated with a trunk, update each local physical port's SW state */ 3815 if (ing_nh_info.trunk != -1) { 3816 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 3817 bcm_port_t local_member_array[SOC_MAX_NUM_PP_PORTS]; 3818 int max_num_ports = SOC_MAX_NUM_PP_PORTS; 3819 #else 3820 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 3821 int max_num_ports = SOC_MAX_NUM_PORTS; 3822 #endif 3823 int local_member_count; 3824 int idx; 3825 3826 rv = _bcm_esw_trunk_local_members_get(unit, trunk_id, 3827 max_num_ports, local_member_array, &local_member_count); 3828 if (rv < 0) { 3829 goto cleanup; 3830 } 3831 for (idx = 0; idx < local_member_count; idx++) { 3832 _bcm_port_info_access(unit, local_member_array[idx], &info); 3833 info->vp_count++; 3834 rv = bcm_esw_port_vlan_member_get( 3835 unit, local_member_array[idx], &port_flags); 3836 if (rv < 0) { 3837 goto cleanup; 3838 } 3839 rv = bcm_esw_port_vlan_member_set( 3840 unit, local_member_array[idx], port_flags); 3841 if (rv < 0) { 3842 goto cleanup; 3843 } 3844 } 3845 } 3846 3847 #if defined(BCM_ENDURO_SUPPORT) 3848 if (!SOC_IS_ENDURO(unit)) { 3849 #endif 3850 if (BCM_SUCCESS(_bcm_tr2_mim_failover_check(unit, mim_port))) { 3851 /* Get egress next-hop index from Failover MIM gport */ 3852 failover_vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port->failover_gport_id); 3853 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, failover_vp, 3854 &failover_dvp); 3855 if (rv < 0) { 3856 goto cleanup; 3857 } 3858 failover_nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &failover_dvp, 3859 NEXT_HOP_INDEXf); 3860 if (_BCM_MULTICAST_IS_SET(mim_port->failover_mc_group)) { 3861 protection_flags |= _BCM_FAILOVER_1_PLUS_PROTECTION; 3862 } 3863 rv = _bcm_esw_failover_prot_nhi_create(unit, protection_flags, (uint32) *nh_index, 3864 failover_nh_index, mim_port->failover_mc_group, mim_port->failover_id); 3865 if (rv < 0) { 3866 goto cleanup; 3867 } 3868 } 3869 #if defined(BCM_ENDURO_SUPPORT) 3870 } 3871 #endif 3872 /* Delete old TPID, MAC indexes */ 3873 if (old_macda_idx != -1) { 3874 rv = _bcm_mac_da_profile_entry_delete(unit, old_macda_idx); 3875 BCM_IF_ERROR_RETURN(rv); 3876 } 3877 if (old_tpid_idx != -1) { 3878 (void)_bcm_fb2_outer_tpid_entry_delete(unit, old_tpid_idx); 3879 } 3880 return rv; 3881 3882 cleanup: 3883 if (!(mim_port->flags & BCM_MIM_PORT_REPLACE)) { 3884 (void) bcm_xgs3_nh_del(unit, _BCM_L3_SHR_WRITE_DISABLE, *nh_index); 3885 } 3886 if (egr_nh_info.tpid_index != -1) { 3887 (void) _bcm_fb2_outer_tpid_entry_delete(unit, egr_nh_info.tpid_index); 3888 } 3889 if (egr_nh_info.macda_index != -1) { 3890 (void) _bcm_mac_da_profile_entry_delete(unit, egr_nh_info.macda_index); 3891 } 3892 return rv; 3893 } 3894 3895 STATIC int 3896 _bcm_tr2_mim_l2_nh_info_delete(int unit, int nh_index) 3897 { 3898 int rv, old_macda_idx = -1; 3899 int action_present, action_not_present, old_tpid_idx = -1; 3900 initial_ing_l3_next_hop_entry_t initial_ing_nh; 3901 ing_l3_next_hop_entry_t ing_nh; 3902 egr_l3_next_hop_entry_t egr_nh; 3903 int entry_type = 0; 3904 3905 BCM_IF_ERROR_RETURN (soc_mem_read(unit, EGR_L3_NEXT_HOPm, 3906 MEM_BLOCK_ANY, nh_index, &egr_nh)); 3907 BCM_IF_ERROR_RETURN (soc_mem_read(unit, ING_L3_NEXT_HOPm, 3908 MEM_BLOCK_ANY, nh_index, &ing_nh)); 3909 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_ING_L3_NEXT_HOPm, 3910 MEM_BLOCK_ANY, nh_index, &initial_ing_nh)); 3911 3912 #if defined(BCM_TRIDENT3_SUPPORT) 3913 if (SOC_IS_TRIDENT3X(unit)) { 3914 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 3915 &egr_nh, DATA_TYPEf); 3916 } else 3917 #endif /* BCM_TRIDENT3_SUPPORT */ 3918 { 3919 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 3920 &egr_nh, ENTRY_TYPEf); 3921 } 3922 3923 if (entry_type == 0x2) { 3924 /* Access port */ 3925 action_present = 3926 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3927 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 3928 action_not_present = 3929 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3930 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 3931 if ((action_not_present == 0x1) || (action_present == 0x1) 3932 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 3933 || (action_present == 0x7) 3934 #endif 3935 ) { 3936 /* If SD tag action is ADD or REPLACE_VID_TPID, the tpid 3937 * index of the entry is valid. Save 3938 * the old tpid index to be deleted later. 3939 */ 3940 old_tpid_idx = 3941 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3942 SD_TAG__SD_TAG_TPID_INDEXf); 3943 } 3944 } else if (entry_type == 0x3) { 3945 /* Network or peer port */ 3946 old_macda_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 3947 MIM__MAC_DA_PROFILE_INDEXf); 3948 } else { 3949 return BCM_E_NOT_FOUND; 3950 } 3951 3952 /* Clear EGR_L3_NEXT_HOP entry */ 3953 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 3954 BCM_IF_ERROR_RETURN (soc_mem_write(unit, EGR_L3_NEXT_HOPm, 3955 MEM_BLOCK_ALL, nh_index, &egr_nh)); 3956 3957 /* Clear ING_L3_NEXT_HOP entry */ 3958 sal_memset(&ing_nh, 0, sizeof(ing_l3_next_hop_entry_t)); 3959 BCM_IF_ERROR_RETURN (soc_mem_write (unit, ING_L3_NEXT_HOPm, 3960 MEM_BLOCK_ALL, nh_index, &ing_nh)); 3961 3962 /* Clear INITIAL_ING_L3_NEXT_HOP entry */ 3963 sal_memset(&initial_ing_nh, 0, sizeof(initial_ing_l3_next_hop_entry_t)); 3964 BCM_IF_ERROR_RETURN (soc_mem_write(unit, INITIAL_ING_L3_NEXT_HOPm, 3965 MEM_BLOCK_ALL, nh_index, &initial_ing_nh)); 3966 3967 #if defined(BCM_ENDURO_SUPPORT) 3968 if (!SOC_IS_ENDURO(unit)) { 3969 #endif 3970 if (soc_feature(unit, soc_feature_failover)) { 3971 /* Delete the protection next-hop (if applicable) */ 3972 rv = _bcm_esw_failover_prot_nhi_cleanup(unit, nh_index); 3973 if ((rv != BCM_E_NOT_FOUND) && (rv != BCM_E_NONE)) { 3974 return rv; 3975 } 3976 } 3977 #if defined(BCM_ENDURO_SUPPORT) 3978 } 3979 #endif 3980 /* Delete old TPID */ 3981 if (old_tpid_idx != -1) { 3982 (void) _bcm_fb2_outer_tpid_entry_delete(unit, old_tpid_idx); 3983 } 3984 3985 /* Delete old MAC profile reference */ 3986 if (old_macda_idx != -1) { 3987 rv = _bcm_mac_da_profile_entry_delete(unit, old_macda_idx); 3988 BCM_IF_ERROR_RETURN(rv); 3989 } 3990 3991 /* Free the next-hop entry. */ 3992 rv = bcm_xgs3_nh_del(unit, _BCM_L3_SHR_WRITE_DISABLE, nh_index); 3993 return rv; 3994 } 3995 3996 /* 3997 * Function: 3998 * __bcm_tr2_mim_match_trunk_add 3999 * Purpose: 4000 * Assign SVP of an MIM Trunk port 4001 * Parameters: 4002 * unit - (IN) Device Number 4003 * tgid - (IN) Trunk group Id 4004 * vp - (IN) Source Virtual Port 4005 * Returns: 4006 * BCM_E_XXX 4007 */ 4008 4009 int 4010 _bcm_tr2_mim_match_trunk_add(int unit, bcm_trunk_t tgid, int vp) 4011 { 4012 bcm_module_t my_modid; 4013 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 4014 bcm_port_t local_member_array[SOC_MAX_NUM_PP_PORTS]; 4015 int max_num_ports = SOC_MAX_NUM_PP_PORTS; 4016 #else 4017 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 4018 int max_num_ports = SOC_MAX_NUM_PORTS; 4019 #endif 4020 4021 int local_member_count; 4022 int p; 4023 int rv = BCM_E_NONE; 4024 int rv_cleanup; 4025 int stm_index; 4026 4027 4028 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 4029 4030 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid, 4031 max_num_ports, local_member_array, &local_member_count)); 4032 4033 for (p = 0; p < local_member_count; p++) { 4034 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 4035 local_member_array[p], &stm_index); 4036 if (BCM_FAILURE(rv)) { 4037 goto trunk_cleanup; 4038 } 4039 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4040 stm_index, SOURCE_VPf, vp); 4041 if (BCM_FAILURE(rv)) { 4042 goto trunk_cleanup; 4043 } 4044 4045 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf)) { 4046 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4047 stm_index, SVP_VALIDf, 1); 4048 if (BCM_FAILURE(rv)) { 4049 goto trunk_cleanup; 4050 } 4051 } 4052 #if defined(BCM_TRIDENT3_SUPPORT) 4053 if(SOC_IS_TRIDENT3X(unit)) { 4054 rv = _bcm_esw_port_tab_set( 4055 unit, local_member_array[p], 4056 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0x1); /* L2_SVP */ 4057 } else 4058 #endif 4059 { 4060 rv = soc_mem_field32_modify(unit, PORT_TABm, local_member_array[p], 4061 PORT_OPERATIONf, 0x1); /* L2_SVP */ 4062 } 4063 if (BCM_FAILURE(rv)) { 4064 goto trunk_cleanup; 4065 } 4066 } 4067 4068 return BCM_E_NONE; 4069 4070 trunk_cleanup: 4071 for (;p >= 0; p--) { 4072 rv_cleanup = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 4073 local_member_array[p], &stm_index); 4074 if (BCM_SUCCESS(rv_cleanup)) { 4075 (void) soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4076 stm_index, SOURCE_VPf, 0); 4077 #if defined(BCM_TRIDENT3_SUPPORT) 4078 if(SOC_IS_TRIDENT3X(unit)) { 4079 (void)_bcm_esw_port_tab_set( 4080 unit, local_member_array[p], 4081 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0); 4082 } else 4083 #endif 4084 { 4085 (void) soc_mem_field32_modify(unit, PORT_TABm, local_member_array[p], 4086 PORT_OPERATIONf, 0); 4087 } 4088 } 4089 } 4090 return rv; 4091 } 4092 4093 /* 4094 * Function: 4095 * _bcm_tr_mim_match_trunk_delete 4096 * Purpose: 4097 * Remove SVP of an MIM Trunk port 4098 * Parameters: 4099 * unit - (IN) Device Number 4100 * tgid - (IN) Trunk group Id 4101 * vp - (IN) Source Virtual Port 4102 * Returns: 4103 * BCM_E_XXX 4104 */ 4105 4106 int 4107 _bcm_tr_mim_match_trunk_delete(int unit, bcm_trunk_t tgid, int vp) 4108 { 4109 bcm_module_t my_modid; 4110 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 4111 bcm_port_t local_member_array[SOC_MAX_NUM_PP_PORTS]; 4112 int max_num_ports = SOC_MAX_NUM_PP_PORTS; 4113 #else 4114 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 4115 int max_num_ports = SOC_MAX_NUM_PORTS; 4116 #endif 4117 4118 int local_member_count; 4119 int p; 4120 int rv = BCM_E_NONE; 4121 int rv_cleanup; 4122 int stm_index; 4123 4124 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 4125 4126 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid, 4127 max_num_ports, local_member_array, &local_member_count)); 4128 4129 for (p = 0; p < local_member_count; p++) { 4130 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 4131 local_member_array[p], &stm_index); 4132 if (BCM_FAILURE(rv)) { 4133 goto trunk_cleanup; 4134 } 4135 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4136 stm_index, SOURCE_VPf, 0); 4137 if (BCM_FAILURE(rv)) { 4138 goto trunk_cleanup; 4139 } 4140 4141 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf)) { 4142 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4143 stm_index, SVP_VALIDf, 0); 4144 if (BCM_FAILURE(rv)) { 4145 goto trunk_cleanup; 4146 } 4147 } 4148 #if defined(BCM_TRIDENT3_SUPPORT) 4149 if(SOC_IS_TRIDENT3X(unit)) { 4150 rv = _bcm_esw_port_tab_set( 4151 unit, local_member_array[p], 4152 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0); /* L2_SVP */ 4153 } else 4154 #endif 4155 { 4156 rv = soc_mem_field32_modify(unit, PORT_TABm, local_member_array[p], 4157 PORT_OPERATIONf, 0x0); /* L2_SVP */ 4158 } 4159 if (BCM_FAILURE(rv)) { 4160 goto trunk_cleanup; 4161 } 4162 } 4163 4164 return BCM_E_NONE; 4165 4166 trunk_cleanup: 4167 for (;p >= 0; p--) { 4168 rv_cleanup = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 4169 local_member_array[p], &stm_index); 4170 if (BCM_SUCCESS(rv_cleanup)) { 4171 (void) soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4172 stm_index, SOURCE_VPf, vp); 4173 #if defined(BCM_TRIDENT3_SUPPORT) 4174 if(SOC_IS_TRIDENT3X(unit)) { 4175 (void)_bcm_esw_port_tab_set( 4176 unit, local_member_array[p], 4177 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 1); /* L2_SVP */ 4178 } else 4179 #endif 4180 { 4181 (void) soc_mem_field32_modify(unit, PORT_TABm, local_member_array[p], 4182 PORT_OPERATIONf, 1); 4183 } 4184 } 4185 } 4186 4187 return rv; 4188 } 4189 4190 int 4191 _bcm_tr2_mim_match_add(int unit, bcm_mim_port_t *mim_port, 4192 int vp, bcm_mim_vpn_t vpn) 4193 { 4194 int rv = BCM_E_NONE, i, gport_id; 4195 bcm_module_t mod_out; 4196 bcm_port_t port_out; 4197 bcm_trunk_t trunk_id; 4198 #if defined(BCM_KATANA2_SUPPORT) 4199 int my_modid = 0, is_local_subport = FALSE, pp_port; 4200 int min_subport = SOC_INFO(unit).pp_port_index_min; 4201 int max_subport = SOC_INFO(unit).pp_port_index_max; 4202 #endif 4203 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4204 int vfi = 0; 4205 _bcm_vp_info_t vp_info; 4206 #endif 4207 soc_mem_t xlate_mem; 4208 soc_mem_t port_mem; 4209 4210 #if defined(BCM_TRIDENT3_SUPPORT) 4211 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 4212 port_mem = ING_DEVICE_PORTm; 4213 } else 4214 #endif 4215 { 4216 port_mem = PORT_TABm; 4217 } 4218 #if defined(BCM_TRIDENT3_SUPPORT) 4219 if (soc_feature(unit, soc_feature_base_valid)) { 4220 xlate_mem = VLAN_XLATE_1_DOUBLEm; 4221 } else 4222 #endif 4223 { 4224 xlate_mem = VLAN_XLATEm; 4225 } 4226 4227 if (mim_port->criteria == BCM_MIM_PORT_MATCH_SHARE) { 4228 /* There is no criteria to be configurated for shared vp, 4229 * only updating software state to indicate this is a shared vp */ 4230 MIM_INFO(unit)->port_info[vp].flags |= _BCM_MIM_PORT_TYPE_ACCESS_SHARED; 4231 return BCM_E_NONE; 4232 } 4233 4234 rv = _bcm_esw_gport_resolve(unit, mim_port->port, &mod_out, 4235 &port_out, &trunk_id, &gport_id); 4236 BCM_IF_ERROR_RETURN(rv); 4237 4238 #if defined(BCM_KATANA2_SUPPORT) 4239 if (BCM_GPORT_IS_SET(mim_port->port) && 4240 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 4241 mim_port->port)) { 4242 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 4243 if (_bcm_kt2_mod_is_coe_mod_check(unit, mod_out) == BCM_E_NONE) { 4244 rv = _bcm_kt2_modport_to_pp_port_get( 4245 unit, mod_out, port_out, &pp_port); 4246 #if defined BCM_METROLITE_SUPPORT 4247 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 4248 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 4249 is_local_subport = TRUE; 4250 } 4251 } else 4252 #endif 4253 { 4254 if ((pp_port >= min_subport) && 4255 (pp_port <= max_subport)) { 4256 is_local_subport = TRUE; 4257 } 4258 } 4259 } 4260 } 4261 #endif 4262 4263 4264 if ((mim_port->criteria == BCM_MIM_PORT_MATCH_PORT_VLAN) || 4265 (mim_port->criteria == BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED)) { 4266 uint32 vent[SOC_MAX_MEM_WORDS]; 4267 int xlate_index = -1; 4268 uint32 return_vent[SOC_MAX_MEM_WORDS]; 4269 4270 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4271 #if defined(BCM_TRIDENT3_SUPPORT) 4272 if (soc_feature(unit, soc_feature_base_valid)) { 4273 soc_mem_field32_set(unit, xlate_mem, 4274 vent, BASE_VALID_0f, 0x3); 4275 soc_mem_field32_set(unit, xlate_mem, 4276 vent, BASE_VALID_1f, 0x7); 4277 } else 4278 #endif 4279 { 4280 soc_mem_field32_set(unit, xlate_mem, vent, VALIDf, 1); 4281 } 4282 soc_mem_field32_set(unit, xlate_mem, vent, MPLS_ACTIONf, 0x1); /* SVP */ 4283 soc_mem_field32_set(unit, xlate_mem, vent, DISABLE_VLAN_CHECKSf, 1); 4284 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_VPf, vp); 4285 #if defined(BCM_TRIDENT2_SUPPORT) 4286 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 4287 SOC_IS_TRIDENT3X(unit)) { 4288 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_TYPEf, 1); 4289 soc_mem_field32_set(unit, xlate_mem, vent, VLAN_ACTION_VALIDf, 1); 4290 } 4291 #endif /* BCM_TRIDENT2_SUPPORT */ 4292 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4293 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 4294 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 4295 _BCM_MIM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 4296 soc_mem_field32_set(unit, xlate_mem, vent, XLATE__VFIf, vfi); 4297 } 4298 #endif 4299 #if defined(BCM_KATANA2_SUPPORT) 4300 if (SOC_IS_KATANA2(unit)) { 4301 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_TYPEf, 1); 4302 } 4303 #endif /* BCM_KATANA2_SUPPORT */ 4304 4305 if (mim_port->criteria == BCM_MIM_PORT_MATCH_PORT_VLAN) { 4306 if (!BCM_VLAN_VALID(mim_port->match_vlan)) { 4307 return BCM_E_PARAM; 4308 } 4309 soc_mem_field32_set(unit, xlate_mem, vent, KEY_TYPEf, 4310 TR_VLXLT_HASH_KEY_TYPE_OVID); 4311 if (soc_mem_field_valid(unit, xlate_mem, DATA_TYPEf)) { 4312 soc_mem_field32_set(unit, xlate_mem, vent, DATA_TYPEf, 4313 TR_VLXLT_HASH_KEY_TYPE_OVID); 4314 } 4315 soc_mem_field32_set(unit, xlate_mem, vent, OVIDf, 4316 mim_port->match_vlan); 4317 if (!(MIM_INFO(unit)->port_info[vp].flags & 4318 _BCM_MIM_PORT_TYPE_ACCESS_SHARED)) { 4319 MIM_INFO(unit)->port_info[vp].flags |= 4320 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN; 4321 MIM_INFO(unit)->port_info[vp].match_vlan = mim_port->match_vlan; 4322 } 4323 } else { 4324 if (!BCM_VLAN_VALID(mim_port->match_vlan) || 4325 !BCM_VLAN_VALID(mim_port->match_inner_vlan)) { 4326 return BCM_E_PARAM; 4327 } 4328 soc_mem_field32_set(unit, xlate_mem, vent, KEY_TYPEf, 4329 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 4330 soc_mem_field32_set(unit, xlate_mem, vent, OVIDf, 4331 mim_port->match_vlan); 4332 soc_mem_field32_set(unit, xlate_mem, vent, IVIDf, 4333 mim_port->match_inner_vlan); 4334 if (!(MIM_INFO(unit)->port_info[vp].flags & 4335 _BCM_MIM_PORT_TYPE_ACCESS_SHARED)) { 4336 MIM_INFO(unit)->port_info[vp].flags |= 4337 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED; 4338 MIM_INFO(unit)->port_info[vp].match_vlan = mim_port->match_vlan; 4339 MIM_INFO(unit)->port_info[vp].match_inner_vlan = 4340 mim_port->match_inner_vlan; 4341 } 4342 } 4343 4344 if (BCM_GPORT_IS_TRUNK(mim_port->port)) { 4345 soc_mem_field32_set(unit, xlate_mem, vent, Tf, 1); 4346 soc_mem_field32_set(unit, xlate_mem, vent, TGIDf, trunk_id); 4347 } else { 4348 soc_mem_field32_set(unit, xlate_mem, vent, MODULE_IDf, mod_out); 4349 soc_mem_field32_set(unit, xlate_mem, vent, PORT_NUMf, port_out); 4350 } 4351 rv = soc_mem_search(unit, xlate_mem, MEM_BLOCK_ANY, &xlate_index, 4352 vent, return_vent, 0); 4353 if (BCM_E_NONE == rv) { 4354 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4355 BCM_IF_ERROR_RETURN( 4356 soc_mem_write(unit, 4357 xlate_mem, MEM_BLOCK_ALL, xlate_index, vent)); 4358 } else { 4359 return BCM_E_EXISTS; 4360 } 4361 } else if (BCM_E_NOT_FOUND == rv) { 4362 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4363 return BCM_E_NOT_FOUND; 4364 } 4365 rv = soc_mem_insert(unit, xlate_mem, MEM_BLOCK_ALL, vent); 4366 BCM_IF_ERROR_RETURN(rv); 4367 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 4368 } else { 4369 return rv; 4370 } 4371 } else if (mim_port->criteria == BCM_MIM_PORT_MATCH_PORT) { 4372 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4373 if (!((MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK) || 4374 (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_ACCESS_PORT))) { 4375 BCM_IF_ERROR_RETURN(BCM_E_NOT_FOUND); 4376 } 4377 4378 if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK) { 4379 int trunk_id = 0;; 4380 trunk_id = MIM_INFO(unit)->port_info[vp].index; 4381 rv = _bcm_tr_mim_match_trunk_delete(unit, trunk_id, vp); 4382 BCM_IF_ERROR_RETURN(rv); 4383 } 4384 4385 if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_ACCESS_PORT) { 4386 int port= 0; 4387 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4388 MIM_INFO(unit)->port_info[vp].index, 4389 SOURCE_VPf, 0); 4390 BCM_IF_ERROR_RETURN(rv); 4391 4392 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf)) { 4393 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4394 MIM_INFO(unit)->port_info[vp].index, 4395 SVP_VALIDf, 0); 4396 BCM_IF_ERROR_RETURN(rv); 4397 } 4398 4399 port = MIM_INFO(unit)->port_info[vp].index & SOC_PORT_ADDR_MAX(unit); 4400 #if defined(BCM_TRIDENT3_SUPPORT) 4401 if(SOC_IS_TRIDENT3X(unit)) { 4402 rv = _bcm_esw_port_tab_set( 4403 unit, port, _BCM_CPU_TABS_NONE, 4404 PORT_OPERATIONf, 0x0); /* NORMAL */ 4405 } else 4406 #endif 4407 { 4408 rv = soc_mem_field32_modify(unit, port_mem, port, 4409 PORT_OPERATIONf, 0x0); /* NORMAL */ 4410 } 4411 BCM_IF_ERROR_RETURN(rv); 4412 } 4413 } 4414 4415 if (BCM_GPORT_IS_TRUNK(mim_port->port)) { 4416 rv = _bcm_tr2_mim_match_trunk_add(unit, trunk_id, vp); 4417 if (rv >= 0) { 4418 MIM_INFO(unit)->port_info[vp].flags |= 4419 _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK; 4420 MIM_INFO(unit)->port_info[vp].index = trunk_id; 4421 } 4422 BCM_IF_ERROR_RETURN(rv); 4423 } else { 4424 int is_local; 4425 4426 BCM_IF_ERROR_RETURN 4427 ( _bcm_esw_modid_is_local(unit, mod_out, &is_local)); 4428 4429 /* Get index to source trunk map table */ 4430 BCM_IF_ERROR_RETURN( 4431 _bcm_esw_src_mod_port_table_index_get(unit, mod_out, 4432 port_out, &i)); 4433 4434 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4435 i, SOURCE_VPf, vp); 4436 BCM_IF_ERROR_RETURN(rv); 4437 4438 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf)) { 4439 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4440 i, SVP_VALIDf, 1); 4441 BCM_IF_ERROR_RETURN(rv); 4442 } 4443 4444 if (is_local) { 4445 #if defined(BCM_TRIDENT3_SUPPORT) 4446 if(SOC_IS_TRIDENT3X(unit)) { 4447 rv = _bcm_esw_port_tab_set( 4448 unit, port_out, _BCM_CPU_TABS_NONE, 4449 PORT_OPERATIONf, 0x1); /* L2_SVP2_SVP */ 4450 } else 4451 #endif 4452 { 4453 rv = soc_mem_field32_modify(unit, port_mem, port_out, 4454 PORT_OPERATIONf, 0x1); /* L2_SVP */ 4455 } 4456 BCM_IF_ERROR_RETURN(rv); 4457 } 4458 #ifdef BCM_KATANA2_SUPPORT 4459 if (soc_feature(unit, soc_feature_linkphy_coe) || 4460 soc_feature(unit, soc_feature_linkphy_coe)) { 4461 if (is_local_subport) { 4462 rv = soc_mem_field32_modify(unit, port_mem, port_out, 4463 PORT_OPERATIONf, 0x1); /* L2_SVP */ 4464 BCM_IF_ERROR_RETURN(rv); 4465 } 4466 } 4467 #endif 4468 MIM_INFO(unit)->port_info[vp].flags |= 4469 _BCM_MIM_PORT_TYPE_ACCESS_PORT; 4470 MIM_INFO(unit)->port_info[vp].index = i; 4471 } 4472 4473 } else if ((mim_port->criteria == BCM_MIM_PORT_MATCH_LABEL)) { 4474 uint32 ment[SOC_MAX_MEM_WORDS]; 4475 int index = -1; 4476 uint32 return_ment[SOC_MAX_MEM_WORDS]; 4477 soc_mem_t mpls_mem = MPLS_ENTRYm; 4478 4479 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4480 if (BCM_GPORT_IS_TRUNK(mim_port->port)) { 4481 soc_mem_field32_set(unit, mpls_mem, ment, Tf, 1); 4482 soc_mem_field32_set(unit, mpls_mem, ment, TGIDf, trunk_id); 4483 } else { 4484 soc_mem_field32_set(unit, mpls_mem, ment, MODULE_IDf, mod_out); 4485 soc_mem_field32_set(unit, mpls_mem, ment, PORT_NUMf, port_out); 4486 } 4487 soc_mem_field32_set(unit, mpls_mem, ment, MPLS_LABELf, 4488 mim_port->match_label); 4489 #if defined(BCM_TRIDENT3_SUPPORT) 4490 if (soc_feature(unit, soc_feature_base_valid)) { 4491 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_0f, 3); 4492 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_1f, 7); 4493 } else 4494 #endif 4495 { 4496 soc_mem_field32_set(unit, mpls_mem, ment, VALIDf, 0x1); 4497 } 4498 soc_mem_field32_set(unit, mpls_mem, ment, SOURCE_VPf, vp); 4499 soc_mem_field32_set(unit, mpls_mem, ment, MPLS_ACTION_IF_BOSf, 4500 0x1); /* L2 SVP */ 4501 soc_mem_field32_set(unit, mpls_mem, ment, MPLS_ACTION_IF_NOT_BOSf, 4502 0x0); /* INVALID */ 4503 rv = soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, &index, 4504 ment, return_ment, 0); 4505 if (BCM_E_NONE == rv) { 4506 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4507 BCM_IF_ERROR_RETURN( 4508 soc_mem_write(unit, 4509 mpls_mem, MEM_BLOCK_ALL, index, ment)); 4510 } else { 4511 return BCM_E_EXISTS; 4512 } 4513 } else if (BCM_E_NOT_FOUND == rv) { 4514 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4515 return BCM_E_NOT_FOUND; 4516 } 4517 rv = soc_mem_insert(unit, mpls_mem, MEM_BLOCK_ALL, ment); 4518 BCM_IF_ERROR_RETURN(rv); 4519 } else { 4520 return rv; 4521 } 4522 MIM_INFO(unit)->port_info[vp].flags |= 4523 _BCM_MIM_PORT_TYPE_ACCESS_LABEL; 4524 MIM_INFO(unit)->port_info[vp].match_label = mim_port->match_label; 4525 4526 } else if ((mim_port->criteria == BCM_MIM_PORT_MATCH_TUNNEL_VLAN_SRCMAC)) { 4527 uint32 ment[SOC_MAX_MEM_WORDS]; 4528 uint64 temp_mac; 4529 int index = -1; 4530 uint32 return_ment[SOC_MAX_MEM_WORDS]; 4531 soc_mem_t mpls_mem = MPLS_ENTRYm; 4532 4533 if (!BCM_VLAN_VALID(mim_port->match_tunnel_vlan)) { 4534 return BCM_E_PARAM; 4535 } 4536 4537 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4538 soc_mem_field32_set(unit, mpls_mem, ment, KEY_TYPEf, 1); /* MIM NVP */ 4539 #if defined(BCM_TRIDENT3_SUPPORT) 4540 if (soc_mem_field_valid(unit, mpls_mem, DATA_TYPEf)) { 4541 soc_mem_field32_set(unit, mpls_mem, ment, DATA_TYPEf, 1); 4542 } 4543 #endif 4544 if (BCM_GPORT_IS_TRUNK(mim_port->port)) { 4545 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__Tf, 1); 4546 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__TGIDf, trunk_id); 4547 } else { 4548 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__MODULE_IDf, mod_out); 4549 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__PORT_NUMf, port_out); 4550 } 4551 if (mim_port->flags & BCM_MIM_PORT_TYPE_PEER) { 4552 soc_mem_field32_set(unit, mpls_mem, ment, 4553 MIM_NVP__ISID_LOOKUP_TYPEf, 1); 4554 MIM_INFO(unit)->port_info[vp].flags |= 4555 _BCM_MIM_PORT_TYPE_PEER; 4556 #if defined(BCM_TRIDENT_SUPPORT) 4557 if (soc_feature(unit, soc_feature_mim_peer_sharing) && 4558 (mim_port->flags & BCM_MIM_PORT_SHARE)) { 4559 MIM_INFO(unit)->port_info[vp].flags |= 4560 _BCM_MIM_PORT_TYPE_SHARE; 4561 4562 } 4563 #endif /* BCM_TRIDENT_SUPPORT */ 4564 } else { 4565 MIM_INFO(unit)->port_info[vp].flags |= 4566 _BCM_MIM_PORT_TYPE_NETWORK; 4567 } 4568 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4569 if (soc_feature(unit, soc_feature_ingress_failover)) { 4570 int local_failover_id = 0; 4571 int prot_type = 0; 4572 if (mim_port->flags & BCM_MIM_PORT_FAILOVER_DROP) { 4573 soc_mem_field32_set(unit, mpls_mem, ment, 4574 MIM_NVP__DROP_DATA_ENABLEf, 1); 4575 } else { 4576 soc_mem_field32_set(unit, mpls_mem, ment, 4577 MIM_NVP__DROP_DATA_ENABLEf, 0); 4578 } 4579 4580 if (mim_port->ingress_failover_id != 0) { 4581 local_failover_id = mim_port->ingress_failover_id; 4582 _BCM_GET_FAILOVER_TYPE(local_failover_id, prot_type); 4583 _BCM_GET_FAILOVER_ID(local_failover_id); 4584 4585 if ((prot_type & _BCM_FAILOVER_INGRESS) && 4586 (BCM_SUCCESS(_bcm_td2p_failover_ingress_id_validate( 4587 unit, local_failover_id)))) { 4588 soc_mem_field32_set(unit, mpls_mem, ment, 4589 MIM_NVP__RX_PROT_GROUPf, 4590 local_failover_id); 4591 } 4592 } else { 4593 soc_mem_field32_set(unit, mpls_mem, ment, 4594 MIM_NVP__RX_PROT_GROUPf, 0); 4595 } 4596 } 4597 #endif 4598 #if defined(BCM_TRIDENT3_SUPPORT) 4599 if (soc_feature(unit, soc_feature_base_valid)) { 4600 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_0f, 3); 4601 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_1f, 7); 4602 } else 4603 #endif 4604 { 4605 soc_mem_field32_set(unit, mpls_mem, ment, VALIDf, 0x1); 4606 } 4607 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__SVPf, vp); 4608 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__BVIDf, 4609 mim_port->match_tunnel_vlan); 4610 soc_mem_mac_addr_set(unit, mpls_mem, ment, MIM_NVP__BMACSAf, 4611 mim_port->match_tunnel_srcmac); 4612 rv = soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, &index, 4613 ment, return_ment, 0); 4614 if (BCM_E_NONE == rv) { 4615 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4616 BCM_IF_ERROR_RETURN( 4617 soc_mem_write(unit, 4618 mpls_mem, MEM_BLOCK_ALL, index, ment)); 4619 } else { 4620 return BCM_E_EXISTS; 4621 } 4622 } else if (BCM_E_NOT_FOUND == rv) { 4623 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 4624 return BCM_E_NOT_FOUND; 4625 } 4626 rv = soc_mem_insert(unit, mpls_mem, MEM_BLOCK_ALL, ment); 4627 BCM_IF_ERROR_RETURN(rv); 4628 } else { 4629 return rv; 4630 } 4631 SAL_MAC_ADDR_TO_UINT64(mim_port->match_tunnel_srcmac, temp_mac); 4632 SAL_MAC_ADDR_FROM_UINT64 4633 (MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac, temp_mac); 4634 MIM_INFO(unit)->port_info[vp].match_tunnel_vlan = 4635 mim_port->match_tunnel_vlan; 4636 } 4637 return rv; 4638 } 4639 4640 int 4641 _bcm_tr2_mim_match_delete(int unit, int vp, bcm_mim_port_t mim_port) 4642 { 4643 int port, rv; 4644 int is_local; 4645 bcm_module_t mod_out; 4646 soc_mem_t xlate_mem; 4647 soc_mem_t port_mem; 4648 4649 #if defined(BCM_TRIDENT3_SUPPORT) 4650 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 4651 port_mem = ING_DEVICE_PORTm; 4652 } else 4653 #endif 4654 { 4655 port_mem = PORT_TABm; 4656 } 4657 #if defined(BCM_TRIDENT3_SUPPORT) 4658 if (soc_feature(unit, soc_feature_base_valid)) { 4659 xlate_mem = VLAN_XLATE_1_DOUBLEm; 4660 } else 4661 #endif 4662 { 4663 xlate_mem = VLAN_XLATEm; 4664 } 4665 4666 if (MIM_INFO(unit)->port_info[vp].flags & 4667 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN) { 4668 uint32 vent[SOC_MAX_MEM_WORDS]; 4669 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4670 4671 #if defined(BCM_TRIDENT3_SUPPORT) 4672 if (soc_feature(unit, soc_feature_base_valid)) { 4673 soc_mem_field32_set(unit, xlate_mem, 4674 vent, BASE_VALID_0f, 0x3); 4675 soc_mem_field32_set(unit, xlate_mem, 4676 vent, BASE_VALID_1f, 0x7); 4677 } else 4678 #endif 4679 { 4680 soc_mem_field32_set(unit, xlate_mem, vent, VALIDf, 1); 4681 } 4682 4683 soc_mem_field32_set(unit, xlate_mem, vent, KEY_TYPEf, 4684 TR_VLXLT_HASH_KEY_TYPE_OVID); 4685 if (soc_mem_field_valid(unit, xlate_mem, DATA_TYPEf)) { 4686 soc_mem_field32_set(unit, xlate_mem, vent, DATA_TYPEf, 4687 TR_VLXLT_HASH_KEY_TYPE_OVID); 4688 } 4689 soc_mem_field32_set(unit, xlate_mem, vent, OVIDf, 4690 MIM_INFO(unit)->port_info[vp].match_vlan); 4691 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 4692 4693 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_KATANA2(unit) || 4694 SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 4695 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_TYPEf, 1); 4696 } 4697 #endif /* BCM_TRIDENT2_SUPPORT || BCM_KATANA2_SUPPORT */ 4698 if (MIM_INFO(unit)->port_info[vp].modid != -1) { 4699 soc_mem_field32_set(unit, xlate_mem, vent, MODULE_IDf, 4700 MIM_INFO(unit)->port_info[vp].modid); 4701 soc_mem_field32_set(unit, xlate_mem, vent, PORT_NUMf, 4702 MIM_INFO(unit)->port_info[vp].port); 4703 } else { 4704 soc_mem_field32_set(unit, xlate_mem, vent, Tf, 1); 4705 soc_mem_field32_set(unit, xlate_mem, vent, TGIDf, 4706 MIM_INFO(unit)->port_info[vp].tgid); 4707 } 4708 rv = soc_mem_delete(unit, xlate_mem, MEM_BLOCK_ANY, vent); 4709 if (rv != BCM_E_NOT_FOUND) { 4710 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 4711 return rv; /* Match has been deleted by bcm_port_match_delete */ 4712 } 4713 4714 } else if (MIM_INFO(unit)->port_info[vp].flags & 4715 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED) { 4716 uint32 vent[SOC_MAX_MEM_WORDS]; 4717 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4718 4719 soc_mem_field32_set(unit, xlate_mem, vent, KEY_TYPEf, 4720 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 4721 if (soc_mem_field_valid(unit, xlate_mem, DATA_TYPEf)) { 4722 soc_mem_field32_set(unit, xlate_mem, vent, DATA_TYPEf, 4723 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 4724 } 4725 soc_mem_field32_set(unit, xlate_mem, vent, OVIDf, 4726 MIM_INFO(unit)->port_info[vp].match_vlan); 4727 soc_mem_field32_set(unit, xlate_mem, vent, IVIDf, 4728 MIM_INFO(unit)->port_info[vp].match_inner_vlan); 4729 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 4730 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_TYPEf, 1); 4731 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_KATANA2(unit) || 4732 SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 4733 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_TYPEf, 1); 4734 } 4735 #endif /* BCM_TRIDENT2_SUPPORT || BCM_KATANA2_SUPPORT */ 4736 4737 if (MIM_INFO(unit)->port_info[vp].modid != -1) { 4738 soc_mem_field32_set(unit, xlate_mem, vent, MODULE_IDf, 4739 MIM_INFO(unit)->port_info[vp].modid); 4740 soc_mem_field32_set(unit, xlate_mem, vent, PORT_NUMf, 4741 MIM_INFO(unit)->port_info[vp].port); 4742 } else { 4743 soc_mem_field32_set(unit, xlate_mem, vent, Tf, 1); 4744 soc_mem_field32_set(unit, xlate_mem, vent, TGIDf, 4745 MIM_INFO(unit)->port_info[vp].tgid); 4746 } 4747 rv = soc_mem_delete(unit, xlate_mem, MEM_BLOCK_ANY, vent); 4748 BCM_IF_ERROR_RETURN(rv); 4749 4750 } else if (MIM_INFO(unit)->port_info[vp].flags & 4751 _BCM_MIM_PORT_TYPE_ACCESS_PORT) { 4752 rv = _bcm_esw_src_modid_port_get(unit, 4753 MIM_INFO(unit)->port_info[vp].index, 4754 &mod_out, &port); 4755 BCM_IF_ERROR_RETURN(rv); 4756 rv = _bcm_esw_modid_is_local(unit, mod_out, &is_local); 4757 BCM_IF_ERROR_RETURN(rv); 4758 4759 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4760 MIM_INFO(unit)->port_info[vp].index, 4761 SOURCE_VPf, 0); 4762 BCM_IF_ERROR_RETURN(rv); 4763 4764 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf)) { 4765 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 4766 MIM_INFO(unit)->port_info[vp].index, 4767 SVP_VALIDf, 0); 4768 4769 BCM_IF_ERROR_RETURN(rv); 4770 } 4771 4772 if (is_local) { 4773 #if defined(BCM_TRIDENT3_SUPPORT) 4774 if(SOC_IS_TRIDENT3X(unit)) { 4775 rv = _bcm_esw_port_tab_set( 4776 unit, port, _BCM_CPU_TABS_NONE, 4777 PORT_OPERATIONf, 0x0); /* NORMAL */ 4778 } else 4779 #endif 4780 { 4781 rv = soc_mem_field32_modify(unit, port_mem, port, 4782 PORT_OPERATIONf, 0x0); /* NORMAL */ 4783 BCM_IF_ERROR_RETURN(rv); 4784 } 4785 } 4786 4787 } else if(MIM_INFO(unit)->port_info[vp].flags & 4788 _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK) { 4789 int trunk_id; 4790 trunk_id = MIM_INFO(unit)->port_info[vp].index; 4791 rv = _bcm_tr_mim_match_trunk_delete(unit, trunk_id, vp); 4792 BCM_IF_ERROR_RETURN(rv); 4793 } else if (MIM_INFO(unit)->port_info[vp].flags & 4794 _BCM_MIM_PORT_TYPE_ACCESS_LABEL) { 4795 uint32 ment[SOC_MAX_MEM_WORDS]; 4796 soc_mem_t mpls_mem = MPLS_ENTRYm; 4797 4798 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4799 if (MIM_INFO(unit)->port_info[vp].modid != -1) { 4800 soc_mem_field32_set(unit, mpls_mem, ment, MODULE_IDf, 4801 MIM_INFO(unit)->port_info[vp].modid); 4802 soc_mem_field32_set(unit, mpls_mem, ment, PORT_NUMf, 4803 MIM_INFO(unit)->port_info[vp].port); 4804 } else { 4805 soc_mem_field32_set(unit, mpls_mem, ment, Tf, 1); 4806 soc_mem_field32_set(unit, mpls_mem, ment, TGIDf, 4807 MIM_INFO(unit)->port_info[vp].tgid); 4808 } 4809 soc_mem_field32_set(unit, mpls_mem, ment, MPLS_LABELf, 4810 MIM_INFO(unit)->port_info[vp].match_label); 4811 rv = soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ANY, ment); 4812 BCM_IF_ERROR_RETURN(rv); 4813 } else if (MIM_INFO(unit)->port_info[vp].flags & 4814 _BCM_MIM_PORT_TYPE_ACCESS_SHARED) { 4815 uint32 vent[SOC_MAX_MEM_WORDS]; 4816 bcm_module_t mod_out = -1; 4817 bcm_port_t port_out = -1; 4818 int gport_id =-1; 4819 bcm_trunk_t trunk_id; 4820 4821 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4822 4823 soc_mem_field32_set(unit, xlate_mem, vent, SOURCE_TYPEf, 1); 4824 #if defined(BCM_TRIDENT3_SUPPORT) 4825 if (soc_feature(unit, soc_feature_base_valid)) { 4826 soc_mem_field32_set(unit, xlate_mem, 4827 vent, BASE_VALID_0f, 0x3); 4828 soc_mem_field32_set(unit, xlate_mem, 4829 vent, BASE_VALID_1f, 0x7); 4830 } else 4831 #endif 4832 { 4833 soc_mem_field32_set(unit, xlate_mem, vent, VALIDf, 1); 4834 } 4835 if (BCM_MIM_PORT_MATCH_PORT_VLAN == mim_port.criteria) { 4836 soc_mem_field32_set(unit, xlate_mem, vent, KEY_TYPEf, 4837 TR_VLXLT_HASH_KEY_TYPE_OVID); 4838 soc_mem_field32_set(unit, xlate_mem, vent, XLATE__OVIDf, 4839 mim_port.match_vlan); 4840 } else if (BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED == mim_port.criteria) { 4841 soc_mem_field32_set(unit, xlate_mem, vent, KEY_TYPEf, 4842 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 4843 soc_mem_field32_set(unit, xlate_mem, vent, XLATE__OVIDf, 4844 mim_port.match_vlan); 4845 soc_mem_field32_set(unit, xlate_mem, vent, XLATE__IVIDf, 4846 mim_port.match_inner_vlan); 4847 } else { 4848 return BCM_E_UNAVAIL; 4849 } 4850 4851 rv = _bcm_esw_gport_resolve(unit, mim_port.port, &mod_out, 4852 &port_out, &trunk_id, &gport_id); 4853 BCM_IF_ERROR_RETURN(rv); 4854 4855 if (BCM_GPORT_IS_TRUNK(mim_port.port)) { 4856 soc_mem_field32_set(unit, xlate_mem, vent, Tf, 1); 4857 soc_mem_field32_set(unit, xlate_mem, vent, TGIDf, trunk_id); 4858 } else { 4859 soc_mem_field32_set(unit, xlate_mem, vent, MODULE_IDf, mod_out); 4860 soc_mem_field32_set(unit, xlate_mem, vent, PORT_NUMf, port_out); 4861 } 4862 4863 rv = soc_mem_delete(unit, xlate_mem, MEM_BLOCK_ANY, vent); 4864 BCM_IF_ERROR_RETURN(rv); 4865 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 4866 } else if (MIM_INFO(unit)->port_info[vp].flags & 4867 (_BCM_MIM_PORT_TYPE_NETWORK | _BCM_MIM_PORT_TYPE_PEER)) { 4868 uint32 ment[SOC_MAX_MEM_WORDS]; 4869 soc_mem_t mpls_mem = MPLS_ENTRYm; 4870 4871 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4872 soc_mem_field32_set(unit, mpls_mem, ment, KEY_TYPEf, 1); /* MIM NVP */ 4873 #if defined(BCM_TRIDENT3_SUPPORT) 4874 if (soc_feature(unit, soc_feature_base_valid)) { 4875 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_0f, 3); 4876 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_1f, 7); 4877 } else 4878 #endif 4879 { 4880 soc_mem_field32_set(unit, mpls_mem, ment, VALIDf, 0x1); 4881 } 4882 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__BVIDf, 4883 MIM_INFO(unit)->port_info[vp].match_tunnel_vlan); 4884 soc_mem_mac_addr_set(unit, mpls_mem, ment, MIM_NVP__BMACSAf, 4885 MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac); 4886 rv = soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ALL, ment); 4887 BCM_IF_ERROR_RETURN(rv); 4888 } 4889 return BCM_E_NONE; 4890 } 4891 4892 STATIC int 4893 _bcm_tr2_mim_peer_port_config_add(int unit, bcm_mim_port_t *mim_port, 4894 int vp, bcm_mim_vpn_t vpn) { 4895 uint32 ment[SOC_MAX_MEM_WORDS]; 4896 uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS]; 4897 int index, vfi, rv = BCM_E_NONE; 4898 soc_mem_t egr_xlate_mem; 4899 soc_mem_t mpls_mem = MPLS_ENTRYm; 4900 4901 #if defined(BCM_TRIDENT3_SUPPORT) 4902 if (soc_feature(unit, soc_feature_base_valid)) { 4903 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 4904 } else 4905 #endif 4906 { 4907 egr_xlate_mem = EGR_VLAN_XLATEm; 4908 } 4909 4910 /* Need an ISID-SVP entry in MPLS_ENTRY */ 4911 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 4912 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4913 4914 soc_mem_field32_set(unit, mpls_mem, ment, KEY_TYPEf, 3); /* MIM_ISID_SVP */ 4915 #if defined(BCM_TRIDENT3_SUPPORT) 4916 if (soc_feature(unit, soc_feature_base_valid)) { 4917 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_0f, 3); 4918 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_1f, 7); 4919 } else 4920 #endif 4921 { 4922 soc_mem_field32_set(unit, mpls_mem, ment, VALIDf, 0x1); 4923 } 4924 if (mim_port->flags & BCM_MIM_PORT_EGRESS_TUNNEL_SERVICE_REPLACE) { 4925 soc_mem_field32_set(unit, mpls_mem, ment, MIM_ISID__ISIDf, 4926 (mim_port->egress_tunnel_service & 0xffffff)); 4927 } else { 4928 soc_mem_field32_set(unit, mpls_mem, ment, MIM_ISID__ISIDf, 4929 VPN_ISID(unit, vfi)); 4930 } 4931 soc_mem_field32_set(unit, mpls_mem, ment, MIM_ISID__SVPf, vp); 4932 soc_mem_field32_set(unit, mpls_mem, ment, MIM_ISID__VFIf, vfi); 4933 rv = soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, &index, 4934 ment, ment, 0); 4935 if (rv == SOC_E_NONE) { 4936 return BCM_E_EXISTS; 4937 } else if (rv != SOC_E_NOT_FOUND) { 4938 return rv; 4939 } 4940 BCM_IF_ERROR_RETURN(soc_mem_insert(unit, mpls_mem, MEM_BLOCK_ALL, ment)); 4941 4942 /* Also need the reverse entry in the egress */ 4943 sal_memset(egr_vlan_xlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 4944 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__VFIf, 4945 vfi); 4946 #if defined(BCM_TRIDENT3_SUPPORT) 4947 if (soc_feature(unit, soc_feature_base_valid)) { 4948 soc_mem_field32_set(unit, egr_xlate_mem, 4949 egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 4950 soc_mem_field32_set(unit, egr_xlate_mem, 4951 egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 4952 soc_mem_field32_set(unit, egr_xlate_mem, 4953 egr_vlan_xlate_entry, DATA_TYPEf, 0x4); 4954 soc_mem_field32_set(unit, egr_xlate_mem, 4955 egr_vlan_xlate_entry, KEY_TYPEf, 0x4); 4956 } else 4957 #endif 4958 { 4959 soc_mem_field32_set(unit, egr_xlate_mem, 4960 egr_vlan_xlate_entry, VALIDf, 0x1); 4961 soc_mem_field32_set(unit, egr_xlate_mem, 4962 egr_vlan_xlate_entry, ENTRY_TYPEf, 0x4); 4963 } 4964 4965 if (mim_port->flags & BCM_MIM_PORT_EGRESS_TUNNEL_SERVICE_REPLACE) { 4966 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 4967 MIM_ISID__ISIDf, 4968 (mim_port->egress_tunnel_service & 0xffffff)); 4969 } else { 4970 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 4971 MIM_ISID__ISIDf, VPN_ISID(unit, vfi)); 4972 } 4973 4974 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 4975 MIM_ISID__DVPf, vp); 4976 4977 /* Deal with egress SD tag actions */ 4978 if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TAGGED) { 4979 BCM_IF_ERROR_RETURN 4980 (_bcm_tr2_mim_egr_vxlt_sd_tag_actions(unit, mim_port, NULL, 4981 egr_vlan_xlate_entry)); 4982 } 4983 4984 rv = soc_mem_search(unit, egr_xlate_mem, MEM_BLOCK_ANY, &index, 4985 egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0); 4986 if (rv == SOC_E_NONE) { 4987 return BCM_E_EXISTS; 4988 } else if (rv != SOC_E_NOT_FOUND) { 4989 return rv; 4990 } 4991 rv = soc_mem_insert(unit, egr_xlate_mem, MEM_BLOCK_ALL, egr_vlan_xlate_entry); 4992 if (rv < 0) { 4993 return rv; 4994 } 4995 #if defined(BCM_TRIDENT_SUPPORT) 4996 if (soc_feature(unit, soc_feature_mim_peer_sharing) && 4997 !(mim_port->flags & BCM_MIM_PORT_REPLACE)) { 4998 MIM_INFO(unit)->port_info[vp].vfi_count++; 4999 } 5000 #endif /* BCM_TRIDENT_SUPPORT */ 5001 5002 return BCM_E_NONE; 5003 } 5004 5005 /* Function: 5006 * _bcm_tr2_mim_vpn_is_eline 5007 * Purpose: 5008 * Find if given MIM VPN is ELINE 5009 * Parameters: 5010 * unit - Device Number 5011 * vpn - MIM VPN 5012 * is_eline - Flag 5013 * Returns: 5014 * BCM_E_XXXX 5015 * Assumes: 5016 * l2vpn is valid 5017 */ 5018 5019 STATIC int 5020 _bcm_tr2_mim_vpn_is_eline( int unit, bcm_mim_vpn_t vpn, int *is_eline) 5021 { 5022 vfi_entry_t vfi_entry; 5023 bcm_vpn_t mim_vpn_min=0; 5024 int vfi_index = -1; 5025 int num_vfi = 0; 5026 5027 5028 num_vfi = soc_mem_index_count(unit, VFIm); 5029 5030 _BCM_MIM_VPN_SET(mim_vpn_min, _BCM_MIM_VPN_TYPE_MIM, 0); 5031 5032 if (vpn < mim_vpn_min || vpn > (mim_vpn_min + num_vfi - 1) ) { 5033 return BCM_E_PARAM; 5034 } 5035 5036 _BCM_MIM_VPN_GET(vfi_index, _BCM_MIM_VPN_TYPE_MIM, vpn); 5037 5038 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeMim)) { 5039 return BCM_E_NOT_FOUND; 5040 } 5041 5042 /* Read the VFI table to check if point-to-point vpn */ 5043 BCM_IF_ERROR_RETURN 5044 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 5045 5046 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 5047 *is_eline = 1; /* ELINE */ 5048 } 5049 5050 return BCM_E_NONE; 5051 } 5052 5053 /* Function: 5054 * _bcm_tr2_mim_eline_port_add 5055 * Purpose: 5056 * Add a port to VFI table for Point-to-Point(ELINE) service 5057 * Parameters: 5058 * unit - Device Number 5059 * vpn - MIM VPN 5060 * mim_port - MIM port 5061 * Returns: 5062 * BCM_E_XXXX 5063 */ 5064 5065 STATIC int 5066 _bcm_tr2_mim_eline_port_add(int unit, 5067 int current_vp, 5068 bcm_mim_vpn_t vpn, 5069 bcm_mim_port_t *mim_port) 5070 { 5071 5072 vfi_entry_t vfi_entry; 5073 source_vp_entry_t svp0, svp1; 5074 bcm_vpn_t mim_vpn_min=0; 5075 int vfi_index = -1; 5076 int num_vfi = 0; 5077 int vp0 = -1; /* virtual port 1 */ 5078 int vp1 = -1; /* virtual port 2 */ 5079 uint32 vp0_valid = 0, vp1_valid = 0; 5080 soc_field_t field = INVALIDf; 5081 int rv = BCM_E_NONE; 5082 5083 5084 /* 5085 * 1. check if vpn is valid 5086 * 2. get vfi index 5087 * 3. Read VFI entry from the VFI table. 5088 * 4. if PT2PTf is set 5089 * 5. get VP0 and VP1f fields 5090 * 6. If both are set and not REPLACE flag 5091 * return error - BCM_E_FULL 5092 * 7. Add it to vp0 or vp1 5093 */ 5094 5095 num_vfi = soc_mem_index_count(unit, VFIm); 5096 5097 _BCM_MIM_VPN_SET(mim_vpn_min, _BCM_MIM_VPN_TYPE_MIM, 0); 5098 5099 if (vpn < mim_vpn_min || vpn > (mim_vpn_min + num_vfi - 1) ) { 5100 return BCM_E_PARAM; 5101 } 5102 5103 _BCM_MIM_VPN_GET(vfi_index, _BCM_MIM_VPN_TYPE_MIM, vpn); 5104 5105 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeMim)) { 5106 return BCM_E_NOT_FOUND; 5107 } 5108 5109 BCM_IF_ERROR_RETURN 5110 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 5111 5112 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 5113 vp0 = soc_VFIm_field32_get(unit, &vfi_entry, VP_0f); 5114 vp1 = soc_VFIm_field32_get(unit, &vfi_entry, VP_1f); 5115 } else { 5116 return BCM_E_PARAM; 5117 } 5118 5119 if (_bcm_vp_used_get(unit, vp0, _bcmVpTypeMim)) { 5120 BCM_IF_ERROR_RETURN ( 5121 READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp0, &svp0)); 5122 if (soc_SOURCE_VPm_field32_get(unit, &svp0, ENTRY_TYPEf) == 0x1) { 5123 vp0_valid = 1; 5124 } 5125 } 5126 5127 if (_bcm_vp_used_get(unit, vp1, _bcmVpTypeMim)) { 5128 BCM_IF_ERROR_RETURN ( 5129 READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp1, &svp1)); 5130 if (soc_SOURCE_VPm_field32_get(unit, &svp1, ENTRY_TYPEf) == 0x1) { 5131 vp1_valid = 1; 5132 } 5133 } 5134 5135 /* 5136 * if both vp0 and vp1 are valid 5137 * if port flags PORT_REPLACE is not set. 5138 * return BCM_E_FULL only 2 ports are required 5139 * for a point-to-point(ELINE) service 5140 */ 5141 if (vp0_valid && vp1_valid) { 5142 if ((mim_port->flags & BCM_MIM_PORT_REPLACE)) { 5143 if ((current_vp == vp0) || (current_vp == vp1)) { 5144 return BCM_E_NONE; 5145 } else { 5146 return BCM_E_NOT_FOUND; 5147 } 5148 } else { 5149 return BCM_E_FULL; 5150 } 5151 } else if (vp0_valid && !vp1_valid) { 5152 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 5153 if (current_vp != vp0) { 5154 return BCM_E_NOT_FOUND; 5155 } 5156 } 5157 field = VP_1f; 5158 } else if (!vp0_valid && vp1_valid) { 5159 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 5160 if (current_vp != vp1) { 5161 return BCM_E_NOT_FOUND; 5162 } 5163 } 5164 field = VP_0f; 5165 } else if (!vp0_valid && !vp1_valid) { 5166 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 5167 return BCM_E_NOT_FOUND; 5168 } 5169 field = VP_0f; 5170 } 5171 5172 if (field != INVALIDf) { 5173 soc_VFIm_field32_set(unit, &vfi_entry, field, current_vp); 5174 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 5175 } 5176 5177 return rv; 5178 5179 } 5180 5181 /* Function: 5182 * _bcm_tr2_mim_eline_port_delete 5183 * Purpose: 5184 * Delete a port from VFI table for Point-to-Point(ELINE) service 5185 * Parameters: 5186 * unit - Device Number 5187 * vpn - MIM VPN 5188 * vp - MIM virtual port 5189 * Returns: 5190 * BCM_E_XXXX 5191 */ 5192 5193 STATIC int 5194 _bcm_tr2_mim_eline_port_delete(int unit, 5195 bcm_mim_vpn_t vpn, 5196 int vp) 5197 { 5198 5199 vfi_entry_t vfi_entry; 5200 bcm_vpn_t mim_vpn_min=0; 5201 int vfi_index = -1; 5202 int num_vfi = 0; 5203 int vp0 = -1; /* virtual port 1 */ 5204 int vp1 = -1; /* virtual port 2 */ 5205 5206 5207 num_vfi = soc_mem_index_count(unit, VFIm); 5208 5209 _BCM_MIM_VPN_SET(mim_vpn_min, _BCM_MIM_VPN_TYPE_MIM, 0); 5210 5211 if (vpn < mim_vpn_min || vpn > (mim_vpn_min + num_vfi - 1) ) { 5212 return BCM_E_PARAM; 5213 } 5214 5215 _BCM_MIM_VPN_GET(vfi_index, _BCM_MIM_VPN_TYPE_MIM, vpn); 5216 5217 if (!(_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeMim))) { 5218 return BCM_E_NOT_FOUND; 5219 } 5220 5221 BCM_IF_ERROR_RETURN 5222 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 5223 5224 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 5225 vp0 = soc_VFIm_field32_get(unit, &vfi_entry, VP_0f); 5226 vp1 = soc_VFIm_field32_get(unit, &vfi_entry, VP_1f); 5227 } else { 5228 return BCM_E_PARAM; 5229 } 5230 5231 if (vp == vp0) { 5232 soc_VFIm_field32_set(unit, &vfi_entry, VP_0f, 0); 5233 } else if (vp == vp1) { 5234 soc_VFIm_field32_set(unit, &vfi_entry, VP_1f, 0); 5235 } else { 5236 return BCM_E_PARAM; 5237 } 5238 5239 return WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 5240 5241 } 5242 5243 STATIC int 5244 _bcm_tr2_mim_peer_port_config_delete(int unit, int vp, bcm_mim_vpn_t vpn) 5245 { 5246 uint32 ment[SOC_MAX_MEM_WORDS]; 5247 uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS]; 5248 int vfi, rv = BCM_E_NONE; 5249 soc_mem_t egr_xlate_mem; 5250 soc_mem_t mpls_mem = MPLS_ENTRYm; 5251 int isid = -1, index = -1; 5252 5253 #if defined(BCM_TRIDENT3_SUPPORT) 5254 if (soc_feature(unit, soc_feature_base_valid)) { 5255 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 5256 } else 5257 #endif 5258 { 5259 egr_xlate_mem = EGR_VLAN_XLATEm; 5260 } 5261 5262 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 5263 5264 sal_memset(egr_vlan_xlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 5265 #if defined(BCM_TRIDENT3_SUPPORT) 5266 if (soc_feature(unit, soc_feature_base_valid)) { 5267 soc_mem_field32_set(unit, egr_xlate_mem, 5268 egr_vlan_xlate_entry, DATA_TYPEf, 0x4); 5269 soc_mem_field32_set(unit, egr_xlate_mem, 5270 egr_vlan_xlate_entry, KEY_TYPEf, 0x4); 5271 } else 5272 #endif 5273 { 5274 soc_mem_field32_set(unit, egr_xlate_mem, 5275 egr_vlan_xlate_entry, ENTRY_TYPEf, 0x4); 5276 } 5277 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 5278 MIM_ISID__VFIf, vfi); 5279 #if defined(BCM_TRIDENT3_SUPPORT) 5280 if (soc_feature(unit, soc_feature_base_valid)) { 5281 soc_mem_field32_set(unit, egr_xlate_mem, 5282 egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 5283 soc_mem_field32_set(unit, egr_xlate_mem, 5284 egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 5285 } else 5286 #endif 5287 { 5288 soc_mem_field32_set(unit, egr_xlate_mem, 5289 egr_vlan_xlate_entry, VALIDf, 0x1); 5290 } 5291 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, 5292 MIM_ISID__DVPf, vp); 5293 5294 rv = soc_mem_search(unit, egr_xlate_mem, MEM_BLOCK_ANY, &index, 5295 egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0); 5296 BCM_IF_ERROR_RETURN(rv); 5297 5298 isid = soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 5299 MIM_ISID__ISIDf); 5300 5301 /* Delete the ISID-SVP entry in MPLS_ENTRY */ 5302 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 5303 soc_mem_field32_set(unit, mpls_mem, ment, KEY_TYPEf, 3); /* MIM_ISID_SVP */ 5304 #if defined(BCM_TRIDENT3_SUPPORT) 5305 if (soc_feature(unit, soc_feature_base_valid)) { 5306 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_0f, 3); 5307 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_1f, 7); 5308 } else 5309 #endif 5310 { 5311 soc_mem_field32_set(unit, mpls_mem, ment, VALIDf, 0x1); 5312 } 5313 soc_mem_field32_set(unit, mpls_mem, ment, MIM_ISID__ISIDf, isid); 5314 soc_mem_field32_set(unit, mpls_mem, ment, MIM_ISID__SVPf, vp); 5315 rv = soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ANY, ment); 5316 BCM_IF_ERROR_RETURN(rv); 5317 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 5318 /*delete TP_ID from software*/ 5319 BCM_IF_ERROR_RETURN( 5320 _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete(unit, 5321 egr_vlan_xlate_entry)); 5322 #endif 5323 /* Delete the reverse entry in the egress */ 5324 rv = soc_mem_delete(unit, egr_xlate_mem, MEM_BLOCK_ANY, 5325 egr_vlan_xlate_entry); 5326 #if defined(BCM_TRIDENT_SUPPORT) 5327 if (soc_feature(unit, soc_feature_mim_peer_sharing)) { 5328 MIM_INFO(unit)->port_info[vp].vfi_count--; 5329 } 5330 #endif /* BCM_TRIDENT_SUPPORT */ 5331 5332 return BCM_E_NONE; 5333 } 5334 5335 #if defined(BCM_TRIDENT3_SUPPORT) 5336 /* 5337 * Function: 5338 * _bcm_tr2_mim_dvp_set 5339 * Purpose: 5340 * Set Egress DVP tables 5341 * Parameters: 5342 * IN : Unit 5343 * IN : vp 5344 * IN : mim_port 5345 * Returns: 5346 * BCM_E_XXX 5347 */ 5348 STATIC int 5349 _bcm_tr2_mim_dvp_set(int unit, int vp, bcm_mim_port_t *mim_port) 5350 { 5351 int rv = BCM_E_NONE; 5352 egr_dvp_attribute_entry_t egr_dvp_attribute; 5353 int network_group = 0; 5354 soc_mem_t mem = EGR_DVP_ATTRIBUTEm; 5355 5356 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 5357 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 5358 BCM_IF_ERROR_RETURN(rv); 5359 if (SOC_MEM_FIELD_VALID(unit, mem, COMMON__DVP_NETWORK_GROUPf)) { 5360 5361 network_group = mim_port->network_group_id; 5362 rv = _bcm_validate_splithorizon_network_group(unit, 5363 mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE, &network_group); 5364 BCM_IF_ERROR_RETURN(rv); 5365 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 5366 COMMON__DVP_NETWORK_GROUPf, network_group); 5367 } 5368 5369 if (SOC_MEM_FIELD_VALID(unit, mem, COMMON__EVXLT_KEY_SELf)) { 5370 if (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) { 5371 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 5372 COMMON__EVXLT_KEY_SELf, 0x1); 5373 } else if (mim_port->flags & BCM_MIM_PORT_TYPE_PEER) { 5374 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 5375 COMMON__EVXLT_KEY_SELf, 0x2); 5376 } 5377 } 5378 5379 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 5380 BCM_IF_ERROR_RETURN(rv); 5381 5382 return rv; 5383 } 5384 5385 STATIC int 5386 _bcm_tr2_mim_dvp_get(int unit, int vp, bcm_mim_port_t *mim_port) 5387 { 5388 int rv = BCM_E_NONE; 5389 soc_mem_t mem = EGR_DVP_ATTRIBUTEm; 5390 egr_dvp_attribute_entry_t egr_dvp_attribute; 5391 5392 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 5393 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 5394 BCM_IF_ERROR_RETURN(rv); 5395 5396 if (SOC_MEM_FIELD_VALID(unit, mem, COMMON__EVXLT_KEY_SELf)) { 5397 if (soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 5398 COMMON__EVXLT_KEY_SELf) == 0x1) { 5399 mim_port->flags |= BCM_MIM_PORT_TYPE_BACKBONE; 5400 } else if (soc_mem_field32_get(unit, mem, &egr_dvp_attribute, 5401 COMMON__EVXLT_KEY_SELf) == 0x2) { 5402 mim_port->flags |= BCM_MIM_PORT_TYPE_PEER; 5403 } 5404 } 5405 5406 return rv; 5407 } 5408 #endif 5409 5410 /* 5411 * Function: 5412 * bcm_mim_port_add 5413 * Purpose: 5414 * Create a VPN instance 5415 * Parameters: 5416 * unit - (IN) Device Number 5417 * vpn - (IN) VPN id 5418 * mim_port - (IN/OUT) MIM port configuration info 5419 * Returns: 5420 * BCM_E_XXX 5421 */ 5422 int 5423 bcm_tr2_mim_port_add(int unit, bcm_mim_vpn_t vpn, bcm_mim_port_t *mim_port) 5424 { 5425 int drop, mode, is_local = 0, rv = BCM_E_PARAM, nh_index = 0; 5426 int old_tpid_enable = 0, tpid_enable = 0, tpid_index; 5427 bcm_port_t local_port; 5428 int i, vp, num_vp, ipmc_id, vfi = -1; 5429 source_vp_entry_t svp; 5430 ing_dvp_table_entry_t dvp; 5431 vfi_entry_t vfi_entry; 5432 bcm_multicast_t mc_group = 0; 5433 int failover_vp = 0; 5434 int cml_default_enable=0, cml_default_new=0, cml_default_move=0; 5435 ing_pri_cng_map_entry_t imap; 5436 ing_untagged_phb_entry_t phb; 5437 int is_eline = 0; 5438 int network_group=0; 5439 #if defined(BCM_KATANA2_SUPPORT) 5440 int my_modid = 0, mod_out =0, id = -1; 5441 bcm_port_t port_out = -1; 5442 bcm_trunk_t trunk_id = -1; 5443 int is_local_subport = FALSE; 5444 int min_subport = SOC_INFO(unit).pp_port_index_min; 5445 int max_subport = SOC_INFO(unit).pp_port_index_max; 5446 #endif 5447 bcm_mim_vpn_config_t vpn_info; 5448 int mim_use_default_reserve_svp = 0; 5449 _bcm_vp_info_t vp_info; 5450 #if defined(BCM_TRIDENT3_SUPPORT) 5451 uint32 svp1[SOC_MAX_MEM_WORDS] = {0}; 5452 #endif 5453 5454 _bcm_vp_info_init(&vp_info); 5455 vp_info.vp_type = _bcmVpTypeMim; 5456 5457 MIM_INIT(unit); 5458 5459 rv = bcm_xgs3_l3_egress_mode_get(unit, &mode); 5460 BCM_IF_ERROR_RETURN(rv); 5461 if (!mode) { 5462 LOG_INFO(BSL_LS_BCM_L3, 5463 (BSL_META_U(unit, 5464 "L3 egress mode must be set first\n"))); 5465 return BCM_E_DISABLED; 5466 } 5467 5468 if (!(mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE)) { 5469 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 5470 return BCM_E_PARAM; 5471 } 5472 } 5473 5474 if ((SOC_IS_TRIUMPH2(unit) || 5475 SOC_IS_TRIDENT3(unit) )&& 5476 !(mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE)) { 5477 /* check if ELINE vpn service */ 5478 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_vpn_is_eline(unit, vpn, &is_eline)); 5479 } 5480 5481 /* BCM_MIM_PORT_DEFAULT is used on TR2 B0, setting mim_port_id to 5482 * _BCM_MIM_DEFAULT_PORT 5483 */ 5484 if (soc_feature(unit, soc_feature_mim_reserve_default_port) && 5485 soc_property_get(unit, spn_RESERVE_MIM_DEFAULT_SVP, 0) && 5486 (mim_port->flags & BCM_MIM_PORT_DEFAULT)) { 5487 5488 BCM_GPORT_MIM_PORT_ID_SET(mim_port->mim_port_id, 5489 _BCM_MIM_DEFAULT_PORT); 5490 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port->mim_port_id); 5491 mim_use_default_reserve_svp = 1; 5492 } 5493 5494 /* Allocate a new VP or use provided one */ 5495 if (mim_port->criteria == BCM_MIM_PORT_MATCH_SHARE) { 5496 if (!soc_feature(unit, soc_feature_vp_sharing)) { 5497 return BCM_E_UNAVAIL; 5498 } 5499 if (mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS) { 5500 vp_info.flags |= _BCM_VP_INFO_SHARED_PORT; 5501 } else { 5502 return BCM_E_UNAVAIL; 5503 } 5504 } 5505 5506 if (mim_port->flags & BCM_MIM_PORT_SHARE) { 5507 if (!soc_feature(unit, soc_feature_mim_peer_sharing)) { 5508 return BCM_E_UNAVAIL; 5509 } 5510 #if defined(BCM_TRIDENT_SUPPORT) 5511 else if (!(mim_port->flags & BCM_MIM_PORT_TYPE_PEER)) { 5512 return BCM_E_PARAM; 5513 } 5514 #endif /* BCM_TRIDENT_SUPPORT */ 5515 } 5516 5517 MIM_LOCK(unit); 5518 5519 if (mim_port->flags & BCM_MIM_PORT_WITH_ID) { 5520 if (!BCM_GPORT_IS_MIM_PORT((mim_port->mim_port_id))) { 5521 MIM_UNLOCK(unit); 5522 return BCM_E_PARAM; 5523 } 5524 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port->mim_port_id); 5525 if (vp >= soc_mem_index_count(unit, SOURCE_VPm)) { 5526 MIM_UNLOCK(unit); 5527 return BCM_E_PARAM; 5528 } 5529 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeMim) && 5530 (!mim_use_default_reserve_svp)) { 5531 if (!(mim_port->flags & BCM_MIM_PORT_REPLACE)) { 5532 #if defined(BCM_TRIDENT_SUPPORT) 5533 if (soc_feature(unit, soc_feature_mim_peer_sharing) && 5534 (mim_port->flags & BCM_MIM_PORT_TYPE_PEER)) { 5535 if (!(MIM_INFO(unit)->port_info[vp].flags & 5536 _BCM_MIM_PORT_TYPE_SHARE)) { 5537 MIM_UNLOCK(unit); 5538 return BCM_E_EXISTS; 5539 } 5540 5541 /* for share peer vp */ 5542 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp); 5543 if (rv < 0) { 5544 MIM_UNLOCK(unit); 5545 return rv; 5546 } 5547 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 5548 NEXT_HOP_INDEXf); 5549 5550 rv = _bcm_tr2_mim_peer_port_config_add(unit, mim_port, 5551 vp, vpn); 5552 if (rv < 0) { 5553 MIM_UNLOCK(unit); 5554 return rv; 5555 } 5556 5557 mim_port->encap_id = nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 5558 5559 goto port_cleanup; 5560 } else 5561 #endif /* BCM_TRIDENT_SUPPORT */ 5562 { 5563 MIM_UNLOCK(unit); 5564 return BCM_E_EXISTS; 5565 } 5566 } 5567 } else { 5568 if ((mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS) || 5569 (mim_port->flags & BCM_MIM_PORT_TYPE_PEER)) { 5570 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 5571 } else { 5572 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 5573 } 5574 5575 rv = _bcm_vp_used_set(unit, vp, vp_info); 5576 if (rv < 0) { 5577 MIM_UNLOCK(unit); 5578 return rv; 5579 } 5580 } 5581 } else if (!mim_use_default_reserve_svp) { 5582 /* allocate a new VP index */ 5583 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 5584 if ((mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS) || 5585 (mim_port->flags & BCM_MIM_PORT_TYPE_PEER)) { 5586 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 5587 } else { 5588 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 5589 } 5590 5591 rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp); 5592 if (rv < 0) { 5593 MIM_UNLOCK(unit); 5594 return rv; 5595 } 5596 } 5597 5598 /* Deal with the different kinds of VPs */ 5599 if (mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS) { 5600 /* Deal with access VPs */ 5601 if (vpn == _BCM_MIM_VPN_INVALID) { 5602 MIM_UNLOCK(unit); 5603 return BCM_E_PARAM; 5604 } 5605 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 5606 5607 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 5608 MIM_UNLOCK(unit); 5609 return BCM_E_NOT_FOUND; 5610 } 5611 } else if (mim_port->flags & BCM_MIM_PORT_TYPE_PEER) { 5612 /* Deal with peer VPs - tunnel and associated VPN */ 5613 if (vpn == _BCM_MIM_VPN_INVALID) { 5614 MIM_UNLOCK(unit); 5615 return BCM_E_PARAM; 5616 } 5617 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 5618 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 5619 MIM_UNLOCK(unit); 5620 return BCM_E_NOT_FOUND; 5621 } 5622 } 5623 5624 /* Program, the next hop, matching and egress tables */ 5625 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 5626 /* For existing access ports, NH entry already exists */ 5627 #if defined(BCM_TRIDENT3_SUPPORT) 5628 if (SOC_IS_TRIDENT3X(unit)) { 5629 rv = READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1); 5630 if (rv < 0) { 5631 MIM_UNLOCK(unit); 5632 return rv; 5633 } 5634 } 5635 #endif 5636 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 5637 if (rv < 0) { 5638 MIM_UNLOCK(unit); 5639 return rv; 5640 } 5641 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp); 5642 if (rv < 0) { 5643 MIM_UNLOCK(unit); 5644 return rv; 5645 } 5646 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 5647 NEXT_HOP_INDEXf); 5648 if (soc_SOURCE_VPm_field32_get(unit, &svp, SD_TAG_MODEf)) { 5649 /* SD-tag mode, save the old TPID enable bits */ 5650 #if defined(BCM_TRIDENT3_SUPPORT) 5651 if (SOC_IS_TRIDENT3X(unit)) { 5652 old_tpid_enable = soc_SVP_ATTRS_1m_field32_get(unit, &svp1, 5653 TPID_ENABLEf); 5654 } else 5655 #endif 5656 { 5657 old_tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp, 5658 TPID_ENABLEf); 5659 } 5660 } 5661 } else { 5662 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 5663 sal_memset(&dvp, 0, sizeof(ing_dvp_table_entry_t)); 5664 } 5665 5666 /* if ELINE service check if it valid to add the port */ 5667 if (is_eline) { 5668 rv = _bcm_tr2_mim_eline_port_add(unit, vp, vpn, mim_port); 5669 if (rv < 0) { 5670 MIM_UNLOCK(unit); 5671 return rv; 5672 } 5673 5674 } 5675 5676 /* Program next hop entry using existing or new index */ 5677 drop = (mim_port->flags & BCM_MIM_PORT_DROP) ? 1 : 0; 5678 rv = _bcm_tr2_mim_l2_nh_info_add(unit, mim_port, vp, drop, 5679 &nh_index, &local_port, &is_local); 5680 if (rv < 0) { 5681 goto port_cleanup; 5682 } 5683 5684 bcm_mim_vpn_config_t_init(&vpn_info); 5685 rv = bcm_tr2_mim_vpn_get(unit, vpn, &vpn_info); 5686 if (rv < 0 && !((rv == BCM_E_NOT_FOUND) && (mim_port->flags & 5687 BCM_MIM_PORT_TYPE_BACKBONE))) { 5688 goto port_cleanup; 5689 } 5690 /* Program the VP tables */ 5691 if (mim_port->flags & BCM_MIM_PORT_MATCH_SERVICE_VLAN_TPID) { 5692 rv = _bcm_fb2_outer_tpid_entry_add(unit, mim_port->match_service_tpid, 5693 &tpid_index); 5694 if (rv < 0) { 5695 goto port_cleanup; 5696 } 5697 tpid_enable = (1 << tpid_index); 5698 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 1); 5699 #if defined(BCM_TRIDENT3_SUPPORT) 5700 if (SOC_IS_TRIDENT3X(unit)) { 5701 soc_SVP_ATTRS_1m_field32_set(unit, &svp1, TPID_ENABLEf, tpid_enable); 5702 } else 5703 #endif 5704 { 5705 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, tpid_enable); 5706 } 5707 } else { 5708 if (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) { 5709 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_VFI_ENABLEf, 1); 5710 #if defined(BCM_TRIDENT2_SUPPORT) 5711 if (soc_mem_field_valid(unit, SOURCE_VPm, TPID_SOURCEf)) { 5712 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, 1); 5713 } 5714 #endif /* BCM_TRIDENT2_SUPPORT */ 5715 } else { 5716 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 0); 5717 } 5718 } 5719 soc_SOURCE_VPm_field32_set(unit, &svp, CLASS_IDf, 5720 mim_port->if_class); 5721 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, TRUST_OUTER_DOT1Pf)) { 5722 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_OUTER_DOT1Pf, 1); 5723 } 5724 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 5725 defined(BCM_APACHE_SUPPORT) 5726 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_APACHE(unit)) { 5727 rv = _bcm_esw_add_policer_to_table(unit, mim_port->policer_id, 5728 SOURCE_VPm, 0 , &svp); 5729 BCM_IF_ERROR_RETURN(rv); 5730 } 5731 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT or BCM_APACHE_SUPPORT */ 5732 5733 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 5734 network_group = mim_port->network_group_id; 5735 rv = _bcm_validate_splithorizon_network_group(unit, 5736 mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE, 5737 &network_group); 5738 BCM_IF_ERROR_RETURN(rv); 5739 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_GROUPf, 5740 network_group); 5741 } else { 5742 if ((mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS) || 5743 (mim_port->flags & BCM_MIM_PORT_TYPE_PEER)) { 5744 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 0); 5745 } else { 5746 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 1); 5747 } 5748 } 5749 5750 /* Assign fixed internal priority per VP or trust inner tag */ 5751 if ((mim_port->flags & BCM_MIM_PORT_FIX_PRIORITY) && 5752 (mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS)) { 5753 5754 sal_memset(&imap, 0, sizeof(ing_pri_cng_map_entry_t)); 5755 sal_memset(&phb, 0, sizeof(ing_untagged_phb_entry_t)); 5756 if (SOC_IS_ENDURO(unit) || SOC_IS_TRIUMPH2(unit)) { 5757 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DOT1P_PTRf, 5758 mim_port->int_pri + 16); 5759 soc_SOURCE_VPm_field32_set(unit, &svp, USE_INNER_PRIf, 0); 5760 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_OUTER_DOT1Pf, 0); 5761 5762 BCM_IF_ERROR_RETURN(READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, 5763 1024 + mim_port->int_pri, &imap)); 5764 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &imap, PRIf, 5765 mim_port->int_pri); 5766 BCM_IF_ERROR_RETURN(WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, 5767 1024 + mim_port->int_pri, &imap)); 5768 } 5769 5770 if (SOC_IS_TRIUMPH3(unit)) { 5771 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, 5772 &phb, PRIf, mim_port->int_pri); 5773 BCM_IF_ERROR_RETURN(WRITE_ING_UNTAGGED_PHBm(unit, MEM_BLOCK_ANY, 5774 mim_port->int_pri, &phb)); 5775 soc_SOURCE_VPm_field32_set(unit, &svp, USE_INNER_PRIf, 1); 5776 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DOT1P_PTRf, 5777 mim_port->int_pri); 5778 } 5779 } 5780 5781 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 5782 #ifdef BCM_RIOT_SUPPORT 5783 /* Not setting dvp as network port for RIOT as all 5784 * routed packet gets dropped if overlay SVP and DVP 5785 * both are network ports. 5786 * SVP and DVP as network ports is a valid used case 5787 * but reg file says that this field 5788 * is set when DVP is a TRILL port */ 5789 if ((BCMI_RIOT_IS_ENABLED(unit)) && 5790 ((mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) || 5791 (mim_port->flags & BCM_MIM_PORT_TYPE_PEER))) { 5792 /* explicitly setting it to zero. */ 5793 if(!(soc_property_get(unit, spn_USE_ALL_SPLITHORIZON_GROUPS, 0))) { 5794 network_group = 0; 5795 } 5796 } 5797 #endif 5798 if (soc_mem_field_valid(unit, ING_DVP_TABLEm, NETWORK_GROUPf)) { 5799 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_GROUPf, 5800 network_group); 5801 } 5802 #if defined(BCM_TRIDENT3_SUPPORT) 5803 if(SOC_IS_TRIDENT3X(unit)) { 5804 rv = _bcm_tr2_mim_dvp_set(unit, vp, mim_port); 5805 5806 if (rv < 0) { 5807 goto port_cleanup; 5808 } 5809 } 5810 #endif 5811 } 5812 5813 5814 /* Program the matching criteria */ 5815 if (mim_port->flags & BCM_MIM_PORT_REPLACE) { 5816 #if defined(BCM_TRIDENT3_SUPPORT) 5817 if (SOC_IS_TRIDENT3X(unit)) { 5818 rv = WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1); 5819 if (rv < 0) { 5820 goto port_cleanup; 5821 } 5822 } 5823 #endif 5824 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 5825 if (rv < 0) { 5826 goto port_cleanup; 5827 } 5828 5829 if (soc_mem_field_valid(unit, ING_DVP_TABLEm, NETWORK_PORTf)) { 5830 #ifdef BCM_RIOT_SUPPORT 5831 if (BCMI_RIOT_IS_ENABLED(unit)) { 5832 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_PORTf, 0); 5833 } else 5834 #endif 5835 { 5836 soc_ING_DVP_TABLEm_field32_set( 5837 unit, &dvp, NETWORK_PORTf, 5838 (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) ? 1 : 0); 5839 } 5840 } 5841 5842 rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp); 5843 if (rv < 0) { 5844 goto port_cleanup; 5845 } 5846 5847 rv = _bcm_vp_ing_dvp_to_ing_dvp2_2(unit, &dvp, vp, network_group); 5848 if (rv < 0) { 5849 goto port_cleanup; 5850 } 5851 5852 BCM_IF_ERROR_RETURN( 5853 _bcm_tr2_mim_match_add(unit, mim_port, vp, vpn)); 5854 } else { 5855 /* Link in the newly allocated next-hop entry */ 5856 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NEXT_HOP_INDEXf, 5857 nh_index); 5858 5859 if (soc_mem_field_valid(unit, ING_DVP_TABLEm, NETWORK_PORTf)) { 5860 #ifdef BCM_RIOT_SUPPORT 5861 if (BCMI_RIOT_IS_ENABLED(unit)) { 5862 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_PORTf, 0); 5863 } else 5864 #endif 5865 { 5866 soc_ING_DVP_TABLEm_field32_set( 5867 unit, &dvp, NETWORK_PORTf, 5868 (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE) ? 1 : 0); 5869 } 5870 } 5871 5872 rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp); 5873 if (rv < 0) { 5874 goto port_cleanup; 5875 } 5876 5877 rv = _bcm_vp_ing_dvp_to_ing_dvp2_2(unit, &dvp, vp, network_group); 5878 if (rv < 0) { 5879 goto port_cleanup; 5880 } 5881 5882 /* Initialize the SVP parameters */ 5883 soc_SOURCE_VPm_field32_set(unit, &svp, 5884 ENTRY_TYPEf, 0x1); /* L2 VP */ 5885 if ((vfi != -1) && (mim_port->criteria != BCM_MIM_PORT_MATCH_SHARE)) { 5886 soc_SOURCE_VPm_field32_set(unit, &svp, VFIf, vfi); 5887 } 5888 5889 5890 /* 5891 * if ELINE VPN service and the port type is access 5892 * learning to be disabled 5893 */ 5894 if (!((mim_port->flags & BCM_MIM_PORT_TYPE_ACCESS) && is_eline)) { 5895 /* Set the CML */ 5896 rv = _bcm_vp_default_cml_mode_get (unit, 5897 &cml_default_enable, &cml_default_new, 5898 &cml_default_move); 5899 if (rv < 0) { 5900 goto port_cleanup; 5901 } 5902 5903 if (cml_default_enable) { 5904 /* Set the CML to default values */ 5905 soc_SOURCE_VPm_field32_set(unit, &svp, 5906 CML_FLAGS_NEWf, cml_default_new); 5907 soc_SOURCE_VPm_field32_set(unit, &svp, 5908 CML_FLAGS_MOVEf, cml_default_move); 5909 } else { 5910 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 5911 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, 0x8); 5912 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, 0x8); 5913 } 5914 } 5915 5916 if (soc_mem_field_valid(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) { 5917 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)) { 5918 soc_SOURCE_VPm_field32_set(unit, &svp, DISABLE_VLAN_CHECKSf, 1); 5919 } 5920 } 5921 #if defined(BCM_TRIDENT3_SUPPORT) 5922 if (SOC_IS_TRIDENT3X(unit)) { 5923 rv = WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1); 5924 if (rv < 0) { 5925 goto port_cleanup; 5926 } 5927 } 5928 #endif 5929 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 5930 if (rv < 0) { 5931 goto port_cleanup; 5932 } 5933 5934 #if defined(BCM_TRIDENT3_SUPPORT) 5935 if (SOC_IS_TRIDENT3X(unit)) { 5936 if ((vpn != _BCM_MIM_VPN_INVALID) && 5937 (mim_port->flags & BCM_MIM_PORT_TYPE_BACKBONE)) { 5938 if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, 5939 SOURCE_VPm, vp, ENTRY_TYPEf, 5940 CANCUN_APP__SOURCE_VP__No_Control_Word, 0x1)) { 5941 LOG_ERROR(BSL_LS_BCM_MIM, 5942 (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n"))); 5943 } 5944 } 5945 } 5946 #endif 5947 5948 /* Add the port to the VFI broadcast replication list */ 5949 #if defined(BCM_KATANA2_SUPPORT) 5950 if (soc_feature(unit, soc_feature_linkphy_coe) || 5951 soc_feature(unit, soc_feature_subtag_coe)) { 5952 rv =_bcm_esw_gport_resolve(unit, mim_port->port, &mod_out, 5953 &port_out, &trunk_id, &id); 5954 if (rv < 0) { 5955 goto port_cleanup; 5956 } 5957 rv = bcm_esw_stk_my_modid_get(unit, &my_modid); 5958 if (rv < 0) { 5959 goto port_cleanup; 5960 } 5961 if (BCM_GPORT_IS_SET(mim_port->port) && 5962 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 5963 mim_port->port)) { 5964 if (_bcm_kt2_mod_is_coe_mod_check(unit, mod_out) == BCM_E_NONE) { 5965 rv = _bcm_kt2_modport_to_pp_port_get( 5966 unit, mod_out, port_out, &port_out); 5967 if (rv < 0) { 5968 goto port_cleanup; 5969 } 5970 #if defined BCM_METROLITE_SUPPORT 5971 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 5972 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port_out)) { 5973 is_local_subport = TRUE; 5974 } 5975 } else 5976 #endif 5977 { 5978 if ((port_out >= min_subport ) && 5979 (port_out <= max_subport)) { 5980 is_local_subport = TRUE; 5981 } 5982 } 5983 } 5984 } 5985 if ((is_local_subport) && (vfi != -1)) { 5986 /* Get IPMC index from HW */ 5987 rv = READ_VFIm(unit, MEM_BLOCK_ANY, vfi, &vfi_entry); 5988 if (rv < 0) { 5989 goto port_cleanup; 5990 } 5991 #if defined(BCM_TRIDENT3_SUPPORT) 5992 if (soc_feature(unit, soc_feature_generic_dest)) { 5993 uint32 dt = SOC_MEM_FIF_DEST_INVALID; 5994 ipmc_id = soc_mem_field32_dest_get(unit, VFIm, 5995 &vfi_entry, BC_DESTINATIONf, &dt); 5996 if (dt != SOC_MEM_FIF_DEST_IPMC) { 5997 rv = BCM_E_INTERNAL; 5998 goto port_cleanup; 5999 } 6000 } else 6001 #endif 6002 { 6003 ipmc_id = soc_VFIm_field32_get(unit, 6004 &vfi_entry, BC_INDEXf); 6005 } 6006 _BCM_MULTICAST_GROUP_SET(mc_group, 6007 _BCM_MULTICAST_TYPE_MIM, ipmc_id); 6008 rv = bcm_esw_multicast_egress_add(unit, mc_group, 6009 mim_port->port, nh_index + 6010 BCM_XGS3_DVP_EGRESS_IDX_MIN(unit)); 6011 if (rv < 0) { 6012 goto port_cleanup; 6013 } 6014 } 6015 } 6016 #endif 6017 if ((is_local || BCM_GPORT_IS_TRUNK(mim_port->port)) && 6018 (vfi != -1) && (!is_eline)) { 6019 bcm_gport_t local_gport; 6020 6021 /* Get IPMC index from HW */ 6022 rv = READ_VFIm(unit, MEM_BLOCK_ANY, vfi, &vfi_entry); 6023 if (rv < 0) { 6024 goto port_cleanup; 6025 } 6026 #if defined(BCM_TRIDENT3_SUPPORT) 6027 if (soc_feature(unit, soc_feature_generic_dest)) { 6028 uint32 dt = SOC_MEM_FIF_DEST_INVALID; 6029 ipmc_id = soc_mem_field32_dest_get(unit, VFIm, 6030 &vfi_entry, BC_DESTINATIONf, &dt); 6031 if (dt != SOC_MEM_FIF_DEST_IPMC) { 6032 rv = BCM_E_INTERNAL; 6033 goto port_cleanup; 6034 } 6035 } else 6036 #endif 6037 { 6038 ipmc_id = soc_VFIm_field32_get(unit, 6039 &vfi_entry, BC_INDEXf); 6040 } 6041 _BCM_MULTICAST_GROUP_SET(mc_group, _BCM_MULTICAST_TYPE_MIM, ipmc_id); 6042 if (is_local) { 6043 /* Convert system local_port to physical local_port */ 6044 if (soc_feature(unit, soc_feature_sysport_remap)) { 6045 BCM_XLATE_SYSPORT_S2P(unit, &local_port); 6046 } 6047 rv = bcm_esw_port_gport_get(unit, local_port, &local_gport); 6048 if (BCM_FAILURE(rv)) { 6049 goto port_cleanup; 6050 } 6051 } else { 6052 local_gport = mim_port->port; /* Trunk gport */ 6053 } 6054 #if defined(BCM_ENDURO_SUPPORT) 6055 if (SOC_IS_ENDURO(unit)) { 6056 rv = bcm_esw_multicast_egress_add(unit, mc_group, 6057 local_gport, nh_index); 6058 } else 6059 #endif /* BCM_ENDURO_SUPPORT */ 6060 { 6061 rv = bcm_esw_multicast_egress_add(unit, mc_group, 6062 local_gport, nh_index + 6063 BCM_XGS3_DVP_EGRESS_IDX_MIN(unit)); 6064 } 6065 if (rv < 0) { 6066 goto port_cleanup; 6067 } 6068 } 6069 6070 /* Configure failover VP */ 6071 if (BCM_SUCCESS(_bcm_tr2_mim_failover_check(unit, mim_port))) { 6072 failover_vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port->failover_gport_id); 6073 if (failover_vp == vp) { 6074 rv = BCM_E_PORT; 6075 goto port_cleanup; 6076 } 6077 if (!_bcm_vp_used_get(unit, failover_vp, _bcmVpTypeMim)) { 6078 /* coverity[assigned_value] */ 6079 rv = BCM_E_NOT_FOUND; 6080 } 6081 } 6082 6083 /* 6084 * Match entries cannot be replaced, instead, callers 6085 * need to delete the existing entry and re-add with the 6086 * new match parameters. 6087 */ 6088 #if defined(BCM_TRIUMPH3_SUPPORT) 6089 if (SOC_IS_TRIUMPH3(unit)) { 6090 rv = _bcm_tr3_mim_match_add(unit, mim_port, vp); 6091 } else 6092 #endif /* BCM_TRIUMPH3_SUPPORT */ 6093 { 6094 rv = _bcm_tr2_mim_match_add(unit, mim_port, vp, vpn); 6095 } 6096 6097 if (rv < 0) { 6098 bcm_gport_t local_gport; 6099 if (is_local && !is_eline) { 6100 (void) bcm_esw_port_gport_get(unit, local_port, &local_gport); 6101 #if defined(BCM_ENDURO_SUPPORT) 6102 if (SOC_IS_ENDURO(unit)) { 6103 (void) bcm_esw_multicast_egress_delete(unit, mc_group, 6104 local_gport, nh_index); 6105 } else 6106 #endif /* BCM_ENDURO_SUPPORT */ 6107 { 6108 (void) bcm_esw_multicast_egress_delete(unit, mc_group, 6109 local_gport, nh_index + 6110 BCM_XGS3_DVP_EGRESS_IDX_MIN(unit)); 6111 } 6112 } 6113 #if defined(BCM_KATANA2_SUPPORT) 6114 if (soc_feature(unit, soc_feature_linkphy_coe) || 6115 soc_feature(unit, soc_feature_subtag_coe)) { 6116 if (is_local_subport) { 6117 (void) bcm_esw_multicast_egress_delete(unit, mc_group, 6118 mim_port->port, nh_index + 6119 BCM_XGS3_DVP_EGRESS_IDX_MIN(unit)); 6120 } 6121 } 6122 #endif 6123 } else { 6124 /* For peer ports, create entries in ingress and egress 6125 VLAN translate tables */ 6126 if (mim_port->flags & BCM_MIM_PORT_TYPE_PEER) { 6127 #if defined(BCM_TRIUMPH3_SUPPORT) 6128 if (SOC_IS_TRIUMPH3(unit)) { 6129 rv = _bcm_tr3_mim_peer_port_config_add(unit, mim_port, 6130 vp, vpn); 6131 } else 6132 #endif /* BCM_TRIUMPH3_SUPPORT */ 6133 { 6134 rv = _bcm_tr2_mim_peer_port_config_add(unit, mim_port, 6135 vp, vpn); 6136 } 6137 } 6138 /* Set the MIM port ID */ 6139 BCM_GPORT_MIM_PORT_ID_SET(mim_port->mim_port_id, vp); 6140 mim_port->encap_id = nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 6141 } 6142 } 6143 6144 #ifdef BCM_WARM_BOOT_SUPPORT 6145 SOC_CONTROL_LOCK(unit); 6146 SOC_CONTROL(unit)->scache_dirty = 1; 6147 SOC_CONTROL_UNLOCK(unit); 6148 #endif 6149 6150 port_cleanup: 6151 if (rv < 0) { 6152 if (tpid_enable) { 6153 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 6154 } 6155 if (!(mim_port->flags & BCM_MIM_PORT_REPLACE)) { 6156 if (!mim_use_default_reserve_svp) { 6157 (void) _bcm_vp_free(unit, _bcmVpTypeMim, 1, vp); 6158 } 6159 _bcm_tr2_mim_l2_nh_info_delete(unit, nh_index); 6160 } 6161 if (vp > 0) { 6162 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 6163 defined(BCM_APACHE_SUPPORT) 6164 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_APACHE(unit)) { 6165 /* reset the policer entry to 0 and decrement reference count */ 6166 _bcm_esw_reset_policer_from_table(unit, mim_port->policer_id, 6167 SOURCE_VPm, vp, &svp); 6168 } 6169 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT or BCM_APACHE_SUPPORT */ 6170 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 6171 (void)WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 6172 #if defined(BCM_TRIDENT3_SUPPORT) 6173 sal_memset(&svp1, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 6174 if (SOC_IS_TRIDENT3X(unit)) { 6175 (void)WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1); 6176 } 6177 #endif 6178 (void)_bcm_vp_ing_dvp_config(unit, _bcmVpIngDvpConfigClear, vp, 6179 ING_DVP_CONFIG_INVALID_VP_TYPE, 6180 ING_DVP_CONFIG_INVALID_INTF_ID, 6181 ING_DVP_CONFIG_INVALID_PORT_TYPE); 6182 } 6183 } 6184 if (old_tpid_enable) { 6185 for (i = 0; i < 4; i++) { 6186 if (old_tpid_enable & (1 << i)) { 6187 (void) _bcm_fb2_outer_tpid_entry_delete(unit, i); 6188 break; 6189 } 6190 } 6191 } 6192 MIM_UNLOCK(unit); 6193 return rv; 6194 } 6195 6196 /* 6197 * Function: 6198 * _bcm_tr2_mim_egress_dvp_reset 6199 * Purpose: 6200 * Reet Egress DVP tables 6201 * Parameters: 6202 * IN : Unit 6203 * IN : vp 6204 * Returns: 6205 * BCM_E_XXX 6206 */ 6207 6208 STATIC int 6209 _bcm_tr2_mim_egress_dvp_reset(int unit, int vp) 6210 { 6211 int rv=BCM_E_NONE; 6212 egr_dvp_attribute_entry_t egr_dvp_attribute; 6213 egr_dvp_attribute_1_entry_t egr_dvp_attribute_1; 6214 6215 if (SOC_MEM_IS_VALID(unit, EGR_DVP_ATTRIBUTEm)) { 6216 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 6217 rv = soc_mem_write(unit, EGR_DVP_ATTRIBUTEm, 6218 MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 6219 BCM_IF_ERROR_RETURN(rv); 6220 } 6221 6222 if (SOC_MEM_IS_VALID(unit, EGR_DVP_ATTRIBUTE_1m)) { 6223 sal_memset(&egr_dvp_attribute_1, 0, sizeof(egr_dvp_attribute_1_entry_t)); 6224 rv = soc_mem_write(unit, EGR_DVP_ATTRIBUTE_1m, 6225 MEM_BLOCK_ALL, vp, &egr_dvp_attribute_1); 6226 } 6227 6228 return rv; 6229 } 6230 6231 6232 STATIC int 6233 _bcm_tr2_mim_port_delete(int unit, bcm_vpn_t vpn, int vp) 6234 { 6235 int rv = BCM_E_NONE; 6236 int nh_index = 0, vfi, ipmc_id, is_local = FALSE; 6237 source_vp_entry_t svp; 6238 ing_dvp_table_entry_t dvp; 6239 ing_l3_next_hop_entry_t ing_nh; 6240 vfi_entry_t vfi_entry; 6241 bcm_module_t modid; 6242 bcm_port_t port; 6243 bcm_trunk_t tgid; 6244 bcm_multicast_t mc_group = 0; 6245 bcm_gport_t local_gport = BCM_GPORT_INVALID; 6246 _bcm_port_info_t *info; 6247 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 6248 int policer_id=0; 6249 #endif 6250 #if defined(BCM_KATANA2_SUPPORT) 6251 bcm_port_t pp_port = -1; 6252 int is_local_subport = FALSE; 6253 int min_subport = SOC_INFO(unit).pp_port_index_min; 6254 int max_subport = SOC_INFO(unit).pp_port_index_max; 6255 #endif 6256 int is_eline = 0; 6257 int mim_reserve_svp_delete = 0; 6258 int old_tpid_enable, i; 6259 bcm_mim_port_t mim_port; 6260 uint32 port_flags; 6261 int is_trunk = 0; 6262 #if defined(BCM_TRIDENT3_SUPPORT) 6263 uint32 svp1[SOC_MAX_MEM_WORDS] = {0}; 6264 #endif 6265 int tpid_enable_length = 0; 6266 6267 /* We can not delete shared VP's match in this API, so if the 6268 * VP is using by match, do not delete this vp */ 6269 if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_ACCESS_SHARED) { 6270 if(MIM_INFO(unit)->port_info[vp].match_count >= 1) { 6271 return BCM_E_BUSY; 6272 } 6273 } else { 6274 if(MIM_INFO(unit)->port_info[vp].match_count > 1) { 6275 return BCM_E_BUSY; 6276 } 6277 } 6278 6279 #if defined(BCM_TRIDENT_SUPPORT) 6280 if (soc_feature(unit, soc_feature_mim_peer_sharing) && 6281 (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_SHARE)) { 6282 if (MIM_INFO(unit)->port_info[vp].vfi_count > 1) { 6283 rv = _bcm_tr2_mim_peer_port_config_delete(unit, vp, vpn); 6284 return rv; 6285 } 6286 } 6287 #endif /* BCM_TRIDENT_SUPPORT */ 6288 6289 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 6290 6291 if (!(MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_NETWORK)) { 6292 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 6293 return BCM_E_NOT_FOUND; 6294 } 6295 } 6296 6297 if (SOC_IS_TRIUMPH2(unit) && (!(MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_NETWORK))) { 6298 /* check if point-to-point vpn */ 6299 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_vpn_is_eline(unit, vpn, &is_eline)); 6300 } 6301 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp); 6302 BCM_IF_ERROR_RETURN(rv); 6303 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 6304 6305 #if defined(BCM_TRIUMPH3_SUPPORT) 6306 if (SOC_IS_TRIUMPH3(unit)) { 6307 rv = _bcm_tr3_mim_match_delete(unit, vp); 6308 } else 6309 #endif /* BCM_TRIUMPH3_SUPPORT */ 6310 { 6311 _bcm_vp_info_t vp_info; 6312 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 6313 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 6314 rv = _bcm_tr2_mim_match_delete(unit, vp, mim_port); 6315 } 6316 } 6317 6318 if (rv < 0) { 6319 return rv; 6320 } 6321 6322 /* Check if this port is on the local unit */ 6323 rv = soc_mem_read(unit, ING_L3_NEXT_HOPm, 6324 MEM_BLOCK_ANY, nh_index, &ing_nh); 6325 BCM_IF_ERROR_RETURN(rv); 6326 6327 if (!(MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_NETWORK)) { 6328 if (soc_feature(unit, soc_feature_generic_dest)) { 6329 uint32 dt, dv; 6330 dv = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, 6331 &ing_nh, DESTINATIONf, &dt); 6332 if (dt == SOC_MEM_FIF_DEST_LAG) { 6333 /* Trunk group */ 6334 tgid = dv & SOC_MEM_FIF_DGPP_TGID_MASK; 6335 is_trunk = 1; 6336 } else { 6337 port = dv & SOC_MEM_FIF_DGPP_PORT_MASK; 6338 modid = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 6339 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 6340 } 6341 } else { 6342 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 6343 tgid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 6344 is_trunk = 1; 6345 } else { 6346 modid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 6347 port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 6348 } 6349 } 6350 6351 if (!is_trunk) { 6352 BCM_IF_ERROR_RETURN( 6353 _bcm_esw_modid_is_local(unit, modid, &is_local)); 6354 if (TRUE == is_local) { 6355 /* Convert system port to physical port */ 6356 if (soc_feature(unit, soc_feature_sysport_remap)) { 6357 BCM_XLATE_SYSPORT_S2P(unit, &port); 6358 } 6359 BCM_IF_ERROR_RETURN( 6360 bcm_esw_port_gport_get(unit, port, &local_gport)); 6361 } 6362 #if defined(BCM_KATANA2_SUPPORT) 6363 if (soc_feature(unit, soc_feature_linkphy_coe) || 6364 soc_feature(unit, soc_feature_subtag_coe)) { 6365 /* For LinkPHY/SubportPktTag pp_ports, check if the mod is a valid one */ 6366 if (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) { 6367 BCM_IF_ERROR_RETURN( 6368 _bcm_kt2_modport_to_pp_port_get(unit, modid, 6369 port, &pp_port)); 6370 #if defined BCM_METROLITE_SUPPORT 6371 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 6372 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 6373 _BCM_KT2_SUBPORT_PORT_ID_SET(local_gport, pp_port); 6374 if (BCM_PBMP_MEMBER( 6375 SOC_INFO(unit).linkphy_pp_port_pbm, pp_port)) { 6376 _BCM_KT2_SUBPORT_PORT_TYPE_SET(local_gport, 6377 _BCM_KT2_SUBPORT_TYPE_LINKPHY); 6378 } else if (BCM_PBMP_MEMBER( 6379 SOC_INFO(unit).subtag_pp_port_pbm, pp_port)) { 6380 _BCM_KT2_SUBPORT_PORT_TYPE_SET(local_gport, 6381 _BCM_KT2_SUBPORT_TYPE_SUBTAG); 6382 } else { 6383 return BCM_E_PORT; 6384 } 6385 /* If this port is on the local unit and is not a network port, 6386 * *remove from replication list 6387 * * Get IPMC index from HW */ 6388 BCM_IF_ERROR_RETURN( 6389 READ_VFIm(unit, MEM_BLOCK_ANY, vfi, &vfi_entry)); 6390 ipmc_id = 6391 soc_VFIm_field32_get(unit, &vfi_entry, BC_INDEXf); 6392 _BCM_MULTICAST_GROUP_SET(mc_group, 6393 _BCM_MULTICAST_TYPE_MIM, ipmc_id); 6394 6395 BCM_IF_ERROR_RETURN( 6396 bcm_esw_multicast_egress_delete(unit, mc_group, 6397 local_gport, 6398 nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit))); 6399 is_local_subport = TRUE; 6400 } 6401 } else 6402 #endif 6403 /*For KT2, pp_port >=42 are used for LinkPHY/SubportPktTag subport. 6404 * Get the subport info associated with the pp_port and form the 6405 * subport_gport */ 6406 { 6407 if ((pp_port >= min_subport) && 6408 (pp_port <= max_subport)) { 6409 _BCM_KT2_SUBPORT_PORT_ID_SET(local_gport, pp_port); 6410 if (BCM_PBMP_MEMBER( 6411 SOC_INFO(unit).linkphy_pp_port_pbm, pp_port)) { 6412 _BCM_KT2_SUBPORT_PORT_TYPE_SET(local_gport, 6413 _BCM_KT2_SUBPORT_TYPE_LINKPHY); 6414 } else if (BCM_PBMP_MEMBER( 6415 SOC_INFO(unit).subtag_pp_port_pbm, pp_port)) { 6416 _BCM_KT2_SUBPORT_PORT_TYPE_SET(local_gport, 6417 _BCM_KT2_SUBPORT_TYPE_SUBTAG); 6418 } else { 6419 return BCM_E_PORT; 6420 } 6421 /* If this port is on the local unit and is not a network port, 6422 *remove from replication list 6423 * Get IPMC index from HW */ 6424 BCM_IF_ERROR_RETURN( 6425 READ_VFIm(unit, MEM_BLOCK_ANY, vfi, &vfi_entry)); 6426 ipmc_id = 6427 soc_VFIm_field32_get(unit, &vfi_entry, BC_INDEXf); 6428 _BCM_MULTICAST_GROUP_SET(mc_group, 6429 _BCM_MULTICAST_TYPE_MIM, ipmc_id); 6430 6431 BCM_IF_ERROR_RETURN( 6432 bcm_esw_multicast_egress_delete(unit, mc_group, 6433 local_gport, 6434 nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit))); 6435 is_local_subport = TRUE; 6436 } 6437 /* If this port is on the local unit and is not a network port, 6438 *remove from replication list 6439 * Get IPMC index from HW */ 6440 BCM_IF_ERROR_RETURN( 6441 READ_VFIm(unit, MEM_BLOCK_ANY, vfi, &vfi_entry)); 6442 #if defined(BCM_TRIDENT3_SUPPORT) 6443 if (soc_feature(unit, soc_feature_generic_dest)) { 6444 uint32 dt = SOC_MEM_FIF_DEST_INVALID; 6445 ipmc_id = soc_mem_field32_dest_get(unit, VFIm, 6446 &vfi_entry, BC_DESTINATIONf, &dt); 6447 if (dt != SOC_MEM_FIF_DEST_IPMC) { 6448 return BCM_E_INTERNAL; 6449 } 6450 } else 6451 #endif 6452 { 6453 ipmc_id = soc_VFIm_field32_get(unit, 6454 &vfi_entry, BC_INDEXf); 6455 } 6456 ipmc_id = soc_VFIm_field32_get(unit, 6457 &vfi_entry, BC_INDEXf); 6458 _BCM_MULTICAST_GROUP_SET(mc_group, 6459 _BCM_MULTICAST_TYPE_MIM, ipmc_id); 6460 6461 BCM_IF_ERROR_RETURN( 6462 bcm_esw_multicast_egress_delete(unit, mc_group, 6463 local_gport, 6464 nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit))); 6465 is_local_subport = TRUE; 6466 } 6467 } 6468 } 6469 #endif /* BCM_KATANA2_SUPPORT */ 6470 } else { 6471 BCM_GPORT_TRUNK_SET(local_gport, tgid); 6472 } 6473 /* 6474 * If point-to-point vpn service, BC_INDEXf 6475 * UC_INDEXf are overlaid with VP_0f, VP_1f. 6476 * and are not relevant. skip multicast operations 6477 * If this port is on the local unit and is not 6478 * a network port, remove from replication list 6479 */ 6480 6481 if (((TRUE == is_local) || BCM_GPORT_IS_TRUNK(local_gport)) && 6482 (!is_eline)) { 6483 /* Get IPMC index from HW */ 6484 rv = READ_VFIm(unit, MEM_BLOCK_ANY, vfi, &vfi_entry); 6485 BCM_IF_ERROR_RETURN(rv); 6486 #if defined(BCM_TRIDENT3_SUPPORT) 6487 if (soc_feature(unit, soc_feature_generic_dest)) { 6488 uint32 dt = SOC_MEM_FIF_DEST_INVALID; 6489 ipmc_id = soc_mem_field32_dest_get(unit, VFIm, 6490 &vfi_entry, BC_DESTINATIONf, &dt); 6491 if (dt != SOC_MEM_FIF_DEST_IPMC) { 6492 return BCM_E_INTERNAL; 6493 } 6494 } else 6495 #endif 6496 { 6497 ipmc_id = soc_VFIm_field32_get(unit, 6498 &vfi_entry, BC_INDEXf); 6499 } 6500 _BCM_MULTICAST_GROUP_SET(mc_group, _BCM_MULTICAST_TYPE_MIM, ipmc_id); 6501 #if defined(BCM_ENDURO_SUPPORT) 6502 if (SOC_IS_ENDURO(unit)) { 6503 rv = bcm_esw_multicast_egress_delete(unit, mc_group, 6504 local_gport, nh_index); 6505 } else 6506 #endif /* BCM_ENDURO_SUPPORT */ 6507 { 6508 rv = bcm_esw_multicast_egress_delete(unit, mc_group, 6509 local_gport, 6510 nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit)); 6511 } 6512 BCM_IF_ERROR_RETURN(rv); 6513 } 6514 } 6515 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 6516 if (soc_feature(unit, soc_feature_global_meter)) { 6517 rv = _bcm_esw_get_policer_from_table(unit, SOURCE_VPm, vp, &svp, 6518 &policer_id, 0); 6519 if(BCM_SUCCESS(rv)) { 6520 _bcm_esw_policer_decrement_ref_count(unit, policer_id); 6521 } else { 6522 return rv; 6523 } 6524 } 6525 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT */ 6526 6527 /* if Point-to-Point vpn, clear the vp in VFI table */ 6528 if (is_eline) { 6529 rv = _bcm_tr2_mim_eline_port_delete(unit, vpn, vp); 6530 BCM_IF_ERROR_RETURN(rv); 6531 } 6532 6533 /* Clear the SVP and DVP table entries */ 6534 BCM_IF_ERROR_RETURN 6535 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 6536 6537 #if defined(BCM_TRIDENT3_SUPPORT) 6538 if (SOC_IS_TRIDENT3X(unit)) { 6539 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 6540 MEM_BLOCK_ANY, vp, &svp1)); 6541 old_tpid_enable = soc_SVP_ATTRS_1m_field32_get(unit, &svp1, 6542 TPID_ENABLEf); 6543 tpid_enable_length = soc_mem_field_length(unit, 6544 SVP_ATTRS_1m, TPID_ENABLEf); 6545 } else 6546 #endif 6547 { 6548 old_tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp, 6549 TPID_ENABLEf); 6550 tpid_enable_length = soc_mem_field_length(unit, 6551 SOURCE_VPm, TPID_ENABLEf); 6552 } 6553 6554 if (old_tpid_enable) { 6555 for (i= 0; i < tpid_enable_length; i++) { 6556 if (old_tpid_enable & (1 << i)) { 6557 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_delete(unit, i)); 6558 } 6559 } 6560 } 6561 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 6562 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 6563 BCM_IF_ERROR_RETURN(rv); 6564 6565 #if defined(BCM_TRIDENT3_SUPPORT) 6566 if (SOC_IS_TRIDENT3X(unit)) { 6567 sal_memset(&svp1, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 6568 BCM_IF_ERROR_RETURN(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1)); 6569 } 6570 #endif 6571 6572 sal_memset(&dvp, 0, sizeof(ing_dvp_table_entry_t)); 6573 rv = _bcm_vp_ing_dvp_config(unit, _bcmVpIngDvpConfigClear, vp, 6574 ING_DVP_CONFIG_INVALID_VP_TYPE, 6575 ING_DVP_CONFIG_INVALID_INTF_ID, 6576 ING_DVP_CONFIG_INVALID_PORT_TYPE); 6577 BCM_IF_ERROR_RETURN(rv); 6578 6579 /* Clear the next-hop table entries */ 6580 rv = _bcm_tr2_mim_l2_nh_info_delete(unit, nh_index); 6581 BCM_IF_ERROR_RETURN(rv); 6582 6583 /* For peer ports, delete entries in ingress and egress 6584 VLAN translate tables */ 6585 if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_PEER) { 6586 #if defined(BCM_TRIUMPH3_SUPPORT) 6587 if (SOC_IS_TRIUMPH3(unit)) { 6588 rv = _bcm_tr3_mim_peer_port_config_delete(unit, vp, vpn); 6589 } else 6590 #endif /* BCM_TRIUMPH3_SUPPORT */ 6591 { 6592 rv = _bcm_tr2_mim_peer_port_config_delete(unit, vp, vpn); 6593 } 6594 BCM_IF_ERROR_RETURN(rv); 6595 } 6596 6597 /* Update the physical port's SW state */ 6598 #if defined(BCM_KATANA2_SUPPORT) 6599 if (soc_feature(unit, soc_feature_linkphy_coe) || 6600 soc_feature(unit, soc_feature_subtag_coe)) { 6601 6602 if (is_local_subport && (MIM_INFO(unit)->port_info[vp].tgid == -1)) { 6603 _bcm_port_info_access(unit, 6604 MIM_INFO(unit)->port_info[vp].port, &info); 6605 info->vp_count--; 6606 BCM_IF_ERROR_RETURN( 6607 bcm_esw_port_vlan_member_get( 6608 unit, MIM_INFO(unit)->port_info[vp].port, &port_flags)); 6609 BCM_IF_ERROR_RETURN( 6610 bcm_esw_port_vlan_member_set( 6611 unit, MIM_INFO(unit)->port_info[vp].port, port_flags)); 6612 } 6613 } 6614 #endif 6615 if (soc_feature(unit, soc_feature_generic_dest)) { 6616 uint32 dt, dv; 6617 dv = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, 6618 &ing_nh, DESTINATIONf, &dt); 6619 if (dt == SOC_MEM_FIF_DEST_DGPP) { 6620 modid = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 6621 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 6622 BCM_IF_ERROR_RETURN( 6623 _bcm_esw_modid_is_local(unit, modid, &is_local)); 6624 } 6625 } else { 6626 if (!soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 6627 modid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 6628 BCM_IF_ERROR_RETURN( 6629 _bcm_esw_modid_is_local(unit, modid, &is_local)); 6630 } 6631 } 6632 if (is_local && (MIM_INFO(unit)->port_info[vp].tgid == -1)) { 6633 bcm_port_t phys_port = MIM_INFO(unit)->port_info[vp].port; 6634 if (soc_feature(unit, soc_feature_sysport_remap)) { 6635 BCM_XLATE_SYSPORT_S2P(unit, &phys_port); 6636 } 6637 _bcm_port_info_access(unit, phys_port, &info); 6638 info->vp_count--; 6639 BCM_IF_ERROR_RETURN( 6640 bcm_esw_port_vlan_member_get(unit, phys_port, &port_flags)); 6641 BCM_IF_ERROR_RETURN( 6642 bcm_esw_port_vlan_member_set(unit, phys_port, port_flags)); 6643 } 6644 6645 /* If associated with a trunk, update each local physical port's SW state */ 6646 if (MIM_INFO(unit)->port_info[vp].tgid != -1) { 6647 int idx; 6648 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 6649 bcm_port_t local_member_array[SOC_MAX_NUM_PP_PORTS]; 6650 int max_num_ports = SOC_MAX_NUM_PP_PORTS; 6651 #else 6652 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 6653 int max_num_ports = SOC_MAX_NUM_PORTS; 6654 #endif 6655 int local_member_count; 6656 6657 bcm_trunk_t trunk_id = MIM_INFO(unit)->port_info[vp].tgid; 6658 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, trunk_id, 6659 max_num_ports, local_member_array, &local_member_count)); 6660 for (idx = 0; idx < local_member_count; idx++) { 6661 _bcm_port_info_access(unit, local_member_array[idx], &info); 6662 info->vp_count--; 6663 BCM_IF_ERROR_RETURN( 6664 bcm_esw_port_vlan_member_get( 6665 unit, local_member_array[idx], &port_flags)); 6666 BCM_IF_ERROR_RETURN( 6667 bcm_esw_port_vlan_member_set( 6668 unit, local_member_array[idx], port_flags)); 6669 } 6670 } 6671 6672 /* Clear the SW state */ 6673 sal_memset(&(MIM_INFO(unit)->port_info[vp]), 0, 6674 sizeof(_bcm_tr2_mim_port_info_t)); 6675 6676 if (soc_feature(unit, soc_feature_gport_service_counters)) { 6677 bcm_gport_t gport; 6678 6679 /* Release Service counter, if any */ 6680 BCM_GPORT_MIM_PORT_ID_SET(gport, vp); 6681 _bcm_esw_flex_stat_handle_free(unit, _bcmFlexStatTypeGport, gport); 6682 } 6683 6684 /* if spn_RESERVE_MIM_DEFAULT_SVP is set, mim svp 1 memory is already 6685 * allocated during init time, skipping svp 1 memory free 6686 */ 6687 if(soc_feature(unit, soc_feature_mim_reserve_default_port) && 6688 soc_property_get(unit, spn_RESERVE_MIM_DEFAULT_SVP, 0) && 6689 (vp == _BCM_MIM_DEFAULT_PORT)) { 6690 mim_reserve_svp_delete = 1; 6691 } 6692 6693 if (!mim_reserve_svp_delete) { 6694 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_egress_dvp_reset(unit, vp)); 6695 /* Free the VP */ 6696 (void) _bcm_vp_free(unit, _bcmVpTypeMim, 1, vp); 6697 } 6698 return rv; 6699 } 6700 6701 /* 6702 * Function: 6703 * bcm_mim_port_delete 6704 * Purpose: 6705 * Delete an mim port from a VPN 6706 * Parameters: 6707 * unit - (IN) Device Number 6708 * vpn - (IN) VPN instance ID 6709 * mim_port_id - (IN) mim port information 6710 * Returns: 6711 * BCM_E_XXX 6712 */ 6713 int 6714 bcm_tr2_mim_port_delete(int unit, bcm_vpn_t vpn, bcm_gport_t mim_port_id) 6715 { 6716 int vp, rv; 6717 6718 MIM_INIT(unit); 6719 if (!BCM_GPORT_IS_MIM_PORT(mim_port_id)) { 6720 return BCM_E_PORT; 6721 } 6722 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port_id); 6723 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 6724 return BCM_E_NOT_FOUND; 6725 } 6726 if (!(MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_NETWORK)) { 6727 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 6728 return BCM_E_PARAM; 6729 } 6730 } 6731 MIM_LOCK(unit); 6732 rv = _bcm_tr2_mim_port_delete(unit, vpn, vp); 6733 6734 #ifdef BCM_WARM_BOOT_SUPPORT 6735 SOC_CONTROL_LOCK(unit); 6736 SOC_CONTROL(unit)->scache_dirty = 1; 6737 SOC_CONTROL_UNLOCK(unit); 6738 #endif 6739 6740 MIM_UNLOCK(unit); 6741 return rv; 6742 } 6743 6744 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6745 /* 6746 * Function: 6747 * _bcm_mim_share_vp_get 6748 * Purpose: 6749 * Get shared VPs info per VPN 6750 * Parameters: 6751 * unit - (IN) Device Number 6752 * vpn - (IN) VPN that shared vp belong to 6753 * vp_bitmap - (OUT) shared vp bitmap 6754 * Returns: 6755 * BCM_E_XXX 6756 */ 6757 int 6758 _bcm_mim_share_vp_get(int unit, bcm_vpn_t vpn, SHR_BITDCL *vp_bitmap) 6759 { 6760 void *vent; 6761 soc_mem_t mem; 6762 int index_min = 0; 6763 int index_max = 0; 6764 uint8 *xlate_buf = NULL; 6765 int buf_size = 0; 6766 int i = 0; 6767 int rv = BCM_E_NONE; 6768 int vfi = -1; 6769 int vp = -1; 6770 6771 #if defined(BCM_TRIDENT3_SUPPORT) 6772 if (soc_feature(unit, soc_feature_base_valid)) { 6773 mem = VLAN_XLATE_1_DOUBLEm; 6774 } else 6775 #endif 6776 { 6777 mem = VLAN_XLATEm; 6778 } 6779 6780 if(NULL == vp_bitmap) { 6781 return BCM_E_PARAM; 6782 } 6783 6784 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 6785 return BCM_E_PARAM; 6786 } 6787 6788 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 6789 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 6790 return BCM_E_NOT_FOUND; 6791 } 6792 6793 index_min = soc_mem_index_min(unit, mem); 6794 index_max = soc_mem_index_max(unit, mem); 6795 6796 buf_size = SOC_MEM_TABLE_BYTES(unit, mem); 6797 xlate_buf = soc_cm_salloc(unit, buf_size, "VLAN_XLATE buffer"); 6798 if (NULL == xlate_buf) { 6799 return BCM_E_MEMORY; 6800 } 6801 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max, xlate_buf); 6802 if (rv < 0) { 6803 soc_cm_sfree(unit, xlate_buf); 6804 return rv; 6805 } 6806 6807 for (i = index_min; i <= index_max; i++) { 6808 vent = soc_mem_table_idx_to_pointer(unit, 6809 mem, void *, xlate_buf, i); 6810 #if defined(BCM_TRIDENT3_SUPPORT) 6811 if (soc_feature(unit, soc_feature_base_valid)) { 6812 if (soc_mem_field32_get(unit, mem, 6813 vent, BASE_VALID_0f) != 3) { 6814 continue; 6815 } 6816 if (soc_mem_field32_get(unit, mem, 6817 vent, BASE_VALID_1f) != 7) { 6818 continue; 6819 } 6820 } else 6821 #endif 6822 { 6823 if (soc_mem_field32_get(unit, mem, 6824 vent, VALIDf) == 0) { 6825 continue; 6826 } 6827 } 6828 6829 if (soc_mem_field32_get(unit, mem, vent, XLATE__MPLS_ACTIONf) != 0x1) { 6830 continue; 6831 } 6832 6833 if (soc_mem_field32_get(unit, mem, vent, XLATE__VFIf) != vfi) { 6834 continue; 6835 } 6836 6837 vp = soc_mem_field32_get(unit, mem, vent, XLATE__SOURCE_VPf); 6838 SHR_BITSET(vp_bitmap, vp); 6839 } 6840 6841 (void)soc_cm_sfree(unit, xlate_buf); 6842 6843 return BCM_E_NONE; 6844 } 6845 6846 /* 6847 * Function: 6848 * _bcm_mim_share_vp_delete 6849 * Purpose: 6850 * Delete match criteria of shared VPs 6851 * Parameters: 6852 * unit - (IN) Device Number 6853 * vpn - (IN) VPN that shared vp belong to 6854 * vp - (IN) Source Virtual Port 6855 * Returns: 6856 * BCM_E_XXX 6857 */ 6858 int 6859 _bcm_mim_share_vp_delete(int unit, bcm_vpn_t vpn, int vp) 6860 { 6861 void *vent; 6862 soc_mem_t mem; 6863 int index_min = 0; 6864 int index_max = 0; 6865 uint8 *xlate_buf = NULL; 6866 int buf_size = 0; 6867 int i = 0; 6868 int rv = BCM_E_NONE; 6869 int vfi = -1; 6870 int source_vp = -1; 6871 6872 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 6873 return BCM_E_PARAM; 6874 } 6875 6876 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 6877 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 6878 return BCM_E_NOT_FOUND; 6879 } 6880 6881 #if defined(BCM_TRIDENT3_SUPPORT) 6882 if (soc_feature(unit, soc_feature_base_valid)) { 6883 mem = VLAN_XLATE_1_DOUBLEm; 6884 } else 6885 #endif 6886 { 6887 mem = VLAN_XLATEm; 6888 } 6889 6890 index_min = soc_mem_index_min(unit, mem); 6891 index_max = soc_mem_index_max(unit, mem); 6892 6893 buf_size = SOC_MEM_TABLE_BYTES(unit, mem); 6894 xlate_buf = soc_cm_salloc(unit, buf_size, "VLAN_XLATE buffer"); 6895 if (NULL == xlate_buf) { 6896 return BCM_E_MEMORY; 6897 } 6898 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max, xlate_buf); 6899 if (rv < 0) { 6900 soc_cm_sfree(unit, xlate_buf); 6901 return rv; 6902 } 6903 6904 for (i = index_min; i <= index_max; i++) { 6905 vent = soc_mem_table_idx_to_pointer(unit, 6906 mem, void *, xlate_buf, i); 6907 #if defined(BCM_TRIDENT3_SUPPORT) 6908 if (soc_feature(unit, soc_feature_base_valid)) { 6909 if (soc_mem_field32_get(unit, mem, 6910 vent, BASE_VALID_0f) != 3) { 6911 continue; 6912 } 6913 if (soc_mem_field32_get(unit, mem, 6914 vent, BASE_VALID_1f) != 7) { 6915 continue; 6916 } 6917 } else 6918 #endif 6919 { 6920 if (soc_mem_field32_get(unit, mem, 6921 vent, VALIDf) == 0) { 6922 continue; 6923 } 6924 } 6925 6926 if (soc_mem_field32_get(unit, mem, vent, XLATE__MPLS_ACTIONf) != 0x1) { 6927 continue; 6928 } 6929 6930 if (soc_mem_field32_get(unit, mem, vent, XLATE__VFIf) != vfi) { 6931 continue; 6932 } 6933 6934 source_vp = soc_mem_field32_get(unit, mem, vent, XLATE__SOURCE_VPf); 6935 if (vp != source_vp) { 6936 continue; 6937 } 6938 6939 rv = soc_mem_delete_index(unit, mem, MEM_BLOCK_ALL, i); 6940 if (rv < 0) { 6941 soc_cm_sfree(unit, xlate_buf); 6942 return rv; 6943 } 6944 _bcm_tr2_mim_port_match_count_adjust(unit, source_vp, -1); 6945 } 6946 6947 (void)soc_cm_sfree(unit, xlate_buf); 6948 6949 return BCM_E_NONE; 6950 } 6951 #endif 6952 6953 /* 6954 * Function: 6955 * bcm_mim_port_delete_all 6956 * Purpose: 6957 * Delete all mim ports from a VPN 6958 * Parameters: 6959 * unit - Device Number 6960 * vpn - VPN instance ID 6961 * Returns: 6962 * BCM_E_XXX 6963 */ 6964 int 6965 bcm_tr2_mim_port_delete_all(int unit, bcm_vpn_t vpn) 6966 { 6967 int rv = BCM_E_NONE; 6968 uint32 vfi, vp, num_vp; 6969 source_vp_entry_t *psvp; 6970 uint8 *source_vp_buf = NULL; 6971 int network_port = 0; 6972 _bcm_vp_info_t vp_info; 6973 6974 MIM_INIT(unit); 6975 6976 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 6977 return BCM_E_PARAM; 6978 } 6979 6980 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 6981 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 6982 rv = BCM_E_NOT_FOUND; 6983 goto done; 6984 } 6985 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 6986 6987 source_vp_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, SOURCE_VPm), 6988 "SOURCE_VP buffer"); 6989 6990 if (NULL == source_vp_buf) { 6991 return BCM_E_MEMORY; 6992 } 6993 6994 rv = soc_mem_read_range(unit, SOURCE_VPm, MEM_BLOCK_ANY, 6995 0, num_vp-1, source_vp_buf); 6996 if (rv < 0) { 6997 goto done; 6998 } 6999 7000 for (vp = 0; vp < num_vp; vp++) { 7001 network_port = FALSE; 7002 psvp = soc_mem_table_idx_to_pointer 7003 (unit, SOURCE_VPm, source_vp_entry_t *, source_vp_buf, vp); 7004 if (soc_SOURCE_VPm_field32_get(unit, psvp, ENTRY_TYPEf) != 0) { 7005 /* Network ports do not belong to a certain VPN uniquely, 7006 * it should be ignored. */ 7007 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 7008 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 7009 network_port = TRUE; 7010 } 7011 /* Shared access ports do not belong to a certain VPN uniquely, 7012 * Remove both software and hardware status of the given VPN. */ 7013 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7014 if ((!network_port) && (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 7015 if (MIM_INFO(unit)->port_info[vp].match_count > 0) { 7016 BCM_IF_ERROR_RETURN(_bcm_mim_share_vp_delete(unit, vpn, vp)); 7017 } 7018 } 7019 #endif 7020 if((vfi == soc_SOURCE_VPm_field32_get(unit, psvp, VFIf)) && 7021 (!network_port)) { 7022 rv = _bcm_tr2_mim_port_delete(unit, vpn, vp); 7023 } 7024 if (rv < 0) { 7025 goto done; 7026 } 7027 } 7028 } 7029 7030 done: 7031 if ( source_vp_buf != NULL ){ 7032 soc_cm_sfree( unit, source_vp_buf); 7033 } 7034 return rv; 7035 } 7036 7037 STATIC int 7038 _bcm_tr2_mim_l2_nh_info_get(int unit, bcm_mim_port_t *mim_port, int nh_index) 7039 { 7040 ing_l3_next_hop_entry_t ing_nh; 7041 egr_l3_next_hop_entry_t egr_nh, failover_egr_nh; 7042 egr_l3_intf_entry_t egr_intf; 7043 egr_mac_da_profile_entry_t macda; 7044 int action_present, action_not_present; 7045 int intf_num = -1, macda_idx = -1, tpid_idx = -1; 7046 bcm_module_t mod_out, mod_in; 7047 bcm_port_t port_out, port_in; 7048 bcm_trunk_t trunk_id; 7049 bcm_failover_t failover_id; 7050 int failover_nh_index = 0; 7051 int failover_vp; 7052 bcm_multicast_t failover_mc_group = 0; 7053 #if defined(BCM_KATANA2_SUPPORT) 7054 int is_local_subport = 0; 7055 bcm_port_t pp_port; 7056 int min_subport = SOC_INFO(unit).pp_port_index_min; 7057 int max_subport = SOC_INFO(unit).pp_port_index_max; 7058 #endif 7059 int entry_type = 0; 7060 int is_trunk = 0; 7061 7062 /* Read the HW entries */ 7063 BCM_IF_ERROR_RETURN (soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, 7064 nh_index, &ing_nh)); 7065 BCM_IF_ERROR_RETURN (soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 7066 nh_index, &egr_nh)); 7067 7068 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, 7069 ENTRY_TYPEf) == 0x2) { 7070 if (soc_feature(unit, soc_feature_generic_dest)) { 7071 uint32 dt, dv; 7072 dv = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, 7073 &ing_nh, DESTINATIONf, &dt); 7074 if (dt == SOC_MEM_FIF_DEST_LAG) { 7075 /* Trunk group */ 7076 trunk_id = dv & SOC_MEM_FIF_DGPP_TGID_MASK; 7077 is_trunk = 1; 7078 } else { 7079 port_in = dv & SOC_MEM_FIF_DGPP_PORT_MASK; 7080 mod_in = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 7081 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 7082 } 7083 } else { 7084 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 7085 trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 7086 is_trunk = 1; 7087 } else { 7088 mod_in = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 7089 port_in = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 7090 } 7091 } 7092 7093 if (is_trunk) { 7094 BCM_GPORT_TRUNK_SET(mim_port->port, trunk_id); 7095 } else { 7096 #if defined(BCM_KATANA2_SUPPORT) 7097 is_local_subport = 0; 7098 if (soc_feature(unit, soc_feature_linkphy_coe) || 7099 soc_feature(unit, soc_feature_subtag_coe)) { 7100 if (_bcm_kt2_mod_is_coe_mod_check(unit, mod_in) == BCM_E_NONE) { 7101 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get( 7102 unit, mod_in, port_in, &pp_port)); 7103 #if defined BCM_METROLITE_SUPPORT 7104 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 7105 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 7106 is_local_subport = 1; 7107 } 7108 } else 7109 #endif 7110 { 7111 if ((pp_port >= min_subport) && 7112 (pp_port <= max_subport)) { 7113 is_local_subport = 1; 7114 } 7115 } 7116 } 7117 } 7118 if (is_local_subport) { 7119 _BCM_KT2_SUBPORT_PORT_ID_SET(mim_port->port, pp_port); 7120 if (BCM_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, 7121 pp_port)) { 7122 _BCM_KT2_SUBPORT_PORT_TYPE_SET(mim_port->port, 7123 _BCM_KT2_SUBPORT_TYPE_LINKPHY); 7124 } else if (BCM_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, 7125 pp_port)) { 7126 _BCM_KT2_SUBPORT_PORT_TYPE_SET(mim_port->port, 7127 _BCM_KT2_SUBPORT_TYPE_SUBTAG); 7128 } else { 7129 return BCM_E_PORT; 7130 } 7131 } else 7132 #endif 7133 { 7134 SOC_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, 7135 BCM_STK_MODMAP_GET, mod_in, port_in, &mod_out, &port_out)); 7136 BCM_GPORT_MODPORT_SET(mim_port->port, mod_out, port_out); 7137 } 7138 } 7139 } else { 7140 return BCM_E_NOT_FOUND; 7141 } 7142 7143 #if defined(BCM_TRIDENT3_SUPPORT) 7144 if (SOC_IS_TRIDENT3X(unit)) { 7145 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7146 &egr_nh, DATA_TYPEf); 7147 } else 7148 #endif /* BCM_TRIDENT3_SUPPORT */ 7149 { 7150 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7151 &egr_nh, ENTRY_TYPEf); 7152 } 7153 7154 if (entry_type == 0x2) { 7155 action_present = 7156 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7157 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 7158 if (action_present) { 7159 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TAGGED; 7160 } 7161 action_not_present = 7162 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7163 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 7164 7165 if ((action_not_present == 0x1) || (action_present == 0x1)) { 7166 /* If SD tag action is ADD or REPLACE_VID_TPID, the tpid 7167 * index of the entry is valid. Get the tpid index for later. 7168 */ 7169 tpid_idx = 7170 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7171 SD_TAG__SD_TAG_TPID_INDEXf); 7172 mim_port->egress_service_vlan = 7173 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__SD_TAG_VIDf); 7174 if (action_not_present) { 7175 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD; 7176 } 7177 if (action_present) { 7178 mim_port->flags |= 7179 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE; 7180 } 7181 _bcm_fb2_outer_tpid_entry_get(unit, &mim_port->egress_service_tpid, tpid_idx); 7182 } else if (action_present == 0x2) { /* REPLACE_VID_ONLY */ 7183 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_REPLACE; 7184 mim_port->egress_service_vlan = 7185 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__SD_TAG_VIDf); 7186 } else if (action_present == 0x3) { /* DELETE */ 7187 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_DELETE; 7188 } else if (action_present == 0x4) { /* REPLACE VID TPID PRI ONLY */ 7189 mim_port->flags |= 7190 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_PRI_TPID_REPLACE; 7191 mim_port->egress_service_vlan = 7192 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__SD_TAG_VIDf); 7193 mim_port->egress_service_pri = 7194 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__NEW_PRIf); 7195 mim_port->egress_service_cfi = 7196 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__NEW_CFIf); 7197 tpid_idx = 7198 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7199 SD_TAG__SD_TAG_TPID_INDEXf); 7200 _bcm_fb2_outer_tpid_entry_get(unit, &mim_port->egress_service_tpid, tpid_idx); 7201 } else if (action_present == 0x5) { /* REPLACE VID PRI ONLY */ 7202 mim_port->flags |= 7203 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_PRI_REPLACE; 7204 mim_port->egress_service_vlan = 7205 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__SD_TAG_VIDf); 7206 mim_port->egress_service_pri = 7207 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__NEW_PRIf); 7208 mim_port->egress_service_cfi = 7209 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__NEW_CFIf); 7210 } 7211 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 7212 else if (action_present == 0x6) { 7213 mim_port->flags |= 7214 BCM_MIM_PORT_EGRESS_SERVICE_PRI_REPLACE; 7215 mim_port->egress_service_pri = 7216 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__NEW_PRIf); 7217 mim_port->egress_service_cfi = 7218 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, SD_TAG__NEW_CFIf); 7219 } else if (action_present == 0x7){ 7220 mim_port->flags |= 7221 BCM_MIM_PORT_EGRESS_SERVICE_TPID_REPLACE; 7222 tpid_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7223 SD_TAG__SD_TAG_TPID_INDEXf); 7224 _bcm_fb2_outer_tpid_entry_get(unit, &mim_port->egress_service_tpid, tpid_idx); 7225 } 7226 #endif 7227 } else if (entry_type == 0x3) { 7228 /* Backbone / peer VP */ 7229 /* Get the tunnel encap attributes */ 7230 mim_port->egress_tunnel_vlan = 7231 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, MIM__BVIDf); 7232 intf_num = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7233 MIM__INTF_NUMf); 7234 macda_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7235 MIM__MAC_DA_PROFILE_INDEXf); 7236 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_INTFm, MEM_BLOCK_ANY, 7237 intf_num, &egr_intf)); 7238 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MAC_DA_PROFILEm, 7239 MEM_BLOCK_ANY, macda_idx, &macda)); 7240 soc_mem_mac_addr_get(unit, EGR_L3_INTFm, &egr_intf, MAC_ADDRESSf, 7241 mim_port->egress_tunnel_srcmac); 7242 soc_mem_mac_addr_get(unit, EGR_MAC_DA_PROFILEm, &macda, MAC_ADDRESSf, 7243 mim_port->egress_tunnel_dstmac); 7244 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, MIM__ISID_LOOKUP_TYPEf)) { 7245 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7246 MIM__ISID_LOOKUP_TYPEf) == 0) { 7247 mim_port->flags |= BCM_MIM_PORT_TYPE_BACKBONE; 7248 } else { 7249 mim_port->flags |= BCM_MIM_PORT_TYPE_PEER; 7250 } 7251 } 7252 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7253 MIM__ADD_ISID_TO_MACDAf) == 1) { 7254 mim_port->flags |= BCM_MIM_PORT_EGRESS_TUNNEL_DEST_MAC_USE_SERVICE; 7255 } 7256 } 7257 7258 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, DROPf)) { 7259 mim_port->flags |= BCM_MIM_PORT_DROP; 7260 } 7261 7262 #if defined(BCM_ENDURO_SUPPORT) 7263 if (!SOC_IS_ENDURO(unit)) { 7264 #endif 7265 /* Get failover info */ 7266 BCM_IF_ERROR_RETURN( 7267 _bcm_esw_failover_prot_nhi_get (unit, nh_index, 7268 &failover_id, &failover_nh_index, &failover_mc_group)); 7269 7270 mim_port->failover_id = failover_id; 7271 if (failover_mc_group != 0) { 7272 _BCM_MULTICAST_GROUP_SET(mim_port->failover_mc_group, 7273 _BCM_MULTICAST_TYPE_MIM, 7274 _BCM_MULTICAST_ID_GET(failover_mc_group)); 7275 } 7276 if (failover_nh_index > 0) { 7277 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 7278 failover_nh_index, &failover_egr_nh)); 7279 #if defined(BCM_TRIDENT3_SUPPORT) 7280 if (SOC_IS_TRIDENT3X(unit)) { 7281 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7282 &failover_egr_nh, DATA_TYPEf); 7283 } else 7284 #endif /* BCM_TRIDENT3_SUPPORT */ 7285 { 7286 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7287 &failover_egr_nh, ENTRY_TYPEf); 7288 } 7289 7290 if (entry_type == 0x3) { 7291 failover_vp = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7292 &failover_egr_nh, 7293 MIM__DVPf); 7294 } else if (entry_type == 0x2) { 7295 failover_vp = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7296 &failover_egr_nh, 7297 SD_TAG__DVPf); 7298 } else { 7299 return BCM_E_INTERNAL; /* should not get here */ 7300 } 7301 BCM_GPORT_MIM_PORT_ID_SET(mim_port->failover_gport_id, failover_vp); 7302 } 7303 7304 #if defined(BCM_ENDURO_SUPPORT) 7305 } 7306 #endif 7307 return BCM_E_NONE; 7308 } 7309 7310 STATIC int 7311 _bcm_tr2_mim_match_get(int unit, bcm_mim_port_t *mim_port, int vp) 7312 { 7313 int modid_count, rv = BCM_E_NONE; 7314 bcm_module_t mod_in, mod_out; 7315 bcm_port_t port_in, port_out; 7316 bcm_trunk_t trunk_id; 7317 uint64 temp_mac; 7318 7319 if ((MIM_INFO(unit)->port_info[vp].flags & 7320 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN) || 7321 (MIM_INFO(unit)->port_info[vp].flags & 7322 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED)) { 7323 7324 if (MIM_INFO(unit)->port_info[vp].match_count == 0) { 7325 return BCM_E_NONE; 7326 } 7327 mim_port->flags |= BCM_MIM_PORT_TYPE_ACCESS; 7328 mim_port->match_vlan = MIM_INFO(unit)->port_info[vp].match_vlan; 7329 7330 if ((MIM_INFO(unit)->port_info[vp].flags & 7331 _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED)) { 7332 mim_port->match_inner_vlan = 7333 MIM_INFO(unit)->port_info[vp].match_inner_vlan; 7334 mim_port->criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED; 7335 } else { 7336 mim_port->criteria = BCM_MIM_PORT_MATCH_PORT_VLAN; 7337 } 7338 7339 if ((MIM_INFO(unit)->port_info[vp].tgid != -1)) { 7340 trunk_id = MIM_INFO(unit)->port_info[vp].tgid; 7341 BCM_GPORT_TRUNK_SET(mim_port->port, trunk_id); 7342 } else { 7343 mod_in = MIM_INFO(unit)->port_info[vp].modid; 7344 port_in = MIM_INFO(unit)->port_info[vp].port; 7345 7346 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 7347 mod_in, port_in, &mod_out, &port_out); 7348 BCM_GPORT_MODPORT_SET(mim_port->port, mod_out, port_out); 7349 } 7350 7351 } else if (MIM_INFO(unit)->port_info[vp].flags & 7352 _BCM_MIM_PORT_TYPE_ACCESS_PORT) { 7353 mim_port->flags |= (BCM_MIM_PORT_TYPE_ACCESS); 7354 mim_port->criteria = BCM_MIM_PORT_MATCH_PORT; 7355 modid_count = SOC_MODID_MAX(unit) + 1; 7356 7357 if ( SOC_IS_TRIUMPH3(unit) ) { 7358 int src_trk_idx=0; /*Source Trunk table index.*/ 7359 source_trunk_map_modbase_entry_t modbase_entry; 7360 7361 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_in)); 7362 src_trk_idx = MIM_INFO(unit)->port_info[vp].index % modid_count; 7363 7364 BCM_IF_ERROR_RETURN 7365 (soc_mem_read(unit, SOURCE_TRUNK_MAP_MODBASEm, 7366 MEM_BLOCK_ANY, mod_in, &modbase_entry)); 7367 7368 port_in = src_trk_idx - soc_mem_field32_get(unit, 7369 SOURCE_TRUNK_MAP_MODBASEm, 7370 &modbase_entry, BASEf); 7371 } else { 7372 port_in = MIM_INFO(unit)->port_info[vp].index % modid_count; 7373 mod_in = MIM_INFO(unit)->port_info[vp].index / modid_count; 7374 } 7375 7376 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 7377 mod_in, port_in, &mod_out, &port_out); 7378 BCM_GPORT_MODPORT_SET(mim_port->port, mod_out, port_out); 7379 7380 } else if (MIM_INFO(unit)->port_info[vp].flags & 7381 _BCM_MIM_PORT_TYPE_ACCESS_LABEL) { 7382 mim_port->flags |= (BCM_MIM_PORT_TYPE_ACCESS); 7383 mim_port->criteria = BCM_MIM_PORT_MATCH_LABEL; 7384 mim_port->match_label = MIM_INFO(unit)->port_info[vp].match_label; 7385 7386 if ((MIM_INFO(unit)->port_info[vp].tgid != -1)) { 7387 trunk_id = MIM_INFO(unit)->port_info[vp].tgid; 7388 BCM_GPORT_TRUNK_SET(mim_port->port, trunk_id); 7389 } else { 7390 mod_in = MIM_INFO(unit)->port_info[vp].modid; 7391 port_in = MIM_INFO(unit)->port_info[vp].port; 7392 7393 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 7394 mod_in, port_in, &mod_out, &port_out); 7395 BCM_GPORT_MODPORT_SET(mim_port->port, mod_out, port_out); 7396 } 7397 7398 } else if (MIM_INFO(unit)->port_info[vp].flags & 7399 (_BCM_MIM_PORT_TYPE_NETWORK | _BCM_MIM_PORT_TYPE_PEER)) { 7400 mim_port->criteria = BCM_MIM_PORT_MATCH_TUNNEL_VLAN_SRCMAC; 7401 if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_PEER) { 7402 mim_port->flags |= BCM_MIM_PORT_TYPE_PEER; 7403 #if defined(BCM_TRIDENT_SUPPORT) 7404 if (soc_feature(unit, soc_feature_mim_peer_sharing) && 7405 (MIM_INFO(unit)->port_info[vp].flags & 7406 _BCM_MIM_PORT_TYPE_SHARE)) { 7407 mim_port->flags |= BCM_MIM_PORT_SHARE; 7408 } 7409 #endif /* BCM_TRIDENT_SUPPORT */ 7410 } else { 7411 mim_port->flags |= BCM_MIM_PORT_TYPE_BACKBONE; 7412 } 7413 7414 SAL_MAC_ADDR_TO_UINT64 7415 (MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac, temp_mac); 7416 SAL_MAC_ADDR_FROM_UINT64(mim_port->match_tunnel_srcmac, temp_mac); 7417 mim_port->match_tunnel_vlan = 7418 MIM_INFO(unit)->port_info[vp].match_tunnel_vlan; 7419 7420 if ((MIM_INFO(unit)->port_info[vp].tgid != -1)) { 7421 trunk_id = MIM_INFO(unit)->port_info[vp].tgid; 7422 BCM_GPORT_TRUNK_SET(mim_port->port, trunk_id); 7423 } else { 7424 mod_in = MIM_INFO(unit)->port_info[vp].modid; 7425 port_in = MIM_INFO(unit)->port_info[vp].port; 7426 7427 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 7428 mod_in, port_in, &mod_out, &port_out); 7429 BCM_GPORT_MODPORT_SET(mim_port->port, mod_out, port_out); 7430 } 7431 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7432 if (soc_feature(unit, soc_feature_ingress_failover)) { 7433 uint32 ment[SOC_MAX_MEM_WORDS]; 7434 int index = -1; 7435 soc_mem_t mpls_mem = MPLS_ENTRYm; 7436 7437 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 7438 soc_mem_field32_set(unit, mpls_mem, ment, KEY_TYPEf, 1); 7439 #if defined(BCM_TRIDENT3_SUPPORT) 7440 if (soc_feature(unit, soc_feature_base_valid)) { 7441 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_0f, 3); 7442 soc_mem_field32_set(unit, mpls_mem, ment, BASE_VALID_1f, 7); 7443 } else 7444 #endif 7445 { 7446 soc_mem_field32_set(unit, mpls_mem, ment, VALIDf, 0x1); 7447 } 7448 soc_mem_field32_set(unit, mpls_mem, ment, MIM_NVP__BVIDf, 7449 MIM_INFO(unit)->port_info[vp].match_tunnel_vlan); 7450 soc_mem_mac_addr_set(unit, mpls_mem, ment, MIM_NVP__BMACSAf, 7451 MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac); 7452 BCM_IF_ERROR_RETURN(soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, 7453 &index, ment, ment, 0)); 7454 if (soc_mem_field32_get(unit, mpls_mem, ment, 7455 MIM_NVP__DROP_DATA_ENABLEf)) { 7456 mim_port->flags |= BCM_MIM_PORT_FAILOVER_DROP; 7457 } 7458 mim_port->ingress_failover_id = 7459 soc_mem_field32_get(unit, mpls_mem, ment, 7460 MIM_NVP__RX_PROT_GROUPf); 7461 if (mim_port->ingress_failover_id != 0) { 7462 _BCM_ENCAP_TYPE_IN_FAILOVER_ID(mim_port->ingress_failover_id, 7463 _BCM_FAILOVER_INGRESS); 7464 } 7465 } 7466 #endif 7467 } else if (MIM_INFO(unit)->port_info[vp].flags & 7468 _BCM_MIM_PORT_TYPE_ACCESS_SHARED) { 7469 mim_port->flags |= BCM_MIM_PORT_TYPE_ACCESS; 7470 mim_port->criteria = BCM_MIM_PORT_MATCH_SHARE; 7471 } 7472 return rv; 7473 } 7474 7475 STATIC int 7476 _bcm_tr2_mim_egr_vxlt_sd_tag_actions_get( 7477 int unit, bcm_mim_port_t *mim_port, bcm_mim_vpn_config_t *vpn_info, 7478 uint32 *egr_vlan_xlate_entry) 7479 { 7480 int action_present, action_not_present, tpid_idx; 7481 soc_mem_t egr_xlate_mem; 7482 7483 #if defined(BCM_TRIDENT3_SUPPORT) 7484 if (soc_feature(unit, soc_feature_base_valid)) { 7485 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 7486 } else 7487 #endif 7488 { 7489 egr_xlate_mem = EGR_VLAN_XLATEm; 7490 } 7491 7492 /* Populate the API structure */ 7493 action_present = 7494 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7495 MIM_ISID__SD_TAG_ACTION_IF_PRESENTf); 7496 action_not_present = 7497 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7498 MIM_ISID__SD_TAG_ACTION_IF_NOT_PRESENTf); 7499 if (mim_port != NULL) { 7500 if (action_present) { 7501 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TAGGED; 7502 } 7503 7504 if ((action_not_present == 0x1) || (action_present == 0x1)) { 7505 /* If SD tag action is ADD or REPLACE_VID_TPID, the tpid 7506 * index of the entry is valid. Get the tpid index for later. 7507 */ 7508 tpid_idx = 7509 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7510 MIM_ISID__SD_TAG_TPID_INDEXf); 7511 mim_port->egress_service_vlan = 7512 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7513 MIM_ISID__SD_TAG_VIDf); 7514 if (action_not_present) { 7515 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_ADD; 7516 } 7517 if (action_present) { 7518 mim_port->flags |= 7519 BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TPID_REPLACE; 7520 } 7521 _bcm_fb2_outer_tpid_entry_get(unit, &mim_port->egress_service_tpid, tpid_idx); 7522 } else if (action_present == 0x2) { /* REPLACE_VID_ONLY */ 7523 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_REPLACE; 7524 mim_port->egress_service_vlan = 7525 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7526 MIM_ISID__SD_TAG_VIDf); 7527 } else if (action_present == 0x3) { /* DELETE */ 7528 mim_port->flags |= BCM_MIM_PORT_EGRESS_SERVICE_VLAN_DELETE; 7529 } 7530 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 7531 else if (action_present == 0x6) { 7532 mim_port->flags |= 7533 BCM_MIM_PORT_EGRESS_SERVICE_PRI_REPLACE; 7534 mim_port->egress_service_pri = 7535 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7536 MIM_ISID__NEW_PRIf); 7537 mim_port->egress_service_cfi = 7538 soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7539 MIM_ISID__NEW_CFIf); 7540 } else if (action_present == 0x7) { 7541 mim_port->flags |= 7542 BCM_MIM_PORT_EGRESS_SERVICE_TPID_REPLACE; 7543 tpid_idx = soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7544 MIM_ISID__SD_TAG_TPID_INDEXf); 7545 _bcm_fb2_outer_tpid_entry_get(unit, &mim_port->egress_service_tpid, tpid_idx); 7546 } 7547 #endif 7548 } else if (vpn_info != NULL) { 7549 if (action_present == 0x7) { 7550 vpn_info->flags |= BCM_MIM_VPN_EGRESS_SERVICE_TPID_REPLACE; 7551 tpid_idx = soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7552 MIM_ISID__SD_TAG_TPID_INDEXf); 7553 _bcm_fb2_outer_tpid_entry_get(unit, &vpn_info->egress_service_tpid, 7554 tpid_idx); 7555 } 7556 } 7557 7558 return BCM_E_NONE; 7559 } 7560 7561 /* 7562 * Function: 7563 * _bcm_tr2_mim_peer_port_config_get 7564 * Purpose: 7565 * Get the information of peer port 7566 * Parameters: 7567 * unit - (IN) Device Number 7568 * mim_port - (IN/OUT) MIM port information 7569 * vp - (IN) Virtual Port 7570 * vpn - (IN) VPN instance ID 7571 */ 7572 STATIC int 7573 _bcm_tr2_mim_peer_port_config_get(int unit, bcm_mim_port_t *mim_port, 7574 int vp, bcm_mim_vpn_t vpn) 7575 { 7576 uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS]; 7577 int index = -1; 7578 int vfi = -1; 7579 int isid = -1; 7580 int rv = BCM_E_NONE; 7581 soc_mem_t egr_xlate_mem; 7582 7583 #if defined(BCM_TRIDENT3_SUPPORT) 7584 if (soc_feature(unit, soc_feature_base_valid)) { 7585 egr_xlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 7586 } else 7587 #endif 7588 { 7589 egr_xlate_mem = EGR_VLAN_XLATEm; 7590 } 7591 7592 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 7593 7594 sal_memset(egr_vlan_xlate_entry, 0, sizeof(egr_vlan_xlate_entry)); 7595 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, ENTRY_TYPEf, 0x4); 7596 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__VFIf, vfi); 7597 if (soc_feature(unit, soc_feature_base_valid)) { 7598 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, BASE_VALID_0f, 0x3); 7599 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, BASE_VALID_1f, 0x7); 7600 } else { 7601 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, VALIDf, 0x1); 7602 } 7603 soc_mem_field32_set(unit, egr_xlate_mem, egr_vlan_xlate_entry, MIM_ISID__DVPf, vp); 7604 7605 rv = soc_mem_search(unit, egr_xlate_mem, MEM_BLOCK_ANY, &index, 7606 egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0); 7607 BCM_IF_ERROR_RETURN(rv); 7608 7609 isid = soc_mem_field32_get(unit, egr_xlate_mem, egr_vlan_xlate_entry, 7610 MIM_ISID__ISIDf); 7611 if (isid != -1) { 7612 mim_port->egress_tunnel_service = isid; 7613 mim_port->flags |= BCM_MIM_PORT_EGRESS_TUNNEL_SERVICE_REPLACE; 7614 } 7615 7616 BCM_IF_ERROR_RETURN( 7617 _bcm_tr2_mim_egr_vxlt_sd_tag_actions_get(unit, mim_port, NULL, 7618 egr_vlan_xlate_entry)); 7619 7620 return rv; 7621 } 7622 7623 STATIC int 7624 _bcm_tr2_mim_port_get(int unit, bcm_vpn_t vpn, int vp, 7625 bcm_mim_port_t *mim_port) 7626 { 7627 int i, nh_index, tpid_enable = 0, rv = BCM_E_NONE; 7628 ing_dvp_table_entry_t dvp; 7629 source_vp_entry_t svp; 7630 #if defined(BCM_TRIDENT3_SUPPORT) 7631 uint32 svp1[SOC_MAX_MEM_WORDS] = {0}; 7632 #endif 7633 7634 /* Initialize the structure */ 7635 bcm_mim_port_t_init(mim_port); 7636 BCM_GPORT_MIM_PORT_ID_SET(mim_port->mim_port_id, vp); 7637 7638 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 7639 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 7640 7641 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 7642 if (soc_mem_field_valid(unit, ING_DVP_TABLEm, NETWORK_GROUPf)) { 7643 mim_port->network_group_id = soc_ING_DVP_TABLEm_field32_get( 7644 unit, &dvp, NETWORK_GROUPf); 7645 } 7646 } 7647 7648 /* Get the match parameters */ 7649 rv = _bcm_tr2_mim_match_get(unit, mim_port, vp); 7650 BCM_IF_ERROR_RETURN(rv); 7651 7652 /* Get the next-hop parameters */ 7653 rv = _bcm_tr2_mim_l2_nh_info_get(unit, mim_port, nh_index); 7654 BCM_IF_ERROR_RETURN(rv); 7655 7656 #if defined(BCM_TRIDENT3_SUPPORT) 7657 if (SOC_IS_TRIDENT3X(unit)) { 7658 rv = _bcm_tr2_mim_dvp_get(unit, vp, mim_port); 7659 BCM_IF_ERROR_RETURN(rv); 7660 } 7661 #endif 7662 7663 mim_port->encap_id = nh_index + BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 7664 7665 /* For peer ports, get the peer information if configured */ 7666 if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_PEER) { 7667 if (!SOC_IS_TRIUMPH3(unit)) { 7668 rv = _bcm_tr2_mim_peer_port_config_get(unit, mim_port, vp, vpn); 7669 BCM_IF_ERROR_RETURN(rv); 7670 } 7671 } 7672 7673 /* Fill in SVP parameters */ 7674 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 7675 #if defined(BCM_TRIDENT3_SUPPORT) 7676 if (SOC_IS_TRIDENT3X(unit)) { 7677 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1)); 7678 7679 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 7680 if (soc_mem_field_valid(unit, SOURCE_VPm, NETWORK_GROUPf)) { 7681 mim_port->network_group_id = soc_SOURCE_VPm_field32_get(unit, 7682 &svp, NETWORK_GROUPf); 7683 } 7684 } 7685 } 7686 #endif 7687 mim_port->if_class = soc_SOURCE_VPm_field32_get(unit, &svp, CLASS_IDf); 7688 if (soc_SOURCE_VPm_field32_get(unit, &svp, SD_TAG_MODEf)) { 7689 #if defined(BCM_TRIDENT3_SUPPORT) 7690 if (SOC_IS_TRIDENT3X(unit)) { 7691 tpid_enable = soc_SVP_ATTRS_1m_field32_get(unit, &svp1, TPID_ENABLEf); 7692 } else 7693 #endif 7694 { 7695 tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 7696 } 7697 if (tpid_enable) { 7698 mim_port->flags |= BCM_MIM_PORT_MATCH_SERVICE_VLAN_TPID; 7699 for (i = 0; i < 4; i++) { 7700 if (tpid_enable & (1 << i)) { 7701 _bcm_fb2_outer_tpid_entry_get(unit, 7702 &mim_port->match_service_tpid, i); 7703 } 7704 } 7705 } 7706 } 7707 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 7708 if (soc_feature(unit, soc_feature_global_meter)) { 7709 rv = _bcm_esw_get_policer_from_table(unit, SOURCE_VPm, vp, &svp, 7710 &mim_port->policer_id, 1); 7711 } 7712 #endif 7713 return rv; 7714 } 7715 7716 /* 7717 * Function: 7718 * bcm_mim_port_get 7719 * Purpose: 7720 * Get an mim port 7721 * Parameters: 7722 * unit - (IN) Device Number 7723 * vpn - (IN) VPN instance ID 7724 * mim_port - (IN/OUT) mim port information 7725 */ 7726 int 7727 bcm_tr2_mim_port_get(int unit, bcm_vpn_t vpn, bcm_mim_port_t *mim_port) 7728 { 7729 int vp; 7730 7731 MIM_INIT(unit); 7732 7733 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 7734 return BCM_E_PARAM; 7735 } 7736 if (!BCM_GPORT_IS_MIM_PORT(mim_port->mim_port_id)) { 7737 return BCM_E_PORT; 7738 } 7739 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port->mim_port_id); 7740 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 7741 return BCM_E_NOT_FOUND; 7742 } 7743 return _bcm_tr2_mim_port_get(unit, vpn, vp, mim_port); 7744 } 7745 7746 /* 7747 * Function: 7748 * bcm_mim_port_get_all 7749 * Purpose: 7750 * Get all the mim ports from a VPN 7751 * Parameters: 7752 * unit - (IN) Device Number 7753 * vpn - (IN) VPN instance ID 7754 * port_max - (IN) Maximum number of interfaces in array 7755 * port_array - (OUT) Array of mpls ports 7756 * port_count - (OUT) Number of interfaces returned in array 7757 */ 7758 int 7759 bcm_tr2_mim_port_get_all(int unit, bcm_vpn_t vpn, int port_max, 7760 bcm_mim_port_t *port_array, int *port_count) 7761 { 7762 int vp = 0, rv = BCM_E_NONE; 7763 uint32 vfi = -1, num_vp = 0; 7764 source_vp_entry_t svp; 7765 int network_port = 0; 7766 _bcm_vp_info_t vp_info; 7767 SHR_BITDCL *share_vp_bitmap = NULL; 7768 7769 MIM_INIT(unit); 7770 7771 if (!_BCM_MIM_VPN_IS_SET(vpn)) { 7772 return BCM_E_PARAM; 7773 } 7774 7775 *port_count = 0; 7776 7777 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn); 7778 7779 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 7780 rv = BCM_E_NOT_FOUND; 7781 goto done; 7782 } 7783 7784 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 7785 share_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "share_vp_bitmap"); 7786 if (share_vp_bitmap == NULL) { 7787 return BCM_E_MEMORY; 7788 } 7789 sal_memset(share_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 7790 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7791 if (soc_feature(unit, soc_feature_vp_sharing)) { 7792 rv = _bcm_mim_share_vp_get(unit, vpn, share_vp_bitmap); 7793 if (rv < 0) { 7794 goto done; 7795 } 7796 } 7797 #endif 7798 7799 for (vp = 0; vp < num_vp; vp++) { 7800 if (*port_count == port_max) { 7801 break; 7802 } 7803 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 7804 if (rv < 0) { 7805 goto done; 7806 } 7807 7808 if (soc_SOURCE_VPm_field32_get( unit, &svp, ENTRY_TYPEf) == 1) { 7809 /* Network ports do not belong to a certain VPN uniquely, 7810 * it should be ignored. */ 7811 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 7812 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 7813 network_port = TRUE; 7814 } 7815 7816 if(((vfi == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf)) && 7817 (!network_port)) 7818 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7819 || (SHR_BITGET(share_vp_bitmap, vp) 7820 && (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) 7821 #endif 7822 ) { 7823 rv = _bcm_tr2_mim_port_get(unit, vpn, vp, 7824 &port_array[*port_count]); 7825 if ((rv < 0) && rv != BCM_E_NOT_FOUND) { 7826 goto done; 7827 } 7828 if (rv != BCM_E_NOT_FOUND) { 7829 BCM_GPORT_MIM_PORT_ID_SET 7830 (port_array[*port_count].mim_port_id, vp); 7831 (*port_count)++; 7832 } 7833 } 7834 } 7835 } 7836 done: 7837 if(share_vp_bitmap != NULL) { 7838 sal_free(share_vp_bitmap); 7839 } 7840 return (*port_count > 0)? BCM_E_NONE:rv; 7841 } 7842 7843 /* 7844 * Function: 7845 * _bcm_tr2_mim_port_resolve 7846 * Purpose: 7847 * Get the modid, port, trunk values for a MIM port 7848 * Returns: 7849 * BCM_E_XXX 7850 */ 7851 int 7852 _bcm_tr2_mim_port_resolve(int unit, bcm_gport_t mim_port_id, 7853 bcm_module_t *modid, bcm_port_t *port, 7854 bcm_trunk_t *trunk_id, int *id) 7855 7856 { 7857 int rv = BCM_E_NONE, nh_index, vp; 7858 ing_l3_next_hop_entry_t ing_nh; 7859 ing_dvp_table_entry_t dvp; 7860 7861 MIM_INIT(unit); 7862 7863 if (!BCM_GPORT_IS_MIM_PORT(mim_port_id)) { 7864 return (BCM_E_BADID); 7865 } 7866 7867 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port_id); 7868 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 7869 return BCM_E_NOT_FOUND; 7870 } 7871 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 7872 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 7873 NEXT_HOP_INDEXf); 7874 BCM_IF_ERROR_RETURN (soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, 7875 nh_index, &ing_nh)); 7876 7877 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf) != 0x2) { 7878 /* Entry type is not L2 DVP */ 7879 return BCM_E_NOT_FOUND; 7880 } 7881 7882 if (soc_feature(unit, soc_feature_generic_dest)) { 7883 uint32 dt, dv; 7884 dv = soc_mem_field32_dest_get(unit, ING_L3_NEXT_HOPm, 7885 &ing_nh, DESTINATIONf, &dt); 7886 if (dt == SOC_MEM_FIF_DEST_LAG) { 7887 /* Trunk group */ 7888 *trunk_id = dv & SOC_MEM_FIF_DGPP_TGID_MASK; 7889 } else { 7890 *port = dv & SOC_MEM_FIF_DGPP_PORT_MASK; 7891 *modid = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 7892 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 7893 } 7894 } else { 7895 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 7896 *trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 7897 } else { 7898 *modid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 7899 *port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 7900 } 7901 } 7902 *id = vp; 7903 return rv; 7904 } 7905 7906 /* 7907 * Function: 7908 * bcm_tr2_mim_port_learn_get 7909 * Purpose: 7910 * Get the CML bits for an mim port 7911 * Returns: 7912 * BCM_E_XXX 7913 */ 7914 int 7915 bcm_tr2_mim_port_learn_get(int unit, bcm_gport_t mim_port_id, uint32 *flags) 7916 { 7917 int rv, vp, cml = 0; 7918 source_vp_entry_t svp; 7919 7920 MIM_INIT(unit); 7921 7922 /* Get the VP index from the gport */ 7923 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port_id); 7924 if (vp == -1) { 7925 return BCM_E_PARAM; 7926 } 7927 7928 MEM_LOCK(unit, SOURCE_VPm); 7929 /* Be sure the entry is used and is set for VPLS */ 7930 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) { 7931 MEM_UNLOCK(unit, SOURCE_VPm); 7932 return BCM_E_NOT_FOUND; 7933 } 7934 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 7935 if (rv < 0) { 7936 MEM_UNLOCK(unit, SOURCE_VPm); 7937 return rv; 7938 } 7939 if (soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf) != 1) { /* L2 VP */ 7940 MEM_UNLOCK(unit, SOURCE_VPm); 7941 return BCM_E_NOT_FOUND; 7942 } 7943 MEM_UNLOCK(unit, SOURCE_VPm); 7944 cml = soc_SOURCE_VPm_field32_get(unit, &svp, CML_FLAGS_NEWf); 7945 7946 *flags = 0; 7947 if (!(cml & (1 << 0))) { 7948 *flags |= BCM_PORT_LEARN_FWD; 7949 } 7950 if (cml & (1 << 1)) { 7951 *flags |= BCM_PORT_LEARN_CPU; 7952 } 7953 if (cml & (1 << 2)) { 7954 *flags |= BCM_PORT_LEARN_PENDING; 7955 } 7956 if (cml & (1 << 3)) { 7957 *flags |= BCM_PORT_LEARN_ARL; 7958 } 7959 return BCM_E_NONE; 7960 } 7961 7962 /* 7963 * Function: 7964 * bcm_tr2_mim_port_learn_set 7965 * Purpose: 7966 * Set the CML bits for an mim port. 7967 * Returns: 7968 * BCM_E_XXX 7969 */ 7970 int 7971 bcm_tr2_mim_port_learn_set(int unit, bcm_gport_t mim_port_id, uint32 flags) 7972 { 7973 int vp, cml = 0, rv = BCM_E_NONE; 7974 source_vp_entry_t svp; 7975 7976 MIM_INIT(unit); 7977 7978 cml = 0; 7979 if (!(flags & BCM_PORT_LEARN_FWD)) { 7980 cml |= (1 << 0); 7981 } 7982 if (flags & BCM_PORT_LEARN_CPU) { 7983 cml |= (1 << 1); 7984 } 7985 if (flags & BCM_PORT_LEARN_PENDING) { 7986 cml |= (1 << 2); 7987 } 7988 if (flags & BCM_PORT_LEARN_ARL) { 7989 cml |= (1 << 3); 7990 } 7991 7992 /* Get the VP index from the gport */ 7993 vp = BCM_GPORT_MIM_PORT_ID_GET(mim_port_id); 7994 if (vp == -1) { 7995 return BCM_E_PARAM; 7996 } 7997 7998 MEM_LOCK(unit, SOURCE_VPm); 7999 /* Be sure the entry is used and is set for MIM */ 8000 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) { 8001 MEM_UNLOCK(unit, SOURCE_VPm); 8002 return BCM_E_NOT_FOUND; 8003 } 8004 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 8005 if (rv < 0) { 8006 MEM_UNLOCK(unit, SOURCE_VPm); 8007 return rv; 8008 } 8009 if (soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf) != 1) { /* L2 VP */ 8010 MEM_UNLOCK(unit, SOURCE_VPm); 8011 return BCM_E_NOT_FOUND; 8012 } 8013 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, cml); 8014 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, cml); 8015 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 8016 MEM_UNLOCK(unit, SOURCE_VPm); 8017 return rv; 8018 } 8019 8020 int 8021 _bcm_esw_mim_flex_stat_index_set(int unit, bcm_gport_t port, int fs_idx, 8022 uint32 flags) 8023 { 8024 int rv, vp, nh_index; 8025 source_vp_entry_t svp; 8026 ing_dvp_table_entry_t dvp; 8027 egr_l3_next_hop_entry_t next_hop; 8028 8029 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 8030 if (vp == -1) { 8031 return BCM_E_PARAM; 8032 } 8033 8034 rv = BCM_E_NONE; 8035 8036 MIM_LOCK(unit); 8037 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 8038 MIM_UNLOCK(unit); 8039 return BCM_E_NOT_FOUND; 8040 } else { 8041 /* Ingress side */ 8042 if (flags & _BCM_FLEX_STAT_HW_INGRESS) { 8043 rv = soc_mem_read(unit, SOURCE_VPm, MEM_BLOCK_ANY, vp, &svp); 8044 if (BCM_SUCCESS(rv)) { 8045 if (soc_mem_field_valid(unit, SOURCE_VPm, USE_VINTF_CTR_IDXf)) { 8046 soc_mem_field32_set(unit, SOURCE_VPm, &svp, USE_VINTF_CTR_IDXf, 8047 fs_idx > 0 ? 1 : 0); 8048 } 8049 soc_mem_field32_set(unit, SOURCE_VPm, &svp, VINTF_CTR_IDXf, 8050 fs_idx); 8051 rv = soc_mem_write(unit, SOURCE_VPm, MEM_BLOCK_ALL, vp, &svp); 8052 } 8053 } 8054 if (flags & _BCM_FLEX_STAT_HW_EGRESS) { 8055 if (BCM_SUCCESS(rv)) { 8056 /* Egress side */ 8057 rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp); 8058 } 8059 if (BCM_SUCCESS(rv)) { 8060 nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp, 8061 NEXT_HOP_INDEXf); 8062 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 8063 nh_index, &next_hop); 8064 if (BCM_SUCCESS(rv)) { 8065 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 8066 USE_VINTF_CTR_IDXf)) { 8067 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &next_hop, 8068 USE_VINTF_CTR_IDXf, 8069 fs_idx > 0 ? 1 : 0); 8070 } 8071 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &next_hop, 8072 VINTF_CTR_IDXf, fs_idx); 8073 rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL, 8074 nh_index, &next_hop); 8075 } 8076 } 8077 } 8078 } 8079 8080 MIM_UNLOCK(unit); 8081 return rv; 8082 } 8083 8084 int 8085 _bcm_tr2_mim_svp_field_set(int unit, bcm_gport_t vp, 8086 soc_field_t field, int value) 8087 { 8088 int rv = BCM_E_NONE; 8089 source_vp_entry_t svp; 8090 8091 MIM_LOCK(unit); 8092 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 8093 if (rv < 0) { 8094 MIM_UNLOCK(unit); 8095 return rv; 8096 } 8097 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, field)) { 8098 soc_SOURCE_VPm_field32_set(unit, &svp, field, value); 8099 } else { 8100 MIM_UNLOCK(unit); 8101 return BCM_E_UNAVAIL; 8102 } 8103 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 8104 MIM_UNLOCK(unit); 8105 return rv; 8106 } 8107 8108 int 8109 _bcm_tr2_mim_port_phys_gport_get(int unit, int vp, bcm_gport_t *gp) 8110 { 8111 if (MIM_INFO(unit)->port_info[vp].modid != -1) { 8112 BCM_GPORT_MODPORT_SET(*gp, MIM_INFO(unit)->port_info[vp].modid, 8113 MIM_INFO(unit)->port_info[vp].port); 8114 } else { 8115 BCM_GPORT_TRUNK_SET(*gp, MIM_INFO(unit)->port_info[vp].tgid); 8116 } 8117 return BCM_E_NONE; 8118 } 8119 8120 void 8121 _bcm_tr2_mim_port_match_count_adjust(int unit, int vp, int step) 8122 { 8123 MIM_INFO(unit)->port_info[vp].match_count += step; 8124 } 8125 8126 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 8127 /* 8128 * Function: 8129 * _bcm_mim_sw_dump 8130 * Purpose: 8131 * Displays mim information maintained by software. 8132 * Parameters: 8133 * unit - Device unit number 8134 * Returns: 8135 * None 8136 */ 8137 void 8138 _bcm_mim_sw_dump(int unit) 8139 { 8140 int i, num_vp, num_vfi; 8141 uint32 mac[2]; 8142 8143 LOG_CLI((BSL_META_U(unit, 8144 "\nSW Information MIM - Unit %d\n"), unit)); 8145 LOG_CLI((BSL_META_U(unit, 8146 " VPN Info : \n"))); 8147 8148 num_vfi = soc_mem_index_count(unit, VFIm); 8149 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 8150 8151 for (i = 0; i < num_vfi; i++) { 8152 if (VPN_ISID(unit, i) != 0) { 8153 LOG_CLI((BSL_META_U(unit, 8154 "VFI = %x ISID=%x\n"), i, VPN_ISID(unit, i))); 8155 } 8156 } 8157 8158 LOG_CLI((BSL_META_U(unit, 8159 "\n Port Info : \n"))); 8160 for (i = 0; i < num_vp; i++) { 8161 if ((MIM_INFO(unit)->port_info[i].tgid == 0) && 8162 (MIM_INFO(unit)->port_info[i].modid == 0) && 8163 (MIM_INFO(unit)->port_info[i].port == 0)) { 8164 continue; 8165 } 8166 LOG_CLI((BSL_META_U(unit, 8167 "\n MiM port vp = %d\n"), i)); 8168 LOG_CLI((BSL_META_U(unit, 8169 "Flags = %x\n"), MIM_INFO(unit)->port_info[i].flags)); 8170 LOG_CLI((BSL_META_U(unit, 8171 "Index = %x\n"), MIM_INFO(unit)->port_info[i].index)); 8172 LOG_CLI((BSL_META_U(unit, 8173 "TGID = %d\n"), MIM_INFO(unit)->port_info[i].tgid)); 8174 LOG_CLI((BSL_META_U(unit, 8175 "Modid = %d\n"), MIM_INFO(unit)->port_info[i].modid)); 8176 LOG_CLI((BSL_META_U(unit, 8177 "Port = %d\n"), MIM_INFO(unit)->port_info[i].port)); 8178 LOG_CLI((BSL_META_U(unit, 8179 "Match VLAN = %d\n"), 8180 MIM_INFO(unit)->port_info[i].match_vlan)); 8181 LOG_CLI((BSL_META_U(unit, 8182 "Match Inner VLAN = %d\n"), 8183 MIM_INFO(unit)->port_info[i].match_inner_vlan)); 8184 LOG_CLI((BSL_META_U(unit, 8185 "Match Label = %d\n"), 8186 MIM_INFO(unit)->port_info[i].match_label)); 8187 SAL_MAC_ADDR_TO_UINT32 8188 (MIM_INFO(unit)->port_info[i].match_tunnel_srcmac, mac); 8189 LOG_CLI((BSL_META_U(unit, 8190 "Match tunnel SrcMac = %x %x\n"), mac[1], mac[0])); 8191 LOG_CLI((BSL_META_U(unit, 8192 "Match tunnel VLAN = %d\n"), 8193 MIM_INFO(unit)->port_info[i].match_tunnel_vlan)); 8194 LOG_CLI((BSL_META_U(unit, 8195 "Match Count = %d\n"), 8196 MIM_INFO(unit)->port_info[i].match_count)); 8197 LOG_CLI((BSL_META_U(unit, 8198 "Vfi Count = %d\n"), 8199 MIM_INFO(unit)->port_info[i].vfi_count)); 8200 8201 } 8202 return; 8203 } 8204 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */ 8205 8206 #ifdef BCM_WARM_BOOT_SUPPORT 8207 /* 8208 * Function: 8209 * _bcm_chunk_memory_alloc 8210 * Purpose: 8211 * Allocate Chunk memory for set of memory entries. 8212 * Chunk memory is allocated with offset at the beginning of the 8213 * memory block. 8214 * 8215 * +--------------+ [0] 8216 * | entry offset| 8217 * +--------------+ [4] 8218 * | memory | 8219 * | entries | 8220 * | | 8221 * +--------------+ [MEM_CHUNK_MAX_ENTRY * mem_entry size] 8222 * Parameters: 8223 * unit - (IN) bcm device 8224 * mem - (IN) table memory 8225 * mem_buffer - (OUT) Allocated memory chunk buffer 8226 * 8227 * Returns: 8228 * BCM_E_NONE - Success 8229 * BCM_E_XXX 8230 * Notes: 8231 */ 8232 STATIC int 8233 _bcm_chunk_memory_alloc(int unit, soc_mem_t mem, void **mem_buf) 8234 { 8235 int entry_size; 8236 8237 /* Validate parameters */ 8238 if (!SOC_MEM_IS_VALID(unit, mem)) { 8239 return BCM_E_PARAM; 8240 } 8241 8242 /* Allocate chunk memory */ 8243 entry_size = soc_mem_entry_words(unit, mem) * sizeof(uint32); 8244 *mem_buf = soc_cm_salloc(unit, ((entry_size * MEM_CHUNK_MAX_ENTRY) + 8245 sizeof(int32*)), "Memory Chunk Buffer"); 8246 if (NULL == *mem_buf) { 8247 return BCM_E_MEMORY; 8248 } 8249 8250 /* Initialize offset */ 8251 _BCM_CHUNK_SET_INDEX_OFFSET(*mem_buf, -1); 8252 8253 return BCM_E_NONE; 8254 } 8255 8256 /* 8257 * Function: 8258 * bcm_chunk_memory_read 8259 * Purpose: 8260 * Read and replenish chunk buffer for range of memory indexes 8261 * 8262 * Parameters: 8263 * unit - (IN) bcm device 8264 * mem - (IN) table memory 8265 * chunk - (IN) chunk 8266 * chunk_buf - (IN) memory chunk buffer 8267 * 8268 * Returns: 8269 * BCM_E_NONE - Success 8270 * BCM_E_XXX 8271 * Notes: 8272 * For generic usage, add atomic memory locks to update chunk buffer. 8273 */ 8274 STATIC int 8275 _bcm_chunk_memory_read(int unit, soc_mem_t mem, int chunk, void *chunk_buf) 8276 { 8277 int rv, entry_index_min, entry_index_max; 8278 void *mem_buf = _BCM_CHUNK_GET_MEM_BUFFER(chunk_buf); 8279 8280 /* clear chunk buffer before refill */ 8281 sal_memset(chunk_buf, 0, ((soc_mem_entry_words(unit, mem) * sizeof(uint32) * 8282 MEM_CHUNK_MAX_ENTRY) + sizeof(int32*))); 8283 8284 /* Read chunk of entries */ 8285 entry_index_min = chunk * MEM_CHUNK_MAX_ENTRY; 8286 entry_index_max = entry_index_min + MEM_CHUNK_MAX_ENTRY - 1; 8287 if (entry_index_max > soc_mem_index_max(unit, mem)) { 8288 entry_index_max = soc_mem_index_max(unit, mem); 8289 } 8290 8291 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 8292 entry_index_min, entry_index_max, mem_buf); 8293 if (BCM_FAILURE(rv)) { 8294 return rv; 8295 } 8296 8297 _BCM_CHUNK_SET_INDEX_OFFSET(chunk_buf, entry_index_min); 8298 8299 return BCM_E_NONE; 8300 } 8301 8302 /* 8303 * Function: 8304 * _bcm_chunk_get_mem_entry 8305 * Purpose: 8306 * Get memory entry from the memory chunk buffer. For the given index, memory chunk buffer is 8307 * refilled with the range of memory index entries. 8308 * 8309 * Parameters: 8310 * unit - (IN) bcm device 8311 * mem - (IN) table memory 8312 * index - (IN) index 8313 * mem_buffer - (OUT) Allocated memory chunk buffer 8314 * 8315 * Returns: 8316 * BCM_E_NONE - Success 8317 * BCM_E_XXX 8318 * Notes: 8319 */ 8320 STATIC int 8321 _bcm_chunk_get_mem_entry(int unit, soc_mem_t mem, int index, 8322 void *chunk_buf, void **mem_entry) 8323 { 8324 int rv, chunk, offset; 8325 void *mem_buf; 8326 8327 /* Validate parameters */ 8328 if (!SOC_MEM_IS_VALID(unit, mem) || (NULL == chunk_buf)) { 8329 return BCM_E_PARAM; 8330 } 8331 8332 chunk = index / MEM_CHUNK_MAX_ENTRY; 8333 8334 offset = _BCM_CHUNK_GET_INDEX_OFFSET(chunk_buf); 8335 8336 if ((offset == -1) || 8337 !(index >= offset && index < (offset + MEM_CHUNK_MAX_ENTRY))) { 8338 /* Replenish chunk buffer*/ 8339 rv = _bcm_chunk_memory_read(unit, mem, chunk, chunk_buf); 8340 if (BCM_FAILURE(rv)) { 8341 return rv; 8342 } 8343 } 8344 mem_buf = _BCM_CHUNK_GET_MEM_BUFFER(chunk_buf); 8345 8346 *mem_entry = soc_mem_table_idx_to_pointer(unit, mem, void*, mem_buf, 8347 _BCM_CHUNK_GET_INDEX(unit, mem, index)); 8348 8349 return BCM_E_NONE; 8350 } 8351 #endif /* BCM_WARM_BOOT_SUPPORT */ 8352 8353 #if defined(BCM_TRIDENT2_SUPPORT) 8354 /* 8355 * Function: 8356 * _bcm_td2_mim_match_vp_replace 8357 * Purpose: 8358 * Replace VP value in MIM VP's match entry. 8359 * Parameters: 8360 * unit - (IN) SOC unit number. 8361 * vp - (IN) MIM VP whose match entry is being replaced. 8362 * new_vp - (IN) New VP value. 8363 * old_vp - (OUT) Old VP value. 8364 * Returns: 8365 * BCM_X_XXX 8366 */ 8367 STATIC int 8368 _bcm_td2_mim_match_vp_replace(int unit, int vp, int new_vp, int *old_vp) 8369 { 8370 int rv = BCM_E_NONE; 8371 soc_mem_t mem; 8372 int key_type = bcmVlanTranslateKeyInvalid; 8373 uint32 svp_valid; 8374 int entry_index; 8375 int port, my_modid, stm_idx, i; 8376 int local_port[SOC_MAX_NUM_PORTS]; 8377 int local_port_count = 0; 8378 uint32 vent[SOC_MAX_MEM_WORDS], old_vent[SOC_MAX_MEM_WORDS]; 8379 source_trunk_map_table_entry_t stm_entry; 8380 uint32 ment[SOC_MAX_MEM_WORDS], old_ment[SOC_MAX_MEM_WORDS]; 8381 _bcm_tr2_mim_port_info_t *mkey = NULL; 8382 8383 mkey = &(MIM_INFO(unit)->port_info[vp]); 8384 8385 switch (mkey->flags) { 8386 case _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN: 8387 if (key_type == bcmVlanTranslateKeyInvalid) { 8388 key_type = bcmVlanTranslateKeyPortOuter; 8389 } 8390 /* Fall through */ 8391 case _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED: 8392 if (key_type == bcmVlanTranslateKeyInvalid) { 8393 key_type = bcmVlanTranslateKeyPortDouble; 8394 } 8395 8396 #if defined(BCM_TRIDENT3_SUPPORT) 8397 if (soc_feature(unit, soc_feature_base_valid)) { 8398 mem = VLAN_XLATE_1_DOUBLEm; 8399 } else 8400 #endif 8401 { 8402 mem = VLAN_XLATEm; 8403 } 8404 8405 if (mkey->modid != -1) { 8406 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port); 8407 } else { 8408 BCM_GPORT_TRUNK_SET(port, mkey->tgid); 8409 } 8410 /* Construct lookup key */ 8411 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8412 rv = _bcm_trx_vlan_translate_entry_assemble( 8413 unit, vent, port, key_type, 8414 mkey->match_inner_vlan, mkey->match_vlan); 8415 if (BCM_FAILURE(rv)) { 8416 return rv; 8417 } 8418 soc_mem_lock(unit, mem); 8419 /* Lookup existing entry */ 8420 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, 8421 &entry_index, vent, old_vent, 0); 8422 if (BCM_FAILURE(rv)) { 8423 soc_mem_unlock(unit, mem); 8424 return rv; 8425 } 8426 /* Replace entry's VP value */ 8427 *old_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf); 8428 soc_mem_field32_set(unit, mem, old_vent, SOURCE_VPf, new_vp); 8429 8430 /* Insert new entry */ 8431 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, old_vent); 8432 if (rv == SOC_E_EXISTS) { 8433 rv = BCM_E_NONE; 8434 } else { 8435 soc_mem_unlock(unit, mem); 8436 return BCM_E_INTERNAL; 8437 } 8438 soc_mem_unlock(unit, mem); 8439 break; 8440 case _BCM_MIM_PORT_TYPE_ACCESS_PORT: 8441 mem = SOURCE_TRUNK_MAP_TABLEm; 8442 8443 soc_mem_lock(unit, mem); 8444 8445 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8446 mkey->index, &stm_entry); 8447 if (BCM_FAILURE(rv)) { 8448 soc_mem_unlock(unit, mem); 8449 return rv; 8450 } 8451 /* Resolve SVP Mode */ 8452 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 8453 svp_valid = soc_mem_field32_get(unit, mem, 8454 &stm_entry, SVP_VALIDf); 8455 if (svp_valid == 0) { 8456 soc_mem_unlock(unit, mem); 8457 return BCM_E_INTERNAL; 8458 } 8459 } 8460 *old_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf); 8461 rv = soc_mem_field32_modify(unit, mem, mkey->index, 8462 SOURCE_VPf, new_vp); 8463 soc_mem_unlock(unit, mem); 8464 break; 8465 case _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK: 8466 mem = SOURCE_TRUNK_MAP_TABLEm; 8467 8468 /* Get module id for unit. */ 8469 rv = bcm_esw_stk_my_modid_get(unit, &my_modid); 8470 if (BCM_FAILURE(rv)) { 8471 return rv; 8472 } 8473 8474 rv = _bcm_esw_trunk_local_members_get( 8475 unit, mkey->tgid, SOC_MAX_NUM_PORTS, 8476 local_port, &local_port_count); 8477 if (BCM_FAILURE(rv)) { 8478 return rv; 8479 } 8480 8481 soc_mem_lock(unit, mem); 8482 for (i = 0; i < local_port_count; i++) { 8483 /* Get index to source trunk map table */ 8484 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 8485 local_port[i], 8486 &stm_idx); 8487 if (BCM_FAILURE(rv)) { 8488 soc_mem_unlock(unit, mem); 8489 return rv; 8490 } 8491 8492 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8493 stm_idx, &stm_entry); 8494 if (BCM_FAILURE(rv)) { 8495 soc_mem_unlock(unit, mem); 8496 return rv; 8497 } 8498 8499 /* Resolve SVP Mode */ 8500 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 8501 svp_valid = soc_mem_field32_get(unit, mem, 8502 &stm_entry, SVP_VALIDf); 8503 if (svp_valid == 0) { 8504 soc_mem_unlock(unit, mem); 8505 return BCM_E_INTERNAL; 8506 } 8507 } 8508 *old_vp = soc_mem_field32_get(unit, mem, 8509 &stm_entry, SOURCE_VPf); 8510 rv = soc_mem_field32_modify(unit, mem, stm_idx, 8511 SOURCE_VPf, new_vp); 8512 if (BCM_FAILURE(rv)) { 8513 soc_mem_unlock(unit, mem); 8514 return rv; 8515 } 8516 } 8517 8518 soc_mem_unlock(unit, mem); 8519 break; 8520 case _BCM_MIM_PORT_TYPE_ACCESS_LABEL: 8521 mem = MPLS_ENTRYm; 8522 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8523 sal_memset(old_ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8524 soc_mem_lock(unit, mem); 8525 if (mkey->modid != -1) { 8526 soc_mem_field32_set(unit, mem, ment, MODULE_IDf, mkey->modid); 8527 soc_mem_field32_set(unit, mem, ment, PORT_NUMf, mkey->port); 8528 } else { 8529 soc_mem_field32_set(unit, mem, ment, Tf, 1); 8530 soc_mem_field32_set(unit, mem, ment, TGIDf, mkey->tgid); 8531 } 8532 soc_mem_field32_set( 8533 unit, mem, ment, MPLS_LABELf, mkey->match_label); 8534 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, 8535 ment, old_ment, 0); 8536 if (rv == BCM_E_NOT_FOUND) { 8537 rv = BCM_E_PARAM; 8538 } 8539 if (BCM_FAILURE(rv)) { 8540 soc_mem_unlock(unit, mem); 8541 return rv; 8542 } 8543 #if defined(BCM_TRIDENT3_SUPPORT) 8544 if (soc_feature(unit, soc_feature_base_valid)) { 8545 if (soc_mem_field32_get(unit, mem, old_ment, BASE_VALID_0f) != 3) { 8546 soc_mem_unlock(unit, mem); 8547 return BCM_E_INTERNAL; 8548 } 8549 if (soc_mem_field32_get(unit, mem, old_ment, BASE_VALID_1f) != 7) { 8550 soc_mem_unlock(unit, mem); 8551 return BCM_E_INTERNAL; 8552 } 8553 } else 8554 #endif 8555 { 8556 if (!soc_mem_field32_get(unit, mem, old_ment, VALIDf)) { 8557 soc_mem_unlock(unit, mem); 8558 return BCM_E_INTERNAL; 8559 } 8560 8561 } 8562 8563 /* Replace entry's VP value */ 8564 *old_vp = soc_mem_field32_get(unit, mem, old_ment, 8565 SOURCE_VPf); 8566 soc_mem_field32_set(unit, mem, old_ment, 8567 SOURCE_VPf, new_vp); 8568 /* Insert new entry */ 8569 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, old_ment); 8570 if (rv == SOC_E_EXISTS) { 8571 rv = BCM_E_NONE; 8572 } else { 8573 soc_mem_unlock(unit, mem); 8574 return BCM_E_INTERNAL; 8575 } 8576 soc_mem_unlock(unit, mem); 8577 break; 8578 case _BCM_MIM_PORT_TYPE_NETWORK: 8579 case _BCM_MIM_PORT_TYPE_PEER: 8580 mem = MPLS_ENTRYm; 8581 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8582 sal_memset(old_ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8583 8584 soc_mem_lock(unit, mem); 8585 8586 soc_mem_field32_set(unit, mem, ment, KEY_TYPEf, 0x1);/* MIM NVP */ 8587 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 8588 soc_mem_field32_set(unit, mem, ment, DATA_TYPEf, 0x1); 8589 } 8590 soc_mem_field32_set(unit, mem, ment, MIM_NVP__BVIDf, 8591 mkey->match_tunnel_vlan); 8592 soc_mem_mac_addr_set(unit, mem, ment, MIM_NVP__BMACSAf, 8593 mkey->match_tunnel_srcmac); 8594 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, 8595 &entry_index, ment, old_ment, 0); 8596 if (rv == BCM_E_NOT_FOUND) { 8597 rv = BCM_E_PARAM; 8598 } 8599 8600 if (BCM_FAILURE(rv)) { 8601 soc_mem_unlock(unit, mem); 8602 return rv; 8603 } 8604 8605 #if defined(BCM_TRIDENT3_SUPPORT) 8606 if (soc_feature(unit, soc_feature_base_valid)) { 8607 if (soc_mem_field32_get(unit, mem, old_ment, BASE_VALID_0f) != 3) { 8608 soc_mem_unlock(unit, mem); 8609 return BCM_E_INTERNAL; 8610 } 8611 if (soc_mem_field32_get(unit, mem, old_ment, BASE_VALID_1f) != 7) { 8612 soc_mem_unlock(unit, mem); 8613 return BCM_E_INTERNAL; 8614 } 8615 } else 8616 #endif 8617 { 8618 if (!soc_mem_field32_get(unit, mem, old_ment, VALIDf)) { 8619 soc_mem_unlock(unit, mem); 8620 return BCM_E_INTERNAL; 8621 } 8622 8623 } 8624 /* Replace entry's VP value */ 8625 *old_vp = soc_mem_field32_get(unit, mem, old_ment, 8626 MIM_NVP__SVPf); 8627 soc_mem_field32_set(unit, mem, old_ment, 8628 MIM_NVP__SVPf, new_vp); 8629 /* Insert new entry */ 8630 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, old_ment); 8631 if (rv == SOC_E_EXISTS) { 8632 rv = BCM_E_NONE; 8633 } else { 8634 soc_mem_unlock(unit, mem); 8635 return BCM_E_INTERNAL; 8636 } 8637 8638 soc_mem_unlock(unit, mem); 8639 break; 8640 default: 8641 return BCM_E_PARAM; 8642 } 8643 8644 return rv; 8645 } 8646 8647 /* 8648 * Function: 8649 * _bcm_td2_mim_port_source_vp_lag_set 8650 * Purpose: 8651 * Set source VP LAG for a MIM virtual port. 8652 * Parameters: 8653 * unit - (IN) SOC unit number. 8654 * gport - (IN) MIM virtual port GPORT ID. 8655 * vp_lag_vp - (IN) VP representing the VP LAG. 8656 * Returns: 8657 * BCM_X_XXX 8658 */ 8659 STATIC int 8660 _bcm_td2_mim_port_source_vp_lag_set(int unit, bcm_gport_t gport, 8661 int vp_lag_vp) 8662 { 8663 int vp, old_vp; 8664 int rv = BCM_E_NONE; 8665 8666 if (!BCM_GPORT_IS_MIM_PORT(gport)) { 8667 return BCM_E_PARAM; 8668 } 8669 8670 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 8671 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 8672 return BCM_E_PARAM; 8673 } 8674 8675 /* Set source VP LAG by replacing the SVP field in MIM VP's 8676 * match entry with the VP value representing the VP LAG. 8677 */ 8678 rv = _bcm_td2_mim_match_vp_replace(unit, vp, vp_lag_vp, &old_vp); 8679 if (BCM_FAILURE(rv)) { 8680 return rv; 8681 } 8682 8683 return BCM_E_NONE; 8684 } 8685 8686 /* 8687 * Function: 8688 * bcm_td2_mim_port_source_vp_lag_set 8689 * Purpose: 8690 * Set source VP LAG for a MIM virtual port. 8691 * Parameters: 8692 * unit - (IN) SOC unit number. 8693 * gport - (IN) MIM virtual port GPORT ID. 8694 * vp_lag_vp - (IN) VP representing the VP LAG. 8695 * Returns: 8696 * BCM_X_XXX 8697 */ 8698 int 8699 bcm_td2_mim_port_source_vp_lag_set(int unit, bcm_gport_t gport, 8700 int vp_lag_vp) 8701 { 8702 int rv = BCM_E_NONE; 8703 8704 MIM_INIT(unit); 8705 MIM_LOCK(unit); 8706 rv = _bcm_td2_mim_port_source_vp_lag_set(unit, gport, vp_lag_vp); 8707 MIM_UNLOCK(unit); 8708 8709 return rv; 8710 } 8711 8712 /* 8713 * Function: 8714 * _bcm_td2_mim_port_source_vp_lag_clear 8715 * Purpose: 8716 * Clear source VP LAG for a MIM virtual port. 8717 * Parameters: 8718 * unit - (IN) SOC unit number. 8719 * gport - (IN) MIM virtual port GPORT ID. 8720 * vp_lag_vp - (IN) VP representing the VP LAG. 8721 * Returns: 8722 * BCM_X_XXX 8723 */ 8724 STATIC int 8725 _bcm_td2_mim_port_source_vp_lag_clear(int unit, bcm_gport_t gport, 8726 int vp_lag_vp) 8727 { 8728 int vp, old_vp; 8729 int rv = BCM_E_NONE; 8730 8731 if (!BCM_GPORT_IS_MIM_PORT(gport)) { 8732 return BCM_E_PARAM; 8733 } 8734 8735 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 8736 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 8737 return BCM_E_PARAM; 8738 } 8739 8740 /* Clear source VP LAG by replacing the SVP field in MIM VP's 8741 * match entry with the original VP value. 8742 */ 8743 rv = _bcm_td2_mim_match_vp_replace(unit, vp, vp, &old_vp); 8744 if (BCM_FAILURE(rv)) { 8745 return rv; 8746 } 8747 8748 /* Check that the old VP value matches the VP value representing 8749 * the VP LAG or has been restored. 8750 */ 8751 if ((old_vp != vp_lag_vp) && (old_vp != vp)) { 8752 return BCM_E_INTERNAL; 8753 } 8754 8755 return BCM_E_NONE; 8756 } 8757 8758 /* 8759 * Function: 8760 * bcm_td2_mim_port_source_vp_lag_clear 8761 * Purpose: 8762 * Clear source VP LAG for a MIM virtual port. 8763 * Parameters: 8764 * unit - (IN) SOC unit number. 8765 * gport - (IN) MIM virtual port GPORT ID. 8766 * vp_lag_vp - (IN) VP representing the VP LAG. 8767 * Returns: 8768 * BCM_X_XXX 8769 */ 8770 int 8771 bcm_td2_mim_port_source_vp_lag_clear(int unit, bcm_gport_t gport, 8772 int vp_lag_vp) 8773 { 8774 int rv = BCM_E_NONE; 8775 8776 MIM_INIT(unit); 8777 MIM_LOCK(unit); 8778 rv = _bcm_td2_mim_port_source_vp_lag_clear(unit, gport, vp_lag_vp); 8779 MIM_UNLOCK(unit); 8780 8781 return rv; 8782 } 8783 8784 8785 /* 8786 * Function: 8787 * _bcm_td2_mim_port_source_vp_lag_get 8788 * Purpose: 8789 * Get source VP LAG for a MIM virtual port. 8790 * Parameters: 8791 * unit - (IN) SOC unit number. 8792 * gport - (IN) MIM virtual port GPORT ID. 8793 * vp_lag_vp - (OUT) VP representing the VP LAG. 8794 * Returns: 8795 * BCM_X_XXX 8796 */ 8797 STATIC int 8798 _bcm_td2_mim_port_source_vp_lag_get(int unit, bcm_gport_t gport, 8799 int *vp_lag_vp) 8800 { 8801 int rv = BCM_E_NONE; 8802 soc_mem_t mem; 8803 int key_type = bcmVlanTranslateKeyInvalid; 8804 bcm_gport_t vp; 8805 uint32 svp_valid; 8806 int entry_index; 8807 int port, my_modid, stm_idx; 8808 int local_port[SOC_MAX_NUM_PORTS]; 8809 int local_port_count = 0; 8810 uint32 vent[SOC_MAX_MEM_WORDS], old_vent[SOC_MAX_MEM_WORDS]; 8811 source_trunk_map_table_entry_t stm_entry; 8812 uint32 ment[SOC_MAX_MEM_WORDS], old_ment[SOC_MAX_MEM_WORDS]; 8813 _bcm_tr2_mim_port_info_t *mkey = NULL; 8814 8815 8816 if (!BCM_GPORT_IS_MIM_PORT(gport)) { 8817 return BCM_E_PARAM; 8818 } 8819 8820 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 8821 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 8822 return BCM_E_PARAM; 8823 } 8824 8825 mkey = &(MIM_INFO(unit)->port_info[vp]); 8826 8827 switch(mkey->flags) { 8828 case _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN: 8829 if (key_type == bcmVlanTranslateKeyInvalid) { 8830 key_type = bcmVlanTranslateKeyPortOuter; 8831 } 8832 /* Fall through */ 8833 case _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED: 8834 if (key_type == bcmVlanTranslateKeyInvalid) { 8835 key_type = bcmVlanTranslateKeyPortDouble; 8836 } 8837 8838 #if defined(BCM_TRIDENT3_SUPPORT) 8839 if (soc_feature(unit, soc_feature_base_valid)) { 8840 mem = VLAN_XLATE_1_DOUBLEm; 8841 } else 8842 #endif 8843 { 8844 mem = VLAN_XLATEm; 8845 } 8846 8847 if (mkey->modid != -1) { 8848 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port); 8849 } else { 8850 BCM_GPORT_TRUNK_SET(port, mkey->tgid); 8851 } 8852 /* Construct lookup key */ 8853 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8854 rv = _bcm_trx_vlan_translate_entry_assemble( 8855 unit, vent, port, key_type, 8856 mkey->match_inner_vlan, mkey->match_vlan); 8857 if (BCM_FAILURE(rv)) { 8858 return rv; 8859 } 8860 /* Lookup existing entry */ 8861 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, 8862 &entry_index, vent, old_vent, 0); 8863 if (BCM_FAILURE(rv)) { 8864 return rv; 8865 } 8866 /* Get VP value representing VP LAG */ 8867 *vp_lag_vp = soc_mem_field32_get(unit, mem, old_vent, 8868 SOURCE_VPf); 8869 break; 8870 case _BCM_MIM_PORT_TYPE_ACCESS_PORT: 8871 mem = SOURCE_TRUNK_MAP_TABLEm; 8872 8873 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8874 mkey->index, &stm_entry); 8875 if (BCM_FAILURE(rv)) { 8876 return rv; 8877 } 8878 /* Resolve SVP Mode */ 8879 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 8880 svp_valid = soc_mem_field32_get(unit, mem, 8881 &stm_entry, SVP_VALIDf); 8882 if (svp_valid == 0) { 8883 return BCM_E_INTERNAL; 8884 } 8885 } 8886 /* Get VP value representing VP LAG */ 8887 *vp_lag_vp = soc_mem_field32_get(unit, mem, 8888 &stm_entry, SOURCE_VPf); 8889 break; 8890 case _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK: 8891 mem = SOURCE_TRUNK_MAP_TABLEm; 8892 8893 /* Get module id for unit. */ 8894 rv = bcm_esw_stk_my_modid_get(unit, &my_modid); 8895 if (BCM_FAILURE(rv)) { 8896 return rv; 8897 } 8898 8899 rv = _bcm_esw_trunk_local_members_get( 8900 unit, mkey->tgid, SOC_MAX_NUM_PORTS, 8901 local_port, &local_port_count); 8902 if (BCM_FAILURE(rv)) { 8903 return rv; 8904 } 8905 8906 /* Get index to source trunk map table, 8907 * Only get it from the first member in LAG 8908 */ 8909 rv = _bcm_esw_src_mod_port_table_index_get( 8910 unit, my_modid, local_port[0], &stm_idx); 8911 if (BCM_FAILURE(rv)) { 8912 return rv; 8913 } 8914 8915 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx, &stm_entry); 8916 if (BCM_FAILURE(rv)) { 8917 return rv; 8918 } 8919 8920 /* Resolve SVP Mode */ 8921 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 8922 svp_valid = soc_mem_field32_get(unit, mem, 8923 &stm_entry, SVP_VALIDf); 8924 if (svp_valid == 0) { 8925 return BCM_E_INTERNAL; 8926 } 8927 } 8928 /* Get VP value representing VP LAG */ 8929 *vp_lag_vp = soc_mem_field32_get(unit, mem, 8930 &stm_entry, SOURCE_VPf); 8931 break; 8932 case _BCM_MIM_PORT_TYPE_ACCESS_LABEL: 8933 mem = MPLS_ENTRYm; 8934 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8935 sal_memset(old_ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8936 if (mkey->modid != -1) { 8937 soc_mem_field32_set(unit, mem, ment, MODULE_IDf, mkey->modid); 8938 soc_mem_field32_set(unit, mem, ment, PORT_NUMf, mkey->port); 8939 } else { 8940 soc_mem_field32_set(unit, mem, ment, Tf, 1); 8941 soc_mem_field32_set(unit, mem, ment, TGIDf, mkey->tgid); 8942 } 8943 soc_mem_field32_set( 8944 unit, mem, ment, MPLS_LABELf, mkey->match_label); 8945 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, 8946 ment, old_ment, 0); 8947 if (rv == BCM_E_NOT_FOUND) { 8948 rv = BCM_E_PARAM; 8949 } 8950 8951 if (BCM_FAILURE(rv)) { 8952 return rv; 8953 } 8954 #if defined(BCM_TRIDENT3_SUPPORT) 8955 if (soc_feature(unit, soc_feature_base_valid)) { 8956 if (soc_mem_field32_get(unit, mem, old_ment, BASE_VALID_0f) != 3) { 8957 return BCM_E_INTERNAL; 8958 } 8959 if (soc_mem_field32_get(unit, mem, old_ment, BASE_VALID_1f) != 7) { 8960 return BCM_E_INTERNAL; 8961 } 8962 } else 8963 #endif 8964 { 8965 if (!soc_mem_field32_get(unit, mem, old_ment, VALIDf)) { 8966 return BCM_E_INTERNAL; 8967 } 8968 } 8969 /* Get VP value representing VP LAG */ 8970 *vp_lag_vp = soc_mem_field32_get(unit, mem, 8971 old_ment, SOURCE_VPf); 8972 break; 8973 case _BCM_MIM_PORT_TYPE_NETWORK: 8974 case _BCM_MIM_PORT_TYPE_PEER: 8975 mem = MPLS_ENTRYm; 8976 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8977 sal_memset(old_ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8978 8979 soc_mem_field32_set(unit, mem, ment, KEY_TYPEf, 0x1);/* MIM NVP */ 8980 8981 soc_mem_field32_set(unit, mem, ment, MIM_NVP__BVIDf, 8982 mkey->match_tunnel_vlan); 8983 soc_mem_mac_addr_set(unit, mem, ment, MIM_NVP__BMACSAf, 8984 mkey->match_tunnel_srcmac); 8985 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, 8986 &entry_index, ment, old_ment, 0); 8987 if (rv == BCM_E_NOT_FOUND) { 8988 rv = BCM_E_PARAM; 8989 } 8990 8991 if (BCM_FAILURE(rv)) { 8992 return rv; 8993 } 8994 8995 if (!soc_mem_field32_get(unit, mem, old_ment, VALIDf)) { 8996 return BCM_E_INTERNAL; 8997 } 8998 /* Get VP value representing VP LAG */ 8999 *vp_lag_vp = soc_mem_field32_get(unit, mem, 9000 old_ment, MIM_NVP__SVPf); 9001 9002 break; 9003 default: 9004 return BCM_E_PARAM; 9005 } 9006 9007 if (!_bcm_vp_used_get(unit, *vp_lag_vp, _bcmVpTypeVpLag)) { 9008 return BCM_E_INTERNAL; 9009 } 9010 9011 return rv; 9012 } 9013 9014 /* 9015 * Function: 9016 * bcm_td2_mim_port_source_vp_lag_get 9017 * Purpose: 9018 * Get source VP LAG for a MIM virtual port. 9019 * Parameters: 9020 * unit - (IN) SOC unit number. 9021 * gport - (IN) MIM virtual port GPORT ID. 9022 * vp_lag_vp - (OUT) VP representing the VP LAG. 9023 * Returns: 9024 * BCM_X_XXX 9025 */ 9026 int 9027 bcm_td2_mim_port_source_vp_lag_get(int unit, bcm_gport_t gport, 9028 int *vp_lag_vp) 9029 { 9030 int rv = BCM_E_NONE; 9031 9032 MIM_INIT(unit); 9033 MIM_LOCK(unit); 9034 rv = _bcm_td2_mim_port_source_vp_lag_get(unit, gport, vp_lag_vp); 9035 MIM_UNLOCK(unit); 9036 9037 return rv; 9038 } 9039 9040 #endif /* BCM_TRIDENT2_SUPPORT */ 9041 9042 #endif /* BCM_TRIUMPH2_SUPPORT */