l2gre.c (61787B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: l2gre.c 8 * Purpose: TD2 L2GRE enhancements 9 */ 10 #include <soc/defs.h> 11 12 #include <assert.h> 13 14 #include <sal/core/libc.h> 15 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 16 17 #include <soc/drv.h> 18 #include <soc/mem.h> 19 #include <soc/util.h> 20 #include <soc/hash.h> 21 #include <soc/debug.h> 22 #include <bcm/types.h> 23 #include <bcm/error.h> 24 25 #include <bcm_int/esw/mbcm.h> 26 #include <bcm_int/esw_dispatch.h> 27 #include <bcm_int/esw/virtual.h> 28 #include <bcm_int/esw/trx.h> 29 #include <bcm_int/esw/triumph3.h> 30 #include <bcm_int/esw/trident2.h> 31 #include <bcm_int/esw/l2gre.h> 32 #include <bcm_int/esw/stack.h> 33 #include <bcm_int/common/multicast.h> 34 35 #if defined(BCM_TRIDENT3_SUPPORT) 36 #include <soc/esw/cancun.h> 37 #endif 38 39 #define L2GRE_INFO(_unit_) (_bcm_tr3_l2gre_bk_info[_unit_]) 40 41 /* 42 * Function: 43 * _bcm_td2_l2gre_match_vxlate_entry_set 44 * Purpose: 45 * Set L2GRE Match Vxlate Entry 46 * Parameters: 47 * IN : Unit 48 * IN : l2gre_port 49 * IN : vlan_xlate_entry_t 50 * Returns: 51 * BCM_E_XXX 52 */ 53 54 STATIC int 55 _bcm_td2_l2gre_match_vxlate_entry_set(int unit, bcm_l2gre_port_t *l2gre_port, uint32 *vent) 56 { 57 int rv = BCM_E_UNAVAIL; 58 int index; 59 bcm_module_t mod_out = -1; 60 bcm_port_t port_out = -1; 61 bcm_trunk_t trunk_id = -1; 62 int gport_id = -1; 63 soc_mem_t mem; 64 uint32 rvent[SOC_MAX_MEM_WORDS]; 65 int vp = _SHR_GPORT_L2GRE_PORT_ID_GET(l2gre_port->l2gre_port_id); 66 _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit); 67 68 69 #if defined(BCM_TRIDENT3_SUPPORT) 70 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 71 mem = VLAN_XLATE_1_DOUBLEm; 72 73 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 74 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 75 } else 76 #endif 77 { 78 mem = VLAN_XLATEm; 79 soc_mem_field32_set(unit, mem, vent, VALIDf, 0x1); 80 } 81 82 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 83 BCM_IF_ERROR_RETURN(_bcm_tr3_l2gre_port_resolve(unit, l2gre_port->l2gre_port_id, -1, &mod_out, 84 &port_out, &trunk_id, &gport_id)); 85 } else { 86 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, l2gre_port->match_port, &mod_out, 87 &port_out, &trunk_id, &gport_id)); 88 } 89 90 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 91 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 92 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 93 } else { 94 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 95 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 96 } 97 98 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 99 soc_mem_field32_set(unit, mem, vent, XLATE__MPLS_ACTIONf, 0x1); /* SVP */ 100 soc_mem_field32_set(unit, mem, vent, XLATE__SOURCE_VPf, vp); 101 soc_mem_field32_set(unit, mem, vent, XLATE__DISABLE_VLAN_CHECKSf, 1); 102 if (l2gre_port->flags & BCM_L2GRE_PORT_ENABLE_VLAN_CHECKS) { 103 soc_mem_field32_set(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf, 1); 104 } 105 106 107 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vent, &rvent, 0); 108 if (rv == BCM_E_NONE) { 109 BCM_IF_ERROR_RETURN( 110 soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, vent)); 111 } else if (rv == BCM_E_NOT_FOUND) { 112 if (l2gre_port->flags & BCM_VXLAN_PORT_REPLACE) { 113 return BCM_E_NOT_FOUND; 114 } 115 BCM_IF_ERROR_RETURN(soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent)); 116 } else { 117 return rv; 118 } 119 120 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 121 /* Update software state */ 122 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 123 l2gre_info->match_key[vp].trunk_id = trunk_id; 124 l2gre_info->match_key[vp].modid = -1; 125 } else { 126 l2gre_info->match_key[vp].port = port_out; 127 l2gre_info->match_key[vp].modid = mod_out; 128 l2gre_info->match_key[vp].trunk_id = -1; 129 } 130 } 131 132 return BCM_E_NONE; 133 } 134 135 136 /* 137 * Function: 138 * _bcm_td2_l2gre_match_add 139 * Purpose: 140 * Assign match criteria of an L2GRE port 141 * Parameters: 142 * unit - (IN) Device Number 143 * l2gre_port - (IN) l2gre port information 144 * vp - (IN) Source Virtual Port 145 * Returns: 146 * BCM_E_XXX 147 */ 148 149 int 150 bcm_td2_l2gre_match_add(int unit, bcm_l2gre_port_t *l2gre_port, int vp, bcm_vpn_t vpn) 151 { 152 _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit); 153 int rv = BCM_E_NONE; 154 bcm_module_t mod_out = -1; 155 bcm_port_t port_out = -1; 156 bcm_trunk_t trunk_id = -1; 157 int src_trk_idx=0; /*Source Trunk table index.*/ 158 int gport_id=-1; 159 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 160 _bcm_vp_info_t vp_info; 161 #endif 162 soc_mem_t mem; 163 uint32 vent[SOC_MAX_MEM_WORDS] = {0}; 164 165 #if defined(BCM_TRIDENT3_SUPPORT) 166 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 167 mem = VLAN_XLATE_1_DOUBLEm; 168 } else 169 #endif 170 { 171 mem = VLAN_XLATEm; 172 } 173 if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_SHARE) { 174 /* there is no criteria to be configurated for shared vp, 175 only updating software state to indicate this is a shared vp */ 176 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_SHARED; 177 return BCM_E_NONE; 178 } 179 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 180 rv = _bcm_tr3_l2gre_port_resolve(unit, l2gre_port->l2gre_port_id, -1, &mod_out, 181 &port_out, &trunk_id, &gport_id); 182 } else { 183 rv = _bcm_esw_gport_resolve(unit, l2gre_port->match_port, &mod_out, 184 &port_out, &trunk_id, &gport_id); 185 } 186 BCM_IF_ERROR_RETURN(rv); 187 188 if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_VLAN ) { 189 if (!BCM_VLAN_VALID(l2gre_port->match_vlan)) { 190 return BCM_E_PARAM; 191 } 192 193 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 194 #if defined(BCM_TRIDENT3_SUPPORT) 195 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 196 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 197 } 198 #endif 199 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan); 200 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 201 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 202 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 203 } else { 204 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 205 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 206 } 207 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 208 if (soc_feature(unit, soc_feature_vp_sharing)) { 209 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 210 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 211 int vfi = 0; 212 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 213 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi); 214 } 215 } 216 #endif 217 218 BCM_IF_ERROR_RETURN( 219 _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent)); 220 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 221 /* Update software state */ 222 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_VLAN; 223 l2gre_info->match_key[vp].match_vlan = l2gre_port->match_vlan; 224 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 225 l2gre_info->match_key[vp].trunk_id = trunk_id; 226 l2gre_info->match_key[vp].modid = -1; 227 } else { 228 l2gre_info->match_key[vp].port = port_out; 229 l2gre_info->match_key[vp].modid = mod_out; 230 l2gre_info->match_key[vp].trunk_id = -1; 231 } 232 } 233 if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) { 234 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1); 235 } 236 } else if (l2gre_port->criteria == 237 BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN) { 238 if (!BCM_VLAN_VALID(l2gre_port->match_inner_vlan)) { 239 return BCM_E_PARAM; 240 } 241 242 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 243 #if defined(BCM_TRIDENT3_SUPPORT) 244 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 245 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 246 } 247 #endif 248 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan); 249 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 250 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 251 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 252 } else { 253 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 254 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 255 } 256 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 257 if (soc_feature(unit, soc_feature_vp_sharing)) { 258 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 259 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 260 int vfi = 0; 261 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 262 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi); 263 } 264 } 265 #endif 266 BCM_IF_ERROR_RETURN( 267 _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent)); 268 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 269 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN; 270 l2gre_info->match_key[vp].match_inner_vlan = l2gre_port->match_inner_vlan; 271 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 272 l2gre_info->match_key[vp].trunk_id = trunk_id; 273 l2gre_info->match_key[vp].modid = -1; 274 } else { 275 l2gre_info->match_key[vp].port = port_out; 276 l2gre_info->match_key[vp].modid = mod_out; 277 l2gre_info->match_key[vp].trunk_id = -1; 278 } 279 } 280 if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) { 281 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1); 282 } 283 } else if (l2gre_port->criteria == 284 BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED) { 285 if (!BCM_VLAN_VALID(l2gre_port->match_vlan) || 286 !BCM_VLAN_VALID(l2gre_port->match_inner_vlan)) { 287 return BCM_E_PARAM; 288 } 289 290 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 291 #if defined(BCM_TRIDENT3_SUPPORT) 292 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 293 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 294 } 295 #endif 296 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan); 297 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan); 298 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 299 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 300 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 301 } else { 302 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 303 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 304 } 305 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 306 if (soc_feature(unit, soc_feature_vp_sharing)) { 307 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 308 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 309 int vfi = 0; 310 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 311 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi); 312 } 313 } 314 #endif 315 BCM_IF_ERROR_RETURN( 316 _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent)); 317 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 318 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED; 319 l2gre_info->match_key[vp].match_vlan = l2gre_port->match_vlan; 320 l2gre_info->match_key[vp].match_inner_vlan = l2gre_port->match_inner_vlan; 321 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 322 l2gre_info->match_key[vp].trunk_id = trunk_id; 323 l2gre_info->match_key[vp].modid = -1; 324 } else { 325 l2gre_info->match_key[vp].port = port_out; 326 l2gre_info->match_key[vp].modid = mod_out; 327 l2gre_info->match_key[vp].trunk_id = -1; 328 } 329 } 330 if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) { 331 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1); 332 } 333 } else if (l2gre_port->criteria == 334 BCM_L2GRE_PORT_MATCH_VLAN_PRI) { 335 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 336 /* match_vlan : Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */ 337 soc_mem_field32_set(unit, mem, vent, OTAGf, l2gre_port->match_vlan); 338 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 339 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 340 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 341 } else { 342 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 343 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 344 } 345 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 346 if (soc_feature(unit, soc_feature_vp_sharing)) { 347 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 348 if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) { 349 int vfi = 0; 350 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 351 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi); 352 } 353 } 354 #endif 355 BCM_IF_ERROR_RETURN( 356 _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent)); 357 if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 358 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI; 359 l2gre_info->match_key[vp].match_vlan = l2gre_port->match_vlan; 360 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 361 l2gre_info->match_key[vp].trunk_id = trunk_id; 362 l2gre_info->match_key[vp].modid = -1; 363 } else { 364 l2gre_info->match_key[vp].port = port_out; 365 l2gre_info->match_key[vp].modid = mod_out; 366 l2gre_info->match_key[vp].trunk_id = -1; 367 } 368 } 369 if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) { 370 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1); 371 } 372 }else if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT) { 373 if (l2gre_info->match_key[vp].flags == 374 _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 375 return BCM_E_PARAM; 376 } 377 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 378 rv = bcm_tr3_l2gre_match_trunk_add(unit, trunk_id, vp); 379 if (rv >= 0) { 380 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK; 381 l2gre_info->match_key[vp].trunk_id = trunk_id; 382 } 383 BCM_IF_ERROR_RETURN(rv); 384 } else { 385 int is_local; 386 387 BCM_IF_ERROR_RETURN 388 ( _bcm_esw_modid_is_local(unit, mod_out, &is_local)); 389 390 /* Get index to source trunk map table */ 391 BCM_IF_ERROR_RETURN( 392 _bcm_esw_src_mod_port_table_index_get(unit, mod_out, 393 port_out, &src_trk_idx)); 394 395 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 396 src_trk_idx, SOURCE_VPf, vp); 397 BCM_IF_ERROR_RETURN(rv); 398 /* Enable SVP Mode */ 399 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf) ) { 400 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 401 src_trk_idx, SVP_VALIDf, 0x1); 402 BCM_IF_ERROR_RETURN(rv); 403 } 404 if (is_local) { 405 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, 406 l2gre_port->match_port, _BCM_CPU_TABS_NONE, 407 PORT_OPERATIONf, 0x1)); /* L2_SVP */ 408 409 /* Set TAG_ACTION_PROFILE_PTR */ 410 rv = bcm_tr3_l2gre_port_untagged_profile_set(unit, port_out); 411 BCM_IF_ERROR_RETURN(rv); 412 } 413 414 l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_PORT; 415 l2gre_info->match_key[vp].index = src_trk_idx; 416 } 417 }else if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_VPNID) { 418 BCM_IF_ERROR_RETURN( 419 bcm_tr3_l2gre_match_tunnel_entry_set(unit, vp, l2gre_port)); 420 } 421 422 return rv; 423 } 424 425 /* 426 * Function: 427 * bcm_td2_l2gre_match_delete 428 * Purpose: 429 * Delete match criteria of an L2GRE port 430 * Parameters: 431 * unit - (IN) Device Number 432 * l2gre_port - (IN) L2GRE port information 433 * vp - (IN) Source Virtual Port 434 * Returns: 435 * BCM_E_XXX 436 */ 437 438 int 439 bcm_td2_l2gre_match_delete(int unit, int vp, bcm_l2gre_port_t *l2gre_port) 440 { 441 _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit); 442 int rv=BCM_E_NONE; 443 bcm_trunk_t trunk_id; 444 int mod_id_idx=0; /* Module_Id */ 445 soc_mem_t mem; 446 uint32 vent[SOC_MAX_MEM_WORDS] = {0}; 447 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 448 bcm_module_t mod_out = -1; 449 bcm_port_t port_out = -1; 450 int gport_id =-1; 451 #endif 452 int src_trk_idx = 0; /*Source Trunk table index.*/ 453 int port = 0; 454 455 #if defined(BCM_TRIDENT3_SUPPORT) 456 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 457 mem = VLAN_XLATE_1_DOUBLEm; 458 459 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 460 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 461 } else 462 #endif 463 { 464 mem = VLAN_XLATEm; 465 466 soc_mem_field32_set(unit, mem, vent, VALIDf, 1); 467 } 468 469 /* Get module id for unit. */ 470 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_id_idx)); 471 472 if (l2gre_info->match_key[vp].flags == _BCM_L2GRE_PORT_MATCH_TYPE_VLAN) { 473 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 474 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 475 #if defined(BCM_TRIDENT3_SUPPORT) 476 if (mem == VLAN_XLATE_1_DOUBLEm) { 477 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 478 TR_VLXLT_HASH_KEY_TYPE_OVID); 479 } 480 #endif 481 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, 482 l2gre_info->match_key[vp].match_vlan); 483 if (l2gre_info->match_key[vp].modid != -1) { 484 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, 485 l2gre_info->match_key[vp].modid); 486 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, 487 l2gre_info->match_key[vp].port); 488 } else { 489 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 490 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, 491 l2gre_info->match_key[vp].trunk_id); 492 } 493 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 494 BCM_IF_ERROR_RETURN(rv); 495 496 (void) bcm_tr3_l2gre_match_clear (unit, vp); 497 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1); 498 } else if (l2gre_info->match_key[vp].flags == 499 _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN) { 500 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 501 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, VLXLT_HASH_KEY_TYPE_IVID); 502 #if defined(BCM_TRIDENT3_SUPPORT) 503 if (mem == VLAN_XLATE_1_DOUBLEm) { 504 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 505 VLXLT_HASH_KEY_TYPE_IVID); 506 } 507 #endif 508 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, 509 l2gre_info->match_key[vp].match_inner_vlan); 510 if (l2gre_info->match_key[vp].modid != -1) { 511 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, 512 l2gre_info->match_key[vp].modid); 513 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, 514 l2gre_info->match_key[vp].port); 515 } else { 516 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 517 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, 518 l2gre_info->match_key[vp].trunk_id); 519 } 520 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, &vent); 521 BCM_IF_ERROR_RETURN(rv); 522 523 (void) bcm_tr3_l2gre_match_clear (unit, vp); 524 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1); 525 } else if (l2gre_info->match_key[vp].flags == 526 _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED) { 527 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 528 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 529 #if defined(BCM_TRIDENT3_SUPPORT) 530 if (mem == VLAN_XLATE_1_DOUBLEm) { 531 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 532 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 533 } 534 #endif 535 soc_mem_field32_set(unit, mem, vent, 536 XLATE__OVIDf, l2gre_info->match_key[vp].match_vlan); 537 soc_mem_field32_set(unit, mem, vent, 538 XLATE__IVIDf, l2gre_info->match_key[vp].match_inner_vlan); 539 if (l2gre_info->match_key[vp].modid != -1) { 540 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, 541 l2gre_info->match_key[vp].modid); 542 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, 543 l2gre_info->match_key[vp].port); 544 } else { 545 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 546 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, 547 l2gre_info->match_key[vp].trunk_id); 548 } 549 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 550 BCM_IF_ERROR_RETURN(rv); 551 552 (void) bcm_tr3_l2gre_match_clear (unit, vp); 553 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1); 554 } else if (l2gre_info->match_key[vp].flags == 555 _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI) { 556 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 557 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 558 #if defined(BCM_TRIDENT3_SUPPORT) 559 if (mem == VLAN_XLATE_1_DOUBLEm) { 560 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 561 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 562 } 563 #endif 564 565 soc_mem_field32_set(unit, mem, vent, XLATE__OTAGf, 566 l2gre_info->match_key[vp].match_vlan); 567 if (l2gre_info->match_key[vp].modid != -1) { 568 soc_mem_field32_set(unit, mem, vent, 569 XLATE__MODULE_IDf, l2gre_info->match_key[vp].modid); 570 soc_mem_field32_set(unit, mem, vent, 571 XLATE__PORT_NUMf, l2gre_info->match_key[vp].port); 572 } else { 573 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 574 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, 575 l2gre_info->match_key[vp].trunk_id); 576 } 577 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 578 BCM_IF_ERROR_RETURN(rv); 579 580 (void) bcm_tr3_l2gre_match_clear (unit, vp); 581 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1); 582 } 583 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 584 else if (l2gre_info->match_key[vp].flags == 585 _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 586 bcm_trunk_t trunk_id = -1; 587 if (NULL == l2gre_port) { 588 return BCM_E_PARAM; 589 } 590 591 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 592 593 if (BCM_L2GRE_PORT_MATCH_PORT_VLAN == l2gre_port->criteria) { 594 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 595 TR_VLXLT_HASH_KEY_TYPE_OVID); 596 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, 597 l2gre_port->match_vlan); 598 } else if (BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED == l2gre_port->criteria) { 599 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 600 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 601 #if defined(BCM_TRIDENT3_SUPPORT) 602 if (mem == VLAN_XLATE_1_DOUBLEm) { 603 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 604 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 605 } 606 #endif 607 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, 608 l2gre_port->match_vlan); 609 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, 610 l2gre_port->match_inner_vlan); 611 } else if (BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN == l2gre_port->criteria) { 612 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 613 TR_VLXLT_HASH_KEY_TYPE_IVID); 614 #if defined(BCM_TRIDENT3_SUPPORT) 615 if (mem == VLAN_XLATE_1_DOUBLEm) { 616 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 617 TR_VLXLT_HASH_KEY_TYPE_IVID); 618 } 619 #endif 620 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, 621 l2gre_port->match_inner_vlan); 622 } else if (BCM_L2GRE_PORT_MATCH_VLAN_PRI == l2gre_port->criteria) { 623 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, 624 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 625 #if defined(BCM_TRIDENT3_SUPPORT) 626 if (mem == VLAN_XLATE_1_DOUBLEm) { 627 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 628 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 629 } 630 #endif 631 soc_mem_field32_set(unit, mem, vent, XLATE__OTAGf, 632 l2gre_port->match_vlan); 633 } else { 634 return BCM_E_UNAVAIL; 635 } 636 637 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, l2gre_port->match_port, &mod_out, 638 &port_out, &trunk_id, &gport_id)); 639 640 if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) { 641 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 642 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 643 } else { 644 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out); 645 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out); 646 } 647 648 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, &vent); 649 BCM_IF_ERROR_RETURN(rv); 650 651 bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1); 652 } 653 #endif 654 else if (l2gre_info->match_key[vp].flags == 655 _BCM_L2GRE_PORT_MATCH_TYPE_PORT) { 656 int is_local; 657 658 src_trk_idx = l2gre_info->match_key[vp].index; 659 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 660 src_trk_idx, SOURCE_VPf, 0); 661 BCM_IF_ERROR_RETURN(rv); 662 /* Disable SVP Mode */ 663 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf) ) { 664 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 665 src_trk_idx, SVP_VALIDf, 0x0); 666 BCM_IF_ERROR_RETURN(rv); 667 } 668 669 BCM_IF_ERROR_RETURN(_bcm_esw_src_modid_port_get( unit, src_trk_idx, 670 &mod_id_idx, &port)); 671 BCM_IF_ERROR_RETURN 672 ( _bcm_esw_modid_is_local(unit, mod_id_idx, &is_local)); 673 674 if (is_local) { 675 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, 676 port, _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0x0)); 677 678 /* Reset TAG_ACTION_PROFILE_PTR */ 679 rv = bcm_tr3_l2gre_port_untagged_profile_reset(unit, port); 680 BCM_IF_ERROR_RETURN(rv); 681 } 682 (void) bcm_tr3_l2gre_match_clear (unit, vp); 683 } else if (l2gre_info->match_key[vp].flags == 684 _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK) { 685 trunk_id = l2gre_info->match_key[vp].trunk_id; 686 rv = bcm_tr3_l2gre_match_trunk_delete(unit, trunk_id, vp); 687 BCM_IF_ERROR_RETURN(rv); 688 689 (void) bcm_tr3_l2gre_match_clear (unit, vp); 690 } else if (l2gre_info->match_key[vp].flags == 691 _BCM_L2GRE_PORT_MATCH_TYPE_VPNID) { 692 rv = bcm_tr3_l2gre_match_tunnel_entry_reset(unit, vp); 693 } 694 return rv; 695 } 696 697 /* 698 * Function: 699 * _bcm_td2_l2gre_match_get 700 * Purpose: 701 * Obtain match information of an l2gre port 702 * Parameters: 703 * unit - (IN) Device Number 704 * l2gre_port - (OUT) l2gre port information 705 * vp - (IN) Source Virtual Port 706 * Returns: 707 * BCM_E_XXX 708 */ 709 710 int 711 bcm_td2_l2gre_match_get(int unit, bcm_l2gre_port_t *l2gre_port, int vp) 712 { 713 _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit); 714 bcm_module_t mod_in=0, mod_out=0; 715 bcm_port_t port_in=0, port_out=0; 716 bcm_trunk_t trunk_id=0; 717 int src_trk_idx=0; /*Source Trunk table index.*/ 718 int tunnel_idx = -1; 719 int index; 720 soc_mem_t mem; 721 uint32 vent[SOC_MAX_MEM_WORDS] = {0}; 722 723 #if defined(BCM_TRIDENT3_SUPPORT) 724 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 725 mem = VLAN_XLATE_1_DOUBLEm; 726 727 soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3); 728 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 729 } else 730 #endif 731 { 732 mem = VLAN_XLATEm; 733 734 soc_mem_field32_set(unit, mem, vent, VALIDf, 1); 735 } 736 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 737 738 if (l2gre_info->match_key[vp].flags & _BCM_L2GRE_PORT_MATCH_TYPE_VLAN) { 739 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID); 740 #if defined(BCM_TRIDENT3_SUPPORT) 741 if (mem == VLAN_XLATE_1_DOUBLEm) { 742 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 743 TR_VLXLT_HASH_KEY_TYPE_OVID); 744 } 745 #endif 746 747 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN; 748 l2gre_port->match_vlan = l2gre_info->match_key[vp].match_vlan; 749 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan); 750 } else if (l2gre_info->match_key[vp].flags & 751 _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN) { 752 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID); 753 #if defined(BCM_TRIDENT3_SUPPORT) 754 if (mem == VLAN_XLATE_1_DOUBLEm) { 755 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 756 TR_VLXLT_HASH_KEY_TYPE_IVID); 757 } 758 #endif 759 760 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN; 761 l2gre_port->match_inner_vlan = l2gre_info->match_key[vp].match_inner_vlan; 762 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan); 763 }else if (l2gre_info->match_key[vp].flags & 764 _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED) { 765 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 766 #if defined(BCM_TRIDENT3_SUPPORT) 767 if (mem == VLAN_XLATE_1_DOUBLEm) { 768 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 769 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID); 770 } 771 #endif 772 773 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED; 774 l2gre_port->match_vlan = l2gre_info->match_key[vp].match_vlan; 775 l2gre_port->match_inner_vlan = l2gre_info->match_key[vp].match_inner_vlan; 776 soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan); 777 soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan); 778 } else if (l2gre_info->match_key[vp].flags & _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI) { 779 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 780 #if defined(BCM_TRIDENT3_SUPPORT) 781 if (mem == VLAN_XLATE_1_DOUBLEm) { 782 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 783 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI); 784 } 785 #endif 786 787 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI; 788 l2gre_port->match_vlan = l2gre_info->match_key[vp].match_vlan; 789 soc_mem_field32_set(unit, mem, vent, OTAGf, l2gre_port->match_vlan); 790 } else if (l2gre_info->match_key[vp].flags & 791 _BCM_L2GRE_PORT_MATCH_TYPE_PORT) { 792 793 src_trk_idx = l2gre_info->match_key[vp].index; 794 BCM_IF_ERROR_RETURN(_bcm_esw_src_modid_port_get( unit, src_trk_idx, 795 &mod_in, &port_in)); 796 797 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT; 798 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, 799 BCM_STK_MODMAP_GET, mod_in, port_in, &mod_out, &port_out)); 800 BCM_GPORT_MODPORT_SET(l2gre_port->match_port, mod_out, port_out); 801 }else if (l2gre_info->match_key[vp].flags & 802 _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK) { 803 804 trunk_id = l2gre_info->match_key[vp].trunk_id; 805 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT; 806 BCM_GPORT_TRUNK_SET(l2gre_port->match_port, trunk_id); 807 } else if ((l2gre_info->match_key[vp].flags & 808 _BCM_L2GRE_PORT_MATCH_TYPE_VPNID)) { 809 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_VPNID; 810 811 tunnel_idx = l2gre_info->match_key[vp].match_tunnel_index; 812 BCM_GPORT_TUNNEL_ID_SET(l2gre_port->match_tunnel_id, tunnel_idx); 813 }else if (l2gre_info->match_key[vp].flags & _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) { 814 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_SHARE; 815 } else { 816 l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_NONE; 817 } 818 819 if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_VLAN || 820 l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN || 821 l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED || 822 l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_VLAN_PRI) { 823 824 if (l2gre_info->match_key[vp].trunk_id != -1) { 825 trunk_id = l2gre_info->match_key[vp].trunk_id; 826 BCM_GPORT_TRUNK_SET(l2gre_port->match_port, trunk_id); 827 soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1); 828 soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id); 829 } else { 830 port_in = l2gre_info->match_key[vp].port; 831 mod_in = l2gre_info->match_key[vp].modid; 832 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, 833 BCM_STK_MODMAP_GET, mod_in, port_in, &mod_out, &port_out)); 834 BCM_GPORT_MODPORT_SET(l2gre_port->match_port, mod_out, port_out); 835 soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_in); 836 soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_in); 837 } 838 839 BCM_IF_ERROR_RETURN( 840 soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vent, vent, 0)); 841 842 if (soc_mem_field32_get(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf)) { 843 l2gre_port->flags |= BCM_L2GRE_PORT_ENABLE_VLAN_CHECKS; 844 } 845 } 846 847 return BCM_E_NONE; 848 } 849 850 /* 851 * Function: 852 * _bcm_td2_l2gre_eline_vp_configure 853 * Purpose: 854 * Configure L2GRE ELINE virtual port 855 * Parameters: 856 * unit - (IN) Device Number 857 * vpn - (IN) VPN instance ID 858 * Returns: 859 * BCM_E_XXX 860 */ 861 862 int 863 _bcm_td2_l2gre_eline_vp_configure (int unit, int vfi_index, int active_vp, 864 source_vp_entry_t *svp, int tpid_enable, bcm_l2gre_port_t *l2gre_port) 865 { 866 int rv = BCM_E_NONE; 867 int network_group=0; 868 source_vp_2_entry_t svp_2_entry; 869 870 /* Set SOURCE_VP */ 871 soc_SOURCE_VPm_field32_set(unit, svp, CLASS_IDf, 872 l2gre_port->if_class); 873 874 network_group = l2gre_port->network_group_id; 875 rv = _bcm_validate_splithorizon_network_group(unit, 876 l2gre_port->flags & BCM_L2GRE_PORT_NETWORK, &network_group); 877 BCM_IF_ERROR_RETURN(rv); 878 879 /*Default Split Horizon Group Id 880 *0 - For Access Port;1 - For Network Port*/ 881 if (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK) { 882 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 883 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf, 884 network_group); 885 } else { 886 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 1); 887 } 888 #if defined(BCM_TRIDENT3_SUPPORT) 889 if (SOC_IS_TRIDENT3X(unit)) { 890 } else 891 #endif 892 { 893 soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SVP_BASED); 894 } 895 } else { 896 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 897 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf, 898 network_group); 899 } else { 900 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 0); 901 } 902 #if defined(BCM_TRIDENT3_SUPPORT) 903 if (SOC_IS_TRIDENT3X(unit)) { 904 } else 905 #endif 906 { 907 soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SGLP_BASED); 908 /* Configure IPARS Parser to signal to IMPLS Parser - Applicable only for HG2 PPD2 packets 909 to reconstruct TPID state based on HG header information - Only for VXLAN Access ports */ 910 sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t)); 911 soc_SOURCE_VP_2m_field32_set(unit, &svp_2_entry, PARSE_USING_SGLP_TPIDf, 1); 912 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VP_2m(unit, 913 MEM_BLOCK_ALL, active_vp, &svp_2_entry)); 914 } 915 } 916 917 if (l2gre_port->flags & BCM_L2GRE_PORT_SERVICE_TAGGED) { 918 soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 1); 919 #if defined(BCM_TRIDENT3_SUPPORT) 920 if (SOC_IS_TRIDENT3X(unit)) { 921 uint32 svp1[SOC_MAX_MEM_WORDS]; 922 923 sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 924 925 soc_SVP_ATTRS_1m_field_set(unit, &svp1, TPID_ENABLEf, (uint32 *)&tpid_enable); 926 BCM_IF_ERROR_RETURN(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, active_vp, &svp1)); 927 } else 928 #endif 929 { 930 soc_SOURCE_VPm_field32_set(unit, svp, TPID_ENABLEf, tpid_enable); 931 } 932 } else { 933 soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 0); 934 } 935 936 soc_SOURCE_VPm_field32_set(unit, svp, DISABLE_VLAN_CHECKSf, 1); 937 soc_SOURCE_VPm_field32_set(unit, svp, 938 ENTRY_TYPEf, _BCM_L2GRE_SOURCE_VP_TYPE_VFI); /* VFI Type */ 939 soc_SOURCE_VPm_field32_set(unit, svp, VFIf, vfi_index); 940 941 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, active_vp, svp); 942 943 #if defined(BCM_TRIDENT3_SUPPORT) 944 if (SOC_IS_TRIDENT3X(unit)) { 945 if ((vfi_index != _BCM_L2GRE_VFI_INVALID) && 946 (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK)) { 947 if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm, 948 active_vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word, 949 _BCM_L2GRE_SOURCE_VP_TYPE_VFI)) { 950 LOG_ERROR(BSL_LS_BCM_L2GRE, 951 (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n"))); 952 } 953 } 954 } 955 #endif 956 957 return rv; 958 } 959 960 /* 961 * Function: 962 * _bcm_td2_l2gre_elan_vp_configure 963 * Purpose: 964 * Configure L2GRE ELAN virtual port 965 * Parameters: 966 * unit - (IN) Device Number 967 * vpn - (IN) VPN instance ID 968 * Returns: 969 * BCM_E_XXX 970 */ 971 972 int 973 _bcm_td2_l2gre_elan_vp_configure (int unit, int vfi_index, int vp, 974 source_vp_entry_t *svp, int tpid_enable, bcm_l2gre_port_t *l2gre_port) 975 { 976 int rv = BCM_E_NONE; 977 int network_group=0; 978 int cml_default_enable=0, cml_default_new=0, cml_default_move=0; 979 source_vp_2_entry_t svp_2_entry; 980 981 /* Set SOURCE_VP */ 982 soc_SOURCE_VPm_field32_set(unit, svp, CLASS_IDf, 983 l2gre_port->if_class); 984 985 if (vfi_index == _BCM_L2GRE_VFI_INVALID) { 986 soc_SOURCE_VPm_field32_set(unit, svp, 987 ENTRY_TYPEf, _BCM_L2GRE_SOURCE_VP_TYPE_INVALID); /* INVALID */ 988 } else { 989 /* Initialize VP parameters */ 990 soc_SOURCE_VPm_field32_set(unit, svp, 991 ENTRY_TYPEf, _BCM_L2GRE_SOURCE_VP_TYPE_VFI); /* VFI Type */ 992 } 993 994 995 /*Default Split Horizon Group Id 996 *0 - For Access Port;1 - For Network Port*/ 997 network_group = l2gre_port->network_group_id; 998 rv = _bcm_validate_splithorizon_network_group(unit, 999 l2gre_port->flags & BCM_L2GRE_PORT_NETWORK, &network_group); 1000 BCM_IF_ERROR_RETURN(rv); 1001 1002 if (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK) { 1003 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 1004 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf, 1005 network_group); 1006 } else { 1007 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 1); 1008 } 1009 #if defined(BCM_TRIDENT3_SUPPORT) 1010 if (SOC_IS_TRIDENT3X(unit)) { 1011 } else 1012 #endif 1013 { 1014 soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SVP_BASED); 1015 } 1016 } else { 1017 if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) { 1018 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf, 1019 network_group); 1020 } else { 1021 soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 0); 1022 } 1023 #if defined(BCM_TRIDENT3_SUPPORT) 1024 if (SOC_IS_TRIDENT3X(unit)) { 1025 } else 1026 #endif 1027 { 1028 soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SGLP_BASED); 1029 /* Configure IPARS Parser to signal to IMPLS Parser - Applicable only for HG2 PPD2 packets 1030 to reconstruct TPID state based on HG header information - Only for VXLAN Access ports */ 1031 sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t)); 1032 soc_SOURCE_VP_2m_field32_set(unit, &svp_2_entry, PARSE_USING_SGLP_TPIDf, 1); 1033 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VP_2m(unit, MEM_BLOCK_ALL, vp, &svp_2_entry)); 1034 } 1035 } 1036 1037 if (vfi_index == _BCM_L2GRE_VFI_INVALID) { 1038 soc_SOURCE_VPm_field32_set(unit, svp, VFIf, 0); 1039 } else { 1040 soc_SOURCE_VPm_field32_set(unit, svp, VFIf, vfi_index); 1041 } 1042 1043 if (l2gre_port->flags & BCM_L2GRE_PORT_SERVICE_TAGGED) { 1044 soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 1); 1045 #if defined(BCM_TRIDENT3_SUPPORT) 1046 if (SOC_IS_TRIDENT3X(unit)) { 1047 uint32 svp1[SOC_MAX_MEM_WORDS]; 1048 1049 sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1050 1051 soc_SVP_ATTRS_1m_field_set(unit, &svp1, TPID_ENABLEf, (uint32 *)&tpid_enable); 1052 BCM_IF_ERROR_RETURN(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, vp, &svp1)); 1053 } else 1054 #endif 1055 { 1056 soc_SOURCE_VPm_field32_set(unit, svp, TPID_ENABLEf, tpid_enable); 1057 } 1058 } else { 1059 soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 0); 1060 } 1061 rv = _bcm_vp_default_cml_mode_get (unit, 1062 &cml_default_enable, &cml_default_new, 1063 &cml_default_move); 1064 if (rv < 0) { 1065 return rv; 1066 } 1067 if (cml_default_enable) { 1068 /* Set the CML to default values */ 1069 soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_NEWf, cml_default_new); 1070 soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_MOVEf, cml_default_move); 1071 } else { 1072 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 1073 soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_NEWf, 0x8); 1074 soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_MOVEf, 0x8); 1075 } 1076 if (soc_mem_field_valid(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) { 1077 if (!soc_feature(unit, soc_feature_vlan_vfi_membership)) { 1078 soc_SOURCE_VPm_field32_set(unit, svp, DISABLE_VLAN_CHECKSf, 1); 1079 } 1080 } 1081 1082 BCM_IF_ERROR_RETURN 1083 (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, svp)); 1084 1085 #if defined(BCM_TRIDENT3_SUPPORT) 1086 if (SOC_IS_TRIDENT3X(unit)) { 1087 if ((vfi_index != _BCM_L2GRE_VFI_INVALID) && 1088 (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK)) { 1089 if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm, 1090 vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word, 1091 _BCM_L2GRE_SOURCE_VP_TYPE_VFI)) { 1092 LOG_ERROR(BSL_LS_BCM_L2GRE, 1093 (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n"))); 1094 } 1095 } 1096 } 1097 #endif 1098 1099 return rv; 1100 } 1101 /* 1102 * Function: 1103 * _bcm_td2_l2gre_match_vp_replace 1104 * Purpose: 1105 * Replace VP value in L2GRE VP's match entry. 1106 * Parameters: 1107 * unit - (IN) SOC unit number. 1108 * vp - (IN) L2GRE VP whose match entry is being replaced. 1109 * new_vp - (IN) New VP value. 1110 * old_vp - (OUT) Old VP value. 1111 * Returns: 1112 * BCM_X_XXX 1113 */ 1114 STATIC int 1115 _bcm_td2_l2gre_match_vp_replace(int unit, int vp, int new_vp, 1116 int *old_vp) 1117 { 1118 int rv = BCM_E_NONE; 1119 soc_mem_t mem; 1120 int key_type = bcmVlanTranslateKeyInvalid; 1121 uint32 svp_valid, tunnel_index, tunnel_sip; 1122 int entry_index; 1123 int port, my_modid, stm_idx, i; 1124 int local_port[SOC_MAX_NUM_PORTS]; 1125 int local_port_count = 0; 1126 uint32 vent[SOC_MAX_MEM_WORDS], old_vent[SOC_MAX_MEM_WORDS]; 1127 source_trunk_map_table_entry_t stm_entry; 1128 uint32 ment[SOC_MAX_MEM_WORDS]; 1129 _bcm_l2gre_match_port_info_t *mkey = NULL; 1130 1131 mkey = &(L2GRE_INFO(unit)->match_key[vp]); 1132 1133 switch (mkey->flags) { 1134 case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN: 1135 if (key_type == bcmVlanTranslateKeyInvalid) { 1136 key_type = bcmVlanTranslateKeyPortOuter; 1137 } 1138 /* Fall through */ 1139 case _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN: 1140 if (key_type == bcmVlanTranslateKeyInvalid) { 1141 key_type = bcmVlanTranslateKeyPortInner; 1142 } 1143 /* Fall through */ 1144 case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED: 1145 if (key_type == bcmVlanTranslateKeyInvalid) { 1146 key_type = bcmVlanTranslateKeyPortDouble; 1147 } 1148 /* Fall through */ 1149 case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI: 1150 if (key_type == bcmVlanTranslateKeyInvalid) { 1151 key_type = bcmVlanTranslateKeyPortOuterPri; 1152 } 1153 1154 mem = VLAN_XLATEm; 1155 1156 if (mkey->modid != -1) { 1157 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port); 1158 } else { 1159 BCM_GPORT_TRUNK_SET(port, mkey->trunk_id); 1160 } 1161 /* Construct lookup key */ 1162 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1163 rv = _bcm_trx_vlan_translate_entry_assemble( 1164 unit, &vent, port, key_type, mkey->match_inner_vlan, 1165 mkey->match_vlan); 1166 if (BCM_FAILURE(rv)) { 1167 return rv; 1168 } 1169 soc_mem_lock(unit, mem); 1170 /* Lookup existing entry */ 1171 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, 1172 &entry_index, vent, old_vent, 0); 1173 if (BCM_FAILURE(rv)) { 1174 soc_mem_unlock(unit, mem); 1175 return rv; 1176 } 1177 /* Replace entry's VP value */ 1178 *old_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf); 1179 soc_mem_field32_set(unit, mem, old_vent, SOURCE_VPf, new_vp); 1180 1181 /* Insert new entry */ 1182 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, old_vent); 1183 if (rv == SOC_E_EXISTS) { 1184 rv = BCM_E_NONE; 1185 } else { 1186 soc_mem_unlock(unit, mem); 1187 return BCM_E_INTERNAL; 1188 } 1189 soc_mem_unlock(unit, mem); 1190 break; 1191 case _BCM_L2GRE_PORT_MATCH_TYPE_PORT: 1192 mem = SOURCE_TRUNK_MAP_TABLEm; 1193 1194 soc_mem_lock(unit, mem); 1195 1196 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, mkey->index, 1197 &stm_entry); 1198 if (BCM_FAILURE(rv)) { 1199 soc_mem_unlock(unit, mem); 1200 return rv; 1201 } 1202 /* Resolve SVP Mode */ 1203 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 1204 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry, 1205 SVP_VALIDf); 1206 if (svp_valid == 0) { 1207 soc_mem_unlock(unit, mem); 1208 return BCM_E_INTERNAL; 1209 } 1210 } 1211 *old_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf); 1212 rv = soc_mem_field32_modify(unit, mem, mkey->index, SOURCE_VPf, 1213 new_vp); 1214 soc_mem_unlock(unit, mem); 1215 break; 1216 case _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK: 1217 mem = SOURCE_TRUNK_MAP_TABLEm; 1218 1219 /* Get module id for unit. */ 1220 rv = bcm_esw_stk_my_modid_get(unit, &my_modid); 1221 if (BCM_FAILURE(rv)) { 1222 return rv; 1223 } 1224 1225 rv = _bcm_esw_trunk_local_members_get( 1226 unit, mkey->trunk_id, SOC_MAX_NUM_PORTS, 1227 local_port, &local_port_count); 1228 if (BCM_FAILURE(rv)) { 1229 return rv; 1230 } 1231 1232 soc_mem_lock(unit, mem); 1233 for (i = 0; i < local_port_count; i++) { 1234 /* Get index to source trunk map table */ 1235 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 1236 local_port[i], 1237 &stm_idx); 1238 if (BCM_FAILURE(rv)) { 1239 soc_mem_unlock(unit, mem); 1240 return rv; 1241 } 1242 1243 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx, 1244 &stm_entry); 1245 if (BCM_FAILURE(rv)) { 1246 soc_mem_unlock(unit, mem); 1247 return rv; 1248 } 1249 1250 /* Resolve SVP Mode */ 1251 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 1252 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry, 1253 SVP_VALIDf); 1254 if (svp_valid == 0) { 1255 soc_mem_unlock(unit, mem); 1256 return BCM_E_INTERNAL; 1257 } 1258 } 1259 *old_vp = soc_mem_field32_get(unit, mem, &stm_entry, 1260 SOURCE_VPf); 1261 rv = soc_mem_field32_modify(unit, mem, stm_idx, SOURCE_VPf, 1262 new_vp); 1263 if (BCM_FAILURE(rv)) { 1264 soc_mem_unlock(unit, mem); 1265 return rv; 1266 } 1267 } 1268 1269 soc_mem_unlock(unit, mem); 1270 break; 1271 case _BCM_L2GRE_PORT_MATCH_TYPE_VPNID: 1272 tunnel_index = mkey->match_tunnel_index; 1273 tunnel_sip = L2GRE_INFO(unit)->l2gre_tunnel_term[tunnel_index].sip; 1274 1275 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1276 mem = MPLS_ENTRYm; 1277 soc_mem_lock(unit, mem); 1278 soc_mem_field32_set(unit, mem, &ment, VALIDf, 1); 1279 1280 soc_mem_field32_set(unit, mem, &ment, L2GRE_SIP__SIPf, tunnel_sip); 1281 soc_mem_field32_set(unit, mem, &ment, KEY_TYPEf, 1282 _BCM_L2GRE_KEY_TYPE_TUNNEL); 1283 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, &ment, 1284 &ment, 0); 1285 1286 if (rv == BCM_E_NOT_FOUND) { 1287 rv = BCM_E_PARAM; 1288 } 1289 1290 if (BCM_FAILURE(rv)) { 1291 soc_mem_unlock(unit, mem); 1292 return rv; 1293 } 1294 1295 /* Replace entry's VP value */ 1296 *old_vp = soc_mem_field32_get(unit, mem, &ment, L2GRE_SIP__SVPf); 1297 soc_mem_field32_set(unit, mem, &ment, L2GRE_SIP__SVPf, new_vp); 1298 /* Insert new entry */ 1299 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, ment); 1300 1301 soc_mem_unlock(unit, mem); 1302 1303 if (rv == SOC_E_EXISTS) { 1304 rv = BCM_E_NONE; 1305 } else { 1306 return BCM_E_INTERNAL; 1307 } 1308 break; 1309 default: 1310 return BCM_E_PARAM; 1311 } 1312 1313 return rv; 1314 } 1315 1316 /* 1317 * Function: 1318 * bcm_td2_l2gre_port_source_vp_lag_set 1319 * Purpose: 1320 * Set source VP LAG for a L2GRE virtual port. 1321 * Parameters: 1322 * unit - (IN) SOC unit number. 1323 * gport - (IN) L2GRE virtual port GPORT ID. 1324 * vp_lag_vp - (IN) VP representing the VP LAG. 1325 * Returns: 1326 * BCM_X_XXX 1327 */ 1328 int 1329 bcm_td2_l2gre_port_source_vp_lag_set(int unit, bcm_gport_t gport, 1330 int vp_lag_vp) 1331 { 1332 int vp, old_vp; 1333 int rv = BCM_E_NONE; 1334 1335 if (!BCM_GPORT_IS_L2GRE_PORT(gport)) { 1336 return BCM_E_PARAM; 1337 } 1338 1339 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 1340 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 1341 return BCM_E_PARAM; 1342 } 1343 1344 /* Set source VP LAG by replacing the SVP field in L2GRE VP's 1345 * match entry with the VP value representing the VP LAG. 1346 */ 1347 rv = _bcm_td2_l2gre_match_vp_replace(unit, vp, vp_lag_vp, &old_vp); 1348 if (BCM_FAILURE(rv)) { 1349 return rv; 1350 } 1351 1352 return rv; 1353 } 1354 /* 1355 * Function: 1356 * bcm_td2_l2gre_port_source_vp_lag_clear 1357 * Purpose: 1358 * Clear source VP LAG for a L2GRE virtual port. 1359 * Parameters: 1360 * unit - (IN) SOC unit number. 1361 * gport - (IN) L2GRE virtual port GPORT ID. 1362 * vp_lag_vp - (IN) VP representing the VP LAG. 1363 * Returns: 1364 * BCM_X_XXX 1365 */ 1366 int 1367 bcm_td2_l2gre_port_source_vp_lag_clear(int unit, bcm_gport_t gport, 1368 int vp_lag_vp) 1369 { 1370 int vp, old_vp; 1371 1372 if (!BCM_GPORT_IS_L2GRE_PORT(gport)) { 1373 return BCM_E_PARAM; 1374 } 1375 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 1376 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 1377 return BCM_E_PARAM; 1378 } 1379 1380 /* Clear source VP LAG by replacing the SVP field in L2GRE VP's 1381 * match entry with the VP value. 1382 */ 1383 BCM_IF_ERROR_RETURN( 1384 _bcm_td2_l2gre_match_vp_replace(unit, vp, vp, &old_vp)); 1385 1386 /* Check that the old VP value matches the VP value representing 1387 * the VP LAG or has been restored. 1388 */ 1389 if ((old_vp != vp_lag_vp) && (old_vp != vp)) { 1390 return BCM_E_INTERNAL; 1391 } 1392 1393 return BCM_E_NONE; 1394 } 1395 1396 /* 1397 * Function: 1398 * bcm_td2_l2gre_port_source_vp_lag_get 1399 * Purpose: 1400 * Get source VP LAG for a L2GRE virtual port. 1401 * Parameters: 1402 * unit - (IN) SOC unit number. 1403 * gport - (IN) L2GRE virtual port GPORT ID. 1404 * vp_lag_vp - (OUT) VP representing the VP LAG. 1405 * Returns: 1406 * BCM_X_XXX 1407 */ 1408 int 1409 bcm_td2_l2gre_port_source_vp_lag_get(int unit, bcm_gport_t gport, 1410 int *vp_lag_vp) 1411 { 1412 int rv = BCM_E_NONE; 1413 soc_mem_t mem; 1414 int key_type = bcmVlanTranslateKeyInvalid; 1415 bcm_gport_t vp; 1416 uint32 svp_valid, tunnel_index, tunnel_sip; 1417 int entry_index; 1418 int port, my_modid, stm_idx; 1419 int local_port[SOC_MAX_NUM_PORTS]; 1420 int local_port_count = 0; 1421 uint32 vent[SOC_MAX_MEM_WORDS], old_vent[SOC_MAX_MEM_WORDS]; 1422 uint32 ment[SOC_MAX_MEM_WORDS]; 1423 source_trunk_map_table_entry_t stm_entry; 1424 _bcm_l2gre_match_port_info_t *mkey = NULL; 1425 1426 1427 if (!BCM_GPORT_IS_L2GRE_PORT(gport)) { 1428 return BCM_E_PARAM; 1429 } 1430 1431 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 1432 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 1433 return BCM_E_PARAM; 1434 } 1435 1436 mkey = &(L2GRE_INFO(unit)->match_key[vp]); 1437 1438 switch (mkey->flags) { 1439 case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN: 1440 if (key_type == bcmVlanTranslateKeyInvalid) { 1441 key_type = bcmVlanTranslateKeyPortOuter; 1442 } 1443 /* Fall through */ 1444 case _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN: 1445 if (key_type == bcmVlanTranslateKeyInvalid) { 1446 key_type = bcmVlanTranslateKeyPortInner; 1447 } 1448 /* Fall through */ 1449 case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED: 1450 if (key_type == bcmVlanTranslateKeyInvalid) { 1451 key_type = bcmVlanTranslateKeyPortDouble; 1452 } 1453 /* Fall through */ 1454 case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI: 1455 if (key_type == bcmVlanTranslateKeyInvalid) { 1456 key_type = bcmVlanTranslateKeyPortOuterPri; 1457 } 1458 1459 mem = VLAN_XLATEm; 1460 1461 if (mkey->modid != -1) { 1462 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port); 1463 } else { 1464 BCM_GPORT_TRUNK_SET(port, mkey->trunk_id); 1465 } 1466 /* Construct lookup key */ 1467 sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1468 rv = _bcm_trx_vlan_translate_entry_assemble( 1469 unit, &vent, port, key_type, mkey->match_inner_vlan, 1470 mkey->match_vlan); 1471 if (BCM_FAILURE(rv)) { 1472 return rv; 1473 } 1474 /* Lookup existing entry */ 1475 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &entry_index, vent, 1476 old_vent, 0); 1477 if (BCM_FAILURE(rv)) { 1478 return rv; 1479 } 1480 /* Get VP value representing VP LAG */ 1481 *vp_lag_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf); 1482 break; 1483 case _BCM_L2GRE_PORT_MATCH_TYPE_PORT: 1484 mem = SOURCE_TRUNK_MAP_TABLEm; 1485 1486 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, mkey->index, 1487 &stm_entry); 1488 if (BCM_FAILURE(rv)) { 1489 return rv; 1490 } 1491 /* Resolve SVP Mode */ 1492 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 1493 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry, 1494 SVP_VALIDf); 1495 if (svp_valid == 0) { 1496 return BCM_E_INTERNAL; 1497 } 1498 } 1499 /* Get VP value representing VP LAG */ 1500 *vp_lag_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf); 1501 break; 1502 case _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK: 1503 mem = SOURCE_TRUNK_MAP_TABLEm; 1504 1505 /* Get module id for unit. */ 1506 rv = bcm_esw_stk_my_modid_get(unit, &my_modid); 1507 if (BCM_FAILURE(rv)) { 1508 return rv; 1509 } 1510 1511 rv = _bcm_esw_trunk_local_members_get( 1512 unit, mkey->trunk_id, SOC_MAX_NUM_PORTS, local_port, 1513 &local_port_count); 1514 if (BCM_FAILURE(rv)) { 1515 return rv; 1516 } 1517 1518 /* Get index to source trunk map table, 1519 * Only get it from the first member in LAG 1520 */ 1521 rv = _bcm_esw_src_mod_port_table_index_get( 1522 unit, my_modid, local_port[0], &stm_idx); 1523 if (BCM_FAILURE(rv)) { 1524 return rv; 1525 } 1526 1527 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx, &stm_entry); 1528 if (BCM_FAILURE(rv)) { 1529 return rv; 1530 } 1531 1532 /* Resolve SVP Mode */ 1533 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) { 1534 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry, 1535 SVP_VALIDf); 1536 if (svp_valid == 0) { 1537 return BCM_E_INTERNAL; 1538 } 1539 } 1540 /* Get VP value representing VP LAG */ 1541 *vp_lag_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf); 1542 break; 1543 case _BCM_L2GRE_PORT_MATCH_TYPE_VPNID: 1544 tunnel_index = mkey->match_tunnel_index; 1545 tunnel_sip = L2GRE_INFO(unit)->l2gre_tunnel_term[tunnel_index].sip; 1546 1547 sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1548 mem = MPLS_ENTRYm; 1549 soc_mem_lock(unit, mem); 1550 soc_mem_field32_set(unit, mem, &ment, VALIDf, 1); 1551 1552 soc_mem_field32_set(unit, mem, &ment, L2GRE_SIP__SIPf, tunnel_sip); 1553 soc_mem_field32_set(unit, mem, &ment, 1554 KEY_TYPEf, _BCM_L2GRE_KEY_TYPE_TUNNEL); 1555 soc_mem_lock(unit, mem); 1556 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, &ment, 1557 &ment, 0); 1558 soc_mem_unlock(unit, mem); 1559 if (rv == BCM_E_NOT_FOUND) { 1560 rv = BCM_E_PARAM; 1561 } 1562 1563 if (BCM_FAILURE(rv)) { 1564 return rv; 1565 } 1566 1567 /* Get VP value representing VP LAG */ 1568 *vp_lag_vp = soc_mem_field32_get(unit, mem, &ment, L2GRE_SIP__SVPf); 1569 break; 1570 default: 1571 return BCM_E_PARAM; 1572 } 1573 1574 if (!_bcm_vp_used_get(unit, *vp_lag_vp, _bcmVpTypeVpLag)) { 1575 return BCM_E_INTERNAL; 1576 } 1577 1578 return rv; 1579 } 1580 #else /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 1581 int bcm_esw_td2_l2gre_not_empty; 1582 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */