vxlan.c (556089B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * VXLAN API 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <soc/defs.h> 14 #include <sal/core/libc.h> 15 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 16 #include <soc/drv.h> 17 #include <soc/scache.h> 18 #include <soc/util.h> 19 #include <soc/hash.h> 20 #include <soc/debug.h> 21 #include <bcm/types.h> 22 #include <bcm/error.h> 23 24 #include <bcm/types.h> 25 #include <bcm/l3.h> 26 #include <soc/ism_hash.h> 27 28 #include <bcm_int/esw/mbcm.h> 29 #include <bcm_int/api_xlate_port.h> 30 #include <bcm_int/esw_dispatch.h> 31 #include <bcm_int/esw/virtual.h> 32 #include <bcm_int/esw/trx.h> 33 #include <bcm_int/esw/triumph2.h> 34 #include <bcm_int/esw/trident2.h> 35 #include <bcm_int/esw/vxlan.h> 36 #include <bcm_int/esw/stack.h> 37 #include <bcm_int/common/multicast.h> 38 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 39 #include <bcm_int/esw/trident2plus.h> 40 #include <bcm_int/esw/xgs5.h> 41 #include <bcm_int/esw/port.h> 42 #include <soc/td2_td2p.h> 43 #endif /* BCM_TRIDENT2PLUS_SUPPORT*/ 44 45 #if defined(BCM_TRIDENT3_SUPPORT) 46 #include <bcm_int/esw/trident3.h> 47 #include <bcm_int/esw/flow.h> 48 #include <soc/esw/cancun.h> 49 #endif 50 _bcm_td2_vxlan_bookkeeping_t *_bcm_td2_vxlan_bk_info[BCM_MAX_NUM_UNITS] = { 0 }; 51 52 #define VXLAN_INFO(_unit_) (_bcm_td2_vxlan_bk_info[_unit_]) 53 #define L3_INFO(_unit_) (&_bcm_l3_bk_info[_unit_]) 54 #define VIRTUAL_INFO(_unit_) (&_bcm_virtual_bk_info[_unit_]) 55 56 /* 57 * EGR_IP_TUNNEL table usage bitmap operations 58 */ 59 #define _BCM_VXLAN_IP_TNL_USED_GET(_u_, _tnl_) \ 60 SHR_BITGET(VXLAN_INFO(_u_)->vxlan_ip_tnl_bitmap, (_tnl_)) 61 #define _BCM_VXLAN_IP_TNL_USED_SET(_u_, _tnl_) \ 62 SHR_BITSET(VXLAN_INFO((_u_))->vxlan_ip_tnl_bitmap, (_tnl_)) 63 #define _BCM_VXLAN_IP_TNL_USED_CLR(_u_, _tnl_) \ 64 SHR_BITCLR(VXLAN_INFO((_u_))->vxlan_ip_tnl_bitmap, (_tnl_)) 65 66 #define _BCM_VXLAN_CLEANUP(_rv_) \ 67 if ( (_rv_) < 0) { \ 68 goto cleanup; \ 69 } 70 71 STATIC int _bcm_td2_vxlan_match_vnid_entry_reset(int unit, uint32 vnid, 72 bcm_vlan_t ovid); 73 STATIC int _bcm_td2_vxlan_bud_loopback_disable(int unit); 74 STATIC int _bcm_td2_vxlan_sd_tag_set( int unit, bcm_vxlan_vpn_config_t *vxlan_vpn_info, 75 bcm_vxlan_port_t *vxlan_port, 76 _bcm_td2_vxlan_nh_info_t *egr_nh_info, 77 uint32 *vxlate_entry, 78 int *tpid_index ); 79 STATIC int _bcm_td2_vxlan_egr_xlate_entry_reset(int unit, bcm_vpn_t vpn); 80 STATIC int 81 _bcm_td2_vxlan_egr_xlate_entry_get(int unit, int vfi, int vp, uint32 *vxlate_entry); 82 STATIC void _bcm_td2_vxlan_sd_tag_get( int unit, bcm_vxlan_vpn_config_t *vxlan_vpn_info, 83 bcm_vxlan_port_t *vxlan_port, 84 egr_l3_next_hop_entry_t *egr_nh, 85 uint32 *vxlate_entry, 86 int network_port_flag ); 87 STATIC int _bcm_td2_vxlan_tunnel_initiator_idx_translate(int unit, 88 int soft_idx, 89 int *hw_idx); 90 #if defined(BCM_TRIDENT3_SUPPORT) 91 STATIC void 92 _bcm_td3_vxlan_vxlate_entry_assemble(int unit, _bcm_td3_vxlan_vxlate_entry_t info, uint32* ment); 93 STATIC int 94 _bcm_td3_vxlan_tpid_delete(int unit, uint32* vxlate, uint32* egr_nh); 95 #endif 96 97 void bcm_td2_vxlan_match_clear (int unit, int vp); 98 int _bcm_td2_vxlan_vpn_is_tunnel_based_vnid( int unit, bcm_vpn_t l2vpn, uint8 *vxlan_vpn_type); 99 STATIC int _bcm_td2_vxlan_vp_based_vnid_delete_all(int unit); 100 101 /* 102 * Function: 103 * _bcm_vxlan_check_init 104 * Purpose: 105 * Check if VXLAN is initialized 106 * Parameters: 107 * unit - Device Number 108 * Returns: 109 * BCM_E_XXX 110 */ 111 112 113 STATIC int 114 _bcm_vxlan_check_init(int unit) 115 { 116 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 117 118 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { 119 return BCM_E_UNIT; 120 } 121 122 vxlan_info = VXLAN_INFO(unit); 123 124 if ((vxlan_info == NULL) || (vxlan_info->initialized == FALSE)) { 125 return BCM_E_INIT; 126 } else { 127 return BCM_E_NONE; 128 } 129 } 130 131 /* 132 * Function: 133 * bcm_td2_vxlan_lock 134 * Purpose: 135 * Take VXLAN Lock Sempahore 136 * Parameters: 137 * unit - Device Number 138 * Returns: 139 * BCM_E_XXX 140 */ 141 142 143 int 144 bcm_td2_vxlan_lock(int unit) 145 { 146 int rv=BCM_E_NONE; 147 148 rv = _bcm_vxlan_check_init(unit); 149 150 if ( rv == BCM_E_NONE ) { 151 sal_mutex_take(VXLAN_INFO((unit))->vxlan_mutex, sal_mutex_FOREVER); 152 } 153 return rv; 154 } 155 156 157 158 /* 159 * Function: 160 * bcm_td2_vxlan_unlock 161 * Purpose: 162 * Release VXLAN Lock Semaphore 163 * Parameters: 164 * unit - Device Number 165 * Returns: 166 * BCM_E_XXX 167 */ 168 169 170 void 171 bcm_td2_vxlan_unlock(int unit) 172 { 173 int rv=BCM_E_NONE; 174 175 rv = _bcm_vxlan_check_init(unit); 176 if ( rv == BCM_E_NONE ) { 177 sal_mutex_give(VXLAN_INFO((unit))->vxlan_mutex); 178 } 179 } 180 181 /* 182 * Function: 183 * bcm_td2_vxlan_udpDestPort_set 184 * Purpose: 185 * Set UDP Dest port for VXLAN 186 * Parameters: 187 * unit - SOC unit number. 188 * UDP Dest port - Non-zero value 189 * Returns: 190 * BCM_E_XXX. 191 */ 192 int 193 bcm_td2_vxlan_udpDestPort_set(int unit, int udpDestPort) 194 { 195 int rv = BCM_E_NONE; 196 uint64 reg64; 197 198 COMPILER_64_ZERO(reg64); 199 200 if ((udpDestPort < 0) || (udpDestPort > 0xFFFF) ) { 201 return BCM_E_PARAM; 202 } 203 204 if (SOC_REG_FIELD_VALID(unit, VXLAN_CONTROLr, UDP_DEST_PORTf)){ 205 SOC_IF_ERROR_RETURN(READ_VXLAN_CONTROLr(unit, ®64)); 206 soc_reg64_field32_set(unit, VXLAN_CONTROLr, ®64, 207 UDP_DEST_PORTf, udpDestPort); 208 SOC_IF_ERROR_RETURN(WRITE_VXLAN_CONTROLr(unit, reg64)); 209 } else { 210 rv = BCM_E_UNAVAIL; 211 } 212 213 return rv; 214 } 215 216 /* 217 * Function: 218 * bcm_td2_vxlan_udpSourcePort_set 219 * Purpose: 220 * Enable UDP Source port based HASH for VXLAN 221 * Parameters: 222 * unit - SOC unit number. 223 * hashEnable - Enable Hash for UDP SourcePort 224 * Returns: 225 * BCM_E_XXX. 226 */ 227 int 228 bcm_td2_vxlan_udpSourcePort_set(int unit, int hashEnable) 229 { 230 int rv = BCM_E_NONE; 231 uint64 reg64; 232 233 COMPILER_64_ZERO(reg64); 234 235 if ((hashEnable < 0) || (hashEnable > 1) ) { 236 return BCM_E_PARAM; 237 } 238 239 if (!SOC_REG_IS_VALID(unit, EGR_VXLAN_CONTROLr)) { 240 return rv; 241 } 242 243 if (SOC_REG_FIELD_VALID(unit, EGR_VXLAN_CONTROLr, USE_SOURCE_PORT_SELf)){ 244 soc_reg64_field32_set(unit, EGR_VXLAN_CONTROLr, ®64, 245 USE_SOURCE_PORT_SELf, hashEnable); 246 } 247 248 #if defined(BCM_TRIDENT3_SUPPORT) 249 if (SOC_REG_IS_VALID(unit,FLEX_EDITOR_VXLAN_CONTROL_64r)) { 250 SOC_IF_ERROR_RETURN( 251 soc_reg_field32_modify(unit, FLEX_EDITOR_VXLAN_CONTROL_64r, 252 REG_PORT_ANY, VXLAN_FLAGSf, 0x8)); 253 } else 254 #endif 255 { 256 soc_reg64_field32_set(unit, EGR_VXLAN_CONTROLr, ®64, 257 VXLAN_FLAGSf, 0x8); 258 } 259 260 SOC_IF_ERROR_RETURN(WRITE_EGR_VXLAN_CONTROLr(unit, reg64)); 261 return rv; 262 } 263 264 /* 265 * Function: 266 * bcm_td2_vxlan_udpDestPort_get 267 * Purpose: 268 * Get UDP Dest port for VXLAN 269 * Parameters: 270 * unit - SOC unit number. 271 * UDP Dest port - Non-zero value 272 * Returns: 273 * BCM_E_XXX. 274 */ 275 int 276 bcm_td2_vxlan_udpDestPort_get(int unit, int *udpDestPort) 277 { 278 int rv = BCM_E_NONE; 279 uint64 reg64; 280 281 COMPILER_64_ZERO(reg64); 282 283 if (SOC_REG_FIELD_VALID(unit, VXLAN_CONTROLr, UDP_DEST_PORTf)) { 284 SOC_IF_ERROR_RETURN(READ_VXLAN_CONTROLr(unit, ®64)); 285 *udpDestPort = soc_reg64_field32_get(unit, VXLAN_CONTROLr, 286 reg64, UDP_DEST_PORTf); 287 } else { 288 rv = BCM_E_UNAVAIL; 289 } 290 291 return rv; 292 } 293 294 /* 295 * Function: 296 * bcm_td2_vxlan_udpSourcePort_get 297 * Purpose: 298 * Get UDP Source port based HASH for VXLAN 299 * Parameters: 300 * unit - SOC unit number. 301 * hashEnable - Enable Hash for UDP SourcePort 302 * Returns: 303 * BCM_E_XXX. 304 */ 305 int 306 bcm_td2_vxlan_udpSourcePort_get(int unit, int *hashEnable) 307 { 308 int rv = BCM_E_NONE; 309 uint64 reg64; 310 311 COMPILER_64_ZERO(reg64); 312 313 SOC_IF_ERROR_RETURN(READ_EGR_VXLAN_CONTROLr(unit, ®64)); 314 *hashEnable = soc_reg64_field32_get(unit, EGR_VXLAN_CONTROLr, 315 reg64, USE_SOURCE_PORT_SELf); 316 return rv; 317 } 318 319 320 /* 321 * Function: 322 * _bcm_td2_vxlan_free_resource 323 * Purpose: 324 * Free all allocated software resources 325 * Parameters: 326 * unit - SOC unit number 327 * Returns: 328 * Nothing 329 */ 330 331 332 STATIC void 333 _bcm_td2_vxlan_free_resource(int unit) 334 { 335 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 336 337 /* If software tables were not allocated we are done. */ 338 if (NULL == VXLAN_INFO(unit)) { 339 return; 340 } 341 342 /* Destroy EGR_IP_TUNNEL usage bitmap */ 343 if (vxlan_info->vxlan_ip_tnl_bitmap) { 344 sal_free(vxlan_info->vxlan_ip_tnl_bitmap); 345 vxlan_info->vxlan_ip_tnl_bitmap = NULL; 346 } 347 348 if (vxlan_info->match_key) { 349 sal_free(vxlan_info->match_key); 350 vxlan_info->match_key = NULL; 351 } 352 353 if (vxlan_info->vxlan_tunnel_init) { 354 sal_free(vxlan_info->vxlan_tunnel_init); 355 vxlan_info->vxlan_tunnel_init = NULL; 356 } 357 358 if (vxlan_info->vxlan_tunnel_term) { 359 sal_free(vxlan_info->vxlan_tunnel_term); 360 vxlan_info->vxlan_tunnel_term = NULL; 361 } 362 363 if (vxlan_info->vxlan_vpn_vlan) { 364 sal_free(vxlan_info->vxlan_vpn_vlan); 365 vxlan_info->vxlan_vpn_vlan = NULL; 366 } 367 if (vxlan_info->vxlan_vpn_info) { 368 sal_free(vxlan_info->vxlan_vpn_info); 369 vxlan_info->vxlan_vpn_info = NULL; 370 } 371 if (vxlan_info->vfi_vnid_map_count) { 372 sal_free(vxlan_info->vfi_vnid_map_count); 373 vxlan_info->vfi_vnid_map_count = NULL; 374 } 375 /* Free module data. */ 376 sal_free(VXLAN_INFO(unit)); 377 VXLAN_INFO(unit) = NULL; 378 } 379 380 /* 381 * Function: 382 * bcm_td2_vxlan_allocate_bk 383 * Purpose: 384 * Initialize VXLAN software book-kepping 385 * Parameters: 386 * unit - Device Number 387 * Returns: 388 * BCM_E_XXX 389 */ 390 391 STATIC int 392 bcm_td2_vxlan_allocate_bk(int unit) 393 { 394 /* Allocate/Init unit software tables. */ 395 if (NULL == VXLAN_INFO(unit)) { 396 BCMI_VXLAN_ALLOC(VXLAN_INFO(unit), sizeof(_bcm_td2_vxlan_bookkeeping_t), 397 "vxlan_bk_module_data"); 398 if (NULL == VXLAN_INFO(unit)) { 399 return (BCM_E_MEMORY); 400 } else { 401 VXLAN_INFO(unit)->initialized = FALSE; 402 } 403 } 404 return BCM_E_NONE; 405 } 406 407 /* 408 * Function: 409 * _bcm_td2_vxlan_hw_clear 410 * Purpose: 411 * Perform hw tables clean up for VXLAN module. 412 * Parameters: 413 * unit - Device Number 414 * Returns: 415 * BCM_E_XXX 416 */ 417 418 STATIC int 419 _bcm_td2_vxlan_hw_clear(int unit) 420 { 421 int rv = BCM_E_NONE, rv_error = BCM_E_NONE; 422 423 rv = bcm_td2_vxlan_tunnel_terminator_destroy_all(unit); 424 if (BCM_FAILURE(rv) && (BCM_E_NONE == rv_error)) { 425 rv_error = rv; 426 } 427 428 rv = bcm_td2_vxlan_tunnel_initiator_destroy_all(unit); 429 if (BCM_FAILURE(rv) && (BCM_E_NONE == rv_error)) { 430 rv_error = rv; 431 } 432 433 rv =_bcm_td2_vxlan_vp_based_vnid_delete_all(unit); 434 if (BCM_FAILURE(rv) && (BCM_E_NONE == rv_error)){ 435 rv_error = rv; 436 } 437 438 rv = bcm_td2_vxlan_vpn_destroy_all(unit); 439 if (BCM_FAILURE(rv) && (BCM_E_NONE == rv_error)) { 440 rv_error = rv; 441 } 442 443 rv = _bcm_td2_vxlan_bud_loopback_disable(unit); 444 if (BCM_FAILURE(rv) && (BCM_E_NONE == rv_error)) { 445 rv_error = rv; 446 } 447 448 return rv_error; 449 } 450 451 /* 452 * Function: 453 * bcm_td2_vxlan_cleanup 454 * Purpose: 455 * DeInit VXLAN software module 456 * Parameters: 457 * unit - Device Number 458 * Returns: 459 * BCM_E_XXX 460 */ 461 462 int 463 bcm_td2_vxlan_cleanup(int unit) 464 { 465 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 466 int rv = BCM_E_UNAVAIL; 467 468 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { 469 return BCM_E_UNIT; 470 } 471 472 vxlan_info = VXLAN_INFO(unit); 473 474 if (FALSE == vxlan_info->initialized) { 475 return (BCM_E_NONE); 476 } 477 478 rv = bcm_td2_vxlan_lock (unit); 479 if (BCM_FAILURE(rv)) { 480 return rv; 481 } 482 483 if (0 == SOC_HW_ACCESS_DISABLE(unit)) { 484 rv = _bcm_td2_vxlan_hw_clear(unit); 485 } 486 487 /* Mark the state as uninitialized */ 488 vxlan_info->initialized = FALSE; 489 490 sal_mutex_give(vxlan_info->vxlan_mutex); 491 492 /* Destroy protection mutex. */ 493 sal_mutex_destroy(vxlan_info->vxlan_mutex ); 494 495 /* Free software resources */ 496 (void) _bcm_td2_vxlan_free_resource(unit); 497 498 return rv; 499 } 500 501 /* 502 * Function: 503 * bcm_td2_vxlan_port_match_count_adjust 504 * Purpose: 505 * Obtain ref-count for a VXLAN port 506 * Returns: 507 * BCM_E_XXX 508 */ 509 510 void 511 bcm_td2_vxlan_port_match_count_adjust(int unit, int vp, int step) 512 { 513 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 514 515 vxlan_info->match_key[vp].match_count += step; 516 } 517 518 519 #ifdef BCM_WARM_BOOT_SUPPORT 520 521 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1, 0) 522 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1, 1) 523 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1, 2) 524 #define BCM_WB_VERSION_1_3 SOC_SCACHE_VERSION(1, 3) 525 #define BCM_WB_VERSION_1_4 SOC_SCACHE_VERSION(1, 4) 526 #define BCM_WB_VERSION_1_5 SOC_SCACHE_VERSION(1, 5) 527 #define BCM_WB_VERSION_1_6 SOC_SCACHE_VERSION(1, 6) 528 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_6 529 530 STATIC int _bcm_td2_vxlan_wb_alloc(int unit); 531 532 /* 533 * Function: 534 * _bcm_td2_vxlan_wb_recover 535 * 536 * Purpose: 537 * Recover VXLAN module info for Level 2 Warm Boot from persisitent memory 538 * 539 * Warm Boot Version Map: 540 * see _bcm_esw_vxlan_sync definition 541 * 542 * Parameters: 543 * unit - (IN) Device Unit Number. 544 * 545 * Returns: 546 * BCM_E_XXX 547 */ 548 549 STATIC int 550 _bcm_td2_vxlan_wb_recover(int unit) 551 { 552 int i, sz = 0, rv = BCM_E_NONE; 553 int num_tnl = 0, num_vp = 0; 554 int stable_size; 555 int additional_scache_size = 0; 556 uint16 recovered_ver = 0; 557 int add_sz_1_0 = 0; 558 int add_sz_1_1 = 0; 559 int add_sz_1_2 = 0; 560 int add_sz_1_4 = 0; 561 int tnl_idx = 0; 562 bcm_ip_t sip = 0; 563 bcm_gport_t gport; 564 uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS]; 565 uint8 *vxlan_state = NULL; 566 soc_scache_handle_t scache_handle; 567 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 568 int num_vfi = 0; 569 570 vxlan_info = VXLAN_INFO(unit); 571 572 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 573 574 /* Requires extended scache support level-2 warmboot */ 575 if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) { 576 return BCM_E_NONE; 577 } 578 579 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VXLAN, 0); 580 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 581 0, &vxlan_state, 582 BCM_WB_DEFAULT_VERSION, &recovered_ver); 583 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 584 return rv; 585 } else if (rv == BCM_E_NOT_FOUND) { 586 return _bcm_td2_vxlan_wb_alloc(unit); 587 } 588 589 if (vxlan_state != NULL) { 590 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 591 num_tnl = soc_mem_index_count(unit, EGR_IP_TUNNELm); 592 num_vfi = soc_mem_index_count(unit, VFIm); 593 594 if (recovered_ver >= BCM_WB_VERSION_1_4) { 595 sz = num_vp * sizeof(_bcm_vxlan_tunnel_endpoint_t); 596 } else if (recovered_ver >= BCM_WB_VERSION_1_2) { 597 sz = num_vp * (sizeof(_bcm_vxlan_tunnel_endpoint_t) - sizeof(bcm_vlan_t)); 598 additional_scache_size = 599 ((num_vp * sizeof(_bcm_vxlan_tunnel_endpoint_t)) - sz) * 2; 600 } else if (recovered_ver >= BCM_WB_VERSION_1_1) { 601 /* Warm boot upgrade case, activate_flag was added.*/ 602 sz = num_vp * (sizeof(_bcm_vxlan_tunnel_endpoint_t) - sizeof(int) 603 - sizeof(bcm_vlan_t)); 604 additional_scache_size = 605 ((num_vp * sizeof(_bcm_vxlan_tunnel_endpoint_t)) - sz) * 2; 606 } else { 607 /* Warm boot upgrade case, in the previous version (SDK 6.3.4) 608 tunnel_state was uint8, now changed to uint16 */ 609 sz = num_vp * (sizeof(_bcm_vxlan_tunnel_endpoint_t) - 1 - sizeof(int) 610 - sizeof(bcm_vlan_t)); 611 additional_scache_size = 612 ((num_vp * sizeof(_bcm_vxlan_tunnel_endpoint_t)) - sz) * 2; 613 } 614 615 /* Version_1_0: _bcm_vxlan_tunnel_endpoint_t in vxlan_bookkeeping_t 616 * bcm_ip_t dip + bcm_ip_t sip + uint8 tunnel_state 617 * comments: (tunnel_state is ONLY valid to Tunnel Terminator in v_1_0) 618 * Version_1_1: _bcm_vxlan_tunnel_endpoint_t in vxlan_bookkeeping_t 619 * bcm_ip_t dip + bcm_ip_t sip + uint16 tunnel_state; 620 * 621 * Version_1_2: _bcm_vxlan_tunnel_endpoint_t in vxlan_bookkeeping_t 622 * bcm_ip_t dip + bcm_ip_t sip + uint16 tunnel_state + int activate_flag 623 * comments: (activate_flag is ONLY valid to Tunnel Terminator in v_1_2) 624 * Version_1_0 -> Version_1_1: tunnel_state (uni8->unit16) 625 * Version_1_0 -> Version_1_2: tunnel_state (uni8->unit16) 626 * + activate_flag 627 * Version_1_1 -> Version_1_2: + activate_flag 628 */ 629 630 /* size of (DIP, SIP, Tunnel State(uint8)) */ 631 add_sz_1_0 = sizeof(bcm_ip_t) + sizeof(bcm_ip_t) + sizeof(uint8); 632 633 /* Tunnel State uint8==> uint16 */ 634 add_sz_1_1 = 1; 635 636 /* Add activate_flag */ 637 add_sz_1_2 = sizeof(int); 638 639 /* Add vlan */ 640 add_sz_1_4 = sizeof(bcm_vlan_t); 641 642 /* Recover Vxlan Tunnel Terminator (DIP, SIP, Tunnel State(unit8)) 643 * To correspond with the sync actions in Version_1_0 644 */ 645 if (recovered_ver == BCM_WB_VERSION_1_0) { 646 for (i = 0; i < num_vp; i++) { 647 sal_memcpy(&(vxlan_info->vxlan_tunnel_term[i]), 648 vxlan_state, add_sz_1_0 - sizeof(uint8)); 649 vxlan_state += add_sz_1_0 - sizeof(uint8); 650 /* Tunnel State uint8 --> uint16 */ 651 vxlan_info->vxlan_tunnel_term[i].tunnel_state = 652 *((uint8 *)vxlan_state); 653 vxlan_state += sizeof(uint8); 654 } 655 } 656 657 /* Recover Vxlan Tunnel Terminator (DIP, SIP, Tunnel State(uint16)) 658 * To correspond with the sync actions in Version_1_1 659 */ 660 if (recovered_ver == BCM_WB_VERSION_1_1) { 661 for (i = 0; i < num_vp; i++) { 662 sal_memcpy(&(vxlan_info->vxlan_tunnel_term[i]), 663 vxlan_state, add_sz_1_0 + add_sz_1_1); 664 vxlan_state += add_sz_1_0 + add_sz_1_1; 665 } 666 } 667 668 /* Recover Vxlan Tunnel Terminator 669 * (DIP, SIP, Tunnel State(uint16), activate_flag) 670 * To correspond with the sync actions in Version_1_2 671 */ 672 if ((recovered_ver >= BCM_WB_VERSION_1_2) 673 && (recovered_ver < BCM_WB_VERSION_1_4)) { 674 for (i = 0; i < num_vp; i++) { 675 sal_memcpy(&(vxlan_info->vxlan_tunnel_term[i]), 676 vxlan_state, add_sz_1_0 + add_sz_1_1 + add_sz_1_2); 677 vxlan_state += add_sz_1_0 + add_sz_1_1 + add_sz_1_2; 678 } 679 } 680 681 /* Recover Vxlan Tunnel Terminator 682 * (DIP, SIP, Tunnel State(uint16), activate_flag, vlan) 683 * To correspond with the sync actions in Version_1_4 684 */ 685 if (recovered_ver >= BCM_WB_VERSION_1_4) { 686 for (i = 0; i < num_vp; i++) { 687 sal_memcpy(&(vxlan_info->vxlan_tunnel_term[i]), 688 vxlan_state, 689 add_sz_1_0 + add_sz_1_1 + add_sz_1_2 + add_sz_1_4); 690 vxlan_state += add_sz_1_0 + add_sz_1_1 + add_sz_1_2 + add_sz_1_4; 691 } 692 } 693 /* Recover Vxlan Tunnel Initiator (DIP, SIP, Tunnel State(unit8)) 694 * To correspond with the sync actions in Version_1_0 695 */ 696 if (recovered_ver == BCM_WB_VERSION_1_0) { 697 for (i = 0; i < num_vp; i++) { 698 sal_memcpy(&(vxlan_info->vxlan_tunnel_init[i]), 699 vxlan_state, add_sz_1_0 - sizeof(uint8)); 700 vxlan_state += add_sz_1_0 - sizeof(uint8); 701 vxlan_info->vxlan_tunnel_init[i].tunnel_state = 702 *((uint8 *)vxlan_state); 703 vxlan_state += sizeof(uint8); 704 } 705 } 706 707 /* Recover Vxlan Tunnel Initiator (DIP, SIP, Tunnel State(uint16)) 708 * To correspond with the sync actions in Version_1_1 709 */ 710 if (recovered_ver == BCM_WB_VERSION_1_1) { 711 for (i = 0; i < num_vp; i++) { 712 sal_memcpy(&(vxlan_info->vxlan_tunnel_init[i]), 713 vxlan_state, add_sz_1_0 + add_sz_1_1); 714 vxlan_state += (add_sz_1_0 + add_sz_1_1); 715 } 716 } 717 718 /* Recover Vxlan Tunnel Initiator 719 * (DIP, SIP, Tunnel State(uint16), activate_flag) 720 * To correspond with the sync actions in Version_1_2 721 */ 722 if (recovered_ver >= BCM_WB_VERSION_1_2 723 && (recovered_ver < BCM_WB_VERSION_1_4)) { 724 for (i = 0; i < num_vp; i++) { 725 sal_memcpy(&(vxlan_info->vxlan_tunnel_init[i]), 726 vxlan_state, add_sz_1_0 + add_sz_1_1 + add_sz_1_2); 727 vxlan_state += add_sz_1_0 + add_sz_1_1 + add_sz_1_2; 728 } 729 } 730 731 /* Recover Vxlan Tunnel Initiator 732 * (DIP, SIP, Tunnel State(uint16), activate_flag, vlan) 733 * To correspond with the sync actions in Version_1_4 734 */ 735 736 if (recovered_ver >= BCM_WB_VERSION_1_4) { 737 for (i = 0; i < num_vp; i++) { 738 sal_memcpy(&(vxlan_info->vxlan_tunnel_init[i]), 739 vxlan_state, add_sz_1_0 + add_sz_1_1 + add_sz_1_2 + add_sz_1_4); 740 vxlan_state += add_sz_1_0 + add_sz_1_1 + add_sz_1_2 + add_sz_1_4; 741 } 742 } 743 744 /* Recover the BITMAP of Vxlan Tunnel usage */ 745 sal_memcpy(vxlan_info->vxlan_ip_tnl_bitmap, vxlan_state, 746 SHR_BITALLOCSIZE(num_tnl)); 747 vxlan_state += SHR_BITALLOCSIZE(num_tnl); 748 749 /* Recover the flags & match_tunnel_index of each Match Key */ 750 for (i = 0; i < num_vp; i++) { 751 sal_memcpy(&(vxlan_info->match_key[i].flags), vxlan_state, 752 sizeof(uint32)); 753 vxlan_state += sizeof(uint32); 754 sal_memcpy(&(vxlan_info->match_key[i].match_tunnel_index), vxlan_state, 755 sizeof(uint32)); 756 vxlan_state += sizeof(uint32); 757 } 758 759 /* set default information for warm boot upgrade case */ 760 if (recovered_ver < BCM_WB_VERSION_1_2) { 761 for (i = 0; i < num_vp; i++) { 762 /* Version_1_0/Version_1_1 -> Version_1_2: 763 * activate_flag is introduced by Version_1_2 764 * and ONLY valid to Tunnel Terminator. 765 * Here is to set default flag with TERM_ENABLE. 766 */ 767 if (vxlan_info->vxlan_tunnel_term[i].sip != 0) { 768 vxlan_info->vxlan_tunnel_term[i].activate_flag |= 769 _BCM_VXLAN_TUNNEL_TERM_ENABLE; 770 } 771 } 772 773 if (recovered_ver == BCM_WB_VERSION_1_0) { 774 /* Version_1_0 -> Version_1_2: 775 * Start from Version_1_1 - Set dest udp port on tunnel_state 776 * field for Tunnel Initiator. Here is to get dest udp port 777 * from HW entry. 778 */ 779 for (tnl_idx = 0; tnl_idx < num_tnl; tnl_idx++) { 780 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_IP_TUNNELm, 781 MEM_BLOCK_ANY, tnl_idx, tnl_entry)); 782 sip = soc_mem_field32_get(unit, EGR_IP_TUNNELm, 783 tnl_entry, SIPf); 784 if (sip != 0) { 785 for (i = 0; i < num_vp; i++) { 786 if (sip == vxlan_info->vxlan_tunnel_init[i].sip) { 787 vxlan_info->vxlan_tunnel_init[i].tunnel_state = 788 soc_mem_field32_get(unit, EGR_IP_TUNNELm, 789 tnl_entry, L4_DEST_PORTf); 790 } 791 } 792 } 793 } 794 } 795 } 796 797 /* 798 * Recover the index && gport(trunk_id, modid, port) && match_vlan && 799 * match_inner_vlan of each Match Key 800 */ 801 if (recovered_ver >= BCM_WB_VERSION_1_3) { 802 for (i = 0; i < num_vp; i++) { 803 sal_memcpy(&(vxlan_info->match_key[i].index), vxlan_state, 804 sizeof(uint32)); 805 vxlan_state += sizeof(uint32); 806 sal_memcpy(&gport, vxlan_state, sizeof(bcm_gport_t)); 807 if (BCM_GPORT_IS_TRUNK(gport)) { 808 vxlan_info->match_key[i].trunk_id = 809 BCM_GPORT_TRUNK_GET(gport); 810 } else if (BCM_GPORT_IS_MODPORT(gport)) { 811 vxlan_info->match_key[i].modid = 812 BCM_GPORT_MODPORT_MODID_GET(gport); 813 vxlan_info->match_key[i].port = 814 BCM_GPORT_MODPORT_PORT_GET(gport); 815 } 816 vxlan_state += sizeof(bcm_gport_t); 817 sal_memcpy(&(vxlan_info->match_key[i].match_vlan), vxlan_state, 818 sizeof(bcm_vlan_t)); 819 vxlan_state += sizeof(bcm_vlan_t); 820 sal_memcpy(&(vxlan_info->match_key[i].match_inner_vlan), 821 vxlan_state, sizeof(bcm_vlan_t)); 822 vxlan_state += sizeof(bcm_vlan_t); 823 } 824 } else { 825 additional_scache_size += num_vp * (sizeof(uint32) + 826 sizeof(bcm_gport_t) + 827 sizeof(bcm_vlan_t) * 2); 828 } 829 830 if (recovered_ver >= BCM_WB_VERSION_1_5) { 831 for (i = 0; i < num_vfi; i++) { 832 sal_memcpy(&(vxlan_info->vxlan_vpn_vlan[i]), vxlan_state, 833 sizeof(bcm_vlan_t)); 834 vxlan_state += sizeof(bcm_vlan_t); 835 } 836 } else { 837 additional_scache_size += num_vfi * sizeof(bcm_vlan_t); 838 } 839 if (recovered_ver >= BCM_WB_VERSION_1_6) { 840 /* Recover the type of each vxlan vpn */ 841 for (i = 0; i < num_vfi; i++) { 842 sal_memcpy(&(vxlan_info->vxlan_vpn_info[i].sip), vxlan_state, 843 sizeof(bcm_ip_t)); 844 vxlan_state += sizeof(bcm_ip_t); 845 sal_memcpy(&(vxlan_info->vxlan_vpn_info[i].vnid), vxlan_state, 846 sizeof(uint32)); 847 vxlan_state += sizeof(uint32); 848 sal_memcpy(&(vxlan_info->vxlan_vpn_info[i].vxlan_vpn_type), vxlan_state, 849 sizeof(uint8)); 850 vxlan_state += sizeof(uint8); 851 } 852 for (i = 0; i < num_vp; i++) { 853 sal_memcpy(&(vxlan_info->match_key[i].vfi), vxlan_state, 854 sizeof(int)); 855 vxlan_state += sizeof(int); 856 } 857 } else { 858 additional_scache_size += num_vfi * (sizeof(uint8) + sizeof(bcm_ip_t) + 859 sizeof(uint32)) + num_vp * sizeof(int); 860 } 861 862 /* Reallocate additional scache size required for tunnel_state in 863 Vxlan Tunnel Terminator and Vxlan Tunnel Initiator */ 864 if (additional_scache_size > 0) { 865 rv = soc_scache_realloc(unit,scache_handle,additional_scache_size); 866 if(BCM_FAILURE(rv)) { 867 return rv; 868 } 869 } 870 } 871 872 return BCM_E_NONE; 873 } 874 875 /* 876 * Function: 877 * _bcm_td2_vxlan_wb_alloc 878 * 879 * Purpose: 880 * Alloc persisitent memory for Level 2 Warm Boot scache. 881 * 882 * Parameters: 883 * unit - (IN) Device Unit Number. 884 * 885 * Returns: 886 * BCM_E_XXX 887 */ 888 889 STATIC int 890 _bcm_td2_vxlan_wb_alloc(int unit) 891 { 892 int alloc_sz = 0, rv = BCM_E_NONE; 893 soc_scache_handle_t scache_handle; 894 int num_tnl = 0, num_vp = 0; 895 int num_vfi = 0; 896 897 uint8 *vxlan_state; 898 int stable_size; 899 900 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 901 902 if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) { 903 return BCM_E_NONE; 904 } 905 906 /* Size of Tunnel Terminator & Initiator of all VP */ 907 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 908 alloc_sz += num_vp * sizeof(_bcm_vxlan_tunnel_endpoint_t) * 2; 909 910 /* Size of EGR_IP_TUNNEL index bitmap */ 911 num_tnl = soc_mem_index_count(unit, EGR_IP_TUNNELm); 912 alloc_sz += SHR_BITALLOCSIZE(num_tnl); 913 914 /* Size of All match_key's flags & match_tunnel_index */ 915 alloc_sz += num_vp * sizeof(uint32) * 2; 916 917 /* 918 * Size of All match_key's index && gport(trunk_id, modid, port) && 919 * match_vlan && match_inner_vlan 920 */ 921 alloc_sz += num_vp * (sizeof(uint32) + sizeof(bcm_gport_t) + 922 sizeof(bcm_vlan_t) * 2); 923 924 /* BCM_WB_VERSION_1_5 */ 925 num_vfi = soc_mem_index_count(unit, VFIm); 926 alloc_sz += num_vfi * sizeof(bcm_vlan_t); 927 928 /* BCM_WB_VERSION_1_6 */ 929 alloc_sz += num_vfi * sizeof(_bcm_vxlan_vpn_info_t); 930 alloc_sz += num_vp * sizeof(int); 931 932 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VXLAN, 0); 933 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 934 alloc_sz, (uint8**)&vxlan_state, 935 BCM_WB_DEFAULT_VERSION, NULL); 936 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 937 return rv; 938 } 939 940 return BCM_E_NONE; 941 } 942 943 /* 944 * Function: 945 * _bcm_td2_vxlan_tunnel_initiator_reinit 946 * Purpose: 947 * Tunnel initiator hash and ref-count recovery. 948 * Parameters: 949 * unit - (IN) BCM device number. 950 * Returns: 951 * BCM_E_XXX 952 */ 953 STATIC int 954 _bcm_td2_vxlan_tunnel_initiator_reinit(int unit) 955 { 956 bcm_tunnel_initiator_t tnl_init_info; 957 int rv = BCM_E_NONE; 958 int i = 0; 959 int idx_min = 0; 960 int idx_max = 0; 961 egr_ip_tunnel_entry_t *egr_tnl_entry = NULL; 962 uint8 *egr_tnl_buf = NULL; 963 964 idx_min = soc_mem_index_min(unit, EGR_IP_TUNNELm); 965 idx_max = soc_mem_index_max(unit, EGR_IP_TUNNELm); 966 967 egr_tnl_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, EGR_IP_TUNNELm), 968 "EGR_IP_TUNNEL buffer"); 969 if (NULL == egr_tnl_buf) { 970 return BCM_E_MEMORY; 971 } 972 973 rv = soc_mem_read_range(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 974 idx_min, idx_max, egr_tnl_buf); 975 if (SOC_FAILURE(rv)) { 976 goto clean_up; 977 } 978 979 for (i = idx_min; i <= idx_max; i++) { 980 981 egr_tnl_entry = soc_mem_table_idx_to_pointer(unit, EGR_IP_TUNNELm, 982 egr_ip_tunnel_entry_t *, 983 egr_tnl_buf, i); 984 if (_BCM_VXLAN_TUNNEL_TYPE == 985 soc_mem_field32_get(unit, EGR_IP_TUNNELm, 986 egr_tnl_entry, TUNNEL_TYPEf)) { 987 988 bcm_tunnel_initiator_t_init(&tnl_init_info); 989 tnl_init_info.type = bcmTunnelTypeVxlan; 990 tnl_init_info.sip = 991 soc_mem_field32_get(unit, EGR_IP_TUNNELm, 992 egr_tnl_entry, SIPf); 993 tnl_init_info.udp_dst_port = 994 soc_mem_field32_get(unit, EGR_IP_TUNNELm, 995 egr_tnl_entry, L4_DEST_PORTf); 996 rv = _bcm_td2_vxlan_tunnel_initiator_hash_calc( 997 unit, &tnl_init_info, 998 &BCM_XGS3_L3_ENT_HASH( 999 BCM_XGS3_L3_TBL_PTR(unit, tnl_init), i)); 1000 if (BCM_FAILURE(rv)) { 1001 goto clean_up; 1002 } 1003 BCM_XGS3_L3_ENT_REF_CNT_INC( 1004 BCM_XGS3_L3_TBL_PTR(unit, tnl_init), i, 1005 ((_BCM_TUNNEL_OUTER_HEADER_IPV6(tnl_init_info.type)) ? 1006 _BCM_DOUBLE_WIDE : _BCM_SINGLE_WIDE)); 1007 } 1008 } 1009 clean_up: 1010 1011 if (NULL != egr_tnl_buf) { 1012 soc_cm_sfree(unit, egr_tnl_buf); 1013 } 1014 return rv; 1015 } 1016 1017 1018 /* 1019 * Function: 1020 * _bcm_d2_vxlan_vp_based_vnid_reinit 1021 * Purpose: 1022 * Per VP VFI-VNID mappings rules ref-count recovery. 1023 * Parameters: 1024 * unit - (IN) BCM device number. 1025 * Returns: 1026 * BCM_E_XXX 1027 */ 1028 STATIC int 1029 _bcm_td2_vxlan_vp_based_vnid_reinit(int unit) 1030 { 1031 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 1032 soc_field_t valid_field; 1033 soc_field_t type_field; 1034 soc_mem_t egr_vxlate_mem; 1035 int rv = BCM_E_NONE; 1036 int i = 0; 1037 int idx_min = 0; 1038 int idx_max = 0; 1039 int decouple = 0; 1040 void *egr_vxlate_entry = NULL; 1041 uint8 *egr_vxlate_buf = NULL; 1042 uint32 entry_type; 1043 int vfi; 1044 bcm_vpn_t vpn; 1045 int vp; 1046 uint8 vxlan_vpn_type; 1047 1048 #if defined(BCM_TRIDENT3_SUPPORT) 1049 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 1050 egr_vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 1051 valid_field = BASE_VALIDf; 1052 type_field = KEY_TYPEf; 1053 decouple = 1; 1054 } else 1055 #endif 1056 { 1057 egr_vxlate_mem = EGR_VLAN_XLATEm; 1058 valid_field = VALIDf; 1059 type_field = ENTRY_TYPEf; 1060 } 1061 1062 idx_min = soc_mem_index_min(unit, egr_vxlate_mem); 1063 idx_max = soc_mem_index_max(unit, egr_vxlate_mem); 1064 1065 egr_vxlate_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, egr_vxlate_mem), 1066 "EGR_VLAN_XLATE buffer"); 1067 if (NULL == egr_vxlate_buf) { 1068 return BCM_E_MEMORY; 1069 } 1070 1071 rv = soc_mem_read_range(unit, egr_vxlate_mem, MEM_BLOCK_ANY, 1072 idx_min, idx_max, egr_vxlate_buf); 1073 if (SOC_FAILURE(rv)) { 1074 goto clean_up; 1075 } 1076 1077 for (i = idx_min; i <= idx_max; i++) { 1078 egr_vxlate_entry = soc_mem_table_idx_to_pointer(unit, egr_vxlate_mem, 1079 void*, egr_vxlate_buf, i); 1080 1081 if (soc_mem_field32_get(unit, egr_vxlate_mem, egr_vxlate_entry, valid_field)) { 1082 entry_type = soc_mem_field32_get(unit, egr_vxlate_mem, egr_vxlate_entry, type_field); 1083 if (entry_type != _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP) { 1084 continue; 1085 } 1086 1087 vfi = soc_mem_field32_get(unit, egr_vxlate_mem, 1088 egr_vxlate_entry, BCM_VXLAN_VFI_FIELD(decouple, VFIf)); 1089 _BCM_VXLAN_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, vfi); 1090 rv = _bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type); 1091 if (BCM_FAILURE(rv)) { 1092 goto clean_up; 1093 } 1094 if (vxlan_vpn_type) { 1095 continue; 1096 } 1097 1098 vp = soc_mem_field32_get(unit, egr_vxlate_mem, 1099 egr_vxlate_entry, BCM_VXLAN_VFI_FIELD(decouple, DVPf)); 1100 vxlan_info->vfi_vnid_map_count[vp]++; 1101 } 1102 } 1103 1104 clean_up: 1105 1106 if (NULL != egr_vxlate_buf) { 1107 soc_cm_sfree(unit, egr_vxlate_buf); 1108 } 1109 return rv; 1110 } 1111 1112 /* 1113 * Function: 1114 * _bcm_td2_vxlan_reinit 1115 * Purpose: 1116 * Warm boot recovery for the VXLAN software module 1117 * Parameters: 1118 * unit - Device Number 1119 * Returns: 1120 * BCM_E_XXX 1121 */ 1122 STATIC int 1123 _bcm_td2_vxlan_reinit(int unit) 1124 { 1125 soc_mem_t mem; 1126 int i, index_min, index_max, buf_size; 1127 int vp; 1128 int rv = BCM_E_NONE; 1129 void *entry; 1130 uint32 trunk, tgid, mod_id, port_num, key_type; 1131 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 1132 uint8 *trunk_buf = NULL; 1133 uint8 *xlate_buf = NULL; 1134 uint8 *mpls_buf = NULL; 1135 soc_field_t vld_fld = SOURCE_VPf; 1136 soc_field_t tgid_fld = TGIDf; 1137 int d = 0; 1138 1139 vxlan_info = VXLAN_INFO(unit); 1140 1141 mem = SOURCE_TRUNK_MAP_TABLEm; 1142 index_min = soc_mem_index_min(unit, mem); 1143 index_max = soc_mem_index_max(unit, mem); 1144 1145 /* We check SOURCE_TRUNK_MAP_TABLE table outside to avoid the HUGE loop. 1146 * Set each match_key[vp].index first, and override it to zero later if 1147 * it's not needed. 1148 */ 1149 buf_size = SOC_MEM_TABLE_BYTES(unit, mem); 1150 trunk_buf = soc_cm_salloc(unit, buf_size, "SOURCE_TRUNK_MAP_TABLE buffer"); 1151 if (NULL == trunk_buf) { 1152 rv = BCM_E_MEMORY; 1153 goto clean_up; 1154 } 1155 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max, trunk_buf); 1156 if (SOC_FAILURE(rv)) { 1157 goto clean_up; 1158 } 1159 1160 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 1161 vld_fld = SVP_VALIDf; 1162 } 1163 1164 if (SOC_IS_TRIDENT3X(unit) && soc_mem_field_valid(unit, mem, SRC_TGIDf)) { 1165 tgid_fld = SRC_TGIDf; 1166 } 1167 1168 for (i = index_min; i <= index_max; i++) { 1169 bcm_trunk_t tgid = -1; 1170 int port_type = 0; 1171 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, trunk_buf, i); 1172 if (soc_mem_field32_get(unit, mem, entry, vld_fld) == 0) { 1173 continue; 1174 } 1175 1176 port_type = soc_mem_field32_get(unit, mem, entry, PORT_TYPEf); 1177 if (port_type == 1) { /* Trunk */ 1178 tgid = soc_mem_field32_get(unit, mem, entry, tgid_fld); 1179 } 1180 1181 vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf); 1182 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1183 if (port_type == 1) { /* Trunk */ 1184 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK; 1185 vxlan_info->match_key[vp].trunk_id = tgid; 1186 vxlan_info->match_key[vp].modid = -1; 1187 } else { 1188 vxlan_info->match_key[vp].index = i; /* SRC Trunk table index */ 1189 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_PORT; 1190 vxlan_info->match_key[vp].trunk_id = -1; 1191 vxlan_info->match_key[vp].modid = -1; 1192 } 1193 } 1194 } 1195 1196 /* 1197 * For Trident2 device currently 1198 * 1199 * foreach valid Source VP used by VXLAN of VLAN_XLANTE table 1200 * build the inner/outer 802.1Q tag info, trunk/port info, flag of each SVP. 1201 * base on hash key type and trunk. 1202 * 1203 * Sets the following fields: 1204 * 1205 * VXLAN_INFO[unit].match_key[SVP].flags 1206 * VXLAN_INFO[unit].match_key[SVP].match_vlan 1207 * VXLAN_INFO[unit].match_key[SVP].match_inner_vlan 1208 * VXLAN_INFO[unit].match_key[SVP].trunk_id 1209 * VXLAN_INFO[unit].match_key[SVP].port 1210 * VXLAN_INFO[unit].match_key[SVP].modid 1211 * VXLAN_INFO[unit].match_key[SVP].index 1212 */ 1213 1214 #if defined(BCM_TRIDENT3_SUPPORT) 1215 if (soc_feature(unit, soc_feature_base_valid)) { 1216 mem = VLAN_XLATE_1_DOUBLEm; 1217 } else 1218 #endif 1219 { 1220 mem = VLAN_XLATEm; 1221 } 1222 1223 index_min = soc_mem_index_min(unit, mem); 1224 index_max = soc_mem_index_max(unit, mem); 1225 1226 buf_size = SOC_MEM_TABLE_BYTES(unit, mem); 1227 xlate_buf = soc_cm_salloc(unit, buf_size, "VLAN_XLATE buffer"); 1228 if (NULL == xlate_buf) { 1229 rv = BCM_E_MEMORY; 1230 goto clean_up; 1231 } 1232 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max, xlate_buf); 1233 if (SOC_FAILURE(rv)) { 1234 goto clean_up; 1235 } 1236 1237 for (i = index_min; i <= index_max; i++) { 1238 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, xlate_buf, i); 1239 1240 #if defined(BCM_TRIDENT3_SUPPORT) 1241 if (soc_feature(unit, soc_feature_base_valid)) { 1242 if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_0f) != 3) { 1243 continue; 1244 } 1245 if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_1f) != 7) { 1246 continue; 1247 } 1248 } else 1249 #endif 1250 { 1251 if (soc_mem_field32_get(unit, mem, entry, VALIDf) == 0) { 1252 continue; 1253 } 1254 } 1255 1256 if (soc_mem_field32_get(unit, mem, entry, XLATE__MPLS_ACTIONf) != 0x1) { 1257 continue; 1258 } 1259 1260 vp = soc_mem_field32_get(unit, mem, entry, XLATE__SOURCE_VPf); 1261 1262 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1263 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1264 _bcm_vp_info_t vp_info; 1265 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 1266 1267 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 1268 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_SHARED; 1269 } else 1270 #endif 1271 { 1272 key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPEf); 1273 trunk = soc_mem_field32_get(unit, mem, entry, XLATE__Tf); 1274 tgid = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf); 1275 mod_id = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf); 1276 port_num = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf); 1277 1278 if (TR_VLXLT_HASH_KEY_TYPE_OVID == key_type) { 1279 vxlan_info->match_key[vp].flags = 1280 _BCM_VXLAN_PORT_MATCH_TYPE_VLAN; 1281 vxlan_info->match_key[vp].match_vlan = 1282 soc_mem_field32_get(unit, mem, entry, XLATE__OVIDf); 1283 } else if (TR_VLXLT_HASH_KEY_TYPE_IVID == key_type) { 1284 vxlan_info->match_key[vp].flags = 1285 _BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN; 1286 vxlan_info->match_key[vp].match_inner_vlan = 1287 soc_mem_field32_get(unit, mem, entry, XLATE__IVIDf); 1288 } else if (TR_VLXLT_HASH_KEY_TYPE_IVID_OVID == key_type) { 1289 vxlan_info->match_key[vp].flags = 1290 _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED; 1291 vxlan_info->match_key[vp].match_vlan = 1292 soc_mem_field32_get(unit, mem, entry, XLATE__OVIDf); 1293 vxlan_info->match_key[vp].match_inner_vlan = 1294 soc_mem_field32_get(unit, mem, entry, XLATE__IVIDf); 1295 } else if (TR_VLXLT_HASH_KEY_TYPE_PRI_CFI == key_type) { 1296 vxlan_info->match_key[vp].flags = 1297 _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI; 1298 vxlan_info->match_key[vp].match_vlan = 1299 soc_mem_field32_get(unit, mem, entry, OTAGf); 1300 } 1301 1302 if (trunk) { 1303 vxlan_info->match_key[vp].trunk_id = tgid; 1304 vxlan_info->match_key[vp].modid = -1; 1305 vxlan_info->match_key[vp].index = 0; 1306 } else { 1307 vxlan_info->match_key[vp].port = port_num; 1308 vxlan_info->match_key[vp].modid = mod_id; 1309 vxlan_info->match_key[vp].trunk_id = -1; 1310 vxlan_info->match_key[vp].index = 0; 1311 } 1312 } 1313 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 1314 } 1315 } 1316 1317 /* Recovery based on entry in MPLS tbl */ 1318 1319 mem = MPLS_ENTRYm; 1320 #if defined(BCM_TRIDENT3_SUPPORT) 1321 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 1322 mem = MPLS_ENTRY_SINGLEm; 1323 d = 1; 1324 } 1325 #endif 1326 index_min = soc_mem_index_min(unit, mem); 1327 index_max = soc_mem_index_max(unit, mem); 1328 1329 /* 1330 * foreach valid entry with key_type TUNNEL/VFI of MPLS_ENTRY table 1331 * recover the tunnel sip info and flag of each SVP used by VXLAN. 1332 * 1333 * Sets the following fields: 1334 * 1335 * VXLAN_INFO[unit].match_key[SVP].flags 1336 * VXLAN_INFO[unit].match_key[SVP].match_tunnel_index 1337 */ 1338 1339 buf_size = SOC_MEM_TABLE_BYTES(unit, mem); 1340 mpls_buf = soc_cm_salloc(unit, buf_size, "MPLS_ENTRY buffer"); 1341 if (NULL == mpls_buf) { 1342 rv = BCM_E_MEMORY; 1343 goto clean_up; 1344 } 1345 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max, mpls_buf); 1346 if (SOC_FAILURE(rv)) { 1347 goto clean_up; 1348 } 1349 1350 for (i = index_min; i <= index_max; i++) { 1351 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, mpls_buf, i); 1352 #if defined(BCM_TRIDENT3_SUPPORT) 1353 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 1354 if (soc_mem_field32_get(unit, mem, entry, BASE_VALIDf) != 1) { 1355 continue; 1356 } 1357 } else 1358 #endif 1359 { 1360 if (soc_mem_field32_get(unit, mem, entry, VALIDf) == 0) { 1361 continue; 1362 } 1363 } 1364 1365 /* Looking for entries of type vxlan only */ 1366 key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPEf); 1367 if ((key_type != _BCM_VXLAN_KEY_TYPE_TUNNEL) && 1368 (key_type != _BCM_VXLAN_KEY_TYPE_VNID_VFI) && 1369 (key_type != _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI)) { 1370 continue; 1371 } 1372 1373 vp = soc_mem_field32_get(unit, mem, entry, BCM_VXLAN_SIP_FIELD(d, SVPf)); 1374 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1375 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_VNID; 1376 } 1377 1378 } 1379 1380 /* Tunnel initiator hash and ref-count recovery */ 1381 rv = _bcm_td2_vxlan_tunnel_initiator_reinit(unit); 1382 if (BCM_FAILURE(rv)) { 1383 goto clean_up; 1384 } 1385 1386 /* Recover L2 scache */ 1387 rv = _bcm_td2_vxlan_wb_recover(unit); 1388 if (BCM_FAILURE(rv)) { 1389 goto clean_up; 1390 } 1391 1392 rv = _bcm_td2_vxlan_vp_based_vnid_reinit(unit); 1393 1394 clean_up: 1395 if (NULL != trunk_buf) { 1396 soc_cm_sfree(unit, trunk_buf); 1397 } 1398 if (NULL != xlate_buf) { 1399 soc_cm_sfree(unit, xlate_buf); 1400 } 1401 if (NULL != mpls_buf) { 1402 soc_cm_sfree(unit, mpls_buf); 1403 } 1404 1405 return rv; 1406 } 1407 #endif /* BCM_WARM_BOOT_SUPPORT */ 1408 1409 /* 1410 * Function: 1411 * bcm_td2_vxlan_init 1412 * Purpose: 1413 * Initialize the VXLAN software module 1414 * Parameters: 1415 * unit - Device Number 1416 * Returns: 1417 * BCM_E_XXX 1418 */ 1419 1420 1421 int 1422 bcm_td2_vxlan_init(int unit) 1423 { 1424 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 1425 int i, num_tnl=0, num_vp=0; 1426 int rv = BCM_E_NONE; 1427 int num_vfi = 0; 1428 1429 if (!L3_INFO(unit)->l3_initialized) { 1430 LOG_ERROR(BSL_LS_BCM_VXLAN, 1431 (BSL_META_U(unit, 1432 "L3 module must be initialized prior to VXLAN Init\n"))); 1433 return BCM_E_CONFIG; 1434 } 1435 1436 /* Allocate BK Info */ 1437 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_allocate_bk(unit)); 1438 vxlan_info = VXLAN_INFO(unit); 1439 1440 /* 1441 * allocate resources 1442 */ 1443 if (vxlan_info->initialized) { 1444 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_cleanup(unit)); 1445 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_allocate_bk(unit)); 1446 vxlan_info = VXLAN_INFO(unit); 1447 } 1448 1449 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 1450 vxlan_info->match_key = 1451 sal_alloc(sizeof(_bcm_vxlan_match_port_info_t) * num_vp, "match_key"); 1452 if (vxlan_info->match_key == NULL) { 1453 _bcm_td2_vxlan_free_resource(unit); 1454 return BCM_E_MEMORY; 1455 } 1456 sal_memset(vxlan_info->match_key, 0, 1457 sizeof(_bcm_vxlan_match_port_info_t) * num_vp); 1458 /* Stay same after recover */ 1459 for (i = 0; i < num_vp; i++) { 1460 bcm_td2_vxlan_match_clear(unit, i); 1461 } 1462 1463 /* Create EGR_IP_TUNNEL usage bitmap */ 1464 num_tnl = soc_mem_index_count(unit, EGR_IP_TUNNELm); 1465 1466 vxlan_info->vxlan_ip_tnl_bitmap = 1467 sal_alloc(SHR_BITALLOCSIZE(num_tnl), "vxlan_ip_tnl_bitmap"); 1468 if (vxlan_info->vxlan_ip_tnl_bitmap == NULL) { 1469 _bcm_td2_vxlan_free_resource(unit); 1470 return BCM_E_MEMORY; 1471 } 1472 sal_memset(vxlan_info->vxlan_ip_tnl_bitmap, 0, SHR_BITALLOCSIZE(num_tnl)); 1473 1474 /* Create VXLAN protection mutex. */ 1475 vxlan_info->vxlan_mutex = sal_mutex_create("vxlan_mutex"); 1476 if (!vxlan_info->vxlan_mutex) { 1477 _bcm_td2_vxlan_free_resource(unit); 1478 return BCM_E_MEMORY; 1479 } 1480 1481 if (NULL == vxlan_info->vxlan_tunnel_term) { 1482 vxlan_info->vxlan_tunnel_term = 1483 sal_alloc(sizeof(_bcm_vxlan_tunnel_endpoint_t) * num_vp, "vxlan tunnel term store"); 1484 if (vxlan_info->vxlan_tunnel_term == NULL) { 1485 _bcm_td2_vxlan_free_resource(unit); 1486 return BCM_E_MEMORY; 1487 } 1488 sal_memset(vxlan_info->vxlan_tunnel_term, 0, 1489 sizeof(_bcm_vxlan_tunnel_endpoint_t) * num_vp); 1490 } 1491 1492 if (NULL == vxlan_info->vxlan_tunnel_init) { 1493 vxlan_info->vxlan_tunnel_init = 1494 sal_alloc(sizeof(_bcm_vxlan_tunnel_endpoint_t) * num_vp, "vxlan tunnel init store"); 1495 if (vxlan_info->vxlan_tunnel_init == NULL) { 1496 _bcm_td2_vxlan_free_resource(unit); 1497 return BCM_E_MEMORY; 1498 } 1499 sal_memset(vxlan_info->vxlan_tunnel_init, 0, 1500 sizeof(_bcm_vxlan_tunnel_endpoint_t) * num_vp); 1501 } 1502 1503 num_vfi = soc_mem_index_count(unit, VFIm); 1504 if (NULL == vxlan_info->vxlan_vpn_vlan) { 1505 vxlan_info->vxlan_vpn_vlan = 1506 sal_alloc(sizeof(bcm_vlan_t) * num_vfi, "vxlan vpn vlan store"); 1507 if (vxlan_info->vxlan_vpn_vlan == NULL) { 1508 _bcm_td2_vxlan_free_resource(unit); 1509 return BCM_E_MEMORY; 1510 } 1511 sal_memset(vxlan_info->vxlan_vpn_vlan, 0, sizeof(bcm_vlan_t) * num_vfi); 1512 } 1513 1514 if (NULL == vxlan_info->vxlan_vpn_info) { 1515 vxlan_info->vxlan_vpn_info = 1516 sal_alloc(sizeof(_bcm_vxlan_vpn_info_t) * num_vfi, "vxlan vpn info store"); 1517 if (vxlan_info->vxlan_vpn_info == NULL) { 1518 _bcm_td2_vxlan_free_resource(unit); 1519 return BCM_E_MEMORY; 1520 } 1521 sal_memset(vxlan_info->vxlan_vpn_info, 0, sizeof(_bcm_vxlan_vpn_info_t) * num_vfi); 1522 } 1523 1524 if (vxlan_info->vfi_vnid_map_count == NULL) { 1525 vxlan_info->vfi_vnid_map_count = sal_alloc(sizeof(uint32) * num_vp, "vxlan vfi vnid map count"); 1526 if (vxlan_info->vfi_vnid_map_count == NULL) { 1527 _bcm_td2_vxlan_free_resource(unit); 1528 return BCM_E_MEMORY; 1529 } 1530 sal_memset(vxlan_info->vfi_vnid_map_count, 0, sizeof(uint32) * num_vp); 1531 } 1532 1533 #ifdef BCM_WARM_BOOT_SUPPORT 1534 if (SOC_WARM_BOOT(unit)) { 1535 rv = _bcm_td2_vxlan_reinit(unit); 1536 if (BCM_FAILURE(rv)) { 1537 _bcm_td2_vxlan_free_resource(unit); 1538 } 1539 } else { 1540 rv = _bcm_td2_vxlan_wb_alloc(unit); 1541 } 1542 #endif /* BCM_WARM_BOOT_SUPPORT */ 1543 /* Mark the state as initialized */ 1544 vxlan_info->initialized = TRUE; 1545 1546 return rv; 1547 } 1548 1549 /* 1550 * Function: 1551 * _bcm_td2_vxlan_bud_loopback_enable 1552 * Purpose: 1553 * Enable loopback for VXLAN BUD node multicast 1554 * Parameters: 1555 * IN : unit 1556 * Returns: 1557 * BCM_E_XXX 1558 */ 1559 1560 STATIC int 1561 _bcm_td2_vxlan_bud_loopback_enable(int unit) 1562 { 1563 int field_num = 0; 1564 1565 soc_field_t lport_fields[] = { 1566 VXLAN_TERMINATION_ALLOWEDf, 1567 V4IPMC_ENABLEf, 1568 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, 1569 PORT_TYPEf, 1570 VXLAN_DEFAULT_SVP_ENABLEf 1571 }; 1572 uint32 lport_values[] = { 1573 0x1, /* VXLAN_TERMINATION_ALLOWEDf */ 1574 0x1, /* V4IPMC_ENABLEf */ 1575 0x0, /* VXLAN_VN_ID_LOOKUP_KEY_TYPEf */ 1576 0x0, /* PORT_TYPEf */ 1577 0x1, /* VXLAN_DEFAULT_SVP_ENABLEf */ 1578 }; 1579 1580 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VXLAN_DEFAULT_SVP_ENABLEf)) { 1581 field_num = 5; 1582 } else { 1583 field_num = 3; /* TD3TBD */ 1584 } 1585 1586 /* Update LPORT Profile Table */ 1587 return _bcm_lport_profile_fields32_modify(unit, LPORT_PROFILE_LPORT_TAB, 1588 field_num, lport_fields, lport_values); 1589 } 1590 1591 /* 1592 * Function: 1593 * _bcm_td2_vxlan_bud_loopback_disable 1594 * Purpose: 1595 * Disable loopback for VXLAN BUD node multicast 1596 * Parameters: 1597 * IN : unit 1598 * Returns: 1599 * BCM_E_XXX 1600 */ 1601 1602 STATIC int 1603 _bcm_td2_vxlan_bud_loopback_disable(int unit) 1604 { 1605 int field_num = 0; 1606 1607 soc_field_t lport_fields[] = { 1608 VXLAN_TERMINATION_ALLOWEDf, 1609 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, 1610 V4IPMC_ENABLEf, 1611 PORT_TYPEf, 1612 VXLAN_DEFAULT_SVP_ENABLEf 1613 }; 1614 uint32 lport_values[] = { 1615 0x0, /* VXLAN_TERMINATION_ALLOWEDf */ 1616 0x0, /* VXLAN_VN_ID_LOOKUP_KEY_TYPEf */ 1617 0x0, /* V4IPMC_ENABLEf */ 1618 0x0, /* PORT_TYPEf */ 1619 0x0 /* VXLAN_DEFAULT_SVP_ENABLEf */ 1620 }; 1621 1622 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, PORT_TYPEf)) { 1623 field_num = 5; 1624 } else if (SOC_IS_TRIDENT3X(unit)) { 1625 field_num = 2; 1626 } else { 1627 field_num = 3; 1628 } 1629 1630 /* Update LPORT Profile Table */ 1631 return _bcm_lport_profile_fields32_modify(unit, LPORT_PROFILE_LPORT_TAB, 1632 field_num, lport_fields, lport_values); 1633 } 1634 1635 /* Function: 1636 * _bcm_td2_vxlan_vpn_is_valid 1637 * Purpose: 1638 * Find if given VXLAN VPN is Valid 1639 * Parameters: 1640 * unit - Device Number 1641 * l2vpn - VXLAN VPN 1642 * Returns: 1643 * BCM_E_XXXX 1644 */ 1645 int 1646 _bcm_td2_vxlan_vpn_is_valid( int unit, bcm_vpn_t l2vpn) 1647 { 1648 bcm_vpn_t vxlan_vpn_min=0; 1649 int vfi_index=-1, num_vfi=0; 1650 1651 num_vfi = soc_mem_index_count(unit, VFIm); 1652 1653 /* Check for Valid vpn */ 1654 _BCM_VXLAN_VPN_SET(vxlan_vpn_min, _BCM_VPN_TYPE_VFI, 0); 1655 if ( l2vpn < vxlan_vpn_min || l2vpn > (vxlan_vpn_min+num_vfi-1) ) { 1656 return BCM_E_PARAM; 1657 } 1658 1659 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, l2vpn); 1660 1661 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 1662 return BCM_E_NOT_FOUND; 1663 } 1664 return BCM_E_NONE; 1665 } 1666 1667 /* Function: 1668 * _bcm_td2_vxlan_vpn_is_eline 1669 * Purpose: 1670 * Find if given VXLAN VPN is ELINE 1671 * Parameters: 1672 * unit - Device Number 1673 * l2vpn - VXLAN VPN 1674 * isEline - Flag 1675 * Returns: 1676 * BCM_E_XXXX 1677 * Assumes: 1678 * l2vpn is valid 1679 */ 1680 1681 int 1682 _bcm_td2_vxlan_vpn_is_eline( int unit, bcm_vpn_t l2vpn, uint8 *isEline) 1683 { 1684 int vfi_index=-1; 1685 vfi_entry_t vfi_entry; 1686 1687 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, l2vpn)); 1688 1689 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, l2vpn); 1690 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 1691 1692 /* Set the returned VPN id */ 1693 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 1694 *isEline = 1; /* ELINE */ 1695 } else { 1696 *isEline = 0; /* ELAN */ 1697 } 1698 return BCM_E_NONE; 1699 } 1700 1701 /* Function: 1702 * _bcm_td2_vxlan_vpn_is_based_vnid 1703 * Purpose: 1704 * Find if given VXLAN VPN is vnid basedE 1705 * Parameters: 1706 * unit - Device Number 1707 * l2vpn - VXLAN VPN 1708 * vxlan_vpn_type - type 1709 * Returns: 1710 * BCM_E_XXXX 1711 * Assumes: 1712 * l2vpn is valid 1713 */ 1714 int 1715 _bcm_td2_vxlan_vpn_is_tunnel_based_vnid( int unit, bcm_vpn_t l2vpn, uint8 *vxlan_vpn_type) 1716 { 1717 int vfi = 0; 1718 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 1719 if (l2vpn == BCM_VXLAN_VPN_INVALID) { 1720 *vxlan_vpn_type = 0; 1721 return BCM_E_NONE; 1722 } 1723 vxlan_info = VXLAN_INFO(unit); 1724 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, l2vpn); 1725 if (vfi > soc_mem_index_count(unit, VFIm)) { 1726 return BCM_E_PARAM; 1727 } 1728 if (vxlan_info->vxlan_vpn_info[vfi].vxlan_vpn_type) { 1729 *vxlan_vpn_type = _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID; 1730 } else { 1731 *vxlan_vpn_type = 0; 1732 } 1733 return BCM_E_NONE; 1734 } 1735 1736 1737 1738 1739 /* Function: 1740 * _bcm_td2_vxlan_vp_is_eline 1741 * Purpose: 1742 * Find if given VXLAN VP is ELINE 1743 * Parameters: 1744 * unit - Device Number 1745 * vp - VXLAN VP 1746 * isEline - Flag 1747 * Returns: 1748 * BCM_E_XXXX 1749 * Assumes: 1750 * l2vpn is valid 1751 */ 1752 1753 int 1754 _bcm_td2_vxlan_vp_is_eline( int unit, int vp, uint8 *isEline) 1755 { 1756 source_vp_entry_t svp; 1757 vfi_entry_t vfi_entry; 1758 int rv = BCM_E_PARAM; 1759 int vfi_index; 1760 1761 if (vp == -1) { 1762 return BCM_E_PARAM; 1763 } 1764 1765 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1766 return BCM_E_NOT_FOUND; 1767 } 1768 1769 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 1770 if (rv < 0) { 1771 return rv; 1772 } 1773 1774 vfi_index = soc_SOURCE_VPm_field32_get(unit, &svp, VFIf); 1775 BCM_IF_ERROR_RETURN 1776 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 1777 1778 /* Set the returned VPN id */ 1779 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 1780 *isEline = 0x1; 1781 } else { 1782 *isEline = 0x0; 1783 } 1784 return BCM_E_NONE; 1785 } 1786 1787 /* 1788 * Function: 1789 * _bcm_td2_vxlan_nexthop_glp_get 1790 * Purpose: 1791 * Get the modid, port, trunk values for a VXLAN nexthop 1792 * Returns: 1793 * BCM_E_XXX 1794 */ 1795 STATIC int 1796 _bcm_td2_vxlan_nexthop_glp_get(int unit, int nh_idx, 1797 bcm_module_t *modid, bcm_port_t *port, bcm_trunk_t *trunk_id) 1798 1799 { 1800 ing_l3_next_hop_entry_t ing_nh; 1801 1802 BCM_IF_ERROR_RETURN (soc_mem_read(unit, 1803 ING_L3_NEXT_HOPm, MEM_BLOCK_ANY, nh_idx, &ing_nh)); 1804 1805 #if defined(BCM_TRIDENT3_SUPPORT) 1806 if (soc_feature(unit, soc_feature_generic_dest)) { 1807 uint32 dt, dv; 1808 1809 dv = soc_mem_field32_dest_get(unit, 1810 ING_L3_NEXT_HOPm, &ing_nh, DESTINATIONf, &dt); 1811 if (dt == SOC_MEM_FIF_DEST_LAG) { 1812 *trunk_id = dv & SOC_MEM_FIF_DGPP_TGID_MASK; 1813 } else if (dt == SOC_MEM_FIF_DEST_DGPP) { 1814 *port = (dv & SOC_MEM_FIF_DGPP_PORT_MASK); 1815 *modid = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 1816 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 1817 } else { 1818 return BCM_E_INTERNAL; 1819 } 1820 } else 1821 #endif 1822 { 1823 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 1824 *trunk_id = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, TGIDf); 1825 } else { 1826 /* Only add this to replication set if destination is local */ 1827 *modid = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, MODULE_IDf); 1828 *port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, PORT_NUMf); 1829 } 1830 } 1831 1832 return BCM_E_NONE; 1833 } 1834 1835 /* 1836 * Function: 1837 * _bcm_td2_vxlan_port_resolve 1838 * Purpose: 1839 * Get the modid, port, trunk values for a VXLAN port 1840 * Returns: 1841 * BCM_E_XXX 1842 */ 1843 int 1844 _bcm_td2_vxlan_port_resolve(int unit, bcm_gport_t vxlan_port_id, 1845 bcm_if_t encap_id, bcm_module_t *modid, bcm_port_t *port, 1846 bcm_trunk_t *trunk_id, int *id) 1847 1848 { 1849 int rv = BCM_E_NONE; 1850 egr_l3_next_hop_entry_t egr_nh; 1851 ing_dvp_table_entry_t dvp; 1852 int ecmp=0, nh_index=-1, nh_ecmp_index=-1, vp=-1; 1853 uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to read hw entry. */ 1854 int idx, max_ent_count, base_idx; 1855 1856 rv = _bcm_vxlan_check_init(unit); 1857 if (rv < 0) { 1858 return rv; 1859 } 1860 1861 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port_id); 1862 if (vp == -1) { 1863 return BCM_E_PARAM; 1864 } 1865 1866 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1867 return BCM_E_NOT_FOUND; 1868 } 1869 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 1870 ecmp = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMPf); 1871 if (!ecmp) { 1872 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 1873 1874 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_nexthop_glp_get(unit, 1875 nh_index, modid, port, trunk_id)); 1876 } else { 1877 /* Select the desired nhop from ECMP group - pointed by encap_id */ 1878 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMP_PTRf); 1879 BCM_IF_ERROR_RETURN( 1880 soc_mem_read(unit, L3_ECMP_COUNTm, MEM_BLOCK_ANY, 1881 nh_ecmp_index, hw_buf)); 1882 1883 if (soc_feature(unit, soc_feature_l3_ecmp_1k_groups)) { 1884 max_ent_count = soc_mem_field32_get(unit, L3_ECMP_COUNTm, 1885 hw_buf, COUNTf); 1886 base_idx = soc_mem_field32_get(unit, L3_ECMP_COUNTm, 1887 hw_buf, BASE_PTRf); 1888 } else { 1889 max_ent_count = soc_mem_field32_get(unit, L3_ECMP_COUNTm, 1890 hw_buf, COUNT_0f); 1891 base_idx = soc_mem_field32_get(unit, L3_ECMP_COUNTm, 1892 hw_buf, BASE_PTR_0f); 1893 } 1894 max_ent_count++; /* Count is zero based. */ 1895 1896 if(encap_id == -1) { 1897 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 1898 L3_ECMPm, MEM_BLOCK_ANY, base_idx, hw_buf)); 1899 nh_index = soc_mem_field32_get(unit, 1900 L3_ECMPm, hw_buf, NEXT_HOP_INDEXf); 1901 1902 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_nexthop_glp_get(unit, 1903 nh_index, modid, port, trunk_id)); 1904 } else { 1905 for (idx = 0; idx < max_ent_count; idx++) { 1906 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 1907 L3_ECMPm, MEM_BLOCK_ANY, (base_idx+idx), hw_buf)); 1908 nh_index = soc_mem_field32_get(unit, 1909 L3_ECMPm, hw_buf, NEXT_HOP_INDEXf); 1910 BCM_IF_ERROR_RETURN (soc_mem_read(unit, 1911 EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, nh_index, &egr_nh)); 1912 if (encap_id == soc_mem_field32_get(unit, 1913 EGR_L3_NEXT_HOPm, &egr_nh, INTF_NUMf)) { 1914 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_nexthop_glp_get(unit, 1915 nh_index, modid, port, trunk_id)); 1916 break; 1917 } 1918 } 1919 } 1920 } 1921 *id = vp; 1922 return rv; 1923 } 1924 1925 /* 1926 * Function: 1927 * _bcm_td2_vxlan_port_nh_cnt_dec 1928 * Purpose: 1929 * Decrease vxlan port's nexthop count. 1930 * Parameters: 1931 * unit - (IN) SOC unit number. 1932 * vp - (IN) Virtual port number. 1933 * Returns: 1934 * BCM_E_XXX 1935 */ 1936 1937 STATIC int 1938 _bcm_td2_vxlan_port_nh_cnt_dec(int unit, int vp) 1939 { 1940 int nh_ecmp_index = -1; 1941 ing_dvp_table_entry_t dvp; 1942 uint32 flags = 0; 1943 int ref_count = 0; 1944 int ecmp = 0; 1945 1946 BCM_IF_ERROR_RETURN( 1947 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 1948 1949 ecmp = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMPf); 1950 if (ecmp) { 1951 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMP_PTRf); 1952 flags = BCM_L3_MULTIPATH; 1953 /* Decrement reference count */ 1954 BCM_IF_ERROR_RETURN( 1955 bcm_xgs3_get_ref_count_from_nhi(unit, flags, &ref_count, nh_ecmp_index)); 1956 } else { 1957 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 1958 NEXT_HOP_INDEXf); 1959 if(nh_ecmp_index != 0) { 1960 /* Decrement reference count */ 1961 BCM_IF_ERROR_RETURN( 1962 bcm_xgs3_get_ref_count_from_nhi(unit, flags, &ref_count, nh_ecmp_index)); 1963 } 1964 } 1965 1966 return BCM_E_NONE; 1967 } 1968 1969 /* 1970 * Function: 1971 * _bcm_td2_vxlan_port_cnt_update 1972 * Purpose: 1973 * Update port's VP count. 1974 * Parameters: 1975 * unit - (IN) SOC unit number. 1976 * gport - (IN) GPORT ID. 1977 * vp - (IN) Virtual port number. 1978 * incr - (IN) If TRUE, increment VP count, else decrease VP count. 1979 * Returns: 1980 * BCM_X_XXX 1981 */ 1982 1983 STATIC int 1984 _bcm_td2_vxlan_port_cnt_update(int unit, bcm_gport_t gport, 1985 int vp, int incr_decr_flag) 1986 { 1987 int mod_out=-1, port_out=-1, tgid_out=-1, vp_out=-1; 1988 bcm_port_t local_member_array[SOC_MAX_NUM_PORTS]; 1989 int local_member_count=0; 1990 int idx=-1; 1991 int mod_local=-1; 1992 _bcm_port_info_t *port_info; 1993 uint32 port_flags; 1994 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1995 bcm_gport_t tmp_gport; 1996 #endif 1997 1998 BCM_IF_ERROR_RETURN( 1999 _bcm_td2_vxlan_port_resolve(unit, gport, -1, &mod_out, 2000 &port_out, &tgid_out, &vp_out)); 2001 2002 if (vp_out == -1) { 2003 return BCM_E_PARAM; 2004 } 2005 2006 /* Update the physical port's SW state. If associated with a trunk, 2007 * update each local physical port's SW state. 2008 */ 2009 2010 if (BCM_TRUNK_INVALID != tgid_out) { 2011 2012 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid_out, 2013 SOC_MAX_NUM_PORTS, local_member_array, &local_member_count)); 2014 2015 for (idx = 0; idx < local_member_count; idx++) { 2016 _bcm_port_info_access(unit, local_member_array[idx], &port_info); 2017 if (incr_decr_flag) { 2018 port_info->vp_count++; 2019 } else { 2020 port_info->vp_count--; 2021 } 2022 BCM_IF_ERROR_RETURN( 2023 bcm_esw_port_vlan_member_get( 2024 unit, local_member_array[idx], &port_flags)); 2025 BCM_IF_ERROR_RETURN( 2026 bcm_esw_port_vlan_member_set( 2027 unit, local_member_array[idx], port_flags)); 2028 } 2029 } else { 2030 #if defined(BCM_HGPROXY_COE_SUPPORT) 2031 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 2032 (_bcm_xgs5_subport_coe_mod_port_local(unit, mod_out, port_out))) { 2033 BCM_IF_ERROR_RETURN( 2034 _bcmi_coe_subport_mod_port_physical_port_get( 2035 unit, mod_out, port_out, &port_out)); 2036 mod_local = 1; 2037 } else 2038 #endif 2039 { 2040 BCM_IF_ERROR_RETURN( 2041 _bcm_esw_modid_is_local(unit, mod_out, &mod_local)); 2042 if (mod_local && soc_feature(unit, soc_feature_sysport_remap)) { 2043 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 2044 } 2045 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2046 if (!mod_local && soc_feature(unit, soc_feature_multi_next_hops_on_port) && 2047 _bcm_esw_is_multi_nexthop_mod_port(unit, mod_out, port_out)) { 2048 BCM_GPORT_MODPORT_SET(tmp_gport, mod_out, port_out); 2049 BCM_IF_ERROR_RETURN( 2050 _bcm_esw_modport_local_get(unit, tmp_gport, &port_out)); 2051 mod_local = 1; 2052 } 2053 #endif 2054 } 2055 if (mod_local) { 2056 if (soc_feature(unit, soc_feature_sysport_remap)) { 2057 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 2058 } 2059 _bcm_port_info_access(unit, port_out, &port_info); 2060 if (incr_decr_flag) { 2061 port_info->vp_count++; 2062 } else { 2063 port_info->vp_count--; 2064 } 2065 BCM_IF_ERROR_RETURN( 2066 bcm_esw_port_vlan_member_get( 2067 unit, port_out, &port_flags)); 2068 BCM_IF_ERROR_RETURN( 2069 bcm_esw_port_vlan_member_set( 2070 unit, port_out, port_flags)); 2071 } 2072 } 2073 2074 return BCM_E_NONE; 2075 } 2076 2077 #if defined(BCM_TRIDENT3_SUPPORT) 2078 /* 2079 * Function: 2080 * _bcm_td3_vxlan_vxlate_entry_assemble 2081 * Purpose: 2082 * Create a VPN instance 2083 * Parameters: 2084 * unit - (IN) Device Number 2085 * info - (IN) configuration entry info 2086 * ment - (IN/OUT) point of mem entry 2087 * Returns: 2088 * BCM_E_XXX 2089 */ 2090 STATIC void 2091 _bcm_td3_vxlan_vxlate_entry_assemble(int unit, _bcm_td3_vxlan_vxlate_entry_t info, uint32* ment) 2092 { 2093 soc_mem_t mmem = VLAN_XLATE_1_DOUBLEm; 2094 uint32 profile_idx = 0; 2095 2096 soc_mem_field32_set(unit, mmem, ment, BASE_VALID_0f, 3); 2097 soc_mem_field32_set(unit, mmem, ment, BASE_VALID_1f, 7); 2098 soc_mem_field32_set(unit, mmem, ment, DATA_TYPEf, info.dtype); 2099 soc_mem_field32_set(unit, mmem, ment, KEY_TYPEf, info.ktype); 2100 soc_mem_field32_set(unit, mmem, ment, VXLAN_FLEX__VFI_ACTION_SETf, info.vfi); 2101 /* action profile */ 2102 if (info.vlan != 0) { 2103 soc_mem_field32_set(unit, mmem, ment, VXLAN_FLEX__OVIDf, info.vlan); 2104 _bcm_td3_def_vlan_profile_get(unit, &profile_idx); 2105 soc_mem_field32_set(unit,mmem, ment, 2106 VXLAN_FLEX__ING_TAG_ACTION_PROFILE_IDXf,profile_idx); 2107 } 2108 2109 } 2110 #endif 2111 2112 /* 2113 * Function: 2114 * bcm_td2_vxlan_vpn_create 2115 * Purpose: 2116 * Create a VPN instance 2117 * Parameters: 2118 * unit - (IN) Device Number 2119 * info - (IN/OUT) VPN configuration info 2120 * Returns: 2121 * BCM_E_XXX 2122 */ 2123 2124 int 2125 bcm_td2_vxlan_vpn_create(int unit, bcm_vxlan_vpn_config_t *info) 2126 { 2127 int rv = BCM_E_PARAM; 2128 vfi_entry_t vfi_entry; 2129 int vfi_index=-1; 2130 int bc_group=0, umc_group=0, uuc_group=0; 2131 int bc_group_type=0, umc_group_type=0, uuc_group_type=0; 2132 uint32 vnid = 0; 2133 uint32 ment[SOC_MAX_MEM_WORDS]; 2134 soc_mem_t mmem = MPLS_ENTRYm; 2135 soc_mem_t vxlate_mem; 2136 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 2137 int tpid_index = -1; 2138 int action_present=0, action_not_present=0; 2139 uint8 vpn_alloc_flag=0; 2140 uint8 vnid_alloc_flag = 0; 2141 int proto_pkt_idx = 0; 2142 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 2143 int d = 0; /*vxlan decoupled mode*/ 2144 2145 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2146 sal_memset(vxlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2147 2148 #if defined(BCM_TRIDENT3_SUPPORT) 2149 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2150 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 2151 d = 1; 2152 } else 2153 #endif 2154 { 2155 vxlate_mem = EGR_VLAN_XLATEm; 2156 } 2157 2158 vxlan_info = VXLAN_INFO(unit); 2159 /*Allocate VFI*/ 2160 if (info->flags & BCM_VXLAN_VPN_REPLACE) { 2161 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, info->vpn)); 2162 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, info->vpn); 2163 } else if (info->flags & BCM_VXLAN_VPN_WITH_ID) { 2164 rv = _bcm_td2_vxlan_vpn_is_valid(unit, info->vpn); 2165 if (BCM_E_NONE == rv) { 2166 return BCM_E_EXISTS; 2167 } else if (BCM_E_NOT_FOUND != rv) { 2168 return rv; 2169 } 2170 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, info->vpn); 2171 BCM_IF_ERROR_RETURN(_bcm_vfi_alloc_with_id(unit, VFIm, _bcmVfiTypeVxlan, vfi_index)); 2172 vpn_alloc_flag = 1; 2173 } else { 2174 BCM_IF_ERROR_RETURN(_bcm_vfi_alloc(unit, VFIm, _bcmVfiTypeVxlan, &vfi_index)); 2175 _BCM_VXLAN_VPN_SET(info->vpn, _BCM_VPN_TYPE_VFI, vfi_index); 2176 vpn_alloc_flag = 1; 2177 } 2178 2179 /*Initial and configure VFI*/ 2180 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2181 if (info->flags & BCM_VXLAN_VPN_ELINE) { 2182 soc_VFIm_field32_set(unit, &vfi_entry, PT2PT_ENf, 0x1); 2183 } else if (info->flags & BCM_VXLAN_VPN_ELAN) { 2184 /* Check that the groups are valid. */ 2185 bc_group_type = _BCM_MULTICAST_TYPE_GET(info->broadcast_group); 2186 bc_group = _BCM_MULTICAST_ID_GET(info->broadcast_group); 2187 umc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_multicast_group); 2188 umc_group = _BCM_MULTICAST_ID_GET(info->unknown_multicast_group); 2189 uuc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_unicast_group); 2190 uuc_group = _BCM_MULTICAST_ID_GET(info->unknown_unicast_group); 2191 2192 if ((bc_group_type != _BCM_MULTICAST_TYPE_VXLAN) || 2193 (umc_group_type != _BCM_MULTICAST_TYPE_VXLAN) || 2194 (uuc_group_type != _BCM_MULTICAST_TYPE_VXLAN) || 2195 (bc_group >= soc_mem_index_count(unit, L3_IPMCm)) || 2196 (umc_group >= soc_mem_index_count(unit, L3_IPMCm)) || 2197 (uuc_group >= soc_mem_index_count(unit, L3_IPMCm))) { 2198 rv = BCM_E_PARAM; 2199 _BCM_VXLAN_CLEANUP(rv) 2200 } 2201 2202 /* Commit the entry to HW */ 2203 #if defined(BCM_TRIDENT3_SUPPORT) 2204 if (soc_feature(unit, soc_feature_generic_dest)) { 2205 soc_mem_field32_dest_set(unit, VFIm, &vfi_entry, 2206 UMC_DESTINATIONf, SOC_MEM_FIF_DEST_IPMC, umc_group); 2207 soc_mem_field32_dest_set(unit, VFIm, &vfi_entry, 2208 UUC_DESTINATIONf, SOC_MEM_FIF_DEST_IPMC, uuc_group); 2209 soc_mem_field32_dest_set(unit, VFIm, &vfi_entry, 2210 BC_DESTINATIONf, SOC_MEM_FIF_DEST_IPMC, bc_group); 2211 } else 2212 #endif 2213 { 2214 soc_VFIm_field32_set(unit, &vfi_entry, UMC_INDEXf, umc_group); 2215 soc_VFIm_field32_set(unit, &vfi_entry, UUC_INDEXf, uuc_group); 2216 soc_VFIm_field32_set(unit, &vfi_entry, BC_INDEXf, bc_group); 2217 } 2218 #if defined(BCM_TRIDENT3_SUPPORT) 2219 if (SOC_IS_TRIDENT3X(unit)) { 2220 uint32 profile_idx = 0; 2221 rv = _bcm_td3_def_vfi_profile_add(unit, 2222 info->flags & BCM_VXLAN_VPN_ELINE, &profile_idx); 2223 if (BCM_E_NONE == rv) { 2224 soc_VFIm_field32_set(unit, &vfi_entry, VFI_PROFILE_PTRf, profile_idx); 2225 } 2226 _BCM_VXLAN_CLEANUP(rv) 2227 } 2228 #endif 2229 } 2230 2231 /* Configure protocol packet control */ 2232 rv = _bcm_xgs3_protocol_packet_actions_validate(unit, &info->protocol_pkt); 2233 _BCM_VXLAN_CLEANUP(rv) 2234 proto_pkt_idx = soc_VFIm_field32_get(unit, &vfi_entry, PROTOCOL_PKT_INDEXf); 2235 rv = _bcm_xgs3_protocol_pkt_ctrl_set(unit, proto_pkt_idx, &info->protocol_pkt, &proto_pkt_idx); 2236 _BCM_VXLAN_CLEANUP(rv) 2237 soc_VFIm_field32_set(unit, &vfi_entry, PROTOCOL_PKT_INDEXf, proto_pkt_idx); 2238 /*Write VFI to ASIC*/ 2239 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 2240 _BCM_VXLAN_CLEANUP(rv) 2241 2242 if (info->flags & BCM_VXLAN_VPN_WITH_VPNID) { 2243 if (info->vnid > 0xFFFFFF || 2244 (info->flags & BCM_VXLAN_VPN_TUNNEL_BASED_VNID)) { 2245 rv = BCM_E_PARAM; 2246 _BCM_VXLAN_CLEANUP(rv) 2247 } 2248 2249 /* Configure Ingress VNID */ 2250 #if defined(BCM_TRIDENT3_SUPPORT) 2251 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2252 _bcm_td3_vxlan_vxlate_entry_t ent; 2253 2254 mmem = VLAN_XLATE_1_DOUBLEm; 2255 sal_memset(&ent, 0, sizeof(_bcm_td3_vxlan_vxlate_entry_t)); 2256 ent.dtype = _BCM_VXLAN_DATA_TYPE_VNID_VFI_FLEX; 2257 ent.ktype = _BCM_VXLAN_KEY_TYPE_VNID_VFI_FLEX; 2258 ent.vfi = vfi_index; 2259 if (info->vlan > BCM_VLAN_MAX) { 2260 rv = BCM_E_PARAM; 2261 _BCM_VXLAN_CLEANUP(rv) 2262 } 2263 ent.vlan = info->default_vlan; 2264 _bcm_td3_vxlan_vxlate_entry_assemble(unit, ent, ment); 2265 } else 2266 #endif 2267 { 2268 soc_mem_field32_set(unit, mmem, &ment, VALIDf, 1); 2269 soc_mem_field32_set(unit, mmem, &ment, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_VNID_VFI); 2270 soc_mem_field32_set(unit, mmem, &ment, VXLAN_VN_ID__VFIf, vfi_index); 2271 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2272 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 2273 if (info->vlan > BCM_VLAN_MAX) { 2274 rv = BCM_E_PARAM; 2275 _BCM_VXLAN_CLEANUP(rv) 2276 } 2277 soc_mem_field32_set(unit, mmem, &ment, VXLAN_VN_ID__OVIDf, info->vlan); 2278 } 2279 #endif 2280 } 2281 2282 if (info->flags & BCM_VXLAN_VPN_REPLACE) { 2283 /*Delete old match vnid entry*/ 2284 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi_index, -1, vxlate_entry); 2285 if (rv == BCM_E_NONE) { 2286 vnid = soc_mem_field32_get(unit, vxlate_mem, 2287 vxlate_entry, (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf)); 2288 soc_mem_field32_set(unit, mmem, &ment, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), 2289 vnid); 2290 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2291 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 2292 soc_mem_field32_set(unit, mmem, &ment, VXLAN_VN_ID__OVIDf, 2293 vxlan_info->vxlan_vpn_vlan[vfi_index]); 2294 } 2295 #endif 2296 rv = soc_mem_delete(unit, mmem, MEM_BLOCK_ALL, &ment); 2297 _BCM_VXLAN_CLEANUP(rv) 2298 } else if (rv != BCM_E_NOT_FOUND) { 2299 _BCM_VXLAN_CLEANUP(rv) 2300 } 2301 } 2302 soc_mem_field32_set(unit, mmem, &ment, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), 2303 info->vnid); 2304 rv = soc_mem_insert(unit, mmem, MEM_BLOCK_ALL, &ment); 2305 _BCM_VXLAN_CLEANUP(rv) 2306 vnid_alloc_flag = 1; 2307 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2308 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 2309 vxlan_info->vxlan_vpn_vlan[vfi_index] = info->vlan; 2310 } 2311 #endif 2312 #if defined(BCM_TRIDENT3_SUPPORT) 2313 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2314 /*on td3, soc_feature_vrf_aware_vxlan_termination disabled*/ 2315 vxlan_info->vxlan_vpn_vlan[vfi_index] = info->default_vlan; 2316 } 2317 #endif 2318 if (info->flags & BCM_VXLAN_VPN_REPLACE) { 2319 soc_field_t tpid_fld; 2320 #if defined(BCM_TRIDENT3_SUPPORT) 2321 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2322 /*TAP process, delete tpid*/ 2323 int profile_index = -1; 2324 2325 tpid_fld = VXLAN_VFI_FLEX__OUTER_TPID_INDEXf; 2326 profile_index = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 2327 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 2328 (void)_bcm_td3_sd_tag_action_get(unit, profile_index, &action_present, 2329 &action_not_present); 2330 } else 2331 #endif 2332 { 2333 tpid_fld = VXLAN_VFI__SD_TAG_TPID_INDEXf; 2334 /*If old tpid exist, delete it*/ 2335 action_present = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 2336 VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf); 2337 action_not_present = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 2338 VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf); 2339 } 2340 2341 if (1 == action_present || 4 == action_present || 2342 7 == action_present || 1 == action_not_present) { 2343 tpid_index = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 2344 tpid_fld); 2345 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 2346 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 2347 _BCM_VXLAN_CLEANUP(rv) 2348 } 2349 } 2350 2351 rv = soc_mem_delete(unit, vxlate_mem, MEM_BLOCK_ALL, vxlate_entry); 2352 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 2353 _BCM_VXLAN_CLEANUP(rv) 2354 } 2355 } 2356 2357 /* Configure Egress VNID */ 2358 sal_memset(vxlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2359 #if defined(BCM_TRIDENT3_SUPPORT) 2360 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2361 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, BASE_VALIDf, 1); 2362 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, 2363 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 2364 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, 2365 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 2366 } else 2367 #endif 2368 { 2369 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, VALIDf, 0x1); 2370 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, 2371 ENTRY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 2372 } 2373 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, BCM_VXLAN_VFI_FIELD(d,VFIf), vfi_index); 2374 soc_mem_field32_set(unit, vxlate_mem, vxlate_entry, (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf), info->vnid); 2375 2376 /* Configure EGR_VLAN_XLATE - SD_TAG setting */ 2377 if (info->flags & BCM_VXLAN_VPN_SERVICE_TAGGED) { 2378 rv = _bcm_td2_vxlan_sd_tag_set(unit, info, NULL, NULL, vxlate_entry, &tpid_index); 2379 _BCM_VXLAN_CLEANUP(rv) 2380 } 2381 2382 rv = soc_mem_insert(unit, vxlate_mem, MEM_BLOCK_ALL, vxlate_entry); 2383 _BCM_VXLAN_CLEANUP(rv) 2384 vxlan_info->vxlan_vpn_info[vfi_index].vxlan_vpn_type = 0; 2385 } else { 2386 2387 /* Reset match vnid table */ 2388 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi_index, -1, vxlate_entry); 2389 if (rv == BCM_E_NONE) { 2390 vnid = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 2391 (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf)); 2392 /* Delete mpls_entry */ 2393 rv = _bcm_td2_vxlan_match_vnid_entry_reset(unit, vnid, 2394 vxlan_info->vxlan_vpn_vlan[vfi_index]); 2395 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 2396 return rv; 2397 } 2398 /* Delete egr_vxlate entry */ 2399 rv = _bcm_td2_vxlan_egr_xlate_entry_reset(unit, info->vpn); 2400 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 2401 return rv; 2402 } 2403 } else if (rv != BCM_E_NOT_FOUND) { 2404 return rv; 2405 } 2406 if (info->flags & BCM_VXLAN_VPN_TUNNEL_BASED_VNID) { 2407 vxlan_info->vxlan_vpn_info[vfi_index].vxlan_vpn_type = _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID; 2408 #if defined(BCM_TRIDENT3_SUPPORT) 2409 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2410 vxlan_info->vxlan_vpn_vlan[vfi_index] = info->default_vlan; 2411 } 2412 #endif 2413 } 2414 } 2415 2416 return BCM_E_NONE; 2417 2418 cleanup: 2419 if (tpid_index != -1) { 2420 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 2421 } 2422 if (vnid_alloc_flag) { 2423 soc_mem_delete(unit, mmem, MEM_BLOCK_ALL, &ment); 2424 } 2425 if (vpn_alloc_flag) { 2426 (void) _bcm_vfi_free(unit, _bcmVfiTypeVxlan, vfi_index); 2427 } 2428 return rv; 2429 } 2430 2431 /* Function: 2432 * bcm_td2_vxlan_vpn_vnid_get 2433 * Purpose: 2434 * Get VNID per VPN instance 2435 * Parameters: 2436 * unit - Device Number 2437 * l2vpn - VXLAN VPN 2438 * info - VXLAN VPN Config 2439 * Returns: 2440 * BCM_E_XXXX 2441 */ 2442 2443 STATIC int 2444 _bcm_td2_vxlan_egr_xlate_entry_get(int unit, int vfi, int vp, uint32 *vxlate_entry) 2445 { 2446 soc_mem_t vxlate_mem; 2447 uint32 key_vxlate[SOC_MAX_MEM_WORDS]; 2448 int index=0; 2449 2450 sal_memset(key_vxlate, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2451 2452 #if defined(BCM_TRIDENT3_SUPPORT) 2453 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2454 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 2455 2456 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, BASE_VALIDf, 1); 2457 if (vp != -1) { 2458 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, VXLAN_VFI_FLEX__DVPf, vp); 2459 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, 2460 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 2461 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, 2462 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 2463 } else { 2464 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, 2465 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 2466 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, 2467 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 2468 } 2469 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, VXLAN_VFI_FLEX__VFIf, vfi); 2470 } else 2471 #endif 2472 { 2473 vxlate_mem = EGR_VLAN_XLATEm; 2474 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, VALIDf, 0x1); 2475 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, ENTRY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 2476 if (vp != -1) { 2477 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, VXLAN_VFI__DVPf, vp); 2478 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, 2479 ENTRY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 2480 } else { 2481 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, 2482 ENTRY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 2483 } 2484 soc_mem_field32_set(unit, vxlate_mem, key_vxlate, VXLAN_VFI__VFIf, vfi); 2485 } 2486 2487 return soc_mem_search(unit, vxlate_mem, MEM_BLOCK_ANY, 2488 &index, key_vxlate, vxlate_entry, 0); 2489 } 2490 2491 2492 /* 2493 * Function: 2494 * bcm_td2_vxlan_vpn_destroy 2495 * Purpose: 2496 * Delete a VPN instance 2497 * Parameters: 2498 * unit - Device Number 2499 * vpn - VPN instance ID 2500 * Returns: 2501 * BCM_E_XXX 2502 */ 2503 2504 int 2505 bcm_td2_vxlan_vpn_destroy(int unit, bcm_vpn_t l2vpn) 2506 { 2507 int vfi = 0; 2508 vfi_entry_t vfi_entry; 2509 uint8 isEline = 0; 2510 uint32 vnid = 0; 2511 uint32 stat_counter_id; 2512 int num_ctr = 0; 2513 int ref_count; 2514 int index; 2515 int rv = 0; 2516 soc_mem_t vxlate_mem; 2517 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 2518 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 2519 int d = 0; /*vxlan decoupled mode*/ 2520 2521 #if defined(BCM_TRIDENT3_SUPPORT) 2522 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2523 d = 1; 2524 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 2525 } else 2526 #endif 2527 { 2528 vxlate_mem = EGR_VLAN_XLATEm; 2529 } 2530 2531 /* Get vfi index */ 2532 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_eline(unit, l2vpn, &isEline)); 2533 if (isEline == 0x1 ) { 2534 _BCM_VXLAN_VPN_GET(vfi, _BCM_VXLAN_VPN_TYPE_ELINE, l2vpn); 2535 } else if (isEline == 0x0 ) { 2536 _BCM_VXLAN_VPN_GET(vfi, _BCM_VXLAN_VPN_TYPE_ELAN, l2vpn); 2537 } 2538 if (!vxlan_info->vxlan_vpn_info[vfi].vxlan_vpn_type) { 2539 /* Reset match vnid table */ 2540 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi, -1, vxlate_entry); 2541 if (rv == BCM_E_NONE) { 2542 vnid = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf)); 2543 /* Delete mpls_entry */ 2544 rv = _bcm_td2_vxlan_match_vnid_entry_reset( 2545 unit, vnid, vxlan_info->vxlan_vpn_vlan[vfi]); 2546 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 2547 return rv; 2548 } 2549 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2550 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 2551 vxlan_info->vxlan_vpn_vlan[vfi] = 0; 2552 } 2553 #endif 2554 /* Delete egr_vxlate entry */ 2555 rv = _bcm_td2_vxlan_egr_xlate_entry_reset(unit, l2vpn); 2556 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 2557 return rv; 2558 } 2559 } else if (rv != BCM_E_NOT_FOUND) { 2560 return rv; 2561 } 2562 } 2563 2564 /* Delete all VXLAN ports on this VPN */ 2565 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_port_delete_all(unit, l2vpn)); 2566 2567 /* Check counters before delete vpn */ 2568 if (bcm_esw_vxlan_stat_id_get(unit, BCM_GPORT_INVALID, l2vpn, 2569 bcmVxlanOutPackets, &stat_counter_id) == BCM_E_NONE) { 2570 num_ctr++; 2571 } 2572 if (bcm_esw_vxlan_stat_id_get(unit, BCM_GPORT_INVALID, l2vpn, 2573 bcmVxlanInPackets, &stat_counter_id) == BCM_E_NONE) { 2574 num_ctr++; 2575 } 2576 2577 if (num_ctr != 0) { 2578 BCM_IF_ERROR_RETURN( 2579 bcm_esw_vxlan_stat_detach(unit, BCM_GPORT_INVALID, l2vpn)); 2580 } 2581 2582 /* Delete protocol packet control */ 2583 sal_memset(&vfi_entry, 0, sizeof(vfi_entry_t)); 2584 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry)); 2585 index = soc_VFIm_field32_get(unit, &vfi_entry, PROTOCOL_PKT_INDEXf); 2586 BCM_IF_ERROR_RETURN( 2587 _bcm_prot_pkt_ctrl_ref_count_get(unit, index, &ref_count)); 2588 if ((ref_count > 0) && index) { 2589 BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_delete(unit, index)); 2590 } 2591 2592 /* Reset VFI table */ 2593 (void)_bcm_vfi_free(unit, _bcmVfiTypeVxlan, vfi); 2594 vxlan_info->vxlan_vpn_info[vfi].vxlan_vpn_type = 0; 2595 return BCM_E_NONE; 2596 } 2597 2598 /* Function: 2599 * bcm_td2_vxlan_vpn_id_destroy_all 2600 * Purpose: 2601 * Delete all L2-VPN instances 2602 * Parameters: 2603 * unit - Device Number 2604 * Returns: 2605 * BCM_E_XXXX 2606 */ 2607 2608 int 2609 bcm_td2_vxlan_vpn_destroy_all(int unit) 2610 { 2611 int num_vfi = 0, idx = 0; 2612 bcm_vpn_t l2vpn = 0; 2613 2614 /* Destroy all VXLAN VPNs */ 2615 num_vfi = soc_mem_index_count(unit, VFIm); 2616 for (idx = 0; idx < num_vfi; idx++) { 2617 if (_bcm_vfi_used_get(unit, idx, _bcmVfiTypeVxlan)) { 2618 _BCM_VXLAN_VPN_SET(l2vpn, _BCM_VPN_TYPE_VFI, idx); 2619 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_vpn_destroy(unit, l2vpn)); 2620 } 2621 } 2622 return BCM_E_NONE; 2623 } 2624 2625 /* Function: 2626 * bcm_td2_vxlan_vpn_get 2627 * Purpose: 2628 * Get L2-VPN instance 2629 * Parameters: 2630 * unit - Device Number 2631 * l2vpn - VXLAN VPN 2632 * info - VXLAN VPN Config 2633 * Returns: 2634 * BCM_E_XXXX 2635 */ 2636 2637 int 2638 bcm_td2_vxlan_vpn_get( int unit, bcm_vpn_t l2vpn, bcm_vxlan_vpn_config_t *info) 2639 { 2640 int vfi_index = -1; 2641 vfi_entry_t vfi_entry; 2642 uint8 isEline=0; 2643 int rv = BCM_E_NONE; 2644 int proto_pkt_inx; 2645 soc_mem_t vxlate_mem; 2646 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 2647 int d = 0; /*vxlan decoupled mode*/ 2648 2649 #if defined(BCM_TRIDENT3_SUPPORT) 2650 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2651 d = 1; 2652 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 2653 } else 2654 #endif 2655 { 2656 vxlate_mem = EGR_VLAN_XLATEm; 2657 } 2658 2659 /*Get vfi table*/ 2660 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_eline(unit, l2vpn, &isEline)); 2661 if (isEline == 0x1 ) { 2662 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VXLAN_VPN_TYPE_ELINE, l2vpn); 2663 } else if (isEline == 0x0 ) { 2664 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VXLAN_VPN_TYPE_ELAN, l2vpn); 2665 } 2666 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2667 2668 /* Get info associated with vfi table */ 2669 if (isEline) { 2670 info->flags = BCM_VXLAN_VPN_ELINE; 2671 } else { 2672 info->flags = BCM_VXLAN_VPN_ELAN; 2673 2674 #if defined(BCM_TRIDENT3_SUPPORT) 2675 if (soc_feature(unit, soc_feature_generic_dest)) { 2676 uint32 dt, dv; 2677 2678 dv = soc_mem_field32_dest_get(unit, VFIm, 2679 &vfi_entry, BC_DESTINATIONf, &dt); 2680 if (dt == SOC_MEM_FIF_DEST_IPMC) { 2681 _BCM_MULTICAST_GROUP_SET(info->broadcast_group, 2682 _BCM_MULTICAST_TYPE_VXLAN, dv); 2683 } else { 2684 return BCM_E_INTERNAL; 2685 } 2686 2687 dv = soc_mem_field32_dest_get(unit, VFIm, 2688 &vfi_entry, UUC_DESTINATIONf, &dt); 2689 if (dt == SOC_MEM_FIF_DEST_IPMC) { 2690 _BCM_MULTICAST_GROUP_SET(info->unknown_unicast_group, 2691 _BCM_MULTICAST_TYPE_VXLAN, dv); 2692 } else { 2693 return BCM_E_INTERNAL; 2694 } 2695 2696 dv = soc_mem_field32_dest_get(unit, VFIm, 2697 &vfi_entry, UMC_DESTINATIONf, &dt); 2698 if (dt == SOC_MEM_FIF_DEST_IPMC) { 2699 _BCM_MULTICAST_GROUP_SET(info->unknown_multicast_group, 2700 _BCM_MULTICAST_TYPE_VXLAN, dv); 2701 } else { 2702 return BCM_E_INTERNAL; 2703 } 2704 } else 2705 #endif 2706 { 2707 _BCM_MULTICAST_GROUP_SET(info->broadcast_group, 2708 _BCM_MULTICAST_TYPE_VXLAN, 2709 soc_VFIm_field32_get(unit, &vfi_entry, BC_INDEXf)); 2710 _BCM_MULTICAST_GROUP_SET(info->unknown_unicast_group, 2711 _BCM_MULTICAST_TYPE_VXLAN, 2712 soc_VFIm_field32_get(unit, &vfi_entry, UUC_INDEXf)); 2713 _BCM_MULTICAST_GROUP_SET(info->unknown_multicast_group, 2714 _BCM_MULTICAST_TYPE_VXLAN, 2715 soc_VFIm_field32_get(unit, &vfi_entry, UMC_INDEXf)); 2716 } 2717 } 2718 _BCM_VXLAN_VPN_SET(info->vpn, _BCM_VPN_TYPE_VFI, vfi_index); 2719 /*Get protocol packet control*/ 2720 proto_pkt_inx = soc_VFIm_field32_get(unit, &vfi_entry, PROTOCOL_PKT_INDEXf); 2721 BCM_IF_ERROR_RETURN(_bcm_xgs3_protocol_pkt_ctrl_get(unit,proto_pkt_inx, &info->protocol_pkt)); 2722 2723 /* Get VNID */ 2724 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi_index, -1, vxlate_entry); 2725 if (rv == BCM_E_NONE) { 2726 info->flags |= BCM_VXLAN_VPN_WITH_VPNID; 2727 info->vnid = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry,(d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf)); 2728 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2729 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 2730 info->vlan = VXLAN_INFO(unit)->vxlan_vpn_vlan[vfi_index]; 2731 } 2732 #endif 2733 #if defined(BCM_TRIDENT3_SUPPORT) 2734 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2735 info->default_vlan = VXLAN_INFO(unit)->vxlan_vpn_vlan[vfi_index]; 2736 } 2737 #endif 2738 /* Get SDTAG settings */ 2739 (void)_bcm_td2_vxlan_sd_tag_get( unit, info, NULL, NULL, vxlate_entry, 1); 2740 } else if (rv == BCM_E_NOT_FOUND) { 2741 rv = BCM_E_NONE; 2742 } 2743 if (VXLAN_INFO(unit)->vxlan_vpn_info[vfi_index].vxlan_vpn_type) { 2744 info->flags |= BCM_VXLAN_VPN_TUNNEL_BASED_VNID; 2745 } 2746 return rv; 2747 } 2748 2749 /* Function: 2750 * _bcm_td2_vxlan_vpn_get 2751 * Purpose: 2752 * Get L2-VPN instance for VXLAN 2753 * Parameters: 2754 * unit - Device Number 2755 * vfi_index - vfi_index 2756 * vid (OUT) VLAN Id (l2vpn id) 2757 2758 * Returns: 2759 * BCM_E_XXXX 2760 */ 2761 int 2762 _bcm_td2_vxlan_vpn_get(int unit, int vfi_index, bcm_vlan_t *vid) 2763 { 2764 vfi_entry_t vfi_entry; 2765 2766 BCM_IF_ERROR_RETURN 2767 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 2768 2769 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 2770 _BCM_VXLAN_VPN_SET(*vid, _BCM_VXLAN_VPN_TYPE_ELINE, vfi_index); 2771 } else { 2772 _BCM_VXLAN_VPN_SET(*vid, _BCM_VXLAN_VPN_TYPE_ELAN, vfi_index); 2773 } 2774 return BCM_E_NONE; 2775 } 2776 2777 /* 2778 * Function: 2779 * bcm_td2_vxlan_vpn_traverse 2780 * Purpose: 2781 * Get information about a VPN instance 2782 * Parameters: 2783 * unit - (IN) Device Number 2784 * cb - (IN) User-provided callback 2785 * info - (IN/OUT) Cookie 2786 * Returns: 2787 * BCM_E_XXX 2788 */ 2789 2790 int bcm_td2_vxlan_vpn_traverse(int unit, bcm_vxlan_vpn_traverse_cb cb, 2791 void *user_data) 2792 { 2793 int idx, num_vfi; 2794 int vpn; 2795 bcm_vxlan_vpn_config_t info; 2796 2797 if (cb == NULL) { 2798 return BCM_E_PARAM; 2799 } 2800 2801 /* VXLAN VPNs */ 2802 num_vfi = soc_mem_index_count(unit, VFIm); 2803 for (idx = 0; idx < num_vfi; idx++) { 2804 if (_bcm_vfi_used_get(unit, idx, _bcmVfiTypeVxlan)) { 2805 _BCM_VXLAN_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, idx); 2806 bcm_vxlan_vpn_config_t_init(&info); 2807 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_vpn_get(unit, vpn, &info)); 2808 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2809 } 2810 } 2811 return BCM_E_NONE; 2812 } 2813 2814 2815 /* 2816 * Function: 2817 * bcm_td2_vxlan_port_traverse 2818 * Purpose: 2819 * Get information about a port instance 2820 * Parameters: 2821 * unit - (IN) Device Number 2822 * cb - (IN) User-provided callback 2823 * info - (IN/OUT) Cookie 2824 * Returns: 2825 * BCM_E_XXX 2826 */ 2827 2828 int bcm_td2_vxlan_port_traverse(int unit, bcm_vxlan_port_traverse_cb cb, 2829 void *user_data) 2830 { 2831 int idx = 0; 2832 int vp = 0; 2833 bcm_vxlan_port_t info; 2834 int split_horizon_port_flag = 0; 2835 _bcm_vp_info_t vp_info; 2836 int default_vp = -1; 2837 uint32 reg_val = 0; 2838 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 2839 vxlan_info = VXLAN_INFO(unit); 2840 2841 if (cb == NULL) { 2842 return BCM_E_PARAM; 2843 } 2844 2845 #if defined(BCM_TRIDENT3_SUPPORT) 2846 if (SOC_IS_TRIDENT3X(unit)) { 2847 } else 2848 #endif 2849 { 2850 BCM_IF_ERROR_RETURN(READ_VXLAN_DEFAULT_NETWORK_SVPr(unit, ®_val)); 2851 default_vp = soc_reg_field_get(unit, 2852 VXLAN_DEFAULT_NETWORK_SVPr, reg_val, SVPf); 2853 } 2854 2855 /* VXLAN VPNs */ 2856 vp = soc_mem_index_count(unit, SOURCE_VPm); 2857 for (idx = 0; idx < vp; idx++) { 2858 if (_bcm_vp_used_get(unit, idx, _bcmVpTypeVxlan)) { 2859 bcm_vxlan_port_t_init(&info); 2860 2861 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, idx, &vp_info)); 2862 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 2863 split_horizon_port_flag = TRUE; 2864 } 2865 2866 /*only for Access VP */ 2867 if ((_bcm_vp_used_get(unit, idx, _bcmVpTypeNiv) || 2868 _bcm_vp_used_get(unit, idx, _bcmVpTypeExtender)) && 2869 (!split_horizon_port_flag)) { 2870 BCM_GPORT_VXLAN_PORT_ID_SET(info.vxlan_port_id, idx); 2871 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2872 } else if (_bcm_vp_used_get(unit, idx, _bcmVpTypeVpLag)) { 2873 bcm_trunk_t tid = 0; 2874 bcm_trunk_member_t trunk_member; 2875 int port_count = 0; 2876 BCM_IF_ERROR_RETURN( 2877 _bcm_esw_trunk_vp_lag_vp_to_tid(unit, idx, &tid)); 2878 BCM_IF_ERROR_RETURN( 2879 bcm_td2_vp_lag_get(unit, tid, NULL, 1, 2880 &trunk_member, &port_count)); 2881 if (BCM_GPORT_IS_NIV_PORT(trunk_member.gport) || 2882 BCM_GPORT_IS_EXTENDER_PORT(trunk_member.gport)) { 2883 BCM_GPORT_TRUNK_SET(info.vxlan_port_id, tid); 2884 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2885 } else { 2886 int vfi; 2887 uint32 tunnel_sip; 2888 uint32 tunnel_index; 2889 int tunnel_based_vpn_get = 0; 2890 tunnel_index = vxlan_info->match_key[idx].match_tunnel_index; 2891 tunnel_sip = vxlan_info->vxlan_tunnel_term[tunnel_index].sip; 2892 vfi = vxlan_info->match_key[idx].vfi; 2893 if (vxlan_info->vxlan_vpn_info[vfi].vxlan_vpn_type == 2894 _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID && 2895 tunnel_sip == vxlan_info->vxlan_vpn_info[vfi].sip) { 2896 int l2vpn; 2897 _BCM_VXLAN_VPN_SET(l2vpn, _BCM_VPN_TYPE_VFI, vfi); 2898 BCM_IF_ERROR_RETURN( 2899 _bcm_td2_vxlan_port_get(unit, l2vpn, idx, &info)); 2900 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2901 tunnel_based_vpn_get = 1; 2902 } 2903 if (!tunnel_based_vpn_get) { 2904 BCM_IF_ERROR_RETURN( 2905 _bcm_td2_vxlan_port_get(unit, BCM_VXLAN_VPN_INVALID, idx, &info)); 2906 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2907 } 2908 } 2909 } else { 2910 2911 if (idx == default_vp) { 2912 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_default_port_get(unit, 2913 idx, &info)); 2914 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2915 } else { 2916 int vfi; 2917 uint32 tunnel_sip; 2918 uint32 tunnel_index; 2919 int tunnel_based_vpn_get = 0; 2920 tunnel_index = vxlan_info->match_key[idx].match_tunnel_index; 2921 tunnel_sip = vxlan_info->vxlan_tunnel_term[tunnel_index].sip; 2922 vfi = vxlan_info->match_key[idx].vfi; 2923 if (vxlan_info->vxlan_vpn_info[vfi].vxlan_vpn_type == 2924 _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID && 2925 tunnel_sip == vxlan_info->vxlan_vpn_info[vfi].sip) { 2926 int l2vpn; 2927 _BCM_VXLAN_VPN_SET(l2vpn, _BCM_VPN_TYPE_VFI, vfi); 2928 BCM_IF_ERROR_RETURN( 2929 _bcm_td2_vxlan_port_get(unit, l2vpn, idx, &info)); 2930 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2931 tunnel_based_vpn_get = 1; 2932 } 2933 if (!tunnel_based_vpn_get) { 2934 BCM_IF_ERROR_RETURN( 2935 _bcm_td2_vxlan_port_get(unit, BCM_VXLAN_VPN_INVALID, idx, &info)); 2936 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 2937 } 2938 } 2939 } 2940 2941 } 2942 } 2943 return BCM_E_NONE; 2944 } 2945 2946 2947 /* 2948 * Function: 2949 * _bcm_td2_vxlan_tunnel_terminate_entry_key_set 2950 * Purpose: 2951 * Set VXLAN Tunnel Terminate entry key set 2952 * Parameters: 2953 * IN : Unit 2954 * IN : tnl_info 2955 * IN(OUT) : tr_ent VLAN_XLATE entry pointer 2956 * IN : clean_flag 2957 * Returns: BCM_E_XXX 2958 */ 2959 2960 STATIC void 2961 _bcm_td2_vxlan_tunnel_terminate_entry_key_set(int unit, 2962 bcm_tunnel_terminator_t *tnl_info, uint32 *tr_ent, uint8 out_mode, int clean_flag) 2963 { 2964 soc_mem_t mem; 2965 int d = 0; /*vxlan decoupled mode*/ 2966 if (clean_flag) { 2967 sal_memset(tr_ent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 2968 } 2969 2970 #if defined(BCM_TRIDENT3_SUPPORT) 2971 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 2972 mem = MPLS_ENTRY_SINGLEm; 2973 d =1; 2974 soc_mem_field32_set(unit, mem, tr_ent, BASE_VALIDf, 1); 2975 soc_mem_field32_set(unit, mem, tr_ent, DATA_TYPEf, 2976 _BCM_VXLAN_DATA_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY); 2977 soc_mem_field32_set(unit, mem, tr_ent, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY); 2978 soc_mem_field32_set(unit, mem, tr_ent, VXLAN_FLEX_IPV4_DIP__TERM_TUNNELf, 1); 2979 } else 2980 #endif 2981 { 2982 mem = VLAN_XLATEm; 2983 soc_mem_field32_set(unit, mem, tr_ent, VALIDf, 0x1); 2984 soc_mem_field32_set(unit, mem, tr_ent, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 2985 } 2986 soc_mem_field32_set(unit, mem, tr_ent, BCM_VXLAN_DIP_FIELD(d, DIPf), tnl_info->dip); 2987 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2988 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 2989 soc_mem_field32_set(unit, mem, tr_ent, VXLAN_DIP__OVIDf, tnl_info->vlan); 2990 } 2991 #endif 2992 if (out_mode == _BCM_VXLAN_MULTICAST_BUD) { 2993 soc_mem_field32_set(unit, mem, tr_ent, 2994 BCM_VXLAN_DIP_FIELD(d,NETWORK_RECEIVERS_PRESENTf), 0x1); 2995 _bcm_td2_vxlan_bud_loopback_enable(unit); 2996 } else if (out_mode == _BCM_VXLAN_MULTICAST_LEAF) { 2997 soc_mem_field32_set(unit, mem, tr_ent, 2998 BCM_VXLAN_DIP_FIELD(d,NETWORK_RECEIVERS_PRESENTf), 0x0); 2999 } 3000 3001 soc_mem_field32_set(unit, mem, tr_ent, BCM_VXLAN_DIP_FIELD(d,IGNORE_UDP_CHECKSUMf), 3002 (tnl_info->flags & BCM_TUNNEL_TERM_UDP_CHECKSUM_ENABLE) ? 0x0 : 0x1); 3003 3004 if (tnl_info->flags & BCM_TUNNEL_TERM_USE_OUTER_DSCP) { 3005 soc_mem_field32_set(unit, mem, tr_ent, 3006 BCM_VXLAN_DIP_FIELD(d,USE_OUTER_HEADER_PHBf), 0x1); 3007 } else if (tnl_info->flags & BCM_TUNNEL_TERM_USE_OUTER_PCP) { 3008 soc_mem_field32_set(unit, mem, tr_ent, 3009 BCM_VXLAN_DIP_FIELD(d,USE_OUTER_HEADER_PHBf), 0x2); 3010 } 3011 } 3012 3013 /* 3014 * Function: 3015 * _bcm_td2_vxlan_tunnel_terminator_reference_count 3016 * Purpose: 3017 * Find VXLAN Tunnel terminator DIP reference count 3018 * Returns: BCM_E_XXX 3019 */ 3020 3021 STATIC int 3022 _bcm_td2_vxlan_tunnel_terminator_reference_count(int unit, 3023 bcm_ip_t dest_ip_addr, 3024 int threshold_count) 3025 { 3026 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3027 int tunnel_idx=0, num_vp=0, ref_count=0; 3028 3029 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 3030 vxlan_info = VXLAN_INFO(unit); 3031 3032 for (tunnel_idx=0; tunnel_idx< num_vp; tunnel_idx++) { 3033 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].dip == dest_ip_addr) { 3034 ref_count ++; 3035 if (ref_count == threshold_count) { 3036 break; 3037 } 3038 } 3039 } 3040 return ref_count; 3041 } 3042 3043 /* 3044 * Function: 3045 * _bcm_td2_vxlan_multicast_tunnel_state_set 3046 * Purpose: 3047 * Set VXLAN Tunnel terminator Multicast State 3048 * Returns: BCM_E_XXX 3049 */ 3050 3051 3052 STATIC void 3053 _bcm_td2_vxlan_multicast_tunnel_state_set (int unit, int tunnel_idx, uint16 tunnel_state) 3054 { 3055 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3056 3057 vxlan_info = VXLAN_INFO(unit); 3058 3059 if (tunnel_idx != -1) { 3060 vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state = tunnel_state; 3061 } 3062 } 3063 3064 /* 3065 * Function: 3066 * _bcm_td2_vxlan_tunnel_terminator_state_find 3067 * Purpose: 3068 * Find VXLAN Tunnel terminator DIP State 3069 * Returns: BCM_E_XXX 3070 */ 3071 3072 STATIC int 3073 _bcm_td2_vxlan_tunnel_terminator_state_find(int unit, bcm_ip_t dest_ip_addr) 3074 { 3075 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3076 int tunnel_idx=0, num_vp=0, tunnel_state=0; 3077 3078 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 3079 vxlan_info = VXLAN_INFO(unit); 3080 3081 for (tunnel_idx=0; tunnel_idx< num_vp; tunnel_idx++) { 3082 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].dip == dest_ip_addr) { 3083 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state == _BCM_VXLAN_TUNNEL_TERM_MULTICAST_LEAF ) { 3084 tunnel_state += 0; 3085 } else if (vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state == _BCM_VXLAN_TUNNEL_TERM_MULTICAST_BUD ) { 3086 tunnel_state += 1; 3087 break; 3088 } 3089 } 3090 } 3091 return tunnel_state; 3092 } 3093 3094 /* 3095 * Function: 3096 * bcm_td2_vxlan_multicast_leaf_entry_check 3097 * Purpose: 3098 * To find whether LEAF-multicast entry exists for DIP? 3099 * Returns: 3100 * BCM_E_XXX 3101 */ 3102 3103 int 3104 bcm_td2_vxlan_multicast_leaf_entry_check(int unit, 3105 int tunnel_idx, 3106 int multicast_flag) 3107 { 3108 soc_mem_t mem; 3109 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 3110 int rv=BCM_E_NONE, index=0; 3111 uint16 tunnel_multicast_state = 0; 3112 int tunnel_mc_states = 0; 3113 bcm_ip_t mc_ip_addr; 3114 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3115 uint8 net_receiver = 0; 3116 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3117 bcm_vlan_t vlan = 0; 3118 #endif 3119 int d = 0; /*vxlan decoupled mode*/ 3120 3121 vxlan_info = VXLAN_INFO(unit); 3122 tunnel_multicast_state = 3123 vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state; 3124 mc_ip_addr = vxlan_info->vxlan_tunnel_term[tunnel_idx].dip; 3125 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3126 vlan = vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan; 3127 #endif 3128 3129 /* Set (SIP, DIP) based Software State */ 3130 if (multicast_flag == BCM_VXLAN_MULTICAST_TUNNEL_STATE_BUD_ENABLE) { 3131 if (tunnel_multicast_state == _BCM_VXLAN_TUNNEL_TERM_MULTICAST_LEAF) { 3132 (void) _bcm_td2_vxlan_multicast_tunnel_state_set(unit, 3133 tunnel_idx, _BCM_VXLAN_TUNNEL_TERM_MULTICAST_BUD); 3134 } 3135 tunnel_mc_states = 1; 3136 } else if (multicast_flag == BCM_VXLAN_MULTICAST_TUNNEL_STATE_BUD_DISABLE){ 3137 if (tunnel_multicast_state == _BCM_VXLAN_TUNNEL_TERM_MULTICAST_BUD) { 3138 (void) _bcm_td2_vxlan_multicast_tunnel_state_set(unit, 3139 tunnel_idx, _BCM_VXLAN_TUNNEL_TERM_MULTICAST_LEAF); 3140 } 3141 } 3142 3143 /* Set DIP-based cumulative hardware State */ 3144 if (!tunnel_mc_states) { 3145 tunnel_mc_states = 3146 _bcm_td2_vxlan_tunnel_terminator_state_find(unit, mc_ip_addr); 3147 } 3148 3149 sal_memset(vxlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 3150 #if defined(BCM_TRIDENT3_SUPPORT) 3151 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 3152 bcm_tunnel_terminator_t tnl_info; 3153 3154 d =1; 3155 mem = MPLS_ENTRY_SINGLEm; 3156 bcm_tunnel_terminator_t_init(&tnl_info); 3157 tnl_info.dip = mc_ip_addr; 3158 _bcm_td2_vxlan_tunnel_terminate_entry_key_set(unit, &tnl_info, vxlate_entry, 0, 1); 3159 } else 3160 #endif 3161 { 3162 #if defined(BCM_TRIDENT3_SUPPORT) 3163 if (soc_feature(unit, soc_feature_base_valid)) { 3164 mem = VLAN_XLATE_1_DOUBLEm; 3165 soc_mem_field32_set(unit, mem, vxlate_entry, BASE_VALID_0f, 3); 3166 soc_mem_field32_set(unit, mem, vxlate_entry, BASE_VALID_1f, 7); 3167 soc_mem_field32_set(unit, mem, vxlate_entry, DATA_TYPEf, 3168 _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 3169 } else 3170 #endif 3171 { 3172 mem = VLAN_XLATEm; 3173 soc_mem_field32_set(unit, mem, vxlate_entry, VALIDf, 0x1); 3174 } 3175 3176 soc_mem_field32_set(unit, mem, vxlate_entry, 3177 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 3178 soc_mem_field32_set(unit, mem, vxlate_entry, VXLAN_DIP__DIPf, mc_ip_addr); 3179 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3180 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 3181 soc_mem_field32_set(unit, mem, vxlate_entry, VXLAN_DIP__OVIDf, vlan); 3182 } 3183 #endif 3184 } 3185 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 3186 vxlate_entry, vxlate_entry, 0); 3187 3188 if (rv == SOC_E_NONE) { 3189 net_receiver = tunnel_mc_states ? 0x1 : 0x0; 3190 3191 if (net_receiver != soc_mem_field32_get(unit, mem, 3192 vxlate_entry, BCM_VXLAN_DIP_FIELD(d,NETWORK_RECEIVERS_PRESENTf))) { 3193 soc_mem_field32_set(unit, mem, vxlate_entry, 3194 BCM_VXLAN_DIP_FIELD(d,NETWORK_RECEIVERS_PRESENTf), net_receiver); 3195 if (net_receiver) { 3196 _bcm_td2_vxlan_bud_loopback_enable(unit); 3197 } 3198 BCM_IF_ERROR_RETURN( 3199 soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, vxlate_entry)); 3200 } 3201 } 3202 3203 return BCM_E_NONE; 3204 } 3205 3206 /* 3207 * Function: 3208 * bcm_td2_vxlan_tunnel_terminator_create 3209 * Purpose: 3210 * Set VXLAN Tunnel terminator 3211 * Parameters: 3212 * unit - Device Number 3213 * tnl_info 3214 * Returns: 3215 * BCM_E_XXX 3216 */ 3217 int 3218 bcm_td2_vxlan_tunnel_terminator_create(int unit, bcm_tunnel_terminator_t *tnl_info) 3219 { 3220 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3221 int index=-1, tunnel_idx=-1; 3222 soc_mem_t mem; 3223 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 3224 int rv = BCM_E_NONE; 3225 3226 if (tnl_info->type != bcmTunnelTypeVxlan) { 3227 return BCM_E_PARAM; 3228 } 3229 3230 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3231 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 3232 VLAN_CHK_ID(unit, tnl_info->vlan); 3233 } 3234 #endif 3235 3236 /* Program tunnel id */ 3237 if (tnl_info->flags & BCM_TUNNEL_TERM_TUNNEL_WITH_ID) { 3238 if (!BCM_GPORT_IS_TUNNEL(tnl_info->tunnel_id)) { 3239 return BCM_E_PARAM; 3240 } 3241 if ((0 == tnl_info->dip) || (0 == tnl_info->sip)) { 3242 return BCM_E_PARAM; 3243 } 3244 tunnel_idx = BCM_GPORT_TUNNEL_ID_GET(tnl_info->tunnel_id); 3245 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_idx); 3246 } else { 3247 /* Only BCM_TUNNEL_TERM_TUNNEL_WITH_ID supported */ 3248 /* Use tunnel_id retuned by _create */ 3249 return BCM_E_PARAM; 3250 } 3251 3252 vxlan_info = VXLAN_INFO(unit); 3253 3254 if ((0 != vxlan_info->vxlan_tunnel_term[tunnel_idx].dip) && 3255 (vxlan_info->vxlan_tunnel_term[tunnel_idx].dip != tnl_info->dip)) { 3256 /* Entry exists with the same idx*/ 3257 return BCM_E_EXISTS; 3258 } 3259 3260 #if defined(BCM_TRIDENT3_SUPPORT) 3261 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 3262 mem = MPLS_ENTRY_SINGLEm; 3263 } else 3264 #endif 3265 { 3266 mem = VLAN_XLATEm; 3267 } 3268 3269 /* Search Tunnel term-entry for given DIP to Hardware */ 3270 (void)_bcm_td2_vxlan_tunnel_terminate_entry_key_set(unit, tnl_info, vxlate_entry, 0, 1); 3271 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vxlate_entry, vxlate_entry, 0); 3272 if (rv == SOC_E_NOT_FOUND) { 3273 /* Insert Tunnel term-entry */ 3274 (void)_bcm_td2_vxlan_tunnel_terminate_entry_key_set(unit, tnl_info, vxlate_entry, 0, 0); 3275 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vxlate_entry); 3276 } else if (rv != SOC_E_NONE) { 3277 return rv; 3278 } 3279 3280 sal_memset(&(vxlan_info->vxlan_tunnel_term[tunnel_idx]), 0, sizeof(_bcm_vxlan_tunnel_endpoint_t)); 3281 if (BCM_SUCCESS(rv) && (tunnel_idx != -1)) { 3282 vxlan_info->vxlan_tunnel_term[tunnel_idx].sip = tnl_info->sip; 3283 vxlan_info->vxlan_tunnel_term[tunnel_idx].dip = tnl_info->dip; 3284 vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan = tnl_info->vlan; 3285 vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state = _BCM_VXLAN_TUNNEL_TERM_MULTICAST_LEAF; 3286 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag |= _BCM_VXLAN_TUNNEL_TERM_ENABLE; 3287 if (tnl_info->flags & BCM_TUNNEL_TERM_UDP_CHECKSUM_ENABLE) { 3288 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag |= 3289 _BCM_VXLAN_TUNNEL_TERM_UDP_CHECKSUM_ENABLE; 3290 } 3291 if (tnl_info->flags & BCM_TUNNEL_TERM_USE_OUTER_DSCP) { 3292 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag |= 3293 _BCM_VXLAN_TUNNEL_TERM_USE_OUTER_DSCP; 3294 } else if (tnl_info->flags & BCM_TUNNEL_TERM_USE_OUTER_PCP) { 3295 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag |= 3296 _BCM_VXLAN_TUNNEL_TERM_USE_OUTER_PCP; 3297 } 3298 } 3299 return rv; 3300 } 3301 3302 /* 3303 * Function: 3304 * bcm_td2_vxlan_tunnel_terminator_update 3305 * Purpose: 3306 * Update VXLAN Tunnel terminator multicast state 3307 * Parameters: 3308 * unit - Device Number 3309 * tnl_info 3310 * Returns: 3311 * BCM_E_XXX 3312 */ 3313 int 3314 bcm_td2_vxlan_tunnel_terminator_update(int unit, bcm_tunnel_terminator_t *tnl_info) 3315 { 3316 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3317 int rv = BCM_E_NONE; 3318 int tunnel_idx=-1, index=-1; 3319 uint32 tunnel_dip=0; 3320 soc_mem_t mem; 3321 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 3322 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3323 bcm_vlan_t vlan = 0; 3324 #endif 3325 int d = 0; /*vxlan decoupled mode*/ 3326 3327 vxlan_info = VXLAN_INFO(unit); 3328 3329 /* Program tunnel id */ 3330 if (tnl_info->flags & BCM_TUNNEL_TERM_TUNNEL_WITH_ID) { 3331 if (!BCM_GPORT_IS_TUNNEL(tnl_info->tunnel_id)) { 3332 return BCM_E_PARAM; 3333 } 3334 tunnel_idx = BCM_GPORT_TUNNEL_ID_GET(tnl_info->tunnel_id); 3335 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_idx); 3336 } else { 3337 /* Only BCM_TUNNEL_TERM_TUNNEL_WITH_ID supported */ 3338 /* Use tunnel_id retuned by _create */ 3339 return BCM_E_PARAM; 3340 } 3341 3342 3343 tunnel_dip = vxlan_info->vxlan_tunnel_term[tunnel_idx].dip; 3344 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3345 vlan = vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan; 3346 #endif 3347 3348 sal_memset(vxlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 3349 #if defined(BCM_TRIDENT3_SUPPORT) 3350 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 3351 bcm_tunnel_terminator_t tnl_info_1; 3352 3353 d = 1; 3354 mem = MPLS_ENTRY_SINGLEm; 3355 bcm_tunnel_terminator_t_init(&tnl_info_1); 3356 tnl_info_1.dip = tunnel_dip; 3357 _bcm_td2_vxlan_tunnel_terminate_entry_key_set(unit, &tnl_info_1, vxlate_entry, 0, 1); 3358 } else 3359 #endif 3360 { 3361 #if defined(BCM_TRIDENT3_SUPPORT) 3362 if (soc_feature(unit, soc_feature_base_valid)) { 3363 mem = VLAN_XLATE_1_DOUBLEm; 3364 3365 soc_mem_field32_set(unit, mem, vxlate_entry, BASE_VALID_0f, 3); 3366 soc_mem_field32_set(unit, mem, vxlate_entry, BASE_VALID_1f, 7); 3367 soc_mem_field32_set(unit, mem, vxlate_entry, DATA_TYPEf, 3368 _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 3369 } else 3370 #endif 3371 { 3372 mem = VLAN_XLATEm; 3373 soc_mem_field32_set(unit, mem, vxlate_entry, VALIDf, 0x1); 3374 } 3375 3376 soc_mem_field32_set(unit, mem, vxlate_entry, 3377 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 3378 soc_mem_field32_set(unit, mem, vxlate_entry, VXLAN_DIP__DIPf, tunnel_dip); 3379 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3380 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 3381 soc_mem_field32_set(unit, mem, vxlate_entry, VXLAN_DIP__OVIDf, vlan); 3382 } 3383 #endif 3384 } 3385 if (tnl_info->flags & BCM_TUNNEL_TERM_TUNNEL_DEACTIVATE) { 3386 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 3387 vxlate_entry, vxlate_entry, 0); 3388 if (rv == BCM_E_NONE) { 3389 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ALL, vxlate_entry); 3390 if (BCM_FAILURE(rv)) { 3391 return rv; 3392 } 3393 } else if (rv != BCM_E_NOT_FOUND) { 3394 return rv; 3395 } 3396 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag &= (~_BCM_VXLAN_TUNNEL_TERM_ENABLE); 3397 return BCM_E_NONE; 3398 } else if (!(vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & _BCM_VXLAN_TUNNEL_TERM_ENABLE)) { 3399 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].dip != 0) { 3400 soc_mem_field32_set(unit, mem, vxlate_entry, BCM_VXLAN_DIP_FIELD(d,IGNORE_UDP_CHECKSUMf), 3401 (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag 3402 & _BCM_VXLAN_TUNNEL_TERM_UDP_CHECKSUM_ENABLE) ? 0x0 : 0x1); 3403 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & 3404 _BCM_VXLAN_TUNNEL_TERM_USE_OUTER_DSCP) { 3405 soc_mem_field32_set(unit, mem, vxlate_entry, BCM_VXLAN_DIP_FIELD(d,USE_OUTER_HEADER_PHBf), 0x1); 3406 } else if (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & 3407 _BCM_VXLAN_TUNNEL_TERM_USE_OUTER_PCP) { 3408 soc_mem_field32_set(unit, mem, vxlate_entry, BCM_VXLAN_DIP_FIELD(d,USE_OUTER_HEADER_PHBf), 0x2); 3409 } 3410 3411 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vxlate_entry, vxlate_entry, 0); 3412 if (rv == BCM_E_NOT_FOUND) { 3413 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vxlate_entry); 3414 if (BCM_FAILURE(rv)) { 3415 return rv; 3416 } 3417 } else if (rv != BCM_E_NONE) { 3418 return rv; 3419 } 3420 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag |= _BCM_VXLAN_TUNNEL_TERM_ENABLE; 3421 } 3422 } 3423 3424 rv = bcm_td2_vxlan_multicast_leaf_entry_check(unit, tunnel_idx, 3425 tnl_info->multicast_flag); 3426 return rv; 3427 } 3428 3429 /* 3430 * Function: 3431 * bcm_td2_vxlan_tunnel_terminate_destroy 3432 * Purpose: 3433 * Destroy VXLAN tunnel_terminate Entry 3434 * Parameters: 3435 * IN : Unit 3436 * IN : vxlan_tunnel_id 3437 * Returns: 3438 * BCM_E_XXX 3439 */ 3440 3441 int 3442 bcm_td2_vxlan_tunnel_terminator_destroy(int unit, bcm_gport_t vxlan_tunnel_id) 3443 { 3444 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3445 int tunnel_idx=-1, index=-1; 3446 soc_mem_t mem; 3447 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 3448 uint32 tunnel_dip=0; 3449 int rv = BCM_E_NONE; 3450 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3451 bcm_vlan_t vlan = 0; 3452 #endif 3453 int d = 0; /*vxlan decoupled mode*/ 3454 3455 if (!BCM_GPORT_IS_TUNNEL(vxlan_tunnel_id)) { 3456 return BCM_E_PARAM; 3457 } 3458 tunnel_idx = BCM_GPORT_TUNNEL_ID_GET(vxlan_tunnel_id); 3459 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_idx); 3460 3461 vxlan_info = VXLAN_INFO(unit); 3462 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3463 vlan = vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan; 3464 #endif 3465 tunnel_dip = vxlan_info->vxlan_tunnel_term[tunnel_idx].dip; 3466 if (tunnel_dip == 0) { 3467 return BCM_E_NOT_FOUND; 3468 } 3469 3470 if (!(_BCM_VXLAN_TUNNEL_TERM_ENABLE & 3471 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag)) { 3472 /* Deactivated tunnel terminator can not be destroyed */ 3473 return BCM_E_DISABLED; 3474 } 3475 3476 sal_memset(vxlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 3477 /* Remove Tunnel term-entry for given DIP from Hardware based on ref-count */ 3478 if (_bcm_td2_vxlan_tunnel_terminator_reference_count(unit, tunnel_dip, 2) == 1) { 3479 #if defined(BCM_TRIDENT3_SUPPORT) 3480 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 3481 bcm_tunnel_terminator_t tnl_info; 3482 3483 mem = MPLS_ENTRY_SINGLEm; 3484 d = 1; 3485 bcm_tunnel_terminator_t_init(&tnl_info); 3486 _bcm_td2_vxlan_tunnel_terminate_entry_key_set(unit, &tnl_info, 3487 vxlate_entry, 0, 1); 3488 } else 3489 #endif 3490 { 3491 mem = VLAN_XLATEm; 3492 soc_mem_field32_set(unit, mem, vxlate_entry, VALIDf, 0x1); 3493 soc_mem_field32_set(unit, mem, vxlate_entry, 3494 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 3495 } 3496 soc_mem_field32_set(unit, mem, vxlate_entry, BCM_VXLAN_DIP_FIELD(d,DIPf), tunnel_dip); 3497 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3498 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 3499 soc_mem_field32_set(unit, mem, vxlate_entry, VXLAN_DIP__OVIDf, vlan); 3500 } 3501 #endif 3502 soc_mem_field32_set(unit, mem, vxlate_entry, 3503 BCM_VXLAN_DIP_FIELD(d,NETWORK_RECEIVERS_PRESENTf), 0); 3504 3505 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, 3506 &index, vxlate_entry, vxlate_entry, 0); 3507 if (BCM_FAILURE(rv)) { 3508 return rv; 3509 } 3510 /* Delete the entry from HW */ 3511 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ALL, vxlate_entry); 3512 if (BCM_FAILURE(rv)) { 3513 return rv; 3514 } 3515 } 3516 3517 /* Activate the entry , then Delete the entry */ 3518 if (BCM_SUCCESS(rv) && (tunnel_idx != -1) && 3519 (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & _BCM_VXLAN_TUNNEL_TERM_ENABLE)) { 3520 vxlan_info->vxlan_tunnel_term[tunnel_idx].dip = 0; 3521 vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan = 0; 3522 vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state = _BCM_VXLAN_TUNNEL_TERM_MULTICAST_LEAF; 3523 vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag = 0; 3524 } 3525 3526 return rv; 3527 } 3528 3529 /* 3530 * Function: 3531 * bcm_td2_vxlan_tunnel_terminator_destroy_all 3532 * Purpose: 3533 * Destroy all incoming VXLAN tunnel 3534 * Parameters: 3535 * unit - (IN) Device Number 3536 */ 3537 int 3538 bcm_td2_vxlan_tunnel_terminator_destroy_all(int unit) 3539 { 3540 soc_mem_t vxlate_mem; 3541 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 3542 int rv = BCM_E_UNAVAIL, tnl_idx=0,num_vp=0; 3543 uint32 *vtab, *vtabp; 3544 int i, imin, imax, nent; 3545 int d = 0; /*vxlan decoupled mode*/ 3546 3547 #if defined(BCM_TRIDENT3_SUPPORT) 3548 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 3549 d = 1; 3550 vxlate_mem = MPLS_ENTRY_SINGLEm; 3551 } else 3552 #endif 3553 { 3554 vxlate_mem = VLAN_XLATEm; 3555 } 3556 3557 if (!SOC_HW_RESET(unit) && (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_NONE)) { 3558 imin = soc_mem_index_min(unit, vxlate_mem); 3559 imax = soc_mem_index_max(unit, vxlate_mem); 3560 nent = soc_mem_index_count(unit, vxlate_mem); 3561 3562 vtab = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, vxlate_mem), "vlan_xlate"); 3563 if (vtab == NULL) { 3564 return BCM_E_MEMORY; 3565 } 3566 sal_memset(vtab, 0, SOC_MEM_TABLE_BYTES(unit, vxlate_mem)); 3567 3568 soc_mem_lock(unit, vxlate_mem); 3569 rv = soc_mem_read_range(unit, vxlate_mem, MEM_BLOCK_ANY, 3570 imin, imax, vtab); 3571 if (BCM_FAILURE(rv)) { 3572 soc_mem_unlock(unit, vxlate_mem); 3573 soc_cm_sfree(unit, vtab); 3574 return rv; 3575 } 3576 for (i = 0; i < nent; i++) { 3577 vtabp = soc_mem_table_idx_to_pointer(unit, vxlate_mem, 3578 void *, vtab, i); 3579 3580 #if defined(BCM_TRIDENT3_SUPPORT) 3581 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 3582 if (soc_mem_field32_get(unit, vxlate_mem, 3583 vtabp, BASE_VALIDf) != 1) { 3584 continue; 3585 } 3586 if (soc_mem_field32_get(unit, vxlate_mem, vtabp, DATA_TYPEf) 3587 != _BCM_VXLAN_DATA_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY) { 3588 continue; 3589 } 3590 } else 3591 #endif 3592 { 3593 if (!soc_mem_field32_get(unit, vxlate_mem, vtabp, VALIDf)) { 3594 continue; 3595 } 3596 } 3597 3598 if (soc_mem_field32_get(unit, vxlate_mem, vtabp, KEY_TYPEf) != 3599 (d ? _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY : _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP)) { 3600 continue; 3601 } 3602 /* Delete the entry from HW */ 3603 rv = soc_mem_delete(unit, vxlate_mem, MEM_BLOCK_ALL, vtabp); 3604 if (BCM_FAILURE(rv)) { 3605 soc_mem_unlock(unit, vxlate_mem); 3606 soc_cm_sfree(unit, vtab); 3607 return rv; 3608 } 3609 } 3610 soc_mem_unlock(unit, vxlate_mem); 3611 soc_cm_sfree(unit, vtab); 3612 } 3613 3614 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 3615 for (tnl_idx = 0; tnl_idx < num_vp; tnl_idx++) { 3616 vxlan_info->vxlan_tunnel_term[tnl_idx].dip = 0; 3617 vxlan_info->vxlan_tunnel_term[tnl_idx].vlan = 0; 3618 vxlan_info->vxlan_tunnel_term[tnl_idx].tunnel_state = 0; 3619 } 3620 3621 return BCM_E_NONE; 3622 } 3623 3624 /* 3625 * Function: 3626 * bcm_td2_vxlan_tunnel_initiator_get 3627 * Purpose: 3628 * Get VXLAN tunnel_terminate Entry 3629 * Parameters: 3630 * unit - (IN) Device Number 3631 * info - (IN/OUT) Tunnel terminator structure 3632 */ 3633 int 3634 bcm_td2_vxlan_tunnel_terminator_get(int unit, bcm_tunnel_terminator_t *tnl_info) 3635 { 3636 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3637 int tunnel_idx=-1, index=-1; 3638 soc_mem_t mem; 3639 uint32 vxlate_entry[SOC_MAX_MEM_WORDS]; 3640 uint32 tunnel_dip=0; 3641 int rv = BCM_E_UNAVAIL; 3642 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3643 bcm_vlan_t vlan = 0; 3644 #endif 3645 int d = 0; /*vxlan decoupled mode*/ 3646 3647 /* Program tunnel id */ 3648 if (!BCM_GPORT_IS_TUNNEL(tnl_info->tunnel_id)) { 3649 return BCM_E_PARAM; 3650 } 3651 tunnel_idx = BCM_GPORT_TUNNEL_ID_GET(tnl_info->tunnel_id); 3652 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_idx); 3653 3654 vxlan_info = VXLAN_INFO(unit); 3655 tunnel_dip = vxlan_info->vxlan_tunnel_term[tunnel_idx].dip; 3656 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3657 vlan = vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan; 3658 #endif 3659 3660 sal_memset(vxlate_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 3661 #if defined(BCM_TRIDENT3_SUPPORT) 3662 if (soc_feature(unit, soc_feature_base_valid)) { 3663 mem = MPLS_ENTRY_SINGLEm; 3664 d = 1; 3665 soc_mem_field32_set(unit, mem, vxlate_entry, BASE_VALIDf, 1); 3666 soc_mem_field32_set(unit, mem, vxlate_entry, DATA_TYPEf, 3667 _BCM_VXLAN_DATA_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY); 3668 soc_mem_field32_set(unit, mem, vxlate_entry, KEY_TYPEf, 3669 _BCM_VXLAN_DATA_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY); 3670 } else 3671 #endif 3672 { 3673 mem = VLAN_XLATEm; 3674 soc_mem_field32_set(unit, mem, vxlate_entry, VALIDf, 0x1); 3675 soc_mem_field32_set(unit, mem, vxlate_entry, KEY_TYPEf, 3676 _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 3677 } 3678 3679 soc_mem_field32_set(unit, mem, vxlate_entry, BCM_VXLAN_DIP_FIELD(d,DIPf), tunnel_dip); 3680 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3681 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 3682 soc_mem_field32_set(unit, mem, vxlate_entry, VXLAN_DIP__OVIDf, vlan); 3683 } 3684 #endif 3685 3686 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, 3687 &index, vxlate_entry, vxlate_entry, 0); 3688 3689 /* not exist or De-activated */ 3690 if (rv == BCM_E_NOT_FOUND) { 3691 if (!(vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & _BCM_VXLAN_TUNNEL_TERM_ENABLE) && 3692 (vxlan_info->vxlan_tunnel_term[tunnel_idx].dip != 0)) { 3693 tnl_info->flags |= BCM_TUNNEL_TERM_TUNNEL_DEACTIVATE; 3694 } else { 3695 return rv; 3696 } 3697 } else if (rv != BCM_E_NONE) { 3698 return rv; 3699 } 3700 3701 tnl_info->sip = vxlan_info->vxlan_tunnel_term[tunnel_idx].sip; 3702 tnl_info->dip = vxlan_info->vxlan_tunnel_term[tunnel_idx].dip; 3703 tnl_info->vlan = vxlan_info->vxlan_tunnel_term[tunnel_idx].vlan; 3704 tnl_info->type = bcmTunnelTypeVxlan; 3705 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state == _BCM_VXLAN_TUNNEL_TERM_MULTICAST_BUD) { 3706 tnl_info->multicast_flag = BCM_VXLAN_MULTICAST_TUNNEL_STATE_BUD_ENABLE; 3707 } else if (vxlan_info->vxlan_tunnel_term[tunnel_idx].tunnel_state == _BCM_VXLAN_TUNNEL_TERM_MULTICAST_LEAF){ 3708 tnl_info->multicast_flag = BCM_VXLAN_MULTICAST_TUNNEL_STATE_BUD_DISABLE; 3709 } else { 3710 tnl_info->multicast_flag = 0; 3711 } 3712 3713 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & _BCM_VXLAN_TUNNEL_TERM_UDP_CHECKSUM_ENABLE) { 3714 tnl_info->flags |= BCM_TUNNEL_TERM_UDP_CHECKSUM_ENABLE; 3715 } 3716 3717 if (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & 3718 _BCM_VXLAN_TUNNEL_TERM_USE_OUTER_DSCP) { 3719 tnl_info->flags |= BCM_TUNNEL_TERM_USE_OUTER_DSCP; 3720 } else if (vxlan_info->vxlan_tunnel_term[tunnel_idx].activate_flag & 3721 _BCM_VXLAN_TUNNEL_TERM_USE_OUTER_PCP) { 3722 tnl_info->flags |= BCM_TUNNEL_TERM_USE_OUTER_PCP; 3723 } 3724 3725 return BCM_E_NONE; 3726 } 3727 3728 /* 3729 * Function: 3730 * bcm_td2_vxlan_tunnel_terminator_traverse 3731 * Purpose: 3732 * Traverse VXLAN tunnel terminator entries 3733 * Parameters: 3734 * unit - (IN) Device Number 3735 * cb - (IN) User callback function, called once per entry 3736 * user_data - (IN) User supplied cookie used in parameter in callback function 3737 */ 3738 int 3739 bcm_td2_vxlan_tunnel_terminator_traverse(int unit, bcm_tunnel_terminator_traverse_cb cb, void *user_data) 3740 { 3741 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3742 int num_tnl = 0, idx = 0; 3743 bcm_tunnel_terminator_t info; 3744 int rv = BCM_E_NONE; 3745 3746 vxlan_info = VXLAN_INFO(unit); 3747 num_tnl = soc_mem_index_count(unit, SOURCE_VPm); 3748 3749 /* Iterate over all the entries - search valid ones. */ 3750 for(idx = 0; idx < num_tnl; idx++) { 3751 /* Check a valid entry */ 3752 if ((vxlan_info->vxlan_tunnel_term[idx].dip) 3753 || (vxlan_info->vxlan_tunnel_term[idx].sip)){ 3754 /* Reset buffer before read. */ 3755 bcm_tunnel_terminator_t_init(&info); 3756 3757 BCM_GPORT_TUNNEL_ID_SET(info.tunnel_id, idx); 3758 3759 rv = bcm_td2_vxlan_tunnel_terminator_get(unit,&info); 3760 3761 /* search failure */ 3762 if (BCM_FAILURE(rv)) { 3763 if (rv != BCM_E_NOT_FOUND) { 3764 break; 3765 } 3766 continue; 3767 } 3768 3769 if (cb) { 3770 rv = (*cb) (unit, &info, user_data); 3771 #ifdef BCM_CB_ABORT_ON_ERR 3772 if (BCM_FAILURE(rv) && SOC_CB_ABORT_ON_ERR(unit)) { 3773 break; 3774 } 3775 #endif 3776 } 3777 } 3778 } 3779 3780 /* Reset last read status. */ 3781 if (BCM_E_NOT_FOUND == rv) { 3782 rv = BCM_E_NONE; 3783 } 3784 3785 return rv; 3786 } 3787 3788 /* 3789 * Function: 3790 * _bcm_td2_vxlan_tunnel_init_add 3791 * Purpose: 3792 * Add tunnel initiator entry to hw. 3793 * Parameters: 3794 * unit - (IN)SOC unit number. 3795 * idx - (IN)Index to insert tunnel initiator. 3796 * info - (IN)Tunnel initiator entry info. 3797 * Returns: 3798 * BCM_E_XXX 3799 */ 3800 STATIC int 3801 _bcm_td2_vxlan_tunnel_init_add(int unit, int idx, bcm_tunnel_initiator_t *info) 3802 { 3803 uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to write hw entry */ 3804 soc_mem_t mem; /* Tunnel initiator table memory */ 3805 int rv = BCM_E_NONE; /* Return value */ 3806 int df_val=0; /* Don't fragment encoding */ 3807 3808 mem = EGR_IP_TUNNELm; 3809 3810 /* Zero write buffer. */ 3811 sal_memset(tnl_entry, 0, sizeof(tnl_entry)); 3812 3813 /* If replacing existing entry, first read the entry to get old 3814 profile pointer and TPID */ 3815 if (info->flags & BCM_TUNNEL_REPLACE) { 3816 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, tnl_entry); 3817 BCM_IF_ERROR_RETURN(rv); 3818 } 3819 3820 /* Set source address only within Tunnel Table */ 3821 soc_mem_field_set(unit, mem, tnl_entry, SIPf, (uint32 *)&info->sip); 3822 3823 /* IP tunnel hdr DF bit for IPv4. */ 3824 df_val = 0; 3825 if (info->flags & BCM_TUNNEL_INIT_USE_INNER_DF) { 3826 df_val |= 0x2; 3827 } else if (info->flags & BCM_TUNNEL_INIT_IPV4_SET_DF) { 3828 df_val |= 0x1; 3829 } 3830 soc_mem_field32_set(unit, mem, tnl_entry, IPV4_DF_SELf, df_val); 3831 3832 /* IP tunnel hdr DF bit for IPv6. */ 3833 if (info->flags & BCM_TUNNEL_INIT_IPV6_SET_DF) { 3834 soc_mem_field32_set(unit, mem, tnl_entry, IPV6_DF_SELf, 1); 3835 } 3836 3837 /* Tunnel header DSCP select. */ 3838 soc_mem_field32_set(unit, mem, tnl_entry, DSCP_SELf, info->dscp_sel); 3839 3840 if (info->dscp_sel == bcmTunnelDscpMap) { 3841 /* Set DSCP_MAP value. */ 3842 int hw_map_idx = 0; 3843 BCM_IF_ERROR_RETURN( 3844 _bcm_tr2_qos_id2idx(unit, info->dscp_map, &hw_map_idx)); 3845 soc_mem_field32_set(unit, mem, tnl_entry, 3846 DSCP_MAPPING_PTRf, hw_map_idx); 3847 } else { 3848 /* Set DSCP value. */ 3849 soc_mem_field32_set(unit, mem, tnl_entry, DSCPf, info->dscp); 3850 } 3851 3852 /* Set TTL. */ 3853 soc_mem_field32_set(unit, mem, tnl_entry, TTLf, info->ttl); 3854 3855 /* Set UDP Dest Port */ 3856 soc_mem_field32_set(unit, mem, tnl_entry, L4_DEST_PORTf, info->udp_dst_port); 3857 3858 /* Set UDP Src Port */ 3859 soc_mem_field32_set(unit, mem, tnl_entry, L4_SRC_PORTf, info->udp_src_port); 3860 3861 /* Set Tunnel type = VXLAN */ 3862 soc_mem_field32_set(unit, mem, tnl_entry, TUNNEL_TYPEf, _BCM_VXLAN_TUNNEL_TYPE); 3863 3864 /* Set entry type = IPv4 */ 3865 #if defined(BCM_TRIDENT3_SUPPORT) 3866 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 3867 soc_mem_field32_set(unit, mem, tnl_entry, DATA_TYPEf, 0x1); 3868 } else 3869 #endif 3870 { 3871 soc_mem_field32_set(unit, mem, tnl_entry, ENTRY_TYPEf, 0x1); 3872 } 3873 3874 if ((info->flags & BCM_TUNNEL_INIT_IP4_ID_SET_FIXED) || 3875 (info->flags & BCM_TUNNEL_INIT_IP4_ID_SET_RANDOM)) { 3876 int val; 3877 uint16 random; 3878 #if defined(BCM_TRIDENT3_SUPPORT) 3879 if (SOC_IS_TRIDENT3X(unit)) { 3880 uint64 rval; 3881 uint32 base_idx; 3882 egr_sequence_number_table_entry_t entry; 3883 3884 BCM_IF_ERROR_RETURN(READ_EGR_SEQUENCE_NUMBER_CTRLr(unit, &rval)); 3885 base_idx = soc_reg64_field32_get(unit, EGR_SEQUENCE_NUMBER_CTRLr, 3886 rval,EGR_IP_TUNNEL_OFFSET_BASEf); 3887 3888 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_SEQUENCE_NUMBER_TABLEm, 3889 MEM_BLOCK_ANY, idx + base_idx, &entry)); 3890 if (info->flags & BCM_TUNNEL_INIT_IP4_ID_SET_FIXED) { 3891 soc_EGR_SEQUENCE_NUMBER_TABLEm_field32_set(unit, &entry, 3892 SEQUENCE_NUMBERf, 3893 info->ip4_id); 3894 } else if (info->flags & BCM_TUNNEL_INIT_IP4_ID_SET_RANDOM) { 3895 random = (uint16) (sal_time_usecs() & 0xFFFF); 3896 soc_EGR_SEQUENCE_NUMBER_TABLEm_field32_set(unit, &entry, 3897 SEQUENCE_NUMBERf, 3898 random); 3899 } 3900 BCM_IF_ERROR_RETURN(soc_mem_write( 3901 unit, EGR_SEQUENCE_NUMBER_TABLEm, MEM_BLOCK_ANY, 3902 idx + base_idx, &entry)); 3903 } else 3904 #endif 3905 { 3906 BCM_IF_ERROR_RETURN( 3907 bcm_esw_switch_control_get(unit, bcmSwitchTunnelIp4IdShared, &val)); 3908 if (val == 0) { 3909 egr_fragment_id_table_entry_t entry; 3910 sal_memset(&entry, 0, sizeof(egr_fragment_id_table_entry_t)); 3911 3912 if (info->flags & BCM_TUNNEL_INIT_IP4_ID_SET_FIXED) { 3913 soc_EGR_FRAGMENT_ID_TABLEm_field32_set(unit, &entry, 3914 FRAGMENT_IDf, 3915 info->ip4_id); 3916 } else if (info->flags & BCM_TUNNEL_INIT_IP4_ID_SET_RANDOM) { 3917 random = (uint16) (sal_time_usecs() & 0xFFFF); 3918 soc_EGR_FRAGMENT_ID_TABLEm_field32_set(unit, &entry, 3919 FRAGMENT_IDf, 3920 random); 3921 } 3922 BCM_IF_ERROR_RETURN(soc_mem_write( 3923 unit, EGR_FRAGMENT_ID_TABLEm, SOC_BLOCK_ALL, idx, &entry)); 3924 } 3925 } 3926 } 3927 3928 /* Write buffer to hw. */ 3929 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, tnl_entry); 3930 return rv; 3931 3932 } 3933 3934 /* 3935 * Function: 3936 * _bcm_td2_vxlan_tunnel_initiator_entry_add 3937 * Purpose: 3938 * Configure VXLAN Tunnel initiator hardware Entry 3939 * Returns: 3940 * BCM_E_XXX 3941 */ 3942 STATIC int 3943 _bcm_td2_vxlan_tunnel_initiator_entry_add(int unit, uint32 flags, bcm_tunnel_initiator_t *info, int *tnl_idx) 3944 { 3945 int rv = BCM_E_NONE; 3946 3947 rv = bcm_xgs3_tnl_init_add(unit, flags, info, tnl_idx); 3948 if (BCM_FAILURE(rv)) { 3949 return rv; 3950 } 3951 /* Write the entry to HW */ 3952 rv = _bcm_td2_vxlan_tunnel_init_add(unit, *tnl_idx, info); 3953 if (BCM_FAILURE(rv)) { 3954 flags = _BCM_L3_SHR_WRITE_DISABLE; 3955 (void) bcm_xgs3_tnl_init_del(unit, flags, *tnl_idx); 3956 } 3957 return rv; 3958 } 3959 3960 /* 3961 * Function: 3962 * _bcm_td2_vxlan_tunnel_initiator_get_tunnel_id 3963 * Purpose: 3964 * Get an available tunnel id for vxlan tunnel initiator 3965 * Parameters: 3966 * unit - (IN) SOC unit number. 3967 * info - (IN) the informaton of tunnel initiator 3968 * hw_match_flag - (IN) Indicate if an existing EGR_IP_TUNNEL entry 3969 * soft_tnl_idx - (out) Tunnel id for tunnel initiator 3970 * new_id_flag - (out) Indicate if a new free tunnel id 3971 * Returns: 3972 * BCM_E_XXX 3973 */ 3974 STATIC int 3975 _bcm_td2_vxlan_tunnel_initiator_get_tunnel_id(int unit, 3976 bcm_tunnel_initiator_t *info, int hw_match_flag, 3977 int *soft_tnl_idx, int *new_id_flag) 3978 { 3979 int rv = BCM_E_NONE; 3980 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 3981 int idx = 0; 3982 int num_vp = 0; 3983 int free_index = -1; 3984 int free_entry_found = 0; 3985 3986 if ((NULL == info) || (NULL == soft_tnl_idx) || (NULL == new_id_flag)) { 3987 return BCM_E_PARAM; 3988 } 3989 3990 vxlan_info = VXLAN_INFO(unit); 3991 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 3992 *new_id_flag = FALSE; 3993 3994 for (idx = 0; idx < num_vp; idx++) { 3995 if (vxlan_info->vxlan_tunnel_init[idx].sip == info->sip && 3996 vxlan_info->vxlan_tunnel_init[idx].tunnel_state == 3997 info->udp_dst_port && 3998 vxlan_info->vxlan_tunnel_init[idx].dip == info->dip) { 3999 /* Obtain existed index */ 4000 *soft_tnl_idx = idx; 4001 return BCM_E_NONE; 4002 } 4003 4004 if (vxlan_info->vxlan_tunnel_init[idx].sip == 0 && !free_entry_found) { 4005 /* Obtain Free index */ 4006 free_index = idx; 4007 free_entry_found = 1; 4008 if (!hw_match_flag) { 4009 break; 4010 } 4011 } 4012 } 4013 4014 if (free_entry_found) { 4015 *new_id_flag = TRUE; 4016 *soft_tnl_idx = free_index; 4017 } else { 4018 /* No free resource */ 4019 return BCM_E_RESOURCE; 4020 } 4021 4022 return rv; 4023 } 4024 4025 /* 4026 * Function: 4027 * bcm_td2_vxlan_tunnel_initiator_create 4028 * Purpose: 4029 * Set VXLAN Tunnel initiator 4030 * Parameters: 4031 * unit - Device Number 4032 * Returns: 4033 * BCM_E_XXX 4034 */ 4035 int 4036 bcm_td2_vxlan_tunnel_initiator_create(int unit, bcm_tunnel_initiator_t *info) 4037 { 4038 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 4039 int tnl_idx=-1, rv = BCM_E_NONE, ref_count=0; 4040 uint32 flags=0; 4041 int idx = 0, num_vp = 0; 4042 uint8 match_entry_present=0; 4043 int soft_tnl_idx = -1; 4044 int new_idx_flag = FALSE; 4045 4046 /* Input parameters check. */ 4047 if (NULL == info) { 4048 return (BCM_E_PARAM); 4049 } 4050 if (info->type != bcmTunnelTypeVxlan) { 4051 return BCM_E_PARAM; 4052 } 4053 if (!BCM_TTL_VALID(info->ttl)) { 4054 return BCM_E_PARAM; 4055 } 4056 if (info->dscp_sel > 2 || info->dscp_sel < 0) { 4057 return BCM_E_PARAM; 4058 } 4059 if (info->dscp > 63 || info->dscp < 0) { 4060 return BCM_E_PARAM; 4061 } 4062 if ((0 == info->dip) || (0 == info->sip)) { 4063 return BCM_E_PARAM; 4064 } 4065 4066 vxlan_info = VXLAN_INFO(unit); 4067 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 4068 if (info->flags & BCM_TUNNEL_REPLACE) { 4069 int tunnel_idx = -1; 4070 tunnel_idx = BCM_GPORT_TUNNEL_ID_GET(info->tunnel_id); 4071 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_idx); 4072 if(info->sip != vxlan_info->vxlan_tunnel_init[tunnel_idx].sip 4073 || info->udp_dst_port != 4074 vxlan_info->vxlan_tunnel_init[tunnel_idx].tunnel_state 4075 || info->dip != vxlan_info->vxlan_tunnel_init[tunnel_idx].dip) { 4076 return BCM_E_UNAVAIL; 4077 } 4078 } 4079 4080 /* Allocate either existing or new tunnel initiator entry */ 4081 flags = _BCM_L3_SHR_MATCH_DISABLE | _BCM_L3_SHR_WRITE_DISABLE | 4082 _BCM_L3_SHR_SKIP_INDEX_ZERO; 4083 4084 if (BCM_E_NONE == _bcm_xgs3_l3_tnl_init_find(unit, info, &tnl_idx)) { 4085 match_entry_present = 1; 4086 } 4087 /* Get an available tunnel id */ 4088 BCM_IF_ERROR_RETURN( 4089 _bcm_td2_vxlan_tunnel_initiator_get_tunnel_id( 4090 unit, info, match_entry_present, &soft_tnl_idx, &new_idx_flag)); 4091 4092 if (match_entry_present) { 4093 if (info->flags & BCM_TUNNEL_REPLACE) { 4094 if (new_idx_flag) { 4095 return BCM_E_UNAVAIL; 4096 } 4097 flags |= _BCM_L3_SHR_UPDATE | _BCM_L3_SHR_WITH_ID; 4098 /* Check for Ref-count in (SIP, multi-DIP) situation */ 4099 for (idx = 0; idx < num_vp; idx++) { 4100 if ((info->sip == 4101 vxlan_info->vxlan_tunnel_init[idx].sip) && 4102 (info->udp_dst_port == 4103 vxlan_info->vxlan_tunnel_init[idx].tunnel_state)) { 4104 if (++ref_count > 1) { 4105 return BCM_E_RESOURCE; 4106 } 4107 } 4108 } 4109 rv = _bcm_td2_vxlan_tunnel_initiator_entry_add( 4110 unit, flags, info, &tnl_idx); 4111 if (BCM_FAILURE(rv)) { 4112 return rv; 4113 } 4114 } 4115 } else { 4116 /* Parse tunnel replace flag */ 4117 if (info->flags & BCM_TUNNEL_REPLACE) { 4118 /* replace an inexistent tunnel initiator */ 4119 return BCM_E_NOT_FOUND; 4120 } 4121 rv = _bcm_td2_vxlan_tunnel_initiator_entry_add(unit, flags, info, &tnl_idx); 4122 if (BCM_FAILURE(rv)) { 4123 return rv; 4124 } 4125 } 4126 4127 if (soft_tnl_idx !=- 1) { 4128 vxlan_info->vxlan_tunnel_init[soft_tnl_idx].sip = info->sip; 4129 vxlan_info->vxlan_tunnel_init[soft_tnl_idx].dip = info->dip; 4130 vxlan_info->vxlan_tunnel_init[soft_tnl_idx].tunnel_state = info->udp_dst_port; 4131 BCM_GPORT_TUNNEL_ID_SET(info->tunnel_id, soft_tnl_idx); 4132 } else { 4133 return BCM_E_NOT_FOUND; 4134 } 4135 4136 return rv; 4137 } 4138 4139 /* 4140 * Function: 4141 * _bcm_td2_vxlan_tunnel_init_get 4142 * Purpose: 4143 * Get a tunnel initiator entry from hw. 4144 * Parameters: 4145 * unit - (IN)SOC unit number. 4146 * idx - (IN/OUT)Index to read tunnel initiator. 4147 * info - (OUT)Tunnel initiator entry info. 4148 * Returns: 4149 * BCM_E_XXX 4150 */ 4151 STATIC int 4152 _bcm_td2_vxlan_tunnel_init_get(int unit, int *hw_idx, bcm_tunnel_initiator_t *info) 4153 { 4154 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 4155 egr_fragment_id_table_entry_t entry; 4156 uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to read hw entry. */ 4157 soc_mem_t mem; /* Tunnel initiator table memory.*/ 4158 int df_val=0; /* Don't fragment encoded value. */ 4159 int tnl_type=0; /* Tunnel type. */ 4160 uint32 entry_type = BCM_XGS3_TUNNEL_INIT_V4;/* Entry type (IPv4/IPv6/MPLS)*/ 4161 int idx = 0; 4162 4163 /* Get table memory. */ 4164 mem = EGR_IP_TUNNELm; 4165 idx = *hw_idx; 4166 4167 /* Initialize the buffer. */ 4168 sal_memset(tnl_entry, 0, sizeof(tnl_entry)); 4169 vxlan_info = VXLAN_INFO(unit); 4170 info->dip = vxlan_info->vxlan_tunnel_init[idx].dip; 4171 BCM_IF_ERROR_RETURN( 4172 _bcm_td2_vxlan_tunnel_initiator_idx_translate(unit, idx, hw_idx)); 4173 BCM_IF_ERROR_RETURN( 4174 soc_mem_read(unit, mem, MEM_BLOCK_ANY, *hw_idx, tnl_entry)); 4175 4176 /* Get tunnel type. */ 4177 tnl_type = soc_mem_field32_get(unit, mem, tnl_entry, TUNNEL_TYPEf); 4178 if (tnl_type != _BCM_VXLAN_TUNNEL_TYPE) { 4179 return BCM_E_NOT_FOUND; 4180 } 4181 4182 /* Get entry_type. */ 4183 #if defined(BCM_TRIDENT3_SUPPORT) 4184 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 4185 entry_type = soc_mem_field32_get(unit, mem, tnl_entry, DATA_TYPEf); 4186 } else 4187 #endif 4188 { 4189 entry_type = soc_mem_field32_get(unit, mem, tnl_entry, ENTRY_TYPEf); 4190 } 4191 if (entry_type != 0x1) { 4192 return BCM_E_NOT_FOUND; 4193 } 4194 4195 /* Parse hw buffer. */ 4196 /* Check will not fail. entry_type already validated */ 4197 if (BCM_XGS3_TUNNEL_INIT_V4 == entry_type) { 4198 /* Get source ip. */ 4199 info->sip = soc_mem_field32_get(unit, mem, tnl_entry, SIPf); 4200 } 4201 4202 /* Tunnel header DSCP select. */ 4203 info->dscp_sel = soc_mem_field32_get(unit, mem, tnl_entry, DSCP_SELf); 4204 4205 if (info->dscp_sel == bcmTunnelDscpMap) { 4206 /* Tunnel header DSCP_MAP value. */ 4207 BCM_IF_ERROR_RETURN( 4208 _bcm_tr2_qos_idx2id(unit, soc_mem_field32_get(unit, mem, tnl_entry, 4209 DSCP_MAPPING_PTRf), 4210 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, 4211 &info->dscp_map)); 4212 } else { 4213 /* Tunnel header DSCP value. */ 4214 info->dscp = soc_mem_field32_get(unit, mem, tnl_entry, DSCPf); 4215 } 4216 4217 /* IP tunnel hdr DF bit for IPv4 */ 4218 df_val = soc_mem_field32_get(unit, mem, tnl_entry, IPV4_DF_SELf); 4219 if (0x2 <= df_val) { 4220 info->flags |= BCM_TUNNEL_INIT_USE_INNER_DF; 4221 } else if (0x1 == df_val) { 4222 info->flags |= BCM_TUNNEL_INIT_IPV4_SET_DF; 4223 } 4224 4225 df_val = soc_mem_field32_get(unit, mem, tnl_entry, IPV6_DF_SELf); 4226 if (0x1 == df_val) { 4227 info->flags |= BCM_TUNNEL_INIT_IPV6_SET_DF; 4228 } 4229 4230 /* Get TTL. */ 4231 info->ttl = soc_mem_field32_get(unit, mem, tnl_entry, TTLf); 4232 4233 /* Get UDP Dest Port */ 4234 info->udp_dst_port = soc_mem_field32_get(unit, mem, tnl_entry, L4_DEST_PORTf); 4235 4236 /* Get UDP Src Port */ 4237 info->udp_src_port = soc_mem_field32_get(unit, mem, tnl_entry, L4_SRC_PORTf); 4238 4239 /* Translate hw tunnel type into API encoding. - bcmTunnelTypeVxlan */ 4240 BCM_IF_ERROR_RETURN(_bcm_trx_tnl_hw_code_to_type(unit, tnl_type, 4241 entry_type, 4242 &info->type)); 4243 #if defined(BCM_TRIDENT3_SUPPORT) 4244 if (SOC_IS_TRIDENT3X(unit)) { 4245 uint64 rval; 4246 uint32 base_idx; 4247 4248 BCM_IF_ERROR_RETURN(READ_EGR_SEQUENCE_NUMBER_CTRLr(unit, &rval)); 4249 base_idx = soc_reg64_field32_get(unit, EGR_SEQUENCE_NUMBER_CTRLr, rval, 4250 EGR_IP_TUNNEL_OFFSET_BASEf); 4251 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_SEQUENCE_NUMBER_TABLEm, 4252 MEM_BLOCK_ANY, idx + base_idx, &entry)); 4253 info->ip4_id = soc_mem_field32_get(unit, EGR_SEQUENCE_NUMBER_TABLEm, 4254 &entry, SEQUENCE_NUMBERf); 4255 } else 4256 #endif 4257 { 4258 BCM_IF_ERROR_RETURN(soc_mem_read( 4259 unit, EGR_FRAGMENT_ID_TABLEm, MEM_BLOCK_ANY, *hw_idx, &entry)); 4260 info->ip4_id = soc_mem_field32_get( 4261 unit, EGR_FRAGMENT_ID_TABLEm, &entry, FRAGMENT_IDf); 4262 } 4263 4264 *hw_idx = idx; 4265 return BCM_E_NONE; 4266 } 4267 4268 /* 4269 * Function: 4270 * bcm_td2_vxlan_tunnel_initiator_destroy 4271 * Purpose: 4272 * Destroy outgoing VXLAN tunnel 4273 * Parameters: 4274 * unit - (IN) Device Number 4275 * vxlan_tunnel_id - (IN) Tunnel ID (Gport) 4276 */ 4277 int 4278 bcm_td2_vxlan_tunnel_initiator_destroy(int unit, bcm_gport_t vxlan_tunnel_id) 4279 { 4280 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 4281 int tnl_idx=-1, temp_tnl_idx=-1, rv = BCM_E_NONE, ref_count=0, idx=0; 4282 uint32 flags = 0; 4283 int num_vp=0; 4284 bcm_ip_t sip=0; /* Tunnel header SIP (IPv4). */ 4285 uint16 udp_dst_port; /* Destination UDP port */ 4286 4287 vxlan_info = VXLAN_INFO(unit); 4288 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 4289 4290 /* Input parameters check. */ 4291 if (!BCM_GPORT_IS_TUNNEL(vxlan_tunnel_id)) { 4292 return BCM_E_PARAM; 4293 } 4294 tnl_idx = BCM_GPORT_TUNNEL_ID_GET(vxlan_tunnel_id); 4295 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tnl_idx); 4296 4297 sip = vxlan_info->vxlan_tunnel_init[tnl_idx].sip; 4298 udp_dst_port = vxlan_info->vxlan_tunnel_init[tnl_idx].tunnel_state; 4299 if (sip == 0) { 4300 return BCM_E_NOT_FOUND; 4301 } 4302 /* Remove HW TNL entry only if all matching SIP, UDP_DEST_PORT gets removed */ 4303 for (idx=0; idx < num_vp; idx++) { 4304 if ((vxlan_info->vxlan_tunnel_init[idx].sip == sip) && 4305 (vxlan_info->vxlan_tunnel_init[idx].tunnel_state == udp_dst_port)) { 4306 ref_count++; 4307 } 4308 } 4309 4310 if (ref_count == 1) { 4311 /* Get the entry first */ 4312 temp_tnl_idx = tnl_idx; 4313 BCM_IF_ERROR_RETURN( 4314 _bcm_td2_vxlan_tunnel_initiator_idx_translate( 4315 unit, temp_tnl_idx, &tnl_idx)); 4316 /* Destroy the tunnel entry */ 4317 (void) bcm_xgs3_tnl_init_del(unit, flags, tnl_idx); 4318 vxlan_info->vxlan_tunnel_init[temp_tnl_idx].sip = 0; 4319 vxlan_info->vxlan_tunnel_init[temp_tnl_idx].dip = 0; 4320 vxlan_info->vxlan_tunnel_init[temp_tnl_idx].tunnel_state = 0; 4321 } else if (ref_count) { 4322 vxlan_info->vxlan_tunnel_init[tnl_idx].sip = 0; 4323 vxlan_info->vxlan_tunnel_init[tnl_idx].dip = 0; 4324 vxlan_info->vxlan_tunnel_init[tnl_idx].tunnel_state = 0; 4325 } 4326 return rv; 4327 } 4328 4329 /* 4330 * Function: 4331 * bcm_td2_vxlan_tunnel_initiator_destroy_all 4332 * Purpose: 4333 * Destroy all outgoing VXLAN tunnel 4334 * Parameters: 4335 * unit - (IN) Device Number 4336 */ 4337 int 4338 bcm_td2_vxlan_tunnel_initiator_destroy_all(int unit) 4339 { 4340 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 4341 soc_field_t type_field; 4342 egr_ip_tunnel_entry_t *tnl_entry, *tnl_entries; 4343 int rv = BCM_E_NONE, tnl_idx, num_entries, num_vp; 4344 4345 vxlan_info = VXLAN_INFO(unit); 4346 num_entries = soc_mem_index_count(unit, EGR_IP_TUNNELm); 4347 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 4348 4349 #if defined(BCM_TRIDENT3_SUPPORT) 4350 if (SOC_MEM_FIELD_VALID(unit, EGR_IP_TUNNELm, DATA_TYPEf)) { 4351 type_field = DATA_TYPEf; 4352 } else 4353 #endif 4354 { 4355 type_field = ENTRY_TYPEf; 4356 } 4357 4358 tnl_entries = soc_cm_salloc(unit, num_entries * sizeof(*tnl_entries), 4359 "egr_ip_tunnel"); 4360 if (tnl_entries == NULL) { 4361 return BCM_E_MEMORY; 4362 } 4363 sal_memset(tnl_entries, 0, num_entries * sizeof(*tnl_entries)); 4364 4365 soc_mem_lock(unit, EGR_IP_TUNNELm); 4366 rv = soc_mem_read_range(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 4367 0, num_entries - 1, tnl_entries); 4368 if (BCM_FAILURE(rv)) { 4369 soc_mem_unlock(unit, EGR_IP_TUNNELm); 4370 soc_cm_sfree(unit, tnl_entries); 4371 return rv; 4372 } 4373 4374 for (tnl_idx = 0; tnl_idx < num_entries; tnl_idx++) { 4375 tnl_entry = soc_mem_table_idx_to_pointer(unit, EGR_IP_TUNNELm, 4376 egr_ip_tunnel_entry_t *, tnl_entries, tnl_idx); 4377 4378 vxlan_info->vxlan_tunnel_init[tnl_idx].sip = 0; 4379 vxlan_info->vxlan_tunnel_init[tnl_idx].dip = 0; 4380 vxlan_info->vxlan_tunnel_init[tnl_idx].tunnel_state = 0; 4381 4382 if (!soc_EGR_IP_TUNNELm_field32_get(unit, tnl_entry, type_field)) { 4383 continue; 4384 } 4385 if (soc_EGR_IP_TUNNELm_field32_get(unit, tnl_entry, 4386 TUNNEL_TYPEf) != _BCM_VXLAN_TUNNEL_TYPE) { 4387 continue; 4388 } 4389 4390 /* Delete the entry from HW */ 4391 (void) bcm_xgs3_tnl_init_del(unit, 0, tnl_idx); 4392 4393 vxlan_info->vxlan_tunnel_init[tnl_idx].sip = 0; 4394 vxlan_info->vxlan_tunnel_init[tnl_idx].dip = 0; 4395 vxlan_info->vxlan_tunnel_init[tnl_idx].tunnel_state = 0; 4396 } 4397 soc_mem_unlock(unit, EGR_IP_TUNNELm); 4398 soc_cm_sfree(unit, tnl_entries); 4399 4400 for (tnl_idx = num_entries; tnl_idx < num_vp; tnl_idx++) { 4401 vxlan_info->vxlan_tunnel_init[tnl_idx].sip = 0; 4402 vxlan_info->vxlan_tunnel_init[tnl_idx].dip = 0; 4403 vxlan_info->vxlan_tunnel_init[tnl_idx].tunnel_state = 0; 4404 } 4405 return BCM_E_NONE; 4406 4407 } 4408 4409 /* 4410 * Function: 4411 * bcm_td2_vxlan_tunnel_initiator_get 4412 * Purpose: 4413 * Get an outgong VXLAN tunnel info 4414 * Parameters: 4415 * unit - (IN) Device Number 4416 * info - (IN/OUT) Tunnel initiator structure 4417 */ 4418 int 4419 bcm_td2_vxlan_tunnel_initiator_get(int unit, bcm_tunnel_initiator_t *info) 4420 { 4421 int tnl_idx=-1, rv = BCM_E_NONE; 4422 4423 /* Input parameters check. */ 4424 if (info == NULL) { 4425 return BCM_E_PARAM; 4426 } 4427 if (!BCM_GPORT_IS_TUNNEL(info->tunnel_id)) { 4428 return BCM_E_PARAM; 4429 } 4430 tnl_idx = BCM_GPORT_TUNNEL_ID_GET(info->tunnel_id); 4431 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tnl_idx); 4432 4433 /* Get the entry */ 4434 rv = _bcm_td2_vxlan_tunnel_init_get(unit, &tnl_idx, info); 4435 return rv; 4436 } 4437 4438 /* 4439 * Function: 4440 * bcm_td2_vxlan_tunnel_initiator_traverse 4441 * Purpose: 4442 * Traverse VXLAN tunnel initiator entries 4443 * Parameters: 4444 * unit - (IN) Device Number 4445 * cb - (IN) User callback function, called once per entry 4446 * user_data - (IN) User supplied cookie used in parameter in callback function 4447 */ 4448 int 4449 bcm_td2_vxlan_tunnel_initiator_traverse(int unit, bcm_tunnel_initiator_traverse_cb cb, void *user_data) 4450 { 4451 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 4452 int num_vp = 0, idx = 0; 4453 bcm_tunnel_initiator_t info; 4454 int rv = BCM_E_NONE; 4455 4456 vxlan_info = VXLAN_INFO(unit); 4457 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 4458 4459 /* Iterate over all the entries - search valid ones. */ 4460 for(idx = 0; idx < num_vp; idx++) { 4461 /* Check a valid entry */ 4462 if (vxlan_info->vxlan_tunnel_init[idx].sip != 0) { 4463 /* Reset buffer before read. */ 4464 bcm_tunnel_initiator_t_init(&info); 4465 4466 BCM_GPORT_TUNNEL_ID_SET(info.tunnel_id, idx); 4467 rv = bcm_td2_vxlan_tunnel_initiator_get(unit, &info); 4468 4469 /* search failure */ 4470 if (BCM_FAILURE(rv)) { 4471 if (rv != BCM_E_NOT_FOUND) { 4472 break; 4473 } 4474 continue; 4475 } 4476 4477 if (cb) { 4478 rv = (*cb) (unit, &info, user_data); 4479 #ifdef BCM_CB_ABORT_ON_ERR 4480 if (BCM_FAILURE(rv) && SOC_CB_ABORT_ON_ERR(unit)) { 4481 break; 4482 } 4483 #endif 4484 } 4485 } 4486 } 4487 4488 /* Reset last read status. */ 4489 if (BCM_E_NOT_FOUND == rv) { 4490 rv = BCM_E_NONE; 4491 } 4492 4493 return rv; 4494 } 4495 4496 /* 4497 * Function: 4498 * _bcm_td2_vxlan_tunnel_initiator_idx_translate 4499 * Purpose: 4500 * Translate the index of software object to the index 4501 * of hw entry for tunnel initiator 4502 * Parameters: 4503 * unit - (IN) SOC unit number. 4504 * soft_idx - (IN) The index of software object 4505 * hw_idx - (IN) The index of hw entry 4506 * Returns: 4507 * BCM_E_XXX 4508 */ 4509 STATIC int 4510 _bcm_td2_vxlan_tunnel_initiator_idx_translate(int unit, int soft_idx, 4511 int *hw_idx) 4512 { 4513 bcm_tunnel_initiator_t init_tnl_info; 4514 int rv = BCM_E_NONE; 4515 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 4516 vxlan_info = VXLAN_INFO(unit); 4517 4518 if (NULL == hw_idx) { 4519 return BCM_E_PARAM; 4520 } 4521 4522 bcm_tunnel_initiator_t_init(&init_tnl_info); 4523 init_tnl_info.type = bcmTunnelTypeVxlan; 4524 init_tnl_info.sip = vxlan_info->vxlan_tunnel_init[soft_idx].sip; 4525 init_tnl_info.udp_dst_port = 4526 vxlan_info->vxlan_tunnel_init[soft_idx].tunnel_state; 4527 4528 rv = _bcm_xgs3_l3_tnl_init_find(unit, &init_tnl_info, hw_idx); 4529 4530 return rv; 4531 } 4532 4533 /* 4534 * Function: 4535 * _bcm_td2_vxlan_tunnel_initiator_cmp 4536 * Purpose: 4537 * Routine compares vxlan tunnel initiator entry with entry in the chip 4538 * with specified index. 4539 * Parameters: 4540 * unit - (IN) SOC unit number. 4541 * buf - (IN) Tunnel initiator entry to compare. 4542 * index - (IN) Entry index in the chip to compare. 4543 * cmp_result - (OUT)Compare result. 4544 * Returns: 4545 * BCM_E_XXX 4546 */ 4547 int 4548 _bcm_td2_vxlan_tunnel_initiator_cmp(int unit, void *buf, 4549 int index, int *cmp_result) 4550 { 4551 bcm_tunnel_initiator_t hw_entry; /* Entry read from hw */ 4552 bcm_tunnel_initiator_t *tnl_entry; /* Api passed buffer */ 4553 int rv = BCM_E_NONE; 4554 4555 if ((NULL == buf) || (NULL == cmp_result)) { 4556 return BCM_E_PARAM; 4557 } 4558 4559 *cmp_result = BCM_L3_CMP_NOT_EQUAL; 4560 4561 /* Copy buffer to structure */ 4562 tnl_entry = (bcm_tunnel_initiator_t *)buf; 4563 4564 /* Initialization */ 4565 bcm_tunnel_initiator_t_init(&hw_entry); 4566 4567 /* Get tunnel initiator entry from hw */ 4568 if (BCM_XGS3_L3_HWCALL_CHECK(unit, tnl_init_get)) { 4569 BCM_XGS3_L3_MODULE_LOCK(unit); 4570 rv = (BCM_XGS3_L3_HWCALL_EXEC(unit, tnl_init_get)( 4571 unit, index, &hw_entry)); 4572 BCM_XGS3_L3_MODULE_UNLOCK(unit); 4573 BCM_IF_ERROR_RETURN(rv); 4574 } else { 4575 return BCM_E_UNAVAIL; 4576 } 4577 4578 /* Compare source ip */ 4579 if (tnl_entry->sip != hw_entry.sip) { 4580 return BCM_E_NONE; 4581 } 4582 4583 /* Compare udp dst port */ 4584 if (tnl_entry->udp_dst_port != hw_entry.udp_dst_port) { 4585 return BCM_E_NONE; 4586 } 4587 4588 *cmp_result = BCM_L3_CMP_EQUAL; 4589 return BCM_E_NONE; 4590 } 4591 4592 /* 4593 * Function: 4594 * _bcm_td2_vxlan_tunnel_initiator_hash_calc 4595 * Purpose: 4596 * Calculate tunnel initiator entry hash(signature). 4597 * Parameters: 4598 * unit - (IN) SOC unit number. 4599 * buf - (IN) Tunnel initiator entry information. 4600 * hash - (OUT)Hash(signature) calculated value. 4601 * Returns: 4602 * BCM_X_XXX 4603 */ 4604 int 4605 _bcm_td2_vxlan_tunnel_initiator_hash_calc(int unit, void *buf, uint16 *hash) 4606 { 4607 4608 bcm_tunnel_initiator_t tnl_entry; 4609 4610 if ((NULL == buf) || (NULL == hash)) { 4611 return (BCM_E_PARAM); 4612 } 4613 4614 bcm_tunnel_initiator_t_init(&tnl_entry); 4615 tnl_entry.type = ((bcm_tunnel_initiator_t *)buf)->type; 4616 4617 /* Set source ip */ 4618 tnl_entry.sip = ((bcm_tunnel_initiator_t *)buf)->sip; 4619 4620 tnl_entry.udp_dst_port = 4621 ((bcm_tunnel_initiator_t *)buf)->udp_dst_port; 4622 /* Calculate hash */ 4623 *hash = _shr_crc16(0, (uint8 *)&tnl_entry, 4624 sizeof(bcm_tunnel_initiator_t)); 4625 return BCM_E_NONE; 4626 } 4627 4628 /* 4629 * Function: 4630 * _bcm_td2_vxlan_ingress_dvp_set 4631 * Purpose: 4632 * Set Ingress DVP tables 4633 * Parameters: 4634 * IN : Unit 4635 * IN : vp 4636 * IN : vxlan_port 4637 * Returns: 4638 * BCM_E_XXX 4639 */ 4640 4641 STATIC int 4642 _bcm_td2_vxlan_ingress_dvp_set(int unit, int vp, uint32 mpath_flag, 4643 int vp_nh_ecmp_index, bcm_vxlan_port_t *vxlan_port) 4644 { 4645 ing_dvp_table_entry_t dvp; 4646 int network_group; 4647 int rv = BCM_E_NONE; 4648 4649 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 4650 BCM_IF_ERROR_RETURN( 4651 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 4652 } else if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID ) { 4653 sal_memset(&dvp, 0, sizeof(ing_dvp_table_entry_t)); 4654 } else { 4655 sal_memset(&dvp, 0, sizeof(ing_dvp_table_entry_t)); 4656 } 4657 4658 if (!(vxlan_port->flags & BCM_VXLAN_PORT_SHARE)) { 4659 if (mpath_flag) { 4660 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4661 NEXT_HOP_INDEXf, 0x0); 4662 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4663 ECMPf, 0x1); 4664 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4665 ECMP_PTRf, vp_nh_ecmp_index); 4666 } else { 4667 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4668 ECMPf, 0x0); 4669 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4670 ECMP_PTRf, 0); 4671 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4672 NEXT_HOP_INDEXf, vp_nh_ecmp_index); 4673 } 4674 } 4675 4676 #if defined(BCM_TRIDENT3_SUPPORT) 4677 if (SOC_IS_TRIDENT3X(unit)) { 4678 } else 4679 #endif 4680 { 4681 network_group = vxlan_port->network_group_id; 4682 BCM_IF_ERROR_RETURN(_bcm_validate_splithorizon_network_group(unit, 4683 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group)); 4684 if (vxlan_port->flags & BCM_VXLAN_PORT_EGRESS_TUNNEL) { 4685 /* Not setting dvp as network port for RIOT as all 4686 routed packet gets dropped if overlay SVP and DVP 4687 both are network ports. 4688 SVP and DVP as network ports is a valid used case 4689 but reg file says that this field 4690 is set when DVP is a TRILL port */ 4691 #ifdef BCM_RIOT_SUPPORT 4692 if ((BCMI_RIOT_IS_ENABLED(unit))) { 4693 /* explicitly setting it to zero. */ 4694 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 4695 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_GROUPf,0x0); 4696 } else { 4697 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_PORTf, 0x0); 4698 } 4699 } else 4700 #endif 4701 { 4702 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 4703 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_GROUPf, 4704 network_group); 4705 } else { 4706 if (!(vxlan_port->flags & 4707 BCM_VXLAN_PORT_NO_SPLIT_HORIZON_INGRESS)) { 4708 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4709 NETWORK_PORTf, 0x1); 4710 } 4711 } 4712 } 4713 } else { 4714 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 4715 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_GROUPf, 4716 network_group); 4717 } else { 4718 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, NETWORK_PORTf, 0x0); 4719 } 4720 } 4721 } 4722 4723 if (vxlan_port->flags & BCM_VXLAN_PORT_EGRESS_TUNNEL) { 4724 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4725 VP_TYPEf, _BCM_VXLAN_INGRESS_DEST_VP_TYPE); 4726 } else { 4727 soc_ING_DVP_TABLEm_field32_set(unit, &dvp, 4728 VP_TYPEf, _BCM_VXLAN_DEST_VP_TYPE_ACCESS); 4729 } 4730 4731 rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp); 4732 return rv; 4733 } 4734 4735 /* 4736 * Function: 4737 * _bcm_td2_vxlan_ingress_dvp_get 4738 * Purpose: 4739 * Get Ingress DVP tables 4740 * Parameters: 4741 * IN : Unit 4742 * IN : vp 4743 * IN : vxlan_port 4744 * Returns: 4745 * BCM_E_XXX 4746 */ 4747 4748 STATIC int 4749 _bcm_td2_vxlan_ingress_dvp_get(int unit, int vp, bcm_vxlan_port_t *vxlan_port) 4750 { 4751 int rv = BCM_E_NONE; 4752 ing_dvp_table_entry_t dvp; 4753 int vp_type = 0; /* access / tunnel vp type*/ 4754 int network_port = 0; 4755 _bcm_vp_info_t vp_info; 4756 4757 #ifdef BCM_RIOT_SUPPORT 4758 if ((BCMI_RIOT_IS_ENABLED(unit))) { 4759 return rv; 4760 } else 4761 #endif 4762 { 4763 sal_memset(&dvp, 0, sizeof(ing_dvp_table_entry_t)); 4764 BCM_IF_ERROR_RETURN(soc_mem_read(unit, ING_DVP_TABLEm, 4765 MEM_BLOCK_ANY, vp, &dvp)); 4766 4767 vp_type = soc_mem_field32_get(unit, 4768 ING_DVP_TABLEm, &dvp, VP_TYPEf); 4769 if (soc_mem_field_valid(unit, ING_DVP_TABLEm, NETWORK_PORTf) && 4770 (vp_type == _BCM_VXLAN_INGRESS_DEST_VP_TYPE)) { 4771 network_port = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp, 4772 NETWORK_PORTf); 4773 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 4774 if ((vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) && 4775 network_port == 0) { 4776 vxlan_port->flags |= BCM_VXLAN_PORT_NO_SPLIT_HORIZON_INGRESS; 4777 } 4778 } 4779 } 4780 4781 return rv; 4782 } 4783 4784 4785 /* 4786 * Function: 4787 * _bcm_td2_vxlan_ingress_dvp_2_set 4788 * Purpose: 4789 * Set Ingress DVP tables 4790 * Parameters: 4791 * IN : Unit 4792 * IN : vp 4793 * IN : vxlan_port 4794 * Returns: 4795 * BCM_E_XXX 4796 */ 4797 4798 STATIC int 4799 _bcm_td2_vxlan_ingress_dvp_2_set(int unit, int vp, uint32 mpath_flag, 4800 int vp_nh_ecmp_index, bcm_vxlan_port_t *vxlan_port) 4801 { 4802 ing_dvp_2_table_entry_t dvp; 4803 int rv = BCM_E_NONE; 4804 int network_group=0; 4805 4806 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 4807 BCM_IF_ERROR_RETURN( 4808 READ_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 4809 } else if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID ) { 4810 sal_memset(&dvp, 0, sizeof(ing_dvp_2_table_entry_t)); 4811 } else { 4812 sal_memset(&dvp, 0, sizeof(ing_dvp_2_table_entry_t)); 4813 } 4814 4815 if (!(vxlan_port->flags & BCM_VXLAN_PORT_SHARE)) { 4816 if (mpath_flag) { 4817 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4818 NEXT_HOP_INDEXf, 0x0); 4819 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4820 ECMPf, 0x1); 4821 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4822 ECMP_PTRf, vp_nh_ecmp_index); 4823 } else { 4824 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4825 ECMPf, 0x0); 4826 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4827 ECMP_PTRf, 0); 4828 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4829 NEXT_HOP_INDEXf, vp_nh_ecmp_index); 4830 } 4831 } 4832 4833 network_group = vxlan_port->network_group_id; 4834 rv = _bcm_validate_splithorizon_network_group(unit, 4835 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 4836 BCM_IF_ERROR_RETURN(rv); 4837 /* Enable DVP as Network_port */ 4838 if (vxlan_port->flags & BCM_VXLAN_PORT_EGRESS_TUNNEL) { 4839 /* Not setting dvp as network port for RIOT as all 4840 routed packet gets dropped if overlay SVP and DVP 4841 both are network ports. 4842 SVP and DVP as network ports is a valid used case 4843 but reg file says that this field 4844 is set when DVP is a TRILL port */ 4845 #ifdef BCM_RIOT_SUPPORT 4846 if ((BCMI_RIOT_IS_ENABLED(unit))) { 4847 if (soc_feature(unit, 4848 soc_feature_multiple_split_horizon_group)) { 4849 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4850 NETWORK_GROUPf, 0x0); 4851 } else { 4852 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4853 NETWORK_PORTf, 0x0); 4854 } 4855 } else 4856 #endif 4857 { 4858 4859 if (soc_feature(unit, 4860 soc_feature_multiple_split_horizon_group)) { 4861 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, NETWORK_GROUPf, 4862 network_group); 4863 } else { 4864 if (!(vxlan_port->flags & 4865 BCM_VXLAN_PORT_NO_SPLIT_HORIZON_INGRESS)) { 4866 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4867 NETWORK_PORTf, 0x1); 4868 } 4869 } 4870 } 4871 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4872 VP_TYPEf, _BCM_VXLAN_INGRESS_DEST_VP_TYPE); 4873 } else { 4874 4875 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 4876 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, NETWORK_GROUPf, 4877 network_group); 4878 } else { 4879 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, NETWORK_PORTf, 0x0); 4880 } 4881 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp, 4882 VP_TYPEf, _BCM_VXLAN_DEST_VP_TYPE_ACCESS); 4883 } 4884 4885 rv = WRITE_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp); 4886 return rv; 4887 } 4888 4889 4890 /* 4891 * Function: 4892 * _bcm_td2_vxlan_ingress_dvp_reset 4893 * Purpose: 4894 * Reset Ingress DVP tables 4895 * Parameters: 4896 * IN : Unit 4897 * IN : vp 4898 * Returns: 4899 * BCM_E_XXX 4900 */ 4901 4902 STATIC int 4903 _bcm_td2_vxlan_ingress_dvp_reset(int unit, int vp) 4904 { 4905 int rv=BCM_E_UNAVAIL; 4906 ing_dvp_table_entry_t dvp; 4907 ing_dvp_2_table_entry_t dvp_2; 4908 4909 4910 sal_memset(&dvp, 0, sizeof(ing_dvp_table_entry_t)); 4911 rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp); 4912 BCM_IF_ERROR_RETURN(rv); 4913 sal_memset(&dvp_2, 0, sizeof(ing_dvp_2_table_entry_t)); 4914 rv = WRITE_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp_2); 4915 4916 return rv; 4917 } 4918 4919 /* 4920 * Function: 4921 * _bcm_td2_vxlan_egress_access_dvp_set 4922 * Purpose: 4923 * Set Egress DVP tables - For access virtual ports 4924 * Parameters: 4925 * IN : Unit 4926 * IN : vp 4927 * IN : drop (unused for now) 4928 * IN : vxlan_port 4929 * Returns: 4930 * BCM_E_XXX 4931 */ 4932 4933 STATIC int 4934 _bcm_td2_vxlan_egress_access_dvp_set(int unit, int vp, int drop, 4935 bcm_vxlan_port_t *vxlan_port) 4936 { 4937 int rv = BCM_E_UNAVAIL; 4938 int network_group=0; 4939 soc_mem_t mem = EGR_DVP_ATTRIBUTEm; 4940 egr_dvp_attribute_entry_t egr_dvp_attribute; 4941 4942 /* Access ports only */ 4943 if (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 4944 return BCM_E_PARAM; 4945 } 4946 4947 /* Read entry and then update */ 4948 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 4949 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 4950 4951 #if defined(BCM_TRIDENT3_SUPPORT) 4952 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 4953 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4954 DATA_TYPEf, _BCM_VXLAN_DEST_VP_TYPE_ACCESS); 4955 } else 4956 #endif 4957 { 4958 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4959 VP_TYPEf, _BCM_VXLAN_DEST_VP_TYPE_ACCESS); 4960 } 4961 4962 4963 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 4964 network_group = vxlan_port->network_group_id; 4965 rv = _bcm_validate_splithorizon_network_group(unit, 4966 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 4967 BCM_IF_ERROR_RETURN(rv); 4968 #if defined(BCM_TRIDENT3_SUPPORT) 4969 if (SOC_MEM_FIELD_VALID(unit, mem, COMMON__DVP_NETWORK_GROUPf)) { 4970 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 4971 COMMON__DVP_NETWORK_GROUPf, network_group); 4972 } else 4973 #endif 4974 { 4975 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 4976 VXLAN__DVP_NETWORK_GROUPf, network_group); 4977 } 4978 } 4979 4980 /* L2 MTU - This is different from L3 MTU */ 4981 if (vxlan_port->mtu > 0) { 4982 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4983 COMMON__MTU_VALUEf, vxlan_port->mtu); 4984 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4985 COMMON__MTU_ENABLEf, 0x1); 4986 } else { 4987 /* Disable mtu checking if mtu = 0 */ 4988 soc_mem_field32_set(unit, mem, &egr_dvp_attribute, 4989 COMMON__MTU_ENABLEf, 0x0); 4990 } 4991 4992 4993 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 4994 BCM_IF_ERROR_RETURN(rv); 4995 4996 return rv; 4997 4998 } 4999 5000 /* 5001 * Function: 5002 * _bcm_td2_vxlan_egress_dvp_set 5003 * Purpose: 5004 * Set Egress DVP tables 5005 * Parameters: 5006 * IN : Unit 5007 * IN : vp 5008 * IN : vxlan_port 5009 * Returns: 5010 * BCM_E_XXX 5011 */ 5012 5013 STATIC int 5014 _bcm_td2_vxlan_egress_dvp_set(int unit, int vp, int drop, bcm_vxlan_port_t *vxlan_port) 5015 { 5016 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 5017 int rv=BCM_E_UNAVAIL; 5018 egr_dvp_attribute_entry_t egr_dvp_attribute; 5019 egr_dvp_attribute_1_entry_t egr_dvp_attribute_1; 5020 bcm_ip_t dip=0; /* DIP for tunnel header */ 5021 int tunnel_index = -1; 5022 int local_drop = 0; 5023 int network_group=0; 5024 5025 vxlan_info = VXLAN_INFO(unit); 5026 5027 tunnel_index = BCM_GPORT_TUNNEL_ID_GET(vxlan_port->egress_tunnel_id); 5028 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_index); 5029 5030 /* Obtain Tunnel DIP */ 5031 dip = vxlan_info->vxlan_tunnel_init[tunnel_index].dip; 5032 5033 /* Got HW tunnel index */ 5034 BCM_IF_ERROR_RETURN( 5035 _bcm_td2_vxlan_tunnel_initiator_idx_translate( 5036 unit, tunnel_index, &tunnel_index)); 5037 5038 /* Zero write buffer. */ 5039 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 5040 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 5041 EGR_DVP_ATTRIBUTEm, MEM_BLOCK_ANY, vp, &egr_dvp_attribute)); 5042 } else { 5043 /* Zero write buffer. */ 5044 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 5045 } 5046 5047 #if defined(BCM_TRIDENT3_SUPPORT) 5048 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, DATA_TYPEf)) { 5049 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5050 &egr_dvp_attribute, DATA_TYPEf, _BCM_VXLAN_EGRESS_DEST_VP_TYPE); 5051 } else 5052 #endif 5053 { 5054 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5055 &egr_dvp_attribute, VP_TYPEf, _BCM_VXLAN_EGRESS_DEST_VP_TYPE); 5056 } 5057 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 5058 VXLAN__TUNNEL_INDEXf, tunnel_index); 5059 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 5060 VXLAN__DIPf, dip); 5061 5062 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)){ 5063 network_group = vxlan_port->network_group_id; 5064 rv = _bcm_validate_splithorizon_network_group(unit, 5065 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 5066 BCM_IF_ERROR_RETURN(rv); 5067 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 5068 VXLAN__DVP_NETWORK_GROUPf, network_group); 5069 } else { 5070 if (!(vxlan_port->flags & BCM_VXLAN_PORT_NO_SPLIT_HORIZON_EGRESS)) { 5071 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 5072 VXLAN__DVP_IS_NETWORK_PORTf, 0x1); 5073 } 5074 } 5075 5076 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 5077 VXLAN__DISABLE_VP_PRUNINGf, 0x0); 5078 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 5079 VXLAN__DELETE_VNTAGf, 0x1); 5080 5081 #if defined(BCM_TRIDENT3_SUPPORT) 5082 if (SOC_IS_TRIDENT3X(unit)) { 5083 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5084 &egr_dvp_attribute, VXLAN__CLASS_IDf, vxlan_port->if_class); 5085 5086 /* L2 MTU - This is different from L3 MTU */ 5087 if (vxlan_port->mtu > 0) { 5088 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5089 &egr_dvp_attribute, VXLAN__MTU_VALUEf, vxlan_port->mtu); 5090 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5091 &egr_dvp_attribute, VXLAN__MTU_ENABLEf, 0x1); 5092 } else { 5093 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5094 &egr_dvp_attribute, VXLAN__MTU_VALUEf, 0x0); 5095 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5096 &egr_dvp_attribute, VXLAN__MTU_ENABLEf, 0x0); 5097 } 5098 if (vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST) { 5099 local_drop = drop ? 1 : 0; 5100 } 5101 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5102 &egr_dvp_attribute, VXLAN__UUC_DROPf, local_drop); 5103 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5104 &egr_dvp_attribute, VXLAN__UMC_DROPf, local_drop); 5105 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5106 &egr_dvp_attribute, VXLAN__BC_DROPf, local_drop); 5107 } else 5108 #endif 5109 { 5110 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 5111 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_DVP_ATTRIBUTE_1m, 5112 MEM_BLOCK_ANY, vp, &egr_dvp_attribute_1)); 5113 } else { 5114 /* Zero write buffer. */ 5115 sal_memset(&egr_dvp_attribute_1, 0, sizeof(egr_dvp_attribute_1_entry_t)); 5116 } 5117 5118 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5119 &egr_dvp_attribute_1, VXLAN__CLASS_IDf, vxlan_port->if_class); 5120 /* L2 MTU - This is different from L3 MTU */ 5121 if (vxlan_port->mtu > 0) { 5122 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5123 &egr_dvp_attribute_1, VXLAN__MTU_VALUEf, vxlan_port->mtu); 5124 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5125 &egr_dvp_attribute_1, VXLAN__MTU_ENABLEf, 0x1); 5126 } else { 5127 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5128 &egr_dvp_attribute_1, VXLAN__MTU_VALUEf, 0x0); 5129 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5130 &egr_dvp_attribute_1, VXLAN__MTU_ENABLEf, 0x0); 5131 } 5132 if (vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST) { 5133 local_drop = drop ? 1 : 0; 5134 } 5135 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5136 &egr_dvp_attribute_1, VXLAN__UUC_DROPf, local_drop); 5137 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5138 &egr_dvp_attribute_1, VXLAN__UMC_DROPf, local_drop); 5139 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTE_1m, 5140 &egr_dvp_attribute_1, VXLAN__BC_DROPf, local_drop); 5141 5142 BCM_IF_ERROR_RETURN(soc_mem_write(unit, EGR_DVP_ATTRIBUTE_1m, 5143 MEM_BLOCK_ALL, vp, &egr_dvp_attribute_1)); 5144 } 5145 5146 #if defined(BCM_TRIDENT3_SUPPORT) 5147 if(SOC_MEM_FIELD_VALID(unit,EGR_DVP_ATTRIBUTEm,VXLAN__EVXLT_KEY_SELf)) { 5148 if (vxlan_port->vnid <= 0xFFFFFF) { 5149 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5150 &egr_dvp_attribute, VXLAN__EVXLT_KEY_SELf, TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_VFI); 5151 } else { 5152 soc_mem_field32_set(unit, EGR_DVP_ATTRIBUTEm, 5153 &egr_dvp_attribute, VXLAN__EVXLT_KEY_SELf, TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_VFI); 5154 } 5155 } 5156 #endif 5157 5158 rv = soc_mem_write(unit, EGR_DVP_ATTRIBUTEm, 5159 MEM_BLOCK_ALL, vp, &egr_dvp_attribute); 5160 return rv; 5161 } 5162 5163 5164 /* 5165 * Function: 5166 * _bcm_td2_vxlan_egress_dvp_get 5167 * Purpose: 5168 * Get Egress DVP tables 5169 * Parameters: 5170 * IN : Unit 5171 * IN : vp 5172 * IN : vxlan_port 5173 * Returns: 5174 * BCM_E_XXX 5175 */ 5176 5177 STATIC int 5178 _bcm_td2_vxlan_egress_dvp_get(int unit, int vp, bcm_vxlan_port_t *vxlan_port) 5179 { 5180 _bcm_td2_vxlan_bookkeeping_t *vxlan_info; 5181 int rv=BCM_E_NONE; 5182 egr_dvp_attribute_entry_t egr_dvp_attribute; 5183 egr_dvp_attribute_1_entry_t egr_dvp_attribute_1; 5184 int tunnel_index=-1; 5185 bcm_ip_t dip=0; /* DIP for tunnel header */ 5186 int idx=0, num_vp=0; 5187 int vp_type = 0; /* access / tunnel vp type*/ 5188 int network_port = 0; 5189 _bcm_vp_info_t vp_info; 5190 5191 vxlan_info = VXLAN_INFO(unit); 5192 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 5193 5194 sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t)); 5195 rv = soc_mem_read(unit, EGR_DVP_ATTRIBUTEm, 5196 MEM_BLOCK_ANY, vp, &egr_dvp_attribute); 5197 BCM_IF_ERROR_RETURN(rv); 5198 5199 #if defined(BCM_TRIDENT3_SUPPORT) 5200 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, DATA_TYPEf)) { 5201 vp_type = soc_mem_field32_get(unit, 5202 EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, DATA_TYPEf); 5203 } else 5204 #endif 5205 { 5206 vp_type = soc_mem_field32_get(unit, 5207 EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, VP_TYPEf); 5208 } 5209 5210 /* Only mtu field is valid for access DVPs */ 5211 if (vp_type == 0) { 5212 if (soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5213 &egr_dvp_attribute, COMMON__MTU_ENABLEf)) { 5214 vxlan_port->mtu = soc_mem_field32_get(unit, 5215 EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, COMMON__MTU_VALUEf); 5216 } 5217 return rv; 5218 } 5219 5220 /* Extract Network port details */ 5221 dip = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5222 &egr_dvp_attribute, VXLAN__DIPf); 5223 5224 /* Find DIP within Softare State */ 5225 for (idx=0; idx < num_vp; idx++) { 5226 if (vxlan_info->vxlan_tunnel_init[idx].dip == dip) { 5227 tunnel_index = idx; 5228 break; 5229 } 5230 } 5231 5232 BCM_GPORT_TUNNEL_ID_SET(vxlan_port->egress_tunnel_id, tunnel_index); 5233 5234 #if defined(BCM_TRIDENT3_SUPPORT) 5235 if (SOC_IS_TRIDENT3X(unit)) { 5236 vxlan_port->if_class = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5237 &egr_dvp_attribute, VXLAN__CLASS_IDf); 5238 if (soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5239 &egr_dvp_attribute, VXLAN__MTU_ENABLEf)) { 5240 vxlan_port->mtu = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5241 &egr_dvp_attribute, VXLAN__MTU_VALUEf); 5242 } 5243 if (soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5244 &egr_dvp_attribute, VXLAN__BC_DROPf) 5245 || soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5246 &egr_dvp_attribute, VXLAN__UUC_DROPf) 5247 || soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5248 &egr_dvp_attribute, VXLAN__UMC_DROPf)) { 5249 vxlan_port->flags |= BCM_VXLAN_PORT_DROP; 5250 } 5251 } else 5252 #endif 5253 { 5254 sal_memset(&egr_dvp_attribute_1, 0, sizeof(egr_dvp_attribute_1_entry_t)); 5255 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_DVP_ATTRIBUTE_1m, 5256 MEM_BLOCK_ANY, vp, &egr_dvp_attribute_1)); 5257 5258 vxlan_port->if_class = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTE_1m, 5259 &egr_dvp_attribute_1, VXLAN__CLASS_IDf); 5260 if (soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTE_1m, 5261 &egr_dvp_attribute_1, VXLAN__MTU_ENABLEf)) { 5262 vxlan_port->mtu = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTE_1m, 5263 &egr_dvp_attribute_1, VXLAN__MTU_VALUEf); 5264 } 5265 if (soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTE_1m, 5266 &egr_dvp_attribute_1, VXLAN__BC_DROPf) 5267 || soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTE_1m, 5268 &egr_dvp_attribute_1, VXLAN__UUC_DROPf) 5269 || soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTE_1m, 5270 &egr_dvp_attribute_1, VXLAN__UMC_DROPf)) { 5271 vxlan_port->flags |= BCM_VXLAN_PORT_DROP; 5272 } 5273 } 5274 5275 if (soc_mem_field_valid(unit, EGR_DVP_ATTRIBUTEm, VXLAN__DVP_IS_NETWORK_PORTf) && 5276 (vp_type == _BCM_VXLAN_EGRESS_DEST_VP_TYPE)) { 5277 network_port = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, 5278 &egr_dvp_attribute, 5279 VXLAN__DVP_IS_NETWORK_PORTf); 5280 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 5281 if ((vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) && 5282 network_port == 0) { 5283 vxlan_port->flags |= BCM_VXLAN_PORT_NO_SPLIT_HORIZON_EGRESS; 5284 } 5285 } 5286 5287 return rv; 5288 } 5289 5290 /* 5291 * Function: 5292 * _bcm_td2_vxlan_egress_dvp_reset 5293 * Purpose: 5294 * Reet Egress DVP tables 5295 * Parameters: 5296 * IN : Unit 5297 * IN : vp 5298 * Returns: 5299 * BCM_E_XXX 5300 */ 5301 5302 STATIC int 5303 _bcm_td2_vxlan_egress_dvp_reset(int unit, int vp) 5304 { 5305 uint32 dvp[SOC_MAX_MEM_WORDS]; 5306 5307 sal_memset(dvp, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 5308 BCM_IF_ERROR_RETURN(soc_mem_write(unit, 5309 EGR_DVP_ATTRIBUTEm, MEM_BLOCK_ALL, vp, dvp)); 5310 5311 if (!SOC_IS_TRIDENT3X(unit)) { 5312 BCM_IF_ERROR_RETURN(soc_mem_write(unit, 5313 EGR_DVP_ATTRIBUTE_1m, MEM_BLOCK_ALL, vp, dvp)); 5314 } 5315 5316 return BCM_E_NONE; 5317 } 5318 5319 #if defined(BCM_TRIDENT3_SUPPORT) 5320 /* 5321 * Function: 5322 * _bcm_td3_vxlan_tpid_delete 5323 * Purpose: 5324 * del TPID 5325 * Parameters: 5326 * IN : Unit 5327 * IN : ptr of vxlate entry 5328 * IN : ptr of egr nh entry 5329 * Returns: 5330 * BCM_E_XXX 5331 */ 5332 5333 STATIC int 5334 _bcm_td3_vxlan_tpid_delete(int unit, uint32* vxlate, uint32* egr_nh){ 5335 int rv = BCM_E_NONE; 5336 int profile_idx = -1; 5337 int action_present = 0; 5338 int action_not_present = 0; 5339 int tpid_index = -1; 5340 5341 if (vxlate != NULL) { 5342 soc_mem_t vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 5343 profile_idx = soc_mem_field32_get(unit, vxlate_mem, vxlate, 5344 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 5345 (void)_bcm_td3_sd_tag_action_get(unit, profile_idx, &action_present, 5346 &action_not_present); 5347 5348 if (1 == action_present || 4 == action_present || 5349 7 == action_present || 1 == action_not_present) { 5350 tpid_index = soc_mem_field32_get(unit, 5351 vxlate_mem, vxlate, 5352 VXLAN_VFI_FLEX__OUTER_TPID_INDEXf); 5353 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 5354 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 5355 return rv; 5356 } 5357 } 5358 } else if (egr_nh != NULL) { 5359 soc_mem_t vxlate_mem = EGR_L3_NEXT_HOPm; 5360 profile_idx = soc_mem_field32_get(unit, vxlate_mem, egr_nh, 5361 L2_OTAG__TAG_ACTION_PROFILE_PTRf); 5362 (void)_bcm_td3_sd_tag_action_get(unit, profile_idx, &action_present, 5363 &action_not_present); 5364 5365 if (1 == action_present || 4 == action_present || 5366 7 == action_present || 1 == action_not_present) { 5367 tpid_index = soc_mem_field32_get(unit, 5368 vxlate_mem, egr_nh, 5369 L2_OTAG__TPID_INDEXf); 5370 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 5371 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 5372 return rv; 5373 } 5374 } 5375 } 5376 5377 return rv; 5378 } 5379 #endif 5380 5381 /* 5382 * Function: 5383 * _bcm_td2_vxlan_egr_xlate_entry_reset 5384 * Purpose: 5385 * Reset VXLAN egr_xlate Entry 5386 * Parameters: 5387 * IN : Unit 5388 * IN : vpn id 5389 * Returns: 5390 * BCM_E_XXX 5391 */ 5392 5393 STATIC int 5394 _bcm_td2_vxlan_egr_xlate_entry_reset(int unit, bcm_vpn_t vpn) 5395 { 5396 int index = 0; 5397 int vfi = 0; 5398 int tpid_index = -1; 5399 soc_mem_t vxlate_mem; 5400 uint32 vxlate[SOC_MAX_MEM_WORDS]; 5401 int action_present = 0, action_not_present = 0; 5402 int d = 0; /*vxlan decoupled mode*/ 5403 5404 sal_memset(vxlate, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 5405 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 5406 5407 #if defined(BCM_TRIDENT3_SUPPORT) 5408 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 5409 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 5410 d = 1; 5411 soc_mem_field32_set(unit, vxlate_mem, vxlate, BASE_VALIDf, 1); 5412 soc_mem_field32_set(unit, vxlate_mem, vxlate, 5413 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 5414 soc_mem_field32_set(unit, vxlate_mem, vxlate, 5415 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 5416 } else 5417 #endif 5418 { 5419 vxlate_mem = EGR_VLAN_XLATEm; 5420 soc_mem_field32_set(unit, vxlate_mem, vxlate, VALIDf, 0x1); 5421 soc_mem_field32_set(unit, vxlate_mem, vxlate, 5422 ENTRY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI); 5423 } 5424 soc_mem_field32_set(unit, vxlate_mem, vxlate, BCM_VXLAN_VFI_FIELD(d,VFIf), vfi); 5425 5426 BCM_IF_ERROR_RETURN(soc_mem_search(unit, vxlate_mem, 5427 MEM_BLOCK_ANY, &index, vxlate, vxlate, 0)); 5428 #if defined(BCM_TRIDENT3_SUPPORT) 5429 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 5430 _bcm_td3_vxlan_tpid_delete(unit, vxlate, NULL); 5431 5432 } else 5433 #endif 5434 { 5435 /* If tpid entry exist, delete it */ 5436 action_present = soc_mem_field32_get(unit, vxlate_mem, 5437 vxlate, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf); 5438 action_not_present = soc_mem_field32_get(unit, vxlate_mem, 5439 vxlate, VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf); 5440 if (1 == action_present || 4 == action_present || 5441 7 == action_present || 1 == action_not_present) { 5442 tpid_index = soc_mem_field32_get(unit, vxlate_mem, 5443 vxlate, VXLAN_VFI__SD_TAG_TPID_INDEXf); 5444 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_delete(unit, tpid_index)); 5445 } 5446 } 5447 5448 /* Delete the entry from HW */ 5449 BCM_IF_ERROR_RETURN(soc_mem_delete(unit, vxlate_mem, MEM_BLOCK_ALL, vxlate)); 5450 5451 return BCM_E_NONE; 5452 } 5453 5454 /* 5455 * Function: 5456 * _bcm_td2_vxlan_port_untagged_profile_set 5457 * Purpose: 5458 * Set VLan profile per Physical port entry 5459 * Parameters: 5460 * unit - (IN) SOC unit # 5461 * port - (IN) Physical port 5462 * Returns: 5463 * BCM_E_XXX 5464 */ 5465 5466 STATIC int 5467 _bcm_td2_vxlan_port_untagged_profile_set (int unit, bcm_port_t port) 5468 { 5469 int rv=BCM_E_NONE; 5470 bcm_vlan_action_set_t action; 5471 uint32 ing_profile_idx = 0xffffffff; 5472 5473 #if defined(BCM_TRIDENT3_SUPPORT) 5474 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 5475 return BCM_E_NONE; 5476 } 5477 #endif 5478 5479 bcm_vlan_action_set_t_init(&action); 5480 action.ut_outer = 0x0; /* No Op */ 5481 action.ut_inner = 0x0; /* No Op */ 5482 5483 rv = _bcm_trx_vlan_action_profile_entry_add(unit, &action, &ing_profile_idx); 5484 if (rv < 0) { 5485 return rv; 5486 } 5487 5488 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 5489 TAG_ACTION_PROFILE_PTRf, ing_profile_idx); 5490 return rv; 5491 } 5492 5493 /* 5494 * Function: 5495 * _bcm_td2_vxlan_port_untagged_profile_reset 5496 * Purpose: 5497 * Reset VLan profile per Physical port entry 5498 * Parameters: 5499 * unit - (IN) SOC unit # 5500 * port - (IN) Physical port 5501 * Returns: 5502 * BCM_E_XXX 5503 */ 5504 5505 STATIC int 5506 _bcm_td2_vxlan_port_untagged_profile_reset(int unit, bcm_port_t port) 5507 { 5508 int rv = BCM_E_NONE; 5509 int ing_profile_idx = -1; 5510 int def_profile_idx = 0; 5511 5512 SOC_IF_ERROR_RETURN( 5513 _bcm_esw_port_tab_get(unit, port, TAG_ACTION_PROFILE_PTRf, 5514 &ing_profile_idx)); 5515 #if defined(BCM_TRIDENT3_SUPPORT) 5516 if (SOC_IS_TRIDENT3X(unit) && (ing_profile_idx == 0)) { 5517 /*index 0 is invalid in Ingress Vlan Tag Action Profile*/ 5518 return rv; 5519 } 5520 #endif 5521 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, ing_profile_idx); 5522 if (rv < 0) { 5523 return rv; 5524 } 5525 /* default profile defined in _bcm_trx_vlan_action_profile_init */ 5526 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 5527 def_profile_idx = 1; 5528 } 5529 5530 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 5531 TAG_ACTION_PROFILE_PTRf, def_profile_idx); 5532 5533 return rv; 5534 } 5535 5536 #if defined(BCM_TRIDENT3_SUPPORT) 5537 /* 5538 * Function: 5539 * _bcm_td3_vxlan_vlan_action_set 5540 * Purpose: 5541 * Program SD_TAG settings 5542 * Parameters: 5543 * unit - (IN) SOC unit # 5544 * vxlan_port - (IN) VXLAN VP 5545 * egr_nh_info (IN/OUT) Egress NHop Info 5546 * Returns: 5547 * BCM_E_XXX 5548 */ 5549 5550 STATIC int 5551 _bcm_td3_vxlan_vlan_action_set( int unit, bcm_vxlan_vpn_config_t *vxlan_vpn_info, 5552 bcm_vxlan_port_t *vxlan_port, 5553 uint32 *vxlate_entry, 5554 int *tpid_index ) 5555 { 5556 soc_mem_t hw_mem = EGR_VLAN_XLATE_1_SINGLEm; 5557 soc_field_t vid_fld = VXLAN_VFI_FLEX__OVIDf; 5558 soc_field_t pri_fld = VXLAN_VFI_FLEX__OPRIf; 5559 soc_field_t cfi_fld = VXLAN_VFI_FLEX__OCFIf; 5560 soc_field_t pri_cfi_sel_fld = VXLAN_VFI_FLEX__OPRI_OCFI_SELf; 5561 int action_if_not_prt = 0; 5562 int action_prt = 0; 5563 uint32 profile_index = -1; 5564 5565 if (vxlan_vpn_info != NULL ) { 5566 if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_ADD) { 5567 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 5568 return BCM_E_PARAM; 5569 } 5570 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 5571 return BCM_E_PARAM; 5572 } 5573 if (vxlan_vpn_info->pkt_cfi > 1) { 5574 return BCM_E_PARAM; 5575 } 5576 soc_mem_field32_set(unit, hw_mem, 5577 vxlate_entry, vid_fld, 5578 vxlan_vpn_info->egress_service_vlan); 5579 if (soc_mem_field_valid(unit, hw_mem, 5580 pri_fld)) { 5581 soc_mem_field32_set(unit, hw_mem, 5582 vxlate_entry, pri_fld, 5583 vxlan_vpn_info->pkt_pri); 5584 } 5585 if (soc_mem_field_valid(unit, hw_mem, 5586 cfi_fld)) { 5587 soc_mem_field32_set(unit, hw_mem, 5588 vxlate_entry, cfi_fld, 5589 vxlan_vpn_info->pkt_cfi); 5590 } 5591 if (soc_mem_field_valid(unit, hw_mem, 5592 pri_cfi_sel_fld)) { 5593 soc_mem_field32_set(unit, hw_mem, 5594 vxlate_entry, pri_cfi_sel_fld, 5595 0x1); 5596 } 5597 action_if_not_prt = 0x1; /* ADD */ 5598 } 5599 5600 if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE) { 5601 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 5602 return BCM_E_PARAM; 5603 } 5604 soc_mem_field32_set(unit, hw_mem, 5605 vxlate_entry, vid_fld, 5606 vxlan_vpn_info->egress_service_vlan); 5607 action_prt = 0x1; /* REPLACE_VID_TPID */ 5608 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_REPLACE) { 5609 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 5610 return BCM_E_PARAM; 5611 } 5612 soc_mem_field32_set(unit, hw_mem, 5613 vxlate_entry, vid_fld, 5614 vxlan_vpn_info->egress_service_vlan); 5615 action_prt = 0x2; /* REPLACE_VID_ONLY */ 5616 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_DELETE) { 5617 action_prt = 0x3; /* DELETE */ 5618 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE) { 5619 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 5620 return BCM_E_PARAM; 5621 } 5622 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 5623 return BCM_E_PARAM; 5624 } 5625 if (vxlan_vpn_info->pkt_cfi > 1) { 5626 return BCM_E_PARAM; 5627 } 5628 soc_mem_field32_set(unit, hw_mem, 5629 vxlate_entry, vid_fld, 5630 vxlan_vpn_info->egress_service_vlan); 5631 if (soc_mem_field_valid(unit, hw_mem, 5632 pri_fld)) { 5633 soc_mem_field32_set(unit, hw_mem, 5634 vxlate_entry, pri_fld, 5635 vxlan_vpn_info->pkt_pri); 5636 } 5637 if (soc_mem_field_valid(unit, hw_mem, 5638 cfi_fld)) { 5639 soc_mem_field32_set(unit, hw_mem, 5640 vxlate_entry, cfi_fld, 5641 vxlan_vpn_info->pkt_cfi); 5642 } 5643 if (soc_mem_field_valid(unit, hw_mem, 5644 pri_cfi_sel_fld)) { 5645 soc_mem_field32_set(unit, hw_mem, 5646 vxlate_entry, pri_cfi_sel_fld, 5647 0x1); 5648 } 5649 action_prt = 0x4; /* REPLACE_VID_PRI_TPID */ 5650 5651 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_REPLACE ){ 5652 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 5653 return BCM_E_PARAM; 5654 } 5655 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 5656 return BCM_E_PARAM; 5657 } 5658 if (vxlan_vpn_info->pkt_cfi > 1) { 5659 return BCM_E_PARAM; 5660 } 5661 soc_mem_field32_set(unit, hw_mem, 5662 vxlate_entry, vid_fld, 5663 vxlan_vpn_info->egress_service_vlan); 5664 5665 if (soc_mem_field_valid(unit, hw_mem, 5666 pri_fld)) { 5667 soc_mem_field32_set(unit, hw_mem, 5668 vxlate_entry, pri_fld, 5669 vxlan_vpn_info->pkt_pri); 5670 } 5671 if (soc_mem_field_valid(unit, hw_mem, 5672 cfi_fld)) { 5673 soc_mem_field32_set(unit, hw_mem, 5674 vxlate_entry, cfi_fld, 5675 vxlan_vpn_info->pkt_cfi); 5676 } 5677 if (soc_mem_field_valid(unit, hw_mem, 5678 pri_cfi_sel_fld)) { 5679 soc_mem_field32_set(unit, hw_mem, 5680 vxlate_entry, pri_cfi_sel_fld, 5681 0x1); 5682 } 5683 5684 action_prt = 0x5; /* REPLACE_VID_PRI */ 5685 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_PRI_REPLACE ) { 5686 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 5687 return BCM_E_PARAM; 5688 } 5689 if (vxlan_vpn_info->pkt_cfi > 1) { 5690 return BCM_E_PARAM; 5691 } 5692 if (soc_mem_field_valid(unit, hw_mem, 5693 pri_fld)) { 5694 soc_mem_field32_set(unit, hw_mem, 5695 vxlate_entry, pri_fld, 5696 vxlan_vpn_info->pkt_pri); 5697 } 5698 if (soc_mem_field_valid(unit, hw_mem, 5699 cfi_fld)) { 5700 soc_mem_field32_set(unit, hw_mem, 5701 vxlate_entry, cfi_fld, 5702 vxlan_vpn_info->pkt_cfi); 5703 } 5704 if (soc_mem_field_valid(unit, hw_mem, 5705 pri_cfi_sel_fld)) { 5706 soc_mem_field32_set(unit, hw_mem, 5707 vxlate_entry, pri_cfi_sel_fld, 5708 0x1); 5709 } 5710 action_prt = 0x6; /* REPLACE_PRI_ONLY */ 5711 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_TPID_REPLACE ) { 5712 action_prt = 0x7; /* REPLACE_TPID_ONLY */ 5713 } 5714 5715 profile_index = soc_mem_field32_get(unit, hw_mem, vxlate_entry, 5716 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 5717 _bcm_td3_sd_tag_action_profile_get(unit, action_prt, 5718 action_if_not_prt, &profile_index); 5719 soc_mem_field32_set(unit, hw_mem, vxlate_entry, VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf, 5720 profile_index); 5721 5722 if ((vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_ADD) || 5723 (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE) || 5724 (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_TPID_REPLACE) || 5725 (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE)) { 5726 /* TPID value is used */ 5727 BCM_IF_ERROR_RETURN( 5728 _bcm_fb2_outer_tpid_entry_add(unit, vxlan_vpn_info->egress_service_tpid, tpid_index)); 5729 soc_mem_field32_set(unit, hw_mem, 5730 vxlate_entry, VXLAN_VFI_FLEX__OUTER_TPID_INDEXf, *tpid_index); 5731 } 5732 } else if (vxlan_port != NULL) { 5733 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) { 5734 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 5735 return BCM_E_PARAM; 5736 } 5737 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 5738 return BCM_E_PARAM; 5739 } 5740 if (vxlan_port->pkt_cfi > 1) { 5741 return BCM_E_PARAM; 5742 } 5743 soc_mem_field32_set(unit, hw_mem, 5744 vxlate_entry, vid_fld, 5745 vxlan_port->egress_service_vlan); 5746 if (soc_mem_field_valid(unit, hw_mem, 5747 pri_fld)) { 5748 soc_mem_field32_set(unit, hw_mem, 5749 vxlate_entry, pri_fld, 5750 vxlan_port->pkt_pri); 5751 } 5752 if (soc_mem_field_valid(unit, hw_mem, 5753 cfi_fld)) { 5754 soc_mem_field32_set(unit, hw_mem, 5755 vxlate_entry, cfi_fld, 5756 vxlan_port->pkt_cfi); 5757 } 5758 if (soc_mem_field_valid(unit, hw_mem, 5759 pri_cfi_sel_fld)) { 5760 soc_mem_field32_set(unit, hw_mem, 5761 vxlate_entry, pri_cfi_sel_fld, 5762 0x1); 5763 } 5764 action_if_not_prt = 0x1; /* ADD */ 5765 } 5766 5767 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) { 5768 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 5769 return BCM_E_PARAM; 5770 } 5771 soc_mem_field32_set(unit, hw_mem, 5772 vxlate_entry, vid_fld, 5773 vxlan_port->egress_service_vlan); 5774 action_prt = 0x1; /* REPLACE_VID_TPID */ 5775 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE) { 5776 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 5777 return BCM_E_PARAM; 5778 } 5779 soc_mem_field32_set(unit, hw_mem, 5780 vxlate_entry, vid_fld, 5781 vxlan_port->egress_service_vlan); 5782 action_prt = 0x2; /* REPLACE_VID_ONLY */ 5783 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_DELETE) { 5784 action_prt = 0x3; /* DELETE */ 5785 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE) { 5786 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 5787 return BCM_E_PARAM; 5788 } 5789 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 5790 return BCM_E_PARAM; 5791 } 5792 if (vxlan_port->pkt_cfi > 1) { 5793 return BCM_E_PARAM; 5794 } 5795 soc_mem_field32_set(unit, hw_mem, 5796 vxlate_entry, vid_fld, 5797 vxlan_port->egress_service_vlan); 5798 if (soc_mem_field_valid(unit, hw_mem, 5799 pri_fld)) { 5800 soc_mem_field32_set(unit, hw_mem, 5801 vxlate_entry, pri_fld, 5802 vxlan_port->pkt_pri); 5803 } 5804 if (soc_mem_field_valid(unit, hw_mem, 5805 cfi_fld)) { 5806 soc_mem_field32_set(unit, hw_mem, 5807 vxlate_entry, cfi_fld, 5808 vxlan_port->pkt_cfi); 5809 } 5810 if (soc_mem_field_valid(unit, hw_mem, 5811 pri_cfi_sel_fld)) { 5812 soc_mem_field32_set(unit, hw_mem, 5813 vxlate_entry, pri_cfi_sel_fld, 5814 0x1); 5815 } 5816 5817 action_prt = 0x4; /* REPLACE_VID_PRI_TPID */ 5818 5819 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE ){ 5820 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 5821 return BCM_E_PARAM; 5822 } 5823 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 5824 return BCM_E_PARAM; 5825 } 5826 if (vxlan_port->pkt_cfi > 1) { 5827 return BCM_E_PARAM; 5828 } 5829 soc_mem_field32_set(unit, hw_mem, 5830 vxlate_entry, vid_fld, 5831 vxlan_port->egress_service_vlan); 5832 5833 if (soc_mem_field_valid(unit, hw_mem, 5834 pri_fld)) { 5835 soc_mem_field32_set(unit, hw_mem, 5836 vxlate_entry, pri_fld, 5837 vxlan_port->pkt_pri); 5838 } 5839 if (soc_mem_field_valid(unit, hw_mem, 5840 cfi_fld)) { 5841 soc_mem_field32_set(unit, hw_mem, 5842 vxlate_entry, cfi_fld, 5843 vxlan_port->pkt_cfi); 5844 } 5845 if (soc_mem_field_valid(unit, hw_mem, 5846 pri_cfi_sel_fld)) { 5847 soc_mem_field32_set(unit, hw_mem, 5848 vxlate_entry, pri_cfi_sel_fld, 5849 0x1); 5850 } 5851 5852 action_prt = 0x5; /* REPLACE_VID_PRI */ 5853 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_PRI_REPLACE ) { 5854 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 5855 return BCM_E_PARAM; 5856 } 5857 if (vxlan_port->pkt_cfi > 1) { 5858 return BCM_E_PARAM; 5859 } 5860 if (soc_mem_field_valid(unit, hw_mem, 5861 pri_fld)) { 5862 soc_mem_field32_set(unit, hw_mem, 5863 vxlate_entry, pri_fld, 5864 vxlan_port->pkt_pri); 5865 } 5866 if (soc_mem_field_valid(unit, hw_mem, 5867 cfi_fld)) { 5868 soc_mem_field32_set(unit, hw_mem, 5869 vxlate_entry, cfi_fld, 5870 vxlan_port->pkt_cfi); 5871 } 5872 if (soc_mem_field_valid(unit, hw_mem, 5873 pri_cfi_sel_fld)) { 5874 soc_mem_field32_set(unit, hw_mem, 5875 vxlate_entry, pri_cfi_sel_fld, 5876 0x1); 5877 } 5878 action_prt = 0x6; /* REPLACE_PRI_ONLY */ 5879 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE ) { 5880 action_prt = 0x7; /* REPLACE_TPID_ONLY */ 5881 } 5882 5883 profile_index = soc_mem_field32_get(unit, hw_mem, vxlate_entry, 5884 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 5885 _bcm_td3_sd_tag_action_profile_get(unit, action_prt, 5886 action_if_not_prt, &profile_index); 5887 soc_mem_field32_set(unit, hw_mem, vxlate_entry, VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf, 5888 profile_index); 5889 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 5890 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 5891 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE) || 5892 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 5893 /* TPID value is used */ 5894 BCM_IF_ERROR_RETURN( 5895 _bcm_fb2_outer_tpid_entry_add(unit, vxlan_port->egress_service_tpid, tpid_index)); 5896 soc_mem_field32_set(unit, hw_mem, 5897 vxlate_entry, VXLAN_VFI_FLEX__OUTER_TPID_INDEXf, *tpid_index); 5898 } 5899 } 5900 return BCM_E_NONE; 5901 } 5902 5903 /* 5904 * Function: 5905 * _bcm_td3_vxlan_vlan_action_get 5906 * Purpose: 5907 * Get SD_TAG settings 5908 * Parameters: 5909 * unit - (IN) SOC unit # 5910 * vxlan_port - (IN) VXLAN VP 5911 * egr_nh_info (IN/OUT) Egress NHop Info 5912 * Returns: 5913 * BCM_E_XXX 5914 */ 5915 5916 STATIC void 5917 _bcm_td3_vxlan_vlan_action_get( int unit, bcm_vxlan_vpn_config_t *vxlan_vpn_info, 5918 bcm_vxlan_port_t *vxlan_port, 5919 egr_l3_next_hop_entry_t *egr_nh, 5920 uint32 *vxlate_entry, 5921 int network_port_flag ) 5922 { 5923 int action_present=0, action_not_present=0, tpid_index = 0; 5924 soc_mem_t vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 5925 int profile_index = -1; 5926 uint32 flags = 0; 5927 bcm_vlan_t egress_service_vlan = 0; 5928 uint8 pkt_pri = 0; 5929 uint8 pkt_cfi = 0; 5930 uint16 egress_service_tpid = 0; 5931 soc_field_t vid_fld = VXLAN_VFI_FLEX__OVIDf; 5932 soc_field_t pri_fld = VXLAN_VFI_FLEX__OPRIf; 5933 soc_field_t cfi_fld = VXLAN_VFI_FLEX__OCFIf; 5934 5935 if (network_port_flag) { 5936 profile_index = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 5937 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 5938 (void)_bcm_td3_sd_tag_action_get(unit, profile_index, &action_present, 5939 &action_not_present); 5940 5941 if (action_not_present == 1) { 5942 flags |= BCM_VXLAN_VPN_SERVICE_TAGGED; 5943 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_ADD; 5944 egress_service_vlan = soc_mem_field32_get(unit, 5945 vxlate_mem, vxlate_entry, vid_fld); 5946 } 5947 5948 if (action_present) { 5949 flags |= BCM_VXLAN_VPN_SERVICE_TAGGED; 5950 } 5951 switch (action_present) { 5952 case 1: 5953 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE; 5954 egress_service_vlan = soc_mem_field32_get(unit, 5955 vxlate_mem, vxlate_entry, vid_fld); 5956 break; 5957 5958 case 2: 5959 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_REPLACE; 5960 egress_service_vlan = soc_mem_field32_get(unit, 5961 vxlate_mem, vxlate_entry, vid_fld); 5962 break; 5963 5964 case 3: 5965 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_DELETE; 5966 egress_service_vlan = BCM_VLAN_INVALID; 5967 break; 5968 5969 case 4: 5970 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE; 5971 egress_service_vlan = soc_mem_field32_get(unit, 5972 vxlate_mem, vxlate_entry, vid_fld); 5973 pkt_pri = soc_mem_field32_get(unit, 5974 vxlate_mem, vxlate_entry, pri_fld); 5975 pkt_cfi = soc_mem_field32_get(unit, 5976 vxlate_mem, vxlate_entry, cfi_fld); 5977 break; 5978 5979 case 5: 5980 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_PRI_REPLACE; 5981 egress_service_vlan = soc_mem_field32_get(unit, 5982 vxlate_mem, vxlate_entry, vid_fld); 5983 pkt_pri = soc_mem_field32_get(unit, 5984 vxlate_mem, vxlate_entry, pri_fld); 5985 pkt_cfi = soc_mem_field32_get(unit, 5986 vxlate_mem, vxlate_entry, cfi_fld); 5987 break; 5988 5989 case 6: 5990 flags |= BCM_VXLAN_VPN_SERVICE_PRI_REPLACE; 5991 egress_service_vlan = BCM_VLAN_INVALID; 5992 pkt_pri = soc_mem_field32_get(unit, 5993 vxlate_mem, vxlate_entry, pri_fld); 5994 pkt_cfi = soc_mem_field32_get(unit, 5995 vxlate_mem, vxlate_entry, cfi_fld); 5996 break; 5997 5998 case 7: 5999 flags |= BCM_VXLAN_VPN_SERVICE_TPID_REPLACE; 6000 egress_service_vlan = BCM_VLAN_INVALID; 6001 break; 6002 6003 default: 6004 break; 6005 } 6006 6007 if ((flags & BCM_VXLAN_VPN_SERVICE_VLAN_ADD) || 6008 (flags & BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE) || 6009 (flags & BCM_VXLAN_VPN_SERVICE_TPID_REPLACE) || 6010 (flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6011 tpid_index = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 6012 VXLAN_VFI_FLEX__OUTER_TPID_INDEXf); 6013 _bcm_fb2_outer_tpid_entry_get(unit, 6014 &egress_service_tpid, tpid_index); 6015 } 6016 6017 if (vxlan_vpn_info != NULL) { 6018 vxlan_vpn_info->flags |= flags; 6019 vxlan_vpn_info->egress_service_vlan = egress_service_vlan; 6020 vxlan_vpn_info->egress_service_tpid = egress_service_tpid; 6021 vxlan_vpn_info->pkt_pri = pkt_pri; 6022 vxlan_vpn_info->pkt_cfi = pkt_cfi; 6023 } 6024 if (vxlan_port != NULL) { 6025 vxlan_port->flags |= flags; 6026 vxlan_port->egress_service_vlan = egress_service_vlan; 6027 vxlan_port->egress_service_tpid = egress_service_tpid; 6028 vxlan_port->pkt_pri = pkt_pri; 6029 vxlan_port->pkt_cfi = pkt_cfi; 6030 } 6031 6032 } else { 6033 vid_fld = L2_OTAG__VIDf; 6034 pri_fld = L2_OTAG__PCPf; 6035 cfi_fld = L2_OTAG__DEf; 6036 profile_index = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, egr_nh, 6037 L2_OTAG__TAG_ACTION_PROFILE_PTRf); 6038 (void)_bcm_td3_sd_tag_action_get(unit, profile_index, &action_present, 6039 &action_not_present); 6040 6041 if (action_not_present == 1) { 6042 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_ADD; 6043 vxlan_port->egress_service_vlan = 6044 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, vid_fld); 6045 } 6046 6047 switch (action_present) { 6048 case 1: 6049 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE; 6050 vxlan_port->egress_service_vlan = 6051 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, vid_fld); 6052 break; 6053 6054 case 2: 6055 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE; 6056 vxlan_port->egress_service_vlan = 6057 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, vid_fld); 6058 break; 6059 6060 case 3: 6061 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_DELETE; 6062 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6063 break; 6064 6065 case 4: 6066 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE; 6067 vxlan_port->egress_service_vlan = 6068 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, vid_fld); 6069 vxlan_port->pkt_pri = 6070 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, pri_fld); 6071 vxlan_port->pkt_cfi = 6072 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, cfi_fld); 6073 break; 6074 6075 case 5: 6076 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE; 6077 vxlan_port->egress_service_vlan = 6078 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, vid_fld); 6079 vxlan_port->pkt_pri = 6080 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, pri_fld); 6081 vxlan_port->pkt_cfi = 6082 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, cfi_fld); 6083 break; 6084 6085 case 6: 6086 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_PRI_REPLACE; 6087 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6088 vxlan_port->pkt_pri = 6089 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, pri_fld); 6090 vxlan_port->pkt_cfi = 6091 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, cfi_fld); 6092 break; 6093 6094 case 7: 6095 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_TPID_REPLACE; 6096 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6097 break; 6098 6099 default: 6100 break; 6101 } 6102 6103 if (soc_feature(unit, soc_feature_vp_sharing) && 6104 soc_feature(unit, soc_feature_egr_intf_vlan_vfi_deoverlay)) { 6105 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 6106 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 6107 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE) || 6108 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE) || 6109 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6110 vxlan_port->egress_service_vlan = (vxlan_port->egress_service_vlan == 0) ? 6111 BCM_VLAN_INVALID : vxlan_port->egress_service_vlan; 6112 } 6113 } 6114 6115 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 6116 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 6117 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE) || 6118 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6119 /* TPID value is used */ 6120 tpid_index = soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, L2_OTAG__TPID_INDEXf); 6121 _bcm_fb2_outer_tpid_entry_get(unit, &vxlan_port->egress_service_tpid, tpid_index); 6122 } 6123 } 6124 } 6125 6126 #endif 6127 6128 /* 6129 * Function: 6130 * _bcm_td2_vxlan_sd_tag_set 6131 * Purpose: 6132 * Program SD_TAG settings 6133 * Parameters: 6134 * unit - (IN) SOC unit # 6135 * vxlan_port - (IN) VXLAN VP 6136 * egr_nh_info (IN/OUT) Egress NHop Info 6137 * Returns: 6138 * BCM_E_XXX 6139 */ 6140 6141 STATIC int 6142 _bcm_td2_vxlan_sd_tag_set( int unit, bcm_vxlan_vpn_config_t *vxlan_vpn_info, 6143 bcm_vxlan_port_t *vxlan_port, 6144 _bcm_td2_vxlan_nh_info_t *egr_nh_info, 6145 uint32 *vxlate_entry, 6146 int *tpid_index ) 6147 { 6148 soc_mem_t hw_mem; 6149 6150 if (vxlan_vpn_info != NULL ) { 6151 #if defined(BCM_TRIDENT3_SUPPORT) 6152 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 6153 int rv = BCM_E_NONE; 6154 rv = _bcm_td3_vxlan_vlan_action_set(unit, vxlan_vpn_info, NULL, vxlate_entry, tpid_index); 6155 return rv; 6156 } 6157 #endif 6158 #if defined(BCM_TRIDENT3_SUPPORT) 6159 if (soc_feature(unit, soc_feature_base_valid)) { 6160 hw_mem = EGR_VLAN_XLATE_1_DOUBLEm; 6161 } else 6162 #endif 6163 { 6164 hw_mem = EGR_VLAN_XLATEm; 6165 } 6166 6167 if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_ADD) { 6168 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 6169 return BCM_E_PARAM; 6170 } 6171 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 6172 return BCM_E_PARAM; 6173 } 6174 if (vxlan_vpn_info->pkt_cfi > 1) { 6175 return BCM_E_PARAM; 6176 } 6177 soc_mem_field32_set(unit, hw_mem, 6178 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6179 vxlan_vpn_info->egress_service_vlan); 6180 if (soc_mem_field_valid(unit, hw_mem, 6181 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6182 soc_mem_field32_set(unit, hw_mem, 6183 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6184 vxlan_vpn_info->pkt_pri); 6185 } 6186 if (soc_mem_field_valid(unit, hw_mem, 6187 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6188 soc_mem_field32_set(unit, hw_mem, 6189 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6190 vxlan_vpn_info->pkt_cfi); 6191 } 6192 if (soc_mem_field_valid(unit, hw_mem, 6193 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6194 soc_mem_field32_set(unit, hw_mem, 6195 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6196 0x1); 6197 } 6198 soc_mem_field32_set(unit, hw_mem, 6199 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf, 6200 0x1); /* ADD */ 6201 } 6202 6203 if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE) { 6204 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 6205 return BCM_E_PARAM; 6206 } 6207 soc_mem_field32_set(unit, hw_mem, 6208 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6209 vxlan_vpn_info->egress_service_vlan); 6210 soc_mem_field32_set(unit, hw_mem, 6211 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6212 0x1); /* REPLACE_VID_TPID */ 6213 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_REPLACE) { 6214 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 6215 return BCM_E_PARAM; 6216 } 6217 soc_mem_field32_set(unit, hw_mem, 6218 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6219 vxlan_vpn_info->egress_service_vlan); 6220 soc_mem_field32_set(unit, hw_mem, 6221 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6222 0x2); /* REPLACE_VID_ONLY */ 6223 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_DELETE) { 6224 soc_mem_field32_set(unit, hw_mem, 6225 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6226 0x3); /* DELETE */ 6227 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE) { 6228 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 6229 return BCM_E_PARAM; 6230 } 6231 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 6232 return BCM_E_PARAM; 6233 } 6234 if (vxlan_vpn_info->pkt_cfi > 1) { 6235 return BCM_E_PARAM; 6236 } 6237 soc_mem_field32_set(unit, hw_mem, 6238 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6239 vxlan_vpn_info->egress_service_vlan); 6240 if (soc_mem_field_valid(unit, hw_mem, 6241 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6242 soc_mem_field32_set(unit, hw_mem, 6243 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6244 vxlan_vpn_info->pkt_pri); 6245 } 6246 if (soc_mem_field_valid(unit, hw_mem, 6247 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6248 soc_mem_field32_set(unit, hw_mem, 6249 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6250 vxlan_vpn_info->pkt_cfi); 6251 } 6252 if (soc_mem_field_valid(unit, hw_mem, 6253 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6254 soc_mem_field32_set(unit, hw_mem, 6255 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6256 0x1); 6257 } 6258 6259 soc_mem_field32_set(unit, hw_mem, 6260 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6261 0x4); /* REPLACE_VID_PRI_TPID */ 6262 6263 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_REPLACE ){ 6264 if (vxlan_vpn_info->egress_service_vlan >= BCM_VLAN_INVALID) { 6265 return BCM_E_PARAM; 6266 } 6267 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 6268 return BCM_E_PARAM; 6269 } 6270 if (vxlan_vpn_info->pkt_cfi > 1) { 6271 return BCM_E_PARAM; 6272 } 6273 soc_mem_field32_set(unit, hw_mem, 6274 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6275 vxlan_vpn_info->egress_service_vlan); 6276 6277 if (soc_mem_field_valid(unit, hw_mem, 6278 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6279 soc_mem_field32_set(unit, hw_mem, 6280 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6281 vxlan_vpn_info->pkt_pri); 6282 } 6283 if (soc_mem_field_valid(unit, hw_mem, 6284 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6285 soc_mem_field32_set(unit, hw_mem, 6286 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6287 vxlan_vpn_info->pkt_cfi); 6288 } 6289 if (soc_mem_field_valid(unit, hw_mem, 6290 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6291 soc_mem_field32_set(unit, hw_mem, 6292 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6293 0x1); 6294 } 6295 6296 soc_mem_field32_set(unit, hw_mem, 6297 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6298 0x5); /* REPLACE_VID_PRI */ 6299 }else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_PRI_REPLACE ) { 6300 if (vxlan_vpn_info->pkt_pri > BCM_PRIO_MAX) { 6301 return BCM_E_PARAM; 6302 } 6303 if (vxlan_vpn_info->pkt_cfi > 1) { 6304 return BCM_E_PARAM; 6305 } 6306 if (soc_mem_field_valid(unit, hw_mem, 6307 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6308 soc_mem_field32_set(unit, hw_mem, 6309 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6310 vxlan_vpn_info->pkt_pri); 6311 } 6312 if (soc_mem_field_valid(unit, hw_mem, 6313 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6314 soc_mem_field32_set(unit, hw_mem, 6315 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6316 vxlan_vpn_info->pkt_cfi); 6317 } 6318 if (soc_mem_field_valid(unit, hw_mem, 6319 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6320 soc_mem_field32_set(unit, hw_mem, 6321 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6322 0x1); 6323 } 6324 6325 soc_mem_field32_set(unit, hw_mem, 6326 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6327 0x6); /* REPLACE_PRI_ONLY */ 6328 6329 } else if (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_TPID_REPLACE ) { 6330 soc_mem_field32_set(unit, hw_mem, 6331 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6332 0x7); /* REPLACE_TPID_ONLY */ 6333 } 6334 6335 if ((vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_ADD) || 6336 (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE) || 6337 (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_TPID_REPLACE) || 6338 (vxlan_vpn_info->flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6339 /* TPID value is used */ 6340 BCM_IF_ERROR_RETURN( 6341 _bcm_fb2_outer_tpid_entry_add(unit, vxlan_vpn_info->egress_service_tpid, tpid_index)); 6342 soc_mem_field32_set(unit, hw_mem, 6343 vxlate_entry, VXLAN_VFI__SD_TAG_TPID_INDEXf, *tpid_index); 6344 } 6345 } else if (vxlan_port != NULL && egr_nh_info != NULL) { 6346 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) { 6347 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6348 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6349 if (soc_feature(unit, soc_feature_vp_sharing)) { 6350 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 6351 } else 6352 #endif 6353 { 6354 return BCM_E_PARAM; 6355 } 6356 6357 } 6358 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6359 return BCM_E_PARAM; 6360 } 6361 if (vxlan_port->pkt_cfi > 1) { 6362 return BCM_E_PARAM; 6363 } 6364 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 6365 egr_nh_info->sd_tag_vlan = vxlan_port->egress_service_vlan; 6366 } 6367 egr_nh_info->sd_tag_pri = vxlan_port->pkt_pri; 6368 egr_nh_info->sd_tag_cfi = vxlan_port->pkt_cfi; 6369 egr_nh_info->sd_tag_action_not_present = 0x1; /* ADD */ 6370 } 6371 6372 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) { 6373 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6374 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6375 if (soc_feature(unit, soc_feature_vp_sharing)) { 6376 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 6377 } else 6378 #endif 6379 { 6380 return BCM_E_PARAM; 6381 } 6382 } 6383 /* REPLACE_VID_TPID */ 6384 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 6385 egr_nh_info->sd_tag_vlan = vxlan_port->egress_service_vlan; 6386 } 6387 egr_nh_info->sd_tag_action_present = 0x1; 6388 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE) { 6389 6390 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6391 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6392 if (soc_feature(unit, soc_feature_vp_sharing)) { 6393 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 6394 } else 6395 #endif 6396 { 6397 return BCM_E_PARAM; 6398 } 6399 } 6400 /* REPLACE_VID_ONLY */ 6401 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 6402 egr_nh_info->sd_tag_vlan = vxlan_port->egress_service_vlan; 6403 } 6404 egr_nh_info->sd_tag_action_present = 0x2; 6405 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_DELETE) { 6406 egr_nh_info->sd_tag_action_present = 0x3; /* DELETE */ 6407 egr_nh_info->sd_tag_action_not_present = 0; 6408 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE) { 6409 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6410 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6411 if (soc_feature(unit, soc_feature_vp_sharing)) { 6412 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 6413 } else 6414 #endif 6415 { 6416 return BCM_E_PARAM; 6417 } 6418 } 6419 6420 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6421 return BCM_E_PARAM; 6422 } 6423 if (vxlan_port->pkt_cfi <= 1) { 6424 egr_nh_info->sd_tag_cfi = vxlan_port->pkt_cfi; 6425 } else if (vxlan_port->pkt_cfi == (uint8)-1) { 6426 egr_nh_info->sd_tag_cfi = -1; 6427 } else { 6428 return BCM_E_PARAM; 6429 } 6430 6431 /* REPLACE_VID_PRI_TPID */ 6432 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 6433 egr_nh_info->sd_tag_vlan = vxlan_port->egress_service_vlan; 6434 } 6435 egr_nh_info->sd_tag_pri = vxlan_port->pkt_pri; 6436 egr_nh_info->sd_tag_action_present = 0x4; 6437 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE ) { 6438 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6439 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6440 if (soc_feature(unit, soc_feature_vp_sharing)) { 6441 egr_nh_info->sd_tag_vlan = BCM_VLAN_INVALID; 6442 } else 6443 #endif 6444 { 6445 return BCM_E_PARAM; 6446 } 6447 } 6448 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6449 return BCM_E_PARAM; 6450 } 6451 if (vxlan_port->pkt_cfi <= 1) { 6452 egr_nh_info->sd_tag_cfi = vxlan_port->pkt_cfi; 6453 } else if (vxlan_port->pkt_cfi == (uint8)-1) { 6454 egr_nh_info->sd_tag_cfi = -1; 6455 } else { 6456 return BCM_E_PARAM; 6457 } 6458 6459 /* REPLACE_VID_PRI_ONLY */ 6460 if (egr_nh_info->sd_tag_vlan != BCM_VLAN_INVALID) { 6461 egr_nh_info->sd_tag_vlan = vxlan_port->egress_service_vlan; 6462 } 6463 egr_nh_info->sd_tag_pri = vxlan_port->pkt_pri; 6464 egr_nh_info->sd_tag_action_present = 0x5; 6465 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_PRI_REPLACE ) { 6466 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6467 return BCM_E_PARAM; 6468 } 6469 if (vxlan_port->pkt_cfi <= 1) { 6470 egr_nh_info->sd_tag_cfi = vxlan_port->pkt_cfi; 6471 } else if (vxlan_port->pkt_cfi == (uint8)-1) { 6472 egr_nh_info->sd_tag_cfi = -1; 6473 } else { 6474 return BCM_E_PARAM; 6475 } 6476 6477 /* REPLACE_PRI_ONLY */ 6478 egr_nh_info->sd_tag_pri = vxlan_port->pkt_pri; 6479 egr_nh_info->sd_tag_action_present = 0x6; 6480 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE ) { 6481 /* REPLACE_TPID_ONLY */ 6482 egr_nh_info->sd_tag_action_present = 0x7; 6483 } 6484 6485 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 6486 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 6487 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE) || 6488 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6489 /* TPID value is used */ 6490 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_add(unit, vxlan_port->egress_service_tpid, tpid_index)); 6491 egr_nh_info->tpid_index = *tpid_index; 6492 } 6493 } else if (vxlan_port != NULL) { 6494 #if defined(BCM_TRIDENT3_SUPPORT) 6495 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 6496 int rv = BCM_E_NONE; 6497 rv = _bcm_td3_vxlan_vlan_action_set(unit, NULL, vxlan_port, vxlate_entry, tpid_index); 6498 return rv; 6499 } 6500 #endif 6501 hw_mem = EGR_VLAN_XLATEm; 6502 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) { 6503 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6504 return BCM_E_PARAM; 6505 } 6506 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6507 return BCM_E_PARAM; 6508 } 6509 if (vxlan_port->pkt_cfi > 1) { 6510 return BCM_E_PARAM; 6511 } 6512 soc_mem_field32_set(unit, hw_mem, 6513 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6514 vxlan_port->egress_service_vlan); 6515 if (soc_mem_field_valid(unit, hw_mem, 6516 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6517 soc_mem_field32_set(unit, hw_mem, 6518 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6519 vxlan_port->pkt_pri); 6520 } 6521 if (soc_mem_field_valid(unit, hw_mem, 6522 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6523 soc_mem_field32_set(unit, hw_mem, 6524 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6525 vxlan_port->pkt_cfi); 6526 } 6527 if (soc_mem_field_valid(unit, hw_mem, 6528 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6529 soc_mem_field32_set(unit, hw_mem, 6530 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6531 0x1); 6532 } 6533 soc_mem_field32_set(unit, hw_mem, 6534 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf, 6535 0x1); /* ADD */ 6536 } 6537 6538 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) { 6539 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6540 return BCM_E_PARAM; 6541 } 6542 soc_mem_field32_set(unit, hw_mem, 6543 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6544 vxlan_port->egress_service_vlan); 6545 soc_mem_field32_set(unit, hw_mem, 6546 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6547 0x1); /* REPLACE_VID_TPID */ 6548 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE) { 6549 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6550 return BCM_E_PARAM; 6551 } 6552 soc_mem_field32_set(unit, hw_mem, 6553 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6554 vxlan_port->egress_service_vlan); 6555 soc_mem_field32_set(unit, hw_mem, 6556 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6557 0x2); /* REPLACE_VID_ONLY */ 6558 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_DELETE) { 6559 soc_mem_field32_set(unit, hw_mem, 6560 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6561 0x3); /* DELETE */ 6562 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE) { 6563 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6564 return BCM_E_PARAM; 6565 } 6566 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6567 return BCM_E_PARAM; 6568 } 6569 if (vxlan_port->pkt_cfi > 1) { 6570 return BCM_E_PARAM; 6571 } 6572 soc_mem_field32_set(unit, hw_mem, 6573 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6574 vxlan_port->egress_service_vlan); 6575 if (soc_mem_field_valid(unit, hw_mem, 6576 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6577 soc_mem_field32_set(unit, hw_mem, 6578 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6579 vxlan_port->pkt_pri); 6580 } 6581 if (soc_mem_field_valid(unit, hw_mem, 6582 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6583 soc_mem_field32_set(unit, hw_mem, 6584 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6585 vxlan_port->pkt_cfi); 6586 } 6587 if (soc_mem_field_valid(unit, hw_mem, 6588 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6589 soc_mem_field32_set(unit, hw_mem, 6590 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6591 0x1); 6592 } 6593 6594 soc_mem_field32_set(unit, hw_mem, 6595 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6596 0x4); /* REPLACE_VID_PRI_TPID */ 6597 6598 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE ){ 6599 if (vxlan_port->egress_service_vlan >= BCM_VLAN_INVALID) { 6600 return BCM_E_PARAM; 6601 } 6602 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6603 return BCM_E_PARAM; 6604 } 6605 if (vxlan_port->pkt_cfi > 1) { 6606 return BCM_E_PARAM; 6607 } 6608 soc_mem_field32_set(unit, hw_mem, 6609 vxlate_entry, VXLAN_VFI__SD_TAG_VIDf, 6610 vxlan_port->egress_service_vlan); 6611 6612 if (soc_mem_field_valid(unit, hw_mem, 6613 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6614 soc_mem_field32_set(unit, hw_mem, 6615 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6616 vxlan_port->pkt_pri); 6617 } 6618 if (soc_mem_field_valid(unit, hw_mem, 6619 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6620 soc_mem_field32_set(unit, hw_mem, 6621 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6622 vxlan_port->pkt_cfi); 6623 } 6624 if (soc_mem_field_valid(unit, hw_mem, 6625 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6626 soc_mem_field32_set(unit, hw_mem, 6627 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6628 0x1); 6629 } 6630 6631 soc_mem_field32_set(unit, hw_mem, 6632 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6633 0x5); /* REPLACE_VID_PRI */ 6634 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_PRI_REPLACE ) { 6635 if (vxlan_port->pkt_pri > BCM_PRIO_MAX) { 6636 return BCM_E_PARAM; 6637 } 6638 if (vxlan_port->pkt_cfi > 1) { 6639 return BCM_E_PARAM; 6640 } 6641 if (soc_mem_field_valid(unit, hw_mem, 6642 VXLAN_VFI__SD_TAG_NEW_PRIf)) { 6643 soc_mem_field32_set(unit, hw_mem, 6644 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf, 6645 vxlan_port->pkt_pri); 6646 } 6647 if (soc_mem_field_valid(unit, hw_mem, 6648 VXLAN_VFI__SD_TAG_NEW_CFIf)) { 6649 soc_mem_field32_set(unit, hw_mem, 6650 vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf, 6651 vxlan_port->pkt_cfi); 6652 } 6653 if (soc_mem_field_valid(unit, hw_mem, 6654 VXLAN_VFI__SD_TAG_REMARK_CFIf)) { 6655 soc_mem_field32_set(unit, hw_mem, 6656 vxlate_entry, VXLAN_VFI__SD_TAG_REMARK_CFIf, 6657 0x1); 6658 } 6659 6660 soc_mem_field32_set(unit, hw_mem, 6661 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6662 0x6); /* REPLACE_PRI_ONLY */ 6663 6664 } else if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE ) { 6665 soc_mem_field32_set(unit, hw_mem, 6666 vxlate_entry, VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf, 6667 0x7); /* REPLACE_TPID_ONLY */ 6668 } 6669 6670 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 6671 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 6672 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE) || 6673 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6674 /* TPID value is used */ 6675 BCM_IF_ERROR_RETURN( 6676 _bcm_fb2_outer_tpid_entry_add(unit, vxlan_port->egress_service_tpid, tpid_index)); 6677 soc_mem_field32_set(unit, hw_mem, 6678 vxlate_entry, VXLAN_VFI__SD_TAG_TPID_INDEXf, *tpid_index); 6679 } 6680 } 6681 return BCM_E_NONE; 6682 } 6683 6684 /* 6685 * Function: 6686 * _bcm_td2_vxlan_sd_tag_get 6687 * Purpose: 6688 * Get SD_TAG settings 6689 * Parameters: 6690 * unit - (IN) SOC unit # 6691 * vxlan_port - (IN) VXLAN VP 6692 * egr_nh_info (IN/OUT) Egress NHop Info 6693 * Returns: 6694 * BCM_E_XXX 6695 */ 6696 6697 STATIC void 6698 _bcm_td2_vxlan_sd_tag_get( int unit, bcm_vxlan_vpn_config_t *vxlan_vpn_info, 6699 bcm_vxlan_port_t *vxlan_port, 6700 egr_l3_next_hop_entry_t *egr_nh, 6701 uint32 *vxlate_entry, 6702 int network_port_flag ) 6703 { 6704 int action_present=0, action_not_present=0, tpid_index = 0; 6705 soc_mem_t vxlate_mem; 6706 uint32 flags = 0; 6707 bcm_vlan_t egress_service_vlan = 0; 6708 uint16 egress_service_tpid = 0; 6709 uint8 pkt_pri = 0; 6710 uint8 pkt_cfi = 0; 6711 6712 #if defined(BCM_TRIDENT3_SUPPORT) 6713 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 6714 _bcm_td3_vxlan_vlan_action_get(unit, vxlan_vpn_info, vxlan_port, egr_nh, 6715 vxlate_entry, network_port_flag); 6716 return; 6717 } 6718 #endif 6719 6720 #if defined(BCM_TRIDENT3_SUPPORT) 6721 if (soc_feature(unit, soc_feature_base_valid)) { 6722 vxlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 6723 } else 6724 #endif 6725 { 6726 vxlate_mem = EGR_VLAN_XLATEm; 6727 } 6728 6729 if (network_port_flag) { 6730 action_present = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 6731 VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf); 6732 action_not_present = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 6733 VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf); 6734 6735 if (action_not_present == 1) { 6736 flags |= BCM_VXLAN_VPN_SERVICE_TAGGED; 6737 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_ADD; 6738 egress_service_vlan = soc_mem_field32_get(unit, 6739 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_VIDf); 6740 } 6741 6742 if (action_present) { 6743 flags |= BCM_VXLAN_VPN_SERVICE_TAGGED; 6744 } 6745 switch (action_present) { 6746 case 1: 6747 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE; 6748 egress_service_vlan = soc_mem_field32_get(unit, 6749 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_VIDf); 6750 break; 6751 6752 case 2: 6753 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_REPLACE; 6754 egress_service_vlan = soc_mem_field32_get(unit, 6755 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_VIDf); 6756 break; 6757 6758 case 3: 6759 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_DELETE; 6760 egress_service_vlan = BCM_VLAN_INVALID; 6761 break; 6762 6763 case 4: 6764 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE; 6765 egress_service_vlan = soc_mem_field32_get(unit, 6766 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_VIDf); 6767 pkt_pri = soc_mem_field32_get(unit, 6768 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf); 6769 pkt_cfi = soc_mem_field32_get(unit, 6770 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf); 6771 break; 6772 6773 case 5: 6774 flags |= BCM_VXLAN_VPN_SERVICE_VLAN_PRI_REPLACE; 6775 egress_service_vlan = soc_mem_field32_get(unit, 6776 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_VIDf); 6777 pkt_pri = soc_mem_field32_get(unit, 6778 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf); 6779 pkt_cfi = soc_mem_field32_get(unit, 6780 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf); 6781 break; 6782 6783 case 6: 6784 flags |= BCM_VXLAN_VPN_SERVICE_PRI_REPLACE; 6785 egress_service_vlan = BCM_VLAN_INVALID; 6786 pkt_pri = soc_mem_field32_get(unit, 6787 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_NEW_PRIf); 6788 pkt_cfi = soc_mem_field32_get(unit, 6789 vxlate_mem, vxlate_entry, VXLAN_VFI__SD_TAG_NEW_CFIf); 6790 break; 6791 6792 case 7: 6793 flags |= BCM_VXLAN_VPN_SERVICE_TPID_REPLACE; 6794 egress_service_vlan = BCM_VLAN_INVALID; 6795 break; 6796 6797 default: 6798 break; 6799 } 6800 6801 if ((flags & BCM_VXLAN_VPN_SERVICE_VLAN_ADD) || 6802 (flags & BCM_VXLAN_VPN_SERVICE_VLAN_TPID_REPLACE) || 6803 (flags & BCM_VXLAN_VPN_SERVICE_TPID_REPLACE) || 6804 (flags & BCM_VXLAN_VPN_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6805 tpid_index = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 6806 VXLAN_VFI__SD_TAG_TPID_INDEXf); 6807 _bcm_fb2_outer_tpid_entry_get(unit, 6808 &egress_service_tpid, tpid_index); 6809 } 6810 if (vxlan_vpn_info) { 6811 vxlan_vpn_info->flags |= flags; 6812 vxlan_vpn_info->egress_service_vlan = egress_service_vlan; 6813 vxlan_vpn_info->egress_service_tpid = egress_service_tpid; 6814 vxlan_vpn_info->pkt_cfi = pkt_cfi; 6815 vxlan_vpn_info->pkt_pri = pkt_pri; 6816 } 6817 6818 if (vxlan_port) { 6819 vxlan_port->flags |= flags; 6820 vxlan_port->egress_service_vlan = egress_service_vlan; 6821 vxlan_port->egress_service_tpid = egress_service_tpid; 6822 vxlan_port->pkt_cfi = pkt_cfi; 6823 vxlan_port->pkt_pri = pkt_pri; 6824 } 6825 6826 } else { 6827 action_present = 6828 soc_EGR_L3_NEXT_HOPm_field32_get(unit, 6829 egr_nh, 6830 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 6831 action_not_present = 6832 soc_EGR_L3_NEXT_HOPm_field32_get(unit, 6833 egr_nh, 6834 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 6835 6836 if (action_not_present == 1) { 6837 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_ADD; 6838 vxlan_port->egress_service_vlan = 6839 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__SD_TAG_VIDf); 6840 } 6841 6842 switch (action_present) { 6843 case 1: 6844 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE; 6845 vxlan_port->egress_service_vlan = 6846 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__SD_TAG_VIDf); 6847 break; 6848 6849 case 2: 6850 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE; 6851 vxlan_port->egress_service_vlan = 6852 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__SD_TAG_VIDf); 6853 break; 6854 6855 case 3: 6856 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_DELETE; 6857 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6858 break; 6859 6860 case 4: 6861 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE; 6862 vxlan_port->egress_service_vlan = 6863 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__SD_TAG_VIDf); 6864 vxlan_port->pkt_pri = 6865 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__NEW_PRIf); 6866 vxlan_port->pkt_cfi = 6867 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__NEW_CFIf); 6868 break; 6869 6870 case 5: 6871 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE; 6872 vxlan_port->egress_service_vlan = 6873 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__SD_TAG_VIDf); 6874 vxlan_port->pkt_pri = 6875 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__NEW_PRIf); 6876 vxlan_port->pkt_cfi = 6877 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__NEW_CFIf); 6878 break; 6879 6880 case 6: 6881 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_PRI_REPLACE; 6882 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6883 vxlan_port->pkt_pri = 6884 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__NEW_PRIf); 6885 vxlan_port->pkt_cfi = 6886 soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__NEW_CFIf); 6887 break; 6888 6889 case 7: 6890 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_TPID_REPLACE; 6891 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6892 break; 6893 6894 default: 6895 break; 6896 } 6897 6898 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6899 if (soc_feature(unit, soc_feature_vp_sharing) && 6900 SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_NOT_VALIDf)) { 6901 int sd_tag_invalid = -1; 6902 sd_tag_invalid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, 6903 SD_TAG__SD_TAG_NOT_VALIDf); 6904 if (sd_tag_invalid) { 6905 vxlan_port->egress_service_vlan = BCM_VLAN_INVALID; 6906 } 6907 } 6908 #endif 6909 6910 #if defined(BCM_TRIDENT3_SUPPORT) 6911 if (soc_feature(unit, soc_feature_vp_sharing) && 6912 soc_feature(unit, soc_feature_egr_intf_vlan_vfi_deoverlay)) { 6913 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 6914 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 6915 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_REPLACE) || 6916 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_REPLACE) || 6917 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6918 vxlan_port->egress_service_vlan = (vxlan_port->egress_service_vlan == 0) ? 6919 BCM_VLAN_INVALID : vxlan_port->egress_service_vlan; 6920 } 6921 } 6922 #endif 6923 6924 if ((vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_ADD) || 6925 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_TPID_REPLACE) || 6926 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TPID_REPLACE) || 6927 (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_VLAN_PRI_TPID_REPLACE)) { 6928 /* TPID value is used */ 6929 tpid_index = soc_EGR_L3_NEXT_HOPm_field32_get(unit, egr_nh, SD_TAG__SD_TAG_TPID_INDEXf); 6930 _bcm_fb2_outer_tpid_entry_get(unit, &vxlan_port->egress_service_tpid, tpid_index); 6931 } 6932 } 6933 } 6934 6935 #if defined(BCM_TRIDENT3_SUPPORT) 6936 /* 6937 * Function: 6938 * _bcm_td3_vxlan_nexthop_l2otag_set 6939 * Purpose: 6940 * set l2otag in nexthop 6941 * Parameters: 6942 * unit - Device Number 6943 * egr_nh_info - ptr of Next Hop Info 6944 * egr_nh - ptr of egr nh 6945 * Returns: 6946 * BCM_E_XXX 6947 */ 6948 6949 STATIC int 6950 _bcm_td3_vxlan_nexthop_l2otag_set(int unit, 6951 _bcm_td2_vxlan_nh_info_t *egr_nh_info, egr_l3_next_hop_entry_t* egr_nh) 6952 { 6953 uint32 profile_idx; 6954 uint8 pcp_de_sel = 0; 6955 6956 if (egr_nh_info->sd_tag_vlan != -1) { 6957 if (egr_nh_info->sd_tag_vlan < BCM_VLAN_INVALID) { 6958 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 6959 egr_nh, L2_OTAG__VIDf, egr_nh_info->sd_tag_vlan); 6960 } 6961 } 6962 6963 if ((egr_nh_info->sd_tag_action_not_present != -1) || (egr_nh_info->sd_tag_action_present != -1)) { 6964 profile_idx = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, egr_nh, 6965 L2_OTAG__TAG_ACTION_PROFILE_PTRf); 6966 _bcm_td3_sd_tag_action_profile_get(unit, egr_nh_info->sd_tag_action_present, 6967 egr_nh_info->sd_tag_action_not_present, &profile_idx); 6968 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 6969 L2_OTAG__TAG_ACTION_PROFILE_PTRf, 6970 profile_idx); 6971 } 6972 6973 if (egr_nh_info->sd_tag_pri != -1) { 6974 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 6975 L2_OTAG__PCPf, 6976 egr_nh_info->sd_tag_pri); 6977 pcp_de_sel = 1; 6978 } 6979 6980 if (egr_nh_info->sd_tag_cfi != -1) { 6981 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 6982 L2_OTAG__DEf, 6983 egr_nh_info->sd_tag_cfi); 6984 pcp_de_sel = 1; 6985 } 6986 6987 if (pcp_de_sel != 0) { 6988 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, egr_nh, 6989 L2_OTAG__PCP_DE_SELf, 6990 pcp_de_sel); 6991 } 6992 6993 if (egr_nh_info->tpid_index != -1) { 6994 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 6995 egr_nh, L2_OTAG__TPID_INDEXf, 6996 egr_nh_info->tpid_index); 6997 } 6998 6999 return BCM_E_NONE; 7000 7001 } 7002 #endif 7003 7004 /* 7005 * Function: 7006 * _bcm_td2_vxlan_nexthop_entry_modify 7007 * Purpose: 7008 * Modify Egress entry 7009 * Parameters: 7010 * unit - Device Number 7011 * nh_index - Next Hop Index 7012 * new_entry_type - New Entry type 7013 * Returns: 7014 * BCM_E_XXX 7015 */ 7016 7017 int 7018 _bcm_td2_vxlan_nexthop_entry_modify(int unit, int nh_index, int drop, 7019 _bcm_td2_vxlan_nh_info_t *egr_nh_info, int new_entry_type) 7020 { 7021 egr_l3_next_hop_entry_t egr_nh; 7022 int rv = BCM_E_NONE; 7023 uint32 old_entry_type=0, intf_num=0, vntag_actions=0; 7024 uint32 vntag_dst_vif=0, vntag_pf=0, vntag_force_lf=0; 7025 uint32 etag_pcp_de_sourcef=0, etag_pcpf=0, etag_dot1p_mapping_ptr=0, etag_def=0; 7026 bcm_mac_t mac_addr; /* Next hop forwarding destination mac. */ 7027 uint32 hg_ppd_type = 0; 7028 soc_field_t type_field; 7029 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7030 ing_l3_next_hop_entry_t ing_nh; 7031 bcm_port_t port = 0; 7032 bcm_module_t modid = 0; 7033 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 7034 int d = 0; /*vxlan decoupled mode*/ 7035 7036 #if defined(BCM_TRIDENT3_SUPPORT) 7037 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7038 d = 1; 7039 } 7040 #endif 7041 7042 #if defined(BCM_TRIDENT3_SUPPORT) 7043 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 7044 type_field = DATA_TYPEf; 7045 } else 7046 #endif 7047 { 7048 type_field = ENTRY_TYPEf; 7049 } 7050 7051 sal_memset(&mac_addr, 0, sizeof (mac_addr)); 7052 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL, 7053 nh_index, &egr_nh)); 7054 7055 old_entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, type_field); 7056 7057 if ((new_entry_type == BCM_VXLAN_TAG_VIEW(d)) && 7058 (old_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW)) { 7059 hg_ppd_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7060 L3__HG_HDR_SELf); 7061 /*Zero buffers.*/ 7062 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 7063 #if defined(BCM_TRIDENT3_SUPPORT) 7064 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7065 /*mapping to L2OTA TAP*/ 7066 BCM_IF_ERROR_RETURN(_bcm_td3_vxlan_nexthop_l2otag_set(unit, egr_nh_info, &egr_nh)); 7067 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7068 L2_OTAG__FLOW_SELECT_CTRL_IDf, 8); 7069 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7070 L2_OTAG__NEXT_PTR_TYPEf, 1); 7071 } else 7072 #endif 7073 { 7074 if (egr_nh_info->sd_tag_vlan != -1) { 7075 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7076 if (soc_feature(unit, soc_feature_vp_sharing)) { 7077 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_NOT_VALIDf)) { 7078 if (egr_nh_info->sd_tag_vlan == BCM_VLAN_INVALID) { 7079 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7080 &egr_nh, SD_TAG__SD_TAG_NOT_VALIDf, 1); 7081 } else { 7082 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7083 &egr_nh, SD_TAG__SD_TAG_NOT_VALIDf, 0); 7084 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7085 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info->sd_tag_vlan); 7086 } 7087 } else { 7088 if (egr_nh_info->sd_tag_vlan < BCM_VLAN_INVALID) { 7089 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7090 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info->sd_tag_vlan); 7091 } 7092 } 7093 } else 7094 #endif 7095 { 7096 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7097 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info->sd_tag_vlan); 7098 } 7099 } 7100 7101 if (egr_nh_info->sd_tag_action_present != -1) { 7102 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7103 SD_TAG__SD_TAG_ACTION_IF_PRESENTf, 7104 egr_nh_info->sd_tag_action_present); 7105 } 7106 7107 if (egr_nh_info->sd_tag_action_not_present != -1) { 7108 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7109 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf, 7110 egr_nh_info->sd_tag_action_not_present); 7111 } 7112 7113 if (egr_nh_info->sd_tag_pri != -1) { 7114 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_PRIf)) { 7115 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7116 SD_TAG__NEW_PRIf, 7117 egr_nh_info->sd_tag_pri); 7118 } 7119 } 7120 7121 if (egr_nh_info->sd_tag_cfi != -1) { 7122 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_CFIf)) { 7123 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7124 SD_TAG__NEW_CFIf, 7125 egr_nh_info->sd_tag_cfi); 7126 } 7127 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_REMARK_CFIf)) { 7128 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7129 SD_TAG__SD_TAG_REMARK_CFIf, 7130 0x1); 7131 } 7132 } 7133 7134 if (egr_nh_info->tpid_index != -1) { 7135 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7136 &egr_nh, SD_TAG__SD_TAG_TPID_INDEXf, 7137 egr_nh_info->tpid_index); 7138 } 7139 } 7140 7141 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7142 BCM_VXLAN_TAG_FIELD(d, BC_DROPf), drop ? 1 : 0); 7143 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7144 BCM_VXLAN_TAG_FIELD(d, UUC_DROPf), drop ? 1 : 0); 7145 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7146 BCM_VXLAN_TAG_FIELD(d, UMC_DROPf), drop ? 1 : 0); 7147 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7148 BCM_VXLAN_TAG_FIELD(d, DVPf), egr_nh_info->dvp); 7149 7150 #if defined(BCM_TRIDENT3_SUPPORT) 7151 if (SOC_IS_TRIDENT3X(unit)) { 7152 } else 7153 #endif 7154 { 7155 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 7156 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7157 &egr_nh, SD_TAG__DVP_NETWORK_GROUPf, 7158 egr_nh_info->dvp_network_group_id); 7159 } else { 7160 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7161 &egr_nh, SD_TAG__DVP_IS_NETWORK_PORTf, 7162 egr_nh_info->dvp_is_network); 7163 } 7164 } 7165 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7166 BCM_VXLAN_TAG_FIELD(d, HG_LEARN_OVERRIDEf), egr_nh_info->is_eline ? 1 : 0); 7167 /* HG_MODIFY_ENABLE must be 0x0 for Ingress and Egress Chip */ 7168 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7169 BCM_VXLAN_TAG_FIELD(d, HG_MODIFY_ENABLEf), 0x0); 7170 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7171 BCM_VXLAN_TAG_FIELD(d, HG_HDR_SELf), hg_ppd_type); 7172 7173 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7174 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 7175 BCM_VXLAN_TAG_FIELD(d, HG_MC_DST_PORT_NUMf))) { 7176 int is_trunk = 0; 7177 BCM_IF_ERROR_RETURN( 7178 soc_mem_read(unit, ING_L3_NEXT_HOPm, 7179 MEM_BLOCK_ANY, nh_index, &ing_nh)); 7180 7181 #if defined(BCM_TRIDENT3_SUPPORT) 7182 if (soc_feature(unit, soc_feature_generic_dest)) { 7183 uint32 dt, dv; 7184 7185 dv = soc_mem_field32_dest_get(unit, 7186 ING_L3_NEXT_HOPm, &ing_nh, DESTINATIONf, &dt); 7187 if (dt == SOC_MEM_FIF_DEST_DGPP) { 7188 port = (dv & SOC_MEM_FIF_DGPP_PORT_MASK); 7189 modid = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 7190 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 7191 is_trunk = 0; 7192 } else if (dt == SOC_MEM_FIF_DEST_LAG) { 7193 is_trunk = 1; 7194 } 7195 } else 7196 #endif 7197 { 7198 if (!soc_mem_field32_get(unit, ING_L3_NEXT_HOPm, &ing_nh, Tf)) { 7199 port = soc_mem_field32_get(unit, ING_L3_NEXT_HOPm, 7200 &ing_nh, PORT_NUMf); 7201 modid = soc_mem_field32_get(unit, ING_L3_NEXT_HOPm, 7202 &ing_nh, MODULE_IDf); 7203 is_trunk = 0; 7204 } else { 7205 is_trunk = 1; 7206 } 7207 } 7208 7209 if (!is_trunk) { 7210 if (_bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) { 7211 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7212 BCM_VXLAN_TAG_FIELD(d, HG_MC_DST_PORT_NUMf), port); 7213 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7214 BCM_VXLAN_TAG_FIELD(d, HG_MC_DST_MODIDf), modid); 7215 } 7216 } 7217 } 7218 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 7219 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7220 type_field, BCM_VXLAN_TAG_VIEW(d)); 7221 } else if ((new_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW) && 7222 (old_entry_type == BCM_VXLAN_TAG_VIEW(d))) { 7223 #if defined(BCM_TRIDENT3_SUPPORT) 7224 uint32 profile_index = 0; 7225 int action_present = 0; 7226 int action_not_present = 0; 7227 int old_tpid_idx = 0; 7228 7229 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7230 profile_index = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7231 &egr_nh, L2_OTAG__TAG_ACTION_PROFILE_PTRf); 7232 BCM_IF_ERROR_RETURN(_bcm_td3_sd_tag_action_get(unit, profile_index, 7233 &action_present, &action_not_present)); 7234 if (profile_index != 0) { 7235 BCM_IF_ERROR_RETURN( 7236 _bcm_trx_egr_vlan_action_profile_entry_delete(unit, 7237 profile_index)); 7238 } 7239 if ((action_not_present == 0x1) || (action_present == 0x1) || 7240 (action_present == 0x4) || (action_present == 0x7)) { 7241 old_tpid_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7242 &egr_nh, L2_OTAG__TPID_INDEXf); 7243 BCM_IF_ERROR_RETURN( 7244 _bcm_fb2_outer_tpid_entry_delete(unit, old_tpid_idx)); 7245 } 7246 } 7247 #endif 7248 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7249 type_field, _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW); 7250 7251 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7252 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 7253 BCM_VXLAN_TAG_FIELD(d, HG_MC_DST_PORT_NUMf))) { 7254 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7255 BCM_VXLAN_TAG_FIELD(d, HG_MC_DST_PORT_NUMf), 0); 7256 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7257 BCM_VXLAN_TAG_FIELD(d, HG_MC_DST_MODIDf), 0); 7258 } 7259 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 7260 if( SOC_IS_APACHE(unit) && (egr_nh_info == NULL)) { 7261 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7262 L3__INTF_NUMf, 0); 7263 } 7264 } else if ((new_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW) && 7265 (old_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW)) { 7266 7267 /* Get mac address. */ 7268 soc_mem_mac_addr_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7269 L3__MAC_ADDRESSf, mac_addr); 7270 7271 /* Get int_num */ 7272 intf_num = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7273 L3__INTF_NUMf); 7274 7275 vntag_actions = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7276 L3__VNTAG_ACTIONSf); 7277 7278 vntag_dst_vif = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7279 L3__VNTAG_DST_VIFf); 7280 7281 vntag_pf = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7282 L3__VNTAG_Pf); 7283 7284 vntag_force_lf = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7285 L3__VNTAG_FORCE_Lf); 7286 7287 etag_pcp_de_sourcef = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7288 L3__ETAG_PCP_DE_SOURCEf); 7289 7290 etag_pcpf = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7291 L3__ETAG_PCPf); 7292 7293 etag_dot1p_mapping_ptr = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7294 L3__ETAG_DOT1P_MAPPING_PTRf); 7295 7296 etag_def = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7297 L3__ETAG_DEf); 7298 hg_ppd_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7299 L3__HG_HDR_SELf); 7300 /*Zero buffers.*/ 7301 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 7302 7303 soc_mem_mac_addr_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7304 L3MC__MAC_ADDRESSf, mac_addr); 7305 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7306 L3MC__INTF_NUMf, intf_num); 7307 7308 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7309 if (soc_feature(unit, soc_feature_egr_l3_next_hop_next_ptr)) { 7310 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7311 L3MC__NEXT_PTR_TYPEf, 0x1); 7312 } else 7313 #endif 7314 { 7315 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7316 L3MC__DVP_VALIDf, 0x1); 7317 } 7318 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7319 L3MC__DVPf, egr_nh_info->dvp); 7320 #if defined(BCM_TRIDENT3_SUPPORT) 7321 if (SOC_IS_TRIDENT3X(unit)) { 7322 } else 7323 #endif 7324 { 7325 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7326 L3MC__L2_MC_DA_DISABLEf, 0x1); 7327 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7328 L3MC__L2_MC_SA_DISABLEf, 0x1); 7329 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7330 L3MC__L2_MC_VLAN_DISABLEf, 0x1); 7331 } 7332 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7333 L3MC__L2_DROPf, 0x0); 7334 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7335 L3MC__L3_DROPf, drop ? 1 : 0); 7336 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7337 L3MC__L3MC_USE_CONFIGURED_MACf, 0x1); 7338 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7339 L3MC__VNTAG_ACTIONSf, vntag_actions); 7340 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7341 L3MC__VNTAG_DST_VIFf, vntag_dst_vif); 7342 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7343 L3MC__VNTAG_Pf, vntag_pf); 7344 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7345 L3MC__VNTAG_FORCE_Lf, vntag_force_lf); 7346 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7347 L3MC__ETAG_PCP_DE_SOURCEf, etag_pcp_de_sourcef); 7348 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7349 L3MC__ETAG_PCPf, etag_pcpf); 7350 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7351 L3MC__ETAG_DOT1P_MAPPING_PTRf, etag_dot1p_mapping_ptr); 7352 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7353 L3MC__ETAG_DEf, etag_def); 7354 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7355 L3MC__HG_HDR_SELf, hg_ppd_type); 7356 7357 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7358 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, L3MC__HG_MC_DST_PORT_NUMf) && 7359 soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, L3MC__USE_MAC_DA_PROFILEf)) { 7360 int is_trunk = 0; 7361 BCM_IF_ERROR_RETURN( 7362 soc_mem_read(unit, ING_L3_NEXT_HOPm, 7363 MEM_BLOCK_ANY, nh_index, &ing_nh)); 7364 #if defined(BCM_TRIDENT3_SUPPORT) 7365 if (soc_feature(unit, soc_feature_generic_dest)) { 7366 uint32 dt, dv; 7367 7368 dv = soc_mem_field32_dest_get(unit, 7369 ING_L3_NEXT_HOPm, &ing_nh, DESTINATIONf, &dt); 7370 if (dt == SOC_MEM_FIF_DEST_DGPP) { 7371 port = (dv & SOC_MEM_FIF_DGPP_PORT_MASK); 7372 modid = (dv & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 7373 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 7374 is_trunk = 0; 7375 } else if (dt == SOC_MEM_FIF_DEST_LAG) { 7376 is_trunk = 1; 7377 } 7378 } else 7379 #endif 7380 { 7381 if (!soc_mem_field32_get(unit, ING_L3_NEXT_HOPm, &ing_nh, Tf)) { 7382 port = soc_mem_field32_get(unit, ING_L3_NEXT_HOPm, 7383 &ing_nh, PORT_NUMf); 7384 modid = soc_mem_field32_get(unit, ING_L3_NEXT_HOPm, 7385 &ing_nh, MODULE_IDf); 7386 is_trunk = 0; 7387 } else { 7388 is_trunk = 1; 7389 } 7390 } 7391 7392 if (!is_trunk) { 7393 if (_bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) { 7394 uint32 macda_index; 7395 void *entries[1]; 7396 egr_mac_da_profile_entry_t macda; 7397 7398 sal_memset(&macda, 0, sizeof(egr_mac_da_profile_entry_t)); 7399 soc_mem_mac_addr_set(unit, EGR_MAC_DA_PROFILEm, 7400 &macda, MAC_ADDRESSf, mac_addr); 7401 entries[0] = &macda; 7402 BCM_IF_ERROR_RETURN( 7403 _bcm_mac_da_profile_entry_add(unit, entries, 1, &macda_index)); 7404 7405 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7406 L3MC__HG_MC_DST_PORT_NUMf, port); 7407 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7408 L3MC__HG_MC_DST_MODIDf, modid); 7409 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7410 L3MC__USE_MAC_DA_PROFILEf, 1); 7411 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7412 L3MC__MAC_DA_PROFILE_INDEXf, macda_index); 7413 } 7414 } 7415 } 7416 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 7417 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7418 type_field, _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW); 7419 7420 } else if ((new_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW) && 7421 (old_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW)) { 7422 7423 /* Update entry with DVP info if it is already IPMC entry */ 7424 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7425 if (soc_feature(unit, soc_feature_egr_l3_next_hop_next_ptr)) { 7426 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7427 L3MC__NEXT_PTR_TYPEf, 0x1); 7428 } else 7429 #endif 7430 { 7431 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7432 L3MC__DVP_VALIDf, 0x1); 7433 } 7434 7435 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7436 L3MC__DVPf, egr_nh_info->dvp); 7437 #if defined(BCM_TRIDENT3_SUPPORT) 7438 if (SOC_IS_TRIDENT3X(unit)) { 7439 } else 7440 #endif 7441 { 7442 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7443 L3MC__L2_MC_DA_DISABLEf, 0x1); 7444 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7445 L3MC__L2_MC_SA_DISABLEf, 0x1); 7446 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7447 L3MC__L2_MC_VLAN_DISABLEf, 0x1); 7448 } 7449 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7450 L3MC__L2_DROPf, 0x0); 7451 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7452 L3MC__L3_DROPf, drop ? 1 : 0); 7453 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7454 L3MC__L3MC_USE_CONFIGURED_MACf, 0x1); 7455 7456 } else if ((new_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW) && 7457 (old_entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW)) { 7458 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7459 type_field, _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW); 7460 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7461 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, L3MC__HG_MC_DST_PORT_NUMf) && 7462 soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, L3MC__USE_MAC_DA_PROFILEf)) { 7463 if (soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7464 L3MC__USE_MAC_DA_PROFILEf)) { 7465 uint32 macda_index; 7466 7467 macda_index = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7468 L3MC__MAC_DA_PROFILE_INDEXf); 7469 BCM_IF_ERROR_RETURN( 7470 _bcm_mac_da_profile_entry_delete(unit, macda_index)); 7471 } 7472 } 7473 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 7474 /* Get mac address. */ 7475 soc_mem_mac_addr_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7476 L3MC__MAC_ADDRESSf, mac_addr); 7477 7478 /* Get int_num */ 7479 intf_num = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7480 L3MC__INTF_NUMf); 7481 7482 vntag_actions = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7483 L3MC__VNTAG_ACTIONSf); 7484 7485 vntag_dst_vif = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7486 L3MC__VNTAG_DST_VIFf); 7487 7488 vntag_pf = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7489 L3MC__VNTAG_Pf); 7490 7491 vntag_force_lf = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7492 L3MC__VNTAG_FORCE_Lf); 7493 7494 etag_pcp_de_sourcef = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 7495 &egr_nh, 7496 L3MC__ETAG_PCP_DE_SOURCEf); 7497 7498 etag_pcpf = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7499 L3MC__ETAG_PCPf); 7500 7501 etag_dot1p_mapping_ptr = soc_mem_field32_get( 7502 unit, EGR_L3_NEXT_HOPm, &egr_nh, L3MC__ETAG_DOT1P_MAPPING_PTRf); 7503 7504 etag_def = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7505 L3MC__ETAG_DEf); 7506 hg_ppd_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7507 L3MC__HG_HDR_SELf); 7508 /*Zero buffers.*/ 7509 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 7510 7511 soc_mem_mac_addr_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7512 L3__MAC_ADDRESSf, mac_addr); 7513 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7514 L3__INTF_NUMf, intf_num); 7515 7516 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7517 L3__VNTAG_ACTIONSf, vntag_actions); 7518 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7519 L3__VNTAG_DST_VIFf, vntag_dst_vif); 7520 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7521 L3__VNTAG_Pf, vntag_pf); 7522 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7523 L3__VNTAG_FORCE_Lf, vntag_force_lf); 7524 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7525 L3__ETAG_PCP_DE_SOURCEf, etag_pcp_de_sourcef); 7526 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7527 L3__ETAG_PCPf, etag_pcpf); 7528 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7529 L3__ETAG_DOT1P_MAPPING_PTRf, 7530 etag_dot1p_mapping_ptr); 7531 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7532 L3__ETAG_DEf, etag_def); 7533 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7534 L3__HG_HDR_SELf, hg_ppd_type); 7535 7536 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7537 type_field, _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW); 7538 } else if ((new_entry_type == BCM_VXLAN_TAG_VIEW(d)) && 7539 (old_entry_type == BCM_VXLAN_TAG_VIEW(d))) { 7540 /* Case of VXLAN Proxy Next-Hop */ 7541 #if defined(BCM_TRIDENT3_SUPPORT) 7542 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7543 BCM_IF_ERROR_RETURN(_bcm_td3_vxlan_nexthop_l2otag_set(unit, egr_nh_info, &egr_nh)); 7544 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7545 L2_OTAG__FLOW_SELECT_CTRL_IDf, 8); 7546 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7547 L2_OTAG__NEXT_PTR_TYPEf, 1); 7548 } else 7549 #endif 7550 { 7551 if (egr_nh_info->sd_tag_vlan != -1) { 7552 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7553 if (soc_feature(unit, soc_feature_vp_sharing)) { 7554 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_NOT_VALIDf)) { 7555 if (egr_nh_info->sd_tag_vlan == BCM_VLAN_INVALID) { 7556 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7557 &egr_nh, SD_TAG__SD_TAG_NOT_VALIDf, 1); 7558 } else { 7559 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7560 &egr_nh, SD_TAG__SD_TAG_NOT_VALIDf, 0); 7561 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7562 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info->sd_tag_vlan); 7563 } 7564 } else { 7565 if (egr_nh_info->sd_tag_vlan < BCM_VLAN_INVALID) { 7566 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7567 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info->sd_tag_vlan); 7568 } 7569 } 7570 } else 7571 #endif 7572 { 7573 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7574 &egr_nh, SD_TAG__SD_TAG_VIDf, egr_nh_info->sd_tag_vlan); 7575 } 7576 } 7577 7578 if (egr_nh_info->sd_tag_action_present != -1) { 7579 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7580 SD_TAG__SD_TAG_ACTION_IF_PRESENTf, 7581 egr_nh_info->sd_tag_action_present); 7582 } else { 7583 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7584 SD_TAG__SD_TAG_ACTION_IF_PRESENTf, 0x0); 7585 7586 } 7587 7588 if (egr_nh_info->sd_tag_action_not_present != -1) { 7589 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7590 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf, 7591 egr_nh_info->sd_tag_action_not_present); 7592 } else { 7593 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7594 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf, 0x0); 7595 } 7596 7597 if (egr_nh_info->sd_tag_pri != -1) { 7598 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_PRIf)) { 7599 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7600 SD_TAG__NEW_PRIf, 7601 egr_nh_info->sd_tag_pri); 7602 } 7603 } else { 7604 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_PRIf)) { 7605 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7606 SD_TAG__NEW_PRIf, 0x0); 7607 } 7608 } 7609 7610 if (egr_nh_info->sd_tag_cfi != -1) { 7611 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__NEW_CFIf)) { 7612 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7613 SD_TAG__NEW_CFIf, 7614 egr_nh_info->sd_tag_cfi); 7615 } 7616 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_REMARK_CFIf)) { 7617 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7618 SD_TAG__SD_TAG_REMARK_CFIf, 7619 0x1); 7620 } 7621 } else { 7622 if(soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, SD_TAG__SD_TAG_REMARK_CFIf)) { 7623 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7624 SD_TAG__SD_TAG_REMARK_CFIf, 7625 0x0); 7626 } 7627 } 7628 7629 if (egr_nh_info->tpid_index != -1) { 7630 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, 7631 &egr_nh, SD_TAG__SD_TAG_TPID_INDEXf, 7632 egr_nh_info->tpid_index); 7633 } 7634 } 7635 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7636 BCM_VXLAN_TAG_FIELD(d, DVPf), egr_nh_info->dvp); 7637 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7638 BCM_VXLAN_TAG_FIELD(d, BC_DROPf), drop ? 1 : 0); 7639 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7640 BCM_VXLAN_TAG_FIELD(d, UUC_DROPf), drop ? 1 : 0); 7641 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 7642 BCM_VXLAN_TAG_FIELD(d, UMC_DROPf), drop ? 1 : 0); 7643 } 7644 7645 rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, 7646 MEM_BLOCK_ALL, nh_index, &egr_nh); 7647 return rv; 7648 } 7649 7650 /* 7651 * Function: 7652 * bcm_td2_vxlan_next_hop_set 7653 * Purpose: 7654 * Set VXLAN NextHop Entry 7655 * Parameters: 7656 * IN : Unit 7657 * IN : nh_index 7658 * Returns: 7659 * BCM_E_XXX 7660 */ 7661 7662 int 7663 bcm_td2_vxlan_next_hop_set(int unit, int nh_index, uint32 flags, int vp, int drop) 7664 { 7665 int rv = BCM_E_NONE; 7666 ing_l3_next_hop_entry_t ing_nh; 7667 bcm_port_t port = -1; 7668 bcm_module_t modid = -1, local_modid = -1; 7669 bcm_trunk_t tgid = -1; 7670 int num_ports=0, idx=-1; 7671 bcm_port_t local_ports[SOC_MAX_NUM_PORTS]; 7672 int old_nh_index=-1; 7673 int replace=0; 7674 int gport = 0; 7675 _bcm_td2_vxlan_nh_info_t egr_nh_info; 7676 _bcm_vp_info_t vp_info; 7677 soc_mem_t hw_mem = ING_L3_NEXT_HOPm; 7678 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7679 bcm_trunk_member_t *tmp_member_gports_array = NULL; 7680 #endif 7681 7682 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 7683 hw_mem, MEM_BLOCK_ANY, nh_index, &ing_nh)); 7684 soc_mem_field32_set(unit, hw_mem, &ing_nh, 7685 ENTRY_TYPEf, _BCM_VXLAN_INGRESS_NEXT_HOP_ENTRY_TYPE); 7686 if (SOC_MEM_FIELD_VALID(unit, hw_mem, MTU_SIZEf)) { 7687 soc_mem_field32_set(unit, hw_mem, &ing_nh, MTU_SIZEf, 0x3fff); 7688 } 7689 BCM_IF_ERROR_RETURN( 7690 soc_mem_write(unit, hw_mem, MEM_BLOCK_ALL, nh_index, &ing_nh)); 7691 7692 if (flags & BCM_L3_IPMC) { 7693 egr_l3_next_hop_entry_t egr_nh; 7694 int entry_type = 0; 7695 7696 (void)_bcm_vp_info_get(unit, vp, &vp_info); 7697 7698 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT && 7699 vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { /* Shared network VP */ 7700 7701 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL, 7702 nh_index, &egr_nh)); 7703 #if defined(BCM_TRIDENT3_SUPPORT) 7704 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 7705 entry_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, DATA_TYPEf); 7706 } else 7707 #endif 7708 { 7709 entry_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &egr_nh, ENTRY_TYPEf); 7710 } 7711 if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW) { 7712 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, L3__HG_HDR_SELf, 1); 7713 } 7714 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_L3_NEXT_HOPm, 7715 MEM_BLOCK_ALL, nh_index, &egr_nh)); 7716 egr_nh_info.dvp = vp; 7717 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_nexthop_entry_modify(unit, 7718 nh_index, drop, &egr_nh_info, _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW)); 7719 } 7720 } else { /* Only for VXLAN Unicast Nexthops */ 7721 replace = flags & BCM_L3_REPLACE; 7722 7723 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_nexthop_glp_get(unit, 7724 nh_index, &modid, &port, &tgid)); 7725 7726 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &local_modid)); 7727 if (tgid != -1) { 7728 BCM_IF_ERROR_RETURN(_bcm_trunk_id_validate(unit, tgid)); 7729 rv = bcm_esw_trunk_get(unit, tgid, NULL, 0, NULL, &num_ports); 7730 if (BCM_FAILURE(rv)) { 7731 return BCM_E_PORT; 7732 } 7733 if (num_ports == 0) { 7734 return BCM_E_NONE; 7735 } 7736 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7737 if(soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 7738 tmp_member_gports_array = sal_alloc( 7739 sizeof(bcm_trunk_member_t) * num_ports, "tmp_member_gports_arry"); 7740 if (tmp_member_gports_array == NULL) { 7741 return BCM_E_MEMORY; 7742 } 7743 sal_memset(tmp_member_gports_array, 0, 7744 sizeof(bcm_trunk_member_t) * num_ports); 7745 rv = bcm_esw_trunk_get(unit, tgid, NULL, 7746 num_ports, tmp_member_gports_array, &num_ports); 7747 if (BCM_FAILURE(rv)) { 7748 goto clean_up; 7749 } 7750 } else 7751 #endif 7752 { 7753 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid, 7754 SOC_MAX_NUM_PORTS, local_ports, &num_ports)); 7755 modid = local_modid; 7756 } 7757 } else { 7758 if (modid != local_modid) { 7759 if (!soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 7760 /* Ignore EGR_PORT_TO_NHI_MAPPINGs */ 7761 return BCM_E_NONE; 7762 } 7763 } 7764 7765 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7766 if(soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 7767 /* Alloc one trunk member size memory */ 7768 tmp_member_gports_array = sal_alloc( 7769 sizeof(bcm_trunk_member_t), "tmp_member_gports_arry"); 7770 if (tmp_member_gports_array == NULL) { 7771 return BCM_E_MEMORY; 7772 } 7773 sal_memset(tmp_member_gports_array, 0, 7774 sizeof(bcm_trunk_member_t)); 7775 BCM_GPORT_MODPORT_SET(gport, modid, port); 7776 tmp_member_gports_array[num_ports++].gport = gport; 7777 } else 7778 #endif 7779 { 7780 local_ports[num_ports++] = port; 7781 } 7782 } 7783 7784 for (idx = 0; idx < num_ports; idx++) { 7785 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7786 if(soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 7787 gport = tmp_member_gports_array[idx].gport; 7788 } else 7789 #endif 7790 { 7791 BCM_GPORT_MODPORT_SET(gport, modid, local_ports[idx]); 7792 } 7793 7794 rv = _bcm_trx_gport_to_nhi_get(unit, gport, &old_nh_index); 7795 if (BCM_FAILURE(rv)) { 7796 goto clean_up; 7797 } 7798 if (old_nh_index && !replace) { 7799 if (old_nh_index != nh_index) { 7800 /* Limitation: For TD/TR3/TD2, 7801 VxLAN egress port can be configured with one NHI */ 7802 rv = BCM_E_RESOURCE; 7803 goto clean_up; 7804 } 7805 } else { 7806 rv = _bcm_trx_gport_to_nhi_set(unit, gport, nh_index); 7807 if (BCM_FAILURE(rv)) { 7808 goto clean_up; 7809 } 7810 } 7811 } 7812 } 7813 7814 clean_up: 7815 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7816 if (NULL != tmp_member_gports_array) { 7817 sal_free(tmp_member_gports_array); 7818 } 7819 #endif 7820 return rv; 7821 } 7822 7823 /* 7824 * Function: 7825 * bcm_td2_vxlan_nexthop_get 7826 * Purpose: 7827 * Get VXLAN NextHop entry 7828 * Parameters: 7829 * unit - (IN) SOC unit 7830 * egr_nh - (IN) Egress NHop Info 7831 * vxlan_port - (IN/OUT) VXLAN port 7832 * Returns: 7833 * BCM_E_XXX 7834 */ 7835 7836 int 7837 bcm_td2_vxlan_nexthop_get(int unit, egr_l3_next_hop_entry_t *egr_nh, 7838 bcm_vxlan_port_t *vxlan_port) 7839 { 7840 soc_mem_t hw_mem; 7841 uint32 entry_type; 7842 int d = 0; /*vxlan decoupled mode*/ 7843 7844 #if defined(BCM_TRIDENT3_SUPPORT) 7845 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7846 d = 1; 7847 } 7848 #endif 7849 7850 hw_mem = EGR_L3_NEXT_HOPm; 7851 7852 #if defined(BCM_TRIDENT3_SUPPORT) 7853 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 7854 entry_type = soc_mem_field32_get(unit, hw_mem, egr_nh, DATA_TYPEf); 7855 } else 7856 #endif 7857 { 7858 entry_type = soc_mem_field32_get(unit, hw_mem, egr_nh, ENTRY_TYPEf); 7859 } 7860 7861 if (entry_type == BCM_VXLAN_TAG_VIEW(d)) { 7862 if (soc_mem_field32_get(unit, hw_mem, egr_nh, BCM_VXLAN_TAG_FIELD(d, BC_DROPf)) 7863 || soc_mem_field32_get(unit, hw_mem, egr_nh, BCM_VXLAN_TAG_FIELD(d, UUC_DROPf)) 7864 || soc_mem_field32_get(unit, hw_mem, egr_nh, BCM_VXLAN_TAG_FIELD(d, UMC_DROPf))) { 7865 vxlan_port->flags |= BCM_VXLAN_PORT_DROP; 7866 } 7867 7868 if (!soc_mem_field32_get(unit, hw_mem, egr_nh, BCM_VXLAN_TAG_FIELD(d, HG_HDR_SELf))) { 7869 vxlan_port->flags |= BCM_VXLAN_PORT_ENCAP_LOCAL; 7870 } 7871 } else if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW) { 7872 if (soc_mem_field32_get(unit, hw_mem, egr_nh, L3MC__L3_DROPf)) { 7873 vxlan_port->flags |= BCM_VXLAN_PORT_DROP; 7874 } 7875 7876 if (!soc_mem_field32_get(unit, hw_mem, egr_nh, L3MC__HG_HDR_SELf)) { 7877 vxlan_port->flags |= BCM_VXLAN_PORT_ENCAP_LOCAL; 7878 } 7879 7880 vxlan_port->flags |= BCM_VXLAN_PORT_MULTICAST; 7881 } else if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW) { 7882 if (!soc_mem_field32_get(unit, hw_mem, egr_nh, L3__HG_HDR_SELf)) { 7883 vxlan_port->flags |= BCM_VXLAN_PORT_ENCAP_LOCAL; 7884 } 7885 } 7886 7887 return BCM_E_NONE; 7888 } 7889 7890 7891 /* 7892 * Function: 7893 * _bcm_td2_vxlan_port_egress_nexthop_reset 7894 * Purpose: 7895 * Reset VXLAN Egress NextHop 7896 * Parameters: 7897 * IN : Unit 7898 * IN : nh_index 7899 * Returns: 7900 * BCM_E_XXX 7901 */ 7902 7903 int 7904 _bcm_td2_vxlan_port_egress_nexthop_reset(int unit, int nh_index, int vp_type, int vp, bcm_vpn_t vpn) 7905 { 7906 egr_l3_next_hop_entry_t egr_nh; 7907 int rv=BCM_E_NONE; 7908 int action_present=0, action_not_present=0, old_tpid_idx = -1; 7909 uint32 entry_type=0; 7910 bcm_vxlan_port_t vxlan_port; 7911 int d = 0; /*vxlan decoupled mode*/ 7912 7913 #if defined(BCM_TRIDENT3_SUPPORT) 7914 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7915 d = 1; 7916 } 7917 #endif 7918 7919 BCM_IF_ERROR_RETURN( 7920 _bcm_td2_vxlan_port_get(unit, vpn, vp, &vxlan_port)); 7921 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 7922 MEM_BLOCK_ANY, nh_index, &egr_nh)); 7923 /* egressing into a regular port */ 7924 #if defined(BCM_TRIDENT3_SUPPORT) 7925 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 7926 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, DATA_TYPEf); 7927 } else 7928 #endif 7929 { 7930 entry_type = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, ENTRY_TYPEf); 7931 } 7932 if (vp_type== _BCM_VXLAN_DEST_VP_TYPE_ACCESS) { 7933 if (entry_type == BCM_VXLAN_TAG_VIEW(d)) { 7934 #if defined(BCM_TRIDENT3_SUPPORT) 7935 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 7936 _bcm_td3_vxlan_tpid_delete(unit, NULL, (uint32*)&egr_nh); 7937 } else 7938 #endif 7939 { 7940 action_present = 7941 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7942 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 7943 action_not_present = 7944 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 7945 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 7946 if ((action_not_present == 0x1) || (action_present == 0x1) || 7947 (action_present == 0x4) || (action_present == 0x7)) { 7948 old_tpid_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 7949 &egr_nh, SD_TAG__SD_TAG_TPID_INDEXf); 7950 BCM_IF_ERROR_RETURN( 7951 _bcm_fb2_outer_tpid_entry_delete(unit, old_tpid_idx)); 7952 } 7953 } 7954 } 7955 /* Normalize Next-hop Entry -- L3 View */ 7956 rv = _bcm_td2_vxlan_nexthop_entry_modify(unit, nh_index, 0, 7957 NULL, _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW); 7958 7959 } else if ( vp_type == _BCM_VXLAN_INGRESS_DEST_VP_TYPE ){ 7960 /* egressing into a tunnel, vp type should be _BCM_VXLAN_INGRESS_DEST_VP_TYPE */ 7961 /* Normalize Next-hop Entry -- L3 View */ 7962 if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW) { 7963 rv = _bcm_td2_vxlan_nexthop_entry_modify(unit, nh_index, 0, NULL, 7964 _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW); 7965 } 7966 } 7967 7968 return rv; 7969 } 7970 7971 /* 7972 * Function: 7973 * bcm_td2_vxlan_ecmp_port_egress_nexthop_reset 7974 * Purpose: 7975 * Reset VXLAN ecmp Egress NextHop 7976 * Parameters: 7977 * IN : Unit 7978 * IN : ecmp_index 7979 * Returns: 7980 * BCM_E_XXX 7981 */ 7982 7983 int 7984 _bcm_td2_vxlan_ecmp_port_egress_nexthop_reset(int unit, int ecmp_index, int vp_type, int vp, bcm_vpn_t vpn) 7985 { 7986 int i = 0, ecmp_member_count = 0; 7987 int alloc_size, index; 7988 bcm_l3_egress_ecmp_t ecmp_info; 7989 bcm_if_t *ecmp_member_array = NULL; 7990 int rv = BCM_E_NONE; 7991 7992 if (!BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit, ecmp_index)) { 7993 return BCM_E_PARAM; 7994 } 7995 ecmp_info.ecmp_intf = ecmp_index; 7996 alloc_size = sizeof(bcm_if_t)*BCM_XGS3_L3_ECMP_MAX(unit); 7997 ecmp_member_array = sal_alloc(alloc_size, "ecmp member array"); 7998 if (NULL == ecmp_member_array) { 7999 return BCM_E_MEMORY; 8000 } 8001 sal_memset(ecmp_member_array, 0, alloc_size); 8002 8003 rv = bcm_esw_l3_egress_ecmp_get(unit, &ecmp_info, BCM_XGS3_L3_ECMP_MAX(unit), 8004 ecmp_member_array, &ecmp_member_count); 8005 if (BCM_FAILURE(rv)) { 8006 goto clean_up; 8007 } 8008 8009 while(i < ecmp_member_count) { 8010 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, 8011 ecmp_member_array[i])) { 8012 index = (ecmp_member_array[i] - BCM_XGS3_EGRESS_IDX_MIN(unit)); 8013 } else { 8014 rv = BCM_E_PARAM; 8015 goto clean_up; 8016 } 8017 8018 rv = _bcm_td2_vxlan_port_egress_nexthop_reset(unit, index, vp_type, 8019 vp, vpn); 8020 if (BCM_FAILURE(rv)) { 8021 goto clean_up; 8022 } 8023 i++; 8024 } 8025 8026 clean_up: 8027 if (ecmp_member_array) { 8028 sal_free(ecmp_member_array); 8029 ecmp_member_array = NULL; 8030 } 8031 8032 return rv; 8033 } 8034 8035 #if defined(BCM_TRIDENT3_SUPPORT) 8036 /* 8037 * Function: 8038 * _bcm_td3_vxlan_ecmp_acess_port_egress_nexthop_reset 8039 * Purpose: 8040 * Reset VXLAN access ecmp Egress NextHop 8041 * Parameters: 8042 * IN : Unit 8043 * IN : vp_type 8044 * IN : vp 8045 * IN : vpn 8046 * Returns: 8047 * BCM_E_XXX 8048 */ 8049 8050 int 8051 _bcm_td3_vxlan_ecmp_acess_port_egress_nexthop_reset(int unit, int vp_type, int vp, bcm_vpn_t vpn){ 8052 int rv = BCM_E_NONE; 8053 uint32 *vtab, *vtabp; 8054 int i, imin, imax, nent; 8055 soc_mem_t egr_l3_nh_mem = EGR_L3_NEXT_HOPm; 8056 int d = 0; /*vxlan decoupled mode*/ 8057 8058 #if defined(BCM_TRIDENT3_SUPPORT) 8059 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 8060 d = 1; 8061 } 8062 #endif 8063 8064 imin = soc_mem_index_min(unit, egr_l3_nh_mem); 8065 imax = soc_mem_index_max(unit, egr_l3_nh_mem); 8066 nent = soc_mem_index_count(unit, egr_l3_nh_mem); 8067 8068 vtab = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, egr_l3_nh_mem), "egr_l3_next_hop"); 8069 if (vtab == NULL) { 8070 return BCM_E_MEMORY; 8071 } 8072 sal_memset(vtab, 0, SOC_MEM_TABLE_BYTES(unit, egr_l3_nh_mem)); 8073 8074 soc_mem_lock(unit, egr_l3_nh_mem); 8075 rv = soc_mem_read_range(unit, egr_l3_nh_mem, MEM_BLOCK_ANY, 8076 imin, imax, vtab); 8077 if (BCM_FAILURE(rv)) { 8078 soc_mem_unlock(unit, egr_l3_nh_mem); 8079 soc_cm_sfree(unit, vtab); 8080 return rv; 8081 } 8082 8083 for (i = 0; i < nent; i++) { 8084 vtabp = soc_mem_table_idx_to_pointer(unit, egr_l3_nh_mem, 8085 void *, vtab, i); 8086 if (soc_mem_field32_get(unit, egr_l3_nh_mem, vtabp, DATA_TYPEf) 8087 != BCM_VXLAN_TAG_VIEW(d)) { 8088 continue; 8089 } 8090 8091 if (soc_mem_field32_get(unit, egr_l3_nh_mem, vtabp, BCM_VXLAN_TAG_FIELD(d, DVPf)) != vp) { 8092 continue; 8093 } 8094 /* Delete the entry from HW */ 8095 rv = _bcm_td2_vxlan_port_egress_nexthop_reset(unit, i, vp_type, 8096 vp, vpn); 8097 if (BCM_FAILURE(rv)) { 8098 soc_mem_unlock(unit, egr_l3_nh_mem); 8099 soc_cm_sfree(unit, vtab); 8100 return rv; 8101 } 8102 } 8103 soc_mem_unlock(unit, egr_l3_nh_mem); 8104 soc_cm_sfree(unit, vtab); 8105 8106 return rv; 8107 } 8108 #endif 8109 8110 /* 8111 * Function: 8112 * bcm_td2_vxlan_nexthop_reset 8113 * Purpose: 8114 * Reset VXLAN NextHop entry 8115 * Parameters: 8116 * IN : Unit 8117 * IN : nh_index 8118 * Returns: 8119 * BCM_E_XXX 8120 */ 8121 8122 STATIC int 8123 _bcm_td2_vxlan_nexthop_reset(int unit, int nh_index) 8124 { 8125 int rv=BCM_E_NONE; 8126 ing_l3_next_hop_entry_t ing_nh; 8127 egr_l3_next_hop_entry_t egr_nh; 8128 bcm_port_t port=0; 8129 bcm_trunk_t tgid= BCM_TRUNK_INVALID; 8130 int num_ports=0, idx=-1; 8131 bcm_port_t local_ports[SOC_MAX_NUM_PORTS]; 8132 soc_mem_t hw_mem; 8133 bcm_module_t modid=0, local_modid=0; 8134 uint8 multicast_entry=0; 8135 int old_nh_index=-1; 8136 int gport = 0; 8137 soc_field_t type_field; 8138 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8139 bcm_trunk_member_t *tmp_member_gports_array = NULL; 8140 #endif 8141 8142 hw_mem = EGR_L3_NEXT_HOPm; 8143 8144 #if defined(BCM_TRIDENT3_SUPPORT) 8145 if (SOC_MEM_FIELD_VALID(unit, hw_mem, DATA_TYPEf)) { 8146 type_field = DATA_TYPEf; 8147 } else 8148 #endif 8149 { 8150 type_field = ENTRY_TYPEf; 8151 } 8152 8153 BCM_IF_ERROR_RETURN(soc_mem_read(unit, hw_mem, 8154 MEM_BLOCK_ANY, nh_index, &egr_nh)); 8155 if (_BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW == soc_mem_field32_get(unit, 8156 hw_mem, &egr_nh, type_field)) { 8157 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8158 if (soc_feature(unit, soc_feature_egr_l3_next_hop_next_ptr)) { 8159 if (0x1 == soc_mem_field32_get(unit, hw_mem, &egr_nh, 8160 L3MC__NEXT_PTR_TYPEf)) { 8161 multicast_entry = 1; /* Multicast NextHop */ 8162 } 8163 } else 8164 #endif 8165 if (0x1 == soc_mem_field32_get(unit, hw_mem, &egr_nh, 8166 L3MC__DVP_VALIDf)) { 8167 multicast_entry = 1; /* Multicast NextHop */ 8168 } 8169 } 8170 8171 hw_mem = ING_L3_NEXT_HOPm; 8172 BCM_IF_ERROR_RETURN(soc_mem_read(unit, hw_mem, 8173 MEM_BLOCK_ANY, nh_index, &ing_nh)); 8174 soc_mem_field32_set(unit, hw_mem, &ing_nh, 8175 DROPf, 0x0); 8176 soc_mem_field32_set(unit, hw_mem, &ing_nh, 8177 ENTRY_TYPEf, 0x0); 8178 BCM_IF_ERROR_RETURN(soc_mem_write(unit, hw_mem, 8179 MEM_BLOCK_ALL, nh_index, &ing_nh)); 8180 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_nexthop_glp_get(unit, 8181 nh_index, &modid, &port, &tgid)); 8182 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get (unit, &local_modid)); 8183 if (tgid != BCM_TRUNK_INVALID) { 8184 rv = _bcm_trunk_id_validate(unit, tgid); 8185 if (BCM_FAILURE(rv)) { 8186 return BCM_E_PORT; 8187 } 8188 rv = bcm_esw_trunk_get(unit, tgid, NULL, 0, NULL, &num_ports); 8189 if (BCM_FAILURE(rv)) { 8190 return BCM_E_PORT; 8191 } 8192 if (num_ports == 0) { 8193 return BCM_E_NONE; 8194 } 8195 8196 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8197 if(soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 8198 tmp_member_gports_array = sal_alloc( 8199 sizeof(bcm_trunk_member_t) * num_ports, "tmp_member_gports_arry"); 8200 if (tmp_member_gports_array == NULL) { 8201 return BCM_E_MEMORY; 8202 } 8203 sal_memset(tmp_member_gports_array, 0, 8204 sizeof(bcm_trunk_member_t) * num_ports); 8205 rv = bcm_esw_trunk_get(unit, tgid, NULL, 8206 num_ports, tmp_member_gports_array, &num_ports); 8207 if (BCM_FAILURE(rv)) { 8208 goto clean_up; 8209 } 8210 } else 8211 #endif 8212 { 8213 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid, 8214 SOC_MAX_NUM_PORTS, local_ports, &num_ports)); 8215 modid = local_modid; 8216 } 8217 } else { 8218 if (modid != local_modid) { 8219 if (!soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 8220 /* Ignore EGR_PORT_TO_NHI_MAPPINGs */ 8221 return BCM_E_NONE; 8222 } 8223 } 8224 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8225 if(soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 8226 /* Alloc one trunk member size memory */ 8227 tmp_member_gports_array = sal_alloc( 8228 sizeof(bcm_trunk_member_t), "tmp_member_gports_arry"); 8229 if (tmp_member_gports_array == NULL) { 8230 return BCM_E_MEMORY; 8231 } 8232 sal_memset(tmp_member_gports_array, 0, 8233 sizeof(bcm_trunk_member_t)); 8234 BCM_GPORT_MODPORT_SET(gport, modid, port); 8235 tmp_member_gports_array[num_ports++].gport = gport; 8236 } else 8237 #endif 8238 { 8239 local_ports[num_ports++] = port; 8240 } 8241 } 8242 8243 if (!multicast_entry) { 8244 for (idx = 0; idx < num_ports; idx++) { 8245 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8246 if(soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 8247 gport = tmp_member_gports_array[idx].gport; 8248 } else 8249 #endif 8250 { 8251 BCM_GPORT_MODPORT_SET(gport, modid, local_ports[idx]); 8252 } 8253 8254 rv = _bcm_trx_gport_to_nhi_get(unit, gport, &old_nh_index); 8255 if (BCM_FAILURE(rv)) { 8256 goto clean_up; 8257 } 8258 if (old_nh_index == nh_index) { 8259 rv = _bcm_trx_gport_to_nhi_set(unit, gport, 0); 8260 if (BCM_FAILURE(rv)) { 8261 goto clean_up; 8262 } 8263 } 8264 } 8265 } 8266 8267 clean_up: 8268 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8269 if (NULL != tmp_member_gports_array) { 8270 sal_free(tmp_member_gports_array); 8271 } 8272 #endif 8273 return rv; 8274 } 8275 8276 /* 8277 * Function: 8278 * bcm_td2_vxlan_egress_reset 8279 * Purpose: 8280 * Reset VXLAN Egress NextHop 8281 * Parameters: 8282 * IN : Unit 8283 * IN : nh_index 8284 * Returns: 8285 * BCM_E_XXX 8286 */ 8287 8288 int 8289 bcm_td2_vxlan_egress_reset(int unit, int nh_index) 8290 { 8291 ing_l3_next_hop_entry_t ing_nh; 8292 soc_mem_t hw_mem; 8293 int rv=BCM_E_NONE; 8294 8295 hw_mem = ING_L3_NEXT_HOPm; 8296 BCM_IF_ERROR_RETURN(soc_mem_read(unit, hw_mem, 8297 MEM_BLOCK_ANY, nh_index, &ing_nh)); 8298 soc_mem_field32_set(unit, hw_mem, &ing_nh, 8299 ENTRY_TYPEf, 0x0); 8300 if (SOC_MEM_FIELD_VALID(unit, ING_L3_NEXT_HOPm, MTU_SIZEf)) { 8301 soc_mem_field32_set(unit, ING_L3_NEXT_HOPm, 8302 &ing_nh, MTU_SIZEf, 0x0); 8303 } 8304 BCM_IF_ERROR_RETURN(soc_mem_write(unit, hw_mem, 8305 MEM_BLOCK_ALL, nh_index, &ing_nh)); 8306 8307 rv = _bcm_td2_vxlan_nexthop_reset(unit, nh_index); 8308 return rv; 8309 } 8310 8311 /* 8312 * Function: 8313 * bcm_td2_vxlan_egress_get 8314 * Purpose: 8315 * Get VXLAN Egress NextHop 8316 * Parameters: 8317 * IN : Unit 8318 * IN : nh_index 8319 * Returns: 8320 * BCM_E_XXX 8321 */ 8322 8323 int 8324 bcm_td2_vxlan_egress_get(int unit, bcm_l3_egress_t *egr, int nh_index) 8325 { 8326 int int_l3_flag; 8327 int_l3_flag = BCM_XGS3_L3_ENT_FLAG(BCM_XGS3_L3_TBL_PTR(unit, next_hop), 8328 nh_index); 8329 if (int_l3_flag == _BCM_L3_VXLAN_ONLY) { 8330 egr->flags |= BCM_L3_VXLAN_ONLY; 8331 } 8332 8333 return BCM_E_NONE; 8334 } 8335 8336 /* 8337 * Function: 8338 * _bcm_td2_vxlan_higig_ppd_select 8339 * Purpose: 8340 * Select PPD type for Higig header 8341 * Parameters: 8342 * IN : Unit 8343 * IN : nh_index 8344 * IN : flags 8345 * Returns: 8346 * BCM_E_XXX 8347 */ 8348 int 8349 _bcm_td2_vxlan_higig_ppd_select(int unit, int nh_index, uint32 flags) 8350 { 8351 egr_l3_next_hop_entry_t egr_nh; 8352 int entry_type = 0; 8353 int d = 0; /*vxlan decoupled mode*/ 8354 8355 #if defined(BCM_TRIDENT3_SUPPORT) 8356 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 8357 d = 1; 8358 } 8359 #endif 8360 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL, 8361 nh_index, &egr_nh)); 8362 #if defined(BCM_TRIDENT3_SUPPORT) 8363 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 8364 entry_type = soc_mem_field32_get(unit, 8365 EGR_L3_NEXT_HOPm, &egr_nh, DATA_TYPEf); 8366 } else 8367 #endif 8368 { 8369 entry_type = soc_mem_field32_get(unit, 8370 EGR_L3_NEXT_HOPm, &egr_nh, ENTRY_TYPEf); 8371 } 8372 8373 if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3_VIEW) { 8374 if (flags & BCM_VXLAN_PORT_ENCAP_LOCAL) { 8375 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 8376 L3__HG_L2_TUNNEL_ENCAP_ENABLEf)) { 8377 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8378 L3__HG_L2_TUNNEL_ENCAP_ENABLEf, 1); 8379 } 8380 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8381 L3__HG_HDR_SELf, 0); 8382 } else { 8383 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 8384 L3__HG_L2_TUNNEL_ENCAP_ENABLEf)) { 8385 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8386 L3__HG_L2_TUNNEL_ENCAP_ENABLEf, 0); 8387 } 8388 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8389 L3__HG_HDR_SELf, 1); 8390 } 8391 } else if (entry_type == BCM_VXLAN_TAG_VIEW(d)) { 8392 if (flags & BCM_VXLAN_PORT_ENCAP_LOCAL) { 8393 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8394 BCM_VXLAN_TAG_FIELD(d, HG_HDR_SELf), 0); 8395 } else { 8396 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8397 BCM_VXLAN_TAG_FIELD(d, HG_HDR_SELf), 1); 8398 } 8399 } else if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW) { 8400 if (flags & BCM_VXLAN_PORT_ENCAP_LOCAL) { 8401 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8402 L3MC__HG_HDR_SELf, 0); 8403 } else { 8404 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 8405 L3MC__HG_HDR_SELf, 1); 8406 } 8407 } 8408 8409 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_L3_NEXT_HOPm, 8410 MEM_BLOCK_ALL, nh_index, &egr_nh)); 8411 return BCM_E_NONE; 8412 } 8413 8414 /* 8415 * Function: 8416 * _bcm_td2_vxlan_ecmp_higig_ppd_select 8417 * Purpose: 8418 * Modify vxlan ecmp member object's higig ppd select 8419 * Parameters: 8420 * unit - Device Number 8421 * ecmp_index - ECMP index 8422 * flags - vxlan vp flags 8423 * Returns: 8424 * BCM_E_XXX 8425 */ 8426 8427 int 8428 _bcm_td2_vxlan_ecmp_higig_ppd_select(int unit, int ecmp_index, uint32 flags) 8429 { 8430 int i = 0, ecmp_member_count = 0; 8431 int alloc_size, index; 8432 bcm_l3_egress_ecmp_t ecmp_info; 8433 bcm_if_t *ecmp_member_array = NULL; 8434 int rv = BCM_E_NONE; 8435 8436 if (!BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit, ecmp_index)) { 8437 return BCM_E_PARAM; 8438 } 8439 ecmp_info.ecmp_intf = ecmp_index; 8440 alloc_size = sizeof(bcm_if_t) * BCM_XGS3_L3_ECMP_MAX(unit); 8441 ecmp_member_array = sal_alloc(alloc_size, "ecmp member array"); 8442 if (NULL == ecmp_member_array) { 8443 return BCM_E_MEMORY; 8444 } 8445 sal_memset(ecmp_member_array, 0, alloc_size); 8446 8447 rv = bcm_esw_l3_egress_ecmp_get(unit, &ecmp_info, BCM_XGS3_L3_ECMP_MAX(unit), 8448 ecmp_member_array, &ecmp_member_count); 8449 if (BCM_FAILURE(rv)) { 8450 goto clean_up; 8451 } 8452 8453 while(i < ecmp_member_count) { 8454 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, 8455 ecmp_member_array[i])) { 8456 index = (ecmp_member_array[i] - BCM_XGS3_EGRESS_IDX_MIN(unit)); 8457 8458 } else { 8459 rv = BCM_E_PARAM; 8460 goto clean_up; 8461 } 8462 rv = _bcm_td2_vxlan_higig_ppd_select(unit, index, flags); 8463 8464 if (BCM_FAILURE(rv)) { 8465 goto clean_up; 8466 } 8467 8468 i++; 8469 } 8470 8471 clean_up: 8472 if (ecmp_member_array) { 8473 sal_free(ecmp_member_array); 8474 ecmp_member_array = NULL; 8475 } 8476 8477 return rv; 8478 } 8479 8480 /* 8481 * Function: 8482 * _bcm_td2_vxlan_ecmp_nexthop_entry_modify 8483 * Purpose: 8484 * Modify vxlan ecmp member object's Egress next hop entry 8485 * Parameters: 8486 * unit - Device Number 8487 * ecmp_nh_index - ECMP index 8488 * drop - local drop 8489 * egr_nh_info - egr nh info 8490 * new_entry_type - New Entry type 8491 * Returns: 8492 * BCM_E_XXX 8493 */ 8494 8495 int 8496 _bcm_td2_vxlan_ecmp_nexthop_entry_modify(int unit, int ecmp_index, int drop, 8497 _bcm_td2_vxlan_nh_info_t egr_nh_info, int new_entry_type) 8498 { 8499 int i = 0, ecmp_member_count = 0; 8500 int alloc_size, index; 8501 bcm_l3_egress_ecmp_t ecmp_info; 8502 bcm_if_t *ecmp_member_array = NULL; 8503 int rv = BCM_E_NONE; 8504 8505 if (!BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit, ecmp_index)) { 8506 return BCM_E_PARAM; 8507 } 8508 ecmp_info.ecmp_intf = ecmp_index; 8509 alloc_size = sizeof(bcm_if_t)*BCM_XGS3_L3_ECMP_MAX(unit); 8510 ecmp_member_array = sal_alloc(alloc_size, "ecmp member array"); 8511 if (NULL == ecmp_member_array) { 8512 return BCM_E_MEMORY; 8513 } 8514 sal_memset(ecmp_member_array, 0, alloc_size); 8515 8516 rv = bcm_esw_l3_egress_ecmp_get(unit, &ecmp_info, BCM_XGS3_L3_ECMP_MAX(unit), 8517 ecmp_member_array, &ecmp_member_count); 8518 if (BCM_FAILURE(rv)) { 8519 goto clean_up; 8520 } 8521 8522 while(i < ecmp_member_count) { 8523 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, 8524 ecmp_member_array[i])) { 8525 index = (ecmp_member_array[i] - BCM_XGS3_EGRESS_IDX_MIN(unit)); 8526 8527 } else { 8528 rv = BCM_E_PARAM; 8529 goto clean_up; 8530 } 8531 rv = _bcm_td2_vxlan_nexthop_entry_modify(unit, index, drop, 8532 &egr_nh_info, new_entry_type); 8533 if (BCM_FAILURE(rv)) { 8534 goto clean_up; 8535 } 8536 8537 i++; 8538 } 8539 clean_up: 8540 if (ecmp_member_array) { 8541 sal_free(ecmp_member_array); 8542 ecmp_member_array = NULL; 8543 } 8544 8545 return rv; 8546 } 8547 8548 /* 8549 * Function: 8550 * _bcm_td2_vxlan_port_nh_add 8551 * Purpose: 8552 * Add VXLAN Next Hop entry 8553 * Parameters: 8554 * Returns: 8555 * BCM_E_XXX 8556 */ 8557 8558 STATIC int 8559 _bcm_td2_vxlan_port_nh_add(int unit, bcm_vxlan_port_t *vxlan_port, int vp, 8560 bcm_vpn_t vpn, int drop) 8561 { 8562 egr_l3_next_hop_entry_t egr_nh; 8563 _bcm_td2_vxlan_nh_info_t egr_nh_info; 8564 int rv=BCM_E_NONE; 8565 int action_present, action_not_present, tpid_index = -1; 8566 int old_tpid_idx = -1; 8567 uint32 mpath_flag=0; 8568 int vp_nh_ecmp_index=-1; 8569 int ref_count = 0; 8570 #ifdef BCM_RIOT_SUPPORT 8571 int nh_ecmp_index = -1; 8572 ing_dvp_table_entry_t dvp; 8573 #endif /* BCM_RIOT_SUPPORT */ 8574 int network_group=0; 8575 int d = 0; /*vxlan decoupled mode*/ 8576 8577 #if defined(BCM_TRIDENT3_SUPPORT) 8578 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 8579 d = 1; 8580 } 8581 #endif 8582 egr_nh_info.dvp = vp; 8583 egr_nh_info.entry_type = -1; 8584 egr_nh_info.dvp_is_network = -1; 8585 egr_nh_info.sd_tag_action_present = -1; 8586 egr_nh_info.sd_tag_action_not_present = -1; 8587 egr_nh_info.intf_num = -1; 8588 egr_nh_info.sd_tag_vlan = -1; 8589 egr_nh_info.sd_tag_pri = -1; 8590 egr_nh_info.sd_tag_cfi = -1; 8591 egr_nh_info.tpid_index = -1; 8592 egr_nh_info.is_eline = 0; /* Change to 1 for Eline */ 8593 egr_nh_info.dvp_network_group_id = 0; 8594 8595 network_group = vxlan_port->network_group_id; 8596 rv = _bcm_validate_splithorizon_network_group(unit, 8597 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 8598 BCM_IF_ERROR_RETURN(rv); 8599 egr_nh_info.dvp_network_group_id = network_group; 8600 8601 #ifdef BCM_RIOT_SUPPORT 8602 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 8603 SOC_IF_ERROR_RETURN( 8604 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 8605 8606 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 8607 NEXT_HOP_INDEXf); 8608 } 8609 #endif /* BCM_RIOT_SUPPORT */ 8610 8611 /* 8612 * Get egress next-hop index from egress object and 8613 * increment egress object reference count. 8614 */ 8615 if (!(vxlan_port->flags & BCM_VXLAN_PORT_SHARE)) { 8616 rv = bcm_xgs3_get_nh_from_egress_object(unit, vxlan_port->egress_if, 8617 &mpath_flag, 1, &vp_nh_ecmp_index); 8618 BCM_IF_ERROR_RETURN(rv); 8619 8620 /* Read the existing egress next_hop entry */ 8621 if (mpath_flag == 0) { 8622 if (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 8623 int l3_flag = BCM_XGS3_L3_ENT_FLAG( 8624 BCM_XGS3_L3_TBL_PTR(unit, next_hop), vp_nh_ecmp_index); 8625 if (l3_flag != _BCM_L3_VXLAN_ONLY) { 8626 rv = BCM_E_CONFIG; 8627 goto cleanup; 8628 } 8629 } 8630 8631 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 8632 vp_nh_ecmp_index, &egr_nh); 8633 _BCM_VXLAN_CLEANUP(rv) 8634 } 8635 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 8636 else { 8637 /* 8638 * When Multi-level ECMP is enabled, ECMP group pointed 8639 * to by DVP must be an underlay group. 8640 */ 8641 if (BCMI_L3_ECMP_IS_MULTI_LEVEL(unit)) { 8642 if (vp_nh_ecmp_index < BCMI_L3_ECMP_OVERLAY_ENTRIES(unit)) { 8643 return BCM_E_PARAM; 8644 } 8645 } 8646 } 8647 #endif 8648 } 8649 8650 if (vxlan_port->flags & BCM_VXLAN_PORT_EGRESS_TUNNEL) { 8651 8652 /* Program DVP entry - Egress */ 8653 rv = _bcm_td2_vxlan_egress_dvp_set(unit, vp, drop, vxlan_port); 8654 _BCM_VXLAN_CLEANUP(rv) 8655 8656 /* Program DVP entry - Ingress */ 8657 rv = _bcm_td2_vxlan_ingress_dvp_set(unit, vp, mpath_flag, vp_nh_ecmp_index, vxlan_port); 8658 _BCM_VXLAN_CLEANUP(rv) 8659 8660 rv = _bcm_td2_vxlan_ingress_dvp_2_set(unit, vp, mpath_flag, vp_nh_ecmp_index, vxlan_port); 8661 _BCM_VXLAN_CLEANUP(rv) 8662 8663 if ((vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST) && 8664 (!(vxlan_port->flags & BCM_VXLAN_PORT_SHARE))) { 8665 /* Egress into Network - Tunnel */ 8666 egr_nh_info.dvp_is_network = 1; /* Enable */ 8667 if (mpath_flag == 0) { 8668 #if defined(BCM_TRIDENT3_SUPPORT) 8669 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_NEXT_HOPm, DATA_TYPEf)) { 8670 egr_nh_info.entry_type = 8671 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, DATA_TYPEf); 8672 } else 8673 #endif 8674 { 8675 egr_nh_info.entry_type = 8676 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, ENTRY_TYPEf); 8677 } 8678 8679 rv = _bcm_td2_vxlan_nexthop_entry_modify(unit, vp_nh_ecmp_index, drop, 8680 &egr_nh_info, _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW); 8681 _BCM_VXLAN_CLEANUP(rv) 8682 } else { 8683 /*ecmp*/ 8684 rv = _bcm_td2_vxlan_ecmp_nexthop_entry_modify(unit, vxlan_port->egress_if, drop, 8685 egr_nh_info, _BCM_VXLAN_EGR_NEXT_HOP_L3MC_VIEW); 8686 _BCM_VXLAN_CLEANUP(rv) 8687 } 8688 } 8689 8690 /* Don't select shared network multicast VP's HG header here*/ 8691 if (!(vxlan_port->flags & BCM_VXLAN_PORT_SHARE)) { 8692 if (mpath_flag == 0) { 8693 rv = _bcm_td2_vxlan_higig_ppd_select(unit, vp_nh_ecmp_index, vxlan_port->flags); 8694 _BCM_VXLAN_CLEANUP(rv) 8695 } else { 8696 rv = _bcm_td2_vxlan_ecmp_higig_ppd_select(unit, vxlan_port->egress_if, 8697 vxlan_port->flags); 8698 _BCM_VXLAN_CLEANUP(rv) 8699 } 8700 } 8701 } else { 8702 /* Program DVP entry - Egress */ 8703 rv = _bcm_td2_vxlan_egress_access_dvp_set(unit, vp, drop, vxlan_port); 8704 _BCM_VXLAN_CLEANUP(rv) 8705 8706 /* Egress into Access - Non Tunnel */ 8707 egr_nh_info.dvp_is_network = 0; /* Disable */ 8708 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 8709 action_present = 8710 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 8711 SD_TAG__SD_TAG_ACTION_IF_PRESENTf); 8712 action_not_present = 8713 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 8714 SD_TAG__SD_TAG_ACTION_IF_NOT_PRESENTf); 8715 if ((action_not_present == 0x1) || (action_present == 0x1) || 8716 (action_present == 0x4) || (action_present == 0x7)) { 8717 /* If old tpid exist, delete it */ 8718 old_tpid_idx = soc_EGR_L3_NEXT_HOPm_field32_get(unit, 8719 &egr_nh, SD_TAG__SD_TAG_TPID_INDEXf); 8720 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_delete(unit, old_tpid_idx)); 8721 } 8722 } 8723 8724 egr_nh_info.entry_type = BCM_VXLAN_TAG_VIEW(d); 8725 /* Configure SD_TAG setting */ 8726 rv = _bcm_td2_vxlan_sd_tag_set(unit, NULL, vxlan_port, &egr_nh_info, NULL, &tpid_index); 8727 _BCM_VXLAN_CLEANUP(rv) 8728 #if defined(BCM_TRIDENT3_SUPPORT) 8729 if (SOC_IS_TRIDENT3X(unit) && mpath_flag) { 8730 rv = _bcm_td2_vxlan_ecmp_nexthop_entry_modify(unit, vxlan_port->egress_if, drop, 8731 egr_nh_info, BCM_VXLAN_TAG_VIEW(d)); 8732 _BCM_VXLAN_CLEANUP(rv) 8733 8734 rv = _bcm_td2_vxlan_ecmp_higig_ppd_select(unit, vxlan_port->egress_if, vxlan_port->flags); 8735 _BCM_VXLAN_CLEANUP(rv) 8736 } else 8737 #endif 8738 { 8739 /* Configure EGR Next Hop entry -- SD_TAG view */ 8740 rv = _bcm_td2_vxlan_nexthop_entry_modify(unit, vp_nh_ecmp_index, drop, 8741 &egr_nh_info, BCM_VXLAN_TAG_VIEW(d)); 8742 _BCM_VXLAN_CLEANUP(rv) 8743 rv = _bcm_td2_vxlan_higig_ppd_select(unit, vp_nh_ecmp_index, vxlan_port->flags); 8744 _BCM_VXLAN_CLEANUP(rv) 8745 } 8746 8747 if (!(vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST)) { 8748 /* Program DVP entry with ECMP / Next Hop Index */ 8749 rv = _bcm_td2_vxlan_ingress_dvp_set(unit, vp, mpath_flag, vp_nh_ecmp_index, vxlan_port); 8750 _BCM_VXLAN_CLEANUP(rv) 8751 8752 rv = _bcm_td2_vxlan_ingress_dvp_2_set(unit, vp, mpath_flag, vp_nh_ecmp_index, vxlan_port); 8753 _BCM_VXLAN_CLEANUP(rv) 8754 8755 } 8756 } 8757 8758 #ifdef BCM_RIOT_SUPPORT 8759 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 8760 rv = bcmi_l3_nh_assoc_ol_ul_link_replace(unit, nh_ecmp_index, 8761 vp_nh_ecmp_index); 8762 } 8763 #endif /* BCM_RIOT_SUPPORT */ 8764 return rv; 8765 8766 cleanup: 8767 if (tpid_index != -1) { 8768 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 8769 } 8770 if (vp_nh_ecmp_index != -1) { 8771 /* Decrement reference count */ 8772 (void) bcm_xgs3_get_ref_count_from_nhi( 8773 unit, mpath_flag, &ref_count, vp_nh_ecmp_index); 8774 } 8775 return rv; 8776 } 8777 8778 /* 8779 * Function: 8780 * _bcm_td2_vxlan_port_nh_delete 8781 * Purpose: 8782 * Delete VXLAN Next Hop entry 8783 * Parameters: 8784 * Returns: 8785 * BCM_E_XXX 8786 */ 8787 8788 STATIC int 8789 _bcm_td2_vxlan_port_nh_delete(int unit, bcm_vpn_t vpn, int vp) 8790 { 8791 int rv=BCM_E_NONE; 8792 int nh_ecmp_index=-1; 8793 ing_dvp_table_entry_t dvp; 8794 uint32 vp_type=0; 8795 uint32 flags=0; 8796 int ref_count=0; 8797 int ecmp =-1; 8798 int ecmp_index_check_skip = 0; 8799 8800 BCM_IF_ERROR_RETURN( 8801 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 8802 8803 vp_type = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, VP_TYPEf); 8804 ecmp = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMPf); 8805 #if defined (BCM_MONTEREY_SUPPORT) 8806 if (SOC_IS_MONTEREY(unit) && (!soc_feature(unit, soc_feature_vp_lag))) { 8807 ecmp_index_check_skip = 1; 8808 } 8809 #endif 8810 8811 if (ecmp) { 8812 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMP_PTRf); 8813 flags = BCM_L3_MULTIPATH; 8814 /* Decrement reference count */ 8815 BCM_IF_ERROR_RETURN( 8816 bcm_xgs3_get_ref_count_from_nhi(unit, flags, &ref_count, nh_ecmp_index)); 8817 if (ref_count == 1) { 8818 if (nh_ecmp_index || ecmp_index_check_skip) { 8819 if (vp_type == _BCM_VXLAN_INGRESS_DEST_VP_TYPE) { 8820 BCM_IF_ERROR_RETURN( 8821 _bcm_td2_vxlan_ecmp_port_egress_nexthop_reset 8822 (unit, (nh_ecmp_index + BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit)), 8823 vp_type, vp, vpn)); 8824 } 8825 #if defined(BCM_TRIDENT3_SUPPORT) 8826 else if ((vp_type == _BCM_VXLAN_DEST_VP_TYPE_ACCESS) && SOC_IS_TRIDENT3X(unit)) { 8827 BCM_IF_ERROR_RETURN( 8828 _bcm_td3_vxlan_ecmp_acess_port_egress_nexthop_reset 8829 (unit, vp_type, vp, vpn)); 8830 } 8831 #endif 8832 } 8833 } 8834 } else { 8835 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 8836 NEXT_HOP_INDEXf); 8837 if(nh_ecmp_index != 0) { 8838 /* Decrement reference count */ 8839 BCM_IF_ERROR_RETURN( 8840 bcm_xgs3_get_ref_count_from_nhi(unit, flags, &ref_count, nh_ecmp_index)); 8841 } 8842 if (ref_count == 1) { 8843 if (nh_ecmp_index) { 8844 BCM_IF_ERROR_RETURN( 8845 _bcm_td2_vxlan_port_egress_nexthop_reset 8846 (unit, nh_ecmp_index, vp_type, vp, vpn)); 8847 } 8848 } 8849 } 8850 return rv; 8851 } 8852 8853 /* 8854 * Function: 8855 * _bcm_td2_vxlan_ecmp_member_egress_get_first 8856 * Purpose: 8857 * Modify vxlan ecmp member object's Egress next hop entry 8858 * Parameters: 8859 * unit - Device Number 8860 * ecmp_index - ECMP index 8861 * index - poiter to first next hop index 8862 * Returns: 8863 * BCM_E_XXX 8864 */ 8865 8866 STATIC int 8867 _bcm_td2_vxlan_ecmp_member_egress_get_first(int unit, int ecmp_index, int* index) 8868 { 8869 int i = 0, ecmp_member_count = 0; 8870 int alloc_size; 8871 bcm_l3_egress_ecmp_t ecmp_info; 8872 bcm_if_t *ecmp_member_array = NULL; 8873 int rv = BCM_E_NONE; 8874 8875 if (!BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit, ecmp_index)) { 8876 return BCM_E_PARAM; 8877 } 8878 ecmp_info.ecmp_intf = ecmp_index; 8879 alloc_size = sizeof(bcm_if_t)*BCM_XGS3_L3_ECMP_MAX(unit); 8880 ecmp_member_array = sal_alloc(alloc_size, "ecmp member array"); 8881 if (NULL == ecmp_member_array) { 8882 return BCM_E_MEMORY; 8883 } 8884 sal_memset(ecmp_member_array, 0, alloc_size); 8885 8886 rv = bcm_esw_l3_egress_ecmp_get(unit, &ecmp_info, BCM_XGS3_L3_ECMP_MAX(unit), 8887 ecmp_member_array, &ecmp_member_count); 8888 if (BCM_FAILURE(rv)) { 8889 goto clean_up; 8890 } 8891 8892 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, 8893 ecmp_member_array[i])) { 8894 *index = (ecmp_member_array[i] - BCM_XGS3_EGRESS_IDX_MIN(unit)); 8895 } else { 8896 rv = BCM_E_PARAM; 8897 goto clean_up; 8898 } 8899 clean_up: 8900 if (ecmp_member_array) { 8901 sal_free(ecmp_member_array); 8902 ecmp_member_array = NULL; 8903 } 8904 8905 return rv; 8906 } 8907 8908 /* 8909 * Function: 8910 * _bcm_td2_vxlan_port_nh_get 8911 * Purpose: 8912 * Get VXLAN Next Hop entry 8913 * Parameters: 8914 * Returns: 8915 * BCM_E_XXX 8916 */ 8917 8918 STATIC int 8919 _bcm_td2_vxlan_port_nh_get(int unit, bcm_vpn_t vpn, int vp, bcm_vxlan_port_t *vxlan_port) 8920 { 8921 egr_l3_next_hop_entry_t egr_nh; 8922 ing_dvp_table_entry_t dvp; 8923 int nh_ecmp_index=0; 8924 uint32 ecmp=0; 8925 int rv = BCM_E_NONE; 8926 8927 /* Read the HW entries */ 8928 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 8929 8930 if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp, VP_TYPEf) == 8931 _BCM_VXLAN_INGRESS_DEST_VP_TYPE) { 8932 /* Egress into VXLAN tunnel, find the tunnel_if */ 8933 vxlan_port->flags |= BCM_VXLAN_PORT_EGRESS_TUNNEL; 8934 BCM_IF_ERROR_RETURN( 8935 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 8936 ecmp = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMPf); 8937 if (ecmp) { 8938 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, ECMP_PTRf); 8939 vxlan_port->egress_if = nh_ecmp_index + BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 8940 /*get ecmp's first member nexthop index*/ 8941 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_ecmp_member_egress_get_first(unit, vxlan_port->egress_if, 8942 &nh_ecmp_index)); 8943 } else { 8944 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 8945 /* Extract next hop index from unipath egress object. */ 8946 vxlan_port->egress_if = nh_ecmp_index + BCM_XGS3_EGRESS_IDX_MIN(unit); 8947 } 8948 8949 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 8950 MEM_BLOCK_ANY, nh_ecmp_index, &egr_nh)); 8951 8952 } else if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 8953 VP_TYPEf) == _BCM_VXLAN_DEST_VP_TYPE_ACCESS) { 8954 /* Egress into Access-side, find the tunnel_if */ 8955 BCM_IF_ERROR_RETURN( 8956 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 8957 nh_ecmp_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 8958 /* Extract next hop index from unipath egress object. */ 8959 vxlan_port->egress_if = nh_ecmp_index + BCM_XGS3_EGRESS_IDX_MIN(unit); 8960 8961 BCM_IF_ERROR_RETURN (soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 8962 nh_ecmp_index, &egr_nh)); 8963 if (BCM_SUCCESS(rv)) { 8964 (void) _bcm_td2_vxlan_sd_tag_get( unit, NULL, vxlan_port, &egr_nh, 8965 NULL, 0); 8966 } 8967 } else { 8968 return BCM_E_NOT_FOUND; 8969 } 8970 8971 rv = bcm_td2_vxlan_nexthop_get(unit, &egr_nh, vxlan_port); 8972 8973 return rv; 8974 } 8975 8976 /* 8977 * Function: 8978 * _bcm_td2_vxlan_match_vnid_entry_reset 8979 * Purpose: 8980 * Reset VXLAN Match VNID Entry 8981 * Parameters: 8982 * IN : Unit 8983 * IN : Vnid 8984 * Returns: 8985 * BCM_E_XXX 8986 */ 8987 8988 STATIC int 8989 _bcm_td2_vxlan_match_vnid_entry_reset(int unit, uint32 vnid, 8990 bcm_vlan_t ovid) 8991 { 8992 soc_mem_t mmem = MPLS_ENTRYm; 8993 uint32 ment[SOC_MAX_MEM_WORDS]; 8994 int d = 0; /*vxlan decoupled mode*/ 8995 8996 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 8997 8998 #if defined(BCM_TRIDENT3_SUPPORT) 8999 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 9000 mmem = VLAN_XLATE_1_DOUBLEm; 9001 d =1; 9002 soc_mem_field32_set(unit, mmem, &ment, BASE_VALID_0f, 3); 9003 soc_mem_field32_set(unit, mmem, &ment, BASE_VALID_1f, 7); 9004 soc_mem_field32_set(unit, mmem, &ment, 9005 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_VNID_VFI_FLEX); 9006 soc_mem_field32_set(unit, mmem, &ment, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_VNID_VFI_FLEX); 9007 } else 9008 #endif 9009 { 9010 soc_mem_field32_set(unit, mmem, &ment, VALIDf, 1); 9011 soc_mem_field32_set(unit, mmem, &ment, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_VNID_VFI); 9012 } 9013 9014 soc_mem_field32_set(unit, mmem, &ment, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), vnid); 9015 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9016 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 9017 soc_mem_field32_set(unit, mmem, &ment, VXLAN_VN_ID__OVIDf, ovid); 9018 } 9019 #endif 9020 9021 BCM_IF_ERROR_RETURN(soc_mem_delete(unit, mmem, MEM_BLOCK_ALL, &ment)); 9022 9023 return BCM_E_NONE; 9024 } 9025 9026 /* 9027 * Function: 9028 * _bcm_td2_vxlan_match_tunnel_entry_update 9029 * Purpose: 9030 * Update Match VXLAN Tunnel Entry 9031 * Parameters: 9032 * IN : Unit 9033 * IN : vxlan_entry 9034 * OUT : vxlan_entry 9035 9036 */ 9037 9038 STATIC int 9039 _bcm_td2_vxlan_match_tunnel_entry_update(int unit, 9040 uint32 *ment, 9041 uint32 *new_ment, 9042 uint32 *return_ment) 9043 { 9044 uint32 value=0, key_type=0; 9045 soc_mem_t mem = MPLS_ENTRYm; 9046 9047 /* Check if Key_Type identical */ 9048 key_type = soc_mem_field32_get(unit, mem, ment, KEY_TYPEf); 9049 value = soc_mem_field32_get(unit, mem, return_ment, KEY_TYPEf); 9050 if (key_type != value) { 9051 return BCM_E_PARAM; 9052 } 9053 #if defined(BCM_TRIDENT3_SUPPORT) 9054 if (soc_feature(unit, soc_feature_base_valid)) { 9055 soc_mem_field32_set(unit, mem, new_ment, BASE_VALID_0f, 3); 9056 soc_mem_field32_set(unit, mem, new_ment, BASE_VALID_1f, 7); 9057 soc_mem_field32_set(unit, mem, new_ment, 9058 DATA_TYPEf, key_type); 9059 } else 9060 #endif 9061 { 9062 soc_mem_field32_set(unit, mem, new_ment, VALIDf, 1); 9063 } 9064 soc_mem_field32_set(unit, mem, new_ment, KEY_TYPEf, key_type); 9065 if (key_type == _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI) { 9066 value = soc_mem_field32_get(unit,mem, ment, VXLAN_VN_ID__SIPf); 9067 soc_mem_field32_set(unit, mem, new_ment, VXLAN_VN_ID__SIPf, value); 9068 value = soc_mem_field32_get(unit,mem, ment, VXLAN_VN_ID__VFIf); 9069 soc_mem_field32_set(unit, mem, new_ment, VXLAN_VN_ID__VFIf, value); 9070 value = soc_mem_field32_get(unit,mem, ment, VXLAN_VN_ID__VN_IDf); 9071 soc_mem_field32_set(unit, mem, new_ment, VXLAN_VN_ID__VN_IDf, value); 9072 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9073 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 9074 value = soc_mem_field32_get(unit,mem, ment, VXLAN_VN_ID__OVIDf); 9075 soc_mem_field32_set(unit, mem, new_ment, VXLAN_VN_ID__OVIDf, value); 9076 } 9077 #endif 9078 } else { 9079 value = soc_mem_field32_get(unit,mem, ment, VXLAN_SIP__SIPf); 9080 soc_mem_field32_set(unit, mem, new_ment, VXLAN_SIP__SIPf, value); 9081 value = soc_mem_field32_get(unit,mem, ment, VXLAN_SIP__SVPf); 9082 soc_mem_field32_set(unit, mem, new_ment, VXLAN_SIP__SVPf, value); 9083 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9084 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 9085 value = soc_mem_field32_get(unit,mem, ment, VXLAN_SIP__OVIDf); 9086 soc_mem_field32_set(unit, mem, new_ment, VXLAN_SIP__OVIDf, value); 9087 } 9088 #endif 9089 } 9090 return BCM_E_NONE; 9091 } 9092 9093 9094 /* 9095 * Function: 9096 * _bcm_td2_vxlan_match_tunnel_entry_set 9097 * Purpose: 9098 * Set VXLAN Match Tunnel Entry 9099 * Parameters: 9100 * IN : Unit 9101 * IN : mpls_entry 9102 * Returns: 9103 * BCM_E_XXX 9104 */ 9105 9106 STATIC int 9107 _bcm_td2_vxlan_match_tunnel_entry_set(int unit, uint32 *ment, uint32 *return_ment) 9108 { 9109 int rv = BCM_E_UNAVAIL; 9110 int index = 0; 9111 int svp = 0; 9112 uint32 key_type = 0; 9113 uint32 tmp_ment[SOC_MAX_MEM_WORDS]={0}; 9114 9115 rv = soc_mem_search(unit, MPLS_ENTRYm, MEM_BLOCK_ANY, &index, 9116 ment, return_ment, 0); 9117 9118 if (rv == SOC_E_NONE) { 9119 BCM_IF_ERROR_RETURN( 9120 _bcm_td2_vxlan_match_tunnel_entry_update(unit, ment, tmp_ment, return_ment)); 9121 9122 key_type = soc_mem_field32_get(unit, MPLS_ENTRYm, return_ment, KEY_TYPEf); 9123 if (key_type == _BCM_VXLAN_KEY_TYPE_TUNNEL) { 9124 svp = soc_mem_field32_get(unit, MPLS_ENTRYm, return_ment, VXLAN_SIP__SVPf); 9125 if (_bcm_vp_used_get(unit, svp, _bcmVpTypeVpLag)) { 9126 soc_mem_field32_set(unit, MPLS_ENTRYm, tmp_ment, VXLAN_SIP__SVPf, svp); 9127 } 9128 } 9129 rv = soc_mem_write(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, index, tmp_ment); 9130 } else if (rv != SOC_E_NOT_FOUND) { 9131 return rv; 9132 } else { 9133 rv = soc_mem_insert(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, ment); 9134 } 9135 return rv; 9136 } 9137 9138 /* 9139 * Function: 9140 * _bcm_td2_vxlan_match_tunnel_entry_delete 9141 * Purpose: 9142 * Delete VXLAN Match Tunnel Entry 9143 * Parameters: 9144 * IN : Unit 9145 * IN : mpls_entry 9146 * Returns: 9147 * BCM_E_XXX 9148 */ 9149 9150 STATIC int 9151 _bcm_td2_vxlan_match_tunnel_entry_delete(int unit, uint32 *ment) 9152 { 9153 int rv = BCM_E_UNAVAIL; 9154 uint32 value=0, key_type=0; 9155 soc_mem_t mem = MPLS_ENTRYm; 9156 uint32 tmp_ment[SOC_MAX_MEM_WORDS]={0}; 9157 9158 /* Check if Key_Type identical */ 9159 key_type = soc_mem_field32_get(unit, mem, &ment, KEY_TYPEf); 9160 soc_mem_field32_set(unit, mem, &tmp_ment, KEY_TYPEf, key_type); 9161 #if defined(BCM_TRIDENT3_SUPPORT) 9162 if (soc_feature(unit, soc_feature_base_valid)) { 9163 soc_mem_field32_set(unit, mem, &tmp_ment, BASE_VALID_0f, 3); 9164 soc_mem_field32_set(unit, mem, &tmp_ment, BASE_VALID_1f, 7); 9165 soc_mem_field32_set(unit, mem, &tmp_ment, 9166 DATA_TYPEf, key_type); 9167 } else 9168 #endif 9169 { 9170 soc_mem_field32_set(unit, mem, &tmp_ment, VALIDf, 1); 9171 } 9172 if (key_type == _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI) { 9173 value = soc_mem_field32_get(unit, mem, &ment, VXLAN_VN_ID__SIPf); 9174 soc_mem_field32_set(unit, mem, &tmp_ment, VXLAN_VN_ID__SIPf, value); 9175 value = soc_mem_field32_get(unit, mem, &ment, VXLAN_VN_ID__VN_IDf); 9176 soc_mem_field32_set(unit, mem, &tmp_ment, VXLAN_VN_ID__VN_IDf, value); 9177 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9178 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 9179 value = soc_mem_field32_get(unit, mem, &ment, VXLAN_VN_ID__OVIDf); 9180 soc_mem_field32_set(unit, mem, &tmp_ment, VXLAN_VN_ID__OVIDf, value); 9181 } 9182 #endif 9183 } else { 9184 value = soc_mem_field32_get(unit, mem, &ment, VXLAN_VN_ID__SIPf); 9185 soc_mem_field32_set(unit, mem, &tmp_ment, VXLAN_VN_ID__SIPf, value); 9186 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9187 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 9188 value = soc_mem_field32_get(unit, mem, &ment, VXLAN_SIP__OVIDf); 9189 soc_mem_field32_set(unit, mem, &tmp_ment, VXLAN_SIP__OVIDf, value); 9190 } 9191 #endif 9192 } 9193 9194 rv = soc_mem_delete(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, tmp_ment); 9195 return rv; 9196 } 9197 9198 /* 9199 * Function: 9200 * _bcm_td2_vxlan_match_vp_find 9201 * Purpose: 9202 * Find network VP has the same match 9203 * Parameters: 9204 * unit - (IN) SOC unit number. 9205 * vp1 - (IN) Network VP. 9206 * vp2 - (OUT) Network VP. 9207 * Returns: 9208 * TRUE - Found 9209 * FALSE - Not Found 9210 */ 9211 int 9212 _bcm_td2_vxlan_match_vp_find(int unit, int vp1, int *vp2) 9213 { 9214 int vp = 0; 9215 int num_vp = 0; 9216 uint32 tunnel_index1 = 0; 9217 uint32 tunnel_index2 = 0; 9218 uint32 tunnel_sip1 = 0; 9219 uint32 tunnel_sip2 = 0; 9220 _bcm_vxlan_match_port_info_t *mkey1 = NULL; 9221 _bcm_vxlan_match_port_info_t *mkey2 = NULL; 9222 9223 mkey1 = &(VXLAN_INFO(unit)->match_key[vp1]); 9224 tunnel_index1 = mkey1->match_tunnel_index; 9225 tunnel_sip1 = VXLAN_INFO(unit)->vxlan_tunnel_term[tunnel_index1].sip; 9226 9227 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 9228 for (vp = 0; vp < num_vp; vp++) { 9229 if (vp == vp1) { 9230 continue; 9231 } 9232 9233 mkey2 = &(VXLAN_INFO(unit)->match_key[vp]); 9234 if (mkey2->flags == _BCM_VXLAN_PORT_MATCH_TYPE_VNID) { 9235 tunnel_index2 = mkey2->match_tunnel_index; 9236 tunnel_sip2 = VXLAN_INFO(unit)->vxlan_tunnel_term[tunnel_index2].sip; 9237 9238 if (tunnel_sip1 == tunnel_sip2) { 9239 *vp2 = vp; 9240 return TRUE; 9241 } 9242 } 9243 } 9244 9245 return FALSE; 9246 } 9247 9248 /* 9249 * Function: 9250 * _bcm_td2_vxlan_match_tunnel_entry_reset 9251 * Purpose: 9252 * Reset VXLAN Match Tunnel Entry 9253 * Parameters: 9254 * IN : Unit 9255 * IN : mpls_entry 9256 * Returns: 9257 * BCM_E_XXX 9258 */ 9259 9260 STATIC int 9261 _bcm_td2_vxlan_match_tunnel_entry_reset(int unit, int vp, uint32 *ment, uint32 *return_ment) 9262 { 9263 int rv = BCM_E_UNAVAIL; 9264 int index = 0; 9265 int svp = 0; 9266 int d = 0; 9267 soc_mem_t mem = MPLS_ENTRYm; 9268 #if defined(BCM_TRIDENT3_SUPPORT) 9269 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 9270 mem = MPLS_ENTRY_SINGLEm; 9271 d = 1; 9272 } 9273 #endif 9274 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 9275 ment, return_ment, 0); 9276 if ((rv != BCM_E_NOT_FOUND) && (rv != BCM_E_NONE)) { 9277 return rv; 9278 } 9279 9280 if (rv == SOC_E_NONE) { 9281 svp = soc_mem_field32_get(unit, mem, return_ment, 9282 BCM_VXLAN_SIP_FIELD(d, SVPf)); 9283 if (svp != vp) { 9284 return BCM_E_NONE; 9285 } 9286 9287 if (_bcm_td2_vxlan_match_vp_find(unit, vp, &svp)) { 9288 soc_mem_field32_set(unit, mem, return_ment, 9289 BCM_VXLAN_SIP_FIELD(d, SVPf), svp); 9290 } else { 9291 sal_memset(return_ment, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 9292 } 9293 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, return_ment); 9294 } 9295 9296 if ((rv != BCM_E_NOT_FOUND) && (rv != BCM_E_NONE)) { 9297 return rv; 9298 } else { 9299 return BCM_E_NONE; 9300 } 9301 } 9302 9303 /* 9304 * Function: 9305 * _bcm_td2_vxlan_match_vxlate_extd_entry_set 9306 * Purpose: 9307 * Set VXLAN Match Vxlate Entry 9308 * Parameters: 9309 * IN : Unit 9310 * IN : vxlan_port 9311 * IN : vlan_xlate_extd_entry_t 9312 * Returns: 9313 * BCM_E_XXX 9314 */ 9315 9316 STATIC int 9317 _bcm_td2_vxlan_match_egr_vxlate_entry_set(int unit, bcm_vpn_t vpn, 9318 bcm_vxlan_port_t *vxlan_port, 9319 uint32 *vent, 9320 uint32 *return_vent) 9321 { 9322 int rv = BCM_E_NONE; 9323 int index = -1; 9324 soc_mem_t vxlate_mem; 9325 9326 #if defined(BCM_TRIDENT3_SUPPORT) 9327 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 9328 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 9329 } else 9330 #endif 9331 { 9332 vxlate_mem = EGR_VLAN_XLATEm; 9333 } 9334 9335 rv = soc_mem_search(unit, vxlate_mem, 9336 MEM_BLOCK_ANY, &index, vent, return_vent, 0); 9337 if (BCM_E_NONE == rv) { 9338 BCM_IF_ERROR_RETURN(soc_mem_write(unit, 9339 vxlate_mem, MEM_BLOCK_ALL, index, 9340 vent)); 9341 } else if (BCM_E_NOT_FOUND == rv) { 9342 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 9343 return BCM_E_NOT_FOUND; 9344 } 9345 BCM_IF_ERROR_RETURN(soc_mem_insert(unit, 9346 vxlate_mem, MEM_BLOCK_ALL, vent)); 9347 } else { 9348 return rv; 9349 } 9350 return BCM_E_NONE; 9351 } 9352 9353 /* 9354 * Function: 9355 * _bcm_td2_vxlan_match_egr_vxlate_entry_delete 9356 * Purpose: 9357 * Delete VXLAN Match Tunnel Entry 9358 * Parameters: 9359 * IN : Unit 9360 * IN : egr_vlan_xlate_entry 9361 * Returns: 9362 * BCM_E_XXX 9363 */ 9364 9365 STATIC int 9366 _bcm_td2_vxlan_match_egr_vxlate_entry_delete(int unit, uint32 *ment) 9367 { 9368 int rv = BCM_E_UNAVAIL; 9369 uint32 value = 0, entry_type = 0; 9370 soc_mem_t vxlate_mem; 9371 uint32 tmp_ment[SOC_MAX_MEM_WORDS] = {0}; 9372 9373 #if defined(BCM_TRIDENT3_SUPPORT) 9374 if (soc_feature(unit, soc_feature_base_valid)) { 9375 vxlate_mem = EGR_VLAN_XLATE_1_DOUBLEm; 9376 } else 9377 #endif 9378 { 9379 vxlate_mem = EGR_VLAN_XLATEm; 9380 } 9381 /* Check if Key_Type identical */ 9382 entry_type = soc_mem_field32_get(unit, vxlate_mem, ment, ENTRY_TYPEf); 9383 soc_mem_field32_set(unit, vxlate_mem, tmp_ment, ENTRY_TYPEf, entry_type); 9384 9385 soc_mem_field32_set(unit, vxlate_mem, tmp_ment, VALIDf, 1); 9386 if (entry_type == _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP) { 9387 value = soc_mem_field32_get(unit, vxlate_mem, ment, VXLAN_VFI__VFIf); 9388 soc_mem_field32_set(unit, vxlate_mem, tmp_ment, VXLAN_VFI__VFIf, value); 9389 value = soc_mem_field32_get(unit, vxlate_mem, ment, VXLAN_VFI__DVPf); 9390 soc_mem_field32_set(unit, vxlate_mem, tmp_ment, VXLAN_VFI__DVPf, value); 9391 9392 } else { 9393 value = soc_mem_field32_get(unit, vxlate_mem, ment, VXLAN_VFI__VFIf); 9394 soc_mem_field32_set(unit, vxlate_mem, tmp_ment, VXLAN_VFI__VFIf, value); 9395 } 9396 9397 rv = soc_mem_delete(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ALL, tmp_ment); 9398 return rv; 9399 } 9400 9401 /* 9402 * Function: 9403 * _bcm_td2_vxlan_match_vxlate_entry_update 9404 * Purpose: 9405 * Update VXLAN Match Vlan_xlate Entry 9406 * Parameters: 9407 * IN : Unit 9408 * IN : vxlan_port 9409 * IN : vlan_xlate_entry_t 9410 * OUT : vlan_xlate_entry_t 9411 */ 9412 STATIC int 9413 _bcm_td2_vxlan_match_vxlate_entry_update(int unit, bcm_vpn_t vpn, 9414 bcm_vxlan_port_t *vxlan_port, 9415 uint32 *vent, uint32 *return_ent) 9416 { 9417 uint32 key_type=0, value=0; 9418 soc_mem_t mem; 9419 int vp = _SHR_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 9420 9421 #if defined(BCM_TRIDENT3_SUPPORT) 9422 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 9423 mem = VLAN_XLATE_1_DOUBLEm; 9424 } else 9425 #endif 9426 { 9427 mem = VLAN_XLATEm; 9428 } 9429 9430 if ((vent == NULL) || (return_ent == NULL)) { 9431 return BCM_E_PARAM; 9432 } 9433 9434 /* Check if Key_Type identical */ 9435 key_type = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 9436 value = soc_mem_field32_get(unit, mem, return_ent, KEY_TYPEf); 9437 if (key_type != value) { 9438 return BCM_E_PARAM; 9439 } 9440 9441 soc_mem_field32_set(unit, mem, return_ent, SOURCE_TYPEf, 1); 9442 value = soc_mem_field32_get(unit, mem, return_ent, XLATE__MPLS_ACTIONf); 9443 /* SVP_VALID and L3_IIF_VALID overlay high and low bits of MPLS_ACTION. */ 9444 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IIF_VALIDf)) { 9445 value |= 0x1; 9446 } else { 9447 value = 0x1; 9448 } 9449 /* Retain original Keys -- Update data only */ 9450 soc_mem_field32_set(unit, mem, return_ent, XLATE__MPLS_ACTIONf, value); 9451 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9452 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 9453 if (vxlan_port->flags & BCM_VXLAN_PORT_ENABLE_VLAN_CHECKS) { 9454 return BCM_E_UNAVAIL; 9455 } 9456 soc_mem_field32_set(unit, mem, return_ent, XLATE__DISABLE_VLAN_CHECKSf, 9457 0); 9458 soc_mem_field32_set(unit, mem, return_ent, XLATE__VLAN_ACTION_VALIDf, 9459 1); 9460 } else 9461 #endif 9462 { 9463 soc_mem_field32_set(unit, mem, return_ent, XLATE__DISABLE_VLAN_CHECKSf, 9464 1); 9465 if (!(vxlan_port->flags & BCM_VXLAN_PORT_ENABLE_VLAN_CHECKS)) { 9466 soc_mem_field32_set(unit, mem, return_ent, 9467 XLATE__VLAN_ACTION_VALIDf, 1); 9468 } else { 9469 soc_mem_field32_set(unit, mem, return_ent, 9470 XLATE__VLAN_ACTION_VALIDf, 0); 9471 } 9472 } 9473 9474 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9475 if (soc_feature(unit, soc_feature_vp_sharing)) { 9476 if (vpn != BCM_VXLAN_VPN_INVALID) { 9477 int vfi = 0; 9478 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 9479 soc_mem_field32_set(unit, mem, return_ent, XLATE__VFIf, vfi); 9480 } 9481 } 9482 #endif 9483 soc_mem_field32_set(unit, mem, return_ent, XLATE__SOURCE_VPf, vp); 9484 9485 return BCM_E_NONE; 9486 } 9487 9488 /* 9489 * Function: 9490 * _bcm_td2_vxlan_match_vxlate_extd_entry_set 9491 * Purpose: 9492 * Set VXLAN Match Vxlate Entry 9493 * Parameters: 9494 * IN : Unit 9495 * IN : vxlan_port 9496 * IN : vlan_xlate_extd_entry_t 9497 * Returns: 9498 * BCM_E_XXX 9499 */ 9500 9501 STATIC int 9502 _bcm_td2_vxlan_match_vxlate_entry_set(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port, uint32 *vent) 9503 { 9504 int rv = BCM_E_NONE; 9505 int index = -1; 9506 bcm_module_t mod_out = -1; 9507 bcm_port_t port_out = -1; 9508 bcm_trunk_t trunk_id = -1; 9509 bcm_port_t gport_id = -1; 9510 soc_mem_t mem; 9511 uint32 return_vent[SOC_MAX_MEM_WORDS]; 9512 int vp = _SHR_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 9513 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 9514 9515 #if defined(BCM_TRIDENT3_SUPPORT) 9516 if (soc_feature(unit, soc_feature_base_valid)) { 9517 mem = VLAN_XLATE_1_DOUBLEm; 9518 9519 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 9520 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 9521 } else 9522 #endif 9523 { 9524 mem = VLAN_XLATEm; 9525 soc_mem_field32_set(unit, mem, vent, VALIDf, 0x1); 9526 } 9527 9528 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, vxlan_port->match_port, 9529 &mod_out, &port_out, &trunk_id, &gport_id)); 9530 if (BCM_GPORT_IS_TRUNK(vxlan_port->match_port)) { 9531 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 9532 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 9533 } else { 9534 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 9535 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 9536 } 9537 9538 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 9539 soc_mem_field32_set(unit, mem, vent, XLATE__MPLS_ACTIONf, 0x1); /* SVP */ 9540 soc_mem_field32_set(unit, mem, vent, XLATE__SOURCE_VPf, vp); 9541 9542 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9543 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 9544 if (vxlan_port->flags & BCM_VXLAN_PORT_ENABLE_VLAN_CHECKS){ 9545 return BCM_E_UNAVAIL; 9546 } 9547 soc_mem_field32_set(unit, mem, vent, XLATE__DISABLE_VLAN_CHECKSf, 0); 9548 soc_mem_field32_set(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf, 1); 9549 } else 9550 #endif 9551 { 9552 soc_mem_field32_set(unit, mem, vent, XLATE__DISABLE_VLAN_CHECKSf, 1); 9553 if (!(vxlan_port->flags & BCM_VXLAN_PORT_ENABLE_VLAN_CHECKS)){ 9554 soc_mem_field32_set(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf, 1); 9555 } 9556 } 9557 9558 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9559 if (soc_feature(unit, soc_feature_vp_sharing)) { 9560 if (vpn != BCM_VXLAN_VPN_INVALID) { 9561 int vfi = 0; 9562 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 9563 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi); 9564 } 9565 } 9566 #endif 9567 9568 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vent, return_vent, 0); 9569 if (BCM_E_NONE == rv) { 9570 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 9571 BCM_IF_ERROR_RETURN( 9572 _bcm_td2_vxlan_match_vxlate_entry_update(unit, vpn, 9573 vxlan_port, vent, return_vent)); 9574 BCM_IF_ERROR_RETURN( 9575 soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, return_vent)); 9576 } else { 9577 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, vent)); 9578 } 9579 } else if (BCM_E_NOT_FOUND == rv) { 9580 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 9581 return BCM_E_NOT_FOUND; 9582 } 9583 BCM_IF_ERROR_RETURN(soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent)); 9584 } else { 9585 return rv; 9586 } 9587 9588 if (vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 9589 if (BCM_GPORT_IS_TRUNK(vxlan_port->match_port)) { 9590 vxlan_info->match_key[vp].trunk_id = trunk_id; 9591 vxlan_info->match_key[vp].modid = -1; 9592 } else { 9593 vxlan_info->match_key[vp].port = port_out; 9594 vxlan_info->match_key[vp].modid = mod_out; 9595 vxlan_info->match_key[vp].trunk_id = -1; 9596 } 9597 } 9598 9599 return BCM_E_NONE; 9600 } 9601 9602 /* 9603 * Function: 9604 * bcm_td2_vxlan_match_clear 9605 * Purpose: 9606 * Clear VXLAN Match Software State 9607 * Parameters: 9608 * unit - (IN) Device Number 9609 * vp - (IN) Source Virtual Port 9610 * Returns: 9611 * void 9612 */ 9613 9614 void 9615 bcm_td2_vxlan_match_clear (int unit, int vp) 9616 { 9617 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 9618 9619 vxlan_info->match_key[vp].flags = 0; 9620 vxlan_info->match_key[vp].match_vlan = 0; 9621 vxlan_info->match_key[vp].match_inner_vlan = 0; 9622 vxlan_info->match_key[vp].trunk_id = -1; 9623 vxlan_info->match_key[vp].port = 0; 9624 vxlan_info->match_key[vp].modid = -1; 9625 vxlan_info->match_key[vp].match_tunnel_index = 0; 9626 return; 9627 } 9628 9629 /* 9630 * Function: 9631 * _bcm_td2_source_trunk_svp_get 9632 * Purpose: 9633 * get source trunk port svp 9634 * Parameters: 9635 * unit - (IN) Device Number 9636 * modid - (IN) module ID 9637 * port - (IN) Trunk member port 9638 * Returns: 9639 * BCM_E_XXX 9640 */ 9641 9642 STATIC int 9643 _bcm_td2_source_trunk_svp_get(int unit, bcm_module_t modid, bcm_port_t port) 9644 { 9645 source_trunk_map_table_entry_t trunk_map_entry;/*Trunk table entry buffer.*/ 9646 int src_trk_idx = -1; 9647 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 9648 9649 /* Get index to source trunk map table */ 9650 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, modid, 9651 port, &src_trk_idx)); 9652 9653 /* Read source trunk map table. */ 9654 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 9655 src_trk_idx, &trunk_map_entry)); 9656 9657 /* get SVP */ 9658 return soc_mem_field32_get(unit, mem, &trunk_map_entry, SOURCE_VPf); 9659 } 9660 9661 /* 9662 * Function: 9663 * _bcm_td2_vxlan_trunk_table_set 9664 * Purpose: 9665 * Configure VXLAN Trunk port entry 9666 * Parameters: 9667 * unit - (IN) Device Number 9668 * port - (IN) Trunk member port 9669 * tgid - (IN) Trunk group Id 9670 * vp - (IN) Virtual port 9671 * Returns: 9672 * BCM_E_XXX 9673 */ 9674 9675 STATIC int 9676 _bcm_td2_vxlan_trunk_table_set(int unit, bcm_port_t port, bcm_trunk_t tgid, int vp) 9677 { 9678 source_trunk_map_table_entry_t trunk_map_entry;/*Trunk table entry buffer.*/ 9679 bcm_module_t my_modid; 9680 int src_trk_idx = -1; 9681 int port_type; 9682 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 9683 int rv = BCM_E_NONE; 9684 9685 if (tgid != BCM_TRUNK_INVALID) { 9686 port_type = 1; /* TRUNK_PORT_TYPE */ 9687 } else { 9688 return BCM_E_PARAM; 9689 } 9690 9691 /* Get module id for unit. */ 9692 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 9693 9694 /* Get index to source trunk map table */ 9695 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid, 9696 port, &src_trk_idx)); 9697 9698 soc_mem_lock(unit, mem); 9699 9700 /* Read source trunk map table. */ 9701 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 9702 src_trk_idx, &trunk_map_entry)); 9703 9704 /* Set trunk group id. */ 9705 #if defined(BCM_TRIDENT3_SUPPORT) 9706 if (soc_mem_field_valid(unit, mem, SRC_TGIDf)) { 9707 soc_mem_field32_set(unit, mem, &trunk_map_entry, SRC_TGIDf, tgid); 9708 } else 9709 #endif 9710 { 9711 soc_mem_field32_set(unit, mem, &trunk_map_entry, TGIDf, tgid); 9712 } 9713 /* Set port is part of Trunk group */ 9714 soc_mem_field32_set(unit, mem, &trunk_map_entry, PORT_TYPEf, port_type); 9715 9716 /* Enable SVP Mode */ 9717 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 9718 soc_mem_field32_set(unit, mem, &trunk_map_entry, SVP_VALIDf, 0x1); 9719 } 9720 9721 /* Set SVP */ 9722 soc_mem_field32_set(unit, mem, &trunk_map_entry, SOURCE_VPf, vp); 9723 9724 /* Write entry to hw. */ 9725 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, src_trk_idx, &trunk_map_entry); 9726 9727 soc_mem_unlock(unit, mem); 9728 9729 return rv; 9730 } 9731 9732 9733 /* 9734 * Function: 9735 * _bcm_td2_vxlan_trunk_table_reset 9736 * Purpose: 9737 * Reset VXLAN Trunk port entry 9738 * Parameters: 9739 * unit - (IN) Device Number 9740 * port - (IN) Trunk member port 9741 * Returns: 9742 * BCM_E_XXX 9743 */ 9744 9745 STATIC int 9746 _bcm_td2_vxlan_trunk_table_reset(int unit, bcm_port_t port) 9747 { 9748 source_trunk_map_table_entry_t trunk_map_entry;/*Trunk table entry buffer.*/ 9749 bcm_module_t my_modid; 9750 int src_trk_idx = -1; 9751 int rv = BCM_E_NONE; 9752 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 9753 9754 /* Get module id for unit. */ 9755 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 9756 9757 /* Get index to source trunk map table */ 9758 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid, 9759 port, &src_trk_idx)); 9760 9761 soc_mem_lock(unit, mem); 9762 9763 /* Read source trunk map table. */ 9764 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 9765 src_trk_idx, &trunk_map_entry)); 9766 9767 /* Enable SVP Mode */ 9768 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 9769 soc_mem_field32_set(unit, mem, &trunk_map_entry, SVP_VALIDf, 0); 9770 } 9771 9772 /* Set SVP */ 9773 soc_mem_field32_set(unit, mem, &trunk_map_entry, SOURCE_VPf, 0); 9774 9775 /* Write entry to hw. */ 9776 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, src_trk_idx, &trunk_map_entry); 9777 9778 soc_mem_unlock(unit, mem); 9779 9780 return rv; 9781 } 9782 9783 /* 9784 * Function: 9785 * bcm_td2_vxlan_match_trunk_add 9786 * Purpose: 9787 * Assign SVP of VXLAN Trunk port 9788 * Parameters: 9789 * unit - (IN) Device Number 9790 * tgid - (IN) Trunk group Id 9791 * vp - (IN) Source Virtual Port 9792 * is_replace - (IN) flag indicates if replace 9793 * Returns: 9794 * BCM_E_XXX 9795 */ 9796 9797 STATIC int 9798 bcm_td2_vxlan_match_trunk_add(int unit, bcm_trunk_t tgid, int vp, int is_replace) 9799 { 9800 int port_idx=0; 9801 int local_port_out[SOC_MAX_NUM_PORTS]; 9802 int local_member_count=0; 9803 int rv = BCM_E_NONE; 9804 int temp = 0; 9805 int my_modid = 0; 9806 9807 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid, 9808 SOC_MAX_NUM_PORTS, local_port_out, &local_member_count)); 9809 9810 if (local_member_count == 0) { 9811 return BCM_E_NONE; 9812 } 9813 9814 /* Get module id for unit. */ 9815 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 9816 9817 temp = _bcm_td2_source_trunk_svp_get(unit, my_modid, local_port_out[0]); 9818 if (temp != 0) { 9819 if ((temp == vp) && (is_replace)) { 9820 /*continue*/ 9821 } else { 9822 return BCM_E_INTERNAL; 9823 } 9824 } 9825 9826 for (port_idx = 0; port_idx < local_member_count; port_idx++) { 9827 rv = _bcm_td2_vxlan_trunk_table_set(unit, local_port_out[port_idx], tgid, vp); 9828 if (BCM_FAILURE(rv)) { 9829 goto trunk_cleanup; 9830 } 9831 rv = _bcm_esw_port_tab_set( 9832 unit, local_port_out[port_idx], 9833 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0x1); /* L2_SVP */ 9834 if (BCM_FAILURE(rv)) { 9835 goto trunk_cleanup; 9836 } 9837 9838 rv = _bcm_td2_vxlan_port_untagged_profile_set(unit, local_port_out[port_idx]); 9839 if (BCM_FAILURE(rv)) { 9840 goto trunk_cleanup; 9841 } 9842 } 9843 9844 return BCM_E_NONE; 9845 9846 trunk_cleanup: 9847 for (; port_idx >= 0; port_idx--) { 9848 (void) _bcm_esw_port_tab_set(unit, local_port_out[port_idx], 9849 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0); 9850 (void) _bcm_td2_vxlan_trunk_table_reset(unit, local_port_out[port_idx]); 9851 } 9852 return rv; 9853 } 9854 9855 /* 9856 * Function: 9857 * bcm_td2_vxlan_match_trunk_delete 9858 * Purpose: 9859 * Remove SVP of VXLAN Trunk port 9860 * Parameters: 9861 * unit - (IN) Device Number 9862 * tgid - (IN) Trunk group Id 9863 * vp - (IN) Source Virtual Port 9864 * Returns: 9865 * BCM_E_XXX 9866 */ 9867 9868 STATIC int 9869 bcm_td2_vxlan_match_trunk_delete(int unit, bcm_trunk_t tgid, int vp) 9870 { 9871 int port_idx=0; 9872 int local_port_out[SOC_MAX_NUM_PORTS]; 9873 int local_member_count=0; 9874 int rv = BCM_E_NONE; 9875 9876 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_local_members_get(unit, tgid, 9877 SOC_MAX_NUM_PORTS, local_port_out, &local_member_count)); 9878 9879 for (port_idx = 0; port_idx < local_member_count; port_idx++) { 9880 rv = _bcm_td2_vxlan_trunk_table_reset(unit, local_port_out[port_idx]); 9881 if (BCM_FAILURE(rv)) { 9882 goto trunk_cleanup; 9883 } 9884 rv = _bcm_esw_port_tab_set(unit, local_port_out[port_idx], 9885 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0); 9886 if (BCM_FAILURE(rv)) { 9887 goto trunk_cleanup; 9888 } 9889 9890 rv = _bcm_td2_vxlan_port_untagged_profile_reset(unit, local_port_out[port_idx]); 9891 if (BCM_FAILURE(rv)) { 9892 goto trunk_cleanup; 9893 } 9894 } 9895 9896 return BCM_E_NONE; 9897 9898 trunk_cleanup: 9899 for (;port_idx >= 0; port_idx--) { 9900 (void)_bcm_esw_port_tab_set(unit, local_port_out[port_idx], 9901 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0x1); 9902 (void) _bcm_td2_vxlan_trunk_table_set(unit, local_port_out[port_idx], tgid, vp); 9903 } 9904 return rv; 9905 } 9906 9907 #if defined(BCM_TRIDENT3_SUPPORT) 9908 /* 9909 * Function: 9910 * _bcm_td3_vxlan_match_vxlate_entry_set 9911 * Purpose: 9912 * Set VXLAN Match Vxlate Entry 9913 * Parameters: 9914 * IN : Unit 9915 * IN : vxlan_port 9916 * IN : vlan_xlate_extd_entry_t 9917 * Returns: 9918 * BCM_E_XXX 9919 */ 9920 9921 STATIC int 9922 _bcm_td3_vxlan_match_vxlate_entry_set(int unit, bcm_vpn_t vpn, 9923 bcm_vxlan_port_t *vxlan_port, 9924 uint32 *vent, 9925 uint32 *return_vent) 9926 { 9927 int rv = BCM_E_NONE; 9928 int index = -1; 9929 soc_mem_t vxlate_mem; 9930 9931 vxlate_mem = VLAN_XLATE_1_DOUBLEm; 9932 9933 rv = soc_mem_search(unit, vxlate_mem, 9934 MEM_BLOCK_ANY, &index, vent, return_vent, 0); 9935 if (BCM_E_NONE == rv) { 9936 BCM_IF_ERROR_RETURN(soc_mem_write(unit, 9937 vxlate_mem, MEM_BLOCK_ALL, index, 9938 vent)); 9939 } else if (BCM_E_NOT_FOUND == rv) { 9940 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 9941 return BCM_E_NOT_FOUND; 9942 } 9943 BCM_IF_ERROR_RETURN(soc_mem_insert(unit, 9944 vxlate_mem, MEM_BLOCK_ALL, vent)); 9945 } else { 9946 return rv; 9947 } 9948 return BCM_E_NONE; 9949 } 9950 9951 /* 9952 * Function: 9953 * _bcm_td3_vxlan_match_vxlate_entry_set 9954 * Purpose: 9955 * Set VXLAN Match Vxlate Entry 9956 * Parameters: 9957 * IN : Unit 9958 * IN : vxlan_port 9959 * IN : vlan_xlate_extd_entry_t 9960 * Returns: 9961 * BCM_E_XXX 9962 */ 9963 9964 STATIC int 9965 _bcm_td3_vxlan_match_tunnel_entry_set(int unit, uint32 *ment, uint32 *return_ment) 9966 { 9967 int rv = BCM_E_NONE; 9968 int index = -1; 9969 int svp = 0; 9970 uint32 key_type = 0; 9971 soc_mem_t vxlate_mem; 9972 9973 vxlate_mem = MPLS_ENTRY_SINGLEm; 9974 9975 rv = soc_mem_search(unit, vxlate_mem, 9976 MEM_BLOCK_ANY, &index, ment, return_ment, 0); 9977 if (BCM_E_NONE == rv) { 9978 key_type = soc_mem_field32_get(unit, vxlate_mem, return_ment, KEY_TYPEf); 9979 if (key_type == _BCM_VXLAN_KEY_TYPE_TUNNEL) { 9980 svp = soc_mem_field32_get( 9981 unit, vxlate_mem, return_ment, VXLAN_FLEX_IPV4_SIP__SVPf); 9982 if (_bcm_vp_used_get(unit, svp, _bcmVpTypeVpLag)) { 9983 soc_mem_field32_set( 9984 unit, vxlate_mem, ment, VXLAN_FLEX_IPV4_SIP__SVPf, svp); 9985 } 9986 } 9987 BCM_IF_ERROR_RETURN(soc_mem_write(unit, 9988 vxlate_mem, MEM_BLOCK_ALL, index, 9989 ment)); 9990 } else if (BCM_E_NOT_FOUND == rv) { 9991 BCM_IF_ERROR_RETURN(soc_mem_insert(unit, 9992 vxlate_mem, MEM_BLOCK_ALL, ment)); 9993 } else { 9994 return rv; 9995 } 9996 return BCM_E_NONE; 9997 } 9998 9999 #endif 10000 10001 /* 10002 * Function: 10003 * _bcm_td2_vxlan_match_add 10004 * Purpose: 10005 * Assign match criteria of an VXLAN port 10006 * Parameters: 10007 * unit - (IN) Device Number 10008 * vxlan_port - (IN) vxlan port information 10009 * vp - (IN) Source Virtual Port 10010 * Returns: 10011 * BCM_E_XXX 10012 */ 10013 10014 int 10015 _bcm_td2_vxlan_match_add(int unit, bcm_vxlan_port_t *vxlan_port, int vp, bcm_vpn_t vpn) 10016 { 10017 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 10018 int rv = BCM_E_NONE; 10019 bcm_module_t mod_out = -1; 10020 bcm_port_t port_out = -1; 10021 bcm_trunk_t trunk_id = -1; 10022 soc_mem_t mem; 10023 uint32 vent[SOC_MAX_MEM_WORDS]; 10024 int src_trk_idx=0; /*Source Trunk table index.*/ 10025 int gport_id=-1; 10026 uint8 vxlan_vpn_type = 0; 10027 10028 if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_NONE) { 10029 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_NONE; 10030 return BCM_E_NONE; 10031 } 10032 10033 if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_SHARE) { 10034 /* there is no criteria to be configurated for shared vp, 10035 only updating software state to indicate this is a shared vp */ 10036 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_SHARED; 10037 return BCM_E_NONE; 10038 } 10039 10040 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 10041 #if defined(BCM_TRIDENT3_SUPPORT) 10042 if (soc_feature(unit, soc_feature_base_valid)) { 10043 mem = VLAN_XLATE_1_DOUBLEm; 10044 } else 10045 #endif 10046 { 10047 mem = VLAN_XLATEm; 10048 } 10049 10050 if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_PORT_VLAN ) { 10051 if (!BCM_VLAN_VALID(vxlan_port->match_vlan)) { 10052 return BCM_E_PARAM; 10053 } 10054 10055 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 10056 #if defined(BCM_TRIDENT3_SUPPORT) 10057 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 10058 soc_mem_field32_set(unit, mem, vent, 10059 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 10060 } 10061 #endif 10062 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, vxlan_port->match_vlan); 10063 10064 rv = _bcm_td2_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, vent); 10065 BCM_IF_ERROR_RETURN(rv); 10066 10067 if (vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10068 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_VLAN; 10069 vxlan_info->match_key[vp].match_vlan = vxlan_port->match_vlan; 10070 } 10071 10072 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 10073 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 10074 } 10075 } else if (vxlan_port->criteria == 10076 BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN) { 10077 if (!BCM_VLAN_VALID(vxlan_port->match_inner_vlan)) { 10078 return BCM_E_PARAM; 10079 } 10080 10081 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10082 #if defined(BCM_TRIDENT3_SUPPORT) 10083 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 10084 soc_mem_field32_set(unit, mem, vent, 10085 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10086 } 10087 #endif 10088 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, vxlan_port->match_inner_vlan); 10089 10090 rv = _bcm_td2_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, vent); 10091 BCM_IF_ERROR_RETURN(rv); 10092 10093 if (vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10094 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN; 10095 vxlan_info->match_key[vp].match_inner_vlan = vxlan_port->match_inner_vlan; 10096 } 10097 10098 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 10099 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 10100 } 10101 } else if (vxlan_port->criteria == 10102 BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED) { 10103 if (!BCM_VLAN_VALID(vxlan_port->match_vlan) || 10104 !BCM_VLAN_VALID(vxlan_port->match_inner_vlan)) { 10105 return BCM_E_PARAM; 10106 } 10107 10108 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 10109 #if defined(BCM_TRIDENT3_SUPPORT) 10110 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 10111 soc_mem_field32_set(unit, mem, vent, 10112 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 10113 } 10114 #endif 10115 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, vxlan_port->match_vlan); 10116 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, vxlan_port->match_inner_vlan); 10117 10118 rv = _bcm_td2_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, vent); 10119 BCM_IF_ERROR_RETURN(rv); 10120 10121 if (vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10122 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED; 10123 vxlan_info->match_key[vp].match_vlan = vxlan_port->match_vlan; 10124 vxlan_info->match_key[vp].match_inner_vlan = vxlan_port->match_inner_vlan; 10125 } 10126 10127 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 10128 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 10129 } 10130 } else if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_VLAN_PRI) { 10131 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 10132 #if defined(BCM_TRIDENT3_SUPPORT) 10133 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 10134 soc_mem_field32_set(unit, mem, vent, 10135 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 10136 } 10137 #endif 10138 /* match_vlan : Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */ 10139 soc_mem_field32_set(unit, mem, vent, OTAGf, vxlan_port->match_vlan); 10140 10141 rv = _bcm_td2_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, vent); 10142 BCM_IF_ERROR_RETURN(rv); 10143 10144 if (vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10145 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI; 10146 vxlan_info->match_key[vp].match_vlan = vxlan_port->match_vlan; 10147 } 10148 10149 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 10150 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 10151 } 10152 } else if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_PORT) { 10153 if (vxlan_info->match_key[vp].flags == 10154 _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10155 return BCM_E_PARAM; 10156 } 10157 10158 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, vxlan_port->match_port, 10159 &mod_out, &port_out, &trunk_id, &gport_id)); 10160 10161 if (BCM_GPORT_IS_TRUNK(vxlan_port->match_port)) { 10162 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_match_trunk_add(unit, trunk_id, vp, vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)); 10163 if (vxlan_info->match_key[vp].flags != 10164 _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10165 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK; 10166 vxlan_info->match_key[vp].trunk_id = trunk_id; 10167 } 10168 } else { 10169 int is_local; 10170 int temp = 0; 10171 10172 temp = _bcm_td2_source_trunk_svp_get(unit, mod_out, port_out); 10173 if (temp != 0) { 10174 if ((temp == vp) && (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 10175 /*continue*/ 10176 } else { 10177 return BCM_E_INTERNAL; 10178 } 10179 } 10180 10181 BCM_IF_ERROR_RETURN 10182 ( _bcm_esw_modid_is_local(unit, mod_out, &is_local)); 10183 10184 /* Get index to source trunk map table */ 10185 BCM_IF_ERROR_RETURN( 10186 _bcm_esw_src_mod_port_table_index_get(unit, mod_out, 10187 port_out, &src_trk_idx)); 10188 10189 /* Enable SVP Mode */ 10190 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf) ) { 10191 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 10192 src_trk_idx, SVP_VALIDf, 0x1); 10193 BCM_IF_ERROR_RETURN(rv); 10194 } 10195 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 10196 src_trk_idx, SOURCE_VPf, vp); 10197 BCM_IF_ERROR_RETURN(rv); 10198 10199 if (is_local) { 10200 rv = _bcm_esw_port_tab_set( 10201 unit, vxlan_port->match_port, _BCM_CPU_TABS_NONE, 10202 PORT_OPERATIONf, 0x1); /* L2_SVP */ 10203 BCM_IF_ERROR_RETURN(rv); 10204 10205 /* Set TAG_ACTION_PROFILE_PTR */ 10206 rv = _bcm_td2_vxlan_port_untagged_profile_set( 10207 unit, vxlan_port->match_port); 10208 BCM_IF_ERROR_RETURN(rv); 10209 } 10210 /* 10211 * The vp has been created based on trunk. 10212 * When a new port is added into the trunk, a match will be 10213 * added for the vp through bcm_port_match_add. 10214 */ 10215 if ((vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK) && 10216 (vxlan_info->match_key[vp].flags != _BCM_VXLAN_PORT_MATCH_TYPE_SHARED)) { 10217 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_PORT; 10218 vxlan_info->match_key[vp].index = src_trk_idx; 10219 } 10220 } 10221 } else if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_VN_ID) { 10222 uint32 ment_svp[SOC_MAX_MEM_WORDS] = {0}; 10223 uint32 ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 10224 uint32 ment_evt[SOC_MAX_MEM_WORDS] = {0}; 10225 uint32 orignal_ment_svp[SOC_MAX_MEM_WORDS] = {0}; 10226 uint32 orignal_ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 10227 uint32 orignal_ment_egr_vt[SOC_MAX_MEM_WORDS] = {0}; 10228 int tunnel_idx=-1; 10229 uint32 tunnel_sip; 10230 soc_mem_t vxlate_mem; 10231 int valid = 0; 10232 int d = 0; /*vxlan decoupled mode*/ 10233 10234 #if defined(BCM_TRIDENT3_SUPPORT) 10235 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10236 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 10237 d = 1; 10238 } else 10239 #endif 10240 { 10241 vxlate_mem = EGR_VLAN_XLATEm; 10242 } 10243 10244 if (!BCM_GPORT_IS_TUNNEL(vxlan_port->match_tunnel_id)) { 10245 return BCM_E_BADID; 10246 } 10247 10248 BCM_IF_ERROR_RETURN( 10249 _bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type)); 10250 if ((vxlan_vpn_type == _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID) && 10251 vxlan_port->vnid > 0xffffff) { 10252 return BCM_E_PARAM; 10253 } 10254 10255 tunnel_idx = BCM_GPORT_TUNNEL_ID_GET(vxlan_port->match_tunnel_id); 10256 _BCM_VXLAN_TUNNEL_ID_IF_INVALID_RETURN(unit, tunnel_idx); 10257 vxlan_info->match_key[vp].match_tunnel_index = tunnel_idx; 10258 vxlan_info->match_key[vp].flags = _BCM_VXLAN_PORT_MATCH_TYPE_VNID; 10259 10260 if (vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST) { 10261 return BCM_E_NONE; 10262 } 10263 mem = MPLS_ENTRYm; 10264 #if defined(BCM_TRIDENT3_SUPPORT) 10265 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10266 mem = MPLS_ENTRY_SINGLEm; 10267 d = 1; 10268 soc_mem_field32_set(unit, mem, ment_svp, BASE_VALIDf, 1); 10269 soc_mem_field32_set(unit, mem, ment_svp, 10270 DATA_TYPEf, _BCM_VXLAN_FLEX_DATA_TYPE_IPV4_SIP); 10271 } else 10272 #endif 10273 { 10274 soc_mem_field32_set(unit, mem, ment_svp, VALIDf, 1); 10275 } 10276 10277 tunnel_sip = vxlan_info->vxlan_tunnel_term[tunnel_idx].sip; 10278 soc_mem_field32_set(unit, mem, ment_svp, BCM_VXLAN_SIP_FIELD(d, SIPf), tunnel_sip); 10279 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 10280 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 10281 VLAN_CHK_ID(unit, vxlan_port->match_vlan); 10282 vxlan_info->match_key[vp].match_vlan = vxlan_port->match_vlan; 10283 soc_mem_field32_set(unit, mem, ment_svp, 10284 VXLAN_SIP__OVIDf, vxlan_port->match_vlan); 10285 } 10286 #endif 10287 soc_mem_field32_set(unit, mem, ment_svp, BCM_VXLAN_SIP_FIELD(d, SVPf), vp); 10288 soc_mem_field32_set(unit, mem, ment_svp, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL); 10289 #if defined(BCM_TRIDENT3_SUPPORT) 10290 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10291 rv = _bcm_td3_vxlan_match_tunnel_entry_set(unit, ment_svp, orignal_ment_svp); 10292 } else 10293 #endif 10294 { 10295 rv = _bcm_td2_vxlan_match_tunnel_entry_set(unit, ment_svp, orignal_ment_svp); 10296 } 10297 BCM_IF_ERROR_RETURN(rv); 10298 if (vxlan_vpn_type) { 10299 int vfi_index; 10300 int tpid_index = -1; 10301 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 10302 /* set egr_vlan_xlate table */ 10303 #if defined(BCM_TRIDENT3_SUPPORT) 10304 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10305 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BASE_VALIDf, 1); 10306 soc_mem_field32_set(unit, vxlate_mem, ment_evt, 10307 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 10308 soc_mem_field32_set(unit, vxlate_mem, ment_evt, 10309 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 10310 } else 10311 #endif 10312 { 10313 soc_mem_field32_set(unit, vxlate_mem, ment_evt, ENTRY_TYPEf, 10314 _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 10315 soc_mem_field32_set(unit, vxlate_mem, ment_evt, VALIDf, 0x1); 10316 } 10317 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BCM_VXLAN_VFI_FIELD(d, VFIf), vfi_index); 10318 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BCM_VXLAN_VFI_FIELD(d, DVPf), vp); 10319 soc_mem_field32_set(unit, vxlate_mem, ment_evt, (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf), 10320 vxlan_port->vnid); 10321 /* Configure EGR_VLAN_XLATE - SD_TAG setting */ 10322 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 10323 int action_present, action_not_present; 10324 uint32 old_vxlate_entry[SOC_MAX_MEM_WORDS] = {0}; 10325 10326 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi_index, vp, old_vxlate_entry); 10327 if (BCM_FAILURE(rv)) { 10328 goto match_add_clean1; 10329 } 10330 #if defined(BCM_TRIDENT3_SUPPORT) 10331 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10332 int profile_idx = -1; 10333 profile_idx = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, 10334 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 10335 (void)_bcm_td3_sd_tag_action_get(unit, profile_idx, &action_present, 10336 &action_not_present); 10337 } else 10338 #endif 10339 { 10340 /*If old tpid exist, delete it*/ 10341 action_present = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, 10342 VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf); 10343 action_not_present = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, 10344 VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf); 10345 } 10346 if (1 == action_present || 4 == action_present || 10347 7 == action_present || 1 == action_not_present) { 10348 tpid_index = soc_mem_field32_get(unit, 10349 vxlate_mem, old_vxlate_entry, 10350 d ? VXLAN_VFI_FLEX__OUTER_TPID_INDEXf : VXLAN_VFI__SD_TAG_TPID_INDEXf); 10351 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 10352 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)) { 10353 goto match_add_clean1; 10354 } 10355 } 10356 } 10357 10358 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TAGGED) { 10359 rv = _bcm_td2_vxlan_sd_tag_set(unit, NULL, vxlan_port, NULL, ment_evt, &tpid_index); 10360 if (BCM_FAILURE(rv)) { 10361 goto match_add_clean1; 10362 } 10363 } 10364 rv = _bcm_td2_vxlan_match_egr_vxlate_entry_set(unit, vpn, vxlan_port, ment_evt, orignal_ment_egr_vt); 10365 if (BCM_FAILURE(rv)) { 10366 goto match_add_clean1; 10367 } 10368 10369 /* set mpls_entry table */ 10370 #if defined(BCM_TRIDENT3_SUPPORT) 10371 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10372 _bcm_td3_vxlan_vxlate_entry_t ent; 10373 10374 mem = VLAN_XLATE_1_DOUBLEm; 10375 sal_memset(&ent, 0, sizeof(_bcm_td3_vxlan_vxlate_entry_t)); 10376 ent.dtype = _BCM_VXLAN_DATA_TYPE_VNID_VFI_FLEX; 10377 ent.ktype = _BCM_VXLAN_KEY_TYPE_VNID_VFI_SIP_FLEX; 10378 ent.vfi = vfi_index; 10379 ent.vlan = vxlan_info->vxlan_vpn_vlan[vfi_index]; 10380 _bcm_td3_vxlan_vxlate_entry_assemble(unit, ent, ment_vnid); 10381 } else 10382 #endif 10383 { 10384 soc_mem_field32_set(unit, mem, ment_vnid, VALIDf, 1); 10385 soc_mem_field32_set(unit, mem, ment_vnid, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI); 10386 soc_mem_field32_set(unit, mem, ment_vnid, VXLAN_VN_ID__VFIf, vfi_index); 10387 } 10388 soc_mem_field32_set(unit, mem, ment_vnid, BCM_VXLAN_VNID_FIELD(d, SIPf), tunnel_sip); 10389 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 10390 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 10391 VLAN_CHK_ID(unit, vxlan_port->match_vlan); 10392 vxlan_info->match_key[vp].match_vlan = vxlan_port->match_vlan; 10393 soc_mem_field32_set(unit, mem, ment_vnid, VXLAN_VN_ID__OVIDf, 10394 vxlan_port->match_vlan); 10395 } 10396 #endif 10397 soc_mem_field32_set(unit, mem, ment_vnid, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), vxlan_port->vnid); 10398 10399 #if defined(BCM_TRIDENT3_SUPPORT) 10400 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10401 rv = _bcm_td3_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, ment_vnid, orignal_ment_vnid); 10402 } else 10403 #endif 10404 { 10405 rv = _bcm_td2_vxlan_match_tunnel_entry_set(unit, ment_vnid, orignal_ment_vnid); 10406 } 10407 if (BCM_FAILURE(rv)) { 10408 goto match_add_clean2; 10409 } 10410 vxlan_info->vxlan_vpn_info[vfi_index].vnid = vxlan_port->vnid; 10411 vxlan_info->vxlan_vpn_info[vfi_index].sip = tunnel_sip; 10412 vxlan_info->match_key[vp].vfi = vfi_index; 10413 return rv; 10414 match_add_clean2: 10415 if (soc_feature(unit, soc_feature_base_valid)) { 10416 if ((soc_mem_field32_get(unit, vxlate_mem, orignal_ment_egr_vt, BASE_VALID_0f) == 3) && 10417 (soc_mem_field32_get(unit, vxlate_mem, orignal_ment_egr_vt, BASE_VALID_1f) == 7)) { 10418 valid = 1; 10419 } 10420 } else { 10421 valid = soc_mem_field32_get(unit, vxlate_mem, orignal_ment_egr_vt, VALIDf); 10422 } 10423 if (valid) { 10424 rv = _bcm_td2_vxlan_match_egr_vxlate_entry_set(unit, vpn, vxlan_port, 10425 orignal_ment_egr_vt, 10426 ment_evt); 10427 BCM_IF_ERROR_RETURN(rv); 10428 } else { 10429 rv = _bcm_td2_vxlan_match_egr_vxlate_entry_delete(unit, ment_evt); 10430 BCM_IF_ERROR_RETURN(rv); 10431 } 10432 match_add_clean1: 10433 if (soc_feature(unit, soc_feature_base_valid)) { 10434 if ((soc_mem_field32_get(unit, vxlate_mem, orignal_ment_egr_vt, BASE_VALID_0f) == 3) && 10435 (soc_mem_field32_get(unit, vxlate_mem, orignal_ment_egr_vt, BASE_VALID_1f) == 7)) { 10436 valid = 1; 10437 } 10438 } else { 10439 valid = soc_mem_field32_get(unit, vxlate_mem, orignal_ment_egr_vt, VALIDf); 10440 } 10441 if (valid) { 10442 rv = _bcm_td2_vxlan_match_tunnel_entry_set(unit, orignal_ment_svp, ment_svp); 10443 BCM_IF_ERROR_RETURN(rv); 10444 } else { 10445 rv = _bcm_td2_vxlan_match_tunnel_entry_delete(unit, ment_svp); 10446 BCM_IF_ERROR_RETURN(rv); 10447 } 10448 if (tpid_index != -1) { 10449 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 10450 } 10451 10452 return rv; 10453 } 10454 } 10455 return rv; 10456 } 10457 10458 /* 10459 * Function: 10460 * _bcm_td2_vxlan_match_delete 10461 * Purpose: 10462 * Delete match criteria of an VXLAN port 10463 * Parameters: 10464 * unit - (IN) Device Number 10465 * vxlan_port - (IN) VXLAN port information 10466 * vp - (IN) Source Virtual Port 10467 * Returns: 10468 * BCM_E_XXX 10469 */ 10470 10471 int 10472 _bcm_td2_vxlan_match_delete(int unit, int vp , bcm_vxlan_port_t vxlan_port, bcm_vpn_t vpn) 10473 { 10474 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 10475 int rv=BCM_E_NONE; 10476 soc_mem_t mem; 10477 uint32 vent[SOC_MAX_MEM_WORDS] = {0}; 10478 bcm_trunk_t trunk_id; 10479 int src_trk_idx=0; /*Source Trunk table index.*/ 10480 int mod_id_idx=0; /* Module_Id */ 10481 int port=0, tunnel_index = -1; 10482 bcm_module_t mod_out = -1; 10483 bcm_port_t port_out = -1; 10484 int gport_id =-1; 10485 uint32 ment_svp[SOC_MAX_MEM_WORDS] = {0}; 10486 uint32 ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 10487 uint32 ment_evt[SOC_MAX_MEM_WORDS] = {0}; 10488 uint32 orignal_ment_svp[SOC_MAX_MEM_WORDS] = {0}; 10489 uint32 orignal_ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 10490 uint32 orignal_ment_evt[SOC_MAX_MEM_WORDS] = {0}; 10491 uint8 vxlan_vpn_type = 0; 10492 10493 #if defined(BCM_TRIDENT3_SUPPORT) 10494 if (soc_feature(unit, soc_feature_base_valid)) { 10495 mem = VLAN_XLATE_1_DOUBLEm; 10496 10497 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 10498 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 10499 } else 10500 #endif 10501 { 10502 mem = VLAN_XLATEm; 10503 10504 soc_mem_field32_set(unit, mem, vent, VALIDf, 1); 10505 } 10506 10507 if (vxlan_info->match_key[vp].flags == _BCM_VXLAN_PORT_MATCH_TYPE_VLAN) { 10508 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 10509 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 10510 #if defined(BCM_TRIDENT3_SUPPORT) 10511 if (mem == VLAN_XLATE_1_DOUBLEm) { 10512 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 10513 } 10514 #endif 10515 soc_mem_field32_set(unit, mem, vent, 10516 XLATE__OVIDf, vxlan_info->match_key[vp].match_vlan); 10517 10518 if (vxlan_info->match_key[vp].modid != -1) { 10519 soc_mem_field32_set(unit, mem, vent, 10520 XLATE__MODULE_IDf, vxlan_info->match_key[vp].modid); 10521 soc_mem_field32_set(unit, mem, vent, 10522 XLATE__PORT_NUMf, vxlan_info->match_key[vp].port); 10523 10524 } else { 10525 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 10526 soc_mem_field32_set(unit, mem, vent, 10527 XLATE__TGIDf, vxlan_info->match_key[vp].trunk_id); 10528 } 10529 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, &vent); 10530 BCM_IF_ERROR_RETURN(rv); 10531 10532 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 10533 } else if (vxlan_info->match_key[vp].flags == 10534 _BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN) { 10535 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 10536 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10537 #if defined(BCM_TRIDENT3_SUPPORT) 10538 if (mem == VLAN_XLATE_1_DOUBLEm) { 10539 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10540 } 10541 #endif 10542 soc_mem_field32_set(unit, mem, vent, 10543 XLATE__IVIDf, vxlan_info->match_key[vp].match_inner_vlan); 10544 if (vxlan_info->match_key[vp].modid != -1) { 10545 soc_mem_field32_set(unit, mem, vent, 10546 XLATE__MODULE_IDf, vxlan_info->match_key[vp].modid); 10547 soc_mem_field32_set(unit, mem, vent, 10548 XLATE__PORT_NUMf, vxlan_info->match_key[vp].port); 10549 } else { 10550 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 10551 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, 10552 vxlan_info->match_key[vp].trunk_id); 10553 } 10554 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 10555 BCM_IF_ERROR_RETURN(rv); 10556 10557 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 10558 }else if (vxlan_info->match_key[vp].flags == 10559 _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED) { 10560 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 10561 soc_mem_field32_set(unit, mem, vent, 10562 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 10563 #if defined(BCM_TRIDENT3_SUPPORT) 10564 if (mem == VLAN_XLATE_1_DOUBLEm) { 10565 soc_mem_field32_set(unit, mem, vent, 10566 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 10567 } 10568 #endif 10569 soc_mem_field32_set(unit, mem, vent, 10570 XLATE__OVIDf, vxlan_info->match_key[vp].match_vlan); 10571 soc_mem_field32_set(unit, mem, vent, 10572 XLATE__IVIDf, vxlan_info->match_key[vp].match_inner_vlan); 10573 if (vxlan_info->match_key[vp].modid != -1) { 10574 soc_mem_field32_set(unit, mem, vent, 10575 XLATE__MODULE_IDf, vxlan_info->match_key[vp].modid); 10576 soc_mem_field32_set(unit, mem, vent, 10577 XLATE__PORT_NUMf, vxlan_info->match_key[vp].port); 10578 } else { 10579 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 10580 soc_mem_field32_set(unit, mem, vent, 10581 XLATE__TGIDf, vxlan_info->match_key[vp].trunk_id); 10582 } 10583 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 10584 BCM_IF_ERROR_RETURN(rv); 10585 10586 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 10587 } else if (vxlan_info->match_key[vp].flags == 10588 _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI) { 10589 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 10590 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 10591 #if defined(BCM_TRIDENT3_SUPPORT) 10592 if (mem == VLAN_XLATE_1_DOUBLEm) { 10593 soc_mem_field32_set(unit, mem, vent, 10594 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 10595 } 10596 #endif 10597 soc_mem_field32_set(unit, mem, vent, 10598 XLATE__OTAGf, vxlan_info->match_key[vp].match_vlan); 10599 if (vxlan_info->match_key[vp].modid != -1) { 10600 soc_mem_field32_set(unit, mem, vent, 10601 XLATE__MODULE_IDf, vxlan_info->match_key[vp].modid); 10602 soc_mem_field32_set(unit, mem, vent, 10603 XLATE__PORT_NUMf, vxlan_info->match_key[vp].port); 10604 } else { 10605 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 10606 soc_mem_field32_set(unit, mem, vent, 10607 XLATE__TGIDf, vxlan_info->match_key[vp].trunk_id); 10608 } 10609 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, &vent); 10610 BCM_IF_ERROR_RETURN(rv); 10611 10612 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 10613 } 10614 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 10615 else if (vxlan_info->match_key[vp].flags == 10616 _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 10617 10618 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 10619 10620 if (BCM_VXLAN_PORT_MATCH_PORT_VLAN == vxlan_port.criteria) { 10621 soc_mem_field32_set(unit, mem, vent, 10622 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 10623 #if defined(BCM_TRIDENT3_SUPPORT) 10624 if (mem == VLAN_XLATE_1_DOUBLEm) { 10625 soc_mem_field32_set(unit, mem, vent, 10626 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10627 } 10628 #endif 10629 soc_mem_field32_set(unit, mem, vent, 10630 XLATE__OVIDf, vxlan_port.match_vlan); 10631 } else if (BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED == vxlan_port.criteria) { 10632 soc_mem_field32_set(unit, mem, vent, 10633 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 10634 #if defined(BCM_TRIDENT3_SUPPORT) 10635 if (mem == VLAN_XLATE_1_DOUBLEm) { 10636 soc_mem_field32_set(unit, mem, vent, 10637 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10638 } 10639 #endif 10640 soc_mem_field32_set(unit, mem, vent, 10641 XLATE__OVIDf, vxlan_port.match_vlan); 10642 soc_mem_field32_set(unit, mem, vent, 10643 XLATE__IVIDf, vxlan_port.match_inner_vlan); 10644 } else if (BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN == vxlan_port.criteria) { 10645 soc_mem_field32_set(unit, mem, vent, 10646 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10647 #if defined(BCM_TRIDENT3_SUPPORT) 10648 if (mem == VLAN_XLATE_1_DOUBLEm) { 10649 soc_mem_field32_set(unit, mem, vent, 10650 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10651 } 10652 #endif 10653 soc_mem_field32_set(unit, mem, vent, 10654 XLATE__IVIDf, vxlan_port.match_inner_vlan); 10655 } else if (BCM_VXLAN_PORT_MATCH_VLAN_PRI == vxlan_port.criteria) { 10656 soc_mem_field32_set(unit, mem, vent, 10657 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 10658 #if defined(BCM_TRIDENT3_SUPPORT) 10659 if (mem == VLAN_XLATE_1_DOUBLEm) { 10660 soc_mem_field32_set(unit, mem, vent, 10661 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 10662 } 10663 #endif 10664 soc_mem_field32_set(unit, mem, vent, 10665 XLATE__OTAGf, vxlan_port.match_vlan); 10666 } else { 10667 return BCM_E_UNAVAIL; 10668 } 10669 10670 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, vxlan_port.match_port, &mod_out, 10671 &port_out, &trunk_id, &gport_id)); 10672 10673 if (BCM_GPORT_IS_TRUNK(vxlan_port.match_port)) { 10674 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 10675 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 10676 } else { 10677 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 10678 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 10679 } 10680 10681 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 10682 BCM_IF_ERROR_RETURN(rv); 10683 10684 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 10685 } 10686 #endif 10687 else if ((vxlan_info->match_key[vp].flags == _BCM_VXLAN_PORT_MATCH_TYPE_PORT) 10688 || ((vxlan_info->match_key[vp].flags == _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK) 10689 && (!BCM_GPORT_IS_TRUNK(vxlan_port.match_port)))) { 10690 int is_local; 10691 10692 if (vxlan_info->match_key[vp].flags == _BCM_VXLAN_PORT_MATCH_TYPE_PORT) { 10693 src_trk_idx = vxlan_info->match_key[vp].index; 10694 } else { 10695 /* 10696 * The vp has been created based on trunk. 10697 * When a new port is deleted from the trunk, a match will be deleted 10698 * for the vp through bcm_port_match_delete. 10699 */ 10700 BCM_IF_ERROR_RETURN( 10701 _bcm_esw_gport_resolve(unit, vxlan_port.match_port, &mod_out, 10702 &port_out, &trunk_id, &gport_id)); 10703 /* Get index to source trunk map table */ 10704 BCM_IF_ERROR_RETURN( 10705 _bcm_esw_src_mod_port_table_index_get( 10706 unit, mod_out, port_out, &src_trk_idx)); 10707 } 10708 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 10709 src_trk_idx, SOURCE_VPf, 0); 10710 BCM_IF_ERROR_RETURN(rv); 10711 10712 /* Disable SVP Mode */ 10713 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf) ) { 10714 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 10715 src_trk_idx, SVP_VALIDf, 0x0); 10716 BCM_IF_ERROR_RETURN(rv); 10717 } 10718 10719 BCM_IF_ERROR_RETURN( 10720 _bcm_esw_src_modid_port_get(unit, src_trk_idx, &mod_id_idx, &port)); 10721 BCM_IF_ERROR_RETURN( 10722 _bcm_esw_modid_is_local(unit, mod_id_idx, &is_local)); 10723 10724 if (is_local) { 10725 rv = _bcm_esw_port_tab_set(unit, vxlan_port.match_port, 10726 _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0); 10727 BCM_IF_ERROR_RETURN(rv); 10728 10729 /* Reset TAG_ACTION_PROFILE_PTR */ 10730 rv = _bcm_td2_vxlan_port_untagged_profile_reset( 10731 unit, vxlan_port.match_port); 10732 BCM_IF_ERROR_RETURN(rv); 10733 } 10734 } else if (vxlan_info->match_key[vp].flags == 10735 _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK) { 10736 trunk_id = vxlan_info->match_key[vp].trunk_id; 10737 rv = bcm_td2_vxlan_match_trunk_delete(unit, trunk_id, vp); 10738 BCM_IF_ERROR_RETURN(rv); 10739 } else if (vxlan_info->match_key[vp].flags == 10740 _BCM_VXLAN_PORT_MATCH_TYPE_VNID) { 10741 int d = 0; /*vxlan decoupled mode*/ 10742 10743 if (vxlan_port.flags & BCM_VXLAN_PORT_MULTICAST) { 10744 return BCM_E_NONE; 10745 } 10746 10747 mem = MPLS_ENTRYm; 10748 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type)); 10749 10750 #if defined(BCM_TRIDENT3_SUPPORT) 10751 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10752 mem = MPLS_ENTRY_SINGLEm; 10753 d = 1; 10754 soc_mem_field32_set(unit, mem, ment_svp, BASE_VALIDf, 1); 10755 soc_mem_field32_set(unit, mem, ment_svp, 10756 DATA_TYPEf, _BCM_VXLAN_FLEX_DATA_TYPE_IPV4_SIP); 10757 } else 10758 #endif 10759 { 10760 soc_mem_field32_set(unit, mem, ment_svp, VALIDf, 1); 10761 } 10762 10763 tunnel_index = vxlan_info->match_key[vp].match_tunnel_index; 10764 soc_mem_field32_set(unit, mem, ment_svp, BCM_VXLAN_SIP_FIELD(d, SIPf), 10765 vxlan_info->vxlan_tunnel_term[tunnel_index].sip); 10766 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 10767 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 10768 soc_mem_field32_set(unit, mem, ment_svp, 10769 VXLAN_SIP__OVIDf, vxlan_info->match_key[vp].match_vlan); 10770 } 10771 #endif 10772 soc_mem_field32_set(unit, mem, ment_svp, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL); 10773 10774 BCM_IF_ERROR_RETURN( 10775 _bcm_td2_vxlan_match_tunnel_entry_reset(unit, vp, ment_svp, 10776 orignal_ment_svp)); 10777 10778 if (vxlan_vpn_type) { 10779 int vfi_index; 10780 int index; 10781 soc_mem_t vxlate_mem; 10782 #if defined(BCM_TRIDENT3_SUPPORT) 10783 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10784 d = 1; 10785 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 10786 } else 10787 #endif 10788 { 10789 vxlate_mem = EGR_VLAN_XLATEm; 10790 } 10791 10792 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 10793 /* set egr_vlan_xlate table */ 10794 #if defined(BCM_TRIDENT3_SUPPORT) 10795 if (soc_feature(unit, soc_feature_base_valid)) { 10796 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BASE_VALIDf, 1); 10797 soc_mem_field32_set(unit, vxlate_mem, ment_evt, 10798 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 10799 soc_mem_field32_set(unit, vxlate_mem, ment_evt, 10800 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 10801 } else 10802 #endif 10803 { 10804 soc_mem_field32_set(unit, vxlate_mem, ment_evt, ENTRY_TYPEf, 10805 _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 10806 soc_mem_field32_set(unit, vxlate_mem, ment_evt, VALIDf, 0x1); 10807 } 10808 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BCM_VXLAN_VFI_FIELD(d, VFIf), vfi_index); 10809 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BCM_VXLAN_VFI_FIELD(d, DVPf), vp); 10810 10811 rv = soc_mem_search(unit, vxlate_mem, MEM_BLOCK_ANY, &index, 10812 ment_evt, orignal_ment_evt, 0); 10813 if (BCM_FAILURE(rv)) { 10814 goto match_delete_clean1; 10815 } 10816 sal_memset(ment_evt, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 10817 rv = soc_mem_write(unit, vxlate_mem, MEM_BLOCK_ALL, index, ment_evt); 10818 if (BCM_FAILURE(rv)) { 10819 goto match_delete_clean1; 10820 10821 } 10822 10823 /* set mpls_entry table */ 10824 #if defined(BCM_TRIDENT3_SUPPORT) 10825 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 10826 mem = VLAN_XLATE_1_DOUBLEm; 10827 soc_mem_field32_set(unit, mem, ment_vnid, BASE_VALID_0f, 3); 10828 soc_mem_field32_set(unit, mem, ment_vnid, BASE_VALID_1f, 7); 10829 soc_mem_field32_set(unit, mem, ment_vnid, 10830 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_VNID_VFI_FLEX); 10831 soc_mem_field32_set(unit, mem, &ment_vnid, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_VNID_VFI_SIP_FLEX); 10832 } else 10833 #endif 10834 { 10835 soc_mem_field32_set(unit, mem, ment_vnid, VALIDf, 1); 10836 soc_mem_field32_set(unit, mem, ment_vnid, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI); 10837 } 10838 soc_mem_field32_set(unit, mem, ment_vnid, BCM_VXLAN_VNID_FIELD(d, SIPf), 10839 vxlan_info->vxlan_tunnel_term[tunnel_index].sip); 10840 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 10841 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 10842 soc_mem_field32_set(unit, mem, ment_vnid, VXLAN_VN_ID__OVIDf, 10843 vxlan_port.match_vlan); 10844 } 10845 #endif 10846 soc_mem_field32_set(unit, mem, ment_vnid, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), vxlan_port.vnid); 10847 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 10848 ment_vnid, orignal_ment_vnid, 0); 10849 if (BCM_FAILURE(rv)) { 10850 goto match_delete_clean2; 10851 } 10852 10853 sal_memset(ment_vnid, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 10854 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, ment_vnid); 10855 if (BCM_FAILURE(rv)) { 10856 goto match_delete_clean2; 10857 } 10858 vxlan_info->vxlan_vpn_info[vfi_index].vnid = 0; 10859 vxlan_info->vxlan_vpn_info[vfi_index].sip = 0; 10860 vxlan_info->match_key[vp].vfi = 0; 10861 } 10862 if (!vxlan_info->vxlan_tunnel_term[tunnel_index].dip) { 10863 vxlan_info->vxlan_tunnel_term[tunnel_index].sip = 0; 10864 } 10865 return rv; 10866 match_delete_clean2: 10867 rv = _bcm_td2_vxlan_match_egr_vxlate_entry_set(unit, vpn, &vxlan_port, 10868 orignal_ment_evt, 10869 ment_evt); 10870 BCM_IF_ERROR_RETURN(rv); 10871 match_delete_clean1: 10872 rv = _bcm_td2_vxlan_match_tunnel_entry_set(unit, orignal_ment_svp, ment_svp); 10873 BCM_IF_ERROR_RETURN(rv); 10874 return rv; 10875 } 10876 10877 return BCM_E_NONE; 10878 } 10879 10880 /* 10881 * Function: 10882 * _bcm_td2_vxlan_match_get 10883 * Purpose: 10884 * Obtain match information of an VXLAN port 10885 * Parameters: 10886 * unit - (IN) Device Number 10887 * vxlan_port - (OUT) VXLAN port information 10888 * vp - (IN) Source Virtual Port 10889 * Returns: 10890 * BCM_E_XXX 10891 */ 10892 10893 int 10894 _bcm_td2_vxlan_match_get(int unit, bcm_vxlan_port_t *vxlan_port, int vp, bcm_vpn_t vpn) 10895 { 10896 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 10897 int rv = BCM_E_NONE; 10898 bcm_module_t mod_in=0, mod_out=0; 10899 bcm_port_t port_in=0, port_out=0; 10900 bcm_trunk_t trunk_id=0; 10901 int src_trk_idx=0; /*Source Trunk table index.*/ 10902 int tunnel_idx = -1; 10903 uint8 vxlan_vpn_type; 10904 if (vxlan_info->match_key[vp].flags & _BCM_VXLAN_PORT_MATCH_TYPE_VLAN) { 10905 10906 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN; 10907 vxlan_port->match_vlan = vxlan_info->match_key[vp].match_vlan; 10908 10909 if (vxlan_info->match_key[vp].trunk_id != -1) { 10910 trunk_id = vxlan_info->match_key[vp].trunk_id; 10911 BCM_GPORT_TRUNK_SET(vxlan_port->match_port, trunk_id); 10912 } else { 10913 port_in = vxlan_info->match_key[vp].port; 10914 mod_in = vxlan_info->match_key[vp].modid; 10915 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 10916 mod_in, port_in, &mod_out, &port_out); 10917 vxlan_port->match_port = 10918 _bcm_esw_port_gport_get_from_modport(unit, mod_out, port_out); 10919 } 10920 } else if (vxlan_info->match_key[vp].flags & 10921 _BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN) { 10922 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN; 10923 vxlan_port->match_inner_vlan = vxlan_info->match_key[vp].match_inner_vlan; 10924 10925 if (vxlan_info->match_key[vp].trunk_id != -1) { 10926 trunk_id = vxlan_info->match_key[vp].trunk_id; 10927 BCM_GPORT_TRUNK_SET(vxlan_port->match_port, trunk_id); 10928 } else { 10929 port_in = vxlan_info->match_key[vp].port; 10930 mod_in = vxlan_info->match_key[vp].modid; 10931 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 10932 mod_in, port_in, &mod_out, &port_out); 10933 vxlan_port->match_port = 10934 _bcm_esw_port_gport_get_from_modport(unit, mod_out, port_out); 10935 } 10936 }else if (vxlan_info->match_key[vp].flags & 10937 _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED) { 10938 10939 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED; 10940 vxlan_port->match_vlan = vxlan_info->match_key[vp].match_vlan; 10941 vxlan_port->match_inner_vlan = vxlan_info->match_key[vp].match_inner_vlan; 10942 10943 if (vxlan_info->match_key[vp].trunk_id != -1) { 10944 trunk_id = vxlan_info->match_key[vp].trunk_id; 10945 BCM_GPORT_TRUNK_SET(vxlan_port->match_port, trunk_id); 10946 } else { 10947 port_in = vxlan_info->match_key[vp].port; 10948 mod_in = vxlan_info->match_key[vp].modid; 10949 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 10950 mod_in, port_in, &mod_out, &port_out); 10951 vxlan_port->match_port = 10952 _bcm_esw_port_gport_get_from_modport(unit, mod_out, port_out); 10953 } 10954 } else if (vxlan_info->match_key[vp].flags & _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI) { 10955 10956 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 10957 vxlan_port->match_vlan = vxlan_info->match_key[vp].match_vlan; 10958 10959 if (vxlan_info->match_key[vp].trunk_id != -1) { 10960 trunk_id = vxlan_info->match_key[vp].trunk_id; 10961 BCM_GPORT_TRUNK_SET(vxlan_port->match_port, trunk_id); 10962 } else { 10963 port_in = vxlan_info->match_key[vp].port; 10964 mod_in = vxlan_info->match_key[vp].modid; 10965 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 10966 mod_in, port_in, &mod_out, &port_out); 10967 vxlan_port->match_port = 10968 _bcm_esw_port_gport_get_from_modport(unit, mod_out, port_out); 10969 } 10970 } else if (vxlan_info->match_key[vp].flags & 10971 _BCM_VXLAN_PORT_MATCH_TYPE_PORT) { 10972 10973 src_trk_idx = vxlan_info->match_key[vp].index; 10974 BCM_IF_ERROR_RETURN(_bcm_esw_src_modid_port_get( unit, src_trk_idx, 10975 &mod_in, &port_in)); 10976 10977 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_PORT; 10978 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 10979 mod_in, port_in, &mod_out, &port_out); 10980 vxlan_port->match_port = 10981 _bcm_esw_port_gport_get_from_modport(unit, mod_out, port_out); 10982 }else if (vxlan_info->match_key[vp].flags & 10983 _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK) { 10984 10985 trunk_id = vxlan_info->match_key[vp].trunk_id; 10986 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_PORT; 10987 BCM_GPORT_TRUNK_SET(vxlan_port->match_port, trunk_id); 10988 } else if ((vxlan_info->match_key[vp].flags & 10989 _BCM_VXLAN_PORT_MATCH_TYPE_VNID)) { 10990 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_VN_ID; 10991 10992 tunnel_idx = vxlan_info->match_key[vp].match_tunnel_index; 10993 BCM_GPORT_TUNNEL_ID_SET(vxlan_port->match_tunnel_id, tunnel_idx); 10994 vxlan_port->match_vlan = vxlan_info->match_key[vp].match_vlan; 10995 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type)); 10996 if (vxlan_vpn_type) { 10997 int vfi_idx; 10998 _BCM_VXLAN_VPN_GET(vfi_idx, _BCM_VPN_TYPE_VFI, vpn); 10999 vxlan_port->vnid = vxlan_info->vxlan_vpn_info[vfi_idx].vnid; 11000 } 11001 }else if (vxlan_info->match_key[vp].flags & _BCM_VXLAN_PORT_MATCH_TYPE_SHARED) { 11002 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_SHARE; 11003 } else { 11004 vxlan_port->criteria = BCM_VXLAN_PORT_MATCH_NONE; 11005 } 11006 return rv; 11007 } 11008 11009 /* 11010 * Function: 11011 * _bcm_td2_vxlan_eline_vp_map_set 11012 * Purpose: 11013 * Set VXLAN ELINE ports from VPN 11014 * Parameters: 11015 * unit - (IN) Device Number 11016 * vpn - (IN) VPN instance ID 11017 * Returns: 11018 * BCM_E_XXX 11019 */ 11020 STATIC int 11021 _bcm_td2_vxlan_eline_vp_map_set(int unit, int vfi_index, int vp1, int vp2) 11022 { 11023 vfi_entry_t vfi_entry; 11024 int rv=BCM_E_NONE; 11025 int num_vp=0; 11026 int vp1_invalid = 0; 11027 int vp2_invalid = 0; 11028 11029 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 11030 return BCM_E_NOT_FOUND; 11031 } 11032 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 11033 11034 BCM_IF_ERROR_RETURN 11035 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 11036 11037 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 11038 if ((vp1 > 0) && (vp1 < num_vp)) { 11039 soc_VFIm_field32_set(unit, &vfi_entry, VP_0f, vp1); 11040 } else { 11041 vp1_invalid = 1; 11042 } 11043 if ((vp2 > 0) && (vp2 < num_vp)) { 11044 soc_VFIm_field32_set(unit, &vfi_entry, VP_1f, vp2); 11045 } else { 11046 vp2_invalid = 1; 11047 } 11048 if (vp1_invalid && vp2_invalid) { 11049 return BCM_E_PARAM; 11050 } 11051 } else { 11052 /* ELAN */ 11053 return BCM_E_PARAM; 11054 } 11055 11056 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 11057 return rv; 11058 } 11059 11060 /* 11061 * Function: 11062 * _bcm_td2_vxlan_eline_vp_map_get 11063 * Purpose: 11064 * Get VXLAN ELINE ports from VPN 11065 * Parameters: 11066 * unit - (IN) Device Number 11067 * vpn - (IN) VPN instance ID 11068 * Returns: 11069 * BCM_E_XXX 11070 */ 11071 11072 STATIC int 11073 _bcm_td2_vxlan_eline_vp_map_get(int unit, int vfi_index, int *vp1, int *vp2) 11074 { 11075 vfi_entry_t vfi_entry; 11076 11077 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 11078 return BCM_E_NOT_FOUND; 11079 } 11080 11081 BCM_IF_ERROR_RETURN 11082 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 11083 11084 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 11085 *vp1 = soc_VFIm_field32_get(unit, &vfi_entry, VP_0f); 11086 *vp2 = soc_VFIm_field32_get(unit, &vfi_entry, VP_1f); 11087 return BCM_E_NONE; 11088 } else { 11089 return BCM_E_PARAM; 11090 } 11091 } 11092 11093 /* 11094 * Function: 11095 * _bcm_td2_vxlan_eline_vp_map_clear 11096 * Purpose: 11097 * Clear VXLAN ELINE ports from VPN 11098 * Parameters: 11099 * unit - (IN) Device Number 11100 * vpn - (IN) VPN instance ID 11101 * Returns: 11102 * BCM_E_XXX 11103 */ 11104 11105 STATIC int 11106 _bcm_td2_vxlan_eline_vp_map_clear(int unit, int vfi_index, int vp1, int vp2) 11107 { 11108 vfi_entry_t vfi_entry; 11109 int rv=BCM_E_NONE; 11110 int num_vp=0; 11111 11112 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 11113 return BCM_E_NOT_FOUND; 11114 } 11115 11116 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 11117 11118 BCM_IF_ERROR_RETURN 11119 (READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 11120 11121 if (soc_VFIm_field32_get(unit, &vfi_entry, PT2PT_ENf)) { 11122 if ((vp1 > 0) && (vp1 < num_vp)) { 11123 soc_VFIm_field32_set(unit, &vfi_entry, VP_0f, 0); 11124 } 11125 if ((vp2 > 0) && (vp2 < num_vp)) { 11126 soc_VFIm_field32_set(unit, &vfi_entry, VP_1f, 0); 11127 } 11128 } else { 11129 /* ELAN */ 11130 return BCM_E_PARAM; 11131 } 11132 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 11133 return rv; 11134 } 11135 11136 /* 11137 * Function: 11138 * _bcm_td2_vxlan_eline_vp_configure 11139 * Purpose: 11140 * Configure VXLAN ELINE virtual port 11141 * Parameters: 11142 * unit - (IN) Device Number 11143 * vpn - (IN) VPN instance ID 11144 * Returns: 11145 * BCM_E_XXX 11146 */ 11147 11148 STATIC int 11149 _bcm_td2_vxlan_eline_vp_configure (int unit, int vfi_index, int active_vp, 11150 source_vp_entry_t *svp, uint32 tpid_enable, bcm_vxlan_port_t *vxlan_port) 11151 { 11152 int rv = BCM_E_NONE; 11153 int network_group=0; 11154 source_vp_2_entry_t svp_2_entry; 11155 11156 /* Set SOURCE_VP */ 11157 soc_SOURCE_VPm_field32_set(unit, svp, CLASS_IDf, 11158 vxlan_port->if_class); 11159 11160 /* Default Split Horizon Group Id 11161 * 0 - For Access Port;1 - For Network Port*/ 11162 network_group = vxlan_port->network_group_id; 11163 rv = _bcm_validate_splithorizon_network_group(unit, 11164 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 11165 BCM_IF_ERROR_RETURN(rv); 11166 if (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 11167 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 11168 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf, 11169 network_group); 11170 } else { 11171 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 1); 11172 } 11173 #if defined(BCM_TRIDENT3_SUPPORT) 11174 if (SOC_IS_TRIDENT3X(unit)) { 11175 } else 11176 #endif 11177 { 11178 soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_VXLAN_TPID_SVP_BASED); 11179 } 11180 } else { 11181 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 11182 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf, 11183 network_group); 11184 } else { 11185 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 0); 11186 } 11187 #if defined(BCM_TRIDENT3_SUPPORT) 11188 if (SOC_IS_TRIDENT3X(unit)) { 11189 } else 11190 #endif 11191 { 11192 soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_VXLAN_TPID_SVP_BASED); 11193 /* Configure IPARS Parser to signal to IMPLS Parser - Applicable only for HG2 PPD2 packets 11194 to reconstruct TPID state based on HG header information - Only for VXLAN Access ports */ 11195 sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t)); 11196 soc_SOURCE_VP_2m_field32_set(unit, &svp_2_entry, PARSE_USING_SGLP_TPIDf, 1); 11197 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VP_2m(unit, MEM_BLOCK_ALL, active_vp, &svp_2_entry)); 11198 } 11199 } 11200 11201 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TAGGED) { 11202 soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 1); 11203 #if defined(BCM_TRIDENT3_SUPPORT) 11204 if (SOC_IS_TRIDENT3X(unit)) { 11205 uint32 svp1[SOC_MAX_MEM_WORDS]; 11206 11207 sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 11208 soc_SVP_ATTRS_1m_field_set(unit, &svp1, TPID_ENABLEf, &tpid_enable); 11209 BCM_IF_ERROR_RETURN( 11210 WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, active_vp, &svp1)); 11211 } else 11212 #endif 11213 { 11214 soc_SOURCE_VPm_field32_set(unit, svp, TPID_ENABLEf, tpid_enable); 11215 } 11216 } else { 11217 soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 0); 11218 } 11219 11220 soc_SOURCE_VPm_field32_set(unit, svp, DISABLE_VLAN_CHECKSf, 1); 11221 soc_SOURCE_VPm_field32_set(unit, svp, 11222 ENTRY_TYPEf, _BCM_VXLAN_SOURCE_VP_TYPE_VFI); /* VFI Type */ 11223 soc_SOURCE_VPm_field32_set(unit, svp, VFIf, vfi_index); 11224 11225 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, active_vp, svp); 11226 #if defined(BCM_TRIDENT3_SUPPORT) 11227 if (SOC_IS_TRIDENT3X(unit)) { 11228 if ((vfi_index != _BCM_VXLAN_VFI_INVALID) && 11229 (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK)) { 11230 if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm, 11231 active_vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word, 11232 _BCM_VXLAN_SOURCE_VP_TYPE_VFI)) { 11233 LOG_ERROR(BSL_LS_BCM_VXLAN, 11234 (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n"))); 11235 } 11236 } 11237 } 11238 #endif 11239 return rv; 11240 } 11241 11242 /* 11243 * Function: 11244 * _bcm_td2_vxlan_access_niv_pe_set 11245 * Purpose: 11246 * Set VXLAN Access virtual port which is of NIV/PE type 11247 * Parameters: 11248 * unit - (IN) Device Number 11249 * vp - (IN) Access Virtual Port 11250 * vfi - (IN) Virtial forwarding instance 11251 * Returns: 11252 * BCM_E_XXX 11253 */ 11254 11255 STATIC int 11256 _bcm_td2_vxlan_access_niv_pe_set (int unit, int vp, int vfi) 11257 { 11258 source_vp_entry_t svp; 11259 int rv = BCM_E_PARAM; 11260 11261 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 11262 if (rv < 0) { 11263 return rv; 11264 } 11265 11266 if (vfi == _BCM_VXLAN_VFI_INVALID) { 11267 soc_SOURCE_VPm_field32_set(unit, &svp, 11268 ENTRY_TYPEf, _BCM_VXLAN_SOURCE_VP_TYPE_INVALID); 11269 } else { 11270 /* Initialize VP parameters */ 11271 soc_SOURCE_VPm_field32_set(unit, &svp, 11272 ENTRY_TYPEf, _BCM_VXLAN_SOURCE_VP_TYPE_VFI); 11273 } 11274 soc_SOURCE_VPm_field32_set(unit, &svp, VFIf, vfi); 11275 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 11276 return rv; 11277 } 11278 11279 /* 11280 * Function: 11281 * _bcm_td2_vxlan_access_niv_pe_reset 11282 * Purpose: 11283 * Reset VXLAN Access virtual port which is of NIV/PE type 11284 * Parameters: 11285 * unit - (IN) Device Number 11286 * vp - (IN) Access Virtual Port 11287 * Returns: 11288 * BCM_E_XXX 11289 */ 11290 11291 STATIC int 11292 _bcm_td2_vxlan_access_niv_pe_reset (int unit, int vp) 11293 { 11294 source_vp_entry_t svp; 11295 11296 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 11297 11298 /* Initialize VP parameters */ 11299 soc_SOURCE_VPm_field32_set(unit, &svp, 11300 ENTRY_TYPEf, _BCM_VXLAN_SOURCE_VP_TYPE_VLAN); 11301 soc_SOURCE_VPm_field32_set(unit, &svp, VFIf, 0); 11302 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp)); 11303 11304 return BCM_E_NONE; 11305 } 11306 11307 11308 /* 11309 * Function: 11310 * _bcm_td2_vxlan_vp_based_vnid_add 11311 * Purpose: 11312 * Add VXLAN VP-based VFI-VNID mapping 11313 * Parameters: 11314 * unit - (IN) Device Number 11315 * vpn - (IN) VPN instance ID 11316 * vxlan_port - (IN) VXLAN port information 11317 * Returns: 11318 * BCM_E_XXX 11319 */ 11320 11321 STATIC int 11322 _bcm_td2_vxlan_vp_based_vnid_add(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 11323 { 11324 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 11325 int vp, vfi; 11326 _bcm_vp_info_t vp_info; 11327 uint32 tunnel_sip; 11328 int32 tunnel_idx; 11329 soc_mem_t vxlate_mem; 11330 soc_mem_t mmem = MPLS_ENTRYm; 11331 int valid = 0; 11332 int tpid_index = -1; 11333 int d = 0; /*vxlan decoupled mode*/ 11334 uint32 ment_evt[SOC_MAX_MEM_WORDS] = {0}; 11335 uint32 ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 11336 uint32 original_ment_evt[SOC_MAX_MEM_WORDS] = {0}; 11337 uint32 original_ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 11338 uint8 vxlan_vpn_type; 11339 int rv; 11340 source_vp_entry_t svp; 11341 bcm_vxlan_port_t vxlan_port_r; 11342 11343 #if defined(BCM_TRIDENT3_SUPPORT) 11344 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11345 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 11346 d = 1; 11347 } else 11348 #endif 11349 { 11350 vxlate_mem = EGR_VLAN_XLATEm; 11351 } 11352 11353 if (vxlan_port == NULL) { 11354 return BCM_E_PARAM; 11355 } 11356 11357 BCM_IF_ERROR_RETURN ( 11358 _bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type)); 11359 if (vxlan_vpn_type == _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID) { 11360 /* could not co-exist */ 11361 return BCM_E_PARAM; 11362 } 11363 11364 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 11365 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 11366 11367 11368 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 11369 if (vp == -1) { 11370 return BCM_E_PARAM; 11371 } 11372 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 11373 return BCM_E_NOT_FOUND; 11374 } 11375 /* Check for Network-Port */ 11376 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 11377 if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) { 11378 return BCM_E_PARAM; 11379 } 11380 11381 bcm_vxlan_port_t_init(&vxlan_port_r); 11382 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_port_get(unit, vpn, vp, &vxlan_port_r)); 11383 11384 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11385 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 11386 if (!(vxlan_port_r.flags & BCM_VXLAN_PORT_MULTICAST)) { 11387 /* match_vlan will be used in MPLS_ENTRY table */ 11388 if (vxlan_port->match_vlan != vxlan_info->match_key[vp].match_vlan) { 11389 return BCM_E_PARAM; 11390 } 11391 } 11392 } 11393 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) */ 11394 11395 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 11396 if (vfi == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf)) { 11397 return BCM_E_PARAM; 11398 } 11399 11400 /* set egr_vlan_xlate table */ 11401 #if defined(BCM_TRIDENT3_SUPPORT) 11402 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11403 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BASE_VALIDf, 1); 11404 soc_mem_field32_set(unit, vxlate_mem, ment_evt, 11405 DATA_TYPEf, _BCM_VXLAN_DATA_TYPE_LOOKUP_VFI); 11406 soc_mem_field32_set(unit, vxlate_mem, ment_evt, 11407 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 11408 } else 11409 #endif 11410 { 11411 soc_mem_field32_set(unit, vxlate_mem, ment_evt, ENTRY_TYPEf, 11412 _BCM_VXLAN_KEY_TYPE_LOOKUP_VFI_DVP); 11413 soc_mem_field32_set(unit, vxlate_mem, ment_evt, VALIDf, 0x1); 11414 } 11415 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BCM_VXLAN_VFI_FIELD(d, DVPf), vp); 11416 soc_mem_field32_set(unit, vxlate_mem, ment_evt, BCM_VXLAN_VFI_FIELD(d, VFIf), vfi); 11417 soc_mem_field32_set(unit, vxlate_mem, ment_evt, (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf), 11418 vxlan_port->vnid); 11419 11420 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TAGGED) { 11421 rv = _bcm_td2_vxlan_sd_tag_set(unit, NULL, vxlan_port, NULL, ment_evt, &tpid_index); 11422 if (BCM_FAILURE(rv)) { 11423 return rv; 11424 } 11425 } 11426 11427 rv = _bcm_td2_vxlan_match_egr_vxlate_entry_set(unit, vpn, vxlan_port, ment_evt, original_ment_evt); 11428 if (BCM_FAILURE(rv)) { 11429 goto _rollback; 11430 } 11431 11432 if (vxlan_port_r.flags & BCM_VXLAN_PORT_MULTICAST) { 11433 vxlan_info->vfi_vnid_map_count[vp]++; 11434 return BCM_E_NONE; 11435 } 11436 11437 /* set mpls_entry table */ 11438 #if defined(BCM_TRIDENT3_SUPPORT) 11439 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11440 _bcm_td3_vxlan_vxlate_entry_t ent; 11441 mmem = VLAN_XLATE_1_DOUBLEm; 11442 sal_memset(&ent, 0, sizeof(_bcm_td3_vxlan_vxlate_entry_t)); 11443 ent.dtype = _BCM_VXLAN_DATA_TYPE_VNID_VFI_FLEX; 11444 ent.ktype = _BCM_VXLAN_KEY_TYPE_VNID_VFI_SIP_FLEX; 11445 ent.vfi = vfi; 11446 ent.vlan = vxlan_info->vxlan_vpn_vlan[vfi]; 11447 _bcm_td3_vxlan_vxlate_entry_assemble(unit, ent, ment_vnid); 11448 } else 11449 #endif 11450 { 11451 soc_mem_field32_set(unit, mmem, ment_vnid, VALIDf, 1); 11452 soc_mem_field32_set(unit, mmem, ment_vnid, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI); 11453 soc_mem_field32_set(unit, mmem, ment_vnid, VXLAN_VN_ID__VFIf, vfi); 11454 } 11455 tunnel_idx = vxlan_info->match_key[vp].match_tunnel_index; 11456 tunnel_sip = vxlan_info->vxlan_tunnel_term[tunnel_idx].sip; 11457 soc_mem_field32_set(unit, mmem, ment_vnid, BCM_VXLAN_VNID_FIELD(d, SIPf), tunnel_sip); 11458 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11459 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 11460 soc_mem_field32_set(unit, mmem, ment_vnid, VXLAN_VN_ID__OVIDf, 11461 vxlan_port->match_vlan); 11462 } 11463 #endif 11464 soc_mem_field32_set(unit, mmem, ment_vnid, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), vxlan_port->vnid); 11465 11466 #if defined(BCM_TRIDENT3_SUPPORT) 11467 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11468 rv = _bcm_td3_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, ment_vnid, original_ment_vnid); 11469 } else 11470 #endif 11471 { 11472 rv = _bcm_td2_vxlan_match_tunnel_entry_set(unit, ment_vnid, original_ment_vnid); 11473 } 11474 if (BCM_FAILURE(rv)) { 11475 goto _rollback; 11476 } 11477 11478 vxlan_info->vfi_vnid_map_count[vp]++; 11479 11480 return rv; 11481 11482 _rollback: 11483 if (tpid_index != -1) { 11484 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 11485 } 11486 11487 if (soc_feature(unit, soc_feature_base_valid)) { 11488 if ((soc_mem_field32_get(unit, vxlate_mem, original_ment_evt, BASE_VALID_0f) == 3) && 11489 (soc_mem_field32_get(unit, vxlate_mem, original_ment_evt, BASE_VALID_1f) == 7)) { 11490 valid = 1; 11491 } else { 11492 valid = 0; 11493 } 11494 } else { 11495 valid = soc_mem_field32_get(unit, vxlate_mem, original_ment_evt, VALIDf); 11496 } 11497 if (valid) { 11498 (void) _bcm_td2_vxlan_match_egr_vxlate_entry_set(unit, vpn, vxlan_port, 11499 original_ment_evt, 11500 ment_evt); 11501 } else { 11502 (void) _bcm_td2_vxlan_match_egr_vxlate_entry_delete(unit, ment_evt); 11503 } 11504 11505 if (soc_feature(unit, soc_feature_base_valid)) { 11506 if ((soc_mem_field32_get(unit, vxlate_mem, original_ment_vnid, BASE_VALID_0f) == 3) && 11507 (soc_mem_field32_get(unit, vxlate_mem, original_ment_vnid, BASE_VALID_1f) == 7)) { 11508 valid = 1; 11509 } else { 11510 valid = 0; 11511 } 11512 } else { 11513 valid = soc_mem_field32_get(unit, vxlate_mem, original_ment_vnid, VALIDf); 11514 } 11515 if (valid) { 11516 #if defined(BCM_TRIDENT3_SUPPORT) 11517 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11518 (void) _bcm_td3_vxlan_match_vxlate_entry_set(unit, vpn, vxlan_port, original_ment_vnid, ment_vnid); 11519 } else 11520 #endif 11521 { 11522 (void) _bcm_td2_vxlan_match_tunnel_entry_set(unit, original_ment_vnid, ment_vnid); 11523 } 11524 } else { 11525 (void) _bcm_td2_vxlan_match_tunnel_entry_delete(unit, ment_vnid); 11526 } 11527 11528 return rv; 11529 } 11530 11531 11532 /* 11533 * Function: 11534 * _bcm_td2_vxlan_vp_based_vnid_delete 11535 * Purpose: 11536 * Delete VXLAN VP-based VFI-VNID mapping 11537 * Parameters: 11538 * unit - (IN) Device Number 11539 * vpn - (IN) VPN instance ID 11540 * vxlan_port - (IN) VXLAN port information 11541 * Returns: 11542 * BCM_E_XXX 11543 */ 11544 11545 STATIC int 11546 _bcm_td2_vxlan_vp_based_vnid_delete(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 11547 { 11548 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 11549 int vp, vfi; 11550 _bcm_vp_info_t vp_info; 11551 uint32 tunnel_sip; 11552 int32 tunnel_idx; 11553 soc_mem_t vxlate_mem; 11554 soc_mem_t mmem = MPLS_ENTRYm; 11555 int tpid_index = -1; 11556 int d = 0; /*vxlan decoupled mode*/ 11557 uint32 ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 11558 uint32 original_ment_vnid[SOC_MAX_MEM_WORDS] = {0}; 11559 uint8 vxlan_vpn_type; 11560 int rv; 11561 int action_present, action_not_present; 11562 uint32 old_vxlate_entry[SOC_MAX_MEM_WORDS] = {0}; 11563 int index; 11564 uint32 vnid; 11565 11566 11567 #if defined(BCM_TRIDENT3_SUPPORT) 11568 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11569 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 11570 d = 1; 11571 } else 11572 #endif 11573 { 11574 vxlate_mem = EGR_VLAN_XLATEm; 11575 } 11576 11577 if (vxlan_port == NULL) { 11578 return BCM_E_PARAM; 11579 } 11580 11581 BCM_IF_ERROR_RETURN( 11582 _bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type)); 11583 if (vxlan_vpn_type == _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID) { 11584 return BCM_E_PARAM; 11585 } 11586 11587 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 11588 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 11589 11590 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 11591 if (vp == -1) { 11592 return BCM_E_PARAM; 11593 } 11594 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 11595 return BCM_E_NOT_FOUND; 11596 } 11597 /* Check for Network-Port */ 11598 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 11599 if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) { 11600 return BCM_E_PARAM; 11601 } 11602 11603 11604 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi, vp, old_vxlate_entry); 11605 if (BCM_FAILURE(rv)) { 11606 return rv; 11607 } 11608 11609 #if defined(BCM_TRIDENT3_SUPPORT) 11610 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11611 int profile_idx = -1; 11612 profile_idx = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, 11613 VXLAN_VFI_FLEX__TAG_ACTION_PROFILE_PTRf); 11614 (void)_bcm_td3_sd_tag_action_get(unit, profile_idx, &action_present, 11615 &action_not_present); 11616 } else 11617 #endif 11618 { 11619 /*If tpid exists, delete it*/ 11620 action_present = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, 11621 VXLAN_VFI__SD_TAG_ACTION_IF_PRESENTf); 11622 action_not_present = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, 11623 VXLAN_VFI__SD_TAG_ACTION_IF_NOT_PRESENTf); 11624 } 11625 11626 if (1 == action_present || 4 == action_present || 11627 7 == action_present || 1 == action_not_present) { 11628 tpid_index = soc_mem_field32_get(unit, 11629 vxlate_mem, old_vxlate_entry, 11630 d ? VXLAN_VFI_FLEX__OUTER_TPID_INDEXf : VXLAN_VFI__SD_TAG_TPID_INDEXf); 11631 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 11632 if (BCM_FAILURE(rv)) { 11633 return rv; 11634 } 11635 } 11636 11637 vnid = soc_mem_field32_get(unit, vxlate_mem, old_vxlate_entry, (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf)); 11638 11639 rv = _bcm_td2_vxlan_match_egr_vxlate_entry_delete(unit, old_vxlate_entry); 11640 if (BCM_FAILURE(rv)) { 11641 return rv; 11642 } 11643 11644 if (!(vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST)) { 11645 /* set mpls_entry table */ 11646 #if defined(BCM_TRIDENT3_SUPPORT) 11647 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11648 _bcm_td3_vxlan_vxlate_entry_t ent; 11649 mmem = VLAN_XLATE_1_DOUBLEm; 11650 sal_memset(&ent, 0, sizeof(_bcm_td3_vxlan_vxlate_entry_t)); 11651 ent.dtype = _BCM_VXLAN_DATA_TYPE_VNID_VFI_FLEX; 11652 ent.ktype = _BCM_VXLAN_KEY_TYPE_VNID_VFI_SIP_FLEX; 11653 ent.vfi = vfi; 11654 ent.vlan = vxlan_info->vxlan_vpn_vlan[vfi]; 11655 _bcm_td3_vxlan_vxlate_entry_assemble(unit, ent, ment_vnid); 11656 } else 11657 #endif 11658 { 11659 soc_mem_field32_set(unit, mmem, ment_vnid, VALIDf, 1); 11660 soc_mem_field32_set(unit, mmem, ment_vnid, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL_VNID_VFI); 11661 soc_mem_field32_set(unit, mmem, ment_vnid, VXLAN_VN_ID__VFIf, vfi); 11662 } 11663 tunnel_idx = vxlan_info->match_key[vp].match_tunnel_index; 11664 tunnel_sip = vxlan_info->vxlan_tunnel_term[tunnel_idx].sip; 11665 soc_mem_field32_set(unit, mmem, ment_vnid, BCM_VXLAN_VNID_FIELD(d, SIPf), tunnel_sip); 11666 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11667 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 11668 soc_mem_field32_set(unit, mmem, ment_vnid, VXLAN_VN_ID__OVIDf, 11669 vxlan_info->match_key[vp].match_vlan); 11670 } 11671 #endif 11672 soc_mem_field32_set(unit, mmem, ment_vnid, (d ? VXLAN_FLEX__VNIDf : VXLAN_VN_ID__VN_IDf), 11673 vnid); 11674 11675 rv = soc_mem_search(unit, mmem, MEM_BLOCK_ANY, &index, ment_vnid, original_ment_vnid, 0); 11676 if (BCM_FAILURE(rv)) { 11677 return rv; 11678 } 11679 sal_memset(ment_vnid, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 11680 rv = soc_mem_write(unit, mmem, MEM_BLOCK_ALL, index, ment_vnid); 11681 } 11682 11683 vxlan_info->vfi_vnid_map_count[vp]--; 11684 11685 return rv; 11686 } 11687 11688 11689 /* 11690 * Function: 11691 * _bcm_td2_vxlan_vp_based_vnid_get 11692 * Purpose: 11693 * Get VXLAN VP-based VFI-VNID mapping 11694 * Parameters: 11695 * unit - (IN) Device Number 11696 * vpn - (IN) VPN instance ID 11697 * vxlan_port - (IN/out) VXLAN port information 11698 * Returns: 11699 * BCM_E_XXX 11700 */ 11701 11702 STATIC int 11703 _bcm_td2_vxlan_vp_based_vnid_get(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 11704 { 11705 int vp, vfi; 11706 _bcm_vp_info_t vp_info; 11707 soc_mem_t vxlate_mem; 11708 int d = 0; /*vxlan decoupled mode*/ 11709 uint8 vxlan_vpn_type; 11710 int rv = BCM_E_NONE; 11711 uint32 vxlate_entry[SOC_MAX_MEM_WORDS] = {0}; 11712 11713 if (vxlan_port == NULL) { 11714 return BCM_E_PARAM; 11715 } 11716 11717 #if defined(BCM_TRIDENT3_SUPPORT) 11718 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 11719 vxlate_mem = EGR_VLAN_XLATE_1_SINGLEm; 11720 d = 1; 11721 } else 11722 #endif 11723 { 11724 vxlate_mem = EGR_VLAN_XLATEm; 11725 } 11726 11727 BCM_IF_ERROR_RETURN( 11728 _bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vxlan_vpn_type)); 11729 if (vxlan_vpn_type == _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID) { 11730 /* should not use this API */ 11731 return BCM_E_PARAM; 11732 } 11733 11734 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 11735 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 11736 11737 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 11738 if (vp == -1) { 11739 return BCM_E_PARAM; 11740 } 11741 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 11742 return BCM_E_NOT_FOUND; 11743 } 11744 /* Check for Network-Port */ 11745 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 11746 if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) { 11747 return BCM_E_BADID; 11748 } 11749 11750 rv = _bcm_td2_vxlan_egr_xlate_entry_get(unit, vfi, vp, vxlate_entry); 11751 if (BCM_FAILURE(rv)) { 11752 return rv; 11753 } 11754 11755 /* Get SDTAG settings */ 11756 (void)_bcm_td2_vxlan_sd_tag_get(unit, NULL, vxlan_port, NULL, vxlate_entry, 1); 11757 vxlan_port->vnid = soc_mem_field32_get(unit, vxlate_mem, vxlate_entry, 11758 (d ? VXLAN_VFI_FLEX__VNIDf : VXLAN_VFI__VN_IDf)); 11759 11760 vxlan_port->flags |= BCM_VXLAN_PORT_VPN_BASED; 11761 11762 return rv; 11763 } 11764 11765 11766 /* 11767 * Function: 11768 * _bcm_td2_vxlan_vp_based_vnid_count 11769 * Purpose: 11770 * Get number of VXLAN VP-based VFI-VNID mapping rules 11771 * Parameters: 11772 * unit - (IN) Device Number 11773 * vp - (IN) VXLAN port ID 11774 * count - (out) number of VFI-VNID mapping rules 11775 * Returns: 11776 * BCM_E_XXX 11777 */ 11778 11779 STATIC int 11780 _bcm_td2_vxlan_vp_based_vnid_count(int unit, int vp, uint32 *count) 11781 { 11782 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 11783 11784 if (count == NULL) { 11785 return BCM_E_PARAM; 11786 } 11787 11788 if (vp == -1) { 11789 return BCM_E_PARAM; 11790 } 11791 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 11792 return BCM_E_NOT_FOUND; 11793 } 11794 11795 *count = vxlan_info->vfi_vnid_map_count[vp]; 11796 11797 return BCM_E_NONE; 11798 } 11799 11800 11801 /* 11802 * Function: 11803 * _bcm_td2_vxlan_vp_based_vnid_delete_all 11804 * Purpose: 11805 * Delete all VXLAN VP-based VFI-VNID mappings 11806 * Parameters: 11807 * unit - (IN) Device Number 11808 * Returns: 11809 * BCM_E_XXX 11810 */ 11811 11812 STATIC int 11813 _bcm_td2_vxlan_vp_based_vnid_delete_all(int unit) 11814 { 11815 int rv = BCM_E_NONE; 11816 uint32 num_vp; 11817 uint32 vp; 11818 uint32 count; 11819 uint32 vfi, num_vfi; 11820 bcm_vpn_t vpn; 11821 bcm_vxlan_port_t vxlan_port; 11822 11823 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 11824 num_vfi = soc_mem_index_count(unit, VFIm); 11825 11826 SHR_BIT_ITER(VIRTUAL_INFO(unit)->vxlan_vp_bitmap, num_vp, vp) { 11827 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vp_based_vnid_count(unit, vp, &count)); 11828 for (vfi = 0; (vfi < num_vfi) && count; vfi++) { 11829 if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVxlan)) { 11830 _BCM_VXLAN_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, vfi); 11831 bcm_vxlan_port_t_init(&vxlan_port); 11832 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port.vxlan_port_id, vp); 11833 rv = _bcm_td2_vxlan_vp_based_vnid_get(unit, vpn, &vxlan_port); 11834 if (BCM_SUCCESS(rv)) { 11835 bcm_vxlan_port_t_init(&vxlan_port); 11836 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_port_get(unit, vpn, vp, &vxlan_port)); 11837 rv = _bcm_td2_vxlan_vp_based_vnid_delete(unit, vpn, &vxlan_port); 11838 if (BCM_SUCCESS(rv)) { 11839 count--; 11840 } else { 11841 return rv; 11842 } 11843 } 11844 } 11845 } 11846 11847 } 11848 11849 return rv; 11850 } 11851 11852 11853 /* 11854 * Function: 11855 * _bcm_td2_vxlan_vplag_vp_update 11856 * Purpose: 11857 * Update vplag vp according to VXLAN port 11858 * Parameters: 11859 * unit - (IN) Device Number 11860 * gport - (IN) VXLAN port 11861 * Returns: 11862 * BCM_E_XXX 11863 */ 11864 STATIC int 11865 _bcm_td2_vxlan_vplag_vp_update(int unit, bcm_gport_t gport) 11866 { 11867 int rv = 0; 11868 int vp = 0; 11869 int vplag_vp = 0; 11870 uint32 vfi = 0; 11871 uint32 network_port = 0; 11872 uint32 network_group = 0; 11873 uint32 tpid_enable = 0; 11874 uint32 sd_tag_mode = 0; 11875 source_vp_entry_t svp_entry; 11876 source_vp_entry_t svp_entry1; 11877 11878 rv = bcm_td2_vxlan_port_source_vp_lag_get(unit, gport, &vplag_vp); 11879 if (BCM_SUCCESS(rv)) { 11880 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 11881 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 11882 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vplag_vp, &svp_entry1)); 11883 11884 vfi = soc_SOURCE_VPm_field32_get(unit, &svp_entry, VFIf); 11885 sd_tag_mode = soc_SOURCE_VPm_field32_get(unit, &svp_entry, SD_TAG_MODEf); 11886 soc_SOURCE_VPm_field32_set(unit, &svp_entry1, VFIf, vfi); 11887 soc_SOURCE_VPm_field32_set(unit, &svp_entry1, SD_TAG_MODEf, sd_tag_mode); 11888 11889 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 11890 network_group = soc_SOURCE_VPm_field32_get(unit, &svp_entry, NETWORK_GROUPf); 11891 soc_SOURCE_VPm_field32_set(unit, &svp_entry1, NETWORK_GROUPf, network_group); 11892 } else { 11893 network_port = soc_SOURCE_VPm_field32_get(unit, &svp_entry, NETWORK_PORTf); 11894 soc_SOURCE_VPm_field32_set(unit, &svp_entry1, NETWORK_PORTf, network_port); 11895 } 11896 #if defined(BCM_TRIDENT3_SUPPORT) 11897 if (SOC_IS_TRIDENT3X(unit)) { 11898 uint32 svp1[SOC_MAX_MEM_WORDS]; 11899 uint32 svp2[SOC_MAX_MEM_WORDS]; 11900 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, svp1)); 11901 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vplag_vp, svp2)); 11902 soc_SVP_ATTRS_1m_field_get(unit, &svp1, TPID_ENABLEf, &tpid_enable); 11903 soc_SVP_ATTRS_1m_field_set(unit, &svp2, TPID_ENABLEf, &tpid_enable); 11904 BCM_IF_ERROR_RETURN(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, vplag_vp, &svp2)); 11905 } else 11906 #endif 11907 { 11908 tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp_entry, TPID_ENABLEf); 11909 soc_SOURCE_VPm_field32_set(unit, &svp_entry1, TPID_ENABLEf, tpid_enable); 11910 } 11911 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vplag_vp, &svp_entry1)); 11912 } 11913 11914 return BCM_E_NONE; 11915 } 11916 11917 11918 /* 11919 * Function: 11920 * _bcm_td2_vxlan_eline_port_add 11921 * Purpose: 11922 * Add VXLAN ELINE port to a VPN 11923 * Parameters: 11924 * unit - (IN) Device Number 11925 * vpn - (IN) VPN instance ID 11926 * vxlan_port - (IN/OUT) VXLAN port information (OUT : vxlan_port_id) 11927 * Returns: 11928 * BCM_E_XXX 11929 */ 11930 11931 STATIC int 11932 _bcm_td2_vxlan_eline_port_add(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 11933 { 11934 int active_vp = 0; /* default VP */ 11935 source_vp_entry_t svp1, svp2; 11936 uint8 vp_valid_flag = 0; 11937 uint32 tpid_enable = 0; 11938 int tpid_index = -1; 11939 int customer_drop=0; 11940 int rv = BCM_E_PARAM; 11941 int num_vp=0; 11942 int vp1=-1, vp2=-1, vfi_index= -1; 11943 _bcm_vp_info_t vp_info; 11944 11945 _bcm_vp_info_init(&vp_info); 11946 vp_info.vp_type = _bcmVpTypeVxlan; 11947 11948 if ( vpn != BCM_VXLAN_VPN_INVALID) { 11949 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VXLAN_VPN_TYPE_ELINE, vpn); 11950 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 11951 return BCM_E_NOT_FOUND; 11952 } 11953 } else { 11954 vfi_index = _BCM_VXLAN_VFI_INVALID; 11955 } 11956 11957 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 11958 if ( vpn != BCM_VXLAN_VPN_INVALID) { 11959 11960 /* ---- Read in current table values for VP1 and VP2 ----- */ 11961 (void) _bcm_td2_vxlan_eline_vp_map_get (unit, vfi_index, &vp1, &vp2); 11962 11963 if (_bcm_vp_used_get(unit, vp1, _bcmVpTypeVxlan)) { 11964 BCM_IF_ERROR_RETURN ( 11965 READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp1, &svp1)); 11966 if (soc_SOURCE_VPm_field32_get(unit, &svp1, ENTRY_TYPEf) == 0x1) { 11967 vp_valid_flag |= 0x1; /* -- VP1 Valid ----- */ 11968 } 11969 } 11970 11971 if (_bcm_vp_used_get(unit, vp2, _bcmVpTypeVxlan)) { 11972 BCM_IF_ERROR_RETURN ( 11973 READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp2, &svp2)); 11974 if (soc_SOURCE_VPm_field32_get(unit, &svp2, ENTRY_TYPEf) == 0x1) { 11975 vp_valid_flag |= 0x2; /* -- VP2 Valid ----- */ 11976 } 11977 } 11978 11979 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 11980 active_vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 11981 if (active_vp == -1) { 11982 return BCM_E_PARAM; 11983 } 11984 if (!_bcm_vp_used_get(unit, active_vp, _bcmVpTypeVxlan)) { 11985 return BCM_E_NOT_FOUND; 11986 } 11987 /* Decrement old-port's nexthop count */ 11988 rv = _bcm_td2_vxlan_port_nh_cnt_dec(unit, active_vp); 11989 if (rv < 0) { 11990 return rv; 11991 } 11992 /* Decrement old-port's VP count */ 11993 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port->vxlan_port_id, 11994 active_vp, FALSE); 11995 if (rv < 0) { 11996 return rv; 11997 } 11998 } 11999 } 12000 12001 switch (vp_valid_flag) { 12002 12003 case 0x0: /* No VP is valid */ 12004 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 12005 return BCM_E_NOT_FOUND; 12006 } 12007 12008 if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID) { 12009 vp1 = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 12010 if (vp1 == -1) { 12011 return BCM_E_PARAM; 12012 } 12013 12014 if (_bcm_vp_used_get(unit, vp1, _bcmVpTypeVxlan)) { 12015 return BCM_E_EXISTS; 12016 } 12017 if (vp1 >= num_vp) { 12018 return (BCM_E_BADID); 12019 } 12020 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 12021 BCM_IF_ERROR_RETURN(_bcm_vp_used_set(unit, vp1, vp_info)); 12022 } else { 12023 12024 /* No entries are used, allocate a new VP index for VP1 */ 12025 12026 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 12027 rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp1); 12028 if (rv < 0) { 12029 return rv; 12030 } 12031 /* Allocate a new VP index for VP2 */ 12032 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 12033 rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp2); 12034 if (rv < 0) { 12035 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp1); 12036 return rv; 12037 } 12038 } 12039 12040 active_vp = vp1; 12041 vp_valid_flag = 1; 12042 sal_memset(&svp1, 0, sizeof(source_vp_entry_t)); 12043 sal_memset(&svp2, 0, sizeof(source_vp_entry_t)); 12044 (void) _bcm_td2_vxlan_eline_vp_map_set(unit, vfi_index, vp1, vp2); 12045 break; 12046 12047 12048 case 0x1: /* Only VP1 is valid */ 12049 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 12050 if (active_vp != vp1) { 12051 return BCM_E_NOT_FOUND; 12052 } 12053 } else if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID) { 12054 vp2 = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 12055 if (vp2 == -1) { 12056 return BCM_E_PARAM; 12057 } 12058 12059 if (_bcm_vp_used_get(unit, vp2, _bcmVpTypeVxlan)) { 12060 return BCM_E_EXISTS; 12061 } 12062 if (vp2 >= num_vp) { 12063 return (BCM_E_BADID); 12064 } 12065 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 12066 BCM_IF_ERROR_RETURN(_bcm_vp_used_set(unit, vp2, vp_info)); 12067 12068 active_vp = vp2; 12069 vp_valid_flag = 3; 12070 sal_memset(&svp2, 0, sizeof(source_vp_entry_t)); 12071 } else { 12072 active_vp = vp2; 12073 vp_valid_flag = 3; 12074 sal_memset(&svp2, 0, sizeof(source_vp_entry_t)); 12075 } 12076 12077 (void) _bcm_td2_vxlan_eline_vp_map_set(unit, vfi_index, vp1, vp2); 12078 break; 12079 12080 12081 12082 case 0x2: /* Only VP2 is valid */ 12083 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 12084 if (active_vp != vp2) { 12085 return BCM_E_NOT_FOUND; 12086 } 12087 } else if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID) { 12088 vp1 = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 12089 if (vp1 == -1) { 12090 return BCM_E_PARAM; 12091 } 12092 12093 if (_bcm_vp_used_get(unit, vp1, _bcmVpTypeVxlan)) { 12094 return BCM_E_EXISTS; 12095 } 12096 if (vp1 >= num_vp) { 12097 return (BCM_E_BADID); 12098 } 12099 vp_info.flags &= ~(_BCM_VP_INFO_NETWORK_PORT); 12100 BCM_IF_ERROR_RETURN(_bcm_vp_used_set(unit, vp1, vp_info)); 12101 12102 } else { 12103 active_vp = vp1; 12104 vp_valid_flag = 3; 12105 sal_memset(&svp1, 0, sizeof(source_vp_entry_t)); 12106 } 12107 12108 (void) _bcm_td2_vxlan_eline_vp_map_set(unit, vfi_index, vp1, vp2); 12109 break; 12110 12111 12112 12113 case 0x3: /* VP1 and VP2 are valid */ 12114 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 12115 return BCM_E_FULL; 12116 } 12117 break; 12118 } 12119 12120 if (active_vp == -1) { 12121 return BCM_E_CONFIG; 12122 } 12123 12124 /* Set VXLAN port ID */ 12125 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 12126 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, active_vp); 12127 } 12128 /* ======== Configure Next-Hop Properties ========== */ 12129 customer_drop = (vxlan_port->flags & BCM_VXLAN_PORT_DROP) ? 1 : 0; 12130 rv = _bcm_td2_vxlan_port_nh_add(unit, vxlan_port, active_vp, vpn, customer_drop); 12131 if (rv < 0) { 12132 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 12133 (void) _bcm_vp_free(unit, _bcmVfiTypeVxlan, 1, active_vp); 12134 } 12135 return rv; 12136 } 12137 12138 /* ======== Configure Service-Tag Properties =========== */ 12139 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TAGGED) { 12140 #if defined(BCM_TRIDENT3_SUPPORT) 12141 if (SOC_IS_TRIDENT3X(unit)) { 12142 rv = _bcm_fb2_outer_tpid_entry_add(unit, 12143 vxlan_port->egress_service_tpid, &tpid_index); 12144 } else 12145 #endif 12146 { 12147 rv = _bcm_fb2_outer_tpid_lkup(unit, vxlan_port->egress_service_tpid, 12148 &tpid_index); 12149 } 12150 if (rv < 0) { 12151 goto vxlan_cleanup; 12152 } 12153 tpid_enable = (1 << tpid_index); 12154 } 12155 12156 /* ======== Configure SVP Property ========== */ 12157 if (active_vp == vp1) { 12158 rv = _bcm_td2_vxlan_eline_vp_configure (unit, vfi_index, active_vp, &svp1, 12159 tpid_enable, vxlan_port); 12160 } else if (active_vp == vp2) { 12161 rv = _bcm_td2_vxlan_eline_vp_configure (unit, vfi_index, active_vp, &svp2, 12162 tpid_enable, vxlan_port); 12163 } 12164 if (rv < 0) { 12165 goto vxlan_cleanup; 12166 } 12167 12168 rv = _bcm_td2_vxlan_match_add(unit, vxlan_port, active_vp, vpn); 12169 if (rv < 0) { 12170 goto vxlan_cleanup; 12171 } 12172 12173 /* Increment new-port's VP count */ 12174 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port->vxlan_port_id, active_vp, TRUE); 12175 if (rv < 0) { 12176 goto vxlan_cleanup; 12177 } 12178 12179 /* Set VXLAN port ID */ 12180 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 12181 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, active_vp); 12182 } 12183 12184 vxlan_cleanup: 12185 if (rv < 0) { 12186 if (tpid_enable) { 12187 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 12188 } 12189 /* Free the VP's */ 12190 if (vp_valid_flag) { 12191 if (vp1 != -1) { 12192 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp1); 12193 } 12194 if (vp2 != -1) { 12195 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp2); 12196 } 12197 } 12198 } 12199 return rv; 12200 } 12201 12202 /* 12203 * Function: 12204 * _bcm_td2_vxlan_elan_port_add 12205 * Purpose: 12206 * Add VXLAN ELAN port to a VPN 12207 * Parameters: 12208 * unit - (IN) Device Number 12209 * vpn - (IN) VPN instance ID 12210 * vxlan_port - (IN/OUT) vxlan port information (OUT : vxlan_port_id) 12211 * Returns: 12212 * BCM_E_XXX 12213 */ 12214 12215 STATIC int 12216 _bcm_td2_vxlan_elan_port_add(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 12217 { 12218 int vp, num_vp, vfi=0; 12219 source_vp_entry_t svp; 12220 source_vp_2_entry_t svp2; 12221 uint32 tpid_enable = 0; 12222 int tpid_index=-1; 12223 int drop=0, rv = BCM_E_PARAM; 12224 int cml_default_enable=0, cml_default_new=0, cml_default_move=0; 12225 _bcm_vp_info_t vp_info; 12226 int network_group=0; 12227 uint8 vpn_type = 0; 12228 #if defined(BCM_TRIDENT3_SUPPORT) 12229 uint32 svp1[SOC_MAX_MEM_WORDS]; 12230 #endif 12231 12232 if (vpn != BCM_VXLAN_VPN_INVALID) { 12233 _BCM_VXLAN_VPN_GET(vfi, _BCM_VXLAN_VPN_TYPE_ELAN, vpn); 12234 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVxlan)) { 12235 return BCM_E_NOT_FOUND; 12236 } 12237 } else { 12238 vfi = _BCM_VXLAN_VFI_INVALID; 12239 } 12240 12241 /*Valid vnid is provided only for tunnel based VPN*/ 12242 BCM_IF_ERROR_RETURN( 12243 _bcm_td2_vxlan_vpn_is_tunnel_based_vnid(unit, vpn, &vpn_type)); 12244 if ((vpn_type != _BCM_VXLAN_VPN_TYPE_TUNNEL_BASED_VNID) && 12245 vxlan_port->vnid <= 0xffffff) { 12246 return BCM_E_PARAM; 12247 } 12248 12249 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 12250 12251 _bcm_vp_info_init(&vp_info); 12252 vp_info.vp_type = _bcmVpTypeVxlan; 12253 if (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 12254 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 12255 } 12256 if ((vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_SHARE) || 12257 (vxlan_port->flags & BCM_VXLAN_PORT_SHARE)) { 12258 vp_info.flags |= _BCM_VP_INFO_SHARED_PORT; 12259 } 12260 12261 /* ======== Allocate/Get Virtual_Port =============== */ 12262 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 12263 if (BCM_GPORT_IS_NIV_PORT(vxlan_port->vxlan_port_id) || 12264 BCM_GPORT_IS_EXTENDER_PORT(vxlan_port->vxlan_port_id)) { 12265 if (BCM_GPORT_IS_NIV_PORT(vxlan_port->vxlan_port_id)) { 12266 vp = BCM_GPORT_NIV_PORT_ID_GET((vxlan_port->vxlan_port_id)); 12267 } else if (BCM_GPORT_IS_EXTENDER_PORT(vxlan_port->vxlan_port_id)) { 12268 vp = BCM_GPORT_EXTENDER_PORT_ID_GET((vxlan_port->vxlan_port_id)); 12269 } 12270 rv = _bcm_td2_vxlan_access_niv_pe_set (unit, vp, vfi); 12271 if (BCM_SUCCESS(rv)) { 12272 /* Set VXLAN port ID */ 12273 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, vp); 12274 rv = _bcm_vp_used_set(unit, vp, vp_info); 12275 } 12276 return rv; 12277 } else if (BCM_GPORT_IS_TRUNK(vxlan_port->vxlan_port_id)) { 12278 bcm_trunk_member_t trunk_member; 12279 int port_count = 0; 12280 bcm_trunk_t tid = 0; 12281 int tid_is_vp_lag = FALSE; 12282 tid = BCM_GPORT_TRUNK_GET(vxlan_port->vxlan_port_id); 12283 BCM_IF_ERROR_RETURN( 12284 _bcm_esw_trunk_id_is_vp_lag(unit, tid, &tid_is_vp_lag)); 12285 if (tid_is_vp_lag) { 12286 BCM_IF_ERROR_RETURN( 12287 bcm_td2_vp_lag_get(unit, tid, NULL, 1, 12288 &trunk_member, &port_count)); 12289 if (BCM_GPORT_IS_NIV_PORT(trunk_member.gport) || 12290 BCM_GPORT_IS_EXTENDER_PORT(trunk_member.gport)) { 12291 BCM_IF_ERROR_RETURN( 12292 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tid, &vp)); 12293 rv = _bcm_td2_vxlan_access_niv_pe_set(unit, vp, vfi); 12294 if (BCM_SUCCESS(rv)) { 12295 rv = _bcm_vp_used_set(unit, vp, vp_info); 12296 } 12297 return rv; 12298 } 12299 } 12300 } 12301 12302 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 12303 if (vp == -1) { 12304 return BCM_E_PARAM; 12305 } 12306 12307 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 12308 return BCM_E_NOT_FOUND; 12309 } 12310 12311 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 12312 #if defined(BCM_TRIDENT3_SUPPORT) 12313 if (SOC_IS_TRIDENT3X(unit)) { 12314 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, &svp1)); 12315 } 12316 #endif 12317 BCM_IF_ERROR_RETURN(READ_SOURCE_VP_2m(unit, MEM_BLOCK_ANY, vp, &svp2)); 12318 /* Decrement old-port's nexthop count */ 12319 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_port_nh_cnt_dec(unit, vp)); 12320 /* Decrement old-port's VP count */ 12321 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_port_cnt_update( 12322 unit, vxlan_port->vxlan_port_id, vp, FALSE)); 12323 } else if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID ) { 12324 if (!BCM_GPORT_IS_VXLAN_PORT(vxlan_port->vxlan_port_id)) { 12325 return (BCM_E_BADID); 12326 } 12327 12328 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 12329 if (vp == -1) { 12330 return BCM_E_PARAM; 12331 } 12332 /* Vp index zero is reserved in function _bcm_virtual_init because of 12333 * HW restriction. 12334 */ 12335 if (vp >= num_vp || vp < 1) { 12336 return BCM_E_BADID; 12337 } 12338 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) { 12339 return BCM_E_EXISTS; 12340 } 12341 BCM_IF_ERROR_RETURN(_bcm_vp_used_set(unit, vp, vp_info)); 12342 12343 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 12344 #if defined(BCM_TRIDENT3_SUPPORT) 12345 sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 12346 #endif 12347 sal_memset(&svp2, 0, sizeof(source_vp_2_entry_t)); 12348 } else { 12349 /* allocate a new VP index */ 12350 BCM_IF_ERROR_RETURN(_bcm_vp_alloc 12351 (unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp)); 12352 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, vp); 12353 12354 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 12355 #if defined(BCM_TRIDENT3_SUPPORT) 12356 sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 12357 #endif 12358 sal_memset(&svp2, 0, sizeof(source_vp_2_entry_t)); 12359 } 12360 12361 /* ======== Configure Next-Hop Properties ========== */ 12362 drop = (vxlan_port->flags & BCM_VXLAN_PORT_DROP) ? 1 : 0; 12363 rv = _bcm_td2_vxlan_port_nh_add(unit, vxlan_port, vp, vpn, drop); 12364 _BCM_VXLAN_CLEANUP(rv) 12365 12366 /* ======== Configure Service-Tag Properties =========== */ 12367 if (vxlan_port->flags & BCM_VXLAN_PORT_SERVICE_TAGGED) { 12368 #if defined(BCM_TRIDENT3_SUPPORT) 12369 if (SOC_IS_TRIDENT3X(unit)) { 12370 rv = _bcm_fb2_outer_tpid_entry_add(unit, 12371 vxlan_port->egress_service_tpid, &tpid_index); 12372 _BCM_VXLAN_CLEANUP(rv) 12373 } else 12374 #endif 12375 { 12376 rv = _bcm_fb2_outer_tpid_lkup(unit, 12377 vxlan_port->egress_service_tpid, &tpid_index); 12378 _BCM_VXLAN_CLEANUP(rv) 12379 } 12380 12381 tpid_enable = (1 << tpid_index); 12382 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 1); 12383 #if defined(BCM_TRIDENT3_SUPPORT) 12384 if (SOC_IS_TRIDENT3X(unit)) { 12385 soc_SVP_ATTRS_1m_field_set(unit, &svp1, TPID_ENABLEf, &tpid_enable); 12386 } else 12387 #endif 12388 { 12389 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, tpid_enable); 12390 } 12391 } else { 12392 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 0); 12393 } 12394 12395 /* ======== Configure SVP/DVP Properties ========== */ 12396 soc_SOURCE_VPm_field32_set(unit, &svp, CLASS_IDf, vxlan_port->if_class); 12397 soc_SOURCE_VPm_field32_set(unit, &svp, ENTRY_TYPEf, _BCM_VXLAN_SOURCE_VP_TYPE_VFI); 12398 12399 /* Default Split Horizon Group Id 12400 * 0 - For Access Port;1 - For Network Port*/ 12401 network_group = vxlan_port->network_group_id; 12402 rv = _bcm_validate_splithorizon_network_group(unit, 12403 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 12404 BCM_IF_ERROR_RETURN(rv); 12405 if (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 12406 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 12407 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_GROUPf, 12408 network_group); 12409 } else { 12410 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 1); 12411 } 12412 #if defined(BCM_TRIDENT3_SUPPORT) 12413 if (SOC_IS_TRIDENT3X(unit)) { 12414 } else 12415 #endif 12416 { 12417 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, _BCM_VXLAN_TPID_SVP_BASED); 12418 } 12419 } else { 12420 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 12421 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_GROUPf, 12422 network_group); 12423 } else { 12424 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 0); 12425 } 12426 #if defined(BCM_TRIDENT3_SUPPORT) 12427 if (SOC_IS_TRIDENT3X(unit)) { 12428 } else 12429 #endif 12430 { 12431 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_SOURCEf, _BCM_VXLAN_TPID_SGLP_BASED); 12432 /* Configure IPARS Parser to signal to IMPLS Parser - Applicable only for HG2 PPD2 packets 12433 to reconstruct TPID state based on HG header information - Only for VXLAN Access ports */ 12434 soc_SOURCE_VP_2m_field32_set(unit, &svp2, PARSE_USING_SGLP_TPIDf, 1); 12435 } 12436 } 12437 soc_SOURCE_VPm_field32_set(unit, &svp, VFIf, vfi); 12438 12439 /* Keep CML in the replace operation. It may be set by bcm_td2_vxlan_port_learn_set before */ 12440 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 12441 rv = _bcm_vp_default_cml_mode_get (unit, &cml_default_enable, 12442 &cml_default_new, &cml_default_move); 12443 _BCM_VXLAN_CLEANUP(rv) 12444 12445 if (cml_default_enable) { 12446 /* Set the CML to default values */ 12447 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, cml_default_new); 12448 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, cml_default_move); 12449 } else { 12450 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 12451 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, 0x8); 12452 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, 0x8); 12453 } 12454 } 12455 if (soc_mem_field_valid(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) { 12456 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)) { 12457 soc_SOURCE_VPm_field32_set(unit, &svp, DISABLE_VLAN_CHECKSf, 1); 12458 } 12459 } 12460 12461 _BCM_VXLAN_CLEANUP(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp)); 12462 #if defined(BCM_TRIDENT3_SUPPORT) 12463 if (SOC_IS_TRIDENT3X(unit)) { 12464 _BCM_VXLAN_CLEANUP(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, vp, &svp1)); 12465 } 12466 #endif 12467 _BCM_VXLAN_CLEANUP(WRITE_SOURCE_VP_2m(unit, MEM_BLOCK_ALL, vp, &svp2)); 12468 12469 #if defined(BCM_TRIDENT3_SUPPORT) 12470 if (SOC_IS_TRIDENT3X(unit)) { 12471 if (vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 12472 if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm, 12473 vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word, 12474 _BCM_VXLAN_SOURCE_VP_TYPE_VFI)) { 12475 LOG_ERROR(BSL_LS_BCM_VXLAN, 12476 (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n"))); 12477 } 12478 } 12479 } 12480 #endif 12481 12482 /* Configure VP match criteria */ 12483 rv = _bcm_td2_vxlan_match_add(unit, vxlan_port, vp, vpn); 12484 _BCM_VXLAN_CLEANUP(rv) 12485 12486 /* Increment new-port's VP count */ 12487 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port->vxlan_port_id, vp, TRUE); 12488 _BCM_VXLAN_CLEANUP(rv) 12489 12490 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 12491 rv = _bcm_td2_vxlan_vplag_vp_update(unit, vxlan_port->vxlan_port_id); 12492 _BCM_VXLAN_CLEANUP(rv) 12493 } 12494 12495 return BCM_E_NONE; 12496 12497 cleanup: 12498 if (tpid_enable) { 12499 (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 12500 } 12501 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 12502 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp); 12503 _bcm_td2_vxlan_port_nh_delete(unit, vpn, vp); 12504 } 12505 return rv; 12506 } 12507 12508 /* 12509 * Function: 12510 * _bcm_td2_vxlan_eline_port_delete 12511 * Purpose: 12512 * Delete VXLAN ELINE port from a VPN 12513 * Parameters: 12514 * unit - (IN) Device Number 12515 * vpn - (IN) VPN instance ID 12516 * vxlan_port_id - (IN) vxlan port information 12517 * Returns: 12518 * BCM_E_XXX 12519 */ 12520 12521 int 12522 _bcm_td2_vxlan_eline_port_delete(int unit, bcm_vpn_t vpn, int active_vp) 12523 { 12524 source_vp_entry_t svp; 12525 source_vp_2_entry_t svp_2_entry; 12526 int network_port_flag=0; 12527 int vp1=0, vp2=0, vfi_index= -1; 12528 int rv = BCM_E_UNAVAIL; 12529 bcm_gport_t vxlan_port_id; 12530 bcm_vxlan_port_t vxlan_port; 12531 _bcm_vp_info_t vp_info; 12532 12533 if ( vpn != BCM_VXLAN_VPN_INVALID) { 12534 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VXLAN_VPN_TYPE_ELINE, vpn); 12535 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 12536 return BCM_E_NOT_FOUND; 12537 } 12538 } else { 12539 vfi_index = _BCM_VXLAN_VFI_INVALID; 12540 } 12541 12542 if (!_bcm_vp_used_get(unit, active_vp, _bcmVpTypeVxlan)) { 12543 return BCM_E_NOT_FOUND; 12544 } 12545 12546 /* Set VXLAN port ID */ 12547 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port_id, active_vp); 12548 12549 /* Delete the next-hop info */ 12550 rv = _bcm_td2_vxlan_port_nh_delete(unit, vpn, active_vp); 12551 if ( rv < 0 ) { 12552 if (rv != BCM_E_NOT_FOUND) { 12553 return rv; 12554 } else { 12555 rv = 0; 12556 } 12557 } 12558 12559 /* ---- Read in current table values for VP1 and VP2 ----- */ 12560 (void) _bcm_td2_vxlan_eline_vp_map_get (unit, vfi_index, &vp1, &vp2); 12561 12562 bcm_vxlan_port_t_init(&vxlan_port); 12563 vxlan_port.vxlan_port_id = vxlan_port_id; 12564 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_port_get(unit, vpn, &vxlan_port)); 12565 rv = _bcm_td2_vxlan_match_delete(unit, active_vp, vxlan_port, vpn); 12566 if ( rv < 0 ) { 12567 if (rv != BCM_E_NOT_FOUND) { 12568 return rv; 12569 } else { 12570 rv = BCM_E_NONE; 12571 } 12572 } 12573 12574 /* If the other port is valid, point it to itself */ 12575 if (active_vp == vp1) { 12576 if (BCM_SUCCESS(rv)) { 12577 rv = _bcm_td2_vxlan_eline_vp_map_clear (unit, vfi_index, active_vp, 0); 12578 } 12579 } else if (active_vp == vp2) { 12580 if (BCM_SUCCESS(rv)) { 12581 rv = _bcm_td2_vxlan_eline_vp_map_clear (unit, vfi_index, 0, active_vp); 12582 } 12583 } 12584 12585 if (rv >= 0) { 12586 12587 /* Check for Network-Port */ 12588 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, active_vp, &vp_info)); 12589 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 12590 network_port_flag = TRUE; 12591 } 12592 12593 if (!network_port_flag) { 12594 sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t)); 12595 BCM_IF_ERROR_RETURN 12596 (WRITE_SOURCE_VP_2m(unit, MEM_BLOCK_ALL, active_vp, &svp_2_entry)); 12597 } 12598 12599 /* Invalidate the VP being deleted */ 12600 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 12601 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, active_vp, &svp); 12602 if (BCM_SUCCESS(rv)) { 12603 rv = _bcm_td2_vxlan_egress_dvp_reset(unit, active_vp); 12604 if (rv < 0) { 12605 return rv; 12606 } 12607 rv = _bcm_td2_vxlan_ingress_dvp_reset(unit, active_vp); 12608 } 12609 } 12610 12611 if (rv < 0) { 12612 return rv; 12613 } 12614 12615 /* Decrement port's VP count */ 12616 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port_id, active_vp, FALSE); 12617 if (rv < 0) { 12618 return rv; 12619 } 12620 12621 /* Free the VP */ 12622 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, active_vp); 12623 return rv; 12624 12625 } 12626 12627 /* 12628 * Function: 12629 * _bcm_td2_vxlan_elan_port_delete 12630 * Purpose: 12631 * Delete VXLAN ELAN port from a VPN 12632 * Parameters: 12633 * unit - (IN) Device Number 12634 * vpn - (IN) VPN instance ID 12635 * vxlan_port_id - (IN) vxlan port information 12636 * Returns: 12637 * BCM_E_XXX 12638 */ 12639 12640 int 12641 _bcm_td2_vxlan_elan_port_delete(int unit, bcm_vpn_t vpn, int vp) 12642 { 12643 source_vp_entry_t svp; 12644 source_vp_2_entry_t svp_2_entry; 12645 int network_port_flag=0; 12646 int rv = BCM_E_NONE; 12647 int vfi_index= -1; 12648 bcm_gport_t vxlan_port_id; 12649 bcm_vxlan_port_t vxlan_port; 12650 _bcm_vp_info_t vp_info; 12651 12652 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 12653 return BCM_E_NOT_FOUND; 12654 } 12655 12656 /* Check for Network-Port */ 12657 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 12658 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 12659 network_port_flag = TRUE; 12660 } 12661 12662 /* Set VXLAN port ID */ 12663 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port_id, vp); 12664 bcm_vxlan_port_t_init(&vxlan_port); 12665 vxlan_port.vxlan_port_id = vxlan_port_id; 12666 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_port_get(unit, vpn, &vxlan_port)); 12667 12668 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 12669 if ((!network_port_flag) && (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 12670 if (VXLAN_INFO(unit)->match_key[vp].match_count > 0) { 12671 BCM_IF_ERROR_RETURN(bcm_td2p_share_vp_delete(unit, vpn, vp)); 12672 } 12673 if (vpn != BCM_VXLAN_VPN_INVALID) { 12674 return BCM_E_NONE; 12675 } 12676 } else 12677 #endif 12678 { 12679 rv = _bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, vpn); 12680 if (rv < 0 && rv != BCM_E_NOT_FOUND) { 12681 return rv; 12682 } 12683 } 12684 12685 (void)bcm_td2_vxlan_match_clear(unit, vp); 12686 12687 if ( vpn != BCM_VXLAN_VPN_INVALID) { 12688 if (!network_port_flag) { /* Check VPN only for Access VP */ 12689 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VXLAN_VPN_TYPE_ELAN, vpn); 12690 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 12691 return BCM_E_NOT_FOUND; 12692 } 12693 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) || 12694 _bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 12695 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp); 12696 return _bcm_td2_vxlan_access_niv_pe_reset (unit, vp); 12697 } 12698 } 12699 } 12700 12701 /* Decrement port's VP count */ 12702 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_port_cnt_update(unit, vxlan_port_id, vp, FALSE)); 12703 12704 /* Delete the next-hop info */ 12705 rv = _bcm_td2_vxlan_port_nh_delete(unit, vpn, vp); 12706 if (rv < 0 && rv != BCM_E_NOT_FOUND) { 12707 return rv; 12708 } 12709 12710 /* Clear the SVP table entries */ 12711 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 12712 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp)); 12713 12714 if (!network_port_flag) { 12715 sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t)); 12716 BCM_IF_ERROR_RETURN 12717 (WRITE_SOURCE_VP_2m(unit, MEM_BLOCK_ALL, vp, &svp_2_entry)); 12718 } 12719 12720 /* Clear the DVP table entries */ 12721 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_egress_dvp_reset(unit, vp)); 12722 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_ingress_dvp_reset(unit, vp)); 12723 12724 /* Free the VP */ 12725 BCM_IF_ERROR_RETURN(_bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp)); 12726 12727 return BCM_E_NONE; 12728 } 12729 12730 /* 12731 * Function: 12732 * _bcm_td2_vxlan_port_vlan_get 12733 * Purpose: 12734 * Obtain vlan information 12735 * Parameters: 12736 * unit - (IN) Device Number 12737 * vp - (IN) Source Virtual Port 12738 * vxlan_port - (OUT) VXLAN port information 12739 * Returns: 12740 * BCM_E_XXX 12741 */ 12742 12743 STATIC int 12744 _bcm_td2_vxlan_port_vlan_get(int unit, int vp, bcm_vxlan_port_t *vxlan_port) 12745 { 12746 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 12747 int index = 0; 12748 soc_mem_t mem; 12749 uint32 vent[SOC_MAX_MEM_WORDS]; 12750 12751 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 12752 #if defined(BCM_TRIDENT3_SUPPORT) 12753 if (soc_feature(unit, soc_feature_base_valid)) { 12754 mem = VLAN_XLATE_1_DOUBLEm; 12755 12756 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 12757 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 12758 } else 12759 #endif 12760 { 12761 mem = VLAN_XLATEm; 12762 12763 soc_mem_field32_set(unit, mem, vent, VALIDf, 1); 12764 } 12765 12766 if (_BCM_VXLAN_PORT_MATCH_TYPE_VLAN == vxlan_info->match_key[vp].flags) { 12767 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12768 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 12769 #if defined(BCM_TRIDENT3_SUPPORT) 12770 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 12771 soc_mem_field32_set(unit, mem, vent, 12772 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 12773 } 12774 #endif 12775 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, 12776 vxlan_info->match_key[vp].match_vlan); 12777 } else if (_BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN == 12778 vxlan_info->match_key[vp].flags) { 12779 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12780 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 12781 #if defined(BCM_TRIDENT3_SUPPORT) 12782 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 12783 soc_mem_field32_set(unit, mem, vent, 12784 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 12785 } 12786 #endif 12787 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, 12788 vxlan_info->match_key[vp].match_inner_vlan); 12789 } else if (_BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED == 12790 vxlan_info->match_key[vp].flags) { 12791 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12792 soc_mem_field32_set(unit, mem, vent, 12793 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 12794 #if defined(BCM_TRIDENT3_SUPPORT) 12795 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 12796 soc_mem_field32_set(unit, mem, vent, 12797 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 12798 } 12799 #endif 12800 soc_mem_field32_set(unit, mem, vent, 12801 XLATE__OVIDf, vxlan_info->match_key[vp].match_vlan); 12802 soc_mem_field32_set(unit, mem, vent, 12803 XLATE__IVIDf, vxlan_info->match_key[vp].match_inner_vlan); 12804 } else if (_BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI == 12805 vxlan_info->match_key[vp].flags) { 12806 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12807 soc_mem_field32_set(unit, mem, vent, 12808 KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 12809 #if defined(BCM_TRIDENT3_SUPPORT) 12810 if (SOC_MEM_FIELD_VALID(unit, mem, DATA_TYPEf)) { 12811 soc_mem_field32_set(unit, mem, vent, 12812 DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 12813 } 12814 #endif 12815 soc_mem_field32_set(unit, mem, vent, 12816 XLATE__OTAGf, vxlan_info->match_key[vp].match_vlan); 12817 } else { 12818 return BCM_E_NONE; 12819 } 12820 12821 if (vxlan_info->match_key[vp].modid != -1) { 12822 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, 12823 vxlan_info->match_key[vp].modid); 12824 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, 12825 vxlan_info->match_key[vp].port); 12826 } else { 12827 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 12828 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, 12829 vxlan_info->match_key[vp].trunk_id); 12830 } 12831 12832 BCM_IF_ERROR_RETURN(soc_mem_search(unit, 12833 mem, MEM_BLOCK_ANY, &index, vent, vent, 0)); 12834 if (!soc_mem_field32_get(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf)) { 12835 vxlan_port->flags |= BCM_VXLAN_PORT_ENABLE_VLAN_CHECKS; 12836 } 12837 12838 return BCM_E_NONE; 12839 } 12840 12841 /* 12842 * Function: 12843 * _bcm_td2_vxlan_port_get 12844 * Purpose: 12845 * Get VXLAN port information from a VPN 12846 * Parameters: 12847 * unit - (IN) Device Number 12848 * vpn - (IN) VPN instance ID 12849 * vxlan_port_id - (IN) vxlan port information 12850 * Returns: 12851 * BCM_E_XXX 12852 */ 12853 12854 int 12855 _bcm_td2_vxlan_port_get(int unit, bcm_vpn_t vpn, int vp, bcm_vxlan_port_t *vxlan_port) 12856 { 12857 int i, rv = BCM_E_NONE; 12858 uint32 tpid_enable = 0; 12859 source_vp_entry_t svp; 12860 int split_horizon_port_flag=0; 12861 _bcm_vp_info_t vp_info; 12862 12863 /* Initialize the structure */ 12864 bcm_vxlan_port_t_init(vxlan_port); 12865 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, vp); 12866 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 12867 12868 /* Check for Network-Port */ 12869 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 12870 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 12871 split_horizon_port_flag = TRUE; 12872 } 12873 12874 if ( vpn != BCM_VXLAN_VPN_INVALID) { 12875 if (!split_horizon_port_flag) { /* Check VPN only for Access VP */ 12876 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) || 12877 _bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 12878 return BCM_E_NONE; 12879 } 12880 } 12881 } 12882 12883 if (split_horizon_port_flag) { 12884 vxlan_port->flags |= BCM_VXLAN_PORT_NETWORK; 12885 vxlan_port->flags |= BCM_VXLAN_PORT_EGRESS_TUNNEL; 12886 if(vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 12887 vxlan_port->flags |= BCM_VXLAN_PORT_SHARE; 12888 /* Shared VXLAN port is used only for multicast now*/ 12889 vxlan_port->flags |= BCM_VXLAN_PORT_MULTICAST; 12890 } 12891 } 12892 12893 /* Get the match parameters */ 12894 rv = _bcm_td2_vxlan_match_get(unit, vxlan_port, vp, vpn); 12895 BCM_IF_ERROR_RETURN(rv); 12896 12897 /* Get the BCM_VXLAN_PORT_ENABLE_VLAN_CHECKS flag */ 12898 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)) { 12899 BCM_IF_ERROR_RETURN( 12900 _bcm_td2_vxlan_port_vlan_get(unit, vp, vxlan_port)); 12901 } 12902 12903 /* Get the next-hop parameters , for shared VXLAN port, don't get next hop here*/ 12904 if (!(vxlan_port->flags & BCM_VXLAN_PORT_SHARE)) { 12905 rv = _bcm_td2_vxlan_port_nh_get(unit, vpn, vp, vxlan_port); 12906 BCM_IF_ERROR_RETURN(rv); 12907 } 12908 12909 rv = _bcm_td2_vxlan_ingress_dvp_get(unit, vp, vxlan_port); 12910 BCM_IF_ERROR_RETURN(rv); 12911 12912 /* Get Tunnel index */ 12913 rv = _bcm_td2_vxlan_egress_dvp_get(unit, vp, vxlan_port); 12914 BCM_IF_ERROR_RETURN(rv); 12915 12916 /* Fill in SVP parameters */ 12917 vxlan_port->if_class = soc_SOURCE_VPm_field32_get(unit, &svp, CLASS_IDf); 12918 12919 if (soc_SOURCE_VPm_field32_get(unit, &svp, SD_TAG_MODEf)) { 12920 #if defined(BCM_TRIDENT3_SUPPORT) 12921 if (SOC_IS_TRIDENT3X(unit)) { 12922 uint32 svp1[SOC_MAX_MEM_WORDS]; 12923 12924 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, MEM_BLOCK_ANY, vp, svp1)); 12925 soc_SVP_ATTRS_1m_field_get(unit, &svp1, TPID_ENABLEf, &tpid_enable); 12926 } else 12927 #endif 12928 { 12929 tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 12930 } 12931 if (tpid_enable) { 12932 vxlan_port->flags |= BCM_VXLAN_PORT_SERVICE_TAGGED; 12933 for (i = 0; i < 4; i++) { 12934 if (tpid_enable & (1 << i)) { 12935 _bcm_fb2_outer_tpid_entry_get(unit, &vxlan_port->egress_service_tpid, i); 12936 } 12937 } 12938 } 12939 } 12940 12941 return rv; 12942 } 12943 12944 /* 12945 * Function: 12946 * bcm_td2_vxlan_port_add 12947 * Purpose: 12948 * Add VXLAN port to a VPN 12949 * Parameters: 12950 * unit - (IN) Device Number 12951 * vpn - (IN) VPN instance ID 12952 * vxlan_port - (IN/OUT) vxlan_port information (OUT : vxlan_port_id) 12953 * Returns: 12954 * BCM_E_XXX 12955 */ 12956 12957 STATIC int 12958 _bcm_td2_vxlan_default_port_add(int unit, bcm_vxlan_port_t *vxlan_port) 12959 { 12960 source_vp_entry_t svp; 12961 int rv = BCM_E_PARAM, vp=0, num_vp=0; 12962 int network_group=0; 12963 int cml_default_enable=0, cml_default_new=0, cml_default_move=0; 12964 _bcm_vp_info_t vp_info; 12965 12966 _bcm_vp_info_init(&vp_info); 12967 vp_info.vp_type = _bcmVpTypeVxlan; 12968 if(vxlan_port->flags & BCM_VXLAN_PORT_NETWORK) { 12969 vp_info.flags |= _BCM_VP_INFO_NETWORK_PORT; 12970 } 12971 12972 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 12973 12974 /* ======== Allocate/Get Virtual_Port =============== */ 12975 if (vxlan_port->flags & BCM_VXLAN_PORT_REPLACE) { 12976 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 12977 if (vp == -1) { 12978 return BCM_E_PARAM; 12979 } 12980 12981 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 12982 return BCM_E_NOT_FOUND; 12983 } 12984 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 12985 if (rv < 0) { 12986 return rv; 12987 } 12988 12989 /* Decrement old-port's nexthop count */ 12990 rv = _bcm_td2_vxlan_port_nh_cnt_dec(unit, vp); 12991 if (rv < 0) { 12992 return rv; 12993 } 12994 12995 /* Decrement old-port's VP count */ 12996 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port->vxlan_port_id, vp, FALSE); 12997 if (rv < 0) { 12998 return rv; 12999 } 13000 13001 } else if (vxlan_port->flags & BCM_VXLAN_PORT_WITH_ID ) { 13002 if (!BCM_GPORT_IS_VXLAN_PORT(vxlan_port->vxlan_port_id)) { 13003 return (BCM_E_BADID); 13004 } 13005 13006 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 13007 if (vp == -1) { 13008 return BCM_E_PARAM; 13009 } 13010 /* Vp index zero is reserved in function _bcm_virtual_init because of 13011 * HW restriction. 13012 */ 13013 if (vp >= num_vp || vp < 1) { 13014 return BCM_E_BADID; 13015 } 13016 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13017 return BCM_E_EXISTS; 13018 } 13019 13020 BCM_IF_ERROR_RETURN(_bcm_vp_used_set(unit, vp, vp_info)); 13021 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 13022 } else { 13023 rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp); 13024 if (rv < 0) { 13025 return rv; 13026 } 13027 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 13028 BCM_IF_ERROR_RETURN(_bcm_vp_used_set(unit, vp, vp_info)); 13029 } 13030 13031 /* ======== Configure SVP/DVP Properties ========== */ 13032 soc_SOURCE_VPm_field32_set(unit, &svp, CLASS_IDf, 13033 vxlan_port->if_class); 13034 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 13035 network_group = vxlan_port->network_group_id; 13036 rv = _bcm_validate_splithorizon_network_group(unit, 13037 vxlan_port->flags & BCM_VXLAN_PORT_NETWORK, &network_group); 13038 BCM_IF_ERROR_RETURN(rv); 13039 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_GROUPf, 13040 network_group); 13041 } else { 13042 soc_SOURCE_VPm_field32_set(unit, &svp, NETWORK_PORTf, 1); 13043 } 13044 13045 soc_SOURCE_VPm_field32_set(unit, &svp, 13046 ENTRY_TYPEf, _BCM_VXLAN_SOURCE_VP_TYPE_VFI); 13047 13048 /* Keep CML in the replace operation. It may be set by bcm_td2_vxlan_port_learn_set before */ 13049 if (!(vxlan_port->flags & BCM_VXLAN_PORT_REPLACE)) { 13050 rv = _bcm_vp_default_cml_mode_get (unit, 13051 &cml_default_enable, &cml_default_new, 13052 &cml_default_move); 13053 if (rv < 0) { 13054 return rv; 13055 } 13056 13057 if (cml_default_enable) { 13058 /* Set the CML to default values */ 13059 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, cml_default_new); 13060 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, cml_default_move); 13061 } else { 13062 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 13063 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, 0x8); 13064 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, 0x8); 13065 } 13066 } 13067 if (soc_mem_field_valid(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) { 13068 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)) { 13069 soc_SOURCE_VPm_field32_set(unit, &svp, DISABLE_VLAN_CHECKSf, 1); 13070 } 13071 } 13072 13073 /* Configure VXLAN_DEFAULT_NETWORK_SVPr.SVP */ 13074 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 13075 BCM_IF_ERROR_RETURN(rv); 13076 13077 #if defined(BCM_TRIDENT3_SUPPORT) 13078 if (SOC_IS_TRIDENT3X(unit)) { 13079 if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm, 13080 vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word, 13081 _BCM_VXLAN_SOURCE_VP_TYPE_VFI)) { 13082 LOG_ERROR(BSL_LS_BCM_VXLAN, 13083 (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n"))); 13084 } 13085 } 13086 #endif 13087 13088 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, vp); 13089 13090 /* Increment new-port's VP count */ 13091 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port->vxlan_port_id, vp, TRUE); 13092 BCM_IF_ERROR_RETURN(rv); 13093 13094 return (soc_reg_field32_modify(unit, VXLAN_DEFAULT_NETWORK_SVPr, 13095 REG_PORT_ANY, SVPf, vp)); 13096 13097 } 13098 13099 /* 13100 * Function: 13101 * _bcm_td2_vxlan_default_port_delete 13102 * Purpose: 13103 * Delete VXLAN Default port from a VPN 13104 * Parameters: 13105 * unit - (IN) Device Number 13106 * vpn - (IN) VPN instance ID 13107 * vxlan_port_id - (IN) vxlan port information 13108 * Returns: 13109 * BCM_E_XXX 13110 */ 13111 13112 int 13113 _bcm_td2_vxlan_default_port_delete(int unit, bcm_vpn_t vpn, int vp) 13114 { 13115 source_vp_entry_t svp; 13116 int rv = BCM_E_UNAVAIL; 13117 int vfi_index= -1; 13118 bcm_gport_t vxlan_port_id; 13119 13120 if ( vpn != BCM_VXLAN_VPN_INVALID) { 13121 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VXLAN_VPN_TYPE_ELAN, vpn); 13122 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeVxlan)) { 13123 return BCM_E_NOT_FOUND; 13124 } 13125 } 13126 13127 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13128 return BCM_E_NOT_FOUND; 13129 } 13130 13131 /* Set VXLAN port ID */ 13132 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port_id, vp); 13133 13134 /* Clear the SVP and DVP table entries */ 13135 sal_memset(&svp, 0, sizeof(source_vp_entry_t)); 13136 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 13137 if (rv < 0) { 13138 return rv; 13139 } 13140 13141 /* Decrement port's VP count */ 13142 rv = _bcm_td2_vxlan_port_cnt_update(unit, vxlan_port_id, vp, FALSE); 13143 if (rv < 0) { 13144 return rv; 13145 } 13146 13147 /* Free the VP */ 13148 (void) _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp); 13149 13150 /* Reset VXLAN_DEFAULT_NETWORK_SVP */ 13151 BCM_IF_ERROR_RETURN(soc_reg_field32_modify 13152 (unit, VXLAN_DEFAULT_NETWORK_SVPr, REG_PORT_ANY, SVPf, 0)); 13153 13154 return rv; 13155 13156 } 13157 13158 /* 13159 * Function: 13160 * _bcm_td2_vxlan_default_port_get 13161 * Purpose: 13162 * Get VXLAN Default port information 13163 * Parameters: 13164 * unit - (IN) Device Number 13165 * vp - (IN) Source Virtual Port 13166 * vxlan_port - (IN/OUT) vxlan port information 13167 * Returns: 13168 * BCM_E_XXX 13169 */ 13170 int 13171 _bcm_td2_vxlan_default_port_get(int unit, int vp, bcm_vxlan_port_t *vxlan_port) 13172 { 13173 int rv = BCM_E_NONE; 13174 source_vp_entry_t svp; 13175 _bcm_vp_info_t vp_info; 13176 13177 bcm_vxlan_port_t_init(vxlan_port); 13178 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port->vxlan_port_id, vp); 13179 13180 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 13181 vxlan_port->if_class = soc_SOURCE_VPm_field32_get(unit, &svp, CLASS_IDf); 13182 13183 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 13184 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 13185 vxlan_port->flags |= BCM_VXLAN_PORT_NETWORK; 13186 } 13187 13188 vxlan_port->flags |= BCM_VXLAN_PORT_DEFAULT; 13189 13190 return rv; 13191 } 13192 13193 /* 13194 * Function: 13195 * bcm_td2_vxlan_port_add 13196 * Purpose: 13197 * Add VXLAN port to a VPN 13198 * Parameters: 13199 * unit - (IN) Device Number 13200 * vpn - (IN) VPN instance ID 13201 * vxlan_port - (IN/OUT) vxlan_port information (OUT : vxlan_port_id) 13202 * Returns: 13203 * BCM_E_XXX 13204 */ 13205 13206 int 13207 bcm_td2_vxlan_port_add(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 13208 { 13209 int mode=0, rv = BCM_E_PARAM; 13210 uint8 isEline = 0; 13211 13212 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_egress_mode_get(unit, &mode)); 13213 if (!mode) { 13214 LOG_INFO(BSL_LS_BCM_L3, 13215 (BSL_META_U(unit, 13216 "L3 egress mode must be set first\n"))); 13217 return BCM_E_DISABLED; 13218 } 13219 13220 if (vxlan_port->if_class > 0xfff) { 13221 return BCM_E_PARAM; 13222 } 13223 13224 if (vxlan_port->mtu > 0x3fff) { 13225 return BCM_E_PARAM; 13226 } 13227 13228 if (vxlan_port->criteria == BCM_VXLAN_PORT_MATCH_SHARE) { 13229 if (soc_feature(unit, soc_feature_vp_sharing)) { 13230 if (vpn != BCM_VXLAN_VPN_INVALID) { 13231 return BCM_E_PARAM; 13232 } 13233 } else { 13234 return BCM_E_UNAVAIL; 13235 } 13236 } 13237 13238 if (vxlan_port->flags & BCM_VXLAN_PORT_SHARE) { 13239 if (!((vxlan_port->flags & BCM_VXLAN_PORT_EGRESS_TUNNEL) && 13240 (vxlan_port->flags & BCM_VXLAN_PORT_MULTICAST))) { 13241 return BCM_E_PARAM; 13242 } 13243 } 13244 13245 #if defined(BCM_TRIDENT3_SUPPORT) 13246 if ((vxlan_port->flags & BCM_VXLAN_PORT_DEFAULT) && 13247 !SOC_REG_IS_VALID(unit, VXLAN_DEFAULT_NETWORK_SVPr)) { 13248 return BCM_E_UNAVAIL; 13249 } 13250 #endif 13251 13252 if (vpn != BCM_VXLAN_VPN_INVALID) { 13253 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_eline(unit, vpn, &isEline)); 13254 } 13255 13256 if (vxlan_port->flags & BCM_VXLAN_PORT_DEFAULT) { 13257 rv = _bcm_td2_vxlan_default_port_add(unit, vxlan_port); 13258 #if defined(BCM_TRIDENT3_SUPPORT) 13259 if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, DEFAULT_SVP_ENABLEr)) { 13260 rv = soc_reg_field32_modify 13261 (unit, DEFAULT_SVP_ENABLEr, REG_PORT_ANY, 13262 VXLAN_DEFAULT_SVP_ENABLEf, 1); 13263 /* this register is removed in cch after cancun 5.1.8. It is 13264 * no longer needed. The cancun access routine will return 13265 * not found if it doesn't exist in cch. Simply ignore 13266 * this error. 13267 */ 13268 if (rv == SOC_E_NOT_FOUND) { 13269 rv = SOC_E_NONE; 13270 } 13271 } 13272 #endif 13273 return rv; 13274 } 13275 13276 if (isEline) { 13277 if (vxlan_port->flags & BCM_VXLAN_PORT_VPN_BASED) { 13278 /* not support for this flag */ 13279 return BCM_E_PARAM; 13280 } 13281 rv = _bcm_td2_vxlan_eline_port_add(unit, vpn, vxlan_port); 13282 } else { 13283 if (vxlan_port->flags & BCM_VXLAN_PORT_VPN_BASED) { 13284 /* this flag is reused to indicate adding VP-based VFI-VIND mapping */ 13285 rv = _bcm_td2_vxlan_vp_based_vnid_add(unit, vpn, vxlan_port); 13286 } else { 13287 rv = _bcm_td2_vxlan_elan_port_add(unit, vpn, vxlan_port); 13288 } 13289 } 13290 13291 return rv; 13292 } 13293 13294 13295 /* 13296 * Function: 13297 * bcm_td2_vxlan_port_delete 13298 * Purpose: 13299 * Delete VXLAN port from a VPN 13300 * Parameters: 13301 * unit - (IN) Device Number 13302 * vpn - (IN) VPN instance ID 13303 * vxlan_port_id - (IN) vxlan port information 13304 * Returns: 13305 * BCM_E_XXX 13306 */ 13307 13308 int 13309 bcm_td2_vxlan_port_delete(int unit, bcm_vpn_t vpn, bcm_gport_t vxlan_port_id) 13310 { 13311 int vp=0; 13312 int rv = BCM_E_UNAVAIL; 13313 uint32 reg_val=0; 13314 uint8 isEline=0; 13315 uint32 stat_counter_id; 13316 int num_ctr = 0; 13317 13318 if (BCM_GPORT_IS_TRUNK(vxlan_port_id)) { 13319 bcm_trunk_member_t trunk_member; 13320 int port_count = 0; 13321 bcm_trunk_t tid = 0; 13322 int tid_is_vp_lag = FALSE; 13323 if (vpn != BCM_VXLAN_VPN_INVALID) { 13324 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 13325 } 13326 tid = BCM_GPORT_TRUNK_GET(vxlan_port_id); 13327 BCM_IF_ERROR_RETURN( 13328 _bcm_esw_trunk_id_is_vp_lag(unit, tid, &tid_is_vp_lag)); 13329 if (tid_is_vp_lag) { 13330 BCM_IF_ERROR_RETURN( 13331 bcm_td2_vp_lag_get(unit, tid, NULL, 1, 13332 &trunk_member, &port_count)); 13333 if (BCM_GPORT_IS_NIV_PORT(trunk_member.gport) || 13334 BCM_GPORT_IS_EXTENDER_PORT(trunk_member.gport)) { 13335 BCM_IF_ERROR_RETURN( 13336 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tid, &vp)); 13337 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13338 return BCM_E_NOT_FOUND; 13339 } 13340 BCM_IF_ERROR_RETURN(_bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp)); 13341 return _bcm_td2_vxlan_access_niv_pe_reset(unit, vp); 13342 } 13343 } 13344 } 13345 13346 /* Check for Valid Vpn */ 13347 if (vpn != BCM_VXLAN_VPN_INVALID) { 13348 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 13349 } 13350 13351 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port_id); 13352 if (vp == -1) { 13353 return BCM_E_PARAM; 13354 } 13355 13356 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13357 return BCM_E_NOT_FOUND; 13358 } 13359 13360 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vp_is_eline(unit, vp, &isEline)); 13361 13362 /* Check for VXLAN default port */ 13363 if (SOC_REG_IS_VALID(unit, VXLAN_DEFAULT_NETWORK_SVPr)) { 13364 BCM_IF_ERROR_RETURN(READ_VXLAN_DEFAULT_NETWORK_SVPr(unit, ®_val)); 13365 if (vp == soc_reg_field_get(unit, 13366 VXLAN_DEFAULT_NETWORK_SVPr, reg_val, SVPf)) { 13367 rv = _bcm_td2_vxlan_default_port_delete(unit, vpn, vp); 13368 #if defined(BCM_TRIDENT3_SUPPORT) 13369 if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, DEFAULT_SVP_ENABLEr)) { 13370 rv = soc_reg_field32_modify 13371 (unit, DEFAULT_SVP_ENABLEr, REG_PORT_ANY, VXLAN_DEFAULT_SVP_ENABLEf, 0); 13372 if (rv == SOC_E_NOT_FOUND) { 13373 rv = SOC_E_NONE; 13374 } 13375 } 13376 #endif 13377 return rv; 13378 } 13379 } 13380 13381 if (isEline == 0x1 ) { 13382 rv = _bcm_td2_vxlan_eline_port_delete(unit, vpn, vp); 13383 } else if (isEline == 0x0 ) { 13384 uint32 count = 0; 13385 source_vp_entry_t svp; 13386 int vfi = 0; 13387 int vfi_r; 13388 _bcm_vp_info_t vp_info; 13389 13390 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 13391 13392 if ((vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) { 13393 rv = _bcm_td2_vxlan_vp_based_vnid_count(unit, vp, &count); 13394 13395 /* 13396 * if no VFI-VNID mappings attached, then delete vxlan port directly, 13397 * this is to backward-compatible with previous API behavior. 13398 */ 13399 if (count != 0) { 13400 if (vpn == BCM_VXLAN_VPN_INVALID) { 13401 return BCM_E_BUSY; 13402 } 13403 13404 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 13405 vfi_r = soc_SOURCE_VPm_field32_get(unit, &svp, VFIf); 13406 _BCM_VXLAN_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 13407 13408 if (vfi != vfi_r) { 13409 /* user is trying to delete VFI-VNID mappings */ 13410 bcm_vxlan_port_t vxlan_port_r; 13411 13412 bcm_vxlan_port_t_init(&vxlan_port_r); 13413 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_port_get(unit, vpn, vp, &vxlan_port_r)); 13414 rv = _bcm_td2_vxlan_vp_based_vnid_delete(unit, vpn, &vxlan_port_r); 13415 return rv; 13416 } else { 13417 return BCM_E_BUSY; 13418 } 13419 } 13420 } 13421 13422 rv = _bcm_td2_vxlan_elan_port_delete(unit, vpn, vp); 13423 } 13424 13425 if (rv != BCM_E_NONE) { 13426 return rv; 13427 } 13428 13429 if (bcm_esw_vxlan_stat_id_get(unit, vxlan_port_id, BCM_VXLAN_VPN_INVALID, 13430 bcmVxlanOutPackets, &stat_counter_id) == BCM_E_NONE) { 13431 num_ctr++; 13432 } 13433 if (bcm_esw_vxlan_stat_id_get(unit, vxlan_port_id, BCM_VXLAN_VPN_INVALID, 13434 bcmVxlanInPackets, &stat_counter_id) == BCM_E_NONE) { 13435 num_ctr++; 13436 } 13437 13438 if (num_ctr != 0) { 13439 BCM_IF_ERROR_RETURN( 13440 bcm_esw_vxlan_stat_detach(unit, vxlan_port_id, BCM_VXLAN_VPN_INVALID)); 13441 } 13442 13443 return rv; 13444 } 13445 13446 /* 13447 * Function: 13448 * bcm_td2_vxlan_port_delete_all 13449 * Purpose: 13450 * Delete all VXLAN ports from a VPN 13451 * Parameters: 13452 * unit - (IN) Device Number 13453 * vpn - (IN) VPN instance ID 13454 * Returns: 13455 * BCM_E_XXX 13456 */ 13457 int 13458 bcm_td2_vxlan_port_delete_all(int unit, bcm_vpn_t vpn) 13459 { 13460 int rv = BCM_E_NONE; 13461 int vfi_index=0; 13462 int vp1 = 0, vp2 = 0; 13463 uint8 isEline = 0; 13464 bcm_gport_t vxlan_port_id; 13465 uint32 reg_val=0; 13466 uint32 vp=0; 13467 13468 if (vpn != BCM_VXLAN_VPN_INVALID) { 13469 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 13470 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_eline(unit, vpn, &isEline)); 13471 } else { 13472 vfi_index = _BCM_VXLAN_VFI_INVALID; 13473 } 13474 13475 if (isEline == 0x1 ) { 13476 /* ---- Read in current table values for VP1 and VP2 ----- */ 13477 (void) _bcm_td2_vxlan_eline_vp_map_get (unit, vfi_index, &vp1, &vp2); 13478 if (vp1 != 0) { 13479 rv = _bcm_td2_vxlan_eline_port_delete(unit, vpn, vp1); 13480 BCM_IF_ERROR_RETURN(rv); 13481 } 13482 if (vp2 != 0) { 13483 rv = _bcm_td2_vxlan_eline_port_delete(unit, vpn, vp2); 13484 BCM_IF_ERROR_RETURN(rv); 13485 } 13486 } else if (isEline == 0x0 ) { 13487 uint32 num_vp = 0, entry_type = 0; 13488 source_vp_entry_t svp; 13489 if (SOC_REG_IS_VALID(unit, VXLAN_DEFAULT_NETWORK_SVPr)) { 13490 BCM_IF_ERROR_RETURN(READ_VXLAN_DEFAULT_NETWORK_SVPr(unit, ®_val)); 13491 vp = soc_reg_field_get(unit, VXLAN_DEFAULT_NETWORK_SVPr, reg_val, SVPf); 13492 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13493 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_default_port_delete(unit, vpn, vp)); 13494 #if defined(BCM_TRIDENT3_SUPPORT) 13495 if (SOC_REG_IS_VALID(unit, DEFAULT_SVP_ENABLEr)) { 13496 rv = soc_reg_field32_modify (unit, DEFAULT_SVP_ENABLEr, 13497 REG_PORT_ANY, VXLAN_DEFAULT_SVP_ENABLEf, 0); 13498 if (SOC_FAILURE(rv)) { 13499 if (rv == SOC_E_NOT_FOUND) { 13500 rv = SOC_E_NONE; 13501 } else { 13502 return rv; 13503 } 13504 } 13505 } 13506 #endif 13507 } 13508 } 13509 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 13510 SHR_BIT_ITER(VIRTUAL_INFO(unit)->vxlan_vp_bitmap, num_vp, vp) { 13511 13512 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 13513 entry_type = soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf); 13514 if ((vfi_index == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf) && 13515 entry_type == _BCM_VXLAN_SOURCE_VP_TYPE_VFI) 13516 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 13517 || SHR_BITGET(VIRTUAL_INFO(unit)->vp_shared_vp_bitmap, vp) 13518 #endif 13519 ) { 13520 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 13521 bcm_trunk_t tid = 0; 13522 bcm_trunk_member_t trunk_member; 13523 int port_count = 0; 13524 BCM_IF_ERROR_RETURN( 13525 _bcm_esw_trunk_vp_lag_vp_to_tid(unit, vp, &tid)); 13526 BCM_IF_ERROR_RETURN( 13527 bcm_td2_vp_lag_get(unit, tid, NULL, 1, 13528 &trunk_member, &port_count)); 13529 if (BCM_GPORT_IS_NIV_PORT(trunk_member.gport) || 13530 BCM_GPORT_IS_EXTENDER_PORT(trunk_member.gport)) { 13531 BCM_IF_ERROR_RETURN( 13532 _bcm_vp_free(unit, _bcmVpTypeVxlan, 1, vp)); 13533 BCM_IF_ERROR_RETURN( 13534 _bcm_td2_vxlan_access_niv_pe_reset(unit, vp)); 13535 continue; 13536 } 13537 } 13538 /* Set VXLAN port ID */ 13539 BCM_GPORT_VXLAN_PORT_ID_SET(vxlan_port_id, vp); 13540 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_port_delete(unit, vpn, vxlan_port_id)); 13541 } 13542 } 13543 } 13544 return rv; 13545 } 13546 13547 /* 13548 * Function: 13549 * bcm_td2_vxlan_port_get 13550 * Purpose: 13551 * Get an VXLAN port from a VPN 13552 * Parameters: 13553 * unit - (IN) Device Number 13554 * vpn - (IN) VPN instance ID 13555 * vxlan_port - (IN/OUT) VXLAN port information 13556 */ 13557 int 13558 bcm_td2_vxlan_port_get(int unit, bcm_vpn_t vpn, bcm_vxlan_port_t *vxlan_port) 13559 { 13560 int vp=0; 13561 int rv = BCM_E_NONE; 13562 uint32 reg_val = 0; 13563 int default_vp = -1; 13564 if (BCM_GPORT_IS_TRUNK(vxlan_port->vxlan_port_id)) { 13565 bcm_trunk_member_t trunk_member; 13566 int port_count = 0; 13567 bcm_trunk_t tid = 0; 13568 int tid_is_vp_lag = FALSE; 13569 if (vpn != BCM_VXLAN_VPN_INVALID) { 13570 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 13571 } 13572 tid = BCM_GPORT_TRUNK_GET(vxlan_port->vxlan_port_id); 13573 BCM_IF_ERROR_RETURN( 13574 _bcm_esw_trunk_id_is_vp_lag(unit, tid, &tid_is_vp_lag)); 13575 if (tid_is_vp_lag) { 13576 BCM_IF_ERROR_RETURN( 13577 bcm_td2_vp_lag_get(unit, tid, NULL, 1, 13578 &trunk_member, &port_count)); 13579 if (BCM_GPORT_IS_NIV_PORT(trunk_member.gport) || 13580 BCM_GPORT_IS_EXTENDER_PORT(trunk_member.gport)) { 13581 BCM_IF_ERROR_RETURN( 13582 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tid, &vp)); 13583 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13584 return BCM_E_NOT_FOUND; 13585 } 13586 return BCM_E_NONE; 13587 } 13588 } 13589 } 13590 13591 if (SOC_REG_IS_VALID(unit, VXLAN_DEFAULT_NETWORK_SVPr)) { 13592 BCM_IF_ERROR_RETURN(READ_VXLAN_DEFAULT_NETWORK_SVPr(unit, ®_val)); 13593 default_vp = soc_reg_field_get(unit, 13594 VXLAN_DEFAULT_NETWORK_SVPr, reg_val, SVPf); 13595 } 13596 13597 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port->vxlan_port_id); 13598 if (vp == -1) { 13599 return BCM_E_PARAM; 13600 } 13601 13602 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13603 return BCM_E_NOT_FOUND; 13604 } 13605 13606 if (vpn != BCM_VXLAN_VPN_INVALID) { 13607 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, vpn)); 13608 } 13609 13610 if (vp == default_vp) { 13611 rv = _bcm_td2_vxlan_default_port_get(unit, vp, vxlan_port); 13612 } else { 13613 if (vxlan_port->flags & BCM_VXLAN_PORT_VPN_BASED) { 13614 rv = _bcm_td2_vxlan_vp_based_vnid_get(unit, vpn, vxlan_port); 13615 } else { 13616 rv = _bcm_td2_vxlan_port_get(unit, vpn, vp, vxlan_port); 13617 } 13618 } 13619 13620 return rv; 13621 } 13622 13623 /* 13624 * Function: 13625 * bcm_td2_vxlan_port_get_all 13626 * Purpose: 13627 * Get all VXLAN ports from a VPN 13628 * Parameters: 13629 * unit - (IN) Device Number 13630 * vpn - (IN) VPN instance ID 13631 * port_max - (IN) Maximum number of interfaces in array 13632 * port_array - (OUT) Array of VXLAN ports 13633 * port_count - (OUT) Number of interfaces returned in array 13634 */ 13635 int 13636 bcm_td2_vxlan_port_get_all(int unit, bcm_vpn_t vpn, int port_max, 13637 bcm_vxlan_port_t *port_array, int *port_count) 13638 { 13639 int vp, rv = BCM_E_NONE; 13640 int vfi_index=-1; 13641 int vp1 = 0, vp2 = 0; 13642 uint8 isEline = 0; 13643 SHR_BITDCL *share_vp_bitmap = NULL; 13644 13645 if (vpn != BCM_VXLAN_VPN_INVALID) { 13646 _BCM_VXLAN_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 13647 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_eline(unit, vpn, &isEline)); 13648 } else { 13649 vfi_index = _BCM_VXLAN_VFI_INVALID; 13650 } 13651 13652 *port_count = 0; 13653 13654 if (isEline == 0x1 ) { 13655 /* ---- Read in current table values for VP1 and VP2 ----- */ 13656 (void) _bcm_td2_vxlan_eline_vp_map_get (unit, vfi_index, &vp1, &vp2); 13657 vp = vp1; 13658 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13659 if (0 == port_max) { 13660 (*port_count)++; 13661 13662 } else if (*port_count < port_max) { 13663 rv = _bcm_td2_vxlan_port_get(unit, vpn, vp, 13664 &port_array[*port_count]); 13665 if (rv < 0) { 13666 return rv; 13667 } 13668 (*port_count)++; 13669 } 13670 } 13671 13672 vp = vp2; 13673 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13674 if (0 == port_max) { 13675 (*port_count)++; 13676 13677 } else if (*port_count < port_max) { 13678 rv = _bcm_td2_vxlan_port_get(unit, vpn, vp, 13679 &port_array[*port_count]); 13680 if (rv < 0) { 13681 return rv; 13682 } 13683 (*port_count)++; 13684 } 13685 } 13686 } else if (isEline == 0x0 ) { 13687 uint32 entry_type = 0; 13688 source_vp_entry_t svp; 13689 int num_vp = soc_mem_index_count(unit, SOURCE_VPm); 13690 13691 share_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "sharr_vp_bitmap"); 13692 if (share_vp_bitmap == NULL) { 13693 return BCM_E_MEMORY; 13694 } 13695 sal_memset(share_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 13696 13697 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 13698 if (soc_feature(unit, soc_feature_vp_sharing)) { 13699 rv = bcm_td2p_share_vp_get(unit, vpn, share_vp_bitmap); 13700 _BCM_VXLAN_CLEANUP(rv) 13701 } 13702 #endif 13703 13704 SHR_BIT_ITER(VIRTUAL_INFO(unit)->vxlan_vp_bitmap, num_vp, vp) { 13705 13706 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 13707 _BCM_VXLAN_CLEANUP(rv) 13708 entry_type = soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf); 13709 13710 if ((vfi_index == soc_SOURCE_VPm_field32_get(unit, &svp, VFIf) && 13711 entry_type == _BCM_VXLAN_SOURCE_VP_TYPE_VFI) 13712 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 13713 || SHR_BITGET(share_vp_bitmap, vp) 13714 #endif 13715 ) { 13716 13717 /* Check if number of ports is requested */ 13718 if (0 == port_max) { 13719 (*port_count)++; 13720 continue; 13721 } else if (*port_count == port_max) { 13722 break; 13723 } 13724 13725 rv = _bcm_td2_vxlan_port_get(unit, 13726 vpn, vp, &port_array[*port_count]); 13727 _BCM_VXLAN_CLEANUP(rv) 13728 13729 (*port_count)++; 13730 } 13731 } 13732 sal_free(share_vp_bitmap); 13733 } 13734 13735 return BCM_E_NONE; 13736 cleanup: 13737 sal_free(share_vp_bitmap); 13738 return rv; 13739 } 13740 13741 /* 13742 * Function: 13743 * bcm_td2_vxlan_port_learn_set 13744 * Purpose: 13745 * Set the CML bits for a vxlan port. 13746 * Returns: 13747 * BCM_E_XXX 13748 */ 13749 int 13750 bcm_td2_vxlan_port_learn_set(int unit, bcm_gport_t vxlan_port_id, 13751 uint32 flags) 13752 { 13753 int vp, cml = 0, rv = BCM_E_NONE, entry_type; 13754 source_vp_entry_t svp; 13755 13756 rv = _bcm_vxlan_check_init(unit); 13757 13758 if (rv != BCM_E_NONE){ 13759 return rv; 13760 } 13761 13762 cml = 0; 13763 if (!(flags & BCM_PORT_LEARN_FWD)) { 13764 cml |= (1 << 0); 13765 } 13766 if (flags & BCM_PORT_LEARN_CPU) { 13767 cml |= (1 << 1); 13768 } 13769 if (flags & BCM_PORT_LEARN_PENDING) { 13770 cml |= (1 << 2); 13771 } 13772 if (flags & BCM_PORT_LEARN_ARL) { 13773 cml |= (1 << 3); 13774 } 13775 13776 /* Get the VP index from the gport */ 13777 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port_id); 13778 13779 MEM_LOCK(unit, SOURCE_VPm); 13780 /* Be sure the entry is used and is set for VxLAN */ 13781 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13782 MEM_UNLOCK(unit, SOURCE_VPm); 13783 return BCM_E_NOT_FOUND; 13784 } 13785 /* coverity[negative_returns] */ 13786 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 13787 if (rv < 0) { 13788 MEM_UNLOCK(unit, SOURCE_VPm); 13789 return rv; 13790 } 13791 13792 /* Ensure that the entry_type is 1 for VxLAN*/ 13793 entry_type = soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf); 13794 if (entry_type != 1){ 13795 MEM_UNLOCK(unit, SOURCE_VPm); 13796 return BCM_E_NOT_FOUND; 13797 } 13798 13799 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_MOVEf, cml); 13800 soc_SOURCE_VPm_field32_set(unit, &svp, CML_FLAGS_NEWf, cml); 13801 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 13802 MEM_UNLOCK(unit, SOURCE_VPm); 13803 return rv; 13804 } 13805 13806 /* 13807 * Function: 13808 * bcm_td2_vxlan_port_learn_get 13809 * Purpose: 13810 * Get the CML bits for a VxLAN port 13811 * Returns: 13812 * BCM_E_XXX 13813 */ 13814 int 13815 bcm_td2_vxlan_port_learn_get(int unit, bcm_gport_t vxlan_port_id, 13816 uint32 *flags) 13817 { 13818 int rv, vp, cml = 0, entry_type; 13819 source_vp_entry_t svp; 13820 13821 rv = _bcm_vxlan_check_init(unit); 13822 13823 if (rv != BCM_E_NONE){ 13824 return rv; 13825 } 13826 13827 /* Get the VP index from the gport */ 13828 vp = BCM_GPORT_VXLAN_PORT_ID_GET(vxlan_port_id); 13829 if (vp == -1) { 13830 return BCM_E_PARAM; 13831 } 13832 13833 /* Be sure the entry is used and is set for VxLAN */ 13834 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 13835 return BCM_E_NOT_FOUND; 13836 } 13837 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 13838 if (rv < 0) { 13839 return rv; 13840 } 13841 13842 13843 /* Ensure that the entry_type is 1 for VxLAN*/ 13844 entry_type = soc_SOURCE_VPm_field32_get(unit, &svp, ENTRY_TYPEf); 13845 if (entry_type != 1){ 13846 return BCM_E_NOT_FOUND; 13847 } 13848 13849 cml = soc_SOURCE_VPm_field32_get(unit, &svp, CML_FLAGS_NEWf); 13850 13851 *flags = 0; 13852 if (!(cml & (1 << 0))) { 13853 *flags |= BCM_PORT_LEARN_FWD; 13854 } 13855 if (cml & (1 << 1)) { 13856 *flags |= BCM_PORT_LEARN_CPU; 13857 } 13858 if (cml & (1 << 2)) { 13859 *flags |= BCM_PORT_LEARN_PENDING; 13860 } 13861 if (cml & (1 << 3)) { 13862 *flags |= BCM_PORT_LEARN_ARL; 13863 } 13864 return BCM_E_NONE; 13865 } 13866 13867 /* 13868 * Function: 13869 * bcm_td2_vxlan_trunk_member_add 13870 * Purpose: 13871 * Activate Trunk Port-membership from 13872 * EGR_PORT_TO_NHI_MAPPING 13873 * Parameters: 13874 * unit - (IN) Device Number 13875 * tgid - (IN) Trunk Group ID 13876 * trunk_member_count - (IN) Count of Trunk members to be added 13877 * trunk_member_array - (IN) Trunk member gports to be added 13878 */ 13879 int 13880 bcm_td2_vxlan_trunk_member_add(int unit, bcm_trunk_t trunk_id, 13881 int trunk_member_count, bcm_port_t *trunk_member_array) 13882 { 13883 int idx = 0; 13884 int rv = BCM_E_NONE; 13885 uint32 reg_val = 0; 13886 int nh_index = 0, old_nh_index = -1; 13887 bcm_l3_egress_t egr; 13888 int gport = 0; 13889 _bcm_port_info_t *port_info; 13890 int local_member = 0; 13891 uint32 port_flags; 13892 13893 rv = _bcm_trunk_id_validate(unit, trunk_id); 13894 if (BCM_FAILURE(rv)) { 13895 return BCM_E_PORT; 13896 } 13897 13898 /* Obtain nh_index for trunk_id */ 13899 rv = _bcm_xgs3_trunk_nh_store_get(unit, trunk_id, &nh_index); 13900 if (nh_index == 0) { 13901 return rv; 13902 } 13903 bcm_l3_egress_t_init(&egr); 13904 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_egress_get(unit, &egr, nh_index)); 13905 13906 if (egr.flags & BCM_L3_VXLAN_ONLY) { 13907 for (idx = 0; idx < trunk_member_count; idx++) { 13908 rv = bcm_esw_port_local_get(unit, trunk_member_array[idx], &local_member); 13909 if (SOC_REG_IS_VALID(unit, EGR_PORT_TO_NHI_MAPPINGr)) { 13910 /* Only support trunk local ports */ 13911 if(BCM_FAILURE(rv)) { 13912 continue; 13913 } 13914 BCM_IF_ERROR_RETURN( 13915 READ_EGR_PORT_TO_NHI_MAPPINGr(unit, local_member, ®_val)); 13916 old_nh_index = soc_reg_field_get(unit, EGR_PORT_TO_NHI_MAPPINGr, reg_val, NEXT_HOP_INDEXf); 13917 if (!old_nh_index) { 13918 /* Set EGR_PORT_TO_NHI_MAPPING */ 13919 BCM_IF_ERROR_RETURN( 13920 soc_reg_field32_modify(unit, EGR_PORT_TO_NHI_MAPPINGr, 13921 local_member, NEXT_HOP_INDEXf, nh_index)); 13922 } 13923 } else { 13924 /* Support trunk remote gports */ 13925 gport = trunk_member_array[idx]; 13926 BCM_IF_ERROR_RETURN( 13927 _bcm_trx_gport_to_nhi_get(unit, gport, &old_nh_index)); 13928 13929 if (!old_nh_index) { 13930 BCM_IF_ERROR_RETURN( 13931 _bcm_trx_gport_to_nhi_set(unit, gport, nh_index)); 13932 } 13933 } 13934 13935 /* Only count the number of VPs on local physical ports */ 13936 if(BCM_SUCCESS(rv)) { 13937 _bcm_port_info_access(unit, local_member, &port_info); 13938 port_info->vp_count++; 13939 BCM_IF_ERROR_RETURN( 13940 bcm_esw_port_vlan_member_get( 13941 unit, local_member, &port_flags)); 13942 BCM_IF_ERROR_RETURN( 13943 bcm_esw_port_vlan_member_set( 13944 unit, local_member, port_flags)); 13945 } 13946 } 13947 } 13948 return BCM_E_NONE; 13949 } 13950 13951 /* 13952 * Function: 13953 * bcm_td2_vxlan_trunk_member_delete 13954 * Purpose: 13955 * Clear Trunk Port-membership from 13956 * EGR_PORT_TO_NHI_MAPPING and EGR_DGPP_TO_NHI 13957 * Parameters: 13958 * unit - (IN) Device Number 13959 * tgid - (IN) Trunk Group ID 13960 * trunk_member_count - (IN) Count of Trunk members to be deleted 13961 * trunk_member_array - (IN) Trunk member gports to be deleted 13962 */ 13963 int 13964 bcm_td2_vxlan_trunk_member_delete(int unit, bcm_trunk_t trunk_id, 13965 int trunk_member_count, bcm_port_t *trunk_member_array) 13966 { 13967 int idx = 0; 13968 int rv = BCM_E_NONE, rv2 = BCM_E_NONE; 13969 uint32 reg_val = 0; 13970 int old_nh_index = 0; 13971 int nh_index = 0; 13972 bcm_l3_egress_t egr; 13973 int gport = 0; 13974 _bcm_port_info_t *port_info; 13975 int local_member = 0; 13976 uint32 port_flags; 13977 13978 rv = _bcm_trunk_id_validate(unit, trunk_id); 13979 if (BCM_FAILURE(rv)) { 13980 return BCM_E_PORT; 13981 } 13982 13983 /* Obtain nh_index for trunk_id */ 13984 rv = _bcm_xgs3_trunk_nh_store_get(unit, trunk_id, &nh_index); 13985 if (nh_index == 0) { 13986 for (idx = 0; idx < trunk_member_count; idx++) { 13987 rv2 = bcm_esw_port_local_get(unit, trunk_member_array[idx], &local_member); 13988 /* Only support trunk local ports for trunk match */ 13989 if(BCM_FAILURE(rv2)) { 13990 continue; 13991 } 13992 rv += _bcm_td2_vxlan_trunk_table_reset(unit, local_member); 13993 } 13994 if (BCM_FAILURE(rv)) { 13995 return rv; 13996 } 13997 } else { 13998 bcm_l3_egress_t_init(&egr); 13999 BCM_IF_ERROR_RETURN(bcm_td2_vxlan_egress_get(unit, &egr, nh_index)); 14000 14001 if (egr.flags & BCM_L3_VXLAN_ONLY) { 14002 for (idx = 0; idx < trunk_member_count; idx++) { 14003 rv2 = bcm_esw_port_local_get(unit, trunk_member_array[idx], &local_member); 14004 if (SOC_REG_IS_VALID(unit, EGR_PORT_TO_NHI_MAPPINGr)) { 14005 /* Only support trunk local ports */ 14006 if(BCM_FAILURE(rv2)) { 14007 continue; 14008 } 14009 BCM_IF_ERROR_RETURN( 14010 READ_EGR_PORT_TO_NHI_MAPPINGr(unit, local_member, ®_val)); 14011 old_nh_index = soc_reg_field_get(unit, EGR_PORT_TO_NHI_MAPPINGr, reg_val, NEXT_HOP_INDEXf); 14012 if (0 != old_nh_index) { 14013 /* Reset EGR_PORT_TO_NHI_MAPPING */ 14014 rv = soc_reg_field32_modify(unit, EGR_PORT_TO_NHI_MAPPINGr, 14015 local_member, NEXT_HOP_INDEXf, 0x0); 14016 if (BCM_FAILURE(rv)) { 14017 return rv; 14018 } 14019 } 14020 } else { 14021 /* Support trunk remote gports */ 14022 gport = trunk_member_array[idx]; 14023 BCM_IF_ERROR_RETURN( 14024 _bcm_trx_gport_to_nhi_get(unit, gport, &old_nh_index)); 14025 14026 if (0 != old_nh_index) { 14027 BCM_IF_ERROR_RETURN( 14028 _bcm_trx_gport_to_nhi_set(unit, gport, 0)); 14029 } 14030 } 14031 14032 /* Only count the number of VPs on local physical ports */ 14033 if(BCM_SUCCESS(rv2)) { 14034 _bcm_port_info_access(unit, local_member, &port_info); 14035 port_info->vp_count--; 14036 BCM_IF_ERROR_RETURN( 14037 bcm_esw_port_vlan_member_get( 14038 unit, local_member, &port_flags)); 14039 BCM_IF_ERROR_RETURN( 14040 bcm_esw_port_vlan_member_set( 14041 unit, local_member, port_flags)); 14042 } 14043 } 14044 } 14045 } 14046 return rv; 14047 } 14048 14049 /* 14050 * Function: 14051 * _bcm_td2_vxlan_match_vp_replace 14052 * Purpose: 14053 * Replace VP value in VXLAN VP's match entry. 14054 * Parameters: 14055 * unit - (IN) SOC unit number. 14056 * vp - (IN) VXLAN VP whose match entry is being replaced. 14057 * new_vp - (IN) New VP value. 14058 * old_vp - (OUT) Old VP value. 14059 * Returns: 14060 * BCM_X_XXX 14061 */ 14062 STATIC int 14063 _bcm_td2_vxlan_match_vp_replace(int unit, int vp, int new_vp, int *old_vp) 14064 { 14065 int rv = BCM_E_NONE; 14066 soc_mem_t mem; 14067 int key_type = bcmVlanTranslateKeyInvalid; 14068 uint32 svp_valid, tunnel_index, tunnel_sip; 14069 int entry_index; 14070 int port, my_modid, stm_idx, i; 14071 int local_port[SOC_MAX_NUM_PORTS]; 14072 int local_port_count = 0; 14073 uint32 vent[SOC_MAX_MEM_WORDS]; 14074 source_trunk_map_table_entry_t stm_entry; 14075 uint32 ment[SOC_MAX_MEM_WORDS]; 14076 _bcm_vxlan_match_port_info_t *mkey = NULL; 14077 int d = 0; 14078 14079 mkey = &(VXLAN_INFO(unit)->match_key[vp]); 14080 14081 #define _BCM_VLXLT_KTYPE_ASSIGN(_ktype, _k) \ 14082 do { \ 14083 if (_ktype == bcmVlanTranslateKeyInvalid) { \ 14084 _ktype = _k; \ 14085 } \ 14086 } while(0) 14087 14088 switch(mkey->flags) { 14089 case _BCM_VXLAN_PORT_MATCH_TYPE_VLAN: 14090 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortOuter); 14091 /* Fall through */ 14092 case _BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN: 14093 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortInner); 14094 /* Fall through */ 14095 case _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED: 14096 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortDouble); 14097 /* Fall through */ 14098 case _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI: 14099 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortOuterPri); 14100 /* Construct lookup key */ 14101 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 14102 14103 #if defined(BCM_TRIDENT3_SUPPORT) 14104 if (soc_feature(unit, soc_feature_base_valid)) { 14105 mem = VLAN_XLATE_1_DOUBLEm; 14106 14107 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 14108 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 14109 } else 14110 #endif 14111 { 14112 mem = VLAN_XLATEm; 14113 14114 soc_mem_field32_set(unit, mem, vent, VALIDf, 0x1); 14115 } 14116 14117 if (mkey->modid != -1) { 14118 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port); 14119 } else { 14120 BCM_GPORT_TRUNK_SET(port, mkey->trunk_id); 14121 } 14122 14123 BCM_IF_ERROR_RETURN( 14124 _bcm_trx_vlan_translate_entry_assemble(unit, &vent, 14125 port, key_type, 14126 mkey->match_inner_vlan, 14127 mkey->match_vlan)); 14128 soc_mem_lock(unit, mem); 14129 /* Lookup existing entry */ 14130 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, 14131 &entry_index, &vent, &vent, 0); 14132 if (BCM_FAILURE(rv)) { 14133 soc_mem_unlock(unit, mem); 14134 return rv; 14135 } 14136 /* Replace entry's VP value */ 14137 *old_vp = soc_mem_field32_get(unit, mem, vent, SOURCE_VPf); 14138 soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, new_vp); 14139 14140 /* Insert new entry */ 14141 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, &vent); 14142 soc_mem_unlock(unit, mem); 14143 if (rv == SOC_E_EXISTS) { 14144 rv = BCM_E_NONE; 14145 } else { 14146 return BCM_E_INTERNAL; 14147 } 14148 break; 14149 case _BCM_VXLAN_PORT_MATCH_TYPE_PORT: 14150 mem = SOURCE_TRUNK_MAP_TABLEm; 14151 14152 soc_mem_lock(unit, mem); 14153 14154 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 14155 mkey->index, &stm_entry); 14156 if (BCM_FAILURE(rv)) { 14157 soc_mem_unlock(unit, mem); 14158 return rv; 14159 } 14160 /* Resolve SVP Mode */ 14161 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 14162 svp_valid = soc_mem_field32_get(unit, mem, 14163 &stm_entry, SVP_VALIDf); 14164 if (svp_valid == 0) { 14165 soc_mem_unlock(unit, mem); 14166 return BCM_E_INTERNAL; 14167 } 14168 } 14169 *old_vp = soc_mem_field32_get(unit, mem, 14170 &stm_entry, SOURCE_VPf); 14171 rv = soc_mem_field32_modify(unit, mem, mkey->index, 14172 SOURCE_VPf, new_vp); 14173 14174 soc_mem_unlock(unit, mem); 14175 break; 14176 case _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK: 14177 mem = SOURCE_TRUNK_MAP_TABLEm; 14178 14179 /* Get module id for unit. */ 14180 BCM_IF_ERROR_RETURN( 14181 bcm_esw_stk_my_modid_get(unit, &my_modid)); 14182 14183 BCM_IF_ERROR_RETURN( 14184 _bcm_esw_trunk_local_members_get(unit, mkey->trunk_id, 14185 SOC_MAX_NUM_PORTS, 14186 local_port, 14187 &local_port_count)); 14188 soc_mem_lock(unit, mem); 14189 14190 for (i = 0; i < local_port_count; i++) { 14191 /* Get index to source trunk map table */ 14192 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 14193 local_port[i], 14194 &stm_idx); 14195 if (BCM_FAILURE(rv)) { 14196 soc_mem_unlock(unit, mem); 14197 return rv; 14198 } 14199 14200 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 14201 stm_idx, &stm_entry); 14202 if (BCM_FAILURE(rv)) { 14203 soc_mem_unlock(unit, mem); 14204 return rv; 14205 } 14206 14207 /* Resolve SVP Mode */ 14208 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 14209 svp_valid = soc_mem_field32_get(unit, mem, 14210 &stm_entry, SVP_VALIDf); 14211 if (svp_valid == 0) { 14212 soc_mem_unlock(unit, mem); 14213 return BCM_E_INTERNAL; 14214 } 14215 } 14216 *old_vp = soc_mem_field32_get(unit, mem, 14217 &stm_entry, SOURCE_VPf); 14218 14219 rv = soc_mem_field32_modify(unit, mem, stm_idx, 14220 SOURCE_VPf, new_vp); 14221 if (BCM_FAILURE(rv)) { 14222 soc_mem_unlock(unit, mem); 14223 return rv; 14224 } 14225 } 14226 14227 soc_mem_unlock(unit, mem); 14228 break; 14229 case _BCM_VXLAN_PORT_MATCH_TYPE_VNID: 14230 tunnel_index = mkey->match_tunnel_index; 14231 tunnel_sip = VXLAN_INFO(unit)->vxlan_tunnel_term[tunnel_index].sip; 14232 14233 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 14234 mem = MPLS_ENTRYm; 14235 #if defined(BCM_TRIDENT3_SUPPORT) 14236 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 14237 mem = MPLS_ENTRY_SINGLEm; 14238 d = 1; 14239 soc_mem_field32_set(unit, mem, &ment, BASE_VALIDf, 1); 14240 soc_mem_field32_set(unit, mem, &ment, 14241 DATA_TYPEf, _BCM_VXLAN_FLEX_DATA_TYPE_IPV4_SIP); 14242 } else 14243 #endif 14244 { 14245 soc_mem_field32_set(unit, mem, &ment, VALIDf, 1); 14246 } 14247 14248 soc_mem_lock(unit, mem); 14249 soc_mem_field32_set(unit, mem, &ment, BCM_VXLAN_SIP_FIELD(d, SIPf), tunnel_sip); 14250 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 14251 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 14252 soc_mem_field32_set(unit, mem, &ment, VXLAN_SIP__OVIDf, 14253 VXLAN_INFO(unit)->vxlan_tunnel_term[tunnel_index].vlan); 14254 } 14255 #endif 14256 soc_mem_field32_set(unit, mem, &ment, 14257 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL); 14258 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, 14259 &entry_index, &ment, &ment, 0); 14260 14261 if (rv == BCM_E_NOT_FOUND) { 14262 rv = BCM_E_PARAM; 14263 } 14264 14265 if (BCM_FAILURE(rv)) { 14266 soc_mem_unlock(unit, mem); 14267 return rv; 14268 } 14269 14270 /* Replace entry's VP value */ 14271 *old_vp = soc_mem_field32_get(unit, mem, &ment, BCM_VXLAN_SIP_FIELD(d, SVPf)); 14272 soc_mem_field32_set(unit, mem, &ment, BCM_VXLAN_SIP_FIELD(d, SVPf), new_vp); 14273 /* Insert new entry */ 14274 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, ment); 14275 14276 soc_mem_unlock(unit, mem); 14277 14278 if (rv == SOC_E_EXISTS) { 14279 rv = BCM_E_NONE; 14280 } else { 14281 return BCM_E_INTERNAL; 14282 } 14283 break; 14284 case _BCM_VXLAN_PORT_MATCH_TYPE_NONE: 14285 *old_vp = vp; 14286 break; 14287 default: 14288 return BCM_E_PARAM; 14289 } 14290 14291 #undef _BCM_VLXLT_KTYPE_ASSIGN 14292 14293 return rv; 14294 } 14295 14296 /* 14297 * Function: 14298 * bcm_td2_vxlan_port_source_vp_lag_set 14299 * Purpose: 14300 * Set source VP LAG for a VXLAN virtual port. 14301 * Parameters: 14302 * unit - (IN) SOC unit number. 14303 * gport - (IN) VXLAN virtual port GPORT ID. 14304 * vp_lag_vp - (IN) VP representing the VP LAG. 14305 * Returns: 14306 * BCM_X_XXX 14307 */ 14308 int 14309 bcm_td2_vxlan_port_source_vp_lag_set(int unit, bcm_gport_t gport, 14310 int vp_lag_vp) 14311 { 14312 int vp, old_vp; 14313 14314 if (!BCM_GPORT_IS_VXLAN_PORT(gport)) { 14315 return BCM_E_PARAM; 14316 } 14317 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 14318 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 14319 return BCM_E_PARAM; 14320 } 14321 14322 /* Set source VP LAG by replacing the SVP field in VXLAN VP's 14323 * match entry with the VP value representing the VP LAG. 14324 */ 14325 BCM_IF_ERROR_RETURN 14326 (_bcm_td2_vxlan_match_vp_replace(unit, vp, vp_lag_vp, &old_vp)); 14327 14328 return BCM_E_NONE; 14329 } 14330 14331 /* 14332 * Function: 14333 * bcm_td2_vxlan_port_source_vp_lag_clear 14334 * Purpose: 14335 * Clear source VP LAG for a VXLAN virtual port. 14336 * Parameters: 14337 * unit - (IN) SOC unit number. 14338 * gport - (IN) VXLAN virtual port GPORT ID. 14339 * vp_lag_vp - (IN) VP representing the VP LAG. 14340 * Returns: 14341 * BCM_X_XXX 14342 */ 14343 int 14344 bcm_td2_vxlan_port_source_vp_lag_clear(int unit, bcm_gport_t gport, 14345 int vp_lag_vp) 14346 { 14347 int vp, old_vp; 14348 14349 if (!BCM_GPORT_IS_VXLAN_PORT(gport)) { 14350 return BCM_E_PARAM; 14351 } 14352 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 14353 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 14354 return BCM_E_PARAM; 14355 } 14356 14357 /* Clear source VP LAG by replacing the SVP field in VXLAN VP's 14358 * match entry with the VP value. 14359 */ 14360 BCM_IF_ERROR_RETURN 14361 (_bcm_td2_vxlan_match_vp_replace(unit, vp, vp, &old_vp)); 14362 14363 return BCM_E_NONE; 14364 } 14365 14366 /* 14367 * Function: 14368 * bcm_td2_vxlan_port_source_vp_lag_get 14369 * Purpose: 14370 * Get source VP LAG for a VXLAN virtual port. 14371 * Parameters: 14372 * unit - (IN) SOC unit number. 14373 * gport - (IN) VXLAN virtual port GPORT ID. 14374 * vp_lag_vp - (OUT) VP representing the VP LAG. 14375 * Returns: 14376 * BCM_X_XXX 14377 */ 14378 int 14379 bcm_td2_vxlan_port_source_vp_lag_get(int unit, bcm_gport_t gport, 14380 int *vp_lag_vp) 14381 { 14382 int rv = BCM_E_NONE; 14383 soc_mem_t mem; 14384 int key_type = bcmVlanTranslateKeyInvalid; 14385 bcm_gport_t vp; 14386 uint32 svp_valid, tunnel_index, tunnel_sip; 14387 int entry_index; 14388 int port, my_modid, stm_idx; 14389 int local_port[SOC_MAX_NUM_PORTS]; 14390 int local_port_count = 0; 14391 uint32 vent[SOC_MAX_MEM_WORDS]; 14392 uint32 ment[SOC_MAX_MEM_WORDS]; 14393 source_trunk_map_table_entry_t stm_entry; 14394 _bcm_vxlan_match_port_info_t *mkey = NULL; 14395 int d = 0; 14396 14397 if (!BCM_GPORT_IS_VXLAN_PORT(gport)) { 14398 return BCM_E_PARAM; 14399 } 14400 14401 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 14402 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 14403 return BCM_E_PARAM; 14404 } 14405 14406 mkey = &(VXLAN_INFO(unit)->match_key[vp]); 14407 14408 #define _BCM_VLXLT_KTYPE_ASSIGN(_ktype, _k) \ 14409 do { \ 14410 if (_ktype == bcmVlanTranslateKeyInvalid) { \ 14411 _ktype = _k; \ 14412 } \ 14413 } while(0) 14414 14415 switch(mkey->flags) { 14416 case _BCM_VXLAN_PORT_MATCH_TYPE_VLAN: 14417 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortOuter); 14418 /* Fall through */ 14419 case _BCM_VXLAN_PORT_MATCH_TYPE_INNER_VLAN: 14420 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortInner); 14421 /* Fall through */ 14422 case _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_STACKED: 14423 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortDouble); 14424 /* Fall through */ 14425 case _BCM_VXLAN_PORT_MATCH_TYPE_VLAN_PRI: 14426 _BCM_VLXLT_KTYPE_ASSIGN(key_type, bcmVlanTranslateKeyPortOuterPri); 14427 14428 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 14429 #if defined(BCM_TRIDENT3_SUPPORT) 14430 if (soc_feature(unit, soc_feature_base_valid)) { 14431 mem = VLAN_XLATE_1_DOUBLEm; 14432 14433 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 14434 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 14435 } else 14436 #endif 14437 { 14438 mem = VLAN_XLATEm; 14439 14440 soc_mem_field32_set(unit, mem, vent, VALIDf, 0x1); 14441 } 14442 14443 if (mkey->modid != -1) { 14444 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port); 14445 } else { 14446 BCM_GPORT_TRUNK_SET(port, mkey->trunk_id); 14447 } 14448 /* Construct lookup key */ 14449 BCM_IF_ERROR_RETURN( 14450 _bcm_trx_vlan_translate_entry_assemble(unit, vent, 14451 port, key_type, 14452 mkey->match_inner_vlan, 14453 mkey->match_vlan)); 14454 soc_mem_lock(unit, mem); 14455 /* Lookup existing entry */ 14456 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, 14457 &entry_index, vent, vent, 0); 14458 soc_mem_unlock(unit, mem); 14459 if (BCM_FAILURE(rv)) { 14460 return rv; 14461 } 14462 /* Get VP value representing VP LAG */ 14463 *vp_lag_vp = soc_mem_field32_get(unit, mem, vent, SOURCE_VPf); 14464 break; 14465 case _BCM_VXLAN_PORT_MATCH_TYPE_PORT: 14466 mem = SOURCE_TRUNK_MAP_TABLEm; 14467 14468 soc_mem_lock(unit, mem); 14469 14470 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 14471 mkey->index, &stm_entry); 14472 soc_mem_unlock(unit, mem); 14473 if (BCM_FAILURE(rv)) { 14474 return rv; 14475 } 14476 /* Resolve SVP Mode */ 14477 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 14478 svp_valid = soc_mem_field32_get(unit, mem, 14479 &stm_entry, SVP_VALIDf); 14480 if (svp_valid == 0) { 14481 return BCM_E_INTERNAL; 14482 } 14483 } 14484 /* Get VP value representing VP LAG */ 14485 *vp_lag_vp = soc_mem_field32_get(unit, mem, 14486 &stm_entry, SOURCE_VPf); 14487 break; 14488 case _BCM_VXLAN_PORT_MATCH_TYPE_TRUNK: 14489 mem = SOURCE_TRUNK_MAP_TABLEm; 14490 14491 /* Get module id for unit. */ 14492 BCM_IF_ERROR_RETURN( 14493 bcm_esw_stk_my_modid_get(unit, &my_modid)); 14494 14495 BCM_IF_ERROR_RETURN( 14496 _bcm_esw_trunk_local_members_get(unit, mkey->trunk_id, 14497 SOC_MAX_NUM_PORTS, 14498 local_port, 14499 &local_port_count)); 14500 14501 /* Get index to source trunk map table, 14502 * Only get it from the first member in LAG 14503 */ 14504 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 14505 local_port[0], 14506 &stm_idx); 14507 if (BCM_FAILURE(rv)) { 14508 return rv; 14509 } 14510 14511 soc_mem_lock(unit, mem); 14512 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 14513 stm_idx, &stm_entry); 14514 soc_mem_unlock(unit, mem); 14515 if (BCM_FAILURE(rv)) { 14516 return rv; 14517 } 14518 14519 /* Resolve SVP Mode */ 14520 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 14521 svp_valid = soc_mem_field32_get(unit, mem, 14522 &stm_entry, SVP_VALIDf); 14523 if (svp_valid == 0) { 14524 return BCM_E_INTERNAL; 14525 } 14526 } 14527 /* Get VP value representing VP LAG */ 14528 *vp_lag_vp = soc_mem_field32_get(unit, mem, 14529 &stm_entry, SOURCE_VPf); 14530 break; 14531 case _BCM_VXLAN_PORT_MATCH_TYPE_VNID: 14532 tunnel_index = mkey->match_tunnel_index; 14533 tunnel_sip = VXLAN_INFO(unit)->vxlan_tunnel_term[tunnel_index].sip; 14534 14535 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 14536 mem = MPLS_ENTRYm; 14537 #if defined(BCM_TRIDENT3_SUPPORT) 14538 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 14539 mem = MPLS_ENTRY_SINGLEm; 14540 d = 1; 14541 soc_mem_field32_set(unit, mem, ment, BASE_VALIDf, 1); 14542 soc_mem_field32_set(unit, mem, &ment, 14543 DATA_TYPEf, _BCM_VXLAN_FLEX_DATA_TYPE_IPV4_SIP); 14544 } else 14545 #endif 14546 { 14547 soc_mem_field32_set(unit, mem, &ment, VALIDf, 1); 14548 } 14549 14550 soc_mem_field32_set(unit, mem, &ment, BCM_VXLAN_SIP_FIELD(d, SIPf), tunnel_sip); 14551 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 14552 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 14553 soc_mem_field32_set(unit, mem, &ment, VXLAN_SIP__OVIDf, 14554 VXLAN_INFO(unit)->vxlan_tunnel_term[tunnel_index].vlan); 14555 } 14556 #endif 14557 soc_mem_field32_set(unit, mem, &ment, 14558 KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_TUNNEL); 14559 soc_mem_lock(unit, mem); 14560 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, &ment, &ment, 0); 14561 soc_mem_unlock(unit, mem); 14562 if (rv == BCM_E_NOT_FOUND) { 14563 rv = BCM_E_PARAM; 14564 } 14565 14566 if (BCM_FAILURE(rv)) { 14567 return rv; 14568 } 14569 14570 /* Get VP value representing VP LAG */ 14571 *vp_lag_vp = soc_mem_field32_get(unit, mem, &ment, BCM_VXLAN_SIP_FIELD(d, SVPf)); 14572 break; 14573 default: 14574 return BCM_E_PARAM; 14575 } 14576 14577 #undef _BCM_VLXLT_KTYPE_ASSIGN 14578 14579 if (!_bcm_vp_used_get(unit, *vp_lag_vp, _bcmVpTypeVpLag)) { 14580 return BCM_E_INTERNAL; 14581 } 14582 14583 return BCM_E_NONE; 14584 } 14585 14586 int 14587 _bcm_td2_vxlan_svp_field_set(int unit, bcm_gport_t vp, 14588 soc_field_t field, int value) 14589 { 14590 int rv = BCM_E_NONE; 14591 source_vp_entry_t svp; 14592 14593 rv = bcm_td2_vxlan_lock(unit); 14594 if (BCM_FAILURE(rv)) { 14595 return rv; 14596 } 14597 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 14598 if (rv < 0) { 14599 bcm_td2_vxlan_unlock(unit); 14600 return rv; 14601 } 14602 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, field)) { 14603 soc_SOURCE_VPm_field32_set(unit, &svp, field, value); 14604 } 14605 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 14606 bcm_td2_vxlan_unlock(unit); 14607 return rv; 14608 } 14609 14610 #ifndef BCM_SW_STATE_DUMP_DISABLE 14611 /* 14612 * Function: 14613 * _bcm_td2_vxlan_sw_dump 14614 * Purpose: 14615 * Displays VXLAN information maintained by software. 14616 * Parameters: 14617 * unit - Device unit number 14618 * Returns: 14619 * None 14620 */ 14621 void 14622 _bcm_td2_vxlan_sw_dump(int unit) 14623 { 14624 int i, num_vp; 14625 _bcm_td2_vxlan_bookkeeping_t *vxlan_info = VXLAN_INFO(unit); 14626 14627 LOG_CLI((BSL_META_U(unit, 14628 "Tunnel Initiator Endpoints:\n"))); 14629 for (i = 0; i < _BCM_MAX_NUM_VXLAN_TUNNEL; i++) { 14630 if (VXLAN_INFO(unit)->vxlan_tunnel_init[i].dip != 0 && 14631 VXLAN_INFO(unit)->vxlan_tunnel_init[i].sip != 0 ) { 14632 LOG_CLI((BSL_META_U(unit, 14633 "Tunnel idx:%d, sip:%x, dip:%x, vlan:%x \n"), i, 14634 vxlan_info->vxlan_tunnel_init[i].sip, 14635 vxlan_info->vxlan_tunnel_init[i].dip, 14636 vxlan_info->vxlan_tunnel_init[i].vlan)); 14637 } 14638 } 14639 14640 LOG_CLI((BSL_META_U(unit, 14641 "\nTunnel Terminator Endpoints:\n"))); 14642 for (i = 0; i < _BCM_MAX_NUM_VXLAN_TUNNEL; i++) { 14643 if (VXLAN_INFO(unit)->vxlan_tunnel_term[i].dip != 0 && 14644 VXLAN_INFO(unit)->vxlan_tunnel_term[i].sip != 0 ) { 14645 LOG_CLI((BSL_META_U(unit, 14646 "Tunnel idx:%d, sip:%x, dip:%x, vlan:%x\n"), i, 14647 vxlan_info->vxlan_tunnel_term[i].sip, 14648 vxlan_info->vxlan_tunnel_term[i].dip, 14649 vxlan_info->vxlan_tunnel_term[i].vlan)); 14650 } 14651 } 14652 14653 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 14654 14655 LOG_CLI((BSL_META_U(unit, 14656 "\n Match Info : \n"))); 14657 for (i = 0; i < num_vp; i++) { 14658 if ((vxlan_info->match_key[i].trunk_id == 0 || 14659 vxlan_info->match_key[i].trunk_id == -1) && 14660 (vxlan_info->match_key[i].modid == 0 || 14661 vxlan_info->match_key[i].modid == -1) && 14662 (vxlan_info->match_key[i].port == 0) && 14663 (vxlan_info->match_key[i].flags == 0)) { 14664 continue; 14665 } 14666 LOG_CLI((BSL_META_U(unit, 14667 "\n VXLAN port vp = %d\n"), i)); 14668 LOG_CLI((BSL_META_U(unit, 14669 "Flags = %x\n"), vxlan_info->match_key[i].flags)); 14670 LOG_CLI((BSL_META_U(unit, 14671 "Index = %x\n"), vxlan_info->match_key[i].index)); 14672 LOG_CLI((BSL_META_U(unit, 14673 "TGID = %d\n"), vxlan_info->match_key[i].trunk_id)); 14674 LOG_CLI((BSL_META_U(unit, 14675 "Modid = %d\n"), vxlan_info->match_key[i].modid)); 14676 LOG_CLI((BSL_META_U(unit, 14677 "Port = %d\n"), vxlan_info->match_key[i].port)); 14678 LOG_CLI((BSL_META_U(unit, 14679 "Match VLAN = %d\n"), 14680 vxlan_info->match_key[i].match_vlan)); 14681 LOG_CLI((BSL_META_U(unit, 14682 "Match Inner VLAN = %d\n"), 14683 vxlan_info->match_key[i].match_inner_vlan)); 14684 LOG_CLI((BSL_META_U(unit, 14685 "Match tunnel Index = %x\n"), 14686 vxlan_info->match_key[i].match_tunnel_index)); 14687 LOG_CLI((BSL_META_U(unit, 14688 "Match count = %x\n"), 14689 vxlan_info->match_key[i].match_count)); 14690 LOG_CLI((BSL_META_U(unit, 14691 "Related VFI = %d\n"), 14692 vxlan_info->match_key[i].vfi)); 14693 } 14694 14695 LOG_CLI((BSL_META_U(unit, 14696 "\nVxlan VPN INFO:\n"))); 14697 for (i = 0; i < soc_mem_index_count(unit, VFIm); i++) { 14698 if (vxlan_info->vxlan_vpn_info[i].vnid != 0 || 14699 vxlan_info->vxlan_vpn_info[i].vxlan_vpn_type != 0 || 14700 vxlan_info->vxlan_vpn_info[i].sip != 0) { 14701 LOG_CLI((BSL_META_U(unit, 14702 "\nVxlan VPN VFI %d:\n"), i)); 14703 LOG_CLI((BSL_META_U(unit, 14704 "VXLAN VPN TYPE = %d \n"), vxlan_info->vxlan_vpn_info[i].vxlan_vpn_type)); 14705 LOG_CLI((BSL_META_U(unit, 14706 "VXLAN VPN SIP = %x \n"), vxlan_info->vxlan_vpn_info[i].sip)); 14707 LOG_CLI((BSL_META_U(unit, 14708 "VXLAN VPN VNID = %d \n"), vxlan_info->vxlan_vpn_info[i].vnid)); 14709 } 14710 } 14711 14712 for (i = 0; i < num_vp; i++) { 14713 if (vxlan_info->vfi_vnid_map_count[i]) { 14714 LOG_CLI((BSL_META_U(unit, 14715 "\nVxlan VP %d: VP-based VFI-VNID mappings count = %d\n"), i, 14716 vxlan_info->vfi_vnid_map_count[i])); 14717 } 14718 } 14719 14720 return; 14721 } 14722 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 14723 14724 /* 14725 * Function: 14726 * _bcm_td2_vxlan_dip_entry_idx_get 14727 * Purpose: 14728 * Get TD2 vxlan_dip_entry index by VxLAN DIP. 14729 * Parameters: 14730 * unit - (IN)SOC unit number. 14731 * vxlan_dip - (IN)VxLAN DIP. 14732 * index - (OUT)vxlan_dip_entry index. 14733 * Returns: 14734 * BCM_E_XXX 14735 */ 14736 int 14737 _bcm_td2_vxlan_dip_entry_idx_get(int unit, 14738 bcm_ip_t vxlan_dip, 14739 int *index) 14740 { 14741 soc_mem_t mem; 14742 uint32 vent[SOC_MAX_MEM_WORDS]; 14743 int d = 0; /*vxlan decoupled mode*/ 14744 14745 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 14746 14747 #if defined(BCM_TRIDENT3_SUPPORT) 14748 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 14749 bcm_tunnel_terminator_t tnl_info; 14750 14751 mem = MPLS_ENTRY_SINGLEm; 14752 d = 1; 14753 bcm_tunnel_terminator_t_init(&tnl_info); 14754 _bcm_td2_vxlan_tunnel_terminate_entry_key_set(unit, &tnl_info, 14755 vent, 0, 1); 14756 } else 14757 #endif 14758 { 14759 mem = VLAN_XLATEm; 14760 14761 soc_mem_field32_set(unit, mem, vent, VALIDf, 0x1); 14762 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 14763 } 14764 14765 soc_mem_field32_set(unit, mem, vent, BCM_VXLAN_DIP_FIELD(d,DIPf), vxlan_dip); 14766 14767 return soc_mem_search(unit, mem, MEM_BLOCK_ANY, index, vent, vent, 0); 14768 } 14769 14770 /* 14771 * Function: 14772 * _bcm_esw_vxlan_dip_stat_get_table_info 14773 * Description: 14774 * Provides relevant flex table information(table-name,index with 14775 * direction) for given ingress interface. 14776 * 14777 * Parameters: 14778 * unit - (IN) unit number 14779 * vxlan_dip - (IN) vxlan dip 14780 * num_of_tables - (OUT) Number of flex counter tables 14781 * table_info - (OUT) Flex counter tables information 14782 * 14783 * Return Value: 14784 * BCM_E_XXX 14785 * Notes: 14786 */ 14787 14788 static 14789 bcm_error_t _bcm_td2_vxlan_dip_stat_get_table_info( 14790 int unit, 14791 bcm_ip_t vxlan_dip, 14792 uint32 *num_of_tables, 14793 bcm_stat_flex_table_info_t *table_info) 14794 { 14795 14796 int index; 14797 soc_mem_t mem; 14798 14799 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 14800 return BCM_E_UNAVAIL; 14801 } 14802 14803 #if defined(BCM_TRIDENT3_SUPPORT) 14804 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 14805 return BCM_E_UNAVAIL; 14806 } 14807 #endif 14808 14809 /* Parameter validation checks */ 14810 if (!SOC_UNIT_VALID(unit)) { 14811 return BCM_E_UNIT; 14812 } 14813 14814 BCM_IF_ERROR_RETURN 14815 (_bcm_td2_vxlan_dip_entry_idx_get(unit, vxlan_dip, &index)); 14816 14817 #if defined(BCM_TRIDENT3_SUPPORT) 14818 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 14819 mem = MPLS_ENTRY_SINGLEm; 14820 } else 14821 #endif 14822 { 14823 mem = VLAN_XLATEm; 14824 } 14825 14826 if (vxlan_dip != 0) { 14827 table_info[*num_of_tables].table = mem; 14828 table_info[*num_of_tables].index = index; 14829 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 14830 (*num_of_tables)++; 14831 } 14832 14833 if (*num_of_tables == 0) { 14834 return BCM_E_PARAM; 14835 } 14836 14837 return BCM_E_NONE; 14838 } 14839 14840 /* 14841 * Function: 14842 * _bcm_td2_vxlan_dip_stat_counter_get 14843 * Description: 14844 * Get counter statistic values for specific vxlan dip 14845 * if sync_mode is set, sync the sw accumulated count 14846 * with hw count value first, else return sw count. 14847 * 14848 * Parameters: 14849 * unit - (IN) unit number 14850 * sync_mode - (IN) hwcount is to be synced to sw count 14851 * vxlan_dip - (IN) vxlan dip information 14852 * stat - (IN) Type of the counter to retrieve 14853 * I.e. ingress/egress byte/packet) 14854 * num_entries - (IN) Number of counter Entries 14855 * counter_indexes - (IN) Pointer to Counter indexes entries 14856 * counter_values - (OUT) Pointer to counter values 14857 * 14858 * Return Value: 14859 * BCM_E_XXX 14860 * Notes: 14861 */ 14862 bcm_error_t 14863 _bcm_td2_vxlan_dip_stat_counter_get( 14864 int unit, 14865 int sync_mode, 14866 bcm_ip_t vxlan_dip, 14867 bcm_vxlan_dip_stat_t stat, 14868 uint32 num_entries, 14869 uint32 *counter_indexes, 14870 bcm_stat_value_t *counter_values) 14871 { 14872 uint32 table_count=0; 14873 uint32 index_count=0; 14874 uint32 num_of_tables=0; 14875 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 14876 uint32 byte_flag=0; 14877 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 14878 14879 if ((stat == bcmVxlanDipInPackets) || 14880 (stat == bcmVxlanDipInBytes)) { 14881 direction = bcmStatFlexDirectionIngress; 14882 } else { 14883 /* direction = bcmStatFlexDirectionEgress; */ 14884 return BCM_E_PARAM; 14885 } 14886 14887 if ((num_entries > 0) && 14888 ((NULL == counter_indexes) || (NULL == counter_values))) { 14889 return BCM_E_PARAM; 14890 } 14891 14892 if (stat == bcmVxlanDipInPackets) { 14893 byte_flag=0; 14894 } else { 14895 byte_flag=1; 14896 } 14897 14898 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_get_table_info( 14899 unit, vxlan_dip,&num_of_tables,&table_info[0])); 14900 14901 for (table_count=0; table_count < num_of_tables; table_count++) { 14902 if (table_info[table_count].direction == direction) { 14903 for (index_count=0; index_count < num_entries ; index_count++) { 14904 /*ctr_offset_info.offset_index = counter_indexes[index_count];*/ 14905 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 14906 unit, sync_mode, 14907 table_info[table_count].index, 14908 table_info[table_count].table, 14909 0, 14910 byte_flag, 14911 counter_indexes[index_count], 14912 &counter_values[index_count])); 14913 } 14914 } 14915 } 14916 return BCM_E_NONE; 14917 } 14918 14919 /* 14920 * Function: 14921 * _bcm_td2_vxlan_dip_stat_multi_get 14922 * 14923 * Description: 14924 * Get Multiple vxlan dip counter value for specified IPMC group index for multiple stat 14925 * types 14926 * 14927 * Parameters: 14928 * unit - (IN) unit number 14929 * vxlan_dip - (IN) vxlan dip 14930 * nstat - (IN) Number of elements in stat array 14931 * stat_arr - (IN) Collected statistics descriptors array 14932 * value_arr - (OUT) Collected counters values 14933 * 14934 * Return Value: 14935 * BCM_E_XXX 14936 * Notes: 14937 */ 14938 bcm_error_t _bcm_td2_vxlan_dip_stat_multi_get( 14939 int unit, 14940 bcm_ip_t vxlan_dip, 14941 int nstat, 14942 bcm_vxlan_dip_stat_t *stat_arr, 14943 uint64 *value_arr) 14944 { 14945 int rv = BCM_E_NONE; 14946 int idx; 14947 uint32 counter_indexes = 0; 14948 bcm_stat_value_t counter_values = {0}; 14949 int sync_mode = 0; 14950 14951 if ((nstat > 0) && ((NULL == stat_arr) || (NULL == value_arr))) { 14952 return BCM_E_PARAM; 14953 } 14954 14955 /* Iterate of all stats array to retrieve flex counter values */ 14956 for (idx = 0; idx < nstat; idx++) { 14957 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_counter_get( 14958 unit, sync_mode, vxlan_dip, stat_arr[idx], 14959 1, &counter_indexes, &counter_values)); 14960 if ((stat_arr[idx] == bcmVxlanDipInPackets)) { 14961 COMPILER_64_SET(value_arr[idx], 14962 COMPILER_64_HI(counter_values.packets64), 14963 COMPILER_64_LO(counter_values.packets64)); 14964 } else { 14965 COMPILER_64_SET(value_arr[idx], 14966 COMPILER_64_HI(counter_values.bytes), 14967 COMPILER_64_LO(counter_values.bytes)); 14968 } 14969 } 14970 return rv; 14971 } 14972 14973 /* 14974 * Function: 14975 * _bcm_td2_vxlan_dip_stat_multi_get32 14976 * 14977 * Description: 14978 * Get 32bit vxlan dip counter value for specified IPMC group index for multiple stat 14979 * types 14980 * 14981 * Parameters: 14982 * unit - (IN) unit number 14983 * vxlan_dip - (IN) vxlan dip 14984 * nstat - (IN) Number of elements in stat array 14985 * stat_arr - (IN) Collected statistics descriptors array 14986 * value_arr - (OUT) Collected counters values 14987 * 14988 * Return Value: 14989 * BCM_E_XXX 14990 * Notes: 14991 */ 14992 bcm_error_t _bcm_td2_vxlan_dip_stat_multi_get32( 14993 int unit, 14994 bcm_ip_t vxlan_dip, 14995 int nstat, 14996 bcm_vxlan_dip_stat_t *stat_arr, 14997 uint32 *value_arr) 14998 { 14999 int rv = BCM_E_NONE; 15000 int idx; 15001 uint32 counter_indexes = 0; 15002 bcm_stat_value_t counter_values = {0}; 15003 int sync_mode = 0; 15004 15005 if ((nstat > 0) && ((NULL == stat_arr) || (NULL == value_arr))) { 15006 return BCM_E_PARAM; 15007 } 15008 15009 /* Iterate of all stats array to retrieve flex counter values */ 15010 for (idx = 0; idx < nstat; idx++) { 15011 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_counter_get( 15012 unit, sync_mode, vxlan_dip, stat_arr[idx], 15013 1, &counter_indexes, &counter_values)); 15014 if ((stat_arr[idx] == bcmVxlanDipInPackets)) { 15015 value_arr[idx] = counter_values.packets; 15016 } else { 15017 value_arr[idx] = COMPILER_64_LO(counter_values.bytes); 15018 } 15019 } 15020 return rv; 15021 } 15022 15023 /* 15024 * Function: 15025 * _bcm_td2_vxlan_dip_stat_counter_set 15026 * Description: 15027 * Set counter statistic values for specific vxlan dip 15028 * 15029 * Parameters: 15030 * unit - (IN) unit number 15031 * vxlan_dip - (IN) vxlan dip 15032 * stat - (IN) Type of the counter to retrieve 15033 * I.e. ingress/egress byte/packet) 15034 * num_entries - (IN) Number of counter Entries 15035 * counter_indexes - (IN) Pointer to Counter indexes entries 15036 * counter_values - (IN) Pointer to counter values 15037 * 15038 * Return Value: 15039 * BCM_E_XXX 15040 * Notes: 15041 */ 15042 bcm_error_t 15043 _bcm_td2_vxlan_dip_stat_counter_set( 15044 int unit, 15045 bcm_ip_t vxlan_dip, 15046 bcm_vxlan_dip_stat_t stat, 15047 uint32 num_entries, 15048 uint32 *counter_indexes, 15049 bcm_stat_value_t *counter_values) 15050 { 15051 uint32 table_count=0; 15052 uint32 index_count=0; 15053 uint32 num_of_tables=0; 15054 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 15055 uint32 byte_flag=0; 15056 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15057 15058 if ((stat == bcmVxlanDipInPackets) || 15059 (stat == bcmVxlanDipInBytes)) { 15060 direction = bcmStatFlexDirectionIngress; 15061 } else { 15062 /* direction = bcmStatFlexDirectionEgress; */ 15063 return BCM_E_PARAM; 15064 } 15065 15066 if ((num_entries > 0) && 15067 ((NULL == counter_indexes) || (NULL == counter_values))) { 15068 return BCM_E_PARAM; 15069 } 15070 15071 if (stat == bcmVxlanDipInPackets) { 15072 byte_flag=0; 15073 } else { 15074 byte_flag=1; 15075 } 15076 15077 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_get_table_info( 15078 unit, vxlan_dip, &num_of_tables, &table_info[0])); 15079 15080 for (table_count=0; table_count < num_of_tables; table_count++) { 15081 if (table_info[table_count].direction == direction) { 15082 for (index_count=0; index_count < num_entries; index_count++) { 15083 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 15084 unit, 15085 table_info[table_count].index, 15086 table_info[table_count].table, 15087 0, 15088 byte_flag, 15089 counter_indexes[index_count], 15090 &counter_values[index_count])); 15091 } 15092 } 15093 } 15094 return BCM_E_NONE; 15095 } 15096 15097 /* 15098 * Function: 15099 * _bcm_esw_vxlan_dip_stat_counter_get 15100 * Description: 15101 * Get counter statistic values for specific vxlan dip 15102 * 15103 * Parameters: 15104 * unit - (IN) unit number 15105 * sync_mode - (IN) if 1 sync sw count value with hw count 15106 * before retieving count else get 15107 * sw accumulated count 15108 * vxlan_dip - (IN) vxlan dip 15109 * stat - (IN) Type of the counter to retrieve 15110 * I.e. ingress/egress byte/packet) 15111 * num_entries - (IN) Number of counter Entries 15112 * counter_indexes - (IN) Pointer to Counter indexes entries 15113 * counter_values - (OUT) Pointer to counter values 15114 * 15115 * Return Value: 15116 * BCM_E_XXX 15117 * Notes: 15118 */ 15119 bcm_error_t 15120 _bcm_esw_vxlan_dip_stat_counter_get( 15121 int unit, 15122 int sync_mode, 15123 bcm_ip_t vxlan_dip, 15124 bcm_vxlan_dip_stat_t stat, 15125 uint32 num_entries, 15126 uint32 *counter_indexes, 15127 bcm_stat_value_t *counter_values) 15128 { 15129 #if defined(BCM_TRIDENT2_SUPPORT) 15130 if (SOC_IS_TD2_TT2(unit)) { 15131 return _bcm_td2_vxlan_dip_stat_counter_get(unit, sync_mode, vxlan_dip, stat, 15132 num_entries, counter_indexes, counter_values); 15133 } else 15134 #endif 15135 { 15136 return BCM_E_UNAVAIL; 15137 } 15138 } 15139 15140 15141 /* 15142 * Function: 15143 * _bcm_td2_vxlan_dip_stat_multi_set 15144 * 15145 * Description: 15146 * Set vxlan dip counter value for specified IPMC group index for multiple stat 15147 * types 15148 * 15149 * Parameters: 15150 * unit - (IN) unit number 15151 * vxlan_dip - (IN) vxlan dip 15152 * stat - (IN) IPMC group counter stat types 15153 * num_entries - (IN) Number of counter Entries 15154 * counter_indexes - (IN) Pointer to Counter indexes entries 15155 * counter_values - (OUT) Pointer to counter values 15156 * 15157 * Return Value: 15158 * BCM_E_XXX 15159 * Notes: 15160 */ 15161 bcm_error_t _bcm_td2_vxlan_dip_stat_multi_set( 15162 int unit, 15163 bcm_ip_t vxlan_dip, 15164 int nstat, 15165 bcm_vxlan_dip_stat_t *stat_arr, 15166 uint64 *value_arr) 15167 { 15168 int rv = BCM_E_NONE; 15169 int idx; 15170 uint32 counter_indexes = 0; 15171 bcm_stat_value_t counter_values = {0}; 15172 15173 if ((nstat > 0) && ((NULL == stat_arr) || (NULL == value_arr))) { 15174 return BCM_E_PARAM; 15175 } 15176 15177 /* Iterate f all stats array to retrieve flex counter values */ 15178 for (idx = 0; idx < nstat; idx++) { 15179 if ((stat_arr[idx] == bcmVxlanDipInPackets)) { 15180 counter_values.packets = COMPILER_64_LO(value_arr[idx]); 15181 } else { 15182 COMPILER_64_SET(counter_values.bytes, 15183 COMPILER_64_HI(value_arr[idx]), 15184 COMPILER_64_LO(value_arr[idx])); 15185 } 15186 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_counter_set( 15187 unit, vxlan_dip, stat_arr[idx], 15188 1, &counter_indexes, &counter_values)); 15189 } 15190 return rv; 15191 15192 } 15193 15194 15195 15196 15197 15198 /* 15199 * Function: 15200 * _bcm_td2_vxlan_dip_stat_multi_set32 15201 * 15202 * Description: 15203 * Set 32biv xlan dip counter value for specified IPMC group index for multiple stat 15204 * types 15205 * 15206 * Parameters: 15207 * unit - (IN) unit number 15208 * vxlan_dip - (IN)vxlan dip 15209 * stat - (IN) IPMC group counter stat types 15210 * num_entries - (IN) Number of counter Entries 15211 * counter_indexes - (IN) Pointer to Counter indexes entries 15212 * counter_values - (OUT) Pointer to counter values 15213 * 15214 * Return Value: 15215 * BCM_E_XXX 15216 * Notes: 15217 */ 15218 15219 bcm_error_t _bcm_td2_vxlan_dip_stat_multi_set32( 15220 int unit, 15221 bcm_ip_t vxlan_dip, 15222 int nstat, 15223 bcm_vxlan_dip_stat_t *stat_arr, 15224 uint32 *value_arr) 15225 { 15226 int rv = BCM_E_NONE; 15227 int idx; 15228 uint32 counter_indexes = 0; 15229 bcm_stat_value_t counter_values = {0}; 15230 15231 if ((nstat > 0) && ((NULL == stat_arr) || (NULL == value_arr))) { 15232 return BCM_E_PARAM; 15233 } 15234 15235 /* Iterate of all stats array to retrieve flex counter values */ 15236 for (idx = 0; idx < nstat; idx++) { 15237 if ((stat_arr[idx] == bcmVxlanDipInPackets)) { 15238 counter_values.packets = value_arr[idx]; 15239 } else { 15240 COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]); 15241 } 15242 15243 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_counter_set( 15244 unit, vxlan_dip, stat_arr[idx], 15245 1, &counter_indexes, &counter_values)); 15246 } 15247 return rv; 15248 } 15249 15250 /* 15251 * Function: 15252 * _bcm_td2_vxlan_dip_stat_id_get 15253 * Description: 15254 * Retrieve associated stat counter for given VXLAN DIP 15255 * 15256 * Parameters: 15257 * unit - (IN) unit number 15258 * vxlan_dip - (IN) vxlan ip 15259 * stat - (IN) Type of the counter to retrieve 15260 * I.e. ingress/egress byte/packet) 15261 * Stat_counter_id - (OUT) Stat Counter ID 15262 * Return Value: 15263 * BCM_E_XXX 15264 * Notes: 15265 */ 15266 bcm_error_t 15267 _bcm_td2_vxlan_dip_stat_id_get( 15268 int unit, 15269 bcm_ip_t vxlan_dip, 15270 bcm_vxlan_dip_stat_t stat, 15271 uint32 *stat_counter_id) 15272 { 15273 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 15274 uint32 num_of_tables=0; 15275 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15276 uint32 index=0; 15277 uint32 num_stat_counter_ids=0; 15278 15279 if ((stat == bcmVxlanDipInPackets) || 15280 (stat == bcmVxlanDipInBytes)) { 15281 direction = bcmStatFlexDirectionIngress; 15282 } else { 15283 /* direction = bcmStatFlexDirectionEgress; */ 15284 return BCM_E_PARAM; 15285 } 15286 15287 if (NULL == stat_counter_id) { 15288 return BCM_E_PARAM; 15289 } 15290 15291 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_get_table_info( 15292 unit,vxlan_dip,&num_of_tables,&table_info[0])); 15293 for (index=0; index < num_of_tables; index++) { 15294 if (table_info[index].direction == direction) 15295 return _bcm_esw_stat_flex_get_counter_id( 15296 unit, 1, &table_info[index], 15297 &num_stat_counter_ids,stat_counter_id); 15298 } 15299 return BCM_E_NOT_FOUND; 15300 } 15301 15302 /* 15303 * Function: 15304 * _bcm_td2_vxlan_dip_stat_detach 15305 * Description: 15306 * Detach counters entries to the given vxlan dip 15307 * 15308 * Parameters: 15309 * unit - (IN) unit number 15310 * vxlan_dip - (IN) vxlan dip 15311 * 15312 * Return Value: 15313 * BCM_E_XXX 15314 * Notes: 15315 */ 15316 bcm_error_t 15317 _bcm_td2_vxlan_dip_stat_detach( 15318 int unit, 15319 bcm_ip_t vxlan_dip) 15320 { 15321 uint32 count=0; 15322 uint32 num_of_tables=0; 15323 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15324 bcm_error_t rv = BCM_E_NONE; 15325 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 15326 15327 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_get_table_info( 15328 unit, vxlan_dip,&num_of_tables,&table_info[0])); 15329 15330 for (count=0; count < num_of_tables; count++) { 15331 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 15332 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 15333 unit, 15334 table_info[count].table, 15335 table_info[count].index); 15336 if (BCM_E_NONE != rv && 15337 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 15338 err_code[bcmStatFlexDirectionIngress] = rv; 15339 } 15340 } else { 15341 return BCM_E_INTERNAL; 15342 } 15343 } 15344 15345 BCM_STAT_FLEX_DETACH_RETURN(err_code) 15346 } 15347 15348 /* 15349 * Function: 15350 * _bcm_td2_vxlan_dip_stat_attach 15351 * Description: 15352 * Attach counters entries to the given vxlan dip 15353 * 15354 * Parameters: 15355 * unit - (IN) unit number 15356 * vxlan_dip - (IN) vxlan dip 15357 * stat_counter_id - (IN) Stat Counter ID. 15358 * 15359 * Return Value: 15360 * BCM_E_XXX 15361 */ 15362 bcm_error_t 15363 _bcm_td2_vxlan_dip_stat_attach( 15364 int unit, 15365 bcm_ip_t vxlan_dip, 15366 uint32 stat_counter_id) 15367 { 15368 soc_mem_t table[4]={0}; 15369 uint32 flex_table_index=0; 15370 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 15371 uint32 pool_number=0; 15372 uint32 base_index=0; 15373 bcm_stat_flex_mode_t offset_mode=0; 15374 bcm_stat_object_t object=bcmStatObjectIngPort; 15375 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 15376 uint32 count=0; 15377 uint32 actual_num_tables=0; 15378 uint32 num_of_tables=0; 15379 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15380 15381 _bcm_esw_stat_get_counter_id_info( 15382 unit, stat_counter_id, 15383 &group_mode,&object,&offset_mode,&pool_number,&base_index); 15384 15385 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 15386 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 15387 15388 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 15389 unit,object,4,&actual_num_tables,&table[0],&direction)); 15390 15391 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_dip_stat_get_table_info( 15392 unit, vxlan_dip,&num_of_tables,&table_info[0])); 15393 for (count=0; count < num_of_tables; count++) { 15394 for (flex_table_index=0; 15395 flex_table_index < actual_num_tables ; 15396 flex_table_index++) { 15397 if ((table_info[count].direction == direction) && 15398 (table_info[count].table == table[flex_table_index]) ) { 15399 if (direction == bcmStatFlexDirectionIngress) { 15400 return _bcm_esw_stat_flex_attach_ingress_table_counters( 15401 unit, 15402 table_info[count].table, 15403 table_info[count].index, 15404 offset_mode, 15405 base_index, 15406 pool_number); 15407 } else { 15408 return BCM_E_INTERNAL; 15409 } 15410 } 15411 } 15412 } 15413 return BCM_E_NOT_FOUND; 15414 } 15415 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 15416